Effiziente Berechnung der Autokorrelation mithilfe von FFTs

12

Ich versuche, eine Autokorrelation auf einer Plattform zu berechnen, auf der das einzige verfügbare beschleunigte Grundelement die (I) FFT ist. Ich habe allerdings ein Problem.

Ich habe es in MATLAB als Prototyp erstellt . Ich bin jedoch etwas verwirrt. Ich nahm an, dass es einfach wie folgt funktioniert (dies ist aus dem Gedächtnis, also entschuldige, wenn ich es etwas falsch verstanden habe).

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

Ich erhalte jedoch ein anderes Ergebnis als bei Verwendung der xcorrFunktion. Jetzt erwarte ich, dass die Autokorrelation nicht auf der linken Seite angezeigt wird (da sie die rechte Seite widerspiegelt und daher ohnehin nicht benötigt wird). Das Problem ist jedoch, dass meine rechte Seite sich auf halber Strecke zu widerspiegeln scheint. Das bedeutet, dass ich ungefähr die Hälfte der erwarteten Datenmenge erhalte.

Ich bin mir also sicher, dass ich etwas sehr Einfaches falsch mache, aber ich kann einfach nicht herausfinden, was.

Goz
quelle
1
Achtung. Sofern die Daten nicht deterministisch sind, können wir in der Regel nur die Autokorrelationssequenz schätzen . Es gibt zwei gängige Versionen von Autokorrelationsschätzungen: voreingenommen und unvoreingenommen. Unvoreingenommene Ergebnisse führen zu Autokorrelationsschätzungen, die statistisch unbefangen sind. Die Varianz kann jedoch für Verzögerungen hoher Ordnung sehr groß sein, was zu Problemen führt, wenn die Autokorrelationsschätzung beispielsweise in Matrixinversionen verwendet wird. Die vorgespannten Proben weisen eine statistische Vorspannung auf, jedoch mit einer geringeren Varianz (und einem mittleren quadratischen Fehler). Beide sind statistisch konsistent. Sie haben oben eine nicht normalisierte voreingenommene Schätzung.
Bryan

Antworten:

16

pichenettes hat natürlich recht. Die FFT implementiert eine Kreisfaltung, während xcorr () auf einer linearen Faltung basiert. Außerdem müssen Sie den Absolutwert auch im Frequenzbereich quadrieren. Hier ist ein Code-Snippet, das das Auffüllen, Verschieben und Abschneiden von Nullen übernimmt.

%% 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)));
Hilmar
quelle
Wow, das hat wunderbar geklappt. Eine gerade C-Version (Single-Threaded, kein SIMD) meines Pitch-Trackers lief mit der obigen Methode in 0,8 Sekunden, im Gegensatz zu einer primitiven Intel-Performance-Version, die in 0,4 Sekunden lief. Das ist erstaunlich! Vielen Dank
Goz
7

2N-1NN-1

Pichenetten
quelle
3

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

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

Eine andere Möglichkeit, dies zu sehen, besteht darin, zu analysieren, was passiert, wenn Sie die DFT einrechnen N2N-1N

N-1N2N-102N-12N-1

Kurz gesagt: Sie sollten dies getan haben (um an Ihre Programmiersprache angepasst zu werden):

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

Oder in MATLAB:

autocorr = ifft(abs(fft(inputData, 2*N-1)).^2)
Jean-Louis Durrieu
quelle
0

Der Hauptgrund für die gewünschte Ausgabe von xcorr- Funktion nicht derjenigen der Anwendung der FFT- und IFFT- Funktion ähnlich ist, besteht darin, dass beim Anwenden dieser Funktion auf Signale das Endergebnis kreisförmig verschlungen ist .

Der Hauptunterschied zwischen linearer und kreisförmiger Faltung besteht in linearer und kreisförmiger Faltung .

Das Problem kann zunächst durch gelöst werden Zero-Padding des Signals und die endgültige Ausgabe von Kürzen IFFT .

Venu
quelle