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