302 lines
10 KiB
Markdown
302 lines
10 KiB
Markdown
[rand.util]
|
||
|
||
# 29 Numerics library [[numerics]](./#numerics)
|
||
|
||
## 29.5 Random number generation [[rand]](rand#util)
|
||
|
||
### 29.5.8 Utilities [rand.util]
|
||
|
||
#### [29.5.8.1](#seedseq) Class seed_seq [[rand.util.seedseq]](rand.util.seedseq)
|
||
|
||
[ð](#lib:seed_seq)
|
||
|
||
namespace std {class seed_seq {public:// typesusing result_type = uint_least32_t; // constructors seed_seq() noexcept; template<class T> seed_seq(initializer_list<T> il); template<class InputIterator> seed_seq(InputIterator begin, InputIterator end); // generating functionstemplate<class RandomAccessIterator>void generate(RandomAccessIterator begin, RandomAccessIterator end); // property functions size_t size() const noexcept; template<class OutputIterator>void param(OutputIterator dest) const; // no copy functions seed_seq(const seed_seq&) = delete; void operator=(const seed_seq&) = delete; private: vector<result_type> v; // *exposition only*};}
|
||
|
||
[ð](#lib:seed_seq,constructor)
|
||
|
||
`seed_seq() noexcept;
|
||
`
|
||
|
||
[1](#seedseq-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4198)
|
||
|
||
*Postconditions*: v.empty() is true[.](#seedseq-1.sentence-1)
|
||
|
||
[ð](#lib:seed_seq,constructor_)
|
||
|
||
`template<class T>
|
||
seed_seq(initializer_list<T> il);
|
||
`
|
||
|
||
[2](#seedseq-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4211)
|
||
|
||
*Constraints*: T is an integer type[.](#seedseq-2.sentence-1)
|
||
|
||
[3](#seedseq-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4215)
|
||
|
||
*Effects*: Same as seed_seq(il.begin(), il.end())[.](#seedseq-3.sentence-1)
|
||
|
||
[ð](#lib:seed_seq,constructor__)
|
||
|
||
`template<class InputIterator>
|
||
seed_seq(InputIterator begin, InputIterator end);
|
||
`
|
||
|
||
[4](#seedseq-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4228)
|
||
|
||
*Mandates*: iterator_traits<InputIterator>::value_type is an integer type[.](#seedseq-4.sentence-1)
|
||
|
||
[5](#seedseq-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4233)
|
||
|
||
*Preconditions*: InputIterator meets the [*Cpp17InputIterator*](input.iterators#:Cpp17InputIterator "24.3.5.3 Input iterators [input.iterators]") requirements ([[input.iterators]](input.iterators "24.3.5.3 Input iterators"))[.](#seedseq-5.sentence-1)
|
||
|
||
[6](#seedseq-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4238)
|
||
|
||
*Effects*: Initializes v by the following algorithm:for (InputIterator s = begin; s != end; ++s) v.push_back((*s)mod232);
|
||
|
||
[ð](#lib:generate,seed_seq)
|
||
|
||
`template<class RandomAccessIterator>
|
||
void generate(RandomAccessIterator begin, RandomAccessIterator end);
|
||
`
|
||
|
||
[7](#seedseq-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4255)
|
||
|
||
*Mandates*: iterator_traits<RandomAccessIterator>::value_type is an unsigned integer type capable of accommodating 32-bit quantities[.](#seedseq-7.sentence-1)
|
||
|
||
[8](#seedseq-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4260)
|
||
|
||
*Preconditions*: RandomAccessIterator meets the [*Cpp17RandomAccessIterator*](random.access.iterators#:Cpp17RandomAccessIterator "24.3.5.7 Random access iterators [random.access.iterators]") requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators"))
|
||
and the requirements of a mutable iterator[.](#seedseq-8.sentence-1)
|
||
|
||
[9](#seedseq-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4266)
|
||
|
||
*Effects*: Does nothing if begin == end[.](#seedseq-9.sentence-1)
|
||
|
||
Otherwise,
|
||
with s=v.size() and n=endâbegin,
|
||
fills the supplied range [begin,end) according to the following algorithm
|
||
in which
|
||
each operation is to be carried out modulo 232,
|
||
each indexing operator applied to begin is to be taken modulo n,
|
||
and T(x) is defined as x xor(x rshift27):
|
||
|
||
- [(9.1)](#seedseq-9.1)
|
||
|
||
By way of initialization,
|
||
set each element of the range to the value 0x8b8b8b8b[.](#seedseq-9.1.sentence-1)
|
||
Additionally,
|
||
for use in subsequent steps,
|
||
let p=(nât)/2 and let q=p+t,
|
||
where
|
||
t=(nâ¥623) ? 11 : (nâ¥68) ? 7 : (nâ¥39) ? 5 : (nâ¥7) ? 3 : (nâ1)/2;
|
||
|
||
- [(9.2)](#seedseq-9.2)
|
||
|
||
With m as the larger of s+1 and n,
|
||
transform the elements of the range:
|
||
iteratively for k=0,â¦,mâ1,
|
||
calculate values
|
||
r1=1664525âT(begin[k]xorbegin[k+p]xorbegin[kâ1])r2=r1+â§âªâ¨âªâ©s, k=0kmodn+v[kâ1], 0<kâ¤skmodn, s<k and, in order,
|
||
increment begin[k+p] by r1,
|
||
increment begin[k+q] by r2,
|
||
and
|
||
set begin[k] to r2[.](#seedseq-9.2.sentence-1)
|
||
|
||
- [(9.3)](#seedseq-9.3)
|
||
|
||
Transform the elements of the range again,
|
||
beginning where the previous step ended:
|
||
iteratively for k=m,â¦,m+nâ1,
|
||
calculate values
|
||
r3=1566083941âT(begin[k]+begin[k+p]+begin[kâ1])r4=r3â(kmodn) and, in order,
|
||
update begin[k+p] by xoring it with r3,
|
||
update begin[k+q] by xoring it with r4,
|
||
and
|
||
set begin[k] to r4[.](#seedseq-9.3.sentence-1)
|
||
|
||
[10](#seedseq-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4339)
|
||
|
||
*Throws*: What and when RandomAccessIterator operations of begin and end throw[.](#seedseq-10.sentence-1)
|
||
|
||
[ð](#lib:size,seed_seq)
|
||
|
||
`size_t size() const noexcept;
|
||
`
|
||
|
||
[11](#seedseq-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4351)
|
||
|
||
*Returns*: The number of 32-bit units
|
||
that would be returned
|
||
by a call to param()[.](#seedseq-11.sentence-1)
|
||
|
||
[12](#seedseq-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4357)
|
||
|
||
*Complexity*: Constant time[.](#seedseq-12.sentence-1)
|
||
|
||
[ð](#lib:param,seed_seq)
|
||
|
||
`template<class OutputIterator>
|
||
void param(OutputIterator dest) const;
|
||
`
|
||
|
||
[13](#seedseq-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4369)
|
||
|
||
*Mandates*: Values of type result_type are writable ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")) to dest[.](#seedseq-13.sentence-1)
|
||
|
||
[14](#seedseq-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4373)
|
||
|
||
*Preconditions*: OutputIterator meets the [*Cpp17OutputIterator*](output.iterators#:Cpp17OutputIterator "24.3.5.4 Output iterators [output.iterators]") requirements ([[output.iterators]](output.iterators "24.3.5.4 Output iterators"))[.](#seedseq-14.sentence-1)
|
||
|
||
[15](#seedseq-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4378)
|
||
|
||
*Effects*: Copies the sequence of prepared 32-bit units
|
||
to the given destination,
|
||
as if by executing the following statement:copy(v.begin(), v.end(), dest);
|
||
|
||
[16](#seedseq-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4387)
|
||
|
||
*Throws*: What and when OutputIterator operations of dest throw[.](#seedseq-16.sentence-1)
|
||
|
||
#### [29.5.8.2](#canonical) Function template generate_canonical [[rand.util.canonical]](rand.util.canonical)
|
||
|
||
[ð](#lib:generate_canonical)
|
||
|
||
`template<class RealType, size_t digits, class URBG>
|
||
RealType generate_canonical(URBG& g);
|
||
`
|
||
|
||
[1](#canonical-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4404)
|
||
|
||
Let
|
||
|
||
- [(1.1)](#canonical-1.1)
|
||
|
||
r be numeric_limits<RealType>::radix,
|
||
|
||
- [(1.2)](#canonical-1.2)
|
||
|
||
R be g.max()âg.min()+1,
|
||
|
||
- [(1.3)](#canonical-1.3)
|
||
|
||
d be the smaller of digits and numeric_limits<RealType>::digits,[245](#footnote-245 "d is introduced to avoid any attempt to produce more bits of randomness than can be held in RealType.")
|
||
|
||
- [(1.4)](#canonical-1.4)
|
||
|
||
k be the smallest integer such that Rkâ¥rd, and
|
||
|
||
- [(1.5)](#canonical-1.5)
|
||
|
||
x be âRk/rdâ[.](#canonical-1.sentence-1)
|
||
|
||
An [*attempt*](#def:attempt "29.5.8.2 Function template generate_canonical [rand.util.canonical]") is k invocations of g() to obtain values g0,â¦,gkâ1, respectively,
|
||
and the calculation of a quantity S given by Formula [29.1](#eq:rand.gencanonical):
|
||
|
||
S=kâ1âi=0(giâg.min())âRi(29.1)
|
||
|
||
[2](#canonical-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4426)
|
||
|
||
*Effects*: Attempts are made until S<xrd[.](#canonical-2.sentence-1)
|
||
|
||
[*Note [1](#canonical-note-1)*:
|
||
|
||
When R is a power of r, precisely one attempt is made[.](#canonical-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[3](#canonical-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4433)
|
||
|
||
*Returns*: âS/xâ/rd[.](#canonical-3.sentence-1)
|
||
|
||
[*Note [2](#canonical-note-2)*:
|
||
|
||
The return value c satisfies0â¤c<1[.](#canonical-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#canonical-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4441)
|
||
|
||
*Throws*: What and when g throws[.](#canonical-4.sentence-1)
|
||
|
||
[5](#canonical-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4445)
|
||
|
||
*Complexity*: Exactly k invocations of g per attempt[.](#canonical-5.sentence-1)
|
||
|
||
[6](#canonical-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4449)
|
||
|
||
[*Note [3](#canonical-note-3)*:
|
||
|
||
If the values gi produced by g are uniformly distributed,
|
||
the instantiation's results are distributed as uniformly as possible[.](#canonical-6.sentence-1)
|
||
|
||
Obtaining a value in this way
|
||
can be a useful step
|
||
in the process of transforming
|
||
a value generated by a uniform random bit generator
|
||
into a value
|
||
that can be delivered by a random number distribution[.](#canonical-6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[7](#canonical-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L4461)
|
||
|
||
[*Note [4](#canonical-note-4)*:
|
||
|
||
When R is a power of r,
|
||
an implementation can avoid using an arithmetic type that is wider
|
||
than the output when computing S[.](#canonical-7.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[245)](#footnote-245)[245)](#footnoteref-245)
|
||
|
||
d is introduced to avoid any attempt
|
||
to produce more bits of randomness
|
||
than can be held in RealType[.](#footnote-245.sentence-1)
|