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

它的文档非常稀少,而且我在计算FFT方面没有太多经验。

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

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

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

c++ - 用FFT计算两个信号之间的相关性-LMLPHP

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

c++ - 用FFT计算两个信号之间的相关性-LMLPHP

该函数的输出最初是:

5
-1
1.70711
3.12132
0
1个
0.292893
1.12132

(实数和虚数均按文档中指定的方式进行了划分)

c++ - 用FFT计算两个信号之间的相关性-LMLPHP

现在,当我将包含DFT结果的两个 vector (我使用实数DFT)相乘(我使用元素逐次乘法)时,问题就开始了,因为Octave的结果与我的程序的结果不同

c++ - 用FFT计算两个信号之间的相关性-LMLPHP

我的乘法代码是:

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

结果是:

c&#43;&#43; - 用FFT计算两个信号之间的相关性-LMLPHP

c&#43;&#43; - 用FFT计算两个信号之间的相关性-LMLPHP

这是我目前停留的地方。

最佳答案

主要的问题在于... drumrolls ...乘法(正如您已经猜到的那样,“我的问题从乘法开始”)!

时域中的卷积(具有足够的零填充)在频域中等效于频谱的复数乘法。在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接受实值输入,仅返回频谱的非冗余下半部分(上半部分可以通过对称获得)。逆变换将相应地获取频谱的非冗余下半部分并计算相应的实值序列(因此在这种情况下,仅处理频谱的一半就不再是问题)。
  • 另外,您可能已经注意到,您使用的C FFT implementation是基于DFT的不同定义(它使用带正数的指数),而不是Octave。只要您还使用一致的逆变换(即指数为负数的逆变换),就没有问题。为了进行比较,您使用C FFT implementation的结果对应于Octave结果的复共轭。
  • 关于c++ - 用FFT计算两个信号之间的相关性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35626105/

    10-11 20:45
    查看更多