[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 {templateclass 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 explicit discard_block_engine(Sseq& q); void seed(); void seed(result_type s); template 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 extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, const discard_block_engine& x); // hostedtemplatefriend basic_istream&operator>>(basic_istream& 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 {templateclass 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 explicit independent_bits_engine(Sseq& q); void seed(); void seed(result_type s); template 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 extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, const independent_bits_engine& x); // hostedtemplatefriend basic_istream&operator>>(basic_istream& 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​::​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 {templateclass 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 explicit shuffle_order_engine(Sseq& q); void seed(); void seed(result_type s); template 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 extractorstemplatefriend basic_ostream&operator<<(basic_ostream& os, const shuffle_order_engine& x); templatefriend basic_istream&operator>>(basic_istream& 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)