考虑以下几行代码:
y[:,:,i,p] = np.divide(x[:,:,i,p], npq) #divide array by constant
orig = np.dot(y[:,:,i,p], npq) #take previous output, and multiply by constant
print(np.mean(x[:,:,i,p] - orig)) #print mean. should be 0
这些计算的预期输出应为0.相反,我得到以下内容:
...
0.0
-1.81671383445
-0.0719097733101
-0.102587446807
...
我做错了什么?我已经尝试将所有数字转换为整数而不是浮点数,并且错误仍然存在。
修改 np.multiply无法解决问题。 我写了自己的乘法代码。它只是贯穿整个阵列,它运行得很好,虽然速度要慢得多。
答案 0 :(得分:1)
原因很可能是有限精度浮点数出现的精度损失。
如果npq
是标量,则np.dot(y[:,:,i,p], npq)
会得到与np.multiply(y[:,:,i,p], npq)
相同的结果。因此,如果浮点计算以无限精度完成,则代码将打印0.0。当然,他们不是;默认浮点数据类型为np.float64
,因此算术计算可能会丢失精度。我怀疑这就是为什么打印的值不是0.0。
例如,
In [78]: npq = 3
In [79]: np.random.seed(123)
In [80]: x = 1e20*np.random.randn(100, 100)
In [81]: y = np.divide(x, npq)
In [82]: orig = np.dot(y, npq)
如果我们有无限精度,那么这个结果将是0:
In [83]: np.mean(x - orig)
Out[83]: -5.2468000000000004
"往返行程中最大的错误"计算是:
In [84]: np.max(np.abs(x - orig))
Out[84]: 32768.0
使用np.multiply(y, npq)
代替np.dot(y, npq)
可以得到完全的结果:
In [85]: xx = np.multiply(y, npq)
In [86]: np.max(np.abs(x - xx))
Out[86]: 32768.0