random.h

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

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1