1 // random number generation (out of line) -*- C++ -*-
3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 /** @file tr1/random.tcc
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{tr1/random}
31 #ifndef _GLIBCXX_TR1_RANDOM_TCC
32 #define _GLIBCXX_TR1_RANDOM_TCC 1
39 * (Further) implementation-space details.
43 // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid
46 // Because a and c are compile-time integral constants the compiler kindly
47 // elides any unreachable paths.
49 // Preconditions: a > 0, m > 0.
51 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
61 static const _Tp __q = __m / __a;
62 static const _Tp __r = __m % __a;
64 _Tp __t1 = __a * (__x % __q);
65 _Tp __t2 = __r * (__x / __q);
69 __x = __m - __t2 + __t1;
74 const _Tp __d = __m - __x;
84 // Special case for m == 0 -- use unsigned integer overflow as modulo
86 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
87 struct _Mod<_Tp, __a, __c, __m, true>
91 { return __a * __x + __c; }
93 } // namespace __detail
96 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
98 linear_congruential<_UIntType, __a, __c, __m>::multiplier;
100 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
102 linear_congruential<_UIntType, __a, __c, __m>::increment;
104 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
106 linear_congruential<_UIntType, __a, __c, __m>::modulus;
109 * Seeds the LCR with integral value @p __x0, adjusted so that the
110 * ring identity is never a member of the convergence set.
112 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
114 linear_congruential<_UIntType, __a, __c, __m>::
115 seed(unsigned long __x0)
117 if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
118 && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
119 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
121 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
125 * Seeds the LCR engine with a value generated by @p __g.
127 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
130 linear_congruential<_UIntType, __a, __c, __m>::
131 seed(_Gen& __g, false_type)
133 _UIntType __x0 = __g();
134 if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
135 && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
136 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
138 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
142 * Gets the next generated value in sequence.
144 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
145 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
146 linear_congruential<_UIntType, __a, __c, __m>::
149 _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x);
153 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
154 typename _CharT, typename _Traits>
155 std::basic_ostream<_CharT, _Traits>&
156 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
157 const linear_congruential<_UIntType, __a, __c, __m>& __lcr)
159 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
160 typedef typename __ostream_type::ios_base __ios_base;
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(' '));
174 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
175 typename _CharT, typename _Traits>
176 std::basic_istream<_CharT, _Traits>&
177 operator>>(std::basic_istream<_CharT, _Traits>& __is,
178 linear_congruential<_UIntType, __a, __c, __m>& __lcr)
180 typedef std::basic_istream<_CharT, _Traits> __istream_type;
181 typedef typename __istream_type::ios_base __ios_base;
183 const typename __ios_base::fmtflags __flags = __is.flags();
184 __is.flags(__ios_base::dec);
193 template<class _UIntType, int __w, int __n, int __m, int __r,
194 _UIntType __a, int __u, int __s,
195 _UIntType __b, int __t, _UIntType __c, int __l>
197 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
198 __b, __t, __c, __l>::word_size;
200 template<class _UIntType, int __w, int __n, int __m, int __r,
201 _UIntType __a, int __u, int __s,
202 _UIntType __b, int __t, _UIntType __c, int __l>
204 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
205 __b, __t, __c, __l>::state_size;
207 template<class _UIntType, int __w, int __n, int __m, int __r,
208 _UIntType __a, int __u, int __s,
209 _UIntType __b, int __t, _UIntType __c, int __l>
211 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
212 __b, __t, __c, __l>::shift_size;
214 template<class _UIntType, int __w, int __n, int __m, int __r,
215 _UIntType __a, int __u, int __s,
216 _UIntType __b, int __t, _UIntType __c, int __l>
218 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
219 __b, __t, __c, __l>::mask_bits;
221 template<class _UIntType, int __w, int __n, int __m, int __r,
222 _UIntType __a, int __u, int __s,
223 _UIntType __b, int __t, _UIntType __c, int __l>
225 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
226 __b, __t, __c, __l>::parameter_a;
228 template<class _UIntType, int __w, int __n, int __m, int __r,
229 _UIntType __a, int __u, int __s,
230 _UIntType __b, int __t, _UIntType __c, int __l>
232 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
233 __b, __t, __c, __l>::output_u;
235 template<class _UIntType, int __w, int __n, int __m, int __r,
236 _UIntType __a, int __u, int __s,
237 _UIntType __b, int __t, _UIntType __c, int __l>
239 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
240 __b, __t, __c, __l>::output_s;
242 template<class _UIntType, int __w, int __n, int __m, int __r,
243 _UIntType __a, int __u, int __s,
244 _UIntType __b, int __t, _UIntType __c, int __l>
246 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
247 __b, __t, __c, __l>::output_b;
249 template<class _UIntType, int __w, int __n, int __m, int __r,
250 _UIntType __a, int __u, int __s,
251 _UIntType __b, int __t, _UIntType __c, int __l>
253 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
254 __b, __t, __c, __l>::output_t;
256 template<class _UIntType, int __w, int __n, int __m, int __r,
257 _UIntType __a, int __u, int __s,
258 _UIntType __b, int __t, _UIntType __c, int __l>
260 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
261 __b, __t, __c, __l>::output_c;
263 template<class _UIntType, int __w, int __n, int __m, int __r,
264 _UIntType __a, int __u, int __s,
265 _UIntType __b, int __t, _UIntType __c, int __l>
267 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
268 __b, __t, __c, __l>::output_l;
270 template<class _UIntType, int __w, int __n, int __m, int __r,
271 _UIntType __a, int __u, int __s,
272 _UIntType __b, int __t, _UIntType __c, int __l>
274 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
275 __b, __t, __c, __l>::
276 seed(unsigned long __value)
278 _M_x[0] = __detail::__mod<_UIntType, 1, 0,
279 __detail::_Shift<_UIntType, __w>::__value>(__value);
281 for (int __i = 1; __i < state_size; ++__i)
283 _UIntType __x = _M_x[__i - 1];
284 __x ^= __x >> (__w - 2);
287 _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
288 __detail::_Shift<_UIntType, __w>::__value>(__x);
293 template<class _UIntType, int __w, int __n, int __m, int __r,
294 _UIntType __a, int __u, int __s,
295 _UIntType __b, int __t, _UIntType __c, int __l>
298 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
299 __b, __t, __c, __l>::
300 seed(_Gen& __gen, false_type)
302 for (int __i = 0; __i < state_size; ++__i)
303 _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
304 __detail::_Shift<_UIntType, __w>::__value>(__gen());
308 template<class _UIntType, int __w, int __n, int __m, int __r,
309 _UIntType __a, int __u, int __s,
310 _UIntType __b, int __t, _UIntType __c, int __l>
312 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
313 __b, __t, __c, __l>::result_type
314 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
315 __b, __t, __c, __l>::
318 // Reload the vector - cost is O(n) amortized over n calls.
319 if (_M_p >= state_size)
321 const _UIntType __upper_mask = (~_UIntType()) << __r;
322 const _UIntType __lower_mask = ~__upper_mask;
324 for (int __k = 0; __k < (__n - __m); ++__k)
326 _UIntType __y = ((_M_x[__k] & __upper_mask)
327 | (_M_x[__k + 1] & __lower_mask));
328 _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
329 ^ ((__y & 0x01) ? __a : 0));
332 for (int __k = (__n - __m); __k < (__n - 1); ++__k)
334 _UIntType __y = ((_M_x[__k] & __upper_mask)
335 | (_M_x[__k + 1] & __lower_mask));
336 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
337 ^ ((__y & 0x01) ? __a : 0));
340 _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
341 | (_M_x[0] & __lower_mask));
342 _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
343 ^ ((__y & 0x01) ? __a : 0));
347 // Calculate o(x(i)).
348 result_type __z = _M_x[_M_p++];
350 __z ^= (__z << __s) & __b;
351 __z ^= (__z << __t) & __c;
357 template<class _UIntType, int __w, int __n, int __m, int __r,
358 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
359 _UIntType __c, int __l,
360 typename _CharT, typename _Traits>
361 std::basic_ostream<_CharT, _Traits>&
362 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
363 const mersenne_twister<_UIntType, __w, __n, __m,
364 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
366 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
367 typedef typename __ostream_type::ios_base __ios_base;
369 const typename __ios_base::fmtflags __flags = __os.flags();
370 const _CharT __fill = __os.fill();
371 const _CharT __space = __os.widen(' ');
372 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
375 for (int __i = 0; __i < __n - 1; ++__i)
376 __os << __x._M_x[__i] << __space;
377 __os << __x._M_x[__n - 1];
384 template<class _UIntType, int __w, int __n, int __m, int __r,
385 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
386 _UIntType __c, int __l,
387 typename _CharT, typename _Traits>
388 std::basic_istream<_CharT, _Traits>&
389 operator>>(std::basic_istream<_CharT, _Traits>& __is,
390 mersenne_twister<_UIntType, __w, __n, __m,
391 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
393 typedef std::basic_istream<_CharT, _Traits> __istream_type;
394 typedef typename __istream_type::ios_base __ios_base;
396 const typename __ios_base::fmtflags __flags = __is.flags();
397 __is.flags(__ios_base::dec | __ios_base::skipws);
399 for (int __i = 0; __i < __n; ++__i)
400 __is >> __x._M_x[__i];
407 template<typename _IntType, _IntType __m, int __s, int __r>
409 subtract_with_carry<_IntType, __m, __s, __r>::modulus;
411 template<typename _IntType, _IntType __m, int __s, int __r>
413 subtract_with_carry<_IntType, __m, __s, __r>::long_lag;
415 template<typename _IntType, _IntType __m, int __s, int __r>
417 subtract_with_carry<_IntType, __m, __s, __r>::short_lag;
419 template<typename _IntType, _IntType __m, int __s, int __r>
421 subtract_with_carry<_IntType, __m, __s, __r>::
422 seed(unsigned long __value)
427 std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563>
430 for (int __i = 0; __i < long_lag; ++__i)
431 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg());
433 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
437 template<typename _IntType, _IntType __m, int __s, int __r>
440 subtract_with_carry<_IntType, __m, __s, __r>::
441 seed(_Gen& __gen, false_type)
443 const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32;
445 for (int __i = 0; __i < long_lag; ++__i)
448 _UIntType __factor = 1;
449 for (int __j = 0; __j < __n; ++__j)
451 __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0>
452 (__gen()) * __factor;
453 __factor *= __detail::_Shift<_UIntType, 32>::__value;
455 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp);
457 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
461 template<typename _IntType, _IntType __m, int __s, int __r>
462 typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
463 subtract_with_carry<_IntType, __m, __s, __r>::
466 // Derive short lag index from current index.
467 int __ps = _M_p - short_lag;
471 // Calculate new x(i) without overflow or division.
472 // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry
475 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
477 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
482 __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
487 // Adjust current index to loop around in ring buffer.
488 if (++_M_p >= long_lag)
494 template<typename _IntType, _IntType __m, int __s, int __r,
495 typename _CharT, typename _Traits>
496 std::basic_ostream<_CharT, _Traits>&
497 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
498 const subtract_with_carry<_IntType, __m, __s, __r>& __x)
500 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
501 typedef typename __ostream_type::ios_base __ios_base;
503 const typename __ios_base::fmtflags __flags = __os.flags();
504 const _CharT __fill = __os.fill();
505 const _CharT __space = __os.widen(' ');
506 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
509 for (int __i = 0; __i < __r; ++__i)
510 __os << __x._M_x[__i] << __space;
511 __os << __x._M_carry;
518 template<typename _IntType, _IntType __m, int __s, int __r,
519 typename _CharT, typename _Traits>
520 std::basic_istream<_CharT, _Traits>&
521 operator>>(std::basic_istream<_CharT, _Traits>& __is,
522 subtract_with_carry<_IntType, __m, __s, __r>& __x)
524 typedef std::basic_ostream<_CharT, _Traits> __istream_type;
525 typedef typename __istream_type::ios_base __ios_base;
527 const typename __ios_base::fmtflags __flags = __is.flags();
528 __is.flags(__ios_base::dec | __ios_base::skipws);
530 for (int __i = 0; __i < __r; ++__i)
531 __is >> __x._M_x[__i];
532 __is >> __x._M_carry;
539 template<typename _RealType, int __w, int __s, int __r>
541 subtract_with_carry_01<_RealType, __w, __s, __r>::word_size;
543 template<typename _RealType, int __w, int __s, int __r>
545 subtract_with_carry_01<_RealType, __w, __s, __r>::long_lag;
547 template<typename _RealType, int __w, int __s, int __r>
549 subtract_with_carry_01<_RealType, __w, __s, __r>::short_lag;
551 template<typename _RealType, int __w, int __s, int __r>
553 subtract_with_carry_01<_RealType, __w, __s, __r>::
554 _M_initialize_npows()
556 for (int __j = 0; __j < __n; ++__j)
557 #if _GLIBCXX_USE_C99_MATH_TR1
558 _M_npows[__j] = std::tr1::ldexp(_RealType(1), -__w + __j * 32);
560 _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32);
564 template<typename _RealType, int __w, int __s, int __r>
566 subtract_with_carry_01<_RealType, __w, __s, __r>::
567 seed(unsigned long __value)
572 // _GLIBCXX_RESOLVE_LIB_DEFECTS
573 // 512. Seeding subtract_with_carry_01 from a single unsigned long.
574 std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563>
580 template<typename _RealType, int __w, int __s, int __r>
583 subtract_with_carry_01<_RealType, __w, __s, __r>::
584 seed(_Gen& __gen, false_type)
586 for (int __i = 0; __i < long_lag; ++__i)
588 for (int __j = 0; __j < __n - 1; ++__j)
589 _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen());
590 _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
591 __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen());
595 for (int __j = 0; __j < __n; ++__j)
596 if (_M_x[long_lag - 1][__j] != 0)
605 template<typename _RealType, int __w, int __s, int __r>
606 typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type
607 subtract_with_carry_01<_RealType, __w, __s, __r>::
610 // Derive short lag index from current index.
611 int __ps = _M_p - short_lag;
615 _UInt32Type __new_carry;
616 for (int __j = 0; __j < __n - 1; ++__j)
618 if (_M_x[__ps][__j] > _M_x[_M_p][__j]
619 || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0))
624 _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry;
625 _M_carry = __new_carry;
628 if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1]
629 || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0))
634 _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
635 __detail::_Shift<_UInt32Type, __w % 32>::__value>
636 (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry);
637 _M_carry = __new_carry;
639 result_type __ret = 0.0;
640 for (int __j = 0; __j < __n; ++__j)
641 __ret += _M_x[_M_p][__j] * _M_npows[__j];
643 // Adjust current index to loop around in ring buffer.
644 if (++_M_p >= long_lag)
650 template<typename _RealType, int __w, int __s, int __r,
651 typename _CharT, typename _Traits>
652 std::basic_ostream<_CharT, _Traits>&
653 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
654 const subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
656 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
657 typedef typename __ostream_type::ios_base __ios_base;
659 const typename __ios_base::fmtflags __flags = __os.flags();
660 const _CharT __fill = __os.fill();
661 const _CharT __space = __os.widen(' ');
662 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
665 for (int __i = 0; __i < __r; ++__i)
666 for (int __j = 0; __j < __x.__n; ++__j)
667 __os << __x._M_x[__i][__j] << __space;
668 __os << __x._M_carry;
675 template<typename _RealType, int __w, int __s, int __r,
676 typename _CharT, typename _Traits>
677 std::basic_istream<_CharT, _Traits>&
678 operator>>(std::basic_istream<_CharT, _Traits>& __is,
679 subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
681 typedef std::basic_istream<_CharT, _Traits> __istream_type;
682 typedef typename __istream_type::ios_base __ios_base;
684 const typename __ios_base::fmtflags __flags = __is.flags();
685 __is.flags(__ios_base::dec | __ios_base::skipws);
687 for (int __i = 0; __i < __r; ++__i)
688 for (int __j = 0; __j < __x.__n; ++__j)
689 __is >> __x._M_x[__i][__j];
690 __is >> __x._M_carry;
696 template<class _UniformRandomNumberGenerator, int __p, int __r>
698 discard_block<_UniformRandomNumberGenerator, __p, __r>::block_size;
700 template<class _UniformRandomNumberGenerator, int __p, int __r>
702 discard_block<_UniformRandomNumberGenerator, __p, __r>::used_block;
704 template<class _UniformRandomNumberGenerator, int __p, int __r>
705 typename discard_block<_UniformRandomNumberGenerator,
706 __p, __r>::result_type
707 discard_block<_UniformRandomNumberGenerator, __p, __r>::
710 if (_M_n >= used_block)
712 while (_M_n < block_size)
723 template<class _UniformRandomNumberGenerator, int __p, int __r,
724 typename _CharT, typename _Traits>
725 std::basic_ostream<_CharT, _Traits>&
726 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
727 const discard_block<_UniformRandomNumberGenerator,
730 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
731 typedef typename __ostream_type::ios_base __ios_base;
733 const typename __ios_base::fmtflags __flags = __os.flags();
734 const _CharT __fill = __os.fill();
735 const _CharT __space = __os.widen(' ');
736 __os.flags(__ios_base::dec | __ios_base::fixed
740 __os << __x._M_b << __space << __x._M_n;
747 template<class _UniformRandomNumberGenerator, int __p, int __r,
748 typename _CharT, typename _Traits>
749 std::basic_istream<_CharT, _Traits>&
750 operator>>(std::basic_istream<_CharT, _Traits>& __is,
751 discard_block<_UniformRandomNumberGenerator, __p, __r>& __x)
753 typedef std::basic_istream<_CharT, _Traits> __istream_type;
754 typedef typename __istream_type::ios_base __ios_base;
756 const typename __ios_base::fmtflags __flags = __is.flags();
757 __is.flags(__ios_base::dec | __ios_base::skipws);
759 __is >> __x._M_b >> __x._M_n;
766 template<class _UniformRandomNumberGenerator1, int __s1,
767 class _UniformRandomNumberGenerator2, int __s2>
769 xor_combine<_UniformRandomNumberGenerator1, __s1,
770 _UniformRandomNumberGenerator2, __s2>::shift1;
772 template<class _UniformRandomNumberGenerator1, int __s1,
773 class _UniformRandomNumberGenerator2, int __s2>
775 xor_combine<_UniformRandomNumberGenerator1, __s1,
776 _UniformRandomNumberGenerator2, __s2>::shift2;
778 template<class _UniformRandomNumberGenerator1, int __s1,
779 class _UniformRandomNumberGenerator2, int __s2>
781 xor_combine<_UniformRandomNumberGenerator1, __s1,
782 _UniformRandomNumberGenerator2, __s2>::
785 const int __w = std::numeric_limits<result_type>::digits;
787 const result_type __m1 =
788 std::min(result_type(_M_b1.max() - _M_b1.min()),
789 __detail::_Shift<result_type, __w - __s1>::__value - 1);
791 const result_type __m2 =
792 std::min(result_type(_M_b2.max() - _M_b2.min()),
793 __detail::_Shift<result_type, __w - __s2>::__value - 1);
795 // NB: In TR1 s1 is not required to be >= s2.
797 _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1;
799 _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2;
802 template<class _UniformRandomNumberGenerator1, int __s1,
803 class _UniformRandomNumberGenerator2, int __s2>
804 typename xor_combine<_UniformRandomNumberGenerator1, __s1,
805 _UniformRandomNumberGenerator2, __s2>::result_type
806 xor_combine<_UniformRandomNumberGenerator1, __s1,
807 _UniformRandomNumberGenerator2, __s2>::
808 _M_initialize_max_aux(result_type __a, result_type __b, int __d)
810 const result_type __two2d = result_type(1) << __d;
811 const result_type __c = __a * __two2d;
813 if (__a == 0 || __b < __two2d)
816 const result_type __t = std::max(__c, __b);
817 const result_type __u = std::min(__c, __b);
819 result_type __ub = __u;
821 for (__p = 0; __ub != 1; __ub >>= 1)
824 const result_type __two2p = result_type(1) << __p;
825 const result_type __k = __t / __two2p;
828 return (__k + 1) * __two2p - 1;
831 return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p)
835 return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p)
840 template<class _UniformRandomNumberGenerator1, int __s1,
841 class _UniformRandomNumberGenerator2, int __s2,
842 typename _CharT, typename _Traits>
843 std::basic_ostream<_CharT, _Traits>&
844 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
845 const xor_combine<_UniformRandomNumberGenerator1, __s1,
846 _UniformRandomNumberGenerator2, __s2>& __x)
848 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
849 typedef typename __ostream_type::ios_base __ios_base;
851 const typename __ios_base::fmtflags __flags = __os.flags();
852 const _CharT __fill = __os.fill();
853 const _CharT __space = __os.widen(' ');
854 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
857 __os << __x.base1() << __space << __x.base2();
864 template<class _UniformRandomNumberGenerator1, int __s1,
865 class _UniformRandomNumberGenerator2, int __s2,
866 typename _CharT, typename _Traits>
867 std::basic_istream<_CharT, _Traits>&
868 operator>>(std::basic_istream<_CharT, _Traits>& __is,
869 xor_combine<_UniformRandomNumberGenerator1, __s1,
870 _UniformRandomNumberGenerator2, __s2>& __x)
872 typedef std::basic_istream<_CharT, _Traits> __istream_type;
873 typedef typename __istream_type::ios_base __ios_base;
875 const typename __ios_base::fmtflags __flags = __is.flags();
876 __is.flags(__ios_base::skipws);
878 __is >> __x._M_b1 >> __x._M_b2;
885 template<typename _IntType>
886 template<typename _UniformRandomNumberGenerator>
887 typename uniform_int<_IntType>::result_type
888 uniform_int<_IntType>::
889 _M_call(_UniformRandomNumberGenerator& __urng,
890 result_type __min, result_type __max, true_type)
892 // XXX Must be fixed to work well for *arbitrary* __urng.max(),
893 // __urng.min(), __max, __min. Currently works fine only in the
894 // most common case __urng.max() - __urng.min() >= __max - __min,
895 // with __urng.max() > __urng.min() >= 0.
896 typedef typename __gnu_cxx::__add_unsigned<typename
897 _UniformRandomNumberGenerator::result_type>::__type __urntype;
898 typedef typename __gnu_cxx::__add_unsigned<result_type>::__type
900 typedef typename __gnu_cxx::__conditional_type<(sizeof(__urntype)
902 __urntype, __utype>::__type __uctype;
906 const __urntype __urnmin = __urng.min();
907 const __urntype __urnmax = __urng.max();
908 const __urntype __urnrange = __urnmax - __urnmin;
909 const __uctype __urange = __max - __min;
910 const __uctype __udenom = (__urnrange <= __urange
911 ? 1 : __urnrange / (__urange + 1));
913 __ret = (__urntype(__urng()) - __urnmin) / __udenom;
914 while (__ret > __max - __min);
916 return __ret + __min;
919 template<typename _IntType, typename _CharT, typename _Traits>
920 std::basic_ostream<_CharT, _Traits>&
921 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
922 const uniform_int<_IntType>& __x)
924 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
925 typedef typename __ostream_type::ios_base __ios_base;
927 const typename __ios_base::fmtflags __flags = __os.flags();
928 const _CharT __fill = __os.fill();
929 const _CharT __space = __os.widen(' ');
930 __os.flags(__ios_base::scientific | __ios_base::left);
933 __os << __x.min() << __space << __x.max();
940 template<typename _IntType, typename _CharT, typename _Traits>
941 std::basic_istream<_CharT, _Traits>&
942 operator>>(std::basic_istream<_CharT, _Traits>& __is,
943 uniform_int<_IntType>& __x)
945 typedef std::basic_istream<_CharT, _Traits> __istream_type;
946 typedef typename __istream_type::ios_base __ios_base;
948 const typename __ios_base::fmtflags __flags = __is.flags();
949 __is.flags(__ios_base::dec | __ios_base::skipws);
951 __is >> __x._M_min >> __x._M_max;
958 template<typename _CharT, typename _Traits>
959 std::basic_ostream<_CharT, _Traits>&
960 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
961 const bernoulli_distribution& __x)
963 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
964 typedef typename __ostream_type::ios_base __ios_base;
966 const typename __ios_base::fmtflags __flags = __os.flags();
967 const _CharT __fill = __os.fill();
968 const std::streamsize __precision = __os.precision();
969 __os.flags(__ios_base::scientific | __ios_base::left);
970 __os.fill(__os.widen(' '));
971 __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10);
977 __os.precision(__precision);
982 template<typename _IntType, typename _RealType>
983 template<class _UniformRandomNumberGenerator>
984 typename geometric_distribution<_IntType, _RealType>::result_type
985 geometric_distribution<_IntType, _RealType>::
986 operator()(_UniformRandomNumberGenerator& __urng)
988 // About the epsilon thing see this thread:
989 // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
990 const _RealType __naf =
991 (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
992 // The largest _RealType convertible to _IntType.
993 const _RealType __thr =
994 std::numeric_limits<_IntType>::max() + __naf;
998 __cand = std::ceil(std::log(__urng()) / _M_log_p);
999 while (__cand >= __thr);
1001 return result_type(__cand + __naf);
1004 template<typename _IntType, typename _RealType,
1005 typename _CharT, typename _Traits>
1006 std::basic_ostream<_CharT, _Traits>&
1007 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1008 const geometric_distribution<_IntType, _RealType>& __x)
1010 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1011 typedef typename __ostream_type::ios_base __ios_base;
1013 const typename __ios_base::fmtflags __flags = __os.flags();
1014 const _CharT __fill = __os.fill();
1015 const std::streamsize __precision = __os.precision();
1016 __os.flags(__ios_base::scientific | __ios_base::left);
1017 __os.fill(__os.widen(' '));
1018 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1022 __os.flags(__flags);
1024 __os.precision(__precision);
1029 template<typename _IntType, typename _RealType>
1031 poisson_distribution<_IntType, _RealType>::
1034 #if _GLIBCXX_USE_C99_MATH_TR1
1037 const _RealType __m = std::floor(_M_mean);
1038 _M_lm_thr = std::log(_M_mean);
1039 _M_lfm = std::tr1::lgamma(__m + 1);
1040 _M_sm = std::sqrt(__m);
1042 const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
1043 const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m
1045 _M_d = std::tr1::round(std::max(_RealType(6),
1046 std::min(__m, __dx)));
1047 const _RealType __cx = 2 * __m + _M_d;
1048 _M_scx = std::sqrt(__cx / 2);
1051 _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
1052 _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d;
1056 _M_lm_thr = std::exp(-_M_mean);
1060 * A rejection algorithm when mean >= 12 and a simple method based
1061 * upon the multiplication of uniform random variates otherwise.
1062 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1066 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1067 * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
1069 template<typename _IntType, typename _RealType>
1070 template<class _UniformRandomNumberGenerator>
1071 typename poisson_distribution<_IntType, _RealType>::result_type
1072 poisson_distribution<_IntType, _RealType>::
1073 operator()(_UniformRandomNumberGenerator& __urng)
1075 #if _GLIBCXX_USE_C99_MATH_TR1
1080 // See comments above...
1081 const _RealType __naf =
1082 (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
1083 const _RealType __thr =
1084 std::numeric_limits<_IntType>::max() + __naf;
1086 const _RealType __m = std::floor(_M_mean);
1088 const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
1089 const _RealType __c1 = _M_sm * __spi_2;
1090 const _RealType __c2 = _M_c2b + __c1;
1091 const _RealType __c3 = __c2 + 1;
1092 const _RealType __c4 = __c3 + 1;
1094 const _RealType __e178 = 1.0129030479320018583185514777512983L;
1095 const _RealType __c5 = __c4 + __e178;
1096 const _RealType __c = _M_cb + __c5;
1097 const _RealType __2cx = 2 * (2 * __m + _M_d);
1099 bool __reject = true;
1102 const _RealType __u = __c * __urng();
1103 const _RealType __e = -std::log(__urng());
1105 _RealType __w = 0.0;
1109 const _RealType __n = _M_nd(__urng);
1110 const _RealType __y = -std::abs(__n) * _M_sm - 1;
1111 __x = std::floor(__y);
1112 __w = -__n * __n / 2;
1116 else if (__u <= __c2)
1118 const _RealType __n = _M_nd(__urng);
1119 const _RealType __y = 1 + std::abs(__n) * _M_scx;
1120 __x = std::ceil(__y);
1121 __w = __y * (2 - __y) * _M_1cx;
1125 else if (__u <= __c3)
1126 // NB: This case not in the book, nor in the Errata,
1127 // but should be ok...
1129 else if (__u <= __c4)
1131 else if (__u <= __c5)
1135 const _RealType __v = -std::log(__urng());
1136 const _RealType __y = _M_d + __v * __2cx / _M_d;
1137 __x = std::ceil(__y);
1138 __w = -_M_d * _M_1cx * (1 + __y / 2);
1141 __reject = (__w - __e - __x * _M_lm_thr
1142 > _M_lfm - std::tr1::lgamma(__x + __m + 1));
1144 __reject |= __x + __m >= __thr;
1148 return result_type(__x + __m + __naf);
1154 _RealType __prod = 1.0;
1161 while (__prod > _M_lm_thr);
1167 template<typename _IntType, typename _RealType,
1168 typename _CharT, typename _Traits>
1169 std::basic_ostream<_CharT, _Traits>&
1170 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1171 const poisson_distribution<_IntType, _RealType>& __x)
1173 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1174 typedef typename __ostream_type::ios_base __ios_base;
1176 const typename __ios_base::fmtflags __flags = __os.flags();
1177 const _CharT __fill = __os.fill();
1178 const std::streamsize __precision = __os.precision();
1179 const _CharT __space = __os.widen(' ');
1180 __os.flags(__ios_base::scientific | __ios_base::left);
1182 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1184 __os << __x.mean() << __space << __x._M_nd;
1186 __os.flags(__flags);
1188 __os.precision(__precision);
1192 template<typename _IntType, typename _RealType,
1193 typename _CharT, typename _Traits>
1194 std::basic_istream<_CharT, _Traits>&
1195 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1196 poisson_distribution<_IntType, _RealType>& __x)
1198 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1199 typedef typename __istream_type::ios_base __ios_base;
1201 const typename __ios_base::fmtflags __flags = __is.flags();
1202 __is.flags(__ios_base::skipws);
1204 __is >> __x._M_mean >> __x._M_nd;
1205 __x._M_initialize();
1207 __is.flags(__flags);
1212 template<typename _IntType, typename _RealType>
1214 binomial_distribution<_IntType, _RealType>::
1217 const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1221 #if _GLIBCXX_USE_C99_MATH_TR1
1222 if (_M_t * __p12 >= 8)
1225 const _RealType __np = std::floor(_M_t * __p12);
1226 const _RealType __pa = __np / _M_t;
1227 const _RealType __1p = 1 - __pa;
1229 const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
1230 const _RealType __d1x =
1231 std::sqrt(__np * __1p * std::log(32 * __np
1232 / (81 * __pi_4 * __1p)));
1233 _M_d1 = std::tr1::round(std::max(_RealType(1), __d1x));
1234 const _RealType __d2x =
1235 std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
1236 / (__pi_4 * __pa)));
1237 _M_d2 = std::tr1::round(std::max(_RealType(1), __d2x));
1240 const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
1241 _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
1242 _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
1243 _M_c = 2 * _M_d1 / __np;
1244 _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
1245 const _RealType __a12 = _M_a1 + _M_s2 * __spi_2;
1246 const _RealType __s1s = _M_s1 * _M_s1;
1247 _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
1249 * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
1250 const _RealType __s2s = _M_s2 * _M_s2;
1251 _M_s = (_M_a123 + 2 * __s2s / _M_d2
1252 * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
1253 _M_lf = (std::tr1::lgamma(__np + 1)
1254 + std::tr1::lgamma(_M_t - __np + 1));
1255 _M_lp1p = std::log(__pa / __1p);
1257 _M_q = -std::log(1 - (__p12 - __pa) / __1p);
1261 _M_q = -std::log(1 - __p12);
1264 template<typename _IntType, typename _RealType>
1265 template<class _UniformRandomNumberGenerator>
1266 typename binomial_distribution<_IntType, _RealType>::result_type
1267 binomial_distribution<_IntType, _RealType>::
1268 _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
1271 _RealType __sum = 0;
1275 const _RealType __e = -std::log(__urng());
1276 __sum += __e / (__t - __x);
1279 while (__sum <= _M_q);
1285 * A rejection algorithm when t * p >= 8 and a simple waiting time
1286 * method - the second in the referenced book - otherwise.
1287 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1291 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1292 * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
1294 template<typename _IntType, typename _RealType>
1295 template<class _UniformRandomNumberGenerator>
1296 typename binomial_distribution<_IntType, _RealType>::result_type
1297 binomial_distribution<_IntType, _RealType>::
1298 operator()(_UniformRandomNumberGenerator& __urng)
1301 const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1303 #if _GLIBCXX_USE_C99_MATH_TR1
1308 // See comments above...
1309 const _RealType __naf =
1310 (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
1311 const _RealType __thr =
1312 std::numeric_limits<_IntType>::max() + __naf;
1314 const _RealType __np = std::floor(_M_t * __p12);
1315 const _RealType __pa = __np / _M_t;
1318 const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
1319 const _RealType __a1 = _M_a1;
1320 const _RealType __a12 = __a1 + _M_s2 * __spi_2;
1321 const _RealType __a123 = _M_a123;
1322 const _RealType __s1s = _M_s1 * _M_s1;
1323 const _RealType __s2s = _M_s2 * _M_s2;
1328 const _RealType __u = _M_s * __urng();
1334 const _RealType __n = _M_nd(__urng);
1335 const _RealType __y = _M_s1 * std::abs(__n);
1336 __reject = __y >= _M_d1;
1339 const _RealType __e = -std::log(__urng());
1340 __x = std::floor(__y);
1341 __v = -__e - __n * __n / 2 + _M_c;
1344 else if (__u <= __a12)
1346 const _RealType __n = _M_nd(__urng);
1347 const _RealType __y = _M_s2 * std::abs(__n);
1348 __reject = __y >= _M_d2;
1351 const _RealType __e = -std::log(__urng());
1352 __x = std::floor(-__y);
1353 __v = -__e - __n * __n / 2;
1356 else if (__u <= __a123)
1358 const _RealType __e1 = -std::log(__urng());
1359 const _RealType __e2 = -std::log(__urng());
1361 const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1;
1362 __x = std::floor(__y);
1363 __v = (-__e2 + _M_d1 * (1 / (_M_t - __np)
1364 -__y / (2 * __s1s)));
1369 const _RealType __e1 = -std::log(__urng());
1370 const _RealType __e2 = -std::log(__urng());
1372 const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2;
1373 __x = std::floor(-__y);
1374 __v = -__e2 - _M_d2 * __y / (2 * __s2s);
1378 __reject = __reject || __x < -__np || __x > _M_t - __np;
1381 const _RealType __lfx =
1382 std::tr1::lgamma(__np + __x + 1)
1383 + std::tr1::lgamma(_M_t - (__np + __x) + 1);
1384 __reject = __v > _M_lf - __lfx + __x * _M_lp1p;
1387 __reject |= __x + __np >= __thr;
1391 __x += __np + __naf;
1393 const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x));
1394 __ret = _IntType(__x) + __z;
1398 __ret = _M_waiting(__urng, _M_t);
1401 __ret = _M_t - __ret;
1405 template<typename _IntType, typename _RealType,
1406 typename _CharT, typename _Traits>
1407 std::basic_ostream<_CharT, _Traits>&
1408 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1409 const binomial_distribution<_IntType, _RealType>& __x)
1411 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1412 typedef typename __ostream_type::ios_base __ios_base;
1414 const typename __ios_base::fmtflags __flags = __os.flags();
1415 const _CharT __fill = __os.fill();
1416 const std::streamsize __precision = __os.precision();
1417 const _CharT __space = __os.widen(' ');
1418 __os.flags(__ios_base::scientific | __ios_base::left);
1420 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1422 __os << __x.t() << __space << __x.p()
1423 << __space << __x._M_nd;
1425 __os.flags(__flags);
1427 __os.precision(__precision);
1431 template<typename _IntType, typename _RealType,
1432 typename _CharT, typename _Traits>
1433 std::basic_istream<_CharT, _Traits>&
1434 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1435 binomial_distribution<_IntType, _RealType>& __x)
1437 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1438 typedef typename __istream_type::ios_base __ios_base;
1440 const typename __ios_base::fmtflags __flags = __is.flags();
1441 __is.flags(__ios_base::dec | __ios_base::skipws);
1443 __is >> __x._M_t >> __x._M_p >> __x._M_nd;
1444 __x._M_initialize();
1446 __is.flags(__flags);
1451 template<typename _RealType, typename _CharT, typename _Traits>
1452 std::basic_ostream<_CharT, _Traits>&
1453 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1454 const uniform_real<_RealType>& __x)
1456 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1457 typedef typename __ostream_type::ios_base __ios_base;
1459 const typename __ios_base::fmtflags __flags = __os.flags();
1460 const _CharT __fill = __os.fill();
1461 const std::streamsize __precision = __os.precision();
1462 const _CharT __space = __os.widen(' ');
1463 __os.flags(__ios_base::scientific | __ios_base::left);
1465 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1467 __os << __x.min() << __space << __x.max();
1469 __os.flags(__flags);
1471 __os.precision(__precision);
1475 template<typename _RealType, typename _CharT, typename _Traits>
1476 std::basic_istream<_CharT, _Traits>&
1477 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1478 uniform_real<_RealType>& __x)
1480 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1481 typedef typename __istream_type::ios_base __ios_base;
1483 const typename __ios_base::fmtflags __flags = __is.flags();
1484 __is.flags(__ios_base::skipws);
1486 __is >> __x._M_min >> __x._M_max;
1488 __is.flags(__flags);
1493 template<typename _RealType, typename _CharT, typename _Traits>
1494 std::basic_ostream<_CharT, _Traits>&
1495 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1496 const exponential_distribution<_RealType>& __x)
1498 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1499 typedef typename __ostream_type::ios_base __ios_base;
1501 const typename __ios_base::fmtflags __flags = __os.flags();
1502 const _CharT __fill = __os.fill();
1503 const std::streamsize __precision = __os.precision();
1504 __os.flags(__ios_base::scientific | __ios_base::left);
1505 __os.fill(__os.widen(' '));
1506 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1508 __os << __x.lambda();
1510 __os.flags(__flags);
1512 __os.precision(__precision);
1518 * Polar method due to Marsaglia.
1520 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1521 * New York, 1986, Ch. V, Sect. 4.4.
1523 template<typename _RealType>
1524 template<class _UniformRandomNumberGenerator>
1525 typename normal_distribution<_RealType>::result_type
1526 normal_distribution<_RealType>::
1527 operator()(_UniformRandomNumberGenerator& __urng)
1531 if (_M_saved_available)
1533 _M_saved_available = false;
1538 result_type __x, __y, __r2;
1541 __x = result_type(2.0) * __urng() - 1.0;
1542 __y = result_type(2.0) * __urng() - 1.0;
1543 __r2 = __x * __x + __y * __y;
1545 while (__r2 > 1.0 || __r2 == 0.0);
1547 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
1548 _M_saved = __x * __mult;
1549 _M_saved_available = true;
1550 __ret = __y * __mult;
1553 __ret = __ret * _M_sigma + _M_mean;
1557 template<typename _RealType, typename _CharT, typename _Traits>
1558 std::basic_ostream<_CharT, _Traits>&
1559 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1560 const normal_distribution<_RealType>& __x)
1562 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1563 typedef typename __ostream_type::ios_base __ios_base;
1565 const typename __ios_base::fmtflags __flags = __os.flags();
1566 const _CharT __fill = __os.fill();
1567 const std::streamsize __precision = __os.precision();
1568 const _CharT __space = __os.widen(' ');
1569 __os.flags(__ios_base::scientific | __ios_base::left);
1571 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1573 __os << __x._M_saved_available << __space
1574 << __x.mean() << __space
1576 if (__x._M_saved_available)
1577 __os << __space << __x._M_saved;
1579 __os.flags(__flags);
1581 __os.precision(__precision);
1585 template<typename _RealType, typename _CharT, typename _Traits>
1586 std::basic_istream<_CharT, _Traits>&
1587 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1588 normal_distribution<_RealType>& __x)
1590 typedef std::basic_istream<_CharT, _Traits> __istream_type;
1591 typedef typename __istream_type::ios_base __ios_base;
1593 const typename __ios_base::fmtflags __flags = __is.flags();
1594 __is.flags(__ios_base::dec | __ios_base::skipws);
1596 __is >> __x._M_saved_available >> __x._M_mean
1598 if (__x._M_saved_available)
1599 __is >> __x._M_saved;
1601 __is.flags(__flags);
1606 template<typename _RealType>
1608 gamma_distribution<_RealType>::
1612 _M_l_d = std::sqrt(2 * _M_alpha - 1);
1614 _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha))
1619 * Cheng's rejection algorithm GB for alpha >= 1 and a modification
1620 * of Vaduva's rejection from Weibull algorithm due to Devroye for
1624 * Cheng, R. C. The Generation of Gamma Random Variables with Non-integral
1625 * Shape Parameter. Applied Statistics, 26, 71-75, 1977.
1627 * Vaduva, I. Computer Generation of Gamma Gandom Variables by Rejection
1628 * and Composition Procedures. Math. Operationsforschung and Statistik,
1629 * Series in Statistics, 8, 545-576, 1977.
1631 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1632 * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!).
1634 template<typename _RealType>
1635 template<class _UniformRandomNumberGenerator>
1636 typename gamma_distribution<_RealType>::result_type
1637 gamma_distribution<_RealType>::
1638 operator()(_UniformRandomNumberGenerator& __urng)
1646 const result_type __b = _M_alpha
1647 - result_type(1.3862943611198906188344642429163531L);
1648 const result_type __c = _M_alpha + _M_l_d;
1649 const result_type __1l = 1 / _M_l_d;
1652 const result_type __k = 2.5040773967762740733732583523868748L;
1656 const result_type __u = __urng();
1657 const result_type __v = __urng();
1659 const result_type __y = __1l * std::log(__v / (1 - __v));
1660 __x = _M_alpha * std::exp(__y);
1662 const result_type __z = __u * __v * __v;
1663 const result_type __r = __b + __c * __y - __x;
1665 __reject = __r < result_type(4.5) * __z - __k;
1667 __reject = __r < std::log(__z);
1673 const result_type __c = 1 / _M_alpha;
1677 const result_type __z = -std::log(__urng());
1678 const result_type __e = -std::log(__urng());
1680 __x = std::pow(__z, __c);
1682 __reject = __z + __e < _M_l_d + __x;
1690 template<typename _RealType, typename _CharT, typename _Traits>
1691 std::basic_ostream<_CharT, _Traits>&
1692 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1693 const gamma_distribution<_RealType>& __x)
1695 typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
1696 typedef typename __ostream_type::ios_base __ios_base;
1698 const typename __ios_base::fmtflags __flags = __os.flags();
1699 const _CharT __fill = __os.fill();
1700 const std::streamsize __precision = __os.precision();
1701 __os.flags(__ios_base::scientific | __ios_base::left);
1702 __os.fill(__os.widen(' '));
1703 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
1705 __os << __x.alpha();
1707 __os.flags(__flags);
1709 __os.precision(__precision);