.. default-domain:: chpl .. module:: PCGRandomLib :synopsis: Low-level PCG RNG implementation. PCGRandomLib ============ **Usage** .. code-block:: chapel use Random.PCGRandomLib; or .. code-block:: chapel import Random.PCGRandomLib; .. warning:: the 'PCGRandomLib' module is unstable and may be removed or moved in the future Low-level PCG RNG implementation. This module includes a number of low-level PCG random functions. See http://www.pcg-random.org/ and the paper, `PCG: A Family of Simple Fast Space-Efficient Statistically Good Algorithms for Random Number Generation` by M.E. O'Neill. This module provides the following low-level PCG RNGs: * :record:`pcg_setseq_64_xsh_rr_32_rng` (the default PCG RNG) * :record:`pcg_setseq_64_rxs_m_xs_64_rng` * :record:`pcg_setseq_32_rxs_m_xs_32_rng` * :record:`pcg_setseq_16_rxs_m_xs_16_rng` * :record:`pcg_setseq_8_rxs_m_xs_8_rng` * :record:`pcg_setseq_N_rxs_m_xs_N_rng` which is a generalization of the above These names come from the PCG paper and reference implementations. The first integer is the number of state bits, and the last integer is the number of output bits. The other parts describe the permutation function in the LCG. Conceptually, a PCG RNG consists of three things: * the algorithm variant (e.g. pcg_setseq_64_xsh_rr_32_rng) * the current state * the RNG sequence constant Note that the sequence constant must be odd for this generator to function correctly. The function :proc:`pcg_getvalid_inc` is available to construct an odd number based upon an arbitrary input. When using these low-level interfaces, the sequence constant is not actually stored inside the RNG. Instead, users of this interface must pass the same sequence constant used in `srandom` to each of the other calls for that RNG object. Besides storing the RNG state in the record, each of these PCG RNGs include at least the following methods: * `srandom` to initialize the state from a seed * `random` to produce the next random value * `advance` to skip ahead some number of steps in RNG generation .. record:: pcg_setseq_64_xsh_rr_32_rng Low-level PCG random number generation interface (64-bits of state, 32-bits output). This record implements the same RNG as pcg32_random_r does in PCG-C-0.94. This RNG has 64-bits of internal state and outputs 32-bits at a time. This RNG will iterate through all possible 64-bit values of state. The sequence constant chooses between 2**63 random sequences that the RNG is iterating through. .. attribute:: var state: uint(64) The RNG state .. method:: proc ref srandom(seed: uint(64), inc: uint(64)) Seed the random number generator. This function corresponds to pcg32_srandom_r. :arg seed: The initial internal state. :arg inc: The sequence constant. .. method:: proc ref random(inc: uint(64)): uint(32) Get the next 32-bit random number. This function corresponds to pcg32_random_r. :arg inc: The sequence constant (same as passed to `srandom`) :returns: 32 bits generated by the RNG. .. method:: proc ref bounded_random(inc: uint(64), bound: uint(32)) Generate a random number in [0,bound). This function corresponds to pcg32_boundedrand_r and can call the random-number generator more than once. :arg inc: The sequence constant (same as passed to `srandom`) :arg bound: The returned value will be < `bound`. :returns: a random number in [0,bound). .. method:: proc ref bounded_random_vary_inc(inc: uint(64), bound: uint(32), seed: uint(64), skip: uint(64), next_inc: uint(64), inc_increment: uint(64)) Generate a random number in [0,bound). This function corresponds to pcg32_boundedrand_r, but has one difference. Because parallel random number generation relies upon advancing to a known position, this function only advances the RNG state once per call. Where the pcg32_boundedrand_r would advance the RNG state multiple times, this function creates a new RNGs with the same initial seed but different sequence numbers and uses those when more random numbers are needed. In this way, this strategy is similar to the strategy for generating 64-bit numbers by pairing 32-bit PCG RNGs. .. note:: The `nextint` and `inc_increment` values need to define a sequence of increments that is different from other increments used. Otherwise, these streams will not be independent. .. note:: This a strategy for generating a value in a particular range that has not been subject to rigorous study and may have statistical problems. Additionally, its performance could be improved in the case that this function is called many times in a row by caching the temporary RNGs at their current position. :arg inc: The sequence constant (same as passed to `srandom`) :arg bound: The returned value will be < `bound`. :arg seed: The seed this RNG started with :arg skip: How many numbers, before this one, has this RNG generated? :arg nextinc: The first increment to pass to pcg_getvalid_inc and that should be unique for this RNG. Defaults to 100. :arg inc_increment: Advance nextinc by inc_increment each time a new value is needed. :returns: a random number in [0,bound). .. method:: proc ref advance(inc: uint(64), delta: uint(64)) Advance the RNG. Adjusts the state of the RNG to be the same as if `delta` calls were made to `random`. This function corresponds to pcg32_advance_r. :arg inc: The sequence constant (same as passed to `srandom`) :arg delta: The number of steps to jump ahead .. record:: pcg_setseq_64_rxs_m_xs_64_rng Low-level PCG random number generation interface (64-bits of state, 64-bits output). This record implements the same RNG as pcg64i_random_r does in PCG-C-0.94. This RNG has 64-bits of internal state and outputs 64-bits at a time. This generator produces each 64-bit value exactly once. This generator should be considered insecure since it reveals its entire internal state with each output. .. attribute:: var state: uint(64) The RNG state .. method:: proc srandom(seed: uint(64), inc: uint(64)) Seed the random number generator. This function corresponds to pcg64i_srandom_r. :arg seed: The initial internal state. :arg inc: The sequence constant. .. method:: proc random(inc: uint(64)): uint(64) Get the next 64-bit random number. This function corresponds to pcg64i_random_r. :arg inc: The sequence constant (same as passed to `srandom`) :returns: 64 bits generated by the RNG. .. method:: proc advance(inc: uint(64), delta: uint(64)) Advance the RNG. Adjusts the state of the RNG to be the same as if `delta` calls were made to `random`. This function corresponds to pcg64i_advance_r. :arg inc: The sequence constant (same as passed to `srandom`) :arg delta: The number of steps to jump ahead .. record:: pcg_setseq_32_rxs_m_xs_32_rng Low-level PCG random number generation interface (32-bits of state, 32-bits output). This record implements the same RNG as pcg32i_random_r does in PCG-C-0.94. This RNG has 32-bits of internal state and outputs 32-bits at a time. This generator produces each 32-bit value exactly once. This generator should be considered insecure since it reveals its entire internal state with each output. .. attribute:: var state: uint(32) The RNG state .. method:: proc srandom(seed: uint(32), inc: uint(32)) Seed the random number generator. This function corresponds to pcg32i_srandom_r. :arg seed: The initial internal state. :arg inc: The sequence constant .. method:: proc random(inc: uint(32)): uint(32) Get the next 32-bit random number. This function corresponds to pcg32i_random_r. :arg inc: The sequence constant (same as passed to `srandom`) :returns: 32 bits generated by the RNG. .. method:: proc advance(inc: uint(32), delta: uint(32)) Advance the RNG. Adjusts the state of the RNG to be the same as if `delta` calls were made to `random`. This function corresponds to pcg32i_advance_r. :arg inc: The sequence constant (same as passed to `srandom`) :arg delta: The number of steps to jump ahead .. record:: pcg_setseq_16_rxs_m_xs_16_rng Low-level PCG random number generation interface (16-bits of state, 16-bits output). This record implements the same RNG as pcg16i_random_r does in PCG-C-0.94. This RNG has 16-bits of internal state and outputs 16-bits at a time. This generator produces each 16-bit value exactly once. This generator should be considered insecure since it reveals its entire internal state with each output. .. attribute:: var state: uint(16) The RNG state .. method:: proc srandom(seed: uint(16), inc: uint(16)) Seed the random number generator. This function corresponds to pcg16i_srandom_r. :arg seed: The initial internal state. :arg inc: The sequence constant .. method:: proc random(inc: uint(16)): uint(16) Get the next 16-bit random number. This function corresponds to pcg16i_random_r. :arg inc: The sequence constant (same as passed to `srandom`) :returns: 16 bits generated by the RNG. .. method:: proc advance(inc: uint(16), delta: uint(16)) Advance the RNG. Adjusts the state of the RNG to be the same as if `delta` calls were made to `random`. This function corresponds to pcg16i_advance_r. :arg inc: The sequence constant (same as passed to `srandom`) :arg delta: The number of steps to jump ahead .. record:: pcg_setseq_8_rxs_m_xs_8_rng Low-level PCG random number generation interface (8-bits of state, 8-bits output). This record implements the same RNG as pcg8i_random_r does in PCG-C-0.94. This RNG has 8-bits of internal state and outputs 8-bits at a time. This generator produces each 8-bit value exactly once. This generator should be considered insecure since it reveals its entire internal state with each output. .. attribute:: var state: uint(8) The RNG state .. method:: proc ref srandom(seed: uint(8), inc: uint(8)) Seed the random number generator. This function corresponds to pcg16i_srandom_r. :arg seed: The initial internal state. :arg inc: The sequence constant .. method:: proc ref random(inc: uint(8)): uint(8) Get the next 16-bit random number. This function corresponds to pcg16i_random_r. :arg inc: The sequence constant (same as passed to `srandom`) :returns: 16 bits generated by the RNG. .. method:: proc advance(inc: uint(8), delta: uint(8)) Advance the RNG. Adjusts the state of the RNG to be the same as if `delta` calls were made to `random`. This function corresponds to pcg16i_advance_r. :arg inc: The sequence constant (same as passed to `srandom`) :arg delta: The number of steps to jump ahead .. record:: pcg_setseq_N_rxs_m_xs_N_rng Low-level PCG random number generation interface for N bits of state, N bits output. This generator can be useful for generating a permutation since it produces each N-bit output exactly once and N is variable. This record implements an N-bit random number generator based upon :record:`pcg_setseq_64_rxs_m_xs_64_rng`, :record:`pcg_setseq_32_rxs_m_xs_32_rng`, :record:`pcg_setseq_16_rxs_m_xs_16_rng`, :record:`pcg_setseq_8_rxs_m_xs_8_rng`, and a custom generalization of these generators. This generator always truncates its internal state to N bits. This generator should be considered insecure since it reveals its entire internal state with each output. It produces each N-bit value exactly once. .. attribute:: const N the number of bits in state and in each output random number .. attribute:: var state: uint The RNG state .. method:: proc ref srandom(seed: uint, inc: uint) Seed the random number generator. :arg seed: The initial internal state. :arg inc: The sequence constant .. method:: proc ref random(inc: uint): uint Get the next N-bit random number. :arg inc: The sequence constant (same as passed to `srandom`) :returns: N bits generated by the RNG. .. method:: proc advance(inc: uint, delta: uint) Advance the RNG. Adjusts the state of the RNG to be the same as if `delta` calls were made to `random`. :arg inc: The sequence constant (same as passed to `srandom`) :arg delta: The number of steps to jump ahead .. function:: proc pcg_getvalid_inc(initseq: uint(64)): uint(64) The `inc` field in the PCG RNG must be odd. This function arranges for that to be the case given any input.