std.random

Facilities for random number generation.

Disclaimer: The random number generators and API provided in this

module are not designed to be cryptographically secure, and are therefore unsuitable for cryptographic or security-related purposes such as generating authentication tokens or network sequence numbers. For such needs, please use a reputable cryptographic library instead.

The new-style generator objects hold their own state so they are immune of threading issues. The generators feature a number of well-known and well-documented methods of generating random numbers. An overall fast and reliable means to generate random numbers is the Mt19937 generator, which derives its name from "Mersenne Twister with a period of 2 to the power of 19937". In memory-constrained situations,

linear congruential generators such as MinstdRand0 and MinstdRand might be

useful. The standard library provides an alias Random for whichever generator it considers the most fit for the target environment.

In addition to random number generators, this module features distributions, which skew a generator's output statistical distribution in various ways. So far the uniform distribution for integers and real numbers have been implemented.

Source: std/random.d

Types 18

structLinearCongruentialEngine(UIntType, UIntType a, UIntType c, UIntType m) if (isUnsigned!UIntType)

Linear Congruential generator. When m = 0, no modulus is used.

Fields
bool isUniformRandomMark this as a Rng
bool hasFixedRangeDoes this generator have a fixed range? (true).
UIntType minLowest generated value (`1` if c == 0, `0` otherwise).
UIntType maxHighest generated value (modulus - 1).
UIntType multiplierThe parameters of this distribution. The random number is x = (x * multipler + increment % modulus).
UIntType incrementditto
UIntType modulusditto
bool emptyAlways `false` (random generators are infinite ranges).
Methods
private ulong gcd(ulong a, ulong b) @safe pure nothrow @nogc
private ulong primeFactorsOnly(ulong n) @safe pure nothrow @nogc
private bool properLinearCongruentialParameters(ulong m, ulong a, ulong c) @safe pure nothrow @nogc
void seed(UIntType x0 = 1) @safe pure nothrow @nogc(Re)seeds the generator.
void popFront() @safe pure nothrow @nogcAdvances the random sequence.
UIntType front() @property const @safe pure nothrow @nogcReturns the current number in the random sequence.
typeof(this) save() @property const @safe pure nothrow @nogc
Constructors
this(UIntType x0)Constructs a LinearCongruentialEngine generator seeded with `x0`.
aliasMinstdRand0 = LinearCongruentialEngine!(uint, 16_807, 0, 2_147_483_647)

Define LinearCongruentialEngine generators with well-chosen parameters. MinstdRand0 implements Park and Miller's "minimal standard" generator that uses 16807 for the multiplier. MinstdRand implements a variant that has slightly better spectral behavior by using the multiplier 48271. Both generators are rather simplistic.

aliasMinstdRand = LinearCongruentialEngine!(uint, 48_271, 0, 2_147_483_647)

ditto

structMersenneTwisterEngine(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.

Fields
bool isUniformRandomMark this as a Rng
size_t wordSizeParameters for the generator.
size_t stateSize
size_t shiftSize
size_t maskBits
UIntType xorMask
size_t temperingU
UIntType temperingD
size_t temperingS
UIntType temperingB
size_t temperingT
UIntType temperingC
size_t temperingL
UIntType initializationMultiplier
UIntType minSmallest generated value (0).
UIntType maxLargest generated value.
UIntType defaultSeedThe default seed value.
private UIntType lowerMask
private State state
bool emptyAlways `false`.
Methods
private State defaultState() @safe pure nothrow @nogcGenerates the default initial state for a Mersenne Twister; equivalent to the internal state obtained by calling `seed(defaultSeed)`
void seed()(UIntType value = defaultSeed) @safe pure nothrow @nogcSeeds a MersenneTwisterEngine object. Note: This seed function gives 2^w starting points (the lowest w bits of the value provided will be used). To allow the RNG to be started in any one of its int...
private void seedImpl(UIntType value, ref State mtState) @nogcImplementation of the seeding mechanism, which can be used with an arbitrary `State` instance
void seed(T)(T range) if (isInputRange!T && is(immutable ElementType!T == immutable UIntType))Seeds a MersenneTwisterEngine object using an InputRange.
private void seedImpl(T)(T range, ref State mtState) if (isInputRange!T && is(immutable ElementType!T == immutable UIntType))Implementation of the range-based seeding mechanism, which can be used with an arbitrary `State` instance
void popFront() @safe pure nothrow @nogcAdvances the generator.
private void popFrontImpl(ref State mtState) @nogc
UIntType front() @property @safe const pure nothrow @nogcReturns the current random value.
typeof(this) save() @property @safe const pure nothrow @nogc
Constructors
this(UIntType value)Constructs a MersenneTwisterEngine object.
Nested Templates
State
aliasMt19937 = MersenneTwisterEngine!(uint, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18, 1_812_433_253)

A MersenneTwisterEngine instantiated with the parameters of the original engine MT19937, generating uniformly-distributed 32-bit numbers with a period of 2 to the power of 19937. Recommended for random number generation unless memory is severely restricted, in which case a LinearCongruentialEngine would be the generator of choice.

aliasMt19937_64 = MersenneTwisterEngine!(ulong, 64, 312, 156, 31, 0xb5026f5aa96619e9, 29, 0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000, 43, 6_364_136_223_846_793_005)

A MersenneTwisterEngine instantiated with the parameters of the original engine MT19937-64, generating uniformly-distributed 64-bit numbers with a period of 2 to the power of 19937.

structXorshiftEngine(UIntType, uint nbits, int sa, int sb, int sc) if (isUnsigned!UIntType && !(sa > 0 && sb > 0 && sc > 0))

Xorshift generator. Implemented according to Xorshift RNGs (Marsaglia, 2003) when the size is small. For larger sizes the generator uses Sebastino Vigna's optimization of using an index to avoid needing to rotate the internal array.

Period is 2 ^^ nbits - 1 except for a legacy 192-bit uint version (see note below).

Parameters

UIntTypeWord size of this xorshift generator and the return type of opCall.
nbitsThe number of bits of state of this generator. This must be a positive multiple of the size in bits of UIntType. If nbits is large this struct may occupy slightly more memory than this so it can use a circular counter instead of shifting the entire array.
saThe direction and magnitude of the 1st shift. Positive means left, negative means right.
sbThe direction and magnitude of the 2nd shift. Positive means left, negative means right.
scThe direction and magnitude of the 3rd shift. Positive means left, negative means right.

Note

For historical compatibility when nbits == 192 and UIntType is uint

a legacy hybrid PRNG is used consisting of a 160-bit xorshift combined with a 32-bit counter. This combined generator has period equal to the least common multiple of 2^^160 - 1 and 2^^32.

Previous versions of XorshiftEngine did not provide any mechanism to specify the directions of the shifts, taking each shift as an unsigned magnitude. For backwards compatibility, because three shifts in the same direction cannot result in a full-period XorshiftEngine, when all three of sa, sb, sc, are positive XorshiftEngine treats them as unsigned magnitudes and uses shift directions to match the old behavior of XorshiftEngine`.

Not every set of shifts results in a full-period xorshift generator. The template does not currently at compile-time perform a full check for maximum period but in a future version might reject parameters resulting in shorter periods.

Fields
bool isUniformRandomMark this as a Rng
false emptyAlways `false` (random generators are infinite ranges).
UIntType minSmallest generated value.
UIntType maxLargest generated value.
bool isLegacy192Bit
(sa < 0 ? - sa : sa) a
(sb < 0 ? - sb : sb) b
(sc < 0 ? - sc : sc) c
nbits / (UIntType.sizeof * 8) N
!isLegacy192Bit && (UIntType.sizeof >= ulong.sizeof ? N > 3 : N > 4) useIndex
Methods
void seed()(UIntType x0) @safe pure nothrow @nogc(Re)seeds the generator.
UIntType front() @property const @safe pure nothrow @nogcReturns the current number in the random sequence.
void popFront() @safe pure nothrow @nogcAdvances the random sequence.
typeof(this) save() @property const @safe pure nothrow @nogcCaptures a range state.
Constructors
this(UIntType x0)Constructs a `XorshiftEngine` generator seeded with x0.
aliasXorshift32 = XorshiftEngine!(uint, 32, 13, 17, 15)

Define XorshiftEngine generators with well-chosen parameters. See each bits examples of "Xorshift RNGs". Xorshift is a Xorshift128's alias because 128bits implementation is mostly used.

aliasXorshift64 = XorshiftEngine!(uint, 64, 10, 13, 10)

ditto

aliasXorshift96 = XorshiftEngine!(uint, 96, 10, 5, 26)

ditto

aliasXorshift128 = XorshiftEngine!(uint, 128, 11, 8, 19)

ditto

aliasXorshift160 = XorshiftEngine!(uint, 160, 2, 1, 4)

ditto

aliasXorshift192 = XorshiftEngine!(uint, 192, 2, 1, 4)

ditto

ditto

The "default", "favorite", "suggested" random number generator type on the current platform. It is an alias for one of the previously-defined generators. You may want to use it if (1) you need to generate some nice random numbers, and (2) you don't care for the minutiae of the method being used.

private structRandomCoverChoices
Fields
private size_t * buffer
private size_t _length
private bool hasPackedBits
private typeof(buffer[0]).sizeof * 8 BITS_PER_WORD
Methods
void opAssign(T)(T) @disable
size_t length() const pure nothrow @nogc @safe @property
bool opIndex(size_t index) const pure nothrow @nogc @trusted
void opIndexAssign(bool value, size_t index) pure nothrow @nogc @trusted
Constructors
this(size_t numChoices)
Destructors
structRandomCover(Range, UniformRNG = void) if (isRandomAccessRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))

Covers a given range r in a random manner, i.e. goes through each element of r once and only once, just in a random order. r must be a random-access range with length.

If no random number generator is passed to randomCover, the thread-global RNG rndGen will be used internally.

Parameters

rrandom-access range to cover
rng(optional) random number generator to use; if not specified, defaults to rndGen

Returns

Range whose elements consist of the elements of r,

in random order. Will be a forward range if both r and rng are forward ranges, an

input range otherwise.
Fields
private Range _input
private RandomCoverChoices _chosen
private size_t _current
private size_t _alreadyChosen
private bool _isEmpty
Methods
@property auto ref front()
void popFront()
bool empty() @property const
structRandomSample(Range, UniformRNG = void) if (isInputRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))

Selects a random subsample out of r, containing exactly n elements. The order of elements is the same as in the original range. The total length of r must be known. If total is passed in, the total number of sample is considered to be total. Otherwise, RandomSample uses r.length.

Parameters

rrange to sample from
nnumber of elements to include in the sample; must be less than or equal to the total number of elements in r and/or the parameter total (if provided)
total(semi-optional) number of elements of r from which to select the sample (counting from the beginning); must be less than or equal to the total number of elements in r itself. May be omitted if r has the .length property and the sample is to be drawn from all elements of r.
rng(optional) random number generator to use; if not specified, defaults to rndGen

Returns

Range whose elements consist of a randomly selected subset of

the elements of r, in the same order as these elements appear in r itself. Will be a forward range if both r and rng are forward ranges, an input range otherwise.

RandomSample implements Jeffrey Scott Vitter's Algorithm D (see Vitter 1984, 1987), which selects a sample of size n in O(n) steps and requiring O(n) random variates, regardless of the size of the data being sampled. The exception to this is if traversing k elements on the input range is itself an O(k) operation (e.g. when sampling lines from an input file), in which case the sampling calculation will inevitably be of O(total).

RandomSample will throw an exception if total is verifiably less than the total number of elements available in the input, or if n > total.

If no random number generator is passed to randomSample, the thread-global RNG rndGen will be used internally.

Fields
private size_t _available
private ushort _alphaInverse
private double _Vprime
private Range _input
private size_t _index
private Skip _skip
Methods
private void initialize(size_t howMany, size_t total)
private void initializeFront()
bool empty() @property constRange primitives.
@property auto ref front()Ditto
void popFront()Ditto
size_t length() @property constDitto
size_t index() @propertyReturns the index of the visited record.
private size_t skip()
private size_t skipA()
private double newVprime(size_t remaining)
private size_t skipD()
private void prime()
Nested Templates
Skip

Functions 33

fnuint unpredictableSeed() @property @trusted nothrow @nogcA "good" seed for initializing random number engines. Initializing with unpredictableSeed makes engines generate different random number sequences every run.
fnRandom rndGen() @property ref @safe nothrow @nogcGlobal random number generator used by various functions in this module whenever no generator is specified. It is allocated per-thread and initialized to an unpredictable value for each thread.
private fnvoid initMTEngine(MTEngine)(scope ref MTEngine mt) if (is(MTEngine : MersenneTwisterEngine!Params, Params...))
fnauto uniform(string boundaries = "[)", T1, T2)(T1 a, T2 b) if (!is(CommonType!(T1, T2) == void))Generates a number between `a` and `b`. The `boundaries` parameter controls the shape of the interval (open vs. closed on either side). Valid values for `boundaries` are `"[]"`, "]", `"["`, and `"(...
fnauto uniform(string boundaries = "[)", T1, T2, UniformRandomNumberGenerator)(T1 a, T2 b, ref UniformRandomNumberGenerator urng) if (isFloatingPoint!(CommonType!(T1, T2)) && isUniformRNG!UniformRandomNumberGenerator)ditto
fnauto uniform(string boundaries = "[)", T1, T2, RandomGen)(T1 a, T2 b, ref RandomGen rng) if ((isIntegral!(CommonType!(T1, T2)) || isSomeChar!(CommonType!(T1, T2))) && isUniformRNG!RandomGen)ditto
private fnUInt _uniformIndex(UniformRNG, UInt = size_t)(const UInt k, ref UniformRNG rng) if (isUnsigned!UInt && isUniformRNG!UniformRNG)
fnauto uniform(T, UniformRandomNumberGenerator)(ref UniformRandomNumberGenerator urng) if (!is(T == enum) && (isIntegral!T || isSomeChar!T) && isUniformRNG!UniformRandomNumberGenerator)Generates a uniformly-distributed number in the range [T.min for any integral or character type `T`. If no random number generator is passed, uses the default `rndGen`.
fnauto uniform(T)() if (!is(T == enum) && (isIntegral!T || isSomeChar!T))Ditto
fnauto uniform(E, UniformRandomNumberGenerator)(ref UniformRandomNumberGenerator urng) if (is(E == enum) && isUniformRNG!UniformRandomNumberGenerator)ditto
fnauto uniform(E)() if (is(E == enum))Ditto
fnT uniform01(T = double)() if (isFloatingPoint!T)Generates a uniformly-distributed floating point number of type `T` in the range [0, 1. If no random number generator is specified, the default RNG `rndGen` will be used as the source of randomness.
fnT uniform01(T = double, UniformRNG)(ref UniformRNG rng) if (isFloatingPoint!T && isUniformRNG!UniformRNG)ditto
fnF[] uniformDistribution(F = double)(size_t n, F[] useThis = null) if (isFloatingPoint!F)Generates a uniform probability distribution of size `n`, i.e., an array of size `n` of positive numbers of type `F` that sum to `1`. If `useThis` is provided, it is used as storage.
fnauto ref choice(Range, RandomGen = Random)(Range range, ref RandomGen urng) if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)Returns a random, uniformly chosen, element `e` from the supplied Range range. If no random number generator is passed, the default `rndGen` is used.
fnauto ref choice(Range)(Range range)ditto
fnauto ref choice(Range, RandomGen = Random)(ref Range range, ref RandomGen urng) if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)ditto
fnauto ref choice(Range)(ref Range range)ditto
fnRange randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen) if (isRandomAccessRange!Range && isUniformRNG!RandomGen)Shuffles elements of `r` using `gen` as a shuffler. `r` must be a random-access range with length. If no RNG is specified, `rndGen` will be used.
fnRange randomShuffle(Range)(Range r) if (isRandomAccessRange!Range)ditto
fnRange partialShuffle(Range, RandomGen)(Range r, in size_t n, ref RandomGen gen) if (isRandomAccessRange!Range && isUniformRNG!RandomGen)Partially shuffles the elements of `r` such that upon returning r[0 .. n] is a random subset of `r` and is randomly ordered. r[n .. r.length] will contain the elements not in r[0 .. n]. These wil...
fnRange partialShuffle(Range)(Range r, in size_t n) if (isRandomAccessRange!Range)ditto
fnsize_t dice(Rng, Num)(ref Rng rnd, Num[] proportions...) if (isNumeric!Num && isForwardRange!Rng)Get a random index into a list of weights corresponding to each index
fnsize_t dice(R, Range)(ref R rnd, Range proportions) if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)Ditto
fnsize_t dice(Range)(Range proportions) if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)Ditto
fnsize_t dice(Num)(Num[] proportions...) if (isNumeric!Num)Ditto
private fnsize_t diceImpl(Rng, Range)(ref Rng rng, scope Range proportions) if (isForwardRange!Range && isNumeric!(ElementType!Range) && isForwardRange!Rng)
fnauto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng) if (isRandomAccessRange!Range && isUniformRNG!UniformRNG)Ditto
fnauto randomCover(Range)(Range r) if (isRandomAccessRange!Range)Ditto
fnauto randomSample(Range)(Range r, size_t n, size_t total) if (isInputRange!Range)Ditto
fnauto randomSample(Range)(Range r, size_t n) if (isInputRange!Range && hasLength!Range)Ditto
fnauto randomSample(Range, UniformRNG)(Range r, size_t n, size_t total, auto ref UniformRNG rng) if (isInputRange!Range && isUniformRNG!UniformRNG)Ditto
fnauto randomSample(Range, UniformRNG)(Range r, size_t n, auto ref UniformRNG rng) if (isInputRange!Range && hasLength!Range && isUniformRNG!UniformRNG)Ditto

Templates 2

tmplXorshiftEngine(UIntType, int bits, int a, int b, int c) if (isUnsigned!UIntType && a > 0 && b > 0 && c > 0)

ditto

tmplunpredictableSeed(UIntType) if (isUnsigned!UIntType)

ditto