.. _guide_random: =============== Random Module =============== In MOCCA, the random numbers are generated in two steps. First, a :ref:`guide_random_engine` 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 :ref:`guide_random_generator`. .. _guide_random_engine: RandomEngine ------------ MOCCA implement three different pseudorandom generators: +--------------+----------+-------------------+---------------------+-----------------+ | **Name** | **Base** | **Output (bits)** | **Period** | **Streams** | +==============+==========+===================+=====================+=================+ | PCG32 | LCG | 32 | :math:`2^{64}` | :math:`2^{63}` | +--------------+----------+-------------------+---------------------+-----------------+ | PCG64 | LCG | 64 | :math:`2^{128}` | :math:`2^{127}` | +--------------+----------+-------------------+---------------------+-----------------+ | SplitMix32 | None | 32 | :math:`2^{64}` | 1 | +--------------+----------+-------------------+---------------------+-----------------+ | SplitMix64 | None | 64 | :math:`2^{64}` | 1 | +--------------+----------+-------------------+---------------------+-----------------+ | Xoroshiro128 | LSFR | 32 | :math:`2^{128} - 1` | 1 | +--------------+----------+-------------------+---------------------+-----------------+ | Xoroshiro256 | LSFR | 64 | :math:`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 :ref:`api_pcg` 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 :ref:`api_splitmix` 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 :ref:`api_xoroshiro` in the API Reference for all available methods. .. _guide_random_generator: Generator ----------- The :ref:`api_generator` then uses the random bit sequence from the :ref:`guide_random_engine` to generate samples from specific distributions, shuffle/permute containers, choose a random element from the container, etc. The ``DefaultGenerator`` uses ``PCG64`` as :ref:`guide_random_engine`. .. code:: cpp using namespace mocca::random; DefaultGenerator rng; // Creates a new DefaultGenerator with the default seed and stream int n = rng.uniform(-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 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.