Approximating continuous FT with DFT
See the page Conventions for details on the notations used, the Fourier conventions, and other definitions used here.
The objective
Given a function \(f(x)\) that is negligible outside the interval \((-L_x/2, L_x/2)\), we want to compute a numerical approximation to its exact continuous Fourier transform (CFT).
The DFT is not an approximation to the CFT and does not allow independent sampling grids
The discrete Fourier transform (DFT) and (mathematically) equivalently the fast Fourier transform (FFT) are not approximations to the CFT. This is an important, albeit possibly pedantic point. Indeed, a suitably scaled and shifted DFT can be used to evaluate a finite-sum approximation to the CFT. However, the input and output sampling grids are intrinsically coupled and cannot be chosen independently. Overcoming this limitation is the motivation for the alternative approach used in this package.
Approximating the CFT with the DFT
In the following we derive an approximation to the CFT that uses a single suitably scaled and shifted DFT. In doing so, we will explicitly see how the spacing of the output samples is fixed by the spacing of the input samples.
A CFT involves an infinite continuous integral. We assume the function \(f(x)\) is negligible outside the interval \((-L_x/2, L_x/2)\). Therefore the first approximation amounts to the truncation
Our second approximation is to use a Riemann sum (rectangle method) to replace the integral
where the centred grid \(\v{x}\) is defined by its components \(\v{x}[n] = (n - c)\delta_x\), with the central index \(c = \lfloor N/2 \rfloor\) and the spacing \(\delta_x = L_x / N\). To proceed with approximating the CFT we also need to define the output grid \(\v{k}\) by its components \(\v{k}[n] = (n - c) \delta_k\). Putting everything together we can approximate the CFT as
where \(\v{f} = f(\v{x})\) (or equivalently \(\v{f}[n]=f(\v{x}[n])\)). Note that we call the vector of samples of the exact CFT as \(\v{F}\), and the vector of samples of the approximation as \(\tilde{\v{F}}\). The next step is where the intrinsic link between the input and output grids becomes apparent in the DFT approach. By fixing the output spacing \(\delta_k\) to be the reciprocal of the input sample length \(\delta_k \equiv 1 / L_x\) (or equivalently \(\delta_k = 1 / (N \delta_x)\)) then we have
To make the notation less cluttered let us introduce \(\phi(x) = \exp(i 2 \pi x / N)\). Substituting this into equation \eqref{eqn:truncation_and_riemann} gives us
Using the definition of the DFT
we have
where \(\v{g}[n] = \v{f}[n]\phi(cn)\). Next, we use the cyclic shift property of the DFT
where \(S_n(\v{x})[m] = \v{x}[m-n]\) is the cyclic shift operator where all indices are interpreted modulo \(N\). Indeed in this documentation, all indices in square brackets should always be interpreted as modulo the vector length \(N\). Applying the shift property to equation \eqref{eqn:after_DFT_def} gives us
Applying the shift property to \(\v{g}\) gives \(S_{-c}(\v{g})[n] = \phi(c^2)\phi(nc)S_{-c}(\v{f})[n]\), which substituted into equation \eqref{eqn:after_shift} gives
where \((x(n))_n\) indicates a vector with components index by \(n\). Applying the alternative (but equivalent) cyclic shift property
to equation \eqref{eqn:shifted_f} gives
Many programming languages define an operator (and its inverse) that shifts the zero-frequency component of a DFT to the centre of the vector. They are defined as
where (just like before) \(c=\lfloor N/2 \rfloor\) is the central index of the vector \(\v{a}\) with length \(N\). Using these common definitions we can rewrite equation \eqref{eqn:result_S_form} as
Final result