如何解决Sympy:多元多项式组合
我在变量 (x,y) 中有一个复杂的多元多项式,我需要通过设置在变量 (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,sqrt(2))',new_poly.gens
assert new_poly.monoms() == [(1,1),(0,1,1)],new_poly.monoms()
assert new_poly.free_symbols == {a,new_poly.free_symbols
print('polynomial: {p}'.format(p=new_poly))
print('generators: {g}'.format(g=new_poly.gens))
print('monomials: {m}'.format(m=new_poly.monoms()))
print('coefficients: {c}'.format(c=new_poly.coeffs()))
打印:
polynomial: Poly((1/2 - I/2)*a*(sqrt(2)) + (1/2 + I/2)*b*(sqrt(2)),a,sqrt(2),domain='QQ_I')
generators: (a,sqrt(2))
monomials: [(1,1)]
coefficients: [1/2 - I/2,1/2 + I/2]
并确保按照评论中的要求,生成的多项式具有 generators 表达式,如果我们从头开始构建新的多项式,即,
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,new_poly.gens
实际上,这样得到的多项式是相等的,只是表达方式略有不同,特别是用小数代替分数,即new_poly
在这种情况下是Poly((0.5 - I/2)*a*(sqrt(2)) + (0.5 + I/2)*b*(sqrt(2)),domain='EX')
。
值得注意的是,仅当 poly
是类 sympy.polys.polytools.Poly
的实例时,才需要进行上述从多项式到表达式并返回到多项式的转换,如上所述。
使用表达式可避免将最终结果从多项式转换为表达式再转换回多项式。相反,从表达式到多项式的转换就足够了,如下(如果有兴趣调用方法 monoms
,则需要转换为多项式,因为表达式是类 sympy.core.expr.Expr
的实例,它不有一个方法monoms
):
import sympy
a,y = sympy.symbols('a b x y')
poly = x + y
let = {x: (a + b) / sympy.sqrt(2),`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,new_poly.free_symbols
print('polynomial: {p}'.format(p=new_poly))
print('generators: {g}'.format(g=new_poly.gens))
print('monomials: {m}'.format(m=new_poly.monoms()))
print('coefficients: {c}'.format(c=new_poly.coeffs()))
此代码块与第一个代码块打印的输出相同。
并对感兴趣的多项式 x**2 + y**2
重复上述两种方法(此多项式已在评论中注明):
import sympy
a,y = sympy.symbols('a b x y')
poly = sympy.poly(x**2 + y**2)
let = {x: (a + b) / sympy.sqrt(2),`new_poly` is:
# Poly(2*a*b,sqrt(2)*(a + b)/2,domain='ZZ[a,b]')
# so the following assertions pass
assert str(new_poly.gens) == '(sqrt(2)*(a + b)/2,# the generators become as expected
new_poly = new_poly.as_expr().as_poly()
assert str(new_poly.gens) == '(a,b)',new_poly.free_symbols
print('polynomial: {p}'.format(p=new_poly))
print('generators: {g}'.format(g=new_poly.gens))
print('monomials: {m}'.format(m=new_poly.monoms()))
print('coefficients: {c}'.format(c=new_poly.coeffs()))
打印输出:
polynomial: Poly(2*a*b,domain='ZZ')
generators: (a,b)
monomials: [(1,1)]
coefficients: [2]
和代码块:
import sympy
a,y = sympy.symbols('a b x y')
poly = x**2 + y**2
let = {x: (a + b) / sympy.sqrt(2),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,new_poly.free_symbols
print('polynomial: {p}'.format(p=new_poly))
print('generators: {g}'.format(g=new_poly.gens))
print('monomials: {m}'.format(m=new_poly.monoms()))
print('coefficients: {c}'.format(c=new_poly.coeffs()))
打印与前一个代码块相同的输出。
关于方法 subs
的其他文档可以在 in the sympy
documentation 中找到(尽管讨论是针对表达式实例的,它也适用于多项式的实例,因为两者都是类 {{1 }} 而不覆盖方法 Basic
)。
还要注意,不是标识符的子表达式的替换大致通过在表达式的语法树中搜索与要替换的子表达式的语法树匹配的子树来进行,然后替换子树。不过,如 in this answer 和方法 subs
的文档字符串中所述,有一些启发式方法需要注意。
(此外,问题中似乎缺少乘号。)
,也许您的意思是要将 a 和 b 重写为 x 和 y 的函数?
from sympy.abc import a,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}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。