Fourier Transforms

Back

Loading concept...

NumPy Fourier Transforms: The Secret Recipe Finder 🔍

The Big Picture: What’s Hidden Inside?

Imagine you’re at a party. Music is playing. You hear drums, guitar, and singing all mixed together. Your ears are amazing—they can pick out each instrument from that jumble of sound!

Fourier Transform is exactly this superpower, but for computers.

It takes a messy, mixed-up signal and reveals all the hidden ingredients inside it.


Our Everyday Analogy: The Smoothie Detective 🥤

Think of any signal (sound, image, data) as a smoothie.

  • Time Domain = The blended smoothie (everything mixed together)
  • Frequency Domain = The recipe card (lists each ingredient separately)

The Fourier Transform is your detective tool that takes a smoothie and figures out: “Ah! This has 2 bananas, 3 strawberries, and 1 cup of milk!”


1. Fourier Transforms Basics

What Does It Actually Do?

A signal in “time” shows you what happens when.

A signal in “frequency” shows you what ingredients are inside.

import numpy as np

# Create a simple signal
# Mix of two "ingredients":
# slow wave (5 Hz) + fast wave (20 Hz)
t = np.linspace(0, 1, 1000)
signal = np.sin(2*np.pi*5*t) + np.sin(2*np.pi*20*t)

# Use Fourier Transform
fft_result = np.fft.fft(signal)

The Magic Behind It

graph TD A["Mixed Signal<br>Time Domain"] --> B["np.fft.fft"] B --> C["Recipe Revealed<br>Frequency Domain"] C --> D["See each<br>frequency ingredient"]

Understanding the Output

The FFT gives you complex numbers. Don’t panic!

  • Magnitude = How loud/strong each ingredient is
  • Phase = When each ingredient starts
# Get the "loudness" of each frequency
magnitudes = np.abs(fft_result)

# Get the "starting point" of each
phases = np.angle(fft_result)

Real Example: Finding Hidden Waves

import numpy as np

# Sample rate: 1000 samples per second
fs = 1000
t = np.arange(0, 1, 1/fs)

# Secret recipe: 10 Hz + 50 Hz waves
signal = 3*np.sin(2*np.pi*10*t) + \
         1*np.sin(2*np.pi*50*t)

# Detect the ingredients!
fft_result = np.fft.fft(signal)
freqs = np.fft.fftfreq(len(signal), 1/fs)

# Look at positive frequencies only
pos_mask = freqs >= 0
magnitudes = np.abs(fft_result[pos_mask])

Result: You’ll see two spikes—one at 10 Hz (tall) and one at 50 Hz (shorter). The Fourier Transform found both ingredients!


2. Inverse Fourier Transform

Going Backwards: Recipe to Smoothie

What if you have the recipe and want to make the smoothie?

Inverse FFT does exactly that. It takes frequency ingredients and blends them back into a time signal.

# Start with our signal
original = np.sin(2*np.pi*5*t)

# Break it down (forward FFT)
broken_down = np.fft.fft(original)

# Put it back together (inverse FFT)
rebuilt = np.fft.ifft(broken_down)

The Round Trip

graph TD A["Original Signal"] -->|np.fft.fft| B["Frequency Data"] B -->|np.fft.ifft| C["Rebuilt Signal"] C -->|Same as| A

Why Is This Useful?

Filtering! You can:

  1. Break signal into ingredients (FFT)
  2. Remove unwanted ingredients
  3. Rebuild the clean signal (IFFT)
# Remove high frequencies (noise filter)
fft_data = np.fft.fft(noisy_signal)

# Kill frequencies above 100 Hz
freqs = np.fft.fftfreq(len(noisy_signal), 1/fs)
fft_data[np.abs(freqs) > 100] = 0

# Rebuild clean signal
clean_signal = np.fft.ifft(fft_data)
clean_signal = np.real(clean_signal)

Important: Real vs Complex

np.fft.ifft() returns complex numbers. If your original signal was real, use:

# Method 1: Take real part
result = np.real(np.fft.ifft(data))

# Method 2: Use irfft for real signals
result = np.fft.irfft(data)

3. FFT Frequencies and Shifting

The Frequency Axis Problem

When you do FFT, what frequencies do you actually get?

NumPy gives you frequencies in a weird order:

  • First half: 0 Hz, positive frequencies
  • Second half: negative frequencies
# 8 samples, 1 second total
n = 8
fs = 8  # 8 samples per second

freqs = np.fft.fftfreq(n, 1/fs)
# Output: [0, 1, 2, 3, -4, -3, -2, -1]

Understanding fftfreq()

np.fft.fftfreq(n, d)
  • n = number of samples
  • d = time between samples (1/sample_rate)
# Example: 1000 samples, 500 Hz sample rate
n = 1000
sample_rate = 500
freqs = np.fft.fftfreq(n, 1/sample_rate)

# Max frequency = sample_rate / 2 = 250 Hz
# (This is the Nyquist frequency)

The Shifting Solution: fftshift()

For plotting, we want frequencies in order: negative → 0 → positive

# Before shift: [0, 1, 2, 3, -4, -3, -2, -1]
freqs = np.fft.fftfreq(8, 1/8)

# After shift: [-4, -3, -2, -1, 0, 1, 2, 3]
shifted_freqs = np.fft.fftshift(freqs)

Shift the Data Too!

When you shift frequencies, shift your FFT data to match:

# Get FFT
fft_data = np.fft.fft(signal)
freqs = np.fft.fftfreq(len(signal), 1/fs)

# Shift both for plotting
shifted_freqs = np.fft.fftshift(freqs)
shifted_data = np.fft.fftshift(fft_data)

# Now they match!

Going Back: ifftshift()

If you modified shifted data, unshift before inverse FFT:

# Shifted domain work
shifted_fft = np.fft.fftshift(np.fft.fft(signal))

# ... do some processing ...

# Unshift before inverse
unshifted = np.fft.ifftshift(shifted_fft)
result = np.fft.ifft(unshifted)
graph TD A["Signal"] -->|fft| B["FFT Output<br>Weird Order"] B -->|fftshift| C["Centered<br>Nice for Plotting"] C -->|ifftshift| B B -->|ifft| A

Complete Example: Analyze a Signal

import numpy as np

# Create signal
fs = 1000
t = np.arange(0, 1, 1/fs)
signal = np.sin(2*np.pi*50*t) + \
         0.5*np.sin(2*np.pi*120*t)

# FFT
fft_result = np.fft.fft(signal)
freqs = np.fft.fftfreq(len(signal), 1/fs)

# Shift for nice plotting
freqs_centered = np.fft.fftshift(freqs)
fft_centered = np.fft.fftshift(fft_result)

# Get magnitudes
mags = np.abs(fft_centered)

Quick Reference

Function What It Does
np.fft.fft() Signal → Frequencies
np.fft.ifft() Frequencies → Signal
np.fft.fftfreq() Get frequency labels
np.fft.fftshift() Center the frequencies
np.fft.ifftshift() Uncenter (undo shift)

The Confidence Boost

You now understand:

✅ FFT breaks signals into frequency ingredients ✅ IFFT rebuilds signals from ingredients ✅ fftfreq tells you which frequencies you’re looking at ✅ fftshift organizes frequencies nicely for viewing

This is the foundation of audio processing, image compression, signal filtering, and so much more. You’ve unlocked a powerful tool!


One Last Analogy

Think of it like a music equalizer:

  1. FFT = Show me all the frequency bands
  2. Adjust = Boost bass, cut treble
  3. IFFT = Play the modified sound

You’re now the DJ of data! 🎧

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.