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)
)
);