Exploring Fast Fourier Transform with Python

Fast Fourier

Data is the backbone of decision-making across various industries, from music to cryptography and signal processing. Big consultancy firms value data analysts highly for their ability to interpret complex datasets. A vital tool in their arsenal is the Fast Fourier Transform (FFT), which analyses frequencies to extract detailed insights across numerous applications. This article delves into FFT, explaining its concepts and demonstrating its implementation in Python.

Recommended: Laplace Distribution in Python [with Examples]

Recommended: Fourier Transform in Medical Imaging with Python Implementation

What is the Fast Fourier Transform?

Physicists and mathematicians get very excited when they hear about the Fast Fourier Transform ( FFT ). In this section, we will understand what it is.

Essentially, FFT is that it takes a signal that is generally a sine curve or a cosine curve or an addition of both and decomposes it into its individual components. This analyzes a signal with much more helpful and can be used to draw insights and understand the signal’s origin. Let us look at the formula of FFT.

Fast Fourier Transform
Fast Fourier Transform

At first glance, it appears as a very scary calculus formula, but with the Python programming language, it becomes a lot easier. In the next section, we will see FFT’s implementation in Python.

Python Implementation of FFT

Let us now look at the Python code for FFT in Python. In the code below, we are directly calling the function rather than going into the mathematical formulation and calculus of Fast Fourier Transform.

import numpy as np
import matplotlib.pyplot as plt

# Define a simple signal (sine wave)
t = np.linspace(0, 1, 1000)  # Time axis
f1 = 200  # Frequency of the sine wave
signal = np.sin(2*np.pi*f1*t)

# Perform FFT
fft_output = np.fft.fft(signal)

# Calculate absolute values for magnitude
magnitude = np.abs(fft_output)

# Only consider positive frequencies (half the spectrum for real signal)
positive_frequencies = magnitude[:len(magnitude) // 2]

# Calculate frequencies corresponding to positive half
f = np.fft.fftfreq(len(signal))[:len(positive_frequencies)]

# Plot the signal in time domain
plt.subplot(2, 1, 1)
plt.plot(t, signal)
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("Signal in Time Domain")

# Plot the magnitude spectrum
plt.subplot(2, 1, 2)
plt.plot(f, positive_frequencies)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Magnitude")
plt.title("Magnitude Spectrum (FFT Output)")

plt.tight_layout()
plt.show()

Here, we have imported the necessary modules and libraries, such as Numpy and Matplotlib. After that, we created a random signal or sine wave and plotted it against the time axis.

We then perform the Fast Fourier Transform and surgically decompose it into individual frequencies. Let us now look at the output of the code above. We only consider the positive frequencies, i.e., the wave above the x-axis.

Fast Fourier Transform Output
Fast Fourier Transform Output

We can observe that after performing FFT, the signal has been decomposed and plotted on the Magnitude and Frequency axes. It sort of looks like a very compressed normal distribution. This also means that the concept of resonance is at work, i.e., at a certain frequency, the magnitude reaches maximum and then phases out.

FFT Applications in Music

Let us now look at how the Fast Fourier Transform can be utilized in the world of music. Below, we have a Python code for the same. It is very similar to the code above, where we decompose a signal into its components.

import numpy as np
import matplotlib.pyplot as plt

# Define base frequency and sampling rate
f0 = 440  # Base frequency (e.g., A4 note)
fs = 44100  # Sampling rate (common audio sampling rate)

# Simulate note duration
duration = 1  # Note duration in seconds
t = np.linspace(0, duration, int(fs*duration))  # Time axis

# Randomize amplitude for a more realistic sound
amplitude = np.random.rand(len(t)) * 0.8  # Random values between 0 and 0.8

# Create a decaying envelope to simulate note fading
envelope = np.exp(-2*t/duration)  # Exponential decay

# Combine frequency, amplitude, and envelope
note = f0 * np.sin(2*np.pi*f0*t) * amplitude * envelope

# Perform FFT
fft_output = np.fft.fft(note)

# Calculate absolute values for magnitude
magnitude = np.abs(fft_output)

# Only consider positive frequencies (half the spectrum for real signal)
positive_frequencies = magnitude[:len(magnitude) // 2]

# Calculate frequencies corresponding to positive half
f = np.fft.fftfreq(len(note))[:len(positive_frequencies)] * fs

# Plot the signal in time domain
plt.subplot(2, 1, 1)
plt.plot(t, note)
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("Simulated Musical Note (Time Domain)")

# Plot the magnitude spectrum (FFT Output)
plt.subplot(2, 1, 2)
plt.plot(f, positive_frequencies)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Magnitude")
plt.title("Magnitude Spectrum (FFT Output)")
plt.xlim(0, fs/2)  # Limit x-axis to show relevant frequencies

plt.tight_layout()
plt.show()

We have random data on a musical note and have decomposed it further into different positive frequencies. For example, we listen to music and want to know sounds from various instruments; the above code is an example of how to do the same. Let us look at the output.

FFT In Music
FFT In Music

Conclusion

Fast Fourier Transform (FFT) is not just a mathematical tool but a bridge connecting theory and real-world applications across diverse fields, from signal processing to music analysis. Through Python, we can tap into FFT’s potential to simplify and clarify complex signal behaviors, transforming raw data into actionable insights. How might future developments in FFT impact our approach to data across different industries?

Recommended: How To Configure Logging In Python?

Recommended: Step-by-Step Guide to Checking Out a Commit ID with GitPython