将一个Sympy矩阵代入多项式

3

我有一个Sympy矩阵A和一个多项式表达式P,我想计算P(A)。

这是一个例子:

x = Symbol('x')
P = x**2 - 3*x + 5
A = Matrix([ [1,3], [-1,2] ])
P.subs(x, A)

我希望Sympy可以计算A**2 - 3*A + 5*eye(2)(在此示例中,结果为零矩阵)。

但是这会导致错误消息:

AttributeError: ImmutableMatrix has no attribute as_coeff_Mul.

有没有办法获得我想要的东西?

编辑: 我尝试将P转换为Sympy的多项式类,然后进行替换,但结果是无用的:

Poly(P).subs(A)
Poly(Matrix([ [ 1, 3], [-1, 2]])**2 - 3*Matrix([ [ 1, 3],        
    [-1, 2]]) + 5, Matrix([ [ 1, 3], [-1, 2]]), domain='ZZ')

我可以使用以下函数获得正确的结果:
def poly_matrix(P, A):
    coeffs = Poly(P).all_coeffs()[::-1]
    res = zeros(A.rows)
    for i in range(len(coeffs)):
        res += coeffs[i]*(A**i)
    return res

但我仍然在寻找更高效的内置选项。

3个回答

2

矩阵表达式目前还有些错误,希望它们能在未来得到修复。

无论如何,这里有一种替代方案来执行替换操作:

In [1]: x = MatrixSymbol('x', 2, 2)

In [2]: P = x**2 - 3*x + 5*eye(2)

In [3]: P
Out[3]: 
                 25  0⎤ + -3⋅x + x 
⎢    ⎥            
⎣0  5⎦            

In [4]: A = Matrix([ [1,3], [-1,2] ])

In [5]: P.subs(x, A)
Out[5]: 
                               25  0⎤ + -3⋅⎡1   3⎤ + ⎛⎡1   3⎤⎞ 
⎢    ⎥      ⎢     ⎥   ⎜⎢     ⎥⎟ 
⎣0  5⎦      ⎣-1  2⎦   ⎝⎣-1  2⎦⎠ 

In [6]: P.subs(x, A).doit()
Out[6]: 
                   22  -9⎤ + ⎛⎡1   3⎤⎞ 
⎢     ⎥   ⎜⎢     ⎥⎟ 
⎣3  -1⎦   ⎝⎣-1  2⎦⎠ 

看起来MatPow无法执行.doit()操作。这可能是另一个错误。

在输出数字5中,打印机也存在一个错误(+ -3应该只是-3)。

我真的希望有人最终能够解决所有这些问题。


有趣的替代方案。doit() 的错误在0.7.7.dev版本中已修复。 - Adrien

0
尝试计算多项式的每一项。
(x**2).subs(x,A) - (3*x).subs(x,A) + 5*(eye(2))

这将评估您的表达式。


如果我要手动逐个替换这些术语,那么我最好从一开始就键入 A**2 - 3*A + 5*eye(2) - Adrien
会寻找更好的解决方案。 - rresol

0

要在A处评估P,您可以使用一个矩阵代替x,并通过乘以eye(2)来转换常数项:

P_ = Poly(P, x)
(P_ - P_.coeff_monomial(1)).as_expr().subs(x, A) * eye(2) + P_.coeff_monomial(1) * eye(2) # P(A)

第一个 eye(2) 的乘法保证了和式的第一项是一个矩阵,即便 P 只是一个常数,例如 P_ - P_.coeff_monomial(1) == 0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接