2

密な複素行列の固有ベクトル分解を見つけたいA

A = V.diag(lambda).V^-1

必要に応じて行列を正確に再現するには少数の固有ベクトルしか必要ありませんが、どの固有ベクトルを含めるかを決定するために、固有値に対して重要なフィルタリングを実行する必要があります。私の問題では、固有値/固有ベクトルが物理的に意味のある結果であるため、特異値分解を使用することは適切ではありません。

私は を使用してscipy.linalg.eigいます。これは、lapack のZGEEVルーチンの便利なラッパーです。数学的にV^-1は、左固有ベクトルの適切にスケーリングされたバージョンから取得できるはずです。Vこれは、右固有ベクトルの行列を反転するよりも効率的で安定していると予想していました。

ただし、2 つのアプローチを比較すると、分解された行列で両方の左固有ベクトルを使用する方が、反転した右固有ベクトルを使用する場合よりもはるかに精度が低いようです。おそらく、これはある種の丸め誤差または切り捨て誤差です。右の固有ベクトルの行列は非常に大きくなる可能性があり (1000 のオーダー)、この操作を何度も繰り返す必要があるため、反転しないことをお勧めします。

効率的かつ正確に分解を行う scipy (または lapack または自分でラップできる他のルーチン) で使用できるルーチンはありますか?

4

2 に答える 2

1

V^-1左の固有ベクトル から取得できることに気付きましたがU、秘訣は の要素Uを の対応する要素に正規化することですV。の列Uをそれ自体に正規化していましたが、これは正しくありませんが、ほぼ正しく見えるほど十分に近いです。

だから私はあなたがV^-1から得ることができるのは正しいですU、それは私の実装の単なる間違いでした.

于 2012-07-13T02:15:39.907 に答える
0

私が正しく理解していれば、乗算を実行してA(の近似値)を再取得したいのですが、ルーチンはV自体を返すだけであり、Vを反転する必要はありません。

ただし、ルーチンは左固有ベクトルUの行列も返し、次のようにUからVの逆行列を取得することができます(私の元の回答へのコメントで注意してください)。

行列U*A * Vのij番目の要素を評価する場合、それは両方に等しくなければなりません

U_i * lambda_j * V_j

U_i * lambda_i * V_j

ここで、U_iはUのi番目の行であり、V_jはVのj番目の列です(ただし、zgeevなどのlapackルーチンは行ベクトルをFortran列ベクトルとして返すことに注意してください)。

したがって、行列U * Vは対角であるため、自分の答えで言うように、次のようにしてV^-1を作成できます。

V^-1_i = U_i / (U_i * V_i)

ここで、UとV ^ -1の添え字は行を示し、Vの添え字は列を示します。

于 2012-07-12T09:35:32.673 に答える