random.h

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