Substitute variable? - maxima

I'm trying to substitute L with Lα:
f(x) := c * (x + L);
c: L;
f(x), L: Lα;
I expected the output:
Lα * (x + Lα)
instead I got
L * (x + Lα)
Maybe I should define f(x) instead?
kill(all);
define(
f(x),
c * (x + L)
);
c: L;
f(x), L: Lα;
Nope — same result.
Do I substitute L for Lα in a wrong way?
Edit:
Turns out it is expected behaviour, as maxima evavluates expression only once. One can impose "infinite evaluation" via the flag infeval:
f(x), L: La, infeval;
=> La*(x + La)
Another solution is to use subst instead:
subst(
Lα, L, f(x)
);
(source)

You need to add an extra eval step to make this work:
f(x) := c * (x + L);
c: L;
f(x), L: Lα, eval;
Output:
Lα (x + Lα)

Use subst instead of ev.
(%i1) f(x) := c * (x + L)$
(%i2) c: L$
(%i3) subst(L=La,f(x));
(%o3) La (x + La)
But keep in mind that the function continues to be c*(x+L). The symbol c has been bound to L and if you then bind the symbol L to La, c will continue to be bound to L and not to La. Maxima variables work as in Lisp, which might be different to what you are used to in other languages.

Related

Maxima: How to replace the variables to simplify the equation?

