Alejandro Jakubi

MaplePrimes Activity


These are answers submitted by Alejandro Jakubi

Surely series is documented as a constructor and probably piecewise is another one, even if not documented as such. I find this subject of constructors quite important, even if the documentation on this subject is still poor and dispersed. 

Functional-stryle programming is yet another relevant subject, also poorly documented.

Pattern matching by patmatch, applyrule and define is also very important, even despite the bag of bugs of the PatternMatching package and the so bad documentation, as conditional constructs are potentially very powerful.

Control of the order of evaluation. It has advanced by the introduction of the inertization prefix % for function names, even when its handlig is yet incomplete in some parts of the system.

 

Jacques has explained here key weaknesses of the of Maple GUIs and the reason why Mathematica is more advanced in this area. So, it seems like a similar functionality to Mathematica's Manipulate will not be possible to implement in Maple until a substantial improvement is made in the GUI design.

Already in 2007, Jacques has qualified the latex facility as ancient, and I have observed just a minimal maintenance on this facility along many years. So, most likely, it does not support atomic identifiers, which were introduced much later, in 2005 for Maple 10.

Because the programmatic (C) and graphic (Java) sides of the Standard GUI have not been developed in sync along the late versions. Find this pessimistic comment by Paulina on the chances of getting both sides in sync for plots.

For example, for saving your plot as a PostScript file, you could write an input.mpl file like:

f:=x->x^2: 
plotsetup(ps,plotoutput="plot.ps"):
plot(f(x),x=0..10);

See ?plotsetup and ?plot,device for options.

@Markiyan Hirnyk 

In Maple 14 a more "powerful" algorithm was introduced for the computation of symbolic derivatives, producing results for expressions that previously returned unevaluated. The problem is that for some expressions, the output of diff is well defined only for some values of the differentiation index, typically negative ones (symbolic integration), but it is singular for the rest, as in the OP's example. In Maple 14 and 15:

diff( (x^2-1)^l,x$l);
   (-l)  l
  x     2  exp(l Pi I)

                                                                  2
        MeijerG([[0, 1/2, l + 1], []], [[0], [1/2 + l/2, l/2]], -x )/

        GAMMA(-l)

while in Maple 13 or before:

diff( (x^2-1)^l,x$l);
                             l
                            d     2     l
                            --- (x  - 1)
                              l
                            dx

In some cases, the regular result for the derivative can be recovered from the singular one by using limit or MultiSeries:-limit for specific values of the index. This issue has been reported already for Maple 14.

The new algorithm is somewhat aware of assumptions. For instance:

diff( (x^2-1)^l,x$l) assuming l::nonnegint;
                             l
                            d     2     l
                            --- (x  - 1)
                              l
                            dx

So, a workaround is using assuming as a mechanism for "disabling" the algorithm computing the symbolic derivative, like:

sum(`assuming`([diff( (x^2-1)^l,x$l)],[l::nonnegint]),l=0..L) ;
                 2       3        2               4
  -3 + 2 x + 12 x  + 48 x  + 72 (x  - 1) x + 384 x

                  2       2         2     2
         + 1152 (x  - 1) x  + 144 (x  - 1)

A common factor of type constant as here can easily be cancelled out by a transformation rule that iteratively extracts the factor out from a sum by taking pairs of summands, and applying it to the subexpressions of type `+`, like:

fac3:=A::constant*B::algebraic+A::constant*C::algebraic=A*(B+C):
ex:=(Pi^2*(c+(1+Pi)/Pi)^2+Pi^2)/((c-(-1+Pi)/Pi)^2*Pi^2+Pi^2):

subsindets(ex,`+`,x->applyrule(fac3,x));

                          /    1 + Pi\2
                          |c + ------|  + 1
                          \      Pi  /
                          ------------------
                          /    -1 + Pi\2
                          |c - -------|  + 1
                          \      Pi   /

The simple pattern above will not work for coefficients of type constant. So, a rule specific for the factor at hand may be better:

p:=identical(Pi^2):
fac0:=A::p*B::algebraic+A::p*C::algebraic=A*(B+C):
subsindets(ex,`+`,x->applyrule(fac0,x));

                          /    1 + Pi\2
                          |c + ------|  + 1
                          \      Pi  /
                          ------------------
                          /    -1 + Pi\2
                          |c - -------|  + 1
                          \      Pi   /

I think that the mechanism, or part of it, can be seen in a procedure named plot/adaptive/evalpoint and created on the fly. Its relevant control part seems to be here:

> stopat(`plot/sample`,10): 
> plot(x+4*sin(x)+(exp(1/x^5)+2.13)*I*1e-7,x=-8..8,
>      thickness=3,color=black);
-8
`plot/sample`:
  10*      x := left+(i-1+jitter[jpos])*gap;

> showstat(`plot/adaptive/evalpoint`,13..19)  

`plot/adaptive/evalpoint` := proc(_x, `plot/_v`)
local err, useevalhf, valid;
       ...
  13   if valid and (true and (type(`plot/_v`[1],('embedded_real')('finite')) 
or type(`plot/_v`[1],('complex')('numeric'))
and abs(Im(`plot/_v`[1])) < abs(Re(`plot/_v`[1]))*10^(isqrt(Digits)-Digits))
and (type(`plot/_v`[2],('embedded_real')('finite'))
or type(`plot/_v`[2],('complex')('numeric'))
and abs(Im(`plot/_v`[2])) < abs(Re(`plot/_v`[2]))*10^(isqrt(Digits)-Digits))
or not true and type(`plot/_v`[1],('embedded_real')('finite'))
and type(`plot/_v`[2],('embedded_real')('finite'))) then 14 `plot/_v`[1] := Re(`plot/_v`[1]); 15 `plot/_v`[2] := Re(`plot/_v`[2]); 16 `plot/_v`[3] := Re(`plot/_v`[3]) else 17 `plot/_v`[1] := undefined; 18 `plot/_v`[2] := undefined; 19 `plot/_v`[3] := undefined end if end proc

