# Optimiser Modes

The SIMetrix simulator can run an optimisation analysis in two different ways.

 Single analysis mode This is a multi-step mode similar to Monte Carlo and Sensitivity analysis. The optimisation process can only use one analysis type (e.g. transient) but runs very efficiently and generates multi-division data Multiple analysis mode This uses the .OPTIMISER statement to define the optimiser analysis but can be coupled to any number of analysis statements. This makes it possible to perform a wide variety of measurements on a circuit using for example, transient AC and noise analyses

In this topic:

## Single analysis mode

The syntax for the single-analysis mode is described in the Multi-step Analysis reference.

In addition to the analysis statement, all optimiser analyses must define at least one .OPTSPEC statement. An .OPTSPEC statement defines the objective function, that is the function that is to be maximised or minimised and may also define constraints.

See the following section for an example that demonstrates this mode of operation.

## Single analysis mode - Example

The following example extracts the parameters of a diode model to an I-V curve obtained from a data sheet. The diode's data is defined using the .DATA statement.

Here is the complete listing:

```V1 V1_P 0 5
D1 V1_P 0 DUT
.model DUT d RS={RS} IS=1e-8 IKF={IKF} N={N}
.TEMP 100
** This is called by .post_process and plots the final result
.file finish
Let data = Diode_data

** Plot reference
plot /ylog /xlog /name Target data

Let res = OptimiserSimulatorResults()
Let bestIndex = res-1
curve /name "Best fit" d1#p[bestIndex]

.endf
.post_process finish
.dc v1 400m 1.4 100m analysis_id=dc_0 sweep opt
+ optparams=[RS,IKF,N]
+ optinitvals=0.01,0.1,1
+ optminvals=1e-06,0.001,0.1
+ abstol=1e-09
+ reltol=0.001
+ show_progress
+ results_file="diode-test_results.sxopt"
.optspec measure="CurveFitLog(Diode_data,d1#p)" type=minimise analysis_id=dc_0
.data Diode_data format=XY
+ 0.2 0.017530716724236
+ 0.254901960784314 0.0357202832826342
+ 0.309803921568627 0.0727830275203565
+ 0.364705882352941 0.14827729430306
+ 0.419607843137255 0.299668595377245
+ 0.474509803921569 0.589675601217673
+ 0.529411764705882 1.10904794310676
+ 0.584313725490196 1.97923148874408
+ 0.63921568627451 3.35105785726025
+ 0.694117647058824 5.38251036969293
+ 0.749019607843137 8.20132439386704
+ 0.803921568627451 11.8538062030208
+ 0.858823529411765 16.2514356239684
+ 0.913725490196078 21.1880160385802
+ 0.968627450980392 26.4796478563484
+ 1.02352941176471 31.9973234288307
+ 1.07843137254902 37.7095034055593
+ 1.13333333333333 43.7173003655197
+ 1.18823529411765 50.1648407603598
+ 1.24313725490196 57.1465442469968
+ 1.29803921568627 64.8085898417056
+ 1.35294117647059 73.3707911567976
+ 1.4078431372549 83.0553217690679
+ 1.46274509803922 94.0181558001952
+ 1.51764705882353 106.428022091678
+ 1.57254901960784 120.475920740442
+ 1.6 128.180625221171```

The actual circuit is defined by the first 4 lines. The .file/.endf and .post_process statements define a post processing script that plots the final result on completion.

### Analysis and Optimiser Definition

The optimiser analysis is defined by these lines:

```.dc v1 400m 1.4 100m analysis_id=dc_0 sweep opt
+ optparams=[RS,IKF,N]
+ optinitvals=0.01,0.1,1
+ optminvals=1e-06,0.001,0.1
+ abstol=1e-09
+ reltol=0.001
+ show_progress
+ results_file="diode-test_results.sxopt"
.optspec measure="CurveFitLog(Diode_data,d1#p)" type=minimise analysis=dc_0```
The first line starts:
`.dc v1 400m 1.4 100m`
and defines a DC sweep which sweep V1 from 0.4V to 1.4V in steps of 0.1V.
`analysis_id=dc_0`

defines the analysis_id. This is important as it links the analysis statement to a corresponding .OPTSPEC statement. .OPTSPEC statements make measurements but need to know which analysis data to apply it to. This is the purpose of the analysis_id parameter. The value used is arbitrary.

`sweep opt`
defines an optimiser analysis
```+ optparams=[RS,IKF,N]
+ optinitvals=0.01,0.1,1
+ optminvals=1e-06,0.001,0.1```

define the parameters. The first line defines the parameter names and these work the same way as parameters defined using .PARAM. optinitvals is compulsory and defines the values the optimiser will use for the first run. optminvals sepcifies the minimum values that the optimiser will use for those parameters. This is optional. There is also optmaxvals which defines the maximum values allowed. The optimiser will not set the parameters to values outside those specs.

`+ alg=NELDER_MEAD`

```+ abstol=1e-09
+ reltol=0.001```

