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