I am testing the validity of the FFT and IFFT functions in Matlab.
I can compare the outputs of these functions to a well-known mathematical fact: the Fourier transform of an even, real function (like a Gaussian centered at 0), is another even, real function (FFT[real, 0-centered Gaussian] = real, 0-centered Gaussian). This fact should hold both for FFT and IFFT.
First I make my grid:
nx = 256; % grid total pixel count
X = 500; % grid size (um)
dx = X/nx; % grid spacing (um)
x = linspace(-nx/2,nx/2-1,nx)*dx; % x grid (um)
df = 1/(nx*dx); % spectral grid spacing (1/um)
f = linspace(-nx/2,nx/2-1,nx)*df; % f grid (1/um)
And I make my Gaussian:
A = 1; % magnitude (arbitrary units)
x_fwhm = 7; % Full width at half maximum diameter (um)
x0 = x_fwhm/sqrt(2*log(2)); % 1/e^2 radius (um)
y = A*exp(-2*x.^2./(x0)^2); % Gaussian (arbitrary units)
And apply the Fourier transform, with FFT:
yFFT = fftshift(fft(fftshift(y)));
Alternatively, with IFFT:
yIFFT = fftshift(ifft(fftshift(y)));
The IFFT does a perfect job: yIFFT is a purely real Gaussian. However, FFT yields a complex number: a very small imaginary part exists. This is fine, since an error should be expected in the fourier transform algorithms, and it's negligible anyway. What confuses me is why there is no error at all in IFFT? Are the FFT and IFFT algorithms that much different?
*** Note: fftshift and ifftshift are equivalent here, since my array has an even number of elements.
Handling of real-valued time-domain signal is a fairly common occurrence. So much so that the ifft
function has built-in handling for the corresponding symmetry that arises in the frequency domain, as described under the "Algorithm" section of the documentation:
The
ifft
function tests whether the vectors inY
are conjugate symmetric. A vectorv
is conjugate symmetric when the ith element satisfiesv(i) = conj(v([1,end:-1:2]))
. If the vectors inY
are conjugate symmetric, then the inverse transform computation is faster and the output is real.
In other words, ifft
constructs the imaginary part of yIFFT
to be exactly 0 since it detects that your input has conjugate symmetry.
On the other hand, even time-domain signals are relatively less common and Mathworks didn't deem it necessary to perform a similar test in the fft
function. That said, you could still take advantage of the conjugate symmetry test by computing the FFT using the ifft
function through
% compute fft(x,[],dim) using ifft:
size(x,dim) * conj(ifft(conj(x),[],dim))