使用 FFT 计算两个信号之间的相关性

Calculating correlation with FFT between two signals

我在获得两组值之间相关性的正确结果时遇到问题(我知道结果是错误的,因为我已经尝试计算 Octave 中的相关性)(我也在计算 post 说)。 我一直在使用一个库,我发现它是用 C 编写的,位于:http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html

它的文档比较少,我也没有多少计算 FFT 的经验。

该程序的结果示例和 Octave 的结果如下:

这两个向量是: a = [1 2 1 1 0 0 0 0], b = [0 0 0 0 1 3 1 1]

向量a和b在Octave上的fft结果为:

而相同向量的fft结果为(分为实数和虚数):

函数输出原为:

5 -1 1.70711 3.12132 0 1个 0.292893 1.12132

(实数和虚数的划分是按照文档中的说明进行的)

现在,当我乘以(我正在使用逐元素乘法)包含 DFT 结果的两个向量(我正在使用 Real DFT)时,我的问题就开始了,因为 Octave 的结果与我的程序

我的乘法密码是:

for (j = 0; j < n; j++) {
    a[j] = a[j] * b[j];
}

结果是:

这就是我目前卡住的地方。

主要问题在于...鼓声...乘法(根据您的 "my problem starts when I multiply" 陈述,您已经猜到了)!

时域中的卷积(具有足够的零填充)在频域中等效于频谱的 复数 乘法。在 Octave 中,这就是 * 运算符所做的。对于 C 或 C++ 中的 floatdouble 数组,* 运算符仅将实部或虚部相乘。

要将光谱的复数相乘,考虑到指定的数据打包顺序,您可以改用:

a[0] = a[0] * b[0]; // a[0] corresponds to real-valued bin 0
a[1] = a[1] * b[1]; // a[1] corresponds to real-valued bin n/2
for (j = 1; j < n/2; j++) {
    tmp      = (a[2*j]*b[2*j]   - a[2*j+1]*b[2*j+1]); // real-part
    a[2*j+1] = (a[2*j]*b[2*j+1] + a[2*j+1]*b[2*j]);   // imaginary-part
    a[2*j]   = tmp;
}

备注

  • C FFT implementation取实值输入,只return频谱的非冗余下半部分(上半部分可以通过对称获得)。逆变换将相应地采用频谱的非冗余下半部分并计算相应的实值序列(因此在这种情况下只处理一半频谱不是问题)。
  • 此外,您可能已经注意到,您使用的 C FFT implementation 基于与 Octave 不同的 DFT 定义(它使用带正参数的指数)。只要您还使用一致的逆变换(即指数具有负参数的逆变换),这就不是问题。出于比较目的,您的 C FFT implementation 结果对应于 Octave 结果的复共轭。