Fitting a filter response with optimise
Fitting a Sallen-Key low pass to a Butterworth response.
The optimise command varies both capacitors of a unity-gain Sallen-Key low pass so that its magnitude response matches an ideal 1kHz second-order Butterworth response across the whole sweep. The expected values are C1 = 22.5nF and C2 = 11.25nF.
- db(v(out))
Output
Optimising 2 parameters, targeting (1/sqrt(1+(frequency/1k)^4)) = mag(v(out)) 1: mse = 0.0046153 c1=1e-08 c2=1e-08 2: mse = 0.00223941 c1=1.5849e-08 c2=1e-08 6: mse = 0.00162405 c1=1.7783e-08 c2=1.2589e-08 8: mse = 0.00148056 c1=2.5119e-08 c2=1e-08 11: mse = 0.000351736 c1=2.4406e-08 c2=1.1885e-08 13: mse = 0.000198428 c1=2.0983e-08 c2=1.1715e-08 15: mse = 0.000155502 c1=2.3842e-08 c2=1.0863e-08 17: mse = 7.81756e-05 c1=2.1412e-08 c2=1.099e-08 19: mse = 1.44593e-05 c1=2.1774e-08 c2=1.1314e-08 22: mse = 1.11318e-05 c1=2.3073e-08 c2=1.133e-08 25: mse = 6.16131e-06 c1=2.2551e-08 c2=1.1163e-08 27: mse = 1.56679e-06 c1=2.2286e-08 c2=1.128e-08 29: mse = 1.54395e-06 c1=2.2743e-08 c2=1.1275e-08 31: mse = 8.53334e-07 c1=2.2532e-08 c2=1.122e-08 33: mse = 1.18149e-07 c1=2.2461e-08 c2=1.1264e-08 39: mse = 5.89111e-08 c1=2.2559e-08 c2=1.1255e-08 41: mse = 1.59336e-08 c1=2.2523e-08 c2=1.125e-08 43: mse = 1.45814e-08 c1=2.2501e-08 c2=1.1258e-08 45: mse = 8.13916e-09 c1=2.2489e-08 c2=1.1254e-08 47: mse = 6.74787e-10 c1=2.2509e-08 c2=1.1253e-08 100: mse = 6.50059e-10 c1=2.2503e-08 c2=1.1254e-08 Converged after 100 simulations Best mean square error = 6.50059e-10 (rms 2.54963e-05) Parameter initial final min max c1 capacitance 1e-08 2.2503e-08 1e-09 1e-07 c2 capacitance 1e-08 1.1254e-08 1e-09 1e-07 Final results are in plot ac1
The circuit: examples/optimise_demo.cir
optimise_demo.cir - fit a Sallen-Key low pass to a 1kHz Butterworth response * Unity gain Sallen-Key low pass, with an ideal buffer vin in 0 dc 0 ac 1 r1 in a 10k r2 a b 10k c1 a out 10n c2 b 0 10n eamp out 0 b 0 1 .control * Fit c1 and c2 so |v(out)| matches the ideal 2nd order Butterworth * magnitude 1/sqrt(1+(f/1k)^4) across the whole sweep. The target is * evaluated on each run's results, so it can use the frequency scale. * Expect c1 = 22.5n, c2 = 11.25n. optimise analysis ac dec 10 100 10k vary c1 1n 100n vary c2 1n 100n target (1/sqrt(1+(frequency/1k)^4)) mag(v(out)) * The final run is left as the current plot let ideal = 1/sqrt(1+(frequency/1k)^4) plot db(v(out)) db(ideal) title "Sallen-Key fitted to Butterworth" .endc .end
Run it with spice optimise_demo.cir, or open it with File › Load netlist in the Qt window. The plots and output above were made by util/mkexamples.py, which runs the deck in batch mode. All examples