Alejandro Jakubi

MaplePrimes Activity


These are answers submitted by Alejandro Jakubi

Actually limit is limited. All the functions it handles have their domain on the reals/complex, rather than on the integers (or some other discrete set) as in this case. Consequently, assuming integer or the like will not make any difference. An extension handling limits on sequences has been asked frequently here. 

Yes, I can believe that there were no keyboard shortcut alternative. The Standard GUI is plenty of similar examples, see e.g. this case.

The save command could be handy in such situations:

> a:=1:b:=2:c:=3:
> save a, "a.m":
> restart:
> a,b,c;
                                    1, b, c

This troblesome transformation arises in the procedure `expand/exp/*`. So, redefining it as follows provides another workaround that may be convenient, though not without risk (of breaking something around that might depend on this transformation):

> expand(exp(2*a+b));
                                       2
                                 exp(a)  exp(b)
> forget(expand):
> `expand/exp/*`:=proc()
> exp(args[2]);
> end proc:
> 
> expand(exp(2*a+b));
                                exp(2 a) exp(b)

Actually, it "works" as designed. Another question is whether the current design is good... Basically, the difference is that cos is a procedure which computes this result -1, taking into account the assumption on k:

> trace(cos):
> trace(frac):
> cos(k*Pi) assuming k::odd;
execute cos, args = k*Pi
{--> enter cos, args = k*Pi
                                    t := k~
...
{--> enter frac, args = 1/2*k-1/2
                                       0
<-- exit frac (now in cos) = 0}
                                   res := -1
                                cos(k~ Pi) := -1
<-- exit cos (now in assuming) = -1}
                                       -1

While, the power "operator" `^` is (basically) a constructor with no code equivalent to cos. The equivalent code is located instead in the procedure `simplify/power`, hence the need to run simplify explicitly (or the like).

You may try raising the infolevel value for solve, like:

> infolevel[solve]:=1:
> eqs:={y-x=0,y-x=1}:
> solve(eqs,{x,y});
solve:   Warning: no solutions found

About Axel's caveat, yes, Maple (as other CAS) is not a theorem prover. So, such a message means that the system is unable to find a solution. Something different from proving that no solution exists.

For rational, here linear, substitution patterns, algsubs works fine:

> solve(eq1,{z});
                        {z = -a x1 - a x2 - a x3 - a x4}
> algsubs(eq2,%);
                                   {z = -a m}

Compare subs with algsubs:

> subs(x+y=u,a*x+a*y);
                                   a x + a y
> algsubs(x+y=u,a*x+a*y);
                                      a u

The difference is that subs makes syntactic substitution, and at the syntactic level x+y is not a subexpression of a*x+a*y. This is basically the same reason why isolate fails (as it relies on has):

> trace(has):
> isolate(a*x+a*y,x+y);
execute has, args = a*x+a*y, x+y
Error, (in isolate) a*x+a*y does not contain x+y

A third (undocumented) way to enlarge the integration database is adding entries to the Maple table `int/itable`. Its entries have a form like:

> `int/itable`[sin(_X)];
                                    -cos(_X)

where the index is the integrand, which may be an expression, with the restrictions that the integration variable has to be represented by  the (protected) global name _X and it cannot contain any other name representing a parameter. So, this method is not actually much useful for your actual integrand containing the parameters a and b, but anyway, setting a=1 and b=1, it would go as follows:

> `int/itable`[_X^2*BesselJ(0, _X)*BesselI(1, _X)]:=
> (BesselJ(1, _X)*BesselI(1, _X)+BesselJ(0, _X)*BesselI(0, _X))*_X^2/2- > 2*(BesselJ(1, _X)*BesselI(0, _X)+BesselJ(0, _X)*BesselI(1, _X))*_X/4: > int(4*r^2*BesselJ(0, r)*BesselI(1, r),r=0..1); -2 BesselI(0, 1) BesselJ(1, 1) + 2 BesselI(0, 1) BesselJ(0, 1) + 2 BesselJ(1, 1) BesselI(1, 1) - 2 BesselJ(0, 1) BesselI(1, 1)

Not exactly, but you can execute kernelopts(memusage) before and after a statement and compare the memory usage change for each kind of internal object (DAG), see ?kernelopts .

By default, Maple show only the direct solution. But the steps it takes can be examined with varied detail, depending on needs. This is an example for the Fourier transform:

> with(inttrans):
> infolevel[`fourier/table`]:=3:
> fourier(t*exp(-3*t^2),t,w);
inttrans/fourier/lookup:   Enter with    t*exp(-3*t^2)   t   v
inttrans/fourier/lookup:   Looking up   t*exp(-3*t^2)   in Exponential table   
 2
