Using random param(eters)

The ngspice frontend (with its 'numparam' parser) contains the .param (see Chapt. 2.8.1) and .func (see Chapt. 2.9) commands. Among the built-in functions supported (see 2.8.5) you will find the following statistical functions:

Built-in function
Notes
gauss(nom, rvar, sigma)
nominal value plus variation drawn from Gaussian distribution with mean 0 and standard deviation rvar (relative to nominal), divided by sigma
agauss(nom, avar, sigma)
nominal value plus variation drawn from Gaussian distribution with mean 0 and standard deviation avar (absolute), divided by sigma
unif(nom, rvar)
nominal value plus relative variation (to nominal) uniformly distributed between +/-rvar
aunif(nom, avar)
nominal value plus absolute variation uniformly distributed between +/-avar
limit(nom, avar)
nominal value +/-avar, depending on random number in [-1, 1[ being > 0 or < 0

The frontend parser evaluates all .param or .func statements upon start-up of ngspice, before the circuit is evaluated. The parameters aga, aga2, lim obtain their numerical values once. If the random function appears in a device card (e.g. v11 11 0 'agauss(1,2,3)'), a new random number is generated.

Random number example using parameters:

* random number tests
.param aga = agauss(1,2,3)
.param aga2='2*aga'
.param lim=limit(0,1.2)
.func rgauss(a,b,c) '5*agauss(a,b,c)'
* always same value as defined above
v1 1 0  'lim'
v2 2 0  'lim'
* may be a different value
v3 3 0  'limit(0,1.2)'
* always new random values
v11 11 0 'agauss(1,2,3)'
v12 12 0 'agauss(1,2,3)'
v13 13 0 'agauss(1,2,3)'
* same value as defined above
v14 14 0 'aga'
v15 15 0 'aga'
v16 16 0 'aga2'
* using .func, new random values
v17 17 0 'rgauss(0,2,3)'
v18 18 0 'rgauss(0,2,3)'
.op
.control
run
print v(1) v(2) v(3) v(11) v(12) v(13)
print v(14) v(15) v(16) v(17) v(18)
.endc
.end

So v1, v2, and v3 will get the same value, whereas v4 might differ. v11, v12, and v13 will get different values, v14, v15, and v16 will obtain the values set above in the .param statements. .func will start its replacement algorithm, rgauss(a,b,c) will be replaced everywhere by 5*agauss(a,b,c).

Thus device and model parameters may obtain statistically distributed starting values. You simply set a model parameter not to a fixed numerical value, but insert a 'parameter' instead, which may consist of a token defined in a .param card, by calling .func or by using a built-in function, including the statistical functions described above. The parameter values will be evaluated once immediately after reading the input file.