在numpy中对C连续数组求和返回错误答案

erhoui1w  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(111)

我有以下数组:

values = np.array(
    [[0.00000000000000000000000e+00,
      0.00000000000000000000000e+00],
     [-4.79999759999999625000000e+14,
      -0.00000000000000000000000e+00],
     [4.79999759999999625000000e+14,
      -0.00000000000000000000000e+00],
     [-0.00000000000000000000000e+00,
      -4.79999759999999625000000e+14],
     [-3.74998499999999072265625e+12,
      -3.74998499999999072265625e+12],
     [3.74998499999999072265625e+12,
      -3.74998499999999072265625e+12],
     [-0.00000000000000000000000e+00,
      4.79999759999999625000000e+14],
     [-3.74998499999999072265625e+12,
      3.74998499999999072265625e+12],
     [3.74998499999999072265625e+12,
      3.74998499999999072265625e+12]]
)

它包含0,4.7999975999999625e +14,3.7499849999999072265625e +12和它们的负对应。

print(np.sum(values, axis=0))

结果应该是[0.0.](或者至少是非常非常小的值),但是它没有,它的结果是[ 0. -0.01855469]
我想,这是一个浮点精度错误,原因是numpy无法进行成对求和,所以我也试了一下:

values_T = np.array(
    [[0.000000000000000000000000e+00,
      -4.799997599999996250000000e+14,
      4.799997599999996250000000e+14,
      -0.000000000000000000000000e+00,
      -3.749984999999990722656250e+12,
      3.749984999999990722656250e+12,
      -0.000000000000000000000000e+00,
      -3.749984999999990722656250e+12,
      3.749984999999990722656250e+12],
     [0.000000000000000000000000e+00,
      -0.000000000000000000000000e+00,
      -0.000000000000000000000000e+00,
      -4.799997599999996250000000e+14,
      -3.749984999999990722656250e+12,
      -3.749984999999990722656250e+12,
      4.799997599999996250000000e+14,
      3.749984999999990722656250e+12,
      3.749984999999990722656250e+12]]
)

print(np.sum(values_T, axis=1))

结果是[ 0. -0.00927734]。不知何故,误差减半了,但仍然不正确。
两个数组都是C连续的(通过np.ndarray.flags检查)。
任何帮助都是感激的!

fcy6dtqo

fcy6dtqo1#

也许在求和之前按绝对值对值进行排序?

v = values[:, 1]
print(v)
print(v.sum())
print(v[abs(v).argsort()].sum())

输出:

[ 0.0000000e+00 -0.0000000e+00 -0.0000000e+00 -4.7999976e+14
 -3.7499850e+12 -3.7499850e+12  4.7999976e+14  3.7499850e+12
  3.7499850e+12]
-0.00927734375
0.0

一个更大的测试,使用10-20个随机数及其否定的数组, Shuffle :

for n in range(10, 21):
  a = np.random.random(n)
  a *= 2 ** np.random.randint(50, size=n)
  a = np.hstack((a, -a))
  np.random.shuffle(a)
  print(a[abs(a).argsort()].sum(), a.sum())

示例输出显示排序的总和总是0.0,而未排序的总和很少是:

0.0 3.335706423968077e-05
0.0 0.00945821466302732
0.0 0.0009765625
0.0 -0.012045614654198289
0.0 0.000331806018948555
0.0 0.010692596435546875
0.0 0.0
0.0 0.009552001953125
0.0 -0.005477488040924072
0.0 -0.006590104184041934
0.0 0.001953125

相关问题