Files
2025-10-25 03:02:53 +03:00

292 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.5Random 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.5Random 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.5Random 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=ˆ’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 ˆ’y0≤⌊y0/Œ‹ 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 ˆ’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; ‰ n0; k += 1) {do u = e() - e.min(); while (‰¥y0); S = 2w0â‹S+umod2w0;}for (k = n0; k ≠n; k += 1) {do u = e() - e.min(); while (‰¥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=⌊‹(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.5Random 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)