1f8a1b7d9SAlexander Kabaev// random number generation -*- C++ -*-
2f8a1b7d9SAlexander Kabaev
3f8a1b7d9SAlexander Kabaev// Copyright (C) 2006 Free Software Foundation, Inc.
4f8a1b7d9SAlexander Kabaev//
5f8a1b7d9SAlexander Kabaev// This file is part of the GNU ISO C++ Library.  This library is free
6f8a1b7d9SAlexander Kabaev// software; you can redistribute it and/or modify it under the
7f8a1b7d9SAlexander Kabaev// terms of the GNU General Public License as published by the
8f8a1b7d9SAlexander Kabaev// Free Software Foundation; either version 2, or (at your option)
9f8a1b7d9SAlexander Kabaev// any later version.
10f8a1b7d9SAlexander Kabaev
11f8a1b7d9SAlexander Kabaev// This library is distributed in the hope that it will be useful,
12f8a1b7d9SAlexander Kabaev// but WITHOUT ANY WARRANTY; without even the implied warranty of
13f8a1b7d9SAlexander Kabaev// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14f8a1b7d9SAlexander Kabaev// GNU General Public License for more details.
15f8a1b7d9SAlexander Kabaev
16f8a1b7d9SAlexander Kabaev// You should have received a copy of the GNU General Public License along
17f8a1b7d9SAlexander Kabaev// with this library; see the file COPYING.  If not, write to the Free
18f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19f8a1b7d9SAlexander Kabaev// USA.
20f8a1b7d9SAlexander Kabaev
21f8a1b7d9SAlexander Kabaev// As a special exception, you may use this file as part of a free software
22f8a1b7d9SAlexander Kabaev// library without restriction.  Specifically, if other files instantiate
23f8a1b7d9SAlexander Kabaev// templates or use macros or inline functions from this file, or you compile
24f8a1b7d9SAlexander Kabaev// this file and link it with other files to produce an executable, this
25f8a1b7d9SAlexander Kabaev// file does not by itself cause the resulting executable to be covered by
26f8a1b7d9SAlexander Kabaev// the GNU General Public License.  This exception does not however
27f8a1b7d9SAlexander Kabaev// invalidate any other reasons why the executable file might be covered by
28f8a1b7d9SAlexander Kabaev// the GNU General Public License.
29f8a1b7d9SAlexander Kabaev
30f8a1b7d9SAlexander Kabaev/**
31f8a1b7d9SAlexander Kabaev * @file tr1/random
32f8a1b7d9SAlexander Kabaev * This is a TR1 C++ Library header.
33f8a1b7d9SAlexander Kabaev */
34f8a1b7d9SAlexander Kabaev
35f8a1b7d9SAlexander Kabaev#ifndef _TR1_RANDOM
36f8a1b7d9SAlexander Kabaev#define _TR1_RANDOM 1
37f8a1b7d9SAlexander Kabaev
38f8a1b7d9SAlexander Kabaev#include <cmath>
39f8a1b7d9SAlexander Kabaev#include <cstdio>
40f8a1b7d9SAlexander Kabaev#include <string>
41f8a1b7d9SAlexander Kabaev#include <iosfwd>
42f8a1b7d9SAlexander Kabaev#include <limits>
43f8a1b7d9SAlexander Kabaev#include <tr1/type_traits>
44f8a1b7d9SAlexander Kabaev#include <tr1/cmath>
45f8a1b7d9SAlexander Kabaev#include <ext/type_traits.h>
46f8a1b7d9SAlexander Kabaev#include <ext/numeric_traits.h>
47f8a1b7d9SAlexander Kabaev#include <bits/concept_check.h>
48f8a1b7d9SAlexander Kabaev#include <debug/debug.h>
49f8a1b7d9SAlexander Kabaev
50f8a1b7d9SAlexander Kabaevnamespace std
51f8a1b7d9SAlexander Kabaev{
52f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(tr1)
53f8a1b7d9SAlexander Kabaev
54f8a1b7d9SAlexander Kabaev  // [5.1] Random number generation
55f8a1b7d9SAlexander Kabaev
56f8a1b7d9SAlexander Kabaev  /**
57f8a1b7d9SAlexander Kabaev   * @addtogroup tr1_random Random Number Generation
58f8a1b7d9SAlexander Kabaev   * A facility for generating random numbers on selected distributions.
59f8a1b7d9SAlexander Kabaev   * @{
60f8a1b7d9SAlexander Kabaev   */
61f8a1b7d9SAlexander Kabaev
62f8a1b7d9SAlexander Kabaev  /*
63f8a1b7d9SAlexander Kabaev   * Implementation-space details.
64f8a1b7d9SAlexander Kabaev   */
65f8a1b7d9SAlexander Kabaev  namespace __detail
66f8a1b7d9SAlexander Kabaev  {
67f8a1b7d9SAlexander Kabaev    template<typename _UIntType, int __w,
68f8a1b7d9SAlexander Kabaev	     bool = __w < std::numeric_limits<_UIntType>::digits>
69f8a1b7d9SAlexander Kabaev      struct _Shift
70f8a1b7d9SAlexander Kabaev      { static const _UIntType __value = 0; };
71f8a1b7d9SAlexander Kabaev
72f8a1b7d9SAlexander Kabaev    template<typename _UIntType, int __w>
73f8a1b7d9SAlexander Kabaev      struct _Shift<_UIntType, __w, true>
74f8a1b7d9SAlexander Kabaev      { static const _UIntType __value = _UIntType(1) << __w; };
75f8a1b7d9SAlexander Kabaev
76f8a1b7d9SAlexander Kabaev    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
77f8a1b7d9SAlexander Kabaev      struct _Mod;
78f8a1b7d9SAlexander Kabaev
79f8a1b7d9SAlexander Kabaev    // Dispatch based on modulus value to prevent divide-by-zero compile-time
80f8a1b7d9SAlexander Kabaev    // errors when m == 0.
81f8a1b7d9SAlexander Kabaev    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
82f8a1b7d9SAlexander Kabaev      inline _Tp
83f8a1b7d9SAlexander Kabaev      __mod(_Tp __x)
84f8a1b7d9SAlexander Kabaev      { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
85f8a1b7d9SAlexander Kabaev
86f8a1b7d9SAlexander Kabaev    typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
87f8a1b7d9SAlexander Kabaev		    unsigned, unsigned long>::__type _UInt32Type;
88f8a1b7d9SAlexander Kabaev
89f8a1b7d9SAlexander Kabaev    /*
90f8a1b7d9SAlexander Kabaev     * An adaptor class for converting the output of any Generator into
91f8a1b7d9SAlexander Kabaev     * the input for a specific Distribution.
92f8a1b7d9SAlexander Kabaev     */
93f8a1b7d9SAlexander Kabaev    template<typename _Engine, typename _Distribution>
94f8a1b7d9SAlexander Kabaev      struct _Adaptor
95f8a1b7d9SAlexander Kabaev      {
96f8a1b7d9SAlexander Kabaev	typedef typename _Engine::result_type        _Engine_result_type;
97f8a1b7d9SAlexander Kabaev	typedef typename _Distribution::input_type   result_type;
98f8a1b7d9SAlexander Kabaev
99f8a1b7d9SAlexander Kabaev      public:
100f8a1b7d9SAlexander Kabaev	_Adaptor(const _Engine& __g)
101f8a1b7d9SAlexander Kabaev	: _M_g(__g) { }
102f8a1b7d9SAlexander Kabaev
103f8a1b7d9SAlexander Kabaev	result_type
104f8a1b7d9SAlexander Kabaev	min() const
105f8a1b7d9SAlexander Kabaev	{
106f8a1b7d9SAlexander Kabaev	  result_type __return_value = 0;
107f8a1b7d9SAlexander Kabaev	  if (is_integral<_Engine_result_type>::value
108f8a1b7d9SAlexander Kabaev	      && is_integral<result_type>::value)
109f8a1b7d9SAlexander Kabaev	    __return_value = _M_g.min();
110f8a1b7d9SAlexander Kabaev	  else if (!is_integral<result_type>::value)
111f8a1b7d9SAlexander Kabaev	    __return_value = result_type(0);
112f8a1b7d9SAlexander Kabaev	  return __return_value;
113f8a1b7d9SAlexander Kabaev	}
114f8a1b7d9SAlexander Kabaev
115f8a1b7d9SAlexander Kabaev	result_type
116f8a1b7d9SAlexander Kabaev	max() const
117f8a1b7d9SAlexander Kabaev	{
118f8a1b7d9SAlexander Kabaev	  result_type __return_value = 0;
119f8a1b7d9SAlexander Kabaev	  if (is_integral<_Engine_result_type>::value
120f8a1b7d9SAlexander Kabaev	      && is_integral<result_type>::value)
121f8a1b7d9SAlexander Kabaev	    __return_value = _M_g.max();
122f8a1b7d9SAlexander Kabaev	  else if (!is_integral<result_type>::value)
123f8a1b7d9SAlexander Kabaev	    __return_value = result_type(1);
124f8a1b7d9SAlexander Kabaev	  return __return_value;
125f8a1b7d9SAlexander Kabaev	}
126f8a1b7d9SAlexander Kabaev
127f8a1b7d9SAlexander Kabaev	result_type
128f8a1b7d9SAlexander Kabaev	operator()();
129f8a1b7d9SAlexander Kabaev
130f8a1b7d9SAlexander Kabaev      private:
131f8a1b7d9SAlexander Kabaev	_Engine _M_g;
132f8a1b7d9SAlexander Kabaev      };
133f8a1b7d9SAlexander Kabaev
134f8a1b7d9SAlexander Kabaev    /*
135f8a1b7d9SAlexander Kabaev     * Converts a value generated by the adapted random number generator into a
136f8a1b7d9SAlexander Kabaev     * value in the input domain for the dependent random number distribution.
137f8a1b7d9SAlexander Kabaev     *
138f8a1b7d9SAlexander Kabaev     * Because the type traits are compile time constants only the appropriate
139f8a1b7d9SAlexander Kabaev     * clause of the if statements will actually be emitted by the compiler.
140f8a1b7d9SAlexander Kabaev     */
141f8a1b7d9SAlexander Kabaev    template<typename _Engine, typename _Distribution>
142f8a1b7d9SAlexander Kabaev      typename _Adaptor<_Engine, _Distribution>::result_type
143f8a1b7d9SAlexander Kabaev      _Adaptor<_Engine, _Distribution>::
144f8a1b7d9SAlexander Kabaev      operator()()
145f8a1b7d9SAlexander Kabaev      {
146f8a1b7d9SAlexander Kabaev	result_type __return_value = 0;
147f8a1b7d9SAlexander Kabaev	if (is_integral<_Engine_result_type>::value
148f8a1b7d9SAlexander Kabaev	    && is_integral<result_type>::value)
149f8a1b7d9SAlexander Kabaev	  __return_value = _M_g();
150f8a1b7d9SAlexander Kabaev      	else if (is_integral<_Engine_result_type>::value
151f8a1b7d9SAlexander Kabaev		 && !is_integral<result_type>::value)
152f8a1b7d9SAlexander Kabaev	  __return_value = result_type(_M_g() - _M_g.min())
153f8a1b7d9SAlexander Kabaev	    / result_type(_M_g.max() - _M_g.min() + result_type(1));
154f8a1b7d9SAlexander Kabaev	else if (!is_integral<_Engine_result_type>::value
155f8a1b7d9SAlexander Kabaev		 && !is_integral<result_type>::value)
156f8a1b7d9SAlexander Kabaev	  __return_value = result_type(_M_g() - _M_g.min())
157f8a1b7d9SAlexander Kabaev	    / result_type(_M_g.max() - _M_g.min());
158f8a1b7d9SAlexander Kabaev      	return __return_value;
159f8a1b7d9SAlexander Kabaev      }
160f8a1b7d9SAlexander Kabaev  } // namespace __detail
161f8a1b7d9SAlexander Kabaev
162f8a1b7d9SAlexander Kabaev  /**
163f8a1b7d9SAlexander Kabaev   * Produces random numbers on a given disribution function using a un uniform
164f8a1b7d9SAlexander Kabaev   * random number generation engine.
165f8a1b7d9SAlexander Kabaev   *
166f8a1b7d9SAlexander Kabaev   * @todo the engine_value_type needs to be studied more carefully.
167f8a1b7d9SAlexander Kabaev   */
168f8a1b7d9SAlexander Kabaev  template<typename _Engine, typename _Dist>
169f8a1b7d9SAlexander Kabaev    class variate_generator
170f8a1b7d9SAlexander Kabaev    {
171f8a1b7d9SAlexander Kabaev      // Concept requirements.
172f8a1b7d9SAlexander Kabaev      __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
173f8a1b7d9SAlexander Kabaev      //  __glibcxx_class_requires(_Engine, _EngineConcept)
174f8a1b7d9SAlexander Kabaev      //  __glibcxx_class_requires(_Dist, _EngineConcept)
175f8a1b7d9SAlexander Kabaev
176f8a1b7d9SAlexander Kabaev    public:
177f8a1b7d9SAlexander Kabaev      typedef _Engine                                engine_type;
178f8a1b7d9SAlexander Kabaev      typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
179f8a1b7d9SAlexander Kabaev      typedef _Dist                                  distribution_type;
180f8a1b7d9SAlexander Kabaev      typedef typename _Dist::result_type            result_type;
181f8a1b7d9SAlexander Kabaev
182f8a1b7d9SAlexander Kabaev      // tr1:5.1.1 table 5.1 requirement
183f8a1b7d9SAlexander Kabaev      typedef typename __gnu_cxx::__enable_if<
184f8a1b7d9SAlexander Kabaev	is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
185f8a1b7d9SAlexander Kabaev
186f8a1b7d9SAlexander Kabaev      /**
187f8a1b7d9SAlexander Kabaev       * Constructs a variate generator with the uniform random number
188f8a1b7d9SAlexander Kabaev       * generator @p __eng for the random distribution @p __dist.
189f8a1b7d9SAlexander Kabaev       *
190f8a1b7d9SAlexander Kabaev       * @throws Any exceptions which may thrown by the copy constructors of
191f8a1b7d9SAlexander Kabaev       * the @p _Engine or @p _Dist objects.
192f8a1b7d9SAlexander Kabaev       */
193f8a1b7d9SAlexander Kabaev      variate_generator(engine_type __eng, distribution_type __dist)
194f8a1b7d9SAlexander Kabaev      : _M_engine(__eng), _M_dist(__dist) { }
195f8a1b7d9SAlexander Kabaev
196f8a1b7d9SAlexander Kabaev      /**
197f8a1b7d9SAlexander Kabaev       * Gets the next generated value on the distribution.
198f8a1b7d9SAlexander Kabaev       */
199f8a1b7d9SAlexander Kabaev      result_type
200f8a1b7d9SAlexander Kabaev      operator()()
201f8a1b7d9SAlexander Kabaev      { return _M_dist(_M_engine); }
202f8a1b7d9SAlexander Kabaev
203f8a1b7d9SAlexander Kabaev      /**
204f8a1b7d9SAlexander Kabaev       * WTF?
205f8a1b7d9SAlexander Kabaev       */
206f8a1b7d9SAlexander Kabaev      template<typename _Tp>
207f8a1b7d9SAlexander Kabaev        result_type
208f8a1b7d9SAlexander Kabaev        operator()(_Tp __value)
209f8a1b7d9SAlexander Kabaev        { return _M_dist(_M_engine, __value); }
210f8a1b7d9SAlexander Kabaev
211f8a1b7d9SAlexander Kabaev      /**
212f8a1b7d9SAlexander Kabaev       * Gets a reference to the underlying uniform random number generator
213f8a1b7d9SAlexander Kabaev       * object.
214f8a1b7d9SAlexander Kabaev       */
215f8a1b7d9SAlexander Kabaev      engine_value_type&
216f8a1b7d9SAlexander Kabaev      engine()
217f8a1b7d9SAlexander Kabaev      { return _M_engine; }
218f8a1b7d9SAlexander Kabaev
219f8a1b7d9SAlexander Kabaev      /**
220f8a1b7d9SAlexander Kabaev       * Gets a const reference to the underlying uniform random number
221f8a1b7d9SAlexander Kabaev       * generator object.
222f8a1b7d9SAlexander Kabaev       */
223f8a1b7d9SAlexander Kabaev      const engine_value_type&
224f8a1b7d9SAlexander Kabaev      engine() const
225f8a1b7d9SAlexander Kabaev      { return _M_engine; }
226f8a1b7d9SAlexander Kabaev
227f8a1b7d9SAlexander Kabaev      /**
228f8a1b7d9SAlexander Kabaev       * Gets a reference to the underlying random distribution.
229f8a1b7d9SAlexander Kabaev       */
230f8a1b7d9SAlexander Kabaev      distribution_type&
231f8a1b7d9SAlexander Kabaev      distribution()
232f8a1b7d9SAlexander Kabaev      { return _M_dist; }
233f8a1b7d9SAlexander Kabaev
234f8a1b7d9SAlexander Kabaev      /**
235f8a1b7d9SAlexander Kabaev       * Gets a const reference to the underlying random distribution.
236f8a1b7d9SAlexander Kabaev       */
237f8a1b7d9SAlexander Kabaev      const distribution_type&
238f8a1b7d9SAlexander Kabaev      distribution() const
239f8a1b7d9SAlexander Kabaev      { return _M_dist; }
240f8a1b7d9SAlexander Kabaev
241f8a1b7d9SAlexander Kabaev      /**
242f8a1b7d9SAlexander Kabaev       * Gets the closed lower bound of the distribution interval.
243f8a1b7d9SAlexander Kabaev       */
244f8a1b7d9SAlexander Kabaev      result_type
245f8a1b7d9SAlexander Kabaev      min() const
246f8a1b7d9SAlexander Kabaev      { return this->distribution().min(); }
247f8a1b7d9SAlexander Kabaev
248f8a1b7d9SAlexander Kabaev      /**
249f8a1b7d9SAlexander Kabaev       * Gets the closed upper bound of the distribution interval.
250f8a1b7d9SAlexander Kabaev       */
251f8a1b7d9SAlexander Kabaev      result_type
252f8a1b7d9SAlexander Kabaev      max() const
253f8a1b7d9SAlexander Kabaev      { return this->distribution().max(); }
254f8a1b7d9SAlexander Kabaev
255f8a1b7d9SAlexander Kabaev    private:
256f8a1b7d9SAlexander Kabaev      engine_value_type _M_engine;
257f8a1b7d9SAlexander Kabaev      distribution_type _M_dist;
258f8a1b7d9SAlexander Kabaev    };
259f8a1b7d9SAlexander Kabaev
260f8a1b7d9SAlexander Kabaev
261f8a1b7d9SAlexander Kabaev  /**
262f8a1b7d9SAlexander Kabaev   * @addtogroup tr1_random_generators Random Number Generators
263f8a1b7d9SAlexander Kabaev   * @ingroup tr1_random
264f8a1b7d9SAlexander Kabaev   *
265f8a1b7d9SAlexander Kabaev   * These classes define objects which provide random or pseudorandom
266f8a1b7d9SAlexander Kabaev   * numbers, either from a discrete or a continuous interval.  The
267f8a1b7d9SAlexander Kabaev   * random number generator supplied as a part of this library are
268f8a1b7d9SAlexander Kabaev   * all uniform random number generators which provide a sequence of
269f8a1b7d9SAlexander Kabaev   * random number uniformly distributed over their range.
270f8a1b7d9SAlexander Kabaev   *
271f8a1b7d9SAlexander Kabaev   * A number generator is a function object with an operator() that
272f8a1b7d9SAlexander Kabaev   * takes zero arguments and returns a number.
273f8a1b7d9SAlexander Kabaev   *
274f8a1b7d9SAlexander Kabaev   * A compliant random number generator must satisy the following
275f8a1b7d9SAlexander Kabaev   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
276f8a1b7d9SAlexander Kabaev   * <caption align=top>Random Number Generator Requirements</caption>
277f8a1b7d9SAlexander Kabaev   * <tr><td>To be documented.</td></tr> </table>
278f8a1b7d9SAlexander Kabaev   *
279f8a1b7d9SAlexander Kabaev   * @{
280f8a1b7d9SAlexander Kabaev   */
281f8a1b7d9SAlexander Kabaev
282f8a1b7d9SAlexander Kabaev  /**
283f8a1b7d9SAlexander Kabaev   * @brief A model of a linear congruential random number generator.
284f8a1b7d9SAlexander Kabaev   *
285f8a1b7d9SAlexander Kabaev   * A random number generator that produces pseudorandom numbers using the
286f8a1b7d9SAlexander Kabaev   * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
287f8a1b7d9SAlexander Kabaev   *
288f8a1b7d9SAlexander Kabaev   * The template parameter @p _UIntType must be an unsigned integral type
289f8a1b7d9SAlexander Kabaev   * large enough to store values up to (__m-1). If the template parameter
290f8a1b7d9SAlexander Kabaev   * @p __m is 0, the modulus @p __m used is
291f8a1b7d9SAlexander Kabaev   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
292f8a1b7d9SAlexander Kabaev   * parameters @p __a and @p __c must be less than @p __m.
293f8a1b7d9SAlexander Kabaev   *
294f8a1b7d9SAlexander Kabaev   * The size of the state is @f$ 1 @f$.
295f8a1b7d9SAlexander Kabaev   */
296f8a1b7d9SAlexander Kabaev  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
297f8a1b7d9SAlexander Kabaev    class linear_congruential
298f8a1b7d9SAlexander Kabaev    {
299f8a1b7d9SAlexander Kabaev      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
300f8a1b7d9SAlexander Kabaev      //  __glibcpp_class_requires(__a < __m && __c < __m)
301f8a1b7d9SAlexander Kabaev
302f8a1b7d9SAlexander Kabaev    public:
303f8a1b7d9SAlexander Kabaev      /** The type of the generated random value. */
304f8a1b7d9SAlexander Kabaev      typedef _UIntType result_type;
305f8a1b7d9SAlexander Kabaev
306f8a1b7d9SAlexander Kabaev      /** The multiplier. */
307f8a1b7d9SAlexander Kabaev      static const _UIntType multiplier = __a;
308f8a1b7d9SAlexander Kabaev      /** An increment. */
309f8a1b7d9SAlexander Kabaev      static const _UIntType increment = __c;
310f8a1b7d9SAlexander Kabaev      /** The modulus. */
311f8a1b7d9SAlexander Kabaev      static const _UIntType modulus = __m;
312f8a1b7d9SAlexander Kabaev
313f8a1b7d9SAlexander Kabaev      /**
314f8a1b7d9SAlexander Kabaev       * Constructs a %linear_congruential random number generator engine with
315f8a1b7d9SAlexander Kabaev       * seed @p __s.  The default seed value is 1.
316f8a1b7d9SAlexander Kabaev       *
317f8a1b7d9SAlexander Kabaev       * @param __s The initial seed value.
318f8a1b7d9SAlexander Kabaev       */
319f8a1b7d9SAlexander Kabaev      explicit
320f8a1b7d9SAlexander Kabaev      linear_congruential(unsigned long __x0 = 1)
321f8a1b7d9SAlexander Kabaev      { this->seed(__x0); }
322f8a1b7d9SAlexander Kabaev
323f8a1b7d9SAlexander Kabaev      /**
324f8a1b7d9SAlexander Kabaev       * Constructs a %linear_congruential random number generator engine
325f8a1b7d9SAlexander Kabaev       * seeded from the generator function @p __g.
326f8a1b7d9SAlexander Kabaev       *
327f8a1b7d9SAlexander Kabaev       * @param __g The seed generator function.
328f8a1b7d9SAlexander Kabaev       */
329f8a1b7d9SAlexander Kabaev      template<class _Gen>
330f8a1b7d9SAlexander Kabaev        linear_congruential(_Gen& __g)
331f8a1b7d9SAlexander Kabaev        { this->seed(__g); }
332f8a1b7d9SAlexander Kabaev
333f8a1b7d9SAlexander Kabaev      /**
334f8a1b7d9SAlexander Kabaev       * Reseeds the %linear_congruential random number generator engine
335f8a1b7d9SAlexander Kabaev       * sequence to the seed @g __s.
336f8a1b7d9SAlexander Kabaev       *
337f8a1b7d9SAlexander Kabaev       * @param __s The new seed.
338f8a1b7d9SAlexander Kabaev       */
339f8a1b7d9SAlexander Kabaev      void
340f8a1b7d9SAlexander Kabaev      seed(unsigned long __s = 1);
341f8a1b7d9SAlexander Kabaev
342f8a1b7d9SAlexander Kabaev      /**
343f8a1b7d9SAlexander Kabaev       * Reseeds the %linear_congruential random number generator engine
344f8a1b7d9SAlexander Kabaev       * sequence using values from the generator function @p __g.
345f8a1b7d9SAlexander Kabaev       *
346f8a1b7d9SAlexander Kabaev       * @param __g the seed generator function.
347f8a1b7d9SAlexander Kabaev       */
348f8a1b7d9SAlexander Kabaev      template<class _Gen>
349f8a1b7d9SAlexander Kabaev        void
350f8a1b7d9SAlexander Kabaev        seed(_Gen& __g)
351f8a1b7d9SAlexander Kabaev        { seed(__g, typename is_fundamental<_Gen>::type()); }
352f8a1b7d9SAlexander Kabaev
353f8a1b7d9SAlexander Kabaev      /**
354f8a1b7d9SAlexander Kabaev       * Gets the smallest possible value in the output range.
355f8a1b7d9SAlexander Kabaev       *
356f8a1b7d9SAlexander Kabaev       * The minumum depends on the @p __c parameter: if it is zero, the
357f8a1b7d9SAlexander Kabaev       * minimum generated must be > 0, otherwise 0 is allowed.
358f8a1b7d9SAlexander Kabaev       */
359f8a1b7d9SAlexander Kabaev      result_type
360f8a1b7d9SAlexander Kabaev      min() const
361f8a1b7d9SAlexander Kabaev      { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
362f8a1b7d9SAlexander Kabaev
363f8a1b7d9SAlexander Kabaev      /**
364f8a1b7d9SAlexander Kabaev       * Gets the largest possible value in the output range.
365f8a1b7d9SAlexander Kabaev       */
366f8a1b7d9SAlexander Kabaev      result_type
367f8a1b7d9SAlexander Kabaev      max() const
368f8a1b7d9SAlexander Kabaev      { return __m - 1; }
369f8a1b7d9SAlexander Kabaev
370f8a1b7d9SAlexander Kabaev      /**
371f8a1b7d9SAlexander Kabaev       * Gets the next random number in the sequence.
372f8a1b7d9SAlexander Kabaev       */
373f8a1b7d9SAlexander Kabaev      result_type
374f8a1b7d9SAlexander Kabaev      operator()();
375f8a1b7d9SAlexander Kabaev
376f8a1b7d9SAlexander Kabaev      /**
377f8a1b7d9SAlexander Kabaev       * Compares two linear congruential random number generator
378f8a1b7d9SAlexander Kabaev       * objects of the same type for equality.
379f8a1b7d9SAlexander Kabaev       *
380f8a1b7d9SAlexander Kabaev       * @param __lhs A linear congruential random number generator object.
381f8a1b7d9SAlexander Kabaev       * @param __rhs Another linear congruential random number generator obj.
382f8a1b7d9SAlexander Kabaev       *
383f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are equal, false otherwise.
384f8a1b7d9SAlexander Kabaev       */
385f8a1b7d9SAlexander Kabaev      friend bool
386f8a1b7d9SAlexander Kabaev      operator==(const linear_congruential& __lhs,
387f8a1b7d9SAlexander Kabaev		 const linear_congruential& __rhs)
388f8a1b7d9SAlexander Kabaev      { return __lhs._M_x == __rhs._M_x; }
389f8a1b7d9SAlexander Kabaev
390f8a1b7d9SAlexander Kabaev      /**
391f8a1b7d9SAlexander Kabaev       * Compares two linear congruential random number generator
392f8a1b7d9SAlexander Kabaev       * objects of the same type for inequality.
393f8a1b7d9SAlexander Kabaev       *
394f8a1b7d9SAlexander Kabaev       * @param __lhs A linear congruential random number generator object.
395f8a1b7d9SAlexander Kabaev       * @param __rhs Another linear congruential random number generator obj.
396f8a1b7d9SAlexander Kabaev       *
397f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are not equal, false otherwise.
398f8a1b7d9SAlexander Kabaev       */
399f8a1b7d9SAlexander Kabaev      friend bool
400f8a1b7d9SAlexander Kabaev      operator!=(const linear_congruential& __lhs,
401f8a1b7d9SAlexander Kabaev		 const linear_congruential& __rhs)
402f8a1b7d9SAlexander Kabaev      { return !(__lhs == __rhs); }
403f8a1b7d9SAlexander Kabaev
404f8a1b7d9SAlexander Kabaev      /**
405f8a1b7d9SAlexander Kabaev       * Writes the textual representation of the state x(i) of x to @p __os.
406f8a1b7d9SAlexander Kabaev       *
407f8a1b7d9SAlexander Kabaev       * @param __os  The output stream.
408f8a1b7d9SAlexander Kabaev       * @param __lcr A % linear_congruential random number generator.
409f8a1b7d9SAlexander Kabaev       * @returns __os.
410f8a1b7d9SAlexander Kabaev       */
411f8a1b7d9SAlexander Kabaev      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
412f8a1b7d9SAlexander Kabaev	       _UIntType1 __m1,
413f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
414f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
415f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
416f8a1b7d9SAlexander Kabaev		   const linear_congruential<_UIntType1, __a1, __c1,
417f8a1b7d9SAlexander Kabaev		   __m1>& __lcr);
418f8a1b7d9SAlexander Kabaev
419f8a1b7d9SAlexander Kabaev      /**
420f8a1b7d9SAlexander Kabaev       * Sets the state of the engine by reading its textual
421f8a1b7d9SAlexander Kabaev       * representation from @p __is.
422f8a1b7d9SAlexander Kabaev       *
423f8a1b7d9SAlexander Kabaev       * The textual representation must have been previously written using an
424f8a1b7d9SAlexander Kabaev       * output stream whose imbued locale and whose type's template
425f8a1b7d9SAlexander Kabaev       * specialization arguments _CharT and _Traits were the same as those of
426f8a1b7d9SAlexander Kabaev       * @p __is.
427f8a1b7d9SAlexander Kabaev       *
428f8a1b7d9SAlexander Kabaev       * @param __is  The input stream.
429f8a1b7d9SAlexander Kabaev       * @param __lcr A % linear_congruential random number generator.
430f8a1b7d9SAlexander Kabaev       * @returns __is.
431f8a1b7d9SAlexander Kabaev       */
432f8a1b7d9SAlexander Kabaev      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
433f8a1b7d9SAlexander Kabaev	       _UIntType1 __m1,
434f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
435f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
436f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
437f8a1b7d9SAlexander Kabaev		   linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
438f8a1b7d9SAlexander Kabaev
439f8a1b7d9SAlexander Kabaev    private:
440f8a1b7d9SAlexander Kabaev      template<class _Gen>
441f8a1b7d9SAlexander Kabaev        void
442f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, true_type)
443f8a1b7d9SAlexander Kabaev        { return seed(static_cast<unsigned long>(__g)); }
444f8a1b7d9SAlexander Kabaev
445f8a1b7d9SAlexander Kabaev      template<class _Gen>
446f8a1b7d9SAlexander Kabaev        void
447f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, false_type);
448f8a1b7d9SAlexander Kabaev
449f8a1b7d9SAlexander Kabaev      _UIntType _M_x;
450f8a1b7d9SAlexander Kabaev    };
451f8a1b7d9SAlexander Kabaev
452f8a1b7d9SAlexander Kabaev  /**
453f8a1b7d9SAlexander Kabaev   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
454f8a1b7d9SAlexander Kabaev   */
455f8a1b7d9SAlexander Kabaev  typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
456f8a1b7d9SAlexander Kabaev
457f8a1b7d9SAlexander Kabaev  /**
458f8a1b7d9SAlexander Kabaev   * An alternative LCR (Lehmer Generator function) .
459f8a1b7d9SAlexander Kabaev   */
460f8a1b7d9SAlexander Kabaev  typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
461f8a1b7d9SAlexander Kabaev
462f8a1b7d9SAlexander Kabaev
463f8a1b7d9SAlexander Kabaev  /**
464f8a1b7d9SAlexander Kabaev   * A generalized feedback shift register discrete random number generator.
465f8a1b7d9SAlexander Kabaev   *
466f8a1b7d9SAlexander Kabaev   * This algorithm avoind multiplication and division and is designed to be
467f8a1b7d9SAlexander Kabaev   * friendly to a pipelined architecture.  If the parameters are chosen
468f8a1b7d9SAlexander Kabaev   * correctly, this generator will produce numbers with a very long period and
469f8a1b7d9SAlexander Kabaev   * fairly good apparent entropy, although still not cryptographically strong.
470f8a1b7d9SAlexander Kabaev   *
471f8a1b7d9SAlexander Kabaev   * The best way to use this generator is with the predefined mt19937 class.
472f8a1b7d9SAlexander Kabaev   *
473f8a1b7d9SAlexander Kabaev   * This algorithm was originally invented by Makoto Matsumoto and
474f8a1b7d9SAlexander Kabaev   * Takuji Nishimura.
475f8a1b7d9SAlexander Kabaev   *
476f8a1b7d9SAlexander Kabaev   * @var word_size   The number of bits in each element of the state vector.
477f8a1b7d9SAlexander Kabaev   * @var state_size  The degree of recursion.
478f8a1b7d9SAlexander Kabaev   * @var shift_size  The period parameter.
479f8a1b7d9SAlexander Kabaev   * @var mask_bits   The separation point bit index.
480f8a1b7d9SAlexander Kabaev   * @var parameter_a The last row of the twist matrix.
481f8a1b7d9SAlexander Kabaev   * @var output_u    The first right-shift tempering matrix parameter.
482f8a1b7d9SAlexander Kabaev   * @var output_s    The first left-shift tempering matrix parameter.
483f8a1b7d9SAlexander Kabaev   * @var output_b    The first left-shift tempering matrix mask.
484f8a1b7d9SAlexander Kabaev   * @var output_t    The second left-shift tempering matrix parameter.
485f8a1b7d9SAlexander Kabaev   * @var output_c    The second left-shift tempering matrix mask.
486f8a1b7d9SAlexander Kabaev   * @var output_l    The second right-shift tempering matrix parameter.
487f8a1b7d9SAlexander Kabaev   */
488f8a1b7d9SAlexander Kabaev  template<class _UIntType, int __w, int __n, int __m, int __r,
489f8a1b7d9SAlexander Kabaev	   _UIntType __a, int __u, int __s, _UIntType __b, int __t,
490f8a1b7d9SAlexander Kabaev	   _UIntType __c, int __l>
491f8a1b7d9SAlexander Kabaev    class mersenne_twister
492f8a1b7d9SAlexander Kabaev    {
493f8a1b7d9SAlexander Kabaev      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
494f8a1b7d9SAlexander Kabaev
495f8a1b7d9SAlexander Kabaev    public:
496f8a1b7d9SAlexander Kabaev      // types
497f8a1b7d9SAlexander Kabaev      typedef _UIntType result_type;
498f8a1b7d9SAlexander Kabaev
499f8a1b7d9SAlexander Kabaev      // parameter values
500f8a1b7d9SAlexander Kabaev      static const int       word_size   = __w;
501f8a1b7d9SAlexander Kabaev      static const int       state_size  = __n;
502f8a1b7d9SAlexander Kabaev      static const int       shift_size  = __m;
503f8a1b7d9SAlexander Kabaev      static const int       mask_bits   = __r;
504f8a1b7d9SAlexander Kabaev      static const _UIntType parameter_a = __a;
505f8a1b7d9SAlexander Kabaev      static const int       output_u    = __u;
506f8a1b7d9SAlexander Kabaev      static const int       output_s    = __s;
507f8a1b7d9SAlexander Kabaev      static const _UIntType output_b    = __b;
508f8a1b7d9SAlexander Kabaev      static const int       output_t    = __t;
509f8a1b7d9SAlexander Kabaev      static const _UIntType output_c    = __c;
510f8a1b7d9SAlexander Kabaev      static const int       output_l    = __l;
511f8a1b7d9SAlexander Kabaev
512f8a1b7d9SAlexander Kabaev      // constructors and member function
513f8a1b7d9SAlexander Kabaev      mersenne_twister()
514f8a1b7d9SAlexander Kabaev      { seed(); }
515f8a1b7d9SAlexander Kabaev
516f8a1b7d9SAlexander Kabaev      explicit
517f8a1b7d9SAlexander Kabaev      mersenne_twister(unsigned long __value)
518f8a1b7d9SAlexander Kabaev      { seed(__value); }
519f8a1b7d9SAlexander Kabaev
520f8a1b7d9SAlexander Kabaev      template<class _Gen>
521f8a1b7d9SAlexander Kabaev        mersenne_twister(_Gen& __g)
522f8a1b7d9SAlexander Kabaev        { seed(__g); }
523f8a1b7d9SAlexander Kabaev
524f8a1b7d9SAlexander Kabaev      void
525f8a1b7d9SAlexander Kabaev      seed()
526f8a1b7d9SAlexander Kabaev      { seed(5489UL); }
527f8a1b7d9SAlexander Kabaev
528f8a1b7d9SAlexander Kabaev      void
529f8a1b7d9SAlexander Kabaev      seed(unsigned long __value);
530f8a1b7d9SAlexander Kabaev
531f8a1b7d9SAlexander Kabaev      template<class _Gen>
532f8a1b7d9SAlexander Kabaev        void
533f8a1b7d9SAlexander Kabaev        seed(_Gen& __g)
534f8a1b7d9SAlexander Kabaev        { seed(__g, typename is_fundamental<_Gen>::type()); }
535f8a1b7d9SAlexander Kabaev
536f8a1b7d9SAlexander Kabaev      result_type
537f8a1b7d9SAlexander Kabaev      min() const
538f8a1b7d9SAlexander Kabaev      { return 0; };
539f8a1b7d9SAlexander Kabaev
540f8a1b7d9SAlexander Kabaev      result_type
541f8a1b7d9SAlexander Kabaev      max() const
542f8a1b7d9SAlexander Kabaev      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
543f8a1b7d9SAlexander Kabaev
544f8a1b7d9SAlexander Kabaev      result_type
545f8a1b7d9SAlexander Kabaev      operator()();
546f8a1b7d9SAlexander Kabaev
547f8a1b7d9SAlexander Kabaev      /**
548f8a1b7d9SAlexander Kabaev       * Compares two % mersenne_twister random number generator objects of
549f8a1b7d9SAlexander Kabaev       * the same type for equality.
550f8a1b7d9SAlexander Kabaev       *
551f8a1b7d9SAlexander Kabaev       * @param __lhs A % mersenne_twister random number generator object.
552f8a1b7d9SAlexander Kabaev       * @param __rhs Another % mersenne_twister random number generator
553f8a1b7d9SAlexander Kabaev       *              object.
554f8a1b7d9SAlexander Kabaev       *
555f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are equal, false otherwise.
556f8a1b7d9SAlexander Kabaev       */
557f8a1b7d9SAlexander Kabaev      friend bool
558f8a1b7d9SAlexander Kabaev      operator==(const mersenne_twister& __lhs,
559f8a1b7d9SAlexander Kabaev		 const mersenne_twister& __rhs)
560f8a1b7d9SAlexander Kabaev      { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
561f8a1b7d9SAlexander Kabaev
562f8a1b7d9SAlexander Kabaev      /**
563f8a1b7d9SAlexander Kabaev       * Compares two % mersenne_twister random number generator objects of
564f8a1b7d9SAlexander Kabaev       * the same type for inequality.
565f8a1b7d9SAlexander Kabaev       *
566f8a1b7d9SAlexander Kabaev       * @param __lhs A % mersenne_twister random number generator object.
567f8a1b7d9SAlexander Kabaev       * @param __rhs Another % mersenne_twister random number generator
568f8a1b7d9SAlexander Kabaev       *              object.
569f8a1b7d9SAlexander Kabaev       *
570f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are not equal, false otherwise.
571f8a1b7d9SAlexander Kabaev       */
572f8a1b7d9SAlexander Kabaev      friend bool
573f8a1b7d9SAlexander Kabaev      operator!=(const mersenne_twister& __lhs,
574f8a1b7d9SAlexander Kabaev		 const mersenne_twister& __rhs)
575f8a1b7d9SAlexander Kabaev      { return !(__lhs == __rhs); }
576f8a1b7d9SAlexander Kabaev
577f8a1b7d9SAlexander Kabaev      /**
578f8a1b7d9SAlexander Kabaev       * Inserts the current state of a % mersenne_twister random number
579f8a1b7d9SAlexander Kabaev       * generator engine @p __x into the output stream @p __os.
580f8a1b7d9SAlexander Kabaev       *
581f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
582f8a1b7d9SAlexander Kabaev       * @param __x  A % mersenne_twister random number generator engine.
583f8a1b7d9SAlexander Kabaev       *
584f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
585f8a1b7d9SAlexander Kabaev       * an error state.
586f8a1b7d9SAlexander Kabaev       */
587f8a1b7d9SAlexander Kabaev      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
588f8a1b7d9SAlexander Kabaev	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
589f8a1b7d9SAlexander Kabaev	       _UIntType1 __c1, int __l1,
590f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
591f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
592f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
593f8a1b7d9SAlexander Kabaev		   const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
594f8a1b7d9SAlexander Kabaev		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
595f8a1b7d9SAlexander Kabaev
596f8a1b7d9SAlexander Kabaev      /**
597f8a1b7d9SAlexander Kabaev       * Extracts the current state of a % mersenne_twister random number
598f8a1b7d9SAlexander Kabaev       * generator engine @p __x from the input stream @p __is.
599f8a1b7d9SAlexander Kabaev       *
600f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
601f8a1b7d9SAlexander Kabaev       * @param __x  A % mersenne_twister random number generator engine.
602f8a1b7d9SAlexander Kabaev       *
603f8a1b7d9SAlexander Kabaev       * @returns The input stream with the state of @p __x extracted or in
604f8a1b7d9SAlexander Kabaev       * an error state.
605f8a1b7d9SAlexander Kabaev       */
606f8a1b7d9SAlexander Kabaev      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
607f8a1b7d9SAlexander Kabaev	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
608f8a1b7d9SAlexander Kabaev	       _UIntType1 __c1, int __l1,
609f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
610f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
611f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
612f8a1b7d9SAlexander Kabaev		   mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
613f8a1b7d9SAlexander Kabaev		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
614f8a1b7d9SAlexander Kabaev
615f8a1b7d9SAlexander Kabaev    private:
616f8a1b7d9SAlexander Kabaev      template<class _Gen>
617f8a1b7d9SAlexander Kabaev        void
618f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, true_type)
619f8a1b7d9SAlexander Kabaev        { return seed(static_cast<unsigned long>(__g)); }
620f8a1b7d9SAlexander Kabaev
621f8a1b7d9SAlexander Kabaev      template<class _Gen>
622f8a1b7d9SAlexander Kabaev        void
623f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, false_type);
624f8a1b7d9SAlexander Kabaev
625f8a1b7d9SAlexander Kabaev      _UIntType _M_x[state_size];
626f8a1b7d9SAlexander Kabaev      int       _M_p;
627f8a1b7d9SAlexander Kabaev    };
628f8a1b7d9SAlexander Kabaev
629f8a1b7d9SAlexander Kabaev  /**
630f8a1b7d9SAlexander Kabaev   * The classic Mersenne Twister.
631f8a1b7d9SAlexander Kabaev   *
632f8a1b7d9SAlexander Kabaev   * Reference:
633f8a1b7d9SAlexander Kabaev   * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
634f8a1b7d9SAlexander Kabaev   * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
635f8a1b7d9SAlexander Kabaev   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
636f8a1b7d9SAlexander Kabaev   */
637f8a1b7d9SAlexander Kabaev  typedef mersenne_twister<
638f8a1b7d9SAlexander Kabaev    unsigned long, 32, 624, 397, 31,
639f8a1b7d9SAlexander Kabaev    0x9908b0dful, 11, 7,
640f8a1b7d9SAlexander Kabaev    0x9d2c5680ul, 15,
641f8a1b7d9SAlexander Kabaev    0xefc60000ul, 18
642f8a1b7d9SAlexander Kabaev    > mt19937;
643f8a1b7d9SAlexander Kabaev
644f8a1b7d9SAlexander Kabaev
645f8a1b7d9SAlexander Kabaev  /**
646f8a1b7d9SAlexander Kabaev   * @brief The Marsaglia-Zaman generator.
647f8a1b7d9SAlexander Kabaev   *
648f8a1b7d9SAlexander Kabaev   * This is a model of a Generalized Fibonacci discrete random number
649f8a1b7d9SAlexander Kabaev   * generator, sometimes referred to as the SWC generator.
650f8a1b7d9SAlexander Kabaev   *
651f8a1b7d9SAlexander Kabaev   * A discrete random number generator that produces pseudorandom
652f8a1b7d9SAlexander Kabaev   * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
653f8a1b7d9SAlexander Kabaev   * carry_{i-1}) \bmod m @f$.
654f8a1b7d9SAlexander Kabaev   *
655f8a1b7d9SAlexander Kabaev   * The size of the state is @f$ r @f$
656f8a1b7d9SAlexander Kabaev   * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
657f8a1b7d9SAlexander Kabaev   *
658f8a1b7d9SAlexander Kabaev   * N1688[4.13] says "the template parameter _IntType shall denote an integral
659f8a1b7d9SAlexander Kabaev   * type large enough to store values up to m."
660f8a1b7d9SAlexander Kabaev   *
661f8a1b7d9SAlexander Kabaev   * @if maint
662f8a1b7d9SAlexander Kabaev   * @var _M_x     The state of the generator.  This is a ring buffer.
663f8a1b7d9SAlexander Kabaev   * @var _M_carry The carry.
664f8a1b7d9SAlexander Kabaev   * @var _M_p     Current index of x(i - r).
665f8a1b7d9SAlexander Kabaev   * @endif
666f8a1b7d9SAlexander Kabaev   */
667f8a1b7d9SAlexander Kabaev  template<typename _IntType, _IntType __m, int __s, int __r>
668f8a1b7d9SAlexander Kabaev    class subtract_with_carry
669f8a1b7d9SAlexander Kabaev    {
670f8a1b7d9SAlexander Kabaev      __glibcxx_class_requires(_IntType, _IntegerConcept)
671f8a1b7d9SAlexander Kabaev
672f8a1b7d9SAlexander Kabaev    public:
673f8a1b7d9SAlexander Kabaev      /** The type of the generated random value. */
674f8a1b7d9SAlexander Kabaev      typedef _IntType result_type;
675f8a1b7d9SAlexander Kabaev
676f8a1b7d9SAlexander Kabaev      // parameter values
677f8a1b7d9SAlexander Kabaev      static const _IntType modulus   = __m;
678f8a1b7d9SAlexander Kabaev      static const int      long_lag  = __r;
679f8a1b7d9SAlexander Kabaev      static const int      short_lag = __s;
680f8a1b7d9SAlexander Kabaev
681f8a1b7d9SAlexander Kabaev      /**
682f8a1b7d9SAlexander Kabaev       * Constructs a default-initialized % subtract_with_carry random number
683f8a1b7d9SAlexander Kabaev       * generator.
684f8a1b7d9SAlexander Kabaev       */
685f8a1b7d9SAlexander Kabaev      subtract_with_carry()
686f8a1b7d9SAlexander Kabaev      { this->seed(); }
687f8a1b7d9SAlexander Kabaev
688f8a1b7d9SAlexander Kabaev      /**
689f8a1b7d9SAlexander Kabaev       * Constructs an explicitly seeded % subtract_with_carry random number
690f8a1b7d9SAlexander Kabaev       * generator.
691f8a1b7d9SAlexander Kabaev       */
692f8a1b7d9SAlexander Kabaev      explicit
693f8a1b7d9SAlexander Kabaev      subtract_with_carry(unsigned long __value)
694f8a1b7d9SAlexander Kabaev      { this->seed(__value); }
695f8a1b7d9SAlexander Kabaev
696f8a1b7d9SAlexander Kabaev      /**
697f8a1b7d9SAlexander Kabaev       * Constructs a %subtract_with_carry random number generator engine
698f8a1b7d9SAlexander Kabaev       * seeded from the generator function @p __g.
699f8a1b7d9SAlexander Kabaev       *
700f8a1b7d9SAlexander Kabaev       * @param __g The seed generator function.
701f8a1b7d9SAlexander Kabaev       */
702f8a1b7d9SAlexander Kabaev      template<class _Gen>
703f8a1b7d9SAlexander Kabaev        subtract_with_carry(_Gen& __g)
704f8a1b7d9SAlexander Kabaev        { this->seed(__g); }
705f8a1b7d9SAlexander Kabaev
706f8a1b7d9SAlexander Kabaev      /**
707f8a1b7d9SAlexander Kabaev       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
708f8a1b7d9SAlexander Kabaev       *
709f8a1b7d9SAlexander Kabaev       * N1688[4.19] modifies this as follows.  If @p __value == 0,
710f8a1b7d9SAlexander Kabaev       * sets value to 19780503.  In any case, with a linear
711f8a1b7d9SAlexander Kabaev       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
712f8a1b7d9SAlexander Kabaev       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
713f8a1b7d9SAlexander Kabaev       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
714f8a1b7d9SAlexander Kabaev       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
715f8a1b7d9SAlexander Kabaev       * set carry to 1, otherwise sets carry to 0.
716f8a1b7d9SAlexander Kabaev       */
717f8a1b7d9SAlexander Kabaev      void
718f8a1b7d9SAlexander Kabaev      seed(unsigned long __value = 19780503);
719f8a1b7d9SAlexander Kabaev
720f8a1b7d9SAlexander Kabaev      /**
721f8a1b7d9SAlexander Kabaev       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
722f8a1b7d9SAlexander Kabaev       * random number generator.
723f8a1b7d9SAlexander Kabaev       */
724f8a1b7d9SAlexander Kabaev      template<class _Gen>
725f8a1b7d9SAlexander Kabaev        void
726f8a1b7d9SAlexander Kabaev        seed(_Gen& __g)
727f8a1b7d9SAlexander Kabaev        { seed(__g, typename is_fundamental<_Gen>::type()); }
728f8a1b7d9SAlexander Kabaev
729f8a1b7d9SAlexander Kabaev      /**
730f8a1b7d9SAlexander Kabaev       * Gets the inclusive minimum value of the range of random integers
731f8a1b7d9SAlexander Kabaev       * returned by this generator.
732f8a1b7d9SAlexander Kabaev       */
733f8a1b7d9SAlexander Kabaev      result_type
734f8a1b7d9SAlexander Kabaev      min() const
735f8a1b7d9SAlexander Kabaev      { return 0; }
736f8a1b7d9SAlexander Kabaev
737f8a1b7d9SAlexander Kabaev      /**
738f8a1b7d9SAlexander Kabaev       * Gets the inclusive maximum value of the range of random integers
739f8a1b7d9SAlexander Kabaev       * returned by this generator.
740f8a1b7d9SAlexander Kabaev       */
741f8a1b7d9SAlexander Kabaev      result_type
742f8a1b7d9SAlexander Kabaev      max() const
743f8a1b7d9SAlexander Kabaev      { return this->modulus - 1; }
744f8a1b7d9SAlexander Kabaev
745f8a1b7d9SAlexander Kabaev      /**
746f8a1b7d9SAlexander Kabaev       * Gets the next random number in the sequence.
747f8a1b7d9SAlexander Kabaev       */
748f8a1b7d9SAlexander Kabaev      result_type
749f8a1b7d9SAlexander Kabaev      operator()();
750f8a1b7d9SAlexander Kabaev
751f8a1b7d9SAlexander Kabaev      /**
752f8a1b7d9SAlexander Kabaev       * Compares two % subtract_with_carry random number generator objects of
753f8a1b7d9SAlexander Kabaev       * the same type for equality.
754f8a1b7d9SAlexander Kabaev       *
755f8a1b7d9SAlexander Kabaev       * @param __lhs A % subtract_with_carry random number generator object.
756f8a1b7d9SAlexander Kabaev       * @param __rhs Another % subtract_with_carry random number generator
757f8a1b7d9SAlexander Kabaev       *              object.
758f8a1b7d9SAlexander Kabaev       *
759f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are equal, false otherwise.
760f8a1b7d9SAlexander Kabaev       */
761f8a1b7d9SAlexander Kabaev      friend bool
762f8a1b7d9SAlexander Kabaev      operator==(const subtract_with_carry& __lhs,
763f8a1b7d9SAlexander Kabaev		 const subtract_with_carry& __rhs)
764f8a1b7d9SAlexander Kabaev      { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
765f8a1b7d9SAlexander Kabaev
766f8a1b7d9SAlexander Kabaev      /**
767f8a1b7d9SAlexander Kabaev       * Compares two % subtract_with_carry random number generator objects of
768f8a1b7d9SAlexander Kabaev       * the same type for inequality.
769f8a1b7d9SAlexander Kabaev       *
770f8a1b7d9SAlexander Kabaev       * @param __lhs A % subtract_with_carry random number generator object.
771f8a1b7d9SAlexander Kabaev       * @param __rhs Another % subtract_with_carry random number generator
772f8a1b7d9SAlexander Kabaev       *              object.
773f8a1b7d9SAlexander Kabaev       *
774f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are not equal, false otherwise.
775f8a1b7d9SAlexander Kabaev       */
776f8a1b7d9SAlexander Kabaev      friend bool
777f8a1b7d9SAlexander Kabaev      operator!=(const subtract_with_carry& __lhs,
778f8a1b7d9SAlexander Kabaev		 const subtract_with_carry& __rhs)
779f8a1b7d9SAlexander Kabaev      { return !(__lhs == __rhs); }
780f8a1b7d9SAlexander Kabaev
781f8a1b7d9SAlexander Kabaev      /**
782f8a1b7d9SAlexander Kabaev       * Inserts the current state of a % subtract_with_carry random number
783f8a1b7d9SAlexander Kabaev       * generator engine @p __x into the output stream @p __os.
784f8a1b7d9SAlexander Kabaev       *
785f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
786f8a1b7d9SAlexander Kabaev       * @param __x  A % subtract_with_carry random number generator engine.
787f8a1b7d9SAlexander Kabaev       *
788f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
789f8a1b7d9SAlexander Kabaev       * an error state.
790f8a1b7d9SAlexander Kabaev       */
791f8a1b7d9SAlexander Kabaev      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
792f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
793f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
794f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
795f8a1b7d9SAlexander Kabaev		   const subtract_with_carry<_IntType1, __m1, __s1,
796f8a1b7d9SAlexander Kabaev		   __r1>& __x);
797f8a1b7d9SAlexander Kabaev
798f8a1b7d9SAlexander Kabaev      /**
799f8a1b7d9SAlexander Kabaev       * Extracts the current state of a % subtract_with_carry random number
800f8a1b7d9SAlexander Kabaev       * generator engine @p __x from the input stream @p __is.
801f8a1b7d9SAlexander Kabaev       *
802f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
803f8a1b7d9SAlexander Kabaev       * @param __x  A % subtract_with_carry random number generator engine.
804f8a1b7d9SAlexander Kabaev       *
805f8a1b7d9SAlexander Kabaev       * @returns The input stream with the state of @p __x extracted or in
806f8a1b7d9SAlexander Kabaev       * an error state.
807f8a1b7d9SAlexander Kabaev       */
808f8a1b7d9SAlexander Kabaev      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
809f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
810f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
811f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
812f8a1b7d9SAlexander Kabaev		   subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
813f8a1b7d9SAlexander Kabaev
814f8a1b7d9SAlexander Kabaev    private:
815f8a1b7d9SAlexander Kabaev      template<class _Gen>
816f8a1b7d9SAlexander Kabaev        void
817f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, true_type)
818f8a1b7d9SAlexander Kabaev        { return seed(static_cast<unsigned long>(__g)); }
819f8a1b7d9SAlexander Kabaev
820f8a1b7d9SAlexander Kabaev      template<class _Gen>
821f8a1b7d9SAlexander Kabaev        void
822f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, false_type);
823f8a1b7d9SAlexander Kabaev
824f8a1b7d9SAlexander Kabaev      typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
825f8a1b7d9SAlexander Kabaev
826f8a1b7d9SAlexander Kabaev      _UIntType  _M_x[long_lag];
827f8a1b7d9SAlexander Kabaev      _UIntType  _M_carry;
828f8a1b7d9SAlexander Kabaev      int        _M_p;
829f8a1b7d9SAlexander Kabaev    };
830f8a1b7d9SAlexander Kabaev
831f8a1b7d9SAlexander Kabaev
832f8a1b7d9SAlexander Kabaev  /**
833f8a1b7d9SAlexander Kabaev   * @brief The Marsaglia-Zaman generator (floats version).
834f8a1b7d9SAlexander Kabaev   *
835f8a1b7d9SAlexander Kabaev   * @if maint
836f8a1b7d9SAlexander Kabaev   * @var _M_x     The state of the generator.  This is a ring buffer.
837f8a1b7d9SAlexander Kabaev   * @var _M_carry The carry.
838f8a1b7d9SAlexander Kabaev   * @var _M_p     Current index of x(i - r).
839f8a1b7d9SAlexander Kabaev   * @var _M_npows Precomputed negative powers of 2.
840f8a1b7d9SAlexander Kabaev   * @endif
841f8a1b7d9SAlexander Kabaev   */
842f8a1b7d9SAlexander Kabaev  template<typename _RealType, int __w, int __s, int __r>
843f8a1b7d9SAlexander Kabaev    class subtract_with_carry_01
844f8a1b7d9SAlexander Kabaev    {
845f8a1b7d9SAlexander Kabaev    public:
846f8a1b7d9SAlexander Kabaev      /** The type of the generated random value. */
847f8a1b7d9SAlexander Kabaev      typedef _RealType result_type;
848f8a1b7d9SAlexander Kabaev
849f8a1b7d9SAlexander Kabaev      // parameter values
850f8a1b7d9SAlexander Kabaev      static const int      word_size = __w;
851f8a1b7d9SAlexander Kabaev      static const int      long_lag  = __r;
852f8a1b7d9SAlexander Kabaev      static const int      short_lag = __s;
853f8a1b7d9SAlexander Kabaev
854f8a1b7d9SAlexander Kabaev      /**
855f8a1b7d9SAlexander Kabaev       * Constructs a default-initialized % subtract_with_carry_01 random
856f8a1b7d9SAlexander Kabaev       * number generator.
857f8a1b7d9SAlexander Kabaev       */
858f8a1b7d9SAlexander Kabaev      subtract_with_carry_01()
859f8a1b7d9SAlexander Kabaev      {
860f8a1b7d9SAlexander Kabaev	this->seed();
861f8a1b7d9SAlexander Kabaev	_M_initialize_npows();
862f8a1b7d9SAlexander Kabaev      }
863f8a1b7d9SAlexander Kabaev
864f8a1b7d9SAlexander Kabaev      /**
865f8a1b7d9SAlexander Kabaev       * Constructs an explicitly seeded % subtract_with_carry_01 random number
866f8a1b7d9SAlexander Kabaev       * generator.
867f8a1b7d9SAlexander Kabaev       */
868f8a1b7d9SAlexander Kabaev      explicit
869f8a1b7d9SAlexander Kabaev      subtract_with_carry_01(unsigned long __value)
870f8a1b7d9SAlexander Kabaev      {
871f8a1b7d9SAlexander Kabaev	this->seed(__value);
872f8a1b7d9SAlexander Kabaev	_M_initialize_npows();
873f8a1b7d9SAlexander Kabaev      }
874f8a1b7d9SAlexander Kabaev
875f8a1b7d9SAlexander Kabaev      /**
876f8a1b7d9SAlexander Kabaev       * Constructs a % subtract_with_carry_01 random number generator engine
877f8a1b7d9SAlexander Kabaev       * seeded from the generator function @p __g.
878f8a1b7d9SAlexander Kabaev       *
879f8a1b7d9SAlexander Kabaev       * @param __g The seed generator function.
880f8a1b7d9SAlexander Kabaev       */
881f8a1b7d9SAlexander Kabaev      template<class _Gen>
882f8a1b7d9SAlexander Kabaev        subtract_with_carry_01(_Gen& __g)
883f8a1b7d9SAlexander Kabaev        {
884f8a1b7d9SAlexander Kabaev	  this->seed(__g);
885f8a1b7d9SAlexander Kabaev	  _M_initialize_npows();
886f8a1b7d9SAlexander Kabaev	}
887f8a1b7d9SAlexander Kabaev
888f8a1b7d9SAlexander Kabaev      /**
889f8a1b7d9SAlexander Kabaev       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
890f8a1b7d9SAlexander Kabaev       */
891f8a1b7d9SAlexander Kabaev      void
892f8a1b7d9SAlexander Kabaev      seed(unsigned long __value = 19780503);
893f8a1b7d9SAlexander Kabaev
894f8a1b7d9SAlexander Kabaev      /**
895f8a1b7d9SAlexander Kabaev       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
896f8a1b7d9SAlexander Kabaev       * random number generator.
897f8a1b7d9SAlexander Kabaev       */
898f8a1b7d9SAlexander Kabaev      template<class _Gen>
899f8a1b7d9SAlexander Kabaev        void
900f8a1b7d9SAlexander Kabaev        seed(_Gen& __g)
901f8a1b7d9SAlexander Kabaev        { seed(__g, typename is_fundamental<_Gen>::type()); }
902f8a1b7d9SAlexander Kabaev
903f8a1b7d9SAlexander Kabaev      /**
904f8a1b7d9SAlexander Kabaev       * Gets the minimum value of the range of random floats
905f8a1b7d9SAlexander Kabaev       * returned by this generator.
906f8a1b7d9SAlexander Kabaev       */
907f8a1b7d9SAlexander Kabaev      result_type
908f8a1b7d9SAlexander Kabaev      min() const
909f8a1b7d9SAlexander Kabaev      { return 0.0; }
910f8a1b7d9SAlexander Kabaev
911f8a1b7d9SAlexander Kabaev      /**
912f8a1b7d9SAlexander Kabaev       * Gets the maximum value of the range of random floats
913f8a1b7d9SAlexander Kabaev       * returned by this generator.
914f8a1b7d9SAlexander Kabaev       */
915f8a1b7d9SAlexander Kabaev      result_type
916f8a1b7d9SAlexander Kabaev      max() const
917f8a1b7d9SAlexander Kabaev      { return 1.0; }
918f8a1b7d9SAlexander Kabaev
919f8a1b7d9SAlexander Kabaev      /**
920f8a1b7d9SAlexander Kabaev       * Gets the next random number in the sequence.
921f8a1b7d9SAlexander Kabaev       */
922f8a1b7d9SAlexander Kabaev      result_type
923f8a1b7d9SAlexander Kabaev      operator()();
924f8a1b7d9SAlexander Kabaev
925f8a1b7d9SAlexander Kabaev      /**
926f8a1b7d9SAlexander Kabaev       * Compares two % subtract_with_carry_01 random number generator objects
927f8a1b7d9SAlexander Kabaev       * of the same type for equality.
928f8a1b7d9SAlexander Kabaev       *
929f8a1b7d9SAlexander Kabaev       * @param __lhs A % subtract_with_carry_01 random number
930f8a1b7d9SAlexander Kabaev       *              generator object.
931f8a1b7d9SAlexander Kabaev       * @param __rhs Another % subtract_with_carry_01 random number generator
932f8a1b7d9SAlexander Kabaev       *              object.
933f8a1b7d9SAlexander Kabaev       *
934f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are equal, false otherwise.
935f8a1b7d9SAlexander Kabaev       */
936f8a1b7d9SAlexander Kabaev      friend bool
937f8a1b7d9SAlexander Kabaev      operator==(const subtract_with_carry_01& __lhs,
938f8a1b7d9SAlexander Kabaev		 const subtract_with_carry_01& __rhs)
939f8a1b7d9SAlexander Kabaev      {
940f8a1b7d9SAlexander Kabaev	for (int __i = 0; __i < long_lag; ++__i)
941f8a1b7d9SAlexander Kabaev	  if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
942f8a1b7d9SAlexander Kabaev			  __rhs._M_x[__i]))
943f8a1b7d9SAlexander Kabaev	    return false;
944f8a1b7d9SAlexander Kabaev	return true;
945f8a1b7d9SAlexander Kabaev      }
946f8a1b7d9SAlexander Kabaev
947f8a1b7d9SAlexander Kabaev      /**
948f8a1b7d9SAlexander Kabaev       * Compares two % subtract_with_carry_01 random number generator objects
949f8a1b7d9SAlexander Kabaev       * of the same type for inequality.
950f8a1b7d9SAlexander Kabaev       *
951f8a1b7d9SAlexander Kabaev       * @param __lhs A % subtract_with_carry_01 random number
952f8a1b7d9SAlexander Kabaev       *              generator object.
953f8a1b7d9SAlexander Kabaev       *
954f8a1b7d9SAlexander Kabaev       * @param __rhs Another % subtract_with_carry_01 random number generator
955f8a1b7d9SAlexander Kabaev       *              object.
956f8a1b7d9SAlexander Kabaev       *
957f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are not equal, false otherwise.
958f8a1b7d9SAlexander Kabaev       */
959f8a1b7d9SAlexander Kabaev      friend bool
960f8a1b7d9SAlexander Kabaev      operator!=(const subtract_with_carry_01& __lhs,
961f8a1b7d9SAlexander Kabaev		 const subtract_with_carry_01& __rhs)
962f8a1b7d9SAlexander Kabaev      { return !(__lhs == __rhs); }
963f8a1b7d9SAlexander Kabaev
964f8a1b7d9SAlexander Kabaev      /**
965f8a1b7d9SAlexander Kabaev       * Inserts the current state of a % subtract_with_carry_01 random number
966f8a1b7d9SAlexander Kabaev       * generator engine @p __x into the output stream @p __os.
967f8a1b7d9SAlexander Kabaev       *
968f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
969f8a1b7d9SAlexander Kabaev       * @param __x  A % subtract_with_carry_01 random number generator engine.
970f8a1b7d9SAlexander Kabaev       *
971f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
972f8a1b7d9SAlexander Kabaev       * an error state.
973f8a1b7d9SAlexander Kabaev       */
974f8a1b7d9SAlexander Kabaev      template<typename _RealType1, int __w1, int __s1, int __r1,
975f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
976f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
977f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
978f8a1b7d9SAlexander Kabaev		   const subtract_with_carry_01<_RealType1, __w1, __s1,
979f8a1b7d9SAlexander Kabaev		   __r1>& __x);
980f8a1b7d9SAlexander Kabaev
981f8a1b7d9SAlexander Kabaev      /**
982f8a1b7d9SAlexander Kabaev       * Extracts the current state of a % subtract_with_carry_01 random number
983f8a1b7d9SAlexander Kabaev       * generator engine @p __x from the input stream @p __is.
984f8a1b7d9SAlexander Kabaev       *
985f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
986f8a1b7d9SAlexander Kabaev       * @param __x  A % subtract_with_carry_01 random number generator engine.
987f8a1b7d9SAlexander Kabaev       *
988f8a1b7d9SAlexander Kabaev       * @returns The input stream with the state of @p __x extracted or in
989f8a1b7d9SAlexander Kabaev       * an error state.
990f8a1b7d9SAlexander Kabaev       */
991f8a1b7d9SAlexander Kabaev      template<typename _RealType1, int __w1, int __s1, int __r1,
992f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
993f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
994f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
995f8a1b7d9SAlexander Kabaev		   subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
996f8a1b7d9SAlexander Kabaev
997f8a1b7d9SAlexander Kabaev    private:
998f8a1b7d9SAlexander Kabaev      template<class _Gen>
999f8a1b7d9SAlexander Kabaev        void
1000f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, true_type)
1001f8a1b7d9SAlexander Kabaev        { return seed(static_cast<unsigned long>(__g)); }
1002f8a1b7d9SAlexander Kabaev
1003f8a1b7d9SAlexander Kabaev      template<class _Gen>
1004f8a1b7d9SAlexander Kabaev        void
1005f8a1b7d9SAlexander Kabaev        seed(_Gen& __g, false_type);
1006f8a1b7d9SAlexander Kabaev
1007f8a1b7d9SAlexander Kabaev      void
1008f8a1b7d9SAlexander Kabaev      _M_initialize_npows();
1009f8a1b7d9SAlexander Kabaev
1010f8a1b7d9SAlexander Kabaev      static const int __n = (__w + 31) / 32;
1011f8a1b7d9SAlexander Kabaev
1012f8a1b7d9SAlexander Kabaev      typedef __detail::_UInt32Type _UInt32Type;
1013f8a1b7d9SAlexander Kabaev      _UInt32Type  _M_x[long_lag][__n];
1014f8a1b7d9SAlexander Kabaev      _RealType    _M_npows[__n];
1015f8a1b7d9SAlexander Kabaev      _UInt32Type  _M_carry;
1016f8a1b7d9SAlexander Kabaev      int          _M_p;
1017f8a1b7d9SAlexander Kabaev    };
1018f8a1b7d9SAlexander Kabaev
1019f8a1b7d9SAlexander Kabaev  typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;
1020f8a1b7d9SAlexander Kabaev
1021f8a1b7d9SAlexander Kabaev  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1022f8a1b7d9SAlexander Kabaev  // 508. Bad parameters for ranlux64_base_01.
1023f8a1b7d9SAlexander Kabaev  typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
1024f8a1b7d9SAlexander Kabaev
1025f8a1b7d9SAlexander Kabaev
1026f8a1b7d9SAlexander Kabaev  /**
1027f8a1b7d9SAlexander Kabaev   * Produces random numbers from some base engine by discarding blocks of
1028f8a1b7d9SAlexander Kabaev   * data.
1029f8a1b7d9SAlexander Kabaev   *
1030f8a1b7d9SAlexander Kabaev   * 0 <= @p __r <= @p __p
1031f8a1b7d9SAlexander Kabaev   */
1032f8a1b7d9SAlexander Kabaev  template<class _UniformRandomNumberGenerator, int __p, int __r>
1033f8a1b7d9SAlexander Kabaev    class discard_block
1034f8a1b7d9SAlexander Kabaev    {
1035f8a1b7d9SAlexander Kabaev      // __glibcxx_class_requires(typename base_type::result_type,
1036f8a1b7d9SAlexander Kabaev      //                          ArithmeticTypeConcept)
1037f8a1b7d9SAlexander Kabaev
1038f8a1b7d9SAlexander Kabaev    public:
1039f8a1b7d9SAlexander Kabaev      /** The type of the underlying generator engine. */
1040f8a1b7d9SAlexander Kabaev      typedef _UniformRandomNumberGenerator   base_type;
1041f8a1b7d9SAlexander Kabaev      /** The type of the generated random value. */
1042f8a1b7d9SAlexander Kabaev      typedef typename base_type::result_type result_type;
1043f8a1b7d9SAlexander Kabaev
1044f8a1b7d9SAlexander Kabaev      // parameter values
1045f8a1b7d9SAlexander Kabaev      static const int block_size = __p;
1046f8a1b7d9SAlexander Kabaev      static const int used_block = __r;
1047f8a1b7d9SAlexander Kabaev
1048f8a1b7d9SAlexander Kabaev      /**
1049f8a1b7d9SAlexander Kabaev       * Constructs a default %discard_block engine.
1050f8a1b7d9SAlexander Kabaev       *
1051f8a1b7d9SAlexander Kabaev       * The underlying engine is default constructed as well.
1052f8a1b7d9SAlexander Kabaev       */
1053f8a1b7d9SAlexander Kabaev      discard_block()
1054f8a1b7d9SAlexander Kabaev      : _M_n(0) { }
1055f8a1b7d9SAlexander Kabaev
1056f8a1b7d9SAlexander Kabaev      /**
1057f8a1b7d9SAlexander Kabaev       * Copy constructs a %discard_block engine.
1058f8a1b7d9SAlexander Kabaev       *
1059f8a1b7d9SAlexander Kabaev       * Copies an existing base class random number geenerator.
1060f8a1b7d9SAlexander Kabaev       * @param rng An existing (base class) engine object.
1061f8a1b7d9SAlexander Kabaev       */
1062f8a1b7d9SAlexander Kabaev      explicit
1063f8a1b7d9SAlexander Kabaev      discard_block(const base_type& __rng)
1064f8a1b7d9SAlexander Kabaev      : _M_b(__rng), _M_n(0) { }
1065f8a1b7d9SAlexander Kabaev
1066f8a1b7d9SAlexander Kabaev      /**
1067f8a1b7d9SAlexander Kabaev       * Seed constructs a %discard_block engine.
1068f8a1b7d9SAlexander Kabaev       *
1069f8a1b7d9SAlexander Kabaev       * Constructs the underlying generator engine seeded with @p __s.
1070f8a1b7d9SAlexander Kabaev       * @param __s A seed value for the base class engine.
1071f8a1b7d9SAlexander Kabaev       */
1072f8a1b7d9SAlexander Kabaev      explicit
1073f8a1b7d9SAlexander Kabaev      discard_block(unsigned long __s)
1074f8a1b7d9SAlexander Kabaev      : _M_b(__s), _M_n(0) { }
1075f8a1b7d9SAlexander Kabaev
1076f8a1b7d9SAlexander Kabaev      /**
1077f8a1b7d9SAlexander Kabaev       * Generator construct a %discard_block engine.
1078f8a1b7d9SAlexander Kabaev       *
1079f8a1b7d9SAlexander Kabaev       * @param __g A seed generator function.
1080f8a1b7d9SAlexander Kabaev       */
1081f8a1b7d9SAlexander Kabaev      template<class _Gen>
1082f8a1b7d9SAlexander Kabaev        discard_block(_Gen& __g)
1083f8a1b7d9SAlexander Kabaev	: _M_b(__g), _M_n(0) { }
1084f8a1b7d9SAlexander Kabaev
1085f8a1b7d9SAlexander Kabaev      /**
1086f8a1b7d9SAlexander Kabaev       * Reseeds the %discard_block object with the default seed for the
1087f8a1b7d9SAlexander Kabaev       * underlying base class generator engine.
1088f8a1b7d9SAlexander Kabaev       */
1089f8a1b7d9SAlexander Kabaev      void seed()
1090f8a1b7d9SAlexander Kabaev      {
1091f8a1b7d9SAlexander Kabaev	_M_b.seed();
1092f8a1b7d9SAlexander Kabaev	_M_n = 0;
1093f8a1b7d9SAlexander Kabaev      }
1094f8a1b7d9SAlexander Kabaev
1095f8a1b7d9SAlexander Kabaev      /**
1096f8a1b7d9SAlexander Kabaev       * Reseeds the %discard_block object with the given seed generator
1097f8a1b7d9SAlexander Kabaev       * function.
1098f8a1b7d9SAlexander Kabaev       * @param __g A seed generator function.
1099f8a1b7d9SAlexander Kabaev       */
1100f8a1b7d9SAlexander Kabaev      template<class _Gen>
1101f8a1b7d9SAlexander Kabaev        void seed(_Gen& __g)
1102f8a1b7d9SAlexander Kabaev        {
1103f8a1b7d9SAlexander Kabaev	  _M_b.seed(__g);
1104f8a1b7d9SAlexander Kabaev	  _M_n = 0;
1105f8a1b7d9SAlexander Kabaev	}
1106f8a1b7d9SAlexander Kabaev
1107f8a1b7d9SAlexander Kabaev      /**
1108f8a1b7d9SAlexander Kabaev       * Gets a const reference to the underlying generator engine object.
1109f8a1b7d9SAlexander Kabaev       */
1110f8a1b7d9SAlexander Kabaev      const base_type&
1111f8a1b7d9SAlexander Kabaev      base() const
1112f8a1b7d9SAlexander Kabaev      { return _M_b; }
1113f8a1b7d9SAlexander Kabaev
1114f8a1b7d9SAlexander Kabaev      /**
1115f8a1b7d9SAlexander Kabaev       * Gets the minimum value in the generated random number range.
1116f8a1b7d9SAlexander Kabaev       */
1117f8a1b7d9SAlexander Kabaev      result_type
1118f8a1b7d9SAlexander Kabaev      min() const
1119f8a1b7d9SAlexander Kabaev      { return _M_b.min(); }
1120f8a1b7d9SAlexander Kabaev
1121f8a1b7d9SAlexander Kabaev      /**
1122f8a1b7d9SAlexander Kabaev       * Gets the maximum value in the generated random number range.
1123f8a1b7d9SAlexander Kabaev       */
1124f8a1b7d9SAlexander Kabaev      result_type
1125f8a1b7d9SAlexander Kabaev      max() const
1126f8a1b7d9SAlexander Kabaev      { return _M_b.max(); }
1127f8a1b7d9SAlexander Kabaev
1128f8a1b7d9SAlexander Kabaev      /**
1129f8a1b7d9SAlexander Kabaev       * Gets the next value in the generated random number sequence.
1130f8a1b7d9SAlexander Kabaev       */
1131f8a1b7d9SAlexander Kabaev      result_type
1132f8a1b7d9SAlexander Kabaev      operator()();
1133f8a1b7d9SAlexander Kabaev
1134f8a1b7d9SAlexander Kabaev      /**
1135f8a1b7d9SAlexander Kabaev       * Compares two %discard_block random number generator objects of
1136f8a1b7d9SAlexander Kabaev       * the same type for equality.
1137f8a1b7d9SAlexander Kabaev       *
1138f8a1b7d9SAlexander Kabaev       * @param __lhs A %discard_block random number generator object.
1139f8a1b7d9SAlexander Kabaev       * @param __rhs Another %discard_block random number generator
1140f8a1b7d9SAlexander Kabaev       *              object.
1141f8a1b7d9SAlexander Kabaev       *
1142f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are equal, false otherwise.
1143f8a1b7d9SAlexander Kabaev       */
1144f8a1b7d9SAlexander Kabaev      friend bool
1145f8a1b7d9SAlexander Kabaev      operator==(const discard_block& __lhs, const discard_block& __rhs)
1146f8a1b7d9SAlexander Kabaev      { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
1147f8a1b7d9SAlexander Kabaev
1148f8a1b7d9SAlexander Kabaev      /**
1149f8a1b7d9SAlexander Kabaev       * Compares two %discard_block random number generator objects of
1150f8a1b7d9SAlexander Kabaev       * the same type for inequality.
1151f8a1b7d9SAlexander Kabaev       *
1152f8a1b7d9SAlexander Kabaev       * @param __lhs A %discard_block random number generator object.
1153f8a1b7d9SAlexander Kabaev       * @param __rhs Another %discard_block random number generator
1154f8a1b7d9SAlexander Kabaev       *              object.
1155f8a1b7d9SAlexander Kabaev       *
1156f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are not equal, false otherwise.
1157f8a1b7d9SAlexander Kabaev       */
1158f8a1b7d9SAlexander Kabaev      friend bool
1159f8a1b7d9SAlexander Kabaev      operator!=(const discard_block& __lhs, const discard_block& __rhs)
1160f8a1b7d9SAlexander Kabaev      { return !(__lhs == __rhs); }
1161f8a1b7d9SAlexander Kabaev
1162f8a1b7d9SAlexander Kabaev      /**
1163f8a1b7d9SAlexander Kabaev       * Inserts the current state of a %discard_block random number
1164f8a1b7d9SAlexander Kabaev       * generator engine @p __x into the output stream @p __os.
1165f8a1b7d9SAlexander Kabaev       *
1166f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
1167f8a1b7d9SAlexander Kabaev       * @param __x  A %discard_block random number generator engine.
1168f8a1b7d9SAlexander Kabaev       *
1169f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
1170f8a1b7d9SAlexander Kabaev       * an error state.
1171f8a1b7d9SAlexander Kabaev       */
1172f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1173f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1174f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
1175f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1176f8a1b7d9SAlexander Kabaev		   const discard_block<_UniformRandomNumberGenerator1,
1177f8a1b7d9SAlexander Kabaev		   __p1, __r1>& __x);
1178f8a1b7d9SAlexander Kabaev
1179f8a1b7d9SAlexander Kabaev      /**
1180f8a1b7d9SAlexander Kabaev       * Extracts the current state of a % subtract_with_carry random number
1181f8a1b7d9SAlexander Kabaev       * generator engine @p __x from the input stream @p __is.
1182f8a1b7d9SAlexander Kabaev       *
1183f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
1184f8a1b7d9SAlexander Kabaev       * @param __x  A %discard_block random number generator engine.
1185f8a1b7d9SAlexander Kabaev       *
1186f8a1b7d9SAlexander Kabaev       * @returns The input stream with the state of @p __x extracted or in
1187f8a1b7d9SAlexander Kabaev       * an error state.
1188f8a1b7d9SAlexander Kabaev       */
1189f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1190f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1191f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
1192f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1193f8a1b7d9SAlexander Kabaev		   discard_block<_UniformRandomNumberGenerator1,
1194f8a1b7d9SAlexander Kabaev		   __p1, __r1>& __x);
1195f8a1b7d9SAlexander Kabaev
1196f8a1b7d9SAlexander Kabaev    private:
1197f8a1b7d9SAlexander Kabaev      base_type _M_b;
1198f8a1b7d9SAlexander Kabaev      int       _M_n;
1199f8a1b7d9SAlexander Kabaev    };
1200f8a1b7d9SAlexander Kabaev
1201f8a1b7d9SAlexander Kabaev
1202f8a1b7d9SAlexander Kabaev  /**
1203f8a1b7d9SAlexander Kabaev   * James's luxury-level-3 integer adaptation of Luescher's generator.
1204f8a1b7d9SAlexander Kabaev   */
1205f8a1b7d9SAlexander Kabaev  typedef discard_block<
1206f8a1b7d9SAlexander Kabaev    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1207f8a1b7d9SAlexander Kabaev      223,
1208f8a1b7d9SAlexander Kabaev      24
1209f8a1b7d9SAlexander Kabaev      > ranlux3;
1210f8a1b7d9SAlexander Kabaev
1211f8a1b7d9SAlexander Kabaev  /**
1212f8a1b7d9SAlexander Kabaev   * James's luxury-level-4 integer adaptation of Luescher's generator.
1213f8a1b7d9SAlexander Kabaev   */
1214f8a1b7d9SAlexander Kabaev  typedef discard_block<
1215f8a1b7d9SAlexander Kabaev    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1216f8a1b7d9SAlexander Kabaev      389,
1217f8a1b7d9SAlexander Kabaev      24
1218f8a1b7d9SAlexander Kabaev      > ranlux4;
1219f8a1b7d9SAlexander Kabaev
1220f8a1b7d9SAlexander Kabaev  typedef discard_block<
1221f8a1b7d9SAlexander Kabaev    subtract_with_carry_01<float, 24, 10, 24>,
1222f8a1b7d9SAlexander Kabaev      223,
1223f8a1b7d9SAlexander Kabaev      24
1224f8a1b7d9SAlexander Kabaev      > ranlux3_01;
1225f8a1b7d9SAlexander Kabaev
1226f8a1b7d9SAlexander Kabaev  typedef discard_block<
1227f8a1b7d9SAlexander Kabaev    subtract_with_carry_01<float, 24, 10, 24>,
1228f8a1b7d9SAlexander Kabaev      389,
1229f8a1b7d9SAlexander Kabaev      24
1230f8a1b7d9SAlexander Kabaev      > ranlux4_01;
1231f8a1b7d9SAlexander Kabaev
1232f8a1b7d9SAlexander Kabaev
1233f8a1b7d9SAlexander Kabaev  /**
1234f8a1b7d9SAlexander Kabaev   * A random number generator adaptor class that combines two random number
1235f8a1b7d9SAlexander Kabaev   * generator engines into a single output sequence.
1236f8a1b7d9SAlexander Kabaev   */
1237f8a1b7d9SAlexander Kabaev  template<class _UniformRandomNumberGenerator1, int __s1,
1238f8a1b7d9SAlexander Kabaev	   class _UniformRandomNumberGenerator2, int __s2>
1239f8a1b7d9SAlexander Kabaev    class xor_combine
1240f8a1b7d9SAlexander Kabaev    {
1241f8a1b7d9SAlexander Kabaev      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
1242f8a1b7d9SAlexander Kabaev      //                          result_type, ArithmeticTypeConcept)
1243f8a1b7d9SAlexander Kabaev      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
1244f8a1b7d9SAlexander Kabaev      //                          result_type, ArithmeticTypeConcept)
1245f8a1b7d9SAlexander Kabaev
1246f8a1b7d9SAlexander Kabaev    public:
1247f8a1b7d9SAlexander Kabaev      /** The type of the the first underlying generator engine. */
1248f8a1b7d9SAlexander Kabaev      typedef _UniformRandomNumberGenerator1   base1_type;
1249f8a1b7d9SAlexander Kabaev      /** The type of the the second underlying generator engine. */
1250f8a1b7d9SAlexander Kabaev      typedef _UniformRandomNumberGenerator2   base2_type;
1251f8a1b7d9SAlexander Kabaev
1252f8a1b7d9SAlexander Kabaev    private:
1253f8a1b7d9SAlexander Kabaev      typedef typename base1_type::result_type _Result_type1;
1254f8a1b7d9SAlexander Kabaev      typedef typename base2_type::result_type _Result_type2;
1255f8a1b7d9SAlexander Kabaev
1256f8a1b7d9SAlexander Kabaev    public:
1257f8a1b7d9SAlexander Kabaev      /** The type of the generated random value. */
1258f8a1b7d9SAlexander Kabaev      typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
1259f8a1b7d9SAlexander Kabaev						      > sizeof(_Result_type2)),
1260f8a1b7d9SAlexander Kabaev	_Result_type1, _Result_type2>::__type result_type;
1261f8a1b7d9SAlexander Kabaev
1262f8a1b7d9SAlexander Kabaev      // parameter values
1263f8a1b7d9SAlexander Kabaev      static const int shift1 = __s1;
1264f8a1b7d9SAlexander Kabaev      static const int shift2 = __s2;
1265f8a1b7d9SAlexander Kabaev
1266f8a1b7d9SAlexander Kabaev      // constructors and member function
1267f8a1b7d9SAlexander Kabaev      xor_combine()
1268f8a1b7d9SAlexander Kabaev      : _M_b1(), _M_b2()
1269f8a1b7d9SAlexander Kabaev      { _M_initialize_max(); }
1270f8a1b7d9SAlexander Kabaev
1271f8a1b7d9SAlexander Kabaev      xor_combine(const base1_type& __rng1, const base2_type& __rng2)
1272f8a1b7d9SAlexander Kabaev      : _M_b1(__rng1), _M_b2(__rng2)
1273f8a1b7d9SAlexander Kabaev      { _M_initialize_max(); }
1274f8a1b7d9SAlexander Kabaev
1275f8a1b7d9SAlexander Kabaev      xor_combine(unsigned long __s)
1276f8a1b7d9SAlexander Kabaev      : _M_b1(__s), _M_b2(__s + 1)
1277f8a1b7d9SAlexander Kabaev      { _M_initialize_max(); }
1278f8a1b7d9SAlexander Kabaev
1279f8a1b7d9SAlexander Kabaev      template<class _Gen>
1280f8a1b7d9SAlexander Kabaev        xor_combine(_Gen& __g)
1281f8a1b7d9SAlexander Kabaev	: _M_b1(__g), _M_b2(__g)
1282f8a1b7d9SAlexander Kabaev        { _M_initialize_max(); }
1283f8a1b7d9SAlexander Kabaev
1284f8a1b7d9SAlexander Kabaev      void
1285f8a1b7d9SAlexander Kabaev      seed()
1286f8a1b7d9SAlexander Kabaev      {
1287f8a1b7d9SAlexander Kabaev	_M_b1.seed();
1288f8a1b7d9SAlexander Kabaev	_M_b2.seed();
1289f8a1b7d9SAlexander Kabaev      }
1290f8a1b7d9SAlexander Kabaev
1291f8a1b7d9SAlexander Kabaev      template<class _Gen>
1292f8a1b7d9SAlexander Kabaev        void
1293f8a1b7d9SAlexander Kabaev        seed(_Gen& __g)
1294f8a1b7d9SAlexander Kabaev        {
1295f8a1b7d9SAlexander Kabaev	  _M_b1.seed(__g);
1296f8a1b7d9SAlexander Kabaev	  _M_b2.seed(__g);
1297f8a1b7d9SAlexander Kabaev	}
1298f8a1b7d9SAlexander Kabaev
1299f8a1b7d9SAlexander Kabaev      const base1_type&
1300f8a1b7d9SAlexander Kabaev      base1() const
1301f8a1b7d9SAlexander Kabaev      { return _M_b1; }
1302f8a1b7d9SAlexander Kabaev
1303f8a1b7d9SAlexander Kabaev      const base2_type&
1304f8a1b7d9SAlexander Kabaev      base2() const
1305f8a1b7d9SAlexander Kabaev      { return _M_b2; }
1306f8a1b7d9SAlexander Kabaev
1307f8a1b7d9SAlexander Kabaev      result_type
1308f8a1b7d9SAlexander Kabaev      min() const
1309f8a1b7d9SAlexander Kabaev      { return 0; }
1310f8a1b7d9SAlexander Kabaev
1311f8a1b7d9SAlexander Kabaev      result_type
1312f8a1b7d9SAlexander Kabaev      max() const
1313f8a1b7d9SAlexander Kabaev      { return _M_max; }
1314f8a1b7d9SAlexander Kabaev
1315f8a1b7d9SAlexander Kabaev      /**
1316f8a1b7d9SAlexander Kabaev       * Gets the next random number in the sequence.
1317f8a1b7d9SAlexander Kabaev       */
1318f8a1b7d9SAlexander Kabaev      // NB: Not exactly the TR1 formula, per N2079 instead.
1319f8a1b7d9SAlexander Kabaev      result_type
1320f8a1b7d9SAlexander Kabaev      operator()()
1321f8a1b7d9SAlexander Kabaev      {
1322f8a1b7d9SAlexander Kabaev	return ((result_type(_M_b1() - _M_b1.min()) << shift1)
1323f8a1b7d9SAlexander Kabaev		^ (result_type(_M_b2() - _M_b2.min()) << shift2));
1324f8a1b7d9SAlexander Kabaev      }
1325f8a1b7d9SAlexander Kabaev
1326f8a1b7d9SAlexander Kabaev      /**
1327f8a1b7d9SAlexander Kabaev       * Compares two %xor_combine random number generator objects of
1328f8a1b7d9SAlexander Kabaev       * the same type for equality.
1329f8a1b7d9SAlexander Kabaev       *
1330f8a1b7d9SAlexander Kabaev       * @param __lhs A %xor_combine random number generator object.
1331f8a1b7d9SAlexander Kabaev       * @param __rhs Another %xor_combine random number generator
1332f8a1b7d9SAlexander Kabaev       *              object.
1333f8a1b7d9SAlexander Kabaev       *
1334f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are equal, false otherwise.
1335f8a1b7d9SAlexander Kabaev       */
1336f8a1b7d9SAlexander Kabaev      friend bool
1337f8a1b7d9SAlexander Kabaev      operator==(const xor_combine& __lhs, const xor_combine& __rhs)
1338f8a1b7d9SAlexander Kabaev      {
1339f8a1b7d9SAlexander Kabaev	return (__lhs.base1() == __rhs.base1())
1340f8a1b7d9SAlexander Kabaev	        && (__lhs.base2() == __rhs.base2());
1341f8a1b7d9SAlexander Kabaev      }
1342f8a1b7d9SAlexander Kabaev
1343f8a1b7d9SAlexander Kabaev      /**
1344f8a1b7d9SAlexander Kabaev       * Compares two %xor_combine random number generator objects of
1345f8a1b7d9SAlexander Kabaev       * the same type for inequality.
1346f8a1b7d9SAlexander Kabaev       *
1347f8a1b7d9SAlexander Kabaev       * @param __lhs A %xor_combine random number generator object.
1348f8a1b7d9SAlexander Kabaev       * @param __rhs Another %xor_combine random number generator
1349f8a1b7d9SAlexander Kabaev       *              object.
1350f8a1b7d9SAlexander Kabaev       *
1351f8a1b7d9SAlexander Kabaev       * @returns true if the two objects are not equal, false otherwise.
1352f8a1b7d9SAlexander Kabaev       */
1353f8a1b7d9SAlexander Kabaev      friend bool
1354f8a1b7d9SAlexander Kabaev      operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
1355f8a1b7d9SAlexander Kabaev      { return !(__lhs == __rhs); }
1356f8a1b7d9SAlexander Kabaev
1357f8a1b7d9SAlexander Kabaev      /**
1358f8a1b7d9SAlexander Kabaev       * Inserts the current state of a %xor_combine random number
1359f8a1b7d9SAlexander Kabaev       * generator engine @p __x into the output stream @p __os.
1360f8a1b7d9SAlexander Kabaev       *
1361f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
1362f8a1b7d9SAlexander Kabaev       * @param __x  A %xor_combine random number generator engine.
1363f8a1b7d9SAlexander Kabaev       *
1364f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
1365f8a1b7d9SAlexander Kabaev       * an error state.
1366f8a1b7d9SAlexander Kabaev       */
1367f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator11, int __s11,
1368f8a1b7d9SAlexander Kabaev	       class _UniformRandomNumberGenerator21, int __s21,
1369f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1370f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
1371f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1372f8a1b7d9SAlexander Kabaev		   const xor_combine<_UniformRandomNumberGenerator11, __s11,
1373f8a1b7d9SAlexander Kabaev		   _UniformRandomNumberGenerator21, __s21>& __x);
1374f8a1b7d9SAlexander Kabaev
1375f8a1b7d9SAlexander Kabaev      /**
1376f8a1b7d9SAlexander Kabaev       * Extracts the current state of a %xor_combine random number
1377f8a1b7d9SAlexander Kabaev       * generator engine @p __x from the input stream @p __is.
1378f8a1b7d9SAlexander Kabaev       *
1379f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
1380f8a1b7d9SAlexander Kabaev       * @param __x  A %xor_combine random number generator engine.
1381f8a1b7d9SAlexander Kabaev       *
1382f8a1b7d9SAlexander Kabaev       * @returns The input stream with the state of @p __x extracted or in
1383f8a1b7d9SAlexander Kabaev       * an error state.
1384f8a1b7d9SAlexander Kabaev       */
1385f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator11, int __s11,
1386f8a1b7d9SAlexander Kabaev	       class _UniformRandomNumberGenerator21, int __s21,
1387f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1388f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
1389f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1390f8a1b7d9SAlexander Kabaev		   xor_combine<_UniformRandomNumberGenerator11, __s11,
1391f8a1b7d9SAlexander Kabaev		   _UniformRandomNumberGenerator21, __s21>& __x);
1392f8a1b7d9SAlexander Kabaev
1393f8a1b7d9SAlexander Kabaev    private:
1394f8a1b7d9SAlexander Kabaev      void
1395f8a1b7d9SAlexander Kabaev      _M_initialize_max();
1396f8a1b7d9SAlexander Kabaev
1397f8a1b7d9SAlexander Kabaev      result_type
1398f8a1b7d9SAlexander Kabaev      _M_initialize_max_aux(result_type, result_type, int);
1399f8a1b7d9SAlexander Kabaev
1400f8a1b7d9SAlexander Kabaev      base1_type  _M_b1;
1401f8a1b7d9SAlexander Kabaev      base2_type  _M_b2;
1402f8a1b7d9SAlexander Kabaev      result_type _M_max;
1403f8a1b7d9SAlexander Kabaev    };
1404f8a1b7d9SAlexander Kabaev
1405f8a1b7d9SAlexander Kabaev
1406f8a1b7d9SAlexander Kabaev  /**
1407f8a1b7d9SAlexander Kabaev   * A standard interface to a platform-specific non-deterministic
1408f8a1b7d9SAlexander Kabaev   * random number generator (if any are available).
1409f8a1b7d9SAlexander Kabaev   */
1410f8a1b7d9SAlexander Kabaev  class random_device
1411f8a1b7d9SAlexander Kabaev  {
1412f8a1b7d9SAlexander Kabaev  public:
1413f8a1b7d9SAlexander Kabaev    // types
1414f8a1b7d9SAlexander Kabaev    typedef unsigned int result_type;
1415f8a1b7d9SAlexander Kabaev
1416f8a1b7d9SAlexander Kabaev    // constructors, destructors and member functions
1417f8a1b7d9SAlexander Kabaev
1418f8a1b7d9SAlexander Kabaev#ifdef _GLIBCXX_USE_RANDOM_TR1
1419f8a1b7d9SAlexander Kabaev
1420f8a1b7d9SAlexander Kabaev    explicit
1421f8a1b7d9SAlexander Kabaev    random_device(const std::string& __token = "/dev/urandom")
1422f8a1b7d9SAlexander Kabaev    {
1423f8a1b7d9SAlexander Kabaev      if ((__token != "/dev/urandom" && __token != "/dev/random")
1424f8a1b7d9SAlexander Kabaev	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
1425f8a1b7d9SAlexander Kabaev	std::__throw_runtime_error(__N("random_device::"
1426f8a1b7d9SAlexander Kabaev				       "random_device(const std::string&)"));
1427f8a1b7d9SAlexander Kabaev    }
1428f8a1b7d9SAlexander Kabaev
1429f8a1b7d9SAlexander Kabaev    ~random_device()
1430f8a1b7d9SAlexander Kabaev    { std::fclose(_M_file); }
1431f8a1b7d9SAlexander Kabaev
1432f8a1b7d9SAlexander Kabaev#else
1433f8a1b7d9SAlexander Kabaev
1434f8a1b7d9SAlexander Kabaev    explicit
1435f8a1b7d9SAlexander Kabaev    random_device(const std::string& __token = "mt19937")
1436f8a1b7d9SAlexander Kabaev    : _M_mt(_M_strtoul(__token)) { }
1437f8a1b7d9SAlexander Kabaev
1438f8a1b7d9SAlexander Kabaev  private:
1439f8a1b7d9SAlexander Kabaev    static unsigned long
1440f8a1b7d9SAlexander Kabaev    _M_strtoul(const std::string& __str)
1441f8a1b7d9SAlexander Kabaev    {
1442f8a1b7d9SAlexander Kabaev      unsigned long __ret = 5489UL;
1443f8a1b7d9SAlexander Kabaev      if (__str != "mt19937")
1444f8a1b7d9SAlexander Kabaev	{
1445f8a1b7d9SAlexander Kabaev	  const char* __nptr = __str.c_str();
1446f8a1b7d9SAlexander Kabaev	  char* __endptr;
1447f8a1b7d9SAlexander Kabaev	  __ret = std::strtoul(__nptr, &__endptr, 0);
1448f8a1b7d9SAlexander Kabaev	  if (*__nptr == '\0' || *__endptr != '\0')
1449f8a1b7d9SAlexander Kabaev	    std::__throw_runtime_error(__N("random_device::_M_strtoul"
1450f8a1b7d9SAlexander Kabaev					   "(const std::string&)"));
1451f8a1b7d9SAlexander Kabaev	}
1452f8a1b7d9SAlexander Kabaev      return __ret;
1453f8a1b7d9SAlexander Kabaev    }
1454f8a1b7d9SAlexander Kabaev
1455f8a1b7d9SAlexander Kabaev  public:
1456f8a1b7d9SAlexander Kabaev
1457f8a1b7d9SAlexander Kabaev#endif
1458f8a1b7d9SAlexander Kabaev
1459f8a1b7d9SAlexander Kabaev    result_type
1460f8a1b7d9SAlexander Kabaev    min() const
1461f8a1b7d9SAlexander Kabaev    { return std::numeric_limits<result_type>::min(); }
1462f8a1b7d9SAlexander Kabaev
1463f8a1b7d9SAlexander Kabaev    result_type
1464f8a1b7d9SAlexander Kabaev    max() const
1465f8a1b7d9SAlexander Kabaev    { return std::numeric_limits<result_type>::max(); }
1466f8a1b7d9SAlexander Kabaev
1467f8a1b7d9SAlexander Kabaev    double
1468f8a1b7d9SAlexander Kabaev    entropy() const
1469f8a1b7d9SAlexander Kabaev    { return 0.0; }
1470f8a1b7d9SAlexander Kabaev
1471f8a1b7d9SAlexander Kabaev    result_type
1472f8a1b7d9SAlexander Kabaev    operator()()
1473f8a1b7d9SAlexander Kabaev    {
1474f8a1b7d9SAlexander Kabaev#ifdef _GLIBCXX_USE_RANDOM_TR1
1475f8a1b7d9SAlexander Kabaev      result_type __ret;
1476f8a1b7d9SAlexander Kabaev      std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
1477f8a1b7d9SAlexander Kabaev		 1, _M_file);
1478f8a1b7d9SAlexander Kabaev      return __ret;
1479f8a1b7d9SAlexander Kabaev#else
1480f8a1b7d9SAlexander Kabaev      return _M_mt();
1481f8a1b7d9SAlexander Kabaev#endif
1482f8a1b7d9SAlexander Kabaev    }
1483f8a1b7d9SAlexander Kabaev
1484f8a1b7d9SAlexander Kabaev  private:
1485f8a1b7d9SAlexander Kabaev    random_device(const random_device&);
1486f8a1b7d9SAlexander Kabaev    void operator=(const random_device&);
1487f8a1b7d9SAlexander Kabaev
1488f8a1b7d9SAlexander Kabaev#ifdef _GLIBCXX_USE_RANDOM_TR1
1489f8a1b7d9SAlexander Kabaev    FILE*        _M_file;
1490f8a1b7d9SAlexander Kabaev#else
1491f8a1b7d9SAlexander Kabaev    mt19937      _M_mt;
1492f8a1b7d9SAlexander Kabaev#endif
1493f8a1b7d9SAlexander Kabaev  };
1494f8a1b7d9SAlexander Kabaev
1495f8a1b7d9SAlexander Kabaev  /* @} */ // group tr1_random_generators
1496f8a1b7d9SAlexander Kabaev
1497f8a1b7d9SAlexander Kabaev  /**
1498f8a1b7d9SAlexander Kabaev   * @addtogroup tr1_random_distributions Random Number Distributions
1499f8a1b7d9SAlexander Kabaev   * @ingroup tr1_random
1500f8a1b7d9SAlexander Kabaev   * @{
1501f8a1b7d9SAlexander Kabaev   */
1502f8a1b7d9SAlexander Kabaev
1503f8a1b7d9SAlexander Kabaev  /**
1504f8a1b7d9SAlexander Kabaev   * @addtogroup tr1_random_distributions_discrete Discrete Distributions
1505f8a1b7d9SAlexander Kabaev   * @ingroup tr1_random_distributions
1506f8a1b7d9SAlexander Kabaev   * @{
1507f8a1b7d9SAlexander Kabaev   */
1508f8a1b7d9SAlexander Kabaev
1509f8a1b7d9SAlexander Kabaev  /**
1510f8a1b7d9SAlexander Kabaev   * @brief Uniform discrete distribution for random numbers.
1511f8a1b7d9SAlexander Kabaev   * A discrete random distribution on the range @f$[min, max]@f$ with equal
1512f8a1b7d9SAlexander Kabaev   * probability throughout the range.
1513f8a1b7d9SAlexander Kabaev   */
1514f8a1b7d9SAlexander Kabaev  template<typename _IntType = int>
1515f8a1b7d9SAlexander Kabaev    class uniform_int
1516f8a1b7d9SAlexander Kabaev    {
1517f8a1b7d9SAlexander Kabaev      __glibcxx_class_requires(_IntType, _IntegerConcept)
1518f8a1b7d9SAlexander Kabaev
1519f8a1b7d9SAlexander Kabaev    public:
1520f8a1b7d9SAlexander Kabaev      /** The type of the parameters of the distribution. */
1521f8a1b7d9SAlexander Kabaev      typedef _IntType input_type;
1522f8a1b7d9SAlexander Kabaev      /** The type of the range of the distribution. */
1523f8a1b7d9SAlexander Kabaev      typedef _IntType result_type;
1524f8a1b7d9SAlexander Kabaev
1525f8a1b7d9SAlexander Kabaev    public:
1526f8a1b7d9SAlexander Kabaev      /**
1527f8a1b7d9SAlexander Kabaev       * Constructs a uniform distribution object.
1528f8a1b7d9SAlexander Kabaev       */
1529f8a1b7d9SAlexander Kabaev      explicit
1530f8a1b7d9SAlexander Kabaev      uniform_int(_IntType __min = 0, _IntType __max = 9)
1531f8a1b7d9SAlexander Kabaev      : _M_min(__min), _M_max(__max)
1532f8a1b7d9SAlexander Kabaev      {
1533f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
1534f8a1b7d9SAlexander Kabaev      }
1535f8a1b7d9SAlexander Kabaev
1536f8a1b7d9SAlexander Kabaev      /**
1537f8a1b7d9SAlexander Kabaev       * Gets the inclusive lower bound of the distribution range.
1538f8a1b7d9SAlexander Kabaev       */
1539f8a1b7d9SAlexander Kabaev      result_type
1540f8a1b7d9SAlexander Kabaev      min() const
1541f8a1b7d9SAlexander Kabaev      { return _M_min; }
1542f8a1b7d9SAlexander Kabaev
1543f8a1b7d9SAlexander Kabaev      /**
1544f8a1b7d9SAlexander Kabaev       * Gets the inclusive upper bound of the distribution range.
1545f8a1b7d9SAlexander Kabaev       */
1546f8a1b7d9SAlexander Kabaev      result_type
1547f8a1b7d9SAlexander Kabaev      max() const
1548f8a1b7d9SAlexander Kabaev      { return _M_max; }
1549f8a1b7d9SAlexander Kabaev
1550f8a1b7d9SAlexander Kabaev      /**
1551f8a1b7d9SAlexander Kabaev       * Resets the distribution state.
1552f8a1b7d9SAlexander Kabaev       *
1553f8a1b7d9SAlexander Kabaev       * Does nothing for the uniform integer distribution.
1554f8a1b7d9SAlexander Kabaev       */
1555f8a1b7d9SAlexander Kabaev      void
1556f8a1b7d9SAlexander Kabaev      reset() { }
1557f8a1b7d9SAlexander Kabaev
1558f8a1b7d9SAlexander Kabaev      /**
1559f8a1b7d9SAlexander Kabaev       * Gets a uniformly distributed random number in the range
1560f8a1b7d9SAlexander Kabaev       * @f$(min, max)@f$.
1561f8a1b7d9SAlexander Kabaev       */
1562f8a1b7d9SAlexander Kabaev      template<typename _UniformRandomNumberGenerator>
1563f8a1b7d9SAlexander Kabaev        result_type
1564f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng)
1565f8a1b7d9SAlexander Kabaev        {
1566f8a1b7d9SAlexander Kabaev	  typedef typename _UniformRandomNumberGenerator::result_type
1567f8a1b7d9SAlexander Kabaev	    _UResult_type;
1568f8a1b7d9SAlexander Kabaev	  return _M_call(__urng, _M_min, _M_max,
1569f8a1b7d9SAlexander Kabaev			 typename is_integral<_UResult_type>::type());
1570f8a1b7d9SAlexander Kabaev	}
1571f8a1b7d9SAlexander Kabaev
1572f8a1b7d9SAlexander Kabaev      /**
1573f8a1b7d9SAlexander Kabaev       * Gets a uniform random number in the range @f$[0, n)@f$.
1574f8a1b7d9SAlexander Kabaev       *
1575f8a1b7d9SAlexander Kabaev       * This function is aimed at use with std::random_shuffle.
1576f8a1b7d9SAlexander Kabaev       */
1577f8a1b7d9SAlexander Kabaev      template<typename _UniformRandomNumberGenerator>
1578f8a1b7d9SAlexander Kabaev        result_type
1579f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
1580f8a1b7d9SAlexander Kabaev        {
1581f8a1b7d9SAlexander Kabaev	  typedef typename _UniformRandomNumberGenerator::result_type
1582f8a1b7d9SAlexander Kabaev	    _UResult_type;
1583f8a1b7d9SAlexander Kabaev	  return _M_call(__urng, 0, __n - 1,
1584f8a1b7d9SAlexander Kabaev			 typename is_integral<_UResult_type>::type());
1585f8a1b7d9SAlexander Kabaev	}
1586f8a1b7d9SAlexander Kabaev
1587f8a1b7d9SAlexander Kabaev      /**
1588f8a1b7d9SAlexander Kabaev       * Inserts a %uniform_int random number distribution @p __x into the
1589f8a1b7d9SAlexander Kabaev       * output stream @p os.
1590f8a1b7d9SAlexander Kabaev       *
1591f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
1592f8a1b7d9SAlexander Kabaev       * @param __x  A %uniform_int random number distribution.
1593f8a1b7d9SAlexander Kabaev       *
1594f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
1595f8a1b7d9SAlexander Kabaev       * an error state.
1596f8a1b7d9SAlexander Kabaev       */
1597f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _CharT, typename _Traits>
1598f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
1599f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1600f8a1b7d9SAlexander Kabaev		   const uniform_int<_IntType1>& __x);
1601f8a1b7d9SAlexander Kabaev
1602f8a1b7d9SAlexander Kabaev      /**
1603f8a1b7d9SAlexander Kabaev       * Extracts a %unform_int random number distribution
1604f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
1605f8a1b7d9SAlexander Kabaev       *
1606f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
1607f8a1b7d9SAlexander Kabaev       * @param __x  A %uniform_int random number generator engine.
1608f8a1b7d9SAlexander Kabaev       *
1609f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
1610f8a1b7d9SAlexander Kabaev       */
1611f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _CharT, typename _Traits>
1612f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
1613f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1614f8a1b7d9SAlexander Kabaev		   uniform_int<_IntType1>& __x);
1615f8a1b7d9SAlexander Kabaev
1616f8a1b7d9SAlexander Kabaev    private:
1617f8a1b7d9SAlexander Kabaev      template<typename _UniformRandomNumberGenerator>
1618f8a1b7d9SAlexander Kabaev        result_type
1619f8a1b7d9SAlexander Kabaev        _M_call(_UniformRandomNumberGenerator& __urng,
1620f8a1b7d9SAlexander Kabaev		result_type __min, result_type __max, true_type)
16215377a726SMartin Matuska        {
1622*05a636f0SPedro F. Giffuni	  // XXX Must be fixed to also work when __urng.max() - __urng.min()
1623*05a636f0SPedro F. Giffuni	  // is smaller than __max - __min.
16245377a726SMartin Matuska	  typedef typename __gnu_cxx::__add_unsigned<typename
16255377a726SMartin Matuska	    _UniformRandomNumberGenerator::result_type>::__type __utype;
1626*05a636f0SPedro F. Giffuni	  return result_type((__max - __min + 1.0L)
1627*05a636f0SPedro F. Giffuni			     * (__utype(__urng()) - __utype(__urng.min()))
1628*05a636f0SPedro F. Giffuni			     / (__utype(__urng.max())
1629*05a636f0SPedro F. Giffuni				- __utype(__urng.min()) + 1.0L)) + __min;
16305377a726SMartin Matuska	}
1631f8a1b7d9SAlexander Kabaev
1632f8a1b7d9SAlexander Kabaev      template<typename _UniformRandomNumberGenerator>
1633f8a1b7d9SAlexander Kabaev        result_type
1634f8a1b7d9SAlexander Kabaev        _M_call(_UniformRandomNumberGenerator& __urng,
1635f8a1b7d9SAlexander Kabaev		result_type __min, result_type __max, false_type)
1636f8a1b7d9SAlexander Kabaev        {
1637f8a1b7d9SAlexander Kabaev	  return result_type((__urng() - __urng.min())
1638f8a1b7d9SAlexander Kabaev			     / (__urng.max() - __urng.min())
1639f8a1b7d9SAlexander Kabaev			     * (__max - __min + 1)) + __min;
1640f8a1b7d9SAlexander Kabaev	}
1641f8a1b7d9SAlexander Kabaev
1642f8a1b7d9SAlexander Kabaev      _IntType _M_min;
1643f8a1b7d9SAlexander Kabaev      _IntType _M_max;
1644f8a1b7d9SAlexander Kabaev    };
1645f8a1b7d9SAlexander Kabaev
1646f8a1b7d9SAlexander Kabaev
1647f8a1b7d9SAlexander Kabaev  /**
1648f8a1b7d9SAlexander Kabaev   * @brief A Bernoulli random number distribution.
1649f8a1b7d9SAlexander Kabaev   *
1650f8a1b7d9SAlexander Kabaev   * Generates a sequence of true and false values with likelihood @f$ p @f$
1651f8a1b7d9SAlexander Kabaev   * that true will come up and @f$ (1 - p) @f$ that false will appear.
1652f8a1b7d9SAlexander Kabaev   */
1653f8a1b7d9SAlexander Kabaev  class bernoulli_distribution
1654f8a1b7d9SAlexander Kabaev  {
1655f8a1b7d9SAlexander Kabaev  public:
1656f8a1b7d9SAlexander Kabaev    typedef int  input_type;
1657f8a1b7d9SAlexander Kabaev    typedef bool result_type;
1658f8a1b7d9SAlexander Kabaev
1659f8a1b7d9SAlexander Kabaev  public:
1660f8a1b7d9SAlexander Kabaev    /**
1661f8a1b7d9SAlexander Kabaev     * Constructs a Bernoulli distribution with likelihood @p p.
1662f8a1b7d9SAlexander Kabaev     *
1663f8a1b7d9SAlexander Kabaev     * @param __p  [IN]  The likelihood of a true result being returned.  Must
1664f8a1b7d9SAlexander Kabaev     * be in the interval @f$ [0, 1] @f$.
1665f8a1b7d9SAlexander Kabaev     */
1666f8a1b7d9SAlexander Kabaev    explicit
1667f8a1b7d9SAlexander Kabaev    bernoulli_distribution(double __p = 0.5)
1668f8a1b7d9SAlexander Kabaev    : _M_p(__p)
1669f8a1b7d9SAlexander Kabaev    {
1670f8a1b7d9SAlexander Kabaev      _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
1671f8a1b7d9SAlexander Kabaev    }
1672f8a1b7d9SAlexander Kabaev
1673f8a1b7d9SAlexander Kabaev    /**
1674f8a1b7d9SAlexander Kabaev     * Gets the @p p parameter of the distribution.
1675f8a1b7d9SAlexander Kabaev     */
1676f8a1b7d9SAlexander Kabaev    double
1677f8a1b7d9SAlexander Kabaev    p() const
1678f8a1b7d9SAlexander Kabaev    { return _M_p; }
1679f8a1b7d9SAlexander Kabaev
1680f8a1b7d9SAlexander Kabaev    /**
1681f8a1b7d9SAlexander Kabaev     * Resets the distribution state.
1682f8a1b7d9SAlexander Kabaev     *
1683f8a1b7d9SAlexander Kabaev     * Does nothing for a bernoulli distribution.
1684f8a1b7d9SAlexander Kabaev     */
1685f8a1b7d9SAlexander Kabaev    void
1686f8a1b7d9SAlexander Kabaev    reset() { }
1687f8a1b7d9SAlexander Kabaev
1688f8a1b7d9SAlexander Kabaev    /**
1689f8a1b7d9SAlexander Kabaev     * Gets the next value in the Bernoullian sequence.
1690f8a1b7d9SAlexander Kabaev     */
1691f8a1b7d9SAlexander Kabaev    template<class _UniformRandomNumberGenerator>
1692f8a1b7d9SAlexander Kabaev      result_type
1693f8a1b7d9SAlexander Kabaev      operator()(_UniformRandomNumberGenerator& __urng)
1694f8a1b7d9SAlexander Kabaev      {
1695f8a1b7d9SAlexander Kabaev	if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
1696f8a1b7d9SAlexander Kabaev	  return true;
1697f8a1b7d9SAlexander Kabaev	return false;
1698f8a1b7d9SAlexander Kabaev      }
1699f8a1b7d9SAlexander Kabaev
1700f8a1b7d9SAlexander Kabaev    /**
1701f8a1b7d9SAlexander Kabaev     * Inserts a %bernoulli_distribution random number distribution
1702f8a1b7d9SAlexander Kabaev     * @p __x into the output stream @p __os.
1703f8a1b7d9SAlexander Kabaev     *
1704f8a1b7d9SAlexander Kabaev     * @param __os An output stream.
1705f8a1b7d9SAlexander Kabaev     * @param __x  A %bernoulli_distribution random number distribution.
1706f8a1b7d9SAlexander Kabaev     *
1707f8a1b7d9SAlexander Kabaev     * @returns The output stream with the state of @p __x inserted or in
1708f8a1b7d9SAlexander Kabaev     * an error state.
1709f8a1b7d9SAlexander Kabaev     */
1710f8a1b7d9SAlexander Kabaev    template<typename _CharT, typename _Traits>
1711f8a1b7d9SAlexander Kabaev      friend std::basic_ostream<_CharT, _Traits>&
1712f8a1b7d9SAlexander Kabaev      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1713f8a1b7d9SAlexander Kabaev		 const bernoulli_distribution& __x);
1714f8a1b7d9SAlexander Kabaev
1715f8a1b7d9SAlexander Kabaev    /**
1716f8a1b7d9SAlexander Kabaev     * Extracts a %bernoulli_distribution random number distribution
1717f8a1b7d9SAlexander Kabaev     * @p __x from the input stream @p __is.
1718f8a1b7d9SAlexander Kabaev     *
1719f8a1b7d9SAlexander Kabaev     * @param __is An input stream.
1720f8a1b7d9SAlexander Kabaev     * @param __x  A %bernoulli_distribution random number generator engine.
1721f8a1b7d9SAlexander Kabaev     *
1722f8a1b7d9SAlexander Kabaev     * @returns The input stream with @p __x extracted or in an error state.
1723f8a1b7d9SAlexander Kabaev     */
1724f8a1b7d9SAlexander Kabaev    template<typename _CharT, typename _Traits>
1725f8a1b7d9SAlexander Kabaev      friend std::basic_istream<_CharT, _Traits>&
1726f8a1b7d9SAlexander Kabaev      operator>>(std::basic_istream<_CharT, _Traits>& __is,
1727f8a1b7d9SAlexander Kabaev		 bernoulli_distribution& __x)
1728f8a1b7d9SAlexander Kabaev      { return __is >> __x._M_p; }
1729f8a1b7d9SAlexander Kabaev
1730f8a1b7d9SAlexander Kabaev  private:
1731f8a1b7d9SAlexander Kabaev    double _M_p;
1732f8a1b7d9SAlexander Kabaev  };
1733f8a1b7d9SAlexander Kabaev
1734f8a1b7d9SAlexander Kabaev
1735f8a1b7d9SAlexander Kabaev  /**
1736f8a1b7d9SAlexander Kabaev   * @brief A discrete geometric random number distribution.
1737f8a1b7d9SAlexander Kabaev   *
1738f8a1b7d9SAlexander Kabaev   * The formula for the geometric probability mass function is
1739f8a1b7d9SAlexander Kabaev   * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
1740f8a1b7d9SAlexander Kabaev   * distribution.
1741f8a1b7d9SAlexander Kabaev   */
1742f8a1b7d9SAlexander Kabaev  template<typename _IntType = int, typename _RealType = double>
1743f8a1b7d9SAlexander Kabaev    class geometric_distribution
1744f8a1b7d9SAlexander Kabaev    {
1745f8a1b7d9SAlexander Kabaev    public:
1746f8a1b7d9SAlexander Kabaev      // types
1747f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
1748f8a1b7d9SAlexander Kabaev      typedef _IntType  result_type;
1749f8a1b7d9SAlexander Kabaev
1750f8a1b7d9SAlexander Kabaev      // constructors and member function
1751f8a1b7d9SAlexander Kabaev      explicit
1752f8a1b7d9SAlexander Kabaev      geometric_distribution(const _RealType& __p = _RealType(0.5))
1753f8a1b7d9SAlexander Kabaev      : _M_p(__p)
1754f8a1b7d9SAlexander Kabaev      {
1755f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
1756f8a1b7d9SAlexander Kabaev	_M_initialize();
1757f8a1b7d9SAlexander Kabaev      }
1758f8a1b7d9SAlexander Kabaev
1759f8a1b7d9SAlexander Kabaev      /**
1760f8a1b7d9SAlexander Kabaev       * Gets the distribution parameter @p p.
1761f8a1b7d9SAlexander Kabaev       */
1762f8a1b7d9SAlexander Kabaev      _RealType
1763f8a1b7d9SAlexander Kabaev      p() const
1764f8a1b7d9SAlexander Kabaev      { return _M_p; }
1765f8a1b7d9SAlexander Kabaev
1766f8a1b7d9SAlexander Kabaev      void
1767f8a1b7d9SAlexander Kabaev      reset() { }
1768f8a1b7d9SAlexander Kabaev
1769f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
1770f8a1b7d9SAlexander Kabaev        result_type
1771f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng);
1772f8a1b7d9SAlexander Kabaev
1773f8a1b7d9SAlexander Kabaev      /**
1774f8a1b7d9SAlexander Kabaev       * Inserts a %geometric_distribution random number distribution
1775f8a1b7d9SAlexander Kabaev       * @p __x into the output stream @p __os.
1776f8a1b7d9SAlexander Kabaev       *
1777f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
1778f8a1b7d9SAlexander Kabaev       * @param __x  A %geometric_distribution random number distribution.
1779f8a1b7d9SAlexander Kabaev       *
1780f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
1781f8a1b7d9SAlexander Kabaev       * an error state.
1782f8a1b7d9SAlexander Kabaev       */
1783f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _RealType1,
1784f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1785f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
1786f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1787f8a1b7d9SAlexander Kabaev		   const geometric_distribution<_IntType1, _RealType1>& __x);
1788f8a1b7d9SAlexander Kabaev
1789f8a1b7d9SAlexander Kabaev      /**
1790f8a1b7d9SAlexander Kabaev       * Extracts a %geometric_distribution random number distribution
1791f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
1792f8a1b7d9SAlexander Kabaev       *
1793f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
1794f8a1b7d9SAlexander Kabaev       * @param __x  A %geometric_distribution random number generator engine.
1795f8a1b7d9SAlexander Kabaev       *
1796f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
1797f8a1b7d9SAlexander Kabaev       */
1798f8a1b7d9SAlexander Kabaev      template<typename _CharT, typename _Traits>
1799f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
1800f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1801f8a1b7d9SAlexander Kabaev		   geometric_distribution& __x)
1802f8a1b7d9SAlexander Kabaev        {
1803f8a1b7d9SAlexander Kabaev	  __is >> __x._M_p;
1804f8a1b7d9SAlexander Kabaev	  __x._M_initialize();
1805f8a1b7d9SAlexander Kabaev	  return __is;
1806f8a1b7d9SAlexander Kabaev	}
1807f8a1b7d9SAlexander Kabaev
1808f8a1b7d9SAlexander Kabaev    private:
1809f8a1b7d9SAlexander Kabaev      void
1810f8a1b7d9SAlexander Kabaev      _M_initialize()
1811f8a1b7d9SAlexander Kabaev      { _M_log_p = std::log(_M_p); }
1812f8a1b7d9SAlexander Kabaev
1813f8a1b7d9SAlexander Kabaev      _RealType _M_p;
1814f8a1b7d9SAlexander Kabaev      _RealType _M_log_p;
1815f8a1b7d9SAlexander Kabaev    };
1816f8a1b7d9SAlexander Kabaev
1817f8a1b7d9SAlexander Kabaev
1818f8a1b7d9SAlexander Kabaev  template<typename _RealType>
1819f8a1b7d9SAlexander Kabaev    class normal_distribution;
1820f8a1b7d9SAlexander Kabaev
1821f8a1b7d9SAlexander Kabaev  /**
1822f8a1b7d9SAlexander Kabaev   * @brief A discrete Poisson random number distribution.
1823f8a1b7d9SAlexander Kabaev   *
1824f8a1b7d9SAlexander Kabaev   * The formula for the poisson probability mass function is
1825f8a1b7d9SAlexander Kabaev   * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
1826f8a1b7d9SAlexander Kabaev   * parameter of the distribution.
1827f8a1b7d9SAlexander Kabaev   */
1828f8a1b7d9SAlexander Kabaev  template<typename _IntType = int, typename _RealType = double>
1829f8a1b7d9SAlexander Kabaev    class poisson_distribution
1830f8a1b7d9SAlexander Kabaev    {
1831f8a1b7d9SAlexander Kabaev    public:
1832f8a1b7d9SAlexander Kabaev      // types
1833f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
1834f8a1b7d9SAlexander Kabaev      typedef _IntType  result_type;
1835f8a1b7d9SAlexander Kabaev
1836f8a1b7d9SAlexander Kabaev      // constructors and member function
1837f8a1b7d9SAlexander Kabaev      explicit
1838f8a1b7d9SAlexander Kabaev      poisson_distribution(const _RealType& __mean = _RealType(1))
1839f8a1b7d9SAlexander Kabaev      : _M_mean(__mean), _M_nd()
1840f8a1b7d9SAlexander Kabaev      {
1841f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
1842f8a1b7d9SAlexander Kabaev	_M_initialize();
1843f8a1b7d9SAlexander Kabaev      }
1844f8a1b7d9SAlexander Kabaev
1845f8a1b7d9SAlexander Kabaev      /**
1846f8a1b7d9SAlexander Kabaev       * Gets the distribution parameter @p mean.
1847f8a1b7d9SAlexander Kabaev       */
1848f8a1b7d9SAlexander Kabaev      _RealType
1849f8a1b7d9SAlexander Kabaev      mean() const
1850f8a1b7d9SAlexander Kabaev      { return _M_mean; }
1851f8a1b7d9SAlexander Kabaev
1852f8a1b7d9SAlexander Kabaev      void
1853f8a1b7d9SAlexander Kabaev      reset()
1854f8a1b7d9SAlexander Kabaev      { _M_nd.reset(); }
1855f8a1b7d9SAlexander Kabaev
1856f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
1857f8a1b7d9SAlexander Kabaev        result_type
1858f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng);
1859f8a1b7d9SAlexander Kabaev
1860f8a1b7d9SAlexander Kabaev      /**
1861f8a1b7d9SAlexander Kabaev       * Inserts a %poisson_distribution random number distribution
1862f8a1b7d9SAlexander Kabaev       * @p __x into the output stream @p __os.
1863f8a1b7d9SAlexander Kabaev       *
1864f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
1865f8a1b7d9SAlexander Kabaev       * @param __x  A %poisson_distribution random number distribution.
1866f8a1b7d9SAlexander Kabaev       *
1867f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
1868f8a1b7d9SAlexander Kabaev       * an error state.
1869f8a1b7d9SAlexander Kabaev       */
1870f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _RealType1,
1871f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1872f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
1873f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1874f8a1b7d9SAlexander Kabaev		   const poisson_distribution<_IntType1, _RealType1>& __x);
1875f8a1b7d9SAlexander Kabaev
1876f8a1b7d9SAlexander Kabaev      /**
1877f8a1b7d9SAlexander Kabaev       * Extracts a %poisson_distribution random number distribution
1878f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
1879f8a1b7d9SAlexander Kabaev       *
1880f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
1881f8a1b7d9SAlexander Kabaev       * @param __x  A %poisson_distribution random number generator engine.
1882f8a1b7d9SAlexander Kabaev       *
1883f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
1884f8a1b7d9SAlexander Kabaev       */
1885f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _RealType1,
1886f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1887f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
1888f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1889f8a1b7d9SAlexander Kabaev		   poisson_distribution<_IntType1, _RealType1>& __x);
1890f8a1b7d9SAlexander Kabaev
1891f8a1b7d9SAlexander Kabaev    private:
1892f8a1b7d9SAlexander Kabaev      void
1893f8a1b7d9SAlexander Kabaev      _M_initialize();
1894f8a1b7d9SAlexander Kabaev
1895f8a1b7d9SAlexander Kabaev      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
1896f8a1b7d9SAlexander Kabaev      normal_distribution<_RealType> _M_nd;
1897f8a1b7d9SAlexander Kabaev
1898f8a1b7d9SAlexander Kabaev      _RealType _M_mean;
1899f8a1b7d9SAlexander Kabaev
1900f8a1b7d9SAlexander Kabaev      // Hosts either log(mean) or the threshold of the simple method.
1901f8a1b7d9SAlexander Kabaev      _RealType _M_lm_thr;
1902f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_MATH_TR1
1903f8a1b7d9SAlexander Kabaev      _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
1904f8a1b7d9SAlexander Kabaev#endif
1905f8a1b7d9SAlexander Kabaev    };
1906f8a1b7d9SAlexander Kabaev
1907f8a1b7d9SAlexander Kabaev
1908f8a1b7d9SAlexander Kabaev  /**
1909f8a1b7d9SAlexander Kabaev   * @brief A discrete binomial random number distribution.
1910f8a1b7d9SAlexander Kabaev   *
1911f8a1b7d9SAlexander Kabaev   * The formula for the binomial probability mass function is
1912f8a1b7d9SAlexander Kabaev   * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
1913f8a1b7d9SAlexander Kabaev   * and @f$ p @f$ are the parameters of the distribution.
1914f8a1b7d9SAlexander Kabaev   */
1915f8a1b7d9SAlexander Kabaev  template<typename _IntType = int, typename _RealType = double>
1916f8a1b7d9SAlexander Kabaev    class binomial_distribution
1917f8a1b7d9SAlexander Kabaev    {
1918f8a1b7d9SAlexander Kabaev    public:
1919f8a1b7d9SAlexander Kabaev      // types
1920f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
1921f8a1b7d9SAlexander Kabaev      typedef _IntType  result_type;
1922f8a1b7d9SAlexander Kabaev
1923f8a1b7d9SAlexander Kabaev      // constructors and member function
1924f8a1b7d9SAlexander Kabaev      explicit
1925f8a1b7d9SAlexander Kabaev      binomial_distribution(_IntType __t = 1,
1926f8a1b7d9SAlexander Kabaev			    const _RealType& __p = _RealType(0.5))
1927f8a1b7d9SAlexander Kabaev      : _M_t(__t), _M_p(__p), _M_nd()
1928f8a1b7d9SAlexander Kabaev      {
1929f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
1930f8a1b7d9SAlexander Kabaev	_M_initialize();
1931f8a1b7d9SAlexander Kabaev      }
1932f8a1b7d9SAlexander Kabaev
1933f8a1b7d9SAlexander Kabaev      /**
1934f8a1b7d9SAlexander Kabaev       * Gets the distribution @p t parameter.
1935f8a1b7d9SAlexander Kabaev       */
1936f8a1b7d9SAlexander Kabaev      _IntType
1937f8a1b7d9SAlexander Kabaev      t() const
1938f8a1b7d9SAlexander Kabaev      { return _M_t; }
1939f8a1b7d9SAlexander Kabaev
1940f8a1b7d9SAlexander Kabaev      /**
1941f8a1b7d9SAlexander Kabaev       * Gets the distribution @p p parameter.
1942f8a1b7d9SAlexander Kabaev       */
1943f8a1b7d9SAlexander Kabaev      _RealType
1944f8a1b7d9SAlexander Kabaev      p() const
1945f8a1b7d9SAlexander Kabaev      { return _M_p; }
1946f8a1b7d9SAlexander Kabaev
1947f8a1b7d9SAlexander Kabaev      void
1948f8a1b7d9SAlexander Kabaev      reset()
1949f8a1b7d9SAlexander Kabaev      { _M_nd.reset(); }
1950f8a1b7d9SAlexander Kabaev
1951f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
1952f8a1b7d9SAlexander Kabaev        result_type
1953f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng);
1954f8a1b7d9SAlexander Kabaev
1955f8a1b7d9SAlexander Kabaev      /**
1956f8a1b7d9SAlexander Kabaev       * Inserts a %binomial_distribution random number distribution
1957f8a1b7d9SAlexander Kabaev       * @p __x into the output stream @p __os.
1958f8a1b7d9SAlexander Kabaev       *
1959f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
1960f8a1b7d9SAlexander Kabaev       * @param __x  A %binomial_distribution random number distribution.
1961f8a1b7d9SAlexander Kabaev       *
1962f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
1963f8a1b7d9SAlexander Kabaev       * an error state.
1964f8a1b7d9SAlexander Kabaev       */
1965f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _RealType1,
1966f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1967f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
1968f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1969f8a1b7d9SAlexander Kabaev		   const binomial_distribution<_IntType1, _RealType1>& __x);
1970f8a1b7d9SAlexander Kabaev
1971f8a1b7d9SAlexander Kabaev      /**
1972f8a1b7d9SAlexander Kabaev       * Extracts a %binomial_distribution random number distribution
1973f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
1974f8a1b7d9SAlexander Kabaev       *
1975f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
1976f8a1b7d9SAlexander Kabaev       * @param __x  A %binomial_distribution random number generator engine.
1977f8a1b7d9SAlexander Kabaev       *
1978f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
1979f8a1b7d9SAlexander Kabaev       */
1980f8a1b7d9SAlexander Kabaev      template<typename _IntType1, typename _RealType1,
1981f8a1b7d9SAlexander Kabaev	       typename _CharT, typename _Traits>
1982f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
1983f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1984f8a1b7d9SAlexander Kabaev		   binomial_distribution<_IntType1, _RealType1>& __x);
1985f8a1b7d9SAlexander Kabaev
1986f8a1b7d9SAlexander Kabaev    private:
1987f8a1b7d9SAlexander Kabaev      void
1988f8a1b7d9SAlexander Kabaev      _M_initialize();
1989f8a1b7d9SAlexander Kabaev
1990f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
1991f8a1b7d9SAlexander Kabaev        result_type
1992f8a1b7d9SAlexander Kabaev        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
1993f8a1b7d9SAlexander Kabaev
1994f8a1b7d9SAlexander Kabaev      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
1995f8a1b7d9SAlexander Kabaev      normal_distribution<_RealType> _M_nd;
1996f8a1b7d9SAlexander Kabaev
1997f8a1b7d9SAlexander Kabaev      _RealType _M_q;
1998f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_MATH_TR1
1999f8a1b7d9SAlexander Kabaev      _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
2000f8a1b7d9SAlexander Kabaev	        _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
2001f8a1b7d9SAlexander Kabaev#endif
2002f8a1b7d9SAlexander Kabaev      _RealType _M_p;
2003f8a1b7d9SAlexander Kabaev      _IntType  _M_t;
2004f8a1b7d9SAlexander Kabaev
2005f8a1b7d9SAlexander Kabaev      bool      _M_easy;
2006f8a1b7d9SAlexander Kabaev    };
2007f8a1b7d9SAlexander Kabaev
2008f8a1b7d9SAlexander Kabaev  /* @} */ // group tr1_random_distributions_discrete
2009f8a1b7d9SAlexander Kabaev
2010f8a1b7d9SAlexander Kabaev  /**
2011f8a1b7d9SAlexander Kabaev   * @addtogroup tr1_random_distributions_continuous Continuous Distributions
2012f8a1b7d9SAlexander Kabaev   * @ingroup tr1_random_distributions
2013f8a1b7d9SAlexander Kabaev   * @{
2014f8a1b7d9SAlexander Kabaev   */
2015f8a1b7d9SAlexander Kabaev
2016f8a1b7d9SAlexander Kabaev  /**
2017f8a1b7d9SAlexander Kabaev   * @brief Uniform continuous distribution for random numbers.
2018f8a1b7d9SAlexander Kabaev   *
2019f8a1b7d9SAlexander Kabaev   * A continuous random distribution on the range [min, max) with equal
2020f8a1b7d9SAlexander Kabaev   * probability throughout the range.  The URNG should be real-valued and
2021f8a1b7d9SAlexander Kabaev   * deliver number in the range [0, 1).
2022f8a1b7d9SAlexander Kabaev   */
2023f8a1b7d9SAlexander Kabaev  template<typename _RealType = double>
2024f8a1b7d9SAlexander Kabaev    class uniform_real
2025f8a1b7d9SAlexander Kabaev    {
2026f8a1b7d9SAlexander Kabaev    public:
2027f8a1b7d9SAlexander Kabaev      // types
2028f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
2029f8a1b7d9SAlexander Kabaev      typedef _RealType result_type;
2030f8a1b7d9SAlexander Kabaev
2031f8a1b7d9SAlexander Kabaev    public:
2032f8a1b7d9SAlexander Kabaev      /**
2033f8a1b7d9SAlexander Kabaev       * Constructs a uniform_real object.
2034f8a1b7d9SAlexander Kabaev       *
2035f8a1b7d9SAlexander Kabaev       * @param __min [IN]  The lower bound of the distribution.
2036f8a1b7d9SAlexander Kabaev       * @param __max [IN]  The upper bound of the distribution.
2037f8a1b7d9SAlexander Kabaev       */
2038f8a1b7d9SAlexander Kabaev      explicit
2039f8a1b7d9SAlexander Kabaev      uniform_real(_RealType __min = _RealType(0),
2040f8a1b7d9SAlexander Kabaev		   _RealType __max = _RealType(1))
2041f8a1b7d9SAlexander Kabaev      : _M_min(__min), _M_max(__max)
2042f8a1b7d9SAlexander Kabaev      {
2043f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
2044f8a1b7d9SAlexander Kabaev      }
2045f8a1b7d9SAlexander Kabaev
2046f8a1b7d9SAlexander Kabaev      result_type
2047f8a1b7d9SAlexander Kabaev      min() const
2048f8a1b7d9SAlexander Kabaev      { return _M_min; }
2049f8a1b7d9SAlexander Kabaev
2050f8a1b7d9SAlexander Kabaev      result_type
2051f8a1b7d9SAlexander Kabaev      max() const
2052f8a1b7d9SAlexander Kabaev      { return _M_max; }
2053f8a1b7d9SAlexander Kabaev
2054f8a1b7d9SAlexander Kabaev      void
2055f8a1b7d9SAlexander Kabaev      reset() { }
2056f8a1b7d9SAlexander Kabaev
2057f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
2058f8a1b7d9SAlexander Kabaev        result_type
2059f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng)
2060f8a1b7d9SAlexander Kabaev        { return (__urng() * (_M_max - _M_min)) + _M_min; }
2061f8a1b7d9SAlexander Kabaev
2062f8a1b7d9SAlexander Kabaev      /**
2063f8a1b7d9SAlexander Kabaev       * Inserts a %uniform_real random number distribution @p __x into the
2064f8a1b7d9SAlexander Kabaev       * output stream @p __os.
2065f8a1b7d9SAlexander Kabaev       *
2066f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
2067f8a1b7d9SAlexander Kabaev       * @param __x  A %uniform_real random number distribution.
2068f8a1b7d9SAlexander Kabaev       *
2069f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
2070f8a1b7d9SAlexander Kabaev       * an error state.
2071f8a1b7d9SAlexander Kabaev       */
2072f8a1b7d9SAlexander Kabaev      template<typename _RealType1, typename _CharT, typename _Traits>
2073f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
2074f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2075f8a1b7d9SAlexander Kabaev		   const uniform_real<_RealType1>& __x);
2076f8a1b7d9SAlexander Kabaev
2077f8a1b7d9SAlexander Kabaev      /**
2078f8a1b7d9SAlexander Kabaev       * Extracts a %unform_real random number distribution
2079f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
2080f8a1b7d9SAlexander Kabaev       *
2081f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
2082f8a1b7d9SAlexander Kabaev       * @param __x  A %uniform_real random number generator engine.
2083f8a1b7d9SAlexander Kabaev       *
2084f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
2085f8a1b7d9SAlexander Kabaev       */
2086f8a1b7d9SAlexander Kabaev      template<typename _RealType1, typename _CharT, typename _Traits>
2087f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
2088f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2089f8a1b7d9SAlexander Kabaev		   uniform_real<_RealType1>& __x);
2090f8a1b7d9SAlexander Kabaev
2091f8a1b7d9SAlexander Kabaev    private:
2092f8a1b7d9SAlexander Kabaev      _RealType _M_min;
2093f8a1b7d9SAlexander Kabaev      _RealType _M_max;
2094f8a1b7d9SAlexander Kabaev    };
2095f8a1b7d9SAlexander Kabaev
2096f8a1b7d9SAlexander Kabaev
2097f8a1b7d9SAlexander Kabaev  /**
2098f8a1b7d9SAlexander Kabaev   * @brief An exponential continuous distribution for random numbers.
2099f8a1b7d9SAlexander Kabaev   *
2100f8a1b7d9SAlexander Kabaev   * The formula for the exponential probability mass function is
2101f8a1b7d9SAlexander Kabaev   * @f$ p(x) = \lambda e^{-\lambda x} @f$.
2102f8a1b7d9SAlexander Kabaev   *
2103f8a1b7d9SAlexander Kabaev   * <table border=1 cellpadding=10 cellspacing=0>
2104f8a1b7d9SAlexander Kabaev   * <caption align=top>Distribution Statistics</caption>
2105f8a1b7d9SAlexander Kabaev   * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2106f8a1b7d9SAlexander Kabaev   * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
2107f8a1b7d9SAlexander Kabaev   * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
2108f8a1b7d9SAlexander Kabaev   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
2109f8a1b7d9SAlexander Kabaev   * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2110f8a1b7d9SAlexander Kabaev   * </table>
2111f8a1b7d9SAlexander Kabaev   */
2112f8a1b7d9SAlexander Kabaev  template<typename _RealType = double>
2113f8a1b7d9SAlexander Kabaev    class exponential_distribution
2114f8a1b7d9SAlexander Kabaev    {
2115f8a1b7d9SAlexander Kabaev    public:
2116f8a1b7d9SAlexander Kabaev      // types
2117f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
2118f8a1b7d9SAlexander Kabaev      typedef _RealType result_type;
2119f8a1b7d9SAlexander Kabaev
2120f8a1b7d9SAlexander Kabaev    public:
2121f8a1b7d9SAlexander Kabaev      /**
2122f8a1b7d9SAlexander Kabaev       * Constructs an exponential distribution with inverse scale parameter
2123f8a1b7d9SAlexander Kabaev       * @f$ \lambda @f$.
2124f8a1b7d9SAlexander Kabaev       */
2125f8a1b7d9SAlexander Kabaev      explicit
2126f8a1b7d9SAlexander Kabaev      exponential_distribution(const result_type& __lambda = result_type(1))
2127f8a1b7d9SAlexander Kabaev      : _M_lambda(__lambda)
2128f8a1b7d9SAlexander Kabaev      {
2129f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
2130f8a1b7d9SAlexander Kabaev      }
2131f8a1b7d9SAlexander Kabaev
2132f8a1b7d9SAlexander Kabaev      /**
2133f8a1b7d9SAlexander Kabaev       * Gets the inverse scale parameter of the distribution.
2134f8a1b7d9SAlexander Kabaev       */
2135f8a1b7d9SAlexander Kabaev      _RealType
2136f8a1b7d9SAlexander Kabaev      lambda() const
2137f8a1b7d9SAlexander Kabaev      { return _M_lambda; }
2138f8a1b7d9SAlexander Kabaev
2139f8a1b7d9SAlexander Kabaev      /**
2140f8a1b7d9SAlexander Kabaev       * Resets the distribution.
2141f8a1b7d9SAlexander Kabaev       *
2142f8a1b7d9SAlexander Kabaev       * Has no effect on exponential distributions.
2143f8a1b7d9SAlexander Kabaev       */
2144f8a1b7d9SAlexander Kabaev      void
2145f8a1b7d9SAlexander Kabaev      reset() { }
2146f8a1b7d9SAlexander Kabaev
2147f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
2148f8a1b7d9SAlexander Kabaev        result_type
2149f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng)
2150f8a1b7d9SAlexander Kabaev        { return -std::log(__urng()) / _M_lambda; }
2151f8a1b7d9SAlexander Kabaev
2152f8a1b7d9SAlexander Kabaev      /**
2153f8a1b7d9SAlexander Kabaev       * Inserts a %exponential_distribution random number distribution
2154f8a1b7d9SAlexander Kabaev       * @p __x into the output stream @p __os.
2155f8a1b7d9SAlexander Kabaev       *
2156f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
2157f8a1b7d9SAlexander Kabaev       * @param __x  A %exponential_distribution random number distribution.
2158f8a1b7d9SAlexander Kabaev       *
2159f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
2160f8a1b7d9SAlexander Kabaev       * an error state.
2161f8a1b7d9SAlexander Kabaev       */
2162f8a1b7d9SAlexander Kabaev      template<typename _RealType1, typename _CharT, typename _Traits>
2163f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
2164f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2165f8a1b7d9SAlexander Kabaev		   const exponential_distribution<_RealType1>& __x);
2166f8a1b7d9SAlexander Kabaev
2167f8a1b7d9SAlexander Kabaev      /**
2168f8a1b7d9SAlexander Kabaev       * Extracts a %exponential_distribution random number distribution
2169f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
2170f8a1b7d9SAlexander Kabaev       *
2171f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
2172f8a1b7d9SAlexander Kabaev       * @param __x A %exponential_distribution random number
2173f8a1b7d9SAlexander Kabaev       *            generator engine.
2174f8a1b7d9SAlexander Kabaev       *
2175f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
2176f8a1b7d9SAlexander Kabaev       */
2177f8a1b7d9SAlexander Kabaev      template<typename _CharT, typename _Traits>
2178f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
2179f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2180f8a1b7d9SAlexander Kabaev		   exponential_distribution& __x)
2181f8a1b7d9SAlexander Kabaev        { return __is >> __x._M_lambda; }
2182f8a1b7d9SAlexander Kabaev
2183f8a1b7d9SAlexander Kabaev    private:
2184f8a1b7d9SAlexander Kabaev      result_type _M_lambda;
2185f8a1b7d9SAlexander Kabaev    };
2186f8a1b7d9SAlexander Kabaev
2187f8a1b7d9SAlexander Kabaev
2188f8a1b7d9SAlexander Kabaev  /**
2189f8a1b7d9SAlexander Kabaev   * @brief A normal continuous distribution for random numbers.
2190f8a1b7d9SAlexander Kabaev   *
2191f8a1b7d9SAlexander Kabaev   * The formula for the normal probability mass function is
2192f8a1b7d9SAlexander Kabaev   * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}}
2193f8a1b7d9SAlexander Kabaev   *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
2194f8a1b7d9SAlexander Kabaev   */
2195f8a1b7d9SAlexander Kabaev  template<typename _RealType = double>
2196f8a1b7d9SAlexander Kabaev    class normal_distribution
2197f8a1b7d9SAlexander Kabaev    {
2198f8a1b7d9SAlexander Kabaev    public:
2199f8a1b7d9SAlexander Kabaev      // types
2200f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
2201f8a1b7d9SAlexander Kabaev      typedef _RealType result_type;
2202f8a1b7d9SAlexander Kabaev
2203f8a1b7d9SAlexander Kabaev    public:
2204f8a1b7d9SAlexander Kabaev      /**
2205f8a1b7d9SAlexander Kabaev       * Constructs a normal distribution with parameters @f$ mean @f$ and
2206f8a1b7d9SAlexander Kabaev       * @f$ \sigma @f$.
2207f8a1b7d9SAlexander Kabaev       */
2208f8a1b7d9SAlexander Kabaev      explicit
2209f8a1b7d9SAlexander Kabaev      normal_distribution(const result_type& __mean = result_type(0),
2210f8a1b7d9SAlexander Kabaev			  const result_type& __sigma = result_type(1))
2211f8a1b7d9SAlexander Kabaev      : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
2212f8a1b7d9SAlexander Kabaev      {
2213f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
2214f8a1b7d9SAlexander Kabaev      }
2215f8a1b7d9SAlexander Kabaev
2216f8a1b7d9SAlexander Kabaev      /**
2217f8a1b7d9SAlexander Kabaev       * Gets the mean of the distribution.
2218f8a1b7d9SAlexander Kabaev       */
2219f8a1b7d9SAlexander Kabaev      _RealType
2220f8a1b7d9SAlexander Kabaev      mean() const
2221f8a1b7d9SAlexander Kabaev      { return _M_mean; }
2222f8a1b7d9SAlexander Kabaev
2223f8a1b7d9SAlexander Kabaev      /**
2224f8a1b7d9SAlexander Kabaev       * Gets the @f$ \sigma @f$ of the distribution.
2225f8a1b7d9SAlexander Kabaev       */
2226f8a1b7d9SAlexander Kabaev      _RealType
2227f8a1b7d9SAlexander Kabaev      sigma() const
2228f8a1b7d9SAlexander Kabaev      { return _M_sigma; }
2229f8a1b7d9SAlexander Kabaev
2230f8a1b7d9SAlexander Kabaev      /**
2231f8a1b7d9SAlexander Kabaev       * Resets the distribution.
2232f8a1b7d9SAlexander Kabaev       */
2233f8a1b7d9SAlexander Kabaev      void
2234f8a1b7d9SAlexander Kabaev      reset()
2235f8a1b7d9SAlexander Kabaev      { _M_saved_available = false; }
2236f8a1b7d9SAlexander Kabaev
2237f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
2238f8a1b7d9SAlexander Kabaev        result_type
2239f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng);
2240f8a1b7d9SAlexander Kabaev
2241f8a1b7d9SAlexander Kabaev      /**
2242f8a1b7d9SAlexander Kabaev       * Inserts a %normal_distribution random number distribution
2243f8a1b7d9SAlexander Kabaev       * @p __x into the output stream @p __os.
2244f8a1b7d9SAlexander Kabaev       *
2245f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
2246f8a1b7d9SAlexander Kabaev       * @param __x  A %normal_distribution random number distribution.
2247f8a1b7d9SAlexander Kabaev       *
2248f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
2249f8a1b7d9SAlexander Kabaev       * an error state.
2250f8a1b7d9SAlexander Kabaev       */
2251f8a1b7d9SAlexander Kabaev      template<typename _RealType1, typename _CharT, typename _Traits>
2252f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
2253f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2254f8a1b7d9SAlexander Kabaev		   const normal_distribution<_RealType1>& __x);
2255f8a1b7d9SAlexander Kabaev
2256f8a1b7d9SAlexander Kabaev      /**
2257f8a1b7d9SAlexander Kabaev       * Extracts a %normal_distribution random number distribution
2258f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
2259f8a1b7d9SAlexander Kabaev       *
2260f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
2261f8a1b7d9SAlexander Kabaev       * @param __x  A %normal_distribution random number generator engine.
2262f8a1b7d9SAlexander Kabaev       *
2263f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
2264f8a1b7d9SAlexander Kabaev       */
2265f8a1b7d9SAlexander Kabaev      template<typename _RealType1, typename _CharT, typename _Traits>
2266f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
2267f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2268f8a1b7d9SAlexander Kabaev		   normal_distribution<_RealType1>& __x);
2269f8a1b7d9SAlexander Kabaev
2270f8a1b7d9SAlexander Kabaev    private:
2271f8a1b7d9SAlexander Kabaev      result_type _M_mean;
2272f8a1b7d9SAlexander Kabaev      result_type _M_sigma;
2273f8a1b7d9SAlexander Kabaev      result_type _M_saved;
2274f8a1b7d9SAlexander Kabaev      bool        _M_saved_available;
2275f8a1b7d9SAlexander Kabaev    };
2276f8a1b7d9SAlexander Kabaev
2277f8a1b7d9SAlexander Kabaev
2278f8a1b7d9SAlexander Kabaev  /**
2279f8a1b7d9SAlexander Kabaev   * @brief A gamma continuous distribution for random numbers.
2280f8a1b7d9SAlexander Kabaev   *
2281f8a1b7d9SAlexander Kabaev   * The formula for the gamma probability mass function is
2282f8a1b7d9SAlexander Kabaev   * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
2283f8a1b7d9SAlexander Kabaev   */
2284f8a1b7d9SAlexander Kabaev  template<typename _RealType = double>
2285f8a1b7d9SAlexander Kabaev    class gamma_distribution
2286f8a1b7d9SAlexander Kabaev    {
2287f8a1b7d9SAlexander Kabaev    public:
2288f8a1b7d9SAlexander Kabaev      // types
2289f8a1b7d9SAlexander Kabaev      typedef _RealType input_type;
2290f8a1b7d9SAlexander Kabaev      typedef _RealType result_type;
2291f8a1b7d9SAlexander Kabaev
2292f8a1b7d9SAlexander Kabaev    public:
2293f8a1b7d9SAlexander Kabaev      /**
2294f8a1b7d9SAlexander Kabaev       * Constructs a gamma distribution with parameters @f$ \alpha @f$.
2295f8a1b7d9SAlexander Kabaev       */
2296f8a1b7d9SAlexander Kabaev      explicit
2297f8a1b7d9SAlexander Kabaev      gamma_distribution(const result_type& __alpha_val = result_type(1))
2298f8a1b7d9SAlexander Kabaev      : _M_alpha(__alpha_val)
2299f8a1b7d9SAlexander Kabaev      {
2300f8a1b7d9SAlexander Kabaev	_GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
2301f8a1b7d9SAlexander Kabaev	_M_initialize();
2302f8a1b7d9SAlexander Kabaev      }
2303f8a1b7d9SAlexander Kabaev
2304f8a1b7d9SAlexander Kabaev      /**
2305f8a1b7d9SAlexander Kabaev       * Gets the @f$ \alpha @f$ of the distribution.
2306f8a1b7d9SAlexander Kabaev       */
2307f8a1b7d9SAlexander Kabaev      _RealType
2308f8a1b7d9SAlexander Kabaev      alpha() const
2309f8a1b7d9SAlexander Kabaev      { return _M_alpha; }
2310f8a1b7d9SAlexander Kabaev
2311f8a1b7d9SAlexander Kabaev      /**
2312f8a1b7d9SAlexander Kabaev       * Resets the distribution.
2313f8a1b7d9SAlexander Kabaev       */
2314f8a1b7d9SAlexander Kabaev      void
2315f8a1b7d9SAlexander Kabaev      reset() { }
2316f8a1b7d9SAlexander Kabaev
2317f8a1b7d9SAlexander Kabaev      template<class _UniformRandomNumberGenerator>
2318f8a1b7d9SAlexander Kabaev        result_type
2319f8a1b7d9SAlexander Kabaev        operator()(_UniformRandomNumberGenerator& __urng);
2320f8a1b7d9SAlexander Kabaev
2321f8a1b7d9SAlexander Kabaev      /**
2322f8a1b7d9SAlexander Kabaev       * Inserts a %gamma_distribution random number distribution
2323f8a1b7d9SAlexander Kabaev       * @p __x into the output stream @p __os.
2324f8a1b7d9SAlexander Kabaev       *
2325f8a1b7d9SAlexander Kabaev       * @param __os An output stream.
2326f8a1b7d9SAlexander Kabaev       * @param __x  A %gamma_distribution random number distribution.
2327f8a1b7d9SAlexander Kabaev       *
2328f8a1b7d9SAlexander Kabaev       * @returns The output stream with the state of @p __x inserted or in
2329f8a1b7d9SAlexander Kabaev       * an error state.
2330f8a1b7d9SAlexander Kabaev       */
2331f8a1b7d9SAlexander Kabaev      template<typename _RealType1, typename _CharT, typename _Traits>
2332f8a1b7d9SAlexander Kabaev        friend std::basic_ostream<_CharT, _Traits>&
2333f8a1b7d9SAlexander Kabaev        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2334f8a1b7d9SAlexander Kabaev		   const gamma_distribution<_RealType1>& __x);
2335f8a1b7d9SAlexander Kabaev
2336f8a1b7d9SAlexander Kabaev      /**
2337f8a1b7d9SAlexander Kabaev       * Extracts a %gamma_distribution random number distribution
2338f8a1b7d9SAlexander Kabaev       * @p __x from the input stream @p __is.
2339f8a1b7d9SAlexander Kabaev       *
2340f8a1b7d9SAlexander Kabaev       * @param __is An input stream.
2341f8a1b7d9SAlexander Kabaev       * @param __x  A %gamma_distribution random number generator engine.
2342f8a1b7d9SAlexander Kabaev       *
2343f8a1b7d9SAlexander Kabaev       * @returns The input stream with @p __x extracted or in an error state.
2344f8a1b7d9SAlexander Kabaev       */
2345f8a1b7d9SAlexander Kabaev      template<typename _CharT, typename _Traits>
2346f8a1b7d9SAlexander Kabaev        friend std::basic_istream<_CharT, _Traits>&
2347f8a1b7d9SAlexander Kabaev        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2348f8a1b7d9SAlexander Kabaev		   gamma_distribution& __x)
2349f8a1b7d9SAlexander Kabaev        {
2350f8a1b7d9SAlexander Kabaev	  __is >> __x._M_alpha;
2351f8a1b7d9SAlexander Kabaev	  __x._M_initialize();
2352f8a1b7d9SAlexander Kabaev	  return __is;
2353f8a1b7d9SAlexander Kabaev	}
2354f8a1b7d9SAlexander Kabaev
2355f8a1b7d9SAlexander Kabaev    private:
2356f8a1b7d9SAlexander Kabaev      void
2357f8a1b7d9SAlexander Kabaev      _M_initialize();
2358f8a1b7d9SAlexander Kabaev
2359f8a1b7d9SAlexander Kabaev      result_type _M_alpha;
2360f8a1b7d9SAlexander Kabaev
2361f8a1b7d9SAlexander Kabaev      // Hosts either lambda of GB or d of modified Vaduva's.
2362f8a1b7d9SAlexander Kabaev      result_type _M_l_d;
2363f8a1b7d9SAlexander Kabaev    };
2364f8a1b7d9SAlexander Kabaev
2365f8a1b7d9SAlexander Kabaev  /* @} */ // group tr1_random_distributions_continuous
2366f8a1b7d9SAlexander Kabaev  /* @} */ // group tr1_random_distributions
2367f8a1b7d9SAlexander Kabaev  /* @} */ // group tr1_random
2368f8a1b7d9SAlexander Kabaev
2369f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE
2370f8a1b7d9SAlexander Kabaev}
2371f8a1b7d9SAlexander Kabaev
2372f8a1b7d9SAlexander Kabaev#include <tr1/random.tcc>
2373f8a1b7d9SAlexander Kabaev
2374f8a1b7d9SAlexander Kabaev#endif // _TR1_RANDOM
2375