## 2448 Reputation

14 years, 26 days

## a way using a parametrical rule...

You may try a procedure that generates a parametric transformation rule extracting the coefficient for a 1-D mode given the function (sin or cos), the numeric label of the mode and the variable name (here x or z):

```fc1d:=proc(f::name,n::posint,v::name)
a::And(algebraic,Not(specfunc(algebraic,{sin,cos})))*f(n*v)+b::algebraic=a:
end proc:

S:= A*cos(2*x)*sin(3*z) + B*cos(7*x)*sin(4*z) + C*sin(3*z)+K*sin(4*z)+cos(7*x):

applyrule(fc1d(sin,3,z),S);
C
applyrule(fc1d(sin,4,z),S);
K
applyrule(fc1d(cos,7,x),S);
1
```

## A GUI way...

An easy GUI way is exporting the  worksheet to html. It generates a gif file for each plot in the array, and the html file contains a table with a cell for each of them. So, you could upload the gif files and copy&paste the table into the graphic editor (or the html code into the html text editor).

## expand with option...

To prevent a single function from the effect of expand, here cos(2*z), it is simpler to use the function name as an option for expand:

```exprsn1:=sin(z)*(A*cos(z) + B*cos(x)*cos(2*z) + C*cos(x)):
exprsn2:= applyrule(sin(z)*cos(2*z)=1/2*(sin(3*z)-sin(z)), expand(exprsn1,cos));
exprsn2:=
sin(z) A cos(z) + (1/2 sin(3 z) - 1/2 sin(z)) B cos(x) + sin(z) C cos(x)
```

On the other hand, the frontend trick is more handy to prevent expansion of all the subexpressions, see ?expand.

Certainly, it would have been better that expand worked the other way round: just apply the distributive property unless told to expand something else, and an option all to apply all the expansion rules. Also, a mathematical pattern matcher is needed that does not require from the user to accomodate the expressions and rules to such syntactic peculiarities.

## More curiosities...

I can confirm that the OP's commands work as expected in Maple 16.02 Classic GUI on Linux Mint 13 32-bit. Yet, on this same platform and Maple version, the Standard GUI (worksheet mode, 1-D input, typesetting standard), produces no output (rather than the symbol `Non-fatal error ...`). Certainly,

```ToInert(eval(soltn));
```

does show the inert form of a procedure after an unusual long time. But

```FromInert(%);
```

shows no output either. On the other hand:

```disassemble(eval(soltn));
```

produces here a "Kernel Connection Lost" crash. And

```S := ToInert(eval(soltn)):
mx := kernelopts('maximmediate'):
select(`>`, FromInert~(indets(S, _Inert_INTPOS(anything))), +mx);
```

produces a set of 272 integer, while

```select(`<`, FromInert~(indets(S, _Inert_INTNEG(anything))), -mx);
```

produces a set of 98 integers. And Digits:=20 does not work here. So there is a 32 vs 64-bit condiment involved in this bug.

Also, this is a regression bug. I observe it also in Maple 14.01 and 15.01 Standard GUI, while it does not occur in Maple 13.02 or before.

## Why does Maple put a space?...

This "feature"  appeared in Maple 11 Standard GUI. This means, at a time of consolidation of 2-D input. Consequently, may be that the designers of this GUI like it this way. Sadly, this information is not available to the users. Many features of this GUI cannot be configured. In particular this space insertion, I think.

## the fix point...

Yes, this "infinite" loop behavior is a consequence of the designed behavior as ?applyrule states: "applyrule computes the fix point". But what if a fix point does not exist? This design does not include an automatic control condition for stopping unending recursions, less a user option that controls the number of iterations. So, I consider these issues as a design bug.

I have written this modified version of the procedure:

```applyrule1 := proc(_rules, expr,n:=1)
rec := proc (e, pattern) local res; res := tablelook(args); if res = FAIL then `if`(type(e,'{`*`, `+`, `^`, set, list, function}'),map(procname,args),e) else res end if end proc;
rules := compiletable(map(proc (rul) if type(rul,'conditional(anything,anything)') then rul elif type(lhs(rul),'`+`') then lhs(rul)+APP::algebraic = rhs(rul)+APP elif type(lhs(rul),'`*`') then lhs(rul)*APP::algebraic = rhs(rul)*APP else rul end if end proc,`if`(_rules::list,_rules,[_rules])));
if _npassed=3 and [_passed][3]='fix' then
i := NULL;
else
texpr:=expr;
for i to n do
texpr:=rec(texpr,rules);
end do;
end if;
end proc:
```

As you see, it adds a third parameter that provides this control. Its default value is 1, so that in your example it works like:

```applyrule1(r,cos(alpha));
alpha 2
2 cos(-----)  - 1
2
```

Otherwise, you may pass the number of times you want as a third argument (a positive integer), or set it to fix if you want to recover the fix point behavior (I notice that Preben suggested using infinity as default value for this parameter, but I find that most frequently what is needed is a single pass, and Mathematica default seems like that).

On the other hand, as you have discovered, a modification of the transformation rule that uses a different function name on its rhs breaks the infinite recursion. It can be done easier by using the inert version of the function name like:

```r1:=cos(th::algebraic)=2*%cos(th/2)^2-1:
applyrule(r1,cos(alpha));
alpha 2
2 %cos(-----)  - 1
2
value(%);
alpha 2
2 cos(-----)  - 1
2
```

## Long Delimiters...

The subsection "Long Delimiters" in ?updates,Maple6,language gives the reasons for this change:

