hap.random.generator

Implements algorithms for uniform pseudo-random number generation. Following the definition used in the C++11 Standard Template Library random header, a uniform random number generator is defined to be an Input Range whose values are unsigned integer values drawn from the closed interval [min, max], such that each value among the possible set of results has (ideally) equal probability of being next in the sequence. Pseudo-random number generators are typically implemented as Forward Ranges, but this is not a requirement.

The uniform random number generators provided by this module are implemented as final classes to ensure reference type semantics. These semantics are assumed by all other functions in the package, so user-defined value-type RNGs may fail in unexpected ways.

Non-deterministic random number generators, or random devices, are provided in a separate module (currently experimental).

License:
Boost License 1.0.

Authors:
Andrei Alexandrescu, Masahiro Nakagawa (Xorshift random generator), Joseph Rushton Wakeling

Credits:
The Mersenne Twister implementation is adapted from the C++ implementation in Boost.Random by Jens Maurer and Steven Watanabe, similarly licensed under the Boost Software License 1.0.

Source:
hap/random/generator.d

alias UniformRNGTypes = (LinearCongruentialEngine!(uint, 16807u, 0u, 2147483647u), LinearCongruentialEngine!(uint, 48271u, 0u, 2147483647u), MersenneTwisterEngine!(uint, 32LU, 351LU, 175LU, 19LU, 3433795303u, 11LU, 4294967295u, 7LU, 834054912u, 15LU, 4293197824u, 17LU, 1812433253u), MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u), MersenneTwisterEngine!(ulong, 64LU, 312LU, 156LU, 31LU, 13043109905998158313LU, 29LU, 6148914691236517205LU, 17LU, 8202884508482404352LU, 37LU, 18444473444759240704LU, 43LU, 6364136223846793005LU), XorshiftEngine!(uint, 32u, 13u, 17u, 15u), XorshiftEngine!(uint, 64u, 10u, 13u, 10u), XorshiftEngine!(uint, 128u, 11u, 8u, 19u), XorshiftEngine!(uint, 160u, 2u, 1u, 4u), XorshiftEngine!(uint, 192u, 2u, 1u, 4u));
TypeTuple of all uniform RNGs defined in this module.

alias Random = MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u).MersenneTwisterEngine;
The "default", "recommended" RNG type for the current platform, implemented as an alias to one of the generators defined elsewhere in this module. Its use is suggested if you want to generate good-quality random numbers without caring about the minutiae of the method being used. The default thread-local RNG instance rndGen is of type Random.

@property ref Random rndGen();
Global random number generator used by various functions in this package whenever no other generator is specified. It is allocated per-thread and initialized with a different unpredictable seed for each thread.

class LinearCongruentialEngine(UIntType, UIntType a, UIntType c, UIntType m) if (isUnsigned!UIntType && isIntegral!UIntType);
Linear congruential generators are some of the oldest algorithms for generating pseudo-random numbers. They tend to be fast but not of particularly high statistical quality, so their use is recommended only in very constrained circumstances, e.g. where memory is very severely restricted. Even then, consider using an Xorshift generator instead, as this should provide much higher statistical quality.

@safe this();
Constructs a LinearCongruentialEngine using the default seed configuration.

@safe this(in UIntType x0);
Constructs a LinearCongruentialEngine seeded with x0.

enum bool empty;
Always false (random number generators are infinite ranges).

const pure nothrow @property @safe UIntType front();
Returns the current pseudo-random value.

pure nothrow @safe void popFront();
Advances the pseudo-random sequence.

alias MinstdRand0 = LinearCongruentialEngine!(uint, 16807u, 0u, 2147483647u).LinearCongruentialEngine;
alias MinstdRand = LinearCongruentialEngine!(uint, 48271u, 0u, 2147483647u).LinearCongruentialEngine;
LinearCongruentialEngine generators with well-chosen parameters. MinstdRand0 implements Park and Miller's "minimal standard" generator, which uses 16807 for the multiplier. MinstdRand implements a variant that has slightly better spectral behaviour by using the multiplier 48271. Both generators are rather simplistic.

Example:
// Initialize generator seeded with constant default value
auto rng0 = new MinstdRand0;
auto n = rng0.front;  // same for each run
// Seed with an unpredictable value
rng0.seed(unpredictableSeed);
n = rng0.front;  // different across runs

// Initialize a different generator with an unpredictable seed
auto rng = new MinstdRand(unpredictableSeed);

class MersenneTwisterEngine(UIntType, size_t w, size_t n, size_t m, size_t r, UIntType a, size_t u, UIntType d, size_t s, UIntType b, size_t t, UIntType c, size_t l, UIntType f) if (isUnsigned!UIntType);
The Mersenne Twister generator, developed by Makoto Matsumoto and Takuji Nishimura (1997), allows for fast generation of high-quality pseudorandom numbers, and is widely used as a default random number generator by many programming languages, including D. The current implementation is adapted from that of Boost.Random and supports both 32- and 64-bit datatypes.

enum bool isUniformRandom;
Mark this as a uniform RNG

