I'm trying to apply a Fourier transform of a one dimensional list of a time history of some quantity using the Fourier
function. I'm interested in the frequency spectrum, but the problem is that the Fourier
function uses the fast Fourier transform algorithm which places the zero frequency at the beginning, complicating my analysis of the results.
So how can I shift the zero frequency to the center?
I tried to search for the solution and found two methods, which seem to give contradicting answers.
Method 1 (from course notes available here). It simply rotates the list before and after the Fourier transform:
DFT1[ls_?(EvenQ@Length[#] &), dt_] := Module[{N0, fft},
N0 = Length[ls];
fft = RotateRight[
dt*Fourier[RotateLeft[ls, N0/2 - 1], FourierParameters -> {1, 1}],
N0/2 - 1];
fft
]
Method 2 (from some code of my professor). It rotates the list only after the transform, and adds a phase shift:
DFT2[ls_?(EvenQ@Length[#] &), dt_] := Module[{N0, dw, wls, fft},
N0 = Length[ls];
dw = (2 π)/(N0 dt);
wls = dw Range[-(N0/2), N0/2 - 1];
fft = dt*
Reverse[RotateRight[Fourier[ls, FourierParameters -> {1, -1}],
N0/2 - 1]]*Exp[(I π)/dw wls];
fft
]
If we use these two methods on an example, we get different answers:
dt = 0.05;
els = Table[Sin[ t] Sin[t/40]^2, {t, 0., 40 π, dt}];
ListPlot[els, Joined -> True]
Row[ListPlot[{#[DFT1[els, dt]], #[DFT2[els, dt]]}, Joined -> True,
PlotRange -> {{1200, 1300}, All}, ImageSize -> 300] & /@ {Abs, Re,
Im}]
Questions:
- Which of the methods is correct (if neither is correct then what is the right way)?
- What are the frequencies corresponding to the Fourier transform results? For example, should the frequencies range from $\{-\frac{N0\Delta \omega}{2},\frac{(N0-1)\Delta \omega}{2}\}$ or $\{-\frac{(N0-1)\Delta \omega}{2},\frac{N0\Delta \omega}{2}\}$? $N0$ is the length of the data, $\Delta t$ is the time interval of the data, $\Delta \omega=\frac{2\pi }{N0 \Delta t}$.
- What difference does it make if N0 is even or odd?
Update:
This is the result using the method in Bill's answer here to a similar question. The results appear to differ from both of the approaches mentioned above.
n = Length[els];
sampInt = dt;
data = els;
ssf = RotateRight[Range[-n/2, n/2 - 1]/(n sampInt), n/2];
fft = dt Fourier[data, FourierParameters -> {1, 1}];
Row[ListPlot[#@
Sort[Transpose[{ssf, fft}], #1[[1]] < #2[[1]] &][[All, 2]],
PlotRange -> {{1200, 1300}, All}, Joined -> True,
ImageSize -> 300] & /@ {Abs, Re, Im}]
0
in the vectorssf
which shows the frequencies for all the terms. $\endgroup$