簡體   English   中英

numpy矩陣求逆四舍五入錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM