[rand.eng] # 29 Numerics library [[numerics]](./#numerics) ## 29.5 Random number generation [[rand]](rand#eng) ### 29.5.4 Random number engine class templates [rand.eng] #### [29.5.4.1](#general) General [[rand.eng.general]](rand.eng.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2595) Each type instantiated from a class template specified in [rand.eng] meets the requirements of a [random number engine](rand.req.eng "29.5.3.4 Random number engine requirements [rand.req.eng]") type[.](#general-1.sentence-1) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2601) Except where specified otherwise, the complexity of each function specified in [rand.eng] is constant[.](#general-2.sentence-1) [3](#general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2607) Except where specified otherwise, no function described in [rand.eng] throws an exception[.](#general-3.sentence-1) [4](#general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2612) Every function described in [rand.eng] that has a function parameter q of type Sseq& for a template type parameter named Sseq that is different from type seed_seq throws what and when the invocation of q.generate throws[.](#general-4.sentence-1) [5](#general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2619) Descriptions are provided in [rand.eng] only for engine operations that are not described in [[rand.req.eng]](rand.req.eng "29.5.3.4 Random number engine requirements") or for operations where there is additional semantic information[.](#general-5.sentence-1) 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[.](#general-5.sentence-2) [6](#general-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2631) Each template specified in [rand.eng] requires one or more relationships, involving the value(s) of its constant template parameter(s), to hold[.](#general-6.sentence-1) A program instantiating any of these templates is ill-formed if any such required relationship fails to hold[.](#general-6.sentence-2) [7](#general-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2639) For every random number engine and for every random number engine adaptor X defined in [rand.eng] and in [[rand.adapt]](rand.adapt "29.5.5 Random number engine adaptor class templates"): - [(7.1)](#general-7.1) if the constructortemplate 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; - [(7.2)](#general-7.2) if the member functiontemplate 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[.](#general-7.sentence-1) 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[.](#general-7.sentence-2) #### [29.5.4.2](#lcong) Class template linear_congruential_engine [[rand.eng.lcong]](rand.eng.lcong) [1](#lcong-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2670) A linear_congruential_engine random number engine produces unsigned integer random numbers[.](#lcong-1.sentence-1) The state xi of a linear_congruential_engine object x is of size 1 and consists of a single integer[.](#lcong-1.sentence-2) The transition algorithm is a modular linear function of the formTA(xi)=(aâ‹xi+c)modm; the generation algorithm is GA(xi)=xi+1[.](#lcong-1.sentence-3) [🔗](#lib:linear_congruential_engine_) namespace std {templateclass linear_congruential_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic 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; // constructors and seeding functions linear_congruential_engine() : linear_congruential_engine(default_seed) {}explicit linear_congruential_engine(result_type s); template explicit linear_congruential_engine(Sseq& q); void seed(result_type s = default_seed); template void seed(Sseq& q); // equality operatorsfriend bool operator==(const linear_congruential_engine& x, const linear_congruential_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, // hostedconst linear_congruential_engine& x); templatefriend basic_istream&operator>>(basic_istream& is, // hosted linear_congruential_engine& x); };} [2](#lcong-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2729) If the template parameterm is 0, the modulus m used throughout [[rand.eng.lcong]](#lcong "29.5.4.2 Class template linear_­congruential_­engine") is numeric_limits​::​max() plus 1[.](#lcong-2.sentence-1) [*Note [1](#lcong-note-1)*: m need not be representable as a value of type result_type[.](#lcong-2.sentence-2) — *end note*] [3](#lcong-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2740) If the template parameterm is not 0, the following relations shall hold: a < m and c < m[.](#lcong-3.sentence-1) [4](#lcong-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2748) The textual representation consists of the value of xi[.](#lcong-4.sentence-1) [🔗](#lib:linear_congruential_engine,constructor) `explicit linear_congruential_engine(result_type s); ` [5](#lcong-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2759) *Effects*: If cmodm is 0 and smodm is 0, sets the engine's state to 1, otherwise sets the engine's state to smodm[.](#lcong-5.sentence-1) [🔗](#lib:linear_congruential_engine,constructor_) `template explicit linear_congruential_engine(Sseq& q); ` [6](#lcong-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2772) *Effects*: With k=⌈log2m32⌉ and a an array (or equivalent) of length k+3, invokes q.generate(a+0, a+k+3) and then computes S=(∑k−1j=0aj+3â‹232j)modm[.](#lcong-6.sentence-1) If cmodm is 0 and S is 0, sets the engine's state to 1, else sets the engine's state to S[.](#lcong-6.sentence-2) #### [29.5.4.3](#mers) Class template mersenne_twister_engine [[rand.eng.mers]](rand.eng.mers) [1](#mers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2793) A mersenne_twister_engine random number engine[242](#footnote-242 "The name of this engine refers, in part, to a property of its period: For properly-selected values of the parameters, the period is closely related to a large Mersenne prime number.") produces unsigned integer random numbers in the closed interval [0,2w−1][.](#mers-1.sentence-1) The statexi of a mersenne_twister_engine object x is of size n and consists of a sequence X of n values of the type delivered by x; all subscripts applied to X are to be taken modulo n[.](#mers-1.sentence-2) [2](#mers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2812) 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[.](#mers-2.sentence-1) To improve the uniformity of the result, the bits of the raw shift register are additionally [*tempered*](#def:tempered) (i.e., scrambled) according to a bit-scrambling matrix defined by values u, d, s, b, t, c, and ℓ[.](#mers-2.sentence-2) The state transition is performed as follows: - [(2.1)](#mers-2.1) Concatenate the upper w−r bits of Xi−n with the lower r bits of Xi+1−n to obtain an unsigned integer value Y[.](#mers-2.1.sentence-1) - [(2.2)](#mers-2.2) With α=aâ‹(Ybitand1), set Xi to Xi+m−nxor(Yrshift1)xorα[.](#mers-2.2.sentence-1) The sequence X is initialized with the help of an initialization multiplier f[.](#mers-2.sentence-4) [3](#mers-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2838) The generation algorithm determines the unsigned integer values z1,z2,z3,z4 as follows, then delivers z4 as its result: - [(3.1)](#mers-3.1) Let z1=Xixor((Xirshiftu)bitandd)[.](#mers-3.1.sentence-1) - [(3.2)](#mers-3.2) Let z2=z1xor((z1lshiftws)bitandb)[.](#mers-3.2.sentence-1) - [(3.3)](#mers-3.3) Let z3=z2xor((z2lshiftwt)bitandc)[.](#mers-3.3.sentence-1) - [(3.4)](#mers-3.4) Let z4=z3xor(z3rshiftℓ)[.](#mers-3.4.sentence-1) [🔗](#lib:mersenne_twister_engine_) namespace std {templateclass mersenne_twister_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic 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 2w−1; }static constexpr result_type default_seed = 5489u; // constructors and seeding functions mersenne_twister_engine() : mersenne_twister_engine(default_seed) {}explicit mersenne_twister_engine(result_type value); template explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); // equality operatorsfriend bool operator==(const mersenne_twister_engine& x, const mersenne_twister_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, // hostedconst mersenne_twister_engine& x); templatefriend basic_istream&operator>>(basic_istream& is, // hosted mersenne_twister_engine& x); };} [4](#mers-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2911) The following relations shall hold: 0 < m, m <= n, 2u < w, r <= w, u <= w, s <= w, t <= w, l <= w, w <= numeric_limits​::​digits, a <= (1u << w) - 1u, b <= (1u << w) - 1u, c <= (1u << w) - 1u, d <= (1u << w) - 1u, and f <= (1u << w) - 1u[.](#mers-4.sentence-1) [5](#mers-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2929) The textual representation of xi consists of the values of Xi−n,…,Xi−1, in that order[.](#mers-5.sentence-1) [🔗](#lib:mersenne_twister_engine,constructor) `explicit mersenne_twister_engine(result_type value); ` [6](#mers-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2941) *Effects*: Sets X−n to valuemod2w[.](#mers-6.sentence-1) Then, iteratively for i=1−n,…,−1, sets Xi to [fâ‹(Xi−1xor(Xi−1rshift(w−2)))+imodn]mod2w[.](#mers-6.sentence-2) [7](#mers-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2954) *Complexity*: O(n)[.](#mers-7.sentence-1) [🔗](#lib:mersenne_twister_engine,constructor_) `template explicit mersenne_twister_engine(Sseq& q); ` [8](#mers-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2965) *Effects*: With k=⌈w/32⌉ and a an array (or equivalent) of length nâ‹k, invokes q.generate(a+0, a+nâ‹k) and then, iteratively for i=−n,…,−1, sets Xi to (∑k−1j=0ak(i+n)+jâ‹232j)mod2w[.](#mers-8.sentence-1) Finally, if the most significant w−r bits of X−n are zero, and if each of the other resulting Xi is 0, changes X−n to 2w−1[.](#mers-8.sentence-2) [242)](#footnote-242)[242)](#footnoteref-242) The name of this engine refers, in part, to a property of its period: For properly-selected values of the parameters, the period is closely related to a large Mersenne prime number[.](#footnote-242.sentence-1) #### [29.5.4.4](#sub) Class template subtract_with_carry_engine [[rand.eng.sub]](rand.eng.sub) [1](#sub-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2989) A subtract_with_carry_engine random number engine produces unsigned integer random numbers[.](#sub-1.sentence-1) [2](#sub-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2993) The state xi of a subtract_with_carry_engine object x is of sizeO(r), and consists of a sequence X of r integer values 0≤Xiclass subtract_with_carry_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic 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 m−1; }static constexpr uint_least32_t default_seed = 19780503u; // constructors and seeding functions subtract_with_carry_engine() : subtract_with_carry_engine(0u) {}explicit subtract_with_carry_engine(result_type value); template explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = 0u); template void seed(Sseq& q); // equality operatorsfriend bool operator==(const subtract_with_carry_engine& x, const subtract_with_carry_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, // hostedconst subtract_with_carry_engine& x); templatefriend basic_istream&operator>>(basic_istream& is, // hosted subtract_with_carry_engine& x); };} [5](#sub-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3079) The following relations shall hold: 0u < s, s < r, 0 < w, and w <= numeric_limits​::​digits[.](#sub-5.sentence-1) [6](#sub-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3087) The textual representation consists of the values of Xi−r,…,Xi−1, in that order, followed by c[.](#sub-6.sentence-1) [🔗](#lib:subtract_with_carry_engine,constructor) `explicit subtract_with_carry_engine(result_type value); ` [7](#sub-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3099) *Effects*: Sets the values of X−r,…,X−1, in that order, as specified below[.](#sub-7.sentence-1) If X−1 is then 0, sets c to 1; otherwise sets c to 0[.](#sub-7.sentence-2) To set the values Xk, first construct e, a linear_congruential_engine object, as if by the following definition:linear_congruential_engine e( value == 0u ? default_seed : static_cast(value % 2147483563u)); Then, to set each Xk, obtain new values z0,…,zn−1 from n=⌈w/32⌉ successive invocations of e[.](#sub-7.sentence-4) Set Xk to (∑n−1j=0zjâ‹232j)modm[.](#sub-7.sentence-5) [8](#sub-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3121) *Complexity*: Exactly nâ‹r invocations of e[.](#sub-8.sentence-1) [🔗](#lib:subtract_with_carry_engine,constructor_) `template explicit subtract_with_carry_engine(Sseq& q); ` [9](#sub-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3133) *Effects*: With k=⌈w/32⌉ and a an array (or equivalent) of length râ‹k, invokes q.generate(a+0, a+râ‹k) and then, iteratively for i=−r,…,−1, sets Xi to (∑k−1j=0ak(i+r)+jâ‹232j)modm[.](#sub-9.sentence-1) If X−1 is then 0, sets c to 1; otherwise sets c to 0[.](#sub-9.sentence-2) #### [29.5.4.5](#philox) Class template philox_engine [[rand.eng.philox]](rand.eng.philox) [1](#philox-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3154) A philox_engine random number engine produces unsigned integer random numbers in the interval [0, m), where m=2w and the template parameter w defines the range of the produced numbers[.](#philox-1.sentence-1) The state of a philox_engine object consists of a sequence X of n unsigned integer values of width w, a sequence K of n/2 values of result_type, a sequence Y of n values of result_type, and a scalar i, where - [(1.1)](#philox-1.1) X is the interpretation of the unsigned integer [*counter*](#def:counter) valueZ:=∑n−1j=0Xjâ‹2wj of nâ‹w bits, - [(1.2)](#philox-1.2) K are keys, which are generated once from the seed (see constructors below) and remain constant unless the seed function ([[rand.req.eng]](rand.req.eng "29.5.3.4 Random number engine requirements")) is invoked, - [(1.3)](#philox-1.3) Y stores a batch of output values, and - [(1.4)](#philox-1.4) i is an index for an element of the sequence Y[.](#philox-1.sentence-2) [2](#philox-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3177) The generation algorithm returns Yi, the value stored in the ith element of Y after applying the transition algorithm[.](#philox-2.sentence-1) [3](#philox-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3182) The state transition is performed as if by the following algorithm:i = i + 1if (i == n) {Y = Philox(K, X) // *see below*Z = Z + 1i = 0} [4](#philox-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3193) The Philox function maps the length-n/2 sequence K and the length-n sequence X into a length-n output sequence Y[.](#philox-4.sentence-1) Philox applies an r-round substitution-permutation network to the values in X[.](#philox-4.sentence-2) A single round of the generation algorithm performs the following steps: - [(4.1)](#philox-4.1) The output sequence X′ of the previous round (X in case of the first round) is permuted to obtain the intermediate state V:Vj=X′fn(j) where j=0,…,n−1 andfn(j) is defined in Table [129](#tab:rand.eng.philox.f "Table 129: Values for the word permutation f�"). Table [129](#tab:rand.eng.philox.f) — Values for the word permutation fn(j) [[tab:rand.eng.philox.f]](./tab:rand.eng.philox.f) | [🔗](#tab:rand.eng.philox.f-row-1)
fn(j) | | **j** | | | | | --- | --- | --- | --- | --- | --- | | [🔗](#tab:rand.eng.philox.f-row-2) | | 0 | 1 | 2 | 3 | | [🔗](#tab:rand.eng.philox.f-row-3)
**n** | 2 | 0 | 1 | | | | [🔗](#tab:rand.eng.philox.f-row-4)
| 4 | 2 | 1 | 0 | 3 | | [🔗](#tab:rand.eng.philox.f-row-5)
| [*Note [1](#philox-note-1)*: For n=2 the sequence is not permuted[.](#philox-4.1.sentence-2) — *end note*] - [(4.2)](#philox-4.2) The following computations are applied to the elements of the V sequence:X2k+0=mulhi(V2k,Mk,w)xorkeyqkxorV2k+1X2k+1=mullo(V2k,Mk,w) where: * [(4.2.1)](#philox-4.2.1) mullo(a, b, w) is the low half of the modular multiplication of a and b: (aâ‹b)mod2w, * [(4.2.2)](#philox-4.2.2) mulhi(a, b, w) is the high half of the modular multiplication of a and b: (⌊(aâ‹b)/2w⌋), * [(4.2.3)](#philox-4.2.3) k=0,…,n/2−1 is the index in the sequences, * [(4.2.4)](#philox-4.2.4) q=0,…,r−1 is the index of the round, * [(4.2.5)](#philox-4.2.5) keyqk is the kth round key for round q, keyqk:=(Kk+qâ‹Ck)mod2w, * [(4.2.6)](#philox-4.2.6) Kk are the elements of the key sequence K, * [(4.2.7)](#philox-4.2.7) Mk is multipliers[k], and * [(4.2.8)](#philox-4.2.8) Ck is round_consts[k]. [5](#philox-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3261) After r applications of the single-round function,Philox returns the sequence Y=X′[.](#philox-5.sentence-1) [🔗](#lib:philox_engine_) namespace std {templateclass philox_engine {static constexpr size_t *array-size* = n / 2; // *exposition only*public:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr size_t word_size = w; static constexpr size_t word_count = n; static constexpr size_t round_count = r; static constexpr array multipliers; static constexpr array* round_consts; static constexpr result_type min() { return 0; }static constexpr result_type max() { return m - 1; }static constexpr result_type default_seed = 20111115u; // constructors and seeding functions philox_engine() : philox_engine(default_seed) {}explicit philox_engine(result_type value); template explicit philox_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); void set_counter(const array& counter); // equality operatorsfriend bool operator==(const philox_engine& x, const philox_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, const philox_engine& x); // hostedtemplatefriend basic_istream&operator>>(basic_istream& is, philox_engine& x); // hosted};} [6](#philox-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3313) *Mandates*: - [(6.1)](#philox-6.1) sizeof...(consts) == n is true, and - [(6.2)](#philox-6.2) n == 2 || n == 4 is true, and - [(6.3)](#philox-6.3) 0 < r is true, and - [(6.4)](#philox-6.4) 0 < w && w <= numeric_limits​::​digits is true[.](#philox-6.sentence-1) [7](#philox-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3322) The template parameter pack consts represents the Mk and Ck constants which are grouped as follows:[M0,C0,M1,C1,M2,C2,…,Mn/2−1,Cn/2−1][.](#philox-7.sentence-1) [8](#philox-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3327) The textual representation consists of the values ofK0,…,Kn/2−1,X0,…,Xn−1,i, in that order[.](#philox-8.sentence-1) [*Note [2](#philox-note-2)*: The stream extraction operator can reconstruct Y from K and X, as needed[.](#philox-8.sentence-2) — *end note*] [🔗](#lib:philox_engine,constructor) `explicit philox_engine(result_type value); ` [9](#philox-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3340) *Effects*: Sets the K0 element of sequence K to valuemod2w[.](#philox-9.sentence-1) All elements of sequences X and K (except K0) are set to 0[.](#philox-9.sentence-2) The value of i is set to n−1[.](#philox-9.sentence-3) [🔗](#lib:philox_engine,constructor_) `template explicit philox_engine(Sseq& q); ` [10](#philox-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3353) *Effects*: With p=⌈w/32⌉ and an array (or equivalent) a of length (n/2)â‹p, invokes q.generate(a + 0, a + n / 2 * p) and then iteratively for k=0,…,n/2−1, sets Kk to(∑p−1j=0akp+jâ‹232j)mod2w[.](#philox-10.sentence-1) All elements of sequence X are set to 0[.](#philox-10.sentence-2) The value of i is set to n−1[.](#philox-10.sentence-3) [🔗](#lib:set_counter,philox_engine) `void set_counter(const array& c); ` [11](#philox-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3371) *Effects*: For j=0,…,n−1 sets Xj to Cn−1−jmod2w[.](#philox-11.sentence-1) The value of i is set to n−1[.](#philox-11.sentence-2) [*Note [3](#philox-note-3)*: The counter is the value Z introduced at the beginning of this subclause[.](#philox-11.sentence-3) — *end note*]