用符号表示符号特征值

Azl*_*lof 6 symbolic-math sympy eigenvalue python-2.7

我正在尝试计算M大小符号复杂矩阵的特征值3x3.在某些情况下,eigenvals()完美的工作.例如,以下代码:

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

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

提出MatrixError("无法计算{}的特征值".format(self))

我还尝试计算特征值如下:

lam = sp.symbols('lambda')
cp = sp.det(M - lam * sp.eye(3))
eigs = sp.solveset(cp, lam)
Run Code Online (Sandbox Code Playgroud)

但它ConditionSet在任何情况下都会让我回报,即使eigenvals()可以胜任这项工作.

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

小智 3

你对 M 的定义让 SymPy 的生活变得太困难了,因为它引入了浮点数。当您想要符号解决方案时,应避免浮动。这意味着:

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

通过这些更改,solveset或者solve找到特征值,尽管solve获得它们的速度要快得多。另外,您可以创建一个 Poly 对象并应用于roots它,这可能是最有效的:

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

from sympy import *(这比输入所有这些 sp更容易。)


我不太清楚为什么 SymPy 的特征值方法即使经过上述修改也会报告失败。正如您在源代码中所看到的,它的作用并不比上面的代码多:调用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')
Run Code Online (Sandbox Code Playgroud)

带着神秘(对我来说)domain='EX'。随后,应用roots返回{},没有找到根。看起来执行上有缺陷。