# random.tcc

Go to the documentation of this file.

    00001 // random number generation (out of line) -*- C++ -*-
    00002
    00003 // Copyright (C) 2007 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 2, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file tr1_impl/random.tcc
    00031  *  This is an internal header file, included by other library headers.
    00032  *  You should not attempt to use it directly.
    00033  */
    00034
    00035 namespace std
    00036 {
    00037 _GLIBCXX_BEGIN_NAMESPACE_TR1
    00038
    00039   /*
    00040    * (Further) implementation-space details.
    00041    */
    00042   namespace __detail
    00043   {
    00044     // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid
    00045     // integer overflow.
    00046     //
    00047     // Because a and c are compile-time integral constants the compiler kindly
    00048     // elides any unreachable paths.
    00049     //
    00050     // Preconditions:  a > 0, m > 0.
    00051     //
    00052     template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
    00053       struct _Mod
    00054       {
    00055     static _Tp
    00056     __calc(_Tp __x)
    00057     {
    00058       if (__a == 1)
    00059         __x %= __m;
    00060       else
    00061         {
    00062           static const _Tp __q = __m / __a;
    00063           static const _Tp __r = __m % __a;
    00064
    00065           _Tp __t1 = __a * (__x % __q);
    00066           _Tp __t2 = __r * (__x / __q);
    00067           if (__t1 >= __t2)
    00068         __x = __t1 - __t2;
    00069           else
    00070         __x = __m - __t2 + __t1;
    00071         }
    00072
    00073       if (__c != 0)
    00074         {
    00075           const _Tp __d = __m - __x;
    00076           if (__d > __c)
    00077         __x += __c;
    00078           else
    00079         __x = __c - __d;
    00080         }
    00081       return __x;
    00082     }
    00083       };
    00084
    00085     // Special case for m == 0 -- use unsigned integer overflow as modulo
    00086     // operator.
    00087     template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
    00088       struct _Mod<_Tp, __a, __c, __m, true>
    00089       {
    00090     static _Tp
    00091     __calc(_Tp __x)
    00092     { return __a * __x + __c; }
    00093       };
    00094   } // namespace __detail
    00095
    00096   /**
    00097    * Seeds the LCR with integral value @p __x0, adjusted so that the
    00098    * ring identity is never a member of the convergence set.
    00099    */
    00100   template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    00101     void
    00102     linear_congruential<_UIntType, __a, __c, __m>::
    00103     seed(unsigned long __x0)
    00104     {
    00105       if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
    00106       && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
    00107     _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
    00108       else
    00109     _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
    00110     }
    00111
    00112   /**
    00113    * Seeds the LCR engine with a value generated by @p __g.
    00114    */
    00115   template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    00116     template<class _Gen>
    00117       void
    00118       linear_congruential<_UIntType, __a, __c, __m>::
    00119       seed(_Gen& __g, false_type)
    00120       {
    00121     _UIntType __x0 = __g();
    00122     if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
    00123         && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
    00124       _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
    00125     else
    00126       _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
    00127       }
    00128
    00129   /**
    00130    * Gets the next generated value in sequence.
    00131    */
    00132   template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    00133     typename linear_congruential<_UIntType, __a, __c, __m>::result_type
    00134     linear_congruential<_UIntType, __a, __c, __m>::
    00135     operator()()
    00136     {
    00137       _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x);
    00138       return _M_x;
    00139     }
    00140
    00141   template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
    00142        typename _CharT, typename _Traits>
    00143     std::basic_ostream<_CharT, _Traits>&
    00144     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00145            const linear_congruential<_UIntType, __a, __c, __m>& __lcr)
    00146     {
    00147       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00148       typedef typename __ostream_type::ios_base    __ios_base;
    00149
    00150       const typename __ios_base::fmtflags __flags = __os.flags();
    00151       const _CharT __fill = __os.fill();
    00152       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
    00153       __os.fill(__os.widen(' '));
    00154
    00155       __os << __lcr._M_x;
    00156
    00157       __os.flags(__flags);
    00158       __os.fill(__fill);
    00159       return __os;
    00160     }
    00161
    00162   template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
    00163        typename _CharT, typename _Traits>
    00164     std::basic_istream<_CharT, _Traits>&
    00165     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00166            linear_congruential<_UIntType, __a, __c, __m>& __lcr)
    00167     {
    00168       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    00169       typedef typename __istream_type::ios_base    __ios_base;
    00170
    00171       const typename __ios_base::fmtflags __flags = __is.flags();
    00172       __is.flags(__ios_base::dec);
    00173
    00174       __is >> __lcr._M_x;
    00175
    00176       __is.flags(__flags);
    00177       return __is;
    00178     }
    00179
    00180
    00181   template<class _UIntType, int __w, int __n, int __m, int __r,
    00182        _UIntType __a, int __u, int __s,
    00183        _UIntType __b, int __t, _UIntType __c, int __l>
    00184     void
    00185     mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
    00186              __b, __t, __c, __l>::
    00187     seed(unsigned long __value)
    00188     {
    00189       _M_x[0] = __detail::__mod<_UIntType, 1, 0,
    00190     __detail::_Shift<_UIntType, __w>::__value>(__value);
    00191
    00192       for (int __i = 1; __i < state_size; ++__i)
    00193     {
    00194       _UIntType __x = _M_x[__i - 1];
    00195       __x ^= __x >> (__w - 2);
    00196       __x *= 1812433253ul;
    00197       __x += __i;
    00198       _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
    00199         __detail::_Shift<_UIntType, __w>::__value>(__x);
    00200     }
    00201       _M_p = state_size;
    00202     }
    00203
    00204   template<class _UIntType, int __w, int __n, int __m, int __r,
    00205        _UIntType __a, int __u, int __s,
    00206        _UIntType __b, int __t, _UIntType __c, int __l>
    00207     template<class _Gen>
    00208       void
    00209       mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
    00210                __b, __t, __c, __l>::
    00211       seed(_Gen& __gen, false_type)
    00212       {
    00213     for (int __i = 0; __i < state_size; ++__i)
    00214       _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
    00215         __detail::_Shift<_UIntType, __w>::__value>(__gen());
    00216     _M_p = state_size;
    00217       }
    00218
    00219   template<class _UIntType, int __w, int __n, int __m, int __r,
    00220        _UIntType __a, int __u, int __s,
    00221        _UIntType __b, int __t, _UIntType __c, int __l>
    00222     typename
    00223     mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
    00224              __b, __t, __c, __l>::result_type
    00225     mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
    00226              __b, __t, __c, __l>::
    00227     operator()()
    00228     {
    00229       // Reload the vector - cost is O(n) amortized over n calls.
    00230       if (_M_p >= state_size)
    00231     {
    00232       const _UIntType __upper_mask = (~_UIntType()) << __r;
    00233       const _UIntType __lower_mask = ~__upper_mask;
    00234
    00235       for (int __k = 0; __k < (__n - __m); ++__k)
    00236         {
    00237           _UIntType __y = ((_M_x[__k] & __upper_mask)
    00238                    | (_M_x[__k + 1] & __lower_mask));
    00239           _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
    00240                ^ ((__y & 0x01) ? __a : 0));
    00241         }
    00242
    00243       for (int __k = (__n - __m); __k < (__n - 1); ++__k)
    00244         {
    00245           _UIntType __y = ((_M_x[__k] & __upper_mask)
    00246                    | (_M_x[__k + 1] & __lower_mask));
    00247           _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
    00248                ^ ((__y & 0x01) ? __a : 0));
    00249         }
    00250
    00251       _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
    00252                | (_M_x[0] & __lower_mask));
    00253       _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
    00254                ^ ((__y & 0x01) ? __a : 0));
    00255       _M_p = 0;
    00256     }
    00257
    00258       // Calculate o(x(i)).
    00259       result_type __z = _M_x[_M_p++];
    00260       __z ^= (__z >> __u);
    00261       __z ^= (__z << __s) & __b;
    00262       __z ^= (__z << __t) & __c;
    00263       __z ^= (__z >> __l);
    00264
    00265       return __z;
    00266     }
    00267
    00268   template<class _UIntType, int __w, int __n, int __m, int __r,
    00269        _UIntType __a, int __u, int __s, _UIntType __b, int __t,
    00270        _UIntType __c, int __l,
    00271        typename _CharT, typename _Traits>
    00272     std::basic_ostream<_CharT, _Traits>&
    00273     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00274            const mersenne_twister<_UIntType, __w, __n, __m,
    00275            __r, __a, __u, __s, __b, __t, __c, __l>& __x)
    00276     {
    00277       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00278       typedef typename __ostream_type::ios_base    __ios_base;
    00279
    00280       const typename __ios_base::fmtflags __flags = __os.flags();
    00281       const _CharT __fill = __os.fill();
    00282       const _CharT __space = __os.widen(' ');
    00283       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
    00284       __os.fill(__space);
    00285
    00286       for (int __i = 0; __i < __n - 1; ++__i)
    00287     __os << __x._M_x[__i] << __space;
    00288       __os << __x._M_x[__n - 1];
    00289
    00290       __os.flags(__flags);
    00291       __os.fill(__fill);
    00292       return __os;
    00293     }
    00294
    00295   template<class _UIntType, int __w, int __n, int __m, int __r,
    00296        _UIntType __a, int __u, int __s, _UIntType __b, int __t,
    00297        _UIntType __c, int __l,
    00298        typename _CharT, typename _Traits>
    00299     std::basic_istream<_CharT, _Traits>&
    00300     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00301            mersenne_twister<_UIntType, __w, __n, __m,
    00302            __r, __a, __u, __s, __b, __t, __c, __l>& __x)
    00303     {
    00304       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    00305       typedef typename __istream_type::ios_base    __ios_base;
    00306
    00307       const typename __ios_base::fmtflags __flags = __is.flags();
    00308       __is.flags(__ios_base::dec | __ios_base::skipws);
    00309
    00310       for (int __i = 0; __i < __n; ++__i)
    00311     __is >> __x._M_x[__i];
    00312
    00313       __is.flags(__flags);
    00314       return __is;
    00315     }
    00316
    00317
    00318   template<typename _IntType, _IntType __m, int __s, int __r>
    00319     void
    00320     subtract_with_carry<_IntType, __m, __s, __r>::
    00321     seed(unsigned long __value)
    00322     {
    00323       if (__value == 0)
    00324     __value = 19780503;
    00325
    00326       std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563>
    00327     __lcg(__value);
    00328
    00329       for (int __i = 0; __i < long_lag; ++__i)
    00330     _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg());
    00331
    00332       _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
    00333       _M_p = 0;
    00334     }
    00335
    00336   template<typename _IntType, _IntType __m, int __s, int __r>
    00337     template<class _Gen>
    00338       void
    00339       subtract_with_carry<_IntType, __m, __s, __r>::
    00340       seed(_Gen& __gen, false_type)
    00341       {
    00342     const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32;
    00343
    00344     for (int __i = 0; __i < long_lag; ++__i)
    00345       {
    00346         _UIntType __tmp = 0;
    00347         _UIntType __factor = 1;
    00348         for (int __j = 0; __j < __n; ++__j)
    00349           {
    00350         __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0>
    00351                  (__gen()) * __factor;
    00352         __factor *= __detail::_Shift<_UIntType, 32>::__value;
    00353           }
    00354         _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp);
    00355       }
    00356     _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
    00357     _M_p = 0;
    00358       }
    00359
    00360   template<typename _IntType, _IntType __m, int __s, int __r>
    00361     typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
    00362     subtract_with_carry<_IntType, __m, __s, __r>::
    00363     operator()()
    00364     {
    00365       // Derive short lag index from current index.
    00366       int __ps = _M_p - short_lag;
    00367       if (__ps < 0)
    00368     __ps += long_lag;
    00369
    00370       // Calculate new x(i) without overflow or division.
    00371       // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry
    00372       // cannot overflow.
    00373       _UIntType __xi;
    00374       if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
    00375     {
    00376       __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
    00377       _M_carry = 0;
    00378     }
    00379       else
    00380     {
    00381       __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
    00382       _M_carry = 1;
    00383     }
    00384       _M_x[_M_p] = __xi;
    00385
    00386       // Adjust current index to loop around in ring buffer.
    00387       if (++_M_p >= long_lag)
    00388     _M_p = 0;
    00389
    00390       return __xi;
    00391     }
    00392
    00393   template<typename _IntType, _IntType __m, int __s, int __r,
    00394        typename _CharT, typename _Traits>
    00395     std::basic_ostream<_CharT, _Traits>&
    00396     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00397            const subtract_with_carry<_IntType, __m, __s, __r>& __x)
    00398     {
    00399       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00400       typedef typename __ostream_type::ios_base    __ios_base;
    00401
    00402       const typename __ios_base::fmtflags __flags = __os.flags();
    00403       const _CharT __fill = __os.fill();
    00404       const _CharT __space = __os.widen(' ');
    00405       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
    00406       __os.fill(__space);
    00407
    00408       for (int __i = 0; __i < __r; ++__i)
    00409     __os << __x._M_x[__i] << __space;
    00410       __os << __x._M_carry;
    00411
    00412       __os.flags(__flags);
    00413       __os.fill(__fill);
    00414       return __os;
    00415     }
    00416
    00417   template<typename _IntType, _IntType __m, int __s, int __r,
    00418        typename _CharT, typename _Traits>
    00419     std::basic_istream<_CharT, _Traits>&
    00420     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00421            subtract_with_carry<_IntType, __m, __s, __r>& __x)
    00422     {
    00423       typedef std::basic_ostream<_CharT, _Traits>  __istream_type;
    00424       typedef typename __istream_type::ios_base    __ios_base;
    00425
    00426       const typename __ios_base::fmtflags __flags = __is.flags();
    00427       __is.flags(__ios_base::dec | __ios_base::skipws);
    00428
    00429       for (int __i = 0; __i < __r; ++__i)
    00430     __is >> __x._M_x[__i];
    00431       __is >> __x._M_carry;
    00432
    00433       __is.flags(__flags);
    00434       return __is;
    00435     }
    00436
    00437
    00438   template<typename _RealType, int __w, int __s, int __r>
    00439     void
    00440     subtract_with_carry_01<_RealType, __w, __s, __r>::
    00441     _M_initialize_npows()
    00442     {
    00443       for (int __j = 0; __j < __n; ++__j)
    00444 #if _GLIBCXX_USE_C99_MATH_TR1
    00445     _M_npows[__j] = std::_GLIBCXX_TR1 ldexp(_RealType(1), -__w + __j * 32);
    00446 #else
    00447         _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32);
    00448 #endif
    00449     }
    00450
    00451   template<typename _RealType, int __w, int __s, int __r>
    00452     void
    00453     subtract_with_carry_01<_RealType, __w, __s, __r>::
    00454     seed(unsigned long __value)
    00455     {
    00456       if (__value == 0)
    00457     __value = 19780503;
    00458
    00459       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00460       // 512. Seeding subtract_with_carry_01 from a single unsigned long.
    00461       std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563>
    00462     __lcg(__value);
    00463
    00464       this->seed(__lcg);
    00465     }
    00466
    00467   template<typename _RealType, int __w, int __s, int __r>
    00468     template<class _Gen>
    00469       void
    00470       subtract_with_carry_01<_RealType, __w, __s, __r>::
    00471       seed(_Gen& __gen, false_type)
    00472       {
    00473     for (int __i = 0; __i < long_lag; ++__i)
    00474       {
    00475         for (int __j = 0; __j < __n - 1; ++__j)
    00476           _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen());
    00477         _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
    00478           __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen());
    00479       }
    00480
    00481     _M_carry = 1;
    00482     for (int __j = 0; __j < __n; ++__j)
    00483       if (_M_x[long_lag - 1][__j] != 0)
    00484         {
    00485           _M_carry = 0;
    00486           break;
    00487         }
    00488
    00489     _M_p = 0;
    00490       }
    00491
    00492   template<typename _RealType, int __w, int __s, int __r>
    00493     typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type
    00494     subtract_with_carry_01<_RealType, __w, __s, __r>::
    00495     operator()()
    00496     {
    00497       // Derive short lag index from current index.
    00498       int __ps = _M_p - short_lag;
    00499       if (__ps < 0)
    00500     __ps += long_lag;
    00501
    00502       _UInt32Type __new_carry;
    00503       for (int __j = 0; __j < __n - 1; ++__j)
    00504     {
    00505       if (_M_x[__ps][__j] > _M_x[_M_p][__j]
    00506           || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0))
    00507         __new_carry = 0;
    00508       else
    00509         __new_carry = 1;
    00510
    00511       _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry;
    00512       _M_carry = __new_carry;
    00513     }
    00514
    00515       if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1]
    00516       || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0))
    00517     __new_carry = 0;
    00518       else
    00519     __new_carry = 1;
    00520
    00521       _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
    00522     __detail::_Shift<_UInt32Type, __w % 32>::__value>
    00523     (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry);
    00524       _M_carry = __new_carry;
    00525
    00526       result_type __ret = 0.0;
    00527       for (int __j = 0; __j < __n; ++__j)
    00528     __ret += _M_x[_M_p][__j] * _M_npows[__j];
    00529
    00530       // Adjust current index to loop around in ring buffer.
    00531       if (++_M_p >= long_lag)
    00532     _M_p = 0;
    00533
    00534       return __ret;
    00535     }
    00536
    00537   template<typename _RealType, int __w, int __s, int __r,
    00538        typename _CharT, typename _Traits>
    00539     std::basic_ostream<_CharT, _Traits>&
    00540     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00541            const subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
    00542     {
    00543       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00544       typedef typename __ostream_type::ios_base    __ios_base;
    00545
    00546       const typename __ios_base::fmtflags __flags = __os.flags();
    00547       const _CharT __fill = __os.fill();
    00548       const _CharT __space = __os.widen(' ');
    00549       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
    00550       __os.fill(__space);
    00551
    00552       for (int __i = 0; __i < __r; ++__i)
    00553     for (int __j = 0; __j < __x.__n; ++__j)
    00554       __os << __x._M_x[__i][__j] << __space;
    00555       __os << __x._M_carry;
    00556
    00557       __os.flags(__flags);
    00558       __os.fill(__fill);
    00559       return __os;
    00560     }
    00561
    00562   template<typename _RealType, int __w, int __s, int __r,
    00563        typename _CharT, typename _Traits>
    00564     std::basic_istream<_CharT, _Traits>&
    00565     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00566            subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
    00567     {
    00568       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    00569       typedef typename __istream_type::ios_base    __ios_base;
    00570
    00571       const typename __ios_base::fmtflags __flags = __is.flags();
    00572       __is.flags(__ios_base::dec | __ios_base::skipws);
    00573
    00574       for (int __i = 0; __i < __r; ++__i)
    00575     for (int __j = 0; __j < __x.__n; ++__j)
    00576       __is >> __x._M_x[__i][__j];
    00577       __is >> __x._M_carry;
    00578
    00579       __is.flags(__flags);
    00580       return __is;
    00581     }
    00582
    00583
    00584   template<class _UniformRandomNumberGenerator, int __p, int __r>
    00585     typename discard_block<_UniformRandomNumberGenerator,
    00586                __p, __r>::result_type
    00587     discard_block<_UniformRandomNumberGenerator, __p, __r>::
    00588     operator()()
    00589     {
    00590       if (_M_n >= used_block)
    00591     {
    00592       while (_M_n < block_size)
    00593         {
    00594           _M_b();
    00595           ++_M_n;
    00596         }
    00597       _M_n = 0;
    00598     }
    00599       ++_M_n;
    00600       return _M_b();
    00601     }
    00602
    00603   template<class _UniformRandomNumberGenerator, int __p, int __r,
    00604        typename _CharT, typename _Traits>
    00605     std::basic_ostream<_CharT, _Traits>&
    00606     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00607            const discard_block<_UniformRandomNumberGenerator,
    00608            __p, __r>& __x)
    00609     {
    00610       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00611       typedef typename __ostream_type::ios_base    __ios_base;
    00612
    00613       const typename __ios_base::fmtflags __flags = __os.flags();
    00614       const _CharT __fill = __os.fill();
    00615       const _CharT __space = __os.widen(' ');
    00616       __os.flags(__ios_base::dec | __ios_base::fixed
    00617          | __ios_base::left);
    00618       __os.fill(__space);
    00619
    00620       __os << __x._M_b << __space << __x._M_n;
    00621
    00622       __os.flags(__flags);
    00623       __os.fill(__fill);
    00624       return __os;
    00625     }
    00626
    00627   template<class _UniformRandomNumberGenerator, int __p, int __r,
    00628        typename _CharT, typename _Traits>
    00629     std::basic_istream<_CharT, _Traits>&
    00630     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00631            discard_block<_UniformRandomNumberGenerator, __p, __r>& __x)
    00632     {
    00633       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    00634       typedef typename __istream_type::ios_base    __ios_base;
    00635
    00636       const typename __ios_base::fmtflags __flags = __is.flags();
    00637       __is.flags(__ios_base::dec | __ios_base::skipws);
    00638
    00639       __is >> __x._M_b >> __x._M_n;
    00640
    00641       __is.flags(__flags);
    00642       return __is;
    00643     }
    00644
    00645
    00646   template<class _UniformRandomNumberGenerator1, int __s1,
    00647        class _UniformRandomNumberGenerator2, int __s2>
    00648     void
    00649     xor_combine<_UniformRandomNumberGenerator1, __s1,
    00650         _UniformRandomNumberGenerator2, __s2>::
    00651     _M_initialize_max()
    00652     {
    00653       const int __w = std::numeric_limits<result_type>::digits;
    00654
    00655       const result_type __m1 =
    00656     std::min(result_type(_M_b1.max() - _M_b1.min()),
    00657          __detail::_Shift<result_type, __w - __s1>::__value - 1);
    00658
    00659       const result_type __m2 =
    00660     std::min(result_type(_M_b2.max() - _M_b2.min()),
    00661          __detail::_Shift<result_type, __w - __s2>::__value - 1);
    00662
    00663       // NB: In TR1 s1 is not required to be >= s2.
    00664       if (__s1 < __s2)
    00665     _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1;
    00666       else
    00667     _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2;
    00668     }
    00669
    00670   template<class _UniformRandomNumberGenerator1, int __s1,
    00671        class _UniformRandomNumberGenerator2, int __s2>
    00672     typename xor_combine<_UniformRandomNumberGenerator1, __s1,
    00673              _UniformRandomNumberGenerator2, __s2>::result_type
    00674     xor_combine<_UniformRandomNumberGenerator1, __s1,
    00675         _UniformRandomNumberGenerator2, __s2>::
    00676     _M_initialize_max_aux(result_type __a, result_type __b, int __d)
    00677     {
    00678       const result_type __two2d = result_type(1) << __d;
    00679       const result_type __c = __a * __two2d;
    00680
    00681       if (__a == 0 || __b < __two2d)
    00682     return __c + __b;
    00683
    00684       const result_type __t = std::max(__c, __b);
    00685       const result_type __u = std::min(__c, __b);
    00686
    00687       result_type __ub = __u;
    00688       result_type __p;
    00689       for (__p = 0; __ub != 1; __ub >>= 1)
    00690     ++__p;
    00691
    00692       const result_type __two2p = result_type(1) << __p;
    00693       const result_type __k = __t / __two2p;
    00694
    00695       if (__k & 1)
    00696     return (__k + 1) * __two2p - 1;
    00697
    00698       if (__c >= __b)
    00699     return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p)
    00700                                / __two2d,
    00701                                __u % __two2p, __d);
    00702       else
    00703     return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p)
    00704                                / __two2d,
    00705                                __t % __two2p, __d);
    00706     }
    00707
    00708   template<class _UniformRandomNumberGenerator1, int __s1,
    00709        class _UniformRandomNumberGenerator2, int __s2,
    00710        typename _CharT, typename _Traits>
    00711     std::basic_ostream<_CharT, _Traits>&
    00712     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00713            const xor_combine<_UniformRandomNumberGenerator1, __s1,
    00714            _UniformRandomNumberGenerator2, __s2>& __x)
    00715     {
    00716       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00717       typedef typename __ostream_type::ios_base    __ios_base;
    00718
    00719       const typename __ios_base::fmtflags __flags = __os.flags();
    00720       const _CharT __fill = __os.fill();
    00721       const _CharT __space = __os.widen(' ');
    00722       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
    00723       __os.fill(__space);
    00724
    00725       __os << __x.base1() << __space << __x.base2();
    00726
    00727       __os.flags(__flags);
    00728       __os.fill(__fill);
    00729       return __os;
    00730     }
    00731
    00732   template<class _UniformRandomNumberGenerator1, int __s1,
    00733        class _UniformRandomNumberGenerator2, int __s2,
    00734        typename _CharT, typename _Traits>
    00735     std::basic_istream<_CharT, _Traits>&
    00736     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00737            xor_combine<_UniformRandomNumberGenerator1, __s1,
    00738            _UniformRandomNumberGenerator2, __s2>& __x)
    00739     {
    00740       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    00741       typedef typename __istream_type::ios_base    __ios_base;
    00742
    00743       const typename __ios_base::fmtflags __flags = __is.flags();
    00744       __is.flags(__ios_base::skipws);
    00745
    00746       __is >> __x._M_b1 >> __x._M_b2;
    00747
    00748       __is.flags(__flags);
    00749       return __is;
    00750     }
    00751
    00752
    00753   template<typename _IntType>
    00754     template<typename _UniformRandomNumberGenerator>
    00755       typename uniform_int<_IntType>::result_type
    00756       uniform_int<_IntType>::
    00757       _M_call(_UniformRandomNumberGenerator& __urng,
    00758           result_type __min, result_type __max, true_type)
    00759       {
    00760     // XXX Must be fixed to work well for *arbitrary* __urng.max(),
    00761     // __urng.min(), __max, __min.  Currently works fine only in the
    00762     // most common case __urng.max() - __urng.min() >= __max - __min,
    00763     // with __urng.max() > __urng.min() >= 0.
    00764     typedef typename __gnu_cxx::__add_unsigned<typename
    00765       _UniformRandomNumberGenerator::result_type>::__type __urntype;
    00766     typedef typename __gnu_cxx::__add_unsigned<result_type>::__type
    00767                                                           __utype;
    00768     typedef typename __gnu_cxx::__conditional_type<(sizeof(__urntype)
    00769                             > sizeof(__utype)),
    00770       __urntype, __utype>::__type                         __uctype;
    00771
    00772     result_type __ret;
    00773
    00774     const __urntype __urnmin = __urng.min();
    00775     const __urntype __urnmax = __urng.max();
    00776     const __urntype __urnrange = __urnmax - __urnmin;
    00777     const __uctype __urange = __max - __min;
    00778     const __uctype __udenom = (__urnrange <= __urange
    00779                    ? 1 : __urnrange / (__urange + 1));
    00780     do
    00781       __ret = (__urntype(__urng()) -  __urnmin) / __udenom;
    00782     while (__ret > __max - __min);
    00783
    00784     return __ret + __min;
    00785       }
    00786
    00787   template<typename _IntType, typename _CharT, typename _Traits>
    00788     std::basic_ostream<_CharT, _Traits>&
    00789     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00790            const uniform_int<_IntType>& __x)
    00791     {
    00792       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00793       typedef typename __ostream_type::ios_base    __ios_base;
    00794
    00795       const typename __ios_base::fmtflags __flags = __os.flags();
    00796       const _CharT __fill = __os.fill();
    00797       const _CharT __space = __os.widen(' ');
    00798       __os.flags(__ios_base::scientific | __ios_base::left);
    00799       __os.fill(__space);
    00800
    00801       __os << __x.min() << __space << __x.max();
    00802
    00803       __os.flags(__flags);
    00804       __os.fill(__fill);
    00805       return __os;
    00806     }
    00807
    00808   template<typename _IntType, typename _CharT, typename _Traits>
    00809     std::basic_istream<_CharT, _Traits>&
    00810     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00811            uniform_int<_IntType>& __x)
    00812     {
    00813       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    00814       typedef typename __istream_type::ios_base    __ios_base;
    00815
    00816       const typename __ios_base::fmtflags __flags = __is.flags();
    00817       __is.flags(__ios_base::dec | __ios_base::skipws);
    00818
    00819       __is >> __x._M_min >> __x._M_max;
    00820
    00821       __is.flags(__flags);
    00822       return __is;
    00823     }
    00824
    00825
    00826   template<typename _CharT, typename _Traits>
    00827     std::basic_ostream<_CharT, _Traits>&
    00828     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00829            const bernoulli_distribution& __x)
    00830     {
    00831       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00832       typedef typename __ostream_type::ios_base    __ios_base;
    00833
    00834       const typename __ios_base::fmtflags __flags = __os.flags();
    00835       const _CharT __fill = __os.fill();
    00836       const std::streamsize __precision = __os.precision();
    00837       __os.flags(__ios_base::scientific | __ios_base::left);
    00838       __os.fill(__os.widen(' '));
    00839       __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10);
    00840
    00841       __os << __x.p();
    00842
    00843       __os.flags(__flags);
    00844       __os.fill(__fill);
    00845       __os.precision(__precision);
    00846       return __os;
    00847     }
    00848
    00849
    00850   template<typename _IntType, typename _RealType>
    00851     template<class _UniformRandomNumberGenerator>
    00852       typename geometric_distribution<_IntType, _RealType>::result_type
    00853       geometric_distribution<_IntType, _RealType>::
    00854       operator()(_UniformRandomNumberGenerator& __urng)
    00855       {
    00856     // About the epsilon thing see this thread:
    00857         // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
    00858     const _RealType __naf =
    00859       (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
    00860     // The largest _RealType convertible to _IntType.
    00861     const _RealType __thr =
    00862       std::numeric_limits<_IntType>::max() + __naf;
    00863
    00864     _RealType __cand;
    00865     do
    00866       __cand = std::ceil(std::log(__urng()) / _M_log_p);
    00867     while (__cand >= __thr);
    00868
    00869     return result_type(__cand + __naf);
    00870       }
    00871
    00872   template<typename _IntType, typename _RealType,
    00873        typename _CharT, typename _Traits>
    00874     std::basic_ostream<_CharT, _Traits>&
    00875     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00876            const geometric_distribution<_IntType, _RealType>& __x)
    00877     {
    00878       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    00879       typedef typename __ostream_type::ios_base    __ios_base;
    00880
    00881       const typename __ios_base::fmtflags __flags = __os.flags();
    00882       const _CharT __fill = __os.fill();
    00883       const std::streamsize __precision = __os.precision();
    00884       __os.flags(__ios_base::scientific | __ios_base::left);
    00885       __os.fill(__os.widen(' '));
    00886       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    00887
    00888       __os << __x.p();
    00889
    00890       __os.flags(__flags);
    00891       __os.fill(__fill);
    00892       __os.precision(__precision);
    00893       return __os;
    00894     }
    00895
    00896
    00897   template<typename _IntType, typename _RealType>
    00898     void
    00899     poisson_distribution<_IntType, _RealType>::
    00900     _M_initialize()
    00901     {
    00902 #if _GLIBCXX_USE_C99_MATH_TR1
    00903       if (_M_mean >= 12)
    00904     {
    00905       const _RealType __m = std::floor(_M_mean);
    00906       _M_lm_thr = std::log(_M_mean);
    00907       _M_lfm = std::_GLIBCXX_TR1 lgamma(__m + 1);
    00908       _M_sm = std::sqrt(__m);
    00909
    00910       const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
    00911       const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m
    00912                                   / __pi_4));
    00913       _M_d = std::_GLIBCXX_TR1 round(std::max(_RealType(6),
    00914                           std::min(__m, __dx)));
    00915       const _RealType __cx = 2 * __m + _M_d;
    00916       _M_scx = std::sqrt(__cx / 2);
    00917       _M_1cx = 1 / __cx;
    00918
    00919       _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
    00920       _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d;
    00921     }
    00922       else
    00923 #endif
    00924     _M_lm_thr = std::exp(-_M_mean);
    00925       }
    00926
    00927   /**
    00928    * A rejection algorithm when mean >= 12 and a simple method based
    00929    * upon the multiplication of uniform random variates otherwise.
    00930    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
    00931    * is defined.
    00932    *
    00933    * Reference:
    00934    * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
    00935    * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
    00936    */
    00937   template<typename _IntType, typename _RealType>
    00938     template<class _UniformRandomNumberGenerator>
    00939       typename poisson_distribution<_IntType, _RealType>::result_type
    00940       poisson_distribution<_IntType, _RealType>::
    00941       operator()(_UniformRandomNumberGenerator& __urng)
    00942       {
    00943 #if _GLIBCXX_USE_C99_MATH_TR1
    00944     if (_M_mean >= 12)
    00945       {
    00946         _RealType __x;
    00947
    00948         // See comments above...
    00949         const _RealType __naf =
    00950           (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
    00951         const _RealType __thr =
    00952           std::numeric_limits<_IntType>::max() + __naf;
    00953
    00954         const _RealType __m = std::floor(_M_mean);
    00955         // sqrt(pi / 2)
    00956         const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
    00957         const _RealType __c1 = _M_sm * __spi_2;
    00958         const _RealType __c2 = _M_c2b + __c1;
    00959         const _RealType __c3 = __c2 + 1;
    00960         const _RealType __c4 = __c3 + 1;
    00961         // e^(1 / 78)
    00962         const _RealType __e178 = 1.0129030479320018583185514777512983L;
    00963         const _RealType __c5 = __c4 + __e178;
    00964         const _RealType __c = _M_cb + __c5;
    00965         const _RealType __2cx = 2 * (2 * __m + _M_d);
    00966
    00967         bool __reject = true;
    00968         do
    00969           {
    00970         const _RealType __u = __c * __urng();
    00971         const _RealType __e = -std::log(__urng());
    00972
    00973         _RealType __w = 0.0;
    00974
    00975         if (__u <= __c1)
    00976           {
    00977             const _RealType __n = _M_nd(__urng);
    00978             const _RealType __y = -std::abs(__n) * _M_sm - 1;
    00979             __x = std::floor(__y);
    00980             __w = -__n * __n / 2;
    00981             if (__x < -__m)
    00982               continue;
    00983           }
    00984         else if (__u <= __c2)
    00985           {
    00986             const _RealType __n = _M_nd(__urng);
    00987             const _RealType __y = 1 + std::abs(__n) * _M_scx;
    00988             __x = std::ceil(__y);
    00989             __w = __y * (2 - __y) * _M_1cx;
    00990             if (__x > _M_d)
    00991               continue;
    00992           }
    00993         else if (__u <= __c3)
    00994           // NB: This case not in the book, nor in the Errata,
    00995           // but should be ok...
    00996           __x = -1;
    00997         else if (__u <= __c4)
    00998           __x = 0;
    00999         else if (__u <= __c5)
    01000           __x = 1;
    01001         else
    01002           {
    01003             const _RealType __v = -std::log(__urng());
    01004             const _RealType __y = _M_d + __v * __2cx / _M_d;
    01005             __x = std::ceil(__y);
    01006             __w = -_M_d * _M_1cx * (1 + __y / 2);
    01007           }
    01008
    01009         __reject = (__w - __e - __x * _M_lm_thr
    01010                 > _M_lfm - std::_GLIBCXX_TR1 lgamma(__x + __m + 1));
    01011
    01012         __reject |= __x + __m >= __thr;
    01013
    01014           } while (__reject);
    01015
    01016         return result_type(__x + __m + __naf);
    01017       }
    01018     else
    01019 #endif
    01020       {
    01021         _IntType     __x = 0;
    01022         _RealType __prod = 1.0;
    01023
    01024         do
    01025           {
    01026         __prod *= __urng();
    01027         __x += 1;
    01028           }
    01029         while (__prod > _M_lm_thr);
    01030
    01031         return __x - 1;
    01032       }
    01033       }
    01034
    01035   template<typename _IntType, typename _RealType,
    01036        typename _CharT, typename _Traits>
    01037     std::basic_ostream<_CharT, _Traits>&
    01038     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01039            const poisson_distribution<_IntType, _RealType>& __x)
    01040     {
    01041       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    01042       typedef typename __ostream_type::ios_base    __ios_base;
    01043
    01044       const typename __ios_base::fmtflags __flags = __os.flags();
    01045       const _CharT __fill = __os.fill();
    01046       const std::streamsize __precision = __os.precision();
    01047       const _CharT __space = __os.widen(' ');
    01048       __os.flags(__ios_base::scientific | __ios_base::left);
    01049       __os.fill(__space);
    01050       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    01051
    01052       __os << __x.mean() << __space << __x._M_nd;
    01053
    01054       __os.flags(__flags);
    01055       __os.fill(__fill);
    01056       __os.precision(__precision);
    01057       return __os;
    01058     }
    01059
    01060   template<typename _IntType, typename _RealType,
    01061        typename _CharT, typename _Traits>
    01062     std::basic_istream<_CharT, _Traits>&
    01063     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01064            poisson_distribution<_IntType, _RealType>& __x)
    01065     {
    01066       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    01067       typedef typename __istream_type::ios_base    __ios_base;
    01068
    01069       const typename __ios_base::fmtflags __flags = __is.flags();
    01070       __is.flags(__ios_base::skipws);
    01071
    01072       __is >> __x._M_mean >> __x._M_nd;
    01073       __x._M_initialize();
    01074
    01075       __is.flags(__flags);
    01076       return __is;
    01077     }
    01078
    01079
    01080   template<typename _IntType, typename _RealType>
    01081     void
    01082     binomial_distribution<_IntType, _RealType>::
    01083     _M_initialize()
    01084     {
    01085       const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
    01086
    01087       _M_easy = true;
    01088
    01089 #if _GLIBCXX_USE_C99_MATH_TR1
    01090       if (_M_t * __p12 >= 8)
    01091     {
    01092       _M_easy = false;
    01093       const _RealType __np = std::floor(_M_t * __p12);
    01094       const _RealType __pa = __np / _M_t;
    01095       const _RealType __1p = 1 - __pa;
    01096
    01097       const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
    01098       const _RealType __d1x =
    01099         std::sqrt(__np * __1p * std::log(32 * __np
    01100                          / (81 * __pi_4 * __1p)));
    01101       _M_d1 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d1x));
    01102       const _RealType __d2x =
    01103         std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
    01104                          / (__pi_4 * __pa)));
    01105       _M_d2 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d2x));
    01106
    01107       // sqrt(pi / 2)
    01108       const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
    01109       _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
    01110       _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
    01111       _M_c = 2 * _M_d1 / __np;
    01112       _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
    01113       const _RealType __a12 = _M_a1 + _M_s2 * __spi_2;
    01114       const _RealType __s1s = _M_s1 * _M_s1;
    01115       _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
    01116                  * 2 * __s1s / _M_d1
    01117                  * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
    01118       const _RealType __s2s = _M_s2 * _M_s2;
    01119       _M_s = (_M_a123 + 2 * __s2s / _M_d2
    01120           * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
    01121       _M_lf = (std::_GLIBCXX_TR1 lgamma(__np + 1)
    01122            + std::_GLIBCXX_TR1 lgamma(_M_t - __np + 1));
    01123       _M_lp1p = std::log(__pa / __1p);
    01124
    01125       _M_q = -std::log(1 - (__p12 - __pa) / __1p);
    01126     }
    01127       else
    01128 #endif
    01129     _M_q = -std::log(1 - __p12);
    01130     }
    01131
    01132   template<typename _IntType, typename _RealType>
    01133     template<class _UniformRandomNumberGenerator>
    01134       typename binomial_distribution<_IntType, _RealType>::result_type
    01135       binomial_distribution<_IntType, _RealType>::
    01136       _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
    01137       {
    01138     _IntType    __x = 0;
    01139     _RealType __sum = 0;
    01140
    01141     do
    01142       {
    01143         const _RealType __e = -std::log(__urng());
    01144         __sum += __e / (__t - __x);
    01145         __x += 1;
    01146       }
    01147     while (__sum <= _M_q);
    01148
    01149     return __x - 1;
    01150       }
    01151
    01152   /**
    01153    * A rejection algorithm when t * p >= 8 and a simple waiting time
    01154    * method - the second in the referenced book - otherwise.
    01155    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
    01156    * is defined.
    01157    *
    01158    * Reference:
    01159    * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
    01160    * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
    01161    */
    01162   template<typename _IntType, typename _RealType>
    01163     template<class _UniformRandomNumberGenerator>
    01164       typename binomial_distribution<_IntType, _RealType>::result_type
    01165       binomial_distribution<_IntType, _RealType>::
    01166       operator()(_UniformRandomNumberGenerator& __urng)
    01167       {
    01168     result_type __ret;
    01169     const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
    01170
    01171 #if _GLIBCXX_USE_C99_MATH_TR1
    01172     if (!_M_easy)
    01173       {
    01174         _RealType __x;
    01175
    01176         // See comments above...
    01177         const _RealType __naf =
    01178           (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
    01179         const _RealType __thr =
    01180           std::numeric_limits<_IntType>::max() + __naf;
    01181
    01182         const _RealType __np = std::floor(_M_t * __p12);
    01183         const _RealType __pa = __np / _M_t;
    01184
    01185         // sqrt(pi / 2)
    01186         const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
    01187         const _RealType __a1 = _M_a1;
    01188         const _RealType __a12 = __a1 + _M_s2 * __spi_2;
    01189         const _RealType __a123 = _M_a123;
    01190         const _RealType __s1s = _M_s1 * _M_s1;
    01191         const _RealType __s2s = _M_s2 * _M_s2;
    01192
    01193         bool __reject;
    01194         do
    01195           {
    01196         const _RealType __u = _M_s * __urng();
    01197
    01198         _RealType __v;
    01199
    01200         if (__u <= __a1)
    01201           {
    01202             const _RealType __n = _M_nd(__urng);
    01203             const _RealType __y = _M_s1 * std::abs(__n);
    01204             __reject = __y >= _M_d1;
    01205             if (!__reject)
    01206               {
    01207             const _RealType __e = -std::log(__urng());
    01208             __x = std::floor(__y);
    01209             __v = -__e - __n * __n / 2 + _M_c;
    01210               }
    01211           }
    01212         else if (__u <= __a12)
    01213           {
    01214             const _RealType __n = _M_nd(__urng);
    01215             const _RealType __y = _M_s2 * std::abs(__n);
    01216             __reject = __y >= _M_d2;
    01217             if (!__reject)
    01218               {
    01219             const _RealType __e = -std::log(__urng());
    01220             __x = std::floor(-__y);
    01221             __v = -__e - __n * __n / 2;
    01222               }
    01223           }
    01224         else if (__u <= __a123)
    01225           {
    01226             const _RealType __e1 = -std::log(__urng());
    01227             const _RealType __e2 = -std::log(__urng());
    01228
    01229             const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1;
    01230             __x = std::floor(__y);
    01231             __v = (-__e2 + _M_d1 * (1 / (_M_t - __np)
    01232                         -__y / (2 * __s1s)));
    01233             __reject = false;
    01234           }
    01235         else
    01236           {
    01237             const _RealType __e1 = -std::log(__urng());
    01238             const _RealType __e2 = -std::log(__urng());
    01239
    01240             const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2;
    01241             __x = std::floor(-__y);
    01242             __v = -__e2 - _M_d2 * __y / (2 * __s2s);
    01243             __reject = false;
    01244           }
    01245
    01246         __reject = __reject || __x < -__np || __x > _M_t - __np;
    01247         if (!__reject)
    01248           {
    01249             const _RealType __lfx =
    01250               std::_GLIBCXX_TR1 lgamma(__np + __x + 1)
    01251               + std::_GLIBCXX_TR1 lgamma(_M_t - (__np + __x) + 1);
    01252             __reject = __v > _M_lf - __lfx + __x * _M_lp1p;
    01253           }
    01254
    01255         __reject |= __x + __np >= __thr;
    01256           }
    01257         while (__reject);
    01258
    01259         __x += __np + __naf;
    01260
    01261         const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x));
    01262         __ret = _IntType(__x) + __z;
    01263       }
    01264     else
    01265 #endif
    01266       __ret = _M_waiting(__urng, _M_t);
    01267
    01268     if (__p12 != _M_p)
    01269       __ret = _M_t - __ret;
    01270     return __ret;
    01271       }
    01272
    01273   template<typename _IntType, typename _RealType,
    01274        typename _CharT, typename _Traits>
    01275     std::basic_ostream<_CharT, _Traits>&
    01276     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01277            const binomial_distribution<_IntType, _RealType>& __x)
    01278     {
    01279       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    01280       typedef typename __ostream_type::ios_base    __ios_base;
    01281
    01282       const typename __ios_base::fmtflags __flags = __os.flags();
    01283       const _CharT __fill = __os.fill();
    01284       const std::streamsize __precision = __os.precision();
    01285       const _CharT __space = __os.widen(' ');
    01286       __os.flags(__ios_base::scientific | __ios_base::left);
    01287       __os.fill(__space);
    01288       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    01289
    01290       __os << __x.t() << __space << __x.p()
    01291        << __space << __x._M_nd;
    01292
    01293       __os.flags(__flags);
    01294       __os.fill(__fill);
    01295       __os.precision(__precision);
    01296       return __os;
    01297     }
    01298
    01299   template<typename _IntType, typename _RealType,
    01300        typename _CharT, typename _Traits>
    01301     std::basic_istream<_CharT, _Traits>&
    01302     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01303            binomial_distribution<_IntType, _RealType>& __x)
    01304     {
    01305       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    01306       typedef typename __istream_type::ios_base    __ios_base;
    01307
    01308       const typename __ios_base::fmtflags __flags = __is.flags();
    01309       __is.flags(__ios_base::dec | __ios_base::skipws);
    01310
    01311       __is >> __x._M_t >> __x._M_p >> __x._M_nd;
    01312       __x._M_initialize();
    01313
    01314       __is.flags(__flags);
    01315       return __is;
    01316     }
    01317
    01318
    01319   template<typename _RealType, typename _CharT, typename _Traits>
    01320     std::basic_ostream<_CharT, _Traits>&
    01321     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01322            const uniform_real<_RealType>& __x)
    01323     {
    01324       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    01325       typedef typename __ostream_type::ios_base    __ios_base;
    01326
    01327       const typename __ios_base::fmtflags __flags = __os.flags();
    01328       const _CharT __fill = __os.fill();
    01329       const std::streamsize __precision = __os.precision();
    01330       const _CharT __space = __os.widen(' ');
    01331       __os.flags(__ios_base::scientific | __ios_base::left);
    01332       __os.fill(__space);
    01333       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    01334
    01335       __os << __x.min() << __space << __x.max();
    01336
    01337       __os.flags(__flags);
    01338       __os.fill(__fill);
    01339       __os.precision(__precision);
    01340       return __os;
    01341     }
    01342
    01343   template<typename _RealType, typename _CharT, typename _Traits>
    01344     std::basic_istream<_CharT, _Traits>&
    01345     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01346            uniform_real<_RealType>& __x)
    01347     {
    01348       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    01349       typedef typename __istream_type::ios_base    __ios_base;
    01350
    01351       const typename __ios_base::fmtflags __flags = __is.flags();
    01352       __is.flags(__ios_base::skipws);
    01353
    01354       __is >> __x._M_min >> __x._M_max;
    01355
    01356       __is.flags(__flags);
    01357       return __is;
    01358     }
    01359
    01360
    01361   template<typename _RealType, typename _CharT, typename _Traits>
    01362     std::basic_ostream<_CharT, _Traits>&
    01363     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01364            const exponential_distribution<_RealType>& __x)
    01365     {
    01366       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    01367       typedef typename __ostream_type::ios_base    __ios_base;
    01368
    01369       const typename __ios_base::fmtflags __flags = __os.flags();
    01370       const _CharT __fill = __os.fill();
    01371       const std::streamsize __precision = __os.precision();
    01372       __os.flags(__ios_base::scientific | __ios_base::left);
    01373       __os.fill(__os.widen(' '));
    01374       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    01375
    01376       __os << __x.lambda();
    01377
    01378       __os.flags(__flags);
    01379       __os.fill(__fill);
    01380       __os.precision(__precision);
    01381       return __os;
    01382     }
    01383
    01384
    01385   /**
    01386    * Polar method due to Marsaglia.
    01387    *
    01388    * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
    01389    * New York, 1986, Ch. V, Sect. 4.4.
    01390    */
    01391   template<typename _RealType>
    01392     template<class _UniformRandomNumberGenerator>
    01393       typename normal_distribution<_RealType>::result_type
    01394       normal_distribution<_RealType>::
    01395       operator()(_UniformRandomNumberGenerator& __urng)
    01396       {
    01397     result_type __ret;
    01398
    01399     if (_M_saved_available)
    01400       {
    01401         _M_saved_available = false;
    01402         __ret = _M_saved;
    01403       }
    01404     else
    01405       {
    01406         result_type __x, __y, __r2;
    01407         do
    01408           {
    01409         __x = result_type(2.0) * __urng() - 1.0;
    01410         __y = result_type(2.0) * __urng() - 1.0;
    01411         __r2 = __x * __x + __y * __y;
    01412           }
    01413         while (__r2 > 1.0 || __r2 == 0.0);
    01414
    01415         const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
    01416         _M_saved = __x * __mult;
    01417         _M_saved_available = true;
    01418         __ret = __y * __mult;
    01419       }
    01420
    01421     __ret = __ret * _M_sigma + _M_mean;
    01422     return __ret;
    01423       }
    01424
    01425   template<typename _RealType, typename _CharT, typename _Traits>
    01426     std::basic_ostream<_CharT, _Traits>&
    01427     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01428            const normal_distribution<_RealType>& __x)
    01429     {
    01430       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    01431       typedef typename __ostream_type::ios_base    __ios_base;
    01432
    01433       const typename __ios_base::fmtflags __flags = __os.flags();
    01434       const _CharT __fill = __os.fill();
    01435       const std::streamsize __precision = __os.precision();
    01436       const _CharT __space = __os.widen(' ');
    01437       __os.flags(__ios_base::scientific | __ios_base::left);
    01438       __os.fill(__space);
    01439       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    01440
    01441       __os << __x._M_saved_available << __space
    01442        << __x.mean() << __space
    01443        << __x.sigma();
    01444       if (__x._M_saved_available)
    01445     __os << __space << __x._M_saved;
    01446
    01447       __os.flags(__flags);
    01448       __os.fill(__fill);
    01449       __os.precision(__precision);
    01450       return __os;
    01451     }
    01452
    01453   template<typename _RealType, typename _CharT, typename _Traits>
    01454     std::basic_istream<_CharT, _Traits>&
    01455     operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01456            normal_distribution<_RealType>& __x)
    01457     {
    01458       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
    01459       typedef typename __istream_type::ios_base    __ios_base;
    01460
    01461       const typename __ios_base::fmtflags __flags = __is.flags();
    01462       __is.flags(__ios_base::dec | __ios_base::skipws);
    01463
    01464       __is >> __x._M_saved_available >> __x._M_mean
    01465        >> __x._M_sigma;
    01466       if (__x._M_saved_available)
    01467     __is >> __x._M_saved;
    01468
    01469       __is.flags(__flags);
    01470       return __is;
    01471     }
    01472
    01473
    01474   template<typename _RealType>
    01475     void
    01476     gamma_distribution<_RealType>::
    01477     _M_initialize()
    01478     {
    01479       if (_M_alpha >= 1)
    01480     _M_l_d = std::sqrt(2 * _M_alpha - 1);
    01481       else
    01482     _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha))
    01483           * (1 - _M_alpha));
    01484     }
    01485
    01486   /**
    01487    * Cheng's rejection algorithm GB for alpha >= 1 and a modification
    01488    * of Vaduva's rejection from Weibull algorithm due to Devroye for
    01489    * alpha < 1.
    01490    *
    01491    * References:
    01492    * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral
    01493    * Shape Parameter." Applied Statistics, 26, 71-75, 1977.
    01494    *
    01495    * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection
    01496    * and Composition Procedures." Math. Operationsforschung and Statistik,
    01497    * Series in Statistics, 8, 545-576, 1977.
    01498    *
    01499    * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
    01500    * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!).
    01501    */
    01502   template<typename _RealType>
    01503     template<class _UniformRandomNumberGenerator>
    01504       typename gamma_distribution<_RealType>::result_type
    01505       gamma_distribution<_RealType>::
    01506       operator()(_UniformRandomNumberGenerator& __urng)
    01507       {
    01508     result_type __x;
    01509
    01510     bool __reject;
    01511     if (_M_alpha >= 1)
    01512       {
    01513         // alpha - log(4)
    01514         const result_type __b = _M_alpha
    01515           - result_type(1.3862943611198906188344642429163531L);
    01516         const result_type __c = _M_alpha + _M_l_d;
    01517         const result_type __1l = 1 / _M_l_d;
    01518
    01519         // 1 + log(9 / 2)
    01520         const result_type __k = 2.5040773967762740733732583523868748L;
    01521
    01522         do
    01523           {
    01524         const result_type __u = __urng();
    01525         const result_type __v = __urng();
    01526
    01527         const result_type __y = __1l * std::log(__v / (1 - __v));
    01528         __x = _M_alpha * std::exp(__y);
    01529
    01530         const result_type __z = __u * __v * __v;
    01531         const result_type __r = __b + __c * __y - __x;
    01532
    01533         __reject = __r < result_type(4.5) * __z - __k;
    01534         if (__reject)
    01535           __reject = __r < std::log(__z);
    01536           }
    01537         while (__reject);
    01538       }
    01539     else
    01540       {
    01541         const result_type __c = 1 / _M_alpha;
    01542
    01543         do
    01544           {
    01545         const result_type __z = -std::log(__urng());
    01546         const result_type __e = -std::log(__urng());
    01547
    01548         __x = std::pow(__z, __c);
    01549
    01550         __reject = __z + __e < _M_l_d + __x;
    01551           }
    01552         while (__reject);
    01553       }
    01554
    01555     return __x;
    01556       }
    01557
    01558   template<typename _RealType, typename _CharT, typename _Traits>
    01559     std::basic_ostream<_CharT, _Traits>&
    01560     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01561            const gamma_distribution<_RealType>& __x)
    01562     {
    01563       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
    01564       typedef typename __ostream_type::ios_base    __ios_base;
    01565
    01566       const typename __ios_base::fmtflags __flags = __os.flags();
    01567       const _CharT __fill = __os.fill();
    01568       const std::streamsize __precision = __os.precision();
    01569       __os.flags(__ios_base::scientific | __ios_base::left);
    01570       __os.fill(__os.widen(' '));
    01571       __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
    01572
    01573       __os << __x.alpha();
    01574
    01575       __os.flags(__flags);
    01576       __os.fill(__fill);
    01577       __os.precision(__precision);
    01578       return __os;
    01579     }
    01580
    01581 _GLIBCXX_END_NAMESPACE_TR1
    01582 }