are stop criteria. abstol specifies an absolute tolerance for the change in objective function. The exact interpretation of the tolerance parameters depends on the algorithm, but typically when the objective function improvement between iterations is less than abstol, the optimiser analysis will complete. For reltol the optimisation analysis completes when the relative value between iterations falls below the reltol value.

`+ show_progress`

Instructs the optimiser to write a message for each iteration. The message will be written to the display device. When running in GUI mode, this is the front end's command shell. If running from a command prompt, this is the command prompt window.

`+ results_file="diode-test_results.sxopt"`

This specifies the results file. The results file is an XML file that contains the entire specification of the optimisation analysis along with the full results.

### Objective Function Definition

`.optspec measure="CurveFitLog(Diode_data,d1#p)" type=minimise analysis_id=dc_0`

This line defines the objective function. Objective functions have the type parameter set to minimise or maximise and there must be one and one-only objective function for an optimiser analysis. The measure parameter defines the expression which is evaluated and in this case minimised. CurveFitLog is a function which compares two vectors and returns a normalised value representing the difference between the two vectors. 0 means they are identical. 1.0 will be returned if one curve is the exact reciprocal of the other. CurveFitLog is one of a family of functions, the others are CurveFit, CurveFitLogX and CurveFitLogY. For full documentation see Script Reference Manual/Function Reference/CurveFit.

analysis_id=dc_0 defines the analysis that the measurement is associated with and must match up with an analysis_id parameter defined in an analysis statement. In this case it is the .DC analysis defined above.

Diode_data refers the .DATA statement that defines the reference curve we are attempting to match.

## Multi-analysis Mode

The multi-analysis optimiser mode is defined using the .OPTIMISER statement. The .OPTIMISER statement defines the optimiser configuration but also needs at least one additional analysis statements such as .TRAN or .AC.

In addition to the .OPTIMISER statement and analysis statements, all optimiser analyses must define at least one .OPTSPEC statement. An .OPTSPEC statement defines the objective function, that is the function that is to be maximised or minimised and may also define constraints.

## Multi-analysis Mode - Example

The following is a direct netlist only version of the amp-700 example shown in the User's Manual. This is a bipolar transistor differential amplifier. Its behaviour is governed by four parameters that decide the values of a number of resistors in the design. Our objective is to minimise its power consumption while maintaining a minimum bandwidth, gain and signal distortion.

The complete netlist is shown below:

```** Differential amplifier

** Circuit definition
V1 V1_P 0 0 AC 1 0 Sin(0 500m 500k 0 0)
V2 0 R11_N 15
R1 R1_P 0 1K
V3 V3_P 0 15
R2 R8_N R11_N 5k
R3 Q2_E R3_N {Rtail}
R4 V3_P R4_N {Rcoll}
R5 V3_P R5_N {Rcoll}
R6 Q3_E R3_N {Rtail}
R7 Q1_E R11_N {Rcurr}
R8 0 R8_N 50k
R9 R9_P V1_P 1K
R10 VOUT 0 10k
R11 Q7_E R11_N 100
R12 V3_P R12_N {Routput}
R13 V3_P R13_N {Routput}
R14 Q4_E R11_N 100
Q1 R3_N R8_N Q1_E 0 N1
Q2 R4_N R1_P Q2_E 0 N1
Q3 R5_N R9_P Q3_E 0 N1
Q4 VOUT Q5_C Q4_E 0 N1
Q5 Q5_C R5_N R12_N 0 P1
Q6 VOUT R4_N R13_N 0 P1
Q7 Q5_C Q5_C Q7_E 0 N1

.MODEL N1 NPN IS=3.8E-16 BF=220 BR=0.7
+ ISE=1.8E-16 IKF=1.7E-2 NK=0.75 IKR=3E-2 NE=1.4 VAF=60
+ VAR=7 RC=63.4 RB=300 RE=19.7 XTB=1.17 XTI=5.4
+ TF=1.5E-10 TR=6E-9 XTF=0.3 VTF=6 ITF=5E-5 CJE=0.21E-12
+ MJE=0.33 VJE=0.7 ISC=5E-12 KF=2E-13 AF=1.4
.MODEL P1 PNP IS=1E-15 BF=100 CJE=0.175E-12 XTI=5.4
+ MJE=0.38 VJE=0.6

** OPTIMISER Definition
.optimiser
+ optparams=[rcurr,rtail,rcoll,routput]
+ optinitvals=[1000,1000,10000,10000]
+ optminvals=[50,50,100,100]
+ optmaxvals=[20000,20000,50000,50000]
+ alg=COBYLA
+ abstol=1e-09
+ reltol=0.001
+ iterlim=25
+ results_file="amp-700_results.sxopt"
+ show_progress

** AC Analysis
.ac dec 25 1k 1000000000 analysis_id=ac_0

** Transient analysis
.tran 0 10u 0 10n analysis_id=tran_1

** .OPTSPEC definitions
** Objective function
.optspec
+ measure="-(v3#p+v2#p)"
+ type=minimum
+ analysis_id=ac_0
+ op
+ label="Supply_current"

** Constraint functions
.optspec
+ measure="lpbw(vout, 3)"
+ type=constraint_minimum
+ analysis_id=ac_0
+ value=2.5e+08
+ label="Bandwidth"

.optspec
+ measure="yatx(db(vout),1meg)"
+ type=constraint_minimum
+ analysis_id=ac_0
+ value=20
+ label="Gain_at_1meg"

.optspec
+ measure="MeasureDistortion(vout)"
+ type=constraint_maximum
+ analysis_id=tran_1
+ value=0.01
+ label="Distortion"```

