random.h

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

Generated on 12 Mar 2010 for libstdc++ by  doxygen 1.6.1