fftw计算来自r2c(实数到复数)数据的分析信号

时间:2017-09-15 14:21:19

标签: c signal-processing fft fftw

我有一个真正的信号,我想要进行傅立叶变换,在频域中计算分析信号然后再变换回来。

的问题
fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out,
                           unsigned flags);

是它只有正频率分量,而我需要将负频率分量归零(fftw_complex(f)= 0,f <0)。

显而易见的解决方案是零填充fftw_complex并将其转换回复杂到复杂,但是,出于性能/内存的原因,我想避免这种情况。

1 个答案:

答案 0 :(得分:1)

因此,目标是优化对应于实信号u()的analytic signal的计算。正如您所写,明显的解决方案包括:

  1. 使用r2c FFTW函数计算前向实数到复数DFT。不计算与负频率对应的傅立叶系数,因为它们是对应于正频率的傅立叶系数的复共轭。
  2. 用零填充复数数组,以便将所有负频率归零。
  3. 使用c2c FFTW计算复数到复数的后向DFT以获得复杂的分析信号。
  4. 首先,由于u()的分析信号在时域中很复杂,因此它是u()的两倍,节省内存将很难。由于分析信号的实部已知(即u()本身),计算分析信号严格等同于将Hilbert tranform应用于u(),因为其结果是分析信号的虚部。

    要使用FFTW应用希尔伯特变换,请参考[1]中的算法:

    1. 应用r2c FFTW变换。
    2. 对于所有(即正)频率,切换实部和复杂部分。切换时采取相反的做法。这归结为将每个复系数乘以-j,其中j ^ 2 = -1。
    3. 应用c2r FFTW变换。得到的实数阵列是分析信号的虚部。
    4. 结果,可以通过使用c2r变换而不是c2c变换来计算分析信号的虚部。然而,虚部是作为第二个数组获得的:数组必须拉链关闭以获得完全等同于第一种方法的结果。使用advanced real-data dfts和2的步幅可以帮助删除该操作。

      更进一步,仍然在[1]中,可以注意到在频域中乘以-j.sign(w)对应于时域中的卷积(参见Discrete Hilbert transform)。离散卷积核h是-j.sign(w)的后向DFT。结果,它写道:

      如果n是偶数,则严格低于n / 2的索引k> 0对应于正频率,索引n / 2必须被静音,因为它对应于n / 2和-n / 2频率并且索引高于n / 2对应于负频率。索引0可以被静音。结果,总和写道:

      几何序列很容易求和,魔术运算:卷积核h的所有偶数项都为空!

      i%2 == 0 =&gt; h_i = 0

      (在2017/09/21,关于奇数i的h_i值,wikipedia是错误的,参见Todoran et.al。[1])

      因此,即使执行与h的卷积,u()的项也永远不会与u()的奇项相混合。实际上,h(u)= u * h的奇数项取决于u()的偶数项,甚至h(u)项也取决于u()的奇项。这似乎是一个有希望的轨道,但让我们引用Todoran et。人。 [1]关于它:

        

      此算法似乎在较短的时间内计算出来。实际上,它需要比使用离散傅立叶变换的算法更长的时间。这可以通过以下事实来解释:对于DFT,开发了快速微积分算法(FFT -Fast Fourier Transform)。

      简短的结论: FFTW再次获胜......

      [1] Gheorghe TODORAN,Rodica HOLONEC和Ciprian IAKAB,离散希尔伯特变换。数值算法.ACTA ELECTROTEHNICA,2008,49,4,485-490