From: Eduardo O. <edu...@gm...> - 2023-10-01 03:26:56
|
On Sat, 30 Sept 2023 at 14:22, Robert Dodier <rob...@gm...> wrote: > On Sat, Sep 30, 2023 at 5:44 AM Eduardo Ochs <edu...@gm...> > wrote: > > > is(equal(op(del(w)), 'del)); > > is(equal(op(f(x,y)), 'del)); > > Maybe you can say something about your larger goal here. If the goal > is to process del(something) expressions somehow, there are ways to > get Maxima to handle a lot of the details for you, via the pattern > matching functions (tellsimp, tellsimpafter, defrule, defmatch). If > you find yourself writing code which tests the operator and perhaps > the arguments as well to check for different conditions, the code can > probably be simplified and extended by using pattern matching > functions. > > best, > > Robert > Hi all, thanks for all the responses! Robert, right now what I am trying to do is to write functions to let me handle shorthands like y=y(x) and z=z(x,y) as "real shorthands", that can be expanded and shortened/contracted... For example, if both "y=y(x)" and "z=z(x,y)" are active in the list of shorthands then "z" expands to "z=z(x,y(x))", but if only "z=z(x,y)" is active then "z" expands to "z=z(x,y)". The code of my current prototype is below, followed by some tests. About tellsimp and friends: I know vaguely what they do and I'm trying to understand some examples - and I don't have any idea if they could be useful in this case or not... I tried to explain the rationale for the code below here: http://anggtwu.net/eev-maxima.html#physicists-notation Cheers, and please send pointers and suggestions... Eduardo Ochs http://anggtwu.net/eev-maxima.html --snip--snip-- pnshorten_del(delx) := buildq([delx, dx:concat('d,args(delx)[1])], delx=dx)$ pnexpand_del (delx) := buildq([delx, dx:concat('d,args(delx)[1])], dx=delx)$ pnshorten_f (zxyz) := buildq([ z : op (lhs(zxyz)), xy : args(lhs(zxyz))], z(splice(xy)) = z)$ pnexpand_f (zxyz) := buildq([ z : op (lhs(zxyz)), xy : args(lhs(zxyz))], z = z(splice(xy)))$ pnshorten_1 (pexpr) := if is(op(pexpr)='del) then pnshorten_del(pexpr) else pnshorten_f(pexpr)$ pnexpand_1 (pexpr) := if is(op(pexpr)='del) then pnexpand_del(pexpr) else pnexpand_f(pexpr)$ pnshorten_ify(pexprs) := map('pnshorten_1,pexprs); pnexpand_ify (pexprs) := map('pnexpand_1, pexprs); pnshorten (pexprs,o) := subst(pnshorten_ify(pexprs), o); pnexpand (pexprs,o) := subst(pnexpand_ify (pexprs), o); pnshortenr(pexprs,o) := subst(reverse(pnshorten_ify(pexprs)), o); pnexpandr (pexprs,o) := subst(reverse(pnexpand_ify (pexprs)), o); pnas : [y(x),y_x(x),del(x),del(y)]; /* Default abbreviations! Change this! */ pnex(o) := pnexpand (pnas, o); /* Expand using the current pnas */ pnsh(o) := pnshortenr(pnas, o); /* Shorten using the current pnas */ /* Basic tests: */ pnshorten_ify([y(x),del(x)]); pnexpand_ify ([y(x),del(x)]); pnshorten ([y(x),del(x)], (y(x1)-y(x))*del(x)); /* The Folium of Descartes is: * x^3 + y^3 = 6*x*y; * In this test we differentiate the Folium implicitly * using only dependent variables. */ gradef(y(x), y_x(x)); "these tests don't use gradef(y,x,y_x)"$ e1 : x^3 + y^3 = 6*x*y; "Folium of Descartes"$ pnex(e1); diff(pnex(e1), x); e2 : pnsh(diff(pnex(e1), x)); e3 : solve(e2, y_x)[1]; /* In this variant we differentiate the Folium * using dependent variables and differentials. */ diff(e1); e2 : pnsh(diff(e1)); solve(e2, dy)[1]; factor(solve(e2, dy)[1]); e3 : factor(solve(e2, dy)[1]) / dx; /* A case in which the partial and the * total derivatives are different. */ "Use z=z(x,y) and y=y(x)"$ map('kill, [z,y]); gradef(z(x,y), z_x(x,y), z_y(x,y)); gradef(y(x), y_x(x)); gradefs; pnas : [z(x,y),z_x(x,y),z_y(x,y), y(x),y_x(x)]; pnex(z); diff(pnex(z),x); pnsh(diff(pnex(z),x)); "=> z_x + z_y y_x"$ "Use only z=z(x,y)"$ map('kill, [z,y]); gradef(z(x,y), z_x(x,y), z_y(x,y)); gradefs; pnas : [z(x,y),z_x(x,y),z_y(x,y)]; pnex(z); diff(pnex(z),x); pnsh(diff(pnex(z),x)); "=> z_x"$ |