random.tcc

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

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1