[英]numpy matrix inversion rounding errors
我的BinvA矩陣的(1,1)條目獲得非常奇怪的值
我只是想將B矩陣求逆,並進行(B ^ -1)A乘法。
我知道,當我手動進行計算時,我的(1,1)應該為0,但我得到1.11022302e-16。 我該如何解決? 我知道浮點數不能完全准確地表示出來,但是為什么這會給我這樣一個不准確的響應,而不能四舍五入到0,有什么辦法可以使我更准確呢?
她是我的代碼:
import numpy as np
A = np.array([[2,2],[4,-1]],np.int)
A = A.transpose()
B = np.array([[1,3],[-1,-1]],np.int)
B = B.transpose()
Binv = np.linalg.inv(B) #calculate the inverse
BinvA = np.dot(Binv,A)
print(BinvA)
我的印刷聲明:
[[ 1.11022302e-16 -2.50000000e+00]
[ -2.00000000e+00 -6.50000000e+00]]
計算逆時,數組將在float64
中轉換,其機器epsilon為1e-15。 ε是浮點數的相對量化步驟 。
如有疑問,我們可以使用finfo
函數詢問有關浮點數據類型的numpy信息。 在這種情況下
np.finfo('float64')
finfo(resolution=1e-15,
min=-1.7976931348623157e+308, max=1.7976931348623157e+308,
dtype=float64)
因此,從技術上講,對於float64
類型,您的值小於eps
可以非常精確地表示為0。
如果僅是表示困擾您,您可以告訴numpy不要打印小的浮點數(0到1 eps或更小):
np.set_printoptions(suppress=True)
之后,您的打印語句返回:
[[ 0. -2.5]
[-2. -6.5]]
請注意,這是所有浮點實現共有的通用數值問題。 您可以找到有關SO上浮點舍入錯誤的更多信息:
或在網上:
這不是一個完整的答案,但可能會為您指明正確的方向。 您真正想要的是使用Decimals進行數學運算的numpy數組。 您可能會合理地考慮嘗試:
import numpy as np
from decimal import Decimal
A = np.array([[2,2],[4,-1]],np.int)
for i, a in np.ndenumerate(A):
A[i] = Decimal(a)
print type(A[i])
但是,可惜的是,十進制不在 numpy 的現成支持的數據類型之列 ,因此,每次嘗試將十進制卡入數組時,它都會將其重新轉換為浮點數。
一種可能性是設置數據類型,因此:
def decimal_array(arr):
X = np.array(arr, dtype = Decimal)
for i, x in np.ndenumerate(X): X[i] = Decimal(x)
return X
A = decimal_array([[2,2],[4,-1]])
B = decimal_array([[1,3],[-1,-1]])
A = A.transpose()
B = B.transpose()
Binv = np.linalg.inv(B) #calculate the inverse
但是現在,如果你
print Binv.dtype
您會看到反轉已將其重鑄為浮動狀態。 原因是linalg.inv(與許多其他函數一樣)尋找B的“ common_type”,它是B認為可以強制執行數組元素的標量。
不過,這可能並非沒有希望。 我看了看是否可以通過創建自定義dtype來解決此問題,但事實證明,標量(int,float等)根本不是dtype。 相反,您可能想做的就是注冊一個新的標量,即Decimal,如有關標量的文章中所述。 您會看到一個指向Numpy C-API的鏈接(不用擔心)。 在頁面上搜索“注冊”和“標量”以開始使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.