# [Tutor] fourier transform (fwd)

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Tue Aug 2 03:31:31 CEST 2005

```Hi Jeff,

> Yes, for an odd square wave the b's of the fourier series are non zero
> for even values and zero for odd values of n. these are the coefficients
> for the fourier series.  Although I beleive the fft (fourier transform)
> should return the amplitude of frequencies that exist. so for example a
> fft on a 10 hz sin wave with amplitude equal 2 should return all zero
> amplitudes except for at 10 hz there should be a spike with amplitude 2.

Up to this point, I agree with you.

> although... this would be bn = 2 for n=1 in the fourier series.

But at this point, I'm not so sure.

I was expecting coefficient bn to be the contribution at n hertz.  n=0 is
the contribution from the steady state, so for n=1, I didn't expect to get
the contribution from the 10hz wave, but the 1hz one instead.  I'm
intro class... *grin*

I think we're straying a bit wildly from Python tutorial material, but
let's try an example and check something out.  I want to sample points
from the function:

f(x) = sin(x) + sin(2x) + sin(3x)

between [0, 2pi].  Let's see...

######
>>> import math
>>> def f(x):
...     return math.sin(x) + math.sin(2*x) + math.sin(3*x)
...
>>> def build_sample(f, n):
...     sample = []
...     x = 0
...     while x < 2*math.pi:
...         sample.append(f(x))
...         x = x + 2*math.pi / float(n)
...     return sample
...
######

This build_sample function will make things nicer to take arbitrary
samples of any function.

######
>>> sample = build_sample(f, 2000)
######

I'll take a sample of 2000 points, just to make the function sorta smooth
to the FFT function.  Ok, let's see what the FFT gives us here:

######
>>> import numarray.fft
>>> frequences = numarray.fft.fft(sample)
>>> frequences.real
-5.0942902674044888e-11
>>> frequences.real
1.5720366156507799
>>> frequences.real
3.1424651347438695
>>> frequences.real
4.7037495618800307
>>> frequences.real
-0.016650764926842861
>>> frequences.real
-0.012744203044761522
>>> frequences.real
-0.011435677529394448
######

And to me, this looks like frequences contains the steady state values,
frequences the frequency contribution from 1Hz, and so on.  (I have to
admit that I don't quite understand what the values mean yet.)

Let's try another test:

######
>>> def f(x):
...     return 42 + math.sin(2*x)
...
>>> sample = build_sample(f, 20000)
>>> frequences = numarray.fft.fft(sample)
>>> frequences.real
840041.99999999814
>>> frequences.real
0.00010469890965382478
>>> frequences.real
3.1415140090902716
>>> frequences.real
-0.00056553943694630812
>>> frequences.real
-0.00041889401962948863
######

Again, I have to plead a huge amount of ignorance here: I don't quite
understand what the real components of the frequencies is supposed to
mean.  *grin*

But it does look like the FFT is sensitive to our f() function at the
right frequences --- it's giving us some honking huge value at the steady
state, and another blip at frequences.

Finally, we can try a square wave:

######
>>> def square(x):
...     if x > math.pi:
...         return -1
...     return 1
...
>>> freqs = numarray.fft.fft(build_sample(square, 1000))
>>> freqs.real
-1.0
>>> freqs.real
2.9999901501133008
>>> freqs.real
-0.99996060055012559
>>> freqs.real
2.9999113516016997
>>> freqs.real
-0.99984240375361688
######

Interesting: I do see some kind of oscillation here, but don't quite
understand what it means.  What happens if we push the sample rate higher?

######
>>> t = numarray.fft.fft(build_sample(square, 100000))
>>> t = numarray.fft.fft(build_sample(square, 100000))
>>> t.real
-1.0
>>> t.real
2.999999999013506
>>> t.real
-0.99999999604174983
>>> t.real
2.9999999911217117
>>> t.real
-0.99999998418203995
>>> t.real
2.9999999753002307
>>> t.real
-0.999999964464928
>>> t.real
2.9999999516338782
######

Hmmm... the numbers seem to be about the same.  What if we drop them down
really low?

######
>>> t = numarray.fft.fft(build_sample(square, 10))
>>> t.real
2.0
>>> t.real
-4.4408920985006262e-15
>>> t.real
2.0
>>> t.real
-1.2382749738730321e-15
>>> t.real
2.0
>>> t.real
2.2764082277776284e-17
>>> t.real
2.0
######

Odd.  Now the odd components look really small!  So sample rate does
appear to be pretty important: otherwise, we get some weird results from
the FFT.

Then again, maybe they're not "weird": maybe I'm just misinterpreting the
results again.  *grin* I wish I knew more about the FFT!  I do have the
excellently whimsical book "Who is Fourier?" in my bookshelf, but haven't