Sympy substituting many variables with powers
Question:
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?
Answers:
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)
term
You can just tell the replace
method to find powers with odd exponents and replace them as you described in the OP.
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.
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?
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)
term
You can just tell the replace
method to find powers with odd exponents and replace them as you described in the OP.
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.