Как сделать частоту оси для четной и нечетной длины БПФ?

12

Могу ли я получить помощь о том, как сделать так, чтобы ось частоты переходила от отрицательной частоты к положительной частоте (в герцах), которая будет осью X в результате FFT, но с учетом либо FFT четной длины, либо FFT нечетной длины. У меня есть некоторые проблемы с этим в MATLAB. (Предположим, вы знаете частоту дискретизации f_s).

TheGrapeBeyond
источник
1
Это может помочь вам думать о частотах, расположенных на одинаковом расстоянии от круга устройства. Например, 4-точечный БПФ имеет частотные интервалы в [0 / 4fs, 1 / 4fs, 2 / 4fs, 3 / 4fs], который чаще записывается как [0, fs / 4, fs / 2, -fs / 4]. Трехточечный БПФ имеет частотные интервалы в [0 / 3fs, 1 / 3fs, 2 / 3fs] или может быть записан как [0, fs / 3, -fs / 3]. Для нечетных размеров это равное расстояние пропускается по частоте Найквиста, но всегда включает 0.
Эндолит
@endolith Эта аналогия мне очень помогла, большое спасибо!
Марк Лемуан

Ответы:

5

Один из подходов состоит в том, чтобы просто рассчитать вектор частоты для несмещенного вывода ДПФ (то есть того, что вы получите непосредственно из fft()функции MATLAB , без выполнения операции fftshift()), а затем переназначить частоты, которые соответствуют местоположениям на отрицательной стороне оси. Пример:

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

Ответ, предоставленный learnvst, также должен работать; это просто еще один способ думать об этом, который не требует специального корпуса для четных / нечетных размеров DFT.

Джейсон Р
источник
Здравствуйте, JasonR, уверен, что этот код работает, так как, если я попробую его с fs = 1000 и Nfft = 256, получаемый мной f_normal_order начинается с положительного числа, становится отрицательным, а затем снова положительным. Также длины не совпадают.
TheGrapeBeyond
Извините, в коде исправлено несколько опечаток. Это должно работать сейчас.
Джейсон Р
9

Вы можете сделать положительный частотный спектр довольно просто (где fsчастота дискретизации и NFFTколичество бин FFT). В реализации алгоритма FFT в Matlab первый элемент всегда является компонентом DC, поэтому массив начинается с нуля. Это верно для нечетных и четных значений NFFT.

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

Если вам нужно обернуть частотный спектр, вы должны принять во внимание, есть ли у вас нечетный NFFT. Всегда должен быть компонент постоянного тока , поэтому. ,

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

Обратите внимание, что вычисление положительной оси частоты идентично приведенному выше, но член со смещением FFT изменяется, чтобы соответствовать четным или нечетным длинам FFT.

Эти фрагменты кода были взяты из длинного ответа, размещенного на SO (который может показаться вам интересным), найденного здесь: /programming/9694297/matlab-fft-xaxis-limits-messing-up-and-fftshift/ 9699983 # 9699983

learnvst
источник
Хорошо, тогда я тоже могу использовать это для нечетного NFFT?
TheGrapeBeyond
Ах, прости. Я вижу небольшое осложнение при переходе от частоты -ve к + ve. Я немного изменил ответ.
учись