[rand.eng] (original) (raw)
29 Numerics library [numerics]
29.5 Random number generation [rand]
29.5.4 Random number engine class templates [rand.eng]
29.5.4.1 General [rand.eng.general]
29.5.4.2 Class template linear_congruential_engine [rand.eng.lcong]
29.5.4.3 Class template mersenne_twister_engine [rand.eng.mers]
29.5.4.4 Class template subtract_with_carry_engine [rand.eng.sub]
29.5.4.5 Class template philox_engine [rand.eng.philox]
29.5.4.1 General [rand.eng.general]
Each type instantiated from a class template specified in [rand.eng] meets the requirements of a random number engine type.
Except where specified otherwise, the complexity of each function specified in [rand.eng] is constant.
Except where specified otherwise, no function described in [rand.eng] throws an exception.
Every function described in [rand.eng] that has a function parameter q of type Sseq&for a template type parameter named Sseqthat is different from type seed_seqthrows what and when the invocation of q.generate throws.
Descriptions are provided in [rand.eng] only for engine operations that are not described in [rand.req.eng]or for operations where there is additional semantic information.
In particular, declarations for copy constructors, for copy assignment operators, for streaming operators, and for equality and inequality operators are not shown in the synopses.
Each template specified in [rand.eng] requires one or more relationships, involving the value(s) of its constant template parameter(s), to hold.
A program instantiating any of these templates is ill-formed if any such required relationship fails to hold.
For every random number engine and for every random number engine adaptor Xdefined in [rand.eng] and in [rand.adapt]:
- if the constructortemplate<class Sseq> explicit X(Sseq& q);is called with a type Sseq that does not qualify as a seed sequence, then this constructor shall not participate in overload resolution;
- if the member functiontemplate<class Sseq> void seed(Sseq& q);is called with a type Sseq that does not qualify as a seed sequence, then this function shall not participate in overload resolution.
The extent to which an implementation determines that a type cannot be a seed sequence is unspecified, except that as a minimum a type shall not qualify as a seed sequence if it is implicitly convertible to X::result_type.
29.5.4.2 Class template linear_congruential_engine [rand.eng.lcong]
A linear_congruential_engine random number engine produces unsigned integer random numbers.
The state xof a linear_congruential_engine object xis of size 1and consists of a single integer.
The transition algorithm is a modular linear function of the form; the generation algorithm is .
namespace std { template<class UIntType, UIntType a, UIntType c, UIntType m> class linear_congruential_engine { public: using result_type = UIntType;static constexpr result_type multiplier = a;static constexpr result_type increment = c;static constexpr result_type modulus = m;static constexpr result_type min() { return c == 0u ? 1u: 0u; } static constexpr result_type max() { return m - 1u; } static constexpr result_type default_seed = 1u; linear_congruential_engine() : linear_congruential_engine(default_seed) {} explicit linear_congruential_engine(result_type s);template<class Sseq> explicit linear_congruential_engine(Sseq& q);void seed(result_type s = default_seed);template<class Sseq> void seed(Sseq& q);friend bool operator==(const linear_congruential_engine& x,const linear_congruential_engine& y); result_type operator()();void discard(unsigned long long z);template<class charT, class traits> friend basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const linear_congruential_engine& x);template<class charT, class traits> friend basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, linear_congruential_engine& x);};}
If the template parameterm is 0, the modulus mused throughout [rand.eng.lcong]is numeric_limits<result_type>::max() plus 1.
[Note 1:
m need not be representable as a value of type result_type.
— _end note_]
If the template parameterm is not 0, the following relations shall hold:a < mandc < m.
The textual representation consists of the value of x.
explicit linear_congruential_engine(result_type s);
Effects: If is 0 and is 0, sets the engine's state to 1, otherwise sets the engine's state to .
template<class Sseq> explicit linear_congruential_engine(Sseq& q);
Effects: With and a an array (or equivalent) of length , invokes q.generate(, ) and then computes.
If is 0 and S is 0, sets the engine's state to 1, else sets the engine's state to S.
29.5.4.3 Class template mersenne_twister_engine [rand.eng.mers]
A mersenne_twister_engine random number engine242produces unsigned integer random numbers in the closed interval .
The statexof a mersenne_twister_engine object xis of size nand consists of a sequence Xof n values of the type delivered by x; all subscripts applied to X are to be taken modulo n.
The transition algorithm employs a twisted generalized feedback shift register defined by shift values n and m, a twist value r, and a conditional xor-mask a.
To improve the uniformity of the result, the bits of the raw shift register are additionally tempered(i.e., scrambled) according to a bit-scrambling matrix defined by values u, d, s, b, t, c, and ℓ.
The state transition is performed as follows:
- Concatenate the upper bits of with the lower r bits of to obtain an unsigned integer value Y.
The sequence X is initialized with the help of an initialization multiplier f.
The generation algorithm determines the unsigned integer values as follows, then delivers as its result:
namespace std { template<class 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> class mersenne_twister_engine { public: using result_type = UIntType;static constexpr size_t word_size = w;static constexpr size_t state_size = n;static constexpr size_t shift_size = m;static constexpr size_t mask_bits = r;static constexpr UIntType xor_mask = a;static constexpr size_t tempering_u = u;static constexpr UIntType tempering_d = d;static constexpr size_t tempering_s = s;static constexpr UIntType tempering_b = b;static constexpr size_t tempering_t = t;static constexpr UIntType tempering_c = c;static constexpr size_t tempering_l = l;static constexpr UIntType initialization_multiplier = f;static constexpr result_type min() { return 0; } static constexpr result_type max() { return ; } static constexpr result_type default_seed = 5489u; mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} explicit mersenne_twister_engine(result_type value);template<class Sseq> explicit mersenne_twister_engine(Sseq& q);void seed(result_type value = default_seed);template<class Sseq> void seed(Sseq& q);friend bool operator==(const mersenne_twister_engine& x, const mersenne_twister_engine& y); result_type operator()();void discard(unsigned long long z);template<class charT, class traits> friend basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const mersenne_twister_engine& x);template<class charT, class traits> friend basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, mersenne_twister_engine& x);};}
The following relations shall hold:0 < m,m <= n,2u < w,r <= w,u <= w,s <= w,t <= w,l <= w,w <= numeric_limits<UIntType>::digits,a <= (1u << w) - 1u,b <= (1u << w) - 1u,c <= (1u << w) - 1u,d <= (1u << w) - 1u, andf <= (1u << w) - 1u.
The textual representation of xconsists of the values of , in that order.
explicit mersenne_twister_engine(result_type value);
Effects: Sets to .
Then, iteratively for , sets to
template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
Effects: With and a an array (or equivalent) of length , invokes q.generate(, ) and then, iteratively for , sets to .
Finally, if the most significant bits of are zero, and if each of the other resulting is 0, changes to .
29.5.4.4 Class template subtract_with_carry_engine [rand.eng.sub]
A subtract_with_carry_engine random number engine produces unsigned integer random numbers.
The state xof a subtract_with_carry_engine object xis of size, and consists of a sequence X of r integer values ; all subscripts applied to X are to be taken modulo r.
The state xadditionally consists of an integer c(known as the carry) whose value is either 0 or 1.
The state transition is performed as follows:
[Note 1:
This algorithm corresponds to a modular linear function of the form, where b is of the form and .
— _end note_]
The generation algorithm is given by , where y is the value produced as a result of advancing the engine's state as described above.
namespace std { template<class UIntType, size_t w, size_t s, size_t r> class subtract_with_carry_engine { public: using result_type = UIntType;static constexpr size_t word_size = w;static constexpr size_t short_lag = s;static constexpr size_t long_lag = r;static constexpr result_type min() { return 0; } static constexpr result_type max() { return ; } static constexpr uint_least32_t default_seed = 19780503u; subtract_with_carry_engine() : subtract_with_carry_engine(0u) {} explicit subtract_with_carry_engine(result_type value);template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);void seed(result_type value = 0u);template<class Sseq> void seed(Sseq& q);friend bool operator==(const subtract_with_carry_engine& x,const subtract_with_carry_engine& y); result_type operator()();void discard(unsigned long long z);template<class charT, class traits> friend basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const subtract_with_carry_engine& x);template<class charT, class traits> friend basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, subtract_with_carry_engine& x);};}
The following relations shall hold:0u < s,s < r,0 < w, andw <= numeric_limits<UIntType>::digits.
The textual representation consists of the values of, in that order, followed by c.
explicit subtract_with_carry_engine(result_type value);
Effects: Sets the values of, in that order, as specified below.
If is then 0, sets c to 1; otherwise sets c to 0.
To set the values , first construct e, a linear_congruential_engine object, as if by the following definition:linear_congruential_engine<uint_least32_t, 40014u, 0u, 2147483563u> e( value == 0u ? default_seed : static_cast<uint_least32_t>(value % 2147483563u));
Then, to set each , obtain new values from successive invocations of e.
Set to .
Complexity: Exactly invocations of e.
template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
Effects: With and a an array (or equivalent) of length , invokes q.generate(, ) and then, iteratively for , sets to .
If is then 0, sets c to 1; otherwise sets c to 0.
29.5.4.5 Class template philox_engine [rand.eng.philox]
A philox_engine random number engine produces unsigned integer random numbers in the interval [0, m), where and the template parameter w defines the range of the produced numbers.
The state of a philox_engine object consists of a sequence X of n unsigned integer values of width w, a sequence K of values of result_type, a sequence Y of n values of result_type, and a scalar i, where
- X is the interpretation of the unsigned integer counter value of bits,
- K are keys, which are generated once from the seed (see constructors below) and remain constant unless the seed function ([rand.req.eng]) is invoked,
- Y stores a batch of output values, and
- i is an index for an element of the sequence Y.
The generation algorithm returns , the value stored in the element of Y after applying the transition algorithm.
The state transition is performed as if by the following algorithm:i = i + 1 if (i == n) { Y = Philox(K, X) Z = Z + 1 i = 0 }
The Philox function maps the length- sequence K and the length-n sequence X into a length-n output sequence Y.
Philox applies an r-round substitution-permutation network to the values in X.
A single round of the generation algorithm performs the following steps:
- The output sequence of the previous round (X in case of the first round) is permuted to obtain the intermediate state V: where and is defined in Table 129.
[Note 1:
For the sequence is not permuted.
— _end note_] - The following computations are applied to the elements of the V sequence: where:
- mullo(a, b, w) is the low half of the modular multiplication of a and b:,
- mulhi(a, b, w) is the high half of the modular multiplication of a and b:,
- is the index in the sequences,
- is the index of the round,
- is the round key for round q,,
- are the elements of the key sequence K,
- is multipliers[k], and
- is round_consts[k].
After r applications of the single-round function,Philox returns the sequence .
namespace std { template<class UIntType, size_t w, size_t n, size_t r, UIntType... consts> class philox_engine { static constexpr size_t array-size = n / 2; public: using result_type = UIntType;static constexpr size_t word_size = w;static constexpr size_t word_count = n;static constexpr size_t round_count = r;static constexpr array<result_type, array-size_> multipliers;static constexpr array<result_type, _array-size> round_consts;static constexpr result_type min() { return 0; } static constexpr result_type max() { return m - 1; } static constexpr result_type default_seed = 20111115u; philox_engine() : philox_engine(default_seed) {} explicit philox_engine(result_type value);template<class Sseq> explicit philox_engine(Sseq& q);void seed(result_type value = default_seed);template<class Sseq> void seed(Sseq& q);void set_counter(const array<result_type, n>& counter);friend bool operator==(const philox_engine& x, const philox_engine& y); result_type operator()();void discard(unsigned long long z);template<class charT, class traits> friend basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const philox_engine& x); template<class charT, class traits> friend basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, philox_engine& x); };}
Mandates:
- sizeof...(consts) == n is true, and
- n == 2 || n == 4 is true, and
- 0 < r is true, and
- 0 < w && w <= numeric_limits<UIntType>::digits is true.
The template parameter pack consts represents the and constants which are grouped as follows:.
The textual representation consists of the values of, in that order.
[Note 2:
The stream extraction operator can reconstruct Y from K and X, as needed.
— _end note_]
explicit philox_engine(result_type value);
Effects: Sets the element of sequence K to .
All elements of sequences X and K (except ) are set to 0.
The value of i is set to .
template<class Sseq> explicit philox_engine(Sseq& q);
Effects: With and an array (or equivalent) a of length , invokes q.generate(a + 0, a + n / 2 * p) and then iteratively for , sets to.
All elements of sequence X are set to 0.
The value of i is set to .
void set_counter(const array<result_type, n>& c);
Effects: For sets to .
The value of i is set to .
[Note 3:
The counter is the value Z introduced at the beginning of this subclause.
— _end note_]