Visualizing and understanding Fourier transforms

skittishdev
Thu, 02 Feb 2023 00:03:00 +0000
Signal and Image Processing

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

5 posts - 3 participants