FFTShift without Moving Elements
My previous post explains how to implement an inplace fftshift/ifftshift in C++. However, shifting still requires moving elements, which can be costly for large arrays. Fortunately, when fftshift/ifftshift are used together with the FFT/iFFT, there is a way to avoid any physical data movement.
Some Facts
Let $S = \lfloor N/2 \rfloor$ for an length-$N$ signal $x[n]$, fftshift is defined as:
and ifftshift is defined as:
An important property for $\bmod$: \(\begin{equation} \begin{split} e^{\pm i 2\pi \alpha \frac{(n \pm S) \bmod N}{N}} = e^{\pm i 2\pi \alpha \frac{n \pm S}{N}} \end{split} \end{equation}\)
In addition, the DFT’s time-shifting and frequency-shifting properties show that shifting in one domain is equivalent to applying a linear phase modulation in the other domain.
fftshift-fft-ifftshift
This combination of operations can be evaluated by first taking the inner fft(ifftshift(x)) part with the time-shifting property:
then the fftshift:
In other words, the combination fftshift(fft(ifftshift(x))) is equivalent to first applying the phase modulation $e^{i2\pi \frac{nS}{N}}$ to the original $x[n]$, then performing the standard fft, and finally appling the phase modulation $e^{i2\pi \frac{kS}{N}}$ to the output, along with a scalar factor $e^{-i2\pi \frac{S^2}{N}}$.
For higher-dimensional arrays, these operations can be performed independently along each dimension.
fftshift-ifft-ifftshift
This combination of operations can be evaluated by first taking the inner ifft(ifftshift(x)) part with the frequency-shifting property:
then the ifftshift:
In other words, the combination fftshift(ifft(ifftshift(x))) is equivalent to first applying the phase modulation $e^{-i2\pi \frac{kS}{N}}$ to the original $X[k]$, then performing the standard ifft, and finally appling the phase modulation $e^{-i2\pi \frac{nS}{N}}$ to the output, along with a scalar factor $e^{i2\pi \frac{S^2}{N}}$.
For higher-dimensional arrays, these operations can be performed independently along each dimension.