random.tcc

Go to the documentation of this file.
00001 // random number generation (out of line) -*- C++ -*-
00002 
00003 // Copyright (C) 2009, 2010 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/random.tcc
00026  *  This is an internal header file, included by other library headers.
00027  *  You should not attempt to use it directly.
00028  */
00029 
00030 #include <numeric>
00031 #include <algorithm>
00032 
00033 namespace std
00034 {
00035   /*
00036    * (Further) implementation-space details.
00037    */
00038   namespace __detail
00039   {
00040     // General case for x = (ax + c) mod m -- use Schrage's algorithm to
00041     // avoid integer overflow.
00042     //
00043     // Because a and c are compile-time integral constants the compiler
00044     // kindly elides any unreachable paths.
00045     //
00046     // Preconditions:  a > 0, m > 0.
00047     //
00048     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool>
00049       struct _Mod
00050       {
00051     static _Tp
00052     __calc(_Tp __x)
00053     {
00054       if (__a == 1)
00055         __x %= __m;
00056       else
00057         {
00058           static const _Tp __q = __m / __a;
00059           static const _Tp __r = __m % __a;
00060 
00061           _Tp __t1 = __a * (__x % __q);
00062           _Tp __t2 = __r * (__x / __q);
00063           if (__t1 >= __t2)
00064         __x = __t1 - __t2;
00065           else
00066         __x = __m - __t2 + __t1;
00067         }
00068 
00069       if (__c != 0)
00070         {
00071           const _Tp __d = __m - __x;
00072           if (__d > __c)
00073         __x += __c;
00074           else
00075         __x = __c - __d;
00076         }
00077       return __x;
00078     }
00079       };
00080 
00081     // Special case for m == 0 -- use unsigned integer overflow as modulo
00082     // operator.
00083     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
00084       struct _Mod<_Tp, __m, __a, __c, true>
00085       {
00086     static _Tp
00087     __calc(_Tp __x)
00088     { return __a * __x + __c; }
00089       };
00090   } // namespace __detail
00091 
00092 
00093   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00094     const _UIntType
00095     linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
00096 
00097   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00098     const _UIntType
00099     linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
00100 
00101   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00102     const _UIntType
00103     linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
00104 
00105   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00106     const _UIntType
00107     linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
00108 
00109   /**
00110    * Seeds the LCR with integral value @p __s, adjusted so that the
00111    * ring identity is never a member of the convergence set.
00112    */
00113   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00114     void
00115     linear_congruential_engine<_UIntType, __a, __c, __m>::
00116     seed(result_type __s)
00117     {
00118       if ((__detail::__mod<_UIntType, __m>(__c) == 0)
00119       && (__detail::__mod<_UIntType, __m>(__s) == 0))
00120     _M_x = 1;
00121       else
00122     _M_x = __detail::__mod<_UIntType, __m>(__s);
00123     }
00124 
00125   /**
00126    * Seeds the LCR engine with a value generated by @p __q.
00127    */
00128   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00129     template<typename _Sseq, typename>
00130       void
00131       linear_congruential_engine<_UIntType, __a, __c, __m>::
00132       seed(_Sseq& __q)
00133       {
00134     const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
00135                                     : std::__lg(__m);
00136     const _UIntType __k = (__k0 + 31) / 32;
00137     uint_least32_t __arr[__k + 3];
00138     __q.generate(__arr + 0, __arr + __k + 3);
00139     _UIntType __factor = 1u;
00140     _UIntType __sum = 0u;
00141     for (size_t __j = 0; __j < __k; ++__j)
00142       {
00143         __sum += __arr[__j + 3] * __factor;
00144         __factor *= __detail::_Shift<_UIntType, 32>::__value;
00145       }
00146     seed(__sum);
00147       }
00148 
00149   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
00150        typename _CharT, typename _Traits>
00151     std::basic_ostream<_CharT, _Traits>&
00152     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00153            const linear_congruential_engine<_UIntType,
00154                         __a, __c, __m>& __lcr)
00155     {
00156       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00157       typedef typename __ostream_type::ios_base    __ios_base;
00158 
00159       const typename __ios_base::fmtflags __flags = __os.flags();
00160       const _CharT __fill = __os.fill();
00161       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
00162       __os.fill(__os.widen(' '));
00163 
00164       __os << __lcr._M_x;
00165 
00166       __os.flags(__flags);
00167       __os.fill(__fill);
00168       return __os;
00169     }
00170 
00171   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
00172        typename _CharT, typename _Traits>
00173     std::basic_istream<_CharT, _Traits>&
00174     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00175            linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr)
00176     {
00177       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
00178       typedef typename __istream_type::ios_base    __ios_base;
00179 
00180       const typename __ios_base::fmtflags __flags = __is.flags();
00181       __is.flags(__ios_base::dec);
00182 
00183       __is >> __lcr._M_x;
00184 
00185       __is.flags(__flags);
00186       return __is;
00187     }
00188 
00189 
00190   template<typename _UIntType,
00191        size_t __w, size_t __n, size_t __m, size_t __r,
00192        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00193        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00194        _UIntType __f>
00195     const size_t
00196     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00197                 __s, __b, __t, __c, __l, __f>::word_size;
00198 
00199   template<typename _UIntType,
00200        size_t __w, size_t __n, size_t __m, size_t __r,
00201        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00202        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00203        _UIntType __f>
00204     const size_t
00205     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00206                 __s, __b, __t, __c, __l, __f>::state_size;
00207 
00208   template<typename _UIntType,
00209        size_t __w, size_t __n, size_t __m, size_t __r,
00210        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00211        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00212        _UIntType __f>
00213     const size_t
00214     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00215                 __s, __b, __t, __c, __l, __f>::shift_size;
00216 
00217   template<typename _UIntType,
00218        size_t __w, size_t __n, size_t __m, size_t __r,
00219        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00220        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00221        _UIntType __f>
00222     const size_t
00223     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00224                 __s, __b, __t, __c, __l, __f>::mask_bits;
00225 
00226   template<typename _UIntType,
00227        size_t __w, size_t __n, size_t __m, size_t __r,
00228        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00229        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00230        _UIntType __f>
00231     const _UIntType
00232     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00233                 __s, __b, __t, __c, __l, __f>::xor_mask;
00234 
00235   template<typename _UIntType,
00236        size_t __w, size_t __n, size_t __m, size_t __r,
00237        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00238        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00239        _UIntType __f>
00240     const size_t
00241     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00242                 __s, __b, __t, __c, __l, __f>::tempering_u;
00243    
00244   template<typename _UIntType,
00245        size_t __w, size_t __n, size_t __m, size_t __r,
00246        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00247        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00248        _UIntType __f>
00249     const _UIntType
00250     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00251                 __s, __b, __t, __c, __l, __f>::tempering_d;
00252 
00253   template<typename _UIntType,
00254        size_t __w, size_t __n, size_t __m, size_t __r,
00255        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00256        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00257        _UIntType __f>
00258     const size_t
00259     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00260                 __s, __b, __t, __c, __l, __f>::tempering_s;
00261 
00262   template<typename _UIntType,
00263        size_t __w, size_t __n, size_t __m, size_t __r,
00264        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00265        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00266        _UIntType __f>
00267     const _UIntType
00268     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00269                 __s, __b, __t, __c, __l, __f>::tempering_b;
00270 
00271   template<typename _UIntType,
00272        size_t __w, size_t __n, size_t __m, size_t __r,
00273        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00274        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00275        _UIntType __f>
00276     const size_t
00277     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00278                 __s, __b, __t, __c, __l, __f>::tempering_t;
00279 
00280   template<typename _UIntType,
00281        size_t __w, size_t __n, size_t __m, size_t __r,
00282        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00283        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00284        _UIntType __f>
00285     const _UIntType
00286     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00287                 __s, __b, __t, __c, __l, __f>::tempering_c;
00288 
00289   template<typename _UIntType,
00290        size_t __w, size_t __n, size_t __m, size_t __r,
00291        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00292        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00293        _UIntType __f>
00294     const size_t
00295     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00296                 __s, __b, __t, __c, __l, __f>::tempering_l;
00297 
00298   template<typename _UIntType,
00299        size_t __w, size_t __n, size_t __m, size_t __r,
00300        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00301        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00302        _UIntType __f>
00303     const _UIntType
00304     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00305                 __s, __b, __t, __c, __l, __f>::
00306                                               initialization_multiplier;
00307 
00308   template<typename _UIntType,
00309        size_t __w, size_t __n, size_t __m, size_t __r,
00310        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00311        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00312        _UIntType __f>
00313     const _UIntType
00314     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00315                 __s, __b, __t, __c, __l, __f>::default_seed;
00316 
00317   template<typename _UIntType,
00318        size_t __w, size_t __n, size_t __m, size_t __r,
00319        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00320        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00321        _UIntType __f>
00322     void
00323     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00324                 __s, __b, __t, __c, __l, __f>::
00325     seed(result_type __sd)
00326     {
00327       _M_x[0] = __detail::__mod<_UIntType,
00328     __detail::_Shift<_UIntType, __w>::__value>(__sd);
00329 
00330       for (size_t __i = 1; __i < state_size; ++__i)
00331     {
00332       _UIntType __x = _M_x[__i - 1];
00333       __x ^= __x >> (__w - 2);
00334       __x *= __f;
00335       __x += __detail::__mod<_UIntType, __n>(__i);
00336       _M_x[__i] = __detail::__mod<_UIntType,
00337         __detail::_Shift<_UIntType, __w>::__value>(__x);
00338     }
00339       _M_p = state_size;
00340     }
00341 
00342   template<typename _UIntType,
00343        size_t __w, size_t __n, size_t __m, size_t __r,
00344        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00345        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00346        _UIntType __f>
00347     template<typename _Sseq, typename>
00348       void
00349       mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00350                   __s, __b, __t, __c, __l, __f>::
00351       seed(_Sseq& __q)
00352       {
00353     const _UIntType __upper_mask = (~_UIntType()) << __r;
00354     const size_t __k = (__w + 31) / 32;
00355     uint_least32_t __arr[__n * __k];
00356     __q.generate(__arr + 0, __arr + __n * __k);
00357 
00358     bool __zero = true;
00359     for (size_t __i = 0; __i < state_size; ++__i)
00360       {
00361         _UIntType __factor = 1u;
00362         _UIntType __sum = 0u;
00363         for (size_t __j = 0; __j < __k; ++__j)
00364           {
00365         __sum += __arr[__k * __i + __j] * __factor;
00366         __factor *= __detail::_Shift<_UIntType, 32>::__value;
00367           }
00368         _M_x[__i] = __detail::__mod<_UIntType,
00369           __detail::_Shift<_UIntType, __w>::__value>(__sum);
00370 
00371         if (__zero)
00372           {
00373         if (__i == 0)
00374           {
00375             if ((_M_x[0] & __upper_mask) != 0u)
00376               __zero = false;
00377           }
00378         else if (_M_x[__i] != 0u)
00379           __zero = false;
00380           }
00381       }
00382         if (__zero)
00383           _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
00384       }
00385 
00386   template<typename _UIntType, size_t __w,
00387        size_t __n, size_t __m, size_t __r,
00388        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00389        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00390        _UIntType __f>
00391     typename
00392     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00393                 __s, __b, __t, __c, __l, __f>::result_type
00394     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
00395                 __s, __b, __t, __c, __l, __f>::
00396     operator()()
00397     {
00398       // Reload the vector - cost is O(n) amortized over n calls.
00399       if (_M_p >= state_size)
00400     {
00401       const _UIntType __upper_mask = (~_UIntType()) << __r;
00402       const _UIntType __lower_mask = ~__upper_mask;
00403 
00404       for (size_t __k = 0; __k < (__n - __m); ++__k)
00405         {
00406           _UIntType __y = ((_M_x[__k] & __upper_mask)
00407                    | (_M_x[__k + 1] & __lower_mask));
00408           _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
00409                ^ ((__y & 0x01) ? __a : 0));
00410         }
00411 
00412       for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
00413         {
00414           _UIntType __y = ((_M_x[__k] & __upper_mask)
00415                    | (_M_x[__k + 1] & __lower_mask));
00416           _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
00417                ^ ((__y & 0x01) ? __a : 0));
00418         }
00419 
00420       _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
00421                | (_M_x[0] & __lower_mask));
00422       _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
00423                ^ ((__y & 0x01) ? __a : 0));
00424       _M_p = 0;
00425     }
00426 
00427       // Calculate o(x(i)).
00428       result_type __z = _M_x[_M_p++];
00429       __z ^= (__z >> __u) & __d;
00430       __z ^= (__z << __s) & __b;
00431       __z ^= (__z << __t) & __c;
00432       __z ^= (__z >> __l);
00433 
00434       return __z;
00435     }
00436 
00437   template<typename _UIntType, size_t __w,
00438        size_t __n, size_t __m, size_t __r,
00439        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00440        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00441        _UIntType __f, typename _CharT, typename _Traits>
00442     std::basic_ostream<_CharT, _Traits>&
00443     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00444            const mersenne_twister_engine<_UIntType, __w, __n, __m,
00445            __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
00446     {
00447       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00448       typedef typename __ostream_type::ios_base    __ios_base;
00449 
00450       const typename __ios_base::fmtflags __flags = __os.flags();
00451       const _CharT __fill = __os.fill();
00452       const _CharT __space = __os.widen(' ');
00453       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
00454       __os.fill(__space);
00455 
00456       for (size_t __i = 0; __i < __n - 1; ++__i)
00457     __os << __x._M_x[__i] << __space;
00458       __os << __x._M_x[__n - 1];
00459 
00460       __os.flags(__flags);
00461       __os.fill(__fill);
00462       return __os;
00463     }
00464 
00465   template<typename _UIntType, size_t __w,
00466        size_t __n, size_t __m, size_t __r,
00467        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00468        _UIntType __b, size_t __t, _UIntType __c, size_t __l,
00469        _UIntType __f, typename _CharT, typename _Traits>
00470     std::basic_istream<_CharT, _Traits>&
00471     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00472            mersenne_twister_engine<_UIntType, __w, __n, __m,
00473            __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
00474     {
00475       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
00476       typedef typename __istream_type::ios_base    __ios_base;
00477 
00478       const typename __ios_base::fmtflags __flags = __is.flags();
00479       __is.flags(__ios_base::dec | __ios_base::skipws);
00480 
00481       for (size_t __i = 0; __i < __n; ++__i)
00482     __is >> __x._M_x[__i];
00483 
00484       __is.flags(__flags);
00485       return __is;
00486     }
00487 
00488 
00489   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00490     const size_t
00491     subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
00492 
00493   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00494     const size_t
00495     subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
00496 
00497   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00498     const size_t
00499     subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
00500 
00501   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00502     const _UIntType
00503     subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
00504 
00505   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00506     void
00507     subtract_with_carry_engine<_UIntType, __w, __s, __r>::
00508     seed(result_type __value)
00509     {
00510       std::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
00511     __lcg(__value == 0u ? default_seed : __value);
00512 
00513       const size_t __n = (__w + 31) / 32;
00514 
00515       for (size_t __i = 0; __i < long_lag; ++__i)
00516     {
00517       _UIntType __sum = 0u;
00518       _UIntType __factor = 1u;
00519       for (size_t __j = 0; __j < __n; ++__j)
00520         {
00521           __sum += __detail::__mod<uint_least32_t,
00522                __detail::_Shift<uint_least32_t, 32>::__value>
00523              (__lcg()) * __factor;
00524           __factor *= __detail::_Shift<_UIntType, 32>::__value;
00525         }
00526       _M_x[__i] = __detail::__mod<_UIntType,
00527         __detail::_Shift<_UIntType, __w>::__value>(__sum);
00528     }
00529       _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
00530       _M_p = 0;
00531     }
00532 
00533   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00534     template<typename _Sseq, typename>
00535       void
00536       subtract_with_carry_engine<_UIntType, __w, __s, __r>::
00537       seed(_Sseq& __q)
00538       {
00539     const size_t __k = (__w + 31) / 32;
00540     uint_least32_t __arr[__r * __k];
00541     __q.generate(__arr + 0, __arr + __r * __k);
00542 
00543     for (size_t __i = 0; __i < long_lag; ++__i)
00544       {
00545         _UIntType __sum = 0u;
00546         _UIntType __factor = 1u;
00547         for (size_t __j = 0; __j < __k; ++__j)
00548           {
00549         __sum += __arr[__k * __i + __j] * __factor;
00550         __factor *= __detail::_Shift<_UIntType, 32>::__value;
00551           }
00552         _M_x[__i] = __detail::__mod<_UIntType,
00553           __detail::_Shift<_UIntType, __w>::__value>(__sum);
00554       }
00555     _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
00556     _M_p = 0;
00557       }
00558 
00559   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00560     typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::
00561          result_type
00562     subtract_with_carry_engine<_UIntType, __w, __s, __r>::
00563     operator()()
00564     {
00565       // Derive short lag index from current index.
00566       long __ps = _M_p - short_lag;
00567       if (__ps < 0)
00568     __ps += long_lag;
00569 
00570       // Calculate new x(i) without overflow or division.
00571       // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry
00572       // cannot overflow.
00573       _UIntType __xi;
00574       if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
00575     {
00576       __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
00577       _M_carry = 0;
00578     }
00579       else
00580     {
00581       __xi = (__detail::_Shift<_UIntType, __w>::__value
00582           - _M_x[_M_p] - _M_carry + _M_x[__ps]);
00583       _M_carry = 1;
00584     }
00585       _M_x[_M_p] = __xi;
00586 
00587       // Adjust current index to loop around in ring buffer.
00588       if (++_M_p >= long_lag)
00589     _M_p = 0;
00590 
00591       return __xi;
00592     }
00593 
00594   template<typename _UIntType, size_t __w, size_t __s, size_t __r,
00595        typename _CharT, typename _Traits>
00596     std::basic_ostream<_CharT, _Traits>&
00597     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00598            const subtract_with_carry_engine<_UIntType,
00599                         __w, __s, __r>& __x)
00600     {
00601       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00602       typedef typename __ostream_type::ios_base    __ios_base;
00603 
00604       const typename __ios_base::fmtflags __flags = __os.flags();
00605       const _CharT __fill = __os.fill();
00606       const _CharT __space = __os.widen(' ');
00607       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
00608       __os.fill(__space);
00609 
00610       for (size_t __i = 0; __i < __r; ++__i)
00611     __os << __x._M_x[__i] << __space;
00612       __os << __x._M_carry;
00613 
00614       __os.flags(__flags);
00615       __os.fill(__fill);
00616       return __os;
00617     }
00618 
00619   template<typename _UIntType, size_t __w, size_t __s, size_t __r,
00620        typename _CharT, typename _Traits>
00621     std::basic_istream<_CharT, _Traits>&
00622     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00623            subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x)
00624     {
00625       typedef std::basic_ostream<_CharT, _Traits>  __istream_type;
00626       typedef typename __istream_type::ios_base    __ios_base;
00627 
00628       const typename __ios_base::fmtflags __flags = __is.flags();
00629       __is.flags(__ios_base::dec | __ios_base::skipws);
00630 
00631       for (size_t __i = 0; __i < __r; ++__i)
00632     __is >> __x._M_x[__i];
00633       __is >> __x._M_carry;
00634 
00635       __is.flags(__flags);
00636       return __is;
00637     }
00638 
00639 
00640   template<typename _RandomNumberEngine, size_t __p, size_t __r>
00641     const size_t
00642     discard_block_engine<_RandomNumberEngine, __p, __r>::block_size;
00643 
00644   template<typename _RandomNumberEngine, size_t __p, size_t __r>
00645     const size_t
00646     discard_block_engine<_RandomNumberEngine, __p, __r>::used_block;
00647 
00648   template<typename _RandomNumberEngine, size_t __p, size_t __r>
00649     typename discard_block_engine<_RandomNumberEngine,
00650                __p, __r>::result_type
00651     discard_block_engine<_RandomNumberEngine, __p, __r>::
00652     operator()()
00653     {
00654       if (_M_n >= used_block)
00655     {
00656       _M_b.discard(block_size - _M_n);
00657       _M_n = 0;
00658     }
00659       ++_M_n;
00660       return _M_b();
00661     }
00662 
00663   template<typename _RandomNumberEngine, size_t __p, size_t __r,
00664        typename _CharT, typename _Traits>
00665     std::basic_ostream<_CharT, _Traits>&
00666     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00667            const discard_block_engine<_RandomNumberEngine,
00668            __p, __r>& __x)
00669     {
00670       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00671       typedef typename __ostream_type::ios_base    __ios_base;
00672 
00673       const typename __ios_base::fmtflags __flags = __os.flags();
00674       const _CharT __fill = __os.fill();
00675       const _CharT __space = __os.widen(' ');
00676       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
00677       __os.fill(__space);
00678 
00679       __os << __x.base() << __space << __x._M_n;
00680 
00681       __os.flags(__flags);
00682       __os.fill(__fill);
00683       return __os;
00684     }
00685 
00686   template<typename _RandomNumberEngine, size_t __p, size_t __r,
00687        typename _CharT, typename _Traits>
00688     std::basic_istream<_CharT, _Traits>&
00689     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00690            discard_block_engine<_RandomNumberEngine, __p, __r>& __x)
00691     {
00692       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
00693       typedef typename __istream_type::ios_base    __ios_base;
00694 
00695       const typename __ios_base::fmtflags __flags = __is.flags();
00696       __is.flags(__ios_base::dec | __ios_base::skipws);
00697 
00698       __is >> __x._M_b >> __x._M_n;
00699 
00700       __is.flags(__flags);
00701       return __is;
00702     }
00703 
00704 
00705   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
00706     typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
00707       result_type
00708     independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
00709     operator()()
00710     {
00711       const long double __r = static_cast<long double>(_M_b.max())
00712                 - static_cast<long double>(_M_b.min()) + 1.0L;
00713       const result_type __m = std::log(__r) / std::log(2.0L);
00714       result_type __n, __n0, __y0, __y1, __s0, __s1;
00715       for (size_t __i = 0; __i < 2; ++__i)
00716     {
00717       __n = (__w + __m - 1) / __m + __i;
00718       __n0 = __n - __w % __n;
00719       const result_type __w0 = __w / __n;
00720       const result_type __w1 = __w0 + 1;
00721       __s0 = result_type(1) << __w0;
00722       __s1 = result_type(1) << __w1;
00723       __y0 = __s0 * (__r / __s0);
00724       __y1 = __s1 * (__r / __s1);
00725       if (__r - __y0 <= __y0 / __n)
00726         break;
00727     }
00728 
00729       result_type __sum = 0;
00730       for (size_t __k = 0; __k < __n0; ++__k)
00731     {
00732       result_type __u;
00733       do
00734         __u = _M_b() - _M_b.min();
00735       while (__u >= __y0);
00736       __sum = __s0 * __sum + __u % __s0;
00737     }
00738       for (size_t __k = __n0; __k < __n; ++__k)
00739     {
00740       result_type __u;
00741       do
00742         __u = _M_b() - _M_b.min();
00743       while (__u >= __y1);
00744       __sum = __s1 * __sum + __u % __s1;
00745     }
00746       return __sum;
00747     }
00748 
00749 
00750   template<typename _RandomNumberEngine, size_t __k>
00751     const size_t
00752     shuffle_order_engine<_RandomNumberEngine, __k>::table_size;
00753 
00754   template<typename _RandomNumberEngine, size_t __k>
00755     typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type
00756     shuffle_order_engine<_RandomNumberEngine, __k>::
00757     operator()()
00758     {
00759       size_t __j = __k * ((_M_y - _M_b.min())
00760               / (_M_b.max() - _M_b.min() + 1.0L));
00761       _M_y = _M_v[__j];
00762       _M_v[__j] = _M_b();
00763 
00764       return _M_y;
00765     }
00766 
00767   template<typename _RandomNumberEngine, size_t __k,
00768        typename _CharT, typename _Traits>
00769     std::basic_ostream<_CharT, _Traits>&
00770     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00771            const shuffle_order_engine<_RandomNumberEngine, __k>& __x)
00772     {
00773       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00774       typedef typename __ostream_type::ios_base    __ios_base;
00775 
00776       const typename __ios_base::fmtflags __flags = __os.flags();
00777       const _CharT __fill = __os.fill();
00778       const _CharT __space = __os.widen(' ');
00779       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
00780       __os.fill(__space);
00781 
00782       __os << __x.base();
00783       for (size_t __i = 0; __i < __k; ++__i)
00784     __os << __space << __x._M_v[__i];
00785       __os << __space << __x._M_y;
00786 
00787       __os.flags(__flags);
00788       __os.fill(__fill);
00789       return __os;
00790     }
00791 
00792   template<typename _RandomNumberEngine, size_t __k,
00793        typename _CharT, typename _Traits>
00794     std::basic_istream<_CharT, _Traits>&
00795     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00796            shuffle_order_engine<_RandomNumberEngine, __k>& __x)
00797     {
00798       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
00799       typedef typename __istream_type::ios_base    __ios_base;
00800 
00801       const typename __ios_base::fmtflags __flags = __is.flags();
00802       __is.flags(__ios_base::dec | __ios_base::skipws);
00803 
00804       __is >> __x._M_b;
00805       for (size_t __i = 0; __i < __k; ++__i)
00806     __is >> __x._M_v[__i];
00807       __is >> __x._M_y;
00808 
00809       __is.flags(__flags);
00810       return __is;
00811     }
00812 
00813 
00814   template<typename _IntType>
00815     template<typename _UniformRandomNumberGenerator>
00816       typename uniform_int_distribution<_IntType>::result_type
00817       uniform_int_distribution<_IntType>::
00818       operator()(_UniformRandomNumberGenerator& __urng,
00819          const param_type& __param)
00820       {
00821     // XXX Must be fixed to work well for *arbitrary* __urng.max(),
00822     // __urng.min(), __param.b(), __param.a().  Currently works fine only
00823     // in the most common case __urng.max() - __urng.min() >=
00824     // __param.b() - __param.a(), with __urng.max() > __urng.min() >= 0.
00825     typedef typename std::make_unsigned<typename
00826       _UniformRandomNumberGenerator::result_type>::type __urntype;
00827     typedef typename std::make_unsigned<result_type>::type __utype;
00828     typedef typename std::conditional<(sizeof(__urntype) > sizeof(__utype)),
00829       __urntype, __utype>::type __uctype;
00830 
00831     result_type __ret;
00832 
00833     const __urntype __urnmin = __urng.min();
00834     const __urntype __urnmax = __urng.max();
00835     const __urntype __urnrange = __urnmax - __urnmin;
00836     const __uctype __urange = __param.b() - __param.a();
00837     const __uctype __udenom = (__urnrange <= __urange
00838                    ? 1 : __urnrange / (__urange + 1));
00839     do
00840       __ret = (__urntype(__urng()) -  __urnmin) / __udenom;
00841     while (__ret > __param.b() - __param.a());
00842 
00843     return __ret + __param.a();
00844       }
00845 
00846   template<typename _IntType, typename _CharT, typename _Traits>
00847     std::basic_ostream<_CharT, _Traits>&
00848     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00849            const uniform_int_distribution<_IntType>& __x)
00850     {
00851       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00852       typedef typename __ostream_type::ios_base    __ios_base;
00853 
00854       const typename __ios_base::fmtflags __flags = __os.flags();
00855       const _CharT __fill = __os.fill();
00856       const _CharT __space = __os.widen(' ');
00857       __os.flags(__ios_base::scientific | __ios_base::left);
00858       __os.fill(__space);
00859 
00860       __os << __x.a() << __space << __x.b();
00861 
00862       __os.flags(__flags);
00863       __os.fill(__fill);
00864       return __os;
00865     }
00866 
00867   template<typename _IntType, typename _CharT, typename _Traits>
00868     std::basic_istream<_CharT, _Traits>&
00869     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00870            uniform_int_distribution<_IntType>& __x)
00871     {
00872       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
00873       typedef typename __istream_type::ios_base    __ios_base;
00874 
00875       const typename __ios_base::fmtflags __flags = __is.flags();
00876       __is.flags(__ios_base::dec | __ios_base::skipws);
00877 
00878       _IntType __a, __b;
00879       __is >> __a >> __b;
00880       __x.param(typename uniform_int_distribution<_IntType>::
00881         param_type(__a, __b));
00882 
00883       __is.flags(__flags);
00884       return __is;
00885     }
00886 
00887 
00888   template<typename _RealType, typename _CharT, typename _Traits>
00889     std::basic_ostream<_CharT, _Traits>&
00890     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00891            const uniform_real_distribution<_RealType>& __x)
00892     {
00893       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00894       typedef typename __ostream_type::ios_base    __ios_base;
00895 
00896       const typename __ios_base::fmtflags __flags = __os.flags();
00897       const _CharT __fill = __os.fill();
00898       const std::streamsize __precision = __os.precision();
00899       const _CharT __space = __os.widen(' ');
00900       __os.flags(__ios_base::scientific | __ios_base::left);
00901       __os.fill(__space);
00902       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
00903 
00904       __os << __x.a() << __space << __x.b();
00905 
00906       __os.flags(__flags);
00907       __os.fill(__fill);
00908       __os.precision(__precision);
00909       return __os;
00910     }
00911 
00912   template<typename _RealType, typename _CharT, typename _Traits>
00913     std::basic_istream<_CharT, _Traits>&
00914     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00915            uniform_real_distribution<_RealType>& __x)
00916     {
00917       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
00918       typedef typename __istream_type::ios_base    __ios_base;
00919 
00920       const typename __ios_base::fmtflags __flags = __is.flags();
00921       __is.flags(__ios_base::skipws);
00922 
00923       _RealType __a, __b;
00924       __is >> __a >> __b;
00925       __x.param(typename uniform_real_distribution<_RealType>::
00926         param_type(__a, __b));
00927 
00928       __is.flags(__flags);
00929       return __is;
00930     }
00931 
00932 
00933   template<typename _CharT, typename _Traits>
00934     std::basic_ostream<_CharT, _Traits>&
00935     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00936            const bernoulli_distribution& __x)
00937     {
00938       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00939       typedef typename __ostream_type::ios_base    __ios_base;
00940 
00941       const typename __ios_base::fmtflags __flags = __os.flags();
00942       const _CharT __fill = __os.fill();
00943       const std::streamsize __precision = __os.precision();
00944       __os.flags(__ios_base::scientific | __ios_base::left);
00945       __os.fill(__os.widen(' '));
00946       __os.precision(std::numeric_limits<double>::digits10 + 1);
00947 
00948       __os << __x.p();
00949 
00950       __os.flags(__flags);
00951       __os.fill(__fill);
00952       __os.precision(__precision);
00953       return __os;
00954     }
00955 
00956 
00957   template<typename _IntType>
00958     template<typename _UniformRandomNumberGenerator>
00959       typename geometric_distribution<_IntType>::result_type
00960       geometric_distribution<_IntType>::
00961       operator()(_UniformRandomNumberGenerator& __urng,
00962          const param_type& __param)
00963       {
00964     // About the epsilon thing see this thread:
00965     // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
00966     const double __naf =
00967       (1 - std::numeric_limits<double>::epsilon()) / 2;
00968     // The largest _RealType convertible to _IntType.
00969     const double __thr =
00970       std::numeric_limits<_IntType>::max() + __naf;
00971     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
00972       __aurng(__urng);
00973 
00974     double __cand;
00975     do
00976       __cand = std::ceil(std::log(__aurng()) / __param._M_log_p);
00977     while (__cand >= __thr);
00978 
00979     return result_type(__cand + __naf);
00980       }
00981 
00982   template<typename _IntType,
00983        typename _CharT, typename _Traits>
00984     std::basic_ostream<_CharT, _Traits>&
00985     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00986            const geometric_distribution<_IntType>& __x)
00987     {
00988       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
00989       typedef typename __ostream_type::ios_base    __ios_base;
00990 
00991       const typename __ios_base::fmtflags __flags = __os.flags();
00992       const _CharT __fill = __os.fill();
00993       const std::streamsize __precision = __os.precision();
00994       __os.flags(__ios_base::scientific | __ios_base::left);
00995       __os.fill(__os.widen(' '));
00996       __os.precision(std::numeric_limits<double>::digits10 + 1);
00997 
00998       __os << __x.p();
00999 
01000       __os.flags(__flags);
01001       __os.fill(__fill);
01002       __os.precision(__precision);
01003       return __os;
01004     }
01005 
01006   template<typename _IntType,
01007        typename _CharT, typename _Traits>
01008     std::basic_istream<_CharT, _Traits>&
01009     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01010            geometric_distribution<_IntType>& __x)
01011     {
01012       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01013       typedef typename __istream_type::ios_base    __ios_base;
01014 
01015       const typename __ios_base::fmtflags __flags = __is.flags();
01016       __is.flags(__ios_base::skipws);
01017 
01018       double __p;
01019       __is >> __p;
01020       __x.param(typename geometric_distribution<_IntType>::param_type(__p));
01021 
01022       __is.flags(__flags);
01023       return __is;
01024     }
01025 
01026 
01027   template<typename _IntType>
01028     template<typename _UniformRandomNumberGenerator>
01029       typename negative_binomial_distribution<_IntType>::result_type
01030       negative_binomial_distribution<_IntType>::
01031       operator()(_UniformRandomNumberGenerator& __urng)
01032       {
01033     const double __y = _M_gd(__urng);
01034 
01035     // XXX Is the constructor too slow?
01036     std::poisson_distribution<result_type> __poisson(__y);
01037     return __poisson(__urng);
01038       }
01039 
01040   template<typename _IntType>
01041     template<typename _UniformRandomNumberGenerator>
01042       typename negative_binomial_distribution<_IntType>::result_type
01043       negative_binomial_distribution<_IntType>::
01044       operator()(_UniformRandomNumberGenerator& __urng,
01045          const param_type& __p)
01046       {
01047     typedef typename std::gamma_distribution<result_type>::param_type
01048       param_type;
01049     
01050     const double __y =
01051       _M_gd(__urng, param_type(__p.k(), __p.p() / (1.0 - __p.p())));
01052 
01053     std::poisson_distribution<result_type> __poisson(__y);
01054     return __poisson(__urng);
01055       }
01056 
01057   template<typename _IntType, typename _CharT, typename _Traits>
01058     std::basic_ostream<_CharT, _Traits>&
01059     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01060            const negative_binomial_distribution<_IntType>& __x)
01061     {
01062       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01063       typedef typename __ostream_type::ios_base    __ios_base;
01064 
01065       const typename __ios_base::fmtflags __flags = __os.flags();
01066       const _CharT __fill = __os.fill();
01067       const std::streamsize __precision = __os.precision();
01068       const _CharT __space = __os.widen(' ');
01069       __os.flags(__ios_base::scientific | __ios_base::left);
01070       __os.fill(__os.widen(' '));
01071       __os.precision(std::numeric_limits<double>::digits10 + 1);
01072 
01073       __os << __x.k() << __space << __x.p()
01074        << __space << __x._M_gd;
01075 
01076       __os.flags(__flags);
01077       __os.fill(__fill);
01078       __os.precision(__precision);
01079       return __os;
01080     }
01081 
01082   template<typename _IntType, typename _CharT, typename _Traits>
01083     std::basic_istream<_CharT, _Traits>&
01084     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01085            negative_binomial_distribution<_IntType>& __x)
01086     {
01087       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01088       typedef typename __istream_type::ios_base    __ios_base;
01089 
01090       const typename __ios_base::fmtflags __flags = __is.flags();
01091       __is.flags(__ios_base::skipws);
01092 
01093       _IntType __k;
01094       double __p;
01095       __is >> __k >> __p >> __x._M_gd;
01096       __x.param(typename negative_binomial_distribution<_IntType>::
01097         param_type(__k, __p));
01098 
01099       __is.flags(__flags);
01100       return __is;
01101     }
01102 
01103 
01104   template<typename _IntType>
01105     void
01106     poisson_distribution<_IntType>::param_type::
01107     _M_initialize()
01108     {
01109 #if _GLIBCXX_USE_C99_MATH_TR1
01110       if (_M_mean >= 12)
01111     {
01112       const double __m = std::floor(_M_mean);
01113       _M_lm_thr = std::log(_M_mean);
01114       _M_lfm = std::lgamma(__m + 1);
01115       _M_sm = std::sqrt(__m);
01116 
01117       const double __pi_4 = 0.7853981633974483096156608458198757L;
01118       const double __dx = std::sqrt(2 * __m * std::log(32 * __m
01119                                   / __pi_4));
01120       _M_d = std::round(std::max(6.0, std::min(__m, __dx)));
01121       const double __cx = 2 * __m + _M_d;
01122       _M_scx = std::sqrt(__cx / 2);
01123       _M_1cx = 1 / __cx;
01124 
01125       _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
01126       _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2))
01127         / _M_d;
01128     }
01129       else
01130 #endif
01131     _M_lm_thr = std::exp(-_M_mean);
01132       }
01133 
01134   /**
01135    * A rejection algorithm when mean >= 12 and a simple method based
01136    * upon the multiplication of uniform random variates otherwise.
01137    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
01138    * is defined.
01139    *
01140    * Reference:
01141    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
01142    * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
01143    */
01144   template<typename _IntType>
01145     template<typename _UniformRandomNumberGenerator>
01146       typename poisson_distribution<_IntType>::result_type
01147       poisson_distribution<_IntType>::
01148       operator()(_UniformRandomNumberGenerator& __urng,
01149          const param_type& __param)
01150       {
01151     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
01152       __aurng(__urng);
01153 #if _GLIBCXX_USE_C99_MATH_TR1
01154     if (__param.mean() >= 12)
01155       {
01156         double __x;
01157 
01158         // See comments above...
01159         const double __naf =
01160           (1 - std::numeric_limits<double>::epsilon()) / 2;
01161         const double __thr =
01162           std::numeric_limits<_IntType>::max() + __naf;
01163 
01164         const double __m = std::floor(__param.mean());
01165         // sqrt(pi / 2)
01166         const double __spi_2 = 1.2533141373155002512078826424055226L;
01167         const double __c1 = __param._M_sm * __spi_2;
01168         const double __c2 = __param._M_c2b + __c1;
01169         const double __c3 = __c2 + 1;
01170         const double __c4 = __c3 + 1;
01171         // e^(1 / 78)
01172         const double __e178 = 1.0129030479320018583185514777512983L;
01173         const double __c5 = __c4 + __e178;
01174         const double __c = __param._M_cb + __c5;
01175         const double __2cx = 2 * (2 * __m + __param._M_d);
01176 
01177         bool __reject = true;
01178         do
01179           {
01180         const double __u = __c * __aurng();
01181         const double __e = -std::log(__aurng());
01182 
01183         double __w = 0.0;
01184 
01185         if (__u <= __c1)
01186           {
01187             const double __n = _M_nd(__urng);
01188             const double __y = -std::abs(__n) * __param._M_sm - 1;
01189             __x = std::floor(__y);
01190             __w = -__n * __n / 2;
01191             if (__x < -__m)
01192               continue;
01193           }
01194         else if (__u <= __c2)
01195           {
01196             const double __n = _M_nd(__urng);
01197             const double __y = 1 + std::abs(__n) * __param._M_scx;
01198             __x = std::ceil(__y);
01199             __w = __y * (2 - __y) * __param._M_1cx;
01200             if (__x > __param._M_d)
01201               continue;
01202           }
01203         else if (__u <= __c3)
01204           // NB: This case not in the book, nor in the Errata,
01205           // but should be ok...
01206           __x = -1;
01207         else if (__u <= __c4)
01208           __x = 0;
01209         else if (__u <= __c5)
01210           __x = 1;
01211         else
01212           {
01213             const double __v = -std::log(__aurng());
01214             const double __y = __param._M_d
01215                      + __v * __2cx / __param._M_d;
01216             __x = std::ceil(__y);
01217             __w = -__param._M_d * __param._M_1cx * (1 + __y / 2);
01218           }
01219 
01220         __reject = (__w - __e - __x * __param._M_lm_thr
01221                 > __param._M_lfm - std::lgamma(__x + __m + 1));
01222 
01223         __reject |= __x + __m >= __thr;
01224 
01225           } while (__reject);
01226 
01227         return result_type(__x + __m + __naf);
01228       }
01229     else
01230 #endif
01231       {
01232         _IntType     __x = 0;
01233         double __prod = 1.0;
01234 
01235         do
01236           {
01237         __prod *= __aurng();
01238         __x += 1;
01239           }
01240         while (__prod > __param._M_lm_thr);
01241 
01242         return __x - 1;
01243       }
01244       }
01245 
01246   template<typename _IntType,
01247        typename _CharT, typename _Traits>
01248     std::basic_ostream<_CharT, _Traits>&
01249     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01250            const poisson_distribution<_IntType>& __x)
01251     {
01252       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01253       typedef typename __ostream_type::ios_base    __ios_base;
01254 
01255       const typename __ios_base::fmtflags __flags = __os.flags();
01256       const _CharT __fill = __os.fill();
01257       const std::streamsize __precision = __os.precision();
01258       const _CharT __space = __os.widen(' ');
01259       __os.flags(__ios_base::scientific | __ios_base::left);
01260       __os.fill(__space);
01261       __os.precision(std::numeric_limits<double>::digits10 + 1);
01262 
01263       __os << __x.mean() << __space << __x._M_nd;
01264 
01265       __os.flags(__flags);
01266       __os.fill(__fill);
01267       __os.precision(__precision);
01268       return __os;
01269     }
01270 
01271   template<typename _IntType,
01272        typename _CharT, typename _Traits>
01273     std::basic_istream<_CharT, _Traits>&
01274     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01275            poisson_distribution<_IntType>& __x)
01276     {
01277       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01278       typedef typename __istream_type::ios_base    __ios_base;
01279 
01280       const typename __ios_base::fmtflags __flags = __is.flags();
01281       __is.flags(__ios_base::skipws);
01282 
01283       double __mean;
01284       __is >> __mean >> __x._M_nd;
01285       __x.param(typename poisson_distribution<_IntType>::param_type(__mean));
01286 
01287       __is.flags(__flags);
01288       return __is;
01289     }
01290 
01291 
01292   template<typename _IntType>
01293     void
01294     binomial_distribution<_IntType>::param_type::
01295     _M_initialize()
01296     {
01297       const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
01298 
01299       _M_easy = true;
01300 
01301 #if _GLIBCXX_USE_C99_MATH_TR1
01302       if (_M_t * __p12 >= 8)
01303     {
01304       _M_easy = false;
01305       const double __np = std::floor(_M_t * __p12);
01306       const double __pa = __np / _M_t;
01307       const double __1p = 1 - __pa;
01308 
01309       const double __pi_4 = 0.7853981633974483096156608458198757L;
01310       const double __d1x =
01311         std::sqrt(__np * __1p * std::log(32 * __np
01312                          / (81 * __pi_4 * __1p)));
01313       _M_d1 = std::round(std::max(1.0, __d1x));
01314       const double __d2x =
01315         std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
01316                          / (__pi_4 * __pa)));
01317       _M_d2 = std::round(std::max(1.0, __d2x));
01318 
01319       // sqrt(pi / 2)
01320       const double __spi_2 = 1.2533141373155002512078826424055226L;
01321       _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
01322       _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
01323       _M_c = 2 * _M_d1 / __np;
01324       _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
01325       const double __a12 = _M_a1 + _M_s2 * __spi_2;
01326       const double __s1s = _M_s1 * _M_s1;
01327       _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
01328                  * 2 * __s1s / _M_d1
01329                  * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
01330       const double __s2s = _M_s2 * _M_s2;
01331       _M_s = (_M_a123 + 2 * __s2s / _M_d2
01332           * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
01333       _M_lf = (std::lgamma(__np + 1)
01334            + std::lgamma(_M_t - __np + 1));
01335       _M_lp1p = std::log(__pa / __1p);
01336 
01337       _M_q = -std::log(1 - (__p12 - __pa) / __1p);
01338     }
01339       else
01340 #endif
01341     _M_q = -std::log(1 - __p12);
01342     }
01343 
01344   template<typename _IntType>
01345     template<typename _UniformRandomNumberGenerator>
01346       typename binomial_distribution<_IntType>::result_type
01347       binomial_distribution<_IntType>::
01348       _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
01349       {
01350     _IntType __x = 0;
01351     double __sum = 0.0;
01352     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
01353       __aurng(__urng);
01354 
01355     do
01356       {
01357         const double __e = -std::log(__aurng());
01358         __sum += __e / (__t - __x);
01359         __x += 1;
01360       }
01361     while (__sum <= _M_param._M_q);
01362 
01363     return __x - 1;
01364       }
01365 
01366   /**
01367    * A rejection algorithm when t * p >= 8 and a simple waiting time
01368    * method - the second in the referenced book - otherwise.
01369    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
01370    * is defined.
01371    *
01372    * Reference:
01373    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
01374    * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
01375    */
01376   template<typename _IntType>
01377     template<typename _UniformRandomNumberGenerator>
01378       typename binomial_distribution<_IntType>::result_type
01379       binomial_distribution<_IntType>::
01380       operator()(_UniformRandomNumberGenerator& __urng,
01381          const param_type& __param)
01382       {
01383     result_type __ret;
01384     const _IntType __t = __param.t();
01385     const _IntType __p = __param.p();
01386     const double __p12 = __p <= 0.5 ? __p : 1.0 - __p;
01387     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
01388       __aurng(__urng);
01389 
01390 #if _GLIBCXX_USE_C99_MATH_TR1
01391     if (!__param._M_easy)
01392       {
01393         double __x;
01394 
01395         // See comments above...
01396         const double __naf =
01397           (1 - std::numeric_limits<double>::epsilon()) / 2;
01398         const double __thr =
01399           std::numeric_limits<_IntType>::max() + __naf;
01400 
01401         const double __np = std::floor(__t * __p12);
01402 
01403         // sqrt(pi / 2)
01404         const double __spi_2 = 1.2533141373155002512078826424055226L;
01405         const double __a1 = __param._M_a1;
01406         const double __a12 = __a1 + __param._M_s2 * __spi_2;
01407         const double __a123 = __param._M_a123;
01408         const double __s1s = __param._M_s1 * __param._M_s1;
01409         const double __s2s = __param._M_s2 * __param._M_s2;
01410 
01411         bool __reject;
01412         do
01413           {
01414         const double __u = __param._M_s * __aurng();
01415 
01416         double __v;
01417 
01418         if (__u <= __a1)
01419           {
01420             const double __n = _M_nd(__urng);
01421             const double __y = __param._M_s1 * std::abs(__n);
01422             __reject = __y >= __param._M_d1;
01423             if (!__reject)
01424               {
01425             const double __e = -std::log(__aurng());
01426             __x = std::floor(__y);
01427             __v = -__e - __n * __n / 2 + __param._M_c;
01428               }
01429           }
01430         else if (__u <= __a12)
01431           {
01432             const double __n = _M_nd(__urng);
01433             const double __y = __param._M_s2 * std::abs(__n);
01434             __reject = __y >= __param._M_d2;
01435             if (!__reject)
01436               {
01437             const double __e = -std::log(__aurng());
01438             __x = std::floor(-__y);
01439             __v = -__e - __n * __n / 2;
01440               }
01441           }
01442         else if (__u <= __a123)
01443           {
01444             const double __e1 = -std::log(__aurng());
01445             const double __e2 = -std::log(__aurng());
01446 
01447             const double __y = __param._M_d1
01448                      + 2 * __s1s * __e1 / __param._M_d1;
01449             __x = std::floor(__y);
01450             __v = (-__e2 + __param._M_d1 * (1 / (__t - __np)
01451                             -__y / (2 * __s1s)));
01452             __reject = false;
01453           }
01454         else
01455           {
01456             const double __e1 = -std::log(__aurng());
01457             const double __e2 = -std::log(__aurng());
01458 
01459             const double __y = __param._M_d2
01460                      + 2 * __s2s * __e1 / __param._M_d2;
01461             __x = std::floor(-__y);
01462             __v = -__e2 - __param._M_d2 * __y / (2 * __s2s);
01463             __reject = false;
01464           }
01465 
01466         __reject = __reject || __x < -__np || __x > __t - __np;
01467         if (!__reject)
01468           {
01469             const double __lfx =
01470               std::lgamma(__np + __x + 1)
01471               + std::lgamma(__t - (__np + __x) + 1);
01472             __reject = __v > __param._M_lf - __lfx
01473                  + __x * __param._M_lp1p;
01474           }
01475 
01476         __reject |= __x + __np >= __thr;
01477           }
01478         while (__reject);
01479 
01480         __x += __np + __naf;
01481 
01482         const _IntType __z = _M_waiting(__urng, __t - _IntType(__x));
01483         __ret = _IntType(__x) + __z;
01484       }
01485     else
01486 #endif
01487       __ret = _M_waiting(__urng, __t);
01488 
01489     if (__p12 != __p)
01490       __ret = __t - __ret;
01491     return __ret;
01492       }
01493 
01494   template<typename _IntType,
01495        typename _CharT, typename _Traits>
01496     std::basic_ostream<_CharT, _Traits>&
01497     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01498            const binomial_distribution<_IntType>& __x)
01499     {
01500       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01501       typedef typename __ostream_type::ios_base    __ios_base;
01502 
01503       const typename __ios_base::fmtflags __flags = __os.flags();
01504       const _CharT __fill = __os.fill();
01505       const std::streamsize __precision = __os.precision();
01506       const _CharT __space = __os.widen(' ');
01507       __os.flags(__ios_base::scientific | __ios_base::left);
01508       __os.fill(__space);
01509       __os.precision(std::numeric_limits<double>::digits10 + 1);
01510 
01511       __os << __x.t() << __space << __x.p()
01512        << __space << __x._M_nd;
01513 
01514       __os.flags(__flags);
01515       __os.fill(__fill);
01516       __os.precision(__precision);
01517       return __os;
01518     }
01519 
01520   template<typename _IntType,
01521        typename _CharT, typename _Traits>
01522     std::basic_istream<_CharT, _Traits>&
01523     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01524            binomial_distribution<_IntType>& __x)
01525     {
01526       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01527       typedef typename __istream_type::ios_base    __ios_base;
01528 
01529       const typename __ios_base::fmtflags __flags = __is.flags();
01530       __is.flags(__ios_base::dec | __ios_base::skipws);
01531 
01532       _IntType __t;
01533       double __p;
01534       __is >> __t >> __p >> __x._M_nd;
01535       __x.param(typename binomial_distribution<_IntType>::
01536         param_type(__t, __p));
01537 
01538       __is.flags(__flags);
01539       return __is;
01540     }
01541 
01542 
01543   template<typename _RealType, typename _CharT, typename _Traits>
01544     std::basic_ostream<_CharT, _Traits>&
01545     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01546            const exponential_distribution<_RealType>& __x)
01547     {
01548       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01549       typedef typename __ostream_type::ios_base    __ios_base;
01550 
01551       const typename __ios_base::fmtflags __flags = __os.flags();
01552       const _CharT __fill = __os.fill();
01553       const std::streamsize __precision = __os.precision();
01554       __os.flags(__ios_base::scientific | __ios_base::left);
01555       __os.fill(__os.widen(' '));
01556       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01557 
01558       __os << __x.lambda();
01559 
01560       __os.flags(__flags);
01561       __os.fill(__fill);
01562       __os.precision(__precision);
01563       return __os;
01564     }
01565 
01566   template<typename _RealType, typename _CharT, typename _Traits>
01567     std::basic_istream<_CharT, _Traits>&
01568     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01569            exponential_distribution<_RealType>& __x)
01570     {
01571       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01572       typedef typename __istream_type::ios_base    __ios_base;
01573 
01574       const typename __ios_base::fmtflags __flags = __is.flags();
01575       __is.flags(__ios_base::dec | __ios_base::skipws);
01576 
01577       _RealType __lambda;
01578       __is >> __lambda;
01579       __x.param(typename exponential_distribution<_RealType>::
01580         param_type(__lambda));
01581 
01582       __is.flags(__flags);
01583       return __is;
01584     }
01585 
01586 
01587   /**
01588    * Polar method due to Marsaglia.
01589    *
01590    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
01591    * New York, 1986, Ch. V, Sect. 4.4.
01592    */
01593   template<typename _RealType>
01594     template<typename _UniformRandomNumberGenerator>
01595       typename normal_distribution<_RealType>::result_type
01596       normal_distribution<_RealType>::
01597       operator()(_UniformRandomNumberGenerator& __urng,
01598          const param_type& __param)
01599       {
01600     result_type __ret;
01601     __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
01602       __aurng(__urng);
01603 
01604     if (_M_saved_available)
01605       {
01606         _M_saved_available = false;
01607         __ret = _M_saved;
01608       }
01609     else
01610       {
01611         result_type __x, __y, __r2;
01612         do
01613           {
01614         __x = result_type(2.0) * __aurng() - 1.0;
01615         __y = result_type(2.0) * __aurng() - 1.0;
01616         __r2 = __x * __x + __y * __y;
01617           }
01618         while (__r2 > 1.0 || __r2 == 0.0);
01619 
01620         const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
01621         _M_saved = __x * __mult;
01622         _M_saved_available = true;
01623         __ret = __y * __mult;
01624       }
01625 
01626     __ret = __ret * __param.stddev() + __param.mean();
01627     return __ret;
01628       }
01629 
01630   template<typename _RealType, typename _CharT, typename _Traits>
01631     std::basic_ostream<_CharT, _Traits>&
01632     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01633            const normal_distribution<_RealType>& __x)
01634     {
01635       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01636       typedef typename __ostream_type::ios_base    __ios_base;
01637 
01638       const typename __ios_base::fmtflags __flags = __os.flags();
01639       const _CharT __fill = __os.fill();
01640       const std::streamsize __precision = __os.precision();
01641       const _CharT __space = __os.widen(' ');
01642       __os.flags(__ios_base::scientific | __ios_base::left);
01643       __os.fill(__space);
01644       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01645 
01646       __os << __x.mean() << __space << __x.stddev()
01647        << __space << __x._M_saved_available;
01648       if (__x._M_saved_available)
01649     __os << __space << __x._M_saved;
01650 
01651       __os.flags(__flags);
01652       __os.fill(__fill);
01653       __os.precision(__precision);
01654       return __os;
01655     }
01656 
01657   template<typename _RealType, typename _CharT, typename _Traits>
01658     std::basic_istream<_CharT, _Traits>&
01659     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01660            normal_distribution<_RealType>& __x)
01661     {
01662       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01663       typedef typename __istream_type::ios_base    __ios_base;
01664 
01665       const typename __ios_base::fmtflags __flags = __is.flags();
01666       __is.flags(__ios_base::dec | __ios_base::skipws);
01667 
01668       double __mean, __stddev;
01669       __is >> __mean >> __stddev
01670        >> __x._M_saved_available;
01671       if (__x._M_saved_available)
01672     __is >> __x._M_saved;
01673       __x.param(typename normal_distribution<_RealType>::
01674         param_type(__mean, __stddev));
01675 
01676       __is.flags(__flags);
01677       return __is;
01678     }
01679 
01680 
01681   template<typename _RealType, typename _CharT, typename _Traits>
01682     std::basic_ostream<_CharT, _Traits>&
01683     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01684            const lognormal_distribution<_RealType>& __x)
01685     {
01686       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01687       typedef typename __ostream_type::ios_base    __ios_base;
01688 
01689       const typename __ios_base::fmtflags __flags = __os.flags();
01690       const _CharT __fill = __os.fill();
01691       const std::streamsize __precision = __os.precision();
01692       const _CharT __space = __os.widen(' ');
01693       __os.flags(__ios_base::scientific | __ios_base::left);
01694       __os.fill(__space);
01695       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01696 
01697       __os << __x.m() << __space << __x.s()
01698        << __space << __x._M_nd;
01699 
01700       __os.flags(__flags);
01701       __os.fill(__fill);
01702       __os.precision(__precision);
01703       return __os;
01704     }
01705 
01706   template<typename _RealType, typename _CharT, typename _Traits>
01707     std::basic_istream<_CharT, _Traits>&
01708     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01709            lognormal_distribution<_RealType>& __x)
01710     {
01711       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01712       typedef typename __istream_type::ios_base    __ios_base;
01713 
01714       const typename __ios_base::fmtflags __flags = __is.flags();
01715       __is.flags(__ios_base::dec | __ios_base::skipws);
01716 
01717       _RealType __m, __s;
01718       __is >> __m >> __s >> __x._M_nd;
01719       __x.param(typename lognormal_distribution<_RealType>::
01720         param_type(__m, __s));
01721 
01722       __is.flags(__flags);
01723       return __is;
01724     }
01725 
01726 
01727   template<typename _RealType, typename _CharT, typename _Traits>
01728     std::basic_ostream<_CharT, _Traits>&
01729     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01730            const chi_squared_distribution<_RealType>& __x)
01731     {
01732       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01733       typedef typename __ostream_type::ios_base    __ios_base;
01734 
01735       const typename __ios_base::fmtflags __flags = __os.flags();
01736       const _CharT __fill = __os.fill();
01737       const std::streamsize __precision = __os.precision();
01738       const _CharT __space = __os.widen(' ');
01739       __os.flags(__ios_base::scientific | __ios_base::left);
01740       __os.fill(__space);
01741       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01742 
01743       __os << __x.n() << __space << __x._M_gd;
01744 
01745       __os.flags(__flags);
01746       __os.fill(__fill);
01747       __os.precision(__precision);
01748       return __os;
01749     }
01750 
01751   template<typename _RealType, typename _CharT, typename _Traits>
01752     std::basic_istream<_CharT, _Traits>&
01753     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01754            chi_squared_distribution<_RealType>& __x)
01755     {
01756       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01757       typedef typename __istream_type::ios_base    __ios_base;
01758 
01759       const typename __ios_base::fmtflags __flags = __is.flags();
01760       __is.flags(__ios_base::dec | __ios_base::skipws);
01761 
01762       _RealType __n;
01763       __is >> __n >> __x._M_gd;
01764       __x.param(typename chi_squared_distribution<_RealType>::
01765         param_type(__n));
01766 
01767       __is.flags(__flags);
01768       return __is;
01769     }
01770 
01771 
01772   template<typename _RealType>
01773     template<typename _UniformRandomNumberGenerator>
01774       typename cauchy_distribution<_RealType>::result_type
01775       cauchy_distribution<_RealType>::
01776       operator()(_UniformRandomNumberGenerator& __urng,
01777          const param_type& __p)
01778       {
01779     __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
01780       __aurng(__urng);
01781     _RealType __u;
01782     do
01783       __u = __aurng();
01784     while (__u == 0.5);
01785 
01786     const _RealType __pi = 3.1415926535897932384626433832795029L;
01787     return __p.a() + __p.b() * std::tan(__pi * __u);
01788       }
01789 
01790   template<typename _RealType, typename _CharT, typename _Traits>
01791     std::basic_ostream<_CharT, _Traits>&
01792     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01793            const cauchy_distribution<_RealType>& __x)
01794     {
01795       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01796       typedef typename __ostream_type::ios_base    __ios_base;
01797 
01798       const typename __ios_base::fmtflags __flags = __os.flags();
01799       const _CharT __fill = __os.fill();
01800       const std::streamsize __precision = __os.precision();
01801       const _CharT __space = __os.widen(' ');
01802       __os.flags(__ios_base::scientific | __ios_base::left);
01803       __os.fill(__space);
01804       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01805 
01806       __os << __x.a() << __space << __x.b();
01807 
01808       __os.flags(__flags);
01809       __os.fill(__fill);
01810       __os.precision(__precision);
01811       return __os;
01812     }
01813 
01814   template<typename _RealType, typename _CharT, typename _Traits>
01815     std::basic_istream<_CharT, _Traits>&
01816     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01817            cauchy_distribution<_RealType>& __x)
01818     {
01819       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01820       typedef typename __istream_type::ios_base    __ios_base;
01821 
01822       const typename __ios_base::fmtflags __flags = __is.flags();
01823       __is.flags(__ios_base::dec | __ios_base::skipws);
01824 
01825       _RealType __a, __b;
01826       __is >> __a >> __b;
01827       __x.param(typename cauchy_distribution<_RealType>::
01828         param_type(__a, __b));
01829 
01830       __is.flags(__flags);
01831       return __is;
01832     }
01833 
01834 
01835   template<typename _RealType, typename _CharT, typename _Traits>
01836     std::basic_ostream<_CharT, _Traits>&
01837     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01838            const fisher_f_distribution<_RealType>& __x)
01839     {
01840       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01841       typedef typename __ostream_type::ios_base    __ios_base;
01842 
01843       const typename __ios_base::fmtflags __flags = __os.flags();
01844       const _CharT __fill = __os.fill();
01845       const std::streamsize __precision = __os.precision();
01846       const _CharT __space = __os.widen(' ');
01847       __os.flags(__ios_base::scientific | __ios_base::left);
01848       __os.fill(__space);
01849       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01850 
01851       __os << __x.m() << __space << __x.n()
01852        << __space << __x._M_gd_x << __space << __x._M_gd_y;
01853 
01854       __os.flags(__flags);
01855       __os.fill(__fill);
01856       __os.precision(__precision);
01857       return __os;
01858     }
01859 
01860   template<typename _RealType, typename _CharT, typename _Traits>
01861     std::basic_istream<_CharT, _Traits>&
01862     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01863            fisher_f_distribution<_RealType>& __x)
01864     {
01865       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01866       typedef typename __istream_type::ios_base    __ios_base;
01867 
01868       const typename __ios_base::fmtflags __flags = __is.flags();
01869       __is.flags(__ios_base::dec | __ios_base::skipws);
01870 
01871       _RealType __m, __n;
01872       __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y;
01873       __x.param(typename fisher_f_distribution<_RealType>::
01874         param_type(__m, __n));
01875 
01876       __is.flags(__flags);
01877       return __is;
01878     }
01879 
01880 
01881   template<typename _RealType, typename _CharT, typename _Traits>
01882     std::basic_ostream<_CharT, _Traits>&
01883     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01884            const student_t_distribution<_RealType>& __x)
01885     {
01886       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01887       typedef typename __ostream_type::ios_base    __ios_base;
01888 
01889       const typename __ios_base::fmtflags __flags = __os.flags();
01890       const _CharT __fill = __os.fill();
01891       const std::streamsize __precision = __os.precision();
01892       const _CharT __space = __os.widen(' ');
01893       __os.flags(__ios_base::scientific | __ios_base::left);
01894       __os.fill(__space);
01895       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01896 
01897       __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd;
01898 
01899       __os.flags(__flags);
01900       __os.fill(__fill);
01901       __os.precision(__precision);
01902       return __os;
01903     }
01904 
01905   template<typename _RealType, typename _CharT, typename _Traits>
01906     std::basic_istream<_CharT, _Traits>&
01907     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01908            student_t_distribution<_RealType>& __x)
01909     {
01910       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
01911       typedef typename __istream_type::ios_base    __ios_base;
01912 
01913       const typename __ios_base::fmtflags __flags = __is.flags();
01914       __is.flags(__ios_base::dec | __ios_base::skipws);
01915 
01916       _RealType __n;
01917       __is >> __n >> __x._M_nd >> __x._M_gd;
01918       __x.param(typename student_t_distribution<_RealType>::param_type(__n));
01919 
01920       __is.flags(__flags);
01921       return __is;
01922     }
01923 
01924 
01925   template<typename _RealType>
01926     void
01927     gamma_distribution<_RealType>::param_type::
01928     _M_initialize()
01929     {
01930       _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha;
01931 
01932       const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0);
01933       _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1);
01934     }
01935 
01936   /**
01937    * Marsaglia, G. and Tsang, W. W.
01938    * "A Simple Method for Generating Gamma Variables"
01939    * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000.
01940    */
01941   template<typename _RealType>
01942     template<typename _UniformRandomNumberGenerator>
01943       typename gamma_distribution<_RealType>::result_type
01944       gamma_distribution<_RealType>::
01945       operator()(_UniformRandomNumberGenerator& __urng,
01946          const param_type& __param)
01947       {
01948     __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
01949       __aurng(__urng);
01950 
01951     result_type __u, __v, __n;
01952     const result_type __a1 = (__param._M_malpha
01953                   - _RealType(1.0) / _RealType(3.0));
01954 
01955     do
01956       {
01957         do
01958           {
01959         __n = _M_nd(__urng);
01960         __v = result_type(1.0) + __param._M_a2 * __n; 
01961           }
01962         while (__v <= 0.0);
01963 
01964         __v = __v * __v * __v;
01965         __u = __aurng();
01966       }
01967     while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
01968            && (std::log(__u) > (0.5 * __n * __n + __a1
01969                     * (1.0 - __v + std::log(__v)))));
01970 
01971     if (__param.alpha() == __param._M_malpha)
01972       return __a1 * __v * __param.beta();
01973     else
01974       {
01975         do
01976           __u = __aurng();
01977         while (__u == 0.0);
01978         
01979         return (std::pow(__u, result_type(1.0) / __param.alpha())
01980             * __a1 * __v * __param.beta());
01981       }
01982       }
01983 
01984   template<typename _RealType, typename _CharT, typename _Traits>
01985     std::basic_ostream<_CharT, _Traits>&
01986     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01987            const gamma_distribution<_RealType>& __x)
01988     {
01989       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
01990       typedef typename __ostream_type::ios_base    __ios_base;
01991 
01992       const typename __ios_base::fmtflags __flags = __os.flags();
01993       const _CharT __fill = __os.fill();
01994       const std::streamsize __precision = __os.precision();
01995       const _CharT __space = __os.widen(' ');
01996       __os.flags(__ios_base::scientific | __ios_base::left);
01997       __os.fill(__space);
01998       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
01999 
02000       __os << __x.alpha() << __space << __x.beta()
02001        << __space << __x._M_nd;
02002 
02003       __os.flags(__flags);
02004       __os.fill(__fill);
02005       __os.precision(__precision);
02006       return __os;
02007     }
02008 
02009   template<typename _RealType, typename _CharT, typename _Traits>
02010     std::basic_istream<_CharT, _Traits>&
02011     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02012            gamma_distribution<_RealType>& __x)
02013     {
02014       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
02015       typedef typename __istream_type::ios_base    __ios_base;
02016 
02017       const typename __ios_base::fmtflags __flags = __is.flags();
02018       __is.flags(__ios_base::dec | __ios_base::skipws);
02019 
02020       _RealType __alpha_val, __beta_val;
02021       __is >> __alpha_val >> __beta_val >> __x._M_nd;
02022       __x.param(typename gamma_distribution<_RealType>::
02023         param_type(__alpha_val, __beta_val));
02024 
02025       __is.flags(__flags);
02026       return __is;
02027     }
02028 
02029 
02030   template<typename _RealType>
02031     template<typename _UniformRandomNumberGenerator>
02032       typename weibull_distribution<_RealType>::result_type
02033       weibull_distribution<_RealType>::
02034       operator()(_UniformRandomNumberGenerator& __urng,
02035          const param_type& __p)
02036       {
02037     __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
02038       __aurng(__urng);
02039     return __p.b() * std::pow(-std::log(__aurng()),
02040                   result_type(1) / __p.a());
02041       }
02042 
02043   template<typename _RealType, typename _CharT, typename _Traits>
02044     std::basic_ostream<_CharT, _Traits>&
02045     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02046            const weibull_distribution<_RealType>& __x)
02047     {
02048       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
02049       typedef typename __ostream_type::ios_base    __ios_base;
02050 
02051       const typename __ios_base::fmtflags __flags = __os.flags();
02052       const _CharT __fill = __os.fill();
02053       const std::streamsize __precision = __os.precision();
02054       const _CharT __space = __os.widen(' ');
02055       __os.flags(__ios_base::scientific | __ios_base::left);
02056       __os.fill(__space);
02057       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
02058 
02059       __os << __x.a() << __space << __x.b();
02060 
02061       __os.flags(__flags);
02062       __os.fill(__fill);
02063       __os.precision(__precision);
02064       return __os;
02065     }
02066 
02067   template<typename _RealType, typename _CharT, typename _Traits>
02068     std::basic_istream<_CharT, _Traits>&
02069     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02070            weibull_distribution<_RealType>& __x)
02071     {
02072       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
02073       typedef typename __istream_type::ios_base    __ios_base;
02074 
02075       const typename __ios_base::fmtflags __flags = __is.flags();
02076       __is.flags(__ios_base::dec | __ios_base::skipws);
02077 
02078       _RealType __a, __b;
02079       __is >> __a >> __b;
02080       __x.param(typename weibull_distribution<_RealType>::
02081         param_type(__a, __b));
02082 
02083       __is.flags(__flags);
02084       return __is;
02085     }
02086 
02087 
02088   template<typename _RealType>
02089     template<typename _UniformRandomNumberGenerator>
02090       typename extreme_value_distribution<_RealType>::result_type
02091       extreme_value_distribution<_RealType>::
02092       operator()(_UniformRandomNumberGenerator& __urng,
02093          const param_type& __p)
02094       {
02095     __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
02096       __aurng(__urng);
02097     return __p.a() - __p.b() * std::log(-std::log(__aurng()));
02098       }
02099 
02100   template<typename _RealType, typename _CharT, typename _Traits>
02101     std::basic_ostream<_CharT, _Traits>&
02102     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02103            const extreme_value_distribution<_RealType>& __x)
02104     {
02105       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
02106       typedef typename __ostream_type::ios_base    __ios_base;
02107 
02108       const typename __ios_base::fmtflags __flags = __os.flags();
02109       const _CharT __fill = __os.fill();
02110       const std::streamsize __precision = __os.precision();
02111       const _CharT __space = __os.widen(' ');
02112       __os.flags(__ios_base::scientific | __ios_base::left);
02113       __os.fill(__space);
02114       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
02115 
02116       __os << __x.a() << __space << __x.b();
02117 
02118       __os.flags(__flags);
02119       __os.fill(__fill);
02120       __os.precision(__precision);
02121       return __os;
02122     }
02123 
02124   template<typename _RealType, typename _CharT, typename _Traits>
02125     std::basic_istream<_CharT, _Traits>&
02126     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02127            extreme_value_distribution<_RealType>& __x)
02128     {
02129       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
02130       typedef typename __istream_type::ios_base    __ios_base;
02131 
02132       const typename __ios_base::fmtflags __flags = __is.flags();
02133       __is.flags(__ios_base::dec | __ios_base::skipws);
02134 
02135       _RealType __a, __b;
02136       __is >> __a >> __b;
02137       __x.param(typename extreme_value_distribution<_RealType>::
02138         param_type(__a, __b));
02139 
02140       __is.flags(__flags);
02141       return __is;
02142     }
02143 
02144 
02145   template<typename _IntType>
02146     void
02147     discrete_distribution<_IntType>::param_type::
02148     _M_initialize()
02149     {
02150       if (_M_prob.size() < 2)
02151     {
02152       _M_prob.clear();
02153       _M_prob.push_back(1.0);
02154       return;
02155     }
02156 
02157       const double __sum = std::accumulate(_M_prob.begin(),
02158                        _M_prob.end(), 0.0);
02159       // Now normalize the probabilites.
02160       std::transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
02161              std::bind2nd(std::divides<double>(), __sum));
02162       // Accumulate partial sums.
02163       _M_cp.reserve(_M_prob.size());
02164       std::partial_sum(_M_prob.begin(), _M_prob.end(),
02165                std::back_inserter(_M_cp));
02166       // Make sure the last cumulative probability is one.
02167       _M_cp[_M_cp.size() - 1] = 1.0;
02168     }
02169 
02170   template<typename _IntType>
02171     template<typename _Func>
02172       discrete_distribution<_IntType>::param_type::
02173       param_type(size_t __nw, double __xmin, double __xmax, _Func __fw)
02174       : _M_prob(), _M_cp()
02175       {
02176     const size_t __n = __nw == 0 ? 1 : __nw;
02177     const double __delta = (__xmax - __xmin) / __n;
02178 
02179     _M_prob.reserve(__n);
02180     for (size_t __k = 0; __k < __nw; ++__k)
02181       _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta));
02182 
02183     _M_initialize();
02184       }
02185 
02186   template<typename _IntType>
02187     template<typename _UniformRandomNumberGenerator>
02188       typename discrete_distribution<_IntType>::result_type
02189       discrete_distribution<_IntType>::
02190       operator()(_UniformRandomNumberGenerator& __urng,
02191          const param_type& __param)
02192       {
02193     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
02194       __aurng(__urng);
02195 
02196     const double __p = __aurng();
02197     auto __pos = std::lower_bound(__param._M_cp.begin(),
02198                       __param._M_cp.end(), __p);
02199 
02200     return __pos - __param._M_cp.begin();
02201       }
02202 
02203   template<typename _IntType, typename _CharT, typename _Traits>
02204     std::basic_ostream<_CharT, _Traits>&
02205     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02206            const discrete_distribution<_IntType>& __x)
02207     {
02208       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
02209       typedef typename __ostream_type::ios_base    __ios_base;
02210 
02211       const typename __ios_base::fmtflags __flags = __os.flags();
02212       const _CharT __fill = __os.fill();
02213       const std::streamsize __precision = __os.precision();
02214       const _CharT __space = __os.widen(' ');
02215       __os.flags(__ios_base::scientific | __ios_base::left);
02216       __os.fill(__space);
02217       __os.precision(std::numeric_limits<double>::digits10 + 1);
02218 
02219       std::vector<double> __prob = __x.probabilities();
02220       __os << __prob.size();
02221       for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit)
02222     __os << __space << *__dit;
02223 
02224       __os.flags(__flags);
02225       __os.fill(__fill);
02226       __os.precision(__precision);
02227       return __os;
02228     }
02229 
02230   template<typename _IntType, typename _CharT, typename _Traits>
02231     std::basic_istream<_CharT, _Traits>&
02232     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02233            discrete_distribution<_IntType>& __x)
02234     {
02235       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
02236       typedef typename __istream_type::ios_base    __ios_base;
02237 
02238       const typename __ios_base::fmtflags __flags = __is.flags();
02239       __is.flags(__ios_base::dec | __ios_base::skipws);
02240 
02241       size_t __n;
02242       __is >> __n;
02243 
02244       std::vector<double> __prob_vec;
02245       __prob_vec.reserve(__n);
02246       for (; __n != 0; --__n)
02247     {
02248       double __prob;
02249       __is >> __prob;
02250       __prob_vec.push_back(__prob);
02251     }
02252 
02253       __x.param(typename discrete_distribution<_IntType>::
02254         param_type(__prob_vec.begin(), __prob_vec.end()));
02255 
02256       __is.flags(__flags);
02257       return __is;
02258     }
02259 
02260 
02261   template<typename _RealType>
02262     void
02263     piecewise_constant_distribution<_RealType>::param_type::
02264     _M_initialize()
02265     {
02266       if (_M_int.size() < 2)
02267     {
02268       _M_int.clear();
02269       _M_int.reserve(2);
02270       _M_int.push_back(_RealType(0));
02271       _M_int.push_back(_RealType(1));
02272 
02273       _M_den.clear();
02274       _M_den.push_back(1.0);
02275 
02276       return;
02277     }
02278 
02279       const double __sum = std::accumulate(_M_den.begin(),
02280                        _M_den.end(), 0.0);
02281 
02282       std::transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
02283              std::bind2nd(std::divides<double>(), __sum));
02284 
02285       _M_cp.reserve(_M_den.size());
02286       std::partial_sum(_M_den.begin(), _M_den.end(),
02287                std::back_inserter(_M_cp));
02288 
02289       // Make sure the last cumulative probability is one.
02290       _M_cp[_M_cp.size() - 1] = 1.0;
02291 
02292       for (size_t __k = 0; __k < _M_den.size(); ++__k)
02293     _M_den[__k] /= _M_int[__k + 1] - _M_int[__k];
02294     }
02295 
02296   template<typename _RealType>
02297     template<typename _InputIteratorB, typename _InputIteratorW>
02298       piecewise_constant_distribution<_RealType>::param_type::
02299       param_type(_InputIteratorB __bbegin,
02300          _InputIteratorB __bend,
02301          _InputIteratorW __wbegin)
02302       : _M_int(), _M_den(), _M_cp()
02303       {
02304     if (__bbegin != __bend)
02305       {
02306         for (;;)
02307           {
02308         _M_int.push_back(*__bbegin);
02309         ++__bbegin;
02310         if (__bbegin == __bend)
02311           break;
02312 
02313         _M_den.push_back(*__wbegin);
02314         ++__wbegin;
02315           }
02316       }
02317 
02318     _M_initialize();
02319       }
02320 
02321   template<typename _RealType>
02322     template<typename _Func>
02323       piecewise_constant_distribution<_RealType>::param_type::
02324       param_type(initializer_list<_RealType> __bl, _Func __fw)
02325       : _M_int(), _M_den(), _M_cp()
02326       {
02327     _M_int.reserve(__bl.size());
02328     for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
02329       _M_int.push_back(*__biter);
02330 
02331     _M_den.reserve(_M_int.size() - 1);
02332     for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
02333       _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k])));
02334 
02335     _M_initialize();
02336       }
02337 
02338   template<typename _RealType>
02339     template<typename _Func>
02340       piecewise_constant_distribution<_RealType>::param_type::
02341       param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
02342       : _M_int(), _M_den(), _M_cp()
02343       {
02344     const size_t __n = __nw == 0 ? 1 : __nw;
02345     const _RealType __delta = (__xmax - __xmin) / __n;
02346 
02347     _M_int.reserve(__n + 1);
02348     for (size_t __k = 0; __k <= __nw; ++__k)
02349       _M_int.push_back(__xmin + __k * __delta);
02350 
02351     _M_den.reserve(__n);
02352     for (size_t __k = 0; __k < __nw; ++__k)
02353       _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta));
02354 
02355     _M_initialize();
02356       }
02357 
02358   template<typename _RealType>
02359     template<typename _UniformRandomNumberGenerator>
02360       typename piecewise_constant_distribution<_RealType>::result_type
02361       piecewise_constant_distribution<_RealType>::
02362       operator()(_UniformRandomNumberGenerator& __urng,
02363          const param_type& __param)
02364       {
02365     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
02366       __aurng(__urng);
02367 
02368     const double __p = __aurng();
02369     auto __pos = std::lower_bound(__param._M_cp.begin(),
02370                       __param._M_cp.end(), __p);
02371     const size_t __i = __pos - __param._M_cp.begin();
02372 
02373     const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
02374 
02375     return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i];
02376       }
02377 
02378   template<typename _RealType, typename _CharT, typename _Traits>
02379     std::basic_ostream<_CharT, _Traits>&
02380     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02381            const piecewise_constant_distribution<_RealType>& __x)
02382     {
02383       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
02384       typedef typename __ostream_type::ios_base    __ios_base;
02385 
02386       const typename __ios_base::fmtflags __flags = __os.flags();
02387       const _CharT __fill = __os.fill();
02388       const std::streamsize __precision = __os.precision();
02389       const _CharT __space = __os.widen(' ');
02390       __os.flags(__ios_base::scientific | __ios_base::left);
02391       __os.fill(__space);
02392       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
02393 
02394       std::vector<_RealType> __int = __x.intervals();
02395       __os << __int.size() - 1;
02396 
02397       for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
02398     __os << __space << *__xit;
02399 
02400       std::vector<double> __den = __x.densities();
02401       for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
02402     __os << __space << *__dit;
02403 
02404       __os.flags(__flags);
02405       __os.fill(__fill);
02406       __os.precision(__precision);
02407       return __os;
02408     }
02409 
02410   template<typename _RealType, typename _CharT, typename _Traits>
02411     std::basic_istream<_CharT, _Traits>&
02412     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02413            piecewise_constant_distribution<_RealType>& __x)
02414     {
02415       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
02416       typedef typename __istream_type::ios_base    __ios_base;
02417 
02418       const typename __ios_base::fmtflags __flags = __is.flags();
02419       __is.flags(__ios_base::dec | __ios_base::skipws);
02420 
02421       size_t __n;
02422       __is >> __n;
02423 
02424       std::vector<_RealType> __int_vec;
02425       __int_vec.reserve(__n + 1);
02426       for (size_t __i = 0; __i <= __n; ++__i)
02427     {
02428       _RealType __int;
02429       __is >> __int;
02430       __int_vec.push_back(__int);
02431     }
02432 
02433       std::vector<double> __den_vec;
02434       __den_vec.reserve(__n);
02435       for (size_t __i = 0; __i < __n; ++__i)
02436     {
02437       double __den;
02438       __is >> __den;
02439       __den_vec.push_back(__den);
02440     }
02441 
02442       __x.param(typename piecewise_constant_distribution<_RealType>::
02443       param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
02444 
02445       __is.flags(__flags);
02446       return __is;
02447     }
02448 
02449 
02450   template<typename _RealType>
02451     void
02452     piecewise_linear_distribution<_RealType>::param_type::
02453     _M_initialize()
02454     {
02455       if (_M_int.size() < 2)
02456     {
02457       _M_int.clear();
02458       _M_int.reserve(2);
02459       _M_int.push_back(_RealType(0));
02460       _M_int.push_back(_RealType(1));
02461 
02462       _M_den.clear();
02463       _M_den.reserve(2);
02464       _M_den.push_back(1.0);
02465       _M_den.push_back(1.0);
02466 
02467       return;
02468     }
02469 
02470       double __sum = 0.0;
02471       _M_cp.reserve(_M_int.size() - 1);
02472       _M_m.reserve(_M_int.size() - 1);
02473       for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
02474     {
02475       const _RealType __delta = _M_int[__k + 1] - _M_int[__k];
02476       __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta;
02477       _M_cp.push_back(__sum);
02478       _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta);
02479     }
02480 
02481       //  Now normalize the densities...
02482       std::transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
02483              std::bind2nd(std::divides<double>(), __sum));
02484       //  ... and partial sums... 
02485       std::transform(_M_cp.begin(), _M_cp.end(), _M_cp.begin(),
02486              std::bind2nd(std::divides<double>(), __sum));
02487       //  ... and slopes.
02488       std::transform(_M_m.begin(), _M_m.end(), _M_m.begin(),
02489              std::bind2nd(std::divides<double>(), __sum));
02490       //  Make sure the last cumulative probablility is one.
02491       _M_cp[_M_cp.size() - 1] = 1.0;
02492      }
02493 
02494   template<typename _RealType>
02495     template<typename _InputIteratorB, typename _InputIteratorW>
02496       piecewise_linear_distribution<_RealType>::param_type::
02497       param_type(_InputIteratorB __bbegin,
02498          _InputIteratorB __bend,
02499          _InputIteratorW __wbegin)
02500       : _M_int(), _M_den(), _M_cp(), _M_m()
02501       {
02502     for (; __bbegin != __bend; ++__bbegin, ++__wbegin)
02503       {
02504         _M_int.push_back(*__bbegin);
02505         _M_den.push_back(*__wbegin);
02506       }
02507 
02508     _M_initialize();
02509       }
02510 
02511   template<typename _RealType>
02512     template<typename _Func>
02513       piecewise_linear_distribution<_RealType>::param_type::
02514       param_type(initializer_list<_RealType> __bl, _Func __fw)
02515       : _M_int(), _M_den(), _M_cp(), _M_m()
02516       {
02517     _M_int.reserve(__bl.size());
02518     _M_den.reserve(__bl.size());
02519     for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
02520       {
02521         _M_int.push_back(*__biter);
02522         _M_den.push_back(__fw(*__biter));
02523       }
02524 
02525     _M_initialize();
02526       }
02527 
02528   template<typename _RealType>
02529     template<typename _Func>
02530       piecewise_linear_distribution<_RealType>::param_type::
02531       param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
02532       : _M_int(), _M_den(), _M_cp(), _M_m()
02533       {
02534     const size_t __n = __nw == 0 ? 1 : __nw;
02535     const _RealType __delta = (__xmax - __xmin) / __n;
02536 
02537     _M_int.reserve(__n + 1);
02538     _M_den.reserve(__n + 1);
02539     for (size_t __k = 0; __k <= __nw; ++__k)
02540       {
02541         _M_int.push_back(__xmin + __k * __delta);
02542         _M_den.push_back(__fw(_M_int[__k] + __delta));
02543       }
02544 
02545     _M_initialize();
02546       }
02547 
02548   template<typename _RealType>
02549     template<typename _UniformRandomNumberGenerator>
02550       typename piecewise_linear_distribution<_RealType>::result_type
02551       piecewise_linear_distribution<_RealType>::
02552       operator()(_UniformRandomNumberGenerator& __urng,
02553          const param_type& __param)
02554       {
02555     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
02556       __aurng(__urng);
02557 
02558     const double __p = __aurng();
02559     auto __pos = std::lower_bound(__param._M_cp.begin(),
02560                       __param._M_cp.end(), __p);
02561     const size_t __i = __pos - __param._M_cp.begin();
02562 
02563     const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
02564 
02565     const double __a = 0.5 * __param._M_m[__i];
02566     const double __b = __param._M_den[__i];
02567     const double __cm = __p - __pref;
02568 
02569     _RealType __x = __param._M_int[__i];
02570     if (__a == 0)
02571       __x += __cm / __b;
02572     else
02573       {
02574         const double __d = __b * __b + 4.0 * __a * __cm;
02575         __x += 0.5 * (std::sqrt(__d) - __b) / __a;
02576           }
02577 
02578         return __x;
02579       }
02580 
02581   template<typename _RealType, typename _CharT, typename _Traits>
02582     std::basic_ostream<_CharT, _Traits>&
02583     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02584            const piecewise_linear_distribution<_RealType>& __x)
02585     {
02586       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
02587       typedef typename __ostream_type::ios_base    __ios_base;
02588 
02589       const typename __ios_base::fmtflags __flags = __os.flags();
02590       const _CharT __fill = __os.fill();
02591       const std::streamsize __precision = __os.precision();
02592       const _CharT __space = __os.widen(' ');
02593       __os.flags(__ios_base::scientific | __ios_base::left);
02594       __os.fill(__space);
02595       __os.precision(std::numeric_limits<_RealType>::digits10 + 1);
02596 
02597       std::vector<_RealType> __int = __x.intervals();
02598       __os << __int.size() - 1;
02599 
02600       for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
02601     __os << __space << *__xit;
02602 
02603       std::vector<double> __den = __x.densities();
02604       for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
02605     __os << __space << *__dit;
02606 
02607       __os.flags(__flags);
02608       __os.fill(__fill);
02609       __os.precision(__precision);
02610       return __os;
02611     }
02612 
02613   template<typename _RealType, typename _CharT, typename _Traits>
02614     std::basic_istream<_CharT, _Traits>&
02615     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02616            piecewise_linear_distribution<_RealType>& __x)
02617     {
02618       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
02619       typedef typename __istream_type::ios_base    __ios_base;
02620 
02621       const typename __ios_base::fmtflags __flags = __is.flags();
02622       __is.flags(__ios_base::dec | __ios_base::skipws);
02623 
02624       size_t __n;
02625       __is >> __n;
02626 
02627       std::vector<_RealType> __int_vec;
02628       __int_vec.reserve(__n + 1);
02629       for (size_t __i = 0; __i <= __n; ++__i)
02630     {
02631       _RealType __int;
02632       __is >> __int;
02633       __int_vec.push_back(__int);
02634     }
02635 
02636       std::vector<double> __den_vec;
02637       __den_vec.reserve(__n + 1);
02638       for (size_t __i = 0; __i <= __n; ++__i)
02639     {
02640       double __den;
02641       __is >> __den;
02642       __den_vec.push_back(__den);
02643     }
02644 
02645       __x.param(typename piecewise_linear_distribution<_RealType>::
02646       param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
02647 
02648       __is.flags(__flags);
02649       return __is;
02650     }
02651 
02652 
02653   template<typename _IntType>
02654     seed_seq::seed_seq(std::initializer_list<_IntType> __il)
02655     {
02656       for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter)
02657     _M_v.push_back(__detail::__mod<result_type,
02658                __detail::_Shift<result_type, 32>::__value>(*__iter));
02659     }
02660 
02661   template<typename _InputIterator>
02662     seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end)
02663     {
02664       for (_InputIterator __iter = __begin; __iter != __end; ++__iter)
02665     _M_v.push_back(__detail::__mod<result_type,
02666                __detail::_Shift<result_type, 32>::__value>(*__iter));
02667     }
02668 
02669   template<typename _RandomAccessIterator>
02670     void
02671     seed_seq::generate(_RandomAccessIterator __begin,
02672                _RandomAccessIterator __end)
02673     {
02674       typedef typename iterator_traits<_RandomAccessIterator>::value_type
02675         _Type;
02676 
02677       if (__begin == __end)
02678     return;
02679 
02680       std::fill(__begin, __end, _Type(0x8b8b8b8bu));
02681 
02682       const size_t __n = __end - __begin;
02683       const size_t __s = _M_v.size();
02684       const size_t __t = (__n >= 623) ? 11
02685                : (__n >=  68) ? 7
02686                : (__n >=  39) ? 5
02687                : (__n >=   7) ? 3
02688                : (__n - 1) / 2;
02689       const size_t __p = (__n - __t) / 2;
02690       const size_t __q = __p + __t;
02691       const size_t __m = std::max(__s + 1, __n);
02692 
02693       for (size_t __k = 0; __k < __m; ++__k)
02694     {
02695       _Type __arg = (__begin[__k % __n]
02696              ^ __begin[(__k + __p) % __n]
02697              ^ __begin[(__k - 1) % __n]);
02698       _Type __r1 = __arg ^ (__arg << 27);
02699       __r1 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value,
02700                              1664525u, 0u>(__r1);
02701       _Type __r2 = __r1;
02702       if (__k == 0)
02703         __r2 += __s;
02704       else if (__k <= __s)
02705         __r2 += __k % __n + _M_v[__k - 1];
02706       else
02707         __r2 += __k % __n;
02708       __r2 = __detail::__mod<_Type,
02709                __detail::_Shift<_Type, 32>::__value>(__r2);
02710       __begin[(__k + __p) % __n] += __r1;
02711       __begin[(__k + __q) % __n] += __r2;
02712       __begin[__k % __n] = __r2;
02713     }
02714 
02715       for (size_t __k = __m; __k < __m + __n; ++__k)
02716     {
02717       _Type __arg = (__begin[__k % __n]
02718              + __begin[(__k + __p) % __n]
02719              + __begin[(__k - 1) % __n]);
02720       _Type __r3 = __arg ^ (__arg << 27);
02721       __r3 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value,
02722                              1566083941u, 0u>(__r3);
02723       _Type __r4 = __r3 - __k % __n;
02724       __r4 = __detail::__mod<_Type,
02725                __detail::_Shift<_Type, 32>::__value>(__r4);
02726       __begin[(__k + __p) % __n] ^= __r4;
02727       __begin[(__k + __q) % __n] ^= __r3;
02728       __begin[__k % __n] = __r4;
02729     }
02730     }
02731 
02732   template<typename _RealType, size_t __bits,
02733        typename _UniformRandomNumberGenerator>
02734     _RealType
02735     generate_canonical(_UniformRandomNumberGenerator& __urng)
02736     {
02737       const size_t __b
02738     = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits),
02739                    __bits);
02740       const long double __r = static_cast<long double>(__urng.max())
02741                 - static_cast<long double>(__urng.min()) + 1.0L;
02742       const size_t __log2r = std::log(__r) / std::log(2.0L);
02743       size_t __k = std::max<size_t>(1UL, (__b + __log2r - 1UL) / __log2r);
02744       _RealType __sum = _RealType(0);
02745       _RealType __tmp = _RealType(1);
02746       for (; __k != 0; --__k)
02747     {
02748       __sum += _RealType(__urng() - __urng.min()) * __tmp;
02749       __tmp *= __r;
02750     }
02751       return __sum / __tmp;
02752     }
02753 }

Generated on 9 Feb 2010 for libstdc++ by  doxygen 1.6.1