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