Joe Shields
Joe Shields

Reputation: 113

Substitution into multiple sub-expressions in SymPy

I have a situation where I'm assigning expressions to many symbols in SymPy. They reference each other, and I want to be able to evaluate one of the higher-level expressions in terms of some starting parameters which determine everything else.

Here is my example code:

In [1]: from sympy import *
In [2]: x, y, z = symbols('x y z')
In [3]: z = x+y
In [4]: x=y
In [5]: z.subs({y: 2})
Out[5]: x + 2

I would expect to get 4, since x should be evaluated to be 2. What am I missing and how can I evaluate z "all the way"?

In my actual code, I want to be able to evaluate things "all the way" even when multiple layers of evaluation are required. Of course, in the real code, I can't just do z.subs({y: 2, x: y}), since the relationships between x and y are complicated.

The real code happens to be this:

In [1]: from sympy import *
   ...: y, q, c, F, M, cr, ct, bst, kq, kF, kM = symbols('y q c F M cr ct bst kq
   ...:  kF kM')
   ...: c = cr + y*(cr+ct)/(bst/2)
   ...: q = kq*c
   ...: F = integrate(q, y) + kF
   ...: kF = -(F-kF).subs({y: bst/2}) # BC: F=0 when y=bst/2
   ...: M = integrate(F, y) + kM
   ...: kM = -(M-kM).subs({y: bst/2}) # BC: M=0 when y=bst/2
   ...: 
   ...: LV3parms = {cr: 18, ct: 5, kq: 1, bst: 6.42}
   ...: M.subs(LV3parms)
Out[1]: kF*y + kM + 1.19418483904465*y**3 + 9*y**2

Upvotes: 1

Views: 874

Answers (1)

Martin Krämer
Martin Krämer

Reputation: 577

Your lines In[3] and In[4] both create new immutable expressions and do not change their right side expressions in any way. So the call in In[5] is in no way related to your In[4] where you set x=y, which only changes x and in In[5] you operate on z.

You simply need to chain the expressions properly:

x,y,z = symbols('x y z')
x = y
z = x+y
z.subs({y: 2})

This outputs 4 as you would expect.

Upvotes: 2

Related Questions