music, guitars & other obsessions

Circuit Optimization

While reading Dmitry Nizh’s great site, I found an article on parameter optimization using SPICE. In Dmitry’s case, he used an AWK script to pipe the output of the distortion analysis from SPICE to a plotting program, so the harmonics vs. power curves could be displayed and further analysed. To see what else can be done with SPICE, I googled “SPICE circuit optimization” and saw a bunch of papers published by Burmen and Tuma of University of Slovenia, which let me to discover their version of the Berkeley/XSPICE port for Windows – SpiceOpus, that contains a built-in optimize function. After going over some of the examples shown on the SpiceOpus website, I managed to try out the optimize function on a simple SPUD amp, the same one that Dmitry used in his SPICE optimization example. Here are  few lines of code that I used for the optimization for both the preamp plate load and power amp load:

SpiceOpus (c) 45 -> define error(f) db(v(3)/230) - db(v(8))
SpiceOpus (c) 46 -> optimize parameter 0 @r6[resistance] low 10k high 50k initial 40k
SpiceOpus (c) 47 -> optimize parameter 1 @r7[resistance] low 2k high 10k initial 5k
SpiceOpus (c) 48 -> optimize analysis 0 ac dec 10 100 10k
SpiceOpus (c) 49 -> optimize implicit 0 ac1.v(3) gt 230
SpiceOpus (c) 50 -> optimize cost mean(mag(error(frequency))^2)
SpiceOpus (c) 51 -> optimize method complex
SpiceOpus (c) 52 -> optimize
Complex: stopped, simplex small enough.
Time needed for optimisation: 0.062 seconds
Number of iterations: 42
Lowest cost function value: 4.926709e-002
Optimal values:
@r6[resistance] = 4.006276e+004
@r7[resistance] = 4.519619e+003

The results were very close to what Dmitry came up with, so I guess it worked. Since I am just using the ac sweep response as a proxy for distortion, I think perhaps the result could be further improved if I can figure out how to provide a more precise cost function to the optimization routine.

Since SpiceOpus has a discrete Fourier transform function, it is possible to calculate the total harmonic distortion without having to export the data to another program for processing. The THD can be calculated as follows:
Then the optimization codes can be written as follows:

SpiceOpus (c) 1 -> source 6f5p_opt.cir
SpiceOpus (c) 2 -> save v(10)
SpiceOpus (c) 3 -> optimize parameter 0 @r6[resistance] low 10k high 50k initial 40k
SpiceOpus (c) 4 -> optimize parameter 1 @r7[resistance] low 4 high 16 initial 8
SpiceOpus (c) 5 -> optimize analysis 0 tran 1u 1m
SpiceOpus (c) 6 -> optimize analysis 1 linearize 1u
SpiceOpus (c) 7 -> optimize analysis 2 spec 0 5k 1k v(10)
SpiceOpus (c) 8 -> optimize cost ((abs(v(10)[2])^2+abs(v(10)[3])^2+abs(v(10)[4])^2+abs(v(10)[5])^2)/abs(v(10)[1])^2)^0.5
SpiceOpus (c) 9 -> optimize method complex
SpiceOpus (c) 10 -> optimize

Warning: Convergence problems at node (1).  
Complex: stopped, simplex small enough.
Time needed for optimisation: 16.765 seconds
Number of iterations: 48
Lowest cost function value: 3.290727e-001
Optimal values:
@r6[resistance]	=	3.998431e+004
@r7[resistance]	=	6.879497e+000

R7 is the speaker load, so the equivalent plate load is 4.3k. Are the load resistances really “optimal”? Can’t tell until I build the circuit and test it on the bench. But it does look promising & fast too!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s