2017-10-05 3 views
0

これは本当にばかげたことかもしれませんが、Numpyのバージョン1.12.1ではかなり奇妙な出力が得られています。私はランダムな対称行列を対角化しようとしていますが、対角の固有値行列を逆変換して品質を確認していますが、それは複雑な値では失敗するようです。基本的に:複素数行列のナンシー固有値/固有ベクトルが間違っていますか?

A = np.random.random((3, 3)) 
A += A.T.conj() 
evals, evecs = np.linalg.eig(A) 
print np.isclose(np.dot(evecs, np.dot(np.diag(evals), evecs.T)), A).all() 

プリントTrue

A = np.random.random((3, 3))+1.0j*np.random.random((3, 3)) 
A += A.T.conj() 
evals, evecs = np.linalg.eig(A) 
print np.isclose(np.dot(evecs, np.dot(np.diag(evals), evecs.T)), A).all() 

に対し印刷 False。私は値をチェックしただけで数値の不正確さには見えないが、それは間違っているようだ。基本的に何か間違っているのですか?私はそれが私が非常に頻繁に使用する何かのように np.linalg.eighを使用するときエルミート行列のために働くことを知っていますが、なぜ eigは対角に沿って複雑な値にも失敗しますか?

答えて

2

あなたの質問に対する答えは、対角化/行列再構成を適切に実行できなかったことです。

A = np.random.random((3, 3))+1.0j*np.random.random((3, 3)) 
A += A.T.conj() 
evals, evecs = np.linalg.eig(A) 
from scipy.linalg import inv 
print(np.isclose(np.dot(evecs, np.dot(np.diag(evals), inv(evecs))), A).all()) 

は適切な数式であるので、きちんと少しTrueを教えてくれます。何を

print np.isclose(np.dot(evecs, np.dot(np.diag(evals), evecs.T)), A).all() #False 

呼び出す場合はどうするあなたは実数値の正規化固有ベクトル行列の場合に有効である固有ベクトル行列の転置を掛けることである今

、。正規化された部分は幸運にも真実です。逆行列を模倣するために必要なのは、行列の複素共役を取ることだけです。

print(np.isclose(np.dot(evecs, np.dot(np.diag(evals), evecs.T.conj())), A).all()) #True 
+0

ああ、それはこのように動作しますが、実際に私の最初の実験は、それが失敗したこと、にのみ使用 'A + = A.T'を持っていました。その場合、固有値は実数ではなく、それほど大きな問題ではないという問題があると私は理解しています。 – Okarin

+0

ええ、正規化固有ベクトル行列の逆数は、実数行列の場合のように、転置だけでなくその複素共役です。 'A + = AT'では、反対角要素が同じ値を持つという意味で対称的な行列になりますが、それは複素共役(共役転置)は元の行列と同じでなければなりません。 – Uvar

関連する問題