【发布时间】:2020-10-23 11:17:55
【问题描述】:
编辑: 事实证明,这仍然是一个浮点舍入误差的问题,就像其他问题一样。 fft 与 ifft 绝对误差的不对称性来自数字大小的差异(1e10 与 1e8)。
所以有很多关于 Numpy/Scipy 和 MATLAB FFT 的区别的问题;然而,其中大部分归结为浮点舍入错误以及 MATLAB 会将 1e-15 顺序的元素变成真正的 0 的事实,这不是我所追求的。
我看到了一个完全不同的问题,对于相同的输入,Numpy/Scipy FFT 会产生来自 MATLAB 的 1e-6 量级的差异。同时对于相同的输入,Numpy/Scipy IFFT 会在订单或 1e-9 上产生差异。我的数据是长度为 2^14 的复杂一维向量,零点位于数组的中间(如果您知道如何分享,请告诉我)。因此,对于这两种语言,我在 fft (ifft) 操作之前和之后都调用 fftshift。
我的问题是这种差异来自哪里,更重要的是,为什么它与 fft 和 ifft 不对称?我可以忍受很小的差异,但是当 1e-6 累积在大量 fft 上时,它就很大了。
对于任何一种语言,fft 的函数形式(我没有对它做任何其他事情)是:
def myfft
return fftshift(fft(fftshift(myData)))
def myifft
return fftshift(ifft(fftshift(myData)))
我将数据保存在 .mat 文件中,并使用 scipy.io.loadmat 将其加载到 python 中。数据是一个 (2**14,) numpy 数组
计算 fft 差异并绘制成图
myData = loadmat('mydata.mat',squeeze_me=True)
plt.figure(1)
py = myfft(myData['fft_IN'])
mat = myData['fft_OUT']
plt.plot(py.real-mat.real)
plt.plot(py.imag-mat.imag)
plt.title('FFT Difference')
plt.legend(['real','imaginary'],loc=3)
plt.savefig('fft_diff')
ift 差值是用
计算的myData = loadmat('mydata.mat',squeeze_me=True)
plt.figure(1)
py = myifft(myData['ifft_IN'])
mat = myData['ifft_OUT']
plt.plot(py.real-mat.real)
plt.plot(py.imag-mat.imag)
plt.title('FFT Difference')
plt.legend(['real','imaginary'],loc=3)
plt.savefig('fft_diff')
版本: 蟒蛇:3.7 MATLAB:R2019a 西比:1.4.1 numpy:1.18.5
【问题讨论】:
-
绝对差异无关紧要,重要的是相对差异。值 1 相差 1e-16 与 1e10 值相差 1e-6 相同。考虑到数据的长度,FFT 很可能会产生如此大的值。简而言之,您的结果仍然仅因浮点舍入误差而有所不同。
-
@CrisLuengo 如果您想将此作为答案,我会接受。你的评论让我回去看看我正在使用的数据的大小。在 fft 函数中,我按照 1e10 的顺序喂食,在 ifft 中,我正在喂食 1e8。因此,我在绝对误差而不是相对误差方面有所不同是有道理的。
-
随意发布答案。还有一件事:
fft的输入必须与ifftshift一起准备。如果数据长度是奇数,这会有所不同。fftshift将原点从左侧移到中间,ifftshift将原点从中间移回左侧。
标签: python matlab numpy scipy fft