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