Maxima 5.25.1: integrate is buggy



On 2012-06-27, Barton Willis <willisb at unk.edu> wrote:

> The substitution takes a lengthy path involving the functions
> no-err-sub, subin, maxima-substitute, and subst1.

Thanks for the hint. I've attached a patch which replaces the call to
MAXIMA-SUBSTITUTE with a call to $AT, which handles 'diff, 'integrate,
and 'sum specially, and otherwise acts like a general substitution
function. With that in place, I get the following:

(%i3) integrate (diff (f (x), x), x, a - b, a + b);
(%o3) f(b+a)-f(a-b)
(%i4) integrate (diff (f (x), x, 2), x, a - b, a + b);
(%o4) ?%at('diff(f(x),x,1),x = b+a)-?%at('diff(f(x),x,1),x = a-b)
(%i5) integrate ('diff (f (t) * diff (g (t), t), t), t, 0, 1);
(%o5) f(1)*(?%at('diff(g(t),t,1),t = 1))-f(0)*(?%at('diff(g(t),t,1),t = 0))

(%i7) assume (alpha > 0);
(%o7) [alpha > 0]
(%i8) integrate ('diff (f (t) * diff (g (t), t), t), t, 0, sqrt (alpha));
(%o8) f(sqrt(alpha))*(?%at('diff(g(t),t,1),t = sqrt(alpha)))
 -f(0)*(?%at('diff(g(t),t,1),t = 0))
(%i9) assume (beta > 0);
(%o9) [beta > 0]
(%i10) integrate ('diff (f (t) * diff (g (t), t), t), t, sqrt (beta), sqrt (alpha));
(%o10) f(sqrt(alpha))*(?%at('diff(g(t),t,1),t = sqrt(alpha)))
 -f(sqrt(beta))*(?%at('diff(g(t),t,1),t = sqrt(beta)))

Here is the last result, pretty-printed:

(%i11) display2d : true;
(%o11)                               true
(%i12) %o10;
                                !
                       d        !
(%o12) f(sqrt(alpha)) (-- (g(t))!               )
                       dt       !
                                !t = sqrt(alpha)
                                                               !
                                                      d        !
                                     - f(sqrt(beta)) (-- (g(t))!
                                       )
                                                      dt       !
                                                               !t = sqrt(beta)


The only change in the test suite is this:

Running tests in rtest16:
********************** Problem 260 ***************
Input:
limit(integrate(f(t), t, 0, x), x, 0, plus)


Result:
0

This differed from the expected result:
limit   integrate(f(t), t, 0, x)
x -> 0+


Comments?

> There is a special *atp* that might control the application of at.
> But setting *atp* to true yields, for example:
>
>  (%i12) integrate(diff(f(x),x,2),x,a+b,a-b);
>  (%o12) 0

Well, I think *ATP* prevents MAXIMA-SUBSTITUTE from substituting into
'diff, so that defint's attempt to compute antideriv(a - b) - antideriv(a + b)
yields 0. I wonder if *ATP* has other unexpected effects ....

> either "at" is trying to be super careful, or it's missing some
> simplifications:
>
>   (%i15) at(diff(f(t),t),x=9);
>   (%o15) at('diff(f(t),t,1),x=9)

Hmm, I suppose f might use x as a global variable ....

best

Robert Dodier

PS.
$ git diff src/limit.lisp
diff --git a/src/limit.lisp b/src/limit.lisp
index f5bf22f..a9ec491 100644
--- a/src/limit.lisp
+++ b/src/limit.lisp
@@ -948,12 +948,16 @@ It appears in LIMIT and DEFINT.......")
     (handler-case
        (setq ans (catch 'errorsw
                    (catch 'raterr
-                     (sratsimp (subin v e)))))
+                     (sratsimp (subin-via-$at v e)))))
       (maxima-$error ()
        (setq ans nil)))
     (cond ((null ans) t)     ; Ratfun package returns NIL for failure.
          (t ans))))
 
+(defun subin-via-$at (v e)
+  (cond ((not (among var e)) e)
+       (t ($at e `((mequal) ,var ,v)))))
+
 ;; substitute value v for var into expression e.
 ;; if result is defined and e is continuous, we have the limit.
 (defun simplimsubst (v e)