Next: Fast Fourier Transform Up: Spectral Methods Previous: Spectral Methods

# Discrete Fourier Transform

Consider the following integral:

 (2.1)

Assume that function f(x) is sampled within the interval on a regularly spaced set of points . In that case we can approximate integral (2.1) by evaluating a finite sum

 (2.2)

If every point xl sits at the left hand side of its interval of length , then the above evaluates to:
 (2.3)

and for we get that

 (2.4)

Let us substitute in equation (2.2):

 (2.5)

We can rewrite this expression in the form of a matrix multiplication:

 (2.6)

The discrete Fourier transform matrix shown in equation (2.6) is a complex Vandermonde matrix. Such matrices appear in polynomial interpolation. It is easy to write a simple Fortran program that builds a discrete Fourier transform matrix. But instead of doing it with Fortran, this time we'll use our interactive Fortran, Octave, to build a discrete Fourier transform matrix.

Octave, version 2.0.13 (sparc-sun-solaris2.6).
Copyright (C) 1996, 1997, 1998 John W. Eaton.
This is free software with ABSOLUTELY NO WARRANTY.
For details, type warranty'.

octave:1> w = exp(-2 * pi * i / 4)
w = -i
octave:2> F = ones(4,4)
F =

1  1  1  1
1  1  1  1
1  1  1  1
1  1  1  1

octave:3> (0:3)
ans =

0  1  2  3

octave:4> F(2,:) = w .^ (0:3)
F =

1  1  1  1
1 -i -1  i
1  1  1  1
1  1  1  1

octave:5> F(3,:) = w .^ (2 * (0:3))
F =

1  1  1  1
1 -i -1  i
1 -1  1 -1
1  1  1  1

octave:6> F(4,:) = w .^ (3 * (0:3))
F =

1  1  1  1
1 -i -1  i
1 -1  1 -1
1  i -1 -i

octave:7>


Another way to accomplish the same would be as follows:

octave:8> F = ones(4,4)
F =

1  1  1  1
1  1  1  1
1  1  1  1
1  1  1  1

octave:9> F(2,:) = w .^ (0:3)
F =

1  1  1  1
1 -i -1  i
1  1  1  1
1  1  1  1

octave:10> F(3,:) = F(2,:) .* F(2,:)
F =

1  1  1  1
1 -i -1  i
1 -1  1 -1
1  1  1  1

octave:11> F(4,:) = F(2,:) .* F(3,:)
F =

1  1  1  1
1 -i -1  i
1 -1  1 -1
1  i -1 -i

octave:13>

This is a faster way because multiplication is cheaper than exponentiation.

Once we have built the discrete Fourier transform matrix we can attempt to find a numerical Fourier transform of, say, a sine function:

octave:39> x = [ 0, 2*pi/4, 2*2*pi/4, 3*2*pi/4 ]
x =

0.00000  1.57080  3.14159  4.71239

octave:40> x = sin(x)
x =

0.00000   1.00000   0.00000  -1.00000

octave:41> 2 * pi / 4 * F * x'
ans =

0.00000 + 0.00000i
0.00000 - 3.14159i
0.00000 + 0.00000i
-0.00000 + 3.14159i

octave:42>

Our numerical result, neglecting the last harmonic, is that

which is just right, because

Recall that you can check that integration easily with Emacs calc, e.g.,
alg' integ(sin(x)^2, x, 0, 2 * pi)
pi

but remember to do it in the radians mode.

What about that last harmonic? Repeating the same computation for n = 8 returns:

octave:43> w = exp(-2 * pi * i / 8)
w = 0.70711 - 0.70711i
octave:44> F = ones(8,8);
octave:45> for k = 2:8
> F(k,:) = w .^ ((k - 1) * (0:7));
> end
octave:46> x = 2 * pi / 8 * (0:7);
octave:47> x = sin(x);
octave:48> 2 * pi / 8 * F * x'
ans =

-0.00000 + 0.00000i
0.00000 - 3.14159i
0.00000 + 0.00000i
0.00000 + 0.00000i
0.00000 + 0.00000i
0.00000 + 0.00000i
0.00000 + 0.00000i
-0.00000 + 3.14159i

octave:49>

So we are still getting the same result, , and the only difference is that the last harmonic has been moved further away.

Let us try a signal with higher harmonics:

octave:45> x = 2 * pi / 8 * (0:7);
octave:46> y = sin(x) + 0.5 * sin (2 * x);
octave:47> 2 * pi / 8 * F * y'
ans =

0.00000 + 0.00000i
0.00000 - 3.14159i
0.00000 - 1.57080i
-0.00000 + 0.00000i
0.00000 + 0.00000i
0.00000 + 0.00000i
-0.00000 + 1.57080i
-0.00000 + 3.14159i

octave:48> y = cos(x) + sin(2 * x) - cos(3 * x);
octave:49> 2 * pi / 8 * F * y'
ans =

0.00000 + 0.00000i
3.14159 + 0.00000i
0.00000 - 3.14159i
-3.14159 - 0.00000i
-0.00000 + 0.00000i
-3.14159 - 0.00000i
-0.00000 + 3.14159i
3.14159 + 0.00000i

octave:50>
`
What is happening is that harmonics are inserted from both ends. The reason for this is that the discrete Fourier transform returns amplitudes that correspond to both positive and negative wave numbers. Amplitudes for positive wave numbers are returned in slots labeled with . Amplitudes for negative wave numbers are returned in reverse order in slots and the Nyquist freqency amplitude

 (2.7)

or

 (2.8)

where is the sampling interval, is returned in slot l = n/2. The amplitude that corresponds to the zero frequency, i.e., a constant shift, is returned in slot l=0. Because in Fortran arrays are normally numbered by default from 1 through n (but this can be changed with an appropriate declaration) you've got to add 1 to l in order to refer to an appropriate slot in a Fortran array.

In our case , kc = 4, and the Nyquist frequency Amplitude is -0.0 + 0.0 i.

How did those negative frequencies creep into our sum:

Observe that Fk is periodic in k with period equal to n. Therefore:

 Fn - k = F-k (2.9)

In other words only half of the vector returned by a discrete Fourier transform corresponds to positive wave numbers. So, if you want, say, m amplitudes associated with positive wave numbers, you must sample your signal on at least 2m + 2 points2.1. Conversely, if you sample on 2m + 2 points the maximum frequency amplitude will correpond not to but to kc = m+1.

What is going to happen if your signal contains harmonics that are higher than the Nyquist frequency kc? It turns out that all of the power spectral density that lies outside of the range [-kc, +kc] will be sneakily moved into that range, i.e., any amplitude that corresponds to a frequency outside that range is going to be aliased into that range.

There is no way to overcome aliasing other than to know the bandwidth limit of a signal in advance and then sample sufficiently densely, so that the Nyquist frequency is higher than the bandwidth limit.

Next: Fast Fourier Transform Up: Spectral Methods Previous: Spectral Methods
Zdzislaw Meglicki
2001-02-26