Sympy substituting many variables with powers


Really, this is two questions in one.

Suppose I have the following code:

from sympy import *

x1, x2, x3, y1, y2, y3 = symbols("x1 x2 x3 y1 y2 y3")

term = x1**5 + (x2**2)*(x3**3) + x1**4 + x1**3 + x1**2 + x1

term = term.subs(x1**2, y1)
term = term.subs(x2**2, y2)
term = term.subs(x3**2, y3)

After the above, term takes the value x1**5 + x1**3 + x1 + x3**3*y2 + y1**2 + y1.

Question 1: I would like to turn all x_i^(2n+1) into the form x_i*(y_i^n) – but this leaves the odd powers of x_i alone. Is there any way to achieve this?

Question 2: Is there a way of typing something like term = term.subs(xi**2, yi), rather than rewriting the substitution for each x_i?

Asked By: Bilbo Baggins



Something like this seems to work. Just be aware of the difference in the index base.

from sympy import *

x = symbols("x1 x2 x3")
y = symbols("y1 y2 y3")

term = x[0]**5 + (x[1]**2)*(x[2]**3) + x[0]**4 + x[0]**3 + x[0]**2 + x[0]
for i in range(3):
  term = term.subs(x[i]**2, y[i])
  for n in range(3):
    term = term.subs(x[i]**(2*n+1), x[i]*y[i]**n)

enter image description here

Answered By: Kota Mori

You can just tell the replace method to find powers with odd exponents and replace them as you described in the OP.

enter image description here

The sym lambda is a function to give a new symbol to use for the odd case. In the first example [15] I use the integer attribute to create a new symbol that looks like the one appearing in the power but behaving distinctly (since symbols are known by their attributes). In the second example, I assume that only the first letter is going to be replaced with y (like you had said).

Since the replace does not care about the name of the variables, there is no need for an explicit loop to check all bases.

Answered By: smichr
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.