Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!
Comments¶
rand::rngs::StdRng (currently, ChaCha block cipher with 12 rounds) is the default recommended RNG which is a trade off among speed, quality and security. While rand::rngs::StdRng is a good default choice as a secure PRNG, it might be too slow for statistical simulations where security is not of a critical concern. rand::rngs::SmallRng (currently, Xoshiro256PlusPlus on 64-bit platforms and Xoshiro128PlusPlus on 32-bit platforms) is a faster alternative for statistical simulations. Note that rand::rngs::SmallRng requires the feature
small_rng!ThreadRng (obtained by calling
rand::thread_rng()) is the default recommended RNG for parallel RNGs. It is based on rand::rngs::StdRng and leverages thread-local storage. See Parallel RNGs With Rayon in Rust for more discussions.Xoshiro256PlusPlus is considered the state-of-the-art (SOTA) PRNG for non-crypographic use cases. Specially, Xoshiro256PlusPlus supports jumping ahead, which means that it can be leveraged to implement a fast and correct parallel PRNG.
getrandom is a small cross-platform library for retrieving random data from system source.
:dep rand = { version = "0.8.5", features = [ "small_rng" ] }:dep rand_xoshiro = "0.6.0"use rand::prelude::*;let mut rng = rand::rngs::StdRng::seed_from_u64(13);
rng.gen::<f64>()0.5377847402315655let mut rng2 = rand::rngs::SmallRng::seed_from_u64(97);
rng2.gen::<f64>()0.4337581964978048Jump Xoshiro256PlusPlus Ahead¶
use rand_xoshiro::Xoshiro256PlusPlus;
let mut rng1 = Xoshiro256PlusPlus::seed_from_u64(12397);
let mut rng2 = rng1.clone();
rng2.jump();
let mut rng3 = rng2.clone();
rng3.jump();Xoshiro256PlusPlus { s: [16294208416658607535, 7960286522194355700, 487617019471545679, 17909611376780542444] }sample¶
The most generic way to sample a value from a specific distribution
is to use the method rng.sample.
Sample from a Discrete Uniform Distribution¶
Basically you define a discrete uniform distribution
and pass it to the method rng.sample.
Question: what is difference among
Uniform::new(0u64, 10),
Uniform::new(0u32, 10),
and
Uniform::new(0u16, 10)?
use rand::distributions::Uniform;
rng.sample(Uniform::new(10u32, 15))11use rand::distributions::Uniform;
rng.sample(Uniform::new(10u16, 15))12use rand::distributions::Uniform;
rng.sample(Uniform::new(10u32, 11))10Random Permutation¶
To generate a random permutation, you have to use the method rand::seq::index::sample . Notice that the returned result is a IndexVec rather than an iterator.
IndexVec is a thin Enum wrapper around Vec.
IndexVec does NOT implement
std:ops::Indexeven though it has aindexmethod.IndexVec can be converted to a Vec using the method
into_vec.
let iv = rand::seq::index::sample(&mut rng, 10, 3);
ivU32([1, 9, 0])IndexVec does not support brackets for accessing elements.
iv[0]
cannot index into a value of type `IndexVec`You can access elements of an IndexVec using the index method.
iv.index(0)1rand::seq::index::sample(&mut rng, 10, 3).into_vec()[7, 0, 2]Shuffle a Vector¶
let mut nums: Vec<i32> = (1..100).collect();
nums.shuffle(&mut rng);println!{"{:?}", nums}[97, 77, 51, 29, 23, 96, 7, 44, 99, 79, 9, 67, 72, 37, 13, 86, 6, 65, 74, 60, 58, 28, 57, 35, 10, 76, 92, 50, 56, 98, 19, 36, 88, 30, 48, 66, 90, 45, 25, 43, 38, 11, 81, 40, 18, 95, 49, 85, 31, 21, 27, 20, 15, 17, 24, 54, 84, 94, 62, 59, 69, 3, 2, 8, 4, 87, 61, 73, 5, 1, 26, 22, 68, 33, 91, 82, 55, 64, 32, 14, 93, 71, 42, 63, 12, 70, 53, 47, 52, 46, 80, 41, 34, 78, 83, 75, 89, 16, 39]
()Parallel RNGs¶
https://