libstdc++
bits/random.tcc
Go to the documentation of this file.
1// random number generation (out of line) -*- C++ -*-
2
3// Copyright (C) 2009-2025 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/random.tcc
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{random}
28 */
29
30#ifndef _RANDOM_TCC
31#define _RANDOM_TCC 1
32
33#include <numeric> // std::accumulate and std::partial_sum
34
35namespace std _GLIBCXX_VISIBILITY(default)
36{
37_GLIBCXX_BEGIN_NAMESPACE_VERSION
38
39 /// @cond undocumented
40 // (Further) implementation-space details.
41 namespace __detail
42 {
43 // General case for x = (ax + c) mod m -- use Schrage's algorithm
44 // to avoid integer overflow.
45 //
46 // Preconditions: a > 0, m > 0.
47 //
48 // Note: only works correctly for __m % __a < __m / __a.
49 template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
50 _Tp
51 _Mod<_Tp, __m, __a, __c, false, true>::
52 __calc(_Tp __x)
53 {
54 if (__a == 1)
55 __x %= __m;
56 else
57 {
58 static const _Tp __q = __m / __a;
59 static const _Tp __r = __m % __a;
60
61 _Tp __t1 = __a * (__x % __q);
62 _Tp __t2 = __r * (__x / __q);
63 if (__t1 >= __t2)
64 __x = __t1 - __t2;
65 else
66 __x = __m - __t2 + __t1;
67 }
68
69 if (__c != 0)
70 {
71 const _Tp __d = __m - __x;
72 if (__d > __c)
73 __x += __c;
74 else
75 __x = __c - __d;
76 }
77 return __x;
78 }
79
80 template<typename _InputIterator, typename _OutputIterator,
81 typename _Tp>
82 _OutputIterator
83 __normalize(_InputIterator __first, _InputIterator __last,
84 _OutputIterator __result, const _Tp& __factor)
85 {
86 for (; __first != __last; ++__first, (void) ++__result)
87 *__result = *__first / __factor;
88 return __result;
89 }
90
91 } // namespace __detail
92 /// @endcond
93
94#if ! __cpp_inline_variables
95 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
96 constexpr _UIntType
98
99 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
100 constexpr _UIntType
102
103 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
104 constexpr _UIntType
106
107 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
108 constexpr _UIntType
109 linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
110#endif
111
112 /**
113 * Seeds the LCR with integral value @p __s, adjusted so that the
114 * ring identity is never a member of the convergence set.
115 */
116 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
117 void
120 {
121 if ((__detail::__mod<_UIntType, __m>(__c) == 0)
122 && (__detail::__mod<_UIntType, __m>(__s) == 0))
123 _M_x = 1;
124 else
125 _M_x = __detail::__mod<_UIntType, __m>(__s);
126 }
127
128 /**
129 * Seeds the LCR engine with a value generated by @p __q.
130 */
131 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
132 template<typename _Sseq>
133 auto
135 seed(_Sseq& __q)
136 -> _If_seed_seq<_Sseq>
137 {
138 const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
139 : std::__lg(__m);
140 const _UIntType __k = (__k0 + 31) / 32;
141 uint_least32_t __arr[__k + 3];
142 __q.generate(__arr + 0, __arr + __k + 3);
143 _UIntType __factor = 1u;
144 _UIntType __sum = 0u;
145 for (size_t __j = 0; __j < __k; ++__j)
146 {
147 __sum += __arr[__j + 3] * __factor;
148 __factor *= __detail::_Shift<_UIntType, 32>::__value;
149 }
150 seed(__sum);
151 }
152
153 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
154 typename _CharT, typename _Traits>
157 const linear_congruential_engine<_UIntType,
158 __a, __c, __m>& __lcr)
159 {
160 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
161
162 const typename __ios_base::fmtflags __flags = __os.flags();
163 const _CharT __fill = __os.fill();
164 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
165 __os.fill(__os.widen(' '));
166
167 __os << __lcr._M_x;
168
169 __os.flags(__flags);
170 __os.fill(__fill);
171 return __os;
172 }
173
174 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
175 typename _CharT, typename _Traits>
178 linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr)
179 {
180 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
181
182 const typename __ios_base::fmtflags __flags = __is.flags();
183 __is.flags(__ios_base::dec);
184
185 __is >> __lcr._M_x;
186
187 __is.flags(__flags);
188 return __is;
189 }
190
191#if ! __cpp_inline_variables
192 template<typename _UIntType,
193 size_t __w, size_t __n, size_t __m, size_t __r,
194 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
195 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
196 _UIntType __f>
197 constexpr size_t
198 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
199 __s, __b, __t, __c, __l, __f>::word_size;
200
201 template<typename _UIntType,
202 size_t __w, size_t __n, size_t __m, size_t __r,
203 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
204 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
205 _UIntType __f>
206 constexpr size_t
207 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
208 __s, __b, __t, __c, __l, __f>::state_size;
209
210 template<typename _UIntType,
211 size_t __w, size_t __n, size_t __m, size_t __r,
212 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
213 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
214 _UIntType __f>
215 constexpr size_t
216 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
217 __s, __b, __t, __c, __l, __f>::shift_size;
218
219 template<typename _UIntType,
220 size_t __w, size_t __n, size_t __m, size_t __r,
221 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
222 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
223 _UIntType __f>
224 constexpr size_t
225 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
226 __s, __b, __t, __c, __l, __f>::mask_bits;
227
228 template<typename _UIntType,
229 size_t __w, size_t __n, size_t __m, size_t __r,
230 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
231 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
232 _UIntType __f>
233 constexpr _UIntType
234 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
235 __s, __b, __t, __c, __l, __f>::xor_mask;
236
237 template<typename _UIntType,
238 size_t __w, size_t __n, size_t __m, size_t __r,
239 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
240 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
241 _UIntType __f>
242 constexpr size_t
243 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
244 __s, __b, __t, __c, __l, __f>::tempering_u;
245
246 template<typename _UIntType,
247 size_t __w, size_t __n, size_t __m, size_t __r,
248 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
249 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
250 _UIntType __f>
251 constexpr _UIntType
252 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
253 __s, __b, __t, __c, __l, __f>::tempering_d;
254
255 template<typename _UIntType,
256 size_t __w, size_t __n, size_t __m, size_t __r,
257 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
258 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
259 _UIntType __f>
260 constexpr size_t
261 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
262 __s, __b, __t, __c, __l, __f>::tempering_s;
263
264 template<typename _UIntType,
265 size_t __w, size_t __n, size_t __m, size_t __r,
266 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
267 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
268 _UIntType __f>
269 constexpr _UIntType
270 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
271 __s, __b, __t, __c, __l, __f>::tempering_b;
272
273 template<typename _UIntType,
274 size_t __w, size_t __n, size_t __m, size_t __r,
275 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
276 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
277 _UIntType __f>
278 constexpr size_t
279 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
280 __s, __b, __t, __c, __l, __f>::tempering_t;
281
282 template<typename _UIntType,
283 size_t __w, size_t __n, size_t __m, size_t __r,
284 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
285 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
286 _UIntType __f>
287 constexpr _UIntType
288 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
289 __s, __b, __t, __c, __l, __f>::tempering_c;
290
291 template<typename _UIntType,
292 size_t __w, size_t __n, size_t __m, size_t __r,
293 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
294 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
295 _UIntType __f>
296 constexpr size_t
297 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
298 __s, __b, __t, __c, __l, __f>::tempering_l;
299
300 template<typename _UIntType,
301 size_t __w, size_t __n, size_t __m, size_t __r,
302 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
303 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
304 _UIntType __f>
305 constexpr _UIntType
306 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
307 __s, __b, __t, __c, __l, __f>::
308 initialization_multiplier;
309
310 template<typename _UIntType,
311 size_t __w, size_t __n, size_t __m, size_t __r,
312 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
313 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
314 _UIntType __f>
315 constexpr _UIntType
316 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
317 __s, __b, __t, __c, __l, __f>::default_seed;
318#endif
319
320 template<typename _UIntType,
321 size_t __w, size_t __n, size_t __m, size_t __r,
322 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
323 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
324 _UIntType __f>
325 void
326 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
327 __s, __b, __t, __c, __l, __f>::
328 seed(result_type __sd)
329 {
330 _M_x[0] = __detail::__mod<_UIntType,
331 __detail::_Shift<_UIntType, __w>::__value>(__sd);
332
333 for (size_t __i = 1; __i < state_size; ++__i)
334 {
335 _UIntType __x = _M_x[__i - 1];
336 __x ^= __x >> (__w - 2);
337 __x *= __f;
338 __x += __detail::__mod<_UIntType, __n>(__i);
339 _M_x[__i] = __detail::__mod<_UIntType,
340 __detail::_Shift<_UIntType, __w>::__value>(__x);
341 }
342 _M_p = state_size;
343 }
344
345 template<typename _UIntType,
346 size_t __w, size_t __n, size_t __m, size_t __r,
347 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
348 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
349 _UIntType __f>
350 template<typename _Sseq>
351 auto
352 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
353 __s, __b, __t, __c, __l, __f>::
354 seed(_Sseq& __q)
355 -> _If_seed_seq<_Sseq>
356 {
357 const _UIntType __upper_mask = (~_UIntType()) << __r;
358 const size_t __k = (__w + 31) / 32;
359 uint_least32_t __arr[__n * __k];
360 __q.generate(__arr + 0, __arr + __n * __k);
361
362 bool __zero = true;
363 for (size_t __i = 0; __i < state_size; ++__i)
364 {
365 _UIntType __factor = 1u;
366 _UIntType __sum = 0u;
367 for (size_t __j = 0; __j < __k; ++__j)
368 {
369 __sum += __arr[__k * __i + __j] * __factor;
370 __factor *= __detail::_Shift<_UIntType, 32>::__value;
371 }
372 _M_x[__i] = __detail::__mod<_UIntType,
373 __detail::_Shift<_UIntType, __w>::__value>(__sum);
374
375 if (__zero)
376 {
377 if (__i == 0)
378 {
379 if ((_M_x[0] & __upper_mask) != 0u)
380 __zero = false;
381 }
382 else if (_M_x[__i] != 0u)
383 __zero = false;
384 }
385 }
386 if (__zero)
387 _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
388 _M_p = state_size;
389 }
390
391 template<typename _UIntType, size_t __w,
392 size_t __n, size_t __m, size_t __r,
393 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
394 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
395 _UIntType __f>
396 void
397 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
398 __s, __b, __t, __c, __l, __f>::
399 _M_gen_rand(void)
400 {
401 const _UIntType __upper_mask = (~_UIntType()) << __r;
402 const _UIntType __lower_mask = ~__upper_mask;
403
404 for (size_t __k = 0; __k < (__n - __m); ++__k)
405 {
406 _UIntType __y = ((_M_x[__k] & __upper_mask)
407 | (_M_x[__k + 1] & __lower_mask));
408 _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
409 ^ ((__y & 0x01) ? __a : 0));
410 }
411
412 for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
413 {
414 _UIntType __y = ((_M_x[__k] & __upper_mask)
415 | (_M_x[__k + 1] & __lower_mask));
416 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
417 ^ ((__y & 0x01) ? __a : 0));
418 }
419
420 _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
421 | (_M_x[0] & __lower_mask));
422 _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
423 ^ ((__y & 0x01) ? __a : 0));
424 _M_p = 0;
425 }
426
427 template<typename _UIntType, size_t __w,
428 size_t __n, size_t __m, size_t __r,
429 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
430 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
431 _UIntType __f>
432 void
433 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
434 __s, __b, __t, __c, __l, __f>::
435 discard(unsigned long long __z)
436 {
437 while (__z > state_size - _M_p)
438 {
439 __z -= state_size - _M_p;
440 _M_gen_rand();
441 }
442 _M_p += __z;
443 }
444
445 template<typename _UIntType, size_t __w,
446 size_t __n, size_t __m, size_t __r,
447 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
448 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
449 _UIntType __f>
450 typename
451 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
452 __s, __b, __t, __c, __l, __f>::result_type
453 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
454 __s, __b, __t, __c, __l, __f>::
455 operator()()
456 {
457 // Reload the vector - cost is O(n) amortized over n calls.
458 if (_M_p >= state_size)
459 _M_gen_rand();
460
461 // Calculate o(x(i)).
462 result_type __z = _M_x[_M_p++];
463 __z ^= (__z >> __u) & __d;
464 __z ^= (__z << __s) & __b;
465 __z ^= (__z << __t) & __c;
466 __z ^= (__z >> __l);
467
468 return __z;
469 }
470
471 template<typename _UIntType, size_t __w,
472 size_t __n, size_t __m, size_t __r,
473 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
474 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
475 _UIntType __f, typename _CharT, typename _Traits>
478 const mersenne_twister_engine<_UIntType, __w, __n, __m,
479 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
480 {
481 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
482
483 const typename __ios_base::fmtflags __flags = __os.flags();
484 const _CharT __fill = __os.fill();
485 const _CharT __space = __os.widen(' ');
486 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
487 __os.fill(__space);
488
489 for (size_t __i = 0; __i < __n; ++__i)
490 __os << __x._M_x[__i] << __space;
491 __os << __x._M_p;
492
493 __os.flags(__flags);
494 __os.fill(__fill);
495 return __os;
496 }
497
498 template<typename _UIntType, size_t __w,
499 size_t __n, size_t __m, size_t __r,
500 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
501 _UIntType __b, size_t __t, _UIntType __c, size_t __l,
502 _UIntType __f, typename _CharT, typename _Traits>
503 std::basic_istream<_CharT, _Traits>&
504 operator>>(std::basic_istream<_CharT, _Traits>& __is,
505 mersenne_twister_engine<_UIntType, __w, __n, __m,
506 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
507 {
508 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
509
510 const typename __ios_base::fmtflags __flags = __is.flags();
511 __is.flags(__ios_base::dec | __ios_base::skipws);
512
513 for (size_t __i = 0; __i < __n; ++__i)
514 __is >> __x._M_x[__i];
515 __is >> __x._M_p;
516
517 __is.flags(__flags);
518 return __is;
519 }
520
521#if ! __cpp_inline_variables
522 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
523 constexpr size_t
524 subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
525
526 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
527 constexpr size_t
528 subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
529
530 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
531 constexpr size_t
532 subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
533
534 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
535 constexpr uint_least32_t
536 subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
537#endif
538
539 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
540 void
542 seed(result_type __value)
543 {
544 // _GLIBCXX_RESOLVE_LIB_DEFECTS
545 // 3809. Is std::subtract_with_carry_engine<uint16_t> supposed to work?
546 // 4014. LWG 3809 changes behavior of some existing code
548 __lcg(__value == 0u ? default_seed : __value % 2147483563u);
549
550 const size_t __n = (__w + 31) / 32;
551
552 for (size_t __i = 0; __i < long_lag; ++__i)
553 {
554 _UIntType __sum = 0u;
555 _UIntType __factor = 1u;
556 for (size_t __j = 0; __j < __n; ++__j)
557 {
558 __sum += __detail::__mod<uint_least32_t,
559 __detail::_Shift<uint_least32_t, 32>::__value>
560 (__lcg()) * __factor;
561 __factor *= __detail::_Shift<_UIntType, 32>::__value;
562 }
563 _M_x[__i] = __detail::__mod<_UIntType,
564 __detail::_Shift<_UIntType, __w>::__value>(__sum);
565 }
566 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
567 _M_p = 0;
568 }
569
570 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
571 template<typename _Sseq>
572 auto
574 seed(_Sseq& __q)
575 -> _If_seed_seq<_Sseq>
576 {
577 const size_t __k = (__w + 31) / 32;
578 uint_least32_t __arr[__r * __k];
579 __q.generate(__arr + 0, __arr + __r * __k);
580
581 for (size_t __i = 0; __i < long_lag; ++__i)
582 {
583 _UIntType __sum = 0u;
584 _UIntType __factor = 1u;
585 for (size_t __j = 0; __j < __k; ++__j)
586 {
587 __sum += __arr[__k * __i + __j] * __factor;
588 __factor *= __detail::_Shift<_UIntType, 32>::__value;
589 }
590 _M_x[__i] = __detail::__mod<_UIntType,
591 __detail::_Shift<_UIntType, __w>::__value>(__sum);
592 }
593 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
594 _M_p = 0;
595 }
596
597 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
599 result_type
602 {
603 // Derive short lag index from current index.
604 long __ps = _M_p - short_lag;
605 if (__ps < 0)
606 __ps += long_lag;
607
608 // Calculate new x(i) without overflow or division.
609 // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry
610 // cannot overflow.
611 _UIntType __xi;
612 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
613 {
614 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
615 _M_carry = 0;
616 }
617 else
618 {
619 __xi = (__detail::_Shift<_UIntType, __w>::__value
620 - _M_x[_M_p] - _M_carry + _M_x[__ps]);
621 _M_carry = 1;
622 }
623 _M_x[_M_p] = __xi;
624
625 // Adjust current index to loop around in ring buffer.
626 if (++_M_p >= long_lag)
627 _M_p = 0;
628
629 return __xi;
630 }
631
632 template<typename _UIntType, size_t __w, size_t __s, size_t __r,
633 typename _CharT, typename _Traits>
636 const subtract_with_carry_engine<_UIntType,
637 __w, __s, __r>& __x)
638 {
639 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
640
641 const typename __ios_base::fmtflags __flags = __os.flags();
642 const _CharT __fill = __os.fill();
643 const _CharT __space = __os.widen(' ');
644 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
645 __os.fill(__space);
646
647 for (size_t __i = 0; __i < __r; ++__i)
648 __os << __x._M_x[__i] << __space;
649 __os << __x._M_carry << __space << __x._M_p;
650
651 __os.flags(__flags);
652 __os.fill(__fill);
653 return __os;
654 }
655
656 template<typename _UIntType, size_t __w, size_t __s, size_t __r,
657 typename _CharT, typename _Traits>
660 subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x)
661 {
662 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
663
664 const typename __ios_base::fmtflags __flags = __is.flags();
665 __is.flags(__ios_base::dec | __ios_base::skipws);
666
667 for (size_t __i = 0; __i < __r; ++__i)
668 __is >> __x._M_x[__i];
669 __is >> __x._M_carry;
670 __is >> __x._M_p;
671
672 __is.flags(__flags);
673 return __is;
674 }
675
676#if ! __cpp_inline_variables
677 template<typename _RandomNumberEngine, size_t __p, size_t __r>
678 constexpr size_t
679 discard_block_engine<_RandomNumberEngine, __p, __r>::block_size;
680
681 template<typename _RandomNumberEngine, size_t __p, size_t __r>
682 constexpr size_t
683 discard_block_engine<_RandomNumberEngine, __p, __r>::used_block;
684#endif
685
686 template<typename _RandomNumberEngine, size_t __p, size_t __r>
687 typename discard_block_engine<_RandomNumberEngine,
688 __p, __r>::result_type
691 {
692 if (_M_n >= used_block)
693 {
694 _M_b.discard(block_size - _M_n);
695 _M_n = 0;
696 }
697 ++_M_n;
698 return _M_b();
699 }
700
701 template<typename _RandomNumberEngine, size_t __p, size_t __r,
702 typename _CharT, typename _Traits>
705 const discard_block_engine<_RandomNumberEngine,
706 __p, __r>& __x)
707 {
708 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
709
710 const typename __ios_base::fmtflags __flags = __os.flags();
711 const _CharT __fill = __os.fill();
712 const _CharT __space = __os.widen(' ');
713 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
714 __os.fill(__space);
715
716 __os << __x.base() << __space << __x._M_n;
717
718 __os.flags(__flags);
719 __os.fill(__fill);
720 return __os;
721 }
722
723 template<typename _RandomNumberEngine, size_t __p, size_t __r,
724 typename _CharT, typename _Traits>
727 discard_block_engine<_RandomNumberEngine, __p, __r>& __x)
728 {
729 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
730
731 const typename __ios_base::fmtflags __flags = __is.flags();
732 __is.flags(__ios_base::dec | __ios_base::skipws);
733
734 __is >> __x._M_b >> __x._M_n;
735
736 __is.flags(__flags);
737 return __is;
738 }
739
740
741 template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
743 result_type
746 {
747 typedef typename _RandomNumberEngine::result_type _Eresult_type;
748 const _Eresult_type __r
749 = (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max()
750 ? _M_b.max() - _M_b.min() + 1 : 0);
751 const unsigned __edig = std::numeric_limits<_Eresult_type>::digits;
752 const unsigned __m = __r ? std::__lg(__r) : __edig;
753
755 __ctype;
756 const unsigned __cdig = std::numeric_limits<__ctype>::digits;
757
758 unsigned __n, __n0;
759 __ctype __s0, __s1, __y0, __y1;
760
761 for (size_t __i = 0; __i < 2; ++__i)
762 {
763 __n = (__w + __m - 1) / __m + __i;
764 __n0 = __n - __w % __n;
765 const unsigned __w0 = __w / __n; // __w0 <= __m
766
767 __s0 = 0;
768 __s1 = 0;
769 if (__w0 < __cdig)
770 {
771 __s0 = __ctype(1) << __w0;
772 __s1 = __s0 << 1;
773 }
774
775 __y0 = 0;
776 __y1 = 0;
777 if (__r)
778 {
779 __y0 = __s0 * (__r / __s0);
780 if (__s1)
781 __y1 = __s1 * (__r / __s1);
782
783 if (__r - __y0 <= __y0 / __n)
784 break;
785 }
786 else
787 break;
788 }
789
790 result_type __sum = 0;
791 for (size_t __k = 0; __k < __n0; ++__k)
792 {
793 __ctype __u;
794 do
795 __u = _M_b() - _M_b.min();
796 while (__y0 && __u >= __y0);
797 __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u);
798 }
799 for (size_t __k = __n0; __k < __n; ++__k)
800 {
801 __ctype __u;
802 do
803 __u = _M_b() - _M_b.min();
804 while (__y1 && __u >= __y1);
805 __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u);
806 }
807 return __sum;
808 }
809
810#if ! __cpp_inline_variables
811 template<typename _RandomNumberEngine, size_t __k>
812 constexpr size_t
813 shuffle_order_engine<_RandomNumberEngine, __k>::table_size;
814#endif
815
816 namespace __detail
817 {
818 // Determine whether an integer is representable as double.
819 template<typename _Tp>
820 constexpr bool
821 __representable_as_double(_Tp __x) noexcept
822 {
823 static_assert(numeric_limits<_Tp>::is_integer, "");
824 static_assert(!numeric_limits<_Tp>::is_signed, "");
825 // All integers <= 2^53 are representable.
826 return (__x <= (1ull << __DBL_MANT_DIG__))
827 // Between 2^53 and 2^54 only even numbers are representable.
828 || (!(__x & 1) && __detail::__representable_as_double(__x >> 1));
829 }
830
831 // Determine whether x+1 is representable as double.
832 template<typename _Tp>
833 constexpr bool
834 __p1_representable_as_double(_Tp __x) noexcept
835 {
836 static_assert(numeric_limits<_Tp>::is_integer, "");
837 static_assert(!numeric_limits<_Tp>::is_signed, "");
838 return numeric_limits<_Tp>::digits < __DBL_MANT_DIG__
839 || (bool(__x + 1u) // return false if x+1 wraps around to zero
840 && __detail::__representable_as_double(__x + 1u));
841 }
842 }
843
844 template<typename _RandomNumberEngine, size_t __k>
848 {
849 constexpr result_type __range = max() - min();
850 size_t __j = __k;
851 const result_type __y = _M_y - min();
852#pragma GCC diagnostic push
853#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
854 // Avoid using slower long double arithmetic if possible.
855 if constexpr (__detail::__p1_representable_as_double(__range))
856 __j *= __y / (__range + 1.0);
857 else
858 __j *= __y / (__range + 1.0L);
859#pragma GCC diagnostic pop
860 _M_y = _M_v[__j];
861 _M_v[__j] = _M_b();
862
863 return _M_y;
864 }
865
866 template<typename _RandomNumberEngine, size_t __k,
867 typename _CharT, typename _Traits>
871 {
872 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
873
874 const typename __ios_base::fmtflags __flags = __os.flags();
875 const _CharT __fill = __os.fill();
876 const _CharT __space = __os.widen(' ');
877 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
878 __os.fill(__space);
879
880 __os << __x.base();
881 for (size_t __i = 0; __i < __k; ++__i)
882 __os << __space << __x._M_v[__i];
883 __os << __space << __x._M_y;
884
885 __os.flags(__flags);
886 __os.fill(__fill);
887 return __os;
888 }
889
890 template<typename _RandomNumberEngine, size_t __k,
891 typename _CharT, typename _Traits>
895 {
896 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
897
898 const typename __ios_base::fmtflags __flags = __is.flags();
899 __is.flags(__ios_base::dec | __ios_base::skipws);
900
901 __is >> __x._M_b;
902 for (size_t __i = 0; __i < __k; ++__i)
903 __is >> __x._M_v[__i];
904 __is >> __x._M_y;
905
906 __is.flags(__flags);
907 return __is;
908 }
909
910#if __glibcxx_philox_engine // >= C++26
911
912 template<typename _UIntType, size_t __w, size_t __n, size_t __r,
913 _UIntType... __consts>
914 _UIntType
915 philox_engine<_UIntType, __w, __n, __r, __consts...>::
916 _S_mulhi(_UIntType __a, _UIntType __b)
917 {
918 using __type = typename __detail::_Select_uint_least_t<__w * 2>::type;
919 const __type __num = static_cast<__type>(__a) * __b;
920 return static_cast<_UIntType>(__num >> __w) & max();
921 }
922
923 template<typename _UIntType, size_t __w, size_t __n, size_t __r,
924 _UIntType... __consts>
925 _UIntType
926 philox_engine<_UIntType, __w, __n, __r, __consts...>::
927 _S_mullo(_UIntType __a, _UIntType __b)
928 {
929 return static_cast<_UIntType>((__a * __b) & max());
930 }
931
932 template<typename _UIntType, size_t __w, size_t __n, size_t __r,
933 _UIntType... __consts>
934 void
935 philox_engine<_UIntType, __w, __n, __r, __consts...>::_M_transition()
936 {
937 ++_M_i;
938 if (_M_i != __n)
939 return;
940
941 using __type = typename __detail::_Select_uint_least_t<__w * 2>::type;
942
943 _M_philox();
944 if constexpr (__n == 4)
945 {
946 __type __uh
947 = (static_cast<__type>(_M_x[1]) << __w)
948 | (static_cast<__type>(_M_x[0]) + 1);
949 __type __lh
950 = (static_cast<__type>(_M_x[3]) << __w)
951 | static_cast<__type>(_M_x[2]);
952 __type __bigMask
953 = ~__type(0) >> ((sizeof(__type) * __CHAR_BIT__) - (__w * 2));
954 if ((__uh & __bigMask) == 0)
955 {
956 ++__lh;
957 __uh = 0;
958 }
959 _M_x[0] = static_cast<_UIntType>(__uh & max());
960 _M_x[1] = static_cast<_UIntType>((__uh >> (__w)) & max());
961 _M_x[2] = static_cast<_UIntType>(__lh & max());
962 _M_x[3] = static_cast<_UIntType>((__lh >> (__w)) & max());
963 }
964 else
965 {
966 __type __num =
967 (static_cast<__type>(_M_x[1]) << __w)
968 | (static_cast<__type>(_M_x[0]) + 1);
969 _M_x[0] = __num & max();
970 _M_x[1] = (__num >> __w) & max();
971 }
972 _M_i = 0;
973 }
974
975 template<typename _UIntType, size_t __w, size_t __n, size_t __r,
976 _UIntType... __consts>
977 void
978 philox_engine<_UIntType, __w, __n, __r, __consts...>::_M_philox()
979 {
980 array<_UIntType, __n> __outputSeq = _M_x;
981 for (size_t __j = 0; __j < __r; ++__j)
982 {
983 array<_UIntType, __n> __intermedSeq{};
984 if constexpr (__n == 4)
985 {
986 __intermedSeq[0] = __outputSeq[2];
987 __intermedSeq[1] = __outputSeq[1];
988 __intermedSeq[2] = __outputSeq[0];
989 __intermedSeq[3] = __outputSeq[3];
990 }
991 else
992 {
993 __intermedSeq[0] = __outputSeq[0];
994 __intermedSeq[1] = __outputSeq[1];
995 }
996 for (unsigned long __k = 0; __k < (__n/2); ++__k)
997 {
998 __outputSeq[2*__k]
999 = _S_mulhi(__intermedSeq[2*__k], multipliers[__k])
1000 ^ (((_M_k[__k] + (__j * round_consts[__k])) & max()))
1001 ^ __intermedSeq[2*__k+1];
1002
1003 __outputSeq[(2*__k)+1]
1004 = _S_mullo(__intermedSeq[2*__k], multipliers[__k]);
1005 }
1006 }
1007 _M_y = __outputSeq;
1008 }
1009
1010 template<typename _UIntType, size_t __w, size_t __n, size_t __r,
1011 _UIntType... __consts>
1012 template<typename _Sseq>
1013 void
1014 philox_engine<_UIntType, __w, __n, __r, __consts...>::seed(_Sseq& __q)
1015 requires __is_seed_seq<_Sseq>
1016 {
1017 seed(0);
1018
1019 const unsigned __p = 1 + ((__w - 1) / 32);
1020 uint_least32_t __tmpArr[(__n/2) * __p];
1021 __q.generate(__tmpArr + 0, __tmpArr + ((__n/2) * __p));
1022 for (unsigned __k = 0; __k < (__n/2); ++__k)
1023 {
1024 unsigned long long __precalc = 0;
1025 for (unsigned __j = 0; __j < __p; ++__j)
1026 {
1027 unsigned long long __multiplicand = (1ull << (32 * __j));
1028 __precalc += (__tmpArr[__k * __p + __j] * __multiplicand) & max();
1029 }
1030 _M_k[__k] = __precalc;
1031 }
1032 }
1033#endif // philox_engine
1034
1035 template<typename _IntType, typename _CharT, typename _Traits>
1036 std::basic_ostream<_CharT, _Traits>&
1037 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1039 {
1040 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1041
1042 const typename __ios_base::fmtflags __flags = __os.flags();
1043 const _CharT __fill = __os.fill();
1044 const _CharT __space = __os.widen(' ');
1045 __os.flags(__ios_base::scientific | __ios_base::left);
1046 __os.fill(__space);
1047
1048 __os << __x.a() << __space << __x.b();
1049
1050 __os.flags(__flags);
1051 __os.fill(__fill);
1052 return __os;
1053 }
1054
1055 template<typename _IntType, typename _CharT, typename _Traits>
1056 std::basic_istream<_CharT, _Traits>&
1059 {
1060 using param_type
1062 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1063
1064 const typename __ios_base::fmtflags __flags = __is.flags();
1065 __is.flags(__ios_base::dec | __ios_base::skipws);
1066
1067 _IntType __a, __b;
1068 if (__is >> __a >> __b)
1069 __x.param(param_type(__a, __b));
1070
1071 __is.flags(__flags);
1072 return __is;
1073 }
1074
1075
1076 template<typename _RealType>
1077 template<typename _ForwardIterator,
1078 typename _UniformRandomNumberGenerator>
1079 void
1081 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1082 _UniformRandomNumberGenerator& __urng,
1083 const param_type& __p)
1084 {
1085 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1086 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1087 __aurng(__urng);
1088 auto __range = __p.b() - __p.a();
1089 while (__f != __t)
1090 *__f++ = __aurng() * __range + __p.a();
1091 }
1092
1093 template<typename _RealType, typename _CharT, typename _Traits>
1096 const uniform_real_distribution<_RealType>& __x)
1097 {
1098 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1099
1100 const typename __ios_base::fmtflags __flags = __os.flags();
1101 const _CharT __fill = __os.fill();
1102 const std::streamsize __precision = __os.precision();
1103 const _CharT __space = __os.widen(' ');
1104 __os.flags(__ios_base::scientific | __ios_base::left);
1105 __os.fill(__space);
1107
1108 __os << __x.a() << __space << __x.b();
1109
1110 __os.flags(__flags);
1111 __os.fill(__fill);
1112 __os.precision(__precision);
1113 return __os;
1114 }
1115
1116 template<typename _RealType, typename _CharT, typename _Traits>
1117 std::basic_istream<_CharT, _Traits>&
1120 {
1121 using param_type
1123 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1124
1125 const typename __ios_base::fmtflags __flags = __is.flags();
1126 __is.flags(__ios_base::skipws);
1127
1128 _RealType __a, __b;
1129 if (__is >> __a >> __b)
1130 __x.param(param_type(__a, __b));
1131
1132 __is.flags(__flags);
1133 return __is;
1134 }
1135
1136
1137 template<typename _ForwardIterator,
1138 typename _UniformRandomNumberGenerator>
1139 void
1140 std::bernoulli_distribution::
1141 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1142 _UniformRandomNumberGenerator& __urng,
1143 const param_type& __p)
1144 {
1145 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1146 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1147 __aurng(__urng);
1148 auto __limit = __p.p() * (__aurng.max() - __aurng.min());
1149
1150 while (__f != __t)
1151 *__f++ = (__aurng() - __aurng.min()) < __limit;
1152 }
1153
1154 template<typename _CharT, typename _Traits>
1157 const bernoulli_distribution& __x)
1158 {
1159 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1160
1161 const typename __ios_base::fmtflags __flags = __os.flags();
1162 const _CharT __fill = __os.fill();
1163 const std::streamsize __precision = __os.precision();
1164 __os.flags(__ios_base::scientific | __ios_base::left);
1165 __os.fill(__os.widen(' '));
1167
1168 __os << __x.p();
1169
1170 __os.flags(__flags);
1171 __os.fill(__fill);
1172 __os.precision(__precision);
1173 return __os;
1174 }
1175
1176
1177 template<typename _IntType>
1178 template<typename _UniformRandomNumberGenerator>
1181 operator()(_UniformRandomNumberGenerator& __urng,
1182 const param_type& __param)
1183 {
1184 // About the epsilon thing see this thread:
1185 // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
1186 const double __naf =
1188 // The largest _RealType convertible to _IntType.
1189 const double __thr =
1191 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1192 __aurng(__urng);
1193
1194 double __cand;
1195 do
1196 __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p);
1197 while (__cand >= __thr);
1198
1199 return result_type(__cand + __naf);
1200 }
1201
1202 template<typename _IntType>
1203 template<typename _ForwardIterator,
1204 typename _UniformRandomNumberGenerator>
1205 void
1207 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1208 _UniformRandomNumberGenerator& __urng,
1209 const param_type& __param)
1210 {
1211 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1212 // About the epsilon thing see this thread:
1213 // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
1214 const double __naf =
1216 // The largest _RealType convertible to _IntType.
1217 const double __thr =
1219 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1220 __aurng(__urng);
1221
1222 while (__f != __t)
1223 {
1224 double __cand;
1225 do
1226 __cand = std::floor(std::log(1.0 - __aurng())
1227 / __param._M_log_1_p);
1228 while (__cand >= __thr);
1229
1230 *__f++ = __cand + __naf;
1231 }
1232 }
1233
1234 template<typename _IntType,
1235 typename _CharT, typename _Traits>
1238 const geometric_distribution<_IntType>& __x)
1239 {
1240 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1241
1242 const typename __ios_base::fmtflags __flags = __os.flags();
1243 const _CharT __fill = __os.fill();
1244 const std::streamsize __precision = __os.precision();
1245 __os.flags(__ios_base::scientific | __ios_base::left);
1246 __os.fill(__os.widen(' '));
1248
1249 __os << __x.p();
1250
1251 __os.flags(__flags);
1252 __os.fill(__fill);
1253 __os.precision(__precision);
1254 return __os;
1255 }
1256
1257 template<typename _IntType,
1258 typename _CharT, typename _Traits>
1259 std::basic_istream<_CharT, _Traits>&
1262 {
1263 using param_type = typename geometric_distribution<_IntType>::param_type;
1264 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1265
1266 const typename __ios_base::fmtflags __flags = __is.flags();
1267 __is.flags(__ios_base::skipws);
1268
1269 double __p;
1270 if (__is >> __p)
1271 __x.param(param_type(__p));
1272
1273 __is.flags(__flags);
1274 return __is;
1275 }
1276
1277 // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5.
1278 template<typename _IntType>
1279 template<typename _UniformRandomNumberGenerator>
1280 typename negative_binomial_distribution<_IntType>::result_type
1282 operator()(_UniformRandomNumberGenerator& __urng)
1283 {
1284 const double __y = _M_gd(__urng);
1285
1286 // XXX Is the constructor too slow?
1288 return __poisson(__urng);
1289 }
1290
1291 template<typename _IntType>
1292 template<typename _UniformRandomNumberGenerator>
1295 operator()(_UniformRandomNumberGenerator& __urng,
1296 const param_type& __p)
1297 {
1299 param_type;
1300
1301 const double __y =
1302 _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p()));
1303
1305 return __poisson(__urng);
1306 }
1307
1308 template<typename _IntType>
1309 template<typename _ForwardIterator,
1310 typename _UniformRandomNumberGenerator>
1311 void
1312 negative_binomial_distribution<_IntType>::
1313 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1314 _UniformRandomNumberGenerator& __urng)
1315 {
1316 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1317 while (__f != __t)
1318 {
1319 const double __y = _M_gd(__urng);
1320
1321 // XXX Is the constructor too slow?
1323 *__f++ = __poisson(__urng);
1324 }
1325 }
1326
1327 template<typename _IntType>
1328 template<typename _ForwardIterator,
1329 typename _UniformRandomNumberGenerator>
1330 void
1332 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1333 _UniformRandomNumberGenerator& __urng,
1334 const param_type& __p)
1335 {
1336 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1337 typename std::gamma_distribution<result_type>::param_type
1338 __p2(__p.k(), (1.0 - __p.p()) / __p.p());
1339
1340 while (__f != __t)
1341 {
1342 const double __y = _M_gd(__urng, __p2);
1343
1344 std::poisson_distribution<result_type> __poisson(__y);
1345 *__f++ = __poisson(__urng);
1346 }
1347 }
1348
1349 template<typename _IntType, typename _CharT, typename _Traits>
1350 std::basic_ostream<_CharT, _Traits>&
1351 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1353 {
1354 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1355
1356 const typename __ios_base::fmtflags __flags = __os.flags();
1357 const _CharT __fill = __os.fill();
1358 const std::streamsize __precision = __os.precision();
1359 const _CharT __space = __os.widen(' ');
1360 __os.flags(__ios_base::scientific | __ios_base::left);
1361 __os.fill(__os.widen(' '));
1363
1364 __os << __x.k() << __space << __x.p()
1365 << __space << __x._M_gd;
1366
1367 __os.flags(__flags);
1368 __os.fill(__fill);
1369 __os.precision(__precision);
1370 return __os;
1371 }
1372
1373 template<typename _IntType, typename _CharT, typename _Traits>
1374 std::basic_istream<_CharT, _Traits>&
1375 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1377 {
1378 using param_type
1380 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1381
1382 const typename __ios_base::fmtflags __flags = __is.flags();
1383 __is.flags(__ios_base::skipws);
1384
1385 _IntType __k;
1386 double __p;
1387 if (__is >> __k >> __p >> __x._M_gd)
1388 __x.param(param_type(__k, __p));
1389
1390 __is.flags(__flags);
1391 return __is;
1392 }
1393
1394
1395 template<typename _IntType>
1396 void
1399 {
1400#if _GLIBCXX_USE_C99_MATH_FUNCS
1401 if (_M_mean >= 12)
1402 {
1403 const double __m = std::floor(_M_mean);
1404 _M_lm_thr = std::log(_M_mean);
1405 _M_lfm = std::lgamma(__m + 1);
1406 _M_sm = std::sqrt(__m);
1407
1408 const double __pi_4 = 0.7853981633974483096156608458198757L;
1409 const double __dx = std::sqrt(2 * __m * std::log(32 * __m
1410 / __pi_4));
1411 _M_d = std::round(std::max<double>(6.0, std::min(__m, __dx)));
1412 const double __cx = 2 * __m + _M_d;
1413 _M_scx = std::sqrt(__cx / 2);
1414 _M_1cx = 1 / __cx;
1415
1416 _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
1417 _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2))
1418 / _M_d;
1419 }
1420 else
1421#endif
1422 _M_lm_thr = std::exp(-_M_mean);
1423 }
1424
1425 /**
1426 * A rejection algorithm when mean >= 12 and a simple method based
1427 * upon the multiplication of uniform random variates otherwise.
1428 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_FUNCS
1429 * is defined.
1430 *
1431 * Reference:
1432 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1433 * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
1434 */
1435 template<typename _IntType>
1436 template<typename _UniformRandomNumberGenerator>
1437 typename poisson_distribution<_IntType>::result_type
1439 operator()(_UniformRandomNumberGenerator& __urng,
1440 const param_type& __param)
1441 {
1442 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1443 __aurng(__urng);
1444#if _GLIBCXX_USE_C99_MATH_FUNCS
1445 if (__param.mean() >= 12)
1446 {
1447 double __x;
1448
1449 // See comments above...
1450 const double __naf =
1452 const double __thr =
1454
1455 const double __m = std::floor(__param.mean());
1456 // sqrt(pi / 2)
1457 const double __spi_2 = 1.2533141373155002512078826424055226L;
1458 const double __c1 = __param._M_sm * __spi_2;
1459 const double __c2 = __param._M_c2b + __c1;
1460 const double __c3 = __c2 + 1;
1461 const double __c4 = __c3 + 1;
1462 // 1 / 78
1463 const double __178 = 0.0128205128205128205128205128205128L;
1464 // e^(1 / 78)
1465 const double __e178 = 1.0129030479320018583185514777512983L;
1466 const double __c5 = __c4 + __e178;
1467 const double __c = __param._M_cb + __c5;
1468 const double __2cx = 2 * (2 * __m + __param._M_d);
1469
1470 bool __reject = true;
1471 do
1472 {
1473 const double __u = __c * __aurng();
1474 const double __e = -std::log(1.0 - __aurng());
1475
1476 double __w = 0.0;
1477
1478 if (__u <= __c1)
1479 {
1480 const double __n = _M_nd(__urng);
1481 const double __y = -std::abs(__n) * __param._M_sm - 1;
1482 __x = std::floor(__y);
1483 __w = -__n * __n / 2;
1484 if (__x < -__m)
1485 continue;
1486 }
1487 else if (__u <= __c2)
1488 {
1489 const double __n = _M_nd(__urng);
1490 const double __y = 1 + std::abs(__n) * __param._M_scx;
1491 __x = std::ceil(__y);
1492 __w = __y * (2 - __y) * __param._M_1cx;
1493 if (__x > __param._M_d)
1494 continue;
1495 }
1496 else if (__u <= __c3)
1497 // NB: This case not in the book, nor in the Errata,
1498 // but should be ok...
1499 __x = -1;
1500 else if (__u <= __c4)
1501 __x = 0;
1502 else if (__u <= __c5)
1503 {
1504 __x = 1;
1505 // Only in the Errata, see libstdc++/83237.
1506 __w = __178;
1507 }
1508 else
1509 {
1510 const double __v = -std::log(1.0 - __aurng());
1511 const double __y = __param._M_d
1512 + __v * __2cx / __param._M_d;
1513 __x = std::ceil(__y);
1514 __w = -__param._M_d * __param._M_1cx * (1 + __y / 2);
1515 }
1516
1517 __reject = (__w - __e - __x * __param._M_lm_thr
1518 > __param._M_lfm - std::lgamma(__x + __m + 1));
1519
1520 __reject |= __x + __m >= __thr;
1521
1522 } while (__reject);
1523
1524 return result_type(__x + __m + __naf);
1525 }
1526 else
1527#endif
1528 {
1529 _IntType __x = 0;
1530 double __prod = 1.0;
1531
1532 do
1533 {
1534 __prod *= __aurng();
1535 __x += 1;
1536 }
1537 while (__prod > __param._M_lm_thr);
1538
1539 return __x - 1;
1540 }
1541 }
1542
1543 template<typename _IntType>
1544 template<typename _ForwardIterator,
1545 typename _UniformRandomNumberGenerator>
1546 void
1548 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1549 _UniformRandomNumberGenerator& __urng,
1550 const param_type& __param)
1551 {
1552 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1553 // We could duplicate everything from operator()...
1554 while (__f != __t)
1555 *__f++ = this->operator()(__urng, __param);
1556 }
1557
1558 template<typename _IntType,
1559 typename _CharT, typename _Traits>
1562 const poisson_distribution<_IntType>& __x)
1563 {
1564 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1565
1566 const typename __ios_base::fmtflags __flags = __os.flags();
1567 const _CharT __fill = __os.fill();
1568 const std::streamsize __precision = __os.precision();
1569 const _CharT __space = __os.widen(' ');
1570 __os.flags(__ios_base::scientific | __ios_base::left);
1571 __os.fill(__space);
1573
1574 __os << __x.mean() << __space << __x._M_nd;
1575
1576 __os.flags(__flags);
1577 __os.fill(__fill);
1578 __os.precision(__precision);
1579 return __os;
1580 }
1581
1582 template<typename _IntType,
1583 typename _CharT, typename _Traits>
1584 std::basic_istream<_CharT, _Traits>&
1585 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1586 poisson_distribution<_IntType>& __x)
1587 {
1588 using param_type = typename poisson_distribution<_IntType>::param_type;
1589 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1590
1591 const typename __ios_base::fmtflags __flags = __is.flags();
1592 __is.flags(__ios_base::skipws);
1593
1594 double __mean;
1595 if (__is >> __mean >> __x._M_nd)
1596 __x.param(param_type(__mean));
1597
1598 __is.flags(__flags);
1599 return __is;
1600 }
1601
1602
1603 template<typename _IntType>
1604 void
1605 binomial_distribution<_IntType>::param_type::
1606 _M_initialize()
1607 {
1608 const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1609
1610 _M_easy = true;
1611
1612#if _GLIBCXX_USE_C99_MATH_FUNCS
1613 if (_M_t * __p12 >= 8)
1614 {
1615 _M_easy = false;
1616 const double __np = std::floor(_M_t * __p12);
1617 const double __pa = __np / _M_t;
1618 const double __1p = 1 - __pa;
1619
1620 const double __pi_4 = 0.7853981633974483096156608458198757L;
1621 const double __d1x =
1622 std::sqrt(__np * __1p * std::log(32 * __np
1623 / (81 * __pi_4 * __1p)));
1624 _M_d1 = std::round(std::max<double>(1.0, __d1x));
1625 const double __d2x =
1626 std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
1627 / (__pi_4 * __pa)));
1628 _M_d2 = std::round(std::max<double>(1.0, __d2x));
1629
1630 // sqrt(pi / 2)
1631 const double __spi_2 = 1.2533141373155002512078826424055226L;
1632 _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
1633 _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * (_M_t * __1p)));
1634 _M_c = 2 * _M_d1 / __np;
1635 _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
1636 const double __a12 = _M_a1 + _M_s2 * __spi_2;
1637 const double __s1s = _M_s1 * _M_s1;
1638 _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
1639 * 2 * __s1s / _M_d1
1640 * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
1641 const double __s2s = _M_s2 * _M_s2;
1642 _M_s = (_M_a123 + 2 * __s2s / _M_d2
1643 * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
1644 _M_lf = (std::lgamma(__np + 1)
1645 + std::lgamma(_M_t - __np + 1));
1646 _M_lp1p = std::log(__pa / __1p);
1647
1648 _M_q = -std::log(1 - (__p12 - __pa) / __1p);
1649 }
1650 else
1651#endif
1652 _M_q = -std::log(1 - __p12);
1653 }
1654
1655 template<typename _IntType>
1656 template<typename _UniformRandomNumberGenerator>
1658 binomial_distribution<_IntType>::
1659 _M_waiting(_UniformRandomNumberGenerator& __urng,
1660 _IntType __t, double __q)
1661 {
1662 _IntType __x = 0;
1663 double __sum = 0.0;
1664 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1665 __aurng(__urng);
1666
1667 do
1668 {
1669 if (__t == __x)
1670 return __x;
1671 const double __e = -std::log(1.0 - __aurng());
1672 __sum += __e / (__t - __x);
1673 __x += 1;
1674 }
1675 while (__sum <= __q);
1676
1677 return __x - 1;
1678 }
1679
1680 /**
1681 * A rejection algorithm when t * p >= 8 and a simple waiting time
1682 * method - the second in the referenced book - otherwise.
1683 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_FUNCS
1684 * is defined.
1685 *
1686 * Reference:
1687 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1688 * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
1689 */
1690 template<typename _IntType>
1691 template<typename _UniformRandomNumberGenerator>
1694 operator()(_UniformRandomNumberGenerator& __urng,
1695 const param_type& __param)
1696 {
1697 result_type __ret;
1698 const _IntType __t = __param.t();
1699 const double __p = __param.p();
1700 const double __p12 = __p <= 0.5 ? __p : 1.0 - __p;
1701 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1702 __aurng(__urng);
1703
1704#if _GLIBCXX_USE_C99_MATH_FUNCS
1705 if (!__param._M_easy)
1706 {
1707 double __x;
1708
1709 // See comments above...
1710 const double __naf =
1712 const double __thr =
1714
1715 const double __np = std::floor(__t * __p12);
1716
1717 // sqrt(pi / 2)
1718 const double __spi_2 = 1.2533141373155002512078826424055226L;
1719 const double __a1 = __param._M_a1;
1720 const double __a12 = __a1 + __param._M_s2 * __spi_2;
1721 const double __a123 = __param._M_a123;
1722 const double __s1s = __param._M_s1 * __param._M_s1;
1723 const double __s2s = __param._M_s2 * __param._M_s2;
1724
1725 bool __reject;
1726 do
1727 {
1728 const double __u = __param._M_s * __aurng();
1729
1730 double __v;
1731
1732 if (__u <= __a1)
1733 {
1734 const double __n = _M_nd(__urng);
1735 const double __y = __param._M_s1 * std::abs(__n);
1736 __reject = __y >= __param._M_d1;
1737 if (!__reject)
1738 {
1739 const double __e = -std::log(1.0 - __aurng());
1740 __x = std::floor(__y);
1741 __v = -__e - __n * __n / 2 + __param._M_c;
1742 }
1743 }
1744 else if (__u <= __a12)
1745 {
1746 const double __n = _M_nd(__urng);
1747 const double __y = __param._M_s2 * std::abs(__n);
1748 __reject = __y >= __param._M_d2;
1749 if (!__reject)
1750 {
1751 const double __e = -std::log(1.0 - __aurng());
1752 __x = std::floor(-__y);
1753 __v = -__e - __n * __n / 2;
1754 }
1755 }
1756 else if (__u <= __a123)
1757 {
1758 const double __e1 = -std::log(1.0 - __aurng());
1759 const double __e2 = -std::log(1.0 - __aurng());
1760
1761 const double __y = __param._M_d1
1762 + 2 * __s1s * __e1 / __param._M_d1;
1763 __x = std::floor(__y);
1764 __v = (-__e2 + __param._M_d1 * (1 / (__t - __np)
1765 -__y / (2 * __s1s)));
1766 __reject = false;
1767 }
1768 else
1769 {
1770 const double __e1 = -std::log(1.0 - __aurng());
1771 const double __e2 = -std::log(1.0 - __aurng());
1772
1773 const double __y = __param._M_d2
1774 + 2 * __s2s * __e1 / __param._M_d2;
1775 __x = std::floor(-__y);
1776 __v = -__e2 - __param._M_d2 * __y / (2 * __s2s);
1777 __reject = false;
1778 }
1779
1780 __reject = __reject || __x < -__np || __x > __t - __np;
1781 if (!__reject)
1782 {
1783 const double __lfx =
1784 std::lgamma(__np + __x + 1)
1785 + std::lgamma(__t - (__np + __x) + 1);
1786 __reject = __v > __param._M_lf - __lfx
1787 + __x * __param._M_lp1p;
1788 }
1789
1790 __reject |= __x + __np >= __thr;
1791 }
1792 while (__reject);
1793
1794 __x += __np + __naf;
1795
1796 const _IntType __z = _M_waiting(__urng, __t - _IntType(__x),
1797 __param._M_q);
1798 __ret = _IntType(__x) + __z;
1799 }
1800 else
1801#endif
1802 __ret = _M_waiting(__urng, __t, __param._M_q);
1803
1804 if (__p12 != __p)
1805 __ret = __t - __ret;
1806 return __ret;
1807 }
1808
1809 template<typename _IntType>
1810 template<typename _ForwardIterator,
1811 typename _UniformRandomNumberGenerator>
1812 void
1814 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1815 _UniformRandomNumberGenerator& __urng,
1816 const param_type& __param)
1817 {
1818 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1819 // We could duplicate everything from operator()...
1820 while (__f != __t)
1821 *__f++ = this->operator()(__urng, __param);
1822 }
1823
1824 template<typename _IntType,
1825 typename _CharT, typename _Traits>
1828 const binomial_distribution<_IntType>& __x)
1829 {
1830 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1831
1832 const typename __ios_base::fmtflags __flags = __os.flags();
1833 const _CharT __fill = __os.fill();
1834 const std::streamsize __precision = __os.precision();
1835 const _CharT __space = __os.widen(' ');
1836 __os.flags(__ios_base::scientific | __ios_base::left);
1837 __os.fill(__space);
1839
1840 __os << __x.t() << __space << __x.p()
1841 << __space << __x._M_nd;
1842
1843 __os.flags(__flags);
1844 __os.fill(__fill);
1845 __os.precision(__precision);
1846 return __os;
1847 }
1848
1849 template<typename _IntType,
1850 typename _CharT, typename _Traits>
1851 std::basic_istream<_CharT, _Traits>&
1852 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1853 binomial_distribution<_IntType>& __x)
1854 {
1855 using param_type = typename binomial_distribution<_IntType>::param_type;
1856 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1857
1858 const typename __ios_base::fmtflags __flags = __is.flags();
1859 __is.flags(__ios_base::dec | __ios_base::skipws);
1860
1861 _IntType __t;
1862 double __p;
1863 if (__is >> __t >> __p >> __x._M_nd)
1864 __x.param(param_type(__t, __p));
1865
1866 __is.flags(__flags);
1867 return __is;
1868 }
1869
1870
1871 template<typename _RealType>
1872 template<typename _ForwardIterator,
1873 typename _UniformRandomNumberGenerator>
1874 void
1876 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1877 _UniformRandomNumberGenerator& __urng,
1878 const param_type& __p)
1879 {
1880 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1881 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1882 __aurng(__urng);
1883 while (__f != __t)
1884 *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda();
1885 }
1886
1887 template<typename _RealType, typename _CharT, typename _Traits>
1890 const exponential_distribution<_RealType>& __x)
1891 {
1892 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
1893
1894 const typename __ios_base::fmtflags __flags = __os.flags();
1895 const _CharT __fill = __os.fill();
1896 const std::streamsize __precision = __os.precision();
1897 __os.flags(__ios_base::scientific | __ios_base::left);
1898 __os.fill(__os.widen(' '));
1900
1901 __os << __x.lambda();
1902
1903 __os.flags(__flags);
1904 __os.fill(__fill);
1905 __os.precision(__precision);
1906 return __os;
1907 }
1908
1909 template<typename _RealType, typename _CharT, typename _Traits>
1910 std::basic_istream<_CharT, _Traits>&
1913 {
1914 using param_type
1916 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
1917
1918 const typename __ios_base::fmtflags __flags = __is.flags();
1919 __is.flags(__ios_base::dec | __ios_base::skipws);
1920
1921 _RealType __lambda;
1922 if (__is >> __lambda)
1923 __x.param(param_type(__lambda));
1924
1925 __is.flags(__flags);
1926 return __is;
1927 }
1928
1929
1930 /**
1931 * Polar method due to Marsaglia.
1932 *
1933 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1934 * New York, 1986, Ch. V, Sect. 4.4.
1935 */
1936 template<typename _RealType>
1937 template<typename _UniformRandomNumberGenerator>
1940 operator()(_UniformRandomNumberGenerator& __urng,
1941 const param_type& __param)
1942 {
1943 result_type __ret;
1944 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1945 __aurng(__urng);
1946
1947 if (_M_saved_available)
1948 {
1949 _M_saved_available = false;
1950 __ret = _M_saved;
1951 }
1952 else
1953 {
1954 result_type __x, __y, __r2;
1955 do
1956 {
1957 __x = result_type(2.0) * __aurng() - 1.0;
1958 __y = result_type(2.0) * __aurng() - 1.0;
1959 __r2 = __x * __x + __y * __y;
1960 }
1961 while (__r2 > 1.0 || __r2 == 0.0);
1962
1963 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
1964 _M_saved = __x * __mult;
1965 _M_saved_available = true;
1966 __ret = __y * __mult;
1967 }
1968
1969 __ret = __ret * __param.stddev() + __param.mean();
1970 return __ret;
1971 }
1972
1973 template<typename _RealType>
1974 template<typename _ForwardIterator,
1975 typename _UniformRandomNumberGenerator>
1976 void
1978 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1979 _UniformRandomNumberGenerator& __urng,
1980 const param_type& __param)
1981 {
1982 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1983
1984 if (__f == __t)
1985 return;
1986
1987 if (_M_saved_available)
1988 {
1989 _M_saved_available = false;
1990 *__f++ = _M_saved * __param.stddev() + __param.mean();
1991
1992 if (__f == __t)
1993 return;
1994 }
1995
1996 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1997 __aurng(__urng);
1998
1999 while (__f + 1 < __t)
2000 {
2001 result_type __x, __y, __r2;
2002 do
2003 {
2004 __x = result_type(2.0) * __aurng() - 1.0;
2005 __y = result_type(2.0) * __aurng() - 1.0;
2006 __r2 = __x * __x + __y * __y;
2007 }
2008 while (__r2 > 1.0 || __r2 == 0.0);
2009
2010 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
2011 *__f++ = __y * __mult * __param.stddev() + __param.mean();
2012 *__f++ = __x * __mult * __param.stddev() + __param.mean();
2013 }
2014
2015 if (__f != __t)
2016 {
2017 result_type __x, __y, __r2;
2018 do
2019 {
2020 __x = result_type(2.0) * __aurng() - 1.0;
2021 __y = result_type(2.0) * __aurng() - 1.0;
2022 __r2 = __x * __x + __y * __y;
2023 }
2024 while (__r2 > 1.0 || __r2 == 0.0);
2025
2026 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
2027 _M_saved = __x * __mult;
2028 _M_saved_available = true;
2029 *__f = __y * __mult * __param.stddev() + __param.mean();
2030 }
2031 }
2032
2033 template<typename _RealType>
2034 bool
2035 operator==(const std::normal_distribution<_RealType>& __d1,
2036 const std::normal_distribution<_RealType>& __d2)
2037 {
2038 if (__d1._M_param == __d2._M_param
2039 && __d1._M_saved_available == __d2._M_saved_available)
2040 return __d1._M_saved_available ? __d1._M_saved == __d2._M_saved : true;
2041 else
2042 return false;
2043 }
2044
2045 template<typename _RealType, typename _CharT, typename _Traits>
2046 std::basic_ostream<_CharT, _Traits>&
2047 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2048 const normal_distribution<_RealType>& __x)
2049 {
2050 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2051
2052 const typename __ios_base::fmtflags __flags = __os.flags();
2053 const _CharT __fill = __os.fill();
2054 const std::streamsize __precision = __os.precision();
2055 const _CharT __space = __os.widen(' ');
2056 __os.flags(__ios_base::scientific | __ios_base::left);
2057 __os.fill(__space);
2059
2060 __os << __x.mean() << __space << __x.stddev()
2061 << __space << __x._M_saved_available;
2062 if (__x._M_saved_available)
2063 __os << __space << __x._M_saved;
2064
2065 __os.flags(__flags);
2066 __os.fill(__fill);
2067 __os.precision(__precision);
2068 return __os;
2069 }
2070
2071 template<typename _RealType, typename _CharT, typename _Traits>
2072 std::basic_istream<_CharT, _Traits>&
2073 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2074 normal_distribution<_RealType>& __x)
2075 {
2076 using param_type = typename normal_distribution<_RealType>::param_type;
2077 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2078
2079 const typename __ios_base::fmtflags __flags = __is.flags();
2080 __is.flags(__ios_base::dec | __ios_base::skipws);
2081
2082 double __mean, __stddev;
2083 bool __saved_avail;
2084 if (__is >> __mean >> __stddev >> __saved_avail)
2085 {
2086 if (!__saved_avail || (__is >> __x._M_saved))
2087 {
2088 __x._M_saved_available = __saved_avail;
2089 __x.param(param_type(__mean, __stddev));
2090 }
2091 }
2092
2093 __is.flags(__flags);
2094 return __is;
2095 }
2096
2097
2098 template<typename _RealType>
2099 template<typename _ForwardIterator,
2100 typename _UniformRandomNumberGenerator>
2101 void
2102 lognormal_distribution<_RealType>::
2103 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2104 _UniformRandomNumberGenerator& __urng,
2105 const param_type& __p)
2106 {
2107 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2108 while (__f != __t)
2109 *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m());
2110 }
2111
2112 template<typename _RealType, typename _CharT, typename _Traits>
2113 std::basic_ostream<_CharT, _Traits>&
2114 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2115 const lognormal_distribution<_RealType>& __x)
2116 {
2117 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2118
2119 const typename __ios_base::fmtflags __flags = __os.flags();
2120 const _CharT __fill = __os.fill();
2121 const std::streamsize __precision = __os.precision();
2122 const _CharT __space = __os.widen(' ');
2123 __os.flags(__ios_base::scientific | __ios_base::left);
2124 __os.fill(__space);
2126
2127 __os << __x.m() << __space << __x.s()
2128 << __space << __x._M_nd;
2129
2130 __os.flags(__flags);
2131 __os.fill(__fill);
2132 __os.precision(__precision);
2133 return __os;
2134 }
2135
2136 template<typename _RealType, typename _CharT, typename _Traits>
2137 std::basic_istream<_CharT, _Traits>&
2138 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2139 lognormal_distribution<_RealType>& __x)
2140 {
2141 using param_type
2142 = typename lognormal_distribution<_RealType>::param_type;
2143 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2144
2145 const typename __ios_base::fmtflags __flags = __is.flags();
2146 __is.flags(__ios_base::dec | __ios_base::skipws);
2147
2148 _RealType __m, __s;
2149 if (__is >> __m >> __s >> __x._M_nd)
2150 __x.param(param_type(__m, __s));
2151
2152 __is.flags(__flags);
2153 return __is;
2154 }
2155
2156 template<typename _RealType>
2157 template<typename _ForwardIterator,
2158 typename _UniformRandomNumberGenerator>
2159 void
2160 std::chi_squared_distribution<_RealType>::
2161 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2162 _UniformRandomNumberGenerator& __urng)
2163 {
2164 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2165 while (__f != __t)
2166 *__f++ = 2 * _M_gd(__urng);
2167 }
2168
2169 template<typename _RealType>
2170 template<typename _ForwardIterator,
2171 typename _UniformRandomNumberGenerator>
2172 void
2173 std::chi_squared_distribution<_RealType>::
2174 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2175 _UniformRandomNumberGenerator& __urng,
2176 const typename
2177 std::gamma_distribution<result_type>::param_type& __p)
2178 {
2179 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2180 while (__f != __t)
2181 *__f++ = 2 * _M_gd(__urng, __p);
2182 }
2183
2184 template<typename _RealType, typename _CharT, typename _Traits>
2185 std::basic_ostream<_CharT, _Traits>&
2186 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2187 const chi_squared_distribution<_RealType>& __x)
2188 {
2189 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2190
2191 const typename __ios_base::fmtflags __flags = __os.flags();
2192 const _CharT __fill = __os.fill();
2193 const std::streamsize __precision = __os.precision();
2194 const _CharT __space = __os.widen(' ');
2195 __os.flags(__ios_base::scientific | __ios_base::left);
2196 __os.fill(__space);
2198
2199 __os << __x.n() << __space << __x._M_gd;
2200
2201 __os.flags(__flags);
2202 __os.fill(__fill);
2203 __os.precision(__precision);
2204 return __os;
2205 }
2206
2207 template<typename _RealType, typename _CharT, typename _Traits>
2208 std::basic_istream<_CharT, _Traits>&
2209 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2210 chi_squared_distribution<_RealType>& __x)
2211 {
2212 using param_type
2213 = typename chi_squared_distribution<_RealType>::param_type;
2214 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2215
2216 const typename __ios_base::fmtflags __flags = __is.flags();
2217 __is.flags(__ios_base::dec | __ios_base::skipws);
2218
2219 _RealType __n;
2220 if (__is >> __n >> __x._M_gd)
2221 __x.param(param_type(__n));
2222
2223 __is.flags(__flags);
2224 return __is;
2225 }
2226
2227
2228 template<typename _RealType>
2229 template<typename _UniformRandomNumberGenerator>
2232 operator()(_UniformRandomNumberGenerator& __urng,
2233 const param_type& __p)
2234 {
2235 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2236 __aurng(__urng);
2237 _RealType __u;
2238 do
2239 __u = __aurng();
2240 while (__u == 0.5);
2241
2242 const _RealType __pi = 3.1415926535897932384626433832795029L;
2243 return __p.a() + __p.b() * std::tan(__pi * __u);
2244 }
2245
2246 template<typename _RealType>
2247 template<typename _ForwardIterator,
2248 typename _UniformRandomNumberGenerator>
2249 void
2251 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2252 _UniformRandomNumberGenerator& __urng,
2253 const param_type& __p)
2254 {
2255 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2256 const _RealType __pi = 3.1415926535897932384626433832795029L;
2257 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2258 __aurng(__urng);
2259 while (__f != __t)
2260 {
2261 _RealType __u;
2262 do
2263 __u = __aurng();
2264 while (__u == 0.5);
2265
2266 *__f++ = __p.a() + __p.b() * std::tan(__pi * __u);
2267 }
2268 }
2269
2270 template<typename _RealType, typename _CharT, typename _Traits>
2273 const cauchy_distribution<_RealType>& __x)
2274 {
2275 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2276
2277 const typename __ios_base::fmtflags __flags = __os.flags();
2278 const _CharT __fill = __os.fill();
2279 const std::streamsize __precision = __os.precision();
2280 const _CharT __space = __os.widen(' ');
2281 __os.flags(__ios_base::scientific | __ios_base::left);
2282 __os.fill(__space);
2284
2285 __os << __x.a() << __space << __x.b();
2286
2287 __os.flags(__flags);
2288 __os.fill(__fill);
2289 __os.precision(__precision);
2290 return __os;
2291 }
2292
2293 template<typename _RealType, typename _CharT, typename _Traits>
2294 std::basic_istream<_CharT, _Traits>&
2297 {
2298 using param_type = typename cauchy_distribution<_RealType>::param_type;
2299 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2300
2301 const typename __ios_base::fmtflags __flags = __is.flags();
2302 __is.flags(__ios_base::dec | __ios_base::skipws);
2303
2304 _RealType __a, __b;
2305 if (__is >> __a >> __b)
2306 __x.param(param_type(__a, __b));
2307
2308 __is.flags(__flags);
2309 return __is;
2310 }
2311
2312
2313 template<typename _RealType>
2314 template<typename _ForwardIterator,
2315 typename _UniformRandomNumberGenerator>
2316 void
2318 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2319 _UniformRandomNumberGenerator& __urng)
2320 {
2321 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2322 while (__f != __t)
2323 *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()));
2324 }
2325
2326 template<typename _RealType>
2327 template<typename _ForwardIterator,
2328 typename _UniformRandomNumberGenerator>
2329 void
2330 std::fisher_f_distribution<_RealType>::
2331 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2332 _UniformRandomNumberGenerator& __urng,
2333 const param_type& __p)
2334 {
2335 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2336 typedef typename std::gamma_distribution<result_type>::param_type
2337 param_type;
2338 param_type __p1(__p.m() / 2);
2339 param_type __p2(__p.n() / 2);
2340 while (__f != __t)
2341 *__f++ = ((_M_gd_x(__urng, __p1) * n())
2342 / (_M_gd_y(__urng, __p2) * m()));
2343 }
2344
2345 template<typename _RealType, typename _CharT, typename _Traits>
2346 std::basic_ostream<_CharT, _Traits>&
2347 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2348 const fisher_f_distribution<_RealType>& __x)
2349 {
2350 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2351
2352 const typename __ios_base::fmtflags __flags = __os.flags();
2353 const _CharT __fill = __os.fill();
2354 const std::streamsize __precision = __os.precision();
2355 const _CharT __space = __os.widen(' ');
2356 __os.flags(__ios_base::scientific | __ios_base::left);
2357 __os.fill(__space);
2359
2360 __os << __x.m() << __space << __x.n()
2361 << __space << __x._M_gd_x << __space << __x._M_gd_y;
2362
2363 __os.flags(__flags);
2364 __os.fill(__fill);
2365 __os.precision(__precision);
2366 return __os;
2367 }
2368
2369 template<typename _RealType, typename _CharT, typename _Traits>
2370 std::basic_istream<_CharT, _Traits>&
2371 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2372 fisher_f_distribution<_RealType>& __x)
2373 {
2374 using param_type
2375 = typename fisher_f_distribution<_RealType>::param_type;
2376 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2377
2378 const typename __ios_base::fmtflags __flags = __is.flags();
2379 __is.flags(__ios_base::dec | __ios_base::skipws);
2380
2381 _RealType __m, __n;
2382 if (__is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y)
2383 __x.param(param_type(__m, __n));
2384
2385 __is.flags(__flags);
2386 return __is;
2387 }
2388
2389
2390 template<typename _RealType>
2391 template<typename _ForwardIterator,
2392 typename _UniformRandomNumberGenerator>
2393 void
2394 std::student_t_distribution<_RealType>::
2395 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2396 _UniformRandomNumberGenerator& __urng)
2397 {
2398 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2399 while (__f != __t)
2400 *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng));
2401 }
2402
2403 template<typename _RealType>
2404 template<typename _ForwardIterator,
2405 typename _UniformRandomNumberGenerator>
2406 void
2407 std::student_t_distribution<_RealType>::
2408 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2409 _UniformRandomNumberGenerator& __urng,
2410 const param_type& __p)
2411 {
2412 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2413 typename std::gamma_distribution<result_type>::param_type
2414 __p2(__p.n() / 2, 2);
2415 while (__f != __t)
2416 *__f++ = _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2));
2417 }
2418
2419 template<typename _RealType, typename _CharT, typename _Traits>
2420 std::basic_ostream<_CharT, _Traits>&
2421 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2422 const student_t_distribution<_RealType>& __x)
2423 {
2424 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2425
2426 const typename __ios_base::fmtflags __flags = __os.flags();
2427 const _CharT __fill = __os.fill();
2428 const std::streamsize __precision = __os.precision();
2429 const _CharT __space = __os.widen(' ');
2430 __os.flags(__ios_base::scientific | __ios_base::left);
2431 __os.fill(__space);
2433
2434 __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd;
2435
2436 __os.flags(__flags);
2437 __os.fill(__fill);
2438 __os.precision(__precision);
2439 return __os;
2440 }
2441
2442 template<typename _RealType, typename _CharT, typename _Traits>
2443 std::basic_istream<_CharT, _Traits>&
2444 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2445 student_t_distribution<_RealType>& __x)
2446 {
2447 using param_type
2448 = typename student_t_distribution<_RealType>::param_type;
2449 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2450
2451 const typename __ios_base::fmtflags __flags = __is.flags();
2452 __is.flags(__ios_base::dec | __ios_base::skipws);
2453
2454 _RealType __n;
2455 if (__is >> __n >> __x._M_nd >> __x._M_gd)
2456 __x.param(param_type(__n));
2457
2458 __is.flags(__flags);
2459 return __is;
2460 }
2461
2462
2463 template<typename _RealType>
2464 void
2465 gamma_distribution<_RealType>::param_type::
2466 _M_initialize()
2467 {
2468 _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha;
2469
2470 const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0);
2471 _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1);
2472 }
2473
2474 /**
2475 * Marsaglia, G. and Tsang, W. W.
2476 * "A Simple Method for Generating Gamma Variables"
2477 * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000.
2478 */
2479 template<typename _RealType>
2480 template<typename _UniformRandomNumberGenerator>
2483 operator()(_UniformRandomNumberGenerator& __urng,
2484 const param_type& __param)
2485 {
2486 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2487 __aurng(__urng);
2488
2489 result_type __u, __v, __n;
2490 const result_type __a1 = (__param._M_malpha
2491 - _RealType(1.0) / _RealType(3.0));
2492
2493 do
2494 {
2495 do
2496 {
2497 __n = _M_nd(__urng);
2498 __v = result_type(1.0) + __param._M_a2 * __n;
2499 }
2500 while (__v <= 0.0);
2501
2502 __v = __v * __v * __v;
2503 __u = __aurng();
2504 }
2505 while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n
2506 && (std::log(__u) > (0.5 * __n * __n + __a1
2507 * (1.0 - __v + std::log(__v)))));
2508
2509 if (__param.alpha() == __param._M_malpha)
2510 return __a1 * __v * __param.beta();
2511 else
2512 {
2513 do
2514 __u = __aurng();
2515 while (__u == 0.0);
2516
2517 return (std::pow(__u, result_type(1.0) / __param.alpha())
2518 * __a1 * __v * __param.beta());
2519 }
2520 }
2521
2522 template<typename _RealType>
2523 template<typename _ForwardIterator,
2524 typename _UniformRandomNumberGenerator>
2525 void
2527 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2528 _UniformRandomNumberGenerator& __urng,
2529 const param_type& __param)
2530 {
2531 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2532 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2533 __aurng(__urng);
2534
2535 result_type __u, __v, __n;
2536 const result_type __a1 = (__param._M_malpha
2537 - _RealType(1.0) / _RealType(3.0));
2538
2539 if (__param.alpha() == __param._M_malpha)
2540 while (__f != __t)
2541 {
2542 do
2543 {
2544 do
2545 {
2546 __n = _M_nd(__urng);
2547 __v = result_type(1.0) + __param._M_a2 * __n;
2548 }
2549 while (__v <= 0.0);
2550
2551 __v = __v * __v * __v;
2552 __u = __aurng();
2553 }
2554 while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n
2555 && (std::log(__u) > (0.5 * __n * __n + __a1
2556 * (1.0 - __v + std::log(__v)))));
2557
2558 *__f++ = __a1 * __v * __param.beta();
2559 }
2560 else
2561 while (__f != __t)
2562 {
2563 do
2564 {
2565 do
2566 {
2567 __n = _M_nd(__urng);
2568 __v = result_type(1.0) + __param._M_a2 * __n;
2569 }
2570 while (__v <= 0.0);
2571
2572 __v = __v * __v * __v;
2573 __u = __aurng();
2574 }
2575 while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n
2576 && (std::log(__u) > (0.5 * __n * __n + __a1
2577 * (1.0 - __v + std::log(__v)))));
2578
2579 do
2580 __u = __aurng();
2581 while (__u == 0.0);
2582
2583 *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha())
2584 * __a1 * __v * __param.beta());
2585 }
2586 }
2587
2588 template<typename _RealType, typename _CharT, typename _Traits>
2589 std::basic_ostream<_CharT, _Traits>&
2590 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2591 const gamma_distribution<_RealType>& __x)
2592 {
2593 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2594
2595 const typename __ios_base::fmtflags __flags = __os.flags();
2596 const _CharT __fill = __os.fill();
2597 const std::streamsize __precision = __os.precision();
2598 const _CharT __space = __os.widen(' ');
2599 __os.flags(__ios_base::scientific | __ios_base::left);
2600 __os.fill(__space);
2602
2603 __os << __x.alpha() << __space << __x.beta()
2604 << __space << __x._M_nd;
2605
2606 __os.flags(__flags);
2607 __os.fill(__fill);
2608 __os.precision(__precision);
2609 return __os;
2610 }
2611
2612 template<typename _RealType, typename _CharT, typename _Traits>
2613 std::basic_istream<_CharT, _Traits>&
2614 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2615 gamma_distribution<_RealType>& __x)
2616 {
2617 using param_type = typename gamma_distribution<_RealType>::param_type;
2618 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2619
2620 const typename __ios_base::fmtflags __flags = __is.flags();
2621 __is.flags(__ios_base::dec | __ios_base::skipws);
2622
2623 _RealType __alpha_val, __beta_val;
2624 if (__is >> __alpha_val >> __beta_val >> __x._M_nd)
2625 __x.param(param_type(__alpha_val, __beta_val));
2626
2627 __is.flags(__flags);
2628 return __is;
2629 }
2630
2631
2632 template<typename _RealType>
2633 template<typename _UniformRandomNumberGenerator>
2636 operator()(_UniformRandomNumberGenerator& __urng,
2637 const param_type& __p)
2638 {
2639 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2640 __aurng(__urng);
2641 return __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
2642 result_type(1) / __p.a());
2643 }
2644
2645 template<typename _RealType>
2646 template<typename _ForwardIterator,
2647 typename _UniformRandomNumberGenerator>
2648 void
2650 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2651 _UniformRandomNumberGenerator& __urng,
2652 const param_type& __p)
2653 {
2654 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2655 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2656 __aurng(__urng);
2657 auto __inv_a = result_type(1) / __p.a();
2658
2659 while (__f != __t)
2660 *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
2661 __inv_a);
2662 }
2663
2664 template<typename _RealType, typename _CharT, typename _Traits>
2667 const weibull_distribution<_RealType>& __x)
2668 {
2669 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2670
2671 const typename __ios_base::fmtflags __flags = __os.flags();
2672 const _CharT __fill = __os.fill();
2673 const std::streamsize __precision = __os.precision();
2674 const _CharT __space = __os.widen(' ');
2675 __os.flags(__ios_base::scientific | __ios_base::left);
2676 __os.fill(__space);
2678
2679 __os << __x.a() << __space << __x.b();
2680
2681 __os.flags(__flags);
2682 __os.fill(__fill);
2683 __os.precision(__precision);
2684 return __os;
2685 }
2686
2687 template<typename _RealType, typename _CharT, typename _Traits>
2688 std::basic_istream<_CharT, _Traits>&
2691 {
2692 using param_type = typename weibull_distribution<_RealType>::param_type;
2693 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2694
2695 const typename __ios_base::fmtflags __flags = __is.flags();
2696 __is.flags(__ios_base::dec | __ios_base::skipws);
2697
2698 _RealType __a, __b;
2699 if (__is >> __a >> __b)
2700 __x.param(param_type(__a, __b));
2701
2702 __is.flags(__flags);
2703 return __is;
2704 }
2705
2706
2707 template<typename _RealType>
2708 template<typename _UniformRandomNumberGenerator>
2711 operator()(_UniformRandomNumberGenerator& __urng,
2712 const param_type& __p)
2713 {
2714 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2715 __aurng(__urng);
2716 return __p.a() - __p.b() * std::log(-std::log(result_type(1)
2717 - __aurng()));
2718 }
2719
2720 template<typename _RealType>
2721 template<typename _ForwardIterator,
2722 typename _UniformRandomNumberGenerator>
2723 void
2725 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2726 _UniformRandomNumberGenerator& __urng,
2727 const param_type& __p)
2728 {
2729 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2730 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2731 __aurng(__urng);
2732
2733 while (__f != __t)
2734 *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1)
2735 - __aurng()));
2736 }
2737
2738 template<typename _RealType, typename _CharT, typename _Traits>
2741 const extreme_value_distribution<_RealType>& __x)
2742 {
2743 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2744
2745 const typename __ios_base::fmtflags __flags = __os.flags();
2746 const _CharT __fill = __os.fill();
2747 const std::streamsize __precision = __os.precision();
2748 const _CharT __space = __os.widen(' ');
2749 __os.flags(__ios_base::scientific | __ios_base::left);
2750 __os.fill(__space);
2752
2753 __os << __x.a() << __space << __x.b();
2754
2755 __os.flags(__flags);
2756 __os.fill(__fill);
2757 __os.precision(__precision);
2758 return __os;
2759 }
2760
2761 template<typename _RealType, typename _CharT, typename _Traits>
2762 std::basic_istream<_CharT, _Traits>&
2765 {
2766 using param_type
2768 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2769
2770 const typename __ios_base::fmtflags __flags = __is.flags();
2771 __is.flags(__ios_base::dec | __ios_base::skipws);
2772
2773 _RealType __a, __b;
2774 if (__is >> __a >> __b)
2775 __x.param(param_type(__a, __b));
2776
2777 __is.flags(__flags);
2778 return __is;
2779 }
2780
2781
2782 template<typename _IntType>
2783 void
2784 discrete_distribution<_IntType>::param_type::
2785 _M_initialize()
2786 {
2787 if (_M_prob.size() < 2)
2788 {
2789 _M_prob.clear();
2790 return;
2791 }
2792
2793 const double __sum = std::accumulate(_M_prob.begin(),
2794 _M_prob.end(), 0.0);
2795 __glibcxx_assert(__sum > 0);
2796 // Now normalize the probabilites.
2797 __detail::__normalize(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
2798 __sum);
2799 // Accumulate partial sums.
2800 _M_cp.reserve(_M_prob.size());
2801 std::partial_sum(_M_prob.begin(), _M_prob.end(),
2802 std::back_inserter(_M_cp));
2803 // Make sure the last cumulative probability is one.
2804 _M_cp[_M_cp.size() - 1] = 1.0;
2805 }
2806
2807 template<typename _IntType>
2808 template<typename _Func>
2809 discrete_distribution<_IntType>::param_type::
2810 param_type(size_t __nw, double __xmin, double __xmax, _Func __fw)
2811 : _M_prob(), _M_cp()
2812 {
2813 const size_t __n = __nw == 0 ? 1 : __nw;
2814 const double __delta = (__xmax - __xmin) / __n;
2815
2816 _M_prob.reserve(__n);
2817 for (size_t __k = 0; __k < __nw; ++__k)
2818 _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta));
2819
2820 _M_initialize();
2821 }
2822
2823 template<typename _IntType>
2824 template<typename _UniformRandomNumberGenerator>
2825 typename discrete_distribution<_IntType>::result_type
2826 discrete_distribution<_IntType>::
2827 operator()(_UniformRandomNumberGenerator& __urng,
2828 const param_type& __param)
2829 {
2830 if (__param._M_cp.empty())
2831 return result_type(0);
2832
2833 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
2834 __aurng(__urng);
2835
2836 const double __p = __aurng();
2837 auto __pos = std::lower_bound(__param._M_cp.begin(),
2838 __param._M_cp.end(), __p);
2839
2840 return __pos - __param._M_cp.begin();
2841 }
2842
2843 template<typename _IntType>
2844 template<typename _ForwardIterator,
2845 typename _UniformRandomNumberGenerator>
2846 void
2847 discrete_distribution<_IntType>::
2848 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2849 _UniformRandomNumberGenerator& __urng,
2850 const param_type& __param)
2851 {
2852 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2853
2854 if (__param._M_cp.empty())
2855 {
2856 while (__f != __t)
2857 *__f++ = result_type(0);
2858 return;
2859 }
2860
2861 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
2862 __aurng(__urng);
2863
2864 while (__f != __t)
2865 {
2866 const double __p = __aurng();
2867 auto __pos = std::lower_bound(__param._M_cp.begin(),
2868 __param._M_cp.end(), __p);
2869
2870 *__f++ = __pos - __param._M_cp.begin();
2871 }
2872 }
2873
2874 template<typename _IntType, typename _CharT, typename _Traits>
2877 const discrete_distribution<_IntType>& __x)
2878 {
2879 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
2880
2881 const typename __ios_base::fmtflags __flags = __os.flags();
2882 const _CharT __fill = __os.fill();
2883 const std::streamsize __precision = __os.precision();
2884 const _CharT __space = __os.widen(' ');
2885 __os.flags(__ios_base::scientific | __ios_base::left);
2886 __os.fill(__space);
2888
2889 std::vector<double> __prob = __x.probabilities();
2890 __os << __prob.size();
2891 for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit)
2892 __os << __space << *__dit;
2893
2894 __os.flags(__flags);
2895 __os.fill(__fill);
2896 __os.precision(__precision);
2897 return __os;
2898 }
2899
2900namespace __detail
2901{
2902 template<typename _ValT, typename _CharT, typename _Traits>
2903 basic_istream<_CharT, _Traits>&
2904 __extract_params(basic_istream<_CharT, _Traits>& __is,
2905 vector<_ValT>& __vals, size_t __n)
2906 {
2907 __vals.reserve(__n);
2908 while (__n--)
2909 {
2910 _ValT __val;
2911 if (__is >> __val)
2912 __vals.push_back(__val);
2913 else
2914 break;
2915 }
2916 return __is;
2917 }
2918} // namespace __detail
2919
2920 template<typename _IntType, typename _CharT, typename _Traits>
2923 discrete_distribution<_IntType>& __x)
2924 {
2925 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
2926
2927 const typename __ios_base::fmtflags __flags = __is.flags();
2928 __is.flags(__ios_base::dec | __ios_base::skipws);
2929
2930 size_t __n;
2931 if (__is >> __n)
2932 {
2933 std::vector<double> __prob_vec;
2934 if (__detail::__extract_params(__is, __prob_vec, __n))
2935 __x.param({__prob_vec.begin(), __prob_vec.end()});
2936 }
2937
2938 __is.flags(__flags);
2939 return __is;
2940 }
2941
2942
2943 template<typename _RealType>
2944 void
2945 piecewise_constant_distribution<_RealType>::param_type::
2946 _M_initialize()
2947 {
2948 if (_M_int.size() < 2
2949 || (_M_int.size() == 2
2950 && _M_int[0] == _RealType(0)
2951 && _M_int[1] == _RealType(1)))
2952 {
2953 _M_int.clear();
2954 _M_den.clear();
2955 return;
2956 }
2957
2958 const double __sum = std::accumulate(_M_den.begin(),
2959 _M_den.end(), 0.0);
2960 __glibcxx_assert(__sum > 0);
2961
2962 __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(),
2963 __sum);
2964
2965 _M_cp.reserve(_M_den.size());
2966 std::partial_sum(_M_den.begin(), _M_den.end(),
2967 std::back_inserter(_M_cp));
2968
2969 // Make sure the last cumulative probability is one.
2970 _M_cp[_M_cp.size() - 1] = 1.0;
2971
2972 for (size_t __k = 0; __k < _M_den.size(); ++__k)
2973 _M_den[__k] /= _M_int[__k + 1] - _M_int[__k];
2974 }
2975
2976 template<typename _RealType>
2977 template<typename _InputIteratorB, typename _InputIteratorW>
2978 piecewise_constant_distribution<_RealType>::param_type::
2979 param_type(_InputIteratorB __bbegin,
2980 _InputIteratorB __bend,
2981 _InputIteratorW __wbegin)
2982 : _M_int(), _M_den(), _M_cp()
2983 {
2984 if (__bbegin != __bend)
2985 {
2986 for (;;)
2987 {
2988 _M_int.push_back(*__bbegin);
2989 ++__bbegin;
2990 if (__bbegin == __bend)
2991 break;
2992
2993 _M_den.push_back(*__wbegin);
2994 ++__wbegin;
2995 }
2996 }
2997
2998 _M_initialize();
2999 }
3000
3001 template<typename _RealType>
3002 template<typename _Func>
3003 piecewise_constant_distribution<_RealType>::param_type::
3004 param_type(initializer_list<_RealType> __bl, _Func __fw)
3005 : _M_int(), _M_den(), _M_cp()
3006 {
3007 _M_int.reserve(__bl.size());
3008 for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
3009 _M_int.push_back(*__biter);
3010
3011 _M_den.reserve(_M_int.size() - 1);
3012 for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
3013 _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k])));
3014
3015 _M_initialize();
3016 }
3017
3018 template<typename _RealType>
3019 template<typename _Func>
3020 piecewise_constant_distribution<_RealType>::param_type::
3021 param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
3022 : _M_int(), _M_den(), _M_cp()
3023 {
3024 const size_t __n = __nw == 0 ? 1 : __nw;
3025 const _RealType __delta = (__xmax - __xmin) / __n;
3026
3027 _M_int.reserve(__n + 1);
3028 for (size_t __k = 0; __k <= __nw; ++__k)
3029 _M_int.push_back(__xmin + __k * __delta);
3030
3031 _M_den.reserve(__n);
3032 for (size_t __k = 0; __k < __nw; ++__k)
3033 _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta));
3034
3035 _M_initialize();
3036 }
3037
3038 template<typename _RealType>
3039 template<typename _UniformRandomNumberGenerator>
3040 typename piecewise_constant_distribution<_RealType>::result_type
3041 piecewise_constant_distribution<_RealType>::
3042 operator()(_UniformRandomNumberGenerator& __urng,
3043 const param_type& __param)
3044 {
3045 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3046 __aurng(__urng);
3047
3048 const double __p = __aurng();
3049 if (__param._M_cp.empty())
3050 return __p;
3051
3052 auto __pos = std::lower_bound(__param._M_cp.begin(),
3053 __param._M_cp.end(), __p);
3054 const size_t __i = __pos - __param._M_cp.begin();
3055
3056 const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3057
3058 return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i];
3059 }
3060
3061 template<typename _RealType>
3062 template<typename _ForwardIterator,
3063 typename _UniformRandomNumberGenerator>
3064 void
3065 piecewise_constant_distribution<_RealType>::
3066 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3067 _UniformRandomNumberGenerator& __urng,
3068 const param_type& __param)
3069 {
3070 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
3071 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3072 __aurng(__urng);
3073
3074 if (__param._M_cp.empty())
3075 {
3076 while (__f != __t)
3077 *__f++ = __aurng();
3078 return;
3079 }
3080
3081 while (__f != __t)
3082 {
3083 const double __p = __aurng();
3084
3085 auto __pos = std::lower_bound(__param._M_cp.begin(),
3086 __param._M_cp.end(), __p);
3087 const size_t __i = __pos - __param._M_cp.begin();
3088
3089 const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3090
3091 *__f++ = (__param._M_int[__i]
3092 + (__p - __pref) / __param._M_den[__i]);
3093 }
3094 }
3095
3096 template<typename _RealType, typename _CharT, typename _Traits>
3099 const piecewise_constant_distribution<_RealType>& __x)
3100 {
3101 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
3102
3103 const typename __ios_base::fmtflags __flags = __os.flags();
3104 const _CharT __fill = __os.fill();
3105 const std::streamsize __precision = __os.precision();
3106 const _CharT __space = __os.widen(' ');
3107 __os.flags(__ios_base::scientific | __ios_base::left);
3108 __os.fill(__space);
3110
3111 std::vector<_RealType> __int = __x.intervals();
3112 __os << __int.size() - 1;
3113
3114 for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
3115 __os << __space << *__xit;
3116
3117 std::vector<double> __den = __x.densities();
3118 for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
3119 __os << __space << *__dit;
3120
3121 __os.flags(__flags);
3122 __os.fill(__fill);
3123 __os.precision(__precision);
3124 return __os;
3125 }
3126
3127 template<typename _RealType, typename _CharT, typename _Traits>
3130 piecewise_constant_distribution<_RealType>& __x)
3131 {
3132 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
3133
3134 const typename __ios_base::fmtflags __flags = __is.flags();
3135 __is.flags(__ios_base::dec | __ios_base::skipws);
3136
3137 size_t __n;
3138 if (__is >> __n)
3139 {
3140 std::vector<_RealType> __int_vec;
3141 if (__detail::__extract_params(__is, __int_vec, __n + 1))
3142 {
3143 std::vector<double> __den_vec;
3144 if (__detail::__extract_params(__is, __den_vec, __n))
3145 {
3146 __x.param({ __int_vec.begin(), __int_vec.end(),
3147 __den_vec.begin() });
3148 }
3149 }
3150 }
3151
3152 __is.flags(__flags);
3153 return __is;
3154 }
3155
3156
3157 template<typename _RealType>
3158 void
3159 piecewise_linear_distribution<_RealType>::param_type::
3160 _M_initialize()
3161 {
3162 if (_M_int.size() < 2
3163 || (_M_int.size() == 2
3164 && _M_int[0] == _RealType(0)
3165 && _M_int[1] == _RealType(1)
3166 && _M_den[0] == _M_den[1]))
3167 {
3168 _M_int.clear();
3169 _M_den.clear();
3170 return;
3171 }
3172
3173 double __sum = 0.0;
3174 _M_cp.reserve(_M_int.size() - 1);
3175 _M_m.reserve(_M_int.size() - 1);
3176 for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
3177 {
3178 const _RealType __delta = _M_int[__k + 1] - _M_int[__k];
3179 __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta;
3180 _M_cp.push_back(__sum);
3181 _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta);
3182 }
3183 __glibcxx_assert(__sum > 0);
3184
3185 // Now normalize the densities...
3186 __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(),
3187 __sum);
3188 // ... and partial sums...
3189 __detail::__normalize(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), __sum);
3190 // ... and slopes.
3191 __detail::__normalize(_M_m.begin(), _M_m.end(), _M_m.begin(), __sum);
3192
3193 // Make sure the last cumulative probablility is one.
3194 _M_cp[_M_cp.size() - 1] = 1.0;
3195 }
3196
3197 template<typename _RealType>
3198 template<typename _InputIteratorB, typename _InputIteratorW>
3199 piecewise_linear_distribution<_RealType>::param_type::
3200 param_type(_InputIteratorB __bbegin,
3201 _InputIteratorB __bend,
3202 _InputIteratorW __wbegin)
3203 : _M_int(), _M_den(), _M_cp(), _M_m()
3204 {
3205 for (; __bbegin != __bend; ++__bbegin, (void) ++__wbegin)
3206 {
3207 _M_int.push_back(*__bbegin);
3208 _M_den.push_back(*__wbegin);
3209 }
3210
3211 _M_initialize();
3212 }
3213
3214 template<typename _RealType>
3215 template<typename _Func>
3216 piecewise_linear_distribution<_RealType>::param_type::
3217 param_type(initializer_list<_RealType> __bl, _Func __fw)
3218 : _M_int(), _M_den(), _M_cp(), _M_m()
3219 {
3220 _M_int.reserve(__bl.size());
3221 _M_den.reserve(__bl.size());
3222 for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
3223 {
3224 _M_int.push_back(*__biter);
3225 _M_den.push_back(__fw(*__biter));
3226 }
3227
3228 _M_initialize();
3229 }
3230
3231 template<typename _RealType>
3232 template<typename _Func>
3233 piecewise_linear_distribution<_RealType>::param_type::
3234 param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
3235 : _M_int(), _M_den(), _M_cp(), _M_m()
3236 {
3237 const size_t __n = __nw == 0 ? 1 : __nw;
3238 const _RealType __delta = (__xmax - __xmin) / __n;
3239
3240 _M_int.reserve(__n + 1);
3241 _M_den.reserve(__n + 1);
3242 for (size_t __k = 0; __k <= __nw; ++__k)
3243 {
3244 _M_int.push_back(__xmin + __k * __delta);
3245 _M_den.push_back(__fw(_M_int[__k] + __delta));
3246 }
3247
3248 _M_initialize();
3249 }
3250
3251 template<typename _RealType>
3252 template<typename _UniformRandomNumberGenerator>
3253 typename piecewise_linear_distribution<_RealType>::result_type
3254 piecewise_linear_distribution<_RealType>::
3255 operator()(_UniformRandomNumberGenerator& __urng,
3256 const param_type& __param)
3257 {
3258 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3259 __aurng(__urng);
3260
3261 const double __p = __aurng();
3262 if (__param._M_cp.empty())
3263 return __p;
3264
3265 auto __pos = std::lower_bound(__param._M_cp.begin(),
3266 __param._M_cp.end(), __p);
3267 const size_t __i = __pos - __param._M_cp.begin();
3268
3269 const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3270
3271 const double __a = 0.5 * __param._M_m[__i];
3272 const double __b = __param._M_den[__i];
3273 const double __cm = __p - __pref;
3274
3275 _RealType __x = __param._M_int[__i];
3276 if (__a == 0)
3277 __x += __cm / __b;
3278 else
3279 {
3280 const double __d = __b * __b + 4.0 * __a * __cm;
3281 __x += 0.5 * (std::sqrt(__d) - __b) / __a;
3282 }
3283
3284 return __x;
3285 }
3286
3287 template<typename _RealType>
3288 template<typename _ForwardIterator,
3289 typename _UniformRandomNumberGenerator>
3290 void
3291 piecewise_linear_distribution<_RealType>::
3292 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3293 _UniformRandomNumberGenerator& __urng,
3294 const param_type& __param)
3295 {
3296 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
3297 // We could duplicate everything from operator()...
3298 while (__f != __t)
3299 *__f++ = this->operator()(__urng, __param);
3300 }
3301
3302 template<typename _RealType, typename _CharT, typename _Traits>
3305 const piecewise_linear_distribution<_RealType>& __x)
3306 {
3307 using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base;
3308
3309 const typename __ios_base::fmtflags __flags = __os.flags();
3310 const _CharT __fill = __os.fill();
3311 const std::streamsize __precision = __os.precision();
3312 const _CharT __space = __os.widen(' ');
3313 __os.flags(__ios_base::scientific | __ios_base::left);
3314 __os.fill(__space);
3316
3317 std::vector<_RealType> __int = __x.intervals();
3318 __os << __int.size() - 1;
3319
3320 for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
3321 __os << __space << *__xit;
3322
3323 std::vector<double> __den = __x.densities();
3324 for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
3325 __os << __space << *__dit;
3326
3327 __os.flags(__flags);
3328 __os.fill(__fill);
3329 __os.precision(__precision);
3330 return __os;
3331 }
3332
3333 template<typename _RealType, typename _CharT, typename _Traits>
3336 piecewise_linear_distribution<_RealType>& __x)
3337 {
3338 using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
3339
3340 const typename __ios_base::fmtflags __flags = __is.flags();
3341 __is.flags(__ios_base::dec | __ios_base::skipws);
3342
3343 size_t __n;
3344 if (__is >> __n)
3345 {
3346 vector<_RealType> __int_vec;
3347 if (__detail::__extract_params(__is, __int_vec, __n + 1))
3348 {
3349 vector<double> __den_vec;
3350 if (__detail::__extract_params(__is, __den_vec, __n + 1))
3351 {
3352 __x.param({ __int_vec.begin(), __int_vec.end(),
3353 __den_vec.begin() });
3354 }
3355 }
3356 }
3357 __is.flags(__flags);
3358 return __is;
3359 }
3360
3361
3362 template<typename _IntType, typename>
3363 seed_seq::seed_seq(std::initializer_list<_IntType> __il)
3364 {
3365 _M_v.reserve(__il.size());
3366 for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter)
3367 _M_v.push_back(__detail::__mod<result_type,
3368 __detail::_Shift<result_type, 32>::__value>(*__iter));
3369 }
3370
3371 template<typename _InputIterator>
3372 seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end)
3373 {
3374#pragma GCC diagnostic push
3375#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
3376 if constexpr (__is_random_access_iter<_InputIterator>::value)
3377 _M_v.reserve(std::distance(__begin, __end));
3378#pragma GCC diagnostic pop
3379
3380 for (_InputIterator __iter = __begin; __iter != __end; ++__iter)
3381 _M_v.push_back(__detail::__mod<result_type,
3382 __detail::_Shift<result_type, 32>::__value>(*__iter));
3383 }
3384
3385 template<typename _RandomAccessIterator>
3386 void
3387 seed_seq::generate(_RandomAccessIterator __begin,
3388 _RandomAccessIterator __end)
3389 {
3390 typedef typename iterator_traits<_RandomAccessIterator>::value_type
3391 _Type;
3392
3393 if (__begin == __end)
3394 return;
3395
3396 std::fill(__begin, __end, _Type(0x8b8b8b8bu));
3397
3398 const size_t __n = __end - __begin;
3399 const size_t __s = _M_v.size();
3400 const size_t __t = (__n >= 623) ? 11
3401 : (__n >= 68) ? 7
3402 : (__n >= 39) ? 5
3403 : (__n >= 7) ? 3
3404 : (__n - 1) / 2;
3405 const size_t __p = (__n - __t) / 2;
3406 const size_t __q = __p + __t;
3407 const size_t __m = std::max(size_t(__s + 1), __n);
3408
3409#ifndef __UINT32_TYPE__
3410 struct _Up
3411 {
3412 _Up(uint_least32_t v) : _M_v(v & 0xffffffffu) { }
3413
3414 operator uint_least32_t() const { return _M_v; }
3415
3416 uint_least32_t _M_v;
3417 };
3418 using uint32_t = _Up;
3419#endif
3420
3421 // k == 0, every element in [begin,end) equals 0x8b8b8b8bu
3422 {
3423 uint32_t __r1 = 1371501266u;
3424 uint32_t __r2 = __r1 + __s;
3425 __begin[__p] += __r1;
3426 __begin[__q] = (uint32_t)__begin[__q] + __r2;
3427 __begin[0] = __r2;
3428 }
3429
3430 for (size_t __k = 1; __k <= __s; ++__k)
3431 {
3432 const size_t __kn = __k % __n;
3433 const size_t __kpn = (__k + __p) % __n;
3434 const size_t __kqn = (__k + __q) % __n;
3435 uint32_t __arg = (__begin[__kn]
3436 ^ __begin[__kpn]
3437 ^ __begin[(__k - 1) % __n]);
3438 uint32_t __r1 = 1664525u * (__arg ^ (__arg >> 27));
3439 uint32_t __r2 = __r1 + (uint32_t)__kn + _M_v[__k - 1];
3440 __begin[__kpn] = (uint32_t)__begin[__kpn] + __r1;
3441 __begin[__kqn] = (uint32_t)__begin[__kqn] + __r2;
3442 __begin[__kn] = __r2;
3443 }
3444
3445 for (size_t __k = __s + 1; __k < __m; ++__k)
3446 {
3447 const size_t __kn = __k % __n;
3448 const size_t __kpn = (__k + __p) % __n;
3449 const size_t __kqn = (__k + __q) % __n;
3450 uint32_t __arg = (__begin[__kn]
3451 ^ __begin[__kpn]
3452 ^ __begin[(__k - 1) % __n]);
3453 uint32_t __r1 = 1664525u * (__arg ^ (__arg >> 27));
3454 uint32_t __r2 = __r1 + (uint32_t)__kn;
3455 __begin[__kpn] = (uint32_t)__begin[__kpn] + __r1;
3456 __begin[__kqn] = (uint32_t)__begin[__kqn] + __r2;
3457 __begin[__kn] = __r2;
3458 }
3459
3460 for (size_t __k = __m; __k < __m + __n; ++__k)
3461 {
3462 const size_t __kn = __k % __n;
3463 const size_t __kpn = (__k + __p) % __n;
3464 const size_t __kqn = (__k + __q) % __n;
3465 uint32_t __arg = (__begin[__kn]
3466 + __begin[__kpn]
3467 + __begin[(__k - 1) % __n]);
3468 uint32_t __r3 = 1566083941u * (__arg ^ (__arg >> 27));
3469 uint32_t __r4 = __r3 - __kn;
3470 __begin[__kpn] ^= __r3;
3471 __begin[__kqn] ^= __r4;
3472 __begin[__kn] = __r4;
3473 }
3474 }
3475
3476// [rand.util.canonical]
3477// generate_canonical(RNG&)
3478
3479#ifndef _GLIBCXX_USE_OLD_GENERATE_CANONICAL
3480
3481#pragma GCC diagnostic push
3482#pragma GCC diagnostic ignored "-Wc++14-extensions" // for variable templates
3483#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
3484
3485 // This version is used when Urbg::max()-Urbg::min() is a power of
3486 // two less 1, the norm in real programs. It works by calling urng()
3487 // as many times as needed to fill the target mantissa, accumulating
3488 // entropy into an integer value, converting that to the float type,
3489 // and then dividing by the range of the integer value (a constexpr
3490 // power of 2, so only adjusts the exponent) to produce a result in
3491 // [0..1]. In case of an exact 1.0 result, we re-try.
3492 //
3493 // It needs to work even when the integer type used is only as big
3494 // as the float mantissa, such as uint64_t for long double. So,
3495 // commented-out assignments represent computations the Standard
3496 // prescribes but cannot be performed, or are not used. Names are
3497 // chosen to match the description in the Standard.
3498 //
3499 // When the result is close to zero, the strict Standard-prescribed
3500 // calculation may leave more low-order zeros in the mantissa than
3501 // is usually necessary. When spare entropy has been extracted, as
3502 // is usual for float and double, some or all of the spare entropy
3503 // can commonly be pulled into the result for better randomness.
3504 // Defining _GLIBCXX_GENERATE_CANONICAL_STRICT discards it instead.
3505 //
3506 // When k calls to urng() yield more bits of entropy, log2_Rk_max,
3507 // than fit into UInt, we discard some of it by overflowing, which
3508 // is OK. On converting the integer representation of the sample
3509 // to the float value, we must divide out the (possibly-truncated)
3510 // size log2_Rk.
3511 //
3512 // This implementation works with std::bfloat16, which can exactly
3513 // represent 2^32, but not with std::float16_t, limited to 2^15.
3514
3515 template<typename _RealT, typename _UInt, size_t __d, typename _Urbg>
3516 _RealT
3517 __generate_canonical_pow2(_Urbg& __urng)
3518 {
3519 // Parameter __d is the actual target number of bits.
3520 // Commented-out assignments below are of values specified in
3521 // the Standard, but not used here for reasons noted.
3522 // r = 2; // Redundant, we only support radix 2.
3523 using _Rng = decltype(_Urbg::max());
3524 const _Rng __rng_range_less_1 = _Urbg::max() - _Urbg::min();
3525 const _UInt __uint_range_less_1 = ~_UInt(0);
3526 // R = _UInt(__rng_range_less_1) + 1; // May wrap to 0.
3527 const auto __log2_R = __builtin_popcountg(__rng_range_less_1);
3528 const auto __log2_uint_max = __builtin_popcountg(__uint_range_less_1);
3529 // rd = _UInt(1) << __d; // Could overflow, UB.
3530 const unsigned __k = (__d + __log2_R - 1) / __log2_R;
3531 const unsigned __log2_Rk_max = __k * __log2_R;
3532 const unsigned __log2_Rk = // Bits of entropy actually obtained:
3533 __log2_uint_max < __log2_Rk_max ? __log2_uint_max : __log2_Rk_max;
3534 static_assert(__log2_Rk >= __d);
3535 // Rk = _UInt(1) << __log2_Rk; // Likely overflows, UB.
3536 constexpr _RealT __Rk = _RealT(_UInt(1) << (__log2_Rk - 1)) * 2.0;
3537#if defined(_GLIBCXX_GENERATE_CANONICAL_STRICT)
3538 const unsigned __log2_x = __log2_Rk - __d; // # of spare entropy bits.
3539#else
3540 const unsigned __log2_x = 0;
3541#endif
3542 const _UInt __x = _UInt(1) << __log2_x;
3543 constexpr _RealT __rd = __Rk / __x;
3544 // xrd = __x << __d; // Could overflow.
3545
3546 while (true)
3547 {
3548 _UInt __sum = _UInt(__urng() - _Urbg::min());
3549 for (unsigned __i = __k - 1, __shift = 0; __i > 0; --__i)
3550 {
3551 __shift += __log2_R;
3552 __sum |= _UInt(__urng() - _Urbg::min()) << __shift;
3553 }
3554 const _RealT __ret = _RealT(__sum >> __log2_x) / __rd;
3555 if (__ret < _RealT(1.0))
3556 return __ret;
3557 }
3558 }
3559
3560 template <typename _UInt>
3561 constexpr _UInt
3562 __gen_can_pow(_UInt __base, size_t __exponent)
3563 {
3564 _UInt __prod = __base;
3565 while (--__exponent != 0) __prod *= __base;
3566 return __prod;
3567 }
3568
3569 template <typename _UInt>
3570 constexpr unsigned
3571 __gen_can_rng_calls_needed(_UInt __R, _UInt __rd)
3572 {
3573 unsigned __i = 1;
3574 for (auto __Ri = __R; __Ri < __rd; __Ri *= __R)
3575 ++__i;
3576 return __i;
3577 }
3578
3579 // This version must be used when the range of possible RNG results,
3580 // Urbg::max()-Urbg::min(), is not a power of two less one. The UInt
3581 // type passed must be big enough to represent Rk, R^k, a power of R
3582 // (the range of values produced by the rng) up to twice the length
3583 // of the mantissa.
3584
3585 template<typename _RealT, typename _UInt, size_t __d, typename _Urbg>
3586 _RealT
3587 __generate_canonical_any(_Urbg& __urng)
3588 {
3589 static_assert(__d < __builtin_popcountg(~_UInt(0)));
3590 // Names below are chosen to match the description in the Standard.
3591 // Parameter d is the actual target number of bits.
3592 const _UInt __r = 2;
3593 const _UInt __R = _UInt(_Urbg::max() - _Urbg::min()) + 1;
3594 const _UInt __rd = _UInt(1) << __d;
3595 const unsigned __k = __gen_can_rng_calls_needed(__R, __rd);
3596 const _UInt __Rk = __gen_can_pow(__R, __k);
3597 const _UInt __x = __Rk/__rd;
3598
3599 while (true)
3600 {
3601 _UInt __Ri = 1, __sum = __urng() - _Urbg::min();
3602 for (int __i = __k - 1; __i > 0; --__i)
3603 {
3604 __Ri *= __R;
3605 __sum += (__urng() - _Urbg::min()) * __Ri;
3606 }
3607 const _RealT __ret = _RealT(__sum / __x) / __rd;
3608 if (__ret < _RealT(1.0))
3609 return __ret;
3610 }
3611 }
3612
3613#if !defined(_GLIBCXX_GENERATE_CANONICAL_STRICT)
3614 template <typename _Tp>
3615 const bool __is_rand_dist_float_v = is_floating_point<_Tp>::value;
3616#else
3617 template <typename _Tp> const bool __is_rand_dist_float_v = false;
3618 template <> const bool __is_rand_dist_float_v<float> = true;
3619 template <> const bool __is_rand_dist_float_v<double> = true;
3620 template <> const bool __is_rand_dist_float_v<long double> = true;
3621#endif
3622
3623 // Note, this works even when (__range + 1) overflows:
3624 template <typename _Rng>
3625 constexpr bool __is_power_of_2_less_1(_Rng __range)
3626 { return ((__range + 1) & __range) == 0; };
3627
3628_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
3629 /** Produce a random floating-point value in the range [0..1)
3630 *
3631 * The result of `std::generate_canonical<RealT,digits>(urng)` is a
3632 * random floating-point value of type `RealT` in the range [0..1),
3633 * using entropy provided by the uniform random bit generator `urng`.
3634 * A value for `digits` may be passed to limit the precision of the
3635 * result to so many bits, but normally `-1u` is passed to get the
3636 * native precision of `RealT`. As many `urng()` calls are made as
3637 * needed to obtain the required entropy. On rare occasions, more
3638 * `urng()` calls are used. It is fastest when the value of
3639 * `Urbg::max()` is a power of two less one, such as from a
3640 * `std::philox4x32` (for `float`) or `philox4x64` (for `double`).
3641 *
3642 * @since C++11
3643 */
3644 template<typename _RealT, size_t __digits,
3645 typename _Urbg>
3646 _RealT
3647 generate_canonical(_Urbg& __urng)
3648 {
3649#ifdef __glibcxx_concepts
3651#endif
3652 static_assert(__is_rand_dist_float_v<_RealT>,
3653 "template argument must be a floating point type");
3654 static_assert(__digits != 0 && _Urbg::max() > _Urbg::min(),
3655 "random samples with 0 bits are not meaningful");
3656 static_assert(std::numeric_limits<_RealT>::radix == 2,
3657 "only base-2 float types are supported");
3658#if defined(__STDCPP_FLOAT16_T__)
3659 static_assert(! is_same_v<_RealT, _Float16>,
3660 "float16_t type is not supported, consider using bfloat16_t");
3661#endif
3662
3663 using _Rng = decltype(_Urbg::max());
3664 const unsigned __d_max = std::numeric_limits<_RealT>::digits;
3665 const unsigned __d = __digits > __d_max ? __d_max : __digits;
3666
3667 // If the RNG range is a power of 2 less 1, the float type mantissa
3668 // is enough bits. If not, we need more.
3669 if constexpr (__is_power_of_2_less_1(_Urbg::max() - _Urbg::min()))
3670 {
3671 if constexpr (__d <= 32)
3672 return __generate_canonical_pow2<_RealT, uint32_t, __d>(__urng);
3673 else if constexpr (__d <= 64)
3674 return __generate_canonical_pow2<_RealT, uint64_t, __d>(__urng);
3675 else
3676 {
3677#if defined(__SIZEOF_INT128__)
3678 // Accommodate double double or float128.
3679 return __extension__ __generate_canonical_pow2<
3680 _RealT, unsigned __int128, __d>(__urng);
3681#else
3682 static_assert(false,
3683 "float precision >64 requires __int128 support");
3684#endif
3685 }
3686 }
3687 else // Need up to 2x bits.
3688 {
3689 if constexpr (__d <= 32)
3690 return __generate_canonical_any<_RealT, uint64_t, __d>(__urng);
3691 else
3692 {
3693#if defined(__SIZEOF_INT128__)
3694 static_assert(__d <= 64,
3695 "irregular RNG with float precision >64 is not supported");
3696 return __extension__ __generate_canonical_any<
3697 _RealT, unsigned __int128, __d>(__urng);
3698#else
3699 static_assert(false, "irregular RNG with float precision"
3700 " >32 requires __int128 support");
3701#endif
3702 }
3703 }
3704 }
3705_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
3706
3707#pragma GCC diagnostic pop
3708
3709#else // _GLIBCXX_USE_OLD_GENERATE_CANONICAL
3710
3711 // This is the pre-P0952 definition, to reproduce old results.
3712
3713 template<typename _RealType, size_t __bits,
3714 typename _UniformRandomNumberGenerator>
3715 _RealType
3716 generate_canonical(_UniformRandomNumberGenerator& __urng)
3717 {
3719 "template argument must be a floating point type");
3720
3721 const size_t __b
3722 = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits),
3723 __bits);
3724 const long double __r = static_cast<long double>(__urng.max())
3725 - static_cast<long double>(__urng.min()) + 1.0L;
3726 const size_t __log2r = std::log(__r) / std::log(2.0L);
3727 const size_t __m = std::max<size_t>(1UL,
3728 (__b + __log2r - 1UL) / __log2r);
3729 _RealType __ret;
3730 _RealType __sum = _RealType(0);
3731 _RealType __tmp = _RealType(1);
3732 for (size_t __k = __m; __k != 0; --__k)
3733 {
3734 __sum += _RealType(__urng() - __urng.min()) * __tmp;
3735 __tmp *= __r;
3736 }
3737 __ret = __sum / __tmp;
3738 if (__builtin_expect(__ret >= _RealType(1), 0))
3739 {
3740# if _GLIBCXX_USE_C99_MATH_FUNCS
3741 __ret = std::nextafter(_RealType(1), _RealType(0));
3742# else
3743 __ret = _RealType(1)
3744 - std::numeric_limits<_RealType>::epsilon() / _RealType(2);
3745# endif
3746 }
3747 return __ret;
3748 }
3749
3750#endif // _GLIBCXX_USE_OLD_GENERATE_CANONICAL
3751
3752_GLIBCXX_END_NAMESPACE_VERSION
3753} // namespace
3754
3755#endif
complex< _Tp > log(const complex< _Tp > &)
Return complex natural logarithm of z.
Definition complex:1162
complex< _Tp > tan(const complex< _Tp > &)
Return complex tangent of z.
Definition complex:1298
_Tp abs(const complex< _Tp > &)
Return magnitude of z.
Definition complex:968
complex< _Tp > exp(const complex< _Tp > &)
Return complex base e exponential of z.
Definition complex:1135
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
Definition complex:1357
complex< _Tp > sqrt(const complex< _Tp > &)
Return complex square root of z.
Definition complex:1271
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
_RealType generate_canonical(_UniformRandomNumberGenerator &__g)
A function template for converting the output of a (integral) uniform random number generator to a fl...
constexpr back_insert_iterator< _Container > back_inserter(_Container &__x)
constexpr _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Accumulate values in a range.
constexpr _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
Return list of partial sums.
ISO C++ entities toplevel namespace is std.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
Definition postypes.h:73
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
constexpr _Tp __lg(_Tp __n)
This is a helper function for the sort routines and for random.tcc.
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1644
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1740
Implementation details not part of the namespace std interface.
constexpr _Iterator __base(_Iterator __it)
initializer_list
A standard container for storing a fixed size sequence of elements.
Definition array:103
char_type widen(char __c) const
Widens characters.
Definition basic_ios.h:465
char_type fill() const
Retrieves the empty character.
Definition basic_ios.h:388
Template class basic_istream.
Definition istream:67
Template class basic_ostream.
Definition ostream.h:67
static constexpr bool is_integer
Definition limits:233
static constexpr int max_digits10
Definition limits:226
static constexpr int digits
Definition limits:218
static constexpr bool is_signed
Definition limits:230
static constexpr int radix
Definition limits:242
static constexpr _Tp max() noexcept
Definition limits:328
static constexpr _Tp epsilon() noexcept
Definition limits:340
is_floating_point
Definition type_traits:601
common_type
Definition type_traits:2540
streamsize precision() const
Flags access.
Definition ios_base.h:765
fmtflags flags() const
Access to format flags.
Definition ios_base.h:694
A model of a linear congruential random number generator.
Definition random.h:696
static constexpr result_type multiplier
Definition random.h:711
static constexpr result_type modulus
Definition random.h:715
void seed(result_type __s=default_seed)
Reseeds the linear_congruential_engine random number generator engine sequence to the seed __s.
static constexpr result_type increment
Definition random.h:713
The Marsaglia-Zaman generator.
Definition random.h:1143
void seed(result_type __sd=0u)
Seeds the initial state of the random number generator.
result_type operator()()
Gets the next random number in the sequence.
result_type operator()()
Gets the next value in the generated random number sequence.
result_type operator()()
Gets the next value in the generated random number sequence.
Produces random numbers by reordering random numbers from some base engine.
Definition random.h:1793
const _RandomNumberEngine & base() const noexcept
Definition random.h:1899
_RandomNumberEngine::result_type result_type
Definition random.h:1799
Uniform continuous distribution for random numbers.
Definition random.h:2485
param_type param() const
Returns the parameter set of the distribution.
Definition random.h:2574
A normal continuous distribution for random numbers.
Definition random.h:2722
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:2841
A gamma continuous distribution for random numbers.
Definition random.h:3174
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:3303
A cauchy_distribution random number distribution.
Definition random.h:3646
param_type param() const
Returns the parameter set of the distribution.
Definition random.h:3723
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:3753
A fisher_f_distribution random number distribution.
Definition random.h:3861
A discrete binomial random number distribution.
Definition random.h:4557
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:4685
A discrete geometric random number distribution.
Definition random.h:4803
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:4914
param_type param() const
Returns the parameter set of the distribution.
Definition random.h:4884
A negative_binomial_distribution random number distribution.
Definition random.h:5020
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
A discrete Poisson random number distribution.
Definition random.h:5257
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:5370
friend bool operator==(const poisson_distribution &__d1, const poisson_distribution &__d2)
Return true if two Poisson distributions have the same parameters and the sequences that would be gen...
Definition random.h:5406
friend std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const std::poisson_distribution< _IntType1 > &__x)
Inserts a poisson_distribution random number distribution __x into the output stream __os.
friend std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, std::poisson_distribution< _IntType1 > &__x)
Extracts a poisson_distribution random number distribution __x from the input stream __is.
An exponential continuous distribution for random numbers.
Definition random.h:5489
param_type param() const
Returns the parameter set of the distribution.
Definition random.h:5569
A weibull_distribution random number distribution.
Definition random.h:5711
param_type param() const
Returns the parameter set of the distribution.
Definition random.h:5791
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:5821
A extreme_value_distribution random number distribution.
Definition random.h:5928
result_type operator()(_UniformRandomNumberGenerator &__urng)
Generating functions.
Definition random.h:6038
param_type param() const
Returns the parameter set of the distribution.
Definition random.h:6008
A standard container which offers fixed time access to individual elements in any order.
Definition stl_vector.h:461
constexpr iterator end() noexcept
constexpr iterator begin() noexcept
Definition stl_vector.h:988
constexpr size_type size() const noexcept
Uniform discrete distribution for random numbers. A discrete random distribution on the range with e...
param_type param() const
Returns the parameter set of the distribution.
Requirements for a uniform random bit generator.