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