如何在多元 sympy 表达式中将所有多项式系数设置为 1
How to set all polynomial coefficients to 1, in a multivariate sympy expression
假设我在 sympy 中有一个多元多项式,例如:
import sympy as sp
from sympy.abc import x,y,z
expr = 2*x**2*y*z - x*z + 5*y**4*z
好的,我知道我们可以使用 Poly 构造函数提取列表中的所有单项式系数:
pol = sp.Poly(expr)
>> pol.coeffs()
[2, -1, 5]
但是,如果我只想通过将多项式的所有系数都设置为 1 来归一化该多项式的所有系数,我该如何继续?
按照前面的示例,最终答案将是:
x**2*y*z + x*z + y**4*z
您可以使用 Expr 操作来做到这一点:
In [17]: Add.make_args(expr)
Out[17]:
⎛ 4 2 ⎞
⎝-x⋅z, 5⋅y ⋅z, 2⋅x ⋅y⋅z⎠
In [18]: terms = Add.make_args(expr)
In [19]: expr
Out[19]:
2 4
2⋅x ⋅y⋅z - x⋅z + 5⋅y ⋅z
In [20]: terms = Add.make_args(expr)
In [21]: terms
Out[21]:
⎛ 4 2 ⎞
⎝-x⋅z, 5⋅y ⋅z, 2⋅x ⋅y⋅z⎠
In [22]: monoms = [t.as_coeff_Mul()[1] for t in terms]
In [23]: monoms
Out[23]:
⎡ 4 2 ⎤
⎣x⋅z, y ⋅z, x ⋅y⋅z⎦
In [24]: monpoly = Add(*monoms)
In [25]: monpoly
Out[25]:
2 4
x ⋅y⋅z + x⋅z + y ⋅z
一行是:
In [26]: Add(*(t.as_coeff_Mul()[1] for t in Add.make_args(expr)))
Out[26]:
2 4
x ⋅y⋅z + x⋅z + y ⋅z
你也可以用 Poly 和 monoms 做这个:
In [27]: p = Poly(expr, [x, y, z])
In [28]: p
Out[28]: Poly(2*x**2*y*z - x*z + 5*y**4*z, x, y, z, domain='ZZ')
In [29]: p.monoms()
Out[29]: [(2, 1, 1), (1, 0, 1), (0, 4, 1)]
In [30]: sum(prod(s**i for s, i in zip([x, y, z], indices)) for indices in p.monoms())
Out[30]:
2 4
x ⋅y⋅z + x⋅z + y ⋅z
如果您想对此进行类似的操作但实际上使用了系数,那么您可以使用 as_coeff_Mul()[0]
作为系数,或者在 Poly
的情况下使用 p.coeffs()
。
在平面表达式中,使用 replace
保留术语的 Mul
部分很简单。第一个参数可以表示您要查找的内容,第二个参数表示您想要对其执行的操作(尽管语法比这丰富得多——请参阅文档字符串):
>>> expr = 2*x**2*y*z - x*z + 5*y**4*z
>>> expr.replace(lambda x: x.is_Mul, lambda x: x.as_coeff_Mul()[1])
x**2*y*z + x*z + y**4*z
假设我在 sympy 中有一个多元多项式,例如:
import sympy as sp
from sympy.abc import x,y,z
expr = 2*x**2*y*z - x*z + 5*y**4*z
好的,我知道我们可以使用 Poly 构造函数提取列表中的所有单项式系数:
pol = sp.Poly(expr)
>> pol.coeffs()
[2, -1, 5]
但是,如果我只想通过将多项式的所有系数都设置为 1 来归一化该多项式的所有系数,我该如何继续? 按照前面的示例,最终答案将是:
x**2*y*z + x*z + y**4*z
您可以使用 Expr 操作来做到这一点:
In [17]: Add.make_args(expr)
Out[17]:
⎛ 4 2 ⎞
⎝-x⋅z, 5⋅y ⋅z, 2⋅x ⋅y⋅z⎠
In [18]: terms = Add.make_args(expr)
In [19]: expr
Out[19]:
2 4
2⋅x ⋅y⋅z - x⋅z + 5⋅y ⋅z
In [20]: terms = Add.make_args(expr)
In [21]: terms
Out[21]:
⎛ 4 2 ⎞
⎝-x⋅z, 5⋅y ⋅z, 2⋅x ⋅y⋅z⎠
In [22]: monoms = [t.as_coeff_Mul()[1] for t in terms]
In [23]: monoms
Out[23]:
⎡ 4 2 ⎤
⎣x⋅z, y ⋅z, x ⋅y⋅z⎦
In [24]: monpoly = Add(*monoms)
In [25]: monpoly
Out[25]:
2 4
x ⋅y⋅z + x⋅z + y ⋅z
一行是:
In [26]: Add(*(t.as_coeff_Mul()[1] for t in Add.make_args(expr)))
Out[26]:
2 4
x ⋅y⋅z + x⋅z + y ⋅z
你也可以用 Poly 和 monoms 做这个:
In [27]: p = Poly(expr, [x, y, z])
In [28]: p
Out[28]: Poly(2*x**2*y*z - x*z + 5*y**4*z, x, y, z, domain='ZZ')
In [29]: p.monoms()
Out[29]: [(2, 1, 1), (1, 0, 1), (0, 4, 1)]
In [30]: sum(prod(s**i for s, i in zip([x, y, z], indices)) for indices in p.monoms())
Out[30]:
2 4
x ⋅y⋅z + x⋅z + y ⋅z
如果您想对此进行类似的操作但实际上使用了系数,那么您可以使用 as_coeff_Mul()[0]
作为系数,或者在 Poly
的情况下使用 p.coeffs()
。
在平面表达式中,使用 replace
保留术语的 Mul
部分很简单。第一个参数可以表示您要查找的内容,第二个参数表示您想要对其执行的操作(尽管语法比这丰富得多——请参阅文档字符串):
>>> expr = 2*x**2*y*z - x*z + 5*y**4*z
>>> expr.replace(lambda x: x.is_Mul, lambda x: x.as_coeff_Mul()[1])
x**2*y*z + x*z + y**4*z