奇异矩阵的高效和pythonic检查

新手上路,请多包涵

在这里研究一些矩阵代数。有时我需要反转一个可能是奇异的或病态的矩阵。我知道简单地这样做是 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 是否只是预先执行我禁止的测试?

原文由 Dr. Andrew 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 791
2 个回答

因此,根据此处的输入,我将我的原始代码块标记为显式测试作为解决方案:

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

令人惊讶的是, numpy.linalg.inv 函数不执行此测试。我检查了代码,发现它经历了所有的阴谋,然后只调用了 lapack 例程——看起来效率很低。另外,我要第二点 DaveP 提出的观点:除非明确需要,否则不应计算矩阵的逆。

原文由 Dr. Andrew 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

如果您正在尝试反转病态矩阵,那么您应该考虑使用 奇异值分解。如果小心使用,它可以在其他例程失败时为您提供明智的答案。

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

原文由 DaveP 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题