[matlab] Understanding Matlab FFT example

I am new to matlab and FFT and want to understand the Matlab FFT example. For now I have two main questions:

1) Why does the x-axis (frequency) end at 500? How do I know that there aren't more frequencies or are they just ignored?

2) How do I know the frequencies are between 0 and 500? Shouldn't the FFT tell me, in which limits the frequencies are? Does the FFT only return the amplitude value without the frequency?

Thanks for any hint!


Example in question:

Consider data sampled at 1000 Hz. Form a signal containing a 50 Hz sinusoid of amplitude 0.7 and 120 Hz sinusoid of amplitude 1 and corrupt it with some zero-mean random noise:

Fs = 1000;                    % Sampling frequency
T = 1/Fs;                     % Sample time
L = 1000;                     % Length of signal
t = (0:L-1)*T;                % Time vector
% Sum of a 50 Hz sinusoid and a 120 Hz sinusoid
x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t); 
y = x + 2*randn(size(t));     % Sinusoids plus noise
plot(Fs*t(1:50),y(1:50))
title('Signal Corrupted with Zero-Mean Random Noise')
xlabel('time (milliseconds)')

time domain

Converting to the frequency domain, the discrete Fourier transform of the noisy signal y is found by taking the fast Fourier transform (FFT):

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

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

frequency domain

This question is related to matlab fft

The answer is


There are some misconceptions here.

Frequencies above 500 can be represented in an FFT result of length 1000. Unfortunately these frequencies are all folded together and mixed into the first 500 FFT result bins. So normally you don't want to feed an FFT a signal containing any frequencies at or above half the sampling rate, as the FFT won't care and will just mix the high frequencies together with the low ones (aliasing) making the result pretty much useless. That's why data should be low-pass filtered before being sampled and fed to an FFT.

The FFT returns amplitudes without frequencies because the frequencies depend, not just on the length of the FFT, but also on the sample rate of the data, which isn't part of the FFT itself or it's input. You can feed the same length FFT data at any sample rate, as thus get any range of frequencies out of it.

The reason the result plots ends at 500 is that, for any real data input, the frequencies above half the length of the FFT are just mirrored repeats (complex conjugated) of the data in the first half. Since they are duplicates, most people just ignore them. Why plot duplicates? The FFT calculates the other half of the result for people who feed the FFT complex data (with both real and imaginary components), which does create two different halves.


It sounds like you need to some background reading on what an FFT is (e.g. http://en.wikipedia.org/wiki/FFT). But to answer your questions:

Why does the x-axis (frequency) end at 500?

Because the input vector is length 1000. In general, the FFT of a length-N input waveform will result in a length-N output vector. If the input waveform is real, then the output will be symmetrical, so the first 501 points are sufficient.

Edit: (I didn't notice that the example padded the time-domain vector.)

The frequency goes to 500 Hz because the time-domain waveform is declared to have a sample-rate of 1 kHz. The Nyquist sampling theorem dictates that a signal with sample-rate fs can support a (real) signal with a maximum bandwidth of fs/2.

How do I know the frequencies are between 0 and 500?

See above.

Shouldn't the FFT tell me, in which limits the frequencies are?

No.

Does the FFT only return the amplitude value without the frequency?

The FFT simply assigns an amplitude (and phase) to every frequency bin.


The reason why your X-axis plots frequencies only till 500 Hz is your command statement 'f = Fs/2*linspace(0,1,NFFT/2+1);'. Your Fs is 1000. So when you divide it by 2 & then multiply by values ranging from 0 to 1, it returns a vector of length NFFT/2+1. This vector consists of equally spaced frequency values, ranging from 0 to Fs/2 (i.e. 500 Hz). Since you plot using 'plot(f,2*abs(Y(1:NFFT/2+1)))' command, your X-axis limit is 500 Hz.