# tr1_impl/random

Go to the documentation of this file.

    00001 // random number generation -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /**
    00031  * @file tr1_impl/random
    00032  *  This is an internal header file, included by other library headers.
    00033  *  You should not attempt to use it directly.
    00034  */
    00035
    00036 namespace std
    00037 {
    00038 _GLIBCXX_BEGIN_NAMESPACE_TR1
    00039
    00040   // [5.1] Random number generation
    00041
    00042   /**
    00043    * @addtogroup tr1_random Random Number Generation
    00044    * A facility for generating random numbers on selected distributions.
    00045    * @{
    00046    */
    00047
    00048   /*
    00049    * Implementation-space details.
    00050    */
    00051   namespace __detail
    00052   {
    00053     template<typename _UIntType, int __w,
    00054          bool = __w < std::numeric_limits<_UIntType>::digits>
    00055       struct _Shift
    00056       { static const _UIntType __value = 0; };
    00057
    00058     template<typename _UIntType, int __w>
    00059       struct _Shift<_UIntType, __w, true>
    00060       { static const _UIntType __value = _UIntType(1) << __w; };
    00061
    00062     template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
    00063       struct _Mod;
    00064
    00065     // Dispatch based on modulus value to prevent divide-by-zero compile-time
    00066     // errors when m == 0.
    00067     template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
    00068       inline _Tp
    00069       __mod(_Tp __x)
    00070       { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
    00071
    00072     typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
    00073             unsigned, unsigned long>::__type _UInt32Type;
    00074
    00075     /*
    00076      * An adaptor class for converting the output of any Generator into
    00077      * the input for a specific Distribution.
    00078      */
    00079     template<typename _Engine, typename _Distribution>
    00080       struct _Adaptor
    00081       {
    00082     typedef typename _Engine::result_type        _Engine_result_type;
    00083     typedef typename _Distribution::input_type   result_type;
    00084
    00085       public:
    00086     _Adaptor(const _Engine& __g)
    00087     : _M_g(__g) { }
    00088
    00089     result_type
    00090     min() const
    00091     {
    00092       result_type __return_value;
    00093       if (is_integral<_Engine_result_type>::value
    00094           && is_integral<result_type>::value)
    00095         __return_value = _M_g.min();
    00096       else
    00097         __return_value = result_type(0);
    00098       return __return_value;
    00099     }
    00100
    00101     result_type
    00102     max() const
    00103     {
    00104       result_type __return_value;
    00105       if (is_integral<_Engine_result_type>::value
    00106           && is_integral<result_type>::value)
    00107         __return_value = _M_g.max();
    00108       else if (!is_integral<result_type>::value)
    00109         __return_value = result_type(1);
    00110       else
    00111         __return_value = std::numeric_limits<result_type>::max() - 1;
    00112       return __return_value;
    00113     }
    00114
    00115     /*
    00116      * Converts a value generated by the adapted random number generator
    00117      * into a value in the input domain for the dependent random number
    00118      * distribution.
    00119      *
    00120      * Because the type traits are compile time constants only the
    00121      * appropriate clause of the if statements will actually be emitted
    00122      * by the compiler.
    00123      */
    00124     result_type
    00125     operator()()
    00126     {
    00127       result_type __return_value;
    00128       if (is_integral<_Engine_result_type>::value
    00129           && is_integral<result_type>::value)
    00130         __return_value = _M_g();
    00131       else if (!is_integral<_Engine_result_type>::value
    00132            && !is_integral<result_type>::value)
    00133         __return_value = result_type(_M_g() - _M_g.min())
    00134           / result_type(_M_g.max() - _M_g.min());
    00135       else if (is_integral<_Engine_result_type>::value
    00136            && !is_integral<result_type>::value)
    00137         __return_value = result_type(_M_g() - _M_g.min())
    00138           / result_type(_M_g.max() - _M_g.min() + result_type(1));
    00139       else
    00140         __return_value = (((_M_g() - _M_g.min())
    00141                    / (_M_g.max() - _M_g.min()))
    00142                   * std::numeric_limits<result_type>::max());
    00143       return __return_value;
    00144     }
    00145
    00146       private:
    00147     _Engine _M_g;
    00148       };
    00149   } // namespace __detail
    00150
    00151   /**
    00152    * Produces random numbers on a given distribution function using a
    00153    * non-uniform random number generation engine.
    00154    *
    00155    * @todo the engine_value_type needs to be studied more carefully.
    00156    */
    00157   template<typename _Engine, typename _Dist>
    00158     class variate_generator
    00159     {
    00160       // Concept requirements.
    00161       __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
    00162       //  __glibcxx_class_requires(_Engine, _EngineConcept)
    00163       //  __glibcxx_class_requires(_Dist, _EngineConcept)
    00164
    00165     public:
    00166       typedef _Engine                                engine_type;
    00167       typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
    00168       typedef _Dist                                  distribution_type;
    00169       typedef typename _Dist::result_type            result_type;
    00170
    00171       // tr1:5.1.1 table 5.1 requirement
    00172       typedef typename __gnu_cxx::__enable_if<
    00173     is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
    00174
    00175       /**
    00176        * Constructs a variate generator with the uniform random number
    00177        * generator @p __eng for the random distribution @p __dist.
    00178        *
    00179        * @throws Any exceptions which may thrown by the copy constructors of
    00180        * the @p _Engine or @p _Dist objects.
    00181        */
    00182       variate_generator(engine_type __eng, distribution_type __dist)
    00183       : _M_engine(__eng), _M_dist(__dist) { }
    00184
    00185       /**
    00186        * Gets the next generated value on the distribution.
    00187        */
    00188       result_type
    00189       operator()()
    00190       { return _M_dist(_M_engine); }
    00191
    00192       /**
    00193        * WTF?
    00194        */
    00195       template<typename _Tp>
    00196         result_type
    00197         operator()(_Tp __value)
    00198         { return _M_dist(_M_engine, __value); }
    00199
    00200       /**
    00201        * Gets a reference to the underlying uniform random number generator
    00202        * object.
    00203        */
    00204       engine_value_type&
    00205       engine()
    00206       { return _M_engine; }
    00207
    00208       /**
    00209        * Gets a const reference to the underlying uniform random number
    00210        * generator object.
    00211        */
    00212       const engine_value_type&
    00213       engine() const
    00214       { return _M_engine; }
    00215
    00216       /**
    00217        * Gets a reference to the underlying random distribution.
    00218        */
    00219       distribution_type&
    00220       distribution()
    00221       { return _M_dist; }
    00222
    00223       /**
    00224        * Gets a const reference to the underlying random distribution.
    00225        */
    00226       const distribution_type&
    00227       distribution() const
    00228       { return _M_dist; }
    00229
    00230       /**
    00231        * Gets the closed lower bound of the distribution interval.
    00232        */
    00233       result_type
    00234       min() const
    00235       { return this->distribution().min(); }
    00236
    00237       /**
    00238        * Gets the closed upper bound of the distribution interval.
    00239        */
    00240       result_type
    00241       max() const
    00242       { return this->distribution().max(); }
    00243
    00244     private:
    00245       engine_value_type _M_engine;
    00246       distribution_type _M_dist;
    00247     };
    00248
    00249
    00250   /**
    00251    * @addtogroup tr1_random_generators Random Number Generators
    00252    * @ingroup tr1_random
    00253    *
    00254    * These classes define objects which provide random or pseudorandom
    00255    * numbers, either from a discrete or a continuous interval.  The
    00256    * random number generator supplied as a part of this library are
    00257    * all uniform random number generators which provide a sequence of
    00258    * random number uniformly distributed over their range.
    00259    *
    00260    * A number generator is a function object with an operator() that
    00261    * takes zero arguments and returns a number.
    00262    *
    00263    * A compliant random number generator must satisfy the following
    00264    * requirements.  <table border=1 cellpadding=10 cellspacing=0>
    00265    * <caption align=top>Random Number Generator Requirements</caption>
    00266    * <tr><td>To be documented.</td></tr> </table>
    00267    *
    00268    * @{
    00269    */
    00270
    00271   /**
    00272    * @brief A model of a linear congruential random number generator.
    00273    *
    00274    * A random number generator that produces pseudorandom numbers using the
    00275    * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
    00276    *
    00277    * The template parameter @p _UIntType must be an unsigned integral type
    00278    * large enough to store values up to (__m-1). If the template parameter
    00279    * @p __m is 0, the modulus @p __m used is
    00280    * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
    00281    * parameters @p __a and @p __c must be less than @p __m.
    00282    *
    00283    * The size of the state is @f$ 1 @f$.
    00284    */
    00285   template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    00286     class linear_congruential
    00287     {
    00288       __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
    00289       //  __glibcpp_class_requires(__a < __m && __c < __m)
    00290
    00291     public:
    00292       /** The type of the generated random value. */
    00293       typedef _UIntType result_type;
    00294
    00295       /** The multiplier. */
    00296       static const _UIntType multiplier = __a;
    00297       /** An increment. */
    00298       static const _UIntType increment = __c;
    00299       /** The modulus. */
    00300       static const _UIntType modulus = __m;
    00301
    00302       /**
    00303        * Constructs a %linear_congruential random number generator engine with
    00304        * seed @p __s.  The default seed value is 1.
    00305        *
    00306        * @param __s The initial seed value.
    00307        */
    00308       explicit
    00309       linear_congruential(unsigned long __x0 = 1)
    00310       { this->seed(__x0); }
    00311
    00312       /**
    00313        * Constructs a %linear_congruential random number generator engine
    00314        * seeded from the generator function @p __g.
    00315        *
    00316        * @param __g The seed generator function.
    00317        */
    00318       template<class _Gen>
    00319         linear_congruential(_Gen& __g)
    00320         { this->seed(__g); }
    00321
    00322       /**
    00323        * Reseeds the %linear_congruential random number generator engine
    00324        * sequence to the seed @g __s.
    00325        *
    00326        * @param __s The new seed.
    00327        */
    00328       void
    00329       seed(unsigned long __s = 1);
    00330
    00331       /**
    00332        * Reseeds the %linear_congruential random number generator engine
    00333        * sequence using values from the generator function @p __g.
    00334        *
    00335        * @param __g the seed generator function.
    00336        */
    00337       template<class _Gen>
    00338         void
    00339         seed(_Gen& __g)
    00340         { seed(__g, typename is_fundamental<_Gen>::type()); }
    00341
    00342       /**
    00343        * Gets the smallest possible value in the output range.
    00344        *
    00345        * The minimum depends on the @p __c parameter: if it is zero, the
    00346        * minimum generated must be > 0, otherwise 0 is allowed.
    00347        */
    00348       result_type
    00349       min() const
    00350       { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
    00351
    00352       /**
    00353        * Gets the largest possible value in the output range.
    00354        */
    00355       result_type
    00356       max() const
    00357       { return __m - 1; }
    00358
    00359       /**
    00360        * Gets the next random number in the sequence.
    00361        */
    00362       result_type
    00363       operator()();
    00364
    00365       /**
    00366        * Compares two linear congruential random number generator
    00367        * objects of the same type for equality.
    00368        *
    00369        * @param __lhs A linear congruential random number generator object.
    00370        * @param __rhs Another linear congruential random number generator obj.
    00371        *
    00372        * @returns true if the two objects are equal, false otherwise.
    00373        */
    00374       friend bool
    00375       operator==(const linear_congruential& __lhs,
    00376          const linear_congruential& __rhs)
    00377       { return __lhs._M_x == __rhs._M_x; }
    00378
    00379       /**
    00380        * Compares two linear congruential random number generator
    00381        * objects of the same type for inequality.
    00382        *
    00383        * @param __lhs A linear congruential random number generator object.
    00384        * @param __rhs Another linear congruential random number generator obj.
    00385        *
    00386        * @returns true if the two objects are not equal, false otherwise.
    00387        */
    00388       friend bool
    00389       operator!=(const linear_congruential& __lhs,
    00390          const linear_congruential& __rhs)
    00391       { return !(__lhs == __rhs); }
    00392
    00393       /**
    00394        * Writes the textual representation of the state x(i) of x to @p __os.
    00395        *
    00396        * @param __os  The output stream.
    00397        * @param __lcr A % linear_congruential random number generator.
    00398        * @returns __os.
    00399        */
    00400       template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
    00401            _UIntType1 __m1,
    00402            typename _CharT, typename _Traits>
    00403         friend std::basic_ostream<_CharT, _Traits>&
    00404         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00405            const linear_congruential<_UIntType1, __a1, __c1,
    00406            __m1>& __lcr);
    00407
    00408       /**
    00409        * Sets the state of the engine by reading its textual
    00410        * representation from @p __is.
    00411        *
    00412        * The textual representation must have been previously written using an
    00413        * output stream whose imbued locale and whose type's template
    00414        * specialization arguments _CharT and _Traits were the same as those of
    00415        * @p __is.
    00416        *
    00417        * @param __is  The input stream.
    00418        * @param __lcr A % linear_congruential random number generator.
    00419        * @returns __is.
    00420        */
    00421       template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
    00422            _UIntType1 __m1,
    00423            typename _CharT, typename _Traits>
    00424         friend std::basic_istream<_CharT, _Traits>&
    00425         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00426            linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
    00427
    00428     private:
    00429       template<class _Gen>
    00430         void
    00431         seed(_Gen& __g, true_type)
    00432         { return seed(static_cast<unsigned long>(__g)); }
    00433
    00434       template<class _Gen>
    00435         void
    00436         seed(_Gen& __g, false_type);
    00437
    00438       _UIntType _M_x;
    00439     };
    00440
    00441   /**
    00442    * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
    00443    */
    00444   typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
    00445
    00446   /**
    00447    * An alternative LCR (Lehmer Generator function) .
    00448    */
    00449   typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
    00450
    00451
    00452   /**
    00453    * A generalized feedback shift register discrete random number generator.
    00454    *
    00455    * This algorithm avoids multiplication and division and is designed to be
    00456    * friendly to a pipelined architecture.  If the parameters are chosen
    00457    * correctly, this generator will produce numbers with a very long period and
    00458    * fairly good apparent entropy, although still not cryptographically strong.
    00459    *
    00460    * The best way to use this generator is with the predefined mt19937 class.
    00461    *
    00462    * This algorithm was originally invented by Makoto Matsumoto and
    00463    * Takuji Nishimura.
    00464    *
    00465    * @var word_size   The number of bits in each element of the state vector.
    00466    * @var state_size  The degree of recursion.
    00467    * @var shift_size  The period parameter.
    00468    * @var mask_bits   The separation point bit index.
    00469    * @var parameter_a The last row of the twist matrix.
    00470    * @var output_u    The first right-shift tempering matrix parameter.
    00471    * @var output_s    The first left-shift tempering matrix parameter.
    00472    * @var output_b    The first left-shift tempering matrix mask.
    00473    * @var output_t    The second left-shift tempering matrix parameter.
    00474    * @var output_c    The second left-shift tempering matrix mask.
    00475    * @var output_l    The second right-shift tempering matrix parameter.
    00476    */
    00477   template<class _UIntType, int __w, int __n, int __m, int __r,
    00478        _UIntType __a, int __u, int __s, _UIntType __b, int __t,
    00479        _UIntType __c, int __l>
    00480     class mersenne_twister
    00481     {
    00482       __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
    00483
    00484     public:
    00485       // types
    00486       typedef _UIntType result_type;
    00487
    00488       // parameter values
    00489       static const int       word_size   = __w;
    00490       static const int       state_size  = __n;
    00491       static const int       shift_size  = __m;
    00492       static const int       mask_bits   = __r;
    00493       static const _UIntType parameter_a = __a;
    00494       static const int       output_u    = __u;
    00495       static const int       output_s    = __s;
    00496       static const _UIntType output_b    = __b;
    00497       static const int       output_t    = __t;
    00498       static const _UIntType output_c    = __c;
    00499       static const int       output_l    = __l;
    00500
    00501       // constructors and member function
    00502       mersenne_twister()
    00503       { seed(); }
    00504
    00505       explicit
    00506       mersenne_twister(unsigned long __value)
    00507       { seed(__value); }
    00508
    00509       template<class _Gen>
    00510         mersenne_twister(_Gen& __g)
    00511         { seed(__g); }
    00512
    00513       void
    00514       seed()
    00515       { seed(5489UL); }
    00516
    00517       void
    00518       seed(unsigned long __value);
    00519
    00520       template<class _Gen>
    00521         void
    00522         seed(_Gen& __g)
    00523         { seed(__g, typename is_fundamental<_Gen>::type()); }
    00524
    00525       result_type
    00526       min() const
    00527       { return 0; };
    00528
    00529       result_type
    00530       max() const
    00531       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
    00532
    00533       result_type
    00534       operator()();
    00535
    00536       /**
    00537        * Compares two % mersenne_twister random number generator objects of
    00538        * the same type for equality.
    00539        *
    00540        * @param __lhs A % mersenne_twister random number generator object.
    00541        * @param __rhs Another % mersenne_twister random number generator
    00542        *              object.
    00543        *
    00544        * @returns true if the two objects are equal, false otherwise.
    00545        */
    00546       friend bool
    00547       operator==(const mersenne_twister& __lhs,
    00548          const mersenne_twister& __rhs)
    00549       { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
    00550
    00551       /**
    00552        * Compares two % mersenne_twister random number generator objects of
    00553        * the same type for inequality.
    00554        *
    00555        * @param __lhs A % mersenne_twister random number generator object.
    00556        * @param __rhs Another % mersenne_twister random number generator
    00557        *              object.
    00558        *
    00559        * @returns true if the two objects are not equal, false otherwise.
    00560        */
    00561       friend bool
    00562       operator!=(const mersenne_twister& __lhs,
    00563          const mersenne_twister& __rhs)
    00564       { return !(__lhs == __rhs); }
    00565
    00566       /**
    00567        * Inserts the current state of a % mersenne_twister random number
    00568        * generator engine @p __x into the output stream @p __os.
    00569        *
    00570        * @param __os An output stream.
    00571        * @param __x  A % mersenne_twister random number generator engine.
    00572        *
    00573        * @returns The output stream with the state of @p __x inserted or in
    00574        * an error state.
    00575        */
    00576       template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
    00577            _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
    00578            _UIntType1 __c1, int __l1,
    00579            typename _CharT, typename _Traits>
    00580         friend std::basic_ostream<_CharT, _Traits>&
    00581         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00582            const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
    00583            __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
    00584
    00585       /**
    00586        * Extracts the current state of a % mersenne_twister random number
    00587        * generator engine @p __x from the input stream @p __is.
    00588        *
    00589        * @param __is An input stream.
    00590        * @param __x  A % mersenne_twister random number generator engine.
    00591        *
    00592        * @returns The input stream with the state of @p __x extracted or in
    00593        * an error state.
    00594        */
    00595       template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
    00596            _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
    00597            _UIntType1 __c1, int __l1,
    00598            typename _CharT, typename _Traits>
    00599         friend std::basic_istream<_CharT, _Traits>&
    00600         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00601            mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
    00602            __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
    00603
    00604     private:
    00605       template<class _Gen>
    00606         void
    00607         seed(_Gen& __g, true_type)
    00608         { return seed(static_cast<unsigned long>(__g)); }
    00609
    00610       template<class _Gen>
    00611         void
    00612         seed(_Gen& __g, false_type);
    00613
    00614       _UIntType _M_x[state_size];
    00615       int       _M_p;
    00616     };
    00617
    00618   /**
    00619    * The classic Mersenne Twister.
    00620    *
    00621    * Reference:
    00622    * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
    00623    * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
    00624    * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
    00625    */
    00626   typedef mersenne_twister<
    00627     unsigned long, 32, 624, 397, 31,
    00628     0x9908b0dful, 11, 7,
    00629     0x9d2c5680ul, 15,
    00630     0xefc60000ul, 18
    00631     > mt19937;
    00632
    00633
    00634   /**
    00635    * @brief The Marsaglia-Zaman generator.
    00636    *
    00637    * This is a model of a Generalized Fibonacci discrete random number
    00638    * generator, sometimes referred to as the SWC generator.
    00639    *
    00640    * A discrete random number generator that produces pseudorandom
    00641    * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
    00642    * carry_{i-1}) \bmod m @f$.
    00643    *
    00644    * The size of the state is @f$ r @f$
    00645    * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
    00646    *
    00647    * N1688[4.13] says "the template parameter _IntType shall denote an integral
    00648    * type large enough to store values up to m."
    00649    *
    00650    * @var _M_x     The state of the generator.  This is a ring buffer.
    00651    * @var _M_carry The carry.
    00652    * @var _M_p     Current index of x(i - r).
    00653    */
    00654   template<typename _IntType, _IntType __m, int __s, int __r>
    00655     class subtract_with_carry
    00656     {
    00657       __glibcxx_class_requires(_IntType, _IntegerConcept)
    00658
    00659     public:
    00660       /** The type of the generated random value. */
    00661       typedef _IntType result_type;
    00662
    00663       // parameter values
    00664       static const _IntType modulus   = __m;
    00665       static const int      long_lag  = __r;
    00666       static const int      short_lag = __s;
    00667
    00668       /**
    00669        * Constructs a default-initialized % subtract_with_carry random number
    00670        * generator.
    00671        */
    00672       subtract_with_carry()
    00673       { this->seed(); }
    00674
    00675       /**
    00676        * Constructs an explicitly seeded % subtract_with_carry random number
    00677        * generator.
    00678        */
    00679       explicit
    00680       subtract_with_carry(unsigned long __value)
    00681       { this->seed(__value); }
    00682
    00683       /**
    00684        * Constructs a %subtract_with_carry random number generator engine
    00685        * seeded from the generator function @p __g.
    00686        *
    00687        * @param __g The seed generator function.
    00688        */
    00689       template<class _Gen>
    00690         subtract_with_carry(_Gen& __g)
    00691         { this->seed(__g); }
    00692
    00693       /**
    00694        * Seeds the initial state @f$ x_0 @f$ of the random number generator.
    00695        *
    00696        * N1688[4.19] modifies this as follows.  If @p __value == 0,
    00697        * sets value to 19780503.  In any case, with a linear
    00698        * congruential generator lcg(i) having parameters @f$ m_{lcg} =
    00699        * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
    00700        * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
    00701        * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
    00702        * set carry to 1, otherwise sets carry to 0.
    00703        */
    00704       void
    00705       seed(unsigned long __value = 19780503);
    00706
    00707       /**
    00708        * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
    00709        * random number generator.
    00710        */
    00711       template<class _Gen>
    00712         void
    00713         seed(_Gen& __g)
    00714         { seed(__g, typename is_fundamental<_Gen>::type()); }
    00715
    00716       /**
    00717        * Gets the inclusive minimum value of the range of random integers
    00718        * returned by this generator.
    00719        */
    00720       result_type
    00721       min() const
    00722       { return 0; }
    00723
    00724       /**
    00725        * Gets the inclusive maximum value of the range of random integers
    00726        * returned by this generator.
    00727        */
    00728       result_type
    00729       max() const
    00730       { return this->modulus - 1; }
    00731
    00732       /**
    00733        * Gets the next random number in the sequence.
    00734        */
    00735       result_type
    00736       operator()();
    00737
    00738       /**
    00739        * Compares two % subtract_with_carry random number generator objects of
    00740        * the same type for equality.
    00741        *
    00742        * @param __lhs A % subtract_with_carry random number generator object.
    00743        * @param __rhs Another % subtract_with_carry random number generator
    00744        *              object.
    00745        *
    00746        * @returns true if the two objects are equal, false otherwise.
    00747        */
    00748       friend bool
    00749       operator==(const subtract_with_carry& __lhs,
    00750          const subtract_with_carry& __rhs)
    00751       { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
    00752
    00753       /**
    00754        * Compares two % subtract_with_carry random number generator objects of
    00755        * the same type for inequality.
    00756        *
    00757        * @param __lhs A % subtract_with_carry random number generator object.
    00758        * @param __rhs Another % subtract_with_carry random number generator
    00759        *              object.
    00760        *
    00761        * @returns true if the two objects are not equal, false otherwise.
    00762        */
    00763       friend bool
    00764       operator!=(const subtract_with_carry& __lhs,
    00765          const subtract_with_carry& __rhs)
    00766       { return !(__lhs == __rhs); }
    00767
    00768       /**
    00769        * Inserts the current state of a % subtract_with_carry random number
    00770        * generator engine @p __x into the output stream @p __os.
    00771        *
    00772        * @param __os An output stream.
    00773        * @param __x  A % subtract_with_carry random number generator engine.
    00774        *
    00775        * @returns The output stream with the state of @p __x inserted or in
    00776        * an error state.
    00777        */
    00778       template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
    00779            typename _CharT, typename _Traits>
    00780         friend std::basic_ostream<_CharT, _Traits>&
    00781         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00782            const subtract_with_carry<_IntType1, __m1, __s1,
    00783            __r1>& __x);
    00784
    00785       /**
    00786        * Extracts the current state of a % subtract_with_carry random number
    00787        * generator engine @p __x from the input stream @p __is.
    00788        *
    00789        * @param __is An input stream.
    00790        * @param __x  A % subtract_with_carry random number generator engine.
    00791        *
    00792        * @returns The input stream with the state of @p __x extracted or in
    00793        * an error state.
    00794        */
    00795       template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
    00796            typename _CharT, typename _Traits>
    00797         friend std::basic_istream<_CharT, _Traits>&
    00798         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00799            subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
    00800
    00801     private:
    00802       template<class _Gen>
    00803         void
    00804         seed(_Gen& __g, true_type)
    00805         { return seed(static_cast<unsigned long>(__g)); }
    00806
    00807       template<class _Gen>
    00808         void
    00809         seed(_Gen& __g, false_type);
    00810
    00811       typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
    00812
    00813       _UIntType  _M_x[long_lag];
    00814       _UIntType  _M_carry;
    00815       int        _M_p;
    00816     };
    00817
    00818
    00819   /**
    00820    * @brief The Marsaglia-Zaman generator (floats version).
    00821    *
    00822    * @var _M_x     The state of the generator.  This is a ring buffer.
    00823    * @var _M_carry The carry.
    00824    * @var _M_p     Current index of x(i - r).
    00825    * @var _M_npows Precomputed negative powers of 2.
    00826    */
    00827   template<typename _RealType, int __w, int __s, int __r>
    00828     class subtract_with_carry_01
    00829     {
    00830     public:
    00831       /** The type of the generated random value. */
    00832       typedef _RealType result_type;
    00833
    00834       // parameter values
    00835       static const int      word_size = __w;
    00836       static const int      long_lag  = __r;
    00837       static const int      short_lag = __s;
    00838
    00839       /**
    00840        * Constructs a default-initialized % subtract_with_carry_01 random
    00841        * number generator.
    00842        */
    00843       subtract_with_carry_01()
    00844       {
    00845     this->seed();
    00846     _M_initialize_npows();
    00847       }
    00848
    00849       /**
    00850        * Constructs an explicitly seeded % subtract_with_carry_01 random number
    00851        * generator.
    00852        */
    00853       explicit
    00854       subtract_with_carry_01(unsigned long __value)
    00855       {
    00856     this->seed(__value);
    00857     _M_initialize_npows();
    00858       }
    00859
    00860       /**
    00861        * Constructs a % subtract_with_carry_01 random number generator engine
    00862        * seeded from the generator function @p __g.
    00863        *
    00864        * @param __g The seed generator function.
    00865        */
    00866       template<class _Gen>
    00867         subtract_with_carry_01(_Gen& __g)
    00868         {
    00869       this->seed(__g);
    00870       _M_initialize_npows();
    00871     }
    00872
    00873       /**
    00874        * Seeds the initial state @f$ x_0 @f$ of the random number generator.
    00875        */
    00876       void
    00877       seed(unsigned long __value = 19780503);
    00878
    00879       /**
    00880        * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
    00881        * random number generator.
    00882        */
    00883       template<class _Gen>
    00884         void
    00885         seed(_Gen& __g)
    00886         { seed(__g, typename is_fundamental<_Gen>::type()); }
    00887
    00888       /**
    00889        * Gets the minimum value of the range of random floats
    00890        * returned by this generator.
    00891        */
    00892       result_type
    00893       min() const
    00894       { return 0.0; }
    00895
    00896       /**
    00897        * Gets the maximum value of the range of random floats
    00898        * returned by this generator.
    00899        */
    00900       result_type
    00901       max() const
    00902       { return 1.0; }
    00903
    00904       /**
    00905        * Gets the next random number in the sequence.
    00906        */
    00907       result_type
    00908       operator()();
    00909
    00910       /**
    00911        * Compares two % subtract_with_carry_01 random number generator objects
    00912        * of the same type for equality.
    00913        *
    00914        * @param __lhs A % subtract_with_carry_01 random number
    00915        *              generator object.
    00916        * @param __rhs Another % subtract_with_carry_01 random number generator
    00917        *              object.
    00918        *
    00919        * @returns true if the two objects are equal, false otherwise.
    00920        */
    00921       friend bool
    00922       operator==(const subtract_with_carry_01& __lhs,
    00923          const subtract_with_carry_01& __rhs)
    00924       {
    00925     for (int __i = 0; __i < long_lag; ++__i)
    00926       if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
    00927               __rhs._M_x[__i]))
    00928         return false;
    00929     return true;
    00930       }
    00931
    00932       /**
    00933        * Compares two % subtract_with_carry_01 random number generator objects
    00934        * of the same type for inequality.
    00935        *
    00936        * @param __lhs A % subtract_with_carry_01 random number
    00937        *              generator object.
    00938        *
    00939        * @param __rhs Another % subtract_with_carry_01 random number generator
    00940        *              object.
    00941        *
    00942        * @returns true if the two objects are not equal, false otherwise.
    00943        */
    00944       friend bool
    00945       operator!=(const subtract_with_carry_01& __lhs,
    00946          const subtract_with_carry_01& __rhs)
    00947       { return !(__lhs == __rhs); }
    00948
    00949       /**
    00950        * Inserts the current state of a % subtract_with_carry_01 random number
    00951        * generator engine @p __x into the output stream @p __os.
    00952        *
    00953        * @param __os An output stream.
    00954        * @param __x  A % subtract_with_carry_01 random number generator engine.
    00955        *
    00956        * @returns The output stream with the state of @p __x inserted or in
    00957        * an error state.
    00958        */
    00959       template<typename _RealType1, int __w1, int __s1, int __r1,
    00960            typename _CharT, typename _Traits>
    00961         friend std::basic_ostream<_CharT, _Traits>&
    00962         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    00963            const subtract_with_carry_01<_RealType1, __w1, __s1,
    00964            __r1>& __x);
    00965
    00966       /**
    00967        * Extracts the current state of a % subtract_with_carry_01 random number
    00968        * generator engine @p __x from the input stream @p __is.
    00969        *
    00970        * @param __is An input stream.
    00971        * @param __x  A % subtract_with_carry_01 random number generator engine.
    00972        *
    00973        * @returns The input stream with the state of @p __x extracted or in
    00974        * an error state.
    00975        */
    00976       template<typename _RealType1, int __w1, int __s1, int __r1,
    00977            typename _CharT, typename _Traits>
    00978         friend std::basic_istream<_CharT, _Traits>&
    00979         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    00980            subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
    00981
    00982     private:
    00983       template<class _Gen>
    00984         void
    00985         seed(_Gen& __g, true_type)
    00986         { return seed(static_cast<unsigned long>(__g)); }
    00987
    00988       template<class _Gen>
    00989         void
    00990         seed(_Gen& __g, false_type);
    00991
    00992       void
    00993       _M_initialize_npows();
    00994
    00995       static const int __n = (__w + 31) / 32;
    00996
    00997       typedef __detail::_UInt32Type _UInt32Type;
    00998       _UInt32Type  _M_x[long_lag][__n];
    00999       _RealType    _M_npows[__n];
    01000       _UInt32Type  _M_carry;
    01001       int          _M_p;
    01002     };
    01003
    01004   typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;
    01005
    01006   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    01007   // 508. Bad parameters for ranlux64_base_01.
    01008   typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
    01009
    01010
    01011   /**
    01012    * Produces random numbers from some base engine by discarding blocks of
    01013    * data.
    01014    *
    01015    * 0 <= @p __r <= @p __p
    01016    */
    01017   template<class _UniformRandomNumberGenerator, int __p, int __r>
    01018     class discard_block
    01019     {
    01020       // __glibcxx_class_requires(typename base_type::result_type,
    01021       //                          ArithmeticTypeConcept)
    01022
    01023     public:
    01024       /** The type of the underlying generator engine. */
    01025       typedef _UniformRandomNumberGenerator   base_type;
    01026       /** The type of the generated random value. */
    01027       typedef typename base_type::result_type result_type;
    01028
    01029       // parameter values
    01030       static const int block_size = __p;
    01031       static const int used_block = __r;
    01032
    01033       /**
    01034        * Constructs a default %discard_block engine.
    01035        *
    01036        * The underlying engine is default constructed as well.
    01037        */
    01038       discard_block()
    01039       : _M_n(0) { }
    01040
    01041       /**
    01042        * Copy constructs a %discard_block engine.
    01043        *
    01044        * Copies an existing base class random number generator.
    01045        * @param rng An existing (base class) engine object.
    01046        */
    01047       explicit
    01048       discard_block(const base_type& __rng)
    01049       : _M_b(__rng), _M_n(0) { }
    01050
    01051       /**
    01052        * Seed constructs a %discard_block engine.
    01053        *
    01054        * Constructs the underlying generator engine seeded with @p __s.
    01055        * @param __s A seed value for the base class engine.
    01056        */
    01057       explicit
    01058       discard_block(unsigned long __s)
    01059       : _M_b(__s), _M_n(0) { }
    01060
    01061       /**
    01062        * Generator construct a %discard_block engine.
    01063        *
    01064        * @param __g A seed generator function.
    01065        */
    01066       template<class _Gen>
    01067         discard_block(_Gen& __g)
    01068     : _M_b(__g), _M_n(0) { }
    01069
    01070       /**
    01071        * Reseeds the %discard_block object with the default seed for the
    01072        * underlying base class generator engine.
    01073        */
    01074       void seed()
    01075       {
    01076     _M_b.seed();
    01077     _M_n = 0;
    01078       }
    01079
    01080       /**
    01081        * Reseeds the %discard_block object with the given seed generator
    01082        * function.
    01083        * @param __g A seed generator function.
    01084        */
    01085       template<class _Gen>
    01086         void seed(_Gen& __g)
    01087         {
    01088       _M_b.seed(__g);
    01089       _M_n = 0;
    01090     }
    01091
    01092       /**
    01093        * Gets a const reference to the underlying generator engine object.
    01094        */
    01095       const base_type&
    01096       base() const
    01097       { return _M_b; }
    01098
    01099       /**
    01100        * Gets the minimum value in the generated random number range.
    01101        */
    01102       result_type
    01103       min() const
    01104       { return _M_b.min(); }
    01105
    01106       /**
    01107        * Gets the maximum value in the generated random number range.
    01108        */
    01109       result_type
    01110       max() const
    01111       { return _M_b.max(); }
    01112
    01113       /**
    01114        * Gets the next value in the generated random number sequence.
    01115        */
    01116       result_type
    01117       operator()();
    01118
    01119       /**
    01120        * Compares two %discard_block random number generator objects of
    01121        * the same type for equality.
    01122        *
    01123        * @param __lhs A %discard_block random number generator object.
    01124        * @param __rhs Another %discard_block random number generator
    01125        *              object.
    01126        *
    01127        * @returns true if the two objects are equal, false otherwise.
    01128        */
    01129       friend bool
    01130       operator==(const discard_block& __lhs, const discard_block& __rhs)
    01131       { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
    01132
    01133       /**
    01134        * Compares two %discard_block random number generator objects of
    01135        * the same type for inequality.
    01136        *
    01137        * @param __lhs A %discard_block random number generator object.
    01138        * @param __rhs Another %discard_block random number generator
    01139        *              object.
    01140        *
    01141        * @returns true if the two objects are not equal, false otherwise.
    01142        */
    01143       friend bool
    01144       operator!=(const discard_block& __lhs, const discard_block& __rhs)
    01145       { return !(__lhs == __rhs); }
    01146
    01147       /**
    01148        * Inserts the current state of a %discard_block random number
    01149        * generator engine @p __x into the output stream @p __os.
    01150        *
    01151        * @param __os An output stream.
    01152        * @param __x  A %discard_block random number generator engine.
    01153        *
    01154        * @returns The output stream with the state of @p __x inserted or in
    01155        * an error state.
    01156        */
    01157       template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
    01158            typename _CharT, typename _Traits>
    01159         friend std::basic_ostream<_CharT, _Traits>&
    01160         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01161            const discard_block<_UniformRandomNumberGenerator1,
    01162            __p1, __r1>& __x);
    01163
    01164       /**
    01165        * Extracts the current state of a % subtract_with_carry random number
    01166        * generator engine @p __x from the input stream @p __is.
    01167        *
    01168        * @param __is An input stream.
    01169        * @param __x  A %discard_block random number generator engine.
    01170        *
    01171        * @returns The input stream with the state of @p __x extracted or in
    01172        * an error state.
    01173        */
    01174       template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
    01175            typename _CharT, typename _Traits>
    01176         friend std::basic_istream<_CharT, _Traits>&
    01177         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01178            discard_block<_UniformRandomNumberGenerator1,
    01179            __p1, __r1>& __x);
    01180
    01181     private:
    01182       base_type _M_b;
    01183       int       _M_n;
    01184     };
    01185
    01186
    01187   /**
    01188    * James's luxury-level-3 integer adaptation of Luescher's generator.
    01189    */
    01190   typedef discard_block<
    01191     subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
    01192       223,
    01193       24
    01194       > ranlux3;
    01195
    01196   /**
    01197    * James's luxury-level-4 integer adaptation of Luescher's generator.
    01198    */
    01199   typedef discard_block<
    01200     subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
    01201       389,
    01202       24
    01203       > ranlux4;
    01204
    01205   typedef discard_block<
    01206     subtract_with_carry_01<float, 24, 10, 24>,
    01207       223,
    01208       24
    01209       > ranlux3_01;
    01210
    01211   typedef discard_block<
    01212     subtract_with_carry_01<float, 24, 10, 24>,
    01213       389,
    01214       24
    01215       > ranlux4_01;
    01216
    01217
    01218   /**
    01219    * A random number generator adaptor class that combines two random number
    01220    * generator engines into a single output sequence.
    01221    */
    01222   template<class _UniformRandomNumberGenerator1, int __s1,
    01223        class _UniformRandomNumberGenerator2, int __s2>
    01224     class xor_combine
    01225     {
    01226       // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
    01227       //                          result_type, ArithmeticTypeConcept)
    01228       // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
    01229       //                          result_type, ArithmeticTypeConcept)
    01230
    01231     public:
    01232       /** The type of the first underlying generator engine. */
    01233       typedef _UniformRandomNumberGenerator1   base1_type;
    01234       /** The type of the second underlying generator engine. */
    01235       typedef _UniformRandomNumberGenerator2   base2_type;
    01236
    01237     private:
    01238       typedef typename base1_type::result_type _Result_type1;
    01239       typedef typename base2_type::result_type _Result_type2;
    01240
    01241     public:
    01242       /** The type of the generated random value. */
    01243       typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
    01244                               > sizeof(_Result_type2)),
    01245     _Result_type1, _Result_type2>::__type result_type;
    01246
    01247       // parameter values
    01248       static const int shift1 = __s1;
    01249       static const int shift2 = __s2;
    01250
    01251       // constructors and member function
    01252       xor_combine()
    01253       : _M_b1(), _M_b2()
    01254       { _M_initialize_max(); }
    01255
    01256       xor_combine(const base1_type& __rng1, const base2_type& __rng2)
    01257       : _M_b1(__rng1), _M_b2(__rng2)
    01258       { _M_initialize_max(); }
    01259
    01260       xor_combine(unsigned long __s)
    01261       : _M_b1(__s), _M_b2(__s + 1)
    01262       { _M_initialize_max(); }
    01263
    01264       template<class _Gen>
    01265         xor_combine(_Gen& __g)
    01266     : _M_b1(__g), _M_b2(__g)
    01267         { _M_initialize_max(); }
    01268
    01269       void
    01270       seed()
    01271       {
    01272     _M_b1.seed();
    01273     _M_b2.seed();
    01274       }
    01275
    01276       template<class _Gen>
    01277         void
    01278         seed(_Gen& __g)
    01279         {
    01280       _M_b1.seed(__g);
    01281       _M_b2.seed(__g);
    01282     }
    01283
    01284       const base1_type&
    01285       base1() const
    01286       { return _M_b1; }
    01287
    01288       const base2_type&
    01289       base2() const
    01290       { return _M_b2; }
    01291
    01292       result_type
    01293       min() const
    01294       { return 0; }
    01295
    01296       result_type
    01297       max() const
    01298       { return _M_max; }
    01299
    01300       /**
    01301        * Gets the next random number in the sequence.
    01302        */
    01303       // NB: Not exactly the TR1 formula, per N2079 instead.
    01304       result_type
    01305       operator()()
    01306       {
    01307     return ((result_type(_M_b1() - _M_b1.min()) << shift1)
    01308         ^ (result_type(_M_b2() - _M_b2.min()) << shift2));
    01309       }
    01310
    01311       /**
    01312        * Compares two %xor_combine random number generator objects of
    01313        * the same type for equality.
    01314        *
    01315        * @param __lhs A %xor_combine random number generator object.
    01316        * @param __rhs Another %xor_combine random number generator
    01317        *              object.
    01318        *
    01319        * @returns true if the two objects are equal, false otherwise.
    01320        */
    01321       friend bool
    01322       operator==(const xor_combine& __lhs, const xor_combine& __rhs)
    01323       {
    01324     return (__lhs.base1() == __rhs.base1())
    01325             && (__lhs.base2() == __rhs.base2());
    01326       }
    01327
    01328       /**
    01329        * Compares two %xor_combine random number generator objects of
    01330        * the same type for inequality.
    01331        *
    01332        * @param __lhs A %xor_combine random number generator object.
    01333        * @param __rhs Another %xor_combine random number generator
    01334        *              object.
    01335        *
    01336        * @returns true if the two objects are not equal, false otherwise.
    01337        */
    01338       friend bool
    01339       operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
    01340       { return !(__lhs == __rhs); }
    01341
    01342       /**
    01343        * Inserts the current state of a %xor_combine random number
    01344        * generator engine @p __x into the output stream @p __os.
    01345        *
    01346        * @param __os An output stream.
    01347        * @param __x  A %xor_combine random number generator engine.
    01348        *
    01349        * @returns The output stream with the state of @p __x inserted or in
    01350        * an error state.
    01351        */
    01352       template<class _UniformRandomNumberGenerator11, int __s11,
    01353            class _UniformRandomNumberGenerator21, int __s21,
    01354            typename _CharT, typename _Traits>
    01355         friend std::basic_ostream<_CharT, _Traits>&
    01356         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01357            const xor_combine<_UniformRandomNumberGenerator11, __s11,
    01358            _UniformRandomNumberGenerator21, __s21>& __x);
    01359
    01360       /**
    01361        * Extracts the current state of a %xor_combine random number
    01362        * generator engine @p __x from the input stream @p __is.
    01363        *
    01364        * @param __is An input stream.
    01365        * @param __x  A %xor_combine random number generator engine.
    01366        *
    01367        * @returns The input stream with the state of @p __x extracted or in
    01368        * an error state.
    01369        */
    01370       template<class _UniformRandomNumberGenerator11, int __s11,
    01371            class _UniformRandomNumberGenerator21, int __s21,
    01372            typename _CharT, typename _Traits>
    01373         friend std::basic_istream<_CharT, _Traits>&
    01374         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01375            xor_combine<_UniformRandomNumberGenerator11, __s11,
    01376            _UniformRandomNumberGenerator21, __s21>& __x);
    01377
    01378     private:
    01379       void
    01380       _M_initialize_max();
    01381
    01382       result_type
    01383       _M_initialize_max_aux(result_type, result_type, int);
    01384
    01385       base1_type  _M_b1;
    01386       base2_type  _M_b2;
    01387       result_type _M_max;
    01388     };
    01389
    01390
    01391   /**
    01392    * A standard interface to a platform-specific non-deterministic
    01393    * random number generator (if any are available).
    01394    */
    01395   class random_device
    01396   {
    01397   public:
    01398     // types
    01399     typedef unsigned int result_type;
    01400
    01401     // constructors, destructors and member functions
    01402
    01403 #ifdef _GLIBCXX_USE_RANDOM_TR1
    01404
    01405     explicit
    01406     random_device(const std::string& __token = "/dev/urandom")
    01407     {
    01408       if ((__token != "/dev/urandom" && __token != "/dev/random")
    01409       || !(_M_file = std::fopen(__token.c_str(), "rb")))
    01410     std::__throw_runtime_error(__N("random_device::"
    01411                        "random_device(const std::string&)"));
    01412     }
    01413
    01414     ~random_device()
    01415     { std::fclose(_M_file); }
    01416
    01417 #else
    01418
    01419     explicit
    01420     random_device(const std::string& __token = "mt19937")
    01421     : _M_mt(_M_strtoul(__token)) { }
    01422
    01423   private:
    01424     static unsigned long
    01425     _M_strtoul(const std::string& __str)
    01426     {
    01427       unsigned long __ret = 5489UL;
    01428       if (__str != "mt19937")
    01429     {
    01430       const char* __nptr = __str.c_str();
    01431       char* __endptr;
    01432       __ret = std::strtoul(__nptr, &__endptr, 0);
    01433       if (*__nptr == '\0' || *__endptr != '\0')
    01434         std::__throw_runtime_error(__N("random_device::_M_strtoul"
    01435                        "(const std::string&)"));
    01436     }
    01437       return __ret;
    01438     }
    01439
    01440   public:
    01441
    01442 #endif
    01443
    01444     result_type
    01445     min() const
    01446     { return std::numeric_limits<result_type>::min(); }
    01447
    01448     result_type
    01449     max() const
    01450     { return std::numeric_limits<result_type>::max(); }
    01451
    01452     double
    01453     entropy() const
    01454     { return 0.0; }
    01455
    01456     result_type
    01457     operator()()
    01458     {
    01459 #ifdef _GLIBCXX_USE_RANDOM_TR1
    01460       result_type __ret;
    01461       std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
    01462          1, _M_file);
    01463       return __ret;
    01464 #else
    01465       return _M_mt();
    01466 #endif
    01467     }
    01468
    01469   private:
    01470     random_device(const random_device&);
    01471     void operator=(const random_device&);
    01472
    01473 #ifdef _GLIBCXX_USE_RANDOM_TR1
    01474     FILE*        _M_file;
    01475 #else
    01476     mt19937      _M_mt;
    01477 #endif
    01478   };
    01479
    01480   /* @} */ // group tr1_random_generators
    01481
    01482   /**
    01483    * @addtogroup tr1_random_distributions Random Number Distributions
    01484    * @ingroup tr1_random
    01485    * @{
    01486    */
    01487
    01488   /**
    01489    * @addtogroup tr1_random_distributions_discrete Discrete Distributions
    01490    * @ingroup tr1_random_distributions
    01491    * @{
    01492    */
    01493
    01494   /**
    01495    * @brief Uniform discrete distribution for random numbers.
    01496    * A discrete random distribution on the range @f$[min, max]@f$ with equal
    01497    * probability throughout the range.
    01498    */
    01499   template<typename _IntType = int>
    01500     class uniform_int
    01501     {
    01502       __glibcxx_class_requires(_IntType, _IntegerConcept)
    01503
    01504     public:
    01505       /** The type of the parameters of the distribution. */
    01506       typedef _IntType input_type;
    01507       /** The type of the range of the distribution. */
    01508       typedef _IntType result_type;
    01509
    01510     public:
    01511       /**
    01512        * Constructs a uniform distribution object.
    01513        */
    01514       explicit
    01515       uniform_int(_IntType __min = 0, _IntType __max = 9)
    01516       : _M_min(__min), _M_max(__max)
    01517       {
    01518     _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
    01519       }
    01520
    01521       /**
    01522        * Gets the inclusive lower bound of the distribution range.
    01523        */
    01524       result_type
    01525       min() const
    01526       { return _M_min; }
    01527
    01528       /**
    01529        * Gets the inclusive upper bound of the distribution range.
    01530        */
    01531       result_type
    01532       max() const
    01533       { return _M_max; }
    01534
    01535       /**
    01536        * Resets the distribution state.
    01537        *
    01538        * Does nothing for the uniform integer distribution.
    01539        */
    01540       void
    01541       reset() { }
    01542
    01543       /**
    01544        * Gets a uniformly distributed random number in the range
    01545        * @f$(min, max)@f$.
    01546        */
    01547       template<typename _UniformRandomNumberGenerator>
    01548         result_type
    01549         operator()(_UniformRandomNumberGenerator& __urng)
    01550         {
    01551       typedef typename _UniformRandomNumberGenerator::result_type
    01552         _UResult_type;
    01553       return _M_call(__urng, _M_min, _M_max,
    01554              typename is_integral<_UResult_type>::type());
    01555     }
    01556
    01557       /**
    01558        * Gets a uniform random number in the range @f$[0, n)@f$.
    01559        *
    01560        * This function is aimed at use with std::random_shuffle.
    01561        */
    01562       template<typename _UniformRandomNumberGenerator>
    01563         result_type
    01564         operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
    01565         {
    01566       typedef typename _UniformRandomNumberGenerator::result_type
    01567         _UResult_type;
    01568       return _M_call(__urng, 0, __n - 1,
    01569              typename is_integral<_UResult_type>::type());
    01570     }
    01571
    01572       /**
    01573        * Inserts a %uniform_int random number distribution @p __x into the
    01574        * output stream @p os.
    01575        *
    01576        * @param __os An output stream.
    01577        * @param __x  A %uniform_int random number distribution.
    01578        *
    01579        * @returns The output stream with the state of @p __x inserted or in
    01580        * an error state.
    01581        */
    01582       template<typename _IntType1, typename _CharT, typename _Traits>
    01583         friend std::basic_ostream<_CharT, _Traits>&
    01584         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01585            const uniform_int<_IntType1>& __x);
    01586
    01587       /**
    01588        * Extracts a %uniform_int random number distribution
    01589        * @p __x from the input stream @p __is.
    01590        *
    01591        * @param __is An input stream.
    01592        * @param __x  A %uniform_int random number generator engine.
    01593        *
    01594        * @returns The input stream with @p __x extracted or in an error state.
    01595        */
    01596       template<typename _IntType1, typename _CharT, typename _Traits>
    01597         friend std::basic_istream<_CharT, _Traits>&
    01598         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01599            uniform_int<_IntType1>& __x);
    01600
    01601     private:
    01602       template<typename _UniformRandomNumberGenerator>
    01603         result_type
    01604         _M_call(_UniformRandomNumberGenerator& __urng,
    01605         result_type __min, result_type __max, true_type);
    01606
    01607       template<typename _UniformRandomNumberGenerator>
    01608         result_type
    01609         _M_call(_UniformRandomNumberGenerator& __urng,
    01610         result_type __min, result_type __max, false_type)
    01611         {
    01612       return result_type((__urng() - __urng.min())
    01613                  / (__urng.max() - __urng.min())
    01614                  * (__max - __min + 1)) + __min;
    01615     }
    01616
    01617       _IntType _M_min;
    01618       _IntType _M_max;
    01619     };
    01620
    01621
    01622   /**
    01623    * @brief A Bernoulli random number distribution.
    01624    *
    01625    * Generates a sequence of true and false values with likelihood @f$ p @f$
    01626    * that true will come up and @f$ (1 - p) @f$ that false will appear.
    01627    */
    01628   class bernoulli_distribution
    01629   {
    01630   public:
    01631     typedef int  input_type;
    01632     typedef bool result_type;
    01633
    01634   public:
    01635     /**
    01636      * Constructs a Bernoulli distribution with likelihood @p p.
    01637      *
    01638      * @param __p  [IN]  The likelihood of a true result being returned.  Must
    01639      * be in the interval @f$ [0, 1] @f$.
    01640      */
    01641     explicit
    01642     bernoulli_distribution(double __p = 0.5)
    01643     : _M_p(__p)
    01644     {
    01645       _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
    01646     }
    01647
    01648     /**
    01649      * Gets the @p p parameter of the distribution.
    01650      */
    01651     double
    01652     p() const
    01653     { return _M_p; }
    01654
    01655     /**
    01656      * Resets the distribution state.
    01657      *
    01658      * Does nothing for a Bernoulli distribution.
    01659      */
    01660     void
    01661     reset() { }
    01662
    01663     /**
    01664      * Gets the next value in the Bernoullian sequence.
    01665      */
    01666     template<class _UniformRandomNumberGenerator>
    01667       result_type
    01668       operator()(_UniformRandomNumberGenerator& __urng)
    01669       {
    01670     if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
    01671       return true;
    01672     return false;
    01673       }
    01674
    01675     /**
    01676      * Inserts a %bernoulli_distribution random number distribution
    01677      * @p __x into the output stream @p __os.
    01678      *
    01679      * @param __os An output stream.
    01680      * @param __x  A %bernoulli_distribution random number distribution.
    01681      *
    01682      * @returns The output stream with the state of @p __x inserted or in
    01683      * an error state.
    01684      */
    01685     template<typename _CharT, typename _Traits>
    01686       friend std::basic_ostream<_CharT, _Traits>&
    01687       operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01688          const bernoulli_distribution& __x);
    01689
    01690     /**
    01691      * Extracts a %bernoulli_distribution random number distribution
    01692      * @p __x from the input stream @p __is.
    01693      *
    01694      * @param __is An input stream.
    01695      * @param __x  A %bernoulli_distribution random number generator engine.
    01696      *
    01697      * @returns The input stream with @p __x extracted or in an error state.
    01698      */
    01699     template<typename _CharT, typename _Traits>
    01700       friend std::basic_istream<_CharT, _Traits>&
    01701       operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01702          bernoulli_distribution& __x)
    01703       { return __is >> __x._M_p; }
    01704
    01705   private:
    01706     double _M_p;
    01707   };
    01708
    01709
    01710   /**
    01711    * @brief A discrete geometric random number distribution.
    01712    *
    01713    * The formula for the geometric probability mass function is
    01714    * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
    01715    * distribution.
    01716    */
    01717   template<typename _IntType = int, typename _RealType = double>
    01718     class geometric_distribution
    01719     {
    01720     public:
    01721       // types
    01722       typedef _RealType input_type;
    01723       typedef _IntType  result_type;
    01724
    01725       // constructors and member function
    01726       explicit
    01727       geometric_distribution(const _RealType& __p = _RealType(0.5))
    01728       : _M_p(__p)
    01729       {
    01730     _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
    01731     _M_initialize();
    01732       }
    01733
    01734       /**
    01735        * Gets the distribution parameter @p p.
    01736        */
    01737       _RealType
    01738       p() const
    01739       { return _M_p; }
    01740
    01741       void
    01742       reset() { }
    01743
    01744       template<class _UniformRandomNumberGenerator>
    01745         result_type
    01746         operator()(_UniformRandomNumberGenerator& __urng);
    01747
    01748       /**
    01749        * Inserts a %geometric_distribution random number distribution
    01750        * @p __x into the output stream @p __os.
    01751        *
    01752        * @param __os An output stream.
    01753        * @param __x  A %geometric_distribution random number distribution.
    01754        *
    01755        * @returns The output stream with the state of @p __x inserted or in
    01756        * an error state.
    01757        */
    01758       template<typename _IntType1, typename _RealType1,
    01759            typename _CharT, typename _Traits>
    01760         friend std::basic_ostream<_CharT, _Traits>&
    01761         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01762            const geometric_distribution<_IntType1, _RealType1>& __x);
    01763
    01764       /**
    01765        * Extracts a %geometric_distribution random number distribution
    01766        * @p __x from the input stream @p __is.
    01767        *
    01768        * @param __is An input stream.
    01769        * @param __x  A %geometric_distribution random number generator engine.
    01770        *
    01771        * @returns The input stream with @p __x extracted or in an error state.
    01772        */
    01773       template<typename _CharT, typename _Traits>
    01774         friend std::basic_istream<_CharT, _Traits>&
    01775         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01776            geometric_distribution& __x)
    01777         {
    01778       __is >> __x._M_p;
    01779       __x._M_initialize();
    01780       return __is;
    01781     }
    01782
    01783     private:
    01784       void
    01785       _M_initialize()
    01786       { _M_log_p = std::log(_M_p); }
    01787
    01788       _RealType _M_p;
    01789       _RealType _M_log_p;
    01790     };
    01791
    01792
    01793   template<typename _RealType>
    01794     class normal_distribution;
    01795
    01796   /**
    01797    * @brief A discrete Poisson random number distribution.
    01798    *
    01799    * The formula for the Poisson probability mass function is
    01800    * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
    01801    * parameter of the distribution.
    01802    */
    01803   template<typename _IntType = int, typename _RealType = double>
    01804     class poisson_distribution
    01805     {
    01806     public:
    01807       // types
    01808       typedef _RealType input_type;
    01809       typedef _IntType  result_type;
    01810
    01811       // constructors and member function
    01812       explicit
    01813       poisson_distribution(const _RealType& __mean = _RealType(1))
    01814       : _M_mean(__mean), _M_nd()
    01815       {
    01816     _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
    01817     _M_initialize();
    01818       }
    01819
    01820       /**
    01821        * Gets the distribution parameter @p mean.
    01822        */
    01823       _RealType
    01824       mean() const
    01825       { return _M_mean; }
    01826
    01827       void
    01828       reset()
    01829       { _M_nd.reset(); }
    01830
    01831       template<class _UniformRandomNumberGenerator>
    01832         result_type
    01833         operator()(_UniformRandomNumberGenerator& __urng);
    01834
    01835       /**
    01836        * Inserts a %poisson_distribution random number distribution
    01837        * @p __x into the output stream @p __os.
    01838        *
    01839        * @param __os An output stream.
    01840        * @param __x  A %poisson_distribution random number distribution.
    01841        *
    01842        * @returns The output stream with the state of @p __x inserted or in
    01843        * an error state.
    01844        */
    01845       template<typename _IntType1, typename _RealType1,
    01846            typename _CharT, typename _Traits>
    01847         friend std::basic_ostream<_CharT, _Traits>&
    01848         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01849            const poisson_distribution<_IntType1, _RealType1>& __x);
    01850
    01851       /**
    01852        * Extracts a %poisson_distribution random number distribution
    01853        * @p __x from the input stream @p __is.
    01854        *
    01855        * @param __is An input stream.
    01856        * @param __x  A %poisson_distribution random number generator engine.
    01857        *
    01858        * @returns The input stream with @p __x extracted or in an error state.
    01859        */
    01860       template<typename _IntType1, typename _RealType1,
    01861            typename _CharT, typename _Traits>
    01862         friend std::basic_istream<_CharT, _Traits>&
    01863         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01864            poisson_distribution<_IntType1, _RealType1>& __x);
    01865
    01866     private:
    01867       void
    01868       _M_initialize();
    01869
    01870       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
    01871       normal_distribution<_RealType> _M_nd;
    01872
    01873       _RealType _M_mean;
    01874
    01875       // Hosts either log(mean) or the threshold of the simple method.
    01876       _RealType _M_lm_thr;
    01877 #if _GLIBCXX_USE_C99_MATH_TR1
    01878       _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
    01879 #endif
    01880     };
    01881
    01882
    01883   /**
    01884    * @brief A discrete binomial random number distribution.
    01885    *
    01886    * The formula for the binomial probability mass function is
    01887    * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
    01888    * and @f$ p @f$ are the parameters of the distribution.
    01889    */
    01890   template<typename _IntType = int, typename _RealType = double>
    01891     class binomial_distribution
    01892     {
    01893     public:
    01894       // types
    01895       typedef _RealType input_type;
    01896       typedef _IntType  result_type;
    01897
    01898       // constructors and member function
    01899       explicit
    01900       binomial_distribution(_IntType __t = 1,
    01901                 const _RealType& __p = _RealType(0.5))
    01902       : _M_t(__t), _M_p(__p), _M_nd()
    01903       {
    01904     _GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
    01905     _M_initialize();
    01906       }
    01907
    01908       /**
    01909        * Gets the distribution @p t parameter.
    01910        */
    01911       _IntType
    01912       t() const
    01913       { return _M_t; }
    01914
    01915       /**
    01916        * Gets the distribution @p p parameter.
    01917        */
    01918       _RealType
    01919       p() const
    01920       { return _M_p; }
    01921
    01922       void
    01923       reset()
    01924       { _M_nd.reset(); }
    01925
    01926       template<class _UniformRandomNumberGenerator>
    01927         result_type
    01928         operator()(_UniformRandomNumberGenerator& __urng);
    01929
    01930       /**
    01931        * Inserts a %binomial_distribution random number distribution
    01932        * @p __x into the output stream @p __os.
    01933        *
    01934        * @param __os An output stream.
    01935        * @param __x  A %binomial_distribution random number distribution.
    01936        *
    01937        * @returns The output stream with the state of @p __x inserted or in
    01938        * an error state.
    01939        */
    01940       template<typename _IntType1, typename _RealType1,
    01941            typename _CharT, typename _Traits>
    01942         friend std::basic_ostream<_CharT, _Traits>&
    01943         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    01944            const binomial_distribution<_IntType1, _RealType1>& __x);
    01945
    01946       /**
    01947        * Extracts a %binomial_distribution random number distribution
    01948        * @p __x from the input stream @p __is.
    01949        *
    01950        * @param __is An input stream.
    01951        * @param __x  A %binomial_distribution random number generator engine.
    01952        *
    01953        * @returns The input stream with @p __x extracted or in an error state.
    01954        */
    01955       template<typename _IntType1, typename _RealType1,
    01956            typename _CharT, typename _Traits>
    01957         friend std::basic_istream<_CharT, _Traits>&
    01958         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    01959            binomial_distribution<_IntType1, _RealType1>& __x);
    01960
    01961     private:
    01962       void
    01963       _M_initialize();
    01964
    01965       template<class _UniformRandomNumberGenerator>
    01966         result_type
    01967         _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
    01968
    01969       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
    01970       normal_distribution<_RealType> _M_nd;
    01971
    01972       _RealType _M_q;
    01973 #if _GLIBCXX_USE_C99_MATH_TR1
    01974       _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
    01975             _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
    01976 #endif
    01977       _RealType _M_p;
    01978       _IntType  _M_t;
    01979
    01980       bool      _M_easy;
    01981     };
    01982
    01983   /* @} */ // group tr1_random_distributions_discrete
    01984
    01985   /**
    01986    * @addtogroup tr1_random_distributions_continuous Continuous Distributions
    01987    * @ingroup tr1_random_distributions
    01988    * @{
    01989    */
    01990
    01991   /**
    01992    * @brief Uniform continuous distribution for random numbers.
    01993    *
    01994    * A continuous random distribution on the range [min, max) with equal
    01995    * probability throughout the range.  The URNG should be real-valued and
    01996    * deliver number in the range [0, 1).
    01997    */
    01998   template<typename _RealType = double>
    01999     class uniform_real
    02000     {
    02001     public:
    02002       // types
    02003       typedef _RealType input_type;
    02004       typedef _RealType result_type;
    02005
    02006     public:
    02007       /**
    02008        * Constructs a uniform_real object.
    02009        *
    02010        * @param __min [IN]  The lower bound of the distribution.
    02011        * @param __max [IN]  The upper bound of the distribution.
    02012        */
    02013       explicit
    02014       uniform_real(_RealType __min = _RealType(0),
    02015            _RealType __max = _RealType(1))
    02016       : _M_min(__min), _M_max(__max)
    02017       {
    02018     _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
    02019       }
    02020
    02021       result_type
    02022       min() const
    02023       { return _M_min; }
    02024
    02025       result_type
    02026       max() const
    02027       { return _M_max; }
    02028
    02029       void
    02030       reset() { }
    02031
    02032       template<class _UniformRandomNumberGenerator>
    02033         result_type
    02034         operator()(_UniformRandomNumberGenerator& __urng)
    02035         { return (__urng() * (_M_max - _M_min)) + _M_min; }
    02036
    02037       /**
    02038        * Inserts a %uniform_real random number distribution @p __x into the
    02039        * output stream @p __os.
    02040        *
    02041        * @param __os An output stream.
    02042        * @param __x  A %uniform_real random number distribution.
    02043        *
    02044        * @returns The output stream with the state of @p __x inserted or in
    02045        * an error state.
    02046        */
    02047       template<typename _RealType1, typename _CharT, typename _Traits>
    02048         friend std::basic_ostream<_CharT, _Traits>&
    02049         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    02050            const uniform_real<_RealType1>& __x);
    02051
    02052       /**
    02053        * Extracts a %uniform_real random number distribution
    02054        * @p __x from the input stream @p __is.
    02055        *
    02056        * @param __is An input stream.
    02057        * @param __x  A %uniform_real random number generator engine.
    02058        *
    02059        * @returns The input stream with @p __x extracted or in an error state.
    02060        */
    02061       template<typename _RealType1, typename _CharT, typename _Traits>
    02062         friend std::basic_istream<_CharT, _Traits>&
    02063         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    02064            uniform_real<_RealType1>& __x);
    02065
    02066     private:
    02067       _RealType _M_min;
    02068       _RealType _M_max;
    02069     };
    02070
    02071
    02072   /**
    02073    * @brief An exponential continuous distribution for random numbers.
    02074    *
    02075    * The formula for the exponential probability mass function is
    02076    * @f$ p(x) = \lambda e^{-\lambda x} @f$.
    02077    *
    02078    * <table border=1 cellpadding=10 cellspacing=0>
    02079    * <caption align=top>Distribution Statistics</caption>
    02080    * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
    02081    * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
    02082    * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
    02083    * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
    02084    * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
    02085    * </table>
    02086    */
    02087   template<typename _RealType = double>
    02088     class exponential_distribution
    02089     {
    02090     public:
    02091       // types
    02092       typedef _RealType input_type;
    02093       typedef _RealType result_type;
    02094
    02095     public:
    02096       /**
    02097        * Constructs an exponential distribution with inverse scale parameter
    02098        * @f$ \lambda @f$.
    02099        */
    02100       explicit
    02101       exponential_distribution(const result_type& __lambda = result_type(1))
    02102       : _M_lambda(__lambda)
    02103       {
    02104     _GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
    02105       }
    02106
    02107       /**
    02108        * Gets the inverse scale parameter of the distribution.
    02109        */
    02110       _RealType
    02111       lambda() const
    02112       { return _M_lambda; }
    02113
    02114       /**
    02115        * Resets the distribution.
    02116        *
    02117        * Has no effect on exponential distributions.
    02118        */
    02119       void
    02120       reset() { }
    02121
    02122       template<class _UniformRandomNumberGenerator>
    02123         result_type
    02124         operator()(_UniformRandomNumberGenerator& __urng)
    02125         { return -std::log(__urng()) / _M_lambda; }
    02126
    02127       /**
    02128        * Inserts a %exponential_distribution random number distribution
    02129        * @p __x into the output stream @p __os.
    02130        *
    02131        * @param __os An output stream.
    02132        * @param __x  A %exponential_distribution random number distribution.
    02133        *
    02134        * @returns The output stream with the state of @p __x inserted or in
    02135        * an error state.
    02136        */
    02137       template<typename _RealType1, typename _CharT, typename _Traits>
    02138         friend std::basic_ostream<_CharT, _Traits>&
    02139         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    02140            const exponential_distribution<_RealType1>& __x);
    02141
    02142       /**
    02143        * Extracts a %exponential_distribution random number distribution
    02144        * @p __x from the input stream @p __is.
    02145        *
    02146        * @param __is An input stream.
    02147        * @param __x A %exponential_distribution random number
    02148        *            generator engine.
    02149        *
    02150        * @returns The input stream with @p __x extracted or in an error state.
    02151        */
    02152       template<typename _CharT, typename _Traits>
    02153         friend std::basic_istream<_CharT, _Traits>&
    02154         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    02155            exponential_distribution& __x)
    02156         { return __is >> __x._M_lambda; }
    02157
    02158     private:
    02159       result_type _M_lambda;
    02160     };
    02161
    02162
    02163   /**
    02164    * @brief A normal continuous distribution for random numbers.
    02165    *
    02166    * The formula for the normal probability mass function is
    02167    * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}}
    02168    *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
    02169    */
    02170   template<typename _RealType = double>
    02171     class normal_distribution
    02172     {
    02173     public:
    02174       // types
    02175       typedef _RealType input_type;
    02176       typedef _RealType result_type;
    02177
    02178     public:
    02179       /**
    02180        * Constructs a normal distribution with parameters @f$ mean @f$ and
    02181        * @f$ \sigma @f$.
    02182        */
    02183       explicit
    02184       normal_distribution(const result_type& __mean = result_type(0),
    02185               const result_type& __sigma = result_type(1))
    02186       : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
    02187       {
    02188     _GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
    02189       }
    02190
    02191       /**
    02192        * Gets the mean of the distribution.
    02193        */
    02194       _RealType
    02195       mean() const
    02196       { return _M_mean; }
    02197
    02198       /**
    02199        * Gets the @f$ \sigma @f$ of the distribution.
    02200        */
    02201       _RealType
    02202       sigma() const
    02203       { return _M_sigma; }
    02204
    02205       /**
    02206        * Resets the distribution.
    02207        */
    02208       void
    02209       reset()
    02210       { _M_saved_available = false; }
    02211
    02212       template<class _UniformRandomNumberGenerator>
    02213         result_type
    02214         operator()(_UniformRandomNumberGenerator& __urng);
    02215
    02216       /**
    02217        * Inserts a %normal_distribution random number distribution
    02218        * @p __x into the output stream @p __os.
    02219        *
    02220        * @param __os An output stream.
    02221        * @param __x  A %normal_distribution random number distribution.
    02222        *
    02223        * @returns The output stream with the state of @p __x inserted or in
    02224        * an error state.
    02225        */
    02226       template<typename _RealType1, typename _CharT, typename _Traits>
    02227         friend std::basic_ostream<_CharT, _Traits>&
    02228         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    02229            const normal_distribution<_RealType1>& __x);
    02230
    02231       /**
    02232        * Extracts a %normal_distribution random number distribution
    02233        * @p __x from the input stream @p __is.
    02234        *
    02235        * @param __is An input stream.
    02236        * @param __x  A %normal_distribution random number generator engine.
    02237        *
    02238        * @returns The input stream with @p __x extracted or in an error state.
    02239        */
    02240       template<typename _RealType1, typename _CharT, typename _Traits>
    02241         friend std::basic_istream<_CharT, _Traits>&
    02242         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    02243            normal_distribution<_RealType1>& __x);
    02244
    02245     private:
    02246       result_type _M_mean;
    02247       result_type _M_sigma;
    02248       result_type _M_saved;
    02249       bool        _M_saved_available;
    02250     };
    02251
    02252
    02253   /**
    02254    * @brief A gamma continuous distribution for random numbers.
    02255    *
    02256    * The formula for the gamma probability mass function is
    02257    * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
    02258    */
    02259   template<typename _RealType = double>
    02260     class gamma_distribution
    02261     {
    02262     public:
    02263       // types
    02264       typedef _RealType input_type;
    02265       typedef _RealType result_type;
    02266
    02267     public:
    02268       /**
    02269        * Constructs a gamma distribution with parameters @f$ \alpha @f$.
    02270        */
    02271       explicit
    02272       gamma_distribution(const result_type& __alpha_val = result_type(1))
    02273       : _M_alpha(__alpha_val)
    02274       {
    02275     _GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
    02276     _M_initialize();
    02277       }
    02278
    02279       /**
    02280        * Gets the @f$ \alpha @f$ of the distribution.
    02281        */
    02282       _RealType
    02283       alpha() const
    02284       { return _M_alpha; }
    02285
    02286       /**
    02287        * Resets the distribution.
    02288        */
    02289       void
    02290       reset() { }
    02291
    02292       template<class _UniformRandomNumberGenerator>
    02293         result_type
    02294         operator()(_UniformRandomNumberGenerator& __urng);
    02295
    02296       /**
    02297        * Inserts a %gamma_distribution random number distribution
    02298        * @p __x into the output stream @p __os.
    02299        *
    02300        * @param __os An output stream.
    02301        * @param __x  A %gamma_distribution random number distribution.
    02302        *
    02303        * @returns The output stream with the state of @p __x inserted or in
    02304        * an error state.
    02305        */
    02306       template<typename _RealType1, typename _CharT, typename _Traits>
    02307         friend std::basic_ostream<_CharT, _Traits>&
    02308         operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    02309            const gamma_distribution<_RealType1>& __x);
    02310
    02311       /**
    02312        * Extracts a %gamma_distribution random number distribution
    02313        * @p __x from the input stream @p __is.
    02314        *
    02315        * @param __is An input stream.
    02316        * @param __x  A %gamma_distribution random number generator engine.
    02317        *
    02318        * @returns The input stream with @p __x extracted or in an error state.
    02319        */
    02320       template<typename _CharT, typename _Traits>
    02321         friend std::basic_istream<_CharT, _Traits>&
    02322         operator>>(std::basic_istream<_CharT, _Traits>& __is,
    02323            gamma_distribution& __x)
    02324         {
    02325       __is >> __x._M_alpha;
    02326       __x._M_initialize();
    02327       return __is;
    02328     }
    02329
    02330     private:
    02331       void
    02332       _M_initialize();
    02333
    02334       result_type _M_alpha;
    02335
    02336       // Hosts either lambda of GB or d of modified Vaduva's.
    02337       result_type _M_l_d;
    02338     };
    02339
    02340   /* @} */ // group tr1_random_distributions_continuous
    02341   /* @} */ // group tr1_random_distributions
    02342   /* @} */ // group tr1_random
    02343
    02344 _GLIBCXX_END_NAMESPACE_TR1
    02345 }
    02346
    02347 #include <tr1_impl/random.tcc>