Companion notebook to the PSO for filter design topic. We watch a swarm escape a local minimum that traps gradient descent, design a biquad with PSO, and look honestly at run-to-run variability. Everything imports from the clean module pso.py.
Show the code
import numpy as npimport matplotlib.pyplot as pltfrom scipy import signalfrom pso import pso, gradient_descent, design_iir_pso, iir_is_stabledef rastrigin(x): x = np.asarray(x)return10*len(x) + np.sum(x**2-10* np.cos(2* np.pi * x))
1. Swarm vs gradient on a rugged surface
The Rastrigin function has one global minimum at the origin buried in a lattice of local minima. Gradient descent from a poor start stalls; the swarm does not.
A particle is a coefficient vector; the fitness is magnitude-response error against a target, with a stability wall. Here we match a Butterworth bandpass.
Most runs reach the global basin, but not all, which is exactly why PSO carries no convergence guarantee. See the embedded page for running the swarm on a microcontroller for online adaptation.