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