I suggest you remove all the print() statements and just try trace(r1)
etc.
Alternatively,
Your program seems to be quite long, and hardly using maxima.
Maxima knows how to do diff(sin(f(x)),x), etc etc so why not use that
information instead of typing it in again?
For example,
something like this..
If E is an atom, then if E=x then 1 else 0
else /* here we know that E= g(a);
compute dE = g(f1(x)).
set df1(x)/dx etc to 1. You then have the gradient of g,
regardless of whether g is sin, cos, asin, ....
now look at a ... and compute its derivative as needed.
This should be about 5 lines of code, except that you will need to deal with
variable numbers of arguments for + and *.
RJF
_____
From: maxima-bounces at math.utexas.edu [mailto:maxima-bounces at math.utexas.edu]
On Behalf Of Robert Marik
Sent: Sunday, March 02, 2008 3:48 PM
To: maxima at math.utexas.edu
Subject: Re: [Maxima] maxima - rules and patterns
On Tue, Feb 26, 2008 at 5:42 PM, Robert Dodier <robert.dodier at gmail.com>
wrote:
If you post the rules you want to implement, in some non-Maxima
notation, I can help you translate them (or I'll try, anyway)
into Maxima rules.
best
Robert Dodier
I have the following code, which seems to work, the function
diff_in_steps(x^2*sin(x^3))
differentiates with respect to x and shows steps, but it fails for
diff_in_steps(x^2*sin(y))
It remains to solve this problem (it is not possible to use parameters or
functions in more variables) and also to format the result for reading --
with tex and texput(derivace,["\\left(","\\right)^\\prime"],matchfix)
Since I am new in Maxima (I use it for less than one year), I would like to
post my code to this group. If you have any suggestions or improvements, let
me know please.
Short explanation of the code:
The string to be differentiated is in the function derivace(expr) - I use
the Czech word in order not to break anything.
The function derivace is declared to be linear
We try the usual rules for basic elementary functions first.
If all the rules fail, we try to use product rule and if this fails as well,
we try quotient rule. (here I observed a strange thing: op(u/v) gives "//"
on debian and "/" on archlinux)
We try the product rule as follows: we replace the function derivace with
derivsoucinu and this new function returns derivace(expr) if expr is not a
product or derivace(u)*v+u*derivace(v). In a similar way we work with
quotient.
We use small maxapplydepth to ensure that only one or few rules are applied
on each step.
We finish if the word "derivace" is missing in the expression or after 100
steps.
Robert Marik
----------------------------------------------------------------------------
---------------------------
constantp_not1 (x%) := constantp(x%) and x% # 1;
matchdeclare(g,true,n,constantp_not1,c,constantp);
/* formulas with chain rule */
defrule(c1, derivace(c), (print ("constant: (",c,")'=0"), 0));
defrule(x1, derivace(x), (print ("x: (",x,")'=1"), 1));
defrule(r1, derivace(sin(g)), (print ("sine:
(sin(",g,"))'=cos(",g,")*(",g,")'"),if g=x then cos(x) else
cos(g)*derivace(g)));
defrule(r2, derivace(cos(g)), (print ("cosine:
(sin(",g,"))'=cos(",g,")*(",g,")'"), if g=x then -sin(x) else
-sin(g)*derivace(g)));
defrule(r3, derivace(tan(g)), (print ("tangent:
(tan(",g,"))'=1/cos^2(",g,")*(",g,")'"), if g=x then 1/(cos(x))^2 else
1/(cos(g))^2*derivace(g)));
defrule(r4, derivace(cot(g)), ( print ("cotangent:
(cot(",g,"))'=1/sin^2(",g,")*(",g,")'"), if g=x then -1/(sin(x))^2 else
-1/(sin(g))^2*derivace(g)));
defrule(r5, derivace(n), (print ("constant",n),0));
defrule(r6, derivace(g^n), (print ("power:
(",g^n,")'=",n*g^(n-1),"*(",(g),")'"), if g=x then n*x^(n-1) else
n*(g)^(n-1)*derivace(g)));
defrule(r7, derivace(exp(g)), (print ("natural eponential:
(",exp(g),")'=",exp(g),"*(",(g),")'"), if g=x then exp(x) else
exp(g)*derivace(g)));
defrule(r8, derivace(n^g), (print ("eponential:
(",n^g,")'=",log(n)*n^g,"*(",(g),")'"), if g=x then log(n)*n^g else
log(n)*n^(g)*derivace(g)));
defrule(r9, derivace(log(g)), (print ("logarithm:
(",log(g),")'=",1/g,"*(",(g),")'"), if g=x then 1/g else
1/(g)*derivace(g)));
defrule(r10, derivace(log10(g)), (print ("decadic logarithm:
(",log10(g),")'=",1/(g*log(10)),"*(",(g),")'"), if g=x then 1/(g*log(10))
else 1/(g*log(10))*derivace(g)));
defrule(r11, derivace(asin(g)), (print ("arcsin:
(",asin(g),")'=",1/sqrt(1-g^2),"*(",(g),")'"), if g=x then 1/sqrt(1-g^2)
else 1/sqrt(1-g^2)*derivace(g)));
defrule(r12, derivace(acos(g)), (print ("arccos:
(",acos(g),")'=",-1/sqrt(1-g^2),"*(",(g),")'"), if g=x then -1/sqrt(1-g^2)
else -1/sqrt(1-g^2)*derivace(g)));
defrule(r13, derivace(atan(g)), (print ("arctan:
(",atan(g),")'=",1/(1+g^2),"*(",(g),")'"), if g=x then 1/(1+g^2) else
1/(1+g^2)*derivace(g)));
defrule(r14, derivace(acot(g)), (print ("arccotan:
(",acot(g),")'=",-1/(1+g^2),"*(",(g),")'"), if g=x then -1/(1+g^2) else
-1/(1+g^2)*derivace(g)));
/* product and quotient rule */
derivsoucinu(expr):= if (op(expr)="*") then (u:args(expr)[1], v:expr/u,
print("product: (",u*v,")'=..."),derivace(u)*v+u*derivace(v)) else
derivace(expr);
derivpodilu(expr):= if (op(expr)=op(u/v)) then (u:args(expr)[1], v:u/expr,
print("quotient: (",u/v,")'=..."), (derivace(u)*v-u*derivace(v))/(v^2)) else
derivace(expr);
declare(derivace,linear);
derivacep(expr):=numberp(ssearch("derivace",string(expr)));
diff_one_step(fce):=
if derivacep(fce) then
(
block(initfce:string(fce),
newfce:fce,
for i:0 step 1 unless ((i>100) or
(string(fce)#string(newfce))) do
(maxapplydepth:i,
newfce:apply2(fce,c1,x1,r5,r1,r2,r3,r4,r6,r7,r8,r9,r10,r11,r12,r13,r14))),
if fce#newfce then newfce else
(aa:''tryproduct(fce),
if aa#fce then aa else
(bb:''tryquotient(fce),
if bb#fce then bb else
fce
)
)
)
else print("nothing more to differentiate ...") ;
/* function to differentiate products and quotients */
tryproduct(expr):=
(
exprstr:string(expr),
newexprstr:ssubst("derivsoucinu","derivace",exprstr),
eval_string(newexprstr)
);
tryquotient(expr):=
(
exprstr:string(expr),
newexprstr:ssubst("derivpodilu","derivace",exprstr),
eval_string(newexprstr)
);
diff_in_steps(expr):=
(newfce:derivace(expr),
for counter:1 step 1 unless ((counter>100) or (not(derivacep(newfce)))) do
(
newfce:diff_one_step(newfce),
print("y'=",newfce)
)
);