2016-06-07 58 views
3

我的代碼的一部分使用numpy.linalg.inv顛倒矩陣(真的是一個ndarray)。然而,這經常出錯如下:numpy爲什麼說這個矩陣是單數*有時*?

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]]) 
+0

你確定它的這個輸入創建這個問題?你可以在代碼中使用try catch(例如,如果你使用循環)來確切地知道它何時發生?還有什麼是X? –

+0

@ColonelBeauvel:我很確定它是這個輸入,因爲print np.dot(np.transpose(X),X)返回我上面寫的矩陣,然後下一行產生錯誤。 –

+0

有沒有理由失敗,所以...你可以肯定與嘗試趕上,並把一個pdb.set_trace()在失敗的情況下,以便您可以調查的代碼? –

回答

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可以倒數,在數學上,你可以計算伴隨和由行列式除以得到倒置矩陣。 數值上,如果行列式太小,這可能會導致你有那種錯誤...

+0

行列式確實很小,但這似乎並不能解釋爲什麼numpy可以在稍後再提問時進行反演。 –

2

這是一個印刷精度問題。 IEEE 754雙打,你最有可能使用,有大約16個十進制數字的精度,你需要寫出17 to preserve the binary value

這是一個小例子。首先創建一個singlular矩陣:

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]]) 

更迭!

提高打印的精度,然後再試一次:

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