Module rand::distributions::uniform[][src]

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, 11) {
    // 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.

use rand::prelude::*;
use rand::distributions::uniform::{Uniform, SampleUniform,
        UniformSampler, UniformFloat};

struct MyF32(f32);

#[derive(Clone, Copy, Debug)]
struct UniformMyF32 {
    inner: UniformFloat<f32>,
}

impl UniformSampler for UniformMyF32 {
    type X = MyF32;
    fn new(low: Self::X, high: Self::X) -> Self {
        UniformMyF32 {
            inner: UniformFloat::<f32>::new(low.0, high.0),
        }
    }
    fn new_inclusive(low: Self::X, high: Self::X) -> Self {
        UniformSampler::new(low, high)
    }
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
        MyF32(self.inner.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

Uniform

Sample values uniformly between two bounds.

UniformDuration

The back-end implementing UniformSampler for Duration.

UniformFloat

The back-end implementing UniformSampler for floating-point types.

UniformInt

The back-end implementing UniformSampler for integer types.

Traits

SampleUniform

Helper trait for creating objects using the correct implementation of UniformSampler for the sampling type.

UniformSampler

Helper trait handling actual uniform sampling.