Matlab,FFT频率范围的差异还是相同的?

时间:2016-03-01 23:14:44

标签: matlab fft dft

我试图了解matlab中的FFT如何工作,特别是如何定义绘制它的频率范围。碰巧我从matlab帮助链接和其他讨论中读到了这些,我认为(猜测)我对此感到困惑。 在matlab链接中: http://es.mathworks.com/help/matlab/math/fast-fourier-transform-fft.html 他们定义了这样一个频率范围:

f = (0:n-1)*(fs/n)

nfs为:

n = 2^nextpow2(L); % Next power of 2 from length of signal x
fs = N/T; % N number of samples in x and T the total time of the recorded signal

但另一方面,在上一篇文章中Understanding Matlab FFT example (基于以前版本的matlab),得到的频率范围定义为:

f = fs/2*linspace(0,1,NFFT/2+1);

NFFT为上述n(信号长度x的下一次幂为2)。 那么,基于此,这些不同的向量(方程1和最终方程)如何相同? 如果你可以看到,向量是不同的,因为前者有n个点而后者有NFFT/2个点!事实上,因素(fs/n)fs/2不同。

2 个答案:

答案 0 :(得分:2)

  

那么,基于此,这些不同的向量(方程1和最终方程)如何相同?

example in the documentation from Mathworks绘制FFT的整个n点输出。这涵盖了从0到接近fs(确切地为(n-1)/n * fs)的频率。然后他们进行以下观察(对FFT的实际输入有效):

  

频率范围的前半部分(从0到奈奎斯特频率fs/2)足以识别数据中的分量频率,因为后半部分只是上半部分的反映。

other post you refer to只是选择不显示冗余的下半场。然后它使用的点数的一半也覆盖了频率范围的一半。

  

事实上,因子(fs / n)与fs / 2不同。

理解它的最简单方法可能是将两个表达式的输出与n的一些小值进行比较,比较n=8并设置fs=1(因为{{1}两个表达式相乘)。一方面,第一个表达式fs的输出将是:

[0:n-1]*(fs/n)

0.000 0.125 0.250 0.500 0.625 0.750 0.875 的输出为:

fs/2*linspace(0,1,n/2+1)

正如您所看到的那样,在奈奎斯特频率0.000 0.125 0.250 0.500 之前,频率组完全相同。

答案 1 :(得分:1)

这种混淆可能是因为你引用的两个例子正在以不同的方式绘制fft的结果。有关此说明中的参考,请参阅以下代码。

在第一个示例中,绘图是频率范围内的功率谱(周期图)。请注意,在第一个图中,周期图不以0为中心,这意味着频率范围似乎是奈奎斯特采样频率的两倍。正如数学工作链接中所提到的,通常的做法是将周期图居中,以避免这种混淆(图2)。

对于第二个例子,采用相同的参数,原始图是具有与第一个例子中不同的归一化的傅里叶谱的幅度(图3)。使用Matlab的全频率排序语法(如代码中所述),将这个看似不同的fft结果转换为示例1的结果是微不足道的。 0中心周期图的相同结果在图4中重复。

因此,要具体回答您的问题,两种情况下的频率范围都是相同的,最大频率等于奈奎斯特采样频率,如下所示:

f = fs/2*linspace(0,1,NFFT/2+1);

理解dfft如何工作的关键(也在Matlab中)是要理解你只是将离散数据集投影到傅立叶空间中,其中matlab中fft()函数返回的是系数。通过以下公式给出每个频率分量的扩展和系数的阶数(在Matlab中,如例2):

f = [f(1:end-1) -fliplr(f(1,2:end))];

有关其他详细信息,请参阅DFT上的Wikipedia页面: https://en.wikipedia.org/wiki/Discrete_Fourier_transform

将fft省略为2参数的幂可能也有帮助

y = fft(x).

在这种情况下,您会看到y中只有少数非零分量对应于输入信号的精确系数。 mathworks页面声称以下是使用或不使用此长度的动机:

"使用2的幂来获得变换长度可以优化FFT算法,但实际上,与使用n = m相比,执行时间通常没有什么差别。"

%% First example:
% http://www.mathworks.com/help/matlab/math/fast-fourier-transform-fft.html

fs = 10;                                % Sample frequency (Hz)
t = 0:1/fs:10-1/fs;                      % 10 sec sample
x = (1.3)*sin(2*pi*15*t) ...             % 15 Hz component
  + (1.7)*sin(2*pi*40*(t-2));            % 40 Hz component 
% Removed the noise

m = length(x);          % Window length
n = pow2(nextpow2(m));  % Transform length
y = fft(x,n);           % DFT
f = (0:n-1)*(fs/n);     % Frequency range
power = y.*conj(y)/n;   % Power of the DFT

subplot(2,2,1)
plot(f,power,'-o')
xlabel('Frequency (Hz)')
ylabel('Power')
title('{\bf Periodogram}')

y0 = fftshift(y);          % Rearrange y values
f0 = (-n/2:n/2-1)*(fs/n);  % 0-centered frequency range
power0 = y0.*conj(y0)/n;   % 0-centered power

subplot(2,2,2)
plot(f0,power0,'-o')
% plot(f0,sqrt_power0,'-o')
xlabel('Frequency (Hz)')
ylabel('Power')
title('{\bf 0-Centered Periodogram} Ex. 1')

%% Second example:
% http://stackoverflow.com/questions/10758315/understanding-matlab-fft-example

% Let's redefine the parameters for consistency between the two examples

Fs = fs;                      % Sampling frequency
% T = 1/Fs;                   % Sample time (not required)
L = m;                        % Length of signal
% t = (0:L-1)*T;              % Time vector (as above)
% % Sum of a 3 Hz sinusoid and a 2 Hz sinusoid
% x = 0.7*sin(2*pi*3*t) + sin(2*pi*2*t); %(as above)

NFFT = 2^nextpow2(L); % Next power of 2 from length of y
                      % NFFT == n (from above)
Y = fft(x,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1);

% Plot single-sided amplitude spectrum.
subplot(2,2,3)
plot(f,2*abs(Y(1:NFFT/2+1)),'-o') 
title('Single-Sided Amplitude Spectrum of y(t)')
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')


% Get the 0-Centered Periodogram using the parameters of the second example
f = [f(1:end-1) -fliplr(f(1,2:end))]; % This is the frequency ordering used
                                      % by the full fft in Matlab

power = (Y*L).*conj(Y*L)/NFFT;

% Rearrange for nicer plot
ToPlot = [f; power]; [~,ind] = sort(f); 
ToPlot = ToPlot(:,ind);

subplot(2,2,4)
plot(ToPlot(1,:),ToPlot(2,:),'-o')
xlabel('Frequency (Hz)')
ylabel('Power')
title('{\bf 0-Centered Periodogram} Ex. 2')