This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
[rand.eng.general]
# 29 Numerics library [[numerics]](./#numerics)
## 29.5 Random number generation [[rand]](rand#eng.general)
### 29.5.4 Random number engine class templates [[rand.eng]](rand.eng#general)
#### 29.5.4.1 General [rand.eng.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2595)
Each type instantiated
from a class template specified in [[rand.eng]](rand.eng "29.5.4Random number engine class templates") meets the requirements
of a [random number engine](rand.req.eng "29.5.3.4Random number engine requirements[rand.req.eng]") type[.](#1.sentence-1)
[2](#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]](rand.eng "29.5.4Random number engine class templates") is constant[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2607)
Except where specified otherwise,
no function described in [[rand.eng]](rand.eng "29.5.4Random number engine class templates") throws an exception[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2612)
Every function described in [[rand.eng]](rand.eng "29.5.4Random number engine class templates") 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[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2619)
Descriptions are provided in [[rand.eng]](rand.eng "29.5.4Random number engine class templates") only for engine operations
that are not described in [[rand.req.eng]](rand.req.eng "29.5.3.4Random number engine requirements") or for operations where there is additional semantic information[.](#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[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2631)
Each template specified in [[rand.eng]](rand.eng "29.5.4Random number engine class templates") requires one or more relationships,
involving the value(s) of its constant template parameter(s), to hold[.](#6.sentence-1)
A program instantiating any of these templates
is ill-formed
if any such required relationship fails to hold[.](#6.sentence-2)
[7](#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]](rand.eng "29.5.4Random number engine class templates") and in [[rand.adapt]](rand.adapt "29.5.5Random number engine adaptor class templates"):
- [(7.1)](#7.1)
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;
- [(7.2)](#7.2)
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[.](#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[.](#7.sentence-2)

View File

@@ -0,0 +1,88 @@
[rand.eng.lcong]
# 29 Numerics library [[numerics]](./#numerics)
## 29.5 Random number generation [[rand]](rand#eng.lcong)
### 29.5.4 Random number engine class templates [[rand.eng]](rand.eng#lcong)
#### 29.5.4.2 Class template linear_congruential_engine [rand.eng.lcong]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2670)
A linear_congruential_engine random number engine
produces unsigned integer random numbers[.](#1.sentence-1)
The state xi of a linear_congruential_engine object x is of size 1 and consists of a single integer[.](#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[.](#1.sentence-3)
[🔗](#lib:linear_congruential_engine_)
namespace std {template<class UIntType, UIntType a, UIntType c, UIntType m>class 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<class Sseq> explicit linear_congruential_engine(Sseq& q); void seed(result_type s = default_seed); template<class Sseq> 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 extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, // hostedconst linear_congruential_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, // hosted linear_congruential_engine& x); };}
[2](#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]
is numeric_limits<result_type>::max() plus 1[.](#2.sentence-1)
[*Note [1](#note-1)*:
m need not be representable
as a value of type result_type[.](#2.sentence-2)
— *end note*]
[3](#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[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2748)
The textual representation
consists of
the value of xi[.](#4.sentence-1)
[🔗](#lib:linear_congruential_engine,constructor)
`explicit linear_congruential_engine(result_type s);
`
[5](#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[.](#5.sentence-1)
[🔗](#lib:linear_congruential_engine,constructor_)
`template<class Sseq> explicit linear_congruential_engine(Sseq& q);
`
[6](#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=ˆ‘ˆ’1j=0aj+3â‹232j)modm[.](#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[.](#6.sentence-2)

141
cppdraft/rand/eng/mers.md Normal file
View File

@@ -0,0 +1,141 @@
[rand.eng.mers]
# 29 Numerics library [[numerics]](./#numerics)
## 29.5 Random number generation [[rand]](rand#eng.mers)
### 29.5.4 Random number engine class templates [[rand.eng]](rand.eng#mers)
#### 29.5.4.3 Class template mersenne_twister_engine [rand.eng.mers]
[1](#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][.](#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[.](#1.sentence-2)
[2](#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[.](#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 ℓ[.](#2.sentence-2)
The state transition is performed as follows:
- [(2.1)](#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[.](#2.1.sentence-1)
- [(2.2)](#2.2)
With α=aâ‹(Ybitand1),
set Xi to Xi+m−nxor(Yrshift1)xorα[.](#2.2.sentence-1)
The sequence X is initialized
with the help of an initialization multiplier f[.](#2.sentence-4)
[3](#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)](#3.1)
Let z1=Xixor((Xirshiftu)bitandd)[.](#3.1.sentence-1)
- [(3.2)](#3.2)
Let z2=z1xor((z1lshiftws)bitandb)[.](#3.2.sentence-1)
- [(3.3)](#3.3)
Let z3=z2xor((z2lshiftwt)bitandc)[.](#3.3.sentence-1)
- [(3.4)](#3.4)
Let z4=z3xor(z3rshiftℓ)[.](#3.4.sentence-1)
[🔗](#lib:mersenne_twister_engine_)
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:// 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<class Sseq> explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> 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 extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, // hostedconst mersenne_twister_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, // hosted mersenne_twister_engine& x); };}
[4](#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<UIntType>::digits, a <= (1u << w) - 1u, b <= (1u << w) - 1u, c <= (1u << w) - 1u, d <= (1u << w) - 1u,
and f <= (1u << w) - 1u[.](#4.sentence-1)
[5](#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[.](#5.sentence-1)
[🔗](#lib:mersenne_twister_engine,constructor)
`explicit mersenne_twister_engine(result_type value);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2941)
*Effects*: Sets ˆ’n to valuemod2w[.](#6.sentence-1)
Then, iteratively for i=ˆ’n,…,−1, sets Xi to
[‹(Xi−1xor(Xi−1rshift(ˆ’2)))+imodn]mod2w[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2954)
*Complexity*: O(n)[.](#7.sentence-1)
[🔗](#lib:mersenne_twister_engine,constructor_)
`template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
`
[8](#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 ‹k,
invokes q.generate(a+0, a+‹k) and then, iteratively for i=−n,…,−1,
sets Xi to (∑ˆ’1j=0ak(i+n)+jâ‹232j)mod2w[.](#8.sentence-1)
Finally,
if the most significant ˆ’r bits of ˆ’n are zero,
and if each of the other resulting Xi is 0,
changes ˆ’n to 2w−1[.](#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)

224
cppdraft/rand/eng/philox.md Normal file
View File

@@ -0,0 +1,224 @@
[rand.eng.philox]
# 29 Numerics library [[numerics]](./#numerics)
## 29.5 Random number generation [[rand]](rand#eng.philox)
### 29.5.4 Random number engine class templates [[rand.eng]](rand.eng#philox)
#### 29.5.4.5 Class template philox_engine [rand.eng.philox]
[1](#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[.](#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)](#1.1)
X is the interpretation of the unsigned integer [*counter*](#def:counter) valueZ:=∑ˆ’1j=0Xjâ‹2wj of nâ‹w bits,
- [(1.2)](#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.4Random number engine requirements")) is invoked,
- [(1.3)](#1.3)
Y stores a batch of output values, and
- [(1.4)](#1.4)
i is an index for an element of the sequence Y[.](#1.sentence-2)
[2](#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[.](#2.sentence-1)
[3](#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](#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[.](#4.sentence-1)
Philox applies an r-round substitution-permutation network to the values in X[.](#4.sentence-2)
A single round of the generation algorithm performs the following steps:
- [(4.1)](#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 <b>f</b>�"). 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)<br>fn(j) | | **j** | | | |
| --- | --- | --- | --- | --- | --- |
| [🔗](#tab:rand.eng.philox.f-row-2) | | 0 | 1 | 2 | 3 |
| [🔗](#tab:rand.eng.philox.f-row-3)<br>**n** | 2 | 0 | 1 | | |
| [🔗](#tab:rand.eng.philox.f-row-4)<br> | 4 | 2 | 1 | 0 | 3 |
| [🔗](#tab:rand.eng.philox.f-row-5)<br> |
[*Note [1](#note-1)*:
For n=2 the sequence is not permuted[.](#4.1.sentence-2)
— *end note*]
- [(4.2)](#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)](#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)](#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)](#4.2.3)
k=0,…,n/2−1 is the index in the sequences,
* [(4.2.4)](#4.2.4)
q=0,…,r−1 is the index of the round,
* [(4.2.5)](#4.2.5)
keyqk is the kth round key for round q, keyqk:=(Kk+qâ‹Ck)mod2w,
* [(4.2.6)](#4.2.6)
Kk are the elements of the key sequence K,
* [(4.2.7)](#4.2.7)
Mk is multipliers[k], and
* [(4.2.8)](#4.2.8)
Ck is round_consts[k].
[5](#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′[.](#5.sentence-1)
[🔗](#lib:philox_engine_)
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; // *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<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; // constructors and seeding functions 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); // 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 extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const philox_engine& x); // hostedtemplate<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, philox_engine& x); // hosted};}
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3313)
*Mandates*:
- [(6.1)](#6.1)
sizeof...(consts) == n is true, and
- [(6.2)](#6.2)
n == 2 || n == 4 is true, and
- [(6.3)](#6.3)
0 < r is true, and
- [(6.4)](#6.4)
0 < w && w <= numeric_limits<UIntType>::digits is true[.](#6.sentence-1)
[7](#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][.](#7.sentence-1)
[8](#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[.](#8.sentence-1)
[*Note [2](#note-2)*:
The stream extraction operator can reconstruct Y from K and X, as needed[.](#8.sentence-2)
— *end note*]
[🔗](#lib:philox_engine,constructor)
`explicit philox_engine(result_type value);
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3340)
*Effects*: Sets the K0 element of sequence K to valuemod2w[.](#9.sentence-1)
All elements of sequences X and K (except K0) are set to 0[.](#9.sentence-2)
The value of i is set to n−1[.](#9.sentence-3)
[🔗](#lib:philox_engine,constructor_)
`template<class Sseq> explicit philox_engine(Sseq& q);
`
[10](#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(∑ˆ’1j=0akp+jâ‹232j)mod2w[.](#10.sentence-1)
All elements of sequence X are set to 0[.](#10.sentence-2)
The value of i is set to n−1[.](#10.sentence-3)
[🔗](#lib:set_counter,philox_engine)
`void set_counter(const array<result_type, n>& c);
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3371)
*Effects*: For j=0,…,n−1 sets Xj to Cn−ˆ’jmod2w[.](#11.sentence-1)
The value of i is set to n−1[.](#11.sentence-2)
[*Note [3](#note-3)*:
The counter is the value Z introduced at the beginning of this subclause[.](#11.sentence-3)
— *end note*]

133
cppdraft/rand/eng/sub.md Normal file
View File

@@ -0,0 +1,133 @@
[rand.eng.sub]
# 29 Numerics library [[numerics]](./#numerics)
## 29.5 Random number generation [[rand]](rand#eng.sub)
### 29.5.4 Random number engine class templates [[rand.eng]](rand.eng#sub)
#### 29.5.4.4 Class template subtract_with_carry_engine [rand.eng.sub]
[1](#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[.](#1.sentence-1)
[2](#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≤Xi<m=2w;
all subscripts applied to X are to be taken modulo r[.](#2.sentence-1)
The state xi additionally consists of an integer c (known as the [*carry*](#def:carry))
whose value is either 0 or 1[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3006)
The state transition
is performed as follows:
- [(3.1)](#3.1)
Let Y=Xi−ˆ’Xi−ˆ’c[.](#3.1.sentence-1)
- [(3.2)](#3.2)
Set Xi to y=Ymodm[.](#3.2.sentence-1)
Set c to 1 if Y<0,
otherwise set c to 0[.](#3.2.sentence-2)
[*Note [1](#note-1)*:
This algorithm corresponds
to a modular linear function
of the form TA(xi)=(‹xi)modb,
where b is of the form mr−ms+1 and a=ˆ’(b−1)/m[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3027)
The generation algorithm
is given by GA(xi)=y,
where y is the value produced as a result
of advancing the engine's state as described above[.](#4.sentence-1)
[🔗](#lib:subtract_with_carry_engine_)
namespace std {template<class UIntType, size_t w, size_t s, size_t r>class 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<class Sseq> explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = 0u); template<class Sseq> 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 extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, // hostedconst subtract_with_carry_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, // hosted subtract_with_carry_engine& x); };}
[5](#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<UIntType>::digits[.](#5.sentence-1)
[6](#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[.](#6.sentence-1)
[🔗](#lib:subtract_with_carry_engine,constructor)
`explicit subtract_with_carry_engine(result_type value);
`
[7](#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[.](#7.sentence-1)
If X−1 is then 0,
sets c to 1;
otherwise sets c to 0[.](#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<uint_least32_t, 40014u, 0u, 2147483563u> e( value == 0u ? default_seed : static_cast<uint_least32_t>(value % 2147483563u));
Then, to set each Xk,
obtain new values z0,…,zn−1 from n=⌈w/32⌉ successive invocations
of e[.](#7.sentence-4)
Set Xk to (∑ˆ’1j=0zjâ‹232j)modm[.](#7.sentence-5)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3121)
*Complexity*: Exactly nâ‹r invocations
of e[.](#8.sentence-1)
[🔗](#lib:subtract_with_carry_engine,constructor_)
`template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
`
[9](#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 (∑ˆ’1j=0ak(i+r)+jâ‹232j)modm[.](#9.sentence-1)
If X−1 is then 0,
sets c to 1;
otherwise sets c to 0[.](#9.sentence-2)