Neither the scale is correct, neither the ‘form’ of the solution.
It’ s easy to properly scale the output of fft(), if I multiply Fnumeric by a factor of dx/2pi, which is the factor that appears in the first order approximation of the F.T., this scales the things down correctly. But i’m still having in incorrect behaviour, as you can see:
import FFTW
using PyPlot
Nx = 1024
x = range(-10, 10, length=Nx)
dx = x[2] - x[1]
k = 2 * pi * FFTW.fftfreq(Nx, 1/dx)
k = FFTW.ifftshift(k)
a = 1.0
f = [abs(i) <= a / 2 ? 1 : 0 for i in x]
sa = @. a * sinc(k * a / 2 / pi) # sinc(x) = sin(pi * x) / (pi * x)
s = FFTW.fftshift(f) # compensate osciallations
s = FFTW.fft(s) * dx
s = FFTW.ifftshift(s)
plot(k, sa)
plot(k, real.(s))
show()
Note that sinc function in Julia is defined as normalized sinc function: sinc(x) = sin(pi * x) / (pi * x).
Spectrum has extra oscillations due to the way how fft algorithm stores arrays. You should apply extra fftshift before calling fft in order to avoid these oscillations (shift in space = frequency modulation in spectrum).
By default FFTW does not normalize the integrals by 2pi.
Thank you for the explanation!
I did not know that I had to write a variable this variable: k = 2 * pi * FFTW.fftfreq(Nx, 1/dx), in order to plot the output of fft().
But i have another question, why the imaginary part of s is so high? Theoretically it should be 0, so I was expecting to have values close to 0. But it’s not what I’m getting.
A value far from machine precision. Is this a matter of some kind of normalization that I’m not taking into account?
The imaginary part is nonzero because the sinc function decays very slow and touches the boundaries of the spectral grid (restricted by the Nyquist frequency). In order to improve the situation you need to increase the size of the spectral grid by decreasing the step size in the real domain (try to increase Nx twice).
One small remark. The even-symmetry of the input signal to the DFT could be further improved by defining x more carefully:
Nx = 1024
x = range(-10,10,length = Nx + 1)
x = x[1:Nx]
Then the code provided in the solution by @fedoroff, will show the imaginary part of the FFT close to zero and thus an even better fit to the analytic solution will result after taking the real part.
PS: the fact that the FT of an even real function is real is exploited.