Two analyses are defined: an AC frequency sweep and a transient analysis. The AC sweep is used to measure the gain and frequency response and the transient analysis is used to measure the distortion. The current consumption is measured using the operating point analysis that is part of the AC analysis mode.

The following paragraphs explain the optimiser definition found in the above netlist.

### Optimiser Definition

```.optimiser
+ optparams=[rcurr,rtail,rcoll,routput]
+ optinitvals=[1000,1000,10000,10000]
+ optminvals=[50,50,100,100]
+ optmaxvals=[20000,20000,50000,50000]
+ alg=COBYLA
+ abstol=1e-09
+ reltol=0.001
+ iterlim=25
+ results_file="amp-700_results.sxopt"
+ show_progress```

The first parameter:

`+ optparams=[rcurr,rtail,rcoll,routput]`

Defines the names of the parameters. These work in the same way as parameters defined using .PARAM. The next line:

`+ optinitvals=[1000,1000,10000,10000]`

is compulsory and defines the values the optimiser will use for the first simulator run. The values are in the same order as the parameter names. The next two lines:

```+ optminvals=[50,50,100,100]
+ optmaxvals=[20000,20000,50000,50000]```

define minimum and maximum limits for the parameters. The optimiser will not use values outside those limits.

`+ alg=COBYLA`

Defines the algorithm to be used. See Algorihms for more information. The lines:

```+ abstol=1e-09
+ reltol=0.001
+ iterlim=25```

define stop criteria. The optimisation process will complete when one of those criteria is met. abstol specifies an absolute tolerance for the change in objective function. The exact interpretation of the tolerance parameters depends on the algorithm, but typically when the objective function improvement between iterations is less than abstol, the optimiser analysis will complete. For reltol the optimisation analysis completes when the relative value between iterations falls below the reltol value. iterlim defines the maximum number of iterations; when the iteration count exceeds this value, the optimiser will stop.

`+ results_file="amp-700_results.sxopt"`

This specifies the results file. The results file is an XML file that contains the entire specification of the optimisation analysis along with the full results.

`+ show_progress`

Instructs the optimiser to write a message for each iteration. The message will be written to the display device. When running in GUI mode, this is the front end's command shell. If running from a command prompt, this is the command prompt window.

### Analysis statements

```.ac dec 25 1k 1000000000 analysis_id=ac_0
.tran 0 10u 0 10n analysis_id=tran_1```

The above are analysis statements. For details see .AC and .TRAN. The important part for optimisation is the analysis_id parameters. These are compulsory for optimisation analysis but not required otherwise. The analysis_id parameters link the analysis to an .OPTSPEC statement.

### Objective and Constraint Definition

The remaining statements are .OPTSPEC statements and these define the objective and constraint functions.

```** Objective function
.optspec
+ measure="-(v3#p+v2#p)"
+ type=minimum
+ analysis_id=ac_0
+ op
+ label="Supply_current"

** Constraint functions
.optspec
+ measure="lpbw(vout, 3)"
+ type=constraint_minimum
+ analysis_id=ac_0
+ value=2.5e+08
+ label="Bandwidth"

.optspec
+ measure="yatx(db(vout),1meg)"
+ type=constraint_minimum
+ analysis_id=ac_0
+ value=20
+ label="Gain_at_1meg"

.optspec
+ measure="MeasureDistortion(vout)"
+ type=constraint_maximum
+ analysis_id=tran_1
+ value=0.01
+ label="Distortion"```
The first definition:
```.optspec
+ measure="-(v3#p+v2#p)"
+ type=minimum
+ analysis=ac_0
+ op
+ label="Supply_current"```

is the objective function. There must be one and one-only objective function. The measure parameter is the actual expression that is calculated. In this case it is calculating the currents into V3 and V2. The focus of the optimisation is the power consumption but in this case both voltage sources are the same voltage so we simply seek to minimise the total current.

The type parameter must be either minimum or maximum for an objective function. In this it is minimum meaning that the optimiser will seek to minimise this value.

The analysis_id links this measurement to the analysis line with the same analysis_id namely the .AC statement shown above.

The op parameter specifies that the measurement should use the operating point data for the specified analysis.

Finally the label parameter defines a label that will be used to identify the measurement in the final report, in progress messages and in any error messages that may be output.

The remaining three .OPTSPEC statements are constraint functions. The optimiser will attempt to minimise the objective while complying with the constraints. Constraints are identified by the type parameter having the value constraint_minimum or constraint_maximum. constraint_minimum means that the optimiser will attempt to not allow the measurement to fall below the value of the value parameter while constraint_maximum means that the optimiser will attempt to not allow the measurement to rise above the value of value.