2017-09-28 103 views
2

有沒有辦法提高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 

若干零個特徵值的虛擬虛部的順序的。

+0

由於在答案中提到,反轉數值矩陣通常會導致較差的結果。幾乎總是有一種更好的方法來解決你的問題,而不需要反轉矩陣。 –

回答

2

在計算上面的錯誤時,您可能會失去一些精度。如果反而計算:

# 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 Theorem給出了特徵值問題的誤差敏感度的上限。

從這個定理,在最壞的情況下,在輸入域名機器精度的誤差可能傳播到了錯誤的1e-8中的特徵值,因爲順序:

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