Maple indefinite integration routines are weak at producing nice, compact answers (see here). In my opinion, the simplest and more reliable way for simplifying such results is using transformation rules, like:

cossq:=A::algebraic*cos(a::algebraic)^(n::even)=A*(1-sin(a)^2)^(n/2):

J1:=int(cos(x)^3, x);
                                2
                J1 := 1/3 cos(x)  sin(x) + 2/3 sin(x)

(expand@applyrule)(cossq,J1);
                                            3
                         sin(x) - 1/3 sin(x)


J2:=int(sin(x)^4*cos(x)^3, x);
                   3       4                     4
  J2 := -1/7 sin(x)  cos(x)  - 3/35 sin(x) cos(x)

                      2
         + 1/35 cos(x)  sin(x) + 2/35 sin(x)

(expand@applyrule)(cossq,J2);
                                5             7
                      1/5 sin(x)  - 1/7 sin(x)

This bug is located in the integration method contour. Excluding it, the outer integral returns unevaluated:

q := exp(-x1*log(x1)-x2*log(x2)):
F:=int(Dirac(x1+x2-r)*q, x1 = 0 .. 1):
int(F,x2=0..1,method=nocontour);

This bug is actually a regression. I observe it in Maple 11.02 but not in Maple 10.06, that returns this integral unevaluated.

On the other hand, when the integrand is simplify(F) instead, all the integration methods are tried and fail, as you can see by:

restart:
q := exp(-x1*log(x1)-x2*log(x2)):
F:=int(Dirac(x1+x2-r)*q, x1 = 0 .. 1):
infolevel[IntegrationTools]:=5:
int(simplify(F),x2=0..1);

Definite Integration:   Integrating expression on x2=0..1
Definite Integration:   Using the integrators [distribution, piecewise, series, o, polynomial, 
ln, lookup, cook, ratpoly, elliptic, elliptictrig, meijergspecial, improper, asymptotic, ftoc,
ftocms, meijerg, contour] Definite Integration: Trying method distribution. Definite Integration: Trying method piecewise. Definite Integration: Trying method series. Definite Integration: Trying method o. Definite Integration: Trying method polynomial. Definite Integration: Trying method ln. Definite Integration: Trying method lookup. LookUp Integrator: unable to find the specified integral in the table Definite Integration: Trying method cook. Definite Integration: Trying method ratpoly. Definite Integration: Trying method elliptic. Definite Integration: Trying method elliptictrig. Definite Integration: Trying method meijergspecial. Definite Integration: Trying method improper. Definite Integration: Trying method asymptotic. Definite Integration: Trying method ftoc. Definite Integration: Trying method ftocms. Definite Integration: Trying method meijerg. Definite Integration: Trying method contour. Definite Integration: Returning integral unevaluated. 1 / | | -(-Heaviside(1 + x2 - r) + Heaviside(x2 - r)) | / 0 (x2 - r) (-x2) (-x2 + r) x2 dx2

You may try something like this:

restart:
interface(imaginaryunit=_I):
define(M, 'flat', 'multilinear', 'identity' = 1,
M(I,I)=-1, M(J,J)=-1, M(K,K)=-1, M(I,J)=K, M(J,I)=-K, M(J,K)=I,
M(K,J)=-I, M(I,K)=-J, M(K,I)=J, M(a::anything*X::dependent(x),c::anything)=M(a,c)*X, M(a::anything,b::anything*X::dependent(x))=M(a,b)*X); M(I,J); K M(I*x,J); K x M(I*x^n,J); n K x M(I*sin(x),J); K sin(x)

Note that Maple does not even have a package for linear algebra with symbolic dimension (see e.g. here).

What Maxima package, after your source, handles tensor calculus with symbolic dimension?

Actually, D calls `PD/PD` (PD presumably stands for "partial derivative"), as it can be seen by tracing:

restart:
trace(`PD/PD`):
D(k -> (y -> y^k));
{--> enter PD/PD, args = k -> y -> y^k, 1, 1
[...]
<-- exit PD/PD (now in D/procedure) = k -> 0}
                                  0

And the PD routines are those making the actual computation, hence failing in this case of nested procedures:

`PD/PD`(k -> y -> y^k, 1, 1);
                                k -> 0

`PD/PD`(y -> y^k, 1, 1);
                                    k
                                   y  k
                              y -> ----
                                    y

Now, these routines seem quite old. On the one hand their copyright says 1992:

op(3,eval(`PD/PD`));
  Copyright (c) 1992 by the University of Waterloo. All rights reserved.

And on the other hand, they exhibit code based on the "hackware package", e.g.:

showstat(`PD/PD`,25);
`PD/PD` := proc(p, i, n)
local j, k, l, m, t, x, params, keyword_opts, types, locals, body, depends, derivs, temps, diffs, funcs, vars, lexicals, opts;
global `PD/CFOLD`, `PD/LOCALS`, `PD/SUBSTS`;
       ...
  25   body := pointto(disassemble(addressof(p))[6]);
       ...
end proc

which, I think, is quite outfashioned (probably used until the mid 90's).

So, in my interpretation, the main cause why such mathematical notation does not work is simply that the code supporting this area of symbolic computation has been basically frozen for over 15 years.

What works in Classic GUI, for cycling between open windows, is Ctrl+F6. I have been using it in all versions since Maple V Release 3, probably. Very handy.

The installation log file includes the font files installed, like:

Install File:             C:\WINDOWS\Fonts\COB_____.ttf
                          Status: SUCCESSFUL
First 25 26 27 28 29 Page 27 of 29