From-scratch 1-D Discrete Fourier Transform (DFT) and iterative radix-2 FFT in Python — a small signal-analysis package with clean architecture, NumPy-validated spectra, and runtime benchmarks that make the
Implements the transform from first principles, exposes a focused analysis API, and verifies results on a controlled multi-tone signal.
Given a discrete time series numpy.fft.
Typical flow:
- Build or load a 1-D signal.
- Compute the spectrum with the matrix DFT or the Cooley–Tukey FFT.
- Inspect magnitude / phase / power spectra on a physical frequency axis.
- Cross-check against NumPy and confirm time–frequency energy consistency (Parseval).
The length-
In matrix form,
The inverse transform restores the time series:
For
(when the spectrum is centered). Parseval’s relation used in the tests is
Further detail lives in docs/use_case.md.
src/fourier_1d/
dft.py # DFT / IDFT (matrix) and radix-2 FFT / IFFT
spectrum.py # frequency axis, magnitude, phase, power
signals.py # synthetic multi-tone fixtures
io.py # two-column time-series load/save
examples/
run_demo.py # end-to-end plot + NumPy error report
run_benchmark.py # DFT vs FFT vs NumPy runtime comparison
tests/ # agreement with numpy.fft and Parseval checks
docs/ # use-case write-up with equations
.github/workflows/ # CI (pytest on Python 3.10–3.12)
Design choices:
- Separation of concerns — transform kernels, spectral helpers, and signal fixtures are independent modules.
-
Explicit algorithms — matrix DFT makes the linear map
$X = W x$ transparent; an iterative radix-2 FFT adds the practical$O(N\log N)$ path without recursion. -
Reference validation — every transform path is checked against
numpy.fftin automated tests (GitHub Actions CI on Python 3.10–3.12). - Reproducible demo signal — synthetic multi-tone fixtures keep every clone runnable without external data files.
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
python examples/run_demo.py
python examples/run_benchmark.pyMinimal API usage:
from fourier_1d import fft, magnitude_spectrum, sample_signal
t, y, fs = sample_signal()
freqs, mag = magnitude_spectrum(y, sample_rate=fs)
X = fft(y)On the bundled multi-tone demo (numpy.fft.fft to machine precision (max absolute error
Runtime on increasing power-of-two lengths shows the expected complexity gap between the matrix DFT and the iterative FFT (NumPy remains the highly optimized baseline):
- Python ≥ 3.10
- NumPy ≥ 1.24
- Optional: Matplotlib (demo), pytest (tests)

