Processing math: 100%

The Fast Fourier Transform

Scope and Background Reading

This session introduces the fast fourier transform (FFT) which is one of the most widely used numerical algorithms in the world. It exploits some features of the symmetry of the computation of the DFT to reduce the complexity to something that takes order N2 (O(N2)) complex operations to something that takes order NlogN (O(NlogN)) operations.

The material in this presentation and notes is based on Chapter 10 of Steven T. Karris, Signals and Systems: with Matlab Computation and Simulink Modelling, 5th Edition from the Required Reading List.

Agenda

  • The inefficiency of the DFT
  • The FFT - a sketch of its development
  • FFT v DFT
  • Two examples

The inefficiency of the DFT

Consider a signal whose highest frequency is 18 kHz, the sampling frequency is 50 kHz, and 1024 samples are taken, i.e., N=1024.

The time required to compute the entire DFT would be:

t=1024samples50×103samples per second=20.48ms

To compute the number of operations required to complete this task, let us expand the N-point DFT defined as:

X[m]=N1n=0x[n]WmnN

Then X[0]=x[0]W0N+x[1]W0N+x[1]W0N++x[N1]W0NX[1]=x[0]W0N+x[1]W1N+x[1]W2N++x[N1]WN1NX[2]=x[0]W0N+x[1]W2N+x[1]W4N++x[N1]W2(N1)NX[N1]=x[0]W0N+x[1]WN1N+x[1]W2(N1)N++x[N1]W(N1)2N

  • It is worth remembering that W0N=ej2πN(0)=1.
  • Since WiN is a complex number, the computation of any frequency component X[k] requires N complex multiplications and N complex additions
  • 2N complex arithmetic operations are required to compute any frequency component of X[k].1
  • If we assume that x[n] is real, then only N/2 of the |X[m]| components are unique.
  • Therefore we would require 2N×N/2=N2 complex operations to compute the entire frequency spectrum.2
  • For our example, the N=1024-point DFT, would require 10242=1,048,576 complex operations
  • These would have to be completed in 20.48 ms.
  • This may be possible with modern computing hardware, perhaps even in a mobile phone, but it seems impractical.
  • Fortunately, many of the WN terms in the computation are unity (=1).
  • Moreover, because the WiN points are equally spaced points on the unit circle;
  • Because N is a power of 2 the points on the upper-half plane (range 0<θ<π are the mirror image of the points on the lower half plane range π<θ<2π;
  • Thus, there is a great deal of symmetry in the computation that can be exploited to simplify the computation and reduce the number of operations considerably to a much more manageable Nlog2N operations3.

This is possible with the algorithm called the FTT (fast Fourier transform) that was originally developed by James Cooley and John Tukey and considerably refined since.

The Fast Fourier Transform (FFT)

The FFT is very well documented, including in the text book, so we will only sketch its development and present its main result.

Much of the development follows from the properties of the rotating vector.4

WN=ej2πN

which results in some simplifications and mathematical short-cuts when N is a power of 2.

The most useful properties are:

WNN=ej2πNN=ej2π=1.WN/2N=ej2πNN2=ejπ=1.WN/4N=ej2πNN4=ejπ/2=j.W3N/4N=ej2πN3N4=ej3π/2=j.WkNN=ej2πNkN=ej2π=1,k=0,1,2,WkN+rN=ej2πNkNej2πNr=1.WrN=WrN.Wk2N=ej2π2Nk=ej2πNk2=Wk/2N.

Representing

X[0]=x[0]W0N+x[1]W0N+x[1]W0N++x[N1]W0NX[1]=x[0]W0N+x[1]W1N+x[1]W2N++x[N1]WN1NX[2]=x[0]W0N+x[1]W2N+x[1]W4N++x[N1]W2(N1)NX[N1]=x[0]W0N+x[1]WN1N+x[1]W2(N1)N++x[N1]W(N1)2N

in matrix form: [X[0]X[1]X[2]X[N1]]=[W0NW0NW0NW0NW0NW1NW2NWN1NW0NW2NW4NW2(N1)NW0NWN1NW2(N1)NW(N1)2N][x[0]x[1]x[2]x[N1]].

This is a complex Vandemonde matrix and it is more compactly expressed as:

X[m]=WNx[n]

The algorithm developed by Cooley and Tukey is based on matrix decomposition methods, where the matrix WN is factored into L smaller matrices, that is: WN=W1W2W3WL where L is chosen as L=log2N or N=2L.

Each row of the matrices on the right side of the decomposition, contains only two, non-zero terms, unity and WkN. Then the vector X[m]=W1W2W3WLx[n].

The FFT computation starts with matrix WL. It operates on x[n] producing a row vector, and each component of the row vector is obtained by one multiplication and one addition. This is because there are only two non-zero elements on a given row, and one of those elements is unity. Since there are N components of x[n], there will be N complex multiplications and N complex additions.

This new vector is then operated on by the WL1 matrix, then on WL1 and so on, until the entire operation is completed.

It appears that the entire operation would require NL=Nlog2N complex additions and also Nlog2N complex additions.

However, since W0N=1, WN/2N=1, and other simplifications, it is estimated that only about half of these, that is, Nlog2N total arithmetic operations are required by the FFT versus the N2 required by the DFT5.

DFT and FFT Comparisons

Under the assumptions about the relative efficiency of the DFT and FFT we can create a table like that shown below:

DFT FFT FFT/DFT
N N2 Nlog2N %
8 64 24 37.5
16 256 64 25
32 1024 160 15.6
64 4096 384 9.4
128 16,384 896 5.5
256 65,536 2048 3.1
512 261,144 4608 1.8
1024 1,048,576 10,240 1
2048 4,194,304 22,528 0.5

As you can see, the efficiy of the FFT actual gets better as the number of samples go up!

FFT in MATLAB

The FFT algorithm is implemented, in MATLAB, as the function fft. We will conclude by working through Exercises 6 and 7 from section 10.8 of Karris.

Example 1

Plot the Fourier transform of the rectangular pulse shown below, using the MATLAB fft func-tion. Then, use the ifft function to verify that the inverse transformation produces the rectangular pulse.

Example 1

FFT Example 1

The rectangular pulse can be produced like so

In [10]:
x = [linspace(-2,-1,50) linspace(-1,1,100) linspace(1,2,50)];
y = [linspace(0,0,50) linspace(1,1,100) linspace(0,0,50)];
plot(x,y)

and the FFT is produced as

In [11]:
plot(x, abs(fft(y)))

unwind

In [12]:
plot(x, abs(fftshift(fft(y))))

The inverse FFT is obtained with

In [13]:
plot(x, ifft(fft(y)))

Example 2

Example 2

FFT Example 2

The triangular pulse is obtained with

In [14]:
x = linspace(-1,1,100);
y = [linspace(0,1,50) linspace(1,0,50)];
plot(x,y)

and the FFT is obtained with

In [15]:
plot(x, abs(fftshift(fft(y))))

The inverse FFT is obtained with

In [16]:
plot(x, ifft(fft(y)))

Summary

  • The inefficiency of the DFT
  • The FFT - a sketch of its development
  • FFT v DFT
  • Two examples

Homework

Read the rest of Chapter 10 of Karris from page 10.9 and make your own notes on the implementation of the FFT.

The End?

  • This concludes this module.
  • There is some material that I have not covered, most notably is a significant amount of additional information about Filter Design (including the use of Matlab for this) in Chapter 11 of Karris.