TriGiamp
TriGiamp

Reputation: 35

Collect and substitute terms in very long and nested expressions with sympy

Short version:I want to collect and substitute some terms that I can clearly read in the expression but are not picked by sympy subs function.

I've done the symbolic computation in python, but in the end I will have to make these computation in C#. For this purpose, I'm trying to do some substitutions and partial numerical evaluations that I will hardcode in C#

As example this is one of the expressions (simple, I have to do this job on expressions ten times longer and with more levels of parenthesis):

from sympy import symbols
x,y,rho_0,v = symbols('x y rho_0 v')
expr = 4*x*(x**2 + y**2)*(7*(-1 + 2*(x**2 + y**2)/rho_0**2)**2 + 8 - 14*(x**2 + y**2)/rho_0**2)/rho_0**4 + (x**2 + y**2)**2*(56*x*(-1 + 2*(x**2 + y**2)/rho_0**2)/rho_0**2 - 28*x/rho_0**2)/rho_0**4

I don't know how to display equations in a better format here, sorry. But the point is that I can clearly see that I can collect and substitute (x**2 + y**2)/rho_0**2 with very small manipulations

Using expr.subs((x**2 + y**2)/rho_0**2, v) has not given any result. I started using sympy last week so I don't know much yet, I think should try to navigate the expression from the innermost level of parenthesis, factorize and try to substitute, but I don't have any clue on how to do it.

Upvotes: 0

Views: 582

Answers (1)

smichr
smichr

Reputation: 19093

subs has a hard time when a target contains an Add and is multiplied by a Rational. Targeting the Add first and continuing from there brings more success:

>>> expr
4*x*(x**2 + y**2)*(7*(-1 + (2*x**2 + 2*y**2)/rho_0**2)**2 + 8 - (14*x**2 + 
14*y**2)/rho_0**2)/rho_0**4 + (x**2 + y**2)**2*(56*x*(-1 + (2*x**2 + 
2*y**2)/rho_0**2)/rho_0**2 - 28*x/rho_0**2)/rho_0**4

Get the Rational separated from the Add

>>> factor_terms(expr)
4*x*(x**2 + y**2)*(7*(-1 + 2*(x**2 + y**2)/rho_0**2)**2 + 8 + 7*(-3 + 4*(x**2 + 
y**2)/rho_0**2)*(x**2 + y**2)/rho_0**2 - 14*(x**2 + y**2)/rho_0**2)/rho_0**4

Do subs in two steps: make Add a Symbol and then Add/Pow the Symbol

>>> _.subs(x**2+y**2, v).subs(v/rho_0**2, v)
4*v*x*(7*v*(4*v - 3) - 14*v + 7*(2*v - 1)**2 + 8)/rho_0**2

Simplify if desired

>>> _.simplify()
4*v*x*(56*v**2 - 63*v + 15)/rho_0**2

Upvotes: 0

Related Questions