问题描述
作为开发工作的一部分,我们使用Python 3.8
(使用NumPy 1.19
)开发算法。然后,我们使用C
NE10库在neon
中实现它。
在一个阶段中,我们使用内置的IFFT函数计算傅立叶逆变换。
当我们在neon (NE10)
(最新版本)IFFT和Python的NumPy 1.19
IFFT之间进行比较时,我们得到了不同的结果(它们相差不大,但相差远远大于数值精度,请参见下面的输出)。 / p>
Python代码:
import numpy as np
nfft = 4096
FREQUENCY_BINS = 2049
NUMBER_OF_OUTPUTS = 4
in02_IFFT = np.zeros((nfft,NUMBER_OF_OUTPUTS))*(0+0j)
# Generating the input
half = np.zeros((FREQUENCY_BINS,NUMBER_OF_OUTPUTS))*(0+0j)
for n in range(FREQUENCY_BINS):
half[n,:] = n % 8 + (n % 4)*1j
# Taking symmetric conjugate for the other half so the output will be real
mirror = np.flip( np.conj(half[1:-1,:]),axis=0 ) # mirror-reflect frequencies
in02_IFFT = np.vstack((half,mirror))
out02_IFFT = np.ones((nfft,NUMBER_OF_OUTPUTS))*(1+0j)
for i in range(NUMBER_OF_OUTPUTS):
out02_IFFT[:,i] = np.fft.ifft(in02_IFFT[:,i])
print(in02_IFFT[0:12,0])
print(out02_IFFT[0:12,0])
以下是前12个条目的输出:
Input[0:12,0] =
[0.+0.j 1.+1.j 2.+2.j 3.+3.j 4.+0.j 5.+1.j 6.+2.j 7.+3.j 0.+0.j 1.+1.j
2.+2.j 3.+3.j]
Output[0:12,0] =
[ 3.5 +0.j -0.95834839+0.j 0. +0.j -0.32173021+0.j
0. +0.j -0.19440795+0.j 0. +0.j -0.13984233+0.j
0. +0.j -0.10952898+0.j 0. +0.j -0.09023946+0.j]
霓虹灯功能为ne10_fft_c2r_1d_float32_neon
,调用为:
ne10_fft_c2r_1d_float32_neon( data_time_final[output_channel_number],BUFFER_BF_OUTPUT[output_channel_number],cfg_fft_r2c );
请参阅文档:https://github.com/projectNe10/Ne10/blob/master/inc/NE10_dsp.h
输出:
3.500000000000000000
-0.958348393440246582
0.000000009662471712
-0.321730166673660278,0.000000001629814506
-0.194407939910888672
-0.000000014028046280
-0.139842316508293152
0.000000007217749953
-0.109529010951519012
0.000000007741618901
-0.090239435434341431
但是,对于“现实生活”数据,输出存在显着差异:
After IFFT Python: [-5.75256348e-08+0.j -1.14624023e-07+0.j -2.39105225e-07+0.j -3.28216553e-07+0.j]
After IFFT C: [-5.58793545e-08 -1.11758709e-07 -2.42143869e-07 -3.29688191e-07]
您能解释一下为什么相对于1e-6
的相对误差而言结果不同而又不同吗
解决方法
通常,数值舍入误差随FFT变换大小而增加。同样,不同的FFT实现可能具有不同的舍入误差。例如。有些使用递归公式可以减少内存成本,但会产生较大的舍入错误。
关于FFTW的此页面是各种FFT实现的准确性比较:
http://www.fftw.org/accuracy/Pentium4-3.60GHz-icc/
对于基于32位浮点数据的4096大小FFT,某些实现的相对RMS误差确实比1e-6差。另请参见their commentary,了解FFT的准确性。