Matlab log和Numpy np.log之间不匹配

lpwwtiir  于 3个月前  发布在  Matlab
关注(0)|答案(1)|浏览(67)

在将旧的Matlab代码重写为NumPy时,我注意到对数计算的差异。在NumPy中,我使用np.log,Matlab使用log函数。

b = [1 1 2 3 5 1 1];
p = b ./ sum(b);
sprintf('log(%.20f) = %.20f', p(5), log(p(5)))

个字符
对于我的MacBook Pro 2020与M1芯片,我得到不匹配的第16位小数。

log(0.35714285714285715079) = -1.02961941718115834732  # Matlab
log(0.35714285714285715079) = -1.02961941718115812527  # NumPy


我想得到完全相同的结果。任何想法,如何修改我的Python代码?

9lowa7mx

9lowa7mx1#

MATLAB和numpy默认都使用尾数为52位的64bit float。这意味着两个float64数字之间的最小相对步长是2**-52 = 2.2e-16。这意味着16位之后的任何小数都没有意义。您看到的差异可能是由于略有不同的实现。您可以使用

np.nextafter(a, 1)-a

字符串
对于a = np.log(0.35714285714285715079),您可以得到2.2e-16,其大小大致为machine precisionnp.finfo(np.float64).eps
即使你看输入:你提供的小数比完全定义一个64位浮点数所需的要多。我们可以将十进制小数的数量设置为100,它仍然只会打印17位数字,原因是:

>>> np.set_printoptions(precision=100)
>>> np.array([0.35714285714285715079])
array([0.35714285714285715])


MATLAB和numpy之间的差异甚至可能是由于对求和进行了重新排序,因为浮点加法不是关联的。如果你确实依赖于小数点后16位,那么你应该使用64位浮点数以外的东西。我建议你熟悉浮点类型是如何实现的,因为这在使用科学软件时至关重要。如果你愿意,我建议你看一下numpy的源代码,看看它是如何实现的,并将它与其他开放库进行比较。

相关问题