des_sim/modeling/sampler/instance/
normal.rs1use crate::modeling::sampler::{DurationSampler, PendingDuration};
11use crate::primitive::time::SimTime;
12use rand::Rng;
13use rand::distr::Distribution;
14use rand_distr::{Normal, NormalError};
15
16#[derive(Debug, Clone)]
22pub struct NormalSampler {
23 dist: Normal<f64>,
24}
25
26impl DurationSampler for NormalSampler {
27 fn sample(&mut self, rng: &mut dyn Rng, _current_tick: SimTime) -> PendingDuration {
28 PendingDuration::new(self.dist.sample(rng))
29 }
30}
31
32impl NormalSampler {
33 pub fn new(mean: f64, std_dev: f64) -> Result<Self, NormalError> {
36 Normal::new(mean, std_dev).map(|dist| NormalSampler { dist })
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use rand::SeedableRng;
44 use rand::rngs::SmallRng;
45
46 #[test]
47 fn test_normal_sampler() {
48 let mut rng = SmallRng::seed_from_u64(2);
49 let mean = 10.0;
50 let std_dev = 2.0;
51 let mut sampler = NormalSampler::new(mean, std_dev).unwrap();
52
53 let mut samples = Vec::new();
54 for _ in 0..10000 {
55 samples.push(sampler.sample(&mut rng, SimTime::from_ticks(0)).raw_value());
56 }
57
58 let sample_mean: f64 = samples.iter().sum::<f64>() / samples.len() as f64;
59 let variance: f64 = samples
60 .iter()
61 .map(|x| (x - sample_mean).powi(2))
62 .sum::<f64>()
63 / samples.len() as f64;
64 let sample_std_dev = variance.sqrt();
65
66 assert!(
68 (sample_mean - mean).abs() < 0.1,
69 "Mean: {}, Expected: {}",
70 sample_mean,
71 mean
72 );
73 assert!(
74 (sample_std_dev - std_dev).abs() < 0.1,
75 "Std Dev: {}, Expected: {}",
76 sample_std_dev,
77 std_dev
78 );
79 }
80
81 #[test]
82 fn test_normal_sampler_infinite_std_dev() {
83 let sampler = NormalSampler::new(0.0, f64::INFINITY);
84 assert_eq!(sampler.err(), Some(NormalError::BadVariance));
85 }
86}