Skip to main content

Crate comnum_sim

Crate comnum_sim 

Source
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 Lightningcomnum_simrole
LightningModulescenario::Scenariowhat one trial does: setup once per condition, trial many times
self.log(...)scenario::Recordthe metrics a trial reports: error counts or values
Trainerrunner::Runnerruns the trials, in batches, on a thread pool
seed_everythingrunner::Runner::seedtrial t of condition c uses stream(seed, name, c, t)
max_epochs, EarlyStoppingstopping::Stopwhen a condition has enough trials (errors, precision, time)
Callbackcallbacks::Callbackhooks at the start and end of the run, of every condition and batch
Loggerloggers::LoggerCSV (one row per condition, written as it completes) and JSON reports
fast_dev_runrunner::Runner::fast_dev_runone batch per condition, to check a scenario quickly
ModuleContent
scenariothe Scenario trait, from_fn, the Record of a trial
gridthe conditions of a campaign: axes, zips, fixed values, explicit lists
runnerthe Runner: batches of trials on a thread pool, seeds, results
stoppingthe stopping rules Stop and their combinations
callbacksthe hooks of a run: progress bar, skipping the rest of a sweep
loggersthe CSV and JSON reports
statserror rates with Wilson intervals, means with normal intervals
jsona 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 Trainer of 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>-dirty when the tracked sources of the library (crates/, bindings/, Cargo.toml, Cargo.lock) have uncommitted changes, staged or not, unknown outside a Git checkout. The build script reruns when HEAD, 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.