The ending delimiter for the if statement was previously fi, while the ending delimiter for loops was od. The ending delimiter for procedures was simply end. With the addition of several new structures (try, module, and use), this scheme of reverse-spelling the beginning delimiter was unworkable. Therefore, a consistent ending delimiter scheme has been adopted.

Compared to typing some full qualified procedure names like verylongmodulename:-exportedprocedure that you may use, end do does not seem so much, even to a lazy typer like me. Anyway, writing code in an editor with a macro facility may help for those frequently used structures.

## collect by rule...

Using a transformation rule may be the easier way like:

```r:=A::algebraic*sqrt(a::algebraic)+B::algebraic*sqrt(a::algebraic)=(A+B)*sqrt(a):
ex:=(-14+9*(2-2*cos(mux))^(1/2))*cos(mu*x)+62+27*(2-2*cos(mux))^(1/2):
applyrule(r,expand(ex));
1/2
(27 + 9 cos(mu x)) (2 - 2 cos(mux))    + 62 - 14 cos(mu x)
```

And as an alternative to having in store a factorization rule specific to sqrt expressions, you may just keep a procedure generating factorization rules for diverse expressions:

```fac:=proc(p)
A::identical(p)*B::algebraic+A::identical(p)*C::algebraic=A*(B+C):
end proc:

applyrule(fac((2-2*cos(mux))^(1/2)),expand(ex));
1/2
(27 + 9 cos(mu x)) (2 - 2 cos(mux))    + 62 - 14 cos(mu x)

```

Note that I dislike retyping input from an image. Just use the preformatted mode.

## unprotect hack...

Yes, this unprotect hack seems to work fine. And the result can be put as shown in the link above, with p=1/3:

```unprotect(`series`):
series:=MultiSeries:-series:
residue(1/x^(1/3)/(x^2+2*x*cos(phi)+1), x=-exp(I*phi));
3 exp(phi I)
- ------------------------------------------------------------
1/3              2
(-exp(phi I))    (7 exp(phi I)  - 8 cos(phi) exp(phi I) + 1)

dividend(%,numer(%),[u->u,simplify@(u->convert(u,exp))]);
1/2 I
-------------------------
1/3
(-exp(phi I))    sin(phi)

```

Where I am using the procedure dividend.

## casesplit...

Not exactly that, but pay a look at ?PDEtools,casesplit (it uses either the Rif subpackage of DEtools or the package DifferentialAlgebra).

## when anything else fails......

Frequently, your best choice in such a case is using a transformation rule. Depending on your needs, one of these rules (or a variation on them) may be fit for you:

```f:=cos(sqrt(g)*sqrt(m+M)/(M^(3/2)*sqrt(l))*t):

r1:=cos(a::algebraic*t)=cos(Omega*t):
applyrule(r1,f);
cos(Omega t)

r2:=sqrt(g)*sqrt(m+M)/(M^(3/2)*sqrt(l))=Omega:
applyrule(r2,f);
cos(Omega t)
```

The advantage of this method is that you get a partial independization from the internal representation constraints.

## by arithmeticâ€“geometric mean...

It uses the AGM method. See also ?GaussAGM. This information should be better documented.

## more alternatives...

By pattern matching, binding equations are generated for the extraction of the exponents and bases:

```patmatch(x^n+ y^3.5,a::algebraic^s::symbol+b::algebraic^f::float,'p');p;p:='p':
true
[a = x, b = y, f = 3.5, s = n]
```

Also, for symbolics, these undocumented commands may become useful:

````tools/symbolic_degree`(x^n,x);
n
`tools/symbolic_base`(x^n,x);
x
```

## larger usage...

Indeed, I observe here a significantly larger usage of resources in Maple 16.02 wrt Maple 15.01, by a factor of 1.7 to 1.8 in CPU and real time:

```#M16.02:
CodeTools:-Usage(Student[Calculus1][FunctionChart](x*exp(1/x)));
memory used=36.33MiB, alloc change=34.71MiB, cpu time=581.00ms, real time=841.00ms

#M15.01:
CodeTools:-Usage(Student[Calculus1][FunctionChart](x*exp(1/x)));
memory used=23.30MiB, alloc change=18.93MiB, cpu time=321.00ms, real time=492.00ms
```

And I agree, this plot looks worst in Maple 16.02.

## value...

The problem with expand, in my opinion, is precisely that it expands even more:

```s:=(2*Pi/z)^``(1/2);
/2 Pi\ (1/2)
s := |----|
\ z  /
expand(s);
1/2   1/2       (1/2)
2    Pi    (1/z)
```

While "normal" should be not pulling 2^(1/2) out unless requested or allowed by the user. So, I think that a better approach is replacing `^` by its inert version `%^` at the begining of automatic simplification time, so that the structure of the expression is kept along this period, and it could be further manipulated if desired. And the automatically simplified version of the expression with 2^(1/2) pulled out can be recovered by using value.

Yet, the null function trick is useful for printing purposes, so that a `print/%^` extension can be used for this purpose:

````print/%^`:=proc(a,b) a^``(b) end proc:
use `^`=`%^` in (2*Pi/z)^(1/2) end use;
/2 Pi\ (1/2)
|----|
\ z  /
s1:=%:

lprint(s1);
`%^`(2*Pi/z,1/2)

value(s1);
1/2 / Pi \1/2
2    |----|
\ z  /
```

However, all of these are fragile tricks. A real solution should involve a builtin capability of switching off the automatic simplification.

 First 18 19 20 21 22 23 24 Last Page 20 of 29
ï»¿