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