10. NB. Fourier wavenumbers

Philipp Schlatter
pschlatt@mech.kth.se
SimEx/FLOW, KTH Engineering Mechanics, Royal Institute of Technology, Stockholm, Sweden

This notebook is a part of the KTH-Nek5000 lecture notes.

In this notebook, we discuss the typical representation of the wavenumbers for one-dimensional real-to-complex Fourier transforms, assuming even-numbered transforms (i.e. the number of grid points in physical space \(N\) is even) in a domain with length \(2\pi/\alpha\).

import numpy as np
from math import pi

10.1. Physical space

We generate a random signal \(u(x_i)=u_i\) and the indices \(i\) as an easy example with \(N=6\):

N=6
u=np.random.rand(N)
i=range(1,N+1)
print(u)
[0.4077557  0.59917605 0.19378549 0.60898424 0.68924684 0.2003087 ]

10.2. Spectral space

uhat=np.fft.fft(u)
k=np.concatenate(( range(0,int(N/2)),range(-int(N/2),0) ))

The Fourier transform is now defined as \(u(x) = \sum_k \hat{u}_k e^{\mathrm{i} \alpha k x}\). The complex Fourier coefficients \(\hat{u}(k)=\hat{u}_k\) have the following wavenumbers \(k\)

print(uhat)
[ 2.69925702+0.00000000e+00j -0.24300233+8.36528630e-02j
  0.17548139-7.74511374e-01j -0.11768097-6.93889390e-18j
  0.17548139+7.74511374e-01j -0.24300233-8.36528630e-02j]
print(k)
[ 0  1  2 -3 -2 -1]

The function fftshift moves the zero mode to the middle

print(np.fft.fftshift(uhat))
[-0.11768097-6.93889390e-18j  0.17548139+7.74511374e-01j
 -0.24300233-8.36528630e-02j  2.69925702+0.00000000e+00j
 -0.24300233+8.36528630e-02j  0.17548139-7.74511374e-01j]
print(np.fft.fftshift(k))
[-3 -2 -1  0  1  2]

10.3. Discussion

Since we start with a real signal \(u(x_i)=u_i\), the data in Fourier space \(\hat{u}(k)=\hat{u}_k\) needs to fulfil \(\hat{u}_k = \hat{u}_{-k}^*\) with the complex conjugate \((\cdot)^*\). For the highest wavenumber \(k=-3\), it turns out that \(e^{\mathrm{i}kx}=\cos(kx)+\mathrm{i}\sin(kx)=\cos(kx)\) because \(\sin(kx)=0\) on all grid points. Thus the condition for \(k=-3\) is only that \(\hat{u}_{-3}\) is real, and the imaginary part needs to be zero. Otherwise an inverse transform would not be real. For a derivative \(i k \hat{u}_k\) of \(a\) to be real, also the real part of \(k=-3\) needs to be zero, \(i.e.\) the whole mode \(k=-3\) needs to be set to zero (oddball mode).

With normal FFT convection, this means (for \(N=6\), i.e. 6 real numbers in physical space):

Physical space: [N N N N N N] \(\rightarrow\) 6 real degrees of freedom

Fourier space: [N 0 N N N N N 0 C C C C] \(\rightarrow\) 6 real degrees of freedom

Here, N indicates a real number, and C a complex conjugate. However, as disussed the oddball mode needs to be set to zero, i.e.

Fourier space without oddball mode: [N 0 N N N N 0 0 C C C C] \(\rightarrow\) 5 real degrees of freedom.

That essentially means that a signal that is represented in physical space with \(N=6\) real numbers will be represented with only 5 numbers in spectral space, with wavenumbers \(k=-2, -1, 0, 1, 2\), i.e. ranging from \(-K\) to \(K\) with \(K=N/2-1\).

A discussion of 2D transforms is given in e.g. the Simson user’s manual.