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 Pareto distribution. 10 11 use Rng; 12 use distributions::{Distribution, OpenClosed01}; 13 14 /// Samples floating-point numbers according to the Pareto distribution 15 /// 16 /// # Example 17 /// ``` 18 /// use rand::prelude::*; 19 /// use rand::distributions::Pareto; 20 /// 21 /// let val: f64 = SmallRng::from_entropy().sample(Pareto::new(1., 2.)); 22 /// println!("{}", val); 23 /// ``` 24 #[derive(Clone, Copy, Debug)] 25 pub struct Pareto { 26 scale: f64, 27 inv_neg_shape: f64, 28 } 29 30 impl Pareto { 31 /// Construct a new Pareto distribution with given `scale` and `shape`. 32 /// 33 /// In the literature, `scale` is commonly written as x<sub>m</sub> or k and 34 /// `shape` is often written as α. 35 /// 36 /// # Panics 37 /// 38 /// `scale` and `shape` have to be non-zero and positive. new(scale: f64, shape: f64) -> Pareto39 pub fn new(scale: f64, shape: f64) -> Pareto { 40 assert!((scale > 0.) & (shape > 0.)); 41 Pareto { scale, inv_neg_shape: -1.0 / shape } 42 } 43 } 44 45 impl Distribution<f64> for Pareto { sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f6446 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 { 47 let u: f64 = rng.sample(OpenClosed01); 48 self.scale * u.powf(self.inv_neg_shape) 49 } 50 } 51 52 #[cfg(test)] 53 mod tests { 54 use distributions::Distribution; 55 use super::Pareto; 56 57 #[test] 58 #[should_panic] invalid()59 fn invalid() { 60 Pareto::new(0., 0.); 61 } 62 63 #[test] sample()64 fn sample() { 65 let scale = 1.0; 66 let shape = 2.0; 67 let d = Pareto::new(scale, shape); 68 let mut rng = ::test::rng(1); 69 for _ in 0..1000 { 70 let r = d.sample(&mut rng); 71 assert!(r >= scale); 72 } 73 } 74 } 75