3


2

大規模なマトリックス反転法

こんにちは、私は行列反転(線形代数)についていくつかの研究を行ってきましたが、アルゴリズムにC テンプレートプログラミングを使用したいと思いました。関数LU_factorize(c ブーストライブラリ)

  1. 他の方法があるかどうか知りたい (利点/欠点)、プログラマーまたは数学者の観点から?

  2. 他に高速なメソッドがない場合は、既に(マトリックス) boostライブラリの反転関数? 、私は多くを検索し、何も見つけられなかったので。

5 Answer


5


おっしゃるように、標準的なアプローチはLU分解を実行してから、IDを解決することです。 これは、たとえば、 dgetrf(factor)および` dgetri`(compute inverse)を使用してLAPACKライ​​ブラリを使用して実装できます。 他のほとんどの線形代数ライブラリには、ほぼ同等の機能があります。

行列が特異またはほぼ特異である場合により緩やかに劣化するいくつかの遅い方法があり、そのために使用されます。 たとえば、http://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_pseudoinverse [Moore-Penrose pseudoinverse]は、マトリックスが反転可能な場合は逆に等しく、マトリックスが反転可能でない場合でもしばしば有用です。 ;特異値分解を使用して計算できます。


3


Eigenソースコードをご覧になることをお勧めします。


2


以下の流行語については、GoogleまたはWikipediaをご覧ください。

最初に、本当に逆にしたいことを確認してください。 システムを解くには、行列を反転する必要はありません。 行列の反転は、単位基底ベクトルを右側としてn個のシステムを解くことにより実行できます。 それで、私はシステムの解決に焦点を合わせます。それは通常あなたが望むものだからです。

「大」の意味に依存します。 分解に基づくメソッドは、通常、マトリックス全体を保存する必要があります。 マトリックスを分解したら、複数の右辺を一度に解決できます(したがって、マトリックスを簡単に反転できます)。 あなたはすでにそれらを知っている可能性が高いので、ここでは因数分解法については説明しません。

マトリックスが大きい場合、その「条件番号」はゼロに近い可能性が非常に高いことに注意してください。これは、マトリックスが「数値的に非可逆」であることを意味します。 対処法:前提条件。 これについてはウィキペディアを確認してください。 記事はよく書かれています。

マトリックスが大きい場合、格納する必要はありません。 多数のゼロがある場合、sparse matrix_です。 構造を持っている(例えば _bandgonalblock matrix、…​)、およびそのような行列を含むシステムを解くための特別な方法がありますが、そうではありません。

明確な構造のないスパース行列に直面したとき、または保存したくない行列に直面したときは、反復メソッドを使用する必要があります。 特定の形式のストレージを必要としない行列ベクトル乗算のみが必要です。必要なときに係数を計算したり、ゼロ以外の係数を必要な方法で保存したりできます。

メソッドは次のとおりです。

  • 対称定正行列の場合:共役勾配法。 つまり、Ax = bを解くと、1/2 x ^ T A x-x ^ T bを最小化することになります。

  • 一般的な行列のバイコン共役勾配法 しかし不安定です。

  • 最小残差法、または最良のGMRES。 ウィキペディアを確認してください 詳細については記事。 アルゴリズムを再起動する前に、反復回数を試してみることができます。

最後に、保存する非ゼロ要素の数を最小限に抑えるために特別に設計されたアルゴリズムを使用して、スパース行列で何らかの分解を実行できます。


1


マトリックスの実際の大きさに応じて、おそらく列の小さなサブセットのみをメモリに保持する必要があります。 これには、マトリックス要素への低レベルの書き込みおよび読み取り操作をオーバーライドする必要がありますが、それ以外の点ではかなり適切なライブラリーであるEigenで許可されるかどうかはわかりません。

*マトリックスが本当に大きいこれらの非常に狭いケースの場合、http://stxxl.sourceforge.net/ [StlXXL]ライブラリがあり、ほとんどがディスクに保存されている配列へのメモリアクセス用に設計されています。

編集*より正確には、使用可能なRAMで固定されないマトリックスがある場合、http://en.wikipedia.org/wiki/Invertible_matrix#Blockwise_inversion [ blockwise inversion ]を実行することをお勧めします。 マトリックスは、各マトリックスがRAMに収まるまで再帰的に分割されます(これはもちろんアルゴリズムの調整パラメーターです)。 ここで注意が必要なのは、ディスクを出し入れするときに行列のCPUが枯渇して反転するのを避けることです。 StlXXLであっても、これが主なボトルネックになる可能性が高いため、適切な並列ファイルシステムで調査する必要がある場合があります。 ただし、マントラを繰り返しましょう。 *早すぎる最適化は、すべてのプログラミングの悪の根源です。 この悪は、*コーディング、実行、プロファイル*のクレンジング儀式でのみ追放できます


0


LAPACKのC ++ラッパーを使用することもできます。 LAPACKは非常に成熟したコードです。十分にテストされ、最適化されています。

そのようなラッパーの1つがhttp://software.intel.com/en-us/intel-mkl/[Intel Math Kernel Library]です。