Wie mache ich die Frequenzachse für gerade und ungerade FFT-Länge?

12

Kann ich Hilfe dazu erhalten, wie die Frequenzachse von der negativen zur positiven Frequenz (in Hertz) verschoben werden kann? Dies ist die x-Achse in einem FFT-Ergebnis, wenn jedoch entweder eine FFT mit gerader Länge oder eine FFT mit ungerader Länge angegeben wird. Ich habe einige Probleme, es in MATLAB zu schaffen. (Angenommen, Sie kennen die Abtastfrequenz f_s).

TheGrapeBeyond
quelle
1
Es kann Ihnen helfen, über den gleichen Abstand der Frequenzen um den Einheitskreis nachzudenken. Eine 4-Punkt-FFT hat beispielsweise Frequenzbereiche bei [0 / 4fs, 1 / 4fs, 2 / 4fs, 3 / 4fs], die häufiger als [0, fs / 4, fs / 2, -fs / 4]. Eine 3-Punkt-FFT hat Frequenzbereiche bei [0 / 3fs, 1 / 3fs, 2 / 3fs] oder kann als [0, fs / 3, -fs / 3] geschrieben werden. Bei ungeraden Größen überspringt dieser gleiche Abstand die Nyquist-Frequenz, schließt jedoch immer 0 ein.
Endolith
@endolith Diese Analogie hat mir sehr geholfen, vielen Dank!
Mark LeMoine

Antworten:

5

Ein Ansatz besteht darin, einfach den Frequenzvektor für die unverschobene DFT-Ausgabe zu berechnen (dh, was Sie direkt aus der MATLAB- fft()Funktion erhalten würden, ohne ein zu tun fftshift()) und dann die Frequenzen neu zuzuordnen, die Stellen auf der negativen Seite der Achse entsprechen. Beispiel:

% assume input signal "x", sampling frequency "fs"
% calculate FFT
X = fft(x,Nfft);
% calculate frequency spacing
df = fs / Nfft;
% calculate unshifted frequency vector
f = (0:(Nfft-1))*df;
% move all frequencies that are greater than fs/2 to the negative side of the axis
f(f >= fs/2) = f(f >= fs/2) - fs;
% now, X and f are aligned with one another; if you want frequencies in strictly
% increasing order, fftshift() them
X_normal_order = fftshift(X);
f_normal_order = fftshift(f);

Die Antwort von learnvst sollte auch funktionieren. Dies ist nur eine andere Denkweise, die für gerade / ungerade DFT-Größen kein spezielles Gehäuse erfordert.

Jason R
quelle
Hallo JasonR, ist es sicher, dass dieser Code funktioniert, da, wenn ich es mit fs = 1000 und Nfft = 256 versuche, die f_normal_order, die ich erhalte, mit einer positiven Zahl beginnt, negativ und dann wieder positiv wird. Auch die Längen stimmen nicht überein.
TheGrapeBeyond
Sorry, ein paar Tippfehler im Code behoben. Es sollte jetzt funktionieren.
Jason R
9

Sie können ganz einfach ein positives Frequenzspektrum erstellen (wobei fses sich um die Abtastrate und NFFTdie Anzahl der FFT-Bins handelt). In der Matlab-Implementierung des FFT-Algorithmus ist das erste Element immer die DC-Komponente, weshalb das Array bei Null beginnt. Dies gilt für ungerade und gerade Werte von NFFT.

%//Calculate frequency axis
df = fs/NFFT;
fAxis = 0:df:(fs-df);

Wenn Sie das Frequenzspektrum umschließen müssen, müssen Sie berücksichtigen, ob Sie eine ungeradzahlige NFFT haben. Es muss also immer eine Gleichstromkomponente geben . .

df = fs/NFFT;
fAxis = (0:df:(fs-df)) - (fs-mod(NFFT,2)*df)/2;

Beachten Sie, dass die Berechnung der positiven Frequenzachse mit der obigen identisch ist, der durch FFT verschobene Term sich jedoch ändert, um gerade oder ungerade FFT-Längen zu berücksichtigen.

Diese Code-Schnipsel stammen aus einer langen Antwort auf SO (die Sie vielleicht interessieren könnte), die Sie hier finden: /programming/9694297/matlab-fft-xaxis-limits-messing-up-and-fftshift/ 9699983 # 9699983

learnvst
quelle
Okay, kann ich das dann auch für ungerade NFFT verwenden?
TheGrapeBeyond
Oh, tut mir leid. Ich sehe die leichte Komplikation, wenn ich von -ve auf + ve Frequenz gehe. Ich habe die Antwort leicht geändert.
Learnvst