1951a39d68df598db08dfced8b4707755864a0492Ying Wang// random number generation -*- C++ -*-
2951a39d68df598db08dfced8b4707755864a0492Ying Wang
343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4951a39d68df598db08dfced8b4707755864a0492Ying Wang//
5951a39d68df598db08dfced8b4707755864a0492Ying Wang// This file is part of the GNU ISO C++ Library.  This library is free
6951a39d68df598db08dfced8b4707755864a0492Ying Wang// software; you can redistribute it and/or modify it under the
7951a39d68df598db08dfced8b4707755864a0492Ying Wang// terms of the GNU General Public License as published by the
8951a39d68df598db08dfced8b4707755864a0492Ying Wang// Free Software Foundation; either version 3, or (at your option)
9951a39d68df598db08dfced8b4707755864a0492Ying Wang// any later version.
10951a39d68df598db08dfced8b4707755864a0492Ying Wang
11951a39d68df598db08dfced8b4707755864a0492Ying Wang// This library is distributed in the hope that it will be useful,
12951a39d68df598db08dfced8b4707755864a0492Ying Wang// but WITHOUT ANY WARRANTY; without even the implied warranty of
13951a39d68df598db08dfced8b4707755864a0492Ying Wang// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14951a39d68df598db08dfced8b4707755864a0492Ying Wang// GNU General Public License for more details.
15951a39d68df598db08dfced8b4707755864a0492Ying Wang
16951a39d68df598db08dfced8b4707755864a0492Ying Wang// Under Section 7 of GPL version 3, you are granted additional
17951a39d68df598db08dfced8b4707755864a0492Ying Wang// permissions described in the GCC Runtime Library Exception, version
18951a39d68df598db08dfced8b4707755864a0492Ying Wang// 3.1, as published by the Free Software Foundation.
19951a39d68df598db08dfced8b4707755864a0492Ying Wang
20951a39d68df598db08dfced8b4707755864a0492Ying Wang// You should have received a copy of the GNU General Public License and
21951a39d68df598db08dfced8b4707755864a0492Ying Wang// a copy of the GCC Runtime Library Exception along with this program;
22951a39d68df598db08dfced8b4707755864a0492Ying Wang// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23951a39d68df598db08dfced8b4707755864a0492Ying Wang// <http://www.gnu.org/licenses/>.
24951a39d68df598db08dfced8b4707755864a0492Ying Wang
25951a39d68df598db08dfced8b4707755864a0492Ying Wang/**
2643f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh * @file tr1/random.h
27951a39d68df598db08dfced8b4707755864a0492Ying Wang *  This is an internal header file, included by other library headers.
2843f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh *  Do not attempt to use it directly. @headername{tr1/random}
29951a39d68df598db08dfced8b4707755864a0492Ying Wang */
30951a39d68df598db08dfced8b4707755864a0492Ying Wang
3143f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh#ifndef _GLIBCXX_TR1_RANDOM_H
3243f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh#define _GLIBCXX_TR1_RANDOM_H 1
3343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh
3443f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh#pragma GCC system_header
35951a39d68df598db08dfced8b4707755864a0492Ying Wang
3643f272afd56a57640c62c952f9266478bacf0244Andrew Hsiehnamespace std _GLIBCXX_VISIBILITY(default)
3743f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh{
3843f272afd56a57640c62c952f9266478bacf0244Andrew Hsiehnamespace tr1
3943f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh{
40951a39d68df598db08dfced8b4707755864a0492Ying Wang  // [5.1] Random number generation
41951a39d68df598db08dfced8b4707755864a0492Ying Wang
42951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
4343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * @addtogroup tr1_random Random Number Generation
44951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A facility for generating random numbers on selected distributions.
45951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @{
46951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
47951a39d68df598db08dfced8b4707755864a0492Ying Wang
48951a39d68df598db08dfced8b4707755864a0492Ying Wang  /*
49951a39d68df598db08dfced8b4707755864a0492Ying Wang   * Implementation-space details.
50951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
51951a39d68df598db08dfced8b4707755864a0492Ying Wang  namespace __detail
52951a39d68df598db08dfced8b4707755864a0492Ying Wang  {
5343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh  _GLIBCXX_BEGIN_NAMESPACE_VERSION
5443f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh
55951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _UIntType, int __w,
56951a39d68df598db08dfced8b4707755864a0492Ying Wang	     bool = __w < std::numeric_limits<_UIntType>::digits>
57951a39d68df598db08dfced8b4707755864a0492Ying Wang      struct _Shift
58951a39d68df598db08dfced8b4707755864a0492Ying Wang      { static const _UIntType __value = 0; };
59951a39d68df598db08dfced8b4707755864a0492Ying Wang
60951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _UIntType, int __w>
61951a39d68df598db08dfced8b4707755864a0492Ying Wang      struct _Shift<_UIntType, __w, true>
62951a39d68df598db08dfced8b4707755864a0492Ying Wang      { static const _UIntType __value = _UIntType(1) << __w; };
63951a39d68df598db08dfced8b4707755864a0492Ying Wang
64951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
65951a39d68df598db08dfced8b4707755864a0492Ying Wang      struct _Mod;
66951a39d68df598db08dfced8b4707755864a0492Ying Wang
67951a39d68df598db08dfced8b4707755864a0492Ying Wang    // Dispatch based on modulus value to prevent divide-by-zero compile-time
68951a39d68df598db08dfced8b4707755864a0492Ying Wang    // errors when m == 0.
69951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
70951a39d68df598db08dfced8b4707755864a0492Ying Wang      inline _Tp
71951a39d68df598db08dfced8b4707755864a0492Ying Wang      __mod(_Tp __x)
72951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
73951a39d68df598db08dfced8b4707755864a0492Ying Wang
74951a39d68df598db08dfced8b4707755864a0492Ying Wang    typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
75951a39d68df598db08dfced8b4707755864a0492Ying Wang		    unsigned, unsigned long>::__type _UInt32Type;
76951a39d68df598db08dfced8b4707755864a0492Ying Wang
77951a39d68df598db08dfced8b4707755864a0492Ying Wang    /*
78951a39d68df598db08dfced8b4707755864a0492Ying Wang     * An adaptor class for converting the output of any Generator into
79951a39d68df598db08dfced8b4707755864a0492Ying Wang     * the input for a specific Distribution.
80951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
81951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _Engine, typename _Distribution>
82951a39d68df598db08dfced8b4707755864a0492Ying Wang      struct _Adaptor
83951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
84951a39d68df598db08dfced8b4707755864a0492Ying Wang	typedef typename remove_reference<_Engine>::type _BEngine;
85951a39d68df598db08dfced8b4707755864a0492Ying Wang	typedef typename _BEngine::result_type           _Engine_result_type;
86951a39d68df598db08dfced8b4707755864a0492Ying Wang	typedef typename _Distribution::input_type       result_type;
87951a39d68df598db08dfced8b4707755864a0492Ying Wang
88951a39d68df598db08dfced8b4707755864a0492Ying Wang      public:
89951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Adaptor(const _Engine& __g)
90951a39d68df598db08dfced8b4707755864a0492Ying Wang	: _M_g(__g) { }
91951a39d68df598db08dfced8b4707755864a0492Ying Wang
92951a39d68df598db08dfced8b4707755864a0492Ying Wang	result_type
93951a39d68df598db08dfced8b4707755864a0492Ying Wang	min() const
94951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
95951a39d68df598db08dfced8b4707755864a0492Ying Wang	  result_type __return_value;
96951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (is_integral<_Engine_result_type>::value
97951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && is_integral<result_type>::value)
98951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = _M_g.min();
99951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
100951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type(0);
101951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __return_value;
102951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
103951a39d68df598db08dfced8b4707755864a0492Ying Wang
104951a39d68df598db08dfced8b4707755864a0492Ying Wang	result_type
105951a39d68df598db08dfced8b4707755864a0492Ying Wang	max() const
106951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
107951a39d68df598db08dfced8b4707755864a0492Ying Wang	  result_type __return_value;
108951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (is_integral<_Engine_result_type>::value
109951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && is_integral<result_type>::value)
110951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = _M_g.max();
111951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (!is_integral<result_type>::value)
112951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type(1);
113951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
114951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = std::numeric_limits<result_type>::max() - 1;
115951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __return_value;
116951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
117951a39d68df598db08dfced8b4707755864a0492Ying Wang
118951a39d68df598db08dfced8b4707755864a0492Ying Wang	/*
119951a39d68df598db08dfced8b4707755864a0492Ying Wang	 * Converts a value generated by the adapted random number generator
120951a39d68df598db08dfced8b4707755864a0492Ying Wang	 * into a value in the input domain for the dependent random number
121951a39d68df598db08dfced8b4707755864a0492Ying Wang	 * distribution.
122951a39d68df598db08dfced8b4707755864a0492Ying Wang	 *
123951a39d68df598db08dfced8b4707755864a0492Ying Wang	 * Because the type traits are compile time constants only the
124951a39d68df598db08dfced8b4707755864a0492Ying Wang	 * appropriate clause of the if statements will actually be emitted
125951a39d68df598db08dfced8b4707755864a0492Ying Wang	 * by the compiler.
126951a39d68df598db08dfced8b4707755864a0492Ying Wang	 */
127951a39d68df598db08dfced8b4707755864a0492Ying Wang	result_type
128951a39d68df598db08dfced8b4707755864a0492Ying Wang	operator()()
129951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
130951a39d68df598db08dfced8b4707755864a0492Ying Wang	  result_type __return_value;
131951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (is_integral<_Engine_result_type>::value
132951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && is_integral<result_type>::value)
133951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = _M_g();
134951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (!is_integral<_Engine_result_type>::value
135951a39d68df598db08dfced8b4707755864a0492Ying Wang		   && !is_integral<result_type>::value)
136951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type(_M_g() - _M_g.min())
137951a39d68df598db08dfced8b4707755864a0492Ying Wang	      / result_type(_M_g.max() - _M_g.min());
138951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (is_integral<_Engine_result_type>::value
139951a39d68df598db08dfced8b4707755864a0492Ying Wang		   && !is_integral<result_type>::value)
140951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type(_M_g() - _M_g.min())
141951a39d68df598db08dfced8b4707755864a0492Ying Wang	      / result_type(_M_g.max() - _M_g.min() + result_type(1));
142951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
143951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = (((_M_g() - _M_g.min())
144951a39d68df598db08dfced8b4707755864a0492Ying Wang			       / (_M_g.max() - _M_g.min()))
145951a39d68df598db08dfced8b4707755864a0492Ying Wang			      * std::numeric_limits<result_type>::max());
146951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __return_value;
147951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
148951a39d68df598db08dfced8b4707755864a0492Ying Wang
149951a39d68df598db08dfced8b4707755864a0492Ying Wang      private:
150951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Engine _M_g;
151951a39d68df598db08dfced8b4707755864a0492Ying Wang      };
152951a39d68df598db08dfced8b4707755864a0492Ying Wang
153951a39d68df598db08dfced8b4707755864a0492Ying Wang    // Specialization for _Engine*.
154951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _Engine, typename _Distribution>
155951a39d68df598db08dfced8b4707755864a0492Ying Wang      struct _Adaptor<_Engine*, _Distribution>
156951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
157951a39d68df598db08dfced8b4707755864a0492Ying Wang	typedef typename _Engine::result_type      _Engine_result_type;
158951a39d68df598db08dfced8b4707755864a0492Ying Wang	typedef typename _Distribution::input_type result_type;
159951a39d68df598db08dfced8b4707755864a0492Ying Wang
160951a39d68df598db08dfced8b4707755864a0492Ying Wang      public:
161951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Adaptor(_Engine* __g)
162951a39d68df598db08dfced8b4707755864a0492Ying Wang	: _M_g(__g) { }
163951a39d68df598db08dfced8b4707755864a0492Ying Wang
164951a39d68df598db08dfced8b4707755864a0492Ying Wang	result_type
165951a39d68df598db08dfced8b4707755864a0492Ying Wang	min() const
166951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
167951a39d68df598db08dfced8b4707755864a0492Ying Wang	  result_type __return_value;
168951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (is_integral<_Engine_result_type>::value
169951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && is_integral<result_type>::value)
170951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = _M_g->min();
171951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
172951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type(0);
173951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __return_value;
174951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
175951a39d68df598db08dfced8b4707755864a0492Ying Wang
176951a39d68df598db08dfced8b4707755864a0492Ying Wang	result_type
177951a39d68df598db08dfced8b4707755864a0492Ying Wang	max() const
178951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
179951a39d68df598db08dfced8b4707755864a0492Ying Wang	  result_type __return_value;
180951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (is_integral<_Engine_result_type>::value
181951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && is_integral<result_type>::value)
182951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = _M_g->max();
183951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (!is_integral<result_type>::value)
184951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type(1);
185951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
186951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = std::numeric_limits<result_type>::max() - 1;
187951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __return_value;
188951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
189951a39d68df598db08dfced8b4707755864a0492Ying Wang
190951a39d68df598db08dfced8b4707755864a0492Ying Wang	result_type
191951a39d68df598db08dfced8b4707755864a0492Ying Wang	operator()()
192951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
193951a39d68df598db08dfced8b4707755864a0492Ying Wang	  result_type __return_value;
194951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (is_integral<_Engine_result_type>::value
195951a39d68df598db08dfced8b4707755864a0492Ying Wang	      && is_integral<result_type>::value)
196951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = (*_M_g)();
197951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (!is_integral<_Engine_result_type>::value
198951a39d68df598db08dfced8b4707755864a0492Ying Wang		   && !is_integral<result_type>::value)
199951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type((*_M_g)() - _M_g->min())
200951a39d68df598db08dfced8b4707755864a0492Ying Wang	      / result_type(_M_g->max() - _M_g->min());
201951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else if (is_integral<_Engine_result_type>::value
202951a39d68df598db08dfced8b4707755864a0492Ying Wang		   && !is_integral<result_type>::value)
203951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = result_type((*_M_g)() - _M_g->min())
204951a39d68df598db08dfced8b4707755864a0492Ying Wang	      / result_type(_M_g->max() - _M_g->min() + result_type(1));
205951a39d68df598db08dfced8b4707755864a0492Ying Wang	  else
206951a39d68df598db08dfced8b4707755864a0492Ying Wang	    __return_value = ((((*_M_g)() - _M_g->min())
207951a39d68df598db08dfced8b4707755864a0492Ying Wang			       / (_M_g->max() - _M_g->min()))
208951a39d68df598db08dfced8b4707755864a0492Ying Wang			      * std::numeric_limits<result_type>::max());
209951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __return_value;
210951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
211951a39d68df598db08dfced8b4707755864a0492Ying Wang
212951a39d68df598db08dfced8b4707755864a0492Ying Wang      private:
213951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Engine* _M_g;
214951a39d68df598db08dfced8b4707755864a0492Ying Wang      };
21543f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh
21643f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh  _GLIBCXX_END_NAMESPACE_VERSION
217951a39d68df598db08dfced8b4707755864a0492Ying Wang  } // namespace __detail
218951a39d68df598db08dfced8b4707755864a0492Ying Wang
21943f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh_GLIBCXX_BEGIN_NAMESPACE_VERSION
22043f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh
221951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
222951a39d68df598db08dfced8b4707755864a0492Ying Wang   * Produces random numbers on a given distribution function using a
223951a39d68df598db08dfced8b4707755864a0492Ying Wang   * non-uniform random number generation engine.
224951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
225951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @todo the engine_value_type needs to be studied more carefully.
226951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
227951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _Engine, typename _Dist>
228951a39d68df598db08dfced8b4707755864a0492Ying Wang    class variate_generator
229951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
230951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Concept requirements.
231951a39d68df598db08dfced8b4707755864a0492Ying Wang      __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
232951a39d68df598db08dfced8b4707755864a0492Ying Wang      //  __glibcxx_class_requires(_Engine, _EngineConcept)
233951a39d68df598db08dfced8b4707755864a0492Ying Wang      //  __glibcxx_class_requires(_Dist, _EngineConcept)
234951a39d68df598db08dfced8b4707755864a0492Ying Wang
235951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
236951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _Engine                                engine_type;
237951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
238951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _Dist                                  distribution_type;
239951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename _Dist::result_type            result_type;
240951a39d68df598db08dfced8b4707755864a0492Ying Wang
241951a39d68df598db08dfced8b4707755864a0492Ying Wang      // tr1:5.1.1 table 5.1 requirement
242951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename __gnu_cxx::__enable_if<
243951a39d68df598db08dfced8b4707755864a0492Ying Wang	is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
244951a39d68df598db08dfced8b4707755864a0492Ying Wang
245951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
246951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a variate generator with the uniform random number
247951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator @p __eng for the random distribution @p __dist.
248951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
249951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @throws Any exceptions which may thrown by the copy constructors of
250951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the @p _Engine or @p _Dist objects.
251951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
252951a39d68df598db08dfced8b4707755864a0492Ying Wang      variate_generator(engine_type __eng, distribution_type __dist)
253951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_engine(__eng), _M_dist(__dist) { }
254951a39d68df598db08dfced8b4707755864a0492Ying Wang
255951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
256951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the next generated value on the distribution.
257951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
258951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
259951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()()
260951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_dist(_M_engine); }
261951a39d68df598db08dfced8b4707755864a0492Ying Wang
262951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
263951a39d68df598db08dfced8b4707755864a0492Ying Wang       * WTF?
264951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
265951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _Tp>
266951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
267951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_Tp __value)
268951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return _M_dist(_M_engine, __value); }
269951a39d68df598db08dfced8b4707755864a0492Ying Wang
270951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
271951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a reference to the underlying uniform random number generator
272951a39d68df598db08dfced8b4707755864a0492Ying Wang       * object.
273951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
274951a39d68df598db08dfced8b4707755864a0492Ying Wang      engine_value_type&
275951a39d68df598db08dfced8b4707755864a0492Ying Wang      engine()
276951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_engine; }
277951a39d68df598db08dfced8b4707755864a0492Ying Wang
278951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
279951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a const reference to the underlying uniform random number
280951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator object.
281951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
282951a39d68df598db08dfced8b4707755864a0492Ying Wang      const engine_value_type&
283951a39d68df598db08dfced8b4707755864a0492Ying Wang      engine() const
284951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_engine; }
285951a39d68df598db08dfced8b4707755864a0492Ying Wang
286951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
287951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a reference to the underlying random distribution.
288951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
289951a39d68df598db08dfced8b4707755864a0492Ying Wang      distribution_type&
290951a39d68df598db08dfced8b4707755864a0492Ying Wang      distribution()
291951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_dist; }
292951a39d68df598db08dfced8b4707755864a0492Ying Wang
293951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
294951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a const reference to the underlying random distribution.
295951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
296951a39d68df598db08dfced8b4707755864a0492Ying Wang      const distribution_type&
297951a39d68df598db08dfced8b4707755864a0492Ying Wang      distribution() const
298951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_dist; }
299951a39d68df598db08dfced8b4707755864a0492Ying Wang
300951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
301951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the closed lower bound of the distribution interval.
302951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
303951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
304951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
305951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return this->distribution().min(); }
306951a39d68df598db08dfced8b4707755864a0492Ying Wang
307951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
308951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the closed upper bound of the distribution interval.
309951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
310951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
311951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
312951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return this->distribution().max(); }
313951a39d68df598db08dfced8b4707755864a0492Ying Wang
314951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
315951a39d68df598db08dfced8b4707755864a0492Ying Wang      engine_value_type _M_engine;
316951a39d68df598db08dfced8b4707755864a0492Ying Wang      distribution_type _M_dist;
317951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
318951a39d68df598db08dfced8b4707755864a0492Ying Wang
319951a39d68df598db08dfced8b4707755864a0492Ying Wang
320951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
32143f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * @addtogroup tr1_random_generators Random Number Generators
322951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @ingroup tr1_random
323951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
324951a39d68df598db08dfced8b4707755864a0492Ying Wang   * These classes define objects which provide random or pseudorandom
325951a39d68df598db08dfced8b4707755864a0492Ying Wang   * numbers, either from a discrete or a continuous interval.  The
326951a39d68df598db08dfced8b4707755864a0492Ying Wang   * random number generator supplied as a part of this library are
327951a39d68df598db08dfced8b4707755864a0492Ying Wang   * all uniform random number generators which provide a sequence of
328951a39d68df598db08dfced8b4707755864a0492Ying Wang   * random number uniformly distributed over their range.
329951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
330951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A number generator is a function object with an operator() that
331951a39d68df598db08dfced8b4707755864a0492Ying Wang   * takes zero arguments and returns a number.
332951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
333951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A compliant random number generator must satisfy the following
334951a39d68df598db08dfced8b4707755864a0492Ying Wang   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
335951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <caption align=top>Random Number Generator Requirements</caption>
336951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <tr><td>To be documented.</td></tr> </table>
337951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
338951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @{
339951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
340951a39d68df598db08dfced8b4707755864a0492Ying Wang
341951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
342951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A model of a linear congruential random number generator.
343951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
344951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A random number generator that produces pseudorandom numbers using the
345951a39d68df598db08dfced8b4707755864a0492Ying Wang   * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
346951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
347951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The template parameter @p _UIntType must be an unsigned integral type
348951a39d68df598db08dfced8b4707755864a0492Ying Wang   * large enough to store values up to (__m-1). If the template parameter
349951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @p __m is 0, the modulus @p __m used is
350951a39d68df598db08dfced8b4707755864a0492Ying Wang   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
351951a39d68df598db08dfced8b4707755864a0492Ying Wang   * parameters @p __a and @p __c must be less than @p __m.
352951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
353951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The size of the state is @f$ 1 @f$.
354951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
355951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
356951a39d68df598db08dfced8b4707755864a0492Ying Wang    class linear_congruential
357951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
358951a39d68df598db08dfced8b4707755864a0492Ying Wang      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
359951a39d68df598db08dfced8b4707755864a0492Ying Wang      //  __glibcpp_class_requires(__a < __m && __c < __m)
360951a39d68df598db08dfced8b4707755864a0492Ying Wang
361951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
362951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the generated random value. */
363951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _UIntType result_type;
364951a39d68df598db08dfced8b4707755864a0492Ying Wang
365951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The multiplier. */
366951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _UIntType multiplier = __a;
367951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** An increment. */
368951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _UIntType increment = __c;
369951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The modulus. */
370951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _UIntType modulus = __m;
371951a39d68df598db08dfced8b4707755864a0492Ying Wang
372951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
373951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a %linear_congruential random number generator engine with
374951a39d68df598db08dfced8b4707755864a0492Ying Wang       * seed @p __s.  The default seed value is 1.
375951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
376951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __s The initial seed value.
377951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
378951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
379951a39d68df598db08dfced8b4707755864a0492Ying Wang      linear_congruential(unsigned long __x0 = 1)
380951a39d68df598db08dfced8b4707755864a0492Ying Wang      { this->seed(__x0); }
381951a39d68df598db08dfced8b4707755864a0492Ying Wang
382951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
383951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a %linear_congruential random number generator engine
384951a39d68df598db08dfced8b4707755864a0492Ying Wang       * seeded from the generator function @p __g.
385951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
386951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __g The seed generator function.
387951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
388951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
389951a39d68df598db08dfced8b4707755864a0492Ying Wang        linear_congruential(_Gen& __g)
390951a39d68df598db08dfced8b4707755864a0492Ying Wang        { this->seed(__g); }
391951a39d68df598db08dfced8b4707755864a0492Ying Wang
392951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
393951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Reseeds the %linear_congruential random number generator engine
394951a39d68df598db08dfced8b4707755864a0492Ying Wang       * sequence to the seed @g __s.
395951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
396951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __s The new seed.
397951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
398951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
399951a39d68df598db08dfced8b4707755864a0492Ying Wang      seed(unsigned long __s = 1);
400951a39d68df598db08dfced8b4707755864a0492Ying Wang
401951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
402951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Reseeds the %linear_congruential random number generator engine
403951a39d68df598db08dfced8b4707755864a0492Ying Wang       * sequence using values from the generator function @p __g.
404951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
405951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __g the seed generator function.
406951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
407951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
408951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
409951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g)
410951a39d68df598db08dfced8b4707755864a0492Ying Wang        { seed(__g, typename is_fundamental<_Gen>::type()); }
411951a39d68df598db08dfced8b4707755864a0492Ying Wang
412951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
413951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the smallest possible value in the output range.
414951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
415951a39d68df598db08dfced8b4707755864a0492Ying Wang       * The minimum depends on the @p __c parameter: if it is zero, the
416951a39d68df598db08dfced8b4707755864a0492Ying Wang       * minimum generated must be > 0, otherwise 0 is allowed.
417951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
418951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
419951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
420951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
421951a39d68df598db08dfced8b4707755864a0492Ying Wang
422951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
423951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the largest possible value in the output range.
424951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
425951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
426951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
427951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return __m - 1; }
428951a39d68df598db08dfced8b4707755864a0492Ying Wang
429951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
430951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the next random number in the sequence.
431951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
432951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
433951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()();
434951a39d68df598db08dfced8b4707755864a0492Ying Wang
435951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
436951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two linear congruential random number generator
437951a39d68df598db08dfced8b4707755864a0492Ying Wang       * objects of the same type for equality.
438951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
439951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A linear congruential random number generator object.
440951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another linear congruential random number generator obj.
441951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
442951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are equal, false otherwise.
443951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
444951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
445951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator==(const linear_congruential& __lhs,
446951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const linear_congruential& __rhs)
447951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return __lhs._M_x == __rhs._M_x; }
448951a39d68df598db08dfced8b4707755864a0492Ying Wang
449951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
450951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two linear congruential random number generator
451951a39d68df598db08dfced8b4707755864a0492Ying Wang       * objects of the same type for inequality.
452951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
453951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A linear congruential random number generator object.
454951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another linear congruential random number generator obj.
455951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
456951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are not equal, false otherwise.
457951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
458951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
459951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator!=(const linear_congruential& __lhs,
460951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const linear_congruential& __rhs)
461951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return !(__lhs == __rhs); }
462951a39d68df598db08dfced8b4707755864a0492Ying Wang
463951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
464951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Writes the textual representation of the state x(i) of x to @p __os.
465951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
466951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os  The output stream.
467951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lcr A % linear_congruential random number generator.
468951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns __os.
469951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
470951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
471951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _UIntType1 __m1,
472951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
473951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
474951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
475951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const linear_congruential<_UIntType1, __a1, __c1,
476951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __m1>& __lcr);
477951a39d68df598db08dfced8b4707755864a0492Ying Wang
478951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
479951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Sets the state of the engine by reading its textual
480951a39d68df598db08dfced8b4707755864a0492Ying Wang       * representation from @p __is.
481951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
482951a39d68df598db08dfced8b4707755864a0492Ying Wang       * The textual representation must have been previously written using an
483951a39d68df598db08dfced8b4707755864a0492Ying Wang       * output stream whose imbued locale and whose type's template
484951a39d68df598db08dfced8b4707755864a0492Ying Wang       * specialization arguments _CharT and _Traits were the same as those of
485951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __is.
486951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
487951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is  The input stream.
488951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lcr A % linear_congruential random number generator.
489951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns __is.
490951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
491951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
492951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _UIntType1 __m1,
493951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
494951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
495951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
496951a39d68df598db08dfced8b4707755864a0492Ying Wang		   linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
497951a39d68df598db08dfced8b4707755864a0492Ying Wang
498951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
499951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
500951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
501951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, true_type)
502951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return seed(static_cast<unsigned long>(__g)); }
503951a39d68df598db08dfced8b4707755864a0492Ying Wang
504951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
505951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
506951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, false_type);
507951a39d68df598db08dfced8b4707755864a0492Ying Wang
508951a39d68df598db08dfced8b4707755864a0492Ying Wang      _UIntType _M_x;
509951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
510951a39d68df598db08dfced8b4707755864a0492Ying Wang
511951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
512951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
513951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
514951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
515951a39d68df598db08dfced8b4707755864a0492Ying Wang
516951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
517951a39d68df598db08dfced8b4707755864a0492Ying Wang   * An alternative LCR (Lehmer Generator function) .
518951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
519951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
520951a39d68df598db08dfced8b4707755864a0492Ying Wang
521951a39d68df598db08dfced8b4707755864a0492Ying Wang
522951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
523951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A generalized feedback shift register discrete random number generator.
524951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
525951a39d68df598db08dfced8b4707755864a0492Ying Wang   * This algorithm avoids multiplication and division and is designed to be
526951a39d68df598db08dfced8b4707755864a0492Ying Wang   * friendly to a pipelined architecture.  If the parameters are chosen
527951a39d68df598db08dfced8b4707755864a0492Ying Wang   * correctly, this generator will produce numbers with a very long period and
528951a39d68df598db08dfced8b4707755864a0492Ying Wang   * fairly good apparent entropy, although still not cryptographically strong.
529951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
530951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The best way to use this generator is with the predefined mt19937 class.
531951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
532951a39d68df598db08dfced8b4707755864a0492Ying Wang   * This algorithm was originally invented by Makoto Matsumoto and
533951a39d68df598db08dfced8b4707755864a0492Ying Wang   * Takuji Nishimura.
534951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
535951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var word_size   The number of bits in each element of the state vector.
536951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var state_size  The degree of recursion.
537951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var shift_size  The period parameter.
538951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var mask_bits   The separation point bit index.
539951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var parameter_a The last row of the twist matrix.
540951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var output_u    The first right-shift tempering matrix parameter.
541951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var output_s    The first left-shift tempering matrix parameter.
542951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var output_b    The first left-shift tempering matrix mask.
543951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var output_t    The second left-shift tempering matrix parameter.
544951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var output_c    The second left-shift tempering matrix mask.
545951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var output_l    The second right-shift tempering matrix parameter.
546951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
547951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _UIntType, int __w, int __n, int __m, int __r,
548951a39d68df598db08dfced8b4707755864a0492Ying Wang	   _UIntType __a, int __u, int __s, _UIntType __b, int __t,
549951a39d68df598db08dfced8b4707755864a0492Ying Wang	   _UIntType __c, int __l>
550951a39d68df598db08dfced8b4707755864a0492Ying Wang    class mersenne_twister
551951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
552951a39d68df598db08dfced8b4707755864a0492Ying Wang      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
553951a39d68df598db08dfced8b4707755864a0492Ying Wang
554951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
555951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
556951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _UIntType result_type;
557951a39d68df598db08dfced8b4707755864a0492Ying Wang
558951a39d68df598db08dfced8b4707755864a0492Ying Wang      // parameter values
559951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       word_size   = __w;
560951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       state_size  = __n;
561951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       shift_size  = __m;
562951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       mask_bits   = __r;
563951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _UIntType parameter_a = __a;
564951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       output_u    = __u;
565951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       output_s    = __s;
566951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _UIntType output_b    = __b;
567951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       output_t    = __t;
568951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _UIntType output_c    = __c;
569951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int       output_l    = __l;
570951a39d68df598db08dfced8b4707755864a0492Ying Wang
571951a39d68df598db08dfced8b4707755864a0492Ying Wang      // constructors and member function
572951a39d68df598db08dfced8b4707755864a0492Ying Wang      mersenne_twister()
573951a39d68df598db08dfced8b4707755864a0492Ying Wang      { seed(); }
574951a39d68df598db08dfced8b4707755864a0492Ying Wang
575951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
576951a39d68df598db08dfced8b4707755864a0492Ying Wang      mersenne_twister(unsigned long __value)
577951a39d68df598db08dfced8b4707755864a0492Ying Wang      { seed(__value); }
578951a39d68df598db08dfced8b4707755864a0492Ying Wang
579951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
580951a39d68df598db08dfced8b4707755864a0492Ying Wang        mersenne_twister(_Gen& __g)
581951a39d68df598db08dfced8b4707755864a0492Ying Wang        { seed(__g); }
582951a39d68df598db08dfced8b4707755864a0492Ying Wang
583951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
584951a39d68df598db08dfced8b4707755864a0492Ying Wang      seed()
585951a39d68df598db08dfced8b4707755864a0492Ying Wang      { seed(5489UL); }
586951a39d68df598db08dfced8b4707755864a0492Ying Wang
587951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
588951a39d68df598db08dfced8b4707755864a0492Ying Wang      seed(unsigned long __value);
589951a39d68df598db08dfced8b4707755864a0492Ying Wang
590951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
591951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
592951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g)
593951a39d68df598db08dfced8b4707755864a0492Ying Wang        { seed(__g, typename is_fundamental<_Gen>::type()); }
594951a39d68df598db08dfced8b4707755864a0492Ying Wang
595951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
596951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
597951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return 0; };
598951a39d68df598db08dfced8b4707755864a0492Ying Wang
599951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
600951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
601951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
602951a39d68df598db08dfced8b4707755864a0492Ying Wang
603951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
604951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()();
605951a39d68df598db08dfced8b4707755864a0492Ying Wang
606951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
607951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two % mersenne_twister random number generator objects of
608951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for equality.
609951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
610951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A % mersenne_twister random number generator object.
611951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another % mersenne_twister random number generator
612951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
613951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
614951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are equal, false otherwise.
615951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
616951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
617951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator==(const mersenne_twister& __lhs,
618951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const mersenne_twister& __rhs)
619951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
620951a39d68df598db08dfced8b4707755864a0492Ying Wang
621951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
622951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two % mersenne_twister random number generator objects of
623951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for inequality.
624951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
625951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A % mersenne_twister random number generator object.
626951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another % mersenne_twister random number generator
627951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
628951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
629951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are not equal, false otherwise.
630951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
631951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
632951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator!=(const mersenne_twister& __lhs,
633951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const mersenne_twister& __rhs)
634951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return !(__lhs == __rhs); }
635951a39d68df598db08dfced8b4707755864a0492Ying Wang
636951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
637951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts the current state of a % mersenne_twister random number
638951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x into the output stream @p __os.
639951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
640951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
641951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A % mersenne_twister random number generator engine.
642951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
643951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
644951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
645951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
646951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
647951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
648951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _UIntType1 __c1, int __l1,
649951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
650951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
651951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
652951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
653951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
654951a39d68df598db08dfced8b4707755864a0492Ying Wang
655951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
656951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts the current state of a % mersenne_twister random number
657951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x from the input stream @p __is.
658951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
659951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
660951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A % mersenne_twister random number generator engine.
661951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
662951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with the state of @p __x extracted or in
663951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
664951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
665951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
666951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
667951a39d68df598db08dfced8b4707755864a0492Ying Wang	       _UIntType1 __c1, int __l1,
668951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
669951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
670951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
671951a39d68df598db08dfced8b4707755864a0492Ying Wang		   mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
672951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
673951a39d68df598db08dfced8b4707755864a0492Ying Wang
674951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
675951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
676951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
677951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, true_type)
678951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return seed(static_cast<unsigned long>(__g)); }
679951a39d68df598db08dfced8b4707755864a0492Ying Wang
680951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
681951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
682951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, false_type);
683951a39d68df598db08dfced8b4707755864a0492Ying Wang
684951a39d68df598db08dfced8b4707755864a0492Ying Wang      _UIntType _M_x[state_size];
685951a39d68df598db08dfced8b4707755864a0492Ying Wang      int       _M_p;
686951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
687951a39d68df598db08dfced8b4707755864a0492Ying Wang
688951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
689951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The classic Mersenne Twister.
690951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
691951a39d68df598db08dfced8b4707755864a0492Ying Wang   * Reference:
69243f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
69343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
694951a39d68df598db08dfced8b4707755864a0492Ying Wang   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
695951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
696951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef mersenne_twister<
697951a39d68df598db08dfced8b4707755864a0492Ying Wang    unsigned long, 32, 624, 397, 31,
698951a39d68df598db08dfced8b4707755864a0492Ying Wang    0x9908b0dful, 11, 7,
699951a39d68df598db08dfced8b4707755864a0492Ying Wang    0x9d2c5680ul, 15,
700951a39d68df598db08dfced8b4707755864a0492Ying Wang    0xefc60000ul, 18
701951a39d68df598db08dfced8b4707755864a0492Ying Wang    > mt19937;
702951a39d68df598db08dfced8b4707755864a0492Ying Wang
703951a39d68df598db08dfced8b4707755864a0492Ying Wang
704951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
705951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief The Marsaglia-Zaman generator.
706951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
707951a39d68df598db08dfced8b4707755864a0492Ying Wang   * This is a model of a Generalized Fibonacci discrete random number
708951a39d68df598db08dfced8b4707755864a0492Ying Wang   * generator, sometimes referred to as the SWC generator.
709951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
710951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A discrete random number generator that produces pseudorandom
711951a39d68df598db08dfced8b4707755864a0492Ying Wang   * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
712951a39d68df598db08dfced8b4707755864a0492Ying Wang   * carry_{i-1}) \bmod m @f$.
713951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
714951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The size of the state is @f$ r @f$
715951a39d68df598db08dfced8b4707755864a0492Ying Wang   * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
716951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
71743f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * N1688[4.13] says <em>the template parameter _IntType shall denote
71843f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * an integral type large enough to store values up to m</em>.
719951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
720951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_x     The state of the generator.  This is a ring buffer.
721951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_carry The carry.
722951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_p     Current index of x(i - r).
723951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
724951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _IntType, _IntType __m, int __s, int __r>
725951a39d68df598db08dfced8b4707755864a0492Ying Wang    class subtract_with_carry
726951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
727951a39d68df598db08dfced8b4707755864a0492Ying Wang      __glibcxx_class_requires(_IntType, _IntegerConcept)
728951a39d68df598db08dfced8b4707755864a0492Ying Wang
729951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
730951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the generated random value. */
731951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _IntType result_type;
732951a39d68df598db08dfced8b4707755864a0492Ying Wang
733951a39d68df598db08dfced8b4707755864a0492Ying Wang      // parameter values
734951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const _IntType modulus   = __m;
735951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int      long_lag  = __r;
736951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int      short_lag = __s;
737951a39d68df598db08dfced8b4707755864a0492Ying Wang
738951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
739951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a default-initialized % subtract_with_carry random number
740951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator.
741951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
742951a39d68df598db08dfced8b4707755864a0492Ying Wang      subtract_with_carry()
743951a39d68df598db08dfced8b4707755864a0492Ying Wang      { this->seed(); }
744951a39d68df598db08dfced8b4707755864a0492Ying Wang
745951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
746951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs an explicitly seeded % subtract_with_carry random number
747951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator.
748951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
749951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
750951a39d68df598db08dfced8b4707755864a0492Ying Wang      subtract_with_carry(unsigned long __value)
751951a39d68df598db08dfced8b4707755864a0492Ying Wang      { this->seed(__value); }
752951a39d68df598db08dfced8b4707755864a0492Ying Wang
753951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
754951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a %subtract_with_carry random number generator engine
755951a39d68df598db08dfced8b4707755864a0492Ying Wang       * seeded from the generator function @p __g.
756951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
757951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __g The seed generator function.
758951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
759951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
760951a39d68df598db08dfced8b4707755864a0492Ying Wang        subtract_with_carry(_Gen& __g)
761951a39d68df598db08dfced8b4707755864a0492Ying Wang        { this->seed(__g); }
762951a39d68df598db08dfced8b4707755864a0492Ying Wang
763951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
764951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
765951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
766951a39d68df598db08dfced8b4707755864a0492Ying Wang       * N1688[4.19] modifies this as follows.  If @p __value == 0,
767951a39d68df598db08dfced8b4707755864a0492Ying Wang       * sets value to 19780503.  In any case, with a linear
768951a39d68df598db08dfced8b4707755864a0492Ying Wang       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
769951a39d68df598db08dfced8b4707755864a0492Ying Wang       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
770951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
771951a39d68df598db08dfced8b4707755864a0492Ying Wang       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
772951a39d68df598db08dfced8b4707755864a0492Ying Wang       * set carry to 1, otherwise sets carry to 0.
773951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
774951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
775951a39d68df598db08dfced8b4707755864a0492Ying Wang      seed(unsigned long __value = 19780503);
776951a39d68df598db08dfced8b4707755864a0492Ying Wang
777951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
778951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
779951a39d68df598db08dfced8b4707755864a0492Ying Wang       * random number generator.
780951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
781951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
782951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
783951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g)
784951a39d68df598db08dfced8b4707755864a0492Ying Wang        { seed(__g, typename is_fundamental<_Gen>::type()); }
785951a39d68df598db08dfced8b4707755864a0492Ying Wang
786951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
787951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the inclusive minimum value of the range of random integers
788951a39d68df598db08dfced8b4707755864a0492Ying Wang       * returned by this generator.
789951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
790951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
791951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
792951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return 0; }
793951a39d68df598db08dfced8b4707755864a0492Ying Wang
794951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
795951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the inclusive maximum value of the range of random integers
796951a39d68df598db08dfced8b4707755864a0492Ying Wang       * returned by this generator.
797951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
798951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
799951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
800951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return this->modulus - 1; }
801951a39d68df598db08dfced8b4707755864a0492Ying Wang
802951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
803951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the next random number in the sequence.
804951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
805951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
806951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()();
807951a39d68df598db08dfced8b4707755864a0492Ying Wang
808951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
809951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two % subtract_with_carry random number generator objects of
810951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for equality.
811951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
812951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A % subtract_with_carry random number generator object.
813951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another % subtract_with_carry random number generator
814951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
815951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
816951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are equal, false otherwise.
817951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
818951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
819951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator==(const subtract_with_carry& __lhs,
820951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const subtract_with_carry& __rhs)
821951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
822951a39d68df598db08dfced8b4707755864a0492Ying Wang
823951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
824951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two % subtract_with_carry random number generator objects of
825951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for inequality.
826951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
827951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A % subtract_with_carry random number generator object.
828951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another % subtract_with_carry random number generator
829951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
830951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
831951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are not equal, false otherwise.
832951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
833951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
834951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator!=(const subtract_with_carry& __lhs,
835951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const subtract_with_carry& __rhs)
836951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return !(__lhs == __rhs); }
837951a39d68df598db08dfced8b4707755864a0492Ying Wang
838951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
839951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts the current state of a % subtract_with_carry random number
840951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x into the output stream @p __os.
841951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
842951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
843951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A % subtract_with_carry random number generator engine.
844951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
845951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
846951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
847951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
848951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
849951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
850951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
851951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
852951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const subtract_with_carry<_IntType1, __m1, __s1,
853951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __r1>& __x);
854951a39d68df598db08dfced8b4707755864a0492Ying Wang
855951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
856951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts the current state of a % subtract_with_carry random number
857951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x from the input stream @p __is.
858951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
859951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
860951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A % subtract_with_carry random number generator engine.
861951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
862951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with the state of @p __x extracted or in
863951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
864951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
865951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
866951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
867951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
868951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
869951a39d68df598db08dfced8b4707755864a0492Ying Wang		   subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
870951a39d68df598db08dfced8b4707755864a0492Ying Wang
871951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
872951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
873951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
874951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, true_type)
875951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return seed(static_cast<unsigned long>(__g)); }
876951a39d68df598db08dfced8b4707755864a0492Ying Wang
877951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
878951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
879951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, false_type);
880951a39d68df598db08dfced8b4707755864a0492Ying Wang
881951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
882951a39d68df598db08dfced8b4707755864a0492Ying Wang
883951a39d68df598db08dfced8b4707755864a0492Ying Wang      _UIntType  _M_x[long_lag];
884951a39d68df598db08dfced8b4707755864a0492Ying Wang      _UIntType  _M_carry;
885951a39d68df598db08dfced8b4707755864a0492Ying Wang      int        _M_p;
886951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
887951a39d68df598db08dfced8b4707755864a0492Ying Wang
888951a39d68df598db08dfced8b4707755864a0492Ying Wang
889951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
890951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief The Marsaglia-Zaman generator (floats version).
891951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
892951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_x     The state of the generator.  This is a ring buffer.
893951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_carry The carry.
894951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_p     Current index of x(i - r).
895951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @var _M_npows Precomputed negative powers of 2.
896951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
897951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _RealType, int __w, int __s, int __r>
898951a39d68df598db08dfced8b4707755864a0492Ying Wang    class subtract_with_carry_01
899951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
900951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
901951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the generated random value. */
902951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType result_type;
903951a39d68df598db08dfced8b4707755864a0492Ying Wang
904951a39d68df598db08dfced8b4707755864a0492Ying Wang      // parameter values
905951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int      word_size = __w;
906951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int      long_lag  = __r;
907951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int      short_lag = __s;
908951a39d68df598db08dfced8b4707755864a0492Ying Wang
909951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
910951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a default-initialized % subtract_with_carry_01 random
911951a39d68df598db08dfced8b4707755864a0492Ying Wang       * number generator.
912951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
913951a39d68df598db08dfced8b4707755864a0492Ying Wang      subtract_with_carry_01()
914951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
915951a39d68df598db08dfced8b4707755864a0492Ying Wang	this->seed();
916951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_initialize_npows();
917951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
918951a39d68df598db08dfced8b4707755864a0492Ying Wang
919951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
920951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs an explicitly seeded % subtract_with_carry_01 random number
921951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator.
922951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
923951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
924951a39d68df598db08dfced8b4707755864a0492Ying Wang      subtract_with_carry_01(unsigned long __value)
925951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
926951a39d68df598db08dfced8b4707755864a0492Ying Wang	this->seed(__value);
927951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_initialize_npows();
928951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
929951a39d68df598db08dfced8b4707755864a0492Ying Wang
930951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
931951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a % subtract_with_carry_01 random number generator engine
932951a39d68df598db08dfced8b4707755864a0492Ying Wang       * seeded from the generator function @p __g.
933951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
934951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __g The seed generator function.
935951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
936951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
937951a39d68df598db08dfced8b4707755864a0492Ying Wang        subtract_with_carry_01(_Gen& __g)
938951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
939951a39d68df598db08dfced8b4707755864a0492Ying Wang	  this->seed(__g);
940951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _M_initialize_npows();
941951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
942951a39d68df598db08dfced8b4707755864a0492Ying Wang
943951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
944951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
945951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
946951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
947951a39d68df598db08dfced8b4707755864a0492Ying Wang      seed(unsigned long __value = 19780503);
948951a39d68df598db08dfced8b4707755864a0492Ying Wang
949951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
950951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
951951a39d68df598db08dfced8b4707755864a0492Ying Wang       * random number generator.
952951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
953951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
954951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
955951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g)
956951a39d68df598db08dfced8b4707755864a0492Ying Wang        { seed(__g, typename is_fundamental<_Gen>::type()); }
957951a39d68df598db08dfced8b4707755864a0492Ying Wang
958951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
959951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the minimum value of the range of random floats
960951a39d68df598db08dfced8b4707755864a0492Ying Wang       * returned by this generator.
961951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
962951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
963951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
964951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return 0.0; }
965951a39d68df598db08dfced8b4707755864a0492Ying Wang
966951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
967951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the maximum value of the range of random floats
968951a39d68df598db08dfced8b4707755864a0492Ying Wang       * returned by this generator.
969951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
970951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
971951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
972951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return 1.0; }
973951a39d68df598db08dfced8b4707755864a0492Ying Wang
974951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
975951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the next random number in the sequence.
976951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
977951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
978951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()();
979951a39d68df598db08dfced8b4707755864a0492Ying Wang
980951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
981951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two % subtract_with_carry_01 random number generator objects
982951a39d68df598db08dfced8b4707755864a0492Ying Wang       * of the same type for equality.
983951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
984951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A % subtract_with_carry_01 random number
985951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              generator object.
986951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another % subtract_with_carry_01 random number generator
987951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
988951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
989951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are equal, false otherwise.
990951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
991951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
992951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator==(const subtract_with_carry_01& __lhs,
993951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const subtract_with_carry_01& __rhs)
994951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
995951a39d68df598db08dfced8b4707755864a0492Ying Wang	for (int __i = 0; __i < long_lag; ++__i)
996951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
997951a39d68df598db08dfced8b4707755864a0492Ying Wang			  __rhs._M_x[__i]))
998951a39d68df598db08dfced8b4707755864a0492Ying Wang	    return false;
999951a39d68df598db08dfced8b4707755864a0492Ying Wang	return true;
1000951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1001951a39d68df598db08dfced8b4707755864a0492Ying Wang
1002951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1003951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two % subtract_with_carry_01 random number generator objects
1004951a39d68df598db08dfced8b4707755864a0492Ying Wang       * of the same type for inequality.
1005951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1006951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A % subtract_with_carry_01 random number
1007951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              generator object.
1008951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1009951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another % subtract_with_carry_01 random number generator
1010951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
1011951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1012951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are not equal, false otherwise.
1013951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1014951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
1015951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator!=(const subtract_with_carry_01& __lhs,
1016951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const subtract_with_carry_01& __rhs)
1017951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return !(__lhs == __rhs); }
1018951a39d68df598db08dfced8b4707755864a0492Ying Wang
1019951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1020951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts the current state of a % subtract_with_carry_01 random number
1021951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x into the output stream @p __os.
1022951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1023951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
1024951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A % subtract_with_carry_01 random number generator engine.
1025951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1026951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
1027951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1028951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1029951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, int __w1, int __s1, int __r1,
1030951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1031951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
1032951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1033951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const subtract_with_carry_01<_RealType1, __w1, __s1,
1034951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __r1>& __x);
1035951a39d68df598db08dfced8b4707755864a0492Ying Wang
1036951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1037951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts the current state of a % subtract_with_carry_01 random number
1038951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x from the input stream @p __is.
1039951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1040951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
1041951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A % subtract_with_carry_01 random number generator engine.
1042951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1043951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with the state of @p __x extracted or in
1044951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1045951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1046951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, int __w1, int __s1, int __r1,
1047951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1048951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
1049951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1050951a39d68df598db08dfced8b4707755864a0492Ying Wang		   subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
1051951a39d68df598db08dfced8b4707755864a0492Ying Wang
1052951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1053951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
1054951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
1055951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, true_type)
1056951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return seed(static_cast<unsigned long>(__g)); }
1057951a39d68df598db08dfced8b4707755864a0492Ying Wang
1058951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
1059951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
1060951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g, false_type);
1061951a39d68df598db08dfced8b4707755864a0492Ying Wang
1062951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1063951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize_npows();
1064951a39d68df598db08dfced8b4707755864a0492Ying Wang
1065951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int __n = (__w + 31) / 32;
1066951a39d68df598db08dfced8b4707755864a0492Ying Wang
1067951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef __detail::_UInt32Type _UInt32Type;
1068951a39d68df598db08dfced8b4707755864a0492Ying Wang      _UInt32Type  _M_x[long_lag][__n];
1069951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType    _M_npows[__n];
1070951a39d68df598db08dfced8b4707755864a0492Ying Wang      _UInt32Type  _M_carry;
1071951a39d68df598db08dfced8b4707755864a0492Ying Wang      int          _M_p;
1072951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
1073951a39d68df598db08dfced8b4707755864a0492Ying Wang
1074951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;
1075951a39d68df598db08dfced8b4707755864a0492Ying Wang
1076951a39d68df598db08dfced8b4707755864a0492Ying Wang  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1077951a39d68df598db08dfced8b4707755864a0492Ying Wang  // 508. Bad parameters for ranlux64_base_01.
1078951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
1079951a39d68df598db08dfced8b4707755864a0492Ying Wang
1080951a39d68df598db08dfced8b4707755864a0492Ying Wang
1081951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1082951a39d68df598db08dfced8b4707755864a0492Ying Wang   * Produces random numbers from some base engine by discarding blocks of
1083951a39d68df598db08dfced8b4707755864a0492Ying Wang   * data.
1084951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
1085951a39d68df598db08dfced8b4707755864a0492Ying Wang   * 0 <= @p __r <= @p __p
1086951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1087951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _UniformRandomNumberGenerator, int __p, int __r>
1088951a39d68df598db08dfced8b4707755864a0492Ying Wang    class discard_block
1089951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1090951a39d68df598db08dfced8b4707755864a0492Ying Wang      // __glibcxx_class_requires(typename base_type::result_type,
1091951a39d68df598db08dfced8b4707755864a0492Ying Wang      //                          ArithmeticTypeConcept)
1092951a39d68df598db08dfced8b4707755864a0492Ying Wang
1093951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1094951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the underlying generator engine. */
1095951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _UniformRandomNumberGenerator   base_type;
1096951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the generated random value. */
1097951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename base_type::result_type result_type;
1098951a39d68df598db08dfced8b4707755864a0492Ying Wang
1099951a39d68df598db08dfced8b4707755864a0492Ying Wang      // parameter values
1100951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int block_size = __p;
1101951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int used_block = __r;
1102951a39d68df598db08dfced8b4707755864a0492Ying Wang
1103951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1104951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a default %discard_block engine.
1105951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1106951a39d68df598db08dfced8b4707755864a0492Ying Wang       * The underlying engine is default constructed as well.
1107951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1108951a39d68df598db08dfced8b4707755864a0492Ying Wang      discard_block()
1109951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_n(0) { }
1110951a39d68df598db08dfced8b4707755864a0492Ying Wang
1111951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1112951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Copy constructs a %discard_block engine.
1113951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1114951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Copies an existing base class random number generator.
1115951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param rng An existing (base class) engine object.
1116951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1117951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
1118951a39d68df598db08dfced8b4707755864a0492Ying Wang      discard_block(const base_type& __rng)
1119951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_b(__rng), _M_n(0) { }
1120951a39d68df598db08dfced8b4707755864a0492Ying Wang
1121951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1122951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Seed constructs a %discard_block engine.
1123951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1124951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs the underlying generator engine seeded with @p __s.
1125951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __s A seed value for the base class engine.
1126951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1127951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
1128951a39d68df598db08dfced8b4707755864a0492Ying Wang      discard_block(unsigned long __s)
1129951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_b(__s), _M_n(0) { }
1130951a39d68df598db08dfced8b4707755864a0492Ying Wang
1131951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1132951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Generator construct a %discard_block engine.
1133951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1134951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __g A seed generator function.
1135951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1136951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
1137951a39d68df598db08dfced8b4707755864a0492Ying Wang        discard_block(_Gen& __g)
1138951a39d68df598db08dfced8b4707755864a0492Ying Wang	: _M_b(__g), _M_n(0) { }
1139951a39d68df598db08dfced8b4707755864a0492Ying Wang
1140951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1141951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Reseeds the %discard_block object with the default seed for the
1142951a39d68df598db08dfced8b4707755864a0492Ying Wang       * underlying base class generator engine.
1143951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1144951a39d68df598db08dfced8b4707755864a0492Ying Wang      void seed()
1145951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1146951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_b.seed();
1147951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_n = 0;
1148951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1149951a39d68df598db08dfced8b4707755864a0492Ying Wang
1150951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1151951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Reseeds the %discard_block object with the given seed generator
1152951a39d68df598db08dfced8b4707755864a0492Ying Wang       * function.
1153951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __g A seed generator function.
1154951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1155951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
1156951a39d68df598db08dfced8b4707755864a0492Ying Wang        void seed(_Gen& __g)
1157951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
1158951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _M_b.seed(__g);
1159951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _M_n = 0;
1160951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1161951a39d68df598db08dfced8b4707755864a0492Ying Wang
1162951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1163951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a const reference to the underlying generator engine object.
1164951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1165951a39d68df598db08dfced8b4707755864a0492Ying Wang      const base_type&
1166951a39d68df598db08dfced8b4707755864a0492Ying Wang      base() const
1167951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_b; }
1168951a39d68df598db08dfced8b4707755864a0492Ying Wang
1169951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1170951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the minimum value in the generated random number range.
1171951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1172951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1173951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
1174951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_b.min(); }
1175951a39d68df598db08dfced8b4707755864a0492Ying Wang
1176951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1177951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the maximum value in the generated random number range.
1178951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1179951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1180951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
1181951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_b.max(); }
1182951a39d68df598db08dfced8b4707755864a0492Ying Wang
1183951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1184951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the next value in the generated random number sequence.
1185951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1186951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1187951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()();
1188951a39d68df598db08dfced8b4707755864a0492Ying Wang
1189951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1190951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two %discard_block random number generator objects of
1191951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for equality.
1192951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1193951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A %discard_block random number generator object.
1194951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another %discard_block random number generator
1195951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
1196951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1197951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are equal, false otherwise.
1198951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1199951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
1200951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator==(const discard_block& __lhs, const discard_block& __rhs)
1201951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
1202951a39d68df598db08dfced8b4707755864a0492Ying Wang
1203951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1204951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two %discard_block random number generator objects of
1205951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for inequality.
1206951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1207951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A %discard_block random number generator object.
1208951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another %discard_block random number generator
1209951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
1210951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1211951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are not equal, false otherwise.
1212951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1213951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
1214951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator!=(const discard_block& __lhs, const discard_block& __rhs)
1215951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return !(__lhs == __rhs); }
1216951a39d68df598db08dfced8b4707755864a0492Ying Wang
1217951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1218951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts the current state of a %discard_block random number
1219951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x into the output stream @p __os.
1220951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1221951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
1222951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %discard_block random number generator engine.
1223951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1224951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
1225951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1226951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1227951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1228951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1229951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
1230951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1231951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const discard_block<_UniformRandomNumberGenerator1,
1232951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __p1, __r1>& __x);
1233951a39d68df598db08dfced8b4707755864a0492Ying Wang
1234951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1235951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts the current state of a % subtract_with_carry random number
1236951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x from the input stream @p __is.
1237951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1238951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
1239951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %discard_block random number generator engine.
1240951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1241951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with the state of @p __x extracted or in
1242951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1243951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1244951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1245951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1246951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
1247951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1248951a39d68df598db08dfced8b4707755864a0492Ying Wang		   discard_block<_UniformRandomNumberGenerator1,
1249951a39d68df598db08dfced8b4707755864a0492Ying Wang		   __p1, __r1>& __x);
1250951a39d68df598db08dfced8b4707755864a0492Ying Wang
1251951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1252951a39d68df598db08dfced8b4707755864a0492Ying Wang      base_type _M_b;
1253951a39d68df598db08dfced8b4707755864a0492Ying Wang      int       _M_n;
1254951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
1255951a39d68df598db08dfced8b4707755864a0492Ying Wang
1256951a39d68df598db08dfced8b4707755864a0492Ying Wang
1257951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1258951a39d68df598db08dfced8b4707755864a0492Ying Wang   * James's luxury-level-3 integer adaptation of Luescher's generator.
1259951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1260951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef discard_block<
1261951a39d68df598db08dfced8b4707755864a0492Ying Wang    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1262951a39d68df598db08dfced8b4707755864a0492Ying Wang      223,
1263951a39d68df598db08dfced8b4707755864a0492Ying Wang      24
1264951a39d68df598db08dfced8b4707755864a0492Ying Wang      > ranlux3;
1265951a39d68df598db08dfced8b4707755864a0492Ying Wang
1266951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1267951a39d68df598db08dfced8b4707755864a0492Ying Wang   * James's luxury-level-4 integer adaptation of Luescher's generator.
1268951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1269951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef discard_block<
1270951a39d68df598db08dfced8b4707755864a0492Ying Wang    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1271951a39d68df598db08dfced8b4707755864a0492Ying Wang      389,
1272951a39d68df598db08dfced8b4707755864a0492Ying Wang      24
1273951a39d68df598db08dfced8b4707755864a0492Ying Wang      > ranlux4;
1274951a39d68df598db08dfced8b4707755864a0492Ying Wang
1275951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef discard_block<
1276951a39d68df598db08dfced8b4707755864a0492Ying Wang    subtract_with_carry_01<float, 24, 10, 24>,
1277951a39d68df598db08dfced8b4707755864a0492Ying Wang      223,
1278951a39d68df598db08dfced8b4707755864a0492Ying Wang      24
1279951a39d68df598db08dfced8b4707755864a0492Ying Wang      > ranlux3_01;
1280951a39d68df598db08dfced8b4707755864a0492Ying Wang
1281951a39d68df598db08dfced8b4707755864a0492Ying Wang  typedef discard_block<
1282951a39d68df598db08dfced8b4707755864a0492Ying Wang    subtract_with_carry_01<float, 24, 10, 24>,
1283951a39d68df598db08dfced8b4707755864a0492Ying Wang      389,
1284951a39d68df598db08dfced8b4707755864a0492Ying Wang      24
1285951a39d68df598db08dfced8b4707755864a0492Ying Wang      > ranlux4_01;
1286951a39d68df598db08dfced8b4707755864a0492Ying Wang
1287951a39d68df598db08dfced8b4707755864a0492Ying Wang
1288951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1289951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A random number generator adaptor class that combines two random number
1290951a39d68df598db08dfced8b4707755864a0492Ying Wang   * generator engines into a single output sequence.
1291951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1292951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<class _UniformRandomNumberGenerator1, int __s1,
1293951a39d68df598db08dfced8b4707755864a0492Ying Wang	   class _UniformRandomNumberGenerator2, int __s2>
1294951a39d68df598db08dfced8b4707755864a0492Ying Wang    class xor_combine
1295951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1296951a39d68df598db08dfced8b4707755864a0492Ying Wang      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
1297951a39d68df598db08dfced8b4707755864a0492Ying Wang      //                          result_type, ArithmeticTypeConcept)
1298951a39d68df598db08dfced8b4707755864a0492Ying Wang      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
1299951a39d68df598db08dfced8b4707755864a0492Ying Wang      //                          result_type, ArithmeticTypeConcept)
1300951a39d68df598db08dfced8b4707755864a0492Ying Wang
1301951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1302951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the first underlying generator engine. */
1303951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _UniformRandomNumberGenerator1   base1_type;
1304951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the second underlying generator engine. */
1305951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _UniformRandomNumberGenerator2   base2_type;
1306951a39d68df598db08dfced8b4707755864a0492Ying Wang
1307951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1308951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename base1_type::result_type _Result_type1;
1309951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename base2_type::result_type _Result_type2;
1310951a39d68df598db08dfced8b4707755864a0492Ying Wang
1311951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1312951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the generated random value. */
1313951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
1314951a39d68df598db08dfced8b4707755864a0492Ying Wang						      > sizeof(_Result_type2)),
1315951a39d68df598db08dfced8b4707755864a0492Ying Wang	_Result_type1, _Result_type2>::__type result_type;
1316951a39d68df598db08dfced8b4707755864a0492Ying Wang
1317951a39d68df598db08dfced8b4707755864a0492Ying Wang      // parameter values
1318951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int shift1 = __s1;
1319951a39d68df598db08dfced8b4707755864a0492Ying Wang      static const int shift2 = __s2;
1320951a39d68df598db08dfced8b4707755864a0492Ying Wang
1321951a39d68df598db08dfced8b4707755864a0492Ying Wang      // constructors and member function
1322951a39d68df598db08dfced8b4707755864a0492Ying Wang      xor_combine()
1323951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_b1(), _M_b2()
1324951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_initialize_max(); }
1325951a39d68df598db08dfced8b4707755864a0492Ying Wang
1326951a39d68df598db08dfced8b4707755864a0492Ying Wang      xor_combine(const base1_type& __rng1, const base2_type& __rng2)
1327951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_b1(__rng1), _M_b2(__rng2)
1328951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_initialize_max(); }
1329951a39d68df598db08dfced8b4707755864a0492Ying Wang
1330951a39d68df598db08dfced8b4707755864a0492Ying Wang      xor_combine(unsigned long __s)
1331951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_b1(__s), _M_b2(__s + 1)
1332951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_initialize_max(); }
1333951a39d68df598db08dfced8b4707755864a0492Ying Wang
1334951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
1335951a39d68df598db08dfced8b4707755864a0492Ying Wang        xor_combine(_Gen& __g)
1336951a39d68df598db08dfced8b4707755864a0492Ying Wang	: _M_b1(__g), _M_b2(__g)
1337951a39d68df598db08dfced8b4707755864a0492Ying Wang        { _M_initialize_max(); }
1338951a39d68df598db08dfced8b4707755864a0492Ying Wang
1339951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1340951a39d68df598db08dfced8b4707755864a0492Ying Wang      seed()
1341951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1342951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_b1.seed();
1343951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_b2.seed();
1344951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1345951a39d68df598db08dfced8b4707755864a0492Ying Wang
1346951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _Gen>
1347951a39d68df598db08dfced8b4707755864a0492Ying Wang        void
1348951a39d68df598db08dfced8b4707755864a0492Ying Wang        seed(_Gen& __g)
1349951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
1350951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _M_b1.seed(__g);
1351951a39d68df598db08dfced8b4707755864a0492Ying Wang	  _M_b2.seed(__g);
1352951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1353951a39d68df598db08dfced8b4707755864a0492Ying Wang
1354951a39d68df598db08dfced8b4707755864a0492Ying Wang      const base1_type&
1355951a39d68df598db08dfced8b4707755864a0492Ying Wang      base1() const
1356951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_b1; }
1357951a39d68df598db08dfced8b4707755864a0492Ying Wang
1358951a39d68df598db08dfced8b4707755864a0492Ying Wang      const base2_type&
1359951a39d68df598db08dfced8b4707755864a0492Ying Wang      base2() const
1360951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_b2; }
1361951a39d68df598db08dfced8b4707755864a0492Ying Wang
1362951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1363951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
1364951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return 0; }
1365951a39d68df598db08dfced8b4707755864a0492Ying Wang
1366951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1367951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
1368951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_max; }
1369951a39d68df598db08dfced8b4707755864a0492Ying Wang
1370951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1371951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the next random number in the sequence.
1372951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1373951a39d68df598db08dfced8b4707755864a0492Ying Wang      // NB: Not exactly the TR1 formula, per N2079 instead.
1374951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1375951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()()
1376951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1377951a39d68df598db08dfced8b4707755864a0492Ying Wang	return ((result_type(_M_b1() - _M_b1.min()) << shift1)
1378951a39d68df598db08dfced8b4707755864a0492Ying Wang		^ (result_type(_M_b2() - _M_b2.min()) << shift2));
1379951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1380951a39d68df598db08dfced8b4707755864a0492Ying Wang
1381951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1382951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two %xor_combine random number generator objects of
1383951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for equality.
1384951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1385951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A %xor_combine random number generator object.
1386951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another %xor_combine random number generator
1387951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
1388951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1389951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are equal, false otherwise.
1390951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1391951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
1392951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator==(const xor_combine& __lhs, const xor_combine& __rhs)
1393951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1394951a39d68df598db08dfced8b4707755864a0492Ying Wang	return (__lhs.base1() == __rhs.base1())
1395951a39d68df598db08dfced8b4707755864a0492Ying Wang	        && (__lhs.base2() == __rhs.base2());
1396951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1397951a39d68df598db08dfced8b4707755864a0492Ying Wang
1398951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1399951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Compares two %xor_combine random number generator objects of
1400951a39d68df598db08dfced8b4707755864a0492Ying Wang       * the same type for inequality.
1401951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1402951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __lhs A %xor_combine random number generator object.
1403951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __rhs Another %xor_combine random number generator
1404951a39d68df598db08dfced8b4707755864a0492Ying Wang       *              object.
1405951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1406951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns true if the two objects are not equal, false otherwise.
1407951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1408951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend bool
1409951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
1410951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return !(__lhs == __rhs); }
1411951a39d68df598db08dfced8b4707755864a0492Ying Wang
1412951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1413951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts the current state of a %xor_combine random number
1414951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x into the output stream @p __os.
1415951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1416951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
1417951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %xor_combine random number generator engine.
1418951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1419951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
1420951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1421951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1422951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator11, int __s11,
1423951a39d68df598db08dfced8b4707755864a0492Ying Wang	       class _UniformRandomNumberGenerator21, int __s21,
1424951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1425951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
1426951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1427951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const xor_combine<_UniformRandomNumberGenerator11, __s11,
1428951a39d68df598db08dfced8b4707755864a0492Ying Wang		   _UniformRandomNumberGenerator21, __s21>& __x);
1429951a39d68df598db08dfced8b4707755864a0492Ying Wang
1430951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1431951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts the current state of a %xor_combine random number
1432951a39d68df598db08dfced8b4707755864a0492Ying Wang       * generator engine @p __x from the input stream @p __is.
1433951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1434951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
1435951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %xor_combine random number generator engine.
1436951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1437951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with the state of @p __x extracted or in
1438951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1439951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1440951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator11, int __s11,
1441951a39d68df598db08dfced8b4707755864a0492Ying Wang	       class _UniformRandomNumberGenerator21, int __s21,
1442951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1443951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
1444951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1445951a39d68df598db08dfced8b4707755864a0492Ying Wang		   xor_combine<_UniformRandomNumberGenerator11, __s11,
1446951a39d68df598db08dfced8b4707755864a0492Ying Wang		   _UniformRandomNumberGenerator21, __s21>& __x);
1447951a39d68df598db08dfced8b4707755864a0492Ying Wang
1448951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1449951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1450951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize_max();
1451951a39d68df598db08dfced8b4707755864a0492Ying Wang
1452951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1453951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize_max_aux(result_type, result_type, int);
1454951a39d68df598db08dfced8b4707755864a0492Ying Wang
1455951a39d68df598db08dfced8b4707755864a0492Ying Wang      base1_type  _M_b1;
1456951a39d68df598db08dfced8b4707755864a0492Ying Wang      base2_type  _M_b2;
1457951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_max;
1458951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
1459951a39d68df598db08dfced8b4707755864a0492Ying Wang
1460951a39d68df598db08dfced8b4707755864a0492Ying Wang
1461951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1462951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A standard interface to a platform-specific non-deterministic
1463951a39d68df598db08dfced8b4707755864a0492Ying Wang   * random number generator (if any are available).
1464951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1465951a39d68df598db08dfced8b4707755864a0492Ying Wang  class random_device
1466951a39d68df598db08dfced8b4707755864a0492Ying Wang  {
1467951a39d68df598db08dfced8b4707755864a0492Ying Wang  public:
1468951a39d68df598db08dfced8b4707755864a0492Ying Wang    // types
1469951a39d68df598db08dfced8b4707755864a0492Ying Wang    typedef unsigned int result_type;
1470951a39d68df598db08dfced8b4707755864a0492Ying Wang
1471951a39d68df598db08dfced8b4707755864a0492Ying Wang    // constructors, destructors and member functions
1472951a39d68df598db08dfced8b4707755864a0492Ying Wang
1473951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef _GLIBCXX_USE_RANDOM_TR1
1474951a39d68df598db08dfced8b4707755864a0492Ying Wang
1475951a39d68df598db08dfced8b4707755864a0492Ying Wang    explicit
1476951a39d68df598db08dfced8b4707755864a0492Ying Wang    random_device(const std::string& __token = "/dev/urandom")
1477951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1478951a39d68df598db08dfced8b4707755864a0492Ying Wang      if ((__token != "/dev/urandom" && __token != "/dev/random")
1479951a39d68df598db08dfced8b4707755864a0492Ying Wang	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
1480951a39d68df598db08dfced8b4707755864a0492Ying Wang	std::__throw_runtime_error(__N("random_device::"
1481951a39d68df598db08dfced8b4707755864a0492Ying Wang				       "random_device(const std::string&)"));
1482951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1483951a39d68df598db08dfced8b4707755864a0492Ying Wang
1484951a39d68df598db08dfced8b4707755864a0492Ying Wang    ~random_device()
1485951a39d68df598db08dfced8b4707755864a0492Ying Wang    { std::fclose(_M_file); }
1486951a39d68df598db08dfced8b4707755864a0492Ying Wang
1487951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
1488951a39d68df598db08dfced8b4707755864a0492Ying Wang
1489951a39d68df598db08dfced8b4707755864a0492Ying Wang    explicit
1490951a39d68df598db08dfced8b4707755864a0492Ying Wang    random_device(const std::string& __token = "mt19937")
1491951a39d68df598db08dfced8b4707755864a0492Ying Wang    : _M_mt(_M_strtoul(__token)) { }
1492951a39d68df598db08dfced8b4707755864a0492Ying Wang
1493951a39d68df598db08dfced8b4707755864a0492Ying Wang  private:
1494951a39d68df598db08dfced8b4707755864a0492Ying Wang    static unsigned long
1495951a39d68df598db08dfced8b4707755864a0492Ying Wang    _M_strtoul(const std::string& __str)
1496951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1497951a39d68df598db08dfced8b4707755864a0492Ying Wang      unsigned long __ret = 5489UL;
1498951a39d68df598db08dfced8b4707755864a0492Ying Wang      if (__str != "mt19937")
1499951a39d68df598db08dfced8b4707755864a0492Ying Wang	{
1500951a39d68df598db08dfced8b4707755864a0492Ying Wang	  const char* __nptr = __str.c_str();
1501951a39d68df598db08dfced8b4707755864a0492Ying Wang	  char* __endptr;
1502951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __ret = std::strtoul(__nptr, &__endptr, 0);
1503951a39d68df598db08dfced8b4707755864a0492Ying Wang	  if (*__nptr == '\0' || *__endptr != '\0')
1504951a39d68df598db08dfced8b4707755864a0492Ying Wang	    std::__throw_runtime_error(__N("random_device::_M_strtoul"
1505951a39d68df598db08dfced8b4707755864a0492Ying Wang					   "(const std::string&)"));
1506951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1507951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __ret;
1508951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1509951a39d68df598db08dfced8b4707755864a0492Ying Wang
1510951a39d68df598db08dfced8b4707755864a0492Ying Wang  public:
1511951a39d68df598db08dfced8b4707755864a0492Ying Wang
1512951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1513951a39d68df598db08dfced8b4707755864a0492Ying Wang
1514951a39d68df598db08dfced8b4707755864a0492Ying Wang    result_type
1515951a39d68df598db08dfced8b4707755864a0492Ying Wang    min() const
1516951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return std::numeric_limits<result_type>::min(); }
1517951a39d68df598db08dfced8b4707755864a0492Ying Wang
1518951a39d68df598db08dfced8b4707755864a0492Ying Wang    result_type
1519951a39d68df598db08dfced8b4707755864a0492Ying Wang    max() const
1520951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return std::numeric_limits<result_type>::max(); }
1521951a39d68df598db08dfced8b4707755864a0492Ying Wang
1522951a39d68df598db08dfced8b4707755864a0492Ying Wang    double
1523951a39d68df598db08dfced8b4707755864a0492Ying Wang    entropy() const
1524951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return 0.0; }
1525951a39d68df598db08dfced8b4707755864a0492Ying Wang
1526951a39d68df598db08dfced8b4707755864a0492Ying Wang    result_type
1527951a39d68df598db08dfced8b4707755864a0492Ying Wang    operator()()
1528951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1529951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef _GLIBCXX_USE_RANDOM_TR1
1530951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type __ret;
1531951a39d68df598db08dfced8b4707755864a0492Ying Wang      std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
1532951a39d68df598db08dfced8b4707755864a0492Ying Wang		 1, _M_file);
1533951a39d68df598db08dfced8b4707755864a0492Ying Wang      return __ret;
1534951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
1535951a39d68df598db08dfced8b4707755864a0492Ying Wang      return _M_mt();
1536951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1537951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1538951a39d68df598db08dfced8b4707755864a0492Ying Wang
1539951a39d68df598db08dfced8b4707755864a0492Ying Wang  private:
1540951a39d68df598db08dfced8b4707755864a0492Ying Wang    random_device(const random_device&);
1541951a39d68df598db08dfced8b4707755864a0492Ying Wang    void operator=(const random_device&);
1542951a39d68df598db08dfced8b4707755864a0492Ying Wang
1543951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef _GLIBCXX_USE_RANDOM_TR1
1544951a39d68df598db08dfced8b4707755864a0492Ying Wang    FILE*        _M_file;
1545951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
1546951a39d68df598db08dfced8b4707755864a0492Ying Wang    mt19937      _M_mt;
1547951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1548951a39d68df598db08dfced8b4707755864a0492Ying Wang  };
1549951a39d68df598db08dfced8b4707755864a0492Ying Wang
1550951a39d68df598db08dfced8b4707755864a0492Ying Wang  /* @} */ // group tr1_random_generators
1551951a39d68df598db08dfced8b4707755864a0492Ying Wang
1552951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
155343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * @addtogroup tr1_random_distributions Random Number Distributions
1554951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @ingroup tr1_random
1555951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @{
1556951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1557951a39d68df598db08dfced8b4707755864a0492Ying Wang
1558951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
155943f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * @addtogroup tr1_random_distributions_discrete Discrete Distributions
1560951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @ingroup tr1_random_distributions
1561951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @{
1562951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1563951a39d68df598db08dfced8b4707755864a0492Ying Wang
1564951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1565951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief Uniform discrete distribution for random numbers.
1566951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A discrete random distribution on the range @f$[min, max]@f$ with equal
1567951a39d68df598db08dfced8b4707755864a0492Ying Wang   * probability throughout the range.
1568951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1569951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _IntType = int>
1570951a39d68df598db08dfced8b4707755864a0492Ying Wang    class uniform_int
1571951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1572951a39d68df598db08dfced8b4707755864a0492Ying Wang      __glibcxx_class_requires(_IntType, _IntegerConcept)
1573951a39d68df598db08dfced8b4707755864a0492Ying Wang
1574951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1575951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the parameters of the distribution. */
1576951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _IntType input_type;
1577951a39d68df598db08dfced8b4707755864a0492Ying Wang      /** The type of the range of the distribution. */
1578951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _IntType result_type;
1579951a39d68df598db08dfced8b4707755864a0492Ying Wang
1580951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1581951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1582951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a uniform distribution object.
1583951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1584951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
1585951a39d68df598db08dfced8b4707755864a0492Ying Wang      uniform_int(_IntType __min = 0, _IntType __max = 9)
1586951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_min(__min), _M_max(__max)
1587951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1588951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
1589951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1590951a39d68df598db08dfced8b4707755864a0492Ying Wang
1591951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1592951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the inclusive lower bound of the distribution range.
1593951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1594951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1595951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
1596951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_min; }
1597951a39d68df598db08dfced8b4707755864a0492Ying Wang
1598951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1599951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the inclusive upper bound of the distribution range.
1600951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1601951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1602951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
1603951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_max; }
1604951a39d68df598db08dfced8b4707755864a0492Ying Wang
1605951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1606951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Resets the distribution state.
1607951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1608951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Does nothing for the uniform integer distribution.
1609951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1610951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1611951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset() { }
1612951a39d68df598db08dfced8b4707755864a0492Ying Wang
1613951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1614951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a uniformly distributed random number in the range
1615951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @f$(min, max)@f$.
1616951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1617951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _UniformRandomNumberGenerator>
1618951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1619951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng)
1620951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
1621951a39d68df598db08dfced8b4707755864a0492Ying Wang	  typedef typename _UniformRandomNumberGenerator::result_type
1622951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _UResult_type;
1623951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return _M_call(__urng, _M_min, _M_max,
1624951a39d68df598db08dfced8b4707755864a0492Ying Wang			 typename is_integral<_UResult_type>::type());
1625951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1626951a39d68df598db08dfced8b4707755864a0492Ying Wang
1627951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1628951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets a uniform random number in the range @f$[0, n)@f$.
1629951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1630951a39d68df598db08dfced8b4707755864a0492Ying Wang       * This function is aimed at use with std::random_shuffle.
1631951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1632951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _UniformRandomNumberGenerator>
1633951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1634951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
1635951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
1636951a39d68df598db08dfced8b4707755864a0492Ying Wang	  typedef typename _UniformRandomNumberGenerator::result_type
1637951a39d68df598db08dfced8b4707755864a0492Ying Wang	    _UResult_type;
1638951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return _M_call(__urng, 0, __n - 1,
1639951a39d68df598db08dfced8b4707755864a0492Ying Wang			 typename is_integral<_UResult_type>::type());
1640951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1641951a39d68df598db08dfced8b4707755864a0492Ying Wang
1642951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1643951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %uniform_int random number distribution @p __x into the
1644951a39d68df598db08dfced8b4707755864a0492Ying Wang       * output stream @p os.
1645951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1646951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
1647951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %uniform_int random number distribution.
1648951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1649951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
1650951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1651951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1652951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _CharT, typename _Traits>
1653951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
1654951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1655951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const uniform_int<_IntType1>& __x);
1656951a39d68df598db08dfced8b4707755864a0492Ying Wang
1657951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1658951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %uniform_int random number distribution
1659951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
1660951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1661951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
1662951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %uniform_int random number generator engine.
1663951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1664951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
1665951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1666951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _CharT, typename _Traits>
1667951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
1668951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1669951a39d68df598db08dfced8b4707755864a0492Ying Wang		   uniform_int<_IntType1>& __x);
1670951a39d68df598db08dfced8b4707755864a0492Ying Wang
1671951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1672951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _UniformRandomNumberGenerator>
1673951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1674951a39d68df598db08dfced8b4707755864a0492Ying Wang        _M_call(_UniformRandomNumberGenerator& __urng,
1675951a39d68df598db08dfced8b4707755864a0492Ying Wang		result_type __min, result_type __max, true_type);
1676951a39d68df598db08dfced8b4707755864a0492Ying Wang
1677951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _UniformRandomNumberGenerator>
1678951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1679951a39d68df598db08dfced8b4707755864a0492Ying Wang        _M_call(_UniformRandomNumberGenerator& __urng,
1680951a39d68df598db08dfced8b4707755864a0492Ying Wang		result_type __min, result_type __max, false_type)
1681951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
1682951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return result_type((__urng() - __urng.min())
1683951a39d68df598db08dfced8b4707755864a0492Ying Wang			     / (__urng.max() - __urng.min())
1684951a39d68df598db08dfced8b4707755864a0492Ying Wang			     * (__max - __min + 1)) + __min;
1685951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1686951a39d68df598db08dfced8b4707755864a0492Ying Wang
1687951a39d68df598db08dfced8b4707755864a0492Ying Wang      _IntType _M_min;
1688951a39d68df598db08dfced8b4707755864a0492Ying Wang      _IntType _M_max;
1689951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
1690951a39d68df598db08dfced8b4707755864a0492Ying Wang
1691951a39d68df598db08dfced8b4707755864a0492Ying Wang
1692951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1693951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A Bernoulli random number distribution.
1694951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
1695951a39d68df598db08dfced8b4707755864a0492Ying Wang   * Generates a sequence of true and false values with likelihood @f$ p @f$
1696951a39d68df598db08dfced8b4707755864a0492Ying Wang   * that true will come up and @f$ (1 - p) @f$ that false will appear.
1697951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1698951a39d68df598db08dfced8b4707755864a0492Ying Wang  class bernoulli_distribution
1699951a39d68df598db08dfced8b4707755864a0492Ying Wang  {
1700951a39d68df598db08dfced8b4707755864a0492Ying Wang  public:
1701951a39d68df598db08dfced8b4707755864a0492Ying Wang    typedef int  input_type;
1702951a39d68df598db08dfced8b4707755864a0492Ying Wang    typedef bool result_type;
1703951a39d68df598db08dfced8b4707755864a0492Ying Wang
1704951a39d68df598db08dfced8b4707755864a0492Ying Wang  public:
1705951a39d68df598db08dfced8b4707755864a0492Ying Wang    /**
1706951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Constructs a Bernoulli distribution with likelihood @p p.
1707951a39d68df598db08dfced8b4707755864a0492Ying Wang     *
1708951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @param __p  [IN]  The likelihood of a true result being returned.  Must
1709951a39d68df598db08dfced8b4707755864a0492Ying Wang     * be in the interval @f$ [0, 1] @f$.
1710951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
1711951a39d68df598db08dfced8b4707755864a0492Ying Wang    explicit
1712951a39d68df598db08dfced8b4707755864a0492Ying Wang    bernoulli_distribution(double __p = 0.5)
1713951a39d68df598db08dfced8b4707755864a0492Ying Wang    : _M_p(__p)
1714951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1715951a39d68df598db08dfced8b4707755864a0492Ying Wang      _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
1716951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
1717951a39d68df598db08dfced8b4707755864a0492Ying Wang
1718951a39d68df598db08dfced8b4707755864a0492Ying Wang    /**
1719951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Gets the @p p parameter of the distribution.
1720951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
1721951a39d68df598db08dfced8b4707755864a0492Ying Wang    double
1722951a39d68df598db08dfced8b4707755864a0492Ying Wang    p() const
1723951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return _M_p; }
1724951a39d68df598db08dfced8b4707755864a0492Ying Wang
1725951a39d68df598db08dfced8b4707755864a0492Ying Wang    /**
1726951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Resets the distribution state.
1727951a39d68df598db08dfced8b4707755864a0492Ying Wang     *
1728951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Does nothing for a Bernoulli distribution.
1729951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
1730951a39d68df598db08dfced8b4707755864a0492Ying Wang    void
1731951a39d68df598db08dfced8b4707755864a0492Ying Wang    reset() { }
1732951a39d68df598db08dfced8b4707755864a0492Ying Wang
1733951a39d68df598db08dfced8b4707755864a0492Ying Wang    /**
1734951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Gets the next value in the Bernoullian sequence.
1735951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
1736951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<class _UniformRandomNumberGenerator>
1737951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
1738951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator()(_UniformRandomNumberGenerator& __urng)
1739951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1740951a39d68df598db08dfced8b4707755864a0492Ying Wang	if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
1741951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return true;
1742951a39d68df598db08dfced8b4707755864a0492Ying Wang	return false;
1743951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1744951a39d68df598db08dfced8b4707755864a0492Ying Wang
1745951a39d68df598db08dfced8b4707755864a0492Ying Wang    /**
1746951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Inserts a %bernoulli_distribution random number distribution
1747951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @p __x into the output stream @p __os.
1748951a39d68df598db08dfced8b4707755864a0492Ying Wang     *
1749951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @param __os An output stream.
1750951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @param __x  A %bernoulli_distribution random number distribution.
1751951a39d68df598db08dfced8b4707755864a0492Ying Wang     *
1752951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @returns The output stream with the state of @p __x inserted or in
1753951a39d68df598db08dfced8b4707755864a0492Ying Wang     * an error state.
1754951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
1755951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _CharT, typename _Traits>
1756951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend std::basic_ostream<_CharT, _Traits>&
1757951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1758951a39d68df598db08dfced8b4707755864a0492Ying Wang		 const bernoulli_distribution& __x);
1759951a39d68df598db08dfced8b4707755864a0492Ying Wang
1760951a39d68df598db08dfced8b4707755864a0492Ying Wang    /**
1761951a39d68df598db08dfced8b4707755864a0492Ying Wang     * Extracts a %bernoulli_distribution random number distribution
1762951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @p __x from the input stream @p __is.
1763951a39d68df598db08dfced8b4707755864a0492Ying Wang     *
1764951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @param __is An input stream.
1765951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @param __x  A %bernoulli_distribution random number generator engine.
1766951a39d68df598db08dfced8b4707755864a0492Ying Wang     *
1767951a39d68df598db08dfced8b4707755864a0492Ying Wang     * @returns The input stream with @p __x extracted or in an error state.
1768951a39d68df598db08dfced8b4707755864a0492Ying Wang     */
1769951a39d68df598db08dfced8b4707755864a0492Ying Wang    template<typename _CharT, typename _Traits>
1770951a39d68df598db08dfced8b4707755864a0492Ying Wang      friend std::basic_istream<_CharT, _Traits>&
1771951a39d68df598db08dfced8b4707755864a0492Ying Wang      operator>>(std::basic_istream<_CharT, _Traits>& __is,
1772951a39d68df598db08dfced8b4707755864a0492Ying Wang		 bernoulli_distribution& __x)
1773951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return __is >> __x._M_p; }
1774951a39d68df598db08dfced8b4707755864a0492Ying Wang
1775951a39d68df598db08dfced8b4707755864a0492Ying Wang  private:
1776951a39d68df598db08dfced8b4707755864a0492Ying Wang    double _M_p;
1777951a39d68df598db08dfced8b4707755864a0492Ying Wang  };
1778951a39d68df598db08dfced8b4707755864a0492Ying Wang
1779951a39d68df598db08dfced8b4707755864a0492Ying Wang
1780951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1781951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A discrete geometric random number distribution.
1782951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
1783951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The formula for the geometric probability mass function is
1784951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
1785951a39d68df598db08dfced8b4707755864a0492Ying Wang   * distribution.
1786951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1787951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _IntType = int, typename _RealType = double>
1788951a39d68df598db08dfced8b4707755864a0492Ying Wang    class geometric_distribution
1789951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1790951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1791951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
1792951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
1793951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _IntType  result_type;
1794951a39d68df598db08dfced8b4707755864a0492Ying Wang
1795951a39d68df598db08dfced8b4707755864a0492Ying Wang      // constructors and member function
1796951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
1797951a39d68df598db08dfced8b4707755864a0492Ying Wang      geometric_distribution(const _RealType& __p = _RealType(0.5))
1798951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_p(__p)
1799951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1800951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
1801951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_initialize();
1802951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1803951a39d68df598db08dfced8b4707755864a0492Ying Wang
1804951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1805951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the distribution parameter @p p.
1806951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1807951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
1808951a39d68df598db08dfced8b4707755864a0492Ying Wang      p() const
1809951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_p; }
1810951a39d68df598db08dfced8b4707755864a0492Ying Wang
1811951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1812951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset() { }
1813951a39d68df598db08dfced8b4707755864a0492Ying Wang
1814951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
1815951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1816951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng);
1817951a39d68df598db08dfced8b4707755864a0492Ying Wang
1818951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1819951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %geometric_distribution random number distribution
1820951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x into the output stream @p __os.
1821951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1822951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
1823951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %geometric_distribution random number distribution.
1824951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1825951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
1826951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1827951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1828951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _RealType1,
1829951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1830951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
1831951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1832951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const geometric_distribution<_IntType1, _RealType1>& __x);
1833951a39d68df598db08dfced8b4707755864a0492Ying Wang
1834951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1835951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %geometric_distribution random number distribution
1836951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
1837951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1838951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
1839951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %geometric_distribution random number generator engine.
1840951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1841951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
1842951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1843951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _CharT, typename _Traits>
1844951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
1845951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1846951a39d68df598db08dfced8b4707755864a0492Ying Wang		   geometric_distribution& __x)
1847951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
1848951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __is >> __x._M_p;
1849951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_initialize();
1850951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __is;
1851951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
1852951a39d68df598db08dfced8b4707755864a0492Ying Wang
1853951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1854951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1855951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize()
1856951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_log_p = std::log(_M_p); }
1857951a39d68df598db08dfced8b4707755864a0492Ying Wang
1858951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_p;
1859951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_log_p;
1860951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
1861951a39d68df598db08dfced8b4707755864a0492Ying Wang
1862951a39d68df598db08dfced8b4707755864a0492Ying Wang
1863951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _RealType>
1864951a39d68df598db08dfced8b4707755864a0492Ying Wang    class normal_distribution;
1865951a39d68df598db08dfced8b4707755864a0492Ying Wang
1866951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1867951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A discrete Poisson random number distribution.
1868951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
1869951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The formula for the Poisson probability mass function is
1870951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
1871951a39d68df598db08dfced8b4707755864a0492Ying Wang   * parameter of the distribution.
1872951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1873951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _IntType = int, typename _RealType = double>
1874951a39d68df598db08dfced8b4707755864a0492Ying Wang    class poisson_distribution
1875951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1876951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1877951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
1878951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
1879951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _IntType  result_type;
1880951a39d68df598db08dfced8b4707755864a0492Ying Wang
1881951a39d68df598db08dfced8b4707755864a0492Ying Wang      // constructors and member function
1882951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
1883951a39d68df598db08dfced8b4707755864a0492Ying Wang      poisson_distribution(const _RealType& __mean = _RealType(1))
1884951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_mean(__mean), _M_nd()
1885951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1886951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
1887951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_initialize();
1888951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1889951a39d68df598db08dfced8b4707755864a0492Ying Wang
1890951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1891951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the distribution parameter @p mean.
1892951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1893951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
1894951a39d68df598db08dfced8b4707755864a0492Ying Wang      mean() const
1895951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_mean; }
1896951a39d68df598db08dfced8b4707755864a0492Ying Wang
1897951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1898951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset()
1899951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_nd.reset(); }
1900951a39d68df598db08dfced8b4707755864a0492Ying Wang
1901951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
1902951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1903951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng);
1904951a39d68df598db08dfced8b4707755864a0492Ying Wang
1905951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1906951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %poisson_distribution random number distribution
1907951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x into the output stream @p __os.
1908951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1909951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
1910951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %poisson_distribution random number distribution.
1911951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1912951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
1913951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
1914951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1915951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _RealType1,
1916951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1917951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
1918951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1919951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const poisson_distribution<_IntType1, _RealType1>& __x);
1920951a39d68df598db08dfced8b4707755864a0492Ying Wang
1921951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1922951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %poisson_distribution random number distribution
1923951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
1924951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1925951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
1926951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %poisson_distribution random number generator engine.
1927951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
1928951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
1929951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1930951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _RealType1,
1931951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
1932951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
1933951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1934951a39d68df598db08dfced8b4707755864a0492Ying Wang		   poisson_distribution<_IntType1, _RealType1>& __x);
1935951a39d68df598db08dfced8b4707755864a0492Ying Wang
1936951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
1937951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1938951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize();
1939951a39d68df598db08dfced8b4707755864a0492Ying Wang
1940951a39d68df598db08dfced8b4707755864a0492Ying Wang      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
1941951a39d68df598db08dfced8b4707755864a0492Ying Wang      normal_distribution<_RealType> _M_nd;
1942951a39d68df598db08dfced8b4707755864a0492Ying Wang
1943951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_mean;
1944951a39d68df598db08dfced8b4707755864a0492Ying Wang
1945951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Hosts either log(mean) or the threshold of the simple method.
1946951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_lm_thr;
1947951a39d68df598db08dfced8b4707755864a0492Ying Wang#if _GLIBCXX_USE_C99_MATH_TR1
1948951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
1949951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
1950951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
1951951a39d68df598db08dfced8b4707755864a0492Ying Wang
1952951a39d68df598db08dfced8b4707755864a0492Ying Wang
1953951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
1954951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A discrete binomial random number distribution.
1955951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
1956951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The formula for the binomial probability mass function is
1957951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
1958951a39d68df598db08dfced8b4707755864a0492Ying Wang   * and @f$ p @f$ are the parameters of the distribution.
1959951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
1960951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _IntType = int, typename _RealType = double>
1961951a39d68df598db08dfced8b4707755864a0492Ying Wang    class binomial_distribution
1962951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
1963951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
1964951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
1965951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
1966951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _IntType  result_type;
1967951a39d68df598db08dfced8b4707755864a0492Ying Wang
1968951a39d68df598db08dfced8b4707755864a0492Ying Wang      // constructors and member function
1969951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
1970951a39d68df598db08dfced8b4707755864a0492Ying Wang      binomial_distribution(_IntType __t = 1,
1971951a39d68df598db08dfced8b4707755864a0492Ying Wang			    const _RealType& __p = _RealType(0.5))
1972951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_t(__t), _M_p(__p), _M_nd()
1973951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
1974951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
1975951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_initialize();
1976951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
1977951a39d68df598db08dfced8b4707755864a0492Ying Wang
1978951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1979951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the distribution @p t parameter.
1980951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1981951a39d68df598db08dfced8b4707755864a0492Ying Wang      _IntType
1982951a39d68df598db08dfced8b4707755864a0492Ying Wang      t() const
1983951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_t; }
1984951a39d68df598db08dfced8b4707755864a0492Ying Wang
1985951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
1986951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the distribution @p p parameter.
1987951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
1988951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
1989951a39d68df598db08dfced8b4707755864a0492Ying Wang      p() const
1990951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_p; }
1991951a39d68df598db08dfced8b4707755864a0492Ying Wang
1992951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
1993951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset()
1994951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_nd.reset(); }
1995951a39d68df598db08dfced8b4707755864a0492Ying Wang
1996951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
1997951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
1998951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng);
1999951a39d68df598db08dfced8b4707755864a0492Ying Wang
2000951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2001951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %binomial_distribution random number distribution
2002951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x into the output stream @p __os.
2003951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2004951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
2005951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %binomial_distribution random number distribution.
2006951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2007951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
2008951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
2009951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2010951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _RealType1,
2011951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
2012951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
2013951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2014951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const binomial_distribution<_IntType1, _RealType1>& __x);
2015951a39d68df598db08dfced8b4707755864a0492Ying Wang
2016951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2017951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %binomial_distribution random number distribution
2018951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
2019951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2020951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
2021951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %binomial_distribution random number generator engine.
2022951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2023951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
2024951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2025951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _IntType1, typename _RealType1,
2026951a39d68df598db08dfced8b4707755864a0492Ying Wang	       typename _CharT, typename _Traits>
2027951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
2028951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2029951a39d68df598db08dfced8b4707755864a0492Ying Wang		   binomial_distribution<_IntType1, _RealType1>& __x);
2030951a39d68df598db08dfced8b4707755864a0492Ying Wang
2031951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
2032951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
2033951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize();
2034951a39d68df598db08dfced8b4707755864a0492Ying Wang
2035951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
2036951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
2037951a39d68df598db08dfced8b4707755864a0492Ying Wang        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
2038951a39d68df598db08dfced8b4707755864a0492Ying Wang
2039951a39d68df598db08dfced8b4707755864a0492Ying Wang      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
2040951a39d68df598db08dfced8b4707755864a0492Ying Wang      normal_distribution<_RealType> _M_nd;
2041951a39d68df598db08dfced8b4707755864a0492Ying Wang
2042951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_q;
2043951a39d68df598db08dfced8b4707755864a0492Ying Wang#if _GLIBCXX_USE_C99_MATH_TR1
2044951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
2045951a39d68df598db08dfced8b4707755864a0492Ying Wang	        _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
2046951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
2047951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_p;
2048951a39d68df598db08dfced8b4707755864a0492Ying Wang      _IntType  _M_t;
2049951a39d68df598db08dfced8b4707755864a0492Ying Wang
2050951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool      _M_easy;
2051951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
2052951a39d68df598db08dfced8b4707755864a0492Ying Wang
2053951a39d68df598db08dfced8b4707755864a0492Ying Wang  /* @} */ // group tr1_random_distributions_discrete
2054951a39d68df598db08dfced8b4707755864a0492Ying Wang
2055951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
205643f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh   * @addtogroup tr1_random_distributions_continuous Continuous Distributions
2057951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @ingroup tr1_random_distributions
2058951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @{
2059951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
2060951a39d68df598db08dfced8b4707755864a0492Ying Wang
2061951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
2062951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief Uniform continuous distribution for random numbers.
2063951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
2064951a39d68df598db08dfced8b4707755864a0492Ying Wang   * A continuous random distribution on the range [min, max) with equal
2065951a39d68df598db08dfced8b4707755864a0492Ying Wang   * probability throughout the range.  The URNG should be real-valued and
2066951a39d68df598db08dfced8b4707755864a0492Ying Wang   * deliver number in the range [0, 1).
2067951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
2068951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _RealType = double>
2069951a39d68df598db08dfced8b4707755864a0492Ying Wang    class uniform_real
2070951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
2071951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2072951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
2073951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
2074951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType result_type;
2075951a39d68df598db08dfced8b4707755864a0492Ying Wang
2076951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2077951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2078951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a uniform_real object.
2079951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2080951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __min [IN]  The lower bound of the distribution.
2081951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __max [IN]  The upper bound of the distribution.
2082951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2083951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
2084951a39d68df598db08dfced8b4707755864a0492Ying Wang      uniform_real(_RealType __min = _RealType(0),
2085951a39d68df598db08dfced8b4707755864a0492Ying Wang		   _RealType __max = _RealType(1))
2086951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_min(__min), _M_max(__max)
2087951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
2088951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
2089951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
2090951a39d68df598db08dfced8b4707755864a0492Ying Wang
2091951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
2092951a39d68df598db08dfced8b4707755864a0492Ying Wang      min() const
2093951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_min; }
2094951a39d68df598db08dfced8b4707755864a0492Ying Wang
2095951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type
2096951a39d68df598db08dfced8b4707755864a0492Ying Wang      max() const
2097951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_max; }
2098951a39d68df598db08dfced8b4707755864a0492Ying Wang
2099951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
2100951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset() { }
2101951a39d68df598db08dfced8b4707755864a0492Ying Wang
2102951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
2103951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
2104951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng)
2105951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return (__urng() * (_M_max - _M_min)) + _M_min; }
2106951a39d68df598db08dfced8b4707755864a0492Ying Wang
2107951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2108951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %uniform_real random number distribution @p __x into the
2109951a39d68df598db08dfced8b4707755864a0492Ying Wang       * output stream @p __os.
2110951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2111951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
2112951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %uniform_real random number distribution.
2113951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2114951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
2115951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
2116951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2117951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, typename _CharT, typename _Traits>
2118951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
2119951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2120951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const uniform_real<_RealType1>& __x);
2121951a39d68df598db08dfced8b4707755864a0492Ying Wang
2122951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2123951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %uniform_real random number distribution
2124951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
2125951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2126951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
2127951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %uniform_real random number generator engine.
2128951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2129951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
2130951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2131951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, typename _CharT, typename _Traits>
2132951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
2133951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2134951a39d68df598db08dfced8b4707755864a0492Ying Wang		   uniform_real<_RealType1>& __x);
2135951a39d68df598db08dfced8b4707755864a0492Ying Wang
2136951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
2137951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_min;
2138951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType _M_max;
2139951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
2140951a39d68df598db08dfced8b4707755864a0492Ying Wang
2141951a39d68df598db08dfced8b4707755864a0492Ying Wang
2142951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
2143951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief An exponential continuous distribution for random numbers.
2144951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
2145951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The formula for the exponential probability mass function is
2146951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @f$ p(x) = \lambda e^{-\lambda x} @f$.
2147951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
2148951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <table border=1 cellpadding=10 cellspacing=0>
2149951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <caption align=top>Distribution Statistics</caption>
2150951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2151951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
2152951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
2153951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
2154951a39d68df598db08dfced8b4707755864a0492Ying Wang   * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2155951a39d68df598db08dfced8b4707755864a0492Ying Wang   * </table>
2156951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
2157951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _RealType = double>
2158951a39d68df598db08dfced8b4707755864a0492Ying Wang    class exponential_distribution
2159951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
2160951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2161951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
2162951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
2163951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType result_type;
2164951a39d68df598db08dfced8b4707755864a0492Ying Wang
2165951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2166951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2167951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs an exponential distribution with inverse scale parameter
2168951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @f$ \lambda @f$.
2169951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2170951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
2171951a39d68df598db08dfced8b4707755864a0492Ying Wang      exponential_distribution(const result_type& __lambda = result_type(1))
2172951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_lambda(__lambda)
2173951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
2174951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
2175951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
2176951a39d68df598db08dfced8b4707755864a0492Ying Wang
2177951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2178951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the inverse scale parameter of the distribution.
2179951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2180951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
2181951a39d68df598db08dfced8b4707755864a0492Ying Wang      lambda() const
2182951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_lambda; }
2183951a39d68df598db08dfced8b4707755864a0492Ying Wang
2184951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2185951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Resets the distribution.
2186951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2187951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Has no effect on exponential distributions.
2188951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2189951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
2190951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset() { }
2191951a39d68df598db08dfced8b4707755864a0492Ying Wang
2192951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
2193951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
2194951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng)
2195951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return -std::log(__urng()) / _M_lambda; }
2196951a39d68df598db08dfced8b4707755864a0492Ying Wang
2197951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2198951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %exponential_distribution random number distribution
2199951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x into the output stream @p __os.
2200951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2201951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
2202951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %exponential_distribution random number distribution.
2203951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2204951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
2205951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
2206951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2207951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, typename _CharT, typename _Traits>
2208951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
2209951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2210951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const exponential_distribution<_RealType1>& __x);
2211951a39d68df598db08dfced8b4707755864a0492Ying Wang
2212951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2213951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %exponential_distribution random number distribution
2214951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
2215951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2216951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
2217951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x A %exponential_distribution random number
2218951a39d68df598db08dfced8b4707755864a0492Ying Wang       *            generator engine.
2219951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2220951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
2221951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2222951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _CharT, typename _Traits>
2223951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
2224951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2225951a39d68df598db08dfced8b4707755864a0492Ying Wang		   exponential_distribution& __x)
2226951a39d68df598db08dfced8b4707755864a0492Ying Wang        { return __is >> __x._M_lambda; }
2227951a39d68df598db08dfced8b4707755864a0492Ying Wang
2228951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
2229951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_lambda;
2230951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
2231951a39d68df598db08dfced8b4707755864a0492Ying Wang
2232951a39d68df598db08dfced8b4707755864a0492Ying Wang
2233951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
2234951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A normal continuous distribution for random numbers.
2235951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
2236951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The formula for the normal probability mass function is
2237951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}}
2238951a39d68df598db08dfced8b4707755864a0492Ying Wang   *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
2239951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
2240951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _RealType = double>
2241951a39d68df598db08dfced8b4707755864a0492Ying Wang    class normal_distribution
2242951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
2243951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2244951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
2245951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
2246951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType result_type;
2247951a39d68df598db08dfced8b4707755864a0492Ying Wang
2248951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2249951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2250951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a normal distribution with parameters @f$ mean @f$ and
2251951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @f$ \sigma @f$.
2252951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2253951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
2254951a39d68df598db08dfced8b4707755864a0492Ying Wang      normal_distribution(const result_type& __mean = result_type(0),
2255951a39d68df598db08dfced8b4707755864a0492Ying Wang			  const result_type& __sigma = result_type(1))
2256951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
2257951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
2258951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
2259951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
2260951a39d68df598db08dfced8b4707755864a0492Ying Wang
2261951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2262951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the mean of the distribution.
2263951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2264951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
2265951a39d68df598db08dfced8b4707755864a0492Ying Wang      mean() const
2266951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_mean; }
2267951a39d68df598db08dfced8b4707755864a0492Ying Wang
2268951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2269951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the @f$ \sigma @f$ of the distribution.
2270951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2271951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
2272951a39d68df598db08dfced8b4707755864a0492Ying Wang      sigma() const
2273951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_sigma; }
2274951a39d68df598db08dfced8b4707755864a0492Ying Wang
2275951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2276951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Resets the distribution.
2277951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2278951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
2279951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset()
2280951a39d68df598db08dfced8b4707755864a0492Ying Wang      { _M_saved_available = false; }
2281951a39d68df598db08dfced8b4707755864a0492Ying Wang
2282951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
2283951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
2284951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng);
2285951a39d68df598db08dfced8b4707755864a0492Ying Wang
2286951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2287951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %normal_distribution random number distribution
2288951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x into the output stream @p __os.
2289951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2290951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
2291951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %normal_distribution random number distribution.
2292951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2293951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
2294951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
2295951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2296951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, typename _CharT, typename _Traits>
2297951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
2298951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2299951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const normal_distribution<_RealType1>& __x);
2300951a39d68df598db08dfced8b4707755864a0492Ying Wang
2301951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2302951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %normal_distribution random number distribution
2303951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
2304951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2305951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
2306951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %normal_distribution random number generator engine.
2307951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2308951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
2309951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2310951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, typename _CharT, typename _Traits>
2311951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
2312951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2313951a39d68df598db08dfced8b4707755864a0492Ying Wang		   normal_distribution<_RealType1>& __x);
2314951a39d68df598db08dfced8b4707755864a0492Ying Wang
2315951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
2316951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_mean;
2317951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_sigma;
2318951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_saved;
2319951a39d68df598db08dfced8b4707755864a0492Ying Wang      bool        _M_saved_available;
2320951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
2321951a39d68df598db08dfced8b4707755864a0492Ying Wang
2322951a39d68df598db08dfced8b4707755864a0492Ying Wang
2323951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
2324951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @brief A gamma continuous distribution for random numbers.
2325951a39d68df598db08dfced8b4707755864a0492Ying Wang   *
2326951a39d68df598db08dfced8b4707755864a0492Ying Wang   * The formula for the gamma probability mass function is
2327951a39d68df598db08dfced8b4707755864a0492Ying Wang   * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
2328951a39d68df598db08dfced8b4707755864a0492Ying Wang   */
2329951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _RealType = double>
2330951a39d68df598db08dfced8b4707755864a0492Ying Wang    class gamma_distribution
2331951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
2332951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2333951a39d68df598db08dfced8b4707755864a0492Ying Wang      // types
2334951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType input_type;
2335951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _RealType result_type;
2336951a39d68df598db08dfced8b4707755864a0492Ying Wang
2337951a39d68df598db08dfced8b4707755864a0492Ying Wang    public:
2338951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2339951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Constructs a gamma distribution with parameters @f$ \alpha @f$.
2340951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2341951a39d68df598db08dfced8b4707755864a0492Ying Wang      explicit
2342951a39d68df598db08dfced8b4707755864a0492Ying Wang      gamma_distribution(const result_type& __alpha_val = result_type(1))
2343951a39d68df598db08dfced8b4707755864a0492Ying Wang      : _M_alpha(__alpha_val)
2344951a39d68df598db08dfced8b4707755864a0492Ying Wang      {
2345951a39d68df598db08dfced8b4707755864a0492Ying Wang	_GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
2346951a39d68df598db08dfced8b4707755864a0492Ying Wang	_M_initialize();
2347951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
2348951a39d68df598db08dfced8b4707755864a0492Ying Wang
2349951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2350951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Gets the @f$ \alpha @f$ of the distribution.
2351951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2352951a39d68df598db08dfced8b4707755864a0492Ying Wang      _RealType
2353951a39d68df598db08dfced8b4707755864a0492Ying Wang      alpha() const
2354951a39d68df598db08dfced8b4707755864a0492Ying Wang      { return _M_alpha; }
2355951a39d68df598db08dfced8b4707755864a0492Ying Wang
2356951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2357951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Resets the distribution.
2358951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2359951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
2360951a39d68df598db08dfced8b4707755864a0492Ying Wang      reset() { }
2361951a39d68df598db08dfced8b4707755864a0492Ying Wang
2362951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<class _UniformRandomNumberGenerator>
2363951a39d68df598db08dfced8b4707755864a0492Ying Wang        result_type
2364951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator()(_UniformRandomNumberGenerator& __urng);
2365951a39d68df598db08dfced8b4707755864a0492Ying Wang
2366951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2367951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Inserts a %gamma_distribution random number distribution
2368951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x into the output stream @p __os.
2369951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2370951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __os An output stream.
2371951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %gamma_distribution random number distribution.
2372951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2373951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The output stream with the state of @p __x inserted or in
2374951a39d68df598db08dfced8b4707755864a0492Ying Wang       * an error state.
2375951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2376951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _RealType1, typename _CharT, typename _Traits>
2377951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_ostream<_CharT, _Traits>&
2378951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2379951a39d68df598db08dfced8b4707755864a0492Ying Wang		   const gamma_distribution<_RealType1>& __x);
2380951a39d68df598db08dfced8b4707755864a0492Ying Wang
2381951a39d68df598db08dfced8b4707755864a0492Ying Wang      /**
2382951a39d68df598db08dfced8b4707755864a0492Ying Wang       * Extracts a %gamma_distribution random number distribution
2383951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @p __x from the input stream @p __is.
2384951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2385951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __is An input stream.
2386951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @param __x  A %gamma_distribution random number generator engine.
2387951a39d68df598db08dfced8b4707755864a0492Ying Wang       *
2388951a39d68df598db08dfced8b4707755864a0492Ying Wang       * @returns The input stream with @p __x extracted or in an error state.
2389951a39d68df598db08dfced8b4707755864a0492Ying Wang       */
2390951a39d68df598db08dfced8b4707755864a0492Ying Wang      template<typename _CharT, typename _Traits>
2391951a39d68df598db08dfced8b4707755864a0492Ying Wang        friend std::basic_istream<_CharT, _Traits>&
2392951a39d68df598db08dfced8b4707755864a0492Ying Wang        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2393951a39d68df598db08dfced8b4707755864a0492Ying Wang		   gamma_distribution& __x)
2394951a39d68df598db08dfced8b4707755864a0492Ying Wang        {
2395951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __is >> __x._M_alpha;
2396951a39d68df598db08dfced8b4707755864a0492Ying Wang	  __x._M_initialize();
2397951a39d68df598db08dfced8b4707755864a0492Ying Wang	  return __is;
2398951a39d68df598db08dfced8b4707755864a0492Ying Wang	}
2399951a39d68df598db08dfced8b4707755864a0492Ying Wang
2400951a39d68df598db08dfced8b4707755864a0492Ying Wang    private:
2401951a39d68df598db08dfced8b4707755864a0492Ying Wang      void
2402951a39d68df598db08dfced8b4707755864a0492Ying Wang      _M_initialize();
2403951a39d68df598db08dfced8b4707755864a0492Ying Wang
2404951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_alpha;
2405951a39d68df598db08dfced8b4707755864a0492Ying Wang
2406951a39d68df598db08dfced8b4707755864a0492Ying Wang      // Hosts either lambda of GB or d of modified Vaduva's.
2407951a39d68df598db08dfced8b4707755864a0492Ying Wang      result_type _M_l_d;
2408951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
2409951a39d68df598db08dfced8b4707755864a0492Ying Wang
2410951a39d68df598db08dfced8b4707755864a0492Ying Wang  /* @} */ // group tr1_random_distributions_continuous
2411951a39d68df598db08dfced8b4707755864a0492Ying Wang  /* @} */ // group tr1_random_distributions
2412951a39d68df598db08dfced8b4707755864a0492Ying Wang  /* @} */ // group tr1_random
241343f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh_GLIBCXX_END_NAMESPACE_VERSION
241443f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh}
2415951a39d68df598db08dfced8b4707755864a0492Ying Wang}
2416951a39d68df598db08dfced8b4707755864a0492Ying Wang
241743f272afd56a57640c62c952f9266478bacf0244Andrew Hsieh#endif // _GLIBCXX_TR1_RANDOM_H
2418