web-dev-qa-db-ja.com

numpy.linalg.solve()がnumpy.linalg.inv()よりも正確なマトリックス反転を提供するのはなぜですか?

なぜnumpy.linalg.solve()がより正確な答えを出すのか、numpy.linalg.inv()が幾分壊れて(私が信じている)推定値を与える理由はよくわかりません。

具体例として、式_C^{-1} * d_を解いています。ここで、Cは行列を示し、dはベクトル配列です。説明のために、Cの寸法は形状_(1000,1000)_であり、dは形状_(1,1000)_です。

numpy.linalg.solve(A, b)はxの方程式_A*x=b_を解きます、つまり_x = A^{-1} * b._したがって、この方程式を解くには

(1)

_inverse = numpy.linalg.inv(C)
result = inverse * d
_

または(2)

_numpy.linalg.solve(C, d)
_

方法(2)では、はるかに正確な結果が得られます。どうしてこれなの?

一方が他方よりも「うまく機能する」ように正確に何が起こっているのでしょうか?

23
ShanZhengYang

np.linalg.solve(A, b)not[〜#〜] a [〜#〜]の逆を計算します。代わりに、 gesv LAPACKルーチン の1つを呼び出します。これは、最初に[〜#〜] a [〜#〜]を因数分解しますLU分解してから、前方置換と後方置換を使用してxを解決します( here を参照)。

np.linalg.invは、同じ方法を使用して[〜#〜] a [〜#〜]の逆数を計算します。これはA-1 in A・A-1 = Iここで[〜#〜] i [〜#〜]はID *です。因数分解の手順は上記とまったく同じですが、A-1n×nマトリックス)-xn-longベクトル)よりも。さらに、IDを介してxを取得する場合A-1・b = xこの場合、余分な行列乗算によりさらに浮動小数点演算が発生するため、パフォーマンスが低下し、数値エラーが増加します。

計算の中間ステップは必要ありませんA-1-xを直接取得する方が高速で正確です。


* invのソースの関連ビットは here です。残念ながら、テンプレートCであるため、理解するのは少し難しいです。注意すべき重要なことは、アイデンティティマトリックスがパラメーターBとしてLAPACKソルバーに渡されることです。

32
ali_m