FFT kullanarak otokorelasyonun etkili bir şekilde hesaplanması


12

Ben mevcut tek hızlandırılmış ilkel (I) FFT olduğu bir platformda bir otokorelasyon hesaplamak çalışıyorum. Yine de bir sorunum var.

MATLAB'da prototip yaptım . Ancak biraz kafam karıştı. Basitçe aşağıdaki gibi çalıştığını varsaydım (biraz yanlış anladıysam bu hafızadan özür dileriz).

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

Ancak xcorrişlevi kullanmaktan aldığımdan farklı bir sonuç alıyorum . Şimdi tam olarak otomatik korelasyonun sol tarafını almamayı bekliyorum (sağ tarafın bir yansıması olduğundan ve yine de gerekli değildir). Ancak, sorun sağ tarafımın kendisinin, yarım noktaya yansıdığı görülüyor. Bu da etkili bir şekilde beklediğim veri miktarının yaklaşık yarısını aldığım anlamına geliyor.

Bu yüzden eminim ki çok basit bir yanlış yapmalıyım ama ne olduğunu anlayamıyorum.


1
Dikkatli ol. Veriler deterministik değilse , tipik olarak sadece otokorelasyon sekansını tahmin edebiliriz . Otokorelasyon tahminlerinin iki yaygın versiyonu vardır: önyargılı ve tarafsız. Otokorelasyon tahminlerinde istatistiksel olarak tarafsız olan tarafsız sonuçlar. Bununla birlikte, yüksek dereceli gecikmeler için varyans çok büyük olabilir ve örneğin, otokorelasyon tahmini, örneğin matris terslemelerinde kullanılırsa sorunlara yol açar. Eğimli örnekler istatistiksel sapma gösterir, ancak daha az varyans (ve ortalama kare hatası) gösterir. Her ikisi de istatistiksel olarak tutarlıdır. Yukarıda normal olmayan bir önyargı tahmininiz var.
Bryan

Yanıtlar:


16

Pichenettes elbette haklı. FFT dairesel bir evrişim uygularken, xcorr () doğrusal bir evrişime dayanır. Ayrıca, frekans alanındaki mutlak değeri de karelemeniz gerekir. İşte tüm sıfır dolgusu, kaydırma ve kesme işlemlerini gerçekleştiren bir kod snippet'i.

%% 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)));

Vay bu güzel çalıştı. Adım takipçimin düz bir C versiyonu (Tek dişli, SIMD yok), 0,4 saniyede çalışan intel performans ilkel tabanlı versiyonun aksine yukarıdaki yöntemi kullanarak 0,8 saniye içinde koştu. Bu inanılmaz! Teşekkürler
Goz


3

N-2N--1[-(N--1),N--1]0

2N--12N--12N--12N--1

N-2N--1N-

N--1N-2N--102N--12N--1

Kısacası: bunu yapmış olmalısınız (programlama dilinize uyarlanmak için):

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

Veya MATLAB'da:

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

0

İstenen çıkış için temel nedeni xcorr fonksiyonunun uygulanması benzer olmamak FFT ve IFFT fonksiyonu sinyallerine nihai sonucu, bu fonksiyonun uygulanması sırasında çünkü dairesel kıvrık .

Doğrusal konvülasyon ve Dairesel konvülasyon arasındaki temel fark bulunabilir Doğrusal ve Dairesel konvülasyon .

Sorun başlangıçta sıfır dolgusu ile çözülebilir sinyali ve son çıkışını kesiliyor IFFT .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.