1 // Copyright 2018 Developers of the Rand project. 2 // Copyright 2013-2017 The Rust Project Developers. 3 // 4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 5 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license 6 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your 7 // option. This file may not be copied, modified, or distributed 8 // except according to those terms. 9 10 //! Generating random samples from probability distributions 11 //! 12 //! This module is the home of the [`Distribution`] trait and several of its 13 //! implementations. It is the workhorse behind some of the convenient 14 //! functionality of the [`Rng`] trait, e.g. [`Rng::gen`] and of course 15 //! [`Rng::sample`]. 16 //! 17 //! Abstractly, a [probability distribution] describes the probability of 18 //! occurrence of each value in its sample space. 19 //! 20 //! More concretely, an implementation of `Distribution<T>` for type `X` is an 21 //! algorithm for choosing values from the sample space (a subset of `T`) 22 //! according to the distribution `X` represents, using an external source of 23 //! randomness (an RNG supplied to the `sample` function). 24 //! 25 //! A type `X` may implement `Distribution<T>` for multiple types `T`. 26 //! Any type implementing [`Distribution`] is stateless (i.e. immutable), 27 //! but it may have internal parameters set at construction time (for example, 28 //! [`Uniform`] allows specification of its sample space as a range within `T`). 29 //! 30 //! 31 //! # The `Standard` distribution 32 //! 33 //! The [`Standard`] distribution is important to mention. This is the 34 //! distribution used by [`Rng::gen`] and represents the "default" way to 35 //! produce a random value for many different types, including most primitive 36 //! types, tuples, arrays, and a few derived types. See the documentation of 37 //! [`Standard`] for more details. 38 //! 39 //! Implementing `Distribution<T>` for [`Standard`] for user types `T` makes it 40 //! possible to generate type `T` with [`Rng::gen`], and by extension also 41 //! with the [`random`] function. 42 //! 43 //! ## Random characters 44 //! 45 //! [`Alphanumeric`] is a simple distribution to sample random letters and 46 //! numbers of the `char` type; in contrast [`Standard`] may sample any valid 47 //! `char`. 48 //! 49 //! 50 //! # Uniform numeric ranges 51 //! 52 //! The [`Uniform`] distribution is more flexible than [`Standard`], but also 53 //! more specialised: it supports fewer target types, but allows the sample 54 //! space to be specified as an arbitrary range within its target type `T`. 55 //! Both [`Standard`] and [`Uniform`] are in some sense uniform distributions. 56 //! 57 //! Values may be sampled from this distribution using [`Rng::sample(Range)`] or 58 //! by creating a distribution object with [`Uniform::new`], 59 //! [`Uniform::new_inclusive`] or `From<Range>`. When the range limits are not 60 //! known at compile time it is typically faster to reuse an existing 61 //! `Uniform` object than to call [`Rng::sample(Range)`]. 62 //! 63 //! User types `T` may also implement `Distribution<T>` for [`Uniform`], 64 //! although this is less straightforward than for [`Standard`] (see the 65 //! documentation in the [`uniform`] module). Doing so enables generation of 66 //! values of type `T` with [`Rng::sample(Range)`]. 67 //! 68 //! ## Open and half-open ranges 69 //! 70 //! There are surprisingly many ways to uniformly generate random floats. A 71 //! range between 0 and 1 is standard, but the exact bounds (open vs closed) 72 //! and accuracy differ. In addition to the [`Standard`] distribution Rand offers 73 //! [`Open01`] and [`OpenClosed01`]. See "Floating point implementation" section of 74 //! [`Standard`] documentation for more details. 75 //! 76 //! # Non-uniform sampling 77 //! 78 //! Sampling a simple true/false outcome with a given probability has a name: 79 //! the [`Bernoulli`] distribution (this is used by [`Rng::gen_bool`]). 80 //! 81 //! For weighted sampling from a sequence of discrete values, use the 82 //! [`WeightedIndex`] distribution. 83 //! 84 //! This crate no longer includes other non-uniform distributions; instead 85 //! it is recommended that you use either [`rand_distr`] or [`statrs`]. 86 //! 87 //! 88 //! [probability distribution]: https://en.wikipedia.org/wiki/Probability_distribution 89 //! [`rand_distr`]: https://crates.io/crates/rand_distr 90 //! [`statrs`]: https://crates.io/crates/statrs 91 92 //! [`random`]: crate::random 93 //! [`rand_distr`]: https://crates.io/crates/rand_distr 94 //! [`statrs`]: https://crates.io/crates/statrs 95 96 use crate::Rng; 97 use core::iter; 98 99 pub use self::bernoulli::{Bernoulli, BernoulliError}; 100 pub use self::float::{Open01, OpenClosed01}; 101 pub use self::other::Alphanumeric; 102 #[doc(inline)] pub use self::uniform::Uniform; 103 104 #[cfg(feature = "alloc")] 105 pub use self::weighted_index::{WeightedError, WeightedIndex}; 106 107 mod bernoulli; 108 pub mod uniform; 109 110 #[deprecated(since = "0.8.0", note = "use rand::distributions::{WeightedIndex, WeightedError} instead")] 111 #[cfg(feature = "alloc")] 112 #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] 113 pub mod weighted; 114 #[cfg(feature = "alloc")] mod weighted_index; 115 116 #[cfg(feature = "serde1")] 117 use serde::{Serialize, Deserialize}; 118 119 mod float; 120 #[doc(hidden)] 121 pub mod hidden_export { 122 pub use super::float::IntoFloat; // used by rand_distr 123 } 124 mod integer; 125 mod other; 126 mod utils; 127 128 /// Types (distributions) that can be used to create a random instance of `T`. 129 /// 130 /// It is possible to sample from a distribution through both the 131 /// `Distribution` and [`Rng`] traits, via `distr.sample(&mut rng)` and 132 /// `rng.sample(distr)`. They also both offer the [`sample_iter`] method, which 133 /// produces an iterator that samples from the distribution. 134 /// 135 /// All implementations are expected to be immutable; this has the significant 136 /// advantage of not needing to consider thread safety, and for most 137 /// distributions efficient state-less sampling algorithms are available. 138 /// 139 /// Implementations are typically expected to be portable with reproducible 140 /// results when used with a PRNG with fixed seed; see the 141 /// [portability chapter](https://rust-random.github.io/book/portability.html) 142 /// of The Rust Rand Book. In some cases this does not apply, e.g. the `usize` 143 /// type requires different sampling on 32-bit and 64-bit machines. 144 /// 145 /// [`sample_iter`]: Distribution::method.sample_iter 146 pub trait Distribution<T> { 147 /// Generate a random value of `T`, using `rng` as the source of randomness. sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T148 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T; 149 150 /// Create an iterator that generates random values of `T`, using `rng` as 151 /// the source of randomness. 152 /// 153 /// Note that this function takes `self` by value. This works since 154 /// `Distribution<T>` is impl'd for `&D` where `D: Distribution<T>`, 155 /// however borrowing is not automatic hence `distr.sample_iter(...)` may 156 /// need to be replaced with `(&distr).sample_iter(...)` to borrow or 157 /// `(&*distr).sample_iter(...)` to reborrow an existing reference. 158 /// 159 /// # Example 160 /// 161 /// ``` 162 /// use rand::thread_rng; 163 /// use rand::distributions::{Distribution, Alphanumeric, Uniform, Standard}; 164 /// 165 /// let mut rng = thread_rng(); 166 /// 167 /// // Vec of 16 x f32: 168 /// let v: Vec<f32> = Standard.sample_iter(&mut rng).take(16).collect(); 169 /// 170 /// // String: 171 /// let s: String = Alphanumeric 172 /// .sample_iter(&mut rng) 173 /// .take(7) 174 /// .map(char::from) 175 /// .collect(); 176 /// 177 /// // Dice-rolling: 178 /// let die_range = Uniform::new_inclusive(1, 6); 179 /// let mut roll_die = die_range.sample_iter(&mut rng); 180 /// while roll_die.next().unwrap() != 6 { 181 /// println!("Not a 6; rolling again!"); 182 /// } 183 /// ``` sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> where R: Rng, Self: Sized,184 fn sample_iter<R>(self, rng: R) -> DistIter<Self, R, T> 185 where 186 R: Rng, 187 Self: Sized, 188 { 189 DistIter { 190 distr: self, 191 rng, 192 phantom: ::core::marker::PhantomData, 193 } 194 } 195 } 196 197 impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D { sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T198 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T { 199 (*self).sample(rng) 200 } 201 } 202 203 204 /// An iterator that generates random values of `T` with distribution `D`, 205 /// using `R` as the source of randomness. 206 /// 207 /// This `struct` is created by the [`sample_iter`] method on [`Distribution`]. 208 /// See its documentation for more. 209 /// 210 /// [`sample_iter`]: Distribution::sample_iter 211 #[derive(Debug)] 212 pub struct DistIter<D, R, T> { 213 distr: D, 214 rng: R, 215 phantom: ::core::marker::PhantomData<T>, 216 } 217 218 impl<D, R, T> Iterator for DistIter<D, R, T> 219 where 220 D: Distribution<T>, 221 R: Rng, 222 { 223 type Item = T; 224 225 #[inline(always)] next(&mut self) -> Option<T>226 fn next(&mut self) -> Option<T> { 227 // Here, self.rng may be a reference, but we must take &mut anyway. 228 // Even if sample could take an R: Rng by value, we would need to do this 229 // since Rng is not copyable and we cannot enforce that this is "reborrowable". 230 Some(self.distr.sample(&mut self.rng)) 231 } 232 size_hint(&self) -> (usize, Option<usize>)233 fn size_hint(&self) -> (usize, Option<usize>) { 234 (usize::max_value(), None) 235 } 236 } 237 238 impl<D, R, T> iter::FusedIterator for DistIter<D, R, T> 239 where 240 D: Distribution<T>, 241 R: Rng, 242 { 243 } 244 245 #[cfg(features = "nightly")] 246 impl<D, R, T> iter::TrustedLen for DistIter<D, R, T> 247 where 248 D: Distribution<T>, 249 R: Rng, 250 { 251 } 252 253 254 /// A generic random value distribution, implemented for many primitive types. 255 /// Usually generates values with a numerically uniform distribution, and with a 256 /// range appropriate to the type. 257 /// 258 /// ## Provided implementations 259 /// 260 /// Assuming the provided `Rng` is well-behaved, these implementations 261 /// generate values with the following ranges and distributions: 262 /// 263 /// * Integers (`i32`, `u32`, `isize`, `usize`, etc.): Uniformly distributed 264 /// over all values of the type. 265 /// * `char`: Uniformly distributed over all Unicode scalar values, i.e. all 266 /// code points in the range `0...0x10_FFFF`, except for the range 267 /// `0xD800...0xDFFF` (the surrogate code points). This includes 268 /// unassigned/reserved code points. 269 /// * `bool`: Generates `false` or `true`, each with probability 0.5. 270 /// * Floating point types (`f32` and `f64`): Uniformly distributed in the 271 /// half-open range `[0, 1)`. See notes below. 272 /// * Wrapping integers (`Wrapping<T>`), besides the type identical to their 273 /// normal integer variants. 274 /// 275 /// The `Standard` distribution also supports generation of the following 276 /// compound types where all component types are supported: 277 /// 278 /// * Tuples (up to 12 elements): each element is generated sequentially. 279 /// * Arrays (up to 32 elements): each element is generated sequentially; 280 /// see also [`Rng::fill`] which supports arbitrary array length for integer 281 /// types and tends to be faster for `u32` and smaller types. 282 /// * `Option<T>` first generates a `bool`, and if true generates and returns 283 /// `Some(value)` where `value: T`, otherwise returning `None`. 284 /// 285 /// ## Custom implementations 286 /// 287 /// The [`Standard`] distribution may be implemented for user types as follows: 288 /// 289 /// ``` 290 /// # #![allow(dead_code)] 291 /// use rand::Rng; 292 /// use rand::distributions::{Distribution, Standard}; 293 /// 294 /// struct MyF32 { 295 /// x: f32, 296 /// } 297 /// 298 /// impl Distribution<MyF32> for Standard { 299 /// fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MyF32 { 300 /// MyF32 { x: rng.gen() } 301 /// } 302 /// } 303 /// ``` 304 /// 305 /// ## Example usage 306 /// ``` 307 /// use rand::prelude::*; 308 /// use rand::distributions::Standard; 309 /// 310 /// let val: f32 = StdRng::from_entropy().sample(Standard); 311 /// println!("f32 from [0, 1): {}", val); 312 /// ``` 313 /// 314 /// # Floating point implementation 315 /// The floating point implementations for `Standard` generate a random value in 316 /// the half-open interval `[0, 1)`, i.e. including 0 but not 1. 317 /// 318 /// All values that can be generated are of the form `n * ε/2`. For `f32` 319 /// the 24 most significant random bits of a `u32` are used and for `f64` the 320 /// 53 most significant bits of a `u64` are used. The conversion uses the 321 /// multiplicative method: `(rng.gen::<$uty>() >> N) as $ty * (ε/2)`. 322 /// 323 /// See also: [`Open01`] which samples from `(0, 1)`, [`OpenClosed01`] which 324 /// samples from `(0, 1]` and `Rng::gen_range(0..1)` which also samples from 325 /// `[0, 1)`. Note that `Open01` uses transmute-based methods which yield 1 bit 326 /// less precision but may perform faster on some architectures (on modern Intel 327 /// CPUs all methods have approximately equal performance). 328 /// 329 /// [`Uniform`]: uniform::Uniform 330 #[derive(Clone, Copy, Debug)] 331 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] 332 pub struct Standard; 333 334 335 #[cfg(test)] 336 mod tests { 337 use super::{Distribution, Uniform}; 338 use crate::Rng; 339 340 #[test] test_distributions_iter()341 fn test_distributions_iter() { 342 use crate::distributions::Open01; 343 let mut rng = crate::test::rng(210); 344 let distr = Open01; 345 let mut iter = Distribution::<f32>::sample_iter(distr, &mut rng); 346 let mut sum: f32 = 0.; 347 for _ in 0..100 { 348 sum += iter.next().unwrap(); 349 } 350 assert!(0. < sum && sum < 100.); 351 } 352 353 #[test] test_make_an_iter()354 fn test_make_an_iter() { 355 fn ten_dice_rolls_other_than_five<'a, R: Rng>( 356 rng: &'a mut R, 357 ) -> impl Iterator<Item = i32> + 'a { 358 Uniform::new_inclusive(1, 6) 359 .sample_iter(rng) 360 .filter(|x| *x != 5) 361 .take(10) 362 } 363 364 let mut rng = crate::test::rng(211); 365 let mut count = 0; 366 for val in ten_dice_rolls_other_than_five(&mut rng) { 367 assert!(val >= 1 && val <= 6 && val != 5); 368 count += 1; 369 } 370 assert_eq!(count, 10); 371 } 372 } 373