inttrans/fourier/lookup:   Looking up   t*exp(-3*t^2)   in other table
inttrans/fourier/lookup:   Returning    FAIL
inttrans/fourier/lookup:   Enter with    exp(-t^2)   t   _S
inttrans/fourier/lookup:   Looking up   exp(-t^2)   in Exponential table    1
inttrans/fourier/lookup:   Returning    exp(-1/4*_S^2)*Pi^(1/2)
                                             2
                         -1    1/2          w      1/2
                         -- I 3    w exp(- ----) Pi
                         18                 12

There are at least two ways to enlarge Maple's integration database. I have sketched a bit hackish but powerful way here. A second way employs the poorly documented extension mechanism for indefinite integration for which I have shown you a toy example here. And for the current example, a function call like rBB(r,a,b), say, has to represent the integrand r^2*BesselJ(0, a*r)*BesselI(1, b*r). Then, you just write the extension procedure for it like:

> `int/rBB`:=proc(f)
> local r:=op(1,f),a:=op(2,f),b:=op(3,f);
> (BesselJ(1, a*r)*BesselI(1, b*r)*a+BesselJ(0, a*r)*BesselI(0, b*r)*b)*r^2/(a^2+b^2)-
> 2*b*(BesselJ(1, a*r)*BesselI(0, b*r)*a+BesselJ(0, a*r)*BesselI(1, b*r)*b)*r/(a^2+b^2)^2;
> end proc:
> 
> int(rBB(r,a,b),r);
                                                                         2   /
(BesselJ(1, a r) BesselI(1, b r) a + BesselJ(0, a r) BesselI(0, b r) b) r   /
                                                                           /
      2    2
    (a  + b ) - 2 b
    (BesselJ(1, a r) BesselI(0, b r) a + BesselJ(0, a r) BesselI(1, b r) b) r/
      2    2 2
    (a  + b )

There are some low level (syntactic) issues with the available pattern matcher. For instance, exp(-x) does not match 1/exp(x) as they are different type, and so on. It means that the transformation rules have to be written "expanded", taking account such diverse type cases. In your example, it could go this way:

> kappa2:=map(expand,kappa,1-w[1]):
> ss2:=map(expand,ss(2),1-w[1]):
> ss3:=map(expand,ss(3),1-w[1]):
> ss4:=map(expand,ss(4),1-w[1]):
> 
> r1:=ss(1)=s[1]:
> r2:=[ss2=s[2],-ss2=-s[2]]:
> r3:=[ss3=s[3],-ss3=-s[3]]:
> r4:=[ss4=s[4],-ss4=-s[4]]:
> map2(applyrule,r1,kappa2):
> map(x->collect(x,s[1]),%):
> map2(applyrule,r4,%):
> map2(applyrule,r3,%):
> map2(applyrule,r2,%);
                     [                 1                  ]
                     [                                    ]
                     [           -s[1] s[3] + 1           ]
                     [                                    ]
                     [             s[3] s[1]              ]
                     [                                    ]
                     [                       2            ]
                     [1 + (-s[3] + s[4]) s[1]  - s[2] s[1]]
                     [                                    ]
                     [                          2         ]
                     [        (s[3] - s[4]) s[1]          ]
                     [                                    ]
                     [           2                        ]
                     [      -s[1]  s[4] + s[1] s[2]       ]
                     [                                    ]
                     [                      2             ]
                     [             s[4] s[1]              ]
 

Type n integer does not follow from property n integer. So (in a fresh session):

> assume(n::integer):
> is(n,integer);
                                      true
> type(n,integer);
                                     false
> type(A^n, `^`(name,name));
                                      true
> type(A^n, `^`(name,integer));
                                     false

PD. Certainly the type satisfies mechanism shown by Edgardo is a method for the integration of property checking in a type statement environment, being suitable here for both, n asumed integer and 5 type integer:

> type(n,satisfies(x->is(x,integer)));
                                      true
> type(5,satisfies(x->is(x,integer)));
                                      true

However, there is an undocumented command `tools/type`, frequently used in the library, and providing the same functionality, that is clearly handier:

> `tools/type`(n,integer);
                                      true
> `tools/type`(5,integer);
                                      true

So, in my opinion, if it turns out so useful for developers, it would be also for ordinary users if they know it. Then it should be provided as a documented top level command with a "normal" name.

4 5 6 7 8 9 10 Last Page 6 of 29