Cで作業している数値ソルバーでは、2x2行列を反転する必要があり、右側で別の行列が乗算されます。
C = B . inv(A)
私は逆2x2行列の次の定義を使用しています。
a = A[0][0];
b = A[0][1];
c = A[1][0];
d = A[1][1];
invA[0][0] = d/(a*d-b*c);
invA[0][1] = -b/(a*d-b*c);
invA[1][0] = -c/(a*d-b*c);
invA[1][1] = a/(a*d-b*c);
私のソルバーの最初の数回の反復では、これは正しい答えを与えるように見えますが、いくつかのステップの後、物事は成長し始め、最終的に爆発します。
さて、SciPyを使用した実装と比較すると、同じ数学が爆発しないことがわかりました。私が見つけることができる唯一の違いは、SciPyコードがを使用していることですscipy.linalg.inv()
。これは内部でLAPACKを使用して反転を実行します。
の呼び出しを上記の計算に置き換えるとinv()
、Pythonバージョンが爆発するので、これが問題であると確信しています。計算のわずかな違いが忍び寄っています。これは数値的な問題であると私に信じさせます。反転操作にとってはまったく驚くべきことではありません。
数値の問題が問題にならないことを期待して、倍精度浮動小数点数(64ビット)を使用していますが、そうではないようです。
しかし、LAPACKのようなライブラリを呼び出さなくても、Cコードでこれを解決したいと思います。これは、純粋なCに移植する理由は、ターゲットシステムで実行するためです。また、ブラックボックスを呼び出すだけでなく、問題を理解したいと思います。最終的には、可能であれば単精度でも実行したいと思います。
だから、私の質問は、そのような小さな行列の場合、Aの逆行列を計算するための数値的により安定した方法がありますか?
ありがとう。
編集:現在、を解くことによって反転を回避できるかどうかを理解しようとしていC
ます。