Fourier Transform, Applied (5): Fourier cheatsheet

A tour of Numpy’s Fourier transform functions

Peter Barrett Bryan
Towards Data Science

--

To close out the series, let’s review the Numpy Fourier transform functions you’ll see most frequently.

Check out the previous articles in the series!

Photo by Alfons Morales on Unsplash

A subtle distinction

So far in our discussion, I’ve used “the Fourier transform” and “the Fast Fourier Transform (FFT)” interchangeably. At this point, it is worth noting the distinction! The FFT is an efficient algorithmic implementation of the “discrete” Fourier transform (DFT). The “discrete” indicates that we can apply the transform to a series of points rather than a full, continuous signal. We typically have a set of samples rather than a continuous input function in data science applications, so we are usually interested in DFTs!

Fourier transform functions

np.fft.fft

The FFT takes as an input a real or complex signal in the temporal or spatial domain and returns the discrete Fourier transform. As we’ve discussed, np.abs allows us to recover the magnitude of frequency components and np.angle allows us to recover the phase.

We’ve seen this function before (see the earlier stories in this series)! We’ll come back to this note, but it is important enough to say it twice! The Fourier transform can be applied to complex input signals. For a complex input, the negative frequency terms returned by the Fourier transform are necessary to fully reconstruct the signal. For real inputs — like the inputs we’ve examined so far in this series — only require positive frequency terms. You can still use a full FFT on a real-value signal, just know that you can use an RFFT with fewer duplicate values (see more context below).

Index 0: The first values is sometimes called the “DC” term (coming from “direct current” in the field of electrical engineering) and serves as an offset term. It does not oscillate and corresponds to 0Hz (thus DC). It is simply the sum of the signal!

Index 1 to ((N/2) -1) if N is even, otherwise 1 to ((N-1)/2): The positive frequency components in increasingly positive order.

Index (N/2) to (N-1) if N is even, otherwise ((N+1)/2) to (N-1): The negative frequency components in decreasingly negative (i.e., increasingly positive) order.

Hint! If you ever get confused about what elements correspond to which frequencies, check out np.fft.fftfreq! It will tell you the order of the frequencies, e.g. np.fft.fftfreq(5) tells us the frequency bin centers 0., 0.2, 0.4, -0.4, and -0.2.

np.fft.ifft

The IFFT takes as an input a Fourier transform and returns the real or complex reconstructed signal in the temporal or spatial domain.

As we’ve discussed, the inverse FFT allows us to transform back from the frequency domain into the temporal/spatial domain. As expected, if we apply the IFFT to the FFT of a signal, we end up back where we started.

IFFT(FFT(x)) ≈ x, the inverse property holds!

np.fft.fftshift

FFT shift takes as an input a Fourier transform and reorders the values from the “standard” order to the “natural” order: most negative to zero to most positive.

It can be a lot easier to visualize and reason about the results of an FFT if the components are sorted into the natural order. The standard order can be pretty confusing!

FFTSHIFT arranges the frequency centers from most negative to most positive.

np.fft.ifftshift

FFT shift takes as an input a Fourier transform and reorders the values from the “natural” order to the “standard” order: DC term, then positive frequencies, and then negative frequencies.

IFFTSHIFT recovers the “standard” order.

np.fft.rfft

The RFFT takes as an input a real signal in the temporal or spatial domain and returns the discrete Fourier transform.

The FFT of a real signal has an interesting property mentioned earlier in the article: the positive and negative frequency components mirror each other. Formally, this means that the Fourier transform of a real signal is “Hermitian.” The mathematical reason for this is fascinating, and I hope to expand on it in a future article. For now, though, we only need to notice that it is true. The RFFT allows us to skip these redundant terms!

RFFT takes advantage of Hermitian symmetry to skip duplicated negative frequency components.

np.fft.irfft

The IRFFT takes as an input the Fourier transform of a real-valued function and returns the real reconstructed signal in the temporal or spatial domain.

IRFFT(RFFT(x)) ≈ x, the inverse property holds!

np.fft.fft2

The FFT2 takes as an input a real or complex 2D signal in the temporal or spatial domain and returns the discrete Fourier transform. As we’ve discussed, np.abs allows us to recover the magnitude of frequency components and np.angle allows us to recover the phase.

In a previous article, we demonstrated that we could use the same logic to decompose the magnitude and angle of frequency components in 2D signals (like images!). np.fft.fft2 allows us to do just this: compute the two-dimensional fast Fourier transform of an input.

np.fft.ifft2

The IFFT takes as an input a Fourier transform and returns the real or complex 2D reconstructed signal in the temporal or spatial domain.

As expected, we have an analogous inverse transform for two-dimensional inputs!

IFFT2(FFT2(x)) ≈ x, the 2D inverse property holds!

np.fft.fftn

We can extend the FFT to three-dimensional, four-dimensional, five-dimensional inputs! Indeed, for an n-dimensional input, there is an n-dimensional FFT…

np.fft.ifftn

… and correspondingly, an n-dimensional inverse transform.

IFFTN(FFTN(x)) ≈ x, the n-D inverse property holds!

Thanks for joining as we’ve worked through this series! I’d like to write some content on the implementation of the Fourier transform next; leave a comment below if you’re interested or if there are other concepts you’d like me to explain.

You might also be interested in some of my other articles about Fourier intuitions!

--

--

Software engineer with specializations in remote sensing, machine learning applied to computer vision, and project management.