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