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>

Generated on Wed Mar 26 00:43:05 2008 for libstdc++ by  doxygen 1.5.1