numpy为什么说这个矩阵是奇异的*有时*?

时间:2016-06-07 13:37:48

标签: python numpy matrix

我的部分代码使用numpy.linalg.inv反转矩阵(实际上是一个ndarray)。但是,这经常出错如下:

numpy.linalg.linalg.LinAlgError: Singular matrix

如果矩阵实际上是奇异的,那就没问题了。但事实似乎并非如此。

例如,我在尝试反转矩阵之前打印矩阵。所以在错误发生之前就打印出来了:

[[ 0.76400334  0.22660491]
[ 0.22660491  0.06721147]]

...然后在尝试反转该矩阵时返回上述奇点错误。但据我所知,这个矩阵可逆的。 Numpy甚至在稍后问到时似乎也同意。

>>> numpy.linalg.inv([[0.76400334, 0.22660491], [0.22660491,    0.06721147]])
array([[  2.88436275e+07,  -9.72469076e+07],
   [ -9.72469076e+07,   3.27870046e+08]])

这是确切的代码段:

print np.dot(np.transpose(X), X)
print np.linalg.inv(np.dot(np.transpose(X),X))

第一行打印上面的矩阵;第二行失败了。

那么上述两种行为的区别是什么呢?为什么独立代码即使在我的脚本中出错也能正常工作?

编辑:按照Beauvel上校的要求,如果我这样做

try:
    print np.dot(np.transpose(X), X)
    z = np.linalg.inv(np.dot(np.transpose(X), X))
except:
    z = "whoops"
print z

输出

[[ 0.01328185  0.1092696 ]
[ 0.1092696   0.89895982]]
whoops

但是我自己尝试了这个

>>> numpy.linalg.inv([[0.01328185, 0.1092696], [0.1092696, 0.89895982]])
array([[  2.24677775e+08,  -2.73098420e+07],
   [ -2.73098420e+07,   3.31954382e+06]])

2 个答案:

答案 0 :(得分:2)

这是印刷精度的问题。您最有可能使用的IEEE 754双精度数大约为16位十进制数,您需要写出17 to preserve the binary value

这是一个小例子。首先创建一个单元矩阵:

In [1]: import numpy as np

In [2]: np.random.seed(0)

In [3]: a, b, c = np.random.rand(3)

In [4]: d = b*c / a

In [5]: X = np.array([[a, b],[c, d]])

打印并尝试将其反转:

In [6]: X
Out[6]: 
array([[ 0.5488135 ,  0.71518937],
       [ 0.60276338,  0.78549444]])

In [7]: np.linalg.inv(X)
LinAlgError: Singular matrix

尝试反转印刷的矩阵:

In [8]: Y = np.array([[ 0.5488135 ,  0.71518937],
   ...:               [ 0.60276338,  0.78549444]])

In [9]: np.linalg.inv(Y)
Out[9]: 
array([[-85805775.2940297 ,  78125795.99532071],
       [ 65844615.19517545, -59951242.76033063]])

SUCCES!

提高打印精度,然后重试:

In [10]: np.set_printoptions(precision=17)

In [11]: X
Out[11]: 
array([[ 0.54881350392732475,  0.71518936637241948],
       [ 0.60276337607164387,  0.78549444195576024]])

In [12]: Z = np.array([[ 0.54881350392732475,  0.71518936637241948],
    ...:               [ 0.60276337607164387,  0.78549444195576024]])

In [13]: np.linalg.inv(Z)
LinAlgError: Singular matrix

答案 1 :(得分:1)

我只计算行列式:

In [130]: m = np.array([[ 0.76400334, 0.22660491],[ 0.22660491,0.06721147]])

In [131]: np.linalg.det(m)
Out[131]: 2.3302017068132921e-09

# which is in fact for a 2D matrix 0.76400334*0.06721147 - 0.22660491*0.22660491

已经退出0附近。

如果可以反转矩阵m,则可以在数学上计算伴随并除以行列式以得到反转矩阵。 在数值上,如果行列式太小,这可能会导致您遇到的那种错误......