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
- Create a known signal as a sum/product of 2 other simple sinusoidal signals of different frequencies (code below uses sum)
- Use the theoretical Fourier transform integral
- 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
- What am I doing wrong w.r.t. using the SymPy.jl module?
- 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)
- 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