web-dev-qa-db-ja.com

MatlabでFFTを使用して自己相関を計算する

信号のfftを使用して自己相関をより効率的に計算し、実数部に複素共役(Fourier領域)を乗算し、次に逆fftを使用して自己相関をより効率的に計算する方法の説明を読みましたが、Matlabでこれを実現するのに問題がありますなぜなら、詳細なレベルで。

22
skj

あなたが述べたように、fftを取り、その複素共役で点ごとに乗算し、次に逆fftを使用します(または2つの信号の相互相関の場合: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 )

実際、xcorr.mのコードを見ると、まさにそれがやっていることです(パディング、正規化、ベクトル/マトリックス入力などのすべてのケースを処理する必要があるだけです)。

30
Amro

Wiener–Khinchinの定理 により、関数のパワースペクトル密度(PSD)は自己相関のフーリエ変換になります。確定的信号の場合、PSDはフーリエ変換の絶対値の2乗です。 convolution theorem も参照してください。

離散フーリエ変換(つまり、FFTを使用)の場合、実際には周期的な自己相関が得られます。適切な(線形)自己相関を得るには、フーリエ変換を行う前に、元のデータを元の長さの2倍にゼロ詰めする必要があります。のようなもの:

x = [ ... ];
x_pad = [x zeros(size(x))];
X     = fft(x_pad);
X_psd = abs(X).^2;
r_xx = ifft(X_psd);
28