random.tcc

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