Fourier Transform
For a more detailed explanation of the Fourier analysis take a look at this article.Long ago, Joseph Fourier (mathematician, physicist, politician, historian and all round smarty pants) discovered that any signal can be represented by a superimposition of sines and cosines.(Strictly speaking, he was talking about periodic signals but the Fourier transform is extended to aperiodic signals as well). The Fast Fourier Transform (FFT) is the most efficient algorithm for computing the Fourier transform of a discrete time signal.
The input signal
The input signal in this example is a combination of two signals
- frequency of 10 Hz and an amplitude of 2
- frequency of 20 Hz and an amplitude of 3
Sampling frequency
The input signal is generated over a period of 0 to 1 with 1000 samples. In real world scenarios, this would mean that the signal has been sampled 1000 times in a single period. Thus, the sampling frequency fs equals 1000 Hz.R code to generate the input signals. The comments are (hopefully) self explanatory.
#set the sampling frequency
samplingFrequency = 1000;
#create the indexes to sample at
timeInterval = 1/samplingFrequency;
signalIndex = seq(0, 1, by=timeInterval);
#define num samples as the dimention of signalIndex. here N = 1000
N = 1000
#amplitude of signal 1
a1 = 2;
#amplitude of signal 2
a2 = 3;
#frequency of signal 1
f1 = 10;
#frequency of signal 2
f2 = 20;
#10 Hz Sine wave with peak amplitude 2
signal1 = a1 * sin(2 * pi * f1 * signalIndex);
#20 Hz Sine wave with peak amplitude 3
signal2 = a2 * sin(2 * pi * f2 * signalIndex);
#input signal is the sum of two signals in this case with frequencies 10 and 20 Hz
inputSignal = signal1 + signal2;
#the input signal
plot(signalIndex, inputSignal);
The FFT
The FFT in this example if performed on all the 1000 points of the input signal. Hence, this is a N = 1000 point FFT. Typically, the number of samples are chosen to be multiples of 8 (e.g 32 point, 64 point) for the sake of efficiency and speed.FFT Bin Spacing
Each bin in the FFT result corresponds to a frequency of (binindex * fs)/N where binindex is the index of the bin, fs is the frequency with which the input signal is sampled and N is the number of points. In the above example, each bin corresponds to a frequency of 1 Hz (binindex * 1000/1000 = binindex). The first bin - Bin 0 denotes the DC component. Each subsequent bin denotes a frequency component increment of 1 Hz (Second bin corresponds to 1 Hz, the third corresponds to 2 Hz and so on).
#perform the FFT. In this case the number of points (N) will be equal to 1000. Output will be the individual components of the FFT.
fourierComponents = fft(inputSignal);
#get the absolute value of the coefficients
fourierCoefficients = abs(fourierComponents);
Understanding the results of the Fast Fourier Transform (FFT)
Astute readers will notice a couple of things that are wrong with the above plot. Interpreting the results of the FFT will be easier once these issues are addressed.
Twin symmetrical spikes
The FFT results (in Fig. 4) show two symmetrical spikes for each input signal - one at bin n and the other at N-n. Since the DFT can accept complex inputs, the result is symmetrical around the frequency axis. When the input is real (as with most real world cases) the output for bins greater than N/2 are redundant and do not add any spectral information. Hence, we can safely ignore the values for bins > N/2.Amplitude
The amplitude at the bin corresponding to 10 Hz is 1000 and 1500 at the 20 Hz bin. However, the input signals had an amplitude of 2 and 3. The discrepancy arises due to lack of normalization. The results need to be normalized for the sample size which is in this case 1000. Since the input is real valued and the data > N/2 is ignored we need to normalize the results by N/2.DC Component
Bin 0 contains the value for the DC component that the signal is riding on. In this case there is no DC component and the value of the first bin is zero.
#Normalize coefficients fig 5 here N = 1000 samples so N/2 = 500
normalizedFourierComponents = fourierCoefficients / (N/2);
#get the first 50 coefficients fig 6
mainCoeffs = normalizedFourierComponents[1:50];
9 comments:
Very good.
You need to add the code that gives figure 5 and 6!
Done
I think I see a contradiction above. Under "FFT Bin Spacing", you say the first bin is for 1 Hz, then under "DC Component", you say the first bin is the DC bin. Which terminology is correct? My understanding is that the first bin is ALWAYS the DC bin.
Yes - The first bin - Bin 0 in the graph - denotes the DC component. Each subsequent bin denotes a frequency component increment of 1 Hz. Updated to reflect this.
Clear and simple!!Thanks
I guess the code is slightly wrong cause actually we have a samplesize of N = 1001 not 1000 here. Right?
very good demo
Really helpful (and simple) example. Thanks!
great tutorial. thank you.
Post a Comment