是否有一种方法可以提高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