36

ここでいくつかの行列代数に取り組んでいます。時々、特異または悪条件の可能性がある行列を反転する必要があります。私はこれを単純に行うのは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は、私が禁止したテストを前もって実行するだけですか?

4

4 に答える 4

24

したがって、ここでの入力に基づいて、ソリューションとして明示的なテストを使用して元のコードブロックをマークしています。

if linalg.cond(x) < 1/sys.float_info.epsilon:
    i = linalg.inv(x)
else:
    #handle it

驚いたことに、numpy.linalg.inv関数はこのテストを実行しません。私はコードをチェックし、それがすべての策略を通過し、次にlapackルーチンを呼び出すだけであることがわかりました-非常に非効率的なようです。また、DavePによって作成された2番目のポイントは、明示的に必要でない限り、行列の逆行列を計算しないことです。

于 2012-11-07T13:26:47.363 に答える
18

最初の解決策は、行列が非常に特異で、numpyがまったく対処できない場合をキャッチします。これは、非常に極端な場合である可能性があります。numpyが答えを出す場合を捕らえるので、2番目の解決策の方が優れていますが、その答えは丸め誤差によって破損する可能性があります。これははるかに賢明なようです。

悪条件の行列を反転しようとしている場合は、特異値分解の使用を検討する必要があります。注意深く使用すれば、他のルーチンが失敗した場合に賢明な答えを得ることができます。

SVDが必要ない場合は、invの代わりにlu_factorを使用することについての私のコメントも参照してください。

于 2012-11-07T07:20:51.840 に答える
5

逆行列であるかどうかを確認するには、行列の条件数を計算する必要があります。

import numpy.linalg

if numpy.isfinite(numpy.linalg.cond(A)):
    B = numpy.linalg.inv(A)
else:
    # handle it
于 2012-11-06T13:55:05.570 に答える
0

行列式がゼロ以外であるかどうかを確認します(ただし、注意してください。以下のコメントを参照してください)。

det = numpy.linalg.det(A)
if not numpy.isclose(det, 0):
   #proceed
于 2017-01-09T07:54:29.293 に答える