On September 09, 2008, Richard Fateman wrote:
>>
>> Edwin Woollett wrote:
>> > integrate(..) returns undefined when it
>> > should know the answer.
>> >
>> > (%i1) declare( [ m, n ], integer )$
>> > (%i2) assume ( m > 0, n > 0 )$
>> > (%i3) integrate( cos(m*x)^2, x, 0, 2*%pi );
>> > (%o3) %pi
>> > (%i4) integrate( cos(m*x)*cos(n*x), x, 0, 2*%pi );
>> > Is n - m positive, negative, or zero?
>> >
>> > zero;
>> > (%o4) undefined
>> >
>> > Is this a known bug?
>>
> Not so clear a bug.
> (n-m)/(n-m) simplifies to 1.
> But if you know n=m, then you have 0/0. So is it a bug if (n-m)/(n-m) -->
> 1?
>
> Answer: maybe. But not clear :)
>
> RJF
>
First, having Maxima return "undefined" is incredibly better than returning
the wrong answer!
My impression is that Maxima's responses encourage the user to
take the care to investigate "special cases" of integral parameters
as independent problems. An attitude of "cautious optimism" and
"trust but verify" is appropriate.
When calculating a definite integral it is worth the extra time to
first see if Maxima can return the indefinite integral. If Maxima
CAN return the indefinite integral, it is pure gold, since you
can immediately check it by differentiation.
And it is not that much extra trouble to use Maxima's powerful
limit(..) function to then calculate the definite integral.
myintegrate(...) could first attempt to get the indefinite integral,
immediately check it by differentiation, and then use Maxima's
limit(...) function to return the answer. Only if the indefinite
integral attempt does not succeed, would myintegrate(..)
try more sophisticated methods.
Here is a stab at that approach in an interactive context
for the example which I presented:
( I have added the assumption that n > m, since the symmetry of
the integrand shows that this is no essential restriction and
why not help out Maxima?)
(%i1) display2d : false$
(%i2) (declare( [m, n], integer ),
assume ( m > 0, n > 0 , n > m) )$
(%i3) expr : cos(m*x)*cos(n*x)$
(%i4) i1 : integrate( expr, x );
(%o4) ( (n - m)*sin( (n + m)*x ) +
(n + m)*sin( (n - m)*x))/(2*n^2 - 2*m^2)
(%i5) di1 : ( diff( i1, x), expand(%%),
trigexpand(%%), ratsimp(%%) );
(%o5) cos(m*x)*cos(n*x)
(%i6) expr - di1;
(%o6) 0
(%i7) [ limit( i1, x, 2*%pi ), limit( i1, x, 0 ) ];
(%o7) [ 0, 0]
/* hence integral = 0 for m not equal to n */
/* now case m = n */
(%i8) i11 : limit( i1, m, n );
(%o8) sin(2*n*x)/(4*n) + x/2
(%i9) [ limit( i11, x, 2*%pi ), limit( i11, x, 0 ) ];
(%o9) [ %pi, 0 ]
/* hence integral = %pi for n = m */
(%i10) integrate( cos(n*x)^2, x, 0, 2*%pi );
(%o10) %pi
(%i11) integrate( expr, x, 0, 2*%pi );
(%o11) 0
On Sept. 11, 2008, Raymond Toy wrote:
>FWIW, here is what is happening. integrate eventually decides that the
>antiderivative should be computed and the limits substituted. Maxima
>tries to be careful with the limits by calling sin-cos-intsubs1. This
>splits the integrand into numerator and denominator. The limits are
>substituted into the numerator and evaluates to zero because we have
>expressions like sin(2*%pi*n), which is zero from the declaration on n.
>
>Since the numerator is 0, we check the denominator. Maxima can't tell
>if the denominator is 0 or not, so it asks. You respond with zero, so
>we know that we have the form 0/0. Hence it returns undefined.
>
>Now suppose we respond with pos instead of zero. Well, the denominator
>is no longer 0, so the answer is then 0.
>
>Anyway, that's why maxima returns undefined or 0 for this integrand. I
>can't think of any way to fix this.
>
In my original example, I did not assume n > m, and hence Maxima
asked if (n - m) was pos, neg, or zero. A possible response to that
answer "zero" would be NOT calling sin-cos-intsubs1 to separately look at
the limit of the numerator and the denominator, but to rather use
Maxima's powerful limit(...) function to look at the limit of the
whole expression as m --> n, as we did in our "rerun" above.
It is not clear that integrate(..) is actually being careful in this case.
Ted Woollett