Expand description
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).unwrap() can sample integers from 1 to 6, like a
standard die. Rng::random_range is implemented over Uniform.
§Example usage
use rand::Rng;
use rand::distr::Uniform;
let mut rng = rand::rng();
let side = Uniform::new(-10.0, 10.0).unwrap();
// sample between 1 and 10 points
for _ in 0..rng.random_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 assertion to check the range is valid (i.e.
low < high). The example below merely wraps another back-end.
The new, new_inclusive, sample_single and sample_single_inclusive
functions use arguments of
type SampleBorrow<X> 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::distr::uniform::{Uniform, SampleUniform,
UniformSampler, UniformFloat, SampleBorrow, Error};
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) -> Result<Self, Error>
where B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized
{
UniformFloat::<f32>::new(low.borrow().0, high.borrow().0).map(UniformMyF32)
}
fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
where B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized
{
UniformFloat::<f32>::new_inclusive(low.borrow().0, high.borrow().0).map(UniformMyF32)
}
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).unwrap();
let x = uniform.sample(&mut rand::rng());Structs§
- Uniform
- Sample values uniformly between two bounds.
- Uniform
Char - The back-end implementing
UniformSamplerforchar. - Uniform
Duration - The back-end implementing
UniformSamplerforDuration. - Uniform
Float - The back-end implementing
UniformSamplerfor floating-point types. - Uniform
Int - The back-end implementing
UniformSamplerfor integer types. - Uniform
Usize - The back-end implementing
UniformSamplerforusize.
Enums§
- Error
- Error type returned from
Uniform::newandnew_inclusive.
Traits§
- Sample
Borrow - Helper trait similar to
Borrowbut implemented only forSampleUniformand references toSampleUniformin order to resolve ambiguity issues. - Sample
Range - Range that supports generating a single sample efficiently.
- Sample
Uniform - Helper trait for creating objects using the correct implementation of
UniformSamplerfor the sampling type. - Uniform
Sampler - Helper trait handling actual uniform sampling.