ここでいくつかの行列代数に取り組んでいます。ときどき、特異な条件や悪条件の行列を反転させる必要があります。私はこれを単純に行うのがPythonicであると理解しています:
try:
i = linalg.inv(x)
except LinAlgErr as err:
#handle it
それがどれほど効率的かはわかりません。これはもっと良いのではないでしょうか?
if linalg.cond(x) < 1/sys.float_info.epsilon:
i = linalg.inv(x)
else:
#handle it
Numpy.linalgは、私が禁止したテストの前に実行するだけですか?
したがって、ここでの入力に基づいて、ソリューションとして明示的なテストで元のコードブロックをマークしています。
if linalg.cond(x) < 1/sys.float_info.epsilon:
i = linalg.inv(x)
else:
#handle it
驚いたことに、numpy.linalg.inv関数はこのテストを実行しません。私はコードをチェックし、それがすべての陰謀を通過していることを確認し、次にlapackルーチンを呼び出すだけです-かなり非効率的です。また、DavePが作成した2つ目のポイントは、明示的に必要でない限り、行列の逆行列を計算しないことです。
最初の解決策は、行列が非常に特異で、numpyがまったく対処できないケースをキャッチします-かなり極端なケースになる可能性があります。 2番目のソリューションの方が優れています。numpyが回答を返すケースをキャッチするためですが、その回答は丸め誤差によって破損する可能性があります。これははるかに賢明なようです。
悪条件の行列を反転しようとしている場合は、 特異値分解 の使用を検討する必要があります。注意深く使用すると、他のルーチンが失敗した場合の賢明な回答が得られます。
SVDが必要ない場合は、invの代わりにlu_factorを使用することについての私のコメントも参照してください。
行列の 条件番号 を計算して、それが反転可能かどうかを確認する必要があります。
import numpy.linalg
if numpy.isfinite(numpy.linalg.cond(A)):
B = numpy.linalg.inv(A)
else:
# handle it
行列式が非ゼロかどうかを確認しないのはなぜですか?
det = numpy.linalg.det(A)
if det != 0:
#proceed