繁体   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