使用FFT有效计算自相关


12

我正在尝试在平台上计算自相关,其中我唯一可用的加速原语是(I)FFT。我有一个问题。

我在MATLAB中原型化了它。但是,我有点困惑。我以为它的工作原理如下(这是从内存中来的,如果我有一点错的话,我深表歉意)。

 autocorr = ifft( complex( abs( fft( inputData ) ), 0 ) )

但是,我得到的结果不同于使用该xcorr函数得到的结果。现在,我完全期望不要获得自动相关的左侧(因为这是右侧的反映,因此无论如何都不需要)。但是,问题是我的右手侧似乎在中点附近反射。这实际上意味着我得到的数据量约为预期的一半。

因此,我敢肯定我一定在做一些非常简单的错误,但我只是不知道该怎么做。


1
小心。除非数据是确定性的,否则我们通常只能估计自相关序列。自相关估计有两种常见的版本:有偏和无偏。自相关估计的无偏结果在统计上是无偏的。但是,对于高阶滞后,方差可能非常大,如果在矩阵求逆中使用自相关估计,则会导致问题。偏倚的样本表现出统计偏倚,但差异较小(和均方差)。两者在统计上都是一致的。您上面有一个未归一化的有偏估计。
布赖恩2012年

Answers:


16

当然,非凡是正确的。FFT实现循环卷积,而xcorr()基于线性卷积。另外,您还需要在频域中平方绝对值。这是一个处理所有零填充,移位和截断的代码段。

%% Cross correlation through a FFT
n = 1024;
x = randn(n,1);
% cross correlation reference
xref = xcorr(x,x);

%FFT method based on zero padding
fx = fft([x; zeros(n,1)]); % zero pad and FFT
x2 = ifft(fx.*conj(fx)); % abs()^2 and IFFT
% circulate to get the peak in the middle and drop one
% excess zero to get to 2*n-1 samples
x2 = [x2(n+2:end); x2(1:n)];
% calculate the error
d = x2-xref; % difference, this is actually zero
fprintf('Max error = %6.2f\n',max(abs(d)));

哇,好漂亮。使用上述方法,我的音高跟踪器的纯C版本(单线程,无SIMD)在0.8秒内运行,而基于Intel性能基元的版本在0.4秒内运行。太棒了!谢谢
Goz 2012年


3

N2N1[(N1),N1]0

2N12N12N12N1

N2N1N

N1N2N102N12N1

简而言之:您应该这样做(以适应您的编程语言):

autocorr = ifft( complex( abs(fft(inputData, n=2*N-1))**2, 0 ) )

或在MATLAB中:

autocorr = ifft(abs(fft(inputData, 2*N-1)).^2)

0

xcorr函数的期望输出与FFTIFFT函数的应用不同的主要原因是因为在将这些函数应用于信号时,最终结果是循环卷积的

线性卷积和圆形卷积的主要区别可以在线性和圆形卷积中找到

可以通过最初对信号进行零填充并截断IFFT的最终输出来解决该问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.