I am looking at the rand crate and I am not sure how to sample from a distribution such that the resulting samples are uniform and deterministic.
Deterministic means that you get the same numbers on 2 distinct program invocations.
The main issue I am facing is that rand by default is not deterministic. Id does have rand_pcg for determinism, but then I don;t know how to make the distribution uniform.
The rand
crate supports everything you are asking for.
The gen*
functions on the Rng
trait do this. Under the hood, they actually defer to the Standard
distribution, which is simply uniform distribution for most common types.
If you wish to provide a custom distribution, simply use Rng::sample*
functions and provide a distribution of your choice.
You are looking for SeedableRng
. As the name implies, rngs that implement this trait should be able to accept a seed on initialisation. Note that determinism is not actually guaranteed by this trait (it depends on the implementation of the specific rng), although in practice seedable rngs are usually deterministic. One such rng provided is StdRng
, but you can also implement your own rng if you so desire.
Note that there is a difference between "deterministic" and "reproducible", as outlined in StdRng
's documentation:
The algorithm is deterministic but should not be considered reproducible due to dependence on configuration and possible replacement in future library versions. For a secure reproducible generator, we recommend use of the rand_chacha crate directly.
use rand::{rngs::StdRng, Rng, SeedableRng};
fn main() {
let mut rng = StdRng::seed_from_u64(69420);
let x: i32 = rng.gen(); // uniform distribution
// this value could be different on you machine (not necessarily reproducible)
// and it's not guaranteed to be the same across rust&rand versions
// but it should be consistent across runs (deterministic)
assert_eq!(x, -817183091);
}