【问题标题】:Neon IFFT compared to Python's NumPy IFFT - why the results are different?Neon IFFT 与 Python 的 NumPy IFFT 相比 - 为什么结果不同?
【发布时间】:2020-11-05 13:36:58
【问题描述】:

作为我们开发的一部分,我们在Python 3.8(使用NumPy 1.19)中开发算法。然后我们使用neon NE10 库在C 中实现它。 在一个阶段,我们使用内置的 IFFT 函数计算傅里叶逆变换。 当我们比较 neon (NE10)(最新版本)IFFT 和 Python 的 NumPy 1.19 IFFT 时,我们会得到不同的结果(它们相差不大,但差异远大于数值精度,请参见下面的输出)。

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]

neon函数是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的相对错误

【问题讨论】:

    标签: python c signal-processing fft neon


    【解决方案1】:

    通常,数值舍入误差随着 FFT 变换大小的增加而增加。此外,不同的 FFT 实现可能具有不同的舍入误差。例如。一些使用递归公式可以降低内存成本,但会产生更大的舍入误差。

    FFTW 上的这个页面是各种 FFT 实现的准确度比较: http://www.fftw.org/accuracy/Pentium4-3.60GHz-icc/
    对于 32 位浮点数据上的 4096 大小 FFT,某些实现确实比 1e-6 相对 RMS 误差更差。有关 FFT 精度,另请参阅 their commentary

    【讨论】:

    • 你知道NE10库使用什么FFT算法吗,从第1个链接看?
    • 嗯,FFT 实现可能不是您观察到的错误的原因。从 NE10 看,ne10_fft_c2r_1d_float32_neon 是一个混合基数 2/4 Cooley-Tukey FFT。 twiddles 似乎是准确预计算的,直接调用 cos() 和 sin(),而不是像 FFTW 页面警告的那样重复出现。我希望 NE10 的准确性很好。
    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多