在matlab中使用FFT计算自相关

skj*_*skj 22 matlab signal-processing fft correlation

我已经阅读了一些解释,如何使用信号的fft更有效地计算自相关,将实部乘以复共轭(傅里叶域),然后使用逆fft,但我在matlab中实现这一点时遇到了麻烦因为在详细程度上,我真的不知道自己在做什么.:o)那里的任何一种灵魂都在乎分享一些代码和智慧?

谢谢!

Amr*_*mro 30

就像你说,取FFT和通过它的复共轭相乘逐点,然后使用逆FFT(或在两个信号的互相关的情况下:Corr(x,y) <=> FFT(x)FFT(y)*)

x = rand(100,1);
len = length(x);

%# autocorrelation
nfft = 2^nextpow2(2*len-1);
r = ifft( fft(x,nfft) .* conj(fft(x,nfft)) );

%# rearrange and keep values corresponding to lags: -(len-1):+(len-1)
r = [r(end-len+2:end) ; r(1:len)];

%# compare with MATLAB's XCORR output
all( (xcorr(x)-r) < 1e-10 )
Run Code Online (Sandbox Code Playgroud)

事实上,如果你看一下代码xcorr.m,那就是它正在做的事情(只有它必须处理所有填充,规范化,矢量/矩阵输入等的情况......)

  • 除了采用复共轭,您还可以反转一个信号,然后对其进行 FFT。一个可能比另一个更容易,这取决于您的程序。 (2认同)
  • @nevos:关键字是厄米对称。引用help ifft`:“ ifft测试X以查看X上沿有效维的矢量是否为*共轭对称*。如果是,则计算速度更快并且输出为实。如果,N元素矢量x为共轭对称,则对于x的每个元素,“ x(i)= conj(x(mod(N-i + 1,N)+1))”。 (2认同)

Oli*_*rth 28

根据Wiener-Khinchin定理,函数的功率谱密度(PSD)是自相关的傅里​​叶变换.对于确定性信号,PSD只是傅立叶变换的幅度平方.另见卷积定理.

当谈到离散傅里叶变换(即使用FFT)时,实际上你得到了循环自相关.为了获得正确的(线性)自相关,您必须在进行傅立叶变换之前将原始数据零填充到其原始长度的两倍.所以类似于:

x = [ ... ];
x_pad = [x zeros(size(x))];
X     = fft(x_pad);
X_psd = abs(X).^2;
r_xx = ifft(X_psd);
Run Code Online (Sandbox Code Playgroud)