Expand description
§comnum-sim — Monte Carlo simulation campaigns
A campaign evaluates a scenario (one random trial of a link) on every condition of a grid (an SNR, a launch power, a modulation order, …), as many times as a stopping rule requires, in parallel on every core, and reports every metric with a confidence interval. The organisation follows PyTorch Lightning, so that the experiment code stays short and the engineering (parallelism, seeds, stopping, logging, progress) is written once:
| PyTorch Lightning | comnum_sim | role |
|---|---|---|
LightningModule | scenario::Scenario | what one trial does: setup once per condition, trial many times |
self.log(...) | scenario::Record | the metrics a trial reports: error counts or values |
Trainer | runner::Runner | runs the trials, in batches, on a thread pool |
seed_everything | runner::Runner::seed | trial t of condition c uses stream(seed, name, c, t) |
max_epochs, EarlyStopping | stopping::Stop | when a condition has enough trials (errors, precision, time) |
Callback | callbacks::Callback | hooks at the start and end of the run, of every condition and batch |
Logger | loggers::Logger | CSV (one row per condition, written as it completes) and JSON reports |
fast_dev_run | runner::Runner::fast_dev_run | one batch per condition, to check a scenario quickly |
| Module | Content |
|---|---|
scenario | the Scenario trait, from_fn, the Record of a trial |
grid | the conditions of a campaign: axes, zips, fixed values, explicit lists |
runner | the Runner: batches of trials on a thread pool, seeds, results |
stopping | the stopping rules Stop and their combinations |
callbacks | the hooks of a run: progress bar, skipping the rest of a sweep |
loggers | the CSV and JSON reports |
stats | error rates with Wilson intervals, means with normal intervals |
json | a minimal JSON writer for the reports |
§Reproducibility
Every trial draws its random numbers from its own stream
stream(seed, scenario name, condition index, trial index) (comnum_core::rng::stream),
the trials of a batch run in parallel, their records are merged in trial order,
and the stopping rule is evaluated after every batch. The results are therefore
identical whatever the number of threads (only a wall-time rule,
stopping::Stop::max_time, depends on the machine).
§Statistics
An error count is an stats::ErrorRate (errors / total, Wilson score interval);
any other value is a stats::Mean (Welford’s running mean and variance, normal
interval of the mean). Both merge exactly across trials.
§Example: BER of QPSK over AWGN against the theory
use comnum_sim::prelude::*;
use comnum_mapping::{constellation::{Constellation, ConstellationKind}, source as sources};
use comnum_channel::awgn as channels;
use comnum_metrics as metrics;
use comnum_sim::scenario::from_fn;
// a scenario written as a closure: no per-condition state
let qpsk = from_fn("qpsk", |cond, rng, rec| {
let c = Constellation::qam(4)?.normalized();
let bits = sources::bits(2000, rng);
let rx = channels::awgn_ebn0(&c.map_bits(&bits)?, cond.f64("ebn0_db")?, 2.0, 1.0, rng);
rec.errors("ber", metrics::bit_errors(&c.demap_bits(&rx), &bits)? as u64, 2000);
Ok(())
});
let grid = Grid::new().axis("ebn0_db", [0.0, 2.0, 4.0]);
let res = Runner::new()
.seed(7)
.batch(16)
.stop(Stop::min_errors("ber", 500).or(Stop::max_trials(2000)))
.run(&qpsk, &grid)
.unwrap();
for r in &res {
let eb = r.condition.f64("ebn0_db").unwrap();
let ber = r.metric("ber").unwrap();
let (lo, hi) = ber.interval(0.99);
let theory = metrics::theory_ber(ConstellationKind::Qam, 4, eb).unwrap();
assert!(lo <= theory && theory <= hi, "{eb} dB: {theory} not in [{lo}, {hi}]");
}Modules§
- callbacks
- Callbacks: hooks into the run.
- grid
- Grids of simulation conditions.
- json
- A minimal JSON writer for the reports (no dependency).
- loggers
- Loggers: where the results go.
- prelude
- The items used by most campaigns.
- runner
- The runner: the
Trainerof a Monte Carlo campaign. - scenario
- Scenarios and the metrics of a trial.
- stats
- Running statistics with confidence intervals.
- stopping
- When a condition has run enough trials.
Constants§
- COMMIT
- Commit of the library at build time, recorded in every run:
<hash>-dirtywhen the tracked sources of the library (crates/,bindings/,Cargo.toml,Cargo.lock) have uncommitted changes, staged or not,unknownoutside a Git checkout. The build script reruns whenHEAD, the branch it points to, the index or one of these sources changes, so that the value is never stale. - VERSION
- Version of the library, recorded in every run.