2017-09-28 45 views
2

numpy.linalg.eig()scipy.linalg.eig()の出力の精度を向上させる方法はありますか?numpy.linalg.eig()とscipy.linalg.eig()の丸め誤差

私は非対称行列を対角化していますが、正の固有値と負の固有値のペアの実際のスペクトルを得るために物理的な根拠を期待しています。確かに、固有値は対になっています。私は、独立した分析計算によって、ペアのうちの2つが正しいことを確認しました。問題のあるペアは、ゼロに近い固有値を持つもので、小さな虚数部分を持つようです。私はこのペアがゼロで縮退することを期待しているので、虚数部は機械精度であることができますが、それらはずっと大きくなります。私はこれが固有ベクトルの小さな誤差につながると考えていますが、それは後の操作で広がります。

以下の例は、変換の妥当性をチェックすることによって架空の虚偽の部分が残っていることを示しています。

3.93435308362e-09 

ゼロ固有値の架空の虚部のオーダーの数を与える

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)) 

+0

:この定理から

は、さらに悪い状況では、入力領域における機械精​​度の誤差は以降の固有値で1e-8のオーダーの誤差に伝播可能性数値的に行列は通常、結果が悪くなります。マトリックスを反転させることなく、問題を解決するために、ほとんどの場合、より良い方法があります。 –

答えて

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は、固有値問題の誤差感度の上限を与える。反転、答えで述べたように

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