在numpy.linalg.eig()和scipy.linalg.eig()中舍入错误



是否有一种方法可以提高numpy.linalg.eig()scipy.linalg.eig()的输出的精度?

我正在对非对称矩阵进行对角线化,但我希望以物理为由获得一对真实和负特征值的真实基础。实际上,特征值确实成对出现,我已经通过独立的分析计算证实了两个对是正确的。有问题的对是具有接近零的特征值的一对,似乎具有较小的假想部分。我希望这对以零为零,因此假想的零件最多可以是机器精确度,但是它们更大。我认为这会导致特征向量的微小错误,但是在随后的操作中可能会传播。

下面的示例表明,通过检查转换的有效性,存在虚拟的假想部分。

import numpy as np 
import scipy.linalg as sla
H = np.array(
     [[ 11.52,  -1.,    -1.,     9.52,   0.,     0.   ],
      [ -1.,    11.52,  -1.,     0.,     9.52,   0.,  ],
      [ -1.,    -1.,    11.52,   0.,     0.,     9.52,],
      [ -9.52,   0.,     0.,   -11.52,   1.,     1.,  ],
      [  0.,    -9.52,   0.,     1.,   -11.52,   1.,  ],
      [  0.,     0.,    -9.52,   1.,     1.,   -11.52 ]],
     dtype=np.float64
            )
#print(H)
E,V = np.linalg.eig(H)
#E,V = sla.eig(H)
H2=reduce(np.dot,[V,np.diag(E),np.linalg.inv(V)])
#print(H2)
print(np.linalg.norm(H-H2))

给出

3.93435308362e-09

零特征值的虚拟想象部分的许多顺序。

您可能会通过计算上面的错误而失去一些精度。相反,如果您计算:

 # H = V.E.inv(V) <=> H.V = V.E
print(np.linalg.norm(H.dot(V)-V.dot(np.diag(E))))
# error: 2.81034671113e-14

错误要小得多。

您的问题也可能遭受不良条件的困扰,这意味着对圆形和其他错误的数值敏感性将非常高。Bauer-Fike定理对特征值问题的误差敏感性给出了上限。

从该定理中,在更糟糕的情况下,输入域中的机器精度上的错误可能会传播到特征值中1e-8顺序的错误,因为:

machine_precison = np.finfo(np.float64).eps
print(np.linalg.cond(V)*(machine_precison))
# 4.54517272701e-08

最新更新