random.h

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

Generated on 9 Feb 2010 for libstdc++ by  doxygen 1.6.1