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