我有一个多元多项式,其中的变量是(x,y),我需要通过设置
x=a+b
y=a-b
来获得一个新的多元多项式,其中的变量是(a,b)。
x = (a+b) / sqrt(2)
y = -i (a-b) / sqrt(2)
您可能会认出这是从/到复坐标的变量更改。
我知道函数“compose”,但它似乎只替换了我的多项式的“x”变量,有没有一种方法可以进行多元组合?
谢谢, 马尔科
我有一个多元多项式,其中的变量是(x,y),我需要通过设置
x=a+b
y=a-b
来获得一个新的多元多项式,其中的变量是(a,b)。
x = (a+b) / sqrt(2)
y = -i (a-b) / sqrt(2)
您可能会认出这是从/到复坐标的变量更改。
我知道函数“compose”,但它似乎只替换了我的多项式的“x”变量,有没有一种方法可以进行多元组合?
谢谢, 马尔科
sympy.core.basic.Basic.subs
进行同步替换,例如:import sympy
a, b, x, y = sympy.symbols('a b x y')
poly = sympy.poly(x + y)
let = {x: (a + b) / sympy.sqrt(2), y: - sympy.I * (a - b) / sympy.sqrt(2)}
new_poly = poly.subs(let, simultaneous=True)
# at this point, `new_poly` is:
# Poly(sqrt(2)*a/2 - sqrt(2)*I*a/2 + sqrt(2)*b/2 + sqrt(2)*I*b/2,
# sqrt(2)*(a + b)/2, -sqrt(2)*I*(a - b)/2, domain='EX')
# so the following assertions pass
assert str(new_poly.gens) == '(sqrt(2)*(a + b)/2, -sqrt(2)*I*(a - b)/2)', (
new_poly.gens)
assert new_poly.monoms() == [(0, 0)], new_poly.monoms()
# worth remarking that
assert new_poly.free_symbols == {a, b}, new_poly.free_symbols
# by converting from an instance of the class `sympy.polys.polytools.Poly`
# to an instance of the class `sympy.core.expr.Expr`, and
# back to an instance of the class `sympy.polys.polytools.Poly`,
# the generators become as expected
new_poly = new_poly.as_expr().as_poly()
# the previous statement is equivalent, as far as I know,
# to the statement:
# `new_poly = sympy.poly(new_poly.as_expr())`
# However, the latter raises an exception for some expressions
# (for an example, see below).
# The exception is avoided by using the expression method `as_poly`.
assert str(new_poly.gens) == '(a, b, sqrt(2))', new_poly.gens
assert new_poly.monoms() == [(1, 0, 1), (0, 1, 1)], new_poly.monoms()
assert new_poly.free_symbols == {a, b}, new_poly.free_symbols
print(f'polynomial: {new_poly}')
print(f'generators: {new_poly.gens}')
print(f'monomials: {new_poly.monoms()}')
print(f'coefficients: {new_poly.coeffs()}')
这将打印:
polynomial: Poly((1/2 - I/2)*a*(sqrt(2)) + (1/2 + I/2)*b*(sqrt(2)), a, b, sqrt(2), domain='QQ_I')
generators: (a, b, sqrt(2))
monomials: [(1, 0, 1), (0, 1, 1)]
coefficients: [1/2 - I/2, 1/2 + I/2]
根据评论的要求,确保结果多项式具有我们从头构造新多项式时期望的表达式作为生成器。
import sympy
a, b = sympy.symbols('a b')
expr = (
(1/2 - sympy.I/2) * a * (sympy.sqrt(2))
+ (1/2 + sympy.I/2) * b *(sympy.sqrt(2)))
new_poly = expr.as_poly()
assert str(new_poly.gens) == '(a, b, sqrt(2))', new_poly.gens
new_poly
为Poly((0.5 - I/2)*a*(sqrt(2)) + (0.5 + I/2)*b*(sqrt(2)), a, b, sqrt(2), domain='EX')
。poly
是类sympy.polys.polytools.Poly
的实例时,才需要将多项式转换为表达式,然后再转回多项式,就像上面那样。monoms
,因为表达式是类sympy.core.expr.Expr
的实例,该类没有方法monoms
)。import sympy
a, b, x, y = sympy.symbols('a b x y')
poly = x + y
let = {x: (a + b) / sympy.sqrt(2), y: - sympy.I * (a - b) / sympy.sqrt(2)}
new_poly = poly.subs(let, simultaneous=True)
# at this point, `new_poly` is an instance of the
# class `sympy.core.expr.Expr`,
# so it does not have methods `monoms` and `gens`,
# thus a conversion to polynomial is needed.
# This conversion creates the expected generators, monomials,
# and coefficients, as follows.
new_poly = new_poly.as_expr().as_poly()
assert str(new_poly.gens) == '(a, b, sqrt(2))', new_poly.gens
assert new_poly.monoms() == [(1, 0, 1), (0, 1, 1)], new_poly.monoms()
assert new_poly.free_symbols == {a, b}, new_poly.free_symbols
print(f'polynomial: {new_poly}')
print(f'generators: {new_poly.gens}')
print(f'monomials: {new_poly.monoms()}')
print(f'coefficients: {new_poly.coeffs()}')
这段代码块打印的输出与第一段代码块相同。
并将上述两种方法应用于感兴趣的多项式x**2 + y**2
(该多项式已在注释中指出):
import sympy
a, b, x, y = sympy.symbols('a b x y')
poly = sympy.poly(x**2 + y**2)
let = {x: (a + b) / sympy.sqrt(2), y: - sympy.I * (a - b) / sympy.sqrt(2)}
new_poly = poly.subs(let, simultaneous=True)
# at this point, `new_poly` is:
# Poly(2*a*b, sqrt(2)*(a + b)/2, -sqrt(2)*I*(a - b)/2, domain='ZZ[a,b]')
# so the following assertions pass
assert str(new_poly.gens) == '(sqrt(2)*(a + b)/2, -sqrt(2)*I*(a - b)/2)', (
new_poly.gens)
assert new_poly.monoms() == [(0, 0)], new_poly.monoms()
# worth remarking that
assert new_poly.free_symbols == {a, b}, new_poly.free_symbols
# by converting from an instance of the class `sympy.polys.polytools.Poly`
# to an instance of the class `sympy.core.expr.Expr`, and
# back to an instance of the class `sympy.polys.polytools.Poly`,
# the generators become as expected
new_poly = new_poly.as_expr().as_poly()
assert str(new_poly.gens) == '(a, b)', new_poly.gens
assert new_poly.monoms() == [(1, 1)], new_poly.monoms()
assert new_poly.free_symbols == {a, b}, new_poly.free_symbols
print(f'polynomial: {new_poly}')
print(f'generators: {new_poly.gens}')
print(f'monomials: {new_poly.monoms()}')
print(f'coefficients: {new_poly.coeffs()}')
打印输出的命令是:
polynomial: Poly(2*a*b, a, b, domain='ZZ')
generators: (a, b)
monomials: [(1, 1)]
coefficients: [2]
并且这段代码块:
import sympy
a, b, x, y = sympy.symbols('a b x y')
poly = x**2 + y**2
let = {x: (a + b) / sympy.sqrt(2), y: - sympy.I * (a - b) / sympy.sqrt(2)}
new_poly = poly.subs(let, simultaneous=True)
# at this point, `new_poly` is an instance of the
# class `sympy.core.expr.Expr`,
# so it does not have methods `monoms` and `gens`,
# thus a conversion to polynomial is needed.
# This conversion creates the expected generators, monomials,
# and coefficients, as follows.
new_poly = new_poly.as_expr().as_poly()
# if the previous statement is replaced with the statement:
# `new_poly = sympy.poly(new_poly.as_expr())`
# then an exception is raised:
# `CoercionFailed: expected an integer, got 1/2`
assert str(new_poly.gens) == '(a, b)', new_poly.gens
assert new_poly.monoms() == [(1, 1)], new_poly.monoms()
assert new_poly.free_symbols == {a, b}, new_poly.free_symbols
print(f'polynomial: {new_poly}')
print(f'generators: {new_poly.gens}')
print(f'monomials: {new_poly.monoms()}')
print(f'coefficients: {new_poly.coeffs()}')
该代码块输出与上一个代码块相同的内容。
有关subs
方法的其他文档可以在sympy
文档中找到(即使在那里讨论是基于表达式实例,它也适用于多项式实例,因为两者都是基于Basic
类而没有覆盖subs
方法)。
还要注意,替换不是标识符的子表达式大致通过搜索表达式的语法树以查找与要替换的子表达式的语法树匹配的子树,并替换这些子树。然而,在一些启发式方面有一个警告,如此答案所述,以及方法sympy.core.basic.Basic.subs
的docstring中描述。
(另外,问题中似乎缺少一个乘号。)
assert new_poly.free_symbols == {sympy.Symbol('a'), sympy.Symbol('b')}
通过了,而确实str(new_poly.gens)
是(sqrt(2)*(a + b)/2, -sqrt(2)*I*(a - b)/2)
(变量更换的表达式,正如你所指出的)。 - 0 _sympy.polys.polytools.Poly.monoms
方法。因此需要将其转换为多项式。使用表达式并将最终结果转换为多项式,生成器与预期相同。但是直接使用多项式会产生意外的结果,这就需要将其转换为表达式,然后再转换回多项式。 - 0 _x**2 + y**2
,我没有得到一个空的 list
(更新后的答案有更多细节),尽管通过比较从头构建相同的多项式,monoms
没有返回预期的结果。我不知道在生成器、单项式和系数方面的意外表示是否可以被认为是 sympy
包中的一个 bug。此外,我假设你的意思是 poly = x**2 + y**2
(写成 x^2
会引发 TypeError: unsupported operand type(s) for ^: 'Symbol' and 'int'
)。 - 0 _也许你的意思是想将a和b重写为x和y的函数?
from sympy.abc import a,b,x,y
from sympy import I, sqrt, solve
eqs = [
x - (a+b) / sqrt(2),
y - -I* (a-b) / sqrt(2)]
>>> solve(eqs,(a,b))
{a: sqrt(2)*x/2 + sqrt(2)*I*y/2, b: sqrt(2)*x/2 - sqrt(2)*I*y/2}
subs
来完成吗? - Oscar Benjaminsubs
方法替换一般子表达式,以下链接很有用:https://dev59.com/w6Pia4cB1Zd3GeqP493-#45383358 - 0 _