C mmap和numpy memmap

时间:2017-07-03 12:21:38

标签: c numpy floating-point mmap numpy-memmap

我有一个包含大量N个32位浮点数的文件。此文件使用numpys memmap函数创建,如下所示:

mmoutput = np.memmap("filename", dtype='f4', mode='w+', offset=0, shape=N)
mmoutput[:] = my_floats
mmoutput.flush()

当我使用numpy加载这些系数并使用以下方法求和时:

mminput = np.memmap("filename", dtype="f4", mode='c', offset=0, shape=N)
mminput.sum()

我得到的值是82435.047(这是正确的)。

但是,当我使用C&#39的mmap读取浮点数时,如下所示:

int fd = open("filename", O_RDONLY, 0);
float * coefs = (float*) mmap(NULL, sizeof(float) * N, PROT_READ, MAP_SHARED, fd, 0);
double sum = 0.0;
for (int i = 0; i < N; i++) sum += coefs[i];

数字总和为不同的值:82435.100。

有人可以帮助发现我的错误吗?也许numpy写它的浮点数和C读它们的方式有区别?

完全披露

我实际上只是计算这些数字的总和作为检查它们是相同的。它们的实际用途是作为bspline中的系数(使用如图所示的einspline库实现,例如,https://github.com/ahay/src/blob/master/user/cram/esc_slow2.c)。当我在python和C中评估样条曲线时,我会得到不同的值。

1 个答案:

答案 0 :(得分:0)

  

我得到的值是82435.047(这是正确的)。

不,不是。您已将“大量”单精度浮点值相加,因此不可能精确到超过四位或五位有效数字,特别是如果值中存在较大的动态范围。

我怀疑numpy正在执行求和以提高精度,例如转换为双精度。 source追溯到几次调用umath.add.reduce然后我迷路了,所以很可能是双精度求和。尝试转换为双打或使用Kahan summation得到一个不会失去精度的结果 - Kahan将提供比任何减少加法更准确的结果,因为它具有动态范围效果的校正。