PCG Family
Permuted Congruential Generators (PCGs) are a family of RNGs which uses a linear congruential generator as the state-transition function, and uses permutation functions on tuples to produce output that is much more random than the RNG's internal state.1
PCG Type
Each PCG generator is available in four variants, based on how it applies the additive constant for its underlying LCG; the variations are:
PCGStateOneseq
(single stream): all instances use the same fixed constant, thus the RNG always somewhere in same sequence.PCGStateMCG
(mcg): adds zero, resulting in a single stream and reduced period.PCGStateSetseq
(specific stream): the constant can be changed at any time, selecting a different random sequence.PCGStateUnique
(unique stream): the constant is based on the memory address of the object, thus every RNG has its own unique sequence.
PCG Method Type
PCG_XSH_RS
: high xorshift, followed by a random shift. It's fast and is a good performer.PCG_XSH_RR
: high xorshift, followed by a random rotate. It's fast and is a good performer. Slightly better statistically thanPCG_XSH_RS
.PCG_RXS_M_XS
: fixed xorshift (to low bits), random rotate. The most statistically powerful generator, but all those steps make it slower than some of the others. (but in this package the benchmark shows it's even fast thanPCG_XSH_RS
, which is an current issue.)PCG_XSL_RR
: fixed xorshift (to low bits), random rotate. Useful for 128-bit types that are split across two CPU registers.PCG_XSL_RR_RR
: fixed xorshift (to low bits), random rotate (both parts). Useful for 128-bit types that are split across two CPU registers. Use this in need of an invertable 128-bit RNG.
Interface and Examples
An instance of PCG generator can be created by specify the state type, the output type, the method and seed. When seed is missing it is set to truly random numbers. The default output type is UInt64
, and the default method is PCG_XSH_RS
. The seed will be converted to the internal state type (a kind of unsigned integer), and for PCGs with specific stream (PCGStateSetseq
) the seed should be a Tuple
of two Integer
s. Note that not all parameter combinations are available (see PCG_LIST
). For example:
julia> using RandomNumbers.PCG julia> PCGStateOneseq(UInt64, 1234567) # create a single stream PCG, specifying the output type and seed. PCGStateOneseq{UInt128,Val{:XSH_RS},UInt64}(0xa10d40ffc2b1e573e589b22b2450d1fd) julia> PCGStateUnique(PCG_RXS_M_XS, 1234567); # unique stream PCG, specifying the method and seed. julia> PCGStateSetseq(UInt32, PCG_XSH_RR, (1234567, 7654321)) PCGStateSetseq{UInt64,Val{:XSH_RR},UInt32}(0xfc77de2cd901ff85, 0x0000000000e99763)
bounded_rand
is provided by this module, in which the bound is must an integer in the output type:
julia> r = PCGStateOneseq(1234567) PCGStateOneseq{UInt128,Val{:XSH_RS},UInt64}(0xa10d40ffc2b1e573e589b22b2450d1fd) julia> [bounded_rand(r, UInt64(100)) for i in 1:6] 6-element Array{UInt64,1}: 0x0000000000000012 0x000000000000000a 0x000000000000002e 0x0000000000000049 0x0000000000000043 0x000000000000002b
PCG also has an advance!
function, used to advance the state of a PCG instance.
julia> import Random julia> Random.seed!(r, 1234567); julia> rand(r, 4) 4-element Array{Float64,1}: 0.5716257379273757 0.9945058856417783 0.8886220302794352 0.08763836824057081 julia> advance!(r, -4); julia> rand(r, 4) 4-element Array{Float64,1}: 0.5716257379273757 0.9945058856417783 0.8886220302794352 0.08763836824057081
-
O’NEILL M E. PCG: A Family of Simple Fast Space-Efficient Statistically Good Algorithms for Random Number Generation[J]. ↩