caiohamamura
caiohamamura

Reputation: 2728

Sympy substitute in fractions won't work as expected

Simpy is not detecting basic substitions with subs.

I have the following fraction:

d₂⋅n₁⋅n₂
──────── + m₂⋅n₁ + mm₂⋅n₂
   nc
─────────────────────────
            nc

Written as

cm2 = (d2*n1*n2/nc + m2*n1 + mm2*n2)/nc

Now I want to replace n1/nc = np1 and n2/nc = np2. So I've written:

cm2.subs({n1/nc : symbols("np1"), n2/nc: symbols("np2")})

The result is:

d₂⋅np1⋅n₂ + m₂⋅n₁ + mm₂⋅n₂
──────────────────────────
            nc

Instead I expected that sympy would figure out the other substitutions and output:

d2⋅np1⋅np2 + m2⋅np1 + mm2⋅np2

What I'm missing here?

Upvotes: 0

Views: 208

Answers (2)

smichr
smichr

Reputation: 19047

subs is mostly literal, so after the first substitution, say n1/nc->n1p, then n2/nc no longer appears and so it cannot be replaced. But it's not necessary to do the re-arrangement of expressions to get them in the form needed to make the substitution, you can use solve to resolve everything for you:

>>> eqs
(Eq(cm2, (d2*n1*n2/nc + m2*n1 + mm2*n2)/nc), Eq(n1/nc, np1), Eq(n2/nc, np2))
>>> solve(eqs,cm2,n1,n2, dict=True)
[{cm2: d2*np1*np2 + m2*np1 + mm2*np2, n1: nc*np1, n2: nc*np2}]

There is also an unimplemented feature described here that offers, perhaps, a more intuitive way of doing this.

Upvotes: 2

JohanC
JohanC

Reputation: 80329

Sympy's subs can have troubles converting an expression by another expression, especially if they don't appear literally in the source expression. It also can be quite ambiguous.

When the goal is that all n1 and n2 disappear from cm2, the substitution can be written differently:

from sympy import symbols

d2, n1, n2, nc, m2, mm2, n = symbols("d2 n1 n2 nc m2 mm2 n")
np1, np2 = symbols("np1 np2")
cm2 = (d2 * n1 * n2 / nc + m2 * n1 + mm2 * n2) / nc
cm2.subs({n1: np1 * nc, n2: np2 * nc}).simplify()

Result: d2*np1*np2 + m2*np1 + mm2*np2

Upvotes: 1

Related Questions