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 } // namespace _Private
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 ((_Private::__mod<_UIntType, 1, 0, __m>(__c) == 0)
118 && (_Private::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
119 _M_x = _Private::__mod<_UIntType, 1, 0, __m>(1);
121 _M_x = _Private::__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 ((_Private::__mod<_UIntType, 1, 0, __m>(__c) == 0)
135 && (_Private::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
136 _M_x = _Private::__mod<_UIntType, 1, 0, __m>(1);
138 _M_x = _Private::__mod<_UIntType, 1, 0, __m>(__x0);
142 * Returns a value that is less than or equal to all values potentially
143 * returned by operator(). The return value of this function does not
144 * change during the lifetime of the object..
146 * The minumum depends on the @p __c parameter: if it is zero, the
147 * minimum generated must be > 0, otherwise 0 is allowed.
149 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
150 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
151 linear_congruential<_UIntType, __a, __c, __m>::
153 { return (_Private::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
156 * Gets the maximum possible value of the generated range.
158 * For a linear congruential generator, the maximum is always @p __m - 1.
160 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
161 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
162 linear_congruential<_UIntType, __a, __c, __m>::
164 { return (__m == 0) ? std::numeric_limits<_UIntType>::max() : (__m - 1); }
167 * Gets the next generated value in sequence.
169 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
170 typename linear_congruential<_UIntType, __a, __c, __m>::result_type
171 linear_congruential<_UIntType, __a, __c, __m>::
174 _M_x = _Private::__mod<_UIntType, __a, __c, __m>(_M_x);
178 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
179 typename _CharT, typename _Traits>
180 std::basic_ostream<_CharT, _Traits>&
181 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
182 const linear_congruential<_UIntType, __a, __c, __m>& __lcr)
184 const std::ios_base::fmtflags __flags = __os.flags();
185 const _CharT __fill = __os.fill();
186 __os.flags(std::ios_base::dec | std::ios_base::fixed
187 | std::ios_base::left);
188 __os.fill(__os.widen(' '));
197 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
198 typename _CharT, typename _Traits>
199 std::basic_istream<_CharT, _Traits>&
200 operator>>(std::basic_istream<_CharT, _Traits>& __is,
201 linear_congruential<_UIntType, __a, __c, __m>& __lcr)
203 const std::ios_base::fmtflags __flags = __is.flags();
204 __is.flags(std::ios_base::dec);
213 template<class _UIntType, int __w, int __n, int __m, int __r,
214 _UIntType __a, int __u, int __s,
215 _UIntType __b, int __t, _UIntType __c, int __l>
217 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
218 __b, __t, __c, __l>::
219 seed(unsigned long __value)
221 _M_x[0] = _Private::__mod<_UIntType, 1, 0,
222 _Private::_Shift<_UIntType, __w>::__value>(__value);
224 for (int __i = 1; __i < state_size; ++__i)
226 _UIntType __x = _M_x[__i - 1];
227 __x ^= __x >> (__w - 2);
230 _M_x[__i] = _Private::__mod<_UIntType, 1, 0,
231 _Private::_Shift<_UIntType, __w>::__value>(__x);
236 template<class _UIntType, int __w, int __n, int __m, int __r,
237 _UIntType __a, int __u, int __s,
238 _UIntType __b, int __t, _UIntType __c, int __l>
241 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
242 __b, __t, __c, __l>::
243 seed(_Gen& __gen, false_type)
245 for (int __i = 0; __i < state_size; ++__i)
246 _M_x[__i] = _Private::__mod<_UIntType, 1, 0,
247 _Private::_Shift<_UIntType, __w>::__value>(__gen());
251 template<class _UIntType, int __w, int __n, int __m, int __r,
252 _UIntType __a, int __u, int __s,
253 _UIntType __b, int __t, _UIntType __c, int __l>
255 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
256 __b, __t, __c, __l>::result_type
257 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
258 __b, __t, __c, __l>::
261 // Reload the vector - cost is O(n) amortized over n calls.
262 if (_M_p >= state_size)
264 const _UIntType __upper_mask = (~_UIntType()) << __r;
265 const _UIntType __lower_mask = ~__upper_mask;
267 for (int __k = 0; __k < (__n - __m); ++__k)
269 _UIntType __y = ((_M_x[__k] & __upper_mask)
270 | (_M_x[__k + 1] & __lower_mask));
271 _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
272 ^ ((__y & 0x01) ? __a : 0));
275 for (int __k = (__n - __m); __k < (__n - 1); ++__k)
277 _UIntType __y = ((_M_x[__k] & __upper_mask)
278 | (_M_x[__k + 1] & __lower_mask));
279 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
280 ^ ((__y & 0x01) ? __a : 0));
283 _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
284 | (_M_x[0] & __lower_mask));
285 _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
286 ^ ((__y & 0x01) ? __a : 0));
290 // Calculate o(x(i)).
291 result_type __z = _M_x[_M_p++];
293 __z ^= (__z << __s) & __b;
294 __z ^= (__z << __t) & __c;
300 template<class _UIntType, int __w, int __n, int __m, int __r,
301 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
302 _UIntType __c, int __l,
303 typename _CharT, typename _Traits>
304 std::basic_ostream<_CharT, _Traits>&
305 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
306 const mersenne_twister<_UIntType, __w, __n, __m,
307 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
309 const std::ios_base::fmtflags __flags = __os.flags();
310 const _CharT __fill = __os.fill();
311 const _CharT __space = __os.widen(' ');
312 __os.flags(std::ios_base::dec | std::ios_base::fixed
313 | std::ios_base::left);
316 for (int __i = 0; __i < __n - 1; ++__i)
317 __os << __x._M_x[__i] << __space;
318 __os << __x._M_x[__n - 1];
325 template<class _UIntType, int __w, int __n, int __m, int __r,
326 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
327 _UIntType __c, int __l,
328 typename _CharT, typename _Traits>
329 std::basic_istream<_CharT, _Traits>&
330 operator>>(std::basic_istream<_CharT, _Traits>& __is,
331 mersenne_twister<_UIntType, __w, __n, __m,
332 __r, __a, __u, __s, __b, __t, __c, __l>& __x)
334 const std::ios_base::fmtflags __flags = __is.flags();
335 __is.flags(std::ios_base::dec | std::ios_base::skipws);
337 for (int __i = 0; __i < __n; ++__i)
338 __is >> __x._M_x[__i];
345 template<typename _IntType, _IntType __m, int __s, int __r>
347 subtract_with_carry<_IntType, __m, __s, __r>::
348 seed(unsigned long __value)
350 std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563>
353 for (int __i = 0; __i < long_lag; ++__i)
354 _M_x[__i] = _Private::__mod<_IntType, 1, 0, modulus>(__lcg());
356 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
361 // This implementation differs from the tr1 spec because the tr1 spec refused
362 // to make any sense to me: the exponent of the factor in the spec goes from
363 // 1 to (n-1), but it would only make sense to me if it went from 0 to (n-1).
365 // This algorithm is still problematic because it can overflow left right and
368 template<typename _IntType, _IntType __m, int __s, int __r>
371 subtract_with_carry<_IntType, __m, __s, __r>::
372 seed(_Gen& __gen, false_type)
374 const int __n = (std::numeric_limits<_IntType>::digits + 31) / 32;
375 for (int __i = 0; __i < long_lag; ++__i)
378 unsigned long __factor = 1;
379 for (int __j = 0; __j < __n; ++__j)
381 _M_x[__i] += __gen() * __factor;
382 __factor *= 0x80000000;
384 _M_x[__i] = _Private::__mod<_IntType, 1, 0, modulus>(_M_x[__i]);
386 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
390 template<typename _IntType, _IntType __m, int __s, int __r>
391 typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
392 subtract_with_carry<_IntType, __m, __s, __r>::
395 // Derive short lag index from current index.
396 int __ps = _M_p - short_lag;
400 // Calculate new x(i) without overflow or division.
402 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
404 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
409 __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
414 // Adjust current index to loop around in ring buffer.
415 if (_M_p >= long_lag)
421 template<typename _IntType, _IntType __m, int __s, int __r,
422 typename _CharT, typename _Traits>
423 std::basic_ostream<_CharT, _Traits>&
424 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
425 const subtract_with_carry<_IntType, __m, __s, __r>& __x)
427 const std::ios_base::fmtflags __flags = __os.flags();
428 const _CharT __fill = __os.fill();
429 const _CharT __space = __os.widen(' ');
430 __os.flags(std::ios_base::dec | std::ios_base::fixed
431 | std::ios_base::left);
434 for (int __i = 0; __i < __r; ++__i)
435 __os << __x._M_x[__i] << __space;
436 __os << __x._M_carry;
443 template<typename _IntType, _IntType __m, int __s, int __r,
444 typename _CharT, typename _Traits>
445 std::basic_istream<_CharT, _Traits>&
446 operator>>(std::basic_istream<_CharT, _Traits>& __is,
447 subtract_with_carry<_IntType, __m, __s, __r>& __x)
449 const std::ios_base::fmtflags __flags = __is.flags();
450 __is.flags(std::ios_base::dec | std::ios_base::skipws);
452 for (int __i = 0; __i < __r; ++__i)
453 __is >> __x._M_x[__i];
454 __is >> __x._M_carry;
461 template<class _UniformRandomNumberGenerator, int __p, int __r>
462 typename discard_block<_UniformRandomNumberGenerator,
463 __p, __r>::result_type
464 discard_block<_UniformRandomNumberGenerator, __p, __r>::
467 if (_M_n >= used_block)
469 while (_M_n < block_size)
480 template<class _UniformRandomNumberGenerator, int __p, int __r,
481 typename _CharT, typename _Traits>
482 std::basic_ostream<_CharT, _Traits>&
483 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
484 const discard_block<_UniformRandomNumberGenerator,
487 const std::ios_base::fmtflags __flags = __os.flags();
488 const _CharT __fill = __os.fill();
489 const _CharT __space = __os.widen(' ');
490 __os.flags(std::ios_base::dec | std::ios_base::fixed
491 | std::ios_base::left);
494 __os << __x._M_b << __space << __x._M_n;
501 template<class _UniformRandomNumberGenerator, int __p, int __r,
502 typename _CharT, typename _Traits>
503 std::basic_istream<_CharT, _Traits>&
504 operator>>(std::basic_istream<_CharT, _Traits>& __is,
505 discard_block<_UniformRandomNumberGenerator, __p, __r>& __x)
507 const std::ios_base::fmtflags __flags = __is.flags();
508 __is.flags(std::ios_base::dec | std::ios_base::skipws);
510 __is >> __x._M_b >> __x._M_n;
517 template<class _UniformRandomNumberGenerator1, int __s1,
518 class _UniformRandomNumberGenerator2, int __s2,
519 typename _CharT, typename _Traits>
520 std::basic_ostream<_CharT, _Traits>&
521 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
522 const xor_combine<_UniformRandomNumberGenerator1, __s1,
523 _UniformRandomNumberGenerator2, __s2>& __x)
525 const std::ios_base::fmtflags __flags = __os.flags();
526 const _CharT __fill = __os.fill();
527 const _CharT __space = __os.widen(' ');
528 __os.flags(std::ios_base::dec | std::ios_base::fixed
529 | std::ios_base::left);
532 __os << __x.base1() << __space << __x.base2();
539 template<class _UniformRandomNumberGenerator1, int __s1,
540 class _UniformRandomNumberGenerator2, int __s2,
541 typename _CharT, typename _Traits>
542 std::basic_istream<_CharT, _Traits>&
543 operator>>(std::basic_istream<_CharT, _Traits>& __is,
544 xor_combine<_UniformRandomNumberGenerator1, __s1,
545 _UniformRandomNumberGenerator2, __s2>& __x)
547 const std::ios_base::fmtflags __flags = __is.flags();
548 __is.flags(std::ios_base::skipws);
550 __is >> __x._M_b1 >> __x._M_b2;
557 template<typename _IntType, typename _CharT, typename _Traits>
558 std::basic_ostream<_CharT, _Traits>&
559 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
560 const uniform_int<_IntType>& __x)
562 const std::ios_base::fmtflags __flags = __os.flags();
563 const _CharT __fill = __os.fill();
564 const _CharT __space = __os.widen(' ');
565 __os.flags(std::ios_base::scientific | std::ios_base::left);
568 __os << __x.min() << __space << __x.max();
575 template<typename _IntType, typename _CharT, typename _Traits>
576 std::basic_istream<_CharT, _Traits>&
577 operator>>(std::basic_istream<_CharT, _Traits>& __is,
578 uniform_int<_IntType>& __x)
580 const std::ios_base::fmtflags __flags = __is.flags();
581 __is.flags(std::ios_base::dec | std::ios_base::skipws);
583 __is >> __x._M_min >> __x._M_max;
590 template<typename _CharT, typename _Traits>
591 std::basic_ostream<_CharT, _Traits>&
592 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
593 const bernoulli_distribution& __x)
595 const std::ios_base::fmtflags __flags = __os.flags();
596 const _CharT __fill = __os.fill();
597 const std::streamsize __precision = __os.precision();
598 __os.flags(std::ios_base::scientific | std::ios_base::left);
599 __os.fill(__os.widen(' '));
600 __os.precision(_Private::_Max_digits10<double>::__value);
606 __os.precision(__precision);
611 template<typename _IntType, typename _RealType,
612 typename _CharT, typename _Traits>
613 std::basic_ostream<_CharT, _Traits>&
614 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
615 const geometric_distribution<_IntType, _RealType>& __x)
617 const std::ios_base::fmtflags __flags = __os.flags();
618 const _CharT __fill = __os.fill();
619 const std::streamsize __precision = __os.precision();
620 __os.flags(std::ios_base::scientific | std::ios_base::left);
621 __os.fill(__os.widen(' '));
622 __os.precision(_Private::_Max_digits10<_RealType>::__value);
628 __os.precision(__precision);
633 template<typename _RealType, typename _CharT, typename _Traits>
634 std::basic_ostream<_CharT, _Traits>&
635 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
636 const uniform_real<_RealType>& __x)
638 const std::ios_base::fmtflags __flags = __os.flags();
639 const _CharT __fill = __os.fill();
640 const std::streamsize __precision = __os.precision();
641 const _CharT __space = __os.widen(' ');
642 __os.flags(std::ios_base::scientific | std::ios_base::left);
644 __os.precision(_Private::_Max_digits10<_RealType>::__value);
646 __os << __x.min() << __space << __x.max();
650 __os.precision(__precision);
654 template<typename _RealType, typename _CharT, typename _Traits>
655 std::basic_istream<_CharT, _Traits>&
656 operator>>(std::basic_istream<_CharT, _Traits>& __is,
657 uniform_real<_RealType>& __x)
659 const std::ios_base::fmtflags __flags = __is.flags();
660 __is.flags(std::ios_base::skipws);
662 __is >> __x._M_min >> __x._M_max;
669 template<typename _RealType, typename _CharT, typename _Traits>
670 std::basic_ostream<_CharT, _Traits>&
671 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
672 const exponential_distribution<_RealType>& __x)
674 const std::ios_base::fmtflags __flags = __os.flags();
675 const _CharT __fill = __os.fill();
676 const std::streamsize __precision = __os.precision();
677 __os.flags(std::ios_base::scientific | std::ios_base::left);
678 __os.fill(__os.widen(' '));
679 __os.precision(_Private::_Max_digits10<_RealType>::__value);
681 __os << __x.lambda();
685 __os.precision(__precision);
691 * Classic Box-Muller method.
694 * Box, G. E. P. and Muller, M. E. "A Note on the Generation of
695 * Random Normal Deviates." Ann. Math. Stat. 29, 610-611, 1958.
697 template<typename _RealType>
698 template<class _UniformRandomNumberGenerator>
699 typename normal_distribution<_RealType>::result_type
700 normal_distribution<_RealType>::
701 operator()(_UniformRandomNumberGenerator& __urng)
705 if (_M_saved_available)
707 _M_saved_available = false;
712 result_type __x, __y, __r2;
715 __x = result_type(2.0) * __urng() - result_type(1.0);
716 __y = result_type(2.0) * __urng() - result_type(1.0);
717 __r2 = __x * __x + __y * __y;
719 while (__r2 > result_type(1.0) || __r2 == result_type(0));
721 const result_type __mult = std::sqrt(-result_type(2.0)
722 * std::log(__r2) / __r2);
723 _M_saved = __x * __mult;
724 _M_saved_available = true;
725 __ret = __y * __mult;
728 return __ret * _M_sigma + _M_mean;
731 template<typename _RealType, typename _CharT, typename _Traits>
732 std::basic_ostream<_CharT, _Traits>&
733 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
734 const normal_distribution<_RealType>& __x)
736 const std::ios_base::fmtflags __flags = __os.flags();
737 const _CharT __fill = __os.fill();
738 const std::streamsize __precision = __os.precision();
739 const _CharT __space = __os.widen(' ');
740 __os.flags(std::ios_base::scientific | std::ios_base::left);
742 __os.precision(_Private::_Max_digits10<_RealType>::__value);
744 __os << __x.mean() << __space
745 << __x.sigma() << __space
746 << __x._M_saved << __space
747 << __x._M_saved_available;
751 __os.precision(__precision);
755 template<typename _RealType, typename _CharT, typename _Traits>
756 std::basic_istream<_CharT, _Traits>&
757 operator>>(std::basic_istream<_CharT, _Traits>& __is,
758 normal_distribution<_RealType>& __x)
760 const std::ios_base::fmtflags __flags = __is.flags();
761 __is.flags(std::ios_base::dec | std::ios_base::skipws);
763 __is >> __x._M_mean >> __x._M_sigma
764 >> __x._M_saved >> __x._M_saved_available;
770 _GLIBCXX_END_NAMESPACE