# Is there any way I can substitute a combination of variables. I know this is a long short but I was wondering whether it is possible to substitute a combination of variables by something else. Let me explain it with an example.

Let $f(x,y,z) = f(x) \sqrt{x^2+y^2+z^2} + f(y) \sqrt{x^2+y^2+z^2} + f(z) \sqrt{x^2+y^2+z^2}$

As we can see the combination $\sqrt{x^2+y^2+z^2}$ occurs very often. Is there a way I call this combination some other variable, say, w. I cannot use substitute in this case as I want to leave $x$,$y$ and $z$ alone if they dont come in this specific combination $\sqrt{x^2+y^2+z^2}$. If it were a string I could have used find and replace. But I want to use the expression as a input later on in the notebook.

Edit: I came across a sympy command which is very close to what I want to do but not quite. There is a command cse in the module simplify. However, it identifies the subexpresssion by itself. As far as I could see it does not offer the flexibility for the users to identify the subexpression. Also for some reason sage expressions cannot be converted to sympy using f._sympy_() if there are "i"'s in the expression.

edit retag close merge delete

Sort by » oldest newest most voted It's occasionally a little flaky, but I think substitute_expression (subs_expr) can do what you want:

sage: var("x y z")
(x, y, z)
sage: var("w")
w
sage: f = function("f")
sage: s = sqrt(x*x+y*y+z*z)
sage: eq = f(x,y,z) == f(x) * s + f(y) * s + f(z) * s
sage: eq
f(x, y, z) == sqrt(x^2 + y^2 + z^2)*f(x) + sqrt(x^2 + y^2 + z^2)*f(y) + sqrt(x^2 + y^2 + z^2)*f(z)
sage: eq.subs_expr(sqrt(x*x+y*y+z*z)== w)
f(x, y, z) == w*f(x) + w*f(y) + w*f(z)
 

Also, if you want to force a replace if subs_expr is being disobedient, you could treat it as a string and then evaluate it back. It's ugly, but there are times you might want to do something like this:


sage: # ugly and dangerous! do not use!
sage: tmp = str(eq)
sage: tmp2 = tmp.replace(str(s), 'w')
sage: sage_eval(tmp2,locals=vars())
f(x, y, z) == w*f(x) + w*f(y) + w*f(z)


but this can lead to problems when the string you're replacing is a substring of something else.

more I figured out that the "subs" command in sympy is far more powerful than substitute in sage. So I converted the sage expression into sympy expression using f=f._sympy_() then did the substitution I wanted to do and after the substitution converted to sage again using f=f._sage_(). The problem is that sympy gives a problem because it cannot recognize i. So I declared a variable name i and restored it in the end. Here is an example script. It would be awesome though if the sage substitute command worked like the sympy subs command.

from sympy import Symbol, cos, sympify, pprint
from sympy.abc import x
x=var('x')
z=var('z')
i=var('i')
f=x*x+x*i+1
view(f)
f=f._sympy_()
view(f)
f=f.subs(x*x,z)
f=f._sage_()
view(f)
restore('i')

more