maximabinomial-cdf

maxima bug in distrib core library using cdf_binomial?


I am pretty new to maxima, which I installed a few days ago via brew on MacOS ARM. ergo, I do not know whether I found a bug, or a feature, or I am doing something stupid altogether. The following example shows the unexpected error I get:

$ maxima
Maxima 5.46.0 https://maxima.sourceforge.io
using Lisp SBCL 2.3.3
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) load ("distrib"); 
(%o1) /opt/homebrew/Cellar/maxima/5.46.0_11/share/maxima/5.46.0/share/distrib/\
distrib.mac
(%i2) cdf_binomial(4,4,p);
(%o2)                                  1
(%i3) subst( [S=3], cdf_binomial(S,4,p)); 
                                     3    2
(%o3)                      (1 - p) (p  + p  + p + 1)
(%i4) subst( [S=4], cdf_binomial(S,4,p));

beta_incomplete: beta_incomplete(0,5,1-p) is undefined.
 -- an error. To debug this try: debugmode(true);
(%i5) 

Am I doing something wrong here? (PS: My real use will be integrating over p up to 1, which also triggers this problem.) Are there standard workarounds?

Advice appreciated.


Solution

  • The error you're seeing is actually a subtle consequence of the way unevaluated conditional expressions are handled. (An example of an unevaluated conditional is returned by cdf_binomial(S, 4, p).) A simpler example of the bug (I'll create a bug report) is '(if 0 > 0 then 0/0 else inf) which bumps into a division by 0 error even though 0 > 0 is false.

    As a workaround, try ev(myexpr, S = 4) where myexpr is assigned the value returned by cdf_binomial(S, 4, p).

    This detour via ev is unnecessary if S has an assigned value -- in that case, cdf_binomial returns one case or another, and doesn't return an unevaluated conditional. The need for special handling comes into play when cdf_binomial was called with S not having an assigned value, so cdf_binomial didn't know which branch to take and therefore returned an unevaluated conditional.

    EDIT: I also investigating equipping beta_incomplete_regularized with an additional identity for the first argument being zero. Looks like beta_incomplete_regularized(0, n, z) equals 1, at least when n is an integer. I'll look for a reference for that, but in the meantime one can tell Maxima to recognize that identity via tellsimp.

    (%i2) matchdeclare (nn, integerp) $             
    (%i3) matchdeclare (zz, all) $
    
    (%i4) tellsimp (beta_incomplete_regularized (0, nn, zz), 1) $
    
    (%i5) beta_incomplete_regularized (0, 5, z);
    (%o5)                           1
    (%i6) load (distrib);
    (%o6) /usr/local/share/maxima/branch_5_46_base_1803_g61b2abdd9/s\
    hare/distrib/distrib.mac
    (%i7) cdf_binomial (S, 4, p);
    (%o7) if S < 0 then 0 elseif S >= 4 then 1
     else beta_incomplete_regularized(4 - floor(S), floor(S) + 1, 
    1 - p)
    

    Now the substitution into the unevaluated conditional is okay because beta_incomplete_regularized doesn't complain.

    (%i8) subst (S = 4, %);
    (%o8)      if 4 < 0 then 0 elseif 4 >= 4 then 1 else 1
    

    The literal inequalities 4 < 0 and 4 >= 4 require an explicit evaluation (a long story which I'll omit) to derive false and true from them.

    (%i9) ''%;
    (%o9)                           1
    

    Now the call to quad_qags succeeds.

    (%i10) quad_qags (subst (S = 4, cdf_binomial (S, 4, p)), p, 0, 1);
    (%o10)         [1.0, 1.110223024625157e-14, 21, 0]