Statistics¶
core ¶
Statistical analysis of simulation output.
Everything here works on plain sequences of numbers (one value per
independent replication, or per Monte Carlo iteration). The confidence
intervals assume independent, identically distributed observations; for
autocorrelated output from a single long run use :func:batch_means
first. Nothing here can guarantee the model itself is right - only that the
sampling error of the reported estimates is quantified.
ReplicationAdvice
dataclass
¶
ReplicationAdvice(n: int, mean: float, half_width: float, relative_half_width: float, target_relative_half_width: float, required_n: int | None, sufficient: bool, note: str = '')
Answer to "have I run enough replications?" for one metric.
Uses the sequential approximation from Law (2015), Simulation Modeling
and Analysis, sec. 9.4.1: the smallest n such that the t-based
relative half-width, using the current variance estimate, is within
target. It is an estimate: the variance itself is uncertain, so
re-check after running the suggested number.
BatchMeans
dataclass
¶
BatchMeans(batch_means: FloatArray, summary: Summary, lag1_autocorrelation: float)
batches_look_independent
property
¶
batches_look_independent: bool
Heuristic: |lag-1 autocorrelation| within the ~95% band 2/sqrt(k)
expected for k independent batch means. Passing does not prove independence.
Difference
dataclass
¶
Difference(mean_a: float, mean_b: float, difference: float, ci_low: float, ci_high: float, p_value: float, method: str, n_a: int, n_b: int, confidence: float)
Estimated difference b - a with a confidence interval.
significant
property
¶
significant: bool
True when the CI excludes zero (no correction for multiple comparisons).
ControlVariateEstimate
dataclass
¶
ControlVariateEstimate(mean: float, ci_low: float, ci_high: float, raw_mean: float, raw_ci_low: float, raw_ci_high: float, coefficients: dict[str, float], n: int, confidence: float)
Mean of y adjusted with control variates, and how much variance that removed.
variance_reduction
property
¶
variance_reduction: float
1 - (CV half-width / raw half-width)^2: share of estimator variance removed.
mean_ci ¶
mean_ci(values: Sequence[float] | FloatArray, confidence: float = 0.95) -> tuple[float, float]
Student-t confidence interval for the mean (NaNs dropped).
bootstrap_ci ¶
bootstrap_ci(values: Sequence[float] | FloatArray, statistic: Callable[..., Any] = np.mean, *, confidence: float = 0.95, n_resamples: int = 2000, seed: int = 0) -> tuple[float, float]
Percentile bootstrap interval for any statistic (e.g. median, p95).
statistic must accept a 2-D array and an axis keyword (NumPy
reductions do), which lets resampling run vectorised.
proportion_ci ¶
proportion_ci(successes: int, n: int, confidence: float = 0.95) -> tuple[float, float]
Wilson score interval for a probability estimated from successes / n.
convergence ¶
convergence(values: Sequence[float] | FloatArray, confidence: float = 0.95) -> Convergence
Running mean and t half-width after each replication (for convergence plots).
batch_means ¶
batch_means(observations: Sequence[float] | FloatArray, n_batches: int = 20, confidence: float = 0.95) -> BatchMeans
Non-overlapping batch means for a CI from one long (steady-state) run.
Observations in the same run are usually autocorrelated (one long wait
follows another), so the naive t-interval is too narrow. Averaging over
large batches reduces the correlation; check lag1_autocorrelation and
use fewer, larger batches if it is high.
paired_difference ¶
paired_difference(a: Sequence[float] | FloatArray, b: Sequence[float] | FloatArray, confidence: float = 0.95) -> Difference
Paired-t CI for b - a - appropriate with common random numbers.
welch_difference ¶
welch_difference(a: Sequence[float] | FloatArray, b: Sequence[float] | FloatArray, confidence: float = 0.95) -> Difference
Welch (unequal-variance) t CI for mean(b) - mean(a) from independent samples.
adjust_p_values ¶
adjust_p_values(p_values: Sequence[float], method: AdjustMethod = 'holm') -> list[float]
Adjust p-values for multiple comparisons; NaNs are kept and not counted.
bonferroni-p * m; controls the family-wise error rate.holm- Holm's step-down; also controls the family-wise error rate but is uniformly more powerful than Bonferroni.bh- Benjamini-Hochberg; controls the false discovery rate (expected share of false positives among the "significant" results).
control_variate ¶
control_variate(y: Sequence[float] | FloatArray, controls: Mapping[str, Sequence[float] | FloatArray], means: Mapping[str, float], *, confidence: float = 0.95) -> ControlVariateEstimate
Control-variate estimator of E[y] (Law 2015, sec. 11.4; regression form).
Each control x_k is an output whose expectation means[k] is known
exactly (e.g. the average sampled service time). Regressing y on
x - mean gives an unbiased intercept (the adjusted mean) with a
standard error from the regression residuals, using n - 1 - q degrees
of freedom for q controls. It helps only when the controls are
correlated with y; with few replications the estimated coefficients
cost some precision, so keep q small.