我有一个numpy数组x
,它是根据一个复杂的等式计算的:
x = (QT-m_μ_Q*M_T)/(m*σ_Q*Σ_T)
print(x)
print(x[0], x[1], x[2])
print(1.0-x)
打印:
[ 1. 1. 1.]
1.0 1.0 1.0
[ -2.22044605e-16 3.33066907e-16 -4.44089210e-16]
请注意,最后一行打印出一些小而非常接近于零但非零的东西。我的下一步是取每个值的平方根,因此它不应包含负值。
显式地从包含以下内容的数组开始:
y = np.array([1., 1., 1.])
print(y)
print(y[0], y[1], y[2])
print(1.0-y)
产生正确的结果,所以我不确定区别是什么:
[ 1. 1. 1.]
1.0 1.0 1.0
[ 0. 0. 0.]
答案 0 :(得分:3)
简而言之x
中的那些不是真的1.这是因为你操作(你使用的公式)不精确的值(浮动是不精确的,另见Is floating point math broken?)。
但默认精度不会显示差异。但是当你减去一个时,就会得到通常所说的灾难性取消(例如参见Wikipedia或Why is 'catastrophic cancellation' called so?)。
例如:
>>> import numpy as np
>>> np.array([1, 1.00000000000002, 1.000000000000002, 1.0000000000000002])
array([ 1., 1., 1., 1.])
>>> 1 - np.array([1, 1.00000000000002, 1.000000000000002, 1.0000000000000002])
array([ 0.00000000e+00, -1.99840144e-14, -1.99840144e-15, -2.22044605e-16])
通常有两种方法可以解决这个问题:
sqrt((y-x)/y)
而不是sqrt(1-x/y)
- 只需为x
(QT-m_μ_Q*M_T
)和y
m*σ_Q*Σ_T
插入正确的表达式)。数学上两者都是等价的,但由于浮点数学,这些可能会给出不同的结果。