Fourier Transform
Transform signals between time and frequency domains.
Overview
The Fourier Transform decomposes a signal into its constituent frequencies, revealing the frequency content of time-domain signals.
Continuous Fourier Transform (CFT)
Forward Transform
$$ X(f) = \int_{-\infty}^{\infty} x(t) e^{-j2\pi ft} dt $$
Inverse Transform
$$ x(t) = \int_{-\infty}^{\infty} X(f) e^{j2\pi ft} df $$
Discrete Fourier Transform (DFT)
For finite-length discrete signals.
Forward DFT
$$ X[k] = \sum_{n=0}^{N-1} x[n] e^{-j\frac{2\pi}{N}kn}, \quad k = 0, 1, \ldots, N-1 $$
Inverse DFT
$$ x[n] = \frac{1}{N} \sum_{k=0}^{N-1} X[k] e^{j\frac{2\pi}{N}kn}, \quad n = 0, 1, \ldots, N-1 $$
Frequency Bins
$$ f[k] = \frac{k \cdot f_s}{N}, \quad k = 0, 1, \ldots, N-1 $$
Where:
- $f_s$ = sampling frequency
- $N$ = number of samples
- Frequency resolution: $\Delta f = \frac{f_s}{N}$
Fast Fourier Transform (FFT)
Efficient algorithm for computing DFT. Complexity: $O(N \log N)$ vs $O(N^2)$ for naive DFT.
Requirement: $N$ should be a power of 2 for best performance.
Practical Implementation
Python (NumPy)
1import numpy as np
2import matplotlib.pyplot as plt
3
4def analyze_spectrum(signal, sample_rate):
5 """
6 Compute and plot frequency spectrum
7 """
8 N = len(signal)
9
10 # Compute FFT
11 fft_result = np.fft.fft(signal)
12
13 # Compute magnitude spectrum
14 magnitude = np.abs(fft_result)
15
16 # Compute frequency bins
17 freqs = np.fft.fftfreq(N, 1/sample_rate)
18
19 # Only plot positive frequencies
20 positive_freqs = freqs[:N//2]
21 positive_magnitude = magnitude[:N//2]
22
23 return positive_freqs, positive_magnitude
24
25# Example usage
26fs = 1000 # 1 kHz sampling rate
27duration = 1.0
28t = np.arange(0, duration, 1/fs)
29
30# Create signal: 50 Hz + 120 Hz
31signal = np.sin(2*np.pi*50*t) + 0.5*np.sin(2*np.pi*120*t)
32
33# Analyze
34freqs, magnitude = analyze_spectrum(signal, fs)
35
36# Plot
37plt.plot(freqs, magnitude)
38plt.xlabel('Frequency (Hz)')
39plt.ylabel('Magnitude')
40plt.title('Frequency Spectrum')
41plt.grid(True)
42plt.show()
Python (Real FFT for Real Signals)
1def real_fft_analysis(signal, sample_rate):
2 """
3 More efficient FFT for real-valued signals
4 """
5 N = len(signal)
6
7 # Use rfft for real signals (more efficient)
8 fft_result = np.fft.rfft(signal)
9 magnitude = np.abs(fft_result)
10 phase = np.angle(fft_result)
11
12 # Frequency bins for rfft
13 freqs = np.fft.rfftfreq(N, 1/sample_rate)
14
15 # Power spectral density
16 psd = (magnitude ** 2) / N
17
18 return freqs, magnitude, phase, psd
Go
1package signals
2
3import (
4 "math"
5 "math/cmplx"
6)
7
8// FFT computes Fast Fourier Transform (Cooley-Tukey radix-2)
9func FFT(x []complex128) []complex128 {
10 N := len(x)
11
12 // Base case
13 if N <= 1 {
14 return x
15 }
16
17 // Divide
18 even := make([]complex128, N/2)
19 odd := make([]complex128, N/2)
20 for i := 0; i < N/2; i++ {
21 even[i] = x[2*i]
22 odd[i] = x[2*i+1]
23 }
24
25 // Conquer
26 evenFFT := FFT(even)
27 oddFFT := FFT(odd)
28
29 // Combine
30 result := make([]complex128, N)
31 for k := 0; k < N/2; k++ {
32 t := cmplx.Exp(complex(0, -2*math.Pi*float64(k)/float64(N))) * oddFFT[k]
33 result[k] = evenFFT[k] + t
34 result[k+N/2] = evenFFT[k] - t
35 }
36
37 return result
38}
39
40// Magnitude computes magnitude spectrum
41func Magnitude(fft []complex128) []float64 {
42 mag := make([]float64, len(fft))
43 for i, v := range fft {
44 mag[i] = cmplx.Abs(v)
45 }
46 return mag
47}
Important Properties
Linearity
$$ \mathcal{F}{ax_1(t) + bx_2(t)} = aX_1(f) + bX_2(f) $$
Time Shift
$$ \mathcal{F}{x(t - t_0)} = X(f) e^{-j2\pi f t_0} $$
Frequency Shift
$$ \mathcal{F}{x(t) e^{j2\pi f_0 t}} = X(f - f_0) $$
Convolution Theorem
$$ \mathcal{F}{x(t) * h(t)} = X(f) \cdot H(f) $$
This is why filtering in frequency domain is often faster!
Parseval's Theorem
Energy is conserved:
$$ \int_{-\infty}^{\infty} |x(t)|^2 dt = \int_{-\infty}^{\infty} |X(f)|^2 df $$
Common Applications
1. Frequency Analysis
1# Find dominant frequency
2freqs, magnitude = analyze_spectrum(signal, fs)
3dominant_freq = freqs[np.argmax(magnitude)]
4print(f"Dominant frequency: {dominant_freq} Hz")
2. Filtering in Frequency Domain
1def lowpass_filter_fft(signal, cutoff_freq, sample_rate):
2 """Low-pass filter using FFT"""
3 N = len(signal)
4 fft_signal = np.fft.fft(signal)
5 freqs = np.fft.fftfreq(N, 1/sample_rate)
6
7 # Zero out frequencies above cutoff
8 fft_signal[np.abs(freqs) > cutoff_freq] = 0
9
10 # Inverse FFT
11 filtered = np.fft.ifft(fft_signal)
12 return np.real(filtered)
3. Spectral Leakage Reduction
1# Apply window before FFT
2window = np.hanning(len(signal))
3windowed_signal = signal * window
4fft_result = np.fft.fft(windowed_signal)
Practical Tips
Zero-padding: Increase frequency resolution
1N_padded = 2**int(np.ceil(np.log2(len(signal)))) * 2 2signal_padded = np.pad(signal, (0, N_padded - len(signal)))DC component: $X[0]$ is the average value
1dc_component = fft_result[0] / NNyquist frequency: Maximum usable frequency is $f_s/2$
Symmetric spectrum: For real signals, negative frequencies are conjugate symmetric
Frequency Resolution vs Time Resolution
Trade-off governed by uncertainty principle:
$$ \Delta t \cdot \Delta f \geq \frac{1}{4\pi} $$
- Long signals: Better frequency resolution, poor time localization
- Short signals: Better time localization, poor frequency resolution
- Solution: Short-Time Fourier Transform (STFT) or Wavelets
Common Pitfalls
- Forgetting to normalize: DFT magnitude scales with $N$
- Ignoring spectral leakage: Use windows for non-periodic signals
- Aliasing: Ensure $f_s > 2f_{max}$
- DC offset: Remove before FFT if not needed
- Not using power-of-2 length: FFT is fastest for $N = 2^k$
Further Reading
- FFT - Wikipedia
- NumPy FFT Documentation
- FFTW Library - Fastest FFT in the West
- Understanding the FFT Algorithm
Related Snippets
- Convolution
Linear systems and filtering operations - Correlation
Signal similarity and pattern matching - Laplace Transform
S-domain analysis and transfer functions - Sampling Theory
Nyquist theorem, reconstruction, and interpolation - Signal Theory Basics
Fundamental concepts in signal processing - Window Functions
Spectral leakage reduction for FFT analysis