1 // Copyright 2018 Developers of the Rand project. 2 // 3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license 5 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your 6 // option. This file may not be copied, modified, or distributed 7 // except according to those terms. 8 9 //! The Weibull distribution. 10 11 use Rng; 12 use distributions::{Distribution, OpenClosed01}; 13 14 /// Samples floating-point numbers according to the Weibull distribution 15 /// 16 /// # Example 17 /// ``` 18 /// use rand::prelude::*; 19 /// use rand::distributions::Weibull; 20 /// 21 /// let val: f64 = SmallRng::from_entropy().sample(Weibull::new(1., 10.)); 22 /// println!("{}", val); 23 /// ``` 24 #[derive(Clone, Copy, Debug)] 25 pub struct Weibull { 26 inv_shape: f64, 27 scale: f64, 28 } 29 30 impl Weibull { 31 /// Construct a new `Weibull` distribution with given `scale` and `shape`. 32 /// 33 /// # Panics 34 /// 35 /// `scale` and `shape` have to be non-zero and positive. new(scale: f64, shape: f64) -> Weibull36 pub fn new(scale: f64, shape: f64) -> Weibull { 37 assert!((scale > 0.) & (shape > 0.)); 38 Weibull { inv_shape: 1./shape, scale } 39 } 40 } 41 42 impl Distribution<f64> for Weibull { sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f6443 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 { 44 let x: f64 = rng.sample(OpenClosed01); 45 self.scale * (-x.ln()).powf(self.inv_shape) 46 } 47 } 48 49 #[cfg(test)] 50 mod tests { 51 use distributions::Distribution; 52 use super::Weibull; 53 54 #[test] 55 #[should_panic] invalid()56 fn invalid() { 57 Weibull::new(0., 0.); 58 } 59 60 #[test] sample()61 fn sample() { 62 let scale = 1.0; 63 let shape = 2.0; 64 let d = Weibull::new(scale, shape); 65 let mut rng = ::test::rng(1); 66 for _ in 0..1000 { 67 let r = d.sample(&mut rng); 68 assert!(r >= 0.); 69 } 70 } 71 } 72