(%i1) r: sqrt(x^2+y^2+z^2);
(r) sqrt(z^2+y^2+x^2)
(%i2) dx: diff(r,x);
(dx) x/sqrt(z^2+y^2+x^2)
I just show a simple code because my code is long and complex.
I want to simplify dx and get the result is x/r not x/sqrt(z^2+y^2+x^2).
However, I can't find the useful command.
Could somebody help me to solve this problem?
In this specific case, you can use subst, although ratsubst is probably useful in a greater number of cases.
(%i1) linel:65;
(%o1) 65
(%i2) r: sqrt(x^2+y^2+z^2);
2 2 2
(%o2) sqrt(z + y + x )
(%i3) diff (r, x);
x
(%o3) ------------------
2 2 2
sqrt(z + y + x )
(%i5) subst (r = 'r, %o3);
x
(%o5) -
r
(%i6) ratsubst ('r, r, %o3);
x
(%o6) -
r
Note that the single quote mark prevents evaluation, so that 'r is the symbol r instead of the value of r (namely sqrt(x^2 + y^2 + z^2)).

Maxima CAS - substitution

I am trying to simplify a differential equation via substitution in maxima. However, the substitution does not seem to be working.
Here's my code:
depends (\rho,[t, r, \theta, z]); depends (V, [t, r, \theta, z]);
f_contin : diff (\rho, t) + diff (\rho*r*V[r], r)*(1/r) = 0;
base : diff (V[b]*r*\rho, r) = 0;
V_sub : V[r] = V[b] + \epsilon*V[r];
subst (V_sub, f_contin);
subst (base, %o6);
The last substitution did not work. What am I doing wrong here?
For clarity I add a Screenshot here:
The problem is that subst(a=b, c) (or equivalently subst(b, a, c)) can only make substitutions when a is an exact subexpression of c.
ratsubst (which see) can handle some cases when a is not an exact subexepression but in this case it doesn't seem to work.
But I think you can get the result you want by just subtracting the one equation from the other. Note that (a=b) - (c=d) yields a - c = b - d. Note also that I've put in another step (in %i7) to apply the diff operator. Also I've multiplied %o7 by r to get something like base.
(%i1) depends (\rho,[t, r, \theta, z]); depends (V, [t, r, \theta, z]);
(%o1) [rho(t, r, theta, z)]
(%o2) [V(t, r, theta, z)]
(%i3) f_contin : diff (\rho, t) + diff (\rho*r*V[r], r)*(1/r) = 0;
drho d
r V ---- + r (-- (V )) rho + V rho
drho r dr dr r r
(%o3) ---- + ------------------------------------ = 0
dt r
(%i4) base : diff (V[b]*r*\rho, r) = 0;
drho d
(%o4) V r ---- + (-- (V )) r rho + V rho = 0
b dr dr b b
(%i5) V_sub : V[r] = V[b] + \epsilon*V[r];
(%o5) V = epsilon V + V
r r b
(%i6) subst (V_sub, f_contin);
drho drho d
(%o6) ---- + (r (epsilon V + V ) ---- + r (-- (epsilon V + V )) rho
dt r b dr dr r b
+ (epsilon V + V ) rho)/r = 0
r b
(%i7) %o6, nouns;
drho drho d d
(%o7) ---- + (r (epsilon V + V ) ---- + r (epsilon (-- (V )) + -- (V )) rho
dt r b dr dr r dr b
+ (epsilon V + V ) rho)/r = 0
r b
(%i8) expand (r*%o7 - base);
drho drho d
(%o8) r ---- + epsilon r V ---- + epsilon r (-- (V )) rho + epsilon V rho = 0
dt r dr dr r r
The function subst (a,b,c) substitutes a for b in c. It uses 3 arguments, your first subst works because its interpreted as subst (V[b] + \epsilon*V[r],V[r], f_contin);
Your second subst is probably interpreted as subst (0,diff (V[b]*r*\rho, r),%) therefor nothing is substituted. What do you want to substitute for what?

maxima: use function as function argument

Like the title says, I want to use a function as a function argument.
Intuitive I tried something like:
a(t,c) := t+c;
b(R_11, R_12, R_13, d_1x, d_1y, d_1z) := R_11*d_1x + R_12*d_1y + R_13*d_1z;
f( a(t,c), b(R_11, R_12, R_13, d_1x, d_1y, d_1z), %lambda ) := a(t,c) +
%lambda * b(R_11, R_12, R_13, d_1x, d_1y, d_1z);
But Maxima stated "define: in definition of f, found bad argument"
My goal is to simplify my equations to get a better overview. When I differentiate like
diff( f(...), R_11 )
the result for this example should be the partial derivative of b with respect to R_11.
f' = b_R11(...)
Is there a way to do such thinks or is this an odd attempt and there is maybe a better way?
You can declare that b depends on some arguments and then diff will construct formal derivatives of b.
(%i1) depends (b, [R1, R2]);
(%o1) [b(R1, R2)]
(%i2) depends (a, t);
(%o2) [a(t)]
(%i3) f(t, R1, R2) := a(t) + b(R1, R2);
(%o3) f(t, R1, R2) := a(t) + b(R1, R2)
(%i4) diff (f(t, R1, R2), R1);
d
(%o4) --- (b(R1, R2))
dR1
(%i5) diff (f(t, R1, R2), t);
d
(%o5) -- (a(t))
dt
But that only works as long as b is undefined. When b is defined, diff will go ahead and call b and compute the derivative with respect to whatever is returned.
(%i8) b(R1, R2) := 2*R1 + 3*R2;
(%o8) b(R1, R2) := 2 R1 + 3 R2
(%i9) diff (f(t, R1, R2), R1);
(%o9) 2

Maxima - differentiating a piecewise function

Suppose you have a function defined by intervals, such as
f(x):=block(if x<0 then x^2 else x^3);
When we differentiate it with
diff(f(x),x);
we get
d/dx (if x<0 then x^2 else x^3)
whereas I'd like to get
(if x<0 then 2*x else 3*x^2)
Is there a way to obtain such result?
This may help in a simple case:
(%i1) f(x):= charfun(x<0)*x^2 + charfun(x>=0)*x^3$
(%i2) gradef(charfun(y), 0)$
(%i3) diff(f(x),x);
2
(%o3) 2 x charfun(x < 0) + 3 x charfun(x >= 0)
charfun, gradef
You can try also Pw.mac package from Richard Hennessy.
Here's a different approach using a simplification rule for "if" expressions. The unsolved part here is to detect discontinuities and generate delta functions for those locations. If you want to ignore those, you can define FOO to return 0. Note that I didn't attempt to implement the function discontinuities; that part is unsolved here. I can give it a try if there is interest.
(%i1) display2d : false $
(%i2) matchdeclare ([aa, bb, cc], all, xx, symbolp) $
(%i3) 'diff (if aa then bb else cc, xx) $
(%i4) tellsimpafter (''%, apply ("if", [aa, diff (bb, xx), true, diff (cc, xx)]) + FOO (aa, bb, cc, xx)) $
(%i5) FOO (a, b, c, x) := 'lsum ((ev (c, x = d) - ev (b, x = d)) * delta (d, x), d, discontinuities (a, x)) $
(%i6) diff (if x > 0 then x^2 else x^3, x);
(%o6) (if x > 0 then 2*x else 3*x^2)+'lsum((d^3-d^2)*delta(d,x),d,
discontinuities(x > 0,x))
Building on slitinov's answer I wrote this quite naive implementation for functions with more than two "pieces":
gradef(charfun(dummy),0)$
/* piecewise function definition */
itv: [[x<0],[x>=0,x<1], [x>=1]]; /* intervals */
fi: [ 1, x^2+1, 2*x ]; /* local functions */
/* creation of global function f and its derivative df */
f:0;
for i: 1 thru 3 do f:f+charfun(apply("and",itv[i]))*fi[i];
df:diff(f,x);
/* display of local functions and derivatives */
for i: 1 thru 3 do (
apply(assume,itv[i]),
newline(),
print(itv[i]),
print("f = ",ev(f)),
print("df = ",ev(df)),
apply(forget,itv[i])
);
plot2d([f,df],[x,-2,3],[y,-1,5],[style,[lines,4,3],[lines,2,2]]);

symbolically replace expressions in maxima

I'm having trouble finding out how to do this:
x=a+b
y=c+d
z=x*y
I would like the output to be
z=ac+ad+bc+bd
not
z=xy
Like this?
(%i1) x: a+b;
(%o1) b + a
(%i2) y: c+d;
(%o2) d + c
(%i3) z: x*y;
(%o3) (b + a) (d + c)
(%i4) z: expand (z);
(%o4) b d + a d + b c + a c
(%i5)
Assignment in maxima is done by :, not = (which is used for checking for equality)
Actually, to get the output he's requesting without assigning a lot of variables,
you can just do this:
(%i1) z = x*y, x = a+b, y = c+d, expand;
(%o1) z = b d + a d + b c + a c
This is an old question, but the canonical solution in my opinion is the subst() function

Resources