Init
This commit is contained in:
83
cppdraft/rand/eng/general.md
Normal file
83
cppdraft/rand/eng/general.md
Normal 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.4 Random number engine class templates") meets the requirements
|
||||
of a [random number engine](rand.req.eng "29.5.3.4 Random 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.4 Random 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.4 Random 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.4 Random 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.4 Random number engine class templates") 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[.](#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.4 Random 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.4 Random number engine class templates") and in [[rand.adapt]](rand.adapt "29.5.5 Random 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)
|
||||
88
cppdraft/rand/eng/lcong.md
Normal file
88
cppdraft/rand/eng/lcong.md
Normal 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=(âkâ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
141
cppdraft/rand/eng/mers.md
Normal 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 Xân to valuemod2w[.](#6.sentence-1)
|
||||
|
||||
Then, iteratively for i=1ân,â¦,â1, sets Xi to
|
||||
[fâ(Xiâ1xor(Xiâ1rshift(wâ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 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[.](#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[.](#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
224
cppdraft/rand/eng/philox.md
Normal 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:=ânâ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.4 Random 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(âpâ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â1â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
133
cppdraft/rand/eng/sub.md
Normal 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âsâXiârâ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)=(aâxi)modb,
|
||||
where b is of the form mrâms+1 and a=bâ(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 (ânâ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 (âkâ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)
|
||||
Reference in New Issue
Block a user