libstdc++
random.h
Go to the documentation of this file.
00001 // random number generation -*- C++ -*-
00002 
00003 // Copyright (C) 2009-2014 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 /**
00026  * @file bits/random.h
00027  *  This is an internal header file, included by other library headers.
00028  *  Do not attempt to use it directly. @headername{random}
00029  */
00030 
00031 #ifndef _RANDOM_H
00032 #define _RANDOM_H 1
00033 
00034 #include <vector>
00035 
00036 namespace std _GLIBCXX_VISIBILITY(default)
00037 {
00038 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00039 
00040   // [26.4] Random number generation
00041 
00042   /**
00043    * @defgroup random Random Number Generation
00044    * @ingroup numerics
00045    *
00046    * A facility for generating random numbers on selected distributions.
00047    * @{
00048    */
00049 
00050   /**
00051    * @brief A function template for converting the output of a (integral)
00052    * uniform random number generator to a floatng point result in the range
00053    * [0-1).
00054    */
00055   template<typename _RealType, size_t __bits,
00056        typename _UniformRandomNumberGenerator>
00057     _RealType
00058     generate_canonical(_UniformRandomNumberGenerator& __g);
00059 
00060 _GLIBCXX_END_NAMESPACE_VERSION
00061 
00062   /*
00063    * Implementation-space details.
00064    */
00065   namespace __detail
00066   {
00067   _GLIBCXX_BEGIN_NAMESPACE_VERSION
00068 
00069     template<typename _UIntType, size_t __w,
00070          bool = __w < static_cast<size_t>
00071               (std::numeric_limits<_UIntType>::digits)>
00072       struct _Shift
00073       { static const _UIntType __value = 0; };
00074 
00075     template<typename _UIntType, size_t __w>
00076       struct _Shift<_UIntType, __w, true>
00077       { static const _UIntType __value = _UIntType(1) << __w; };
00078 
00079     template<int __s,
00080          int __which = ((__s <= __CHAR_BIT__ * sizeof (int))
00081                 + (__s <= __CHAR_BIT__ * sizeof (long))
00082                 + (__s <= __CHAR_BIT__ * sizeof (long long))
00083                 /* assume long long no bigger than __int128 */
00084                 + (__s <= 128))>
00085       struct _Select_uint_least_t
00086       {
00087     static_assert(__which < 0, /* needs to be dependent */
00088               "sorry, would be too much trouble for a slow result");
00089       };
00090 
00091     template<int __s>
00092       struct _Select_uint_least_t<__s, 4>
00093       { typedef unsigned int type; };
00094 
00095     template<int __s>
00096       struct _Select_uint_least_t<__s, 3>
00097       { typedef unsigned long type; };
00098 
00099     template<int __s>
00100       struct _Select_uint_least_t<__s, 2>
00101       { typedef unsigned long long type; };
00102 
00103 #ifdef _GLIBCXX_USE_INT128
00104     template<int __s>
00105       struct _Select_uint_least_t<__s, 1>
00106       { typedef unsigned __int128 type; };
00107 #endif
00108 
00109     // Assume a != 0, a < m, c < m, x < m.
00110     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c,
00111          bool __big_enough = (!(__m & (__m - 1))
00112                   || (_Tp(-1) - __c) / __a >= __m - 1),
00113              bool __schrage_ok = __m % __a < __m / __a>
00114       struct _Mod
00115       {
00116     typedef typename _Select_uint_least_t<std::__lg(__a)
00117                           + std::__lg(__m) + 2>::type _Tp2;
00118     static _Tp
00119     __calc(_Tp __x)
00120     { return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); }
00121       };
00122 
00123     // Schrage.
00124     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
00125       struct _Mod<_Tp, __m, __a, __c, false, true>
00126       {
00127     static _Tp
00128     __calc(_Tp __x);
00129       };
00130 
00131     // Special cases:
00132     // - for m == 2^n or m == 0, unsigned integer overflow is safe.
00133     // - a * (m - 1) + c fits in _Tp, there is no overflow.
00134     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool __s>
00135       struct _Mod<_Tp, __m, __a, __c, true, __s>
00136       {
00137     static _Tp
00138     __calc(_Tp __x)
00139     {
00140       _Tp __res = __a * __x + __c;
00141       if (__m)
00142         __res %= __m;
00143       return __res;
00144     }
00145       };
00146 
00147     template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
00148       inline _Tp
00149       __mod(_Tp __x)
00150       { return _Mod<_Tp, __m, __a, __c>::__calc(__x); }
00151 
00152     /* Determine whether number is a power of 2.  */
00153     template<typename _Tp>
00154       inline bool
00155       _Power_of_2(_Tp __x)
00156       {
00157     return ((__x - 1) & __x) == 0;
00158       };
00159 
00160     /*
00161      * An adaptor class for converting the output of any Generator into
00162      * the input for a specific Distribution.
00163      */
00164     template<typename _Engine, typename _DInputType>
00165       struct _Adaptor
00166       {
00167     static_assert(std::is_floating_point<_DInputType>::value,
00168               "template argument not a floating point type");
00169 
00170       public:
00171     _Adaptor(_Engine& __g)
00172     : _M_g(__g) { }
00173 
00174     _DInputType
00175     min() const
00176     { return _DInputType(0); }
00177 
00178     _DInputType
00179     max() const
00180     { return _DInputType(1); }
00181 
00182     /*
00183      * Converts a value generated by the adapted random number generator
00184      * into a value in the input domain for the dependent random number
00185      * distribution.
00186      */
00187     _DInputType
00188     operator()()
00189     {
00190       return std::generate_canonical<_DInputType,
00191                                 std::numeric_limits<_DInputType>::digits,
00192                                 _Engine>(_M_g);
00193     }
00194 
00195       private:
00196     _Engine& _M_g;
00197       };
00198 
00199   _GLIBCXX_END_NAMESPACE_VERSION
00200   } // namespace __detail
00201 
00202 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00203 
00204   /**
00205    * @addtogroup random_generators Random Number Generators
00206    * @ingroup random
00207    *
00208    * These classes define objects which provide random or pseudorandom
00209    * numbers, either from a discrete or a continuous interval.  The
00210    * random number generator supplied as a part of this library are
00211    * all uniform random number generators which provide a sequence of
00212    * random number uniformly distributed over their range.
00213    *
00214    * A number generator is a function object with an operator() that
00215    * takes zero arguments and returns a number.
00216    *
00217    * A compliant random number generator must satisfy the following
00218    * requirements.  <table border=1 cellpadding=10 cellspacing=0>
00219    * <caption align=top>Random Number Generator Requirements</caption>
00220    * <tr><td>To be documented.</td></tr> </table>
00221    *
00222    * @{
00223    */
00224 
00225   /**
00226    * @brief A model of a linear congruential random number generator.
00227    *
00228    * A random number generator that produces pseudorandom numbers via
00229    * linear function:
00230    * @f[
00231    *     x_{i+1}\leftarrow(ax_{i} + c) \bmod m 
00232    * @f]
00233    *
00234    * The template parameter @p _UIntType must be an unsigned integral type
00235    * large enough to store values up to (__m-1). If the template parameter
00236    * @p __m is 0, the modulus @p __m used is
00237    * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
00238    * parameters @p __a and @p __c must be less than @p __m.
00239    *
00240    * The size of the state is @f$1@f$.
00241    */
00242   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00243     class linear_congruential_engine
00244     {
00245       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
00246             "substituting _UIntType not an unsigned integral type");
00247       static_assert(__m == 0u || (__a < __m && __c < __m),
00248             "template argument substituting __m out of bounds");
00249 
00250     public:
00251       /** The type of the generated random value. */
00252       typedef _UIntType result_type;
00253 
00254       /** The multiplier. */
00255       static constexpr result_type multiplier   = __a;
00256       /** An increment. */
00257       static constexpr result_type increment    = __c;
00258       /** The modulus. */
00259       static constexpr result_type modulus      = __m;
00260       static constexpr result_type default_seed = 1u;
00261 
00262       /**
00263        * @brief Constructs a %linear_congruential_engine random number
00264        *        generator engine with seed @p __s.  The default seed value
00265        *        is 1.
00266        *
00267        * @param __s The initial seed value.
00268        */
00269       explicit
00270       linear_congruential_engine(result_type __s = default_seed)
00271       { seed(__s); }
00272 
00273       /**
00274        * @brief Constructs a %linear_congruential_engine random number
00275        *        generator engine seeded from the seed sequence @p __q.
00276        *
00277        * @param __q the seed sequence.
00278        */
00279       template<typename _Sseq, typename = typename
00280     std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
00281            ::type>
00282         explicit
00283         linear_congruential_engine(_Sseq& __q)
00284         { seed(__q); }
00285 
00286       /**
00287        * @brief Reseeds the %linear_congruential_engine random number generator
00288        *        engine sequence to the seed @p __s.
00289        *
00290        * @param __s The new seed.
00291        */
00292       void
00293       seed(result_type __s = default_seed);
00294 
00295       /**
00296        * @brief Reseeds the %linear_congruential_engine random number generator
00297        *        engine
00298        * sequence using values from the seed sequence @p __q.
00299        *
00300        * @param __q the seed sequence.
00301        */
00302       template<typename _Sseq>
00303         typename std::enable_if<std::is_class<_Sseq>::value>::type
00304         seed(_Sseq& __q);
00305 
00306       /**
00307        * @brief Gets the smallest possible value in the output range.
00308        *
00309        * The minimum depends on the @p __c parameter: if it is zero, the
00310        * minimum generated must be > 0, otherwise 0 is allowed.
00311        */
00312       static constexpr result_type
00313       min()
00314       { return __c == 0u ? 1u : 0u; }
00315 
00316       /**
00317        * @brief Gets the largest possible value in the output range.
00318        */
00319       static constexpr result_type
00320       max()
00321       { return __m - 1u; }
00322 
00323       /**
00324        * @brief Discard a sequence of random numbers.
00325        */
00326       void
00327       discard(unsigned long long __z)
00328       {
00329     for (; __z != 0ULL; --__z)
00330       (*this)();
00331       }
00332 
00333       /**
00334        * @brief Gets the next random number in the sequence.
00335        */
00336       result_type
00337       operator()()
00338       {
00339     _M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
00340     return _M_x;
00341       }
00342 
00343       /**
00344        * @brief Compares two linear congruential random number generator
00345        * objects of the same type for equality.
00346        *
00347        * @param __lhs A linear congruential random number generator object.
00348        * @param __rhs Another linear congruential random number generator
00349        *              object.
00350        *
00351        * @returns true if the infinite sequences of generated values
00352        *          would be equal, false otherwise.
00353        */
00354       friend bool
00355       operator==(const linear_congruential_engine& __lhs,
00356          const linear_congruential_engine& __rhs)
00357       { return __lhs._M_x == __rhs._M_x; }
00358 
00359       /**
00360        * @brief Writes the textual representation of the state x(i) of x to
00361        *        @p __os.
00362        *
00363        * @param __os  The output stream.
00364        * @param __lcr A % linear_congruential_engine random number generator.
00365        * @returns __os.
00366        */
00367       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
00368            _UIntType1 __m1, typename _CharT, typename _Traits>
00369     friend std::basic_ostream<_CharT, _Traits>&
00370     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00371            const std::linear_congruential_engine<_UIntType1,
00372            __a1, __c1, __m1>& __lcr);
00373 
00374       /**
00375        * @brief Sets the state of the engine by reading its textual
00376        *        representation from @p __is.
00377        *
00378        * The textual representation must have been previously written using
00379        * an output stream whose imbued locale and whose type's template
00380        * specialization arguments _CharT and _Traits were the same as those
00381        * of @p __is.
00382        *
00383        * @param __is  The input stream.
00384        * @param __lcr A % linear_congruential_engine random number generator.
00385        * @returns __is.
00386        */
00387       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
00388            _UIntType1 __m1, typename _CharT, typename _Traits>
00389     friend std::basic_istream<_CharT, _Traits>&
00390     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00391            std::linear_congruential_engine<_UIntType1, __a1,
00392            __c1, __m1>& __lcr);
00393 
00394     private:
00395       _UIntType _M_x;
00396     };
00397 
00398   /**
00399    * @brief Compares two linear congruential random number generator
00400    * objects of the same type for inequality.
00401    *
00402    * @param __lhs A linear congruential random number generator object.
00403    * @param __rhs Another linear congruential random number generator
00404    *              object.
00405    *
00406    * @returns true if the infinite sequences of generated values
00407    *          would be different, false otherwise.
00408    */
00409   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00410     inline bool
00411     operator!=(const std::linear_congruential_engine<_UIntType, __a,
00412            __c, __m>& __lhs,
00413            const std::linear_congruential_engine<_UIntType, __a,
00414            __c, __m>& __rhs)
00415     { return !(__lhs == __rhs); }
00416 
00417 
00418   /**
00419    * A generalized feedback shift register discrete random number generator.
00420    *
00421    * This algorithm avoids multiplication and division and is designed to be
00422    * friendly to a pipelined architecture.  If the parameters are chosen
00423    * correctly, this generator will produce numbers with a very long period and
00424    * fairly good apparent entropy, although still not cryptographically strong.
00425    *
00426    * The best way to use this generator is with the predefined mt19937 class.
00427    *
00428    * This algorithm was originally invented by Makoto Matsumoto and
00429    * Takuji Nishimura.
00430    *
00431    * @tparam __w  Word size, the number of bits in each element of 
00432    *              the state vector.
00433    * @tparam __n  The degree of recursion.
00434    * @tparam __m  The period parameter.
00435    * @tparam __r  The separation point bit index.
00436    * @tparam __a  The last row of the twist matrix.
00437    * @tparam __u  The first right-shift tempering matrix parameter.
00438    * @tparam __d  The first right-shift tempering matrix mask.
00439    * @tparam __s  The first left-shift tempering matrix parameter.
00440    * @tparam __b  The first left-shift tempering matrix mask.
00441    * @tparam __t  The second left-shift tempering matrix parameter.
00442    * @tparam __c  The second left-shift tempering matrix mask.
00443    * @tparam __l  The second right-shift tempering matrix parameter.
00444    * @tparam __f  Initialization multiplier.
00445    */
00446   template<typename _UIntType, size_t __w,
00447        size_t __n, size_t __m, size_t __r,
00448        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00449        _UIntType __b, size_t __t,
00450        _UIntType __c, size_t __l, _UIntType __f>
00451     class mersenne_twister_engine
00452     {
00453       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
00454             "substituting _UIntType not an unsigned integral type");
00455       static_assert(1u <= __m && __m <= __n,
00456             "template argument substituting __m out of bounds");
00457       static_assert(__r <= __w, "template argument substituting "
00458             "__r out of bound");
00459       static_assert(__u <= __w, "template argument substituting "
00460             "__u out of bound");
00461       static_assert(__s <= __w, "template argument substituting "
00462             "__s out of bound");
00463       static_assert(__t <= __w, "template argument substituting "
00464             "__t out of bound");
00465       static_assert(__l <= __w, "template argument substituting "
00466             "__l out of bound");
00467       static_assert(__w <= std::numeric_limits<_UIntType>::digits,
00468             "template argument substituting __w out of bound");
00469       static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00470             "template argument substituting __a out of bound");
00471       static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00472             "template argument substituting __b out of bound");
00473       static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00474             "template argument substituting __c out of bound");
00475       static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00476             "template argument substituting __d out of bound");
00477       static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00478             "template argument substituting __f out of bound");
00479 
00480     public:
00481       /** The type of the generated random value. */
00482       typedef _UIntType result_type;
00483 
00484       // parameter values
00485       static constexpr size_t      word_size                 = __w;
00486       static constexpr size_t      state_size                = __n;
00487       static constexpr size_t      shift_size                = __m;
00488       static constexpr size_t      mask_bits                 = __r;
00489       static constexpr result_type xor_mask                  = __a;
00490       static constexpr size_t      tempering_u               = __u;
00491       static constexpr result_type tempering_d               = __d;
00492       static constexpr size_t      tempering_s               = __s;
00493       static constexpr result_type tempering_b               = __b;
00494       static constexpr size_t      tempering_t               = __t;
00495       static constexpr result_type tempering_c               = __c;
00496       static constexpr size_t      tempering_l               = __l;
00497       static constexpr result_type initialization_multiplier = __f;
00498       static constexpr result_type default_seed = 5489u;
00499 
00500       // constructors and member function
00501       explicit
00502       mersenne_twister_engine(result_type __sd = default_seed)
00503       { seed(__sd); }
00504 
00505       /**
00506        * @brief Constructs a %mersenne_twister_engine random number generator
00507        *        engine seeded from the seed sequence @p __q.
00508        *
00509        * @param __q the seed sequence.
00510        */
00511       template<typename _Sseq, typename = typename
00512         std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
00513            ::type>
00514         explicit
00515         mersenne_twister_engine(_Sseq& __q)
00516         { seed(__q); }
00517 
00518       void
00519       seed(result_type __sd = default_seed);
00520 
00521       template<typename _Sseq>
00522     typename std::enable_if<std::is_class<_Sseq>::value>::type
00523         seed(_Sseq& __q);
00524 
00525       /**
00526        * @brief Gets the smallest possible value in the output range.
00527        */
00528       static constexpr result_type
00529       min()
00530       { return 0; };
00531 
00532       /**
00533        * @brief Gets the largest possible value in the output range.
00534        */
00535       static constexpr result_type
00536       max()
00537       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
00538 
00539       /**
00540        * @brief Discard a sequence of random numbers.
00541        */
00542       void
00543       discard(unsigned long long __z);
00544 
00545       result_type
00546       operator()();
00547 
00548       /**
00549        * @brief Compares two % mersenne_twister_engine random number generator
00550        *        objects of the same type for equality.
00551        *
00552        * @param __lhs A % mersenne_twister_engine random number generator
00553        *              object.
00554        * @param __rhs Another % mersenne_twister_engine random number
00555        *              generator object.
00556        *
00557        * @returns true if the infinite sequences of generated values
00558        *          would be equal, false otherwise.
00559        */
00560       friend bool
00561       operator==(const mersenne_twister_engine& __lhs,
00562          const mersenne_twister_engine& __rhs)
00563       { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x)
00564         && __lhs._M_p == __rhs._M_p); }
00565 
00566       /**
00567        * @brief Inserts the current state of a % mersenne_twister_engine
00568        *        random number generator engine @p __x into the output stream
00569        *        @p __os.
00570        *
00571        * @param __os An output stream.
00572        * @param __x  A % mersenne_twister_engine random number generator
00573        *             engine.
00574        *
00575        * @returns The output stream with the state of @p __x inserted or in
00576        * an error state.
00577        */
00578       template<typename _UIntType1,
00579            size_t __w1, size_t __n1,
00580            size_t __m1, size_t __r1,
00581            _UIntType1 __a1, size_t __u1,
00582            _UIntType1 __d1, size_t __s1,
00583            _UIntType1 __b1, size_t __t1,
00584            _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
00585            typename _CharT, typename _Traits>
00586     friend std::basic_ostream<_CharT, _Traits>&
00587     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00588            const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
00589            __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
00590            __l1, __f1>& __x);
00591 
00592       /**
00593        * @brief Extracts the current state of a % mersenne_twister_engine
00594        *        random number generator engine @p __x from the input stream
00595        *        @p __is.
00596        *
00597        * @param __is An input stream.
00598        * @param __x  A % mersenne_twister_engine random number generator
00599        *             engine.
00600        *
00601        * @returns The input stream with the state of @p __x extracted or in
00602        * an error state.
00603        */
00604       template<typename _UIntType1,
00605            size_t __w1, size_t __n1,
00606            size_t __m1, size_t __r1,
00607            _UIntType1 __a1, size_t __u1,
00608            _UIntType1 __d1, size_t __s1,
00609            _UIntType1 __b1, size_t __t1,
00610            _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
00611            typename _CharT, typename _Traits>
00612     friend std::basic_istream<_CharT, _Traits>&
00613     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00614            std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
00615            __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
00616            __l1, __f1>& __x);
00617 
00618     private:
00619       void _M_gen_rand();
00620 
00621       _UIntType _M_x[state_size];
00622       size_t    _M_p;
00623     };
00624 
00625   /**
00626    * @brief Compares two % mersenne_twister_engine random number generator
00627    *        objects of the same type for inequality.
00628    *
00629    * @param __lhs A % mersenne_twister_engine random number generator
00630    *              object.
00631    * @param __rhs Another % mersenne_twister_engine random number
00632    *              generator object.
00633    *
00634    * @returns true if the infinite sequences of generated values
00635    *          would be different, false otherwise.
00636    */
00637   template<typename _UIntType, size_t __w,
00638        size_t __n, size_t __m, size_t __r,
00639        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00640        _UIntType __b, size_t __t,
00641        _UIntType __c, size_t __l, _UIntType __f>
00642     inline bool
00643     operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
00644            __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
00645            const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
00646            __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
00647     { return !(__lhs == __rhs); }
00648 
00649 
00650   /**
00651    * @brief The Marsaglia-Zaman generator.
00652    *
00653    * This is a model of a Generalized Fibonacci discrete random number
00654    * generator, sometimes referred to as the SWC generator.
00655    *
00656    * A discrete random number generator that produces pseudorandom
00657    * numbers using:
00658    * @f[
00659    *     x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m 
00660    * @f]
00661    *
00662    * The size of the state is @f$r@f$
00663    * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$.
00664    *
00665    * @var _M_x     The state of the generator.  This is a ring buffer.
00666    * @var _M_carry The carry.
00667    * @var _M_p     Current index of x(i - r).
00668    */
00669   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00670     class subtract_with_carry_engine
00671     {
00672       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
00673             "substituting _UIntType not an unsigned integral type");
00674       static_assert(0u < __s && __s < __r,
00675             "template argument substituting __s out of bounds");
00676       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
00677             "template argument substituting __w out of bounds");
00678 
00679     public:
00680       /** The type of the generated random value. */
00681       typedef _UIntType result_type;
00682 
00683       // parameter values
00684       static constexpr size_t      word_size    = __w;
00685       static constexpr size_t      short_lag    = __s;
00686       static constexpr size_t      long_lag     = __r;
00687       static constexpr result_type default_seed = 19780503u;
00688 
00689       /**
00690        * @brief Constructs an explicitly seeded % subtract_with_carry_engine
00691        *        random number generator.
00692        */
00693       explicit
00694       subtract_with_carry_engine(result_type __sd = default_seed)
00695       { seed(__sd); }
00696 
00697       /**
00698        * @brief Constructs a %subtract_with_carry_engine random number engine
00699        *        seeded from the seed sequence @p __q.
00700        *
00701        * @param __q the seed sequence.
00702        */
00703       template<typename _Sseq, typename = typename
00704         std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
00705            ::type>
00706         explicit
00707         subtract_with_carry_engine(_Sseq& __q)
00708         { seed(__q); }
00709 
00710       /**
00711        * @brief Seeds the initial state @f$x_0@f$ of the random number
00712        *        generator.
00713        *
00714        * N1688[4.19] modifies this as follows.  If @p __value == 0,
00715        * sets value to 19780503.  In any case, with a linear
00716        * congruential generator lcg(i) having parameters @f$ m_{lcg} =
00717        * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
00718        * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
00719        * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
00720        * set carry to 1, otherwise sets carry to 0.
00721        */
00722       void
00723       seed(result_type __sd = default_seed);
00724 
00725       /**
00726        * @brief Seeds the initial state @f$x_0@f$ of the
00727        * % subtract_with_carry_engine random number generator.
00728        */
00729       template<typename _Sseq>
00730     typename std::enable_if<std::is_class<_Sseq>::value>::type
00731         seed(_Sseq& __q);
00732 
00733       /**
00734        * @brief Gets the inclusive minimum value of the range of random
00735        * integers returned by this generator.
00736        */
00737       static constexpr result_type
00738       min()
00739       { return 0; }
00740 
00741       /**
00742        * @brief Gets the inclusive maximum value of the range of random
00743        * integers returned by this generator.
00744        */
00745       static constexpr result_type
00746       max()
00747       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
00748 
00749       /**
00750        * @brief Discard a sequence of random numbers.
00751        */
00752       void
00753       discard(unsigned long long __z)
00754       {
00755     for (; __z != 0ULL; --__z)
00756       (*this)();
00757       }
00758 
00759       /**
00760        * @brief Gets the next random number in the sequence.
00761        */
00762       result_type
00763       operator()();
00764 
00765       /**
00766        * @brief Compares two % subtract_with_carry_engine random number
00767        *        generator objects of the same type for equality.
00768        *
00769        * @param __lhs A % subtract_with_carry_engine random number generator
00770        *              object.
00771        * @param __rhs Another % subtract_with_carry_engine random number
00772        *              generator object.
00773        *
00774        * @returns true if the infinite sequences of generated values
00775        *          would be equal, false otherwise.
00776       */
00777       friend bool
00778       operator==(const subtract_with_carry_engine& __lhs,
00779          const subtract_with_carry_engine& __rhs)
00780       { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x)
00781         && __lhs._M_carry == __rhs._M_carry
00782         && __lhs._M_p == __rhs._M_p); }
00783 
00784       /**
00785        * @brief Inserts the current state of a % subtract_with_carry_engine
00786        *        random number generator engine @p __x into the output stream
00787        *        @p __os.
00788        *
00789        * @param __os An output stream.
00790        * @param __x  A % subtract_with_carry_engine random number generator
00791        *             engine.
00792        *
00793        * @returns The output stream with the state of @p __x inserted or in
00794        * an error state.
00795        */
00796       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
00797            typename _CharT, typename _Traits>
00798     friend std::basic_ostream<_CharT, _Traits>&
00799     operator<<(std::basic_ostream<_CharT, _Traits>&,
00800            const std::subtract_with_carry_engine<_UIntType1, __w1,
00801            __s1, __r1>&);
00802 
00803       /**
00804        * @brief Extracts the current state of a % subtract_with_carry_engine
00805        *        random number generator engine @p __x from the input stream
00806        *        @p __is.
00807        *
00808        * @param __is An input stream.
00809        * @param __x  A % subtract_with_carry_engine random number generator
00810        *             engine.
00811        *
00812        * @returns The input stream with the state of @p __x extracted or in
00813        * an error state.
00814        */
00815       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
00816            typename _CharT, typename _Traits>
00817     friend std::basic_istream<_CharT, _Traits>&
00818     operator>>(std::basic_istream<_CharT, _Traits>&,
00819            std::subtract_with_carry_engine<_UIntType1, __w1,
00820            __s1, __r1>&);
00821 
00822     private:
00823       _UIntType  _M_x[long_lag];
00824       _UIntType  _M_carry;
00825       size_t     _M_p;
00826     };
00827 
00828   /**
00829    * @brief Compares two % subtract_with_carry_engine random number
00830    *        generator objects of the same type for inequality.
00831    *
00832    * @param __lhs A % subtract_with_carry_engine random number generator
00833    *              object.
00834    * @param __rhs Another % subtract_with_carry_engine random number
00835    *              generator object.
00836    *
00837    * @returns true if the infinite sequences of generated values
00838    *          would be different, false otherwise.
00839    */
00840   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00841     inline bool
00842     operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
00843            __s, __r>& __lhs,
00844            const std::subtract_with_carry_engine<_UIntType, __w,
00845            __s, __r>& __rhs)
00846     { return !(__lhs == __rhs); }
00847 
00848 
00849   /**
00850    * Produces random numbers from some base engine by discarding blocks of
00851    * data.
00852    *
00853    * 0 <= @p __r <= @p __p
00854    */
00855   template<typename _RandomNumberEngine, size_t __p, size_t __r>
00856     class discard_block_engine
00857     {
00858       static_assert(1 <= __r && __r <= __p,
00859             "template argument substituting __r out of bounds");
00860 
00861     public:
00862       /** The type of the generated random value. */
00863       typedef typename _RandomNumberEngine::result_type result_type;
00864 
00865       // parameter values
00866       static constexpr size_t block_size = __p;
00867       static constexpr size_t used_block = __r;
00868 
00869       /**
00870        * @brief Constructs a default %discard_block_engine engine.
00871        *
00872        * The underlying engine is default constructed as well.
00873        */
00874       discard_block_engine()
00875       : _M_b(), _M_n(0) { }
00876 
00877       /**
00878        * @brief Copy constructs a %discard_block_engine engine.
00879        *
00880        * Copies an existing base class random number generator.
00881        * @param __rng An existing (base class) engine object.
00882        */
00883       explicit
00884       discard_block_engine(const _RandomNumberEngine& __rng)
00885       : _M_b(__rng), _M_n(0) { }
00886 
00887       /**
00888        * @brief Move constructs a %discard_block_engine engine.
00889        *
00890        * Copies an existing base class random number generator.
00891        * @param __rng An existing (base class) engine object.
00892        */
00893       explicit
00894       discard_block_engine(_RandomNumberEngine&& __rng)
00895       : _M_b(std::move(__rng)), _M_n(0) { }
00896 
00897       /**
00898        * @brief Seed constructs a %discard_block_engine engine.
00899        *
00900        * Constructs the underlying generator engine seeded with @p __s.
00901        * @param __s A seed value for the base class engine.
00902        */
00903       explicit
00904       discard_block_engine(result_type __s)
00905       : _M_b(__s), _M_n(0) { }
00906 
00907       /**
00908        * @brief Generator construct a %discard_block_engine engine.
00909        *
00910        * @param __q A seed sequence.
00911        */
00912       template<typename _Sseq, typename = typename
00913     std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
00914                && !std::is_same<_Sseq, _RandomNumberEngine>::value>
00915            ::type>
00916         explicit
00917         discard_block_engine(_Sseq& __q)
00918     : _M_b(__q), _M_n(0)
00919         { }
00920 
00921       /**
00922        * @brief Reseeds the %discard_block_engine object with the default
00923        *        seed for the underlying base class generator engine.
00924        */
00925       void
00926       seed()
00927       {
00928     _M_b.seed();
00929     _M_n = 0;
00930       }
00931 
00932       /**
00933        * @brief Reseeds the %discard_block_engine object with the default
00934        *        seed for the underlying base class generator engine.
00935        */
00936       void
00937       seed(result_type __s)
00938       {
00939     _M_b.seed(__s);
00940     _M_n = 0;
00941       }
00942 
00943       /**
00944        * @brief Reseeds the %discard_block_engine object with the given seed
00945        *        sequence.
00946        * @param __q A seed generator function.
00947        */
00948       template<typename _Sseq>
00949         void
00950         seed(_Sseq& __q)
00951         {
00952       _M_b.seed(__q);
00953       _M_n = 0;
00954     }
00955 
00956       /**
00957        * @brief Gets a const reference to the underlying generator engine
00958        *        object.
00959        */
00960       const _RandomNumberEngine&
00961       base() const noexcept
00962       { return _M_b; }
00963 
00964       /**
00965        * @brief Gets the minimum value in the generated random number range.
00966        */
00967       static constexpr result_type
00968       min()
00969       { return _RandomNumberEngine::min(); }
00970 
00971       /**
00972        * @brief Gets the maximum value in the generated random number range.
00973        */
00974       static constexpr result_type
00975       max()
00976       { return _RandomNumberEngine::max(); }
00977 
00978       /**
00979        * @brief Discard a sequence of random numbers.
00980        */
00981       void
00982       discard(unsigned long long __z)
00983       {
00984     for (; __z != 0ULL; --__z)
00985       (*this)();
00986       }
00987 
00988       /**
00989        * @brief Gets the next value in the generated random number sequence.
00990        */
00991       result_type
00992       operator()();
00993 
00994       /**
00995        * @brief Compares two %discard_block_engine random number generator
00996        *        objects of the same type for equality.
00997        *
00998        * @param __lhs A %discard_block_engine random number generator object.
00999        * @param __rhs Another %discard_block_engine random number generator
01000        *              object.
01001        *
01002        * @returns true if the infinite sequences of generated values
01003        *          would be equal, false otherwise.
01004        */
01005       friend bool
01006       operator==(const discard_block_engine& __lhs,
01007          const discard_block_engine& __rhs)
01008       { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; }
01009 
01010       /**
01011        * @brief Inserts the current state of a %discard_block_engine random
01012        *        number generator engine @p __x into the output stream
01013        *        @p __os.
01014        *
01015        * @param __os An output stream.
01016        * @param __x  A %discard_block_engine random number generator engine.
01017        *
01018        * @returns The output stream with the state of @p __x inserted or in
01019        * an error state.
01020        */
01021       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
01022            typename _CharT, typename _Traits>
01023     friend std::basic_ostream<_CharT, _Traits>&
01024     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01025            const std::discard_block_engine<_RandomNumberEngine1,
01026            __p1, __r1>& __x);
01027 
01028       /**
01029        * @brief Extracts the current state of a % subtract_with_carry_engine
01030        *        random number generator engine @p __x from the input stream
01031        *        @p __is.
01032        *
01033        * @param __is An input stream.
01034        * @param __x  A %discard_block_engine random number generator engine.
01035        *
01036        * @returns The input stream with the state of @p __x extracted or in
01037        * an error state.
01038        */
01039       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
01040            typename _CharT, typename _Traits>
01041     friend std::basic_istream<_CharT, _Traits>&
01042     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01043            std::discard_block_engine<_RandomNumberEngine1,
01044            __p1, __r1>& __x);
01045 
01046     private:
01047       _RandomNumberEngine _M_b;
01048       size_t _M_n;
01049     };
01050 
01051   /**
01052    * @brief Compares two %discard_block_engine random number generator
01053    *        objects of the same type for inequality.
01054    *
01055    * @param __lhs A %discard_block_engine random number generator object.
01056    * @param __rhs Another %discard_block_engine random number generator
01057    *              object.
01058    *
01059    * @returns true if the infinite sequences of generated values
01060    *          would be different, false otherwise.
01061    */
01062   template<typename _RandomNumberEngine, size_t __p, size_t __r>
01063     inline bool
01064     operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
01065            __r>& __lhs,
01066            const std::discard_block_engine<_RandomNumberEngine, __p,
01067            __r>& __rhs)
01068     { return !(__lhs == __rhs); }
01069 
01070 
01071   /**
01072    * Produces random numbers by combining random numbers from some base
01073    * engine to produce random numbers with a specifies number of bits @p __w.
01074    */
01075   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
01076     class independent_bits_engine
01077     {
01078       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
01079             "substituting _UIntType not an unsigned integral type");
01080       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
01081             "template argument substituting __w out of bounds");
01082 
01083     public:
01084       /** The type of the generated random value. */
01085       typedef _UIntType result_type;
01086 
01087       /**
01088        * @brief Constructs a default %independent_bits_engine engine.
01089        *
01090        * The underlying engine is default constructed as well.
01091        */
01092       independent_bits_engine()
01093       : _M_b() { }
01094 
01095       /**
01096        * @brief Copy constructs a %independent_bits_engine engine.
01097        *
01098        * Copies an existing base class random number generator.
01099        * @param __rng An existing (base class) engine object.
01100        */
01101       explicit
01102       independent_bits_engine(const _RandomNumberEngine& __rng)
01103       : _M_b(__rng) { }
01104 
01105       /**
01106        * @brief Move constructs a %independent_bits_engine engine.
01107        *
01108        * Copies an existing base class random number generator.
01109        * @param __rng An existing (base class) engine object.
01110        */
01111       explicit
01112       independent_bits_engine(_RandomNumberEngine&& __rng)
01113       : _M_b(std::move(__rng)) { }
01114 
01115       /**
01116        * @brief Seed constructs a %independent_bits_engine engine.
01117        *
01118        * Constructs the underlying generator engine seeded with @p __s.
01119        * @param __s A seed value for the base class engine.
01120        */
01121       explicit
01122       independent_bits_engine(result_type __s)
01123       : _M_b(__s) { }
01124 
01125       /**
01126        * @brief Generator construct a %independent_bits_engine engine.
01127        *
01128        * @param __q A seed sequence.
01129        */
01130       template<typename _Sseq, typename = typename
01131     std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
01132                && !std::is_same<_Sseq, _RandomNumberEngine>::value>
01133                ::type>
01134         explicit
01135         independent_bits_engine(_Sseq& __q)
01136         : _M_b(__q)
01137         { }
01138 
01139       /**
01140        * @brief Reseeds the %independent_bits_engine object with the default
01141        *        seed for the underlying base class generator engine.
01142        */
01143       void
01144       seed()
01145       { _M_b.seed(); }
01146 
01147       /**
01148        * @brief Reseeds the %independent_bits_engine object with the default
01149        *        seed for the underlying base class generator engine.
01150        */
01151       void
01152       seed(result_type __s)
01153       { _M_b.seed(__s); }
01154 
01155       /**
01156        * @brief Reseeds the %independent_bits_engine object with the given
01157        *        seed sequence.
01158        * @param __q A seed generator function.
01159        */
01160       template<typename _Sseq>
01161         void
01162         seed(_Sseq& __q)
01163         { _M_b.seed(__q); }
01164 
01165       /**
01166        * @brief Gets a const reference to the underlying generator engine
01167        *        object.
01168        */
01169       const _RandomNumberEngine&
01170       base() const noexcept
01171       { return _M_b; }
01172 
01173       /**
01174        * @brief Gets the minimum value in the generated random number range.
01175        */
01176       static constexpr result_type
01177       min()
01178       { return 0U; }
01179 
01180       /**
01181        * @brief Gets the maximum value in the generated random number range.
01182        */
01183       static constexpr result_type
01184       max()
01185       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
01186 
01187       /**
01188        * @brief Discard a sequence of random numbers.
01189        */
01190       void
01191       discard(unsigned long long __z)
01192       {
01193     for (; __z != 0ULL; --__z)
01194       (*this)();
01195       }
01196 
01197       /**
01198        * @brief Gets the next value in the generated random number sequence.
01199        */
01200       result_type
01201       operator()();
01202 
01203       /**
01204        * @brief Compares two %independent_bits_engine random number generator
01205        * objects of the same type for equality.
01206        *
01207        * @param __lhs A %independent_bits_engine random number generator
01208        *              object.
01209        * @param __rhs Another %independent_bits_engine random number generator
01210        *              object.
01211        *
01212        * @returns true if the infinite sequences of generated values
01213        *          would be equal, false otherwise.
01214        */
01215       friend bool
01216       operator==(const independent_bits_engine& __lhs,
01217          const independent_bits_engine& __rhs)
01218       { return __lhs._M_b == __rhs._M_b; }
01219 
01220       /**
01221        * @brief Extracts the current state of a % subtract_with_carry_engine
01222        *        random number generator engine @p __x from the input stream
01223        *        @p __is.
01224        *
01225        * @param __is An input stream.
01226        * @param __x  A %independent_bits_engine random number generator
01227        *             engine.
01228        *
01229        * @returns The input stream with the state of @p __x extracted or in
01230        *          an error state.
01231        */
01232       template<typename _CharT, typename _Traits>
01233     friend std::basic_istream<_CharT, _Traits>&
01234     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01235            std::independent_bits_engine<_RandomNumberEngine,
01236            __w, _UIntType>& __x)
01237     {
01238       __is >> __x._M_b;
01239       return __is;
01240     }
01241 
01242     private:
01243       _RandomNumberEngine _M_b;
01244     };
01245 
01246   /**
01247    * @brief Compares two %independent_bits_engine random number generator
01248    * objects of the same type for inequality.
01249    *
01250    * @param __lhs A %independent_bits_engine random number generator
01251    *              object.
01252    * @param __rhs Another %independent_bits_engine random number generator
01253    *              object.
01254    *
01255    * @returns true if the infinite sequences of generated values
01256    *          would be different, false otherwise.
01257    */
01258   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
01259     inline bool
01260     operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
01261            _UIntType>& __lhs,
01262            const std::independent_bits_engine<_RandomNumberEngine, __w,
01263            _UIntType>& __rhs)
01264     { return !(__lhs == __rhs); }
01265 
01266   /**
01267    * @brief Inserts the current state of a %independent_bits_engine random
01268    *        number generator engine @p __x into the output stream @p __os.
01269    *
01270    * @param __os An output stream.
01271    * @param __x  A %independent_bits_engine random number generator engine.
01272    *
01273    * @returns The output stream with the state of @p __x inserted or in
01274    *          an error state.
01275    */
01276   template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
01277        typename _CharT, typename _Traits>
01278     std::basic_ostream<_CharT, _Traits>&
01279     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01280            const std::independent_bits_engine<_RandomNumberEngine,
01281            __w, _UIntType>& __x)
01282     {
01283       __os << __x.base();
01284       return __os;
01285     }
01286 
01287 
01288   /**
01289    * @brief Produces random numbers by combining random numbers from some
01290    * base engine to produce random numbers with a specifies number of bits
01291    * @p __w.
01292    */
01293   template<typename _RandomNumberEngine, size_t __k>
01294     class shuffle_order_engine
01295     {
01296       static_assert(1u <= __k, "template argument substituting "
01297             "__k out of bound");
01298 
01299     public:
01300       /** The type of the generated random value. */
01301       typedef typename _RandomNumberEngine::result_type result_type;
01302 
01303       static constexpr size_t table_size = __k;
01304 
01305       /**
01306        * @brief Constructs a default %shuffle_order_engine engine.
01307        *
01308        * The underlying engine is default constructed as well.
01309        */
01310       shuffle_order_engine()
01311       : _M_b()
01312       { _M_initialize(); }
01313 
01314       /**
01315        * @brief Copy constructs a %shuffle_order_engine engine.
01316        *
01317        * Copies an existing base class random number generator.
01318        * @param __rng An existing (base class) engine object.
01319        */
01320       explicit
01321       shuffle_order_engine(const _RandomNumberEngine& __rng)
01322       : _M_b(__rng)
01323       { _M_initialize(); }
01324 
01325       /**
01326        * @brief Move constructs a %shuffle_order_engine engine.
01327        *
01328        * Copies an existing base class random number generator.
01329        * @param __rng An existing (base class) engine object.
01330        */
01331       explicit
01332       shuffle_order_engine(_RandomNumberEngine&& __rng)
01333       : _M_b(std::move(__rng))
01334       { _M_initialize(); }
01335 
01336       /**
01337        * @brief Seed constructs a %shuffle_order_engine engine.
01338        *
01339        * Constructs the underlying generator engine seeded with @p __s.
01340        * @param __s A seed value for the base class engine.
01341        */
01342       explicit
01343       shuffle_order_engine(result_type __s)
01344       : _M_b(__s)
01345       { _M_initialize(); }
01346 
01347       /**
01348        * @brief Generator construct a %shuffle_order_engine engine.
01349        *
01350        * @param __q A seed sequence.
01351        */
01352       template<typename _Sseq, typename = typename
01353     std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
01354                && !std::is_same<_Sseq, _RandomNumberEngine>::value>
01355            ::type>
01356         explicit
01357         shuffle_order_engine(_Sseq& __q)
01358         : _M_b(__q)
01359         { _M_initialize(); }
01360 
01361       /**
01362        * @brief Reseeds the %shuffle_order_engine object with the default seed
01363                 for the underlying base class generator engine.
01364        */
01365       void
01366       seed()
01367       {
01368     _M_b.seed();
01369     _M_initialize();
01370       }
01371 
01372       /**
01373        * @brief Reseeds the %shuffle_order_engine object with the default seed
01374        *        for the underlying base class generator engine.
01375        */
01376       void
01377       seed(result_type __s)
01378       {
01379     _M_b.seed(__s);
01380     _M_initialize();
01381       }
01382 
01383       /**
01384        * @brief Reseeds the %shuffle_order_engine object with the given seed
01385        *        sequence.
01386        * @param __q A seed generator function.
01387        */
01388       template<typename _Sseq>
01389         void
01390         seed(_Sseq& __q)
01391         {
01392       _M_b.seed(__q);
01393       _M_initialize();
01394     }
01395 
01396       /**
01397        * Gets a const reference to the underlying generator engine object.
01398        */
01399       const _RandomNumberEngine&
01400       base() const noexcept
01401       { return _M_b; }
01402 
01403       /**
01404        * Gets the minimum value in the generated random number range.
01405        */
01406       static constexpr result_type
01407       min()
01408       { return _RandomNumberEngine::min(); }
01409 
01410       /**
01411        * Gets the maximum value in the generated random number range.
01412        */
01413       static constexpr result_type
01414       max()
01415       { return _RandomNumberEngine::max(); }
01416 
01417       /**
01418        * Discard a sequence of random numbers.
01419        */
01420       void
01421       discard(unsigned long long __z)
01422       {
01423     for (; __z != 0ULL; --__z)
01424       (*this)();
01425       }
01426 
01427       /**
01428        * Gets the next value in the generated random number sequence.
01429        */
01430       result_type
01431       operator()();
01432 
01433       /**
01434        * Compares two %shuffle_order_engine random number generator objects
01435        * of the same type for equality.
01436        *
01437        * @param __lhs A %shuffle_order_engine random number generator object.
01438        * @param __rhs Another %shuffle_order_engine random number generator
01439        *              object.
01440        *
01441        * @returns true if the infinite sequences of generated values
01442        *          would be equal, false otherwise.
01443       */
01444       friend bool
01445       operator==(const shuffle_order_engine& __lhs,
01446          const shuffle_order_engine& __rhs)
01447       { return (__lhs._M_b == __rhs._M_b
01448         && std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v)
01449         && __lhs._M_y == __rhs._M_y); }
01450 
01451       /**
01452        * @brief Inserts the current state of a %shuffle_order_engine random
01453        *        number generator engine @p __x into the output stream
01454     @p __os.
01455        *
01456        * @param __os An output stream.
01457        * @param __x  A %shuffle_order_engine random number generator engine.
01458        *
01459        * @returns The output stream with the state of @p __x inserted or in
01460        * an error state.
01461        */
01462       template<typename _RandomNumberEngine1, size_t __k1,
01463            typename _CharT, typename _Traits>
01464     friend std::basic_ostream<_CharT, _Traits>&
01465     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01466            const std::shuffle_order_engine<_RandomNumberEngine1,
01467            __k1>& __x);
01468 
01469       /**
01470        * @brief Extracts the current state of a % subtract_with_carry_engine
01471        *        random number generator engine @p __x from the input stream
01472        *        @p __is.
01473        *
01474        * @param __is An input stream.
01475        * @param __x  A %shuffle_order_engine random number generator engine.
01476        *
01477        * @returns The input stream with the state of @p __x extracted or in
01478        * an error state.
01479        */
01480       template<typename _RandomNumberEngine1, size_t __k1,
01481            typename _CharT, typename _Traits>
01482     friend std::basic_istream<_CharT, _Traits>&
01483     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01484            std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x);
01485 
01486     private:
01487       void _M_initialize()
01488       {
01489     for (size_t __i = 0; __i < __k; ++__i)
01490       _M_v[__i] = _M_b();
01491     _M_y = _M_b();
01492       }
01493 
01494       _RandomNumberEngine _M_b;
01495       result_type _M_v[__k];
01496       result_type _M_y;
01497     };
01498 
01499   /**
01500    * Compares two %shuffle_order_engine random number generator objects
01501    * of the same type for inequality.
01502    *
01503    * @param __lhs A %shuffle_order_engine random number generator object.
01504    * @param __rhs Another %shuffle_order_engine random number generator
01505    *              object.
01506    *
01507    * @returns true if the infinite sequences of generated values
01508    *          would be different, false otherwise.
01509    */
01510   template<typename _RandomNumberEngine, size_t __k>
01511     inline bool
01512     operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
01513            __k>& __lhs,
01514            const std::shuffle_order_engine<_RandomNumberEngine,
01515            __k>& __rhs)
01516     { return !(__lhs == __rhs); }
01517 
01518 
01519   /**
01520    * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
01521    */
01522   typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
01523   minstd_rand0;
01524 
01525   /**
01526    * An alternative LCR (Lehmer Generator function).
01527    */
01528   typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
01529   minstd_rand;
01530 
01531   /**
01532    * The classic Mersenne Twister.
01533    *
01534    * Reference:
01535    * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
01536    * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
01537    * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
01538    */
01539   typedef mersenne_twister_engine<
01540     uint_fast32_t,
01541     32, 624, 397, 31,
01542     0x9908b0dfUL, 11,
01543     0xffffffffUL, 7,
01544     0x9d2c5680UL, 15,
01545     0xefc60000UL, 18, 1812433253UL> mt19937;
01546 
01547   /**
01548    * An alternative Mersenne Twister.
01549    */
01550   typedef mersenne_twister_engine<
01551     uint_fast64_t,
01552     64, 312, 156, 31,
01553     0xb5026f5aa96619e9ULL, 29,
01554     0x5555555555555555ULL, 17,
01555     0x71d67fffeda60000ULL, 37,
01556     0xfff7eee000000000ULL, 43,
01557     6364136223846793005ULL> mt19937_64;
01558 
01559   typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
01560     ranlux24_base;
01561 
01562   typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
01563     ranlux48_base;
01564 
01565   typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
01566 
01567   typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
01568 
01569   typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
01570 
01571   typedef minstd_rand0 default_random_engine;
01572 
01573   /**
01574    * A standard interface to a platform-specific non-deterministic
01575    * random number generator (if any are available).
01576    */
01577   class random_device
01578   {
01579   public:
01580     /** The type of the generated random value. */
01581     typedef unsigned int result_type;
01582 
01583     // constructors, destructors and member functions
01584 
01585 #ifdef _GLIBCXX_USE_RANDOM_TR1
01586 
01587     explicit
01588     random_device(const std::string& __token = "default")
01589     {
01590       _M_init(__token);
01591     }
01592 
01593     ~random_device()
01594     { _M_fini(); }
01595 
01596 #else
01597 
01598     explicit
01599     random_device(const std::string& __token = "mt19937")
01600     { _M_init_pretr1(__token); }
01601 
01602   public:
01603 
01604 #endif
01605 
01606     static constexpr result_type
01607     min()
01608     { return std::numeric_limits<result_type>::min(); }
01609 
01610     static constexpr result_type
01611     max()
01612     { return std::numeric_limits<result_type>::max(); }
01613 
01614     double
01615     entropy() const noexcept
01616     { return 0.0; }
01617 
01618     result_type
01619     operator()()
01620     {
01621 #ifdef _GLIBCXX_USE_RANDOM_TR1
01622       return this->_M_getval();
01623 #else
01624       return this->_M_getval_pretr1();
01625 #endif
01626     }
01627 
01628     // No copy functions.
01629     random_device(const random_device&) = delete;
01630     void operator=(const random_device&) = delete;
01631 
01632   private:
01633 
01634     void _M_init(const std::string& __token);
01635     void _M_init_pretr1(const std::string& __token);
01636     void _M_fini();
01637 
01638     result_type _M_getval();
01639     result_type _M_getval_pretr1();
01640 
01641     union
01642     {
01643       void*      _M_file;
01644       mt19937    _M_mt;
01645     };
01646   };
01647 
01648   /* @} */ // group random_generators
01649 
01650   /**
01651    * @addtogroup random_distributions Random Number Distributions
01652    * @ingroup random
01653    * @{
01654    */
01655 
01656   /**
01657    * @addtogroup random_distributions_uniform Uniform Distributions
01658    * @ingroup random_distributions
01659    * @{
01660    */
01661 
01662   /**
01663    * @brief Uniform discrete distribution for random numbers.
01664    * A discrete random distribution on the range @f$[min, max]@f$ with equal
01665    * probability throughout the range.
01666    */
01667   template<typename _IntType = int>
01668     class uniform_int_distribution
01669     {
01670       static_assert(std::is_integral<_IntType>::value,
01671             "template argument not an integral type");
01672 
01673     public:
01674       /** The type of the range of the distribution. */
01675       typedef _IntType result_type;
01676       /** Parameter type. */
01677       struct param_type
01678       {
01679     typedef uniform_int_distribution<_IntType> distribution_type;
01680 
01681     explicit
01682     param_type(_IntType __a = 0,
01683            _IntType __b = std::numeric_limits<_IntType>::max())
01684     : _M_a(__a), _M_b(__b)
01685     {
01686       _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
01687     }
01688 
01689     result_type
01690     a() const
01691     { return _M_a; }
01692 
01693     result_type
01694     b() const
01695     { return _M_b; }
01696 
01697     friend bool
01698     operator==(const param_type& __p1, const param_type& __p2)
01699     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
01700 
01701       private:
01702     _IntType _M_a;
01703     _IntType _M_b;
01704       };
01705 
01706     public:
01707       /**
01708        * @brief Constructs a uniform distribution object.
01709        */
01710       explicit
01711       uniform_int_distribution(_IntType __a = 0,
01712                _IntType __b = std::numeric_limits<_IntType>::max())
01713       : _M_param(__a, __b)
01714       { }
01715 
01716       explicit
01717       uniform_int_distribution(const param_type& __p)
01718       : _M_param(__p)
01719       { }
01720 
01721       /**
01722        * @brief Resets the distribution state.
01723        *
01724        * Does nothing for the uniform integer distribution.
01725        */
01726       void
01727       reset() { }
01728 
01729       result_type
01730       a() const
01731       { return _M_param.a(); }
01732 
01733       result_type
01734       b() const
01735       { return _M_param.b(); }
01736 
01737       /**
01738        * @brief Returns the parameter set of the distribution.
01739        */
01740       param_type
01741       param() const
01742       { return _M_param; }
01743 
01744       /**
01745        * @brief Sets the parameter set of the distribution.
01746        * @param __param The new parameter set of the distribution.
01747        */
01748       void
01749       param(const param_type& __param)
01750       { _M_param = __param; }
01751 
01752       /**
01753        * @brief Returns the inclusive lower bound of the distribution range.
01754        */
01755       result_type
01756       min() const
01757       { return this->a(); }
01758 
01759       /**
01760        * @brief Returns the inclusive upper bound of the distribution range.
01761        */
01762       result_type
01763       max() const
01764       { return this->b(); }
01765 
01766       /**
01767        * @brief Generating functions.
01768        */
01769       template<typename _UniformRandomNumberGenerator>
01770     result_type
01771     operator()(_UniformRandomNumberGenerator& __urng)
01772         { return this->operator()(__urng, _M_param); }
01773 
01774       template<typename _UniformRandomNumberGenerator>
01775     result_type
01776     operator()(_UniformRandomNumberGenerator& __urng,
01777            const param_type& __p);
01778 
01779       template<typename _ForwardIterator,
01780            typename _UniformRandomNumberGenerator>
01781     void
01782     __generate(_ForwardIterator __f, _ForwardIterator __t,
01783            _UniformRandomNumberGenerator& __urng)
01784     { this->__generate(__f, __t, __urng, _M_param); }
01785 
01786       template<typename _ForwardIterator,
01787            typename _UniformRandomNumberGenerator>
01788     void
01789     __generate(_ForwardIterator __f, _ForwardIterator __t,
01790            _UniformRandomNumberGenerator& __urng,
01791            const param_type& __p)
01792     { this->__generate_impl(__f, __t, __urng, __p); }
01793 
01794       template<typename _UniformRandomNumberGenerator>
01795     void
01796     __generate(result_type* __f, result_type* __t,
01797            _UniformRandomNumberGenerator& __urng,
01798            const param_type& __p)
01799     { this->__generate_impl(__f, __t, __urng, __p); }
01800 
01801       /**
01802        * @brief Return true if two uniform integer distributions have
01803        *        the same parameters.
01804        */
01805       friend bool
01806       operator==(const uniform_int_distribution& __d1,
01807          const uniform_int_distribution& __d2)
01808       { return __d1._M_param == __d2._M_param; }
01809 
01810     private:
01811       template<typename _ForwardIterator,
01812            typename _UniformRandomNumberGenerator>
01813     void
01814     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
01815             _UniformRandomNumberGenerator& __urng,
01816             const param_type& __p);
01817 
01818       param_type _M_param;
01819     };
01820 
01821   /**
01822    * @brief Return true if two uniform integer distributions have
01823    *        different parameters.
01824    */
01825   template<typename _IntType>
01826     inline bool
01827     operator!=(const std::uniform_int_distribution<_IntType>& __d1,
01828            const std::uniform_int_distribution<_IntType>& __d2)
01829     { return !(__d1 == __d2); }
01830 
01831   /**
01832    * @brief Inserts a %uniform_int_distribution random number
01833    *        distribution @p __x into the output stream @p os.
01834    *
01835    * @param __os An output stream.
01836    * @param __x  A %uniform_int_distribution random number distribution.
01837    *
01838    * @returns The output stream with the state of @p __x inserted or in
01839    * an error state.
01840    */
01841   template<typename _IntType, typename _CharT, typename _Traits>
01842     std::basic_ostream<_CharT, _Traits>&
01843     operator<<(std::basic_ostream<_CharT, _Traits>&,
01844            const std::uniform_int_distribution<_IntType>&);
01845 
01846   /**
01847    * @brief Extracts a %uniform_int_distribution random number distribution
01848    * @p __x from the input stream @p __is.
01849    *
01850    * @param __is An input stream.
01851    * @param __x  A %uniform_int_distribution random number generator engine.
01852    *
01853    * @returns The input stream with @p __x extracted or in an error state.
01854    */
01855   template<typename _IntType, typename _CharT, typename _Traits>
01856     std::basic_istream<_CharT, _Traits>&
01857     operator>>(std::basic_istream<_CharT, _Traits>&,
01858            std::uniform_int_distribution<_IntType>&);
01859 
01860 
01861   /**
01862    * @brief Uniform continuous distribution for random numbers.
01863    *
01864    * A continuous random distribution on the range [min, max) with equal
01865    * probability throughout the range.  The URNG should be real-valued and
01866    * deliver number in the range [0, 1).
01867    */
01868   template<typename _RealType = double>
01869     class uniform_real_distribution
01870     {
01871       static_assert(std::is_floating_point<_RealType>::value,
01872             "template argument not a floating point type");
01873 
01874     public:
01875       /** The type of the range of the distribution. */
01876       typedef _RealType result_type;
01877       /** Parameter type. */
01878       struct param_type
01879       {
01880     typedef uniform_real_distribution<_RealType> distribution_type;
01881 
01882     explicit
01883     param_type(_RealType __a = _RealType(0),
01884            _RealType __b = _RealType(1))
01885     : _M_a(__a), _M_b(__b)
01886     {
01887       _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
01888     }
01889 
01890     result_type
01891     a() const
01892     { return _M_a; }
01893 
01894     result_type
01895     b() const
01896     { return _M_b; }
01897 
01898     friend bool
01899     operator==(const param_type& __p1, const param_type& __p2)
01900     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
01901 
01902       private:
01903     _RealType _M_a;
01904     _RealType _M_b;
01905       };
01906 
01907     public:
01908       /**
01909        * @brief Constructs a uniform_real_distribution object.
01910        *
01911        * @param __a [IN]  The lower bound of the distribution.
01912        * @param __b [IN]  The upper bound of the distribution.
01913        */
01914       explicit
01915       uniform_real_distribution(_RealType __a = _RealType(0),
01916                 _RealType __b = _RealType(1))
01917       : _M_param(__a, __b)
01918       { }
01919 
01920       explicit
01921       uniform_real_distribution(const param_type& __p)
01922       : _M_param(__p)
01923       { }
01924 
01925       /**
01926        * @brief Resets the distribution state.
01927        *
01928        * Does nothing for the uniform real distribution.
01929        */
01930       void
01931       reset() { }
01932 
01933       result_type
01934       a() const
01935       { return _M_param.a(); }
01936 
01937       result_type
01938       b() const
01939       { return _M_param.b(); }
01940 
01941       /**
01942        * @brief Returns the parameter set of the distribution.
01943        */
01944       param_type
01945       param() const
01946       { return _M_param; }
01947 
01948       /**
01949        * @brief Sets the parameter set of the distribution.
01950        * @param __param The new parameter set of the distribution.
01951        */
01952       void
01953       param(const param_type& __param)
01954       { _M_param = __param; }
01955 
01956       /**
01957        * @brief Returns the inclusive lower bound of the distribution range.
01958        */
01959       result_type
01960       min() const
01961       { return this->a(); }
01962 
01963       /**
01964        * @brief Returns the inclusive upper bound of the distribution range.
01965        */
01966       result_type
01967       max() const
01968       { return this->b(); }
01969 
01970       /**
01971        * @brief Generating functions.
01972        */
01973       template<typename _UniformRandomNumberGenerator>
01974     result_type
01975     operator()(_UniformRandomNumberGenerator& __urng)
01976         { return this->operator()(__urng, _M_param); }
01977 
01978       template<typename _UniformRandomNumberGenerator>
01979     result_type
01980     operator()(_UniformRandomNumberGenerator& __urng,
01981            const param_type& __p)
01982     {
01983       __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
01984         __aurng(__urng);
01985       return (__aurng() * (__p.b() - __p.a())) + __p.a();
01986     }
01987 
01988       template<typename _ForwardIterator,
01989            typename _UniformRandomNumberGenerator>
01990     void
01991     __generate(_ForwardIterator __f, _ForwardIterator __t,
01992            _UniformRandomNumberGenerator& __urng)
01993     { this->__generate(__f, __t, __urng, _M_param); }
01994 
01995       template<typename _ForwardIterator,
01996            typename _UniformRandomNumberGenerator>
01997     void
01998     __generate(_ForwardIterator __f, _ForwardIterator __t,
01999            _UniformRandomNumberGenerator& __urng,
02000            const param_type& __p)
02001     { this->__generate_impl(__f, __t, __urng, __p); }
02002 
02003       template<typename _UniformRandomNumberGenerator>
02004     void
02005     __generate(result_type* __f, result_type* __t,
02006            _UniformRandomNumberGenerator& __urng,
02007            const param_type& __p)
02008     { this->__generate_impl(__f, __t, __urng, __p); }
02009 
02010       /**
02011        * @brief Return true if two uniform real distributions have
02012        *        the same parameters.
02013        */
02014       friend bool
02015       operator==(const uniform_real_distribution& __d1,
02016          const uniform_real_distribution& __d2)
02017       { return __d1._M_param == __d2._M_param; }
02018 
02019     private:
02020       template<typename _ForwardIterator,
02021            typename _UniformRandomNumberGenerator>
02022     void
02023     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
02024             _UniformRandomNumberGenerator& __urng,
02025             const param_type& __p);
02026 
02027       param_type _M_param;
02028     };
02029 
02030   /**
02031    * @brief Return true if two uniform real distributions have
02032    *        different parameters.
02033    */
02034   template<typename _IntType>
02035     inline bool
02036     operator!=(const std::uniform_real_distribution<_IntType>& __d1,
02037            const std::uniform_real_distribution<_IntType>& __d2)
02038     { return !(__d1 == __d2); }
02039 
02040   /**
02041    * @brief Inserts a %uniform_real_distribution random number
02042    *        distribution @p __x into the output stream @p __os.
02043    *
02044    * @param __os An output stream.
02045    * @param __x  A %uniform_real_distribution random number distribution.
02046    *
02047    * @returns The output stream with the state of @p __x inserted or in
02048    *          an error state.
02049    */
02050   template<typename _RealType, typename _CharT, typename _Traits>
02051     std::basic_ostream<_CharT, _Traits>&
02052     operator<<(std::basic_ostream<_CharT, _Traits>&,
02053            const std::uniform_real_distribution<_RealType>&);
02054 
02055   /**
02056    * @brief Extracts a %uniform_real_distribution random number distribution
02057    * @p __x from the input stream @p __is.
02058    *
02059    * @param __is An input stream.
02060    * @param __x  A %uniform_real_distribution random number generator engine.
02061    *
02062    * @returns The input stream with @p __x extracted or in an error state.
02063    */
02064   template<typename _RealType, typename _CharT, typename _Traits>
02065     std::basic_istream<_CharT, _Traits>&
02066     operator>>(std::basic_istream<_CharT, _Traits>&,
02067            std::uniform_real_distribution<_RealType>&);
02068 
02069   /* @} */ // group random_distributions_uniform
02070 
02071   /**
02072    * @addtogroup random_distributions_normal Normal Distributions
02073    * @ingroup random_distributions
02074    * @{
02075    */
02076 
02077   /**
02078    * @brief A normal continuous distribution for random numbers.
02079    *
02080    * The formula for the normal probability density function is
02081    * @f[
02082    *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
02083    *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } 
02084    * @f]
02085    */
02086   template<typename _RealType = double>
02087     class normal_distribution
02088     {
02089       static_assert(std::is_floating_point<_RealType>::value,
02090             "template argument not a floating point type");
02091 
02092     public:
02093       /** The type of the range of the distribution. */
02094       typedef _RealType result_type;
02095       /** Parameter type. */
02096       struct param_type
02097       {
02098     typedef normal_distribution<_RealType> distribution_type;
02099 
02100     explicit
02101     param_type(_RealType __mean = _RealType(0),
02102            _RealType __stddev = _RealType(1))
02103     : _M_mean(__mean), _M_stddev(__stddev)
02104     {
02105       _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
02106     }
02107 
02108     _RealType
02109     mean() const
02110     { return _M_mean; }
02111 
02112     _RealType
02113     stddev() const
02114     { return _M_stddev; }
02115 
02116     friend bool
02117     operator==(const param_type& __p1, const param_type& __p2)
02118     { return (__p1._M_mean == __p2._M_mean
02119           && __p1._M_stddev == __p2._M_stddev); }
02120 
02121       private:
02122     _RealType _M_mean;
02123     _RealType _M_stddev;
02124       };
02125 
02126     public:
02127       /**
02128        * Constructs a normal distribution with parameters @f$mean@f$ and
02129        * standard deviation.
02130        */
02131       explicit
02132       normal_distribution(result_type __mean = result_type(0),
02133               result_type __stddev = result_type(1))
02134       : _M_param(__mean, __stddev), _M_saved_available(false)
02135       { }
02136 
02137       explicit
02138       normal_distribution(const param_type& __p)
02139       : _M_param(__p), _M_saved_available(false)
02140       { }
02141 
02142       /**
02143        * @brief Resets the distribution state.
02144        */
02145       void
02146       reset()
02147       { _M_saved_available = false; }
02148 
02149       /**
02150        * @brief Returns the mean of the distribution.
02151        */
02152       _RealType
02153       mean() const
02154       { return _M_param.mean(); }
02155 
02156       /**
02157        * @brief Returns the standard deviation of the distribution.
02158        */
02159       _RealType
02160       stddev() const
02161       { return _M_param.stddev(); }
02162 
02163       /**
02164        * @brief Returns the parameter set of the distribution.
02165        */
02166       param_type
02167       param() const
02168       { return _M_param; }
02169 
02170       /**
02171        * @brief Sets the parameter set of the distribution.
02172        * @param __param The new parameter set of the distribution.
02173        */
02174       void
02175       param(const param_type& __param)
02176       { _M_param = __param; }
02177 
02178       /**
02179        * @brief Returns the greatest lower bound value of the distribution.
02180        */
02181       result_type
02182       min() const
02183       { return std::numeric_limits<result_type>::lowest(); }
02184 
02185       /**
02186        * @brief Returns the least upper bound value of the distribution.
02187        */
02188       result_type
02189       max() const
02190       { return std::numeric_limits<result_type>::max(); }
02191 
02192       /**
02193        * @brief Generating functions.
02194        */
02195       template<typename _UniformRandomNumberGenerator>
02196     result_type
02197     operator()(_UniformRandomNumberGenerator& __urng)
02198     { return this->operator()(__urng, _M_param); }
02199 
02200       template<typename _UniformRandomNumberGenerator>
02201     result_type
02202     operator()(_UniformRandomNumberGenerator& __urng,
02203            const param_type& __p);
02204 
02205       template<typename _ForwardIterator,
02206            typename _UniformRandomNumberGenerator>
02207     void
02208     __generate(_ForwardIterator __f, _ForwardIterator __t,
02209            _UniformRandomNumberGenerator& __urng)
02210     { this->__generate(__f, __t, __urng, _M_param); }
02211 
02212       template<typename _ForwardIterator,
02213            typename _UniformRandomNumberGenerator>
02214     void
02215     __generate(_ForwardIterator __f, _ForwardIterator __t,
02216            _UniformRandomNumberGenerator& __urng,
02217            const param_type& __p)
02218     { this->__generate_impl(__f, __t, __urng, __p); }
02219 
02220       template<typename _UniformRandomNumberGenerator>
02221     void
02222     __generate(result_type* __f, result_type* __t,
02223            _UniformRandomNumberGenerator& __urng,
02224            const param_type& __p)
02225     { this->__generate_impl(__f, __t, __urng, __p); }
02226 
02227       /**
02228        * @brief Return true if two normal distributions have
02229        *        the same parameters and the sequences that would
02230        *        be generated are equal.
02231        */
02232       template<typename _RealType1>
02233     friend bool
02234         operator==(const std::normal_distribution<_RealType1>& __d1,
02235            const std::normal_distribution<_RealType1>& __d2);
02236 
02237       /**
02238        * @brief Inserts a %normal_distribution random number distribution
02239        * @p __x into the output stream @p __os.
02240        *
02241        * @param __os An output stream.
02242        * @param __x  A %normal_distribution random number distribution.
02243        *
02244        * @returns The output stream with the state of @p __x inserted or in
02245        * an error state.
02246        */
02247       template<typename _RealType1, typename _CharT, typename _Traits>
02248     friend std::basic_ostream<_CharT, _Traits>&
02249     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02250            const std::normal_distribution<_RealType1>& __x);
02251 
02252       /**
02253        * @brief Extracts a %normal_distribution random number distribution
02254        * @p __x from the input stream @p __is.
02255        *
02256        * @param __is An input stream.
02257        * @param __x  A %normal_distribution random number generator engine.
02258        *
02259        * @returns The input stream with @p __x extracted or in an error
02260        *          state.
02261        */
02262       template<typename _RealType1, typename _CharT, typename _Traits>
02263     friend std::basic_istream<_CharT, _Traits>&
02264     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02265            std::normal_distribution<_RealType1>& __x);
02266 
02267     private:
02268       template<typename _ForwardIterator,
02269            typename _UniformRandomNumberGenerator>
02270     void
02271     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
02272             _UniformRandomNumberGenerator& __urng,
02273             const param_type& __p);
02274 
02275       param_type  _M_param;
02276       result_type _M_saved;
02277       bool        _M_saved_available;
02278     };
02279 
02280   /**
02281    * @brief Return true if two normal distributions are different.
02282    */
02283   template<typename _RealType>
02284     inline bool
02285     operator!=(const std::normal_distribution<_RealType>& __d1,
02286            const std::normal_distribution<_RealType>& __d2)
02287     { return !(__d1 == __d2); }
02288 
02289 
02290   /**
02291    * @brief A lognormal_distribution random number distribution.
02292    *
02293    * The formula for the normal probability mass function is
02294    * @f[
02295    *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
02296    *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}} 
02297    * @f]
02298    */
02299   template<typename _RealType = double>
02300     class lognormal_distribution
02301     {
02302       static_assert(std::is_floating_point<_RealType>::value,
02303             "template argument not a floating point type");
02304 
02305     public:
02306       /** The type of the range of the distribution. */
02307       typedef _RealType result_type;
02308       /** Parameter type. */
02309       struct param_type
02310       {
02311     typedef lognormal_distribution<_RealType> distribution_type;
02312 
02313     explicit
02314     param_type(_RealType __m = _RealType(0),
02315            _RealType __s = _RealType(1))
02316     : _M_m(__m), _M_s(__s)
02317     { }
02318 
02319     _RealType
02320     m() const
02321     { return _M_m; }
02322 
02323     _RealType
02324     s() const
02325     { return _M_s; }
02326 
02327     friend bool
02328     operator==(const param_type& __p1, const param_type& __p2)
02329     { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
02330 
02331       private:
02332     _RealType _M_m;
02333     _RealType _M_s;
02334       };
02335 
02336       explicit
02337       lognormal_distribution(_RealType __m = _RealType(0),
02338                  _RealType __s = _RealType(1))
02339       : _M_param(__m, __s), _M_nd()
02340       { }
02341 
02342       explicit
02343       lognormal_distribution(const param_type& __p)
02344       : _M_param(__p), _M_nd()
02345       { }
02346 
02347       /**
02348        * Resets the distribution state.
02349        */
02350       void
02351       reset()
02352       { _M_nd.reset(); }
02353 
02354       /**
02355        *
02356        */
02357       _RealType
02358       m() const
02359       { return _M_param.m(); }
02360 
02361       _RealType
02362       s() const
02363       { return _M_param.s(); }
02364 
02365       /**
02366        * @brief Returns the parameter set of the distribution.
02367        */
02368       param_type
02369       param() const
02370       { return _M_param; }
02371 
02372       /**
02373        * @brief Sets the parameter set of the distribution.
02374        * @param __param The new parameter set of the distribution.
02375        */
02376       void
02377       param(const param_type& __param)
02378       { _M_param = __param; }
02379 
02380       /**
02381        * @brief Returns the greatest lower bound value of the distribution.
02382        */
02383       result_type
02384       min() const
02385       { return result_type(0); }
02386 
02387       /**
02388        * @brief Returns the least upper bound value of the distribution.
02389        */
02390       result_type
02391       max() const
02392       { return std::numeric_limits<result_type>::max(); }
02393 
02394       /**
02395        * @brief Generating functions.
02396        */
02397       template<typename _UniformRandomNumberGenerator>
02398     result_type
02399     operator()(_UniformRandomNumberGenerator& __urng)
02400         { return this->operator()(__urng, _M_param); }
02401 
02402       template<typename _UniformRandomNumberGenerator>
02403     result_type
02404     operator()(_UniformRandomNumberGenerator& __urng,
02405            const param_type& __p)
02406         { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
02407 
02408       template<typename _ForwardIterator,
02409            typename _UniformRandomNumberGenerator>
02410     void
02411     __generate(_ForwardIterator __f, _ForwardIterator __t,
02412            _UniformRandomNumberGenerator& __urng)
02413     { this->__generate(__f, __t, __urng, _M_param); }
02414 
02415       template<typename _ForwardIterator,
02416            typename _UniformRandomNumberGenerator>
02417     void
02418     __generate(_ForwardIterator __f, _ForwardIterator __t,
02419            _UniformRandomNumberGenerator& __urng,
02420            const param_type& __p)
02421     { this->__generate_impl(__f, __t, __urng, __p); }
02422 
02423       template<typename _UniformRandomNumberGenerator>
02424     void
02425     __generate(result_type* __f, result_type* __t,
02426            _UniformRandomNumberGenerator& __urng,
02427            const param_type& __p)
02428     { this->__generate_impl(__f, __t, __urng, __p); }
02429 
02430       /**
02431        * @brief Return true if two lognormal distributions have
02432        *        the same parameters and the sequences that would
02433        *        be generated are equal.
02434        */
02435       friend bool
02436       operator==(const lognormal_distribution& __d1,
02437          const lognormal_distribution& __d2)
02438       { return (__d1._M_param == __d2._M_param
02439         && __d1._M_nd == __d2._M_nd); }
02440 
02441       /**
02442        * @brief Inserts a %lognormal_distribution random number distribution
02443        * @p __x into the output stream @p __os.
02444        *
02445        * @param __os An output stream.
02446        * @param __x  A %lognormal_distribution random number distribution.
02447        *
02448        * @returns The output stream with the state of @p __x inserted or in
02449        * an error state.
02450        */
02451       template<typename _RealType1, typename _CharT, typename _Traits>
02452     friend std::basic_ostream<_CharT, _Traits>&
02453     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02454            const std::lognormal_distribution<_RealType1>& __x);
02455 
02456       /**
02457        * @brief Extracts a %lognormal_distribution random number distribution
02458        * @p __x from the input stream @p __is.
02459        *
02460        * @param __is An input stream.
02461        * @param __x A %lognormal_distribution random number
02462        *            generator engine.
02463        *
02464        * @returns The input stream with @p __x extracted or in an error state.
02465        */
02466       template<typename _RealType1, typename _CharT, typename _Traits>
02467     friend std::basic_istream<_CharT, _Traits>&
02468     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02469            std::lognormal_distribution<_RealType1>& __x);
02470 
02471     private:
02472       template<typename _ForwardIterator,
02473            typename _UniformRandomNumberGenerator>
02474     void
02475     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
02476             _UniformRandomNumberGenerator& __urng,
02477             const param_type& __p);
02478 
02479       param_type _M_param;
02480 
02481       std::normal_distribution<result_type> _M_nd;
02482     };
02483 
02484   /**
02485    * @brief Return true if two lognormal distributions are different.
02486    */
02487   template<typename _RealType>
02488     inline bool
02489     operator!=(const std::lognormal_distribution<_RealType>& __d1,
02490            const std::lognormal_distribution<_RealType>& __d2)
02491     { return !(__d1 == __d2); }
02492 
02493 
02494   /**
02495    * @brief A gamma continuous distribution for random numbers.
02496    *
02497    * The formula for the gamma probability density function is:
02498    * @f[
02499    *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
02500    *                         (x/\beta)^{\alpha - 1} e^{-x/\beta} 
02501    * @f]
02502    */
02503   template<typename _RealType = double>
02504     class gamma_distribution
02505     {
02506       static_assert(std::is_floating_point<_RealType>::value,
02507             "template argument not a floating point type");
02508 
02509     public:
02510       /** The type of the range of the distribution. */
02511       typedef _RealType result_type;
02512       /** Parameter type. */
02513       struct param_type
02514       {
02515     typedef gamma_distribution<_RealType> distribution_type;
02516     friend class gamma_distribution<_RealType>;
02517 
02518     explicit
02519     param_type(_RealType __alpha_val = _RealType(1),
02520            _RealType __beta_val = _RealType(1))
02521     : _M_alpha(__alpha_val), _M_beta(__beta_val)
02522     {
02523       _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
02524       _M_initialize();
02525     }
02526 
02527     _RealType
02528     alpha() const
02529     { return _M_alpha; }
02530 
02531     _RealType
02532     beta() const
02533     { return _M_beta; }
02534 
02535     friend bool
02536     operator==(const param_type& __p1, const param_type& __p2)
02537     { return (__p1._M_alpha == __p2._M_alpha
02538           && __p1._M_beta == __p2._M_beta); }
02539 
02540       private:
02541     void
02542     _M_initialize();
02543 
02544     _RealType _M_alpha;
02545     _RealType _M_beta;
02546 
02547     _RealType _M_malpha, _M_a2;
02548       };
02549 
02550     public:
02551       /**
02552        * @brief Constructs a gamma distribution with parameters
02553        * @f$\alpha@f$ and @f$\beta@f$.
02554        */
02555       explicit
02556       gamma_distribution(_RealType __alpha_val = _RealType(1),
02557              _RealType __beta_val = _RealType(1))
02558       : _M_param(__alpha_val, __beta_val), _M_nd()
02559       { }
02560 
02561       explicit
02562       gamma_distribution(const param_type& __p)
02563       : _M_param(__p), _M_nd()
02564       { }
02565 
02566       /**
02567        * @brief Resets the distribution state.
02568        */
02569       void
02570       reset()
02571       { _M_nd.reset(); }
02572 
02573       /**
02574        * @brief Returns the @f$\alpha@f$ of the distribution.
02575        */
02576       _RealType
02577       alpha() const
02578       { return _M_param.alpha(); }
02579 
02580       /**
02581        * @brief Returns the @f$\beta@f$ of the distribution.
02582        */
02583       _RealType
02584       beta() const
02585       { return _M_param.beta(); }
02586 
02587       /**
02588        * @brief Returns the parameter set of the distribution.
02589        */
02590       param_type
02591       param() const
02592       { return _M_param; }
02593 
02594       /**
02595        * @brief Sets the parameter set of the distribution.
02596        * @param __param The new parameter set of the distribution.
02597        */
02598       void
02599       param(const param_type& __param)
02600       { _M_param = __param; }
02601 
02602       /**
02603        * @brief Returns the greatest lower bound value of the distribution.
02604        */
02605       result_type
02606       min() const
02607       { return result_type(0); }
02608 
02609       /**
02610        * @brief Returns the least upper bound value of the distribution.
02611        */
02612       result_type
02613       max() const
02614       { return std::numeric_limits<result_type>::max(); }
02615 
02616       /**
02617        * @brief Generating functions.
02618        */
02619       template<typename _UniformRandomNumberGenerator>
02620     result_type
02621     operator()(_UniformRandomNumberGenerator& __urng)
02622     { return this->operator()(__urng, _M_param); }
02623 
02624       template<typename _UniformRandomNumberGenerator>
02625     result_type
02626     operator()(_UniformRandomNumberGenerator& __urng,
02627            const param_type& __p);
02628 
02629       template<typename _ForwardIterator,
02630            typename _UniformRandomNumberGenerator>
02631     void
02632     __generate(_ForwardIterator __f, _ForwardIterator __t,
02633            _UniformRandomNumberGenerator& __urng)
02634     { this->__generate(__f, __t, __urng, _M_param); }
02635 
02636       template<typename _ForwardIterator,
02637            typename _UniformRandomNumberGenerator>
02638     void
02639     __generate(_ForwardIterator __f, _ForwardIterator __t,
02640            _UniformRandomNumberGenerator& __urng,
02641            const param_type& __p)
02642     { this->__generate_impl(__f, __t, __urng, __p); }
02643 
02644       template<typename _UniformRandomNumberGenerator>
02645     void
02646     __generate(result_type* __f, result_type* __t,
02647            _UniformRandomNumberGenerator& __urng,
02648            const param_type& __p)
02649     { this->__generate_impl(__f, __t, __urng, __p); }
02650 
02651       /**
02652        * @brief Return true if two gamma distributions have the same
02653        *        parameters and the sequences that would be generated
02654        *        are equal.
02655        */
02656       friend bool
02657       operator==(const gamma_distribution& __d1,
02658          const gamma_distribution& __d2)
02659       { return (__d1._M_param == __d2._M_param
02660         && __d1._M_nd == __d2._M_nd); }
02661 
02662       /**
02663        * @brief Inserts a %gamma_distribution random number distribution
02664        * @p __x into the output stream @p __os.
02665        *
02666        * @param __os An output stream.
02667        * @param __x  A %gamma_distribution random number distribution.
02668        *
02669        * @returns The output stream with the state of @p __x inserted or in
02670        * an error state.
02671        */
02672       template<typename _RealType1, typename _CharT, typename _Traits>
02673     friend std::basic_ostream<_CharT, _Traits>&
02674     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02675            const std::gamma_distribution<_RealType1>& __x);
02676 
02677       /**
02678        * @brief Extracts a %gamma_distribution random number distribution
02679        * @p __x from the input stream @p __is.
02680        *
02681        * @param __is An input stream.
02682        * @param __x  A %gamma_distribution random number generator engine.
02683        *
02684        * @returns The input stream with @p __x extracted or in an error state.
02685        */
02686       template<typename _RealType1, typename _CharT, typename _Traits>
02687     friend std::basic_istream<_CharT, _Traits>&
02688     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02689            std::gamma_distribution<_RealType1>& __x);
02690 
02691     private:
02692       template<typename _ForwardIterator,
02693            typename _UniformRandomNumberGenerator>
02694     void
02695     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
02696             _UniformRandomNumberGenerator& __urng,
02697             const param_type& __p);
02698 
02699       param_type _M_param;
02700 
02701       std::normal_distribution<result_type> _M_nd;
02702     };
02703 
02704   /**
02705    * @brief Return true if two gamma distributions are different.
02706    */
02707    template<typename _RealType>
02708      inline bool
02709      operator!=(const std::gamma_distribution<_RealType>& __d1,
02710         const std::gamma_distribution<_RealType>& __d2)
02711     { return !(__d1 == __d2); }
02712 
02713 
02714   /**
02715    * @brief A chi_squared_distribution random number distribution.
02716    *
02717    * The formula for the normal probability mass function is
02718    * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
02719    */
02720   template<typename _RealType = double>
02721     class chi_squared_distribution
02722     {
02723       static_assert(std::is_floating_point<_RealType>::value,
02724             "template argument not a floating point type");
02725 
02726     public:
02727       /** The type of the range of the distribution. */
02728       typedef _RealType result_type;
02729       /** Parameter type. */
02730       struct param_type
02731       {
02732     typedef chi_squared_distribution<_RealType> distribution_type;
02733 
02734     explicit
02735     param_type(_RealType __n = _RealType(1))
02736     : _M_n(__n)
02737     { }
02738 
02739     _RealType
02740     n() const
02741     { return _M_n; }
02742 
02743     friend bool
02744     operator==(const param_type& __p1, const param_type& __p2)
02745     { return __p1._M_n == __p2._M_n; }
02746 
02747       private:
02748     _RealType _M_n;
02749       };
02750 
02751       explicit
02752       chi_squared_distribution(_RealType __n = _RealType(1))
02753       : _M_param(__n), _M_gd(__n / 2)
02754       { }
02755 
02756       explicit
02757       chi_squared_distribution(const param_type& __p)
02758       : _M_param(__p), _M_gd(__p.n() / 2)
02759       { }
02760 
02761       /**
02762        * @brief Resets the distribution state.
02763        */
02764       void
02765       reset()
02766       { _M_gd.reset(); }
02767 
02768       /**
02769        *
02770        */
02771       _RealType
02772       n() const
02773       { return _M_param.n(); }
02774 
02775       /**
02776        * @brief Returns the parameter set of the distribution.
02777        */
02778       param_type
02779       param() const
02780       { return _M_param; }
02781 
02782       /**
02783        * @brief Sets the parameter set of the distribution.
02784        * @param __param The new parameter set of the distribution.
02785        */
02786       void
02787       param(const param_type& __param)
02788       { _M_param = __param; }
02789 
02790       /**
02791        * @brief Returns the greatest lower bound value of the distribution.
02792        */
02793       result_type
02794       min() const
02795       { return result_type(0); }
02796 
02797       /**
02798        * @brief Returns the least upper bound value of the distribution.
02799        */
02800       result_type
02801       max() const
02802       { return std::numeric_limits<result_type>::max(); }
02803 
02804       /**
02805        * @brief Generating functions.
02806        */
02807       template<typename _UniformRandomNumberGenerator>
02808     result_type
02809     operator()(_UniformRandomNumberGenerator& __urng)
02810     { return 2 * _M_gd(__urng); }
02811 
02812       template<typename _UniformRandomNumberGenerator>
02813     result_type
02814     operator()(_UniformRandomNumberGenerator& __urng,
02815            const param_type& __p)
02816         {
02817       typedef typename std::gamma_distribution<result_type>::param_type
02818         param_type;
02819       return 2 * _M_gd(__urng, param_type(__p.n() / 2));
02820     }
02821 
02822       template<typename _ForwardIterator,
02823            typename _UniformRandomNumberGenerator>
02824     void
02825     __generate(_ForwardIterator __f, _ForwardIterator __t,
02826            _UniformRandomNumberGenerator& __urng)
02827         { this->__generate_impl(__f, __t, __urng); }
02828 
02829       template<typename _ForwardIterator,
02830            typename _UniformRandomNumberGenerator>
02831     void
02832     __generate(_ForwardIterator __f, _ForwardIterator __t,
02833            _UniformRandomNumberGenerator& __urng,
02834            const param_type& __p)
02835     { typename std::gamma_distribution<result_type>::param_type
02836         __p2(__p.n() / 2);
02837       this->__generate_impl(__f, __t, __urng, __p2); }
02838 
02839       template<typename _UniformRandomNumberGenerator>
02840     void
02841     __generate(result_type* __f, result_type* __t,
02842            _UniformRandomNumberGenerator& __urng)
02843         { this->__generate_impl(__f, __t, __urng); }
02844 
02845       template<typename _UniformRandomNumberGenerator>
02846     void
02847     __generate(result_type* __f, result_type* __t,
02848            _UniformRandomNumberGenerator& __urng,
02849            const param_type& __p)
02850     { typename std::gamma_distribution<result_type>::param_type
02851         __p2(__p.n() / 2);
02852       this->__generate_impl(__f, __t, __urng, __p2); }
02853 
02854       /**
02855        * @brief Return true if two Chi-squared distributions have
02856        *        the same parameters and the sequences that would be
02857        *        generated are equal.
02858        */
02859       friend bool
02860       operator==(const chi_squared_distribution& __d1,
02861          const chi_squared_distribution& __d2)
02862       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
02863 
02864       /**
02865        * @brief Inserts a %chi_squared_distribution random number distribution
02866        * @p __x into the output stream @p __os.
02867        *
02868        * @param __os An output stream.
02869        * @param __x  A %chi_squared_distribution random number distribution.
02870        *
02871        * @returns The output stream with the state of @p __x inserted or in
02872        * an error state.
02873        */
02874       template<typename _RealType1, typename _CharT, typename _Traits>
02875     friend std::basic_ostream<_CharT, _Traits>&
02876     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02877            const std::chi_squared_distribution<_RealType1>& __x);
02878 
02879       /**
02880        * @brief Extracts a %chi_squared_distribution random number distribution
02881        * @p __x from the input stream @p __is.
02882        *
02883        * @param __is An input stream.
02884        * @param __x A %chi_squared_distribution random number
02885        *            generator engine.
02886        *
02887        * @returns The input stream with @p __x extracted or in an error state.
02888        */
02889       template<typename _RealType1, typename _CharT, typename _Traits>
02890     friend std::basic_istream<_CharT, _Traits>&
02891     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02892            std::chi_squared_distribution<_RealType1>& __x);
02893 
02894     private:
02895       template<typename _ForwardIterator,
02896            typename _UniformRandomNumberGenerator>
02897     void
02898     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
02899             _UniformRandomNumberGenerator& __urng);
02900 
02901       template<typename _ForwardIterator,
02902            typename _UniformRandomNumberGenerator>
02903     void
02904     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
02905             _UniformRandomNumberGenerator& __urng,
02906             const typename
02907             std::gamma_distribution<result_type>::param_type& __p);
02908 
02909       param_type _M_param;
02910 
02911       std::gamma_distribution<result_type> _M_gd;
02912     };
02913 
02914   /**
02915    * @brief Return true if two Chi-squared distributions are different.
02916    */
02917   template<typename _RealType>
02918     inline bool
02919     operator!=(const std::chi_squared_distribution<_RealType>& __d1,
02920            const std::chi_squared_distribution<_RealType>& __d2)
02921     { return !(__d1 == __d2); }
02922 
02923 
02924   /**
02925    * @brief A cauchy_distribution random number distribution.
02926    *
02927    * The formula for the normal probability mass function is
02928    * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
02929    */
02930   template<typename _RealType = double>
02931     class cauchy_distribution
02932     {
02933       static_assert(std::is_floating_point<_RealType>::value,
02934             "template argument not a floating point type");
02935 
02936     public:
02937       /** The type of the range of the distribution. */
02938       typedef _RealType result_type;
02939       /** Parameter type. */
02940       struct param_type
02941       {
02942     typedef cauchy_distribution<_RealType> distribution_type;
02943 
02944     explicit
02945     param_type(_RealType __a = _RealType(0),
02946            _RealType __b = _RealType(1))
02947     : _M_a(__a), _M_b(__b)
02948     { }
02949 
02950     _RealType
02951     a() const
02952     { return _M_a; }
02953 
02954     _RealType
02955     b() const
02956     { return _M_b; }
02957 
02958     friend bool
02959     operator==(const param_type& __p1, const param_type& __p2)
02960     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
02961 
02962       private:
02963     _RealType _M_a;
02964     _RealType _M_b;
02965       };
02966 
02967       explicit
02968       cauchy_distribution(_RealType __a = _RealType(0),
02969               _RealType __b = _RealType(1))
02970       : _M_param(__a, __b)
02971       { }
02972 
02973       explicit
02974       cauchy_distribution(const param_type& __p)
02975       : _M_param(__p)
02976       { }
02977 
02978       /**
02979        * @brief Resets the distribution state.
02980        */
02981       void
02982       reset()
02983       { }
02984 
02985       /**
02986        *
02987        */
02988       _RealType
02989       a() const
02990       { return _M_param.a(); }
02991 
02992       _RealType
02993       b() const
02994       { return _M_param.b(); }
02995 
02996       /**
02997        * @brief Returns the parameter set of the distribution.
02998        */
02999       param_type
03000       param() const
03001       { return _M_param; }
03002 
03003       /**
03004        * @brief Sets the parameter set of the distribution.
03005        * @param __param The new parameter set of the distribution.
03006        */
03007       void
03008       param(const param_type& __param)
03009       { _M_param = __param; }
03010 
03011       /**
03012        * @brief Returns the greatest lower bound value of the distribution.
03013        */
03014       result_type
03015       min() const
03016       { return std::numeric_limits<result_type>::lowest(); }
03017 
03018       /**
03019        * @brief Returns the least upper bound value of the distribution.
03020        */
03021       result_type
03022       max() const
03023       { return std::numeric_limits<result_type>::max(); }
03024 
03025       /**
03026        * @brief Generating functions.
03027        */
03028       template<typename _UniformRandomNumberGenerator>
03029     result_type
03030     operator()(_UniformRandomNumberGenerator& __urng)
03031     { return this->operator()(__urng, _M_param); }
03032 
03033       template<typename _UniformRandomNumberGenerator>
03034     result_type
03035     operator()(_UniformRandomNumberGenerator& __urng,
03036            const param_type& __p);
03037 
03038       template<typename _ForwardIterator,
03039            typename _UniformRandomNumberGenerator>
03040     void
03041     __generate(_ForwardIterator __f, _ForwardIterator __t,
03042            _UniformRandomNumberGenerator& __urng)
03043     { this->__generate(__f, __t, __urng, _M_param); }
03044 
03045       template<typename _ForwardIterator,
03046            typename _UniformRandomNumberGenerator>
03047     void
03048     __generate(_ForwardIterator __f, _ForwardIterator __t,
03049            _UniformRandomNumberGenerator& __urng,
03050            const param_type& __p)
03051     { this->__generate_impl(__f, __t, __urng, __p); }
03052 
03053       template<typename _UniformRandomNumberGenerator>
03054     void
03055     __generate(result_type* __f, result_type* __t,
03056            _UniformRandomNumberGenerator& __urng,
03057            const param_type& __p)
03058     { this->__generate_impl(__f, __t, __urng, __p); }
03059 
03060       /**
03061        * @brief Return true if two Cauchy distributions have
03062        *        the same parameters.
03063        */
03064       friend bool
03065       operator==(const cauchy_distribution& __d1,
03066          const cauchy_distribution& __d2)
03067       { return __d1._M_param == __d2._M_param; }
03068 
03069     private:
03070       template<typename _ForwardIterator,
03071            typename _UniformRandomNumberGenerator>
03072     void
03073     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03074             _UniformRandomNumberGenerator& __urng,
03075             const param_type& __p);
03076 
03077       param_type _M_param;
03078     };
03079 
03080   /**
03081    * @brief Return true if two Cauchy distributions have
03082    *        different parameters.
03083    */
03084   template<typename _RealType>
03085     inline bool
03086     operator!=(const std::cauchy_distribution<_RealType>& __d1,
03087            const std::cauchy_distribution<_RealType>& __d2)
03088     { return !(__d1 == __d2); }
03089 
03090   /**
03091    * @brief Inserts a %cauchy_distribution random number distribution
03092    * @p __x into the output stream @p __os.
03093    *
03094    * @param __os An output stream.
03095    * @param __x  A %cauchy_distribution random number distribution.
03096    *
03097    * @returns The output stream with the state of @p __x inserted or in
03098    * an error state.
03099    */
03100   template<typename _RealType, typename _CharT, typename _Traits>
03101     std::basic_ostream<_CharT, _Traits>&
03102     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03103            const std::cauchy_distribution<_RealType>& __x);
03104 
03105   /**
03106    * @brief Extracts a %cauchy_distribution random number distribution
03107    * @p __x from the input stream @p __is.
03108    *
03109    * @param __is An input stream.
03110    * @param __x A %cauchy_distribution random number
03111    *            generator engine.
03112    *
03113    * @returns The input stream with @p __x extracted or in an error state.
03114    */
03115   template<typename _RealType, typename _CharT, typename _Traits>
03116     std::basic_istream<_CharT, _Traits>&
03117     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03118            std::cauchy_distribution<_RealType>& __x);
03119 
03120 
03121   /**
03122    * @brief A fisher_f_distribution random number distribution.
03123    *
03124    * The formula for the normal probability mass function is
03125    * @f[
03126    *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
03127    *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
03128    *                (1 + \frac{mx}{n})^{-(m+n)/2} 
03129    * @f]
03130    */
03131   template<typename _RealType = double>
03132     class fisher_f_distribution
03133     {
03134       static_assert(std::is_floating_point<_RealType>::value,
03135             "template argument not a floating point type");
03136 
03137     public:
03138       /** The type of the range of the distribution. */
03139       typedef _RealType result_type;
03140       /** Parameter type. */
03141       struct param_type
03142       {
03143     typedef fisher_f_distribution<_RealType> distribution_type;
03144 
03145     explicit
03146     param_type(_RealType __m = _RealType(1),
03147            _RealType __n = _RealType(1))
03148     : _M_m(__m), _M_n(__n)
03149     { }
03150 
03151     _RealType
03152     m() const
03153     { return _M_m; }
03154 
03155     _RealType
03156     n() const
03157     { return _M_n; }
03158 
03159     friend bool
03160     operator==(const param_type& __p1, const param_type& __p2)
03161     { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
03162 
03163       private:
03164     _RealType _M_m;
03165     _RealType _M_n;
03166       };
03167 
03168       explicit
03169       fisher_f_distribution(_RealType __m = _RealType(1),
03170                 _RealType __n = _RealType(1))
03171       : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
03172       { }
03173 
03174       explicit
03175       fisher_f_distribution(const param_type& __p)
03176       : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
03177       { }
03178 
03179       /**
03180        * @brief Resets the distribution state.
03181        */
03182       void
03183       reset()
03184       {
03185     _M_gd_x.reset();
03186     _M_gd_y.reset();
03187       }
03188 
03189       /**
03190        *
03191        */
03192       _RealType
03193       m() const
03194       { return _M_param.m(); }
03195 
03196       _RealType
03197       n() const
03198       { return _M_param.n(); }
03199 
03200       /**
03201        * @brief Returns the parameter set of the distribution.
03202        */
03203       param_type
03204       param() const
03205       { return _M_param; }
03206 
03207       /**
03208        * @brief Sets the parameter set of the distribution.
03209        * @param __param The new parameter set of the distribution.
03210        */
03211       void
03212       param(const param_type& __param)
03213       { _M_param = __param; }
03214 
03215       /**
03216        * @brief Returns the greatest lower bound value of the distribution.
03217        */
03218       result_type
03219       min() const
03220       { return result_type(0); }
03221 
03222       /**
03223        * @brief Returns the least upper bound value of the distribution.
03224        */
03225       result_type
03226       max() const
03227       { return std::numeric_limits<result_type>::max(); }
03228 
03229       /**
03230        * @brief Generating functions.
03231        */
03232       template<typename _UniformRandomNumberGenerator>
03233     result_type
03234     operator()(_UniformRandomNumberGenerator& __urng)
03235     { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
03236 
03237       template<typename _UniformRandomNumberGenerator>
03238     result_type
03239     operator()(_UniformRandomNumberGenerator& __urng,
03240            const param_type& __p)
03241         {
03242       typedef typename std::gamma_distribution<result_type>::param_type
03243         param_type;
03244       return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
03245           / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
03246     }
03247 
03248       template<typename _ForwardIterator,
03249            typename _UniformRandomNumberGenerator>
03250     void
03251     __generate(_ForwardIterator __f, _ForwardIterator __t,
03252            _UniformRandomNumberGenerator& __urng)
03253     { this->__generate_impl(__f, __t, __urng); }
03254 
03255       template<typename _ForwardIterator,
03256            typename _UniformRandomNumberGenerator>
03257     void
03258     __generate(_ForwardIterator __f, _ForwardIterator __t,
03259            _UniformRandomNumberGenerator& __urng,
03260            const param_type& __p)
03261     { this->__generate_impl(__f, __t, __urng, __p); }
03262 
03263       template<typename _UniformRandomNumberGenerator>
03264     void
03265     __generate(result_type* __f, result_type* __t,
03266            _UniformRandomNumberGenerator& __urng)
03267     { this->__generate_impl(__f, __t, __urng); }
03268 
03269       template<typename _UniformRandomNumberGenerator>
03270     void
03271     __generate(result_type* __f, result_type* __t,
03272            _UniformRandomNumberGenerator& __urng,
03273            const param_type& __p)
03274     { this->__generate_impl(__f, __t, __urng, __p); }
03275 
03276       /**
03277        * @brief Return true if two Fisher f distributions have
03278        *        the same parameters and the sequences that would
03279        *        be generated are equal.
03280        */
03281       friend bool
03282       operator==(const fisher_f_distribution& __d1,
03283          const fisher_f_distribution& __d2)
03284       { return (__d1._M_param == __d2._M_param
03285         && __d1._M_gd_x == __d2._M_gd_x
03286         && __d1._M_gd_y == __d2._M_gd_y); }
03287 
03288       /**
03289        * @brief Inserts a %fisher_f_distribution random number distribution
03290        * @p __x into the output stream @p __os.
03291        *
03292        * @param __os An output stream.
03293        * @param __x  A %fisher_f_distribution random number distribution.
03294        *
03295        * @returns The output stream with the state of @p __x inserted or in
03296        * an error state.
03297        */
03298       template<typename _RealType1, typename _CharT, typename _Traits>
03299     friend std::basic_ostream<_CharT, _Traits>&
03300     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03301            const std::fisher_f_distribution<_RealType1>& __x);
03302 
03303       /**
03304        * @brief Extracts a %fisher_f_distribution random number distribution
03305        * @p __x from the input stream @p __is.
03306        *
03307        * @param __is An input stream.
03308        * @param __x A %fisher_f_distribution random number
03309        *            generator engine.
03310        *
03311        * @returns The input stream with @p __x extracted or in an error state.
03312        */
03313       template<typename _RealType1, typename _CharT, typename _Traits>
03314     friend std::basic_istream<_CharT, _Traits>&
03315     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03316            std::fisher_f_distribution<_RealType1>& __x);
03317 
03318     private:
03319       template<typename _ForwardIterator,
03320            typename _UniformRandomNumberGenerator>
03321     void
03322     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03323             _UniformRandomNumberGenerator& __urng);
03324 
03325       template<typename _ForwardIterator,
03326            typename _UniformRandomNumberGenerator>
03327     void
03328     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03329             _UniformRandomNumberGenerator& __urng,
03330             const param_type& __p);
03331 
03332       param_type _M_param;
03333 
03334       std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
03335     };
03336 
03337   /**
03338    * @brief Return true if two Fisher f distributions are different.
03339    */
03340   template<typename _RealType>
03341     inline bool
03342     operator!=(const std::fisher_f_distribution<_RealType>& __d1,
03343            const std::fisher_f_distribution<_RealType>& __d2)
03344     { return !(__d1 == __d2); }
03345 
03346   /**
03347    * @brief A student_t_distribution random number distribution.
03348    *
03349    * The formula for the normal probability mass function is:
03350    * @f[
03351    *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
03352    *              (1 + \frac{x^2}{n}) ^{-(n+1)/2} 
03353    * @f]
03354    */
03355   template<typename _RealType = double>
03356     class student_t_distribution
03357     {
03358       static_assert(std::is_floating_point<_RealType>::value,
03359             "template argument not a floating point type");
03360 
03361     public:
03362       /** The type of the range of the distribution. */
03363       typedef _RealType result_type;
03364       /** Parameter type. */
03365       struct param_type
03366       {
03367     typedef student_t_distribution<_RealType> distribution_type;
03368 
03369     explicit
03370     param_type(_RealType __n = _RealType(1))
03371     : _M_n(__n)
03372     { }
03373 
03374     _RealType
03375     n() const
03376     { return _M_n; }
03377 
03378     friend bool
03379     operator==(const param_type& __p1, const param_type& __p2)
03380     { return __p1._M_n == __p2._M_n; }
03381 
03382       private:
03383     _RealType _M_n;
03384       };
03385 
03386       explicit
03387       student_t_distribution(_RealType __n = _RealType(1))
03388       : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
03389       { }
03390 
03391       explicit
03392       student_t_distribution(const param_type& __p)
03393       : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
03394       { }
03395 
03396       /**
03397        * @brief Resets the distribution state.
03398        */
03399       void
03400       reset()
03401       {
03402     _M_nd.reset();
03403     _M_gd.reset();
03404       }
03405 
03406       /**
03407        *
03408        */
03409       _RealType
03410       n() const
03411       { return _M_param.n(); }
03412 
03413       /**
03414        * @brief Returns the parameter set of the distribution.
03415        */
03416       param_type
03417       param() const
03418       { return _M_param; }
03419 
03420       /**
03421        * @brief Sets the parameter set of the distribution.
03422        * @param __param The new parameter set of the distribution.
03423        */
03424       void
03425       param(const param_type& __param)
03426       { _M_param = __param; }
03427 
03428       /**
03429        * @brief Returns the greatest lower bound value of the distribution.
03430        */
03431       result_type
03432       min() const
03433       { return std::numeric_limits<result_type>::lowest(); }
03434 
03435       /**
03436        * @brief Returns the least upper bound value of the distribution.
03437        */
03438       result_type
03439       max() const
03440       { return std::numeric_limits<result_type>::max(); }
03441 
03442       /**
03443        * @brief Generating functions.
03444        */
03445       template<typename _UniformRandomNumberGenerator>
03446     result_type
03447         operator()(_UniformRandomNumberGenerator& __urng)
03448         { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
03449 
03450       template<typename _UniformRandomNumberGenerator>
03451     result_type
03452     operator()(_UniformRandomNumberGenerator& __urng,
03453            const param_type& __p)
03454         {
03455       typedef typename std::gamma_distribution<result_type>::param_type
03456         param_type;
03457     
03458       const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
03459       return _M_nd(__urng) * std::sqrt(__p.n() / __g);
03460         }
03461 
03462       template<typename _ForwardIterator,
03463            typename _UniformRandomNumberGenerator>
03464     void
03465     __generate(_ForwardIterator __f, _ForwardIterator __t,
03466            _UniformRandomNumberGenerator& __urng)
03467     { this->__generate_impl(__f, __t, __urng); }
03468 
03469       template<typename _ForwardIterator,
03470            typename _UniformRandomNumberGenerator>
03471     void
03472     __generate(_ForwardIterator __f, _ForwardIterator __t,
03473            _UniformRandomNumberGenerator& __urng,
03474            const param_type& __p)
03475     { this->__generate_impl(__f, __t, __urng, __p); }
03476 
03477       template<typename _UniformRandomNumberGenerator>
03478     void
03479     __generate(result_type* __f, result_type* __t,
03480            _UniformRandomNumberGenerator& __urng)
03481     { this->__generate_impl(__f, __t, __urng); }
03482 
03483       template<typename _UniformRandomNumberGenerator>
03484     void
03485     __generate(result_type* __f, result_type* __t,
03486            _UniformRandomNumberGenerator& __urng,
03487            const param_type& __p)
03488     { this->__generate_impl(__f, __t, __urng, __p); }
03489 
03490       /**
03491        * @brief Return true if two Student t distributions have
03492        *        the same parameters and the sequences that would
03493        *        be generated are equal.
03494        */
03495       friend bool
03496       operator==(const student_t_distribution& __d1,
03497          const student_t_distribution& __d2)
03498       { return (__d1._M_param == __d2._M_param
03499         && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
03500 
03501       /**
03502        * @brief Inserts a %student_t_distribution random number distribution
03503        * @p __x into the output stream @p __os.
03504        *
03505        * @param __os An output stream.
03506        * @param __x  A %student_t_distribution random number distribution.
03507        *
03508        * @returns The output stream with the state of @p __x inserted or in
03509        * an error state.
03510        */
03511       template<typename _RealType1, typename _CharT, typename _Traits>
03512     friend std::basic_ostream<_CharT, _Traits>&
03513     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03514            const std::student_t_distribution<_RealType1>& __x);
03515 
03516       /**
03517        * @brief Extracts a %student_t_distribution random number distribution
03518        * @p __x from the input stream @p __is.
03519        *
03520        * @param __is An input stream.
03521        * @param __x A %student_t_distribution random number
03522        *            generator engine.
03523        *
03524        * @returns The input stream with @p __x extracted or in an error state.
03525        */
03526       template<typename _RealType1, typename _CharT, typename _Traits>
03527     friend std::basic_istream<_CharT, _Traits>&
03528     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03529            std::student_t_distribution<_RealType1>& __x);
03530 
03531     private:
03532       template<typename _ForwardIterator,
03533            typename _UniformRandomNumberGenerator>
03534     void
03535     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03536             _UniformRandomNumberGenerator& __urng);
03537       template<typename _ForwardIterator,
03538            typename _UniformRandomNumberGenerator>
03539     void
03540     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03541             _UniformRandomNumberGenerator& __urng,
03542             const param_type& __p);
03543 
03544       param_type _M_param;
03545 
03546       std::normal_distribution<result_type> _M_nd;
03547       std::gamma_distribution<result_type> _M_gd;
03548     };
03549 
03550   /**
03551    * @brief Return true if two Student t distributions are different.
03552    */
03553   template<typename _RealType>
03554     inline bool
03555     operator!=(const std::student_t_distribution<_RealType>& __d1,
03556            const std::student_t_distribution<_RealType>& __d2)
03557     { return !(__d1 == __d2); }
03558 
03559 
03560   /* @} */ // group random_distributions_normal
03561 
03562   /**
03563    * @addtogroup random_distributions_bernoulli Bernoulli Distributions
03564    * @ingroup random_distributions
03565    * @{
03566    */
03567 
03568   /**
03569    * @brief A Bernoulli random number distribution.
03570    *
03571    * Generates a sequence of true and false values with likelihood @f$p@f$
03572    * that true will come up and @f$(1 - p)@f$ that false will appear.
03573    */
03574   class bernoulli_distribution
03575   {
03576   public:
03577     /** The type of the range of the distribution. */
03578     typedef bool result_type;
03579     /** Parameter type. */
03580     struct param_type
03581     {
03582       typedef bernoulli_distribution distribution_type;
03583 
03584       explicit
03585       param_type(double __p = 0.5)
03586       : _M_p(__p)
03587       {
03588     _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
03589       }
03590 
03591       double
03592       p() const
03593       { return _M_p; }
03594 
03595       friend bool
03596       operator==(const param_type& __p1, const param_type& __p2)
03597       { return __p1._M_p == __p2._M_p; }
03598 
03599     private:
03600       double _M_p;
03601     };
03602 
03603   public:
03604     /**
03605      * @brief Constructs a Bernoulli distribution with likelihood @p p.
03606      *
03607      * @param __p  [IN]  The likelihood of a true result being returned.
03608      *                   Must be in the interval @f$[0, 1]@f$.
03609      */
03610     explicit
03611     bernoulli_distribution(double __p = 0.5)
03612     : _M_param(__p)
03613     { }
03614 
03615     explicit
03616     bernoulli_distribution(const param_type& __p)
03617     : _M_param(__p)
03618     { }
03619 
03620     /**
03621      * @brief Resets the distribution state.
03622      *
03623      * Does nothing for a Bernoulli distribution.
03624      */
03625     void
03626     reset() { }
03627 
03628     /**
03629      * @brief Returns the @p p parameter of the distribution.
03630      */
03631     double
03632     p() const
03633     { return _M_param.p(); }
03634 
03635     /**
03636      * @brief Returns the parameter set of the distribution.
03637      */
03638     param_type
03639     param() const
03640     { return _M_param; }
03641 
03642     /**
03643      * @brief Sets the parameter set of the distribution.
03644      * @param __param The new parameter set of the distribution.
03645      */
03646     void
03647     param(const param_type& __param)
03648     { _M_param = __param; }
03649 
03650     /**
03651      * @brief Returns the greatest lower bound value of the distribution.
03652      */
03653     result_type
03654     min() const
03655     { return std::numeric_limits<result_type>::min(); }
03656 
03657     /**
03658      * @brief Returns the least upper bound value of the distribution.
03659      */
03660     result_type
03661     max() const
03662     { return std::numeric_limits<result_type>::max(); }
03663 
03664     /**
03665      * @brief Generating functions.
03666      */
03667     template<typename _UniformRandomNumberGenerator>
03668       result_type
03669       operator()(_UniformRandomNumberGenerator& __urng)
03670       { return this->operator()(__urng, _M_param); }
03671 
03672     template<typename _UniformRandomNumberGenerator>
03673       result_type
03674       operator()(_UniformRandomNumberGenerator& __urng,
03675          const param_type& __p)
03676       {
03677     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
03678       __aurng(__urng);
03679     if ((__aurng() - __aurng.min())
03680          < __p.p() * (__aurng.max() - __aurng.min()))
03681       return true;
03682     return false;
03683       }
03684 
03685     template<typename _ForwardIterator,
03686          typename _UniformRandomNumberGenerator>
03687       void
03688       __generate(_ForwardIterator __f, _ForwardIterator __t,
03689          _UniformRandomNumberGenerator& __urng)
03690       { this->__generate(__f, __t, __urng, _M_param); }
03691 
03692     template<typename _ForwardIterator,
03693          typename _UniformRandomNumberGenerator>
03694       void
03695       __generate(_ForwardIterator __f, _ForwardIterator __t,
03696          _UniformRandomNumberGenerator& __urng, const param_type& __p)
03697       { this->__generate_impl(__f, __t, __urng, __p); }
03698 
03699     template<typename _UniformRandomNumberGenerator>
03700       void
03701       __generate(result_type* __f, result_type* __t,
03702          _UniformRandomNumberGenerator& __urng,
03703          const param_type& __p)
03704       { this->__generate_impl(__f, __t, __urng, __p); }
03705 
03706     /**
03707      * @brief Return true if two Bernoulli distributions have
03708      *        the same parameters.
03709      */
03710     friend bool
03711     operator==(const bernoulli_distribution& __d1,
03712            const bernoulli_distribution& __d2)
03713     { return __d1._M_param == __d2._M_param; }
03714 
03715   private:
03716     template<typename _ForwardIterator,
03717          typename _UniformRandomNumberGenerator>
03718       void
03719       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03720               _UniformRandomNumberGenerator& __urng,
03721               const param_type& __p);
03722 
03723     param_type _M_param;
03724   };
03725 
03726   /**
03727    * @brief Return true if two Bernoulli distributions have
03728    *        different parameters.
03729    */
03730   inline bool
03731   operator!=(const std::bernoulli_distribution& __d1,
03732          const std::bernoulli_distribution& __d2)
03733   { return !(__d1 == __d2); }
03734 
03735   /**
03736    * @brief Inserts a %bernoulli_distribution random number distribution
03737    * @p __x into the output stream @p __os.
03738    *
03739    * @param __os An output stream.
03740    * @param __x  A %bernoulli_distribution random number distribution.
03741    *
03742    * @returns The output stream with the state of @p __x inserted or in
03743    * an error state.
03744    */
03745   template<typename _CharT, typename _Traits>
03746     std::basic_ostream<_CharT, _Traits>&
03747     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03748            const std::bernoulli_distribution& __x);
03749 
03750   /**
03751    * @brief Extracts a %bernoulli_distribution random number distribution
03752    * @p __x from the input stream @p __is.
03753    *
03754    * @param __is An input stream.
03755    * @param __x  A %bernoulli_distribution random number generator engine.
03756    *
03757    * @returns The input stream with @p __x extracted or in an error state.
03758    */
03759   template<typename _CharT, typename _Traits>
03760     std::basic_istream<_CharT, _Traits>&
03761     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03762            std::bernoulli_distribution& __x)
03763     {
03764       double __p;
03765       __is >> __p;
03766       __x.param(bernoulli_distribution::param_type(__p));
03767       return __is;
03768     }
03769 
03770 
03771   /**
03772    * @brief A discrete binomial random number distribution.
03773    *
03774    * The formula for the binomial probability density function is
03775    * @f$p(i|t,p) = \binom{t}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
03776    * and @f$p@f$ are the parameters of the distribution.
03777    */
03778   template<typename _IntType = int>
03779     class binomial_distribution
03780     {
03781       static_assert(std::is_integral<_IntType>::value,
03782             "template argument not an integral type");
03783 
03784     public:
03785       /** The type of the range of the distribution. */
03786       typedef _IntType result_type;
03787       /** Parameter type. */
03788       struct param_type
03789       {
03790     typedef binomial_distribution<_IntType> distribution_type;
03791     friend class binomial_distribution<_IntType>;
03792 
03793     explicit
03794     param_type(_IntType __t = _IntType(1), double __p = 0.5)
03795     : _M_t(__t), _M_p(__p)
03796     {
03797       _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
03798                 && (_M_p >= 0.0)
03799                 && (_M_p <= 1.0));
03800       _M_initialize();
03801     }
03802 
03803     _IntType
03804     t() const
03805     { return _M_t; }
03806 
03807     double
03808     p() const
03809     { return _M_p; }
03810 
03811     friend bool
03812     operator==(const param_type& __p1, const param_type& __p2)
03813     { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
03814 
03815       private:
03816     void
03817     _M_initialize();
03818 
03819     _IntType _M_t;
03820     double _M_p;
03821 
03822     double _M_q;
03823 #if _GLIBCXX_USE_C99_MATH_TR1
03824     double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
03825            _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
03826 #endif
03827     bool   _M_easy;
03828       };
03829 
03830       // constructors and member function
03831       explicit
03832       binomial_distribution(_IntType __t = _IntType(1),
03833                 double __p = 0.5)
03834       : _M_param(__t, __p), _M_nd()
03835       { }
03836 
03837       explicit
03838       binomial_distribution(const param_type& __p)
03839       : _M_param(__p), _M_nd()
03840       { }
03841 
03842       /**
03843        * @brief Resets the distribution state.
03844        */
03845       void
03846       reset()
03847       { _M_nd.reset(); }
03848 
03849       /**
03850        * @brief Returns the distribution @p t parameter.
03851        */
03852       _IntType
03853       t() const
03854       { return _M_param.t(); }
03855 
03856       /**
03857        * @brief Returns the distribution @p p parameter.
03858        */
03859       double
03860       p() const
03861       { return _M_param.p(); }
03862 
03863       /**
03864        * @brief Returns the parameter set of the distribution.
03865        */
03866       param_type
03867       param() const
03868       { return _M_param; }
03869 
03870       /**
03871        * @brief Sets the parameter set of the distribution.
03872        * @param __param The new parameter set of the distribution.
03873        */
03874       void
03875       param(const param_type& __param)
03876       { _M_param = __param; }
03877 
03878       /**
03879        * @brief Returns the greatest lower bound value of the distribution.
03880        */
03881       result_type
03882       min() const
03883       { return 0; }
03884 
03885       /**
03886        * @brief Returns the least upper bound value of the distribution.
03887        */
03888       result_type
03889       max() const
03890       { return _M_param.t(); }
03891 
03892       /**
03893        * @brief Generating functions.
03894        */
03895       template<typename _UniformRandomNumberGenerator>
03896     result_type
03897     operator()(_UniformRandomNumberGenerator& __urng)
03898     { return this->operator()(__urng, _M_param); }
03899 
03900       template<typename _UniformRandomNumberGenerator>
03901     result_type
03902     operator()(_UniformRandomNumberGenerator& __urng,
03903            const param_type& __p);
03904 
03905       template<typename _ForwardIterator,
03906            typename _UniformRandomNumberGenerator>
03907     void
03908     __generate(_ForwardIterator __f, _ForwardIterator __t,
03909            _UniformRandomNumberGenerator& __urng)
03910     { this->__generate(__f, __t, __urng, _M_param); }
03911 
03912       template<typename _ForwardIterator,
03913            typename _UniformRandomNumberGenerator>
03914     void
03915     __generate(_ForwardIterator __f, _ForwardIterator __t,
03916            _UniformRandomNumberGenerator& __urng,
03917            const param_type& __p)
03918     { this->__generate_impl(__f, __t, __urng, __p); }
03919 
03920       template<typename _UniformRandomNumberGenerator>
03921     void
03922     __generate(result_type* __f, result_type* __t,
03923            _UniformRandomNumberGenerator& __urng,
03924            const param_type& __p)
03925     { this->__generate_impl(__f, __t, __urng, __p); }
03926 
03927       /**
03928        * @brief Return true if two binomial distributions have
03929        *        the same parameters and the sequences that would
03930        *        be generated are equal.
03931        */
03932     friend bool
03933         operator==(const binomial_distribution& __d1,
03934            const binomial_distribution& __d2)
03935 #ifdef _GLIBCXX_USE_C99_MATH_TR1
03936     { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
03937 #else
03938         { return __d1._M_param == __d2._M_param; }
03939 #endif
03940 
03941       /**
03942        * @brief Inserts a %binomial_distribution random number distribution
03943        * @p __x into the output stream @p __os.
03944        *
03945        * @param __os An output stream.
03946        * @param __x  A %binomial_distribution random number distribution.
03947        *
03948        * @returns The output stream with the state of @p __x inserted or in
03949        * an error state.
03950        */
03951       template<typename _IntType1,
03952            typename _CharT, typename _Traits>
03953     friend std::basic_ostream<_CharT, _Traits>&
03954     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03955            const std::binomial_distribution<_IntType1>& __x);
03956 
03957       /**
03958        * @brief Extracts a %binomial_distribution random number distribution
03959        * @p __x from the input stream @p __is.
03960        *
03961        * @param __is An input stream.
03962        * @param __x  A %binomial_distribution random number generator engine.
03963        *
03964        * @returns The input stream with @p __x extracted or in an error
03965        *          state.
03966        */
03967       template<typename _IntType1,
03968            typename _CharT, typename _Traits>
03969     friend std::basic_istream<_CharT, _Traits>&
03970     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03971            std::binomial_distribution<_IntType1>& __x);
03972 
03973     private:
03974       template<typename _ForwardIterator,
03975            typename _UniformRandomNumberGenerator>
03976     void
03977     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
03978             _UniformRandomNumberGenerator& __urng,
03979             const param_type& __p);
03980 
03981       template<typename _UniformRandomNumberGenerator>
03982     result_type
03983     _M_waiting(_UniformRandomNumberGenerator& __urng,
03984            _IntType __t, double __q);
03985 
03986       param_type _M_param;
03987 
03988       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
03989       std::normal_distribution<double> _M_nd;
03990     };
03991 
03992   /**
03993    * @brief Return true if two binomial distributions are different.
03994    */
03995   template<typename _IntType>
03996     inline bool
03997     operator!=(const std::binomial_distribution<_IntType>& __d1,
03998            const std::binomial_distribution<_IntType>& __d2)
03999     { return !(__d1 == __d2); }
04000 
04001 
04002   /**
04003    * @brief A discrete geometric random number distribution.
04004    *
04005    * The formula for the geometric probability density function is
04006    * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
04007    * distribution.
04008    */
04009   template<typename _IntType = int>
04010     class geometric_distribution
04011     {
04012       static_assert(std::is_integral<_IntType>::value,
04013             "template argument not an integral type");
04014 
04015     public:
04016       /** The type of the range of the distribution. */
04017       typedef _IntType  result_type;
04018       /** Parameter type. */
04019       struct param_type
04020       {
04021     typedef geometric_distribution<_IntType> distribution_type;
04022     friend class geometric_distribution<_IntType>;
04023 
04024     explicit
04025     param_type(double __p = 0.5)
04026     : _M_p(__p)
04027     {
04028       _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
04029       _M_initialize();
04030     }
04031 
04032     double
04033     p() const
04034     { return _M_p; }
04035 
04036     friend bool
04037     operator==(const param_type& __p1, const param_type& __p2)
04038     { return __p1._M_p == __p2._M_p; }
04039 
04040       private:
04041     void
04042     _M_initialize()
04043     { _M_log_1_p = std::log(1.0 - _M_p); }
04044 
04045     double _M_p;
04046 
04047     double _M_log_1_p;
04048       };
04049 
04050       // constructors and member function
04051       explicit
04052       geometric_distribution(double __p = 0.5)
04053       : _M_param(__p)
04054       { }
04055 
04056       explicit
04057       geometric_distribution(const param_type& __p)
04058       : _M_param(__p)
04059       { }
04060 
04061       /**
04062        * @brief Resets the distribution state.
04063        *
04064        * Does nothing for the geometric distribution.
04065        */
04066       void
04067       reset() { }
04068 
04069       /**
04070        * @brief Returns the distribution parameter @p p.
04071        */
04072       double
04073       p() const
04074       { return _M_param.p(); }
04075 
04076       /**
04077        * @brief Returns the parameter set of the distribution.
04078        */
04079       param_type
04080       param() const
04081       { return _M_param; }
04082 
04083       /**
04084        * @brief Sets the parameter set of the distribution.
04085        * @param __param The new parameter set of the distribution.
04086        */
04087       void
04088       param(const param_type& __param)
04089       { _M_param = __param; }
04090 
04091       /**
04092        * @brief Returns the greatest lower bound value of the distribution.
04093        */
04094       result_type
04095       min() const
04096       { return 0; }
04097 
04098       /**
04099        * @brief Returns the least upper bound value of the distribution.
04100        */
04101       result_type
04102       max() const
04103       { return std::numeric_limits<result_type>::max(); }
04104 
04105       /**
04106        * @brief Generating functions.
04107        */
04108       template<typename _UniformRandomNumberGenerator>
04109     result_type
04110     operator()(_UniformRandomNumberGenerator& __urng)
04111     { return this->operator()(__urng, _M_param); }
04112 
04113       template<typename _UniformRandomNumberGenerator>
04114     result_type
04115     operator()(_UniformRandomNumberGenerator& __urng,
04116            const param_type& __p);
04117 
04118       template<typename _ForwardIterator,
04119            typename _UniformRandomNumberGenerator>
04120     void
04121     __generate(_ForwardIterator __f, _ForwardIterator __t,
04122            _UniformRandomNumberGenerator& __urng)
04123     { this->__generate(__f, __t, __urng, _M_param); }
04124 
04125       template<typename _ForwardIterator,
04126            typename _UniformRandomNumberGenerator>
04127     void
04128     __generate(_ForwardIterator __f, _ForwardIterator __t,
04129            _UniformRandomNumberGenerator& __urng,
04130            const param_type& __p)
04131     { this->__generate_impl(__f, __t, __urng, __p); }
04132 
04133       template<typename _UniformRandomNumberGenerator>
04134     void
04135     __generate(result_type* __f, result_type* __t,
04136            _UniformRandomNumberGenerator& __urng,
04137            const param_type& __p)
04138     { this->__generate_impl(__f, __t, __urng, __p); }
04139 
04140       /**
04141        * @brief Return true if two geometric distributions have
04142        *        the same parameters.
04143        */
04144       friend bool
04145       operator==(const geometric_distribution& __d1,
04146          const geometric_distribution& __d2)
04147       { return __d1._M_param == __d2._M_param; }
04148 
04149     private:
04150       template<typename _ForwardIterator,
04151            typename _UniformRandomNumberGenerator>
04152     void
04153     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
04154             _UniformRandomNumberGenerator& __urng,
04155             const param_type& __p);
04156 
04157       param_type _M_param;
04158     };
04159 
04160   /**
04161    * @brief Return true if two geometric distributions have
04162    *        different parameters.
04163    */
04164   template<typename _IntType>
04165     inline bool
04166     operator!=(const std::geometric_distribution<_IntType>& __d1,
04167            const std::geometric_distribution<_IntType>& __d2)
04168     { return !(__d1 == __d2); }
04169 
04170   /**
04171    * @brief Inserts a %geometric_distribution random number distribution
04172    * @p __x into the output stream @p __os.
04173    *
04174    * @param __os An output stream.
04175    * @param __x  A %geometric_distribution random number distribution.
04176    *
04177    * @returns The output stream with the state of @p __x inserted or in
04178    * an error state.
04179    */
04180   template<typename _IntType,
04181        typename _CharT, typename _Traits>
04182     std::basic_ostream<_CharT, _Traits>&
04183     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04184            const std::geometric_distribution<_IntType>& __x);
04185 
04186   /**
04187    * @brief Extracts a %geometric_distribution random number distribution
04188    * @p __x from the input stream @p __is.
04189    *
04190    * @param __is An input stream.
04191    * @param __x  A %geometric_distribution random number generator engine.
04192    *
04193    * @returns The input stream with @p __x extracted or in an error state.
04194    */
04195   template<typename _IntType,
04196        typename _CharT, typename _Traits>
04197     std::basic_istream<_CharT, _Traits>&
04198     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04199            std::geometric_distribution<_IntType>& __x);
04200 
04201 
04202   /**
04203    * @brief A negative_binomial_distribution random number distribution.
04204    *
04205    * The formula for the negative binomial probability mass function is
04206    * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
04207    * and @f$p@f$ are the parameters of the distribution.
04208    */
04209   template<typename _IntType = int>
04210     class negative_binomial_distribution
04211     {
04212       static_assert(std::is_integral<_IntType>::value,
04213             "template argument not an integral type");
04214 
04215     public:
04216       /** The type of the range of the distribution. */
04217       typedef _IntType result_type;
04218       /** Parameter type. */
04219       struct param_type
04220       {
04221     typedef negative_binomial_distribution<_IntType> distribution_type;
04222 
04223     explicit
04224     param_type(_IntType __k = 1, double __p = 0.5)
04225     : _M_k(__k), _M_p(__p)
04226     {
04227       _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
04228     }
04229 
04230     _IntType
04231     k() const
04232     { return _M_k; }
04233 
04234     double
04235     p() const
04236     { return _M_p; }
04237 
04238     friend bool
04239     operator==(const param_type& __p1, const param_type& __p2)
04240     { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
04241 
04242       private:
04243     _IntType _M_k;
04244     double _M_p;
04245       };
04246 
04247       explicit
04248       negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
04249       : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
04250       { }
04251 
04252       explicit
04253       negative_binomial_distribution(const param_type& __p)
04254       : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
04255       { }
04256 
04257       /**
04258        * @brief Resets the distribution state.
04259        */
04260       void
04261       reset()
04262       { _M_gd.reset(); }
04263 
04264       /**
04265        * @brief Return the @f$k@f$ parameter of the distribution.
04266        */
04267       _IntType
04268       k() const
04269       { return _M_param.k(); }
04270 
04271       /**
04272        * @brief Return the @f$p@f$ parameter of the distribution.
04273        */
04274       double
04275       p() const
04276       { return _M_param.p(); }
04277 
04278       /**
04279        * @brief Returns the parameter set of the distribution.
04280        */
04281       param_type
04282       param() const
04283       { return _M_param; }
04284 
04285       /**
04286        * @brief Sets the parameter set of the distribution.
04287        * @param __param The new parameter set of the distribution.
04288        */
04289       void
04290       param(const param_type& __param)
04291       { _M_param = __param; }
04292 
04293       /**
04294        * @brief Returns the greatest lower bound value of the distribution.
04295        */
04296       result_type
04297       min() const
04298       { return result_type(0); }
04299 
04300       /**
04301        * @brief Returns the least upper bound value of the distribution.
04302        */
04303       result_type
04304       max() const
04305       { return std::numeric_limits<result_type>::max(); }
04306 
04307       /**
04308        * @brief Generating functions.
04309        */
04310       template<typename _UniformRandomNumberGenerator>
04311     result_type
04312         operator()(_UniformRandomNumberGenerator& __urng);
04313 
04314       template<typename _UniformRandomNumberGenerator>
04315     result_type
04316     operator()(_UniformRandomNumberGenerator& __urng,
04317            const param_type& __p);
04318 
04319       template<typename _ForwardIterator,
04320            typename _UniformRandomNumberGenerator>
04321     void
04322     __generate(_ForwardIterator __f, _ForwardIterator __t,
04323            _UniformRandomNumberGenerator& __urng)
04324     { this->__generate_impl(__f, __t, __urng); }
04325 
04326       template<typename _ForwardIterator,
04327            typename _UniformRandomNumberGenerator>
04328     void
04329     __generate(_ForwardIterator __f, _ForwardIterator __t,
04330            _UniformRandomNumberGenerator& __urng,
04331            const param_type& __p)
04332     { this->__generate_impl(__f, __t, __urng, __p); }
04333 
04334       template<typename _UniformRandomNumberGenerator>
04335     void
04336     __generate(result_type* __f, result_type* __t,
04337            _UniformRandomNumberGenerator& __urng)
04338     { this->__generate_impl(__f, __t, __urng); }
04339 
04340       template<typename _UniformRandomNumberGenerator>
04341     void
04342     __generate(result_type* __f, result_type* __t,
04343            _UniformRandomNumberGenerator& __urng,
04344            const param_type& __p)
04345     { this->__generate_impl(__f, __t, __urng, __p); }
04346 
04347       /**
04348        * @brief Return true if two negative binomial distributions have
04349        *        the same parameters and the sequences that would be
04350        *        generated are equal.
04351        */
04352       friend bool
04353       operator==(const negative_binomial_distribution& __d1,
04354          const negative_binomial_distribution& __d2)
04355       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
04356 
04357       /**
04358        * @brief Inserts a %negative_binomial_distribution random
04359        *        number distribution @p __x into the output stream @p __os.
04360        *
04361        * @param __os An output stream.
04362        * @param __x  A %negative_binomial_distribution random number
04363        *             distribution.
04364        *
04365        * @returns The output stream with the state of @p __x inserted or in
04366        *          an error state.
04367        */
04368       template<typename _IntType1, typename _CharT, typename _Traits>
04369     friend std::basic_ostream<_CharT, _Traits>&
04370     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04371            const std::negative_binomial_distribution<_IntType1>& __x);
04372 
04373       /**
04374        * @brief Extracts a %negative_binomial_distribution random number
04375        *        distribution @p __x from the input stream @p __is.
04376        *
04377        * @param __is An input stream.
04378        * @param __x A %negative_binomial_distribution random number
04379        *            generator engine.
04380        *
04381        * @returns The input stream with @p __x extracted or in an error state.
04382        */
04383       template<typename _IntType1, typename _CharT, typename _Traits>
04384     friend std::basic_istream<_CharT, _Traits>&
04385     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04386            std::negative_binomial_distribution<_IntType1>& __x);
04387 
04388     private:
04389       template<typename _ForwardIterator,
04390            typename _UniformRandomNumberGenerator>
04391     void
04392     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
04393             _UniformRandomNumberGenerator& __urng);
04394       template<typename _ForwardIterator,
04395            typename _UniformRandomNumberGenerator>
04396     void
04397     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
04398             _UniformRandomNumberGenerator& __urng,
04399             const param_type& __p);
04400 
04401       param_type _M_param;
04402 
04403       std::gamma_distribution<double> _M_gd;
04404     };
04405 
04406   /**
04407    * @brief Return true if two negative binomial distributions are different.
04408    */
04409   template<typename _IntType>
04410     inline bool
04411     operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
04412            const std::negative_binomial_distribution<_IntType>& __d2)
04413     { return !(__d1 == __d2); }
04414 
04415 
04416   /* @} */ // group random_distributions_bernoulli
04417 
04418   /**
04419    * @addtogroup random_distributions_poisson Poisson Distributions
04420    * @ingroup random_distributions
04421    * @{
04422    */
04423 
04424   /**
04425    * @brief A discrete Poisson random number distribution.
04426    *
04427    * The formula for the Poisson probability density function is
04428    * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
04429    * parameter of the distribution.
04430    */
04431   template<typename _IntType = int>
04432     class poisson_distribution
04433     {
04434       static_assert(std::is_integral<_IntType>::value,
04435             "template argument not an integral type");
04436 
04437     public:
04438       /** The type of the range of the distribution. */
04439       typedef _IntType  result_type;
04440       /** Parameter type. */
04441       struct param_type
04442       {
04443     typedef poisson_distribution<_IntType> distribution_type;
04444     friend class poisson_distribution<_IntType>;
04445 
04446     explicit
04447     param_type(double __mean = 1.0)
04448     : _M_mean(__mean)
04449     {
04450       _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
04451       _M_initialize();
04452     }
04453 
04454     double
04455     mean() const
04456     { return _M_mean; }
04457 
04458     friend bool
04459     operator==(const param_type& __p1, const param_type& __p2)
04460     { return __p1._M_mean == __p2._M_mean; }
04461 
04462       private:
04463     // Hosts either log(mean) or the threshold of the simple method.
04464     void
04465     _M_initialize();
04466 
04467     double _M_mean;
04468 
04469     double _M_lm_thr;
04470 #if _GLIBCXX_USE_C99_MATH_TR1
04471     double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
04472 #endif
04473       };
04474 
04475       // constructors and member function
04476       explicit
04477       poisson_distribution(double __mean = 1.0)
04478       : _M_param(__mean), _M_nd()
04479       { }
04480 
04481       explicit
04482       poisson_distribution(const param_type& __p)
04483       : _M_param(__p), _M_nd()
04484       { }
04485 
04486       /**
04487        * @brief Resets the distribution state.
04488        */
04489       void
04490       reset()
04491       { _M_nd.reset(); }
04492 
04493       /**
04494        * @brief Returns the distribution parameter @p mean.
04495        */
04496       double
04497       mean() const
04498       { return _M_param.mean(); }
04499 
04500       /**
04501        * @brief Returns the parameter set of the distribution.
04502        */
04503       param_type
04504       param() const
04505       { return _M_param; }
04506 
04507       /**
04508        * @brief Sets the parameter set of the distribution.
04509        * @param __param The new parameter set of the distribution.
04510        */
04511       void
04512       param(const param_type& __param)
04513       { _M_param = __param; }
04514 
04515       /**
04516        * @brief Returns the greatest lower bound value of the distribution.
04517        */
04518       result_type
04519       min() const
04520       { return 0; }
04521 
04522       /**
04523        * @brief Returns the least upper bound value of the distribution.
04524        */
04525       result_type
04526       max() const
04527       { return std::numeric_limits<result_type>::max(); }
04528 
04529       /**
04530        * @brief Generating functions.
04531        */
04532       template<typename _UniformRandomNumberGenerator>
04533     result_type
04534     operator()(_UniformRandomNumberGenerator& __urng)
04535     { return this->operator()(__urng, _M_param); }
04536 
04537       template<typename _UniformRandomNumberGenerator>
04538     result_type
04539     operator()(_UniformRandomNumberGenerator& __urng,
04540            const param_type& __p);
04541 
04542       template<typename _ForwardIterator,
04543            typename _UniformRandomNumberGenerator>
04544     void
04545     __generate(_ForwardIterator __f, _ForwardIterator __t,
04546            _UniformRandomNumberGenerator& __urng)
04547     { this->__generate(__f, __t, __urng, _M_param); }
04548 
04549       template<typename _ForwardIterator,
04550            typename _UniformRandomNumberGenerator>
04551     void
04552     __generate(_ForwardIterator __f, _ForwardIterator __t,
04553            _UniformRandomNumberGenerator& __urng,
04554            const param_type& __p)
04555     { this->__generate_impl(__f, __t, __urng, __p); }
04556 
04557       template<typename _UniformRandomNumberGenerator>
04558     void
04559     __generate(result_type* __f, result_type* __t,
04560            _UniformRandomNumberGenerator& __urng,
04561            const param_type& __p)
04562     { this->__generate_impl(__f, __t, __urng, __p); }
04563 
04564        /**
04565     * @brief Return true if two Poisson distributions have the same
04566     *        parameters and the sequences that would be generated
04567     *        are equal.
04568     */
04569       friend bool
04570       operator==(const poisson_distribution& __d1,
04571          const poisson_distribution& __d2)
04572 #ifdef _GLIBCXX_USE_C99_MATH_TR1
04573       { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
04574 #else
04575       { return __d1._M_param == __d2._M_param; }
04576 #endif
04577 
04578       /**
04579        * @brief Inserts a %poisson_distribution random number distribution
04580        * @p __x into the output stream @p __os.
04581        *
04582        * @param __os An output stream.
04583        * @param __x  A %poisson_distribution random number distribution.
04584        *
04585        * @returns The output stream with the state of @p __x inserted or in
04586        * an error state.
04587        */
04588       template<typename _IntType1, typename _CharT, typename _Traits>
04589     friend std::basic_ostream<_CharT, _Traits>&
04590     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04591            const std::poisson_distribution<_IntType1>& __x);
04592 
04593       /**
04594        * @brief Extracts a %poisson_distribution random number distribution
04595        * @p __x from the input stream @p __is.
04596        *
04597        * @param __is An input stream.
04598        * @param __x  A %poisson_distribution random number generator engine.
04599        *
04600        * @returns The input stream with @p __x extracted or in an error
04601        *          state.
04602        */
04603       template<typename _IntType1, typename _CharT, typename _Traits>
04604     friend std::basic_istream<_CharT, _Traits>&
04605     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04606            std::poisson_distribution<_IntType1>& __x);
04607 
04608     private:
04609       template<typename _ForwardIterator,
04610            typename _UniformRandomNumberGenerator>
04611     void
04612     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
04613             _UniformRandomNumberGenerator& __urng,
04614             const param_type& __p);
04615 
04616       param_type _M_param;
04617 
04618       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
04619       std::normal_distribution<double> _M_nd;
04620     };
04621 
04622   /**
04623    * @brief Return true if two Poisson distributions are different.
04624    */
04625   template<typename _IntType>
04626     inline bool
04627     operator!=(const std::poisson_distribution<_IntType>& __d1,
04628            const std::poisson_distribution<_IntType>& __d2)
04629     { return !(__d1 == __d2); }
04630 
04631 
04632   /**
04633    * @brief An exponential continuous distribution for random numbers.
04634    *
04635    * The formula for the exponential probability density function is
04636    * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
04637    *
04638    * <table border=1 cellpadding=10 cellspacing=0>
04639    * <caption align=top>Distribution Statistics</caption>
04640    * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
04641    * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
04642    * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
04643    * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
04644    * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
04645    * </table>
04646    */
04647   template<typename _RealType = double>
04648     class exponential_distribution
04649     {
04650       static_assert(std::is_floating_point<_RealType>::value,
04651             "template argument not a floating point type");
04652 
04653     public:
04654       /** The type of the range of the distribution. */
04655       typedef _RealType result_type;
04656       /** Parameter type. */
04657       struct param_type
04658       {
04659     typedef exponential_distribution<_RealType> distribution_type;
04660 
04661     explicit
04662     param_type(_RealType __lambda = _RealType(1))
04663     : _M_lambda(__lambda)
04664     {
04665       _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
04666     }
04667 
04668     _RealType
04669     lambda() const
04670     { return _M_lambda; }
04671 
04672     friend bool
04673     operator==(const param_type& __p1, const param_type& __p2)
04674     { return __p1._M_lambda == __p2._M_lambda; }
04675 
04676       private:
04677     _RealType _M_lambda;
04678       };
04679 
04680     public:
04681       /**
04682        * @brief Constructs an exponential distribution with inverse scale
04683        *        parameter @f$\lambda@f$.
04684        */
04685       explicit
04686       exponential_distribution(const result_type& __lambda = result_type(1))
04687       : _M_param(__lambda)
04688       { }
04689 
04690       explicit
04691       exponential_distribution(const param_type& __p)
04692       : _M_param(__p)
04693       { }
04694 
04695       /**
04696        * @brief Resets the distribution state.
04697        *
04698        * Has no effect on exponential distributions.
04699        */
04700       void
04701       reset() { }
04702 
04703       /**
04704        * @brief Returns the inverse scale parameter of the distribution.
04705        */
04706       _RealType
04707       lambda() const
04708       { return _M_param.lambda(); }
04709 
04710       /**
04711        * @brief Returns the parameter set of the distribution.
04712        */
04713       param_type
04714       param() const
04715       { return _M_param; }
04716 
04717       /**
04718        * @brief Sets the parameter set of the distribution.
04719        * @param __param The new parameter set of the distribution.
04720        */
04721       void
04722       param(const param_type& __param)
04723       { _M_param = __param; }
04724 
04725       /**
04726        * @brief Returns the greatest lower bound value of the distribution.
04727        */
04728       result_type
04729       min() const
04730       { return result_type(0); }
04731 
04732       /**
04733        * @brief Returns the least upper bound value of the distribution.
04734        */
04735       result_type
04736       max() const
04737       { return std::numeric_limits<result_type>::max(); }
04738 
04739       /**
04740        * @brief Generating functions.
04741        */
04742       template<typename _UniformRandomNumberGenerator>
04743     result_type
04744     operator()(_UniformRandomNumberGenerator& __urng)
04745         { return this->operator()(__urng, _M_param); }
04746 
04747       template<typename _UniformRandomNumberGenerator>
04748     result_type
04749     operator()(_UniformRandomNumberGenerator& __urng,
04750            const param_type& __p)
04751     {
04752       __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
04753         __aurng(__urng);
04754       return -std::log(result_type(1) - __aurng()) / __p.lambda();
04755     }
04756 
04757       template<typename _ForwardIterator,
04758            typename _UniformRandomNumberGenerator>
04759     void
04760     __generate(_ForwardIterator __f, _ForwardIterator __t,
04761            _UniformRandomNumberGenerator& __urng)
04762     { this->__generate(__f, __t, __urng, _M_param); }
04763 
04764       template<typename _ForwardIterator,
04765            typename _UniformRandomNumberGenerator>
04766     void
04767     __generate(_ForwardIterator __f, _ForwardIterator __t,
04768            _UniformRandomNumberGenerator& __urng,
04769            const param_type& __p)
04770     { this->__generate_impl(__f, __t, __urng, __p); }
04771 
04772       template<typename _UniformRandomNumberGenerator>
04773     void
04774     __generate(result_type* __f, result_type* __t,
04775            _UniformRandomNumberGenerator& __urng,
04776            const param_type& __p)
04777     { this->__generate_impl(__f, __t, __urng, __p); }
04778 
04779       /**
04780        * @brief Return true if two exponential distributions have the same
04781        *        parameters.
04782        */
04783       friend bool
04784       operator==(const exponential_distribution& __d1,
04785          const exponential_distribution& __d2)
04786       { return __d1._M_param == __d2._M_param; }
04787 
04788     private:
04789       template<typename _ForwardIterator,
04790            typename _UniformRandomNumberGenerator>
04791     void
04792     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
04793             _UniformRandomNumberGenerator& __urng,
04794             const param_type& __p);
04795 
04796       param_type _M_param;
04797     };
04798 
04799   /**
04800    * @brief Return true if two exponential distributions have different
04801    *        parameters.
04802    */
04803   template<typename _RealType>
04804     inline bool
04805     operator!=(const std::exponential_distribution<_RealType>& __d1,
04806            const std::exponential_distribution<_RealType>& __d2)
04807     { return !(__d1 == __d2); }
04808 
04809   /**
04810    * @brief Inserts a %exponential_distribution random number distribution
04811    * @p __x into the output stream @p __os.
04812    *
04813    * @param __os An output stream.
04814    * @param __x  A %exponential_distribution random number distribution.
04815    *
04816    * @returns The output stream with the state of @p __x inserted or in
04817    * an error state.
04818    */
04819   template<typename _RealType, typename _CharT, typename _Traits>
04820     std::basic_ostream<_CharT, _Traits>&
04821     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04822            const std::exponential_distribution<_RealType>& __x);
04823 
04824   /**
04825    * @brief Extracts a %exponential_distribution random number distribution
04826    * @p __x from the input stream @p __is.
04827    *
04828    * @param __is An input stream.
04829    * @param __x A %exponential_distribution random number
04830    *            generator engine.
04831    *
04832    * @returns The input stream with @p __x extracted or in an error state.
04833    */
04834   template<typename _RealType, typename _CharT, typename _Traits>
04835     std::basic_istream<_CharT, _Traits>&
04836     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04837            std::exponential_distribution<_RealType>& __x);
04838 
04839 
04840   /**
04841    * @brief A weibull_distribution random number distribution.
04842    *
04843    * The formula for the normal probability density function is:
04844    * @f[
04845    *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
04846    *                         \exp{(-(\frac{x}{\beta})^\alpha)} 
04847    * @f]
04848    */
04849   template<typename _RealType = double>
04850     class weibull_distribution
04851     {
04852       static_assert(std::is_floating_point<_RealType>::value,
04853             "template argument not a floating point type");
04854 
04855     public:
04856       /** The type of the range of the distribution. */
04857       typedef _RealType result_type;
04858       /** Parameter type. */
04859       struct param_type
04860       {
04861     typedef weibull_distribution<_RealType> distribution_type;
04862 
04863     explicit
04864     param_type(_RealType __a = _RealType(1),
04865            _RealType __b = _RealType(1))
04866     : _M_a(__a), _M_b(__b)
04867     { }
04868 
04869     _RealType
04870     a() const
04871     { return _M_a; }
04872 
04873     _RealType
04874     b() const
04875     { return _M_b; }
04876 
04877     friend bool
04878     operator==(const param_type& __p1, const param_type& __p2)
04879     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
04880 
04881       private:
04882     _RealType _M_a;
04883     _RealType _M_b;
04884       };
04885 
04886       explicit
04887       weibull_distribution(_RealType __a = _RealType(1),
04888                _RealType __b = _RealType(1))
04889       : _M_param(__a, __b)
04890       { }
04891 
04892       explicit
04893       weibull_distribution(const param_type& __p)
04894       : _M_param(__p)
04895       { }
04896 
04897       /**
04898        * @brief Resets the distribution state.
04899        */
04900       void
04901       reset()
04902       { }
04903 
04904       /**
04905        * @brief Return the @f$a@f$ parameter of the distribution.
04906        */
04907       _RealType
04908       a() const
04909       { return _M_param.a(); }
04910 
04911       /**
04912        * @brief Return the @f$b@f$ parameter of the distribution.
04913        */
04914       _RealType
04915       b() const
04916       { return _M_param.b(); }
04917 
04918       /**
04919        * @brief Returns the parameter set of the distribution.
04920        */
04921       param_type
04922       param() const
04923       { return _M_param; }
04924 
04925       /**
04926        * @brief Sets the parameter set of the distribution.
04927        * @param __param The new parameter set of the distribution.
04928        */
04929       void
04930       param(const param_type& __param)
04931       { _M_param = __param; }
04932 
04933       /**
04934        * @brief Returns the greatest lower bound value of the distribution.
04935        */
04936       result_type
04937       min() const
04938       { return result_type(0); }
04939 
04940       /**
04941        * @brief Returns the least upper bound value of the distribution.
04942        */
04943       result_type
04944       max() const
04945       { return std::numeric_limits<result_type>::max(); }
04946 
04947       /**
04948        * @brief Generating functions.
04949        */
04950       template<typename _UniformRandomNumberGenerator>
04951     result_type
04952     operator()(_UniformRandomNumberGenerator& __urng)
04953     { return this->operator()(__urng, _M_param); }
04954 
04955       template<typename _UniformRandomNumberGenerator>
04956     result_type
04957     operator()(_UniformRandomNumberGenerator& __urng,
04958            const param_type& __p);
04959 
04960       template<typename _ForwardIterator,
04961            typename _UniformRandomNumberGenerator>
04962     void
04963     __generate(_ForwardIterator __f, _ForwardIterator __t,
04964            _UniformRandomNumberGenerator& __urng)
04965     { this->__generate(__f, __t, __urng, _M_param); }
04966 
04967       template<typename _ForwardIterator,
04968            typename _UniformRandomNumberGenerator>
04969     void
04970     __generate(_ForwardIterator __f, _ForwardIterator __t,
04971            _UniformRandomNumberGenerator& __urng,
04972            const param_type& __p)
04973     { this->__generate_impl(__f, __t, __urng, __p); }
04974 
04975       template<typename _UniformRandomNumberGenerator>
04976     void
04977     __generate(result_type* __f, result_type* __t,
04978            _UniformRandomNumberGenerator& __urng,
04979            const param_type& __p)
04980     { this->__generate_impl(__f, __t, __urng, __p); }
04981 
04982       /**
04983        * @brief Return true if two Weibull distributions have the same
04984        *        parameters.
04985        */
04986       friend bool
04987       operator==(const weibull_distribution& __d1,
04988          const weibull_distribution& __d2)
04989       { return __d1._M_param == __d2._M_param; }
04990 
04991     private:
04992       template<typename _ForwardIterator,
04993            typename _UniformRandomNumberGenerator>
04994     void
04995     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
04996             _UniformRandomNumberGenerator& __urng,
04997             const param_type& __p);
04998 
04999       param_type _M_param;
05000     };
05001 
05002    /**
05003     * @brief Return true if two Weibull distributions have different
05004     *        parameters.
05005     */
05006   template<typename _RealType>
05007     inline bool
05008     operator!=(const std::weibull_distribution<_RealType>& __d1,
05009            const std::weibull_distribution<_RealType>& __d2)
05010     { return !(__d1 == __d2); }
05011 
05012   /**
05013    * @brief Inserts a %weibull_distribution random number distribution
05014    * @p __x into the output stream @p __os.
05015    *
05016    * @param __os An output stream.
05017    * @param __x  A %weibull_distribution random number distribution.
05018    *
05019    * @returns The output stream with the state of @p __x inserted or in
05020    * an error state.
05021    */
05022   template<typename _RealType, typename _CharT, typename _Traits>
05023     std::basic_ostream<_CharT, _Traits>&
05024     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05025            const std::weibull_distribution<_RealType>& __x);
05026 
05027   /**
05028    * @brief Extracts a %weibull_distribution random number distribution
05029    * @p __x from the input stream @p __is.
05030    *
05031    * @param __is An input stream.
05032    * @param __x A %weibull_distribution random number
05033    *            generator engine.
05034    *
05035    * @returns The input stream with @p __x extracted or in an error state.
05036    */
05037   template<typename _RealType, typename _CharT, typename _Traits>
05038     std::basic_istream<_CharT, _Traits>&
05039     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05040            std::weibull_distribution<_RealType>& __x);
05041 
05042 
05043   /**
05044    * @brief A extreme_value_distribution random number distribution.
05045    *
05046    * The formula for the normal probability mass function is
05047    * @f[
05048    *     p(x|a,b) = \frac{1}{b}
05049    *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b})) 
05050    * @f]
05051    */
05052   template<typename _RealType = double>
05053     class extreme_value_distribution
05054     {
05055       static_assert(std::is_floating_point<_RealType>::value,
05056             "template argument not a floating point type");
05057 
05058     public:
05059       /** The type of the range of the distribution. */
05060       typedef _RealType result_type;
05061       /** Parameter type. */
05062       struct param_type
05063       {
05064     typedef extreme_value_distribution<_RealType> distribution_type;
05065 
05066     explicit
05067     param_type(_RealType __a = _RealType(0),
05068            _RealType __b = _RealType(1))
05069     : _M_a(__a), _M_b(__b)
05070     { }
05071 
05072     _RealType
05073     a() const
05074     { return _M_a; }
05075 
05076     _RealType
05077     b() const
05078     { return _M_b; }
05079 
05080     friend bool
05081     operator==(const param_type& __p1, const param_type& __p2)
05082     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
05083 
05084       private:
05085     _RealType _M_a;
05086     _RealType _M_b;
05087       };
05088 
05089       explicit
05090       extreme_value_distribution(_RealType __a = _RealType(0),
05091                  _RealType __b = _RealType(1))
05092       : _M_param(__a, __b)
05093       { }
05094 
05095       explicit
05096       extreme_value_distribution(const param_type& __p)
05097       : _M_param(__p)
05098       { }
05099 
05100       /**
05101        * @brief Resets the distribution state.
05102        */
05103       void
05104       reset()
05105       { }
05106 
05107       /**
05108        * @brief Return the @f$a@f$ parameter of the distribution.
05109        */
05110       _RealType
05111       a() const
05112       { return _M_param.a(); }
05113 
05114       /**
05115        * @brief Return the @f$b@f$ parameter of the distribution.
05116        */
05117       _RealType
05118       b() const
05119       { return _M_param.b(); }
05120 
05121       /**
05122        * @brief Returns the parameter set of the distribution.
05123        */
05124       param_type
05125       param() const
05126       { return _M_param; }
05127 
05128       /**
05129        * @brief Sets the parameter set of the distribution.
05130        * @param __param The new parameter set of the distribution.
05131        */
05132       void
05133       param(const param_type& __param)
05134       { _M_param = __param; }
05135 
05136       /**
05137        * @brief Returns the greatest lower bound value of the distribution.
05138        */
05139       result_type
05140       min() const
05141       { return std::numeric_limits<result_type>::lowest(); }
05142 
05143       /**
05144        * @brief Returns the least upper bound value of the distribution.
05145        */
05146       result_type
05147       max() const
05148       { return std::numeric_limits<result_type>::max(); }
05149 
05150       /**
05151        * @brief Generating functions.
05152        */
05153       template<typename _UniformRandomNumberGenerator>
05154     result_type
05155     operator()(_UniformRandomNumberGenerator& __urng)
05156     { return this->operator()(__urng, _M_param); }
05157 
05158       template<typename _UniformRandomNumberGenerator>
05159     result_type
05160     operator()(_UniformRandomNumberGenerator& __urng,
05161            const param_type& __p);
05162 
05163       template<typename _ForwardIterator,
05164            typename _UniformRandomNumberGenerator>
05165     void
05166     __generate(_ForwardIterator __f, _ForwardIterator __t,
05167            _UniformRandomNumberGenerator& __urng)
05168     { this->__generate(__f, __t, __urng, _M_param); }
05169 
05170       template<typename _ForwardIterator,
05171            typename _UniformRandomNumberGenerator>
05172     void
05173     __generate(_ForwardIterator __f, _ForwardIterator __t,
05174            _UniformRandomNumberGenerator& __urng,
05175            const param_type& __p)
05176     { this->__generate_impl(__f, __t, __urng, __p); }
05177 
05178       template<typename _UniformRandomNumberGenerator>
05179     void
05180     __generate(result_type* __f, result_type* __t,
05181            _UniformRandomNumberGenerator& __urng,
05182            const param_type& __p)
05183     { this->__generate_impl(__f, __t, __urng, __p); }
05184 
05185       /**
05186        * @brief Return true if two extreme value distributions have the same
05187        *        parameters.
05188        */
05189       friend bool
05190       operator==(const extreme_value_distribution& __d1,
05191          const extreme_value_distribution& __d2)
05192       { return __d1._M_param == __d2._M_param; }
05193 
05194     private:
05195       template<typename _ForwardIterator,
05196            typename _UniformRandomNumberGenerator>
05197     void
05198     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
05199             _UniformRandomNumberGenerator& __urng,
05200             const param_type& __p);
05201 
05202       param_type _M_param;
05203     };
05204 
05205   /**
05206     * @brief Return true if two extreme value distributions have different
05207     *        parameters.
05208    */
05209   template<typename _RealType>
05210     inline bool
05211     operator!=(const std::extreme_value_distribution<_RealType>& __d1,
05212            const std::extreme_value_distribution<_RealType>& __d2)
05213     { return !(__d1 == __d2); }
05214 
05215   /**
05216    * @brief Inserts a %extreme_value_distribution random number distribution
05217    * @p __x into the output stream @p __os.
05218    *
05219    * @param __os An output stream.
05220    * @param __x  A %extreme_value_distribution random number distribution.
05221    *
05222    * @returns The output stream with the state of @p __x inserted or in
05223    * an error state.
05224    */
05225   template<typename _RealType, typename _CharT, typename _Traits>
05226     std::basic_ostream<_CharT, _Traits>&
05227     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05228            const std::extreme_value_distribution<_RealType>& __x);
05229 
05230   /**
05231    * @brief Extracts a %extreme_value_distribution random number
05232    *        distribution @p __x from the input stream @p __is.
05233    *
05234    * @param __is An input stream.
05235    * @param __x A %extreme_value_distribution random number
05236    *            generator engine.
05237    *
05238    * @returns The input stream with @p __x extracted or in an error state.
05239    */
05240   template<typename _RealType, typename _CharT, typename _Traits>
05241     std::basic_istream<_CharT, _Traits>&
05242     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05243            std::extreme_value_distribution<_RealType>& __x);
05244 
05245 
05246   /**
05247    * @brief A discrete_distribution random number distribution.
05248    *
05249    * The formula for the discrete probability mass function is
05250    *
05251    */
05252   template<typename _IntType = int>
05253     class discrete_distribution
05254     {
05255       static_assert(std::is_integral<_IntType>::value,
05256             "template argument not an integral type");
05257 
05258     public:
05259       /** The type of the range of the distribution. */
05260       typedef _IntType result_type;
05261       /** Parameter type. */
05262       struct param_type
05263       {
05264     typedef discrete_distribution<_IntType> distribution_type;
05265     friend class discrete_distribution<_IntType>;
05266 
05267     param_type()
05268     : _M_prob(), _M_cp()
05269     { }
05270 
05271     template<typename _InputIterator>
05272       param_type(_InputIterator __wbegin,
05273              _InputIterator __wend)
05274       : _M_prob(__wbegin, __wend), _M_cp()
05275       { _M_initialize(); }
05276 
05277     param_type(initializer_list<double> __wil)
05278     : _M_prob(__wil.begin(), __wil.end()), _M_cp()
05279     { _M_initialize(); }
05280 
05281     template<typename _Func>
05282       param_type(size_t __nw, double __xmin, double __xmax,
05283              _Func __fw);
05284 
05285     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
05286     param_type(const param_type&) = default;
05287     param_type& operator=(const param_type&) = default;
05288 
05289     std::vector<double>
05290     probabilities() const
05291     { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
05292 
05293     friend bool
05294     operator==(const param_type& __p1, const param_type& __p2)
05295     { return __p1._M_prob == __p2._M_prob; }
05296 
05297       private:
05298     void
05299     _M_initialize();
05300 
05301     std::vector<double> _M_prob;
05302     std::vector<double> _M_cp;
05303       };
05304 
05305       discrete_distribution()
05306       : _M_param()
05307       { }
05308 
05309       template<typename _InputIterator>
05310     discrete_distribution(_InputIterator __wbegin,
05311                   _InputIterator __wend)
05312     : _M_param(__wbegin, __wend)
05313     { }
05314 
05315       discrete_distribution(initializer_list<double> __wl)
05316       : _M_param(__wl)
05317       { }
05318 
05319       template<typename _Func>
05320     discrete_distribution(size_t __nw, double __xmin, double __xmax,
05321                   _Func __fw)
05322     : _M_param(__nw, __xmin, __xmax, __fw)
05323     { }
05324 
05325       explicit
05326       discrete_distribution(const param_type& __p)
05327       : _M_param(__p)
05328       { }
05329 
05330       /**
05331        * @brief Resets the distribution state.
05332        */
05333       void
05334       reset()
05335       { }
05336 
05337       /**
05338        * @brief Returns the probabilities of the distribution.
05339        */
05340       std::vector<double>
05341       probabilities() const
05342       {
05343     return _M_param._M_prob.empty()
05344       ? std::vector<double>(1, 1.0) : _M_param._M_prob;
05345       }
05346 
05347       /**
05348        * @brief Returns the parameter set of the distribution.
05349        */
05350       param_type
05351       param() const
05352       { return _M_param; }
05353 
05354       /**
05355        * @brief Sets the parameter set of the distribution.
05356        * @param __param The new parameter set of the distribution.
05357        */
05358       void
05359       param(const param_type& __param)
05360       { _M_param = __param; }
05361 
05362       /**
05363        * @brief Returns the greatest lower bound value of the distribution.
05364        */
05365       result_type
05366       min() const
05367       { return result_type(0); }
05368 
05369       /**
05370        * @brief Returns the least upper bound value of the distribution.
05371        */
05372       result_type
05373       max() const
05374       {
05375     return _M_param._M_prob.empty()
05376       ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
05377       }
05378 
05379       /**
05380        * @brief Generating functions.
05381        */
05382       template<typename _UniformRandomNumberGenerator>
05383     result_type
05384     operator()(_UniformRandomNumberGenerator& __urng)
05385     { return this->operator()(__urng, _M_param); }
05386 
05387       template<typename _UniformRandomNumberGenerator>
05388     result_type
05389     operator()(_UniformRandomNumberGenerator& __urng,
05390            const param_type& __p);
05391 
05392       template<typename _ForwardIterator,
05393            typename _UniformRandomNumberGenerator>
05394     void
05395     __generate(_ForwardIterator __f, _ForwardIterator __t,
05396            _UniformRandomNumberGenerator& __urng)
05397     { this->__generate(__f, __t, __urng, _M_param); }
05398 
05399       template<typename _ForwardIterator,
05400            typename _UniformRandomNumberGenerator>
05401     void
05402     __generate(_ForwardIterator __f, _ForwardIterator __t,
05403            _UniformRandomNumberGenerator& __urng,
05404            const param_type& __p)
05405     { this->__generate_impl(__f, __t, __urng, __p); }
05406 
05407       template<typename _UniformRandomNumberGenerator>
05408     void
05409     __generate(result_type* __f, result_type* __t,
05410            _UniformRandomNumberGenerator& __urng,
05411            const param_type& __p)
05412     { this->__generate_impl(__f, __t, __urng, __p); }
05413 
05414       /**
05415        * @brief Return true if two discrete distributions have the same
05416        *        parameters.
05417        */
05418       friend bool
05419       operator==(const discrete_distribution& __d1,
05420          const discrete_distribution& __d2)
05421       { return __d1._M_param == __d2._M_param; }
05422 
05423       /**
05424        * @brief Inserts a %discrete_distribution random number distribution
05425        * @p __x into the output stream @p __os.
05426        *
05427        * @param __os An output stream.
05428        * @param __x  A %discrete_distribution random number distribution.
05429        *
05430        * @returns The output stream with the state of @p __x inserted or in
05431        * an error state.
05432        */
05433       template<typename _IntType1, typename _CharT, typename _Traits>
05434     friend std::basic_ostream<_CharT, _Traits>&
05435     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05436            const std::discrete_distribution<_IntType1>& __x);
05437 
05438       /**
05439        * @brief Extracts a %discrete_distribution random number distribution
05440        * @p __x from the input stream @p __is.
05441        *
05442        * @param __is An input stream.
05443        * @param __x A %discrete_distribution random number
05444        *            generator engine.
05445        *
05446        * @returns The input stream with @p __x extracted or in an error
05447        *          state.
05448        */
05449       template<typename _IntType1, typename _CharT, typename _Traits>
05450     friend std::basic_istream<_CharT, _Traits>&
05451     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05452            std::discrete_distribution<_IntType1>& __x);
05453 
05454     private:
05455       template<typename _ForwardIterator,
05456            typename _UniformRandomNumberGenerator>
05457     void
05458     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
05459             _UniformRandomNumberGenerator& __urng,
05460             const param_type& __p);
05461 
05462       param_type _M_param;
05463     };
05464 
05465   /**
05466     * @brief Return true if two discrete distributions have different
05467     *        parameters.
05468     */
05469   template<typename _IntType>
05470     inline bool
05471     operator!=(const std::discrete_distribution<_IntType>& __d1,
05472            const std::discrete_distribution<_IntType>& __d2)
05473     { return !(__d1 == __d2); }
05474 
05475 
05476   /**
05477    * @brief A piecewise_constant_distribution random number distribution.
05478    *
05479    * The formula for the piecewise constant probability mass function is
05480    *
05481    */
05482   template<typename _RealType = double>
05483     class piecewise_constant_distribution
05484     {
05485       static_assert(std::is_floating_point<_RealType>::value,
05486             "template argument not a floating point type");
05487 
05488     public:
05489       /** The type of the range of the distribution. */
05490       typedef _RealType result_type;
05491       /** Parameter type. */
05492       struct param_type
05493       {
05494     typedef piecewise_constant_distribution<_RealType> distribution_type;
05495     friend class piecewise_constant_distribution<_RealType>;
05496 
05497     param_type()
05498     : _M_int(), _M_den(), _M_cp()
05499     { }
05500 
05501     template<typename _InputIteratorB, typename _InputIteratorW>
05502       param_type(_InputIteratorB __bfirst,
05503              _InputIteratorB __bend,
05504              _InputIteratorW __wbegin);
05505 
05506     template<typename _Func>
05507       param_type(initializer_list<_RealType> __bi, _Func __fw);
05508 
05509     template<typename _Func>
05510       param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
05511              _Func __fw);
05512 
05513     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
05514     param_type(const param_type&) = default;
05515     param_type& operator=(const param_type&) = default;
05516 
05517     std::vector<_RealType>
05518     intervals() const
05519     {
05520       if (_M_int.empty())
05521         {
05522           std::vector<_RealType> __tmp(2);
05523           __tmp[1] = _RealType(1);
05524           return __tmp;
05525         }
05526       else
05527         return _M_int;
05528     }
05529 
05530     std::vector<double>
05531     densities() const
05532     { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
05533 
05534     friend bool
05535     operator==(const param_type& __p1, const param_type& __p2)
05536     { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
05537 
05538       private:
05539     void
05540     _M_initialize();
05541 
05542     std::vector<_RealType> _M_int;
05543     std::vector<double> _M_den;
05544     std::vector<double> _M_cp;
05545       };
05546 
05547       explicit
05548       piecewise_constant_distribution()
05549       : _M_param()
05550       { }
05551 
05552       template<typename _InputIteratorB, typename _InputIteratorW>
05553     piecewise_constant_distribution(_InputIteratorB __bfirst,
05554                     _InputIteratorB __bend,
05555                     _InputIteratorW __wbegin)
05556     : _M_param(__bfirst, __bend, __wbegin)
05557     { }
05558 
05559       template<typename _Func>
05560     piecewise_constant_distribution(initializer_list<_RealType> __bl,
05561                     _Func __fw)
05562     : _M_param(__bl, __fw)
05563     { }
05564 
05565       template<typename _Func>
05566     piecewise_constant_distribution(size_t __nw,
05567                     _RealType __xmin, _RealType __xmax,
05568                     _Func __fw)
05569     : _M_param(__nw, __xmin, __xmax, __fw)
05570     { }
05571 
05572       explicit
05573       piecewise_constant_distribution(const param_type& __p)
05574       : _M_param(__p)
05575       { }
05576 
05577       /**
05578        * @brief Resets the distribution state.
05579        */
05580       void
05581       reset()
05582       { }
05583 
05584       /**
05585        * @brief Returns a vector of the intervals.
05586        */
05587       std::vector<_RealType>
05588       intervals() const
05589       {
05590     if (_M_param._M_int.empty())
05591       {
05592         std::vector<_RealType> __tmp(2);
05593         __tmp[1] = _RealType(1);
05594         return __tmp;
05595       }
05596     else
05597       return _M_param._M_int;
05598       }
05599 
05600       /**
05601        * @brief Returns a vector of the probability densities.
05602        */
05603       std::vector<double>
05604       densities() const
05605       {
05606     return _M_param._M_den.empty()
05607       ? std::vector<double>(1, 1.0) : _M_param._M_den;
05608       }
05609 
05610       /**
05611        * @brief Returns the parameter set of the distribution.
05612        */
05613       param_type
05614       param() const
05615       { return _M_param; }
05616 
05617       /**
05618        * @brief Sets the parameter set of the distribution.
05619        * @param __param The new parameter set of the distribution.
05620        */
05621       void
05622       param(const param_type& __param)
05623       { _M_param = __param; }
05624 
05625       /**
05626        * @brief Returns the greatest lower bound value of the distribution.
05627        */
05628       result_type
05629       min() const
05630       {
05631     return _M_param._M_int.empty()
05632       ? result_type(0) : _M_param._M_int.front();
05633       }
05634 
05635       /**
05636        * @brief Returns the least upper bound value of the distribution.
05637        */
05638       result_type
05639       max() const
05640       {
05641     return _M_param._M_int.empty()
05642       ? result_type(1) : _M_param._M_int.back();
05643       }
05644 
05645       /**
05646        * @brief Generating functions.
05647        */
05648       template<typename _UniformRandomNumberGenerator>
05649     result_type
05650     operator()(_UniformRandomNumberGenerator& __urng)
05651     { return this->operator()(__urng, _M_param); }
05652 
05653       template<typename _UniformRandomNumberGenerator>
05654     result_type
05655     operator()(_UniformRandomNumberGenerator& __urng,
05656            const param_type& __p);
05657 
05658       template<typename _ForwardIterator,
05659            typename _UniformRandomNumberGenerator>
05660     void
05661     __generate(_ForwardIterator __f, _ForwardIterator __t,
05662            _UniformRandomNumberGenerator& __urng)
05663     { this->__generate(__f, __t, __urng, _M_param); }
05664 
05665       template<typename _ForwardIterator,
05666            typename _UniformRandomNumberGenerator>
05667     void
05668     __generate(_ForwardIterator __f, _ForwardIterator __t,
05669            _UniformRandomNumberGenerator& __urng,
05670            const param_type& __p)
05671     { this->__generate_impl(__f, __t, __urng, __p); }
05672 
05673       template<typename _UniformRandomNumberGenerator>
05674     void
05675     __generate(result_type* __f, result_type* __t,
05676            _UniformRandomNumberGenerator& __urng,
05677            const param_type& __p)
05678     { this->__generate_impl(__f, __t, __urng, __p); }
05679 
05680       /**
05681        * @brief Return true if two piecewise constant distributions have the
05682        *        same parameters.
05683        */
05684       friend bool
05685       operator==(const piecewise_constant_distribution& __d1,
05686          const piecewise_constant_distribution& __d2)
05687       { return __d1._M_param == __d2._M_param; }
05688 
05689       /**
05690        * @brief Inserts a %piecewise_constant_distribution random
05691        *        number distribution @p __x into the output stream @p __os.
05692        *
05693        * @param __os An output stream.
05694        * @param __x  A %piecewise_constant_distribution random number
05695        *             distribution.
05696        *
05697        * @returns The output stream with the state of @p __x inserted or in
05698        * an error state.
05699        */
05700       template<typename _RealType1, typename _CharT, typename _Traits>
05701     friend std::basic_ostream<_CharT, _Traits>&
05702     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05703            const std::piecewise_constant_distribution<_RealType1>& __x);
05704 
05705       /**
05706        * @brief Extracts a %piecewise_constant_distribution random
05707        *        number distribution @p __x from the input stream @p __is.
05708        *
05709        * @param __is An input stream.
05710        * @param __x A %piecewise_constant_distribution random number
05711        *            generator engine.
05712        *
05713        * @returns The input stream with @p __x extracted or in an error
05714        *          state.
05715        */
05716       template<typename _RealType1, typename _CharT, typename _Traits>
05717     friend std::basic_istream<_CharT, _Traits>&
05718     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05719            std::piecewise_constant_distribution<_RealType1>& __x);
05720 
05721     private:
05722       template<typename _ForwardIterator,
05723            typename _UniformRandomNumberGenerator>
05724     void
05725     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
05726             _UniformRandomNumberGenerator& __urng,
05727             const param_type& __p);
05728 
05729       param_type _M_param;
05730     };
05731 
05732   /**
05733     * @brief Return true if two piecewise constant distributions have 
05734     *        different parameters.
05735    */
05736   template<typename _RealType>
05737     inline bool
05738     operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
05739            const std::piecewise_constant_distribution<_RealType>& __d2)
05740     { return !(__d1 == __d2); }
05741 
05742 
05743   /**
05744    * @brief A piecewise_linear_distribution random number distribution.
05745    *
05746    * The formula for the piecewise linear probability mass function is
05747    *
05748    */
05749   template<typename _RealType = double>
05750     class piecewise_linear_distribution
05751     {
05752       static_assert(std::is_floating_point<_RealType>::value,
05753             "template argument not a floating point type");
05754 
05755     public:
05756       /** The type of the range of the distribution. */
05757       typedef _RealType result_type;
05758       /** Parameter type. */
05759       struct param_type
05760       {
05761     typedef piecewise_linear_distribution<_RealType> distribution_type;
05762     friend class piecewise_linear_distribution<_RealType>;
05763 
05764     param_type()
05765     : _M_int(), _M_den(), _M_cp(), _M_m()
05766     { }
05767 
05768     template<typename _InputIteratorB, typename _InputIteratorW>
05769       param_type(_InputIteratorB __bfirst,
05770              _InputIteratorB __bend,
05771              _InputIteratorW __wbegin);
05772 
05773     template<typename _Func>
05774       param_type(initializer_list<_RealType> __bl, _Func __fw);
05775 
05776     template<typename _Func>
05777       param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
05778              _Func __fw);
05779 
05780     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
05781     param_type(const param_type&) = default;
05782     param_type& operator=(const param_type&) = default;
05783 
05784     std::vector<_RealType>
05785     intervals() const
05786     {
05787       if (_M_int.empty())
05788         {
05789           std::vector<_RealType> __tmp(2);
05790           __tmp[1] = _RealType(1);
05791           return __tmp;
05792         }
05793       else
05794         return _M_int;
05795     }
05796 
05797     std::vector<double>
05798     densities() const
05799     { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
05800 
05801     friend bool
05802     operator==(const param_type& __p1, const param_type& __p2)
05803     { return (__p1._M_int == __p2._M_int
05804           && __p1._M_den == __p2._M_den); }
05805 
05806       private:
05807     void
05808     _M_initialize();
05809 
05810     std::vector<_RealType> _M_int;
05811     std::vector<double> _M_den;
05812     std::vector<double> _M_cp;
05813     std::vector<double> _M_m;
05814       };
05815 
05816       explicit
05817       piecewise_linear_distribution()
05818       : _M_param()
05819       { }
05820 
05821       template<typename _InputIteratorB, typename _InputIteratorW>
05822     piecewise_linear_distribution(_InputIteratorB __bfirst,
05823                       _InputIteratorB __bend,
05824                       _InputIteratorW __wbegin)
05825     : _M_param(__bfirst, __bend, __wbegin)
05826     { }
05827 
05828       template<typename _Func>
05829     piecewise_linear_distribution(initializer_list<_RealType> __bl,
05830                       _Func __fw)
05831     : _M_param(__bl, __fw)
05832     { }
05833 
05834       template<typename _Func>
05835     piecewise_linear_distribution(size_t __nw,
05836                       _RealType __xmin, _RealType __xmax,
05837                       _Func __fw)
05838     : _M_param(__nw, __xmin, __xmax, __fw)
05839     { }
05840 
05841       explicit
05842       piecewise_linear_distribution(const param_type& __p)
05843       : _M_param(__p)
05844       { }
05845 
05846       /**
05847        * Resets the distribution state.
05848        */
05849       void
05850       reset()
05851       { }
05852 
05853       /**
05854        * @brief Return the intervals of the distribution.
05855        */
05856       std::vector<_RealType>
05857       intervals() const
05858       {
05859     if (_M_param._M_int.empty())
05860       {
05861         std::vector<_RealType> __tmp(2);
05862         __tmp[1] = _RealType(1);
05863         return __tmp;
05864       }
05865     else
05866       return _M_param._M_int;
05867       }
05868 
05869       /**
05870        * @brief Return a vector of the probability densities of the
05871        *        distribution.
05872        */
05873       std::vector<double>
05874       densities() const
05875       {
05876     return _M_param._M_den.empty()
05877       ? std::vector<double>(2, 1.0) : _M_param._M_den;
05878       }
05879 
05880       /**
05881        * @brief Returns the parameter set of the distribution.
05882        */
05883       param_type
05884       param() const
05885       { return _M_param; }
05886 
05887       /**
05888        * @brief Sets the parameter set of the distribution.
05889        * @param __param The new parameter set of the distribution.
05890        */
05891       void
05892       param(const param_type& __param)
05893       { _M_param = __param; }
05894 
05895       /**
05896        * @brief Returns the greatest lower bound value of the distribution.
05897        */
05898       result_type
05899       min() const
05900       {
05901     return _M_param._M_int.empty()
05902       ? result_type(0) : _M_param._M_int.front();
05903       }
05904 
05905       /**
05906        * @brief Returns the least upper bound value of the distribution.
05907        */
05908       result_type
05909       max() const
05910       {
05911     return _M_param._M_int.empty()
05912       ? result_type(1) : _M_param._M_int.back();
05913       }
05914 
05915       /**
05916        * @brief Generating functions.
05917        */
05918       template<typename _UniformRandomNumberGenerator>
05919     result_type
05920     operator()(_UniformRandomNumberGenerator& __urng)
05921     { return this->operator()(__urng, _M_param); }
05922 
05923       template<typename _UniformRandomNumberGenerator>
05924     result_type
05925     operator()(_UniformRandomNumberGenerator& __urng,
05926            const param_type& __p);
05927 
05928       template<typename _ForwardIterator,
05929            typename _UniformRandomNumberGenerator>
05930     void
05931     __generate(_ForwardIterator __f, _ForwardIterator __t,
05932            _UniformRandomNumberGenerator& __urng)
05933     { this->__generate(__f, __t, __urng, _M_param); }
05934 
05935       template<typename _ForwardIterator,
05936            typename _UniformRandomNumberGenerator>
05937     void
05938     __generate(_ForwardIterator __f, _ForwardIterator __t,
05939            _UniformRandomNumberGenerator& __urng,
05940            const param_type& __p)
05941     { this->__generate_impl(__f, __t, __urng, __p); }
05942 
05943       template<typename _UniformRandomNumberGenerator>
05944     void
05945     __generate(result_type* __f, result_type* __t,
05946            _UniformRandomNumberGenerator& __urng,
05947            const param_type& __p)
05948     { this->__generate_impl(__f, __t, __urng, __p); }
05949 
05950       /**
05951        * @brief Return true if two piecewise linear distributions have the
05952        *        same parameters.
05953        */
05954       friend bool
05955       operator==(const piecewise_linear_distribution& __d1,
05956          const piecewise_linear_distribution& __d2)
05957       { return __d1._M_param == __d2._M_param; }
05958 
05959       /**
05960        * @brief Inserts a %piecewise_linear_distribution random number
05961        *        distribution @p __x into the output stream @p __os.
05962        *
05963        * @param __os An output stream.
05964        * @param __x  A %piecewise_linear_distribution random number
05965        *             distribution.
05966        *
05967        * @returns The output stream with the state of @p __x inserted or in
05968        *          an error state.
05969        */
05970       template<typename _RealType1, typename _CharT, typename _Traits>
05971     friend std::basic_ostream<_CharT, _Traits>&
05972     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05973            const std::piecewise_linear_distribution<_RealType1>& __x);
05974 
05975       /**
05976        * @brief Extracts a %piecewise_linear_distribution random number
05977        *        distribution @p __x from the input stream @p __is.
05978        *
05979        * @param __is An input stream.
05980        * @param __x  A %piecewise_linear_distribution random number
05981        *             generator engine.
05982        *
05983        * @returns The input stream with @p __x extracted or in an error
05984        *          state.
05985        */
05986       template<typename _RealType1, typename _CharT, typename _Traits>
05987     friend std::basic_istream<_CharT, _Traits>&
05988     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05989            std::piecewise_linear_distribution<_RealType1>& __x);
05990 
05991     private:
05992       template<typename _ForwardIterator,
05993            typename _UniformRandomNumberGenerator>
05994     void
05995     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
05996             _UniformRandomNumberGenerator& __urng,
05997             const param_type& __p);
05998 
05999       param_type _M_param;
06000     };
06001 
06002   /**
06003     * @brief Return true if two piecewise linear distributions have
06004     *        different parameters.
06005    */
06006   template<typename _RealType>
06007     inline bool
06008     operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
06009            const std::piecewise_linear_distribution<_RealType>& __d2)
06010     { return !(__d1 == __d2); }
06011 
06012 
06013   /* @} */ // group random_distributions_poisson
06014 
06015   /* @} */ // group random_distributions
06016 
06017   /**
06018    * @addtogroup random_utilities Random Number Utilities
06019    * @ingroup random
06020    * @{
06021    */
06022 
06023   /**
06024    * @brief The seed_seq class generates sequences of seeds for random
06025    *        number generators.
06026    */
06027   class seed_seq
06028   {
06029 
06030   public:
06031     /** The type of the seed vales. */
06032     typedef uint_least32_t result_type;
06033 
06034     /** Default constructor. */
06035     seed_seq()
06036     : _M_v()
06037     { }
06038 
06039     template<typename _IntType>
06040       seed_seq(std::initializer_list<_IntType> il);
06041 
06042     template<typename _InputIterator>
06043       seed_seq(_InputIterator __begin, _InputIterator __end);
06044 
06045     // generating functions
06046     template<typename _RandomAccessIterator>
06047       void
06048       generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
06049 
06050     // property functions
06051     size_t size() const
06052     { return _M_v.size(); }
06053 
06054     template<typename OutputIterator>
06055       void
06056       param(OutputIterator __dest) const
06057       { std::copy(_M_v.begin(), _M_v.end(), __dest); }
06058 
06059   private:
06060     ///
06061     std::vector<result_type> _M_v;
06062   };
06063 
06064   /* @} */ // group random_utilities
06065 
06066   /* @} */ // group random
06067 
06068 _GLIBCXX_END_NAMESPACE_VERSION
06069 } // namespace std
06070 
06071 #endif