numpy矩阵反演舍入误差

Fir*_*Ace 0 python floating-point numpy matrix-multiplication floating-point-precision

我的BinvA矩阵的(1,1)条目得到一个非常奇怪的值我
只是试图反转B矩阵并做一个(B ^ -1)A乘法.

我明白,当我手工计算时,我的(1,1)应该是0,但我得到的是1.11022302e-16.我该如何解决?我知道浮点数不能完全准确地表示,但为什么这给我这样一个不准确的响应而不是四舍五入到有没有办法让它更精确?

她是我的代码:

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)
Run Code Online (Sandbox Code Playgroud)

我的打印声明:

[[  1.11022302e-16  -2.50000000e+00]
 [ -2.00000000e+00  -6.50000000e+00]]
Run Code Online (Sandbox Code Playgroud)

use*_*916 9

计算逆时,您的数组将被转换float64,其机器epsilon为1e-15.epsilon是浮点数的相对量化步长.

如果有疑问,我们可以使用该finfo函数询问有关浮点数据类型的numpy信息.在这种情况下

np.finfo('float64')
finfo(resolution=1e-15, 
      min=-1.7976931348623157e+308, max=1.7976931348623157e+308, 
      dtype=float64)
Run Code Online (Sandbox Code Playgroud)

因此,从技术上讲,您的值小于eps一个float64类型的非常准确的0表示.

如果它只是困扰你的表示,你可以告诉numpy不要打印小的浮点数(从0开始的1 eps或更小):

np.set_printoptions(suppress=True)
Run Code Online (Sandbox Code Playgroud)

之后,您的print语句返回:

[[ 0.  -2.5]
 [-2.  -6.5]]
Run Code Online (Sandbox Code Playgroud)

请注意,这是所有浮点实现通用的一般数值问题.您可以在SO上找到有关浮点舍入错误的更多信息:

或在网上:

  • 注意**相对**差异.如果在1e-200附近减去两个数字,则最小可表示的差异将约为1e-215.想象一下具有53个有效位的二进制形式的科学记数法. (2认同)