libstdc++

random.h

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