2

As an extension to this question that I asked. The Fourier transform of a real Gaussian is a real Gaussian. Now of course a DFT of a set of points that only resemble a Gaussian will not always be a perfect Gaussian, but it should certainly be close. In the code below I'm taking this [discrete] Fourier transform using GSL. Aside from the issue of the returned/transformed real components (outlined in linked question), I'm getting a weird result for the imaginary component (which should be identically zero). Granted, it's very small in magnitude, but its still weird. What is the cause for this asymmetric & funky output?

#include <gsl/gsl_fft_complex.h>
#include <gsl/gsl_errno.h>
#include <fstream>
#include <iostream>
#include <iomanip> 

#define REAL(z,i) ((z)[2*(i)]) //complex arrays stored as    [Re(z0),Im(z0),Re(z1),Im(z1),...]
#define IMAG(z,i) ((z)[2*(i)+1])
#define MODU(z,i) ((z)[2*(i)])*((z)[2*(i)])+((z)[2*(i)+1])*((z)[2*(i)+1])
#define PI 3.14159265359

using namespace std;

int main(){

    int n = pow(2,9);
    double data[2*n];
    double N = (double) n;

    ofstream file_out("out.txt");

    double xmin=-10.;
    double xmax=10.;
    double dx=(xmax-xmin)/N;
    double x=xmin;

    for (int i=0; i<n; ++i){
        REAL(data,i)=exp(-100.*x*x);
        IMAG(data,i)=0.;
        x+=dx;
    }

    gsl_fft_complex_radix2_forward(data, 1, n); 

    for (int i=0; i<n; ++i){
        file_out<<(i-n/2)<<"    "<<IMAG(data,((i+n/2)%n))<<'\n';
    }

    file_out.close();
}

enter image description here

Community
  • 1
  • 1
Arturo don Juan
  • 249
  • 2
  • 8

1 Answers1

2

Your result for the imaginary part is correct and expected.

The difference to zero (10^-15) is less than accuracy that you give to pi (12 digits, pi is used in the FFT, but I'm can't know whether you are overriding the pi inside the routine).

The FFT of a real function is not in general a real function. When you do the math analytically you integrate over the following expression:

f(t) e^{i w t} = f(t) cos wt  + i f(t) sin wt, 

so only if the function f(t) is real and even will the imaginary part (which is otherwise odd) vanish during integration. This has little meaning though, since the real part and imaginary part have physical meaning only in special cases.

Direct physical meaning is in the abs value (magnitude spectrum), the abs. value squared (intensity spectrum) and the phase or angle (phase spectrum).

A more significant offset from zero in the imaginary part would happen if it wasn't centered at the center of your time vector. Try shifting the x vector by some fraction of dx.

See below how the shift of the input by dx/2 (right column) affects the imaginary part, but not the magnitude (example written in Python, Numpy).

enter image description here

from __future__ import division
import numpy as np
import matplotlib.pyplot as p
%matplotlib inline

n=512    # number of samples 2**9
x0,x1=-10,10
dx=(x1-x0)/n

x= np.arange(-10,10,dx)  # even number, asymmetric range [-10, 10-dx]   

#make signal
s1= np.exp(-100*x**2) 
s2= np.exp(-100*(x+dx/2 )**2)

#make ffts
f1=np.fft.fftshift(np.fft.fft(s1))
f2=np.fft.fftshift(np.fft.fft(s2))

#plots
p.figure(figsize=(16,12))
p.subplot(421)
p.title('gaussian (just ctr shown)')
p.plot(s1[250:262])
p.subplot(422)
p.title('same, shifted by dx/2')
p.plot(s2[250:262])

p.subplot(423)
p.plot(np.imag(f1))
p.title('imaginary part of FFT')
p.subplot(424)
p.plot(np.imag(f2))

p.subplot(425)
p.plot(np.real(f1))
p.title('real part of FFT')
p.subplot(426)
p.plot(np.real(f2))

p.subplot(427)
p.plot(np.abs(f1))
p.title('abs. value of FFT')
p.subplot(428)
p.plot(np.abs(f2))
Paul R
  • 208,748
  • 37
  • 389
  • 560
roadrunner66
  • 7,772
  • 4
  • 32
  • 38