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