]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/tr1/random.tcc
update copyright date
[thirdparty/gcc.git] / libstdc++-v3 / include / tr1 / random.tcc
CommitLineData
8e79468d
BK
1// random number generation (out of line) -*- C++ -*-
2
3// Copyright (C) 2007 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 2, 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// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING. If not, write to the Free
18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction. Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License. This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30/** @file tr1/random.tcc
31 * This is an internal header file, included by other library headers.
32 * You should not attempt to use it directly.
33 */
34
35namespace std
36{
37namespace tr1
38{
39
40 /*
41 * (Further) implementation-space details.
42 */
43 namespace __detail
44 {
45 // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid
46 // integer overflow.
47 //
48 // Because a and c are compile-time integral constants the compiler kindly
49 // elides any unreachable paths.
50 //
51 // Preconditions: a > 0, m > 0.
52 //
53 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
54 struct _Mod
55 {
56 static _Tp
57 __calc(_Tp __x)
58 {
59 if (__a == 1)
60 __x %= __m;
61 else
62 {
63 static const _Tp __q = __m / __a;
64 static const _Tp __r = __m % __a;
65
66 _Tp __t1 = __a * (__x % __q);
67 _Tp __t2 = __r * (__x / __q);
68 if (__t1 >= __t2)
69 __x = __t1 - __t2;
70 else
71 __x = __m - __t2 + __t1;
72 }
73
74 if (__c != 0)
75 {
76 const _Tp __d = __m - __x;
77 if (__d > __c)
78 __x += __c;
79 else
80 __x = __c - __d;
81 }
82 return __x;
83 }
84 };
85
86 // Special case for m == 0 -- use unsigned integer overflow as modulo
87 // operator.
88 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
89 struct _Mod<_Tp, __a, __c, __m, true>
90 {
91 static _Tp
92 __calc(_Tp __x)
93 { return __a * __x + __c; }
94 };
95 } // namespace __detail
96
97 /**
98 * Seeds the LCR with integral value @p __x0, adjusted so that the
99 * ring identity is never a member of the convergence set.
100 */
101 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
102 void
103 linear_congruential<_UIntType, __a, __c, __m>::
104 seed(unsigned long __x0)
105 {
106 if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
107 && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
108 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
109 else
110 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
111 }
112
113 /**
114 * Seeds the LCR engine with a value generated by @p __g.
115 */
116 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
117 template<class _Gen>
118 void
119 linear_congruential<_UIntType, __a, __c, __m>::
120 seed(_Gen& __g, false_type)
121 {
122 _UIntType __x0 = __g();
123 if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
124 && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
125 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
126 else
127 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
128 }
129
130 /**
131 * Gets the next generated value in sequence.
132 */
133 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
134 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
135 linear_congruential<_UIntType, __a, __c, __m>::
136 operator()()
137 {
138 _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x);
139 return _M_x;
140 }
141
142 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
143 typename _CharT, typename _Traits>
144 std::basic_ostream<_CharT, _Traits>&
145 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
146 const linear_congruential<_UIntType, __a, __c, __m>& __lcr)
147 {
148 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
149 typedef typename __ostream_type::ios_base __ios_base;
150
151 const typename __ios_base::fmtflags __flags = __os.flags();
152 const _CharT __fill = __os.fill();
153 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
154 __os.fill(__os.widen(' '));
155
156 __os << __lcr._M_x;
157
158 __os.flags(__flags);
159 __os.fill(__fill);
160 return __os;
161 }
162
163 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
164 typename _CharT, typename _Traits>
165 std::basic_istream<_CharT, _Traits>&
166 operator>>(std::basic_istream<_CharT, _Traits>& __is,
167 linear_congruential<_UIntType, __a, __c, __m>& __lcr)
168 {
169 typedef std::basic_istream<_CharT, _Traits> __istream_type;
170 typedef typename __istream_type::ios_base __ios_base;
171
172 const typename __ios_base::fmtflags __flags = __is.flags();
173 __is.flags(__ios_base::dec);
174
175 __is >> __lcr._M_x;
176
177 __is.flags(__flags);
178 return __is;
179 }
180
181
182 template<class _UIntType, int __w, int __n, int __m, int __r,
183 _UIntType __a, int __u, int __s,
184 _UIntType __b, int __t, _UIntType __c, int __l>
185 void
186 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
187 __b, __t, __c, __l>::
188 seed(unsigned long __value)
189 {
190 _M_x[0] = __detail::__mod<_UIntType, 1, 0,
191 __detail::_Shift<_UIntType, __w>::__value>(__value);
192
193 for (int __i = 1; __i < state_size; ++__i)
194 {
195 _UIntType __x = _M_x[__i - 1];
196 __x ^= __x >> (__w - 2);
197 __x *= 1812433253ul;
198 __x += __i;
199 _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
200 __detail::_Shift<_UIntType, __w>::__value>(__x);
201 }
202 _M_p = state_size;
203 }
204
205 template<class _UIntType, int __w, int __n, int __m, int __r,
206 _UIntType __a, int __u, int __s,
207 _UIntType __b, int __t, _UIntType __c, int __l>
208 template<class _Gen>
209 void
210 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
211 __b, __t, __c, __l>::
212 seed(_Gen& __gen, false_type)
213 {
214 for (int __i = 0; __i < state_size; ++__i)
215 _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
216 __detail::_Shift<_UIntType, __w>::__value>(__gen());
217 _M_p = state_size;
218 }
219
220 template<class _UIntType, int __w, int __n, int __m, int __r,
221 _UIntType __a, int __u, int __s,
222 _UIntType __b, int __t, _UIntType __c, int __l>
223 typename
224 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
225 __b, __t, __c, __l>::result_type
226 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
227 __b, __t, __c, __l>::
228 operator()()
229 {
230 // Reload the vector - cost is O(n) amortized over n calls.
231 if (_M_p >= state_size)
232 {
233 const _UIntType __upper_mask = (~_UIntType()) << __r;
234 const _UIntType __lower_mask = ~__upper_mask;
235
236 for (int __k = 0; __k < (__n - __m); ++__k)
237 {
238 _UIntType __y = ((_M_x[__k] & __upper_mask)
239 | (_M_x[__k + 1] & __lower_mask));
240 _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
241 ^ ((__y & 0x01) ? __a : 0));
242 }
243
244 for (int __k = (__n - __m); __k < (__n - 1); ++__k)
245 {
246 _UIntType __y = ((_M_x[__k] & __upper_mask)
247 | (_M_x[__k + 1] & __lower_mask));
248 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
249 ^ ((__y & 0x01) ? __a : 0));
250 }
251
252 _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
253 | (_M_x[0] & __lower_mask));
254 _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
255 ^ ((__y & 0x01) ? __a : 0));
256 _M_p = 0;
257 }
258
259 // Calculate o(x(i)).
260 result_type __z = _M_x[_M_p++];
261 __z ^= (__z >> __u);
262 __z ^= (__z << __s) & __b;
263 __z ^= (__z << __t) & __c;
264 __z ^= (__z >> __l);
265
266 return __z;
267 }
268
269 template<class _UIntType, int __w, int __n, int __m, int __r,
270 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
271 _UIntType __c, int __l,
272 typename _CharT, typename _Traits>
273 std::basic_ostream<_CharT, _Traits>&
274 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
275 const mersenne_twister<_UIntType, __w, __n, __m,
276 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
277 {
278 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
279 typedef typename __ostream_type::ios_base __ios_base;
280
281 const typename __ios_base::fmtflags __flags = __os.flags();
282 const _CharT __fill = __os.fill();
283 const _CharT __space = __os.widen(' ');
284 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
285 __os.fill(__space);
286
287 for (int __i = 0; __i < __n - 1; ++__i)
288 __os << __x._M_x[__i] << __space;
289 __os << __x._M_x[__n - 1];
290
291 __os.flags(__flags);
292 __os.fill(__fill);
293 return __os;
294 }
295
296 template<class _UIntType, int __w, int __n, int __m, int __r,
297 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
298 _UIntType __c, int __l,
299 typename _CharT, typename _Traits>
300 std::basic_istream<_CharT, _Traits>&
301 operator>>(std::basic_istream<_CharT, _Traits>& __is,
302 mersenne_twister<_UIntType, __w, __n, __m,
303 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
304 {
305 typedef std::basic_istream<_CharT, _Traits> __istream_type;
306 typedef typename __istream_type::ios_base __ios_base;
307
308 const typename __ios_base::fmtflags __flags = __is.flags();
309 __is.flags(__ios_base::dec | __ios_base::skipws);
310
311 for (int __i = 0; __i < __n; ++__i)
312 __is >> __x._M_x[__i];
313
314 __is.flags(__flags);
315 return __is;
316 }
317
318
319 template<typename _IntType, _IntType __m, int __s, int __r>
320 void
321 subtract_with_carry<_IntType, __m, __s, __r>::
322 seed(unsigned long __value)
323 {
324 if (__value == 0)
325 __value = 19780503;
326
327 std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563>
328 __lcg(__value);
329
330 for (int __i = 0; __i < long_lag; ++__i)
331 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg());
332
333 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
334 _M_p = 0;
335 }
336
337 template<typename _IntType, _IntType __m, int __s, int __r>
338 template<class _Gen>
339 void
340 subtract_with_carry<_IntType, __m, __s, __r>::
341 seed(_Gen& __gen, false_type)
342 {
343 const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32;
344
345 for (int __i = 0; __i < long_lag; ++__i)
346 {
347 _UIntType __tmp = 0;
348 _UIntType __factor = 1;
349 for (int __j = 0; __j < __n; ++__j)
350 {
351 __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0>
352 (__gen()) * __factor;
353 __factor *= __detail::_Shift<_UIntType, 32>::__value;
354 }
355 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp);
356 }
357 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
358 _M_p = 0;
359 }
360
361 template<typename _IntType, _IntType __m, int __s, int __r>
362 typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
363 subtract_with_carry<_IntType, __m, __s, __r>::
364 operator()()
365 {
366 // Derive short lag index from current index.
367 int __ps = _M_p - short_lag;
368 if (__ps < 0)
369 __ps += long_lag;
370
371 // Calculate new x(i) without overflow or division.
372 // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry
373 // cannot overflow.
374 _UIntType __xi;
375 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
376 {
377 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
378 _M_carry = 0;
379 }
380 else
381 {
382 __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
383 _M_carry = 1;
384 }
385 _M_x[_M_p] = __xi;
386
387 // Adjust current index to loop around in ring buffer.
388 if (++_M_p >= long_lag)
389 _M_p = 0;
390
391 return __xi;
392 }
393
394 template<typename _IntType, _IntType __m, int __s, int __r,
395 typename _CharT, typename _Traits>
396 std::basic_ostream<_CharT, _Traits>&
397 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
398 const subtract_with_carry<_IntType, __m, __s, __r>& __x)
399 {
400 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
401 typedef typename __ostream_type::ios_base __ios_base;
402
403 const typename __ios_base::fmtflags __flags = __os.flags();
404 const _CharT __fill = __os.fill();
405 const _CharT __space = __os.widen(' ');
406 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
407 __os.fill(__space);
408
409 for (int __i = 0; __i < __r; ++__i)
410 __os << __x._M_x[__i] << __space;
411 __os << __x._M_carry;
412
413 __os.flags(__flags);
414 __os.fill(__fill);
415 return __os;
416 }
417
418 template<typename _IntType, _IntType __m, int __s, int __r,
419 typename _CharT, typename _Traits>
420 std::basic_istream<_CharT, _Traits>&
421 operator>>(std::basic_istream<_CharT, _Traits>& __is,
422 subtract_with_carry<_IntType, __m, __s, __r>& __x)
423 {
424 typedef std::basic_ostream<_CharT, _Traits> __istream_type;
425 typedef typename __istream_type::ios_base __ios_base;
426
427 const typename __ios_base::fmtflags __flags = __is.flags();
428 __is.flags(__ios_base::dec | __ios_base::skipws);
429
430 for (int __i = 0; __i < __r; ++__i)
431 __is >> __x._M_x[__i];
432 __is >> __x._M_carry;
433
434 __is.flags(__flags);
435 return __is;
436 }
437
438
439 template<typename _RealType, int __w, int __s, int __r>
440 void
441 subtract_with_carry_01<_RealType, __w, __s, __r>::
442 _M_initialize_npows()
443 {
444 for (int __j = 0; __j < __n; ++__j)
445#if _GLIBCXX_USE_C99_MATH_TR1
446 _M_npows[__j] = std::_GLIBCXX_TR1 ldexp(_RealType(1), -__w + __j * 32);
447#else
448 _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32);
449#endif
450 }
451
452 template<typename _RealType, int __w, int __s, int __r>
453 void
454 subtract_with_carry_01<_RealType, __w, __s, __r>::
455 seed(unsigned long __value)
456 {
457 if (__value == 0)
458 __value = 19780503;
459
460 // _GLIBCXX_RESOLVE_LIB_DEFECTS
461 // 512. Seeding subtract_with_carry_01 from a single unsigned long.
462 std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563>
463 __lcg(__value);
464
465 this->seed(__lcg);
466 }
467
468 template<typename _RealType, int __w, int __s, int __r>
469 template<class _Gen>
470 void
471 subtract_with_carry_01<_RealType, __w, __s, __r>::
472 seed(_Gen& __gen, false_type)
473 {
474 for (int __i = 0; __i < long_lag; ++__i)
475 {
476 for (int __j = 0; __j < __n - 1; ++__j)
477 _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen());
478 _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
479 __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen());
480 }
481
482 _M_carry = 1;
483 for (int __j = 0; __j < __n; ++__j)
484 if (_M_x[long_lag - 1][__j] != 0)
485 {
486 _M_carry = 0;
487 break;
488 }
489
490 _M_p = 0;
491 }
492
493 template<typename _RealType, int __w, int __s, int __r>
494 typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type
495 subtract_with_carry_01<_RealType, __w, __s, __r>::
496 operator()()
497 {
498 // Derive short lag index from current index.
499 int __ps = _M_p - short_lag;
500 if (__ps < 0)
501 __ps += long_lag;
502
503 _UInt32Type __new_carry;
504 for (int __j = 0; __j < __n - 1; ++__j)
505 {
506 if (_M_x[__ps][__j] > _M_x[_M_p][__j]
507 || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0))
508 __new_carry = 0;
509 else
510 __new_carry = 1;
511
512 _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry;
513 _M_carry = __new_carry;
514 }
515
516 if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1]
517 || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0))
518 __new_carry = 0;
519 else
520 __new_carry = 1;
521
522 _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
523 __detail::_Shift<_UInt32Type, __w % 32>::__value>
524 (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry);
525 _M_carry = __new_carry;
526
527 result_type __ret = 0.0;
528 for (int __j = 0; __j < __n; ++__j)
529 __ret += _M_x[_M_p][__j] * _M_npows[__j];
530
531 // Adjust current index to loop around in ring buffer.
532 if (++_M_p >= long_lag)
533 _M_p = 0;
534
535 return __ret;
536 }
537
538 template<typename _RealType, int __w, int __s, int __r,
539 typename _CharT, typename _Traits>
540 std::basic_ostream<_CharT, _Traits>&
541 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
542 const subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
543 {
544 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
545 typedef typename __ostream_type::ios_base __ios_base;
546
547 const typename __ios_base::fmtflags __flags = __os.flags();
548 const _CharT __fill = __os.fill();
549 const _CharT __space = __os.widen(' ');
550 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
551 __os.fill(__space);
552
553 for (int __i = 0; __i < __r; ++__i)
554 for (int __j = 0; __j < __x.__n; ++__j)
555 __os << __x._M_x[__i][__j] << __space;
556 __os << __x._M_carry;
557
558 __os.flags(__flags);
559 __os.fill(__fill);
560 return __os;
561 }
562
563 template<typename _RealType, int __w, int __s, int __r,
564 typename _CharT, typename _Traits>
565 std::basic_istream<_CharT, _Traits>&
566 operator>>(std::basic_istream<_CharT, _Traits>& __is,
567 subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
568 {
569 typedef std::basic_istream<_CharT, _Traits> __istream_type;
570 typedef typename __istream_type::ios_base __ios_base;
571
572 const typename __ios_base::fmtflags __flags = __is.flags();
573 __is.flags(__ios_base::dec | __ios_base::skipws);
574
575 for (int __i = 0; __i < __r; ++__i)
576 for (int __j = 0; __j < __x.__n; ++__j)
577 __is >> __x._M_x[__i][__j];
578 __is >> __x._M_carry;
579
580 __is.flags(__flags);
581 return __is;
582 }
583
584
585 template<class _UniformRandomNumberGenerator, int __p, int __r>
586 typename discard_block<_UniformRandomNumberGenerator,
587 __p, __r>::result_type
588 discard_block<_UniformRandomNumberGenerator, __p, __r>::
589 operator()()
590 {
591 if (_M_n >= used_block)
592 {
593 while (_M_n < block_size)
594 {
595 _M_b();
596 ++_M_n;
597 }
598 _M_n = 0;
599 }
600 ++_M_n;
601 return _M_b();
602 }
603
604 template<class _UniformRandomNumberGenerator, int __p, int __r,
605 typename _CharT, typename _Traits>
606 std::basic_ostream<_CharT, _Traits>&
607 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
608 const discard_block<_UniformRandomNumberGenerator,
609 __p, __r>& __x)
610 {
611 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
612 typedef typename __ostream_type::ios_base __ios_base;
613
614 const typename __ios_base::fmtflags __flags = __os.flags();
615 const _CharT __fill = __os.fill();
616 const _CharT __space = __os.widen(' ');
617 __os.flags(__ios_base::dec | __ios_base::fixed
618 | __ios_base::left);
619 __os.fill(__space);
620
621 __os << __x._M_b << __space << __x._M_n;
622
623 __os.flags(__flags);
624 __os.fill(__fill);
625 return __os;
626 }
627
628 template<class _UniformRandomNumberGenerator, int __p, int __r,
629 typename _CharT, typename _Traits>
630 std::basic_istream<_CharT, _Traits>&
631 operator>>(std::basic_istream<_CharT, _Traits>& __is,
632 discard_block<_UniformRandomNumberGenerator, __p, __r>& __x)
633 {
634 typedef std::basic_istream<_CharT, _Traits> __istream_type;
635 typedef typename __istream_type::ios_base __ios_base;
636
637 const typename __ios_base::fmtflags __flags = __is.flags();
638 __is.flags(__ios_base::dec | __ios_base::skipws);
639
640 __is >> __x._M_b >> __x._M_n;
641
642 __is.flags(__flags);
643 return __is;
644 }
645
646
647 template<class _UniformRandomNumberGenerator1, int __s1,
648 class _UniformRandomNumberGenerator2, int __s2>
649 void
650 xor_combine<_UniformRandomNumberGenerator1, __s1,
651 _UniformRandomNumberGenerator2, __s2>::
652 _M_initialize_max()
653 {
654 const int __w = std::numeric_limits<result_type>::digits;
655
656 const result_type __m1 =
657 std::min(result_type(_M_b1.max() - _M_b1.min()),
658 __detail::_Shift<result_type, __w - __s1>::__value - 1);
659
660 const result_type __m2 =
661 std::min(result_type(_M_b2.max() - _M_b2.min()),
662 __detail::_Shift<result_type, __w - __s2>::__value - 1);
663
664 // NB: In TR1 s1 is not required to be >= s2.
665 if (__s1 < __s2)
666 _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1;
667 else
668 _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2;
669 }
670
671 template<class _UniformRandomNumberGenerator1, int __s1,
672 class _UniformRandomNumberGenerator2, int __s2>
673 typename xor_combine<_UniformRandomNumberGenerator1, __s1,
674 _UniformRandomNumberGenerator2, __s2>::result_type
675 xor_combine<_UniformRandomNumberGenerator1, __s1,
676 _UniformRandomNumberGenerator2, __s2>::
677 _M_initialize_max_aux(result_type __a, result_type __b, int __d)
678 {
679 const result_type __two2d = result_type(1) << __d;
680 const result_type __c = __a * __two2d;
681
682 if (__a == 0 || __b < __two2d)
683 return __c + __b;
684
685 const result_type __t = std::max(__c, __b);
686 const result_type __u = std::min(__c, __b);
687
688 result_type __ub = __u;
689 result_type __p;
690 for (__p = 0; __ub != 1; __ub >>= 1)
691 ++__p;
692
693 const result_type __two2p = result_type(1) << __p;
694 const result_type __k = __t / __two2p;
695
696 if (__k & 1)
697 return (__k + 1) * __two2p - 1;
698
699 if (__c >= __b)
700 return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p)
701 / __two2d,
702 __u % __two2p, __d);
703 else
704 return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p)
705 / __two2d,
706 __t % __two2p, __d);
707 }
708
709 template<class _UniformRandomNumberGenerator1, int __s1,
710 class _UniformRandomNumberGenerator2, int __s2,
711 typename _CharT, typename _Traits>
712 std::basic_ostream<_CharT, _Traits>&
713 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
714 const xor_combine<_UniformRandomNumberGenerator1, __s1,
715 _UniformRandomNumberGenerator2, __s2>& __x)
716 {
717 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
718 typedef typename __ostream_type::ios_base __ios_base;
719
720 const typename __ios_base::fmtflags __flags = __os.flags();
721 const _CharT __fill = __os.fill();
722 const _CharT __space = __os.widen(' ');
723 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
724 __os.fill(__space);
725
726 __os << __x.base1() << __space << __x.base2();
727
728 __os.flags(__flags);
729 __os.fill(__fill);
730 return __os;
731 }
732
733 template<class _UniformRandomNumberGenerator1, int __s1,
734 class _UniformRandomNumberGenerator2, int __s2,
735 typename _CharT, typename _Traits>
736 std::basic_istream<_CharT, _Traits>&
737 operator>>(std::basic_istream<_CharT, _Traits>& __is,
738 xor_combine<_UniformRandomNumberGenerator1, __s1,
739 _UniformRandomNumberGenerator2, __s2>& __x)
740 {
741 typedef std::basic_istream<_CharT, _Traits> __istream_type;
742 typedef typename __istream_type::ios_base __ios_base;
743
744 const typename __ios_base::fmtflags __flags = __is.flags();
745 __is.flags(__ios_base::skipws);
746
747 __is >> __x._M_b1 >> __x._M_b2;
748
749 __is.flags(__flags);
750 return __is;
751 }
752
753
754 template<typename _IntType>
755 template<typename _UniformRandomNumberGenerator>
756 typename uniform_int<_IntType>::result_type
757 uniform_int<_IntType>::
758 _M_call(_UniformRandomNumberGenerator& __urng,
759 result_type __min, result_type __max, true_type)
760 {
761 // XXX Must be fixed to work well for *arbitrary* __urng.max(),
762 // __urng.min(), __max, __min. Currently works fine only in the
763 // most common case __urng.max() - __urng.min() >= __max - __min,
764 // with __urng.max() > __urng.min() >= 0.
765 typedef typename __gnu_cxx::__add_unsigned<typename
766 _UniformRandomNumberGenerator::result_type>::__type __urntype;
767 typedef typename __gnu_cxx::__add_unsigned<result_type>::__type
768 __utype;
769 typedef typename __gnu_cxx::__conditional_type<(sizeof(__urntype)
770 > sizeof(__utype)),
771 __urntype, __utype>::__type __uctype;
772
773 result_type __ret;
774
775 const __urntype __urnmin = __urng.min();
776 const __urntype __urnmax = __urng.max();
777 const __urntype __urnrange = __urnmax - __urnmin;
778 const __uctype __urange = __max - __min;
779 const __uctype __udenom = (__urnrange <= __urange
780 ? 1 : __urnrange / (__urange + 1));
781 do
782 __ret = (__urntype(__urng()) - __urnmin) / __udenom;
783 while (__ret > __max - __min);
784
785 return __ret + __min;
786 }
787
788 template<typename _IntType, typename _CharT, typename _Traits>
789 std::basic_ostream<_CharT, _Traits>&
790 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
791 const uniform_int<_IntType>& __x)
792 {
793 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
794 typedef typename __ostream_type::ios_base __ios_base;
795
796 const typename __ios_base::fmtflags __flags = __os.flags();
797 const _CharT __fill = __os.fill();
798 const _CharT __space = __os.widen(' ');
799 __os.flags(__ios_base::scientific | __ios_base::left);
800 __os.fill(__space);
801
802 __os << __x.min() << __space << __x.max();
803
804 __os.flags(__flags);
805 __os.fill(__fill);
806 return __os;
807 }
808
809 template<typename _IntType, typename _CharT, typename _Traits>
810 std::basic_istream<_CharT, _Traits>&
811 operator>>(std::basic_istream<_CharT, _Traits>& __is,
812 uniform_int<_IntType>& __x)
813 {
814 typedef std::basic_istream<_CharT, _Traits> __istream_type;
815 typedef typename __istream_type::ios_base __ios_base;
816
817 const typename __ios_base::fmtflags __flags = __is.flags();
818 __is.flags(__ios_base::dec | __ios_base::skipws);
819
820 __is >> __x._M_min >> __x._M_max;
821
822 __is.flags(__flags);
823 return __is;
824 }
825
826
827 template<typename _CharT, typename _Traits>
828 std::basic_ostream<_CharT, _Traits>&
829 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
830 const bernoulli_distribution& __x)
831 {
832 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
833 typedef typename __ostream_type::ios_base __ios_base;
834
835 const typename __ios_base::fmtflags __flags = __os.flags();
836 const _CharT __fill = __os.fill();
837 const std::streamsize __precision = __os.precision();
838 __os.flags(__ios_base::scientific | __ios_base::left);
839 __os.fill(__os.widen(' '));
840 __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10);
841
842 __os << __x.p();
843
844 __os.flags(__flags);
845 __os.fill(__fill);
846 __os.precision(__precision);
847 return __os;
848 }
849
850
851 template<typename _IntType, typename _RealType>
852 template<class _UniformRandomNumberGenerator>
853 typename geometric_distribution<_IntType, _RealType>::result_type
854 geometric_distribution<_IntType, _RealType>::
855 operator()(_UniformRandomNumberGenerator& __urng)
856 {
857 // About the epsilon thing see this thread:
858 // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
859 const _RealType __naf =
860 (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
861 // The largest _RealType convertible to _IntType.
862 const _RealType __thr =
863 std::numeric_limits<_IntType>::max() + __naf;
864
865 _RealType __cand;
866 do
867 __cand = std::ceil(std::log(__urng()) / _M_log_p);
868 while (__cand >= __thr);
869
870 return result_type(__cand + __naf);
871 }
872
873 template<typename _IntType, typename _RealType,
874 typename _CharT, typename _Traits>
875 std::basic_ostream<_CharT, _Traits>&
876 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
877 const geometric_distribution<_IntType, _RealType>& __x)
878 {
879 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
880 typedef typename __ostream_type::ios_base __ios_base;
881
882 const typename __ios_base::fmtflags __flags = __os.flags();
883 const _CharT __fill = __os.fill();
884 const std::streamsize __precision = __os.precision();
885 __os.flags(__ios_base::scientific | __ios_base::left);
886 __os.fill(__os.widen(' '));
887 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
888
889 __os << __x.p();
890
891 __os.flags(__flags);
892 __os.fill(__fill);
893 __os.precision(__precision);
894 return __os;
895 }
896
897
898 template<typename _IntType, typename _RealType>
899 void
900 poisson_distribution<_IntType, _RealType>::
901 _M_initialize()
902 {
903#if _GLIBCXX_USE_C99_MATH_TR1
904 if (_M_mean >= 12)
905 {
906 const _RealType __m = std::floor(_M_mean);
907 _M_lm_thr = std::log(_M_mean);
908 _M_lfm = std::_GLIBCXX_TR1 lgamma(__m + 1);
909 _M_sm = std::sqrt(__m);
910
911 const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
912 const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m
913 / __pi_4));
914 _M_d = std::_GLIBCXX_TR1 round(std::max(_RealType(6),
915 std::min(__m, __dx)));
916 const _RealType __cx = 2 * __m + _M_d;
917 _M_scx = std::sqrt(__cx / 2);
918 _M_1cx = 1 / __cx;
919
920 _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
921 _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d;
922 }
923 else
924#endif
925 _M_lm_thr = std::exp(-_M_mean);
926 }
927
928 /**
929 * A rejection algorithm when mean >= 12 and a simple method based
930 * upon the multiplication of uniform random variates otherwise.
931 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
932 * is defined.
933 *
934 * Reference:
935 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
936 * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
937 */
938 template<typename _IntType, typename _RealType>
939 template<class _UniformRandomNumberGenerator>
940 typename poisson_distribution<_IntType, _RealType>::result_type
941 poisson_distribution<_IntType, _RealType>::
942 operator()(_UniformRandomNumberGenerator& __urng)
943 {
944#if _GLIBCXX_USE_C99_MATH_TR1
945 if (_M_mean >= 12)
946 {
947 _RealType __x;
948
949 // See comments above...
950 const _RealType __naf =
951 (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
952 const _RealType __thr =
953 std::numeric_limits<_IntType>::max() + __naf;
954
955 const _RealType __m = std::floor(_M_mean);
956 // sqrt(pi / 2)
957 const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
958 const _RealType __c1 = _M_sm * __spi_2;
959 const _RealType __c2 = _M_c2b + __c1;
960 const _RealType __c3 = __c2 + 1;
961 const _RealType __c4 = __c3 + 1;
962 // e^(1 / 78)
963 const _RealType __e178 = 1.0129030479320018583185514777512983L;
964 const _RealType __c5 = __c4 + __e178;
965 const _RealType __c = _M_cb + __c5;
966 const _RealType __2cx = 2 * (2 * __m + _M_d);
967
968 bool __reject = true;
969 do
970 {
971 const _RealType __u = __c * __urng();
972 const _RealType __e = -std::log(__urng());
973
974 _RealType __w = 0.0;
975
976 if (__u <= __c1)
977 {
978 const _RealType __n = _M_nd(__urng);
979 const _RealType __y = -std::abs(__n) * _M_sm - 1;
980 __x = std::floor(__y);
981 __w = -__n * __n / 2;
982 if (__x < -__m)
983 continue;
984 }
985 else if (__u <= __c2)
986 {
987 const _RealType __n = _M_nd(__urng);
988 const _RealType __y = 1 + std::abs(__n) * _M_scx;
989 __x = std::ceil(__y);
990 __w = __y * (2 - __y) * _M_1cx;
991 if (__x > _M_d)
992 continue;
993 }
994 else if (__u <= __c3)
995 // NB: This case not in the book, nor in the Errata,
996 // but should be ok...
997 __x = -1;
998 else if (__u <= __c4)
999 __x = 0;
1000 else if (__u <= __c5)
1001 __x = 1;
1002 else
1003 {
1004 const _RealType __v = -std::log(__urng());
1005 const _RealType __y = _M_d + __v * __2cx / _M_d;
1006 __x = std::ceil(__y);
1007 __w = -_M_d * _M_1cx * (1 + __y / 2);
1008 }
1009
1010 __reject = (__w - __e - __x * _M_lm_thr
1011 > _M_lfm - std::_GLIBCXX_TR1 lgamma(__x + __m + 1));
1012
1013 __reject |= __x + __m >= __thr;
1014
1015 } while (__reject);
1016
1017 return result_type(__x + __m + __naf);
1018 }
1019 else
1020#endif
1021 {
1022 _IntType __x = 0;
1023 _RealType __prod = 1.0;
1024
1025 do
1026 {
1027 __prod *= __urng();
1028 __x += 1;
1029 }
1030 while (__prod > _M_lm_thr);
1031
1032 return __x - 1;
1033 }
1034 }
1035
1036 template<typename _IntType, typename _RealType,
1037 typename _CharT, typename _Traits>
1038 std::basic_ostream<_CharT, _Traits>&
1039 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1040 const poisson_distribution<_IntType, _RealType>& __x)
1041 {
1042 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1043 typedef typename __ostream_type::ios_base __ios_base;
1044
1045 const typename __ios_base::fmtflags __flags = __os.flags();
1046 const _CharT __fill = __os.fill();
1047 const std::streamsize __precision = __os.precision();
1048 const _CharT __space = __os.widen(' ');
1049 __os.flags(__ios_base::scientific | __ios_base::left);
1050 __os.fill(__space);
1051 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1052
1053 __os << __x.mean() << __space << __x._M_nd;
1054
1055 __os.flags(__flags);
1056 __os.fill(__fill);
1057 __os.precision(__precision);
1058 return __os;
1059 }
1060
1061 template<typename _IntType, typename _RealType,
1062 typename _CharT, typename _Traits>
1063 std::basic_istream<_CharT, _Traits>&
1064 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1065 poisson_distribution<_IntType, _RealType>& __x)
1066 {
1067 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1068 typedef typename __istream_type::ios_base __ios_base;
1069
1070 const typename __ios_base::fmtflags __flags = __is.flags();
1071 __is.flags(__ios_base::skipws);
1072
1073 __is >> __x._M_mean >> __x._M_nd;
1074 __x._M_initialize();
1075
1076 __is.flags(__flags);
1077 return __is;
1078 }
1079
1080
1081 template<typename _IntType, typename _RealType>
1082 void
1083 binomial_distribution<_IntType, _RealType>::
1084 _M_initialize()
1085 {
1086 const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1087
1088 _M_easy = true;
1089
1090#if _GLIBCXX_USE_C99_MATH_TR1
1091 if (_M_t * __p12 >= 8)
1092 {
1093 _M_easy = false;
1094 const _RealType __np = std::floor(_M_t * __p12);
1095 const _RealType __pa = __np / _M_t;
1096 const _RealType __1p = 1 - __pa;
1097
1098 const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
1099 const _RealType __d1x =
1100 std::sqrt(__np * __1p * std::log(32 * __np
1101 / (81 * __pi_4 * __1p)));
1102 _M_d1 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d1x));
1103 const _RealType __d2x =
1104 std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
1105 / (__pi_4 * __pa)));
1106 _M_d2 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d2x));
1107
1108 // sqrt(pi / 2)
1109 const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
1110 _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
1111 _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
1112 _M_c = 2 * _M_d1 / __np;
1113 _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
1114 const _RealType __a12 = _M_a1 + _M_s2 * __spi_2;
1115 const _RealType __s1s = _M_s1 * _M_s1;
1116 _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
1117 * 2 * __s1s / _M_d1
1118 * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
1119 const _RealType __s2s = _M_s2 * _M_s2;
1120 _M_s = (_M_a123 + 2 * __s2s / _M_d2
1121 * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
1122 _M_lf = (std::_GLIBCXX_TR1 lgamma(__np + 1)
1123 + std::_GLIBCXX_TR1 lgamma(_M_t - __np + 1));
1124 _M_lp1p = std::log(__pa / __1p);
1125
1126 _M_q = -std::log(1 - (__p12 - __pa) / __1p);
1127 }
1128 else
1129#endif
1130 _M_q = -std::log(1 - __p12);
1131 }
1132
1133 template<typename _IntType, typename _RealType>
1134 template<class _UniformRandomNumberGenerator>
1135 typename binomial_distribution<_IntType, _RealType>::result_type
1136 binomial_distribution<_IntType, _RealType>::
1137 _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
1138 {
1139 _IntType __x = 0;
1140 _RealType __sum = 0;
1141
1142 do
1143 {
1144 const _RealType __e = -std::log(__urng());
1145 __sum += __e / (__t - __x);
1146 __x += 1;
1147 }
1148 while (__sum <= _M_q);
1149
1150 return __x - 1;
1151 }
1152
1153 /**
1154 * A rejection algorithm when t * p >= 8 and a simple waiting time
1155 * method - the second in the referenced book - otherwise.
1156 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1157 * is defined.
1158 *
1159 * Reference:
1160 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
1161 * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
1162 */
1163 template<typename _IntType, typename _RealType>
1164 template<class _UniformRandomNumberGenerator>
1165 typename binomial_distribution<_IntType, _RealType>::result_type
1166 binomial_distribution<_IntType, _RealType>::
1167 operator()(_UniformRandomNumberGenerator& __urng)
1168 {
1169 result_type __ret;
1170 const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1171
1172#if _GLIBCXX_USE_C99_MATH_TR1
1173 if (!_M_easy)
1174 {
1175 _RealType __x;
1176
1177 // See comments above...
1178 const _RealType __naf =
1179 (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
1180 const _RealType __thr =
1181 std::numeric_limits<_IntType>::max() + __naf;
1182
1183 const _RealType __np = std::floor(_M_t * __p12);
1184 const _RealType __pa = __np / _M_t;
1185
1186 // sqrt(pi / 2)
1187 const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
1188 const _RealType __a1 = _M_a1;
1189 const _RealType __a12 = __a1 + _M_s2 * __spi_2;
1190 const _RealType __a123 = _M_a123;
1191 const _RealType __s1s = _M_s1 * _M_s1;
1192 const _RealType __s2s = _M_s2 * _M_s2;
1193
1194 bool __reject;
1195 do
1196 {
1197 const _RealType __u = _M_s * __urng();
1198
1199 _RealType __v;
1200
1201 if (__u <= __a1)
1202 {
1203 const _RealType __n = _M_nd(__urng);
1204 const _RealType __y = _M_s1 * std::abs(__n);
1205 __reject = __y >= _M_d1;
1206 if (!__reject)
1207 {
1208 const _RealType __e = -std::log(__urng());
1209 __x = std::floor(__y);
1210 __v = -__e - __n * __n / 2 + _M_c;
1211 }
1212 }
1213 else if (__u <= __a12)
1214 {
1215 const _RealType __n = _M_nd(__urng);
1216 const _RealType __y = _M_s2 * std::abs(__n);
1217 __reject = __y >= _M_d2;
1218 if (!__reject)
1219 {
1220 const _RealType __e = -std::log(__urng());
1221 __x = std::floor(-__y);
1222 __v = -__e - __n * __n / 2;
1223 }
1224 }
1225 else if (__u <= __a123)
1226 {
1227 const _RealType __e1 = -std::log(__urng());
1228 const _RealType __e2 = -std::log(__urng());
1229
1230 const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1;
1231 __x = std::floor(__y);
1232 __v = (-__e2 + _M_d1 * (1 / (_M_t - __np)
1233 -__y / (2 * __s1s)));
1234 __reject = false;
1235 }
1236 else
1237 {
1238 const _RealType __e1 = -std::log(__urng());
1239 const _RealType __e2 = -std::log(__urng());
1240
1241 const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2;
1242 __x = std::floor(-__y);
1243 __v = -__e2 - _M_d2 * __y / (2 * __s2s);
1244 __reject = false;
1245 }
1246
1247 __reject = __reject || __x < -__np || __x > _M_t - __np;
1248 if (!__reject)
1249 {
1250 const _RealType __lfx =
1251 std::_GLIBCXX_TR1 lgamma(__np + __x + 1)
1252 + std::_GLIBCXX_TR1 lgamma(_M_t - (__np + __x) + 1);
1253 __reject = __v > _M_lf - __lfx + __x * _M_lp1p;
1254 }
1255
1256 __reject |= __x + __np >= __thr;
1257 }
1258 while (__reject);
1259
1260 __x += __np + __naf;
1261
1262 const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x));
1263 __ret = _IntType(__x) + __z;
1264 }
1265 else
1266#endif
1267 __ret = _M_waiting(__urng, _M_t);
1268
1269 if (__p12 != _M_p)
1270 __ret = _M_t - __ret;
1271 return __ret;
1272 }
1273
1274 template<typename _IntType, typename _RealType,
1275 typename _CharT, typename _Traits>
1276 std::basic_ostream<_CharT, _Traits>&
1277 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1278 const binomial_distribution<_IntType, _RealType>& __x)
1279 {
1280 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1281 typedef typename __ostream_type::ios_base __ios_base;
1282
1283 const typename __ios_base::fmtflags __flags = __os.flags();
1284 const _CharT __fill = __os.fill();
1285 const std::streamsize __precision = __os.precision();
1286 const _CharT __space = __os.widen(' ');
1287 __os.flags(__ios_base::scientific | __ios_base::left);
1288 __os.fill(__space);
1289 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1290
1291 __os << __x.t() << __space << __x.p()
1292 << __space << __x._M_nd;
1293
1294 __os.flags(__flags);
1295 __os.fill(__fill);
1296 __os.precision(__precision);
1297 return __os;
1298 }
1299
1300 template<typename _IntType, typename _RealType,
1301 typename _CharT, typename _Traits>
1302 std::basic_istream<_CharT, _Traits>&
1303 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1304 binomial_distribution<_IntType, _RealType>& __x)
1305 {
1306 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1307 typedef typename __istream_type::ios_base __ios_base;
1308
1309 const typename __ios_base::fmtflags __flags = __is.flags();
1310 __is.flags(__ios_base::dec | __ios_base::skipws);
1311
1312 __is >> __x._M_t >> __x._M_p >> __x._M_nd;
1313 __x._M_initialize();
1314
1315 __is.flags(__flags);
1316 return __is;
1317 }
1318
1319
1320 template<typename _RealType, typename _CharT, typename _Traits>
1321 std::basic_ostream<_CharT, _Traits>&
1322 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1323 const uniform_real<_RealType>& __x)
1324 {
1325 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1326 typedef typename __ostream_type::ios_base __ios_base;
1327
1328 const typename __ios_base::fmtflags __flags = __os.flags();
1329 const _CharT __fill = __os.fill();
1330 const std::streamsize __precision = __os.precision();
1331 const _CharT __space = __os.widen(' ');
1332 __os.flags(__ios_base::scientific | __ios_base::left);
1333 __os.fill(__space);
1334 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1335
1336 __os << __x.min() << __space << __x.max();
1337
1338 __os.flags(__flags);
1339 __os.fill(__fill);
1340 __os.precision(__precision);
1341 return __os;
1342 }
1343
1344 template<typename _RealType, typename _CharT, typename _Traits>
1345 std::basic_istream<_CharT, _Traits>&
1346 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1347 uniform_real<_RealType>& __x)
1348 {
1349 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1350 typedef typename __istream_type::ios_base __ios_base;
1351
1352 const typename __ios_base::fmtflags __flags = __is.flags();
1353 __is.flags(__ios_base::skipws);
1354
1355 __is >> __x._M_min >> __x._M_max;
1356
1357 __is.flags(__flags);
1358 return __is;
1359 }
1360
1361
1362 template<typename _RealType, typename _CharT, typename _Traits>
1363 std::basic_ostream<_CharT, _Traits>&
1364 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1365 const exponential_distribution<_RealType>& __x)
1366 {
1367 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1368 typedef typename __ostream_type::ios_base __ios_base;
1369
1370 const typename __ios_base::fmtflags __flags = __os.flags();
1371 const _CharT __fill = __os.fill();
1372 const std::streamsize __precision = __os.precision();
1373 __os.flags(__ios_base::scientific | __ios_base::left);
1374 __os.fill(__os.widen(' '));
1375 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1376
1377 __os << __x.lambda();
1378
1379 __os.flags(__flags);
1380 __os.fill(__fill);
1381 __os.precision(__precision);
1382 return __os;
1383 }
1384
1385
1386 /**
1387 * Polar method due to Marsaglia.
1388 *
1389 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
1390 * New York, 1986, Ch. V, Sect. 4.4.
1391 */
1392 template<typename _RealType>
1393 template<class _UniformRandomNumberGenerator>
1394 typename normal_distribution<_RealType>::result_type
1395 normal_distribution<_RealType>::
1396 operator()(_UniformRandomNumberGenerator& __urng)
1397 {
1398 result_type __ret;
1399
1400 if (_M_saved_available)
1401 {
1402 _M_saved_available = false;
1403 __ret = _M_saved;
1404 }
1405 else
1406 {
1407 result_type __x, __y, __r2;
1408 do
1409 {
1410 __x = result_type(2.0) * __urng() - 1.0;
1411 __y = result_type(2.0) * __urng() - 1.0;
1412 __r2 = __x * __x + __y * __y;
1413 }
1414 while (__r2 > 1.0 || __r2 == 0.0);
1415
1416 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
1417 _M_saved = __x * __mult;
1418 _M_saved_available = true;
1419 __ret = __y * __mult;
1420 }
1421
1422 __ret = __ret * _M_sigma + _M_mean;
1423 return __ret;
1424 }
1425
1426 template<typename _RealType, typename _CharT, typename _Traits>
1427 std::basic_ostream<_CharT, _Traits>&
1428 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1429 const normal_distribution<_RealType>& __x)
1430 {
1431 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1432 typedef typename __ostream_type::ios_base __ios_base;
1433
1434 const typename __ios_base::fmtflags __flags = __os.flags();
1435 const _CharT __fill = __os.fill();
1436 const std::streamsize __precision = __os.precision();
1437 const _CharT __space = __os.widen(' ');
1438 __os.flags(__ios_base::scientific | __ios_base::left);
1439 __os.fill(__space);
1440 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1441
1442 __os << __x._M_saved_available << __space
1443 << __x.mean() << __space
1444 << __x.sigma();
1445 if (__x._M_saved_available)
1446 __os << __space << __x._M_saved;
1447
1448 __os.flags(__flags);
1449 __os.fill(__fill);
1450 __os.precision(__precision);
1451 return __os;
1452 }
1453
1454 template<typename _RealType, typename _CharT, typename _Traits>
1455 std::basic_istream<_CharT, _Traits>&
1456 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1457 normal_distribution<_RealType>& __x)
1458 {
1459 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1460 typedef typename __istream_type::ios_base __ios_base;
1461
1462 const typename __ios_base::fmtflags __flags = __is.flags();
1463 __is.flags(__ios_base::dec | __ios_base::skipws);
1464
1465 __is >> __x._M_saved_available >> __x._M_mean
1466 >> __x._M_sigma;
1467 if (__x._M_saved_available)
1468 __is >> __x._M_saved;
1469
1470 __is.flags(__flags);
1471 return __is;
1472 }
1473
1474
1475 template<typename _RealType>
1476 void
1477 gamma_distribution<_RealType>::
1478 _M_initialize()
1479 {
1480 if (_M_alpha >= 1)
1481 _M_l_d = std::sqrt(2 * _M_alpha - 1);
1482 else
1483 _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha))
1484 * (1 - _M_alpha));
1485 }
1486
1487 /**
1488 * Cheng's rejection algorithm GB for alpha >= 1 and a modification
1489 * of Vaduva's rejection from Weibull algorithm due to Devroye for
1490 * alpha < 1.
1491 *
1492 * References:
1493 * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral
1494 * Shape Parameter." Applied Statistics, 26, 71-75, 1977.
1495 *
1496 * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection
1497 * and Composition Procedures." Math. Operationsforschung and Statistik,
1498 * Series in Statistics, 8, 545-576, 1977.
1499 *
1500 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
1501 * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!).
1502 */
1503 template<typename _RealType>
1504 template<class _UniformRandomNumberGenerator>
1505 typename gamma_distribution<_RealType>::result_type
1506 gamma_distribution<_RealType>::
1507 operator()(_UniformRandomNumberGenerator& __urng)
1508 {
1509 result_type __x;
1510
1511 bool __reject;
1512 if (_M_alpha >= 1)
1513 {
1514 // alpha - log(4)
1515 const result_type __b = _M_alpha
1516 - result_type(1.3862943611198906188344642429163531L);
1517 const result_type __c = _M_alpha + _M_l_d;
1518 const result_type __1l = 1 / _M_l_d;
1519
1520 // 1 + log(9 / 2)
1521 const result_type __k = 2.5040773967762740733732583523868748L;
1522
1523 do
1524 {
1525 const result_type __u = __urng();
1526 const result_type __v = __urng();
1527
1528 const result_type __y = __1l * std::log(__v / (1 - __v));
1529 __x = _M_alpha * std::exp(__y);
1530
1531 const result_type __z = __u * __v * __v;
1532 const result_type __r = __b + __c * __y - __x;
1533
1534 __reject = __r < result_type(4.5) * __z - __k;
1535 if (__reject)
1536 __reject = __r < std::log(__z);
1537 }
1538 while (__reject);
1539 }
1540 else
1541 {
1542 const result_type __c = 1 / _M_alpha;
1543
1544 do
1545 {
1546 const result_type __z = -std::log(__urng());
1547 const result_type __e = -std::log(__urng());
1548
1549 __x = std::pow(__z, __c);
1550
1551 __reject = __z + __e < _M_l_d + __x;
1552 }
1553 while (__reject);
1554 }
1555
1556 return __x;
1557 }
1558
1559 template<typename _RealType, typename _CharT, typename _Traits>
1560 std::basic_ostream<_CharT, _Traits>&
1561 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1562 const gamma_distribution<_RealType>& __x)
1563 {
1564 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1565 typedef typename __ostream_type::ios_base __ios_base;
1566
1567 const typename __ios_base::fmtflags __flags = __os.flags();
1568 const _CharT __fill = __os.fill();
1569 const std::streamsize __precision = __os.precision();
1570 __os.flags(__ios_base::scientific | __ios_base::left);
1571 __os.fill(__os.widen(' '));
1572 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1573
1574 __os << __x.alpha();
1575
1576 __os.flags(__flags);
1577 __os.fill(__fill);
1578 __os.precision(__precision);
1579 return __os;
1580 }
1581
1582}
1583}