Search code examples
sympy

How to substitute a term in sympy, if equation would first need to be rewritten


I have the following expression:

O = symbols('O', linear=True)
mu = symbols('mu')
zeta = symbols('zeta')
f = IndexedBase('f')
first_cc = Eq(f[0,0,1] - zeta*f[0,0,0], 0)

expression = -O*mu*zeta*f[0, 0, 0] + O*mu *f[0, 0, 1]

If equation first_cc is used, the expression should evaluate to 0. However, if I am doing this

pprint(expression.subs(first_cc.lhs, first_cc.rhs)) 

Nothing happens, I think because the equation is not explicitly written in terms of f[0,0,1] - zeta*f[0,0,0]`. In this specific case I can get around this by first simplifying:

pprint(simplify(expression).subs(first_cc.lhs, first_cc.rhs))

which gives 0 as expected. The problem is, that simplify doesnt always write expression in terms of first_cc.lhs, so this doest work for more complicated expression. How can I force sympy to use the information from first_cc?


Solution

  • The issue of trying to replace a sum with a symbol (or in your case, use a relationship in an expression) is an often asked question. Unless the sum appears exactly as given in subs -- not with a constant multiplying each term -- the substitution will fail. Solving for one of the symbols in the sum other than the one you want to have in the final expression is the usual solution, e.g.

    >>> from sympy.abc import x,y,z
    >>> rep= solve(Eq(x + z, y),exclude=[y],dict=True)[0]
    >>> (2*x + 2*z).subs(rep)
    2*y
    

    In your case,

    O = symbols('O', linear=True)
    mu = symbols('mu')
    zeta = symbols('zeta')
    f = IndexedBase('f')
    first_cc = Eq(f[0,0,1] - zeta*f[0,0,0], 0)
    expression = -O*mu*zeta*f[0, 0, 0] + O*mu *f[0, 0, 1]
    
    >>> expression.subs(solve(first_cc,dict=True)[0])
    0
    

    In this case there is no further (or preliminary) simplification that is necessary. I wouldn't be suprised if, for some case, an expand would be necessary to bring about the simplification to 0.