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