Uwe.Schneider
Uwe.Schneider

Reputation: 1415

Sympy -- Simplify and gather different variables for variable transformation

In a sympy expression I would like to gather all sub expressions of (x*y) and replace it by z, wherever possible. In a very simple example, that means performing the map

x*a*y+ (x*y**2) -> a*(x*y) + (x*y)*y -> a*z + z*y

The full code is with another example is

from sympy import symbols,Function,Derivative
from sympy import simplify, exp, cos, sin,log

x,y,z = symbols('x y z')
a,b,c = symbols('a b c')
f,g   = Function('f')(x),Function('g')(x)
# Simplify the expression such that all combinations of (x*y) can be replaced by c
expr_1 = ((x**2+y)*y*exp(-c+2*log(x*c*y)))/(x**3*c*y**2)

#simplify(expr_1) ? 

In a final step, I would like to replace two functions f*g by h

expr_2 = f*g + f*Derivative(g,x) + Derivative(f*g, x) -> h + f*Derivative(g,x) + Derivative(h, x)

Upvotes: 0

Views: 230

Answers (1)

smichr
smichr

Reputation: 19077

Sometimes an algebraic substitution will do what you want:

>>> eq
a*x*y + x*y**2
>>> eq.subs(x,z/y)
a*z + y*z

But you could just as well have done subs(y,z/x) but that would not have led to as simple of an expression. In such cases you can try both and take the simpler of the two:

>>> from sympy import ordered
>>> next(ordered([eq.subs(x,z/y),eq.subs(y,z/x)]))
a*z + y*z

For expr_1

>>> eq=((x**2+y)*y*exp(-c+2*log(x*c*y)))/(x**3*c*y**2)
>>> next(ordered([eq.subs(x,z/y),eq.subs(y,z/x)]))
c*z*(x**2 + z/x)*exp(-c)/x**2
>>> next(ordered([eq.subs(x,c/y),eq.subs(y,c/x)]))
y**2*(c**2/y**2 + y)*exp(-c)
>>> simplify(_)
(c**2 + y**3)*exp(-c)

The ordered strategy should also work for expr_2.

Upvotes: 1

Related Questions