将 Sympy 矩阵代入多项式
Substitute a Sympy matrix into a polynomial
我有一个 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 的多项式 class,然后代入,但结果没有用:
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
但我仍在寻找更高效的内置选项。
矩阵表达式仍然存在一些问题,希望它们在未来得到修复。
无论如何,这是执行替换的另一种方法:
In [1]: x = MatrixSymbol('x', 2, 2)
In [2]: P = x**2 - 3*x + 5*eye(2)
In [3]: P
Out[3]:
2
⎡5 0⎤ + -3⋅x + x
⎢ ⎥
⎣0 5⎦
In [4]: A = Matrix([ [1,3], [-1,2] ])
In [5]: P.subs(x, A)
Out[5]:
2
⎡5 0⎤ + -3⋅⎡1 3⎤ + ⎛⎡1 3⎤⎞
⎢ ⎥ ⎢ ⎥ ⎜⎢ ⎥⎟
⎣0 5⎦ ⎣-1 2⎦ ⎝⎣-1 2⎦⎠
In [6]: P.subs(x, A).doit()
Out[6]:
2
⎡2 -9⎤ + ⎛⎡1 3⎤⎞
⎢ ⎥ ⎜⎢ ⎥⎟
⎣3 -1⎦ ⎝⎣-1 2⎦⎠
此处 MatPow 似乎无法执行 .doit() 操作。这可能是另一个错误。
在输出编号 5 中,打印机也存在错误(+ -3 应该只是 -3)。
我真的希望有人最终能解决所有这些问题。
尝试计算多项式的每一项。
(x**2).subs(x,A) - (3*x).subs(x,A) + 5*(eye(2))
这将评估您的表达式。
要在 A
处计算 P
,您可以将 x
替换为 Matrix
并通过乘以 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
.
我有一个 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 的多项式 class,然后代入,但结果没有用:
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
但我仍在寻找更高效的内置选项。
矩阵表达式仍然存在一些问题,希望它们在未来得到修复。
无论如何,这是执行替换的另一种方法:
In [1]: x = MatrixSymbol('x', 2, 2)
In [2]: P = x**2 - 3*x + 5*eye(2)
In [3]: P
Out[3]:
2
⎡5 0⎤ + -3⋅x + x
⎢ ⎥
⎣0 5⎦
In [4]: A = Matrix([ [1,3], [-1,2] ])
In [5]: P.subs(x, A)
Out[5]:
2
⎡5 0⎤ + -3⋅⎡1 3⎤ + ⎛⎡1 3⎤⎞
⎢ ⎥ ⎢ ⎥ ⎜⎢ ⎥⎟
⎣0 5⎦ ⎣-1 2⎦ ⎝⎣-1 2⎦⎠
In [6]: P.subs(x, A).doit()
Out[6]:
2
⎡2 -9⎤ + ⎛⎡1 3⎤⎞
⎢ ⎥ ⎜⎢ ⎥⎟
⎣3 -1⎦ ⎝⎣-1 2⎦⎠
此处 MatPow 似乎无法执行 .doit() 操作。这可能是另一个错误。
在输出编号 5 中,打印机也存在错误(+ -3 应该只是 -3)。
我真的希望有人最终能解决所有这些问题。
尝试计算多项式的每一项。
(x**2).subs(x,A) - (3*x).subs(x,A) + 5*(eye(2))
这将评估您的表达式。
要在 A
处计算 P
,您可以将 x
替换为 Matrix
并通过乘以 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
.