1169691Skan// random number generation -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the
7169691Skan// terms of the GNU General Public License as published by the
8169691Skan// Free Software Foundation; either version 2, or (at your option)
9169691Skan// any later version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful,
12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169691Skan// GNU General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License along
17169691Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19169691Skan// USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free software
22169691Skan// library without restriction.  Specifically, if other files instantiate
23169691Skan// templates or use macros or inline functions from this file, or you compile
24169691Skan// this file and link it with other files to produce an executable, this
25169691Skan// file does not by itself cause the resulting executable to be covered by
26169691Skan// the GNU General Public License.  This exception does not however
27169691Skan// invalidate any other reasons why the executable file might be covered by
28169691Skan// the GNU General Public License.
29169691Skan
30169691Skan/**
31169691Skan * @file tr1/random
32169691Skan * This is a TR1 C++ Library header. 
33169691Skan */
34169691Skan
35169691Skan#ifndef _TR1_RANDOM
36169691Skan#define _TR1_RANDOM 1
37169691Skan
38169691Skan#include <cmath>
39169691Skan#include <cstdio>
40169691Skan#include <string>
41169691Skan#include <iosfwd>
42169691Skan#include <limits>
43169691Skan#include <tr1/type_traits>
44169691Skan#include <tr1/cmath>
45169691Skan#include <ext/type_traits.h>
46169691Skan#include <ext/numeric_traits.h>
47169691Skan#include <bits/concept_check.h>
48169691Skan#include <debug/debug.h>
49169691Skan
50169691Skannamespace std
51169691Skan{
52169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1)
53169691Skan
54169691Skan  // [5.1] Random number generation
55169691Skan
56169691Skan  /**
57169691Skan   * @addtogroup tr1_random Random Number Generation
58169691Skan   * A facility for generating random numbers on selected distributions.
59169691Skan   * @{
60169691Skan   */
61169691Skan
62169691Skan  /*
63169691Skan   * Implementation-space details.
64169691Skan   */
65169691Skan  namespace __detail
66169691Skan  {
67169691Skan    template<typename _UIntType, int __w, 
68169691Skan	     bool = __w < std::numeric_limits<_UIntType>::digits>
69169691Skan      struct _Shift
70169691Skan      { static const _UIntType __value = 0; };
71169691Skan
72169691Skan    template<typename _UIntType, int __w>
73169691Skan      struct _Shift<_UIntType, __w, true>
74169691Skan      { static const _UIntType __value = _UIntType(1) << __w; };
75169691Skan
76169691Skan    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
77169691Skan      struct _Mod;
78169691Skan
79169691Skan    // Dispatch based on modulus value to prevent divide-by-zero compile-time
80169691Skan    // errors when m == 0.
81169691Skan    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
82169691Skan      inline _Tp
83169691Skan      __mod(_Tp __x)
84169691Skan      { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
85169691Skan
86169691Skan    typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
87169691Skan		    unsigned, unsigned long>::__type _UInt32Type;
88169691Skan
89169691Skan    /*
90169691Skan     * An adaptor class for converting the output of any Generator into
91169691Skan     * the input for a specific Distribution.
92169691Skan     */
93169691Skan    template<typename _Engine, typename _Distribution>
94169691Skan      struct _Adaptor
95169691Skan      { 
96169691Skan	typedef typename _Engine::result_type        _Engine_result_type;
97169691Skan	typedef typename _Distribution::input_type   result_type;
98169691Skan
99169691Skan      public:
100169691Skan	_Adaptor(const _Engine& __g)
101169691Skan	: _M_g(__g) { }
102169691Skan
103169691Skan	result_type
104169691Skan	min() const
105169691Skan	{
106169691Skan	  result_type __return_value = 0;
107169691Skan	  if (is_integral<_Engine_result_type>::value
108169691Skan	      && is_integral<result_type>::value)
109169691Skan	    __return_value = _M_g.min();
110169691Skan	  else if (!is_integral<result_type>::value)
111169691Skan	    __return_value = result_type(0);
112169691Skan	  return __return_value;
113169691Skan	}
114169691Skan
115169691Skan	result_type
116169691Skan	max() const
117169691Skan	{
118169691Skan	  result_type __return_value = 0;
119169691Skan	  if (is_integral<_Engine_result_type>::value
120169691Skan	      && is_integral<result_type>::value)
121169691Skan	    __return_value = _M_g.max();
122169691Skan	  else if (!is_integral<result_type>::value)
123169691Skan	    __return_value = result_type(1);
124169691Skan	  return __return_value;
125169691Skan	}
126169691Skan
127169691Skan	result_type
128169691Skan	operator()();
129169691Skan
130169691Skan      private:
131169691Skan	_Engine _M_g;
132169691Skan      };
133169691Skan
134169691Skan    /*
135169691Skan     * Converts a value generated by the adapted random number generator into a
136169691Skan     * value in the input domain for the dependent random number distribution.
137169691Skan     *
138169691Skan     * Because the type traits are compile time constants only the appropriate
139169691Skan     * clause of the if statements will actually be emitted by the compiler.
140169691Skan     */
141169691Skan    template<typename _Engine, typename _Distribution>
142169691Skan      typename _Adaptor<_Engine, _Distribution>::result_type
143169691Skan      _Adaptor<_Engine, _Distribution>::
144169691Skan      operator()()
145169691Skan      {
146169691Skan	result_type __return_value = 0;
147169691Skan	if (is_integral<_Engine_result_type>::value
148169691Skan	    && is_integral<result_type>::value)
149169691Skan	  __return_value = _M_g();
150169691Skan      	else if (is_integral<_Engine_result_type>::value
151169691Skan		 && !is_integral<result_type>::value)
152169691Skan	  __return_value = result_type(_M_g() - _M_g.min())
153169691Skan	    / result_type(_M_g.max() - _M_g.min() + result_type(1));
154169691Skan	else if (!is_integral<_Engine_result_type>::value
155169691Skan		 && !is_integral<result_type>::value)
156169691Skan	  __return_value = result_type(_M_g() - _M_g.min())
157169691Skan	    / result_type(_M_g.max() - _M_g.min());
158169691Skan      	return __return_value;
159169691Skan      }
160169691Skan  } // namespace __detail
161169691Skan
162169691Skan  /**
163169691Skan   * Produces random numbers on a given disribution function using a un uniform
164169691Skan   * random number generation engine.
165169691Skan   *
166169691Skan   * @todo the engine_value_type needs to be studied more carefully.
167169691Skan   */
168169691Skan  template<typename _Engine, typename _Dist>
169169691Skan    class variate_generator
170169691Skan    {
171169691Skan      // Concept requirements.
172169691Skan      __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
173169691Skan      //  __glibcxx_class_requires(_Engine, _EngineConcept)
174169691Skan      //  __glibcxx_class_requires(_Dist, _EngineConcept)
175169691Skan
176169691Skan    public:
177169691Skan      typedef _Engine                                engine_type;
178169691Skan      typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
179169691Skan      typedef _Dist                                  distribution_type;
180169691Skan      typedef typename _Dist::result_type            result_type;
181169691Skan
182169691Skan      // tr1:5.1.1 table 5.1 requirement
183169691Skan      typedef typename __gnu_cxx::__enable_if<
184169691Skan	is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
185169691Skan
186169691Skan      /**
187169691Skan       * Constructs a variate generator with the uniform random number
188169691Skan       * generator @p __eng for the random distribution @p __dist.
189169691Skan       *
190169691Skan       * @throws Any exceptions which may thrown by the copy constructors of
191169691Skan       * the @p _Engine or @p _Dist objects.
192169691Skan       */
193169691Skan      variate_generator(engine_type __eng, distribution_type __dist)
194169691Skan      : _M_engine(__eng), _M_dist(__dist) { }
195169691Skan
196169691Skan      /**
197169691Skan       * Gets the next generated value on the distribution.
198169691Skan       */
199169691Skan      result_type
200169691Skan      operator()()
201169691Skan      { return _M_dist(_M_engine); }
202169691Skan
203169691Skan      /**
204169691Skan       * WTF?
205169691Skan       */
206169691Skan      template<typename _Tp>
207169691Skan        result_type
208169691Skan        operator()(_Tp __value)
209169691Skan        { return _M_dist(_M_engine, __value); }
210169691Skan
211169691Skan      /**
212169691Skan       * Gets a reference to the underlying uniform random number generator
213169691Skan       * object.
214169691Skan       */
215169691Skan      engine_value_type&
216169691Skan      engine()
217169691Skan      { return _M_engine; }
218169691Skan
219169691Skan      /**
220169691Skan       * Gets a const reference to the underlying uniform random number
221169691Skan       * generator object.
222169691Skan       */
223169691Skan      const engine_value_type&
224169691Skan      engine() const
225169691Skan      { return _M_engine; }
226169691Skan
227169691Skan      /**
228169691Skan       * Gets a reference to the underlying random distribution.
229169691Skan       */
230169691Skan      distribution_type&
231169691Skan      distribution()
232169691Skan      { return _M_dist; }
233169691Skan
234169691Skan      /**
235169691Skan       * Gets a const reference to the underlying random distribution.
236169691Skan       */
237169691Skan      const distribution_type&
238169691Skan      distribution() const
239169691Skan      { return _M_dist; }
240169691Skan
241169691Skan      /**
242169691Skan       * Gets the closed lower bound of the distribution interval.
243169691Skan       */
244169691Skan      result_type
245169691Skan      min() const
246169691Skan      { return this->distribution().min(); }
247169691Skan
248169691Skan      /**
249169691Skan       * Gets the closed upper bound of the distribution interval.
250169691Skan       */
251169691Skan      result_type
252169691Skan      max() const
253169691Skan      { return this->distribution().max(); }
254169691Skan
255169691Skan    private:
256169691Skan      engine_value_type _M_engine;
257169691Skan      distribution_type _M_dist;
258169691Skan    };
259169691Skan
260169691Skan
261169691Skan  /**
262169691Skan   * @addtogroup tr1_random_generators Random Number Generators
263169691Skan   * @ingroup tr1_random
264169691Skan   *
265169691Skan   * These classes define objects which provide random or pseudorandom
266169691Skan   * numbers, either from a discrete or a continuous interval.  The
267169691Skan   * random number generator supplied as a part of this library are
268169691Skan   * all uniform random number generators which provide a sequence of
269169691Skan   * random number uniformly distributed over their range.
270169691Skan   *
271169691Skan   * A number generator is a function object with an operator() that
272169691Skan   * takes zero arguments and returns a number.
273169691Skan   *
274169691Skan   * A compliant random number generator must satisy the following
275169691Skan   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
276169691Skan   * <caption align=top>Random Number Generator Requirements</caption>
277169691Skan   * <tr><td>To be documented.</td></tr> </table>
278169691Skan   * 
279169691Skan   * @{
280169691Skan   */
281169691Skan
282169691Skan  /**
283169691Skan   * @brief A model of a linear congruential random number generator.
284169691Skan   *
285169691Skan   * A random number generator that produces pseudorandom numbers using the
286169691Skan   * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
287169691Skan   *
288169691Skan   * The template parameter @p _UIntType must be an unsigned integral type
289169691Skan   * large enough to store values up to (__m-1). If the template parameter
290169691Skan   * @p __m is 0, the modulus @p __m used is
291169691Skan   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
292169691Skan   * parameters @p __a and @p __c must be less than @p __m.
293169691Skan   *
294169691Skan   * The size of the state is @f$ 1 @f$.
295169691Skan   */
296169691Skan  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
297169691Skan    class linear_congruential
298169691Skan    {
299169691Skan      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
300169691Skan      //  __glibcpp_class_requires(__a < __m && __c < __m)
301169691Skan
302169691Skan    public:
303169691Skan      /** The type of the generated random value. */
304169691Skan      typedef _UIntType result_type;
305169691Skan
306169691Skan      /** The multiplier. */
307169691Skan      static const _UIntType multiplier = __a;
308169691Skan      /** An increment. */
309169691Skan      static const _UIntType increment = __c;
310169691Skan      /** The modulus. */
311169691Skan      static const _UIntType modulus = __m;
312169691Skan
313169691Skan      /**
314169691Skan       * Constructs a %linear_congruential random number generator engine with
315169691Skan       * seed @p __s.  The default seed value is 1.
316169691Skan       *
317169691Skan       * @param __s The initial seed value.
318169691Skan       */
319169691Skan      explicit
320169691Skan      linear_congruential(unsigned long __x0 = 1)
321169691Skan      { this->seed(__x0); }
322169691Skan
323169691Skan      /**
324169691Skan       * Constructs a %linear_congruential random number generator engine
325169691Skan       * seeded from the generator function @p __g.
326169691Skan       *
327169691Skan       * @param __g The seed generator function.
328169691Skan       */
329169691Skan      template<class _Gen>
330169691Skan        linear_congruential(_Gen& __g)
331169691Skan        { this->seed(__g); }
332169691Skan
333169691Skan      /**
334169691Skan       * Reseeds the %linear_congruential random number generator engine
335169691Skan       * sequence to the seed @g __s.
336169691Skan       *
337169691Skan       * @param __s The new seed.
338169691Skan       */
339169691Skan      void
340169691Skan      seed(unsigned long __s = 1);
341169691Skan
342169691Skan      /**
343169691Skan       * Reseeds the %linear_congruential random number generator engine
344169691Skan       * sequence using values from the generator function @p __g.
345169691Skan       *
346169691Skan       * @param __g the seed generator function.
347169691Skan       */
348169691Skan      template<class _Gen>
349169691Skan        void
350169691Skan        seed(_Gen& __g)
351169691Skan        { seed(__g, typename is_fundamental<_Gen>::type()); }
352169691Skan
353169691Skan      /**
354169691Skan       * Gets the smallest possible value in the output range.
355169691Skan       *
356169691Skan       * The minumum depends on the @p __c parameter: if it is zero, the
357169691Skan       * minimum generated must be > 0, otherwise 0 is allowed.
358169691Skan       */
359169691Skan      result_type
360169691Skan      min() const
361169691Skan      { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
362169691Skan
363169691Skan      /**
364169691Skan       * Gets the largest possible value in the output range.
365169691Skan       */
366169691Skan      result_type
367169691Skan      max() const
368169691Skan      { return __m - 1; }
369169691Skan
370169691Skan      /**
371169691Skan       * Gets the next random number in the sequence.
372169691Skan       */
373169691Skan      result_type
374169691Skan      operator()();
375169691Skan
376169691Skan      /**
377169691Skan       * Compares two linear congruential random number generator
378169691Skan       * objects of the same type for equality.
379169691Skan       *  
380169691Skan       * @param __lhs A linear congruential random number generator object.
381169691Skan       * @param __rhs Another linear congruential random number generator obj.
382169691Skan       *
383169691Skan       * @returns true if the two objects are equal, false otherwise.
384169691Skan       */
385169691Skan      friend bool
386169691Skan      operator==(const linear_congruential& __lhs,
387169691Skan		 const linear_congruential& __rhs)
388169691Skan      { return __lhs._M_x == __rhs._M_x; }
389169691Skan
390169691Skan      /**
391169691Skan       * Compares two linear congruential random number generator
392169691Skan       * objects of the same type for inequality.
393169691Skan       *
394169691Skan       * @param __lhs A linear congruential random number generator object.
395169691Skan       * @param __rhs Another linear congruential random number generator obj.
396169691Skan       *
397169691Skan       * @returns true if the two objects are not equal, false otherwise.
398169691Skan       */
399169691Skan      friend bool
400169691Skan      operator!=(const linear_congruential& __lhs,
401169691Skan		 const linear_congruential& __rhs)
402169691Skan      { return !(__lhs == __rhs); }
403169691Skan
404169691Skan      /**
405169691Skan       * Writes the textual representation of the state x(i) of x to @p __os.
406169691Skan       *
407169691Skan       * @param __os  The output stream.
408169691Skan       * @param __lcr A % linear_congruential random number generator.
409169691Skan       * @returns __os.
410169691Skan       */
411169691Skan      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
412169691Skan	       _UIntType1 __m1,
413169691Skan	       typename _CharT, typename _Traits>
414169691Skan        friend std::basic_ostream<_CharT, _Traits>&
415169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
416169691Skan		   const linear_congruential<_UIntType1, __a1, __c1,
417169691Skan		   __m1>& __lcr);
418169691Skan
419169691Skan      /**
420169691Skan       * Sets the state of the engine by reading its textual
421169691Skan       * representation from @p __is.
422169691Skan       *
423169691Skan       * The textual representation must have been previously written using an
424169691Skan       * output stream whose imbued locale and whose type's template
425169691Skan       * specialization arguments _CharT and _Traits were the same as those of
426169691Skan       * @p __is.
427169691Skan       *
428169691Skan       * @param __is  The input stream.
429169691Skan       * @param __lcr A % linear_congruential random number generator.
430169691Skan       * @returns __is.
431169691Skan       */
432169691Skan      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
433169691Skan	       _UIntType1 __m1,
434169691Skan	       typename _CharT, typename _Traits>
435169691Skan        friend std::basic_istream<_CharT, _Traits>&
436169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
437169691Skan		   linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
438169691Skan
439169691Skan    private:
440169691Skan      template<class _Gen>
441169691Skan        void
442169691Skan        seed(_Gen& __g, true_type)
443169691Skan        { return seed(static_cast<unsigned long>(__g)); }
444169691Skan
445169691Skan      template<class _Gen>
446169691Skan        void
447169691Skan        seed(_Gen& __g, false_type);
448169691Skan
449169691Skan      _UIntType _M_x;
450169691Skan    };
451169691Skan
452169691Skan  /**
453169691Skan   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
454169691Skan   */
455169691Skan  typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
456169691Skan
457169691Skan  /**
458169691Skan   * An alternative LCR (Lehmer Generator function) .
459169691Skan   */
460169691Skan  typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
461169691Skan
462169691Skan
463169691Skan  /**
464169691Skan   * A generalized feedback shift register discrete random number generator.
465169691Skan   *
466169691Skan   * This algorithm avoind multiplication and division and is designed to be
467169691Skan   * friendly to a pipelined architecture.  If the parameters are chosen
468169691Skan   * correctly, this generator will produce numbers with a very long period and
469169691Skan   * fairly good apparent entropy, although still not cryptographically strong.
470169691Skan   *
471169691Skan   * The best way to use this generator is with the predefined mt19937 class.
472169691Skan   *
473169691Skan   * This algorithm was originally invented by Makoto Matsumoto and
474169691Skan   * Takuji Nishimura.
475169691Skan   *
476169691Skan   * @var word_size   The number of bits in each element of the state vector.
477169691Skan   * @var state_size  The degree of recursion.
478169691Skan   * @var shift_size  The period parameter.
479169691Skan   * @var mask_bits   The separation point bit index.
480169691Skan   * @var parameter_a The last row of the twist matrix.
481169691Skan   * @var output_u    The first right-shift tempering matrix parameter.
482169691Skan   * @var output_s    The first left-shift tempering matrix parameter.
483169691Skan   * @var output_b    The first left-shift tempering matrix mask.
484169691Skan   * @var output_t    The second left-shift tempering matrix parameter.
485169691Skan   * @var output_c    The second left-shift tempering matrix mask.
486169691Skan   * @var output_l    The second right-shift tempering matrix parameter.
487169691Skan   */
488169691Skan  template<class _UIntType, int __w, int __n, int __m, int __r,
489169691Skan	   _UIntType __a, int __u, int __s, _UIntType __b, int __t,
490169691Skan	   _UIntType __c, int __l>
491169691Skan    class mersenne_twister
492169691Skan    {
493169691Skan      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
494169691Skan
495169691Skan    public:
496169691Skan      // types
497169691Skan      typedef _UIntType result_type;
498169691Skan
499169691Skan      // parameter values
500169691Skan      static const int       word_size   = __w;
501169691Skan      static const int       state_size  = __n;
502169691Skan      static const int       shift_size  = __m;
503169691Skan      static const int       mask_bits   = __r;
504169691Skan      static const _UIntType parameter_a = __a;
505169691Skan      static const int       output_u    = __u;
506169691Skan      static const int       output_s    = __s;
507169691Skan      static const _UIntType output_b    = __b;
508169691Skan      static const int       output_t    = __t;
509169691Skan      static const _UIntType output_c    = __c;
510169691Skan      static const int       output_l    = __l;
511169691Skan
512169691Skan      // constructors and member function
513169691Skan      mersenne_twister()
514169691Skan      { seed(); }
515169691Skan
516169691Skan      explicit
517169691Skan      mersenne_twister(unsigned long __value)
518169691Skan      { seed(__value); }
519169691Skan
520169691Skan      template<class _Gen>
521169691Skan        mersenne_twister(_Gen& __g)
522169691Skan        { seed(__g); }
523169691Skan
524169691Skan      void
525169691Skan      seed()
526169691Skan      { seed(5489UL); }
527169691Skan
528169691Skan      void
529169691Skan      seed(unsigned long __value);
530169691Skan
531169691Skan      template<class _Gen>
532169691Skan        void
533169691Skan        seed(_Gen& __g)
534169691Skan        { seed(__g, typename is_fundamental<_Gen>::type()); }
535169691Skan
536169691Skan      result_type
537169691Skan      min() const
538169691Skan      { return 0; };
539169691Skan
540169691Skan      result_type
541169691Skan      max() const
542169691Skan      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
543169691Skan
544169691Skan      result_type
545169691Skan      operator()();
546169691Skan
547169691Skan      /**
548169691Skan       * Compares two % mersenne_twister random number generator objects of
549169691Skan       * the same type for equality.
550169691Skan       *
551169691Skan       * @param __lhs A % mersenne_twister random number generator object.
552169691Skan       * @param __rhs Another % mersenne_twister random number generator
553169691Skan       *              object.
554169691Skan       *
555169691Skan       * @returns true if the two objects are equal, false otherwise.
556169691Skan       */
557169691Skan      friend bool
558169691Skan      operator==(const mersenne_twister& __lhs,
559169691Skan		 const mersenne_twister& __rhs)
560169691Skan      { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
561169691Skan
562169691Skan      /**
563169691Skan       * Compares two % mersenne_twister random number generator objects of
564169691Skan       * the same type for inequality.
565169691Skan       *
566169691Skan       * @param __lhs A % mersenne_twister random number generator object.
567169691Skan       * @param __rhs Another % mersenne_twister random number generator
568169691Skan       *              object.
569169691Skan       *
570169691Skan       * @returns true if the two objects are not equal, false otherwise.
571169691Skan       */
572169691Skan      friend bool
573169691Skan      operator!=(const mersenne_twister& __lhs,
574169691Skan		 const mersenne_twister& __rhs)
575169691Skan      { return !(__lhs == __rhs); }
576169691Skan
577169691Skan      /**
578169691Skan       * Inserts the current state of a % mersenne_twister random number
579169691Skan       * generator engine @p __x into the output stream @p __os.
580169691Skan       *
581169691Skan       * @param __os An output stream.
582169691Skan       * @param __x  A % mersenne_twister random number generator engine.
583169691Skan       *
584169691Skan       * @returns The output stream with the state of @p __x inserted or in
585169691Skan       * an error state.
586169691Skan       */
587169691Skan      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
588169691Skan	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
589169691Skan	       _UIntType1 __c1, int __l1,
590169691Skan	       typename _CharT, typename _Traits>
591169691Skan        friend std::basic_ostream<_CharT, _Traits>&
592169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
593169691Skan		   const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
594169691Skan		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
595169691Skan
596169691Skan      /**
597169691Skan       * Extracts the current state of a % mersenne_twister random number
598169691Skan       * generator engine @p __x from the input stream @p __is.
599169691Skan       *
600169691Skan       * @param __is An input stream.
601169691Skan       * @param __x  A % mersenne_twister random number generator engine.
602169691Skan       *
603169691Skan       * @returns The input stream with the state of @p __x extracted or in
604169691Skan       * an error state.
605169691Skan       */
606169691Skan      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
607169691Skan	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
608169691Skan	       _UIntType1 __c1, int __l1,
609169691Skan	       typename _CharT, typename _Traits>
610169691Skan        friend std::basic_istream<_CharT, _Traits>&
611169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
612169691Skan		   mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
613169691Skan		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
614169691Skan
615169691Skan    private:
616169691Skan      template<class _Gen>
617169691Skan        void
618169691Skan        seed(_Gen& __g, true_type)
619169691Skan        { return seed(static_cast<unsigned long>(__g)); }
620169691Skan
621169691Skan      template<class _Gen>
622169691Skan        void
623169691Skan        seed(_Gen& __g, false_type);
624169691Skan
625169691Skan      _UIntType _M_x[state_size];
626169691Skan      int       _M_p;
627169691Skan    };
628169691Skan
629169691Skan  /**
630169691Skan   * The classic Mersenne Twister.
631169691Skan   *
632169691Skan   * Reference:
633169691Skan   * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
634169691Skan   * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
635169691Skan   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
636169691Skan   */
637169691Skan  typedef mersenne_twister<
638169691Skan    unsigned long, 32, 624, 397, 31,
639169691Skan    0x9908b0dful, 11, 7,
640169691Skan    0x9d2c5680ul, 15,
641169691Skan    0xefc60000ul, 18
642169691Skan    > mt19937;
643169691Skan
644169691Skan
645169691Skan  /**
646169691Skan   * @brief The Marsaglia-Zaman generator.
647169691Skan   * 
648169691Skan   * This is a model of a Generalized Fibonacci discrete random number
649169691Skan   * generator, sometimes referred to as the SWC generator.
650169691Skan   *
651169691Skan   * A discrete random number generator that produces pseudorandom
652169691Skan   * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
653169691Skan   * carry_{i-1}) \bmod m @f$.
654169691Skan   *
655169691Skan   * The size of the state is @f$ r @f$
656169691Skan   * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
657169691Skan   *
658169691Skan   * N1688[4.13] says "the template parameter _IntType shall denote an integral
659169691Skan   * type large enough to store values up to m."
660169691Skan   *
661169691Skan   * @if maint
662169691Skan   * @var _M_x     The state of the generator.  This is a ring buffer.
663169691Skan   * @var _M_carry The carry.
664169691Skan   * @var _M_p     Current index of x(i - r).
665169691Skan   * @endif
666169691Skan   */
667169691Skan  template<typename _IntType, _IntType __m, int __s, int __r>
668169691Skan    class subtract_with_carry
669169691Skan    {
670169691Skan      __glibcxx_class_requires(_IntType, _IntegerConcept)
671169691Skan
672169691Skan    public:
673169691Skan      /** The type of the generated random value. */
674169691Skan      typedef _IntType result_type;
675169691Skan      
676169691Skan      // parameter values
677169691Skan      static const _IntType modulus   = __m;
678169691Skan      static const int      long_lag  = __r;
679169691Skan      static const int      short_lag = __s;
680169691Skan
681169691Skan      /**
682169691Skan       * Constructs a default-initialized % subtract_with_carry random number
683169691Skan       * generator.
684169691Skan       */
685169691Skan      subtract_with_carry()
686169691Skan      { this->seed(); }
687169691Skan
688169691Skan      /**
689169691Skan       * Constructs an explicitly seeded % subtract_with_carry random number
690169691Skan       * generator.
691169691Skan       */
692169691Skan      explicit
693169691Skan      subtract_with_carry(unsigned long __value)
694169691Skan      { this->seed(__value); }
695169691Skan
696169691Skan      /**
697169691Skan       * Constructs a %subtract_with_carry random number generator engine
698169691Skan       * seeded from the generator function @p __g.
699169691Skan       *
700169691Skan       * @param __g The seed generator function.
701169691Skan       */
702169691Skan      template<class _Gen>
703169691Skan        subtract_with_carry(_Gen& __g)
704169691Skan        { this->seed(__g); }
705169691Skan
706169691Skan      /**
707169691Skan       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
708169691Skan       *
709169691Skan       * N1688[4.19] modifies this as follows.  If @p __value == 0,
710169691Skan       * sets value to 19780503.  In any case, with a linear
711169691Skan       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
712169691Skan       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
713169691Skan       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
714169691Skan       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
715169691Skan       * set carry to 1, otherwise sets carry to 0.
716169691Skan       */
717169691Skan      void
718169691Skan      seed(unsigned long __value = 19780503);
719169691Skan
720169691Skan      /**
721169691Skan       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
722169691Skan       * random number generator.
723169691Skan       */
724169691Skan      template<class _Gen>
725169691Skan        void
726169691Skan        seed(_Gen& __g)
727169691Skan        { seed(__g, typename is_fundamental<_Gen>::type()); }
728169691Skan
729169691Skan      /**
730169691Skan       * Gets the inclusive minimum value of the range of random integers
731169691Skan       * returned by this generator.
732169691Skan       */
733169691Skan      result_type
734169691Skan      min() const
735169691Skan      { return 0; }
736169691Skan
737169691Skan      /**
738169691Skan       * Gets the inclusive maximum value of the range of random integers
739169691Skan       * returned by this generator.
740169691Skan       */
741169691Skan      result_type
742169691Skan      max() const
743169691Skan      { return this->modulus - 1; }
744169691Skan
745169691Skan      /**
746169691Skan       * Gets the next random number in the sequence.
747169691Skan       */
748169691Skan      result_type
749169691Skan      operator()();
750169691Skan
751169691Skan      /**
752169691Skan       * Compares two % subtract_with_carry random number generator objects of
753169691Skan       * the same type for equality.
754169691Skan       *
755169691Skan       * @param __lhs A % subtract_with_carry random number generator object.
756169691Skan       * @param __rhs Another % subtract_with_carry random number generator
757169691Skan       *              object.
758169691Skan       *
759169691Skan       * @returns true if the two objects are equal, false otherwise.
760169691Skan       */
761169691Skan      friend bool
762169691Skan      operator==(const subtract_with_carry& __lhs,
763169691Skan		 const subtract_with_carry& __rhs)
764169691Skan      { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
765169691Skan
766169691Skan      /**
767169691Skan       * Compares two % subtract_with_carry random number generator objects of
768169691Skan       * the same type for inequality.
769169691Skan       *
770169691Skan       * @param __lhs A % subtract_with_carry random number generator object.
771169691Skan       * @param __rhs Another % subtract_with_carry random number generator
772169691Skan       *              object.
773169691Skan       *
774169691Skan       * @returns true if the two objects are not equal, false otherwise.
775169691Skan       */
776169691Skan      friend bool
777169691Skan      operator!=(const subtract_with_carry& __lhs,
778169691Skan		 const subtract_with_carry& __rhs)
779169691Skan      { return !(__lhs == __rhs); }
780169691Skan
781169691Skan      /**
782169691Skan       * Inserts the current state of a % subtract_with_carry random number
783169691Skan       * generator engine @p __x into the output stream @p __os.
784169691Skan       *
785169691Skan       * @param __os An output stream.
786169691Skan       * @param __x  A % subtract_with_carry random number generator engine.
787169691Skan       *
788169691Skan       * @returns The output stream with the state of @p __x inserted or in
789169691Skan       * an error state.
790169691Skan       */
791169691Skan      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
792169691Skan	       typename _CharT, typename _Traits>
793169691Skan        friend std::basic_ostream<_CharT, _Traits>&
794169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
795169691Skan		   const subtract_with_carry<_IntType1, __m1, __s1,
796169691Skan		   __r1>& __x);
797169691Skan
798169691Skan      /**
799169691Skan       * Extracts the current state of a % subtract_with_carry random number
800169691Skan       * generator engine @p __x from the input stream @p __is.
801169691Skan       *
802169691Skan       * @param __is An input stream.
803169691Skan       * @param __x  A % subtract_with_carry random number generator engine.
804169691Skan       *
805169691Skan       * @returns The input stream with the state of @p __x extracted or in
806169691Skan       * an error state.
807169691Skan       */
808169691Skan      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
809169691Skan	       typename _CharT, typename _Traits>
810169691Skan        friend std::basic_istream<_CharT, _Traits>&
811169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
812169691Skan		   subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
813169691Skan
814169691Skan    private:
815169691Skan      template<class _Gen>
816169691Skan        void
817169691Skan        seed(_Gen& __g, true_type)
818169691Skan        { return seed(static_cast<unsigned long>(__g)); }
819169691Skan
820169691Skan      template<class _Gen>
821169691Skan        void
822169691Skan        seed(_Gen& __g, false_type);
823169691Skan
824169691Skan      typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
825169691Skan
826169691Skan      _UIntType  _M_x[long_lag];
827169691Skan      _UIntType  _M_carry;
828169691Skan      int        _M_p;
829169691Skan    };
830169691Skan
831169691Skan
832169691Skan  /**
833169691Skan   * @brief The Marsaglia-Zaman generator (floats version).
834169691Skan   *
835169691Skan   * @if maint
836169691Skan   * @var _M_x     The state of the generator.  This is a ring buffer.
837169691Skan   * @var _M_carry The carry.
838169691Skan   * @var _M_p     Current index of x(i - r).
839169691Skan   * @var _M_npows Precomputed negative powers of 2.   
840169691Skan   * @endif
841169691Skan   */
842169691Skan  template<typename _RealType, int __w, int __s, int __r>
843169691Skan    class subtract_with_carry_01
844169691Skan    {
845169691Skan    public:
846169691Skan      /** The type of the generated random value. */
847169691Skan      typedef _RealType result_type;
848169691Skan      
849169691Skan      // parameter values
850169691Skan      static const int      word_size = __w;
851169691Skan      static const int      long_lag  = __r;
852169691Skan      static const int      short_lag = __s;
853169691Skan
854169691Skan      /**
855169691Skan       * Constructs a default-initialized % subtract_with_carry_01 random
856169691Skan       * number generator.
857169691Skan       */
858169691Skan      subtract_with_carry_01()
859169691Skan      {
860169691Skan	this->seed();
861169691Skan	_M_initialize_npows();
862169691Skan      }
863169691Skan
864169691Skan      /**
865169691Skan       * Constructs an explicitly seeded % subtract_with_carry_01 random number
866169691Skan       * generator.
867169691Skan       */
868169691Skan      explicit
869169691Skan      subtract_with_carry_01(unsigned long __value)
870169691Skan      {
871169691Skan	this->seed(__value);
872169691Skan	_M_initialize_npows();
873169691Skan      }
874169691Skan
875169691Skan      /**
876169691Skan       * Constructs a % subtract_with_carry_01 random number generator engine
877169691Skan       * seeded from the generator function @p __g.
878169691Skan       *
879169691Skan       * @param __g The seed generator function.
880169691Skan       */
881169691Skan      template<class _Gen>
882169691Skan        subtract_with_carry_01(_Gen& __g)
883169691Skan        {
884169691Skan	  this->seed(__g);
885169691Skan	  _M_initialize_npows();	  
886169691Skan	}
887169691Skan
888169691Skan      /**
889169691Skan       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
890169691Skan       */
891169691Skan      void
892169691Skan      seed(unsigned long __value = 19780503);
893169691Skan
894169691Skan      /**
895169691Skan       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
896169691Skan       * random number generator.
897169691Skan       */
898169691Skan      template<class _Gen>
899169691Skan        void
900169691Skan        seed(_Gen& __g)
901169691Skan        { seed(__g, typename is_fundamental<_Gen>::type()); }
902169691Skan
903169691Skan      /**
904169691Skan       * Gets the minimum value of the range of random floats
905169691Skan       * returned by this generator.
906169691Skan       */
907169691Skan      result_type
908169691Skan      min() const
909169691Skan      { return 0.0; }
910169691Skan
911169691Skan      /**
912169691Skan       * Gets the maximum value of the range of random floats
913169691Skan       * returned by this generator.
914169691Skan       */
915169691Skan      result_type
916169691Skan      max() const
917169691Skan      { return 1.0; }
918169691Skan
919169691Skan      /**
920169691Skan       * Gets the next random number in the sequence.
921169691Skan       */
922169691Skan      result_type
923169691Skan      operator()();
924169691Skan
925169691Skan      /**
926169691Skan       * Compares two % subtract_with_carry_01 random number generator objects
927169691Skan       * of the same type for equality.
928169691Skan       *
929169691Skan       * @param __lhs A % subtract_with_carry_01 random number
930169691Skan       *              generator object.
931169691Skan       * @param __rhs Another % subtract_with_carry_01 random number generator
932169691Skan       *              object.
933169691Skan       *
934169691Skan       * @returns true if the two objects are equal, false otherwise.
935169691Skan       */
936169691Skan      friend bool
937169691Skan      operator==(const subtract_with_carry_01& __lhs,
938169691Skan		 const subtract_with_carry_01& __rhs)
939169691Skan      {
940169691Skan	for (int __i = 0; __i < long_lag; ++__i)
941169691Skan	  if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
942169691Skan			  __rhs._M_x[__i]))
943169691Skan	    return false;
944169691Skan	return true;
945169691Skan      }
946169691Skan
947169691Skan      /**
948169691Skan       * Compares two % subtract_with_carry_01 random number generator objects
949169691Skan       * of the same type for inequality.
950169691Skan       *
951169691Skan       * @param __lhs A % subtract_with_carry_01 random number
952169691Skan       *              generator object.
953169691Skan       *
954169691Skan       * @param __rhs Another % subtract_with_carry_01 random number generator
955169691Skan       *              object.
956169691Skan       *
957169691Skan       * @returns true if the two objects are not equal, false otherwise.
958169691Skan       */
959169691Skan      friend bool
960169691Skan      operator!=(const subtract_with_carry_01& __lhs,
961169691Skan		 const subtract_with_carry_01& __rhs)
962169691Skan      { return !(__lhs == __rhs); }
963169691Skan
964169691Skan      /**
965169691Skan       * Inserts the current state of a % subtract_with_carry_01 random number
966169691Skan       * generator engine @p __x into the output stream @p __os.
967169691Skan       *
968169691Skan       * @param __os An output stream.
969169691Skan       * @param __x  A % subtract_with_carry_01 random number generator engine.
970169691Skan       *
971169691Skan       * @returns The output stream with the state of @p __x inserted or in
972169691Skan       * an error state.
973169691Skan       */
974169691Skan      template<typename _RealType1, int __w1, int __s1, int __r1,
975169691Skan	       typename _CharT, typename _Traits>
976169691Skan        friend std::basic_ostream<_CharT, _Traits>&
977169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
978169691Skan		   const subtract_with_carry_01<_RealType1, __w1, __s1,
979169691Skan		   __r1>& __x);
980169691Skan
981169691Skan      /**
982169691Skan       * Extracts the current state of a % subtract_with_carry_01 random number
983169691Skan       * generator engine @p __x from the input stream @p __is.
984169691Skan       *
985169691Skan       * @param __is An input stream.
986169691Skan       * @param __x  A % subtract_with_carry_01 random number generator engine.
987169691Skan       *
988169691Skan       * @returns The input stream with the state of @p __x extracted or in
989169691Skan       * an error state.
990169691Skan       */
991169691Skan      template<typename _RealType1, int __w1, int __s1, int __r1,
992169691Skan	       typename _CharT, typename _Traits>
993169691Skan        friend std::basic_istream<_CharT, _Traits>&
994169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
995169691Skan		   subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
996169691Skan
997169691Skan    private:
998169691Skan      template<class _Gen>
999169691Skan        void
1000169691Skan        seed(_Gen& __g, true_type)
1001169691Skan        { return seed(static_cast<unsigned long>(__g)); }
1002169691Skan
1003169691Skan      template<class _Gen>
1004169691Skan        void
1005169691Skan        seed(_Gen& __g, false_type);
1006169691Skan
1007169691Skan      void
1008169691Skan      _M_initialize_npows();
1009169691Skan
1010169691Skan      static const int __n = (__w + 31) / 32;
1011169691Skan
1012169691Skan      typedef __detail::_UInt32Type _UInt32Type;
1013169691Skan      _UInt32Type  _M_x[long_lag][__n];
1014169691Skan      _RealType    _M_npows[__n];
1015169691Skan      _UInt32Type  _M_carry;
1016169691Skan      int          _M_p;
1017169691Skan    };
1018169691Skan
1019169691Skan  typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;
1020169691Skan
1021169691Skan  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1022169691Skan  // 508. Bad parameters for ranlux64_base_01.
1023169691Skan  typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;  
1024169691Skan
1025169691Skan
1026169691Skan  /**
1027169691Skan   * Produces random numbers from some base engine by discarding blocks of
1028169691Skan   * data.
1029169691Skan   *
1030169691Skan   * 0 <= @p __r <= @p __p
1031169691Skan   */
1032169691Skan  template<class _UniformRandomNumberGenerator, int __p, int __r>
1033169691Skan    class discard_block
1034169691Skan    {
1035169691Skan      // __glibcxx_class_requires(typename base_type::result_type,
1036169691Skan      //                          ArithmeticTypeConcept)
1037169691Skan
1038169691Skan    public:
1039169691Skan      /** The type of the underlying generator engine. */
1040169691Skan      typedef _UniformRandomNumberGenerator   base_type;
1041169691Skan      /** The type of the generated random value. */
1042169691Skan      typedef typename base_type::result_type result_type;
1043169691Skan
1044169691Skan      // parameter values
1045169691Skan      static const int block_size = __p;
1046169691Skan      static const int used_block = __r;
1047169691Skan
1048169691Skan      /**
1049169691Skan       * Constructs a default %discard_block engine.
1050169691Skan       *
1051169691Skan       * The underlying engine is default constructed as well.
1052169691Skan       */
1053169691Skan      discard_block()
1054169691Skan      : _M_n(0) { }
1055169691Skan
1056169691Skan      /**
1057169691Skan       * Copy constructs a %discard_block engine.
1058169691Skan       *
1059169691Skan       * Copies an existing base class random number geenerator.
1060169691Skan       * @param rng An existing (base class) engine object.
1061169691Skan       */
1062169691Skan      explicit
1063169691Skan      discard_block(const base_type& __rng)
1064169691Skan      : _M_b(__rng), _M_n(0) { }
1065169691Skan
1066169691Skan      /**
1067169691Skan       * Seed constructs a %discard_block engine.
1068169691Skan       *
1069169691Skan       * Constructs the underlying generator engine seeded with @p __s.
1070169691Skan       * @param __s A seed value for the base class engine.
1071169691Skan       */
1072169691Skan      explicit
1073169691Skan      discard_block(unsigned long __s)
1074169691Skan      : _M_b(__s), _M_n(0) { }
1075169691Skan
1076169691Skan      /**
1077169691Skan       * Generator construct a %discard_block engine.
1078169691Skan       *
1079169691Skan       * @param __g A seed generator function.
1080169691Skan       */
1081169691Skan      template<class _Gen>
1082169691Skan        discard_block(_Gen& __g)
1083169691Skan	: _M_b(__g), _M_n(0) { }
1084169691Skan
1085169691Skan      /**
1086169691Skan       * Reseeds the %discard_block object with the default seed for the
1087169691Skan       * underlying base class generator engine.
1088169691Skan       */
1089169691Skan      void seed()
1090169691Skan      {
1091169691Skan	_M_b.seed();
1092169691Skan	_M_n = 0;
1093169691Skan      }
1094169691Skan
1095169691Skan      /**
1096169691Skan       * Reseeds the %discard_block object with the given seed generator
1097169691Skan       * function.
1098169691Skan       * @param __g A seed generator function.
1099169691Skan       */
1100169691Skan      template<class _Gen>
1101169691Skan        void seed(_Gen& __g)
1102169691Skan        {
1103169691Skan	  _M_b.seed(__g);
1104169691Skan	  _M_n = 0;
1105169691Skan	}
1106169691Skan
1107169691Skan      /**
1108169691Skan       * Gets a const reference to the underlying generator engine object.
1109169691Skan       */
1110169691Skan      const base_type&
1111169691Skan      base() const
1112169691Skan      { return _M_b; }
1113169691Skan
1114169691Skan      /**
1115169691Skan       * Gets the minimum value in the generated random number range.
1116169691Skan       */
1117169691Skan      result_type
1118169691Skan      min() const
1119169691Skan      { return _M_b.min(); }
1120169691Skan
1121169691Skan      /**
1122169691Skan       * Gets the maximum value in the generated random number range.
1123169691Skan       */
1124169691Skan      result_type
1125169691Skan      max() const
1126169691Skan      { return _M_b.max(); }
1127169691Skan
1128169691Skan      /**
1129169691Skan       * Gets the next value in the generated random number sequence.
1130169691Skan       */
1131169691Skan      result_type
1132169691Skan      operator()();
1133169691Skan
1134169691Skan      /**
1135169691Skan       * Compares two %discard_block random number generator objects of
1136169691Skan       * the same type for equality.
1137169691Skan       *
1138169691Skan       * @param __lhs A %discard_block random number generator object.
1139169691Skan       * @param __rhs Another %discard_block random number generator
1140169691Skan       *              object.
1141169691Skan       *
1142169691Skan       * @returns true if the two objects are equal, false otherwise.
1143169691Skan       */
1144169691Skan      friend bool
1145169691Skan      operator==(const discard_block& __lhs, const discard_block& __rhs)
1146169691Skan      { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
1147169691Skan
1148169691Skan      /**
1149169691Skan       * Compares two %discard_block random number generator objects of
1150169691Skan       * the same type for inequality.
1151169691Skan       *
1152169691Skan       * @param __lhs A %discard_block random number generator object.
1153169691Skan       * @param __rhs Another %discard_block random number generator
1154169691Skan       *              object.
1155169691Skan       *
1156169691Skan       * @returns true if the two objects are not equal, false otherwise.
1157169691Skan       */
1158169691Skan      friend bool
1159169691Skan      operator!=(const discard_block& __lhs, const discard_block& __rhs)
1160169691Skan      { return !(__lhs == __rhs); }
1161169691Skan
1162169691Skan      /**
1163169691Skan       * Inserts the current state of a %discard_block random number
1164169691Skan       * generator engine @p __x into the output stream @p __os.
1165169691Skan       *
1166169691Skan       * @param __os An output stream.
1167169691Skan       * @param __x  A %discard_block random number generator engine.
1168169691Skan       *
1169169691Skan       * @returns The output stream with the state of @p __x inserted or in
1170169691Skan       * an error state.
1171169691Skan       */
1172169691Skan      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1173169691Skan	       typename _CharT, typename _Traits>
1174169691Skan        friend std::basic_ostream<_CharT, _Traits>&
1175169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1176169691Skan		   const discard_block<_UniformRandomNumberGenerator1,
1177169691Skan		   __p1, __r1>& __x);
1178169691Skan
1179169691Skan      /**
1180169691Skan       * Extracts the current state of a % subtract_with_carry random number
1181169691Skan       * generator engine @p __x from the input stream @p __is.
1182169691Skan       *
1183169691Skan       * @param __is An input stream.
1184169691Skan       * @param __x  A %discard_block random number generator engine.
1185169691Skan       *
1186169691Skan       * @returns The input stream with the state of @p __x extracted or in
1187169691Skan       * an error state.
1188169691Skan       */
1189169691Skan      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1190169691Skan	       typename _CharT, typename _Traits>
1191169691Skan        friend std::basic_istream<_CharT, _Traits>&
1192169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1193169691Skan		   discard_block<_UniformRandomNumberGenerator1,
1194169691Skan		   __p1, __r1>& __x);
1195169691Skan
1196169691Skan    private:
1197169691Skan      base_type _M_b;
1198169691Skan      int       _M_n;
1199169691Skan    };
1200169691Skan
1201169691Skan
1202169691Skan  /**
1203169691Skan   * James's luxury-level-3 integer adaptation of Luescher's generator.
1204169691Skan   */
1205169691Skan  typedef discard_block<
1206169691Skan    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1207169691Skan      223,
1208169691Skan      24
1209169691Skan      > ranlux3;
1210169691Skan
1211169691Skan  /**
1212169691Skan   * James's luxury-level-4 integer adaptation of Luescher's generator.
1213169691Skan   */
1214169691Skan  typedef discard_block<
1215169691Skan    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1216169691Skan      389,
1217169691Skan      24
1218169691Skan      > ranlux4;
1219169691Skan
1220169691Skan  typedef discard_block<
1221169691Skan    subtract_with_carry_01<float, 24, 10, 24>,
1222169691Skan      223,
1223169691Skan      24
1224169691Skan      > ranlux3_01;
1225169691Skan
1226169691Skan  typedef discard_block<
1227169691Skan    subtract_with_carry_01<float, 24, 10, 24>,
1228169691Skan      389,
1229169691Skan      24
1230169691Skan      > ranlux4_01;
1231169691Skan
1232169691Skan
1233169691Skan  /**
1234169691Skan   * A random number generator adaptor class that combines two random number
1235169691Skan   * generator engines into a single output sequence.
1236169691Skan   */
1237169691Skan  template<class _UniformRandomNumberGenerator1, int __s1,
1238169691Skan	   class _UniformRandomNumberGenerator2, int __s2>
1239169691Skan    class xor_combine
1240169691Skan    {
1241169691Skan      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
1242169691Skan      //                          result_type, ArithmeticTypeConcept)
1243169691Skan      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
1244169691Skan      //                          result_type, ArithmeticTypeConcept)
1245169691Skan
1246169691Skan    public:
1247169691Skan      /** The type of the the first underlying generator engine. */
1248169691Skan      typedef _UniformRandomNumberGenerator1   base1_type;
1249169691Skan      /** The type of the the second underlying generator engine. */
1250169691Skan      typedef _UniformRandomNumberGenerator2   base2_type;
1251169691Skan
1252169691Skan    private:
1253169691Skan      typedef typename base1_type::result_type _Result_type1;
1254169691Skan      typedef typename base2_type::result_type _Result_type2;
1255169691Skan
1256169691Skan    public:
1257169691Skan      /** The type of the generated random value. */
1258169691Skan      typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
1259169691Skan						      > sizeof(_Result_type2)),
1260169691Skan	_Result_type1, _Result_type2>::__type result_type;
1261169691Skan
1262169691Skan      // parameter values
1263169691Skan      static const int shift1 = __s1;
1264169691Skan      static const int shift2 = __s2;
1265169691Skan
1266169691Skan      // constructors and member function
1267169691Skan      xor_combine()
1268169691Skan      : _M_b1(), _M_b2()	
1269169691Skan      { _M_initialize_max(); }
1270169691Skan
1271169691Skan      xor_combine(const base1_type& __rng1, const base2_type& __rng2)
1272169691Skan      : _M_b1(__rng1), _M_b2(__rng2)
1273169691Skan      { _M_initialize_max(); }
1274169691Skan
1275169691Skan      xor_combine(unsigned long __s)
1276169691Skan      : _M_b1(__s), _M_b2(__s + 1)
1277169691Skan      { _M_initialize_max(); }
1278169691Skan
1279169691Skan      template<class _Gen>
1280169691Skan        xor_combine(_Gen& __g)
1281169691Skan	: _M_b1(__g), _M_b2(__g)
1282169691Skan        { _M_initialize_max(); }
1283169691Skan
1284169691Skan      void
1285169691Skan      seed()
1286169691Skan      {
1287169691Skan	_M_b1.seed();
1288169691Skan	_M_b2.seed();
1289169691Skan      }
1290169691Skan
1291169691Skan      template<class _Gen>
1292169691Skan        void
1293169691Skan        seed(_Gen& __g)
1294169691Skan        {
1295169691Skan	  _M_b1.seed(__g);
1296169691Skan	  _M_b2.seed(__g);
1297169691Skan	}
1298169691Skan
1299169691Skan      const base1_type&
1300169691Skan      base1() const
1301169691Skan      { return _M_b1; }
1302169691Skan
1303169691Skan      const base2_type&
1304169691Skan      base2() const
1305169691Skan      { return _M_b2; }
1306169691Skan
1307169691Skan      result_type
1308169691Skan      min() const
1309169691Skan      { return 0; }
1310169691Skan
1311169691Skan      result_type
1312169691Skan      max() const
1313169691Skan      { return _M_max; }
1314169691Skan
1315169691Skan      /**
1316169691Skan       * Gets the next random number in the sequence.
1317169691Skan       */
1318169691Skan      // NB: Not exactly the TR1 formula, per N2079 instead.
1319169691Skan      result_type
1320169691Skan      operator()()
1321169691Skan      {
1322169691Skan	return ((result_type(_M_b1() - _M_b1.min()) << shift1)
1323169691Skan		^ (result_type(_M_b2() - _M_b2.min()) << shift2));
1324169691Skan      }
1325169691Skan
1326169691Skan      /**
1327169691Skan       * Compares two %xor_combine random number generator objects of
1328169691Skan       * the same type for equality.
1329169691Skan       *
1330169691Skan       * @param __lhs A %xor_combine random number generator object.
1331169691Skan       * @param __rhs Another %xor_combine random number generator
1332169691Skan       *              object.
1333169691Skan       *
1334169691Skan       * @returns true if the two objects are equal, false otherwise.
1335169691Skan       */
1336169691Skan      friend bool
1337169691Skan      operator==(const xor_combine& __lhs, const xor_combine& __rhs)
1338169691Skan      {
1339169691Skan	return (__lhs.base1() == __rhs.base1())
1340169691Skan	        && (__lhs.base2() == __rhs.base2());
1341169691Skan      }
1342169691Skan
1343169691Skan      /**
1344169691Skan       * Compares two %xor_combine random number generator objects of
1345169691Skan       * the same type for inequality.
1346169691Skan       *
1347169691Skan       * @param __lhs A %xor_combine random number generator object.
1348169691Skan       * @param __rhs Another %xor_combine random number generator
1349169691Skan       *              object.
1350169691Skan       *
1351169691Skan       * @returns true if the two objects are not equal, false otherwise.
1352169691Skan       */
1353169691Skan      friend bool
1354169691Skan      operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
1355169691Skan      { return !(__lhs == __rhs); }
1356169691Skan
1357169691Skan      /**
1358169691Skan       * Inserts the current state of a %xor_combine random number
1359169691Skan       * generator engine @p __x into the output stream @p __os.
1360169691Skan       *
1361169691Skan       * @param __os An output stream.
1362169691Skan       * @param __x  A %xor_combine random number generator engine.
1363169691Skan       *
1364169691Skan       * @returns The output stream with the state of @p __x inserted or in
1365169691Skan       * an error state.
1366169691Skan       */
1367169691Skan      template<class _UniformRandomNumberGenerator11, int __s11,
1368169691Skan	       class _UniformRandomNumberGenerator21, int __s21,
1369169691Skan	       typename _CharT, typename _Traits>
1370169691Skan        friend std::basic_ostream<_CharT, _Traits>&
1371169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1372169691Skan		   const xor_combine<_UniformRandomNumberGenerator11, __s11,
1373169691Skan		   _UniformRandomNumberGenerator21, __s21>& __x);
1374169691Skan
1375169691Skan      /**
1376169691Skan       * Extracts the current state of a %xor_combine random number
1377169691Skan       * generator engine @p __x from the input stream @p __is.
1378169691Skan       *
1379169691Skan       * @param __is An input stream.
1380169691Skan       * @param __x  A %xor_combine random number generator engine.
1381169691Skan       *
1382169691Skan       * @returns The input stream with the state of @p __x extracted or in
1383169691Skan       * an error state.
1384169691Skan       */
1385169691Skan      template<class _UniformRandomNumberGenerator11, int __s11,
1386169691Skan	       class _UniformRandomNumberGenerator21, int __s21,
1387169691Skan	       typename _CharT, typename _Traits>
1388169691Skan        friend std::basic_istream<_CharT, _Traits>&
1389169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1390169691Skan		   xor_combine<_UniformRandomNumberGenerator11, __s11,
1391169691Skan		   _UniformRandomNumberGenerator21, __s21>& __x);
1392169691Skan
1393169691Skan    private:
1394169691Skan      void
1395169691Skan      _M_initialize_max();
1396169691Skan
1397169691Skan      result_type
1398169691Skan      _M_initialize_max_aux(result_type, result_type, int);
1399169691Skan
1400169691Skan      base1_type  _M_b1;
1401169691Skan      base2_type  _M_b2;
1402169691Skan      result_type _M_max;
1403169691Skan    };
1404169691Skan
1405169691Skan
1406169691Skan  /**
1407169691Skan   * A standard interface to a platform-specific non-deterministic
1408169691Skan   * random number generator (if any are available).
1409169691Skan   */
1410169691Skan  class random_device
1411169691Skan  {
1412169691Skan  public:
1413169691Skan    // types
1414169691Skan    typedef unsigned int result_type;
1415169691Skan
1416169691Skan    // constructors, destructors and member functions
1417169691Skan
1418169691Skan#ifdef _GLIBCXX_USE_RANDOM_TR1
1419169691Skan
1420169691Skan    explicit
1421169691Skan    random_device(const std::string& __token = "/dev/urandom")
1422169691Skan    {
1423169691Skan      if ((__token != "/dev/urandom" && __token != "/dev/random")
1424169691Skan	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
1425169691Skan	std::__throw_runtime_error(__N("random_device::"
1426169691Skan				       "random_device(const std::string&)"));
1427169691Skan    }
1428169691Skan
1429169691Skan    ~random_device()
1430169691Skan    { std::fclose(_M_file); }
1431169691Skan
1432169691Skan#else
1433169691Skan
1434169691Skan    explicit
1435169691Skan    random_device(const std::string& __token = "mt19937")
1436169691Skan    : _M_mt(_M_strtoul(__token)) { }
1437169691Skan
1438169691Skan  private:
1439169691Skan    static unsigned long
1440169691Skan    _M_strtoul(const std::string& __str)
1441169691Skan    {
1442169691Skan      unsigned long __ret = 5489UL;
1443169691Skan      if (__str != "mt19937")
1444169691Skan	{
1445169691Skan	  const char* __nptr = __str.c_str();
1446169691Skan	  char* __endptr;
1447169691Skan	  __ret = std::strtoul(__nptr, &__endptr, 0);
1448169691Skan	  if (*__nptr == '\0' || *__endptr != '\0')
1449169691Skan	    std::__throw_runtime_error(__N("random_device::_M_strtoul"
1450169691Skan					   "(const std::string&)"));
1451169691Skan	}
1452169691Skan      return __ret;
1453169691Skan    }
1454169691Skan
1455169691Skan  public:
1456169691Skan
1457169691Skan#endif
1458169691Skan
1459169691Skan    result_type
1460169691Skan    min() const
1461169691Skan    { return std::numeric_limits<result_type>::min(); }
1462169691Skan
1463169691Skan    result_type
1464169691Skan    max() const
1465169691Skan    { return std::numeric_limits<result_type>::max(); }
1466169691Skan
1467169691Skan    double
1468169691Skan    entropy() const
1469169691Skan    { return 0.0; }
1470169691Skan
1471169691Skan    result_type
1472169691Skan    operator()()
1473169691Skan    {
1474169691Skan#ifdef _GLIBCXX_USE_RANDOM_TR1
1475169691Skan      result_type __ret;
1476169691Skan      std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
1477169691Skan		 1, _M_file);
1478169691Skan      return __ret;
1479169691Skan#else
1480169691Skan      return _M_mt();
1481169691Skan#endif
1482169691Skan    }
1483169691Skan
1484169691Skan  private:
1485169691Skan    random_device(const random_device&);
1486169691Skan    void operator=(const random_device&);
1487169691Skan
1488169691Skan#ifdef _GLIBCXX_USE_RANDOM_TR1
1489169691Skan    FILE*        _M_file;
1490169691Skan#else
1491169691Skan    mt19937      _M_mt;
1492169691Skan#endif
1493169691Skan  };
1494169691Skan
1495169691Skan  /* @} */ // group tr1_random_generators
1496169691Skan
1497169691Skan  /**
1498169691Skan   * @addtogroup tr1_random_distributions Random Number Distributions
1499169691Skan   * @ingroup tr1_random
1500169691Skan   * @{
1501169691Skan   */
1502169691Skan
1503169691Skan  /**
1504169691Skan   * @addtogroup tr1_random_distributions_discrete Discrete Distributions
1505169691Skan   * @ingroup tr1_random_distributions
1506169691Skan   * @{
1507169691Skan   */
1508169691Skan
1509169691Skan  /**
1510169691Skan   * @brief Uniform discrete distribution for random numbers.
1511169691Skan   * A discrete random distribution on the range @f$[min, max]@f$ with equal
1512169691Skan   * probability throughout the range.
1513169691Skan   */
1514169691Skan  template<typename _IntType = int>
1515169691Skan    class uniform_int
1516169691Skan    {
1517169691Skan      __glibcxx_class_requires(_IntType, _IntegerConcept)
1518169691Skan 
1519169691Skan    public:
1520169691Skan      /** The type of the parameters of the distribution. */
1521169691Skan      typedef _IntType input_type;
1522169691Skan      /** The type of the range of the distribution. */
1523169691Skan      typedef _IntType result_type;
1524169691Skan
1525169691Skan    public:
1526169691Skan      /**
1527169691Skan       * Constructs a uniform distribution object.
1528169691Skan       */
1529169691Skan      explicit
1530169691Skan      uniform_int(_IntType __min = 0, _IntType __max = 9)
1531169691Skan      : _M_min(__min), _M_max(__max)
1532169691Skan      {
1533169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
1534169691Skan      }
1535169691Skan
1536169691Skan      /**
1537169691Skan       * Gets the inclusive lower bound of the distribution range.
1538169691Skan       */
1539169691Skan      result_type
1540169691Skan      min() const
1541169691Skan      { return _M_min; }
1542169691Skan
1543169691Skan      /**
1544169691Skan       * Gets the inclusive upper bound of the distribution range.
1545169691Skan       */
1546169691Skan      result_type
1547169691Skan      max() const
1548169691Skan      { return _M_max; }
1549169691Skan
1550169691Skan      /**
1551169691Skan       * Resets the distribution state.
1552169691Skan       *
1553169691Skan       * Does nothing for the uniform integer distribution.
1554169691Skan       */
1555169691Skan      void
1556169691Skan      reset() { }
1557169691Skan
1558169691Skan      /**
1559169691Skan       * Gets a uniformly distributed random number in the range
1560169691Skan       * @f$(min, max)@f$.
1561169691Skan       */
1562169691Skan      template<typename _UniformRandomNumberGenerator>
1563169691Skan        result_type
1564169691Skan        operator()(_UniformRandomNumberGenerator& __urng)
1565169691Skan        {
1566169691Skan	  typedef typename _UniformRandomNumberGenerator::result_type
1567169691Skan	    _UResult_type;
1568169691Skan	  return _M_call(__urng, _M_min, _M_max,
1569169691Skan			 typename is_integral<_UResult_type>::type());
1570169691Skan	}
1571169691Skan
1572169691Skan      /**
1573169691Skan       * Gets a uniform random number in the range @f$[0, n)@f$.
1574169691Skan       *
1575169691Skan       * This function is aimed at use with std::random_shuffle.
1576169691Skan       */
1577169691Skan      template<typename _UniformRandomNumberGenerator>
1578169691Skan        result_type
1579169691Skan        operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
1580169691Skan        {
1581169691Skan	  typedef typename _UniformRandomNumberGenerator::result_type
1582169691Skan	    _UResult_type;
1583169691Skan	  return _M_call(__urng, 0, __n - 1,
1584169691Skan			 typename is_integral<_UResult_type>::type());
1585169691Skan	}
1586169691Skan
1587169691Skan      /**
1588169691Skan       * Inserts a %uniform_int random number distribution @p __x into the
1589169691Skan       * output stream @p os.
1590169691Skan       *
1591169691Skan       * @param __os An output stream.
1592169691Skan       * @param __x  A %uniform_int random number distribution.
1593169691Skan       *
1594169691Skan       * @returns The output stream with the state of @p __x inserted or in
1595169691Skan       * an error state.
1596169691Skan       */
1597169691Skan      template<typename _IntType1, typename _CharT, typename _Traits>
1598169691Skan        friend std::basic_ostream<_CharT, _Traits>&
1599169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1600169691Skan		   const uniform_int<_IntType1>& __x);
1601169691Skan
1602169691Skan      /**
1603169691Skan       * Extracts a %unform_int random number distribution
1604169691Skan       * @p __x from the input stream @p __is.
1605169691Skan       *
1606169691Skan       * @param __is An input stream.
1607169691Skan       * @param __x  A %uniform_int random number generator engine.
1608169691Skan       *
1609169691Skan       * @returns The input stream with @p __x extracted or in an error state.
1610169691Skan       */
1611169691Skan      template<typename _IntType1, typename _CharT, typename _Traits>
1612169691Skan        friend std::basic_istream<_CharT, _Traits>&
1613169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1614169691Skan		   uniform_int<_IntType1>& __x);
1615169691Skan
1616169691Skan    private:
1617169691Skan      template<typename _UniformRandomNumberGenerator>
1618169691Skan        result_type
1619169691Skan        _M_call(_UniformRandomNumberGenerator& __urng,
1620169691Skan		result_type __min, result_type __max, true_type)
1621229551Spfg        {
1622229551Spfg	  // XXX Must be fixed to also work when __urng.max() - __urng.min()
1623229551Spfg	  // is smaller than __max - __min.
1624220150Smm	  typedef typename __gnu_cxx::__add_unsigned<typename
1625220150Smm	    _UniformRandomNumberGenerator::result_type>::__type __utype;
1626229551Spfg	  return result_type((__max - __min + 1.0L)
1627229551Spfg			     * (__utype(__urng()) - __utype(__urng.min()))
1628229551Spfg			     / (__utype(__urng.max())
1629229551Spfg				- __utype(__urng.min()) + 1.0L)) + __min;
1630220150Smm	}
1631169691Skan
1632169691Skan      template<typename _UniformRandomNumberGenerator>
1633169691Skan        result_type
1634169691Skan        _M_call(_UniformRandomNumberGenerator& __urng,
1635169691Skan		result_type __min, result_type __max, false_type)
1636169691Skan        {
1637169691Skan	  return result_type((__urng() - __urng.min())
1638169691Skan			     / (__urng.max() - __urng.min())
1639169691Skan			     * (__max - __min + 1)) + __min;
1640169691Skan	}
1641169691Skan
1642169691Skan      _IntType _M_min;
1643169691Skan      _IntType _M_max;
1644169691Skan    };
1645169691Skan
1646169691Skan
1647169691Skan  /**
1648169691Skan   * @brief A Bernoulli random number distribution.
1649169691Skan   *
1650169691Skan   * Generates a sequence of true and false values with likelihood @f$ p @f$
1651169691Skan   * that true will come up and @f$ (1 - p) @f$ that false will appear.
1652169691Skan   */
1653169691Skan  class bernoulli_distribution
1654169691Skan  {
1655169691Skan  public:
1656169691Skan    typedef int  input_type;
1657169691Skan    typedef bool result_type;
1658169691Skan
1659169691Skan  public:
1660169691Skan    /**
1661169691Skan     * Constructs a Bernoulli distribution with likelihood @p p.
1662169691Skan     *
1663169691Skan     * @param __p  [IN]  The likelihood of a true result being returned.  Must
1664169691Skan     * be in the interval @f$ [0, 1] @f$.
1665169691Skan     */
1666169691Skan    explicit
1667169691Skan    bernoulli_distribution(double __p = 0.5)
1668169691Skan    : _M_p(__p)
1669169691Skan    { 
1670169691Skan      _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
1671169691Skan    }
1672169691Skan
1673169691Skan    /**
1674169691Skan     * Gets the @p p parameter of the distribution.
1675169691Skan     */
1676169691Skan    double
1677169691Skan    p() const
1678169691Skan    { return _M_p; }
1679169691Skan
1680169691Skan    /**
1681169691Skan     * Resets the distribution state.
1682169691Skan     *
1683169691Skan     * Does nothing for a bernoulli distribution.
1684169691Skan     */
1685169691Skan    void
1686169691Skan    reset() { }
1687169691Skan
1688169691Skan    /**
1689169691Skan     * Gets the next value in the Bernoullian sequence.
1690169691Skan     */
1691169691Skan    template<class _UniformRandomNumberGenerator>
1692169691Skan      result_type
1693169691Skan      operator()(_UniformRandomNumberGenerator& __urng)
1694169691Skan      {
1695169691Skan	if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
1696169691Skan	  return true;
1697169691Skan	return false;
1698169691Skan      }
1699169691Skan
1700169691Skan    /**
1701169691Skan     * Inserts a %bernoulli_distribution random number distribution
1702169691Skan     * @p __x into the output stream @p __os.
1703169691Skan     *
1704169691Skan     * @param __os An output stream.
1705169691Skan     * @param __x  A %bernoulli_distribution random number distribution.
1706169691Skan     *
1707169691Skan     * @returns The output stream with the state of @p __x inserted or in
1708169691Skan     * an error state.
1709169691Skan     */
1710169691Skan    template<typename _CharT, typename _Traits>
1711169691Skan      friend std::basic_ostream<_CharT, _Traits>&
1712169691Skan      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1713169691Skan		 const bernoulli_distribution& __x);
1714169691Skan
1715169691Skan    /**
1716169691Skan     * Extracts a %bernoulli_distribution random number distribution
1717169691Skan     * @p __x from the input stream @p __is.
1718169691Skan     *
1719169691Skan     * @param __is An input stream.
1720169691Skan     * @param __x  A %bernoulli_distribution random number generator engine.
1721169691Skan     *
1722169691Skan     * @returns The input stream with @p __x extracted or in an error state.
1723169691Skan     */
1724169691Skan    template<typename _CharT, typename _Traits>
1725169691Skan      friend std::basic_istream<_CharT, _Traits>&
1726169691Skan      operator>>(std::basic_istream<_CharT, _Traits>& __is,
1727169691Skan		 bernoulli_distribution& __x)
1728169691Skan      { return __is >> __x._M_p; }
1729169691Skan
1730169691Skan  private:
1731169691Skan    double _M_p;
1732169691Skan  };
1733169691Skan
1734169691Skan
1735169691Skan  /**
1736169691Skan   * @brief A discrete geometric random number distribution.
1737169691Skan   *
1738169691Skan   * The formula for the geometric probability mass function is 
1739169691Skan   * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
1740169691Skan   * distribution.
1741169691Skan   */
1742169691Skan  template<typename _IntType = int, typename _RealType = double>
1743169691Skan    class geometric_distribution
1744169691Skan    {
1745169691Skan    public:
1746169691Skan      // types
1747169691Skan      typedef _RealType input_type;
1748169691Skan      typedef _IntType  result_type;
1749169691Skan
1750169691Skan      // constructors and member function
1751169691Skan      explicit
1752169691Skan      geometric_distribution(const _RealType& __p = _RealType(0.5))
1753169691Skan      : _M_p(__p)
1754169691Skan      {
1755169691Skan	_GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
1756169691Skan	_M_initialize();
1757169691Skan      }
1758169691Skan
1759169691Skan      /**
1760169691Skan       * Gets the distribution parameter @p p.
1761169691Skan       */
1762169691Skan      _RealType
1763169691Skan      p() const
1764169691Skan      { return _M_p; }
1765169691Skan
1766169691Skan      void
1767169691Skan      reset() { }
1768169691Skan
1769169691Skan      template<class _UniformRandomNumberGenerator>
1770169691Skan        result_type
1771169691Skan        operator()(_UniformRandomNumberGenerator& __urng);
1772169691Skan
1773169691Skan      /**
1774169691Skan       * Inserts a %geometric_distribution random number distribution
1775169691Skan       * @p __x into the output stream @p __os.
1776169691Skan       *
1777169691Skan       * @param __os An output stream.
1778169691Skan       * @param __x  A %geometric_distribution random number distribution.
1779169691Skan       *
1780169691Skan       * @returns The output stream with the state of @p __x inserted or in
1781169691Skan       * an error state.
1782169691Skan       */
1783169691Skan      template<typename _IntType1, typename _RealType1,
1784169691Skan	       typename _CharT, typename _Traits>
1785169691Skan        friend std::basic_ostream<_CharT, _Traits>&
1786169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1787169691Skan		   const geometric_distribution<_IntType1, _RealType1>& __x);
1788169691Skan
1789169691Skan      /**
1790169691Skan       * Extracts a %geometric_distribution random number distribution
1791169691Skan       * @p __x from the input stream @p __is.
1792169691Skan       *
1793169691Skan       * @param __is An input stream.
1794169691Skan       * @param __x  A %geometric_distribution random number generator engine.
1795169691Skan       *
1796169691Skan       * @returns The input stream with @p __x extracted or in an error state.
1797169691Skan       */
1798169691Skan      template<typename _CharT, typename _Traits>
1799169691Skan        friend std::basic_istream<_CharT, _Traits>&
1800169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1801169691Skan		   geometric_distribution& __x)
1802169691Skan        {
1803169691Skan	  __is >> __x._M_p;
1804169691Skan	  __x._M_initialize();
1805169691Skan	  return __is;
1806169691Skan	}
1807169691Skan
1808169691Skan    private:
1809169691Skan      void
1810169691Skan      _M_initialize()
1811169691Skan      { _M_log_p = std::log(_M_p); }
1812169691Skan
1813169691Skan      _RealType _M_p;
1814169691Skan      _RealType _M_log_p;
1815169691Skan    };
1816169691Skan
1817169691Skan
1818169691Skan  template<typename _RealType>
1819169691Skan    class normal_distribution;
1820169691Skan
1821169691Skan  /**
1822169691Skan   * @brief A discrete Poisson random number distribution.
1823169691Skan   *
1824169691Skan   * The formula for the poisson probability mass function is 
1825169691Skan   * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
1826169691Skan   * parameter of the distribution.
1827169691Skan   */
1828169691Skan  template<typename _IntType = int, typename _RealType = double>
1829169691Skan    class poisson_distribution
1830169691Skan    {
1831169691Skan    public:
1832169691Skan      // types
1833169691Skan      typedef _RealType input_type;
1834169691Skan      typedef _IntType  result_type;
1835169691Skan
1836169691Skan      // constructors and member function
1837169691Skan      explicit
1838169691Skan      poisson_distribution(const _RealType& __mean = _RealType(1))
1839169691Skan      : _M_mean(__mean), _M_nd()
1840169691Skan      {
1841169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
1842169691Skan	_M_initialize();
1843169691Skan      }
1844169691Skan
1845169691Skan      /**
1846169691Skan       * Gets the distribution parameter @p mean.
1847169691Skan       */
1848169691Skan      _RealType
1849169691Skan      mean() const
1850169691Skan      { return _M_mean; }
1851169691Skan
1852169691Skan      void
1853169691Skan      reset()
1854169691Skan      { _M_nd.reset(); }
1855169691Skan
1856169691Skan      template<class _UniformRandomNumberGenerator>
1857169691Skan        result_type
1858169691Skan        operator()(_UniformRandomNumberGenerator& __urng);
1859169691Skan
1860169691Skan      /**
1861169691Skan       * Inserts a %poisson_distribution random number distribution
1862169691Skan       * @p __x into the output stream @p __os.
1863169691Skan       *
1864169691Skan       * @param __os An output stream.
1865169691Skan       * @param __x  A %poisson_distribution random number distribution.
1866169691Skan       *
1867169691Skan       * @returns The output stream with the state of @p __x inserted or in
1868169691Skan       * an error state.
1869169691Skan       */
1870169691Skan      template<typename _IntType1, typename _RealType1,
1871169691Skan	       typename _CharT, typename _Traits>
1872169691Skan        friend std::basic_ostream<_CharT, _Traits>&
1873169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1874169691Skan		   const poisson_distribution<_IntType1, _RealType1>& __x);
1875169691Skan
1876169691Skan      /**
1877169691Skan       * Extracts a %poisson_distribution random number distribution
1878169691Skan       * @p __x from the input stream @p __is.
1879169691Skan       *
1880169691Skan       * @param __is An input stream.
1881169691Skan       * @param __x  A %poisson_distribution random number generator engine.
1882169691Skan       *
1883169691Skan       * @returns The input stream with @p __x extracted or in an error state.
1884169691Skan       */
1885169691Skan      template<typename _IntType1, typename _RealType1,
1886169691Skan	       typename _CharT, typename _Traits>
1887169691Skan        friend std::basic_istream<_CharT, _Traits>&
1888169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1889169691Skan		   poisson_distribution<_IntType1, _RealType1>& __x);
1890169691Skan
1891169691Skan    private:
1892169691Skan      void
1893169691Skan      _M_initialize();
1894169691Skan
1895169691Skan      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
1896169691Skan      normal_distribution<_RealType> _M_nd;
1897169691Skan
1898169691Skan      _RealType _M_mean;
1899169691Skan
1900169691Skan      // Hosts either log(mean) or the threshold of the simple method.
1901169691Skan      _RealType _M_lm_thr;
1902169691Skan#if _GLIBCXX_USE_C99_MATH_TR1
1903169691Skan      _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
1904169691Skan#endif
1905169691Skan    };
1906169691Skan
1907169691Skan
1908169691Skan  /**
1909169691Skan   * @brief A discrete binomial random number distribution.
1910169691Skan   *
1911169691Skan   * The formula for the binomial probability mass function is 
1912169691Skan   * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
1913169691Skan   * and @f$ p @f$ are the parameters of the distribution.
1914169691Skan   */
1915169691Skan  template<typename _IntType = int, typename _RealType = double>
1916169691Skan    class binomial_distribution
1917169691Skan    {
1918169691Skan    public:
1919169691Skan      // types
1920169691Skan      typedef _RealType input_type;
1921169691Skan      typedef _IntType  result_type;
1922169691Skan
1923169691Skan      // constructors and member function
1924169691Skan      explicit
1925169691Skan      binomial_distribution(_IntType __t = 1,
1926169691Skan			    const _RealType& __p = _RealType(0.5))
1927169691Skan      : _M_t(__t), _M_p(__p), _M_nd()
1928169691Skan      {
1929169691Skan	_GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
1930169691Skan	_M_initialize();
1931169691Skan      }
1932169691Skan
1933169691Skan      /**
1934169691Skan       * Gets the distribution @p t parameter.
1935169691Skan       */
1936169691Skan      _IntType
1937169691Skan      t() const
1938169691Skan      { return _M_t; }
1939169691Skan      
1940169691Skan      /**
1941169691Skan       * Gets the distribution @p p parameter.
1942169691Skan       */
1943169691Skan      _RealType
1944169691Skan      p() const
1945169691Skan      { return _M_p; }
1946169691Skan
1947169691Skan      void
1948169691Skan      reset()
1949169691Skan      { _M_nd.reset(); }
1950169691Skan
1951169691Skan      template<class _UniformRandomNumberGenerator>
1952169691Skan        result_type
1953169691Skan        operator()(_UniformRandomNumberGenerator& __urng);
1954169691Skan
1955169691Skan      /**
1956169691Skan       * Inserts a %binomial_distribution random number distribution
1957169691Skan       * @p __x into the output stream @p __os.
1958169691Skan       *
1959169691Skan       * @param __os An output stream.
1960169691Skan       * @param __x  A %binomial_distribution random number distribution.
1961169691Skan       *
1962169691Skan       * @returns The output stream with the state of @p __x inserted or in
1963169691Skan       * an error state.
1964169691Skan       */
1965169691Skan      template<typename _IntType1, typename _RealType1,
1966169691Skan	       typename _CharT, typename _Traits>
1967169691Skan        friend std::basic_ostream<_CharT, _Traits>&
1968169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1969169691Skan		   const binomial_distribution<_IntType1, _RealType1>& __x);
1970169691Skan
1971169691Skan      /**
1972169691Skan       * Extracts a %binomial_distribution random number distribution
1973169691Skan       * @p __x from the input stream @p __is.
1974169691Skan       *
1975169691Skan       * @param __is An input stream.
1976169691Skan       * @param __x  A %binomial_distribution random number generator engine.
1977169691Skan       *
1978169691Skan       * @returns The input stream with @p __x extracted or in an error state.
1979169691Skan       */
1980169691Skan      template<typename _IntType1, typename _RealType1,
1981169691Skan	       typename _CharT, typename _Traits>
1982169691Skan        friend std::basic_istream<_CharT, _Traits>&
1983169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1984169691Skan		   binomial_distribution<_IntType1, _RealType1>& __x);
1985169691Skan
1986169691Skan    private:
1987169691Skan      void
1988169691Skan      _M_initialize();
1989169691Skan
1990169691Skan      template<class _UniformRandomNumberGenerator>
1991169691Skan        result_type
1992169691Skan        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
1993169691Skan
1994169691Skan      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
1995169691Skan      normal_distribution<_RealType> _M_nd;
1996169691Skan
1997169691Skan      _RealType _M_q;
1998169691Skan#if _GLIBCXX_USE_C99_MATH_TR1
1999169691Skan      _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
2000169691Skan	        _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
2001169691Skan#endif
2002169691Skan      _RealType _M_p;
2003169691Skan      _IntType  _M_t;
2004169691Skan
2005169691Skan      bool      _M_easy;
2006169691Skan    };
2007169691Skan
2008169691Skan  /* @} */ // group tr1_random_distributions_discrete
2009169691Skan
2010169691Skan  /**
2011169691Skan   * @addtogroup tr1_random_distributions_continuous Continuous Distributions
2012169691Skan   * @ingroup tr1_random_distributions
2013169691Skan   * @{
2014169691Skan   */
2015169691Skan
2016169691Skan  /**
2017169691Skan   * @brief Uniform continuous distribution for random numbers.
2018169691Skan   *
2019169691Skan   * A continuous random distribution on the range [min, max) with equal
2020169691Skan   * probability throughout the range.  The URNG should be real-valued and
2021169691Skan   * deliver number in the range [0, 1).
2022169691Skan   */
2023169691Skan  template<typename _RealType = double>
2024169691Skan    class uniform_real
2025169691Skan    {
2026169691Skan    public:
2027169691Skan      // types
2028169691Skan      typedef _RealType input_type;
2029169691Skan      typedef _RealType result_type;
2030169691Skan
2031169691Skan    public:
2032169691Skan      /**
2033169691Skan       * Constructs a uniform_real object.
2034169691Skan       *
2035169691Skan       * @param __min [IN]  The lower bound of the distribution.
2036169691Skan       * @param __max [IN]  The upper bound of the distribution.
2037169691Skan       */
2038169691Skan      explicit
2039169691Skan      uniform_real(_RealType __min = _RealType(0),
2040169691Skan		   _RealType __max = _RealType(1))
2041169691Skan      : _M_min(__min), _M_max(__max)
2042169691Skan      {
2043169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
2044169691Skan      }
2045169691Skan
2046169691Skan      result_type
2047169691Skan      min() const
2048169691Skan      { return _M_min; }
2049169691Skan
2050169691Skan      result_type
2051169691Skan      max() const
2052169691Skan      { return _M_max; }
2053169691Skan
2054169691Skan      void
2055169691Skan      reset() { }
2056169691Skan
2057169691Skan      template<class _UniformRandomNumberGenerator>
2058169691Skan        result_type
2059169691Skan        operator()(_UniformRandomNumberGenerator& __urng)
2060169691Skan        { return (__urng() * (_M_max - _M_min)) + _M_min; }
2061169691Skan
2062169691Skan      /**
2063169691Skan       * Inserts a %uniform_real random number distribution @p __x into the
2064169691Skan       * output stream @p __os.
2065169691Skan       *
2066169691Skan       * @param __os An output stream.
2067169691Skan       * @param __x  A %uniform_real random number distribution.
2068169691Skan       *
2069169691Skan       * @returns The output stream with the state of @p __x inserted or in
2070169691Skan       * an error state.
2071169691Skan       */
2072169691Skan      template<typename _RealType1, typename _CharT, typename _Traits>
2073169691Skan        friend std::basic_ostream<_CharT, _Traits>&
2074169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2075169691Skan		   const uniform_real<_RealType1>& __x);
2076169691Skan
2077169691Skan      /**
2078169691Skan       * Extracts a %unform_real random number distribution
2079169691Skan       * @p __x from the input stream @p __is.
2080169691Skan       *
2081169691Skan       * @param __is An input stream.
2082169691Skan       * @param __x  A %uniform_real random number generator engine.
2083169691Skan       *
2084169691Skan       * @returns The input stream with @p __x extracted or in an error state.
2085169691Skan       */
2086169691Skan      template<typename _RealType1, typename _CharT, typename _Traits>
2087169691Skan        friend std::basic_istream<_CharT, _Traits>&
2088169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2089169691Skan		   uniform_real<_RealType1>& __x);
2090169691Skan
2091169691Skan    private:
2092169691Skan      _RealType _M_min;
2093169691Skan      _RealType _M_max;
2094169691Skan    };
2095169691Skan
2096169691Skan
2097169691Skan  /**
2098169691Skan   * @brief An exponential continuous distribution for random numbers.
2099169691Skan   *
2100169691Skan   * The formula for the exponential probability mass function is 
2101169691Skan   * @f$ p(x) = \lambda e^{-\lambda x} @f$.
2102169691Skan   *
2103169691Skan   * <table border=1 cellpadding=10 cellspacing=0>
2104169691Skan   * <caption align=top>Distribution Statistics</caption>
2105169691Skan   * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2106169691Skan   * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
2107169691Skan   * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
2108169691Skan   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
2109169691Skan   * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2110169691Skan   * </table>
2111169691Skan   */
2112169691Skan  template<typename _RealType = double>
2113169691Skan    class exponential_distribution
2114169691Skan    {
2115169691Skan    public:
2116169691Skan      // types
2117169691Skan      typedef _RealType input_type;
2118169691Skan      typedef _RealType result_type;
2119169691Skan
2120169691Skan    public:
2121169691Skan      /**
2122169691Skan       * Constructs an exponential distribution with inverse scale parameter
2123169691Skan       * @f$ \lambda @f$.
2124169691Skan       */
2125169691Skan      explicit
2126169691Skan      exponential_distribution(const result_type& __lambda = result_type(1))
2127169691Skan      : _M_lambda(__lambda)
2128169691Skan      { 
2129169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
2130169691Skan      }
2131169691Skan
2132169691Skan      /**
2133169691Skan       * Gets the inverse scale parameter of the distribution.
2134169691Skan       */
2135169691Skan      _RealType
2136169691Skan      lambda() const
2137169691Skan      { return _M_lambda; }
2138169691Skan
2139169691Skan      /**
2140169691Skan       * Resets the distribution.
2141169691Skan       *
2142169691Skan       * Has no effect on exponential distributions.
2143169691Skan       */
2144169691Skan      void
2145169691Skan      reset() { }
2146169691Skan
2147169691Skan      template<class _UniformRandomNumberGenerator>
2148169691Skan        result_type
2149169691Skan        operator()(_UniformRandomNumberGenerator& __urng)
2150169691Skan        { return -std::log(__urng()) / _M_lambda; }
2151169691Skan
2152169691Skan      /**
2153169691Skan       * Inserts a %exponential_distribution random number distribution
2154169691Skan       * @p __x into the output stream @p __os.
2155169691Skan       *
2156169691Skan       * @param __os An output stream.
2157169691Skan       * @param __x  A %exponential_distribution random number distribution.
2158169691Skan       *
2159169691Skan       * @returns The output stream with the state of @p __x inserted or in
2160169691Skan       * an error state.
2161169691Skan       */
2162169691Skan      template<typename _RealType1, typename _CharT, typename _Traits>
2163169691Skan        friend std::basic_ostream<_CharT, _Traits>&
2164169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2165169691Skan		   const exponential_distribution<_RealType1>& __x);
2166169691Skan
2167169691Skan      /**
2168169691Skan       * Extracts a %exponential_distribution random number distribution
2169169691Skan       * @p __x from the input stream @p __is.
2170169691Skan       *
2171169691Skan       * @param __is An input stream.
2172169691Skan       * @param __x A %exponential_distribution random number
2173169691Skan       *            generator engine.
2174169691Skan       *
2175169691Skan       * @returns The input stream with @p __x extracted or in an error state.
2176169691Skan       */
2177169691Skan      template<typename _CharT, typename _Traits>
2178169691Skan        friend std::basic_istream<_CharT, _Traits>&
2179169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2180169691Skan		   exponential_distribution& __x)
2181169691Skan        { return __is >> __x._M_lambda; }
2182169691Skan
2183169691Skan    private:
2184169691Skan      result_type _M_lambda;
2185169691Skan    };
2186169691Skan
2187169691Skan
2188169691Skan  /**
2189169691Skan   * @brief A normal continuous distribution for random numbers.
2190169691Skan   *
2191169691Skan   * The formula for the normal probability mass function is 
2192169691Skan   * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}} 
2193169691Skan   *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
2194169691Skan   */
2195169691Skan  template<typename _RealType = double>
2196169691Skan    class normal_distribution
2197169691Skan    {
2198169691Skan    public:
2199169691Skan      // types
2200169691Skan      typedef _RealType input_type;
2201169691Skan      typedef _RealType result_type;
2202169691Skan
2203169691Skan    public:
2204169691Skan      /**
2205169691Skan       * Constructs a normal distribution with parameters @f$ mean @f$ and
2206169691Skan       * @f$ \sigma @f$.
2207169691Skan       */
2208169691Skan      explicit
2209169691Skan      normal_distribution(const result_type& __mean = result_type(0),
2210169691Skan			  const result_type& __sigma = result_type(1))
2211169691Skan      : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
2212169691Skan      { 
2213169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
2214169691Skan      }
2215169691Skan
2216169691Skan      /**
2217169691Skan       * Gets the mean of the distribution.
2218169691Skan       */
2219169691Skan      _RealType
2220169691Skan      mean() const
2221169691Skan      { return _M_mean; }
2222169691Skan
2223169691Skan      /**
2224169691Skan       * Gets the @f$ \sigma @f$ of the distribution.
2225169691Skan       */
2226169691Skan      _RealType
2227169691Skan      sigma() const
2228169691Skan      { return _M_sigma; }
2229169691Skan
2230169691Skan      /**
2231169691Skan       * Resets the distribution.
2232169691Skan       */
2233169691Skan      void
2234169691Skan      reset()
2235169691Skan      { _M_saved_available = false; }
2236169691Skan
2237169691Skan      template<class _UniformRandomNumberGenerator>
2238169691Skan        result_type
2239169691Skan        operator()(_UniformRandomNumberGenerator& __urng);
2240169691Skan
2241169691Skan      /**
2242169691Skan       * Inserts a %normal_distribution random number distribution
2243169691Skan       * @p __x into the output stream @p __os.
2244169691Skan       *
2245169691Skan       * @param __os An output stream.
2246169691Skan       * @param __x  A %normal_distribution random number distribution.
2247169691Skan       *
2248169691Skan       * @returns The output stream with the state of @p __x inserted or in
2249169691Skan       * an error state.
2250169691Skan       */
2251169691Skan      template<typename _RealType1, typename _CharT, typename _Traits>
2252169691Skan        friend std::basic_ostream<_CharT, _Traits>&
2253169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2254169691Skan		   const normal_distribution<_RealType1>& __x);
2255169691Skan
2256169691Skan      /**
2257169691Skan       * Extracts a %normal_distribution random number distribution
2258169691Skan       * @p __x from the input stream @p __is.
2259169691Skan       *
2260169691Skan       * @param __is An input stream.
2261169691Skan       * @param __x  A %normal_distribution random number generator engine.
2262169691Skan       *
2263169691Skan       * @returns The input stream with @p __x extracted or in an error state.
2264169691Skan       */
2265169691Skan      template<typename _RealType1, typename _CharT, typename _Traits>
2266169691Skan        friend std::basic_istream<_CharT, _Traits>&
2267169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2268169691Skan		   normal_distribution<_RealType1>& __x);
2269169691Skan
2270169691Skan    private:
2271169691Skan      result_type _M_mean;
2272169691Skan      result_type _M_sigma;
2273169691Skan      result_type _M_saved;
2274169691Skan      bool        _M_saved_available;     
2275169691Skan    };
2276169691Skan
2277169691Skan
2278169691Skan  /**
2279169691Skan   * @brief A gamma continuous distribution for random numbers.
2280169691Skan   *
2281169691Skan   * The formula for the gamma probability mass function is 
2282169691Skan   * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
2283169691Skan   */
2284169691Skan  template<typename _RealType = double>
2285169691Skan    class gamma_distribution
2286169691Skan    {
2287169691Skan    public:
2288169691Skan      // types
2289169691Skan      typedef _RealType input_type;
2290169691Skan      typedef _RealType result_type;
2291169691Skan
2292169691Skan    public:
2293169691Skan      /**
2294169691Skan       * Constructs a gamma distribution with parameters @f$ \alpha @f$.
2295169691Skan       */
2296169691Skan      explicit
2297169691Skan      gamma_distribution(const result_type& __alpha_val = result_type(1))
2298169691Skan      : _M_alpha(__alpha_val)
2299169691Skan      { 
2300169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
2301169691Skan	_M_initialize();
2302169691Skan      }
2303169691Skan
2304169691Skan      /**
2305169691Skan       * Gets the @f$ \alpha @f$ of the distribution.
2306169691Skan       */
2307169691Skan      _RealType
2308169691Skan      alpha() const
2309169691Skan      { return _M_alpha; }
2310169691Skan
2311169691Skan      /**
2312169691Skan       * Resets the distribution.
2313169691Skan       */
2314169691Skan      void
2315169691Skan      reset() { }
2316169691Skan
2317169691Skan      template<class _UniformRandomNumberGenerator>
2318169691Skan        result_type
2319169691Skan        operator()(_UniformRandomNumberGenerator& __urng);
2320169691Skan
2321169691Skan      /**
2322169691Skan       * Inserts a %gamma_distribution random number distribution
2323169691Skan       * @p __x into the output stream @p __os.
2324169691Skan       *
2325169691Skan       * @param __os An output stream.
2326169691Skan       * @param __x  A %gamma_distribution random number distribution.
2327169691Skan       *
2328169691Skan       * @returns The output stream with the state of @p __x inserted or in
2329169691Skan       * an error state.
2330169691Skan       */
2331169691Skan      template<typename _RealType1, typename _CharT, typename _Traits>
2332169691Skan        friend std::basic_ostream<_CharT, _Traits>&
2333169691Skan        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2334169691Skan		   const gamma_distribution<_RealType1>& __x);
2335169691Skan
2336169691Skan      /**
2337169691Skan       * Extracts a %gamma_distribution random number distribution
2338169691Skan       * @p __x from the input stream @p __is.
2339169691Skan       *
2340169691Skan       * @param __is An input stream.
2341169691Skan       * @param __x  A %gamma_distribution random number generator engine.
2342169691Skan       *
2343169691Skan       * @returns The input stream with @p __x extracted or in an error state.
2344169691Skan       */
2345169691Skan      template<typename _CharT, typename _Traits>
2346169691Skan        friend std::basic_istream<_CharT, _Traits>&
2347169691Skan        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2348169691Skan		   gamma_distribution& __x)
2349169691Skan        {
2350169691Skan	  __is >> __x._M_alpha;
2351169691Skan	  __x._M_initialize();
2352169691Skan	  return __is;
2353169691Skan	}
2354169691Skan
2355169691Skan    private:
2356169691Skan      void
2357169691Skan      _M_initialize();
2358169691Skan
2359169691Skan      result_type _M_alpha;
2360169691Skan
2361169691Skan      // Hosts either lambda of GB or d of modified Vaduva's.
2362169691Skan      result_type _M_l_d;
2363169691Skan    };
2364169691Skan
2365169691Skan  /* @} */ // group tr1_random_distributions_continuous
2366169691Skan  /* @} */ // group tr1_random_distributions
2367169691Skan  /* @} */ // group tr1_random
2368169691Skan
2369169691Skan_GLIBCXX_END_NAMESPACE
2370169691Skan}
2371169691Skan
2372169691Skan#include <tr1/random.tcc>
2373169691Skan
2374169691Skan#endif // _TR1_RANDOM
2375