diff options
Diffstat (limited to 'third_party/rust/rand/src/distributions/triangular.rs')
-rw-r--r-- | third_party/rust/rand/src/distributions/triangular.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/third_party/rust/rand/src/distributions/triangular.rs b/third_party/rust/rand/src/distributions/triangular.rs new file mode 100644 index 0000000000..3e8f8b03ef --- /dev/null +++ b/third_party/rust/rand/src/distributions/triangular.rs @@ -0,0 +1,79 @@ +// Copyright 2018 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! The triangular distribution. +#![allow(deprecated)] + +use crate::Rng; +use crate::distributions::{Distribution, Standard}; + +/// The triangular distribution. +#[deprecated(since="0.7.0", note="moved to rand_distr crate")] +#[derive(Clone, Copy, Debug)] +pub struct Triangular { + min: f64, + max: f64, + mode: f64, +} + +impl Triangular { + /// Construct a new `Triangular` with minimum `min`, maximum `max` and mode + /// `mode`. + /// + /// # Panics + /// + /// If `max < mode`, `mode < max` or `max == min`. + /// + #[inline] + pub fn new(min: f64, max: f64, mode: f64) -> Triangular { + assert!(max >= mode); + assert!(mode >= min); + assert!(max != min); + Triangular { min, max, mode } + } +} + +impl Distribution<f64> for Triangular { + #[inline] + fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 { + let f: f64 = rng.sample(Standard); + let diff_mode_min = self.mode - self.min; + let diff_max_min = self.max - self.min; + if f * diff_max_min < diff_mode_min { + self.min + (f * diff_max_min * diff_mode_min).sqrt() + } else { + self.max - ((1. - f) * diff_max_min * (self.max - self.mode)).sqrt() + } + } +} + +#[cfg(test)] +mod test { + use crate::distributions::Distribution; + use super::Triangular; + + #[test] + fn test_new() { + for &(min, max, mode) in &[ + (-1., 1., 0.), (1., 2., 1.), (5., 25., 25.), (1e-5, 1e5, 1e-3), + (0., 1., 0.9), (-4., -0.5, -2.), (-13.039, 8.41, 1.17), + ] { + println!("{} {} {}", min, max, mode); + let _ = Triangular::new(min, max, mode); + } + } + + #[test] + fn test_sample() { + let norm = Triangular::new(0., 1., 0.5); + let mut rng = crate::test::rng(1); + for _ in 0..1000 { + norm.sample(&mut rng); + } + } +} |