¿Cómo hacer un eje de frecuencia para una longitud FFT par e impar?

12

¿Puedo obtener ayuda sobre cómo hacer que el eje de frecuencia pase de frecuencia negativa a frecuencia positiva (en hertzios), que será el eje x en un resultado FFT, pero dado un FFT de longitud par o FFT de longitud impar. Tengo problemas para hacerlo en MATLAB. (Suponga que conoce la frecuencia de muestreo f_s).

TheGrapeBeyond
fuente
1
Puede ayudarlo a pensar que las frecuencias se espacian equitativamente alrededor del círculo unitario. Una FFT de 4 puntos tiene intervalos de frecuencia en [0 / 4fs, 1 / 4fs, 2 / 4fs, 3 / 4fs], por ejemplo, que se escribe más comúnmente como [0, fs / 4, fs / 2, -fs / 4]. Una FFT de 3 puntos tiene intervalos de frecuencia en [0 / 3fs, 1 / 3fs, 2 / 3fs], o puede escribirse como [0, fs / 3, -fs / 3]. Para tamaños impares, este espaciado igual omite la frecuencia de Nyquist, pero siempre incluye 0.
endolito
@endolith Esta analogía me ayudó muchísimo, ¡muchas gracias!
Mark LeMoine

Respuestas:

5

Un enfoque es simplemente calcular el vector de frecuencia para la salida DFT no desplazada (es decir, lo que obtendría directamente de la fft()función de MATLAB , sin hacer un fftshift()), y luego reasignar las frecuencias que corresponden a ubicaciones en el lado negativo del eje. Ejemplo:

% 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 respuesta proporcionada por learnvst también debería funcionar; esta es solo otra forma de pensar que no requiere ninguna carcasa especial para tamaños DFT pares / impares.

Jason R
fuente
Hola JasonR, ¿estoy seguro de que este código está funcionando, ya que si lo intento con fs = 1000 y Nfft = 256, el f_normal_order que obtengo comienza con un número positivo, se vuelve negativo y luego positivo nuevamente. Además, las longitudes no coinciden.
TheGrapeBeyond
Lo sentimos, arreglamos un par de errores tipográficos en el código. Debería funcionar ahora.
Jason R
9

Puede hacer un espectro de frecuencia positivo de manera bastante simple (donde fsestá la frecuencia de muestreo y NFFTel número de contenedores fft). En la implementación de Matlab del algoritmo FFT, el primer elemento es siempre el componente DC, de ahí que la matriz comience desde cero. Esto es cierto para los valores pares e impares de NFFT.

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

Si necesita ajustar el espectro de frecuencia, debe tener en cuenta si tiene una NFFT con un número impar. Siempre tiene que haber un componente DC , entonces. .

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

Observe cómo el cálculo del eje de frecuencia positiva es idéntico al anterior, pero el término desplazado FFT cambia para adaptarse a longitudes FFT pares o impares.

Estos fragmentos de código se tomaron de una respuesta larga publicada en SO (que puede resultarle interesante) que se encuentra aquí: /programming/9694297/matlab-fft-xaxis-limits-messing-up-and-fftshift/ 9699983 # 9699983

aprender
fuente
De acuerdo, entonces ¿puedo usar esto para NFFT impar también?
TheGrapeBeyond
Oh, lo siento. Veo la ligera complicación al pasar de -ve a + ve frecuencia. He cambiado la respuesta ligeramente.
learnvst