Random Module¶
In MOCCA, the random numbers are generated in two steps. First, a RandomEngine creates a sequence of 32 or 64 pseudorandom bits that are later transforms into random number that follows a specific probability distribution (such as Uniform and Exponential) within a specific interval by the Generator.
RandomEngine¶
MOCCA implement three different pseudorandom generators:
Name |
Base |
Output (bits) |
Period |
Streams |
---|---|---|---|---|
PCG32 |
LCG |
32 |
\(2^{64}\) |
\(2^{63}\) |
PCG64 |
LCG |
64 |
\(2^{128}\) |
\(2^{127}\) |
SplitMix32 |
None |
32 |
\(2^{64}\) |
1 |
SplitMix64 |
None |
64 |
\(2^{64}\) |
1 |
Xoroshiro128 |
LSFR |
32 |
\(2^{128} - 1\) |
1 |
Xoroshiro256 |
LSFR |
64 |
\(2^{256} - 1\) |
1 |
PCG¶
The Permuted Congruential Generator (PCG) was designed by Melissa O’Neil. The main idea of the PCG is to pass the output of a fast, well-known pseudorandom generator, such as a Linear Congruential Generator (LCG), into a permutation function to enhance its statistical properties. PCG is the default generator from the popular NumPy library. There are two RandomEngine
s from this scheme:
PCG32
(XSH-RR
variant) first applies a xor and a shift on the high bits, then performs a random rotation on the output of a 64-bit LCG.PCG64
(DXSM variant) applies a xor followed by a shift and multiplication on the output of a 128-bit LCG. It is recommend to use a compiler and platform that supports 128-bit arithmetic. Otherwise, MOCCA must emulate all the operations, which may result in a significant performance loss.
See PCG64 in the API Reference for all available methods.
SplitMix¶
The SplitMix is a fast splittable random number generator proposed by Guy L. Steele, Jr., Doug Lea, and Christine H. Flood. SplitMix is a counter-based generator that uses the MurmurHash3 finalizer as a mixing function. The main feature of the SplitMix is the ability to “split” a generator in two, i.e., generating two instances from one. MOCCA uses the “fixed” version of SplitMix (Bugs in SplitMix(es)). See SplitMix64 in the API Reference for all available methods.
Xoroshiro¶
The Xoroshiro family of random number generators was created by David Blackman and Sebastiano Vigna. Xoroshiro consists of a linear generator (i.e., a LFSR, or linear-feedback shift register) and a scrambler. A linear generator produces a bit sequence using a xor, rotate, shift and another xor. This sequence is then passed to a scrambler to improve its quality. MOCCA uses the ++
scrambler, i.e., applies a sum, a rotation and then another sum to the bit sequence. Xoroshiro is currently used in the JavaScript engines of Chrome, Safari and Firefox and it is part of Java’s random module.
The internal state of the Xoroshiro128
and Xoroshiro256
are initialized using the SplitMix
generator. See Xoroshiro256 in the API Reference for all available methods.
Generator¶
The Generator then uses the random bit sequence from the RandomEngine to generate samples from specific distributions, shuffle/permute containers, choose a random element from the container, etc. The DefaultGenerator
uses PCG64
as RandomEngine.
using namespace mocca::random;
DefaultGenerator rng; // Creates a new DefaultGenerator with the default seed and stream
int n = rng.uniform<int>(-10, 10); // Generates a random integer from U(-10, 10)
double f = rng(); // Generates a random double from U(0, 1)
double e = rng.exp(2.0); // Generates a random double from EXP with 2.0 as the rate parameter
DefaultGenerator rng2(8723, 6781); // Creates a new DefaultGenerator with seed=8723 and stream=6781
Generator<Xoroshiro128> rng3(87771); // Creates a new Generator using the Xoroshiro128 as RandomEngine with seed = 87771
When using multiple Generator
instances, it is recommended to use a hash function (such as the hash64() or hash128() methods) to create the seeds (and streams, if applicable) in order to spread them over a wider range of initialization states of the RandomEngine
and reducing the chances of similarities between the instances.