Name Description Size
bernoulli.rs The Bernoulli distribution. 7567
distribution.rs Distribution trait and associates 8381
float.rs Basic floating-point number distributions 12584
integer.rs The implementations of the `Standard` distribution for integer types. 8792
mod.rs Generating random samples from probability distributions This module is the home of the [`Distribution`] trait and several of its implementations. It is the workhorse behind some of the convenient functionality of the [`Rng`] trait, e.g. [`Rng::gen`] and of course [`Rng::sample`]. Abstractly, a [probability distribution] describes the probability of occurrence of each value in its sample space. More concretely, an implementation of `Distribution<T>` for type `X` is an algorithm for choosing values from the sample space (a subset of `T`) according to the distribution `X` represents, using an external source of randomness (an RNG supplied to the `sample` function). A type `X` may implement `Distribution<T>` for multiple types `T`. Any type implementing [`Distribution`] is stateless (i.e. immutable), but it may have internal parameters set at construction time (for example, [`Uniform`] allows specification of its sample space as a range within `T`). # The `Standard` distribution The [`Standard`] distribution is important to mention. This is the distribution used by [`Rng::gen`] and represents the "default" way to produce a random value for many different types, including most primitive types, tuples, arrays, and a few derived types. See the documentation of [`Standard`] for more details. Implementing `Distribution<T>` for [`Standard`] for user types `T` makes it possible to generate type `T` with [`Rng::gen`], and by extension also with the [`random`] function. ## Random characters [`Alphanumeric`] is a simple distribution to sample random letters and numbers of the `char` type; in contrast [`Standard`] may sample any valid `char`. # Uniform numeric ranges The [`Uniform`] distribution is more flexible than [`Standard`], but also more specialised: it supports fewer target types, but allows the sample space to be specified as an arbitrary range within its target type `T`. Both [`Standard`] and [`Uniform`] are in some sense uniform distributions. Values may be sampled from this distribution using [`Rng::sample(Range)`] or by creating a distribution object with [`Uniform::new`], [`Uniform::new_inclusive`] or `From<Range>`. When the range limits are not known at compile time it is typically faster to reuse an existing `Uniform` object than to call [`Rng::sample(Range)`]. User types `T` may also implement `Distribution<T>` for [`Uniform`], although this is less straightforward than for [`Standard`] (see the documentation in the [`uniform`] module). Doing so enables generation of values of type `T` with [`Rng::sample(Range)`]. ## Open and half-open ranges There are surprisingly many ways to uniformly generate random floats. A range between 0 and 1 is standard, but the exact bounds (open vs closed) and accuracy differ. In addition to the [`Standard`] distribution Rand offers [`Open01`] and [`OpenClosed01`]. See "Floating point implementation" section of [`Standard`] documentation for more details. # Non-uniform sampling Sampling a simple true/false outcome with a given probability has a name: the [`Bernoulli`] distribution (this is used by [`Rng::gen_bool`]). For weighted sampling from a sequence of discrete values, use the [`WeightedIndex`] distribution. This crate no longer includes other non-uniform distributions; instead it is recommended that you use either [`rand_distr`] or [`statrs`]. [probability distribution]: https://en.wikipedia.org/wiki/Probability_distribution [`rand_distr`]: https://crates.io/crates/rand_distr [`statrs`]: https://crates.io/crates/statrs 9066
other.rs The implementations of the `Standard` distribution for other built-in types. 11852
slice.rs 3880
uniform.rs A distribution uniformly sampling numbers within a given range. [`Uniform`] is the standard distribution to sample uniformly from a range; e.g. `Uniform::new_inclusive(1, 6)` can sample integers from 1 to 6, like a standard die. [`Rng::gen_range`] supports any type supported by [`Uniform`]. This distribution is provided with support for several primitive types (all integer and floating-point types) as well as [`std::time::Duration`], and supports extension to user-defined types via a type-specific *back-end* implementation. The types [`UniformInt`], [`UniformFloat`] and [`UniformDuration`] are the back-ends supporting sampling from primitive integer and floating-point ranges as well as from [`std::time::Duration`]; these types do not normally need to be used directly (unless implementing a derived back-end). # Example usage ``` use rand::{Rng, thread_rng}; use rand::distributions::Uniform; let mut rng = thread_rng(); let side = Uniform::new(-10.0, 10.0); // sample between 1 and 10 points for _ in 0..rng.gen_range(1..=10) { // sample a point from the square with sides -10 - 10 in two dimensions let (x, y) = (rng.sample(side), rng.sample(side)); println!("Point: {}, {}", x, y); } ``` # Extending `Uniform` to support a custom type To extend [`Uniform`] to support your own types, write a back-end which implements the [`UniformSampler`] trait, then implement the [`SampleUniform`] helper trait to "register" your back-end. See the `MyF32` example below. At a minimum, the back-end needs to store any parameters needed for sampling (e.g. the target range) and implement `new`, `new_inclusive` and `sample`. Those methods should include an assert to check the range is valid (i.e. `low < high`). The example below merely wraps another back-end. The `new`, `new_inclusive` and `sample_single` functions use arguments of type SampleBorrow<X> in order to support passing in values by reference or by value. In the implementation of these functions, you can choose to simply use the reference returned by [`SampleBorrow::borrow`], or you can choose to copy or clone the value, whatever is appropriate for your type. ``` use rand::prelude::*; use rand::distributions::uniform::{Uniform, SampleUniform, UniformSampler, UniformFloat, SampleBorrow}; struct MyF32(f32); #[derive(Clone, Copy, Debug)] struct UniformMyF32(UniformFloat<f32>); impl UniformSampler for UniformMyF32 { type X = MyF32; fn new<B1, B2>(low: B1, high: B2) -> Self where B1: SampleBorrow<Self::X> + Sized, B2: SampleBorrow<Self::X> + Sized { UniformMyF32(UniformFloat::<f32>::new(low.borrow().0, high.borrow().0)) } fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self where B1: SampleBorrow<Self::X> + Sized, B2: SampleBorrow<Self::X> + Sized { UniformMyF32(UniformFloat::<f32>::new_inclusive( low.borrow().0, high.borrow().0, )) } fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X { MyF32(self.0.sample(rng)) } } impl SampleUniform for MyF32 { type Sampler = UniformMyF32; } let (low, high) = (MyF32(17.0f32), MyF32(22.0f32)); let uniform = Uniform::new(low, high); let x = uniform.sample(&mut thread_rng()); ``` [`SampleUniform`]: crate::distributions::uniform::SampleUniform [`UniformSampler`]: crate::distributions::uniform::UniformSampler [`UniformInt`]: crate::distributions::uniform::UniformInt [`UniformFloat`]: crate::distributions::uniform::UniformFloat [`UniformDuration`]: crate::distributions::uniform::UniformDuration [`SampleBorrow::borrow`]: crate::distributions::uniform::SampleBorrow::borrow 62947
utils.rs Math helper functions 13610
weighted.rs Weighted index sampling This module is deprecated. Use [`crate::distributions::WeightedIndex`] and [`crate::distributions::WeightedError`] instead. 1536
weighted_index.rs Weighted index sampling 16268