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

Sot*_*her 7 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')]])
Run Code Online (Sandbox Code Playgroud)

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

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

产生的错误是很长的回溯,结尾为:

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

更具体地说,它有麻烦,result[0].as_expr()因为as_expr()即使它仍然是type的对象,也无法将它转换为expression Poly,因此它仍然可以使用method as_expr()

为什么这些多项式不会自动组合为一个?
还是我可以通过其他方式打电话sympy.Poly(result[0].as_expr(), x)

编辑:以下是一些具有类似错误的问题(尽管有时是由不同的原因引起的):
sympy:PolynomialError:cos(a)包含 与SQRT一起使用POLY时的发电机组元素Sympy Error

GZ0*_*GZ0 2

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

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

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)
Run Code Online (Sandbox Code Playgroud)

输出:

(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]])
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

输出:

Matrix([[Poly(x**2 + 1, x, domain='ZZ')]])
Run Code Online (Sandbox Code Playgroud)