使用sympy计算符号特征值

问题描述:

我正在尝试计算大小为3x3的符号复数矩阵M的特征值。在某些情况下,eigenvals()完美。例如,下面的代码:使用sympy计算符号特征值

import sympy as sp 

kx = sp.symbols('kx') 
x = 0. 

M = sp.Matrix([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]) 
M[0, 0] = 1. 
M[0, 1] = 2./3. 
M[0, 2] = 2./3. 
M[1, 0] = sp.exp(1j*kx) * 1./6. + x 
M[1, 1] = sp.exp(1j*kx) * 2./3. 
M[1, 2] = sp.exp(1j*kx) * -1./3. 
M[2, 0] = sp.exp(-1j*kx) * 1./6. 
M[2, 1] = sp.exp(-1j*kx) * -1./3. 
M[2, 2] = sp.exp(-1j*kx) * 2./3. 

dict_eig = M.eigenvals() 

返回我的M 3个正确的复杂的符号特征值。但是,当我设置x=1.,我得到以下错误:

raise MatrixError("Could not compute eigenvalues for {}".format(self))

我也试着计算特征值如下:

lam = sp.symbols('lambda') 
cp = sp.det(M - lam * sp.eye(3)) 
eigs = sp.solveset(cp, lam) 

但它返回我在任何情况下ConditionSet,即使eigenvals()能做这项工作。

有谁知道如何正确解决这个特征值问题,对于任何值x

您对M的定义让SymPy过于艰难,因为它引入了浮点数。当你想要一个符号解决方案时,浮动应该避免。这意味着:

  • 而不是1./3.(Python的浮点数)使用sp.Rational(1, 3)(SymPy的有理数)或sp.S(1)/3具有相同的效果,但更容易输入。
  • 代替1j(Python的虚数单位)使用sp.I(SymPy的虚数单位)
  • 代替x = 1.,写x = 1(Python 2.7版的习惯和SymPy一起去很差)。

有了这些变化要么solvesetsolve找到的特征值,虽然solve让他们快得多。此外,你可以做一个多边形对象并应用roots它,这可能是最有效的:(这将是更容易做from sympy import *比输入所有这些SP)

M = sp.Matrix([ 
    [ 
     1, 
     sp.Rational(2, 3), 
     sp.Rational(2, 3), 
    ], 
    [ 
     sp.exp(sp.I*kx) * sp.Rational(1, 6) + x, 
     sp.exp(sp.I*kx) * sp.Rational(1, 6), 
     sp.exp(sp.I*kx) * sp.Rational(-1, 3), 
    ], 
    [ 
     sp.exp(-sp.I*kx) * sp.Rational(1, 6), 
     sp.exp(-sp.I*kx) * sp.Rational(-1, 3), 
     sp.exp(-sp.I*kx) * sp.Rational(2, 3), 
    ] 
]) 
lam = sp.symbols('lambda') 
cp = sp.det(M - lam * sp.eye(3)) 
eigs = sp.roots(sp.Poly(cp, lam)) 


我对于为什么SymPy的特征值方法即使在进行上述修改的情况下报告失败也不太清楚。正如你可以看到in the source,它不会比上面的代码做得多:在特征多项式上调用roots。所不同的似乎是在创建这个多项式的方式:M.charpoly(lam)回报

PurePoly(lambda**3 + (I*sin(kx)/2 - 5*cos(kx)/6 - 1)*lambda**2 + (-I*sin(kx)/2 + 11*cos(kx)/18 - 2/3)*lambda + 1/6 + 2*exp(-I*kx)/3, lambda, domain='EX') 

神秘的(对我来说)domain='EX'。随后,roots的申请返回{},找不到根。看起来像是实施的不足之处。

+0

非常感谢您的帮助。似乎我的问题来自使用1j而不是使用sp.I,但使用Rational肯定有帮助!问题已解决,但仍然存在SymPy的特征值问题... – Azlof

+0

我简化了您的示例并发布了[作为SymPy问题](https://github.com/sympy/sympy/issues/13340) – FTP

+0

问题解决在github上。对于那些有兴趣的人来说,修复已经被SymPy的分支大师所推动。谢谢米歇尔! – Azlof