Visualizing and understanding Fourier transforms

Hi,
I am trying to understand Fourier transforms, and decided to create some plots using Julia to help validate my own understanding.

What I want

  1. Create a known signal as a sum/product of 2 other simple sinusoidal signals of different frequencies (code below uses sum)
  2. Use the theoretical Fourier transform integral
  3. Plot that solution

What I expect to see
At step 3, I expect to see two spikes at the frequencies that make up the combined signal (the frequency spectrum).

I understand that there is a FFTW.jl package, but I wanted to check and see what would happen with this approach I just described.

What I am noticing
I am trying to use SymPy.jl to perform symbolic integration, but invoking that via Julia seems to cause the notebook to be stuck, and the appropriate cell does not return. The equivalent integral computation in Python3 with sympy returns in a few seconds.

Julia Code

using Plots, SymPy
signal(t; f=1) = sinpi(2 * t * 1//f)
f1(t) = signal(t; f=1)
f2(t) = signal(t; f=3)
product(t) = f1(t) .+ f2(t)

num_datapoints = 100
step = 1/num_datapoints
max_time = 3
times = 0:step:max_time

p1 = plot(times, product, label="Product signal")
p2 = plot(times, f1, label="sin(2Ď€)")
plot!(times, f2, label="sin(2Ď€/3)")
xlabel!("Time (multiplies of 2Ď€)")
ylabel!("Signal")
plot(p1, p2, layout=2)

SymPy.@syms t, f3
product(t)
ftransform1 = product(t) * â„Ż^(-2 * pi * im * f3 * t)

SymPy.integrate(ftransform1, t) # This line does not return even after 250+ seconds

Python Code

>>> from sympy import *
>>> from spb import *
>>> t, f = symbols('t f')
>>> prod = sin(2 * pi * t) * sin(2 * pi * t/3) * exp(-I * 2 * pi * t * f)
>>> sol = integrate(prod, (t, -oo, oo))
>>> sol
Piecewise((-9*I*f/(64*pi*(1 - 9*f**2/16)) + 9*I*f/(16*pi*(1 - 9*f**2/4)) + I/(4*pi*f*(1 - 4/(9*f**2))) - I/(4*pi*f*(1 - 16/(9*f**2))), (Abs(2*arg(f) + pi) < pi) & (Abs(2*arg(f) - pi) < pi)), (Integral(exp(-2*I*pi*f*t)*sin(2*pi*t/3)*sin(2*pi*t), (t, -oo, oo)), True))

What else I tried
I tried using SymbolicNumericIntegration.jl, but no luck there. I was unable to locate other packages which may help.

using Symbolics, SymbolicNumericIntegration
@variables x, f
product(x)
ftransform(t) = product(t) * Symbolics.Term(exp, -2Ď€ * im * f * t)
ftransform(x)
sol = SymbolicNumericIntegration.integrate(ftransform(x))[1]  # Throws an error: TypeError: non-boolean (Symbolics.Num) used in boolean context
f_fun = eval(build_function(sol, x))
plot(times, f_fun, xlims=(0, 5); grid=0.5, ticks=0:0.5:5)

If I remove * Symbolics.Term(exp, -2π * im * f * t) from ftransform(t), then the numeric integration yields some expression, but plotting that doesn’t result in something I expect either.

Questions

  1. What am I doing wrong w.r.t. using the SymPy.jl module?
  2. How can I get SymbolicNumericIntegration.jl to evaluate the integral above which is of the form \exp^{-2 \pi i ft} \cdot \left( sin(2 \pi f t) + sin(\frac{2 \pi f t}{3}) \right)
  3. I am having a difficult time understanding the FFTW.jl library because I don’t understand Fourier transforms themselves very well. Any pointers on how I can achieve the visualization I want with that library?

Edit
Ufff. I just realized that evaluating it as a definite integral does cause it to return almost immediately.

sol = SymPy.integrate(ftransform1, (t, -oo, oo))

But now when I try to plot this curve, I get another exception

plot(times, sol, xlims=(0, 1.5), ticks=-5:0.1:5) # UndefVarError: arg not defined

I tried defining arg as an alias to angle, but no dice.

arg=angle

FFTW, like all FFTs, computes a discrete Fourier transform. This is not the same as the “theoretical Fourier transform integral”, i.e. the continuous Fourier transform on the real line.

1 Like

So am I embarking on a fool’s errand trying to visualize and understand FFT this way?

No, the two are still related (the DFT approaches the continuous Fourier transform in a certain limit, and the two are qualitatively similar even for finite sizes where they are not exactly the same). But you need to understand the definitions of the transforms you are computing if you want to make sense of them.

When I was first trying to understand the FFT I came upon HP application Note 243 that was good for understanding if less so for the mathematics. I suggest starting with this type of base and then going to Julia to verify what it is telling you.

3 Likes