36

Working on some matrix algebra here. Sometimes I need to invert a matrix that may be singular or ill-conditioned. I understand it is pythonic to simply do this:

try:
    i = linalg.inv(x)
except LinAlgErr as err:
    #handle it

but am not sure how efficient that is. Wouldn't this be better?

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

Does numpy.linalg simply perform up front the test I proscribed?

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 提出的观点:除非明确需要,否则不应计算矩阵的逆矩阵。

于 2012-11-07T13:26:47.363 回答
18

您的第一个解决方案捕获了矩阵如此奇异以至于 numpy 根本无法应对的情况 - 可能是一个非常极端的情况。您的第二个解决方案更好,因为它捕捉到了 numpy 给出答案的情况,但该答案可能被舍入错误破坏 - 这似乎更明智。

如果您试图反转病态矩阵,那么您应该考虑使用奇异值分解。如果仔细使用,它可以在其他例程失败的情况下给你一个明智的答案。

如果您不想要 SVD,请参阅我关于使用 lu_factor 而不是 inv 的评论。

于 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 回答