MATLAB  FFT and Zero Padding
17 Apr 2008 Quan Quach 23 comments 2,631 views
This is the fourth post in the blinkdagger signal processing series.
Introduction
In the previous tutorial, we showed you how correctly scale your xaxis so that your FFT results were meaningful. In this post, we will be discussing zeropadding, a method that can help you better visualize/interpret your fft results. Zeropadding means that you append an array of zeros to the end of your input signal before you fft it. Luckily, the fft
command within Matlab makes it very easy to zeropad.
Why Zero Pad?
Two reasons that you might want to zero pad is to increase the number of data points to a power of 2. Traditionally, the FFT algorithm is more efficient when it is dealing with signals that contain 2^N data points. Nowadays, this isn’t as important with the modern algorithms. Another reason for zeropadding is for a “better” resolution in the frequency spectrum. We’ll discuss why quotes are used around better in a bit. In general, zeropadding can prove quite useful and should be used when using the fft command. In practice, it is helpful to zero pad a signal to 4 times it’s original length, giving you a 4fold increase in the frequency resolution.
A Simple Example
Let’s use the same signal as the previous tutorial as our example signal:
fo = 4; %frequency of the sine wave Fs = 100; %sampling rate Ts = 1/Fs; %sampling time interval t = 0:Ts:1Ts; %sampling period n = length(t); %number of samples y = 2*sin(2*pi*fo*t); %the sine curve %plot the cosine curve in the time domain sinePlot = figure; plot(t,y) xlabel('time (seconds)') ylabel('y(t)') title('Sample Sine Wave') grid
But now, lets append some zeros to the end of this signal:
Case 1: Number of points = 128
Case 2: Number of points = 256
Case 3: Number of points = 512
This is what the signal would look like for these three cases:
Taking the FFT of the ZeroPadded Signals
Luckily, the fft
command within Matlab makes zeropadding extremely easy. The fft command has a second argument that allows you to specify how many data points the fft command will return. I modified the code I presented in the last tutorial to allow for zero padding and used it here:
%remember to save this function as an mfile! function [X,freq]=centeredFFT(x,Fs,N) %this is a custom function that helps in plotting the twosided spectrum %x is the signal that is to be transformed %Fs is the sampling rate %N is the number of points returned in the FFT result %this part of the code generates that frequency axis if mod(N,2)==0 k=N/2:N/21; % N even else k=(N1)/2:(N1)/2; % N odd end T=N/Fs; freq=k/T; %creates the frequency axis X=fft(x,N)/length(x); % normalizes the data X=fftshift(X);%shifts the fft data so that it is centered
Now, lets take the fft of these three signals.
Why Does My Output Look Like a Sinc?
When we pad with zeros, we are effectively multiplying a rectangular box with the sinusoid in the time domain. In the frequency domain, this translates into convolving a sinc function with an impulse resulting in a sinclike output!(You can download the script that I used in creating these plots at the end of this tutorial).
As you can see, there are more sampled points as N gets larger, and it is easier to see the general shape of the spectrum. The larger your N is, the finer the sampling will be. If I keep on increasing the number of zeros, it will make my frequency spectrum more refined. So does this mean I can just zeropad my signal and get a better FFT spectrum every time? Well, technically speaking, you get more frequency bins when you zero pad, so yes, you do get a higher resolution in the frequency domain. But the caveat is that there is no new information added when you zeropad.
When you increase the size of N, all you are really doing is interpolating the data to obtain more sample points. There is NO new information added when zeropadding is applied. The resolution has increased, but I repeat, THERE IS NO NEW INFORMATION ADDED! This might sound confusing and paradoxical, but it is a very important point.
If you have the option to take more data, it is ALWAYS better to get more data than to zero pad. Zeropadding is NOT a substitute for taking more data!
Another Example on how Zero Padding can Help

In this example, we are going to use zero padding to help us distinguish between two peaks that would otherwise be difficult to distinguish.
The example signal has f1 = 4 Hz and f2 = 4.5 Hz (meaning it will have a peak at 4 Hz and a peak at 4.5 Hz):
[tex]y(t)=100sin(2\pi{f}_{1}t)+100sin(2\pi{f}_{2}t)[/tex]
The following MATLAB code is used to generate the curve. Insert this into the MATLAB command prompt
f1 = 4; %frequency of the first sine wave f2 = 4.5; %frequency of the second sine wave Fs = 100; %sampling rate Ts = 1/Fs; %sampling time interval t = 0:Ts:2Ts; %sampling period y = 100*sin(2*pi*f1*t) + 100*sin(2*pi*f2*t); %sum of sine waves plot(t,y) title('Sample Signal', 'FontWeight','Bold') xlabel('Time (seconds)') ylabel('Amplitude') grid

Now, lets take the FFT of the signal without zero padding. Theoretically, we expect two peaks. One peak at 4 Hz, and another at 4.5 Hz.
As you can see, it is difficult to tell that there are two peaks in this plot. It looks like the peaks got smashed together.

Now, lets apply some zero padding up to N = 1024 points.
The following function is used to perform this:
%remember to save this function as an mfile! function [X,freq]=positiveFFT_zero_padding(x,Fs,N) k=0:N1; %create a vector from 0 to N1 T=N/Fs; %get the frequency interval freq=k/T; %create the frequency range X=fft(x,N)/length(x); % normalize the data %only want the first half of the FFT, since it is redundant cutOff = ceil(N/2); %take only the first half of the spectrum X = X(1:cutOff); freq = freq(1:cutOff);
At the Matlab Command prompt, type the following to obtain the plot shown below:
fftPlot2 = figure set(fftPlot2,'Position',[500,500,600,300]) zeroPadFactor = nextpow2(length(y)) + 3; [a,b] = positiveFFT_zero_padding(y,Fs,2^zeroPadFactor); plot(b,abs(a)) title('FFT of Sample Signal: Zero Padding up to N = 1024', 'FontWeight','Bold') xlabel('Freq (Hz)') ylabel('Magnitude') grid xlim([0 10])

But didn’t we just say that no new information is added? How were we able to distinguish these two peaks if no new information is added?
The information was always there, but it was “hidden” in a way. When we took the FFT of the signal without zero padding, the frequency bins were not fine enough to differentiate the two peaks. By the sampling theorem, as long as you sample a bandlimited signal under the Nyquist rate, you know everything you need to know to perfectly reconstruct the signal. Therefore, at that point, you’ve done the best you can do; you can zeropad all you want to get more points at the output of your FFT, but you don’t get any new information, because you already have all the information there is on the continuoustime signal.
Inherently, there is nothing wrong with zeropadding in itself. You just have to be careful in its application. Whenever I use the fft command, I tend to use an N that is 4 times larger than the amount of data points within my signal. Zero padding cannot hurt your FFT result.
Conclusion
It is a common misconception that zeropadding adds more information. Zero padding adds NO NEW information. The perceived benefit of zeropadding is increased spectral resolution. You are getting better resolution, but the key is to realize that there is NO NEW information added from the zeropadding. Zeropadding is useful, but it should not be a substitute for taking larger data samples. If you had to choose between taking twice as much data, or to zero pad your data, the answer is to ALWAYS take more data.
Download Source Files
Download the source files that were used in creating the plots.
Sources and References
Zero Padding Does Not Buy Spectral Resolution
댓글을 달아 주세요