Module rand_distr::uniform
source · [−]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) 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 SampleBorrowSampleBorrow::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());Structs
Sample values uniformly between two bounds.
The back-end implementing UniformSampler for char.
The back-end implementing UniformSampler for Duration.
The back-end implementing UniformSampler for floating-point types.
The back-end implementing UniformSampler for integer types.
Traits
Helper trait similar to Borrow but implemented
only for SampleUniform and references to SampleUniform in
order to resolve ambiguity issues.
Range that supports generating a single sample efficiently.
Helper trait for creating objects using the correct implementation of
UniformSampler for the sampling type.
Helper trait handling actual uniform sampling.
