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

fftw computing analytic signal from r2c (real to complex) data

我有一个真实信号,我想对其进行傅立叶变换,计算频域中的解析信号,然后再变换回来。

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

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

明显的解决方案是零填充 fftw_complex 并从复数转换回复数,但是,出于性能/内存原因,我想避免这种情况。

所以目的是优化对应于真实信号u()的analytic signal的计算。正如您所写,显而易见的解决方案包括:

  1. 使用 r2c FFTW 函数计算前向实数到复数 DFT。不计算对应于负频率的傅里叶系数,因为它们是对应于正频率的傅里叶系数的复共轭。
  2. 用零填充复数数组,以便将所有负频率归零。
  3. 使用 c2c FFTW 计算复数到复数的反向 DFT 以获得复数分析信号。

首先,由于u()的解析信号在时域上很复杂,它是u()的两倍大,节省内存会很困难。由于解析信号的实部已知(即 u() 本身), 计算解析信号严格等效于将 Hilbert tranform 应用于 u(),因为它的结果是分析信号的虚部。

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

  1. 应用 r2c FFTW 变换。
  2. 对于所有(即正)频率,切换实部和复数部分。切换时采取相反的方式。这归结为将每个复数系数乘以 -j,其中 j^2=-1.
  3. 应用 c2r FFTW 变换。得到的实数数组是分析信号的虚部。

因此,分析信号的虚部可以通过使用c2r变换而不是c2c变换来计算。然而,虚部是作为第二个获得的array: 数组必须被压缩以获得与第一种方法完全相同的结果。使用 advanced real-data dfts 和步长 2 可以帮助删除该操作。

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

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

几何序列轻松相加,神奇运行:卷积核h的偶数项全部为空!

i%2==0 => h_i=0

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

因此,在执行与 h 的卷积时,u() 的偶数项永远不会与 u() 的奇数项混合。事实上,h(u)=u*h 的奇数项依赖于 u() 的偶数项,h(u) 的偶数项依赖于 u() 的奇数项。这似乎是一个有前途的轨道,但让我们引用 Todoran et。阿尔。 [1]关于它:

This algorithm seems to be computed in a shorter time. In fact, it requires a longer time than the algorithms that use the discrete Fourier transform. This is explained by the fact that for DFT were developed fast calculus algorithms (FFT -Fast Fourier Transform).

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

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