core:prng
Seedable, reproducible pseudo-randomness for simulation, sampling, procedural generation, randomized algorithms and tests.
Three ways to ask, and they do not mix. [Rng] answers "the next value" one
word at a time and carries the derived uniform operations. [VectorRng]
answers with sixteen words at once, for a consumer that has use for all of
them. [Squares64] answers "the value at this counter", so the draw order
belongs to the caller and nothing is carried between calls.
A [Seed] is data and every constructor of one is arithmetic, so nothing
here declares an effect. Entropy lives one module away: core:secure_random
exports seed(), which carries Random.
Nothing here is cryptographic. These generators are built to pass
statistical tests at the least work per word, not to resist an adversary who
has seen their output. A token, a session identifier, a nonce, a salt or a
key comes from core:secure_random.
An algorithm named in a type is fixed: [Xoshiro256pp] emits what
xoshiro256++ emits, for a given state, forever. Everything else may change
between releases: how a Seed becomes a state, what
split derives, and how many draws an operation takes.
Synopsis
let mut rng = Xoshiro256pp::from_seed(Seed::from_u64(42));
let die = rng.random_range(1..=6);
assert 1 <= die <= 6;
assert 0.0 <= rng.random_f64() < 1.0;
let mut deck: List<i32> = [1, 2, 3, 4, 5];
rng.shuffle(&mut deck);
assert deck.len() == 5;
// The same seed replays the same stream, with no capability to declare.
let mut again = Xoshiro256pp::from_seed(Seed::from_u64(42));
assert again.random_range(1..=6) == die;
Traits
pub trait Seedable with ()
A generator that can be built from a [Seed].
fn from_seed(seed: Seed) -> Self
pub trait Rng with ()
A scalar generator: one u64 per draw, plus the uniform operations derived
from it. A shape other than uniform is a distribution and does not live here.
fn next_u64(&mut self) -> u64
The next 64 bits of the stream, every bit of them usable.
fn random_range<S: SampleRange>(&mut self, range: S) -> S::Value
A uniform value from low..<high or low..=high, by Lemire's
multiply-shift with the rare rejection.
fn random_f64(&mut self) -> f64
A uniform f64 in [0, 1), from the draw's top 53 bits.
fn random_bool(&mut self) -> bool
true or false with equal probability, from one bit of the draw.
fn shuffle<T>(&mut self, items: &mut List<T>)
Permute items in place, uniformly over all permutations (Fisher-Yates).
fn choose<T>(&mut self, items: &List<T>) -> Option<T>
A uniformly chosen element of items, or None when it is empty.
pub trait SampleRange with ()
A range that random_range can draw from: ..< or
..= over any [SampleUniform] type.
fn sample_from<R: Rng>(&self, rng: &mut R) -> Self::Value
pub trait SampleUniform with ()
An integer type a uniform range can be drawn over.
fn sample_inclusive<R: Rng>(rng: &mut R, low: Self, high: Self) -> Self
fn sample_exclusive<R: Rng>(rng: &mut R, low: Self, high: Self) -> Self
pub trait VectorRng with ()
A lane-parallel generator: sixteen u64 per call, as eight u64x2. The
width is the library's, not the engine's, so a whole-batch consumer knows it.
fn next_batch(&mut self) -> [u64x2, u64x2, u64x2, u64x2, u64x2, u64x2, u64x2, u64x2]
Structs
pub struct Seed
Two hundred and fifty-six bits of well-distributed state, and the one input every engine here takes. Nothing about it is secret.
Fields are private.
pub fn from_u64(n: u64) -> Seed
Expand one number into a seed, through SplitMix64.
Seed::from_u64(0) is as good a seed as any other.
pub fn from_bytes<B: AsByteSlice>(bytes: &B) -> Seed
Absorb any byte source — a ByteList, a ByteSlice, or a String's
UTF-8 bytes — into a seed.
pub fn from_str(s: &String) -> Seed
Absorb a string's bytes into a seed, so a world can be named rather than numbered.
pub fn split(&self, index: u64) -> Seed
Derive an independent child seed at index. Worker n derives its own
with no coordination; independence is statistical, not proven.
pub struct Xoshiro256pp
xoshiro256++ (Blackman & Vigna): four words, shifts, xors and two rotates. Period 2^256 - 1, and every 4-tuple of consecutive outputs appears once over it.
Fields are private.
pub fn jump(&mut self)
Advance 2^128 steps, in the time 256 steps take. Two streams a jump apart are provably disjoint for 2^128 draws apiece.
pub fn long_jump(&mut self)
The same, 2^192 steps on.
impl Seedable for Xoshiro256pp
fn from_seed(seed: Seed) -> Xoshiro256pp
impl Rng for Xoshiro256pp
fn next_u64(&mut self) -> u64
pub struct Squares64
Squares (Widynski, arXiv:2004.06278): the value at a counter, not the next one. A revisit regenerates it, and no two callers need agree on draw order.
Fields are private.
pub fn at(&self, counter: u64) -> u64
The value at counter. Distinct counters give unrelated values; the
same counter always gives the same one.
impl Seedable for Squares64
fn from_seed(seed: Seed) -> Squares64
pub struct XoshiroSimd
xoshiro256++ in eight lanes at once. Each lane starts 2^128 steps past the one before, so the eight streams are disjoint for 2^128 draws apiece.
Fields are private.
impl Seedable for XoshiroSimd
fn from_seed(seed: Seed) -> XoshiroSimd
impl VectorRng for XoshiroSimd
fn next_batch(&mut self) -> [u64x2, u64x2, u64x2, u64x2, u64x2, u64x2, u64x2, u64x2]
pub struct Shishua
SHISHUA: the fastest generator here, and vector-only, since its round is eight vectors wide and nothing smaller exists inside it. It has no jump.
Fields are private.
