random.h

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