2017-01-25 112 views
3

我的朋友和我在Python 2Python 3执行的代码这一行:NumPy的反转不可逆矩阵

import numpy as np 
mat = np.array([[1,0,0],[-1,3,3],[1,2,2]]) 
np.linalg.inv(mat) 

将返回:

array([[ 1.00000000e+00, 0.00000000e+00, 0.00000000e+00], 
    [ 1.50119988e+16, 6.00479950e+15, -9.00719925e+15], 
    [ -1.50119988e+16, -6.00479950e+15, 9.00719925e+15]]) 

这是奇怪给出:

np.linalg.matrix_rank(mat) 

返回2,因此表明该矩阵是不是可逆的。

我从这个线程了解到,可能是由于numpy和python处理浮点数的方式,尽管我的矩阵由整数组成。

mat为什么会破坏numpy的逆向实现吗?

+0

请澄清不工作:你的意思是“矩阵是_invertible_”或“矩阵不是_invertible_”? – DyZ

回答

1

Rank = 2意味着矩阵是而不是可逆。对于一个3×3矩阵是可逆的,其等级必须是3

+1

这可能是OPs部分的拼写错误。看起来问题是:为什么Python将Matrix转换为不满秩? – Akavall

+1

@Aavall不清楚。事实上,NumPy 1.10.4并不反转它:'numpy.linalg.linalg.LinAlgError:奇异矩阵' – DyZ

+1

有趣的是,我能够用'1.12.0'重现OP结果 – Akavall

2

由于DYZ指出矩阵不是可逆的,因为它的级别是2不3

你得到这样的结果,就是因为numpy的是使用LU decomposition来计算逆。即使在矩阵奇异的情况下,该算法也可以产生结果。如果您对细节感兴趣,请阅读链接的维基百科文章。

请注意,产生的'逆'是失控的。所以如果你试图用它来求解线性方程组,它很可能会给你一堆NaN和Infs。

我猜numpy不检查高性能库常见的结果质量。您可以通过将原始矩阵乘以假设的逆矩阵并检查对角线上的数字是否接近1而其他数字是否为零来非常便宜地进行此类检查。由于浮点运算的性质,它们不一定完全等于零或一个

由于帝斯曼指出您的矩阵的condition number真的很高。

因此,由于此类病态矩阵,您正在丢失16位数字的精度。除了浮点不精确引起的错误之外。

顺便说为别人指出你上面的例子中numpy的1.12.0

>>> import numpy as np 
>>> np.version.version 
'1.12.0' 

>>> import numpy as np 
>>> mat = np.array([[1,0,0],[-1,3,3],[1,2,2]]) 
>>> np.linalg.inv(mat) 
Traceback (most recent call last): 
    File "/Users/vlad/.pyenv/versions/CourseraDL/lib/python3.4/site-packages/numpy/linalg/linalg.py", line 90, in _raise_linalgerror_singular 
    raise LinAlgError("Singular matrix") 
numpy.linalg.linalg.LinAlgError: Singular matrix 
>>> 
+1

可能还想提一下这个矩阵非常大的条件编号。 – DSM