Comment faire un axe de fréquence pour une longueur FFT paire et impaire?

12

Puis-je obtenir de l'aide sur la façon de faire passer l'axe des fréquences d'une fréquence négative à une fréquence positive (en Hertz), ce sera l'axe des x dans un résultat FFT, mais avec une FFT de longueur paire ou FFT de longueur impaire. J'ai du mal à le faire dans MATLAB. (Supposons que vous connaissiez la fréquence d'échantillonnage f_s).

TheGrapeBeyond
la source
1
Cela peut vous aider à penser aux fréquences espacées également autour du cercle unitaire. Une FFT à 4 points a des bacs de fréquence à [0 / 4fs, 1 / 4fs, 2 / 4fs, 3 / 4fs], par exemple, qui est plus communément écrit comme [0, fs / 4, fs / 2, -fs / 4]. Une FFT à 3 points a des intervalles de fréquence à [0 / 3fs, 1 / 3fs, 2 / 3fs], ou peut être écrit comme [0, fs / 3, -fs / 3]. Pour les tailles impaires, cet espacement égal saute la fréquence de Nyquist, mais inclut toujours 0.
endolith
@endolith Cette analogie m'a énormément aidé, merci beaucoup!
Mark LeMoine

Réponses:

5

Une approche consiste simplement à calculer le vecteur de fréquence pour la sortie DFT non décalée (c'est-à-dire ce que vous obtiendriez directement de la fft()fonction de MATLAB , sans faire de fftshift()), puis remapper les fréquences qui correspondent aux emplacements sur le côté négatif de l'axe. Exemple:

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

La réponse fournie par learnvst devrait également fonctionner; c'est juste une autre façon de penser à ce sujet qui ne nécessite aucun boîtier spécial pour les tailles DFT paires / impaires.

Jason R
la source
Bonjour JasonR, est-il sûr que ce code fonctionne, car si je l'essaie avec fs = 1000 et Nfft = 256, le f_normal_order que je reçois commence par un nombre positif, devient négatif, puis à nouveau positif. De plus, les longueurs ne correspondent pas.
TheGrapeBeyond
Désolé, correction de quelques fautes de frappe dans le code. Ça devrait marcher maintenant.
Jason R
9

Vous pouvez créer un spectre de fréquences positif tout simplement (où fsest le taux d'échantillonnage et NFFTle nombre de cases fft). Dans l'implémentation Matlab de l'algorithme FFT, le premier élément est toujours le composant DC, d'où la raison pour laquelle le tableau part de zéro. Cela est vrai pour les valeurs paires et impaires de NFFT.

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

Si vous devez envelopper le spectre de fréquences, vous devez prendre en compte si vous avez un NFFT impaire. Il doit toujours y avoir un composant DC , donc. .

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

Remarquez comment le calcul de l'axe de fréquence positif est identique à celui ci-dessus, mais le terme décalé FFT change pour s'adapter aux longueurs FFT paires ou impaires.

Ces extraits de code ont été extraits d'une longue réponse publiée sur SO (que vous pourriez trouver intéressante) trouvée ici: /programming/9694297/matlab-fft-xaxis-limits-messing-up-and-fftshift/ 9699983 # 9699983

learnvst
la source
D'accord, puis-je utiliser cela pour NFFT impair aussi alors?
TheGrapeBeyond
Ah désolé. Je vois la légère complication lors du passage de la fréquence -ve à la fréquence + ve. J'ai légèrement changé la réponse.
learnvst