7.40 bug in convert/expsincos in Maple 6 (8.2.01)

7.40.1 Pavel Honzatko
7.40.2 Preben Alsholm (12.2.01)
7.40.3 Robert Israel (12.2.01)
7.40.4 Werner Knoben (16.2.01)

7.40.1 Pavel Honzatko

Does anybody know, why the following occurs in Maple 6.01 and how to fix this.

>convert(I*cos(x),expsincos); 
Error, (in convert/expsincos) too many levels of recursion
 

This problem in slightly modified form appears in integration of

>int(exp(-I*w*t)/cosh(t),t); 
Error, (in convert/expsincos) too many levels of recursion
 

It is corrected with Maple 7. (U. Klein)

7.40.2 Preben Alsholm (12.2.01)

This is no explanation, but just an addition. I tried the following

trace(`convert/expsincos`); 
convert(I*cos(x),expsincos);
 

and I got quite a number of identical statements of the form

enter convert/expsincos, args = I

before my Windows 95 decided to shut down the program.

If we look at the procedure `convert/expsincos` with

> showstat(`convert/expsincos`);
 

then we see in line 24:

map(`convert/expsincos`,f)
 

When `convert/expsincos` is applied to I*cos(x) the first that happens is that `convert/expsincos` is mapped onto 'I' and cos(x). It is 'I' that is the problematic input to `convert/expsincos` since it is not handled by any other line in the procedure. Thus 'I' will by line 24 be sent to `convert/expsincos`(I) which by its line 24 will send 'I' to etc.....

The 'I' should have been handled by the first line but

type(I,ratpoly(numeric));
 

returns false in Release 6, but not in Release 5.1.

I suspect that the bug is caused by the change in the handling of complex numbers from Release 5.1 to 6.

7.40.3 Robert Israel (12.2.01)

This is a bad bug, which makes convert(..., expsincos) practically useless on anything containing I. The problem shows up in an even simpler form:

> convert(I, expsincos); 
 
Error, (in convert/expsincos) too many levels of recursion
 

The problem, I think, is that `convert/expsincos` starts with

       if nargs = 1 and type(f,ratpoly(numeric)) then 
         ... 
       elif nargs = 2 and not has(f,x) then 
         ... 
       elif type(f,function) and nops(f) = 1 then 
         ... 
       elif type(f,name) then 
         ... 
       else 
         map(`convert/expsincos`,f) 
       end if
 

Since none of the other conditions is true in convert(I,expsincos), the last "else" clause will run, and `convert/expsincos` will be called recursively. It used to be that I was an alias for (-1)^(1/2), so there would be two recursive calls of `convert/expsincos` with -1 and with 1/2. However, as of Maple 6, I is of type "complex", and is considered to be atomic. Thus now `convert/expsincos` is called recursively with the same argument I, and we get an infinite recursion.

At first I thought that a fix was to use the remember table of `convert/expsincos`, with

> `convert/expsincos`(I):= I;
 

However, there would still be trouble with every other object of type "complex". Instead, I’ll write a "wrapper" for `convert/expsincos`:

> oldconv:= eval(`convert/expsincos`); 
  `convert/expsincos`:= proc(f) 
      if type(f,And(complex,atomic)) then f 
      else oldconv(args) 
      fi 
   end;
 

This ought to work.

7.40.4 Werner Knoben (16.2.01)

The reason for the mistake of the function convert/expsincos is that the complex unit I is not any more of type numeric. In the fourth line of the source code of the command `convert/expsincos` you find

if nargs = 1 and type(f,ratpoly(numeric)) then f
 

Change this to

if nargs = 1 and type(f,ratpoly({numeric,complex})) then f
 

and the function works correct.