1 // random number generation (out of line) -*- C++ -*-
3 // Copyright (C) 2006 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 2, 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 // 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,
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.
32 _GLIBCXX_BEGIN_NAMESPACE(tr1)
35 * Implementation-space details.
39 // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid
42 // Because a and c are compile-time integral constants the compiler kindly
43 // elides any unreachable paths.
45 // Preconditions: a > 0, m > 0.
47 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
57 static const _Tp __q = __m / __a;
58 static const _Tp __r = __m % __a;
60 _Tp __t1 = __a * (__x % __q);
61 _Tp __t2 = __r * (__x / __q);
65 __x = __m - __t2 + __t1;
70 const _Tp __d = __m - __x;
80 // Special case for m == 0 -- use unsigned integer overflow as modulo
82 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
83 struct _Mod<_Tp, __a, __c, __m, true>
87 { return __a * __x + __c; }
90 // Dispatch based on modulus value to prevent divide-by-zero compile-time
91 // errors when m == 0.
92 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
95 { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
98 template<typename _RealType>
101 static const std::streamsize __value =
102 2 + std::numeric_limits<_RealType>::digits * 3010/10000;
105 template<typename _ValueT>
106 struct _To_Unsigned_Type
107 { typedef _ValueT _Type; };
110 struct _To_Unsigned_Type<short>
111 { typedef unsigned short _Type; };
114 struct _To_Unsigned_Type<int>
115 { typedef unsigned int _Type; };
118 struct _To_Unsigned_Type<long>
119 { typedef unsigned long _Type; };
121 #ifdef _GLIBCXX_USE_LONG_LONG
123 struct _To_Unsigned_Type<long long>
124 { typedef unsigned long long _Type; };
127 } // anonymous namespace
131 * Seeds the LCR with integral value @p __x0, adjusted so that the
132 * ring identity is never a member of the convergence set.
134 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
136 linear_congruential<_UIntType, __a, __c, __m>::
137 seed(unsigned long __x0)
139 if ((__mod<_UIntType, 1, 0, __m>(__c) == 0)
140 && (__mod<_UIntType, 1, 0, __m>(__x0) == 0))
141 _M_x = __mod<_UIntType, 1, 0, __m>(1);
143 _M_x = __mod<_UIntType, 1, 0, __m>(__x0);
147 * Seeds the LCR engine with a value generated by @p __g.
149 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
152 linear_congruential<_UIntType, __a, __c, __m>::
153 seed(_Gen& __g, false_type)
155 _UIntType __x0 = __g();
156 if ((__mod<_UIntType, 1, 0, __m>(__c) == 0)
157 && (__mod<_UIntType, 1, 0, __m>(__x0) == 0))
158 _M_x = __mod<_UIntType, 1, 0, __m>(1);
160 _M_x = __mod<_UIntType, 1, 0, __m>(__x0);
164 * Returns a value that is less than or equal to all values potentially
165 * returned by operator(). The return value of this function does not
166 * change during the lifetime of the object..
168 * The minumum depends on the @p __c parameter: if it is zero, the
169 * minimum generated must be > 0, otherwise 0 is allowed.
171 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
172 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
173 linear_congruential<_UIntType, __a, __c, __m>::
175 { return (__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
178 * Gets the maximum possible value of the generated range.
180 * For a linear congruential generator, the maximum is always @p __m - 1.
182 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
183 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
184 linear_congruential<_UIntType, __a, __c, __m>::
186 { return (__m == 0) ? std::numeric_limits<_UIntType>::max() : (__m - 1); }
189 * Gets the next generated value in sequence.
191 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
192 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
193 linear_congruential<_UIntType, __a, __c, __m>::
196 _M_x = __mod<_UIntType, __a, __c, __m>(_M_x);
200 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
201 typename _CharT, typename _Traits>
202 std::basic_ostream<_CharT, _Traits>&
203 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
204 const linear_congruential<_UIntType, __a, __c, __m>& __lcr)
206 const std::ios_base::fmtflags __flags = __os.flags();
207 const _CharT __fill = __os.fill();
208 __os.flags(std::ios_base::dec | std::ios_base::fixed
209 | std::ios_base::left);
210 __os.fill(__os.widen(' '));
219 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
220 typename _CharT, typename _Traits>
221 std::basic_istream<_CharT, _Traits>&
222 operator>>(std::basic_istream<_CharT, _Traits>& __is,
223 linear_congruential<_UIntType, __a, __c, __m>& __lcr)
225 const std::ios_base::fmtflags __flags = __is.flags();
226 __is.flags(std::ios_base::dec);
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>::
241 seed(unsigned long __value)
243 _M_x[0] = __mod<_UIntType, 1, 0,
244 _Shift<_UIntType, __w>::__value>(__value);
246 for (int __i = 1; __i < state_size; ++__i)
248 _UIntType __x = _M_x[__i - 1];
249 __x ^= __x >> (__w - 2);
252 _M_x[__i] = __mod<_UIntType, 1, 0,
253 _Shift<_UIntType, __w>::__value>(__x);
258 template<class _UIntType, int __w, int __n, int __m, int __r,
259 _UIntType __a, int __u, int __s,
260 _UIntType __b, int __t, _UIntType __c, int __l>
263 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
264 __b, __t, __c, __l>::
265 seed(_Gen& __gen, false_type)
267 for (int __i = 0; __i < state_size; ++__i)
268 _M_x[__i] = __mod<_UIntType, 1, 0,
269 _Shift<_UIntType, __w>::__value>(__gen());
273 template<class _UIntType, int __w, int __n, int __m, int __r,
274 _UIntType __a, int __u, int __s,
275 _UIntType __b, int __t, _UIntType __c, int __l>
277 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
278 __b, __t, __c, __l>::result_type
279 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
280 __b, __t, __c, __l>::
283 // Reload the vector - cost is O(n) amortized over n calls.
284 if (_M_p >= state_size)
286 const _UIntType __upper_mask = (~_UIntType()) << __r;
287 const _UIntType __lower_mask = ~__upper_mask;
288 const _UIntType __fx[2] = { 0, __a };
290 for (int __k = 0; __k < (__n - __m); ++__k)
292 _UIntType __y = ((_M_x[__k] & __upper_mask)
293 | (_M_x[__k + 1] & __lower_mask));
294 _M_x[__k] = _M_x[__k + __m] ^ (__y >> 1) ^ __fx[__y & 0x01];
297 for (int __k = (__n - __m); __k < (__n - 1); ++__k)
299 _UIntType __y = ((_M_x[__k] & __upper_mask)
300 | (_M_x[__k + 1] & __lower_mask));
301 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
305 _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
306 | (_M_x[0] & __lower_mask));
307 _M_x[__n - 1] = _M_x[__m - 1] ^ (__y >> 1) ^ __fx[__y & 0x01];
311 // Calculate o(x(i)).
312 result_type __z = _M_x[_M_p++];
314 __z ^= (__z << __s) & __b;
315 __z ^= (__z << __t) & __c;
321 template<class _UIntType, int __w, int __n, int __m, int __r,
322 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
323 _UIntType __c, int __l,
324 typename _CharT, typename _Traits>
325 std::basic_ostream<_CharT, _Traits>&
326 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
327 const mersenne_twister<_UIntType, __w, __n, __m,
328 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
330 const std::ios_base::fmtflags __flags = __os.flags();
331 const _CharT __fill = __os.fill();
332 const _CharT __space = __os.widen(' ');
333 __os.flags(std::ios_base::dec | std::ios_base::fixed
334 | std::ios_base::left);
337 for (int __i = 0; __i < __n - 1; ++__i)
338 __os << __x._M_x[__i] << __space;
339 __os << __x._M_x[__n - 1];
346 template<class _UIntType, int __w, int __n, int __m, int __r,
347 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
348 _UIntType __c, int __l,
349 typename _CharT, typename _Traits>
350 std::basic_istream<_CharT, _Traits>&
351 operator>>(std::basic_istream<_CharT, _Traits>& __is,
352 mersenne_twister<_UIntType, __w, __n, __m,
353 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
355 const std::ios_base::fmtflags __flags = __is.flags();
356 __is.flags(std::ios_base::dec | std::ios_base::skipws);
358 for (int __i = 0; __i < __n; ++__i)
359 __is >> __x._M_x[__i];
366 template<typename _IntType, _IntType __m, int __s, int __r>
368 subtract_with_carry<_IntType, __m, __s, __r>::
369 seed(unsigned long __value)
374 std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563>
377 for (int __i = 0; __i < long_lag; ++__i)
378 _M_x[__i] = __mod<_IntType, 1, 0, modulus>(__lcg());
380 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
384 template<typename _IntType, _IntType __m, int __s, int __r>
387 subtract_with_carry<_IntType, __m, __s, __r>::
388 seed(_Gen& __gen, false_type)
390 const int __n = (std::numeric_limits<_IntType>::digits + 31) / 32;
392 typedef typename _Select<(sizeof(unsigned) == 4),
393 unsigned, unsigned long>::_Type _UInt32Type;
395 typedef typename _To_Unsigned_Type<_IntType>::_Type
398 for (int __i = 0; __i < long_lag; ++__i)
401 _UIntType __factor = 1;
402 for (int __j = 0; __j < __n; ++__j)
404 __tmp += (__mod<_UInt32Type, 1, 0, 0>(__gen())
406 __factor *= _Shift<_UIntType, 32>::__value;
408 _M_x[__i] = __mod<_UIntType, 1, 0, modulus>(__tmp);
410 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
414 template<typename _IntType, _IntType __m, int __s, int __r>
415 typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
416 subtract_with_carry<_IntType, __m, __s, __r>::
419 // Derive short lag index from current index.
420 int __ps = _M_p - short_lag;
424 // Calculate new x(i) without overflow or division.
426 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
428 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
433 __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
438 // Adjust current index to loop around in ring buffer.
439 if (_M_p >= long_lag)
445 template<typename _IntType, _IntType __m, int __s, int __r,
446 typename _CharT, typename _Traits>
447 std::basic_ostream<_CharT, _Traits>&
448 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
449 const subtract_with_carry<_IntType, __m, __s, __r>& __x)
451 const std::ios_base::fmtflags __flags = __os.flags();
452 const _CharT __fill = __os.fill();
453 const _CharT __space = __os.widen(' ');
454 __os.flags(std::ios_base::dec | std::ios_base::fixed
455 | std::ios_base::left);
458 for (int __i = 0; __i < __r; ++__i)
459 __os << __x._M_x[__i] << __space;
460 __os << __x._M_carry;
467 template<typename _IntType, _IntType __m, int __s, int __r,
468 typename _CharT, typename _Traits>
469 std::basic_istream<_CharT, _Traits>&
470 operator>>(std::basic_istream<_CharT, _Traits>& __is,
471 subtract_with_carry<_IntType, __m, __s, __r>& __x)
473 const std::ios_base::fmtflags __flags = __is.flags();
474 __is.flags(std::ios_base::dec | std::ios_base::skipws);
476 for (int __i = 0; __i < __r; ++__i)
477 __is >> __x._M_x[__i];
478 __is >> __x._M_carry;
485 template<class _UniformRandomNumberGenerator, int __p, int __r>
486 typename discard_block<_UniformRandomNumberGenerator,
487 __p, __r>::result_type
488 discard_block<_UniformRandomNumberGenerator, __p, __r>::
491 if (_M_n >= used_block)
493 while (_M_n < block_size)
504 template<class _UniformRandomNumberGenerator, int __p, int __r,
505 typename _CharT, typename _Traits>
506 std::basic_ostream<_CharT, _Traits>&
507 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
508 const discard_block<_UniformRandomNumberGenerator,
511 const std::ios_base::fmtflags __flags = __os.flags();
512 const _CharT __fill = __os.fill();
513 const _CharT __space = __os.widen(' ');
514 __os.flags(std::ios_base::dec | std::ios_base::fixed
515 | std::ios_base::left);
518 __os << __x._M_b << __space << __x._M_n;
525 template<class _UniformRandomNumberGenerator, int __p, int __r,
526 typename _CharT, typename _Traits>
527 std::basic_istream<_CharT, _Traits>&
528 operator>>(std::basic_istream<_CharT, _Traits>& __is,
529 discard_block<_UniformRandomNumberGenerator, __p, __r>& __x)
531 const std::ios_base::fmtflags __flags = __is.flags();
532 __is.flags(std::ios_base::dec | std::ios_base::skipws);
534 __is >> __x._M_b >> __x._M_n;
541 template<class _UniformRandomNumberGenerator1, int __s1,
542 class _UniformRandomNumberGenerator2, int __s2,
543 typename _CharT, typename _Traits>
544 std::basic_ostream<_CharT, _Traits>&
545 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
546 const xor_combine<_UniformRandomNumberGenerator1, __s1,
547 _UniformRandomNumberGenerator2, __s2>& __x)
549 const std::ios_base::fmtflags __flags = __os.flags();
550 const _CharT __fill = __os.fill();
551 const _CharT __space = __os.widen(' ');
552 __os.flags(std::ios_base::dec | std::ios_base::fixed
553 | std::ios_base::left);
556 __os << __x.base1() << __space << __x.base2();
563 template<class _UniformRandomNumberGenerator1, int __s1,
564 class _UniformRandomNumberGenerator2, int __s2,
565 typename _CharT, typename _Traits>
566 std::basic_istream<_CharT, _Traits>&
567 operator>>(std::basic_istream<_CharT, _Traits>& __is,
568 xor_combine<_UniformRandomNumberGenerator1, __s1,
569 _UniformRandomNumberGenerator2, __s2>& __x)
571 const std::ios_base::fmtflags __flags = __is.flags();
572 __is.flags(std::ios_base::skipws);
574 __is >> __x._M_b1 >> __x._M_b2;
581 template<typename _IntType, typename _CharT, typename _Traits>
582 std::basic_ostream<_CharT, _Traits>&
583 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
584 const uniform_int<_IntType>& __x)
586 const std::ios_base::fmtflags __flags = __os.flags();
587 const _CharT __fill = __os.fill();
588 const _CharT __space = __os.widen(' ');
589 __os.flags(std::ios_base::scientific | std::ios_base::left);
592 __os << __x.min() << __space << __x.max();
599 template<typename _IntType, typename _CharT, typename _Traits>
600 std::basic_istream<_CharT, _Traits>&
601 operator>>(std::basic_istream<_CharT, _Traits>& __is,
602 uniform_int<_IntType>& __x)
604 const std::ios_base::fmtflags __flags = __is.flags();
605 __is.flags(std::ios_base::dec | std::ios_base::skipws);
607 __is >> __x._M_min >> __x._M_max;
614 template<typename _CharT, typename _Traits>
615 std::basic_ostream<_CharT, _Traits>&
616 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
617 const bernoulli_distribution& __x)
619 const std::ios_base::fmtflags __flags = __os.flags();
620 const _CharT __fill = __os.fill();
621 const std::streamsize __precision = __os.precision();
622 __os.flags(std::ios_base::scientific | std::ios_base::left);
623 __os.fill(__os.widen(' '));
624 __os.precision(_Max_digits10<double>::__value);
630 __os.precision(__precision);
635 template<typename _IntType, typename _RealType,
636 typename _CharT, typename _Traits>
637 std::basic_ostream<_CharT, _Traits>&
638 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
639 const geometric_distribution<_IntType, _RealType>& __x)
641 const std::ios_base::fmtflags __flags = __os.flags();
642 const _CharT __fill = __os.fill();
643 const std::streamsize __precision = __os.precision();
644 __os.flags(std::ios_base::scientific | std::ios_base::left);
645 __os.fill(__os.widen(' '));
646 __os.precision(_Max_digits10<_RealType>::__value);
652 __os.precision(__precision);
657 template<typename _IntType, typename _RealType>
658 poisson_distribution<_IntType, _RealType>::
659 poisson_distribution(const _RealType& __mean)
660 : _M_mean(__mean), _M_large(false)
662 _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
664 #if _GLIBCXX_USE_C99_MATH_TR1
668 const _RealType __m = std::floor(_M_mean);
669 _M_lm_thr = std::log(_M_mean);
670 _M_lfm = std::tr1::lgamma(__m + 1);
671 _M_sm = std::sqrt(__m);
673 const _RealType __dx =
675 * std::log(_RealType(40.743665431525205956834243423363677L)
677 _M_d = std::tr1::round(std::max(_RealType(6),
678 std::min(__m, __dx)));
679 const _RealType __cx = 2 * (2 * __m + _M_d);
680 const _RealType __cx4 = __cx / 4;
681 _M_scx4 = std::sqrt(__cx4);
684 const _RealType __pi_2 = 1.5707963267948966192313216916397514L;
685 _M_c2b = std::sqrt(__pi_2 * __cx4) * std::exp(_M_2cx);
686 _M_cb = __cx * std::exp(-_M_d * _M_2cx * (1 + _M_d / 2)) / _M_d;
690 _M_lm_thr = std::exp(-_M_mean);
694 * A rejection algorithm when mean >= 12 and a simple method based
695 * upon the multiplication of uniform random variates otherwise.
696 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
700 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
701 * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
703 template<typename _IntType, typename _RealType>
704 template<class _UniformRandomNumberGenerator>
705 typename poisson_distribution<_IntType, _RealType>::result_type
706 poisson_distribution<_IntType, _RealType>::
707 operator()(_UniformRandomNumberGenerator& __urng)
709 #if _GLIBCXX_USE_C99_MATH_TR1
714 const _RealType __m = std::floor(_M_mean);
716 const _RealType __c1 = (_M_sm
717 * 1.2533141373155002512078826424055226L);
718 const _RealType __c2 = _M_c2b + __c1;
719 const _RealType __c3 = __c2 + 1;
720 const _RealType __c4 = __c3 + 1;
722 const _RealType __c5 = (__c4
723 + 1.0129030479320018583185514777512983L);
724 const _RealType __c = _M_cb + __c5;
725 const _RealType __cx = 2 * (2 * __m + _M_d);
727 normal_distribution<_RealType> __nd;
729 bool __keepgoing = true;
732 const _RealType __u = __c * __urng();
733 const _RealType __e = -std::log(__urng());
739 const _RealType __n = __nd(__urng);
740 const _RealType __y = -std::abs(__n) * _M_sm - 1;
741 __x = std::floor(__y);
742 __w = -__n * __n / 2;
746 else if (__u <= __c2)
748 const _RealType __n = __nd(__urng);
749 const _RealType __y = 1 + std::abs(__n) * _M_scx4;
750 __x = std::ceil(__y);
751 __w = __y * (2 - __y) * _M_2cx;
755 else if (__u <= __c3)
756 // XXX This case not in the book, nor in the Errata...
758 else if (__u <= __c4)
760 else if (__u <= __c5)
764 const _RealType __v = -std::log(__urng());
765 const _RealType __y = _M_d + __v * __cx / _M_d;
766 __x = std::ceil(__y);
767 __w = -_M_d * _M_2cx * (1 + __y / 2);
770 __keepgoing = (__w - __e - __x * _M_lm_thr
771 > _M_lfm - std::tr1::lgamma(__x + __m + 1));
773 } while (__keepgoing);
775 return _IntType(std::tr1::round(__x + __m));
781 _RealType __prod = 1.0;
788 while (__prod > _M_lm_thr);
794 template<typename _IntType, typename _RealType,
795 typename _CharT, typename _Traits>
796 std::basic_ostream<_CharT, _Traits>&
797 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
798 const poisson_distribution<_IntType, _RealType>& __x)
800 const std::ios_base::fmtflags __flags = __os.flags();
801 const _CharT __fill = __os.fill();
802 const std::streamsize __precision = __os.precision();
803 const _CharT __space = __os.widen(' ');
804 __os.flags(std::ios_base::scientific | std::ios_base::left);
806 __os.precision(_Max_digits10<_RealType>::__value);
808 __os << __x._M_large << __space << __x.mean()
809 << __space << __x._M_lm_thr;
810 #if _GLIBCXX_USE_C99_MATH_TR1
812 __os << __space << __x._M_lfm << __space << __x._M_sm
813 << __space << __x._M_d << __space << __x._M_scx4
814 << __space << __x._M_2cx << __space << __x._M_c2b
815 << __space << __x._M_cb;
820 __os.precision(__precision);
824 template<typename _IntType, typename _RealType,
825 typename _CharT, typename _Traits>
826 std::basic_istream<_CharT, _Traits>&
827 operator>>(std::basic_istream<_CharT, _Traits>& __is,
828 poisson_distribution<_IntType, _RealType>& __x)
830 const std::ios_base::fmtflags __flags = __is.flags();
831 __is.flags(std::ios_base::skipws);
833 __is >> __x._M_large >> __x._M_mean >> __x._M_lm_thr;
834 #if _GLIBCXX_USE_C99_MATH_TR1
836 __is >> __x._M_lfm >> __x._M_sm >> __x._M_d >> __x._M_scx4
837 >> __x._M_2cx >> __x._M_c2b >> __x._M_cb;
845 template<typename _RealType, typename _CharT, typename _Traits>
846 std::basic_ostream<_CharT, _Traits>&
847 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
848 const uniform_real<_RealType>& __x)
850 const std::ios_base::fmtflags __flags = __os.flags();
851 const _CharT __fill = __os.fill();
852 const std::streamsize __precision = __os.precision();
853 const _CharT __space = __os.widen(' ');
854 __os.flags(std::ios_base::scientific | std::ios_base::left);
856 __os.precision(_Max_digits10<_RealType>::__value);
858 __os << __x.min() << __space << __x.max();
862 __os.precision(__precision);
866 template<typename _RealType, typename _CharT, typename _Traits>
867 std::basic_istream<_CharT, _Traits>&
868 operator>>(std::basic_istream<_CharT, _Traits>& __is,
869 uniform_real<_RealType>& __x)
871 const std::ios_base::fmtflags __flags = __is.flags();
872 __is.flags(std::ios_base::skipws);
874 __is >> __x._M_min >> __x._M_max;
881 template<typename _RealType, typename _CharT, typename _Traits>
882 std::basic_ostream<_CharT, _Traits>&
883 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
884 const exponential_distribution<_RealType>& __x)
886 const std::ios_base::fmtflags __flags = __os.flags();
887 const _CharT __fill = __os.fill();
888 const std::streamsize __precision = __os.precision();
889 __os.flags(std::ios_base::scientific | std::ios_base::left);
890 __os.fill(__os.widen(' '));
891 __os.precision(_Max_digits10<_RealType>::__value);
893 __os << __x.lambda();
897 __os.precision(__precision);
903 * Classic Box-Muller method.
906 * Box, G. E. P. and Muller, M. E. "A Note on the Generation of
907 * Random Normal Deviates." Ann. Math. Stat. 29, 610-611, 1958.
909 template<typename _RealType>
910 template<class _UniformRandomNumberGenerator>
911 typename normal_distribution<_RealType>::result_type
912 normal_distribution<_RealType>::
913 operator()(_UniformRandomNumberGenerator& __urng)
917 if (_M_saved_available)
919 _M_saved_available = false;
924 result_type __x, __y, __r2;
927 __x = result_type(2.0) * __urng() - result_type(1.0);
928 __y = result_type(2.0) * __urng() - result_type(1.0);
929 __r2 = __x * __x + __y * __y;
931 while (__r2 > result_type(1.0) || __r2 == result_type(0));
933 const result_type __mult = std::sqrt(-result_type(2.0)
934 * std::log(__r2) / __r2);
935 _M_saved = __x * __mult;
936 _M_saved_available = true;
937 __ret = __y * __mult;
940 return __ret * _M_sigma + _M_mean;
943 template<typename _RealType, typename _CharT, typename _Traits>
944 std::basic_ostream<_CharT, _Traits>&
945 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
946 const normal_distribution<_RealType>& __x)
948 const std::ios_base::fmtflags __flags = __os.flags();
949 const _CharT __fill = __os.fill();
950 const std::streamsize __precision = __os.precision();
951 const _CharT __space = __os.widen(' ');
952 __os.flags(std::ios_base::scientific | std::ios_base::left);
954 __os.precision(_Max_digits10<_RealType>::__value);
956 __os << __x._M_saved_available << __space
957 << __x.mean() << __space
959 if (__x._M_saved_available)
960 __os << __space << __x._M_saved;
964 __os.precision(__precision);
968 template<typename _RealType, typename _CharT, typename _Traits>
969 std::basic_istream<_CharT, _Traits>&
970 operator>>(std::basic_istream<_CharT, _Traits>& __is,
971 normal_distribution<_RealType>& __x)
973 const std::ios_base::fmtflags __flags = __is.flags();
974 __is.flags(std::ios_base::dec | std::ios_base::skipws);
976 __is >> __x._M_saved_available >> __x._M_mean
978 if (__x._M_saved_available)
979 __is >> __x._M_saved;
987 * Cheng's rejection algorithm GB for alpha >= 1 and a modification
988 * of Vaduva's rejection from Weibull algorithm due to Devroye for
992 * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral
993 * Shape Parameter." Applied Statistics, 26, 71-75, 1977.
995 * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection
996 * and Composition Procedures." Math. Operationsforschung and Statistik,
997 * Series in Statistics, 8, 545-576, 1977.
999 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
1000 * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!).
1002 template<typename _RealType>
1003 template<class _UniformRandomNumberGenerator>
1004 typename gamma_distribution<_RealType>::result_type
1005 gamma_distribution<_RealType>::
1006 operator()(_UniformRandomNumberGenerator& __urng)
1013 const result_type __b = _M_alpha
1014 - result_type(1.3862943611198906188344642429163531L);
1015 const result_type __l = std::sqrt(2 * _M_alpha - 1);
1016 const result_type __c = _M_alpha + __l;
1017 const result_type __1l = 1 / __l;
1020 const result_type __k = 2.5040773967762740733732583523868748L;
1022 result_type __z, __r;
1025 const result_type __u = __urng();
1026 const result_type __v = __urng();
1028 const result_type __y = __1l * std::log(__v / (1 - __v));
1029 __x = _M_alpha * std::exp(__y);
1031 __z = __u * __v * __v;
1032 __r = __b + __c * __y - __x;
1034 while (__r < result_type(4.5) * __z - __k
1035 && __r < std::log(__z));
1039 const result_type __c = 1 / _M_alpha;
1040 const result_type __d =
1041 std::pow(_M_alpha, _M_alpha / (1 - _M_alpha)) * (1 - _M_alpha);
1043 result_type __z, __e;
1046 __z = -std::log(__urng());
1047 __e = -std::log(__urng());
1049 __x = std::pow(__z, __c);
1051 while (__z + __e < __d + __x);
1057 template<typename _RealType, typename _CharT, typename _Traits>
1058 std::basic_ostream<_CharT, _Traits>&
1059 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1060 const gamma_distribution<_RealType>& __x)
1062 const std::ios_base::fmtflags __flags = __os.flags();
1063 const _CharT __fill = __os.fill();
1064 const std::streamsize __precision = __os.precision();
1065 __os.flags(std::ios_base::scientific | std::ios_base::left);
1066 __os.fill(__os.widen(' '));
1067 __os.precision(_Max_digits10<_RealType>::__value);
1069 __os << __x.alpha();
1071 __os.flags(__flags);
1073 __os.precision(__precision);
1077 _GLIBCXX_END_NAMESPACE