Runs a SPICE3 deck once per assignment of the swept parameters. The
deck stays pure SPICE3 (there is no .step card): it is parsed once,
and each run writes its values into the parsed deck, builds the
circuit afresh and runs every analysis card, exactly as spice_run()
would on the deck edited by hand – bit for bit.
Usage
spice_sweep(
deck,
...,
.mode = c("grid", "zip"),
.includes = NULL,
.options = NULL,
.threads = 1L,
.tmax_divisor = NULL
)Arguments
- deck
The deck, as in
spice_run().- ...
Named numeric vectors: swept parameter = its values. A data frame or list of draws can be spliced with
!!!.- .mode
"grid"runs every combination, the first parameter varying slowest (astidyr::expand_grid());"zip"runs row by row and needs equal lengths (length-one values are recycled).- .includes, .options
As
includesandoptionsinspice_run(); the options apply to every run (a swepttempoverridesoptions$temp).- .threads
Worker threads:
1(the default) runs sequentially,0uses one per core,nusesn. Results are identical either way: every run is an independent circuit.- .tmax_divisor
As
tmax_divisorinspice_run(), for every run.
Value
A spice_sweep: a list with
title: the deck's title line;params: a tibble withrun(the run index, from 1) and one double column per swept parameter, named in canonical form ("r1","@m1[w]","temp");runs: a list ofspice_result, one per run (each with the deck's.measurecards evaluated in itsmeasurements);diagnostics: the deck's parser warnings, as inspice_run().
spice_tidy() turns it into one long tibble.
Details
The simulator holds no random generator: a Monte Carlo is a "zip"
sweep over draws you make with stats::rnorm() and friends, so it is
reproducible from your own set.seed().
Parameter names
Matched case-insensitively:
temp: circuit temperature in degrees Celsius (as.options temp=);an element name:
r1,c1,l1for its value,vin,iinfor a source's DC level;the ngspice form
@name[param]:@r1[resistance],@c1[capacitance],@l1[inductance],@vin[dc],@vin[acmag],@vin[acphase](degrees),@m1[w],@m1[l](MOSFET width and length, m). Non-syntactic names need backticks:spice_sweep(deck, `@m1[w]` = c(2e-6, 4e-6)).
Elements inside subcircuits go by their expanded names (r.x1.r1).
Model parameters are not sweepable yet.
Errors
An unknown element or parameter, a parameter given twice or a
non-finite value is a spice_error_sweep. A run that fails to build
or simulate stops the sweep with the error class of spice_run()
(spice_error_elaborate, spice_error_analysis, or
spice_error_pss with the shooting history for a .pss that did
not converge), naming the run and its values.
Mirror of the Python package
This is the R face of spice.sweep() in Python. Run indices are
1-based here and 0-based in Python.
Examples
deck <- "rc low-pass
vin 1 0 dc 0 ac 1
r1 1 2 1k
c1 2 0 1u
.ac dec 5 10 10k
.end"
sw <- spice_sweep(deck, r1 = c(500, 1000, 2000))
sw
#> <spice_sweep> rc low-pass
#> 3 runs over r1
#> plots: "AC Analysis"
head(spice_tidy(sw))
#> # A tibble: 6 × 13
#> run r1 plot point scale_name scale variable type re im mag
#> <int> <dbl> <chr> <int> <chr> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 1 500 AC Analys… 1 frequency 10 v(1) volt… 1 0 1
#> 2 1 500 AC Analys… 2 frequency 15.8 v(1) volt… 1 0 1
#> 3 1 500 AC Analys… 3 frequency 25.1 v(1) volt… 1 0 1
#> 4 1 500 AC Analys… 4 frequency 39.8 v(1) volt… 1 0 1
#> 5 1 500 AC Analys… 5 frequency 63.1 v(1) volt… 1 0 1
#> 6 1 500 AC Analys… 6 frequency 100 v(1) volt… 1 0 1
#> # ℹ 2 more variables: db <dbl>, phase <dbl>
# Monte Carlo: 5% resistor and capacitor, reproducible from the seed
set.seed(1)
mc <- spice_sweep(deck,
r1 = rnorm(20, 1000, 50), c1 = rnorm(20, 1e-6, 5e-8),
.mode = "zip"
)
mc$params
#> # A tibble: 20 × 3
#> run r1 c1
#> <int> <dbl> <dbl>
#> 1 1 969. 0.00000105
#> 2 2 1009. 0.00000104
#> 3 3 958. 0.00000100
#> 4 4 1080. 0.000000901
#> 5 5 1016. 0.00000103
#> 6 6 959. 0.000000997
#> 7 7 1024. 0.000000992
#> 8 8 1037. 0.000000926
#> 9 9 1029. 0.000000976
#> 10 10 985. 0.00000102
#> 11 11 1076. 0.00000107
#> 12 12 1019. 0.000000995
#> 13 13 969. 0.00000102
#> 14 14 889. 0.000000997
#> 15 15 1056. 0.000000931
#> 16 16 998. 0.000000979
#> 17 17 999. 0.000000980
#> 18 18 1047. 0.000000997
#> 19 19 1041. 0.00000106
#> 20 20 1030. 0.00000104