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 |