enum size_t wordSize;
Parameters for the generator

enum UIntType min;
Smallest generated value (0)

enum UIntType max;
Largest generated value

enum UIntType defaultSeed;
Default seed value

@safe this();
Constructs a MersenneTwisterEngine using the default seed.

@safe this(in UIntType value);
Constructs a MersenneTwisterEngine seeded with value.

enum bool empty;
Always false (random number generators are infinite ranges).

const pure nothrow @property @safe UIntType front();
Returns the current pseudo-random value.

pure nothrow @safe void popFront();
Advances the pseudo-random sequence.

alias Mt11213b = MersenneTwisterEngine!(uint, 32LU, 351LU, 175LU, 19LU, 3433795303u, 11LU, 4294967295u, 7LU, 834054912u, 15LU, 4293197824u, 17LU, 1812433253u).MersenneTwisterEngine;
alias Mt19937 = MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u).MersenneTwisterEngine;
alias Mt19937_64 = MersenneTwisterEngine!(ulong, 64LU, 312LU, 156LU, 31LU, 13043109905998158313LU, 29LU, 6148914691236517205LU, 17LU, 8202884508482404352LU, 37LU, 18444473444759240704LU, 43LU, 6364136223846793005LU).MersenneTwisterEngine;
Mersenne Twister generators with well-chosen parameters. Mt11213b offers a generator with a period of 2^11213 - 1 and a 32-bit datatype, while Mt19937 and Mt19937_64 offer generators with 32- and 64-bit datatypes respectively, both having a period of 2^19937 - 1. The three generators offer a good uniform distribution in up to 350, 623 and 311 dimensions respectively. Mt19937 is the most typical configuration, widely used in many different programming languages as a high-quality default random number generator.

Example:
// Initialize a Mersenne Twister seeded with constant default value
auto rng = new Mt19937;
auto n = rng.front;  // same for each run
// Seed with a thread-safe unpredictable value
rng.seed(unpredictableSeed);
n = rng.front;  // different across runs

For extensive information on the Mersenne Twister generator and the choices of parameters, see the Mersenne Twister homepage hosted by the Department of Mathematics at Hiroshima University.

class XorshiftEngine(UIntType, UIntType bits, UIntType a, UIntType b, UIntType c) if (isUnsigned!UIntType);
The Xorshift family of generators, developed by George Marsaglia (2003), offer high-quality random number generation with minimal storage requirements and computational cost. They are therefore highly suitable for use in low-memory environments or slower processors. The current implementation supports Xorshift random number generation with a 32-bit datatype only.

The total number of bits used to store the internal state is reflected in the statistical quality of the resulting generator. The table below lists the number of bits used by each Xorshift generator (which must be a multiple of the datatype size) and the corresponding period of the generator.

enum bool isUniformRandom;
Mark this as a Rng

enum UIntType min;
Smallest generated value (0).

enum UIntType max;
Largest generated value.

@safe this();
Constructs an XorshiftEngine using the default seed configuration.

@safe this(in UIntType x0);
Constructs an XorshiftEngine generator seeded with x0.

pure nothrow @safe void seed(UIntType x0);
(Re)seeds the generator with x0.

enum bool empty;
Always false (random number generators are infinite ranges).

const pure nothrow @property @safe UIntType front();
Returns the current pseudo-random value.

pure nothrow @safe void popFront();
Advances the pseudo-random sequence.

@property @safe typeof(this) save();
Captures a range state.

const pure nothrow @safe bool opEquals(Object rhs);
Compares against rhs for equality.

alias Xorshift32 = XorshiftEngine!(uint, 32u, 13u, 17u, 15u).XorshiftEngine;
alias Xorshift64 = XorshiftEngine!(uint, 64u, 10u, 13u, 10u).XorshiftEngine;
alias Xorshift96 = XorshiftEngine!(uint, 96u, 10u, 5u, 26u).XorshiftEngine;
alias Xorshift128 = XorshiftEngine!(uint, 128u, 11u, 8u, 19u).XorshiftEngine;
alias Xorshift160 = XorshiftEngine!(uint, 160u, 2u, 1u, 4u).XorshiftEngine;
alias Xorshift192 = XorshiftEngine!(uint, 192u, 2u, 1u, 4u).XorshiftEngine;
alias Xorshift = XorshiftEngine!(uint, 128u, 11u, 8u, 19u).XorshiftEngine;
Define XorshiftEngine generators with well-chosen parameters as provided by Marsaglia (2003). The default provided by Xorshift corresponds to the 128-bit generator as an optimal balance of statistical quality and speed.

Example:
// Initialize an Xorshift generator seeded with constant default value
auto rng = new Xorshift;
auto n = rng.front;  // same for each run

// Seed with an unpredictable value
rng.seed(unpredictableSeed);
n = rng.front;  // different across runs

@property uint unpredictableSeed();
A "good" seed for initializing random number generators. Initializing with unpredictableSeed ensures that RNGs produce different pseudo-random sequences each time they are run.

Example:
auto rng = Random(unpredictableSeed);
auto n = rng.front;