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