如何在Sympy中的矩阵运算中组合多项式?

时间:2019-09-23 19:07:53

标签: python sympy

我正在做一些矩阵运算,有时涉及其条目具有恒定值的矩阵。

但是由于某些原因,即使结果很简单,我也无法通过矩阵运算将结果组合为一个多项式。例如,请考虑以下内容:

from sympy.matrices import *
import sympy

x= sympy.symbol.symbols('x')

Poly_matrix = sympy.Matrix([[sympy.Poly(x, x)],[sympy.Poly(x, x)]])
constant_matrix = sympy.Matrix([[0,1]])
constant_matrix_poly = constant_matrix.applyfunc(lambda val: sympy.Poly(val, x))

# this doesn't combine them
result1 = constant_matrix * Poly_matrix
print result1
>>>> Matrix([[Poly(0, x, domain='ZZ') + Poly(x, x, domain='ZZ')]])

# even THIS doesn't combine them when I convert the constants to Polynomials 
result = constant_matrix_poly * Poly_matrix
print result
>>>> Matrix([[Poly(0, x, domain='ZZ') + Poly(x, x, domain='ZZ')]])

问题是,当我尝试提取表达式并将结果转换为其他多项式时,出现以下错误:

# This is where the trouble starts
sympy.Poly(result[0].as_expr(), x)
sympy.Poly(result1[0].as_expr(), x)

所产生的错误是一个漫长的回溯,结尾为:

PolynomialError: Poly(x, x, domain='ZZ') contains an element of the set of generators.

更具体地说,它在result[0].as_expr()上遇到了麻烦,因为即使它仍然是as_expr()类型的对象,也无法使用Poly将其转换为表达式,因此它仍可以使用方法as_expr()

为什么这些多项式不会自动组合成一个整数?
还是我可以通过另一种方式致电sympy.Poly(result[0].as_expr(), x)

EDIT :以下是一些错误类似的问题(尽管有时是由其他原因引起的):
sympy: PolynomialError: cos(a) contains an element of the generators set Sympy Error when using POLY with SQRT

3 个答案:

答案 0 :(得分:1)

前段时间,我在运行一些代码时偶然发现了这个问题。在查看dense.py的第174行的矩阵乘法函数_eval_matrix_mul的源代码之后,发现sympy.Add用于在计算过程中执行加法,而不是{{1 }}运算符。因此,+不会被调用,并且每次都会创建一个新表达式来添加。

对源代码的进一步检查显示,存在一个PolyMatrix类,该类重写了多项式的矩阵乘法函数。此类可以按预期工作,如下所示。但是,由于未知原因,它没有出现在文档中的任何地方,因此请谨慎使用。链接的源代码中的docstring提供了该类的基本文档。

Poly.add

输出:

from sympy import Poly
from sympy.abc import x
from sympy.polys.polymatrix import PolyMatrix

mat = PolyMatrix([[Poly(x, x)], [1]])
const_mat = PolyMatrix([[4, 3]])
print(mat.shape, const_mat.shape)
print(mat.T * mat)
print(mat * mat.T)
print(2 * mat)
print(2 * mat + const_mat.T)

另一种替代方法是使用Expr.collect,其功能与sympy.collect相同,如下所示:

(2, 1) (1, 2)
Matrix([[Poly(x**2 + 1, x, domain='ZZ')]])
Matrix([[Poly(x**2, x, domain='ZZ'), Poly(x, x, domain='ZZ')], [Poly(x, x, domain='ZZ'), 1]])
Matrix([[Poly(2*x, x, domain='ZZ')], [2]])
Matrix([[Poly(2*x + 4, x, domain='ZZ')], [5]])

输出:

from sympy import Poly, Matrix
from sympy.abc import x

mat = Matrix([[Poly(x, x)], [1]])
result = mat.T * mat
simplified = result.applyfunc(lambda p: p.collect(x))
print(simplified)

答案 1 :(得分:1)

如果只需要特征多项式,请使用charpoly。这比eigenvals更有效率,因为有时符号根的计算可能很昂贵。

样本

lamda = symbols('lamda') p = M.charpoly(lamda) factor(p) 2 (λ - 5) ⋅(λ - 3)⋅(λ + 2)

Source

答案 2 :(得分:0)

这里是执行此操作的一种方法:

BLOB

但是,这似乎是一个非常棘手的解决方案。有更简单的方法吗?