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