292 lines
14 KiB
Markdown
292 lines
14 KiB
Markdown
[rand.adapt]
|
||
|
||
# 29 Numerics library [[numerics]](./#numerics)
|
||
|
||
## 29.5 Random number generation [[rand]](rand#adapt)
|
||
|
||
### 29.5.5 Random number engine adaptor class templates [rand.adapt]
|
||
|
||
#### [29.5.5.1](#general) General [[rand.adapt.general]](rand.adapt.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3393)
|
||
|
||
Each type instantiated
|
||
from a class template specified in [rand.adapt]
|
||
meets the requirements
|
||
of a [random number engine adaptor](rand.req.adapt "29.5.3.5 Random number engine adaptor requirements [rand.req.adapt]") type[.](#general-1.sentence-1)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3399)
|
||
|
||
Except where specified otherwise,
|
||
the complexity of each function
|
||
specified in [rand.adapt]
|
||
is constant[.](#general-2.sentence-1)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3405)
|
||
|
||
Except where specified otherwise,
|
||
no function described in [rand.adapt]
|
||
throws an exception[.](#general-3.sentence-1)
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3410)
|
||
|
||
Every function described in [rand.adapt]
|
||
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#L3417)
|
||
|
||
Descriptions are provided in [rand.adapt]
|
||
only for adaptor operations
|
||
that are not described in subclause [[rand.req.adapt]](rand.req.adapt "29.5.3.5 Random number engine adaptor 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#L3429)
|
||
|
||
Each template specified in [rand.adapt]
|
||
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)
|
||
|
||
#### [29.5.5.2](#disc) Class template discard_block_engine [[rand.adapt.disc]](rand.adapt.disc)
|
||
|
||
[1](#disc-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3443)
|
||
|
||
A discard_block_engine random number engine adaptor
|
||
produces random numbers
|
||
selected from those produced by some base engine e[.](#disc-1.sentence-1)
|
||
|
||
The state xi of a discard_block_engine engine adaptor object x consists of the state ei of its base engine e and an additional integer n[.](#disc-1.sentence-2)
|
||
|
||
The size of the state is
|
||
the size of e's state plus 1[.](#disc-1.sentence-3)
|
||
|
||
[2](#disc-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3454)
|
||
|
||
The transition algorithm
|
||
discards all but r>0 values
|
||
from each block of p ⥠r values delivered by e[.](#disc-2.sentence-1)
|
||
|
||
The state transition is performed as follows:
|
||
If n ⥠r,
|
||
advance the state of e from ei to ei+pâr and set n to 0[.](#disc-2.sentence-2)
|
||
|
||
In any case,
|
||
then increment n and advance e's then-current state ej to ej+1[.](#disc-2.sentence-3)
|
||
|
||
[3](#disc-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3467)
|
||
|
||
The generation algorithm
|
||
yields the value returned by the last invocation of e() while advancing e's state as described above[.](#disc-3.sentence-1)
|
||
|
||
[ð](#lib:discard_block_engine_)
|
||
|
||
namespace std {template<class Engine, size_t p, size_t r>class discard_block_engine {public:// typesusing result_type = typename Engine::result_type; // engine characteristicsstatic constexpr size_t block_size = p; static constexpr size_t used_block = r; static constexpr result_type min() { return Engine::min(); }static constexpr result_type max() { return Engine::max(); }// constructors and seeding functions discard_block_engine(); explicit discard_block_engine(const Engine& e); explicit discard_block_engine(Engine&& e); explicit discard_block_engine(result_type s); template<class Sseq> explicit discard_block_engine(Sseq& q); void seed(); void seed(result_type s); template<class Sseq> void seed(Sseq& q); // equality operatorsfriend bool operator==(const discard_block_engine& x, const discard_block_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // property functionsconst Engine& base() const noexcept { return e; }// inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const discard_block_engine& x); // hostedtemplate<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, discard_block_engine& x); // hostedprivate: Engine e; // *exposition only* size_t n; // *exposition only*};}
|
||
|
||
[4](#disc-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3523)
|
||
|
||
The following relations shall hold: 0 < r and r <= p[.](#disc-4.sentence-1)
|
||
|
||
[5](#disc-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3529)
|
||
|
||
The textual representation
|
||
consists of
|
||
the textual representation of e followed by
|
||
the value of n[.](#disc-5.sentence-1)
|
||
|
||
[6](#disc-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3536)
|
||
|
||
In addition to its behavior
|
||
pursuant to subclause [[rand.req.adapt]](rand.req.adapt "29.5.3.5 Random number engine adaptor requirements"),
|
||
each constructor that is not a copy constructor
|
||
sets n to 0[.](#disc-6.sentence-1)
|
||
|
||
#### [29.5.5.3](#ibits) Class template independent_bits_engine [[rand.adapt.ibits]](rand.adapt.ibits)
|
||
|
||
[1](#ibits-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3550)
|
||
|
||
An independent_bits_engine random number engine adaptor
|
||
combines random numbers
|
||
that are produced by some base engine e,
|
||
so as to produce random numbers
|
||
with a specified number of bits w[.](#ibits-1.sentence-1)
|
||
|
||
The state xi of an independent_bits_engine engine adaptor object x consists of
|
||
the state ei of its base engine e;
|
||
the size of the state is
|
||
the size of e's state[.](#ibits-1.sentence-2)
|
||
|
||
[2](#ibits-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3565)
|
||
|
||
The transition and generation algorithms
|
||
are described in terms
|
||
of the following integral constants:
|
||
|
||
- [(2.1)](#ibits-2.1)
|
||
|
||
Let R=e.max() - e.min() + 1 and m=âlog2Râ[.](#ibits-2.1.sentence-1)
|
||
|
||
- [(2.2)](#ibits-2.2)
|
||
|
||
With n as determined below,
|
||
let w0=âw/nâ, n0=nâwmodn, y0=2w0âR/2w0â,
|
||
and y1=2w0+1âR/2w0+1â[.](#ibits-2.2.sentence-1)
|
||
|
||
- [(2.3)](#ibits-2.3)
|
||
|
||
Let n=âw/mâ if and only if the relation Rây0â¤ây0/nâ holds as a result[.](#ibits-2.3.sentence-1)
|
||
Otherwise let n=1+âw/mâ[.](#ibits-2.3.sentence-2)
|
||
|
||
[*Note [1](#ibits-note-1)*:
|
||
|
||
The relation w=n0w0+(nân0)(w0+1) always holds[.](#ibits-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[3](#ibits-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3598)
|
||
|
||
The transition algorithm
|
||
is carried out by invoking e() as often as needed to obtain n0 values less than y0+e.min() and nân0 values less than y1+e.min()[.](#ibits-3.sentence-1)
|
||
|
||
[4](#ibits-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3605)
|
||
|
||
The generation algorithm
|
||
uses the values produced
|
||
while advancing the state as described above
|
||
to yield a quantity S obtained as if by the following algorithm:S = 0;for (k = 0; kâ n0; k += 1) {do u = e() - e.min(); while (uâ¥y0); S = 2w0âS+umod2w0;}for (k = n0; k â n; k += 1) {do u = e() - e.min(); while (uâ¥y1); S = 2w0+1âS+umod2w0+1;}
|
||
|
||
[ð](#lib:independent_bits_engine_)
|
||
|
||
namespace std {template<class Engine, size_t w, class UIntType>class independent_bits_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr result_type min() { return 0; }static constexpr result_type max() { return 2wâ1; }// constructors and seeding functions independent_bits_engine(); explicit independent_bits_engine(const Engine& e); explicit independent_bits_engine(Engine&& e); explicit independent_bits_engine(result_type s); template<class Sseq> explicit independent_bits_engine(Sseq& q); void seed(); void seed(result_type s); template<class Sseq> void seed(Sseq& q); // equality operatorsfriend bool operator==(const independent_bits_engine& x, const independent_bits_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // property functionsconst Engine& base() const noexcept { return e; }// inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const independent_bits_engine& x); // hostedtemplate<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, independent_bits_engine& x); // hostedprivate: Engine e; // *exposition only*};}
|
||
|
||
[5](#ibits-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3671)
|
||
|
||
The following relations shall hold: 0 < w and w <= numeric_limits<result_type>::digits[.](#ibits-5.sentence-1)
|
||
|
||
[6](#ibits-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3677)
|
||
|
||
The textual representation
|
||
consists of the textual representation of e[.](#ibits-6.sentence-1)
|
||
|
||
#### [29.5.5.4](#shuf) Class template shuffle_order_engine [[rand.adapt.shuf]](rand.adapt.shuf)
|
||
|
||
[1](#shuf-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3688)
|
||
|
||
A shuffle_order_engine random number engine adaptor
|
||
produces the same random numbers
|
||
that are produced by some base engine e,
|
||
but delivers them in a different sequence[.](#shuf-1.sentence-1)
|
||
|
||
The state xi of a shuffle_order_engine engine adaptor object x consists of
|
||
the state ei of its base engine e,
|
||
an additional value Y of the type delivered by e,
|
||
and
|
||
an additional sequence V of k values
|
||
also of the type delivered by e[.](#shuf-1.sentence-2)
|
||
|
||
The size of the state is
|
||
the size of e's state plus k+1[.](#shuf-1.sentence-3)
|
||
|
||
[2](#shuf-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3704)
|
||
|
||
The transition algorithm
|
||
permutes the values produced by e[.](#shuf-2.sentence-1)
|
||
|
||
The state transition is performed as follows:
|
||
|
||
- [(2.1)](#shuf-2.1)
|
||
|
||
Calculate an integer j=âkâ(Yâemin)emaxâemin+1â [.](#shuf-2.1.sentence-1)
|
||
|
||
- [(2.2)](#shuf-2.2)
|
||
|
||
Set Y to Vj and then set Vj to e()[.](#shuf-2.2.sentence-1)
|
||
|
||
[3](#shuf-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3720)
|
||
|
||
The generation algorithm
|
||
yields the last value of Y produced while advancing e's state as described above[.](#shuf-3.sentence-1)
|
||
|
||
[ð](#lib:shuffle_order_engine_)
|
||
|
||
namespace std {template<class Engine, size_t k>class shuffle_order_engine {public:// typesusing result_type = typename Engine::result_type; // engine characteristicsstatic constexpr size_t table_size = k; static constexpr result_type min() { return Engine::min(); }static constexpr result_type max() { return Engine::max(); }// constructors and seeding functions shuffle_order_engine(); explicit shuffle_order_engine(const Engine& e); explicit shuffle_order_engine(Engine&& e); explicit shuffle_order_engine(result_type s); template<class Sseq> explicit shuffle_order_engine(Sseq& q); void seed(); void seed(result_type s); template<class Sseq> void seed(Sseq& q); // equality operatorsfriend bool operator==(const shuffle_order_engine& x, const shuffle_order_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // property functionsconst Engine& base() const noexcept { return e; }// inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const shuffle_order_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, shuffle_order_engine& x); private: Engine e; // *exposition only* result_type V[k]; // *exposition only* result_type Y; // *exposition only*};}
|
||
|
||
[4](#shuf-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3776)
|
||
|
||
The following relation shall hold: 0 < k[.](#shuf-4.sentence-1)
|
||
|
||
[5](#shuf-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3780)
|
||
|
||
The textual representation
|
||
consists of
|
||
the textual representation of e,
|
||
followed by
|
||
the k values of V,
|
||
followed by
|
||
the value of Y[.](#shuf-5.sentence-1)
|
||
|
||
[6](#shuf-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3789)
|
||
|
||
In addition to its behavior
|
||
pursuant to subclause [[rand.req.adapt]](rand.req.adapt "29.5.3.5 Random number engine adaptor requirements"),
|
||
each constructor that is not a copy constructor
|
||
initializes V[0], …, V[k - 1] and Y,
|
||
in that order,
|
||
with values returned by successive invocations of e()[.](#shuf-6.sentence-1)
|