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>()
let mut rng2 = rand::rngs::SmallRng::seed_from_u64(97);
rng2.gen::<f64>()
Jump 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();
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))
use rand::distributions::Uniform;
rng.sample(Uniform::new(10u16, 15))
use rand::distributions::Uniform;
rng.sample(Uniform::new(10u32, 11))
Random 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::Index
even though it has aindex
method. - IndexVec can be converted to a Vec using the method
into_vec
.
let iv = rand::seq::index::sample(&mut rng, 10, 3);
iv
IndexVec does not support brackets for accessing elements.
iv[0]
You can access elements of an IndexVec using the index
method.
iv.index(0)
rand::seq::index::sample(&mut rng, 10, 3).into_vec()
Shuffle a Vector¶
let mut nums: Vec<i32> = (1..100).collect();
nums.shuffle(&mut rng);
println!{"{:?}", nums}
Parallel RNGs¶
https://crates.io/crates/rayon supports parallel RNGs. Xoshiro256PlusPlus can be used to construct parallel RNGs as it supports jumping ahead.