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