Probability Distributions
Numra’s numra-stats crate provides a rich collection of probability
distributions, both continuous and discrete. Each distribution implements a
common trait with PDF/PMF, CDF, quantile, mean, variance, and random sampling.
Distribution Traits
Section titled “Distribution Traits”ContinuousDistribution
Section titled “ContinuousDistribution”All continuous distributions implement ContinuousDistribution<S>:
| Method | Signature | Description |
|---|---|---|
pdf(x) | fn pdf(&self, x: S) -> S | Probability density function |
cdf(x) | fn cdf(&self, x: S) -> S | Cumulative distribution function |
quantile(p) | fn quantile(&self, p: S) -> S | Inverse CDF () |
mean() | fn mean(&self) -> S | Distribution mean |
variance() | fn variance(&self) -> S | Distribution variance |
std_dev() | fn std_dev(&self) -> S | Standard deviation () |
sample(rng) | fn sample(&self, rng) -> S | Generate a single random sample |
sample_n(rng, n) | fn sample_n(&self, rng, n) -> Vec<S> | Generate random samples |
DiscreteDistribution
Section titled “DiscreteDistribution”Discrete distributions implement DiscreteDistribution<S>:
| Method | Signature | Description |
|---|---|---|
pmf(k) | fn pmf(&self, k: usize) -> S | Probability mass function |
cdf(k) | fn cdf(&self, k: usize) -> S | Cumulative |
mean() | fn mean(&self) -> S | Distribution mean |
variance() | fn variance(&self) -> S | Distribution variance |
sample(rng) | fn sample(&self, rng) -> usize | Generate a single random sample |
sample_n(rng, n) | fn sample_n(&self, rng, n) -> Vec<usize> | Generate random samples |
Continuous Distributions
Section titled “Continuous Distributions”Normal (Gaussian)
Section titled “Normal (Gaussian)”The most fundamental continuous distribution. Parameterized by mean and standard deviation :
use numra::stats::{Normal, ContinuousDistribution};
let n = Normal::new(0.0_f64, 1.0); // standard normal N(0, 1)// or equivalently:let n = Normal::<f64>::standard();
// PDF at the mean is the peak valuelet peak = 1.0 / (2.0 * std::f64::consts::PI).sqrt();assert!((n.pdf(0.0) - peak).abs() < 1e-12);
// CDF: P(X <= 0) = 0.5 for standard normalassert!((n.cdf(0.0) - 0.5).abs() < 1e-12);
// Quantile: inverse CDFlet x = n.quantile(0.975);assert!((x - 1.96).abs() < 0.01); // 97.5th percentile ~ 1.96
// Mean and varianceassert!((n.mean()).abs() < 1e-14);assert!((n.variance() - 1.0).abs() < 1e-14);Student’s t
Section titled “Student’s t”Used for hypothesis testing and confidence intervals with small samples. Parameterized by degrees of freedom :
use numra::stats::{StudentT, ContinuousDistribution};
let t = StudentT::new(5.0_f64); // 5 degrees of freedom
// Symmetric about zeroassert!((t.pdf(1.0) - t.pdf(-1.0)).abs() < 1e-12);assert!((t.cdf(0.0) - 0.5).abs() < 1e-10);
// Variance = nu / (nu - 2) for nu > 2assert!((t.variance() - 5.0 / 3.0).abs() < 1e-14);
// Quantile round-tripfor &p in &[0.05, 0.25, 0.5, 0.75, 0.95] { let x = t.quantile(p); assert!((t.cdf(x) - p).abs() < 1e-6);}Chi-Squared
Section titled “Chi-Squared”Special case of the Gamma distribution. Used in goodness-of-fit tests and confidence intervals for variance. Parameterized by degrees of freedom :
use numra::stats::{ChiSquared, ContinuousDistribution};
let chi2 = ChiSquared::new(5.0_f64);
assert!((chi2.mean() - 5.0).abs() < 1e-14); // mean = kassert!((chi2.variance() - 10.0).abs() < 1e-14); // variance = 2kassert!(chi2.cdf(0.0).abs() < 1e-10); // CDF(0) = 0F-Distribution
Section titled “F-Distribution”The ratio of two chi-squared distributions. Used in ANOVA and regression testing. Parameterized by degrees of freedom:
use numra::stats::{FDist, ContinuousDistribution};
let f = FDist::new(5.0_f64, 10.0);
// Mean = d2 / (d2 - 2) for d2 > 2assert!((f.mean() - 10.0 / 8.0).abs() < 1e-12);
assert!(f.cdf(0.0).abs() < 1e-10);Uniform
Section titled “Uniform”Constant density on the interval :
use numra::stats::{Uniform, ContinuousDistribution};
let u = Uniform::new(0.0_f64, 10.0);
assert!((u.pdf(5.0) - 0.1).abs() < 1e-14);assert!((u.cdf(5.0) - 0.5).abs() < 1e-14);assert!((u.mean() - 5.0).abs() < 1e-14);
// Variance = (b-a)^2 / 12assert!((u.variance() - 100.0 / 12.0).abs() < 1e-12);Exponential
Section titled “Exponential”Models the time between events in a Poisson process. Parameterized by rate :
use numra::stats::{Exponential, ContinuousDistribution};
let e = Exponential::new(2.0_f64); // rate = 2
assert!((e.pdf(0.0) - 2.0).abs() < 1e-12); // PDF at 0 = lambdaassert!((e.mean() - 0.5).abs() < 1e-14); // mean = 1/lambdaassert!((e.variance() - 0.25).abs() < 1e-14); // variance = 1/lambda^2
// CDF: P(X <= 1) = 1 - exp(-2)let expected = 1.0 - (-2.0_f64).exp();assert!((e.cdf(1.0) - expected).abs() < 1e-12);Other Continuous Distributions
Section titled “Other Continuous Distributions”| Distribution | Constructor | Parameters | Mean | Variance |
|---|---|---|---|---|
GammaDist | GammaDist::new(alpha, beta) | Shape , rate | ||
BetaDist | BetaDist::new(alpha, beta) | |||
LogNormal | LogNormal::new(mu, sigma) | Log-mean, log-std |
Discrete Distributions
Section titled “Discrete Distributions”Poisson
Section titled “Poisson”Models the number of events in a fixed interval. Parameterized by rate :
use numra::stats::{Poisson, DiscreteDistribution};
let p = Poisson::new(5.0_f64);
// Mean = variance = lambdaassert!((p.mean() - 5.0).abs() < 1e-14);assert!((p.variance() - 5.0).abs() < 1e-14);
// PMF sums to 1let sum: f64 = (0..30).map(|k| p.pmf(k)).sum();assert!((sum - 1.0).abs() < 1e-8);
// CDF is monotonelet mut prev = 0.0;for k in 0..20 { let c = p.cdf(k); assert!(c >= prev); prev = c;}Binomial
Section titled “Binomial”Models the number of successes in independent Bernoulli trials:
use numra::stats::{Binomial, DiscreteDistribution};
let b = Binomial::new(10, 0.3_f64); // n=10 trials, p=0.3
// Mean = np, Variance = np(1-p)assert!((b.mean() - 3.0).abs() < 1e-12);assert!((b.variance() - 2.1).abs() < 1e-12);Random Sampling
Section titled “Random Sampling”All distributions support random sampling through the rand crate’s RngCore
trait. Use a seeded RNG for reproducible results.
use numra::stats::{Normal, ContinuousDistribution};use rand::SeedableRng;
let dist = Normal::new(0.0_f64, 1.0);let mut rng = rand::rngs::StdRng::seed_from_u64(42);
// Single samplelet x = dist.sample(&mut rng);
// Multiple sampleslet samples = dist.sample_n(&mut rng, 10000);
// Sample mean should be close to 0let sample_mean: f64 = samples.iter().sum::<f64>() / samples.len() as f64;assert!(sample_mean.abs() < 0.1);Sampling from Different Distributions
Section titled “Sampling from Different Distributions”use numra::stats::{ Normal, Uniform, Exponential, Poisson, ContinuousDistribution, DiscreteDistribution,};
fn main() { let mut rng = rand::thread_rng();
// Continuous samples let normal_samples = Normal::new(100.0, 15.0).sample_n(&mut rng, 1000); let uniform_samples = Uniform::new(0.0, 1.0).sample_n(&mut rng, 1000); let exp_samples = Exponential::new(0.5).sample_n(&mut rng, 1000);
// Discrete samples let poisson_samples = Poisson::new(7.0).sample_n(&mut rng, 1000);
println!("Normal: mean = {:.2}", normal_samples.iter().sum::<f64>() / 1000.0); println!("Uniform: mean = {:.2}", uniform_samples.iter().sum::<f64>() / 1000.0); println!("Exponential: mean = {:.2}", exp_samples.iter().sum::<f64>() / 1000.0); println!("Poisson: mean = {:.2}", poisson_samples.iter().sum::<usize>() as f64 / 1000.0);}Distribution Summary
Section titled “Distribution Summary”Continuous Distributions
Section titled “Continuous Distributions”| Distribution | Constructor | Key Use |
|---|---|---|
Normal | Normal::new(mu, sigma) | General modeling, central limit theorem |
Normal::standard() | N(0, 1) | Z-scores, standard reference |
StudentT | StudentT::new(df) | Small-sample inference |
ChiSquared | ChiSquared::new(df) | Goodness-of-fit, variance testing |
FDist | FDist::new(df1, df2) | ANOVA, regression F-tests |
Uniform | Uniform::new(a, b) | Simulation, random number generation |
Exponential | Exponential::new(lambda) | Waiting times, reliability |
GammaDist | GammaDist::new(alpha, beta) | Bayesian priors, queuing theory |
BetaDist | BetaDist::new(alpha, beta) | Bayesian priors for proportions |
LogNormal | LogNormal::new(mu, sigma) | Financial modeling, multiplicative processes |
Discrete Distributions
Section titled “Discrete Distributions”| Distribution | Constructor | Key Use |
|---|---|---|
Poisson | Poisson::new(lambda) | Count data, rare events |
Binomial | Binomial::new(n, p) | Success/failure experiments |
Complete Example: Distribution Comparison
Section titled “Complete Example: Distribution Comparison”use numra::stats::{ Normal, StudentT, ContinuousDistribution,};
fn main() { let normal = Normal::<f64>::standard();
// As degrees of freedom increase, Student's t approaches the normal for df in [1, 5, 10, 30, 100] { let t = StudentT::new(df as f64); let x = 1.96; let p_normal = normal.cdf(x); let p_t = t.cdf(x); println!("df={:3}: P(T <= 1.96) = {:.6} P(Z <= 1.96) = {:.6} diff = {:.6}", df, p_t, p_normal, (p_t - p_normal).abs()); } // At df=100, the difference should be very small}