是什么导致了numpy和MATLAB之间的算术差异?我如何在Python中强制执行这两种行为?

0yycz8jy  于 2022-12-04  发布在  Matlab
关注(0)|答案(1)|浏览(168)

我尝试在numpy/Python 3.8中对$k \in {1,\dots,n}$ for $n = 8$的$p_k:= 2^{-k^2}$形式的概率分布进行归一化,使用的是MATLAB的num 2 hex a la C++ / Python Equivalent of Matlab's num2hex的等价物。在Python和MATLAB R2020 a中,归一化分布的和是不同的。
如果$n〈8$,则不存在差异。

这是怎么回事?我如何才能强制Python在$n〉7$的情况下产生与MATLAB相同的结果?我很难分辨其中哪一个符合IEEE 754(可能两者都符合,分组中的差异会影响进位[?]),但我需要MATLAB的行为。

我注意到numpy和MATLAB之间的舍入仍然存在差异(我自己验证了这一点),但不确定这是否有任何影响。

import numpy as np
import struct # for MATLAB num2hex equivalent below
n = 8
unnormalizedPDF = np.array([2**-(k**2) for k in range(1,n+1)])
# MATLAB num2hex equivalent a la https://stackoverflow.com/questions/24790722/
num2hex = lambda x : hex(struct.unpack('!q', struct.pack('!d',x))[0])
hexPDF = [num2hex(unnormalizedPDF[k]/np.sum(unnormalizedPDF)) for k in range(0,n)]
print(hexPDF)
# ['0x3fec5862805436a4', 
#  '0x3fbc5862805436a4', 
#  '0x3f6c5862805436a4', 
#  '0x3efc5862805436a4', 
#  '0x3e6c5862805436a4', 
#  '0x3dbc5862805436a4', 
#  '0x3cec5862805436a4', 
#  '0x3bfc5862805436a4']
hexPDFSum = num2hex(np.sum(unnormalizedPDF/np.sum(unnormalizedPDF)))
print(hexPDFSum)
# 0x3ff0000000000000

下面是MATLAB中的等效函数:

n = 8;
unnormalizedPDF = 2.^-((1:n).^2);
num2hex(unnormalizedPDF/sum(unnormalizedPDF))
% ans =
% 
%   8×16 char array
% 
%     '3fec5862805436a4'
%     '3fbc5862805436a4'
%     '3f6c5862805436a4'
%     '3efc5862805436a4'
%     '3e6c5862805436a4'
%     '3dbc5862805436a4'
%     '3cec5862805436a4'
%     '3bfc5862805436a4'
num2hex(sum(unnormalizedPDF/sum(unnormalizedPDF)))
% ans =
% 
%     '3fefffffffffffff'

注意,未归一化的分布是完全相同的,但是它们归一化后的和只相差一位。如果我使用$n = 7$,所有的结果都一致(都给予0x 3fefffffffffff),并且当$n〈7$时,两个结果也是一样的。

sxissh06

sxissh061#

根据手册,numpy.sum使用pairwise summation来获得更高的精度,另一个常见的算法是Kahan summation
无论如何,我不会指望Numpy和MATLAB在最后一位给出相同的结果,因为如果并行计算,可能会出现操作重新排序的情况。
然而,我们可以稍微作弊一下,强制Python在没有额外精度的情况下进行求和:

hexPDFSum = num2hex(np.sum(np.hstack((np.reshape(unnormalizedPDF / np.sum(unnormalizedPDF), (n, 1)), np.zeros((n, 1)))), 0)[0])
hexPDFSum
'0x3fefffffffffffff'

相关问题