1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
use crate::{Rng, Uncertain}; /// An uncertain value which always yields the same /// value. /// /// This type can be useful when fixed values should /// be conditionally returned e.g. from [`flat_map`](Uncertain::flat_map). /// If you only need a fixed value as part of an uncertain computation, consider /// using [`map`](Uncertain::map). /// /// # Examples /// /// Basic usage: conditional distribution. /// /// ``` /// use uncertain::{Uncertain, PointMass, Distribution}; /// use rand_distr::Normal; /// /// let a = Distribution::from(Normal::new(2.0, 1.0).unwrap()); /// let b = a.flat_map(|a| if a < 1.5 { /// Distribution::from(Normal::new(0.0, 1.0).unwrap()).into_boxed() /// } else { /// PointMass::new(1.0).into_boxed() /// }); /// assert!(b.map(|b| b > 0.5).pr(0.9)); /// ``` /// /// In most cases you can use [`map`](Uncertain::map) instead: /// /// ``` /// use uncertain::{Uncertain, PointMass, Distribution}; /// use rand_distr::StandardNormal; /// /// let x = 1.0; /// let y = Distribution::<f64, _>::from(StandardNormal).into_ref(); /// let a = PointMass::new(x).add(&y); /// let b = (&y).map(|v: f64| v + x); /// assert!(a.join(b, |a, b| a == b).pr(0.999)); /// ``` #[derive(Clone, Copy)] pub struct PointMass<T> where T: Clone, { value: T, } impl<T> PointMass<T> where T: Clone, { /// Create a new `PointMass` centered on /// the given value. pub fn new(value: T) -> Self { Self { value } } } impl<T> Uncertain for PointMass<T> where T: Clone, { type Value = T; fn sample(&self, _rng: &mut Rng, _epoch: usize) -> Self::Value { self.value.clone() } } #[cfg(test)] mod tests { use super::*; use crate::Uncertain; use rand_pcg::Pcg32; #[test] fn samples_are_always_the_same() { let val = 42.0; let point = PointMass::new(val); let mut rng = Pcg32::new(0xcafef00dd15ea5e5, 0xa02bdbf7bb3c0a7); for epoch in 0..100 { assert_eq!(val, point.sample(&mut rng, epoch)); } } }