在这里处理一些矩阵代数。有时我需要反转可能是单数或病态的矩阵。我知道简单地这样做是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是否只是预先执行我禁止的测试?
答案 0 :(得分:15)
你的第一个解决方案可以解决你的矩阵是如此奇异以至于根本无法应对的情况 - 可能是极端的情况。你的第二个解决方案更好,因为它捕获了numpy给出答案的情况,但是答案可能因舍入错误而被破坏 - 这似乎更明智。
如果您试图反转病态矩阵,那么您应该考虑使用singular value decomposition。如果小心使用,它可以为其他例程失败提供合理的答案。
如果你不想要SVD,那么另请参阅我关于使用lu_factor而不是inv的评论。
答案 1 :(得分:11)
所以基于这里的输入,我用标记测试作为解决方案来标记我的原始代码块:
if linalg.cond(x) < 1/sys.float_info.epsilon:
i = linalg.inv(x)
else:
#handle it
令人惊讶的是,numpy.linalg.inv函数不执行此测试。我检查了代码并发现它经历了所有的阴谋,然后只是调用lapack例程 - 看起来非常低效。另外,我要提出DaveP提出的观点:除非明确需要,否则不应计算矩阵的逆矩阵。
答案 2 :(得分:4)
您应该计算矩阵的condition number以查看它是否可逆。
import numpy.linalg
if numpy.isfinite(numpy.linalg.cond(A)):
B = numpy.linalg.inv(A)
else:
# handle it
答案 3 :(得分:1)
为什么不检查行列式是否为非零?
det = numpy.linalg.det(A)
if det != 0:
#proceed