Trait rand_functors::RandomVariable

source ·
pub trait RandomVariable: Sized
where Standard: Distribution<Self>,
{ // Required method fn sample_space() -> impl Iterator<Item = Self>; }
Expand description

A type that is enumerable and can be sampled from uniformly.

This trait requires that an implementor also implement Distribution<Self>, to ensure that it can be sampled from. Additionally, a sample_space associated function must be provided.

Note that a non-uniform distribution or a non-exhaustive sample space will result in a logic error. In particular, this means that this trait should not be implemented for Option<T>, as the probability of None being sampled is 0.5, regardless of the cardinality of the sample space of T.

§Provided Implementations

This crate provides implementations of RandomVariable for bool and all twelve built-in integer types.

Implementations are provided for u32, u64, u128, usize, i32, i64, i128, and isize strictly for sampling from ranges (through RandomStrategy::fmap_rand_range). The use of RandomStrategy::fmap_rand with a 32-bit integer RandomVariable would involve, at minimum, a 4 GiB allocation just to enumerate the outcomes of a random process. This is obviously intractable on current computers.

§Implementing RandomVariable

Neither Distribution<T> for Standard nor RandomVariable for T are derivable. However, implementations for simple structs tends to follow a pattern. Distribution<Self> implementations will typically call self.sample(rng) for each field of the struct. RandomVariable implementations will typically use Iterator::flat_map to create a Cartesian product of all the sample spaces of the struct’s fields.

use rand::distributions::Standard;
use rand::prelude::*;
use rand_functors::RandomVariable;

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct Coordinate {
    x: u8,
    y: u8,
}

impl Distribution<Coordinate> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Coordinate {
        Coordinate {
            x: self.sample(rng),
            y: self.sample(rng),
        }
    }
}

impl RandomVariable for Coordinate {
    fn sample_space() -> impl Iterator<Item = Self> {
        u8::sample_space().flat_map(|x| u8::sample_space().map(move |y| Coordinate { x, y }))
    }
}

Required Methods§

source

fn sample_space() -> impl Iterator<Item = Self>

Produce an Iterator containing all possible values of this type.

This iterator must be finite, though a trait bound of ExactSizeIterator is not specified, to allow the use of Iterator::flat_map in implementations of this trait.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl RandomVariable for bool

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for i8

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for i16

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for i32

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for i64

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for i128

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for isize

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for u8

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for u16

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for u32

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for u64

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for u128

source§

fn sample_space() -> impl Iterator<Item = Self>

source§

impl RandomVariable for usize

source§

fn sample_space() -> impl Iterator<Item = Self>

Implementors§