summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/tr1
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-02 23:45:56 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-02 23:45:56 +0000
commitfca66f47520328658166c82251fc204ea0e6b15c (patch)
treef4ed79c52311d112b705d66b823f394ed5470229 /libstdc++-v3/include/tr1
parent72a07504e70410117d850c90bef3a1f681723155 (diff)
downloadgcc-fca66f47520328658166c82251fc204ea0e6b15c.tar.gz
2009-04-02 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc: Change to mersenne_twister_engine, add same defaults as mersenne_twister_engine/cons/default.cc. * testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc: Same. * include/bits/random.tcc (seed_seq::seed_seq): Uglify parameter to __il. * include/bits/random.h (mersenne_twister_engine): Qualify _ShiftMin1 with namespace __detail. (__detail::_ShiftMin1): Use __gnu_cxx::__numeric_traits::max until constexpr std::numeric_limits::max() can be used. (mersenne_twister_engine): Split apart static asserts into one assert per message. Temporarily disable the last three. 2009-04-02 Edward Smith-Rowland <3dw4rd@verizon.net> * include/Makefile.am: Update to N2836. Modified for new random headers. * include/Makefile.in: Ditto. * include/tr1_impl/random: Moved to tr1/random.h * include/tr1_impl/random.tcc: Moved to tr1 * include/tr1/random: Just point to moved tr1 random headers. * include/tr1/random.tcc: Moved from tr1_impl. * include/tr1/random.h: Moved from tr1_impl/random. * include/std/random: Modified to point to std random headers. * include/bits/random.tcc: New implementation of std random facilities. * include/bits/random.h: Ditto. * testsuite/26_numerics/headers/random/std_c++0x_neg.cc: Changed. * testsuite/26_numerics/random/linear_congruential_engine/cons/ seed1.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/cons/ seed2.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/cons/ default.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/requirements/ non_uint_neg.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/operators/ equal.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/operators/ serialize.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/cons/ seed1.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/cons/ seed2.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/cons/ default.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/operators/ equal.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/operators/ serialize.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/cons/ seed1.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/cons/ seed2.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/cons/ default.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/operators/ equal.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/operators/ serialize.cc: New. * testsuite/26_numerics/random/discard_block_engine/cons/ base_move.cc: New. * testsuite/26_numerics/random/discard_block_engine/cons/ seed1.cc: New. * testsuite/26_numerics/random/discard_block_engine/cons/ seed2.cc: New. * testsuite/26_numerics/random/discard_block_engine/cons/ base_copy.cc: New. * testsuite/26_numerics/random/discard_block_engine/cons/ default.cc: New. * testsuite/26_numerics/random/discard_block_engine/cons/ seed_seq.cc: New. * testsuite/26_numerics/random/discard_block_engine/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/discard_block_engine/operators/ equal.cc: New. * testsuite/26_numerics/random/discard_block_engine/operators/ serialize.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ base_move.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ seed1.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ seed2.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ base_copy.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ default.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ seed_seq.cc: New. * testsuite/26_numerics/random/independent_bits_engine/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/independent_bits_engine/operators/ equal.cc: New. * testsuite/26_numerics/random/independent_bits_engine/operators/ serialize.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/cons/ base_move.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/cons/ seed1.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/cons/ seed2.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/cons/ base_copy.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/cons/ default.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/cons/ seed_seq.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/operators/ equal.cc: New. * testsuite/26_numerics/random/shuffle_order_engine/operators/ serialize.cc * testsuite/26_numerics/random/mt19937.cc: New. * testsuite/26_numerics/random/mt19937_64.cc: New. * testsuite/26_numerics/random/minstd_rand.cc: New. * testsuite/26_numerics/random/minstd_rand0.cc: New. * testsuite/26_numerics/random/ranlux24_base.cc: New. * testsuite/26_numerics/random/ranlux48_base.cc: New. * testsuite/26_numerics/random/ranlux24.cc: New. * testsuite/26_numerics/random/ranlux48.cc: New. * testsuite/26_numerics/random/knuth_b.cc: New. * testsuite/26_numerics/random/default_random_engine.cc: New. * testsuite/26_numerics/random/chi_squared_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/chi_squared_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/chi_squared_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/chi_squared_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/normal_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/normal_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/normal_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/normal_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/seed_seq/cons/range.cc: New. * testsuite/26_numerics/random/seed_seq/cons/default.cc: New. * testsuite/26_numerics/random/seed_seq/requirements/typedefs.cc: New. * testsuite/26_numerics/random/uniform_int_distribution/cons/ parms_neg.cc: New. * testsuite/26_numerics/random/uniform_int_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/uniform_int_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/uniform_int_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/uniform_int_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/uniform_real_distribution/cons/ parms_neg.cc: New. * testsuite/26_numerics/random/uniform_real_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/uniform_real_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/uniform_real_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/uniform_real_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/poisson_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/poisson_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/poisson_distribution/requirements/ typedefs.cc * testsuite/26_numerics/random/poisson_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/bernoulli_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/bernoulli_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/bernoulli_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/bernoulli_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/discrete_distribution/cons/ range.cc: New. * testsuite/26_numerics/random/discrete_distribution/cons/ initlist.cc: New. * testsuite/26_numerics/random/discrete_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/discrete_distribution/cons/ num_xbound_fun.cc: New. * testsuite/26_numerics/random/discrete_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/discrete_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/weibull_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/weibull_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/weibull_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/weibull_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/negative_binomial_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/negative_binomial_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/negative_binomial_distribution/ requirements/typedefs.cc: New. * testsuite/26_numerics/random/negative_binomial_distribution/ operators/serialize.cc: New. * testsuite/26_numerics/random/cauchy_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/cauchy_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/cauchy_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/cauchy_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/gamma_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/gamma_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/gamma_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/gamma_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/fisher_f_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/fisher_f_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/fisher_f_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/fisher_f_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/exponential_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/exponential_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/exponential_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/exponential_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/lognormal_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/lognormal_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/lognormal_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/lognormal_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/binomial_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/binomial_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/binomial_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/binomial_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/random_device/cons/ token.cc: New. * testsuite/26_numerics/random/random_device/cons/ default.cc: New. * testsuite/26_numerics/random/random_device/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/extreme_value_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/extreme_value_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/extreme_value_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/extreme_value_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/piecewise_linear_distribution/cons/ range.cc: New. * testsuite/26_numerics/random/piecewise_linear_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/piecewise_linear_distribution/cons/ num_xbound_fun.cc: New. * testsuite/26_numerics/random/piecewise_linear_distribution/cons/ initlist_fun.cc: New. * testsuite/26_numerics/random/piecewise_linear_distribution/ requirements/typedefs.cc: New. * testsuite/26_numerics/random/piecewise_linear_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/student_t_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/student_t_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/student_t_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/student_t_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/geometric_distribution/cons/ parms.cc: New. * testsuite/26_numerics/random/geometric_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/geometric_distribution/requirements/ typedefs.cc: New. * testsuite/26_numerics/random/geometric_distribution/operators/ serialize.cc: New. * testsuite/26_numerics/random/piecewise_constant_distribution/cons/ range.cc: New. * testsuite/26_numerics/random/piecewise_constant_distribution/cons/ default.cc: New. * testsuite/26_numerics/random/piecewise_constant_distribution/cons/ num_xbound_fun.cc: New. * testsuite/26_numerics/random/piecewise_constant_distribution/cons/ initlist_fun.cc: New. * testsuite/26_numerics/random/piecewise_constant_distribution/ requirements/typedefs.cc: New. * testsuite/26_numerics/random/piecewise_constant_distribution/ operators/serialize.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145483 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/tr1')
-rw-r--r--libstdc++-v3/include/tr1/random8
-rw-r--r--libstdc++-v3/include/tr1/random.h2436
-rw-r--r--libstdc++-v3/include/tr1/random.tcc1583
3 files changed, 4021 insertions, 6 deletions
diff --git a/libstdc++-v3/include/tr1/random b/libstdc++-v3/include/tr1/random
index 49a3b21cd81..6f6e3234b89 100644
--- a/libstdc++-v3/include/tr1/random
+++ b/libstdc++-v3/include/tr1/random
@@ -55,16 +55,12 @@
#include <tr1/cmath>
#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-# include <tr1_impl/random>
+# include <tr1/random.h>
#else
# define _GLIBCXX_INCLUDE_AS_TR1
-# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
-# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 tr1::
-# include <tr1_impl/random>
+# include <tr1/random.h>
# undef _GLIBCXX_TR1
-# undef _GLIBCXX_END_NAMESPACE_TR1
-# undef _GLIBCXX_BEGIN_NAMESPACE_TR1
# undef _GLIBCXX_INCLUDE_AS_TR1
#endif
diff --git a/libstdc++-v3/include/tr1/random.h b/libstdc++-v3/include/tr1/random.h
new file mode 100644
index 00000000000..5a0f6b741b6
--- /dev/null
+++ b/libstdc++-v3/include/tr1/random.h
@@ -0,0 +1,2436 @@
+// random number generation -*- C++ -*-
+
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/**
+ * @file tr1/random.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_TR1_RANDOM_H
+#define _GLIBCXX_TR1_RANDOM_H 1
+
+#pragma GCC system_header
+
+#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
+# error TR1 header cannot be included from C++0x header
+#endif
+
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <iosfwd>
+#include <limits>
+#include <ext/type_traits.h>
+#include <ext/numeric_traits.h>
+#include <bits/concept_check.h>
+#include <debug/debug.h>
+#include <tr1/type_traits>
+#include <tr1/cmath>
+
+namespace std
+{
+namespace tr1
+{
+
+ // [5.1] Random number generation
+
+ /**
+ * @addtogroup tr1_random Random Number Generation
+ * A facility for generating random numbers on selected distributions.
+ * @{
+ */
+
+ /*
+ * Implementation-space details.
+ */
+ namespace __detail
+ {
+ template<typename _UIntType, int __w,
+ bool = __w < std::numeric_limits<_UIntType>::digits>
+ struct _Shift
+ { static const _UIntType __value = 0; };
+
+ template<typename _UIntType, int __w>
+ struct _Shift<_UIntType, __w, true>
+ { static const _UIntType __value = _UIntType(1) << __w; };
+
+ template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
+ struct _Mod;
+
+ // Dispatch based on modulus value to prevent divide-by-zero compile-time
+ // errors when m == 0.
+ template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
+ inline _Tp
+ __mod(_Tp __x)
+ { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
+
+ typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
+ unsigned, unsigned long>::__type _UInt32Type;
+
+ /*
+ * An adaptor class for converting the output of any Generator into
+ * the input for a specific Distribution.
+ */
+ template<typename _Engine, typename _Distribution>
+ struct _Adaptor
+ {
+ typedef typename remove_reference<_Engine>::type _BEngine;
+ typedef typename _BEngine::result_type _Engine_result_type;
+ typedef typename _Distribution::input_type result_type;
+
+ public:
+ _Adaptor(const _Engine& __g)
+ : _M_g(__g) { }
+
+ result_type
+ min() const
+ {
+ result_type __return_value;
+ if (is_integral<_Engine_result_type>::value
+ && is_integral<result_type>::value)
+ __return_value = _M_g.min();
+ else
+ __return_value = result_type(0);
+ return __return_value;
+ }
+
+ result_type
+ max() const
+ {
+ result_type __return_value;
+ if (is_integral<_Engine_result_type>::value
+ && is_integral<result_type>::value)
+ __return_value = _M_g.max();
+ else if (!is_integral<result_type>::value)
+ __return_value = result_type(1);
+ else
+ __return_value = std::numeric_limits<result_type>::max() - 1;
+ return __return_value;
+ }
+
+ /*
+ * Converts a value generated by the adapted random number generator
+ * into a value in the input domain for the dependent random number
+ * distribution.
+ *
+ * Because the type traits are compile time constants only the
+ * appropriate clause of the if statements will actually be emitted
+ * by the compiler.
+ */
+ result_type
+ operator()()
+ {
+ result_type __return_value;
+ if (is_integral<_Engine_result_type>::value
+ && is_integral<result_type>::value)
+ __return_value = _M_g();
+ else if (!is_integral<_Engine_result_type>::value
+ && !is_integral<result_type>::value)
+ __return_value = result_type(_M_g() - _M_g.min())
+ / result_type(_M_g.max() - _M_g.min());
+ else if (is_integral<_Engine_result_type>::value
+ && !is_integral<result_type>::value)
+ __return_value = result_type(_M_g() - _M_g.min())
+ / result_type(_M_g.max() - _M_g.min() + result_type(1));
+ else
+ __return_value = (((_M_g() - _M_g.min())
+ / (_M_g.max() - _M_g.min()))
+ * std::numeric_limits<result_type>::max());
+ return __return_value;
+ }
+
+ private:
+ _Engine _M_g;
+ };
+
+ // Specialization for _Engine*.
+ template<typename _Engine, typename _Distribution>
+ struct _Adaptor<_Engine*, _Distribution>
+ {
+ typedef typename _Engine::result_type _Engine_result_type;
+ typedef typename _Distribution::input_type result_type;
+
+ public:
+ _Adaptor(_Engine* __g)
+ : _M_g(__g) { }
+
+ result_type
+ min() const
+ {
+ result_type __return_value;
+ if (is_integral<_Engine_result_type>::value
+ && is_integral<result_type>::value)
+ __return_value = _M_g->min();
+ else
+ __return_value = result_type(0);
+ return __return_value;
+ }
+
+ result_type
+ max() const
+ {
+ result_type __return_value;
+ if (is_integral<_Engine_result_type>::value
+ && is_integral<result_type>::value)
+ __return_value = _M_g->max();
+ else if (!is_integral<result_type>::value)
+ __return_value = result_type(1);
+ else
+ __return_value = std::numeric_limits<result_type>::max() - 1;
+ return __return_value;
+ }
+
+ result_type
+ operator()()
+ {
+ result_type __return_value;
+ if (is_integral<_Engine_result_type>::value
+ && is_integral<result_type>::value)
+ __return_value = (*_M_g)();
+ else if (!is_integral<_Engine_result_type>::value
+ && !is_integral<result_type>::value)
+ __return_value = result_type((*_M_g)() - _M_g->min())
+ / result_type(_M_g->max() - _M_g->min());
+ else if (is_integral<_Engine_result_type>::value
+ && !is_integral<result_type>::value)
+ __return_value = result_type((*_M_g)() - _M_g->min())
+ / result_type(_M_g->max() - _M_g->min() + result_type(1));
+ else
+ __return_value = ((((*_M_g)() - _M_g->min())
+ / (_M_g->max() - _M_g->min()))
+ * std::numeric_limits<result_type>::max());
+ return __return_value;
+ }
+
+ private:
+ _Engine* _M_g;
+ };
+ } // namespace __detail
+
+ /**
+ * Produces random numbers on a given distribution function using a
+ * non-uniform random number generation engine.
+ *
+ * @todo the engine_value_type needs to be studied more carefully.
+ */
+ template<typename _Engine, typename _Dist>
+ class variate_generator
+ {
+ // Concept requirements.
+ __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
+ // __glibcxx_class_requires(_Engine, _EngineConcept)
+ // __glibcxx_class_requires(_Dist, _EngineConcept)
+
+ public:
+ typedef _Engine engine_type;
+ typedef __detail::_Adaptor<_Engine, _Dist> engine_value_type;
+ typedef _Dist distribution_type;
+ typedef typename _Dist::result_type result_type;
+
+ // tr1:5.1.1 table 5.1 requirement
+ typedef typename __gnu_cxx::__enable_if<
+ is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
+
+ /**
+ * Constructs a variate generator with the uniform random number
+ * generator @p __eng for the random distribution @p __dist.
+ *
+ * @throws Any exceptions which may thrown by the copy constructors of
+ * the @p _Engine or @p _Dist objects.
+ */
+ variate_generator(engine_type __eng, distribution_type __dist)
+ : _M_engine(__eng), _M_dist(__dist) { }
+
+ /**
+ * Gets the next generated value on the distribution.
+ */
+ result_type
+ operator()()
+ { return _M_dist(_M_engine); }
+
+ /**
+ * WTF?
+ */
+ template<typename _Tp>
+ result_type
+ operator()(_Tp __value)
+ { return _M_dist(_M_engine, __value); }
+
+ /**
+ * Gets a reference to the underlying uniform random number generator
+ * object.
+ */
+ engine_value_type&
+ engine()
+ { return _M_engine; }
+
+ /**
+ * Gets a const reference to the underlying uniform random number
+ * generator object.
+ */
+ const engine_value_type&
+ engine() const
+ { return _M_engine; }
+
+ /**
+ * Gets a reference to the underlying random distribution.
+ */
+ distribution_type&
+ distribution()
+ { return _M_dist; }
+
+ /**
+ * Gets a const reference to the underlying random distribution.
+ */
+ const distribution_type&
+ distribution() const
+ { return _M_dist; }
+
+ /**
+ * Gets the closed lower bound of the distribution interval.
+ */
+ result_type
+ min() const
+ { return this->distribution().min(); }
+
+ /**
+ * Gets the closed upper bound of the distribution interval.
+ */
+ result_type
+ max() const
+ { return this->distribution().max(); }
+
+ private:
+ engine_value_type _M_engine;
+ distribution_type _M_dist;
+ };
+
+
+ /**
+ * @addtogroup tr1_random_generators Random Number Generators
+ * @ingroup tr1_random
+ *
+ * These classes define objects which provide random or pseudorandom
+ * numbers, either from a discrete or a continuous interval. The
+ * random number generator supplied as a part of this library are
+ * all uniform random number generators which provide a sequence of
+ * random number uniformly distributed over their range.
+ *
+ * A number generator is a function object with an operator() that
+ * takes zero arguments and returns a number.
+ *
+ * A compliant random number generator must satisfy the following
+ * requirements. <table border=1 cellpadding=10 cellspacing=0>
+ * <caption align=top>Random Number Generator Requirements</caption>
+ * <tr><td>To be documented.</td></tr> </table>
+ *
+ * @{
+ */
+
+ /**
+ * @brief A model of a linear congruential random number generator.
+ *
+ * A random number generator that produces pseudorandom numbers using the
+ * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
+ *
+ * The template parameter @p _UIntType must be an unsigned integral type
+ * large enough to store values up to (__m-1). If the template parameter
+ * @p __m is 0, the modulus @p __m used is
+ * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
+ * parameters @p __a and @p __c must be less than @p __m.
+ *
+ * The size of the state is @f$ 1 @f$.
+ */
+ template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+ class linear_congruential
+ {
+ __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
+ // __glibcpp_class_requires(__a < __m && __c < __m)
+
+ public:
+ /** The type of the generated random value. */
+ typedef _UIntType result_type;
+
+ /** The multiplier. */
+ static const _UIntType multiplier = __a;
+ /** An increment. */
+ static const _UIntType increment = __c;
+ /** The modulus. */
+ static const _UIntType modulus = __m;
+
+ /**
+ * Constructs a %linear_congruential random number generator engine with
+ * seed @p __s. The default seed value is 1.
+ *
+ * @param __s The initial seed value.
+ */
+ explicit
+ linear_congruential(unsigned long __x0 = 1)
+ { this->seed(__x0); }
+
+ /**
+ * Constructs a %linear_congruential random number generator engine
+ * seeded from the generator function @p __g.
+ *
+ * @param __g The seed generator function.
+ */
+ template<class _Gen>
+ linear_congruential(_Gen& __g)
+ { this->seed(__g); }
+
+ /**
+ * Reseeds the %linear_congruential random number generator engine
+ * sequence to the seed @g __s.
+ *
+ * @param __s The new seed.
+ */
+ void
+ seed(unsigned long __s = 1);
+
+ /**
+ * Reseeds the %linear_congruential random number generator engine
+ * sequence using values from the generator function @p __g.
+ *
+ * @param __g the seed generator function.
+ */
+ template<class _Gen>
+ void
+ seed(_Gen& __g)
+ { seed(__g, typename is_fundamental<_Gen>::type()); }
+
+ /**
+ * Gets the smallest possible value in the output range.
+ *
+ * The minimum depends on the @p __c parameter: if it is zero, the
+ * minimum generated must be > 0, otherwise 0 is allowed.
+ */
+ result_type
+ min() const
+ { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
+
+ /**
+ * Gets the largest possible value in the output range.
+ */
+ result_type
+ max() const
+ { return __m - 1; }
+
+ /**
+ * Gets the next random number in the sequence.
+ */
+ result_type
+ operator()();
+
+ /**
+ * Compares two linear congruential random number generator
+ * objects of the same type for equality.
+ *
+ * @param __lhs A linear congruential random number generator object.
+ * @param __rhs Another linear congruential random number generator obj.
+ *
+ * @returns true if the two objects are equal, false otherwise.
+ */
+ friend bool
+ operator==(const linear_congruential& __lhs,
+ const linear_congruential& __rhs)
+ { return __lhs._M_x == __rhs._M_x; }
+
+ /**
+ * Compares two linear congruential random number generator
+ * objects of the same type for inequality.
+ *
+ * @param __lhs A linear congruential random number generator object.
+ * @param __rhs Another linear congruential random number generator obj.
+ *
+ * @returns true if the two objects are not equal, false otherwise.
+ */
+ friend bool
+ operator!=(const linear_congruential& __lhs,
+ const linear_congruential& __rhs)
+ { return !(__lhs == __rhs); }
+
+ /**
+ * Writes the textual representation of the state x(i) of x to @p __os.
+ *
+ * @param __os The output stream.
+ * @param __lcr A % linear_congruential random number generator.
+ * @returns __os.
+ */
+ template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
+ _UIntType1 __m1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const linear_congruential<_UIntType1, __a1, __c1,
+ __m1>& __lcr);
+
+ /**
+ * Sets the state of the engine by reading its textual
+ * representation from @p __is.
+ *
+ * The textual representation must have been previously written using an
+ * output stream whose imbued locale and whose type's template
+ * specialization arguments _CharT and _Traits were the same as those of
+ * @p __is.
+ *
+ * @param __is The input stream.
+ * @param __lcr A % linear_congruential random number generator.
+ * @returns __is.
+ */
+ template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
+ _UIntType1 __m1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
+
+ private:
+ template<class _Gen>
+ void
+ seed(_Gen& __g, true_type)
+ { return seed(static_cast<unsigned long>(__g)); }
+
+ template<class _Gen>
+ void
+ seed(_Gen& __g, false_type);
+
+ _UIntType _M_x;
+ };
+
+ /**
+ * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
+ */
+ typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
+
+ /**
+ * An alternative LCR (Lehmer Generator function) .
+ */
+ typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
+
+
+ /**
+ * A generalized feedback shift register discrete random number generator.
+ *
+ * This algorithm avoids multiplication and division and is designed to be
+ * friendly to a pipelined architecture. If the parameters are chosen
+ * correctly, this generator will produce numbers with a very long period and
+ * fairly good apparent entropy, although still not cryptographically strong.
+ *
+ * The best way to use this generator is with the predefined mt19937 class.
+ *
+ * This algorithm was originally invented by Makoto Matsumoto and
+ * Takuji Nishimura.
+ *
+ * @var word_size The number of bits in each element of the state vector.
+ * @var state_size The degree of recursion.
+ * @var shift_size The period parameter.
+ * @var mask_bits The separation point bit index.
+ * @var parameter_a The last row of the twist matrix.
+ * @var output_u The first right-shift tempering matrix parameter.
+ * @var output_s The first left-shift tempering matrix parameter.
+ * @var output_b The first left-shift tempering matrix mask.
+ * @var output_t The second left-shift tempering matrix parameter.
+ * @var output_c The second left-shift tempering matrix mask.
+ * @var output_l The second right-shift tempering matrix parameter.
+ */
+ template<class _UIntType, int __w, int __n, int __m, int __r,
+ _UIntType __a, int __u, int __s, _UIntType __b, int __t,
+ _UIntType __c, int __l>
+ class mersenne_twister
+ {
+ __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
+
+ public:
+ // types
+ typedef _UIntType result_type;
+
+ // parameter values
+ static const int word_size = __w;
+ static const int state_size = __n;
+ static const int shift_size = __m;
+ static const int mask_bits = __r;
+ static const _UIntType parameter_a = __a;
+ static const int output_u = __u;
+ static const int output_s = __s;
+ static const _UIntType output_b = __b;
+ static const int output_t = __t;
+ static const _UIntType output_c = __c;
+ static const int output_l = __l;
+
+ // constructors and member function
+ mersenne_twister()
+ { seed(); }
+
+ explicit
+ mersenne_twister(unsigned long __value)
+ { seed(__value); }
+
+ template<class _Gen>
+ mersenne_twister(_Gen& __g)
+ { seed(__g); }
+
+ void
+ seed()
+ { seed(5489UL); }
+
+ void
+ seed(unsigned long __value);
+
+ template<class _Gen>
+ void
+ seed(_Gen& __g)
+ { seed(__g, typename is_fundamental<_Gen>::type()); }
+
+ result_type
+ min() const
+ { return 0; };
+
+ result_type
+ max() const
+ { return __detail::_Shift<_UIntType, __w>::__value - 1; }
+
+ result_type
+ operator()();
+
+ /**
+ * Compares two % mersenne_twister random number generator objects of
+ * the same type for equality.
+ *
+ * @param __lhs A % mersenne_twister random number generator object.
+ * @param __rhs Another % mersenne_twister random number generator
+ * object.
+ *
+ * @returns true if the two objects are equal, false otherwise.
+ */
+ friend bool
+ operator==(const mersenne_twister& __lhs,
+ const mersenne_twister& __rhs)
+ { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
+
+ /**
+ * Compares two % mersenne_twister random number generator objects of
+ * the same type for inequality.
+ *
+ * @param __lhs A % mersenne_twister random number generator object.
+ * @param __rhs Another % mersenne_twister random number generator
+ * object.
+ *
+ * @returns true if the two objects are not equal, false otherwise.
+ */
+ friend bool
+ operator!=(const mersenne_twister& __lhs,
+ const mersenne_twister& __rhs)
+ { return !(__lhs == __rhs); }
+
+ /**
+ * Inserts the current state of a % mersenne_twister random number
+ * generator engine @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A % mersenne_twister random number generator engine.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
+ _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
+ _UIntType1 __c1, int __l1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
+ __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
+
+ /**
+ * Extracts the current state of a % mersenne_twister random number
+ * generator engine @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A % mersenne_twister random number generator engine.
+ *
+ * @returns The input stream with the state of @p __x extracted or in
+ * an error state.
+ */
+ template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
+ _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
+ _UIntType1 __c1, int __l1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
+ __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
+
+ private:
+ template<class _Gen>
+ void
+ seed(_Gen& __g, true_type)
+ { return seed(static_cast<unsigned long>(__g)); }
+
+ template<class _Gen>
+ void
+ seed(_Gen& __g, false_type);
+
+ _UIntType _M_x[state_size];
+ int _M_p;
+ };
+
+ /**
+ * The classic Mersenne Twister.
+ *
+ * Reference:
+ * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
+ * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
+ * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
+ */
+ typedef mersenne_twister<
+ unsigned long, 32, 624, 397, 31,
+ 0x9908b0dful, 11, 7,
+ 0x9d2c5680ul, 15,
+ 0xefc60000ul, 18
+ > mt19937;
+
+
+ /**
+ * @brief The Marsaglia-Zaman generator.
+ *
+ * This is a model of a Generalized Fibonacci discrete random number
+ * generator, sometimes referred to as the SWC generator.
+ *
+ * A discrete random number generator that produces pseudorandom
+ * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
+ * carry_{i-1}) \bmod m @f$.
+ *
+ * The size of the state is @f$ r @f$
+ * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
+ *
+ * N1688[4.13] says "the template parameter _IntType shall denote an integral
+ * type large enough to store values up to m."
+ *
+ * @var _M_x The state of the generator. This is a ring buffer.
+ * @var _M_carry The carry.
+ * @var _M_p Current index of x(i - r).
+ */
+ template<typename _IntType, _IntType __m, int __s, int __r>
+ class subtract_with_carry
+ {
+ __glibcxx_class_requires(_IntType, _IntegerConcept)
+
+ public:
+ /** The type of the generated random value. */
+ typedef _IntType result_type;
+
+ // parameter values
+ static const _IntType modulus = __m;
+ static const int long_lag = __r;
+ static const int short_lag = __s;
+
+ /**
+ * Constructs a default-initialized % subtract_with_carry random number
+ * generator.
+ */
+ subtract_with_carry()
+ { this->seed(); }
+
+ /**
+ * Constructs an explicitly seeded % subtract_with_carry random number
+ * generator.
+ */
+ explicit
+ subtract_with_carry(unsigned long __value)
+ { this->seed(__value); }
+
+ /**
+ * Constructs a %subtract_with_carry random number generator engine
+ * seeded from the generator function @p __g.
+ *
+ * @param __g The seed generator function.
+ */
+ template<class _Gen>
+ subtract_with_carry(_Gen& __g)
+ { this->seed(__g); }
+
+ /**
+ * Seeds the initial state @f$ x_0 @f$ of the random number generator.
+ *
+ * N1688[4.19] modifies this as follows. If @p __value == 0,
+ * sets value to 19780503. In any case, with a linear
+ * congruential generator lcg(i) having parameters @f$ m_{lcg} =
+ * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
+ * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
+ * \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$
+ * set carry to 1, otherwise sets carry to 0.
+ */
+ void
+ seed(unsigned long __value = 19780503);
+
+ /**
+ * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
+ * random number generator.
+ */
+ template<class _Gen>
+ void
+ seed(_Gen& __g)
+ { seed(__g, typename is_fundamental<_Gen>::type()); }
+
+ /**
+ * Gets the inclusive minimum value of the range of random integers
+ * returned by this generator.
+ */
+ result_type
+ min() const
+ { return 0; }
+
+ /**
+ * Gets the inclusive maximum value of the range of random integers
+ * returned by this generator.
+ */
+ result_type
+ max() const
+ { return this->modulus - 1; }
+
+ /**
+ * Gets the next random number in the sequence.
+ */
+ result_type
+ operator()();
+
+ /**
+ * Compares two % subtract_with_carry random number generator objects of
+ * the same type for equality.
+ *
+ * @param __lhs A % subtract_with_carry random number generator object.
+ * @param __rhs Another % subtract_with_carry random number generator
+ * object.
+ *
+ * @returns true if the two objects are equal, false otherwise.
+ */
+ friend bool
+ operator==(const subtract_with_carry& __lhs,
+ const subtract_with_carry& __rhs)
+ { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
+
+ /**
+ * Compares two % subtract_with_carry random number generator objects of
+ * the same type for inequality.
+ *
+ * @param __lhs A % subtract_with_carry random number generator object.
+ * @param __rhs Another % subtract_with_carry random number generator
+ * object.
+ *
+ * @returns true if the two objects are not equal, false otherwise.
+ */
+ friend bool
+ operator!=(const subtract_with_carry& __lhs,
+ const subtract_with_carry& __rhs)
+ { return !(__lhs == __rhs); }
+
+ /**
+ * Inserts the current state of a % subtract_with_carry random number
+ * generator engine @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A % subtract_with_carry random number generator engine.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const subtract_with_carry<_IntType1, __m1, __s1,
+ __r1>& __x);
+
+ /**
+ * Extracts the current state of a % subtract_with_carry random number
+ * generator engine @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A % subtract_with_carry random number generator engine.
+ *
+ * @returns The input stream with the state of @p __x extracted or in
+ * an error state.
+ */
+ template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
+
+ private:
+ template<class _Gen>
+ void
+ seed(_Gen& __g, true_type)
+ { return seed(static_cast<unsigned long>(__g)); }
+
+ template<class _Gen>
+ void
+ seed(_Gen& __g, false_type);
+
+ typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
+
+ _UIntType _M_x[long_lag];
+ _UIntType _M_carry;
+ int _M_p;
+ };
+
+
+ /**
+ * @brief The Marsaglia-Zaman generator (floats version).
+ *
+ * @var _M_x The state of the generator. This is a ring buffer.
+ * @var _M_carry The carry.
+ * @var _M_p Current index of x(i - r).
+ * @var _M_npows Precomputed negative powers of 2.
+ */
+ template<typename _RealType, int __w, int __s, int __r>
+ class subtract_with_carry_01
+ {
+ public:
+ /** The type of the generated random value. */
+ typedef _RealType result_type;
+
+ // parameter values
+ static const int word_size = __w;
+ static const int long_lag = __r;
+ static const int short_lag = __s;
+
+ /**
+ * Constructs a default-initialized % subtract_with_carry_01 random
+ * number generator.
+ */
+ subtract_with_carry_01()
+ {
+ this->seed();
+ _M_initialize_npows();
+ }
+
+ /**
+ * Constructs an explicitly seeded % subtract_with_carry_01 random number
+ * generator.
+ */
+ explicit
+ subtract_with_carry_01(unsigned long __value)
+ {
+ this->seed(__value);
+ _M_initialize_npows();
+ }
+
+ /**
+ * Constructs a % subtract_with_carry_01 random number generator engine
+ * seeded from the generator function @p __g.
+ *
+ * @param __g The seed generator function.
+ */
+ template<class _Gen>
+ subtract_with_carry_01(_Gen& __g)
+ {
+ this->seed(__g);
+ _M_initialize_npows();
+ }
+
+ /**
+ * Seeds the initial state @f$ x_0 @f$ of the random number generator.
+ */
+ void
+ seed(unsigned long __value = 19780503);
+
+ /**
+ * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
+ * random number generator.
+ */
+ template<class _Gen>
+ void
+ seed(_Gen& __g)
+ { seed(__g, typename is_fundamental<_Gen>::type()); }
+
+ /**
+ * Gets the minimum value of the range of random floats
+ * returned by this generator.
+ */
+ result_type
+ min() const
+ { return 0.0; }
+
+ /**
+ * Gets the maximum value of the range of random floats
+ * returned by this generator.
+ */
+ result_type
+ max() const
+ { return 1.0; }
+
+ /**
+ * Gets the next random number in the sequence.
+ */
+ result_type
+ operator()();
+
+ /**
+ * Compares two % subtract_with_carry_01 random number generator objects
+ * of the same type for equality.
+ *
+ * @param __lhs A % subtract_with_carry_01 random number
+ * generator object.
+ * @param __rhs Another % subtract_with_carry_01 random number generator
+ * object.
+ *
+ * @returns true if the two objects are equal, false otherwise.
+ */
+ friend bool
+ operator==(const subtract_with_carry_01& __lhs,
+ const subtract_with_carry_01& __rhs)
+ {
+ for (int __i = 0; __i < long_lag; ++__i)
+ if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
+ __rhs._M_x[__i]))
+ return false;
+ return true;
+ }
+
+ /**
+ * Compares two % subtract_with_carry_01 random number generator objects
+ * of the same type for inequality.
+ *
+ * @param __lhs A % subtract_with_carry_01 random number
+ * generator object.
+ *
+ * @param __rhs Another % subtract_with_carry_01 random number generator
+ * object.
+ *
+ * @returns true if the two objects are not equal, false otherwise.
+ */
+ friend bool
+ operator!=(const subtract_with_carry_01& __lhs,
+ const subtract_with_carry_01& __rhs)
+ { return !(__lhs == __rhs); }
+
+ /**
+ * Inserts the current state of a % subtract_with_carry_01 random number
+ * generator engine @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A % subtract_with_carry_01 random number generator engine.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, int __w1, int __s1, int __r1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const subtract_with_carry_01<_RealType1, __w1, __s1,
+ __r1>& __x);
+
+ /**
+ * Extracts the current state of a % subtract_with_carry_01 random number
+ * generator engine @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A % subtract_with_carry_01 random number generator engine.
+ *
+ * @returns The input stream with the state of @p __x extracted or in
+ * an error state.
+ */
+ template<typename _RealType1, int __w1, int __s1, int __r1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
+
+ private:
+ template<class _Gen>
+ void
+ seed(_Gen& __g, true_type)
+ { return seed(static_cast<unsigned long>(__g)); }
+
+ template<class _Gen>
+ void
+ seed(_Gen& __g, false_type);
+
+ void
+ _M_initialize_npows();
+
+ static const int __n = (__w + 31) / 32;
+
+ typedef __detail::_UInt32Type _UInt32Type;
+ _UInt32Type _M_x[long_lag][__n];
+ _RealType _M_npows[__n];
+ _UInt32Type _M_carry;
+ int _M_p;
+ };
+
+ typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01;
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 508. Bad parameters for ranlux64_base_01.
+ typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
+
+
+ /**
+ * Produces random numbers from some base engine by discarding blocks of
+ * data.
+ *
+ * 0 <= @p __r <= @p __p
+ */
+ template<class _UniformRandomNumberGenerator, int __p, int __r>
+ class discard_block
+ {
+ // __glibcxx_class_requires(typename base_type::result_type,
+ // ArithmeticTypeConcept)
+
+ public:
+ /** The type of the underlying generator engine. */
+ typedef _UniformRandomNumberGenerator base_type;
+ /** The type of the generated random value. */
+ typedef typename base_type::result_type result_type;
+
+ // parameter values
+ static const int block_size = __p;
+ static const int used_block = __r;
+
+ /**
+ * Constructs a default %discard_block engine.
+ *
+ * The underlying engine is default constructed as well.
+ */
+ discard_block()
+ : _M_n(0) { }
+
+ /**
+ * Copy constructs a %discard_block engine.
+ *
+ * Copies an existing base class random number generator.
+ * @param rng An existing (base class) engine object.
+ */
+ explicit
+ discard_block(const base_type& __rng)
+ : _M_b(__rng), _M_n(0) { }
+
+ /**
+ * Seed constructs a %discard_block engine.
+ *
+ * Constructs the underlying generator engine seeded with @p __s.
+ * @param __s A seed value for the base class engine.
+ */
+ explicit
+ discard_block(unsigned long __s)
+ : _M_b(__s), _M_n(0) { }
+
+ /**
+ * Generator construct a %discard_block engine.
+ *
+ * @param __g A seed generator function.
+ */
+ template<class _Gen>
+ discard_block(_Gen& __g)
+ : _M_b(__g), _M_n(0) { }
+
+ /**
+ * Reseeds the %discard_block object with the default seed for the
+ * underlying base class generator engine.
+ */
+ void seed()
+ {
+ _M_b.seed();
+ _M_n = 0;
+ }
+
+ /**
+ * Reseeds the %discard_block object with the given seed generator
+ * function.
+ * @param __g A seed generator function.
+ */
+ template<class _Gen>
+ void seed(_Gen& __g)
+ {
+ _M_b.seed(__g);
+ _M_n = 0;
+ }
+
+ /**
+ * Gets a const reference to the underlying generator engine object.
+ */
+ const base_type&
+ base() const
+ { return _M_b; }
+
+ /**
+ * Gets the minimum value in the generated random number range.
+ */
+ result_type
+ min() const
+ { return _M_b.min(); }
+
+ /**
+ * Gets the maximum value in the generated random number range.
+ */
+ result_type
+ max() const
+ { return _M_b.max(); }
+
+ /**
+ * Gets the next value in the generated random number sequence.
+ */
+ result_type
+ operator()();
+
+ /**
+ * Compares two %discard_block random number generator objects of
+ * the same type for equality.
+ *
+ * @param __lhs A %discard_block random number generator object.
+ * @param __rhs Another %discard_block random number generator
+ * object.
+ *
+ * @returns true if the two objects are equal, false otherwise.
+ */
+ friend bool
+ operator==(const discard_block& __lhs, const discard_block& __rhs)
+ { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
+
+ /**
+ * Compares two %discard_block random number generator objects of
+ * the same type for inequality.
+ *
+ * @param __lhs A %discard_block random number generator object.
+ * @param __rhs Another %discard_block random number generator
+ * object.
+ *
+ * @returns true if the two objects are not equal, false otherwise.
+ */
+ friend bool
+ operator!=(const discard_block& __lhs, const discard_block& __rhs)
+ { return !(__lhs == __rhs); }
+
+ /**
+ * Inserts the current state of a %discard_block random number
+ * generator engine @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %discard_block random number generator engine.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const discard_block<_UniformRandomNumberGenerator1,
+ __p1, __r1>& __x);
+
+ /**
+ * Extracts the current state of a % subtract_with_carry random number
+ * generator engine @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %discard_block random number generator engine.
+ *
+ * @returns The input stream with the state of @p __x extracted or in
+ * an error state.
+ */
+ template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ discard_block<_UniformRandomNumberGenerator1,
+ __p1, __r1>& __x);
+
+ private:
+ base_type _M_b;
+ int _M_n;
+ };
+
+
+ /**
+ * James's luxury-level-3 integer adaptation of Luescher's generator.
+ */
+ typedef discard_block<
+ subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
+ 223,
+ 24
+ > ranlux3;
+
+ /**
+ * James's luxury-level-4 integer adaptation of Luescher's generator.
+ */
+ typedef discard_block<
+ subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
+ 389,
+ 24
+ > ranlux4;
+
+ typedef discard_block<
+ subtract_with_carry_01<float, 24, 10, 24>,
+ 223,
+ 24
+ > ranlux3_01;
+
+ typedef discard_block<
+ subtract_with_carry_01<float, 24, 10, 24>,
+ 389,
+ 24
+ > ranlux4_01;
+
+
+ /**
+ * A random number generator adaptor class that combines two random number
+ * generator engines into a single output sequence.
+ */
+ template<class _UniformRandomNumberGenerator1, int __s1,
+ class _UniformRandomNumberGenerator2, int __s2>
+ class xor_combine
+ {
+ // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
+ // result_type, ArithmeticTypeConcept)
+ // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
+ // result_type, ArithmeticTypeConcept)
+
+ public:
+ /** The type of the first underlying generator engine. */
+ typedef _UniformRandomNumberGenerator1 base1_type;
+ /** The type of the second underlying generator engine. */
+ typedef _UniformRandomNumberGenerator2 base2_type;
+
+ private:
+ typedef typename base1_type::result_type _Result_type1;
+ typedef typename base2_type::result_type _Result_type2;
+
+ public:
+ /** The type of the generated random value. */
+ typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
+ > sizeof(_Result_type2)),
+ _Result_type1, _Result_type2>::__type result_type;
+
+ // parameter values
+ static const int shift1 = __s1;
+ static const int shift2 = __s2;
+
+ // constructors and member function
+ xor_combine()
+ : _M_b1(), _M_b2()
+ { _M_initialize_max(); }
+
+ xor_combine(const base1_type& __rng1, const base2_type& __rng2)
+ : _M_b1(__rng1), _M_b2(__rng2)
+ { _M_initialize_max(); }
+
+ xor_combine(unsigned long __s)
+ : _M_b1(__s), _M_b2(__s + 1)
+ { _M_initialize_max(); }
+
+ template<class _Gen>
+ xor_combine(_Gen& __g)
+ : _M_b1(__g), _M_b2(__g)
+ { _M_initialize_max(); }
+
+ void
+ seed()
+ {
+ _M_b1.seed();
+ _M_b2.seed();
+ }
+
+ template<class _Gen>
+ void
+ seed(_Gen& __g)
+ {
+ _M_b1.seed(__g);
+ _M_b2.seed(__g);
+ }
+
+ const base1_type&
+ base1() const
+ { return _M_b1; }
+
+ const base2_type&
+ base2() const
+ { return _M_b2; }
+
+ result_type
+ min() const
+ { return 0; }
+
+ result_type
+ max() const
+ { return _M_max; }
+
+ /**
+ * Gets the next random number in the sequence.
+ */
+ // NB: Not exactly the TR1 formula, per N2079 instead.
+ result_type
+ operator()()
+ {
+ return ((result_type(_M_b1() - _M_b1.min()) << shift1)
+ ^ (result_type(_M_b2() - _M_b2.min()) << shift2));
+ }
+
+ /**
+ * Compares two %xor_combine random number generator objects of
+ * the same type for equality.
+ *
+ * @param __lhs A %xor_combine random number generator object.
+ * @param __rhs Another %xor_combine random number generator
+ * object.
+ *
+ * @returns true if the two objects are equal, false otherwise.
+ */
+ friend bool
+ operator==(const xor_combine& __lhs, const xor_combine& __rhs)
+ {
+ return (__lhs.base1() == __rhs.base1())
+ && (__lhs.base2() == __rhs.base2());
+ }
+
+ /**
+ * Compares two %xor_combine random number generator objects of
+ * the same type for inequality.
+ *
+ * @param __lhs A %xor_combine random number generator object.
+ * @param __rhs Another %xor_combine random number generator
+ * object.
+ *
+ * @returns true if the two objects are not equal, false otherwise.
+ */
+ friend bool
+ operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
+ { return !(__lhs == __rhs); }
+
+ /**
+ * Inserts the current state of a %xor_combine random number
+ * generator engine @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %xor_combine random number generator engine.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<class _UniformRandomNumberGenerator11, int __s11,
+ class _UniformRandomNumberGenerator21, int __s21,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const xor_combine<_UniformRandomNumberGenerator11, __s11,
+ _UniformRandomNumberGenerator21, __s21>& __x);
+
+ /**
+ * Extracts the current state of a %xor_combine random number
+ * generator engine @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %xor_combine random number generator engine.
+ *
+ * @returns The input stream with the state of @p __x extracted or in
+ * an error state.
+ */
+ template<class _UniformRandomNumberGenerator11, int __s11,
+ class _UniformRandomNumberGenerator21, int __s21,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ xor_combine<_UniformRandomNumberGenerator11, __s11,
+ _UniformRandomNumberGenerator21, __s21>& __x);
+
+ private:
+ void
+ _M_initialize_max();
+
+ result_type
+ _M_initialize_max_aux(result_type, result_type, int);
+
+ base1_type _M_b1;
+ base2_type _M_b2;
+ result_type _M_max;
+ };
+
+
+ /**
+ * A standard interface to a platform-specific non-deterministic
+ * random number generator (if any are available).
+ */
+ class random_device
+ {
+ public:
+ // types
+ typedef unsigned int result_type;
+
+ // constructors, destructors and member functions
+
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+
+ explicit
+ random_device(const std::string& __token = "/dev/urandom")
+ {
+ if ((__token != "/dev/urandom" && __token != "/dev/random")
+ || !(_M_file = std::fopen(__token.c_str(), "rb")))
+ std::__throw_runtime_error(__N("random_device::"
+ "random_device(const std::string&)"));
+ }
+
+ ~random_device()
+ { std::fclose(_M_file); }
+
+#else
+
+ explicit
+ random_device(const std::string& __token = "mt19937")
+ : _M_mt(_M_strtoul(__token)) { }
+
+ private:
+ static unsigned long
+ _M_strtoul(const std::string& __str)
+ {
+ unsigned long __ret = 5489UL;
+ if (__str != "mt19937")
+ {
+ const char* __nptr = __str.c_str();
+ char* __endptr;
+ __ret = std::strtoul(__nptr, &__endptr, 0);
+ if (*__nptr == '\0' || *__endptr != '\0')
+ std::__throw_runtime_error(__N("random_device::_M_strtoul"
+ "(const std::string&)"));
+ }
+ return __ret;
+ }
+
+ public:
+
+#endif
+
+ result_type
+ min() const
+ { return std::numeric_limits<result_type>::min(); }
+
+ result_type
+ max() const
+ { return std::numeric_limits<result_type>::max(); }
+
+ double
+ entropy() const
+ { return 0.0; }
+
+ result_type
+ operator()()
+ {
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+ result_type __ret;
+ std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
+ 1, _M_file);
+ return __ret;
+#else
+ return _M_mt();
+#endif
+ }
+
+ private:
+ random_device(const random_device&);
+ void operator=(const random_device&);
+
+#ifdef _GLIBCXX_USE_RANDOM_TR1
+ FILE* _M_file;
+#else
+ mt19937 _M_mt;
+#endif
+ };
+
+ /* @} */ // group tr1_random_generators
+
+ /**
+ * @addtogroup tr1_random_distributions Random Number Distributions
+ * @ingroup tr1_random
+ * @{
+ */
+
+ /**
+ * @addtogroup tr1_random_distributions_discrete Discrete Distributions
+ * @ingroup tr1_random_distributions
+ * @{
+ */
+
+ /**
+ * @brief Uniform discrete distribution for random numbers.
+ * A discrete random distribution on the range @f$[min, max]@f$ with equal
+ * probability throughout the range.
+ */
+ template<typename _IntType = int>
+ class uniform_int
+ {
+ __glibcxx_class_requires(_IntType, _IntegerConcept)
+
+ public:
+ /** The type of the parameters of the distribution. */
+ typedef _IntType input_type;
+ /** The type of the range of the distribution. */
+ typedef _IntType result_type;
+
+ public:
+ /**
+ * Constructs a uniform distribution object.
+ */
+ explicit
+ uniform_int(_IntType __min = 0, _IntType __max = 9)
+ : _M_min(__min), _M_max(__max)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
+ }
+
+ /**
+ * Gets the inclusive lower bound of the distribution range.
+ */
+ result_type
+ min() const
+ { return _M_min; }
+
+ /**
+ * Gets the inclusive upper bound of the distribution range.
+ */
+ result_type
+ max() const
+ { return _M_max; }
+
+ /**
+ * Resets the distribution state.
+ *
+ * Does nothing for the uniform integer distribution.
+ */
+ void
+ reset() { }
+
+ /**
+ * Gets a uniformly distributed random number in the range
+ * @f$(min, max)@f$.
+ */
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ typedef typename _UniformRandomNumberGenerator::result_type
+ _UResult_type;
+ return _M_call(__urng, _M_min, _M_max,
+ typename is_integral<_UResult_type>::type());
+ }
+
+ /**
+ * Gets a uniform random number in the range @f$[0, n)@f$.
+ *
+ * This function is aimed at use with std::random_shuffle.
+ */
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
+ {
+ typedef typename _UniformRandomNumberGenerator::result_type
+ _UResult_type;
+ return _M_call(__urng, 0, __n - 1,
+ typename is_integral<_UResult_type>::type());
+ }
+
+ /**
+ * Inserts a %uniform_int random number distribution @p __x into the
+ * output stream @p os.
+ *
+ * @param __os An output stream.
+ * @param __x A %uniform_int random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _IntType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const uniform_int<_IntType1>& __x);
+
+ /**
+ * Extracts a %uniform_int random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %uniform_int random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _IntType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ uniform_int<_IntType1>& __x);
+
+ private:
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ _M_call(_UniformRandomNumberGenerator& __urng,
+ result_type __min, result_type __max, true_type);
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ _M_call(_UniformRandomNumberGenerator& __urng,
+ result_type __min, result_type __max, false_type)
+ {
+ return result_type((__urng() - __urng.min())
+ / (__urng.max() - __urng.min())
+ * (__max - __min + 1)) + __min;
+ }
+
+ _IntType _M_min;
+ _IntType _M_max;
+ };
+
+
+ /**
+ * @brief A Bernoulli random number distribution.
+ *
+ * Generates a sequence of true and false values with likelihood @f$ p @f$
+ * that true will come up and @f$ (1 - p) @f$ that false will appear.
+ */
+ class bernoulli_distribution
+ {
+ public:
+ typedef int input_type;
+ typedef bool result_type;
+
+ public:
+ /**
+ * Constructs a Bernoulli distribution with likelihood @p p.
+ *
+ * @param __p [IN] The likelihood of a true result being returned. Must
+ * be in the interval @f$ [0, 1] @f$.
+ */
+ explicit
+ bernoulli_distribution(double __p = 0.5)
+ : _M_p(__p)
+ {
+ _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
+ }
+
+ /**
+ * Gets the @p p parameter of the distribution.
+ */
+ double
+ p() const
+ { return _M_p; }
+
+ /**
+ * Resets the distribution state.
+ *
+ * Does nothing for a Bernoulli distribution.
+ */
+ void
+ reset() { }
+
+ /**
+ * Gets the next value in the Bernoullian sequence.
+ */
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
+ return true;
+ return false;
+ }
+
+ /**
+ * Inserts a %bernoulli_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %bernoulli_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const bernoulli_distribution& __x);
+
+ /**
+ * Extracts a %bernoulli_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %bernoulli_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ bernoulli_distribution& __x)
+ { return __is >> __x._M_p; }
+
+ private:
+ double _M_p;
+ };
+
+
+ /**
+ * @brief A discrete geometric random number distribution.
+ *
+ * The formula for the geometric probability mass function is
+ * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
+ * distribution.
+ */
+ template<typename _IntType = int, typename _RealType = double>
+ class geometric_distribution
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _IntType result_type;
+
+ // constructors and member function
+ explicit
+ geometric_distribution(const _RealType& __p = _RealType(0.5))
+ : _M_p(__p)
+ {
+ _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
+ _M_initialize();
+ }
+
+ /**
+ * Gets the distribution parameter @p p.
+ */
+ _RealType
+ p() const
+ { return _M_p; }
+
+ void
+ reset() { }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng);
+
+ /**
+ * Inserts a %geometric_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %geometric_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _IntType1, typename _RealType1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const geometric_distribution<_IntType1, _RealType1>& __x);
+
+ /**
+ * Extracts a %geometric_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %geometric_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ geometric_distribution& __x)
+ {
+ __is >> __x._M_p;
+ __x._M_initialize();
+ return __is;
+ }
+
+ private:
+ void
+ _M_initialize()
+ { _M_log_p = std::log(_M_p); }
+
+ _RealType _M_p;
+ _RealType _M_log_p;
+ };
+
+
+ template<typename _RealType>
+ class normal_distribution;
+
+ /**
+ * @brief A discrete Poisson random number distribution.
+ *
+ * The formula for the Poisson probability mass function is
+ * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
+ * parameter of the distribution.
+ */
+ template<typename _IntType = int, typename _RealType = double>
+ class poisson_distribution
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _IntType result_type;
+
+ // constructors and member function
+ explicit
+ poisson_distribution(const _RealType& __mean = _RealType(1))
+ : _M_mean(__mean), _M_nd()
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
+ _M_initialize();
+ }
+
+ /**
+ * Gets the distribution parameter @p mean.
+ */
+ _RealType
+ mean() const
+ { return _M_mean; }
+
+ void
+ reset()
+ { _M_nd.reset(); }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng);
+
+ /**
+ * Inserts a %poisson_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %poisson_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _IntType1, typename _RealType1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const poisson_distribution<_IntType1, _RealType1>& __x);
+
+ /**
+ * Extracts a %poisson_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %poisson_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _IntType1, typename _RealType1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ poisson_distribution<_IntType1, _RealType1>& __x);
+
+ private:
+ void
+ _M_initialize();
+
+ // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
+ normal_distribution<_RealType> _M_nd;
+
+ _RealType _M_mean;
+
+ // Hosts either log(mean) or the threshold of the simple method.
+ _RealType _M_lm_thr;
+#if _GLIBCXX_USE_C99_MATH_TR1
+ _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
+#endif
+ };
+
+
+ /**
+ * @brief A discrete binomial random number distribution.
+ *
+ * The formula for the binomial probability mass function is
+ * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
+ * and @f$ p @f$ are the parameters of the distribution.
+ */
+ template<typename _IntType = int, typename _RealType = double>
+ class binomial_distribution
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _IntType result_type;
+
+ // constructors and member function
+ explicit
+ binomial_distribution(_IntType __t = 1,
+ const _RealType& __p = _RealType(0.5))
+ : _M_t(__t), _M_p(__p), _M_nd()
+ {
+ _GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
+ _M_initialize();
+ }
+
+ /**
+ * Gets the distribution @p t parameter.
+ */
+ _IntType
+ t() const
+ { return _M_t; }
+
+ /**
+ * Gets the distribution @p p parameter.
+ */
+ _RealType
+ p() const
+ { return _M_p; }
+
+ void
+ reset()
+ { _M_nd.reset(); }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng);
+
+ /**
+ * Inserts a %binomial_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %binomial_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _IntType1, typename _RealType1,
+ typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const binomial_distribution<_IntType1, _RealType1>& __x);
+
+ /**
+ * Extracts a %binomial_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %binomial_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _IntType1, typename _RealType1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ binomial_distribution<_IntType1, _RealType1>& __x);
+
+ private:
+ void
+ _M_initialize();
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
+
+ // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
+ normal_distribution<_RealType> _M_nd;
+
+ _RealType _M_q;
+#if _GLIBCXX_USE_C99_MATH_TR1
+ _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
+ _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
+#endif
+ _RealType _M_p;
+ _IntType _M_t;
+
+ bool _M_easy;
+ };
+
+ /* @} */ // group tr1_random_distributions_discrete
+
+ /**
+ * @addtogroup tr1_random_distributions_continuous Continuous Distributions
+ * @ingroup tr1_random_distributions
+ * @{
+ */
+
+ /**
+ * @brief Uniform continuous distribution for random numbers.
+ *
+ * A continuous random distribution on the range [min, max) with equal
+ * probability throughout the range. The URNG should be real-valued and
+ * deliver number in the range [0, 1).
+ */
+ template<typename _RealType = double>
+ class uniform_real
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _RealType result_type;
+
+ public:
+ /**
+ * Constructs a uniform_real object.
+ *
+ * @param __min [IN] The lower bound of the distribution.
+ * @param __max [IN] The upper bound of the distribution.
+ */
+ explicit
+ uniform_real(_RealType __min = _RealType(0),
+ _RealType __max = _RealType(1))
+ : _M_min(__min), _M_max(__max)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
+ }
+
+ result_type
+ min() const
+ { return _M_min; }
+
+ result_type
+ max() const
+ { return _M_max; }
+
+ void
+ reset() { }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ { return (__urng() * (_M_max - _M_min)) + _M_min; }
+
+ /**
+ * Inserts a %uniform_real random number distribution @p __x into the
+ * output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %uniform_real random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const uniform_real<_RealType1>& __x);
+
+ /**
+ * Extracts a %uniform_real random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %uniform_real random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ uniform_real<_RealType1>& __x);
+
+ private:
+ _RealType _M_min;
+ _RealType _M_max;
+ };
+
+
+ /**
+ * @brief An exponential continuous distribution for random numbers.
+ *
+ * The formula for the exponential probability mass function is
+ * @f$ p(x) = \lambda e^{-\lambda x} @f$.
+ *
+ * <table border=1 cellpadding=10 cellspacing=0>
+ * <caption align=top>Distribution Statistics</caption>
+ * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
+ * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
+ * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
+ * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
+ * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
+ * </table>
+ */
+ template<typename _RealType = double>
+ class exponential_distribution
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _RealType result_type;
+
+ public:
+ /**
+ * Constructs an exponential distribution with inverse scale parameter
+ * @f$ \lambda @f$.
+ */
+ explicit
+ exponential_distribution(const result_type& __lambda = result_type(1))
+ : _M_lambda(__lambda)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
+ }
+
+ /**
+ * Gets the inverse scale parameter of the distribution.
+ */
+ _RealType
+ lambda() const
+ { return _M_lambda; }
+
+ /**
+ * Resets the distribution.
+ *
+ * Has no effect on exponential distributions.
+ */
+ void
+ reset() { }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ { return -std::log(__urng()) / _M_lambda; }
+
+ /**
+ * Inserts a %exponential_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %exponential_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const exponential_distribution<_RealType1>& __x);
+
+ /**
+ * Extracts a %exponential_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %exponential_distribution random number
+ * generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ exponential_distribution& __x)
+ { return __is >> __x._M_lambda; }
+
+ private:
+ result_type _M_lambda;
+ };
+
+
+ /**
+ * @brief A normal continuous distribution for random numbers.
+ *
+ * The formula for the normal probability mass function is
+ * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}}
+ * e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
+ */
+ template<typename _RealType = double>
+ class normal_distribution
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _RealType result_type;
+
+ public:
+ /**
+ * Constructs a normal distribution with parameters @f$ mean @f$ and
+ * @f$ \sigma @f$.
+ */
+ explicit
+ normal_distribution(const result_type& __mean = result_type(0),
+ const result_type& __sigma = result_type(1))
+ : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
+ }
+
+ /**
+ * Gets the mean of the distribution.
+ */
+ _RealType
+ mean() const
+ { return _M_mean; }
+
+ /**
+ * Gets the @f$ \sigma @f$ of the distribution.
+ */
+ _RealType
+ sigma() const
+ { return _M_sigma; }
+
+ /**
+ * Resets the distribution.
+ */
+ void
+ reset()
+ { _M_saved_available = false; }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng);
+
+ /**
+ * Inserts a %normal_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %normal_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const normal_distribution<_RealType1>& __x);
+
+ /**
+ * Extracts a %normal_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %normal_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ normal_distribution<_RealType1>& __x);
+
+ private:
+ result_type _M_mean;
+ result_type _M_sigma;
+ result_type _M_saved;
+ bool _M_saved_available;
+ };
+
+
+ /**
+ * @brief A gamma continuous distribution for random numbers.
+ *
+ * The formula for the gamma probability mass function is
+ * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
+ */
+ template<typename _RealType = double>
+ class gamma_distribution
+ {
+ public:
+ // types
+ typedef _RealType input_type;
+ typedef _RealType result_type;
+
+ public:
+ /**
+ * Constructs a gamma distribution with parameters @f$ \alpha @f$.
+ */
+ explicit
+ gamma_distribution(const result_type& __alpha_val = result_type(1))
+ : _M_alpha(__alpha_val)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
+ _M_initialize();
+ }
+
+ /**
+ * Gets the @f$ \alpha @f$ of the distribution.
+ */
+ _RealType
+ alpha() const
+ { return _M_alpha; }
+
+ /**
+ * Resets the distribution.
+ */
+ void
+ reset() { }
+
+ template<class _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng);
+
+ /**
+ * Inserts a %gamma_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %gamma_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const gamma_distribution<_RealType1>& __x);
+
+ /**
+ * Extracts a %gamma_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %gamma_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ gamma_distribution& __x)
+ {
+ __is >> __x._M_alpha;
+ __x._M_initialize();
+ return __is;
+ }
+
+ private:
+ void
+ _M_initialize();
+
+ result_type _M_alpha;
+
+ // Hosts either lambda of GB or d of modified Vaduva's.
+ result_type _M_l_d;
+ };
+
+ /* @} */ // group tr1_random_distributions_continuous
+ /* @} */ // group tr1_random_distributions
+ /* @} */ // group tr1_random
+
+}
+}
+
+#include <tr1/random.tcc>
+
+#endif // _GLIBCXX_TR1_RANDOM_H
diff --git a/libstdc++-v3/include/tr1/random.tcc b/libstdc++-v3/include/tr1/random.tcc
new file mode 100644
index 00000000000..ec06ae31a6c
--- /dev/null
+++ b/libstdc++-v3/include/tr1/random.tcc
@@ -0,0 +1,1583 @@
+// random number generation (out of line) -*- C++ -*-
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file tr1/random.tcc
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+namespace std
+{
+namespace tr1
+{
+
+ /*
+ * (Further) implementation-space details.
+ */
+ namespace __detail
+ {
+ // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid
+ // integer overflow.
+ //
+ // Because a and c are compile-time integral constants the compiler kindly
+ // elides any unreachable paths.
+ //
+ // Preconditions: a > 0, m > 0.
+ //
+ template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
+ struct _Mod
+ {
+ static _Tp
+ __calc(_Tp __x)
+ {
+ if (__a == 1)
+ __x %= __m;
+ else
+ {
+ static const _Tp __q = __m / __a;
+ static const _Tp __r = __m % __a;
+
+ _Tp __t1 = __a * (__x % __q);
+ _Tp __t2 = __r * (__x / __q);
+ if (__t1 >= __t2)
+ __x = __t1 - __t2;
+ else
+ __x = __m - __t2 + __t1;
+ }
+
+ if (__c != 0)
+ {
+ const _Tp __d = __m - __x;
+ if (__d > __c)
+ __x += __c;
+ else
+ __x = __c - __d;
+ }
+ return __x;
+ }
+ };
+
+ // Special case for m == 0 -- use unsigned integer overflow as modulo
+ // operator.
+ template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
+ struct _Mod<_Tp, __a, __c, __m, true>
+ {
+ static _Tp
+ __calc(_Tp __x)
+ { return __a * __x + __c; }
+ };
+ } // namespace __detail
+
+ /**
+ * Seeds the LCR with integral value @p __x0, adjusted so that the
+ * ring identity is never a member of the convergence set.
+ */
+ template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+ void
+ linear_congruential<_UIntType, __a, __c, __m>::
+ seed(unsigned long __x0)
+ {
+ if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
+ && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
+ _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
+ else
+ _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
+ }
+
+ /**
+ * Seeds the LCR engine with a value generated by @p __g.
+ */
+ template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+ template<class _Gen>
+ void
+ linear_congruential<_UIntType, __a, __c, __m>::
+ seed(_Gen& __g, false_type)
+ {
+ _UIntType __x0 = __g();
+ if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0)
+ && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0))
+ _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1);
+ else
+ _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0);
+ }
+
+ /**
+ * Gets the next generated value in sequence.
+ */
+ template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+ typename linear_congruential<_UIntType, __a, __c, __m>::result_type
+ linear_congruential<_UIntType, __a, __c, __m>::
+ operator()()
+ {
+ _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x);
+ return _M_x;
+ }
+
+ template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const linear_congruential<_UIntType, __a, __c, __m>& __lcr)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
+ __os.fill(__os.widen(' '));
+
+ __os << __lcr._M_x;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ linear_congruential<_UIntType, __a, __c, __m>& __lcr)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec);
+
+ __is >> __lcr._M_x;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<class _UIntType, int __w, int __n, int __m, int __r,
+ _UIntType __a, int __u, int __s,
+ _UIntType __b, int __t, _UIntType __c, int __l>
+ void
+ mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
+ __b, __t, __c, __l>::
+ seed(unsigned long __value)
+ {
+ _M_x[0] = __detail::__mod<_UIntType, 1, 0,
+ __detail::_Shift<_UIntType, __w>::__value>(__value);
+
+ for (int __i = 1; __i < state_size; ++__i)
+ {
+ _UIntType __x = _M_x[__i - 1];
+ __x ^= __x >> (__w - 2);
+ __x *= 1812433253ul;
+ __x += __i;
+ _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
+ __detail::_Shift<_UIntType, __w>::__value>(__x);
+ }
+ _M_p = state_size;
+ }
+
+ template<class _UIntType, int __w, int __n, int __m, int __r,
+ _UIntType __a, int __u, int __s,
+ _UIntType __b, int __t, _UIntType __c, int __l>
+ template<class _Gen>
+ void
+ mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
+ __b, __t, __c, __l>::
+ seed(_Gen& __gen, false_type)
+ {
+ for (int __i = 0; __i < state_size; ++__i)
+ _M_x[__i] = __detail::__mod<_UIntType, 1, 0,
+ __detail::_Shift<_UIntType, __w>::__value>(__gen());
+ _M_p = state_size;
+ }
+
+ template<class _UIntType, int __w, int __n, int __m, int __r,
+ _UIntType __a, int __u, int __s,
+ _UIntType __b, int __t, _UIntType __c, int __l>
+ typename
+ mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
+ __b, __t, __c, __l>::result_type
+ mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s,
+ __b, __t, __c, __l>::
+ operator()()
+ {
+ // Reload the vector - cost is O(n) amortized over n calls.
+ if (_M_p >= state_size)
+ {
+ const _UIntType __upper_mask = (~_UIntType()) << __r;
+ const _UIntType __lower_mask = ~__upper_mask;
+
+ for (int __k = 0; __k < (__n - __m); ++__k)
+ {
+ _UIntType __y = ((_M_x[__k] & __upper_mask)
+ | (_M_x[__k + 1] & __lower_mask));
+ _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
+ ^ ((__y & 0x01) ? __a : 0));
+ }
+
+ for (int __k = (__n - __m); __k < (__n - 1); ++__k)
+ {
+ _UIntType __y = ((_M_x[__k] & __upper_mask)
+ | (_M_x[__k + 1] & __lower_mask));
+ _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
+ ^ ((__y & 0x01) ? __a : 0));
+ }
+
+ _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
+ | (_M_x[0] & __lower_mask));
+ _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
+ ^ ((__y & 0x01) ? __a : 0));
+ _M_p = 0;
+ }
+
+ // Calculate o(x(i)).
+ result_type __z = _M_x[_M_p++];
+ __z ^= (__z >> __u);
+ __z ^= (__z << __s) & __b;
+ __z ^= (__z << __t) & __c;
+ __z ^= (__z >> __l);
+
+ return __z;
+ }
+
+ template<class _UIntType, int __w, int __n, int __m, int __r,
+ _UIntType __a, int __u, int __s, _UIntType __b, int __t,
+ _UIntType __c, int __l,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const mersenne_twister<_UIntType, __w, __n, __m,
+ __r, __a, __u, __s, __b, __t, __c, __l>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
+ __os.fill(__space);
+
+ for (int __i = 0; __i < __n - 1; ++__i)
+ __os << __x._M_x[__i] << __space;
+ __os << __x._M_x[__n - 1];
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<class _UIntType, int __w, int __n, int __m, int __r,
+ _UIntType __a, int __u, int __s, _UIntType __b, int __t,
+ _UIntType __c, int __l,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ mersenne_twister<_UIntType, __w, __n, __m,
+ __r, __a, __u, __s, __b, __t, __c, __l>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ for (int __i = 0; __i < __n; ++__i)
+ __is >> __x._M_x[__i];
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _IntType, _IntType __m, int __s, int __r>
+ void
+ subtract_with_carry<_IntType, __m, __s, __r>::
+ seed(unsigned long __value)
+ {
+ if (__value == 0)
+ __value = 19780503;
+
+ std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563>
+ __lcg(__value);
+
+ for (int __i = 0; __i < long_lag; ++__i)
+ _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg());
+
+ _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
+ _M_p = 0;
+ }
+
+ template<typename _IntType, _IntType __m, int __s, int __r>
+ template<class _Gen>
+ void
+ subtract_with_carry<_IntType, __m, __s, __r>::
+ seed(_Gen& __gen, false_type)
+ {
+ const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32;
+
+ for (int __i = 0; __i < long_lag; ++__i)
+ {
+ _UIntType __tmp = 0;
+ _UIntType __factor = 1;
+ for (int __j = 0; __j < __n; ++__j)
+ {
+ __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0>
+ (__gen()) * __factor;
+ __factor *= __detail::_Shift<_UIntType, 32>::__value;
+ }
+ _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp);
+ }
+ _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
+ _M_p = 0;
+ }
+
+ template<typename _IntType, _IntType __m, int __s, int __r>
+ typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
+ subtract_with_carry<_IntType, __m, __s, __r>::
+ operator()()
+ {
+ // Derive short lag index from current index.
+ int __ps = _M_p - short_lag;
+ if (__ps < 0)
+ __ps += long_lag;
+
+ // Calculate new x(i) without overflow or division.
+ // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry
+ // cannot overflow.
+ _UIntType __xi;
+ if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
+ {
+ __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
+ _M_carry = 0;
+ }
+ else
+ {
+ __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
+ _M_carry = 1;
+ }
+ _M_x[_M_p] = __xi;
+
+ // Adjust current index to loop around in ring buffer.
+ if (++_M_p >= long_lag)
+ _M_p = 0;
+
+ return __xi;
+ }
+
+ template<typename _IntType, _IntType __m, int __s, int __r,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const subtract_with_carry<_IntType, __m, __s, __r>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
+ __os.fill(__space);
+
+ for (int __i = 0; __i < __r; ++__i)
+ __os << __x._M_x[__i] << __space;
+ __os << __x._M_carry;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<typename _IntType, _IntType __m, int __s, int __r,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ subtract_with_carry<_IntType, __m, __s, __r>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ for (int __i = 0; __i < __r; ++__i)
+ __is >> __x._M_x[__i];
+ __is >> __x._M_carry;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _RealType, int __w, int __s, int __r>
+ void
+ subtract_with_carry_01<_RealType, __w, __s, __r>::
+ _M_initialize_npows()
+ {
+ for (int __j = 0; __j < __n; ++__j)
+#if _GLIBCXX_USE_C99_MATH_TR1
+ _M_npows[__j] = std::_GLIBCXX_TR1 ldexp(_RealType(1), -__w + __j * 32);
+#else
+ _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32);
+#endif
+ }
+
+ template<typename _RealType, int __w, int __s, int __r>
+ void
+ subtract_with_carry_01<_RealType, __w, __s, __r>::
+ seed(unsigned long __value)
+ {
+ if (__value == 0)
+ __value = 19780503;
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 512. Seeding subtract_with_carry_01 from a single unsigned long.
+ std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563>
+ __lcg(__value);
+
+ this->seed(__lcg);
+ }
+
+ template<typename _RealType, int __w, int __s, int __r>
+ template<class _Gen>
+ void
+ subtract_with_carry_01<_RealType, __w, __s, __r>::
+ seed(_Gen& __gen, false_type)
+ {
+ for (int __i = 0; __i < long_lag; ++__i)
+ {
+ for (int __j = 0; __j < __n - 1; ++__j)
+ _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen());
+ _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
+ __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen());
+ }
+
+ _M_carry = 1;
+ for (int __j = 0; __j < __n; ++__j)
+ if (_M_x[long_lag - 1][__j] != 0)
+ {
+ _M_carry = 0;
+ break;
+ }
+
+ _M_p = 0;
+ }
+
+ template<typename _RealType, int __w, int __s, int __r>
+ typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type
+ subtract_with_carry_01<_RealType, __w, __s, __r>::
+ operator()()
+ {
+ // Derive short lag index from current index.
+ int __ps = _M_p - short_lag;
+ if (__ps < 0)
+ __ps += long_lag;
+
+ _UInt32Type __new_carry;
+ for (int __j = 0; __j < __n - 1; ++__j)
+ {
+ if (_M_x[__ps][__j] > _M_x[_M_p][__j]
+ || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0))
+ __new_carry = 0;
+ else
+ __new_carry = 1;
+
+ _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry;
+ _M_carry = __new_carry;
+ }
+
+ if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1]
+ || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0))
+ __new_carry = 0;
+ else
+ __new_carry = 1;
+
+ _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0,
+ __detail::_Shift<_UInt32Type, __w % 32>::__value>
+ (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry);
+ _M_carry = __new_carry;
+
+ result_type __ret = 0.0;
+ for (int __j = 0; __j < __n; ++__j)
+ __ret += _M_x[_M_p][__j] * _M_npows[__j];
+
+ // Adjust current index to loop around in ring buffer.
+ if (++_M_p >= long_lag)
+ _M_p = 0;
+
+ return __ret;
+ }
+
+ template<typename _RealType, int __w, int __s, int __r,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
+ __os.fill(__space);
+
+ for (int __i = 0; __i < __r; ++__i)
+ for (int __j = 0; __j < __x.__n; ++__j)
+ __os << __x._M_x[__i][__j] << __space;
+ __os << __x._M_carry;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<typename _RealType, int __w, int __s, int __r,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ for (int __i = 0; __i < __r; ++__i)
+ for (int __j = 0; __j < __x.__n; ++__j)
+ __is >> __x._M_x[__i][__j];
+ __is >> __x._M_carry;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<class _UniformRandomNumberGenerator, int __p, int __r>
+ typename discard_block<_UniformRandomNumberGenerator,
+ __p, __r>::result_type
+ discard_block<_UniformRandomNumberGenerator, __p, __r>::
+ operator()()
+ {
+ if (_M_n >= used_block)
+ {
+ while (_M_n < block_size)
+ {
+ _M_b();
+ ++_M_n;
+ }
+ _M_n = 0;
+ }
+ ++_M_n;
+ return _M_b();
+ }
+
+ template<class _UniformRandomNumberGenerator, int __p, int __r,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const discard_block<_UniformRandomNumberGenerator,
+ __p, __r>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::dec | __ios_base::fixed
+ | __ios_base::left);
+ __os.fill(__space);
+
+ __os << __x._M_b << __space << __x._M_n;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<class _UniformRandomNumberGenerator, int __p, int __r,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ discard_block<_UniformRandomNumberGenerator, __p, __r>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ __is >> __x._M_b >> __x._M_n;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<class _UniformRandomNumberGenerator1, int __s1,
+ class _UniformRandomNumberGenerator2, int __s2>
+ void
+ xor_combine<_UniformRandomNumberGenerator1, __s1,
+ _UniformRandomNumberGenerator2, __s2>::
+ _M_initialize_max()
+ {
+ const int __w = std::numeric_limits<result_type>::digits;
+
+ const result_type __m1 =
+ std::min(result_type(_M_b1.max() - _M_b1.min()),
+ __detail::_Shift<result_type, __w - __s1>::__value - 1);
+
+ const result_type __m2 =
+ std::min(result_type(_M_b2.max() - _M_b2.min()),
+ __detail::_Shift<result_type, __w - __s2>::__value - 1);
+
+ // NB: In TR1 s1 is not required to be >= s2.
+ if (__s1 < __s2)
+ _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1;
+ else
+ _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2;
+ }
+
+ template<class _UniformRandomNumberGenerator1, int __s1,
+ class _UniformRandomNumberGenerator2, int __s2>
+ typename xor_combine<_UniformRandomNumberGenerator1, __s1,
+ _UniformRandomNumberGenerator2, __s2>::result_type
+ xor_combine<_UniformRandomNumberGenerator1, __s1,
+ _UniformRandomNumberGenerator2, __s2>::
+ _M_initialize_max_aux(result_type __a, result_type __b, int __d)
+ {
+ const result_type __two2d = result_type(1) << __d;
+ const result_type __c = __a * __two2d;
+
+ if (__a == 0 || __b < __two2d)
+ return __c + __b;
+
+ const result_type __t = std::max(__c, __b);
+ const result_type __u = std::min(__c, __b);
+
+ result_type __ub = __u;
+ result_type __p;
+ for (__p = 0; __ub != 1; __ub >>= 1)
+ ++__p;
+
+ const result_type __two2p = result_type(1) << __p;
+ const result_type __k = __t / __two2p;
+
+ if (__k & 1)
+ return (__k + 1) * __two2p - 1;
+
+ if (__c >= __b)
+ return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p)
+ / __two2d,
+ __u % __two2p, __d);
+ else
+ return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p)
+ / __two2d,
+ __t % __two2p, __d);
+ }
+
+ template<class _UniformRandomNumberGenerator1, int __s1,
+ class _UniformRandomNumberGenerator2, int __s2,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const xor_combine<_UniformRandomNumberGenerator1, __s1,
+ _UniformRandomNumberGenerator2, __s2>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
+ __os.fill(__space);
+
+ __os << __x.base1() << __space << __x.base2();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<class _UniformRandomNumberGenerator1, int __s1,
+ class _UniformRandomNumberGenerator2, int __s2,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ xor_combine<_UniformRandomNumberGenerator1, __s1,
+ _UniformRandomNumberGenerator2, __s2>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::skipws);
+
+ __is >> __x._M_b1 >> __x._M_b2;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _IntType>
+ template<typename _UniformRandomNumberGenerator>
+ typename uniform_int<_IntType>::result_type
+ uniform_int<_IntType>::
+ _M_call(_UniformRandomNumberGenerator& __urng,
+ result_type __min, result_type __max, true_type)
+ {
+ // XXX Must be fixed to work well for *arbitrary* __urng.max(),
+ // __urng.min(), __max, __min. Currently works fine only in the
+ // most common case __urng.max() - __urng.min() >= __max - __min,
+ // with __urng.max() > __urng.min() >= 0.
+ typedef typename __gnu_cxx::__add_unsigned<typename
+ _UniformRandomNumberGenerator::result_type>::__type __urntype;
+ typedef typename __gnu_cxx::__add_unsigned<result_type>::__type
+ __utype;
+ typedef typename __gnu_cxx::__conditional_type<(sizeof(__urntype)
+ > sizeof(__utype)),
+ __urntype, __utype>::__type __uctype;
+
+ result_type __ret;
+
+ const __urntype __urnmin = __urng.min();
+ const __urntype __urnmax = __urng.max();
+ const __urntype __urnrange = __urnmax - __urnmin;
+ const __uctype __urange = __max - __min;
+ const __uctype __udenom = (__urnrange <= __urange
+ ? 1 : __urnrange / (__urange + 1));
+ do
+ __ret = (__urntype(__urng()) - __urnmin) / __udenom;
+ while (__ret > __max - __min);
+
+ return __ret + __min;
+ }
+
+ template<typename _IntType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const uniform_int<_IntType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+
+ __os << __x.min() << __space << __x.max();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ return __os;
+ }
+
+ template<typename _IntType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ uniform_int<_IntType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ __is >> __x._M_min >> __x._M_max;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const bernoulli_distribution& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__os.widen(' '));
+ __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10);
+
+ __os << __x.p();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+
+ template<typename _IntType, typename _RealType>
+ template<class _UniformRandomNumberGenerator>
+ typename geometric_distribution<_IntType, _RealType>::result_type
+ geometric_distribution<_IntType, _RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ // About the epsilon thing see this thread:
+ // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
+ const _RealType __naf =
+ (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
+ // The largest _RealType convertible to _IntType.
+ const _RealType __thr =
+ std::numeric_limits<_IntType>::max() + __naf;
+
+ _RealType __cand;
+ do
+ __cand = std::ceil(std::log(__urng()) / _M_log_p);
+ while (__cand >= __thr);
+
+ return result_type(__cand + __naf);
+ }
+
+ template<typename _IntType, typename _RealType,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const geometric_distribution<_IntType, _RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__os.widen(' '));
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x.p();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+
+ template<typename _IntType, typename _RealType>
+ void
+ poisson_distribution<_IntType, _RealType>::
+ _M_initialize()
+ {
+#if _GLIBCXX_USE_C99_MATH_TR1
+ if (_M_mean >= 12)
+ {
+ const _RealType __m = std::floor(_M_mean);
+ _M_lm_thr = std::log(_M_mean);
+ _M_lfm = std::_GLIBCXX_TR1 lgamma(__m + 1);
+ _M_sm = std::sqrt(__m);
+
+ const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
+ const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m
+ / __pi_4));
+ _M_d = std::_GLIBCXX_TR1 round(std::max(_RealType(6),
+ std::min(__m, __dx)));
+ const _RealType __cx = 2 * __m + _M_d;
+ _M_scx = std::sqrt(__cx / 2);
+ _M_1cx = 1 / __cx;
+
+ _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
+ _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d;
+ }
+ else
+#endif
+ _M_lm_thr = std::exp(-_M_mean);
+ }
+
+ /**
+ * A rejection algorithm when mean >= 12 and a simple method based
+ * upon the multiplication of uniform random variates otherwise.
+ * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
+ * is defined.
+ *
+ * Reference:
+ * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
+ * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
+ */
+ template<typename _IntType, typename _RealType>
+ template<class _UniformRandomNumberGenerator>
+ typename poisson_distribution<_IntType, _RealType>::result_type
+ poisson_distribution<_IntType, _RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+#if _GLIBCXX_USE_C99_MATH_TR1
+ if (_M_mean >= 12)
+ {
+ _RealType __x;
+
+ // See comments above...
+ const _RealType __naf =
+ (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
+ const _RealType __thr =
+ std::numeric_limits<_IntType>::max() + __naf;
+
+ const _RealType __m = std::floor(_M_mean);
+ // sqrt(pi / 2)
+ const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
+ const _RealType __c1 = _M_sm * __spi_2;
+ const _RealType __c2 = _M_c2b + __c1;
+ const _RealType __c3 = __c2 + 1;
+ const _RealType __c4 = __c3 + 1;
+ // e^(1 / 78)
+ const _RealType __e178 = 1.0129030479320018583185514777512983L;
+ const _RealType __c5 = __c4 + __e178;
+ const _RealType __c = _M_cb + __c5;
+ const _RealType __2cx = 2 * (2 * __m + _M_d);
+
+ bool __reject = true;
+ do
+ {
+ const _RealType __u = __c * __urng();
+ const _RealType __e = -std::log(__urng());
+
+ _RealType __w = 0.0;
+
+ if (__u <= __c1)
+ {
+ const _RealType __n = _M_nd(__urng);
+ const _RealType __y = -std::abs(__n) * _M_sm - 1;
+ __x = std::floor(__y);
+ __w = -__n * __n / 2;
+ if (__x < -__m)
+ continue;
+ }
+ else if (__u <= __c2)
+ {
+ const _RealType __n = _M_nd(__urng);
+ const _RealType __y = 1 + std::abs(__n) * _M_scx;
+ __x = std::ceil(__y);
+ __w = __y * (2 - __y) * _M_1cx;
+ if (__x > _M_d)
+ continue;
+ }
+ else if (__u <= __c3)
+ // NB: This case not in the book, nor in the Errata,
+ // but should be ok...
+ __x = -1;
+ else if (__u <= __c4)
+ __x = 0;
+ else if (__u <= __c5)
+ __x = 1;
+ else
+ {
+ const _RealType __v = -std::log(__urng());
+ const _RealType __y = _M_d + __v * __2cx / _M_d;
+ __x = std::ceil(__y);
+ __w = -_M_d * _M_1cx * (1 + __y / 2);
+ }
+
+ __reject = (__w - __e - __x * _M_lm_thr
+ > _M_lfm - std::_GLIBCXX_TR1 lgamma(__x + __m + 1));
+
+ __reject |= __x + __m >= __thr;
+
+ } while (__reject);
+
+ return result_type(__x + __m + __naf);
+ }
+ else
+#endif
+ {
+ _IntType __x = 0;
+ _RealType __prod = 1.0;
+
+ do
+ {
+ __prod *= __urng();
+ __x += 1;
+ }
+ while (__prod > _M_lm_thr);
+
+ return __x - 1;
+ }
+ }
+
+ template<typename _IntType, typename _RealType,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const poisson_distribution<_IntType, _RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x.mean() << __space << __x._M_nd;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _IntType, typename _RealType,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ poisson_distribution<_IntType, _RealType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::skipws);
+
+ __is >> __x._M_mean >> __x._M_nd;
+ __x._M_initialize();
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _IntType, typename _RealType>
+ void
+ binomial_distribution<_IntType, _RealType>::
+ _M_initialize()
+ {
+ const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
+
+ _M_easy = true;
+
+#if _GLIBCXX_USE_C99_MATH_TR1
+ if (_M_t * __p12 >= 8)
+ {
+ _M_easy = false;
+ const _RealType __np = std::floor(_M_t * __p12);
+ const _RealType __pa = __np / _M_t;
+ const _RealType __1p = 1 - __pa;
+
+ const _RealType __pi_4 = 0.7853981633974483096156608458198757L;
+ const _RealType __d1x =
+ std::sqrt(__np * __1p * std::log(32 * __np
+ / (81 * __pi_4 * __1p)));
+ _M_d1 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d1x));
+ const _RealType __d2x =
+ std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
+ / (__pi_4 * __pa)));
+ _M_d2 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d2x));
+
+ // sqrt(pi / 2)
+ const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
+ _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
+ _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
+ _M_c = 2 * _M_d1 / __np;
+ _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
+ const _RealType __a12 = _M_a1 + _M_s2 * __spi_2;
+ const _RealType __s1s = _M_s1 * _M_s1;
+ _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
+ * 2 * __s1s / _M_d1
+ * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
+ const _RealType __s2s = _M_s2 * _M_s2;
+ _M_s = (_M_a123 + 2 * __s2s / _M_d2
+ * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
+ _M_lf = (std::_GLIBCXX_TR1 lgamma(__np + 1)
+ + std::_GLIBCXX_TR1 lgamma(_M_t - __np + 1));
+ _M_lp1p = std::log(__pa / __1p);
+
+ _M_q = -std::log(1 - (__p12 - __pa) / __1p);
+ }
+ else
+#endif
+ _M_q = -std::log(1 - __p12);
+ }
+
+ template<typename _IntType, typename _RealType>
+ template<class _UniformRandomNumberGenerator>
+ typename binomial_distribution<_IntType, _RealType>::result_type
+ binomial_distribution<_IntType, _RealType>::
+ _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
+ {
+ _IntType __x = 0;
+ _RealType __sum = 0;
+
+ do
+ {
+ const _RealType __e = -std::log(__urng());
+ __sum += __e / (__t - __x);
+ __x += 1;
+ }
+ while (__sum <= _M_q);
+
+ return __x - 1;
+ }
+
+ /**
+ * A rejection algorithm when t * p >= 8 and a simple waiting time
+ * method - the second in the referenced book - otherwise.
+ * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
+ * is defined.
+ *
+ * Reference:
+ * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
+ * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
+ */
+ template<typename _IntType, typename _RealType>
+ template<class _UniformRandomNumberGenerator>
+ typename binomial_distribution<_IntType, _RealType>::result_type
+ binomial_distribution<_IntType, _RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ result_type __ret;
+ const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
+
+#if _GLIBCXX_USE_C99_MATH_TR1
+ if (!_M_easy)
+ {
+ _RealType __x;
+
+ // See comments above...
+ const _RealType __naf =
+ (1 - std::numeric_limits<_RealType>::epsilon()) / 2;
+ const _RealType __thr =
+ std::numeric_limits<_IntType>::max() + __naf;
+
+ const _RealType __np = std::floor(_M_t * __p12);
+ const _RealType __pa = __np / _M_t;
+
+ // sqrt(pi / 2)
+ const _RealType __spi_2 = 1.2533141373155002512078826424055226L;
+ const _RealType __a1 = _M_a1;
+ const _RealType __a12 = __a1 + _M_s2 * __spi_2;
+ const _RealType __a123 = _M_a123;
+ const _RealType __s1s = _M_s1 * _M_s1;
+ const _RealType __s2s = _M_s2 * _M_s2;
+
+ bool __reject;
+ do
+ {
+ const _RealType __u = _M_s * __urng();
+
+ _RealType __v;
+
+ if (__u <= __a1)
+ {
+ const _RealType __n = _M_nd(__urng);
+ const _RealType __y = _M_s1 * std::abs(__n);
+ __reject = __y >= _M_d1;
+ if (!__reject)
+ {
+ const _RealType __e = -std::log(__urng());
+ __x = std::floor(__y);
+ __v = -__e - __n * __n / 2 + _M_c;
+ }
+ }
+ else if (__u <= __a12)
+ {
+ const _RealType __n = _M_nd(__urng);
+ const _RealType __y = _M_s2 * std::abs(__n);
+ __reject = __y >= _M_d2;
+ if (!__reject)
+ {
+ const _RealType __e = -std::log(__urng());
+ __x = std::floor(-__y);
+ __v = -__e - __n * __n / 2;
+ }
+ }
+ else if (__u <= __a123)
+ {
+ const _RealType __e1 = -std::log(__urng());
+ const _RealType __e2 = -std::log(__urng());
+
+ const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1;
+ __x = std::floor(__y);
+ __v = (-__e2 + _M_d1 * (1 / (_M_t - __np)
+ -__y / (2 * __s1s)));
+ __reject = false;
+ }
+ else
+ {
+ const _RealType __e1 = -std::log(__urng());
+ const _RealType __e2 = -std::log(__urng());
+
+ const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2;
+ __x = std::floor(-__y);
+ __v = -__e2 - _M_d2 * __y / (2 * __s2s);
+ __reject = false;
+ }
+
+ __reject = __reject || __x < -__np || __x > _M_t - __np;
+ if (!__reject)
+ {
+ const _RealType __lfx =
+ std::_GLIBCXX_TR1 lgamma(__np + __x + 1)
+ + std::_GLIBCXX_TR1 lgamma(_M_t - (__np + __x) + 1);
+ __reject = __v > _M_lf - __lfx + __x * _M_lp1p;
+ }
+
+ __reject |= __x + __np >= __thr;
+ }
+ while (__reject);
+
+ __x += __np + __naf;
+
+ const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x));
+ __ret = _IntType(__x) + __z;
+ }
+ else
+#endif
+ __ret = _M_waiting(__urng, _M_t);
+
+ if (__p12 != _M_p)
+ __ret = _M_t - __ret;
+ return __ret;
+ }
+
+ template<typename _IntType, typename _RealType,
+ typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const binomial_distribution<_IntType, _RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x.t() << __space << __x.p()
+ << __space << __x._M_nd;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _IntType, typename _RealType,
+ typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ binomial_distribution<_IntType, _RealType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ __is >> __x._M_t >> __x._M_p >> __x._M_nd;
+ __x._M_initialize();
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const uniform_real<_RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x.min() << __space << __x.max();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ uniform_real<_RealType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::skipws);
+
+ __is >> __x._M_min >> __x._M_max;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const exponential_distribution<_RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__os.widen(' '));
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x.lambda();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+
+ /**
+ * Polar method due to Marsaglia.
+ *
+ * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
+ * New York, 1986, Ch. V, Sect. 4.4.
+ */
+ template<typename _RealType>
+ template<class _UniformRandomNumberGenerator>
+ typename normal_distribution<_RealType>::result_type
+ normal_distribution<_RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ result_type __ret;
+
+ if (_M_saved_available)
+ {
+ _M_saved_available = false;
+ __ret = _M_saved;
+ }
+ else
+ {
+ result_type __x, __y, __r2;
+ do
+ {
+ __x = result_type(2.0) * __urng() - 1.0;
+ __y = result_type(2.0) * __urng() - 1.0;
+ __r2 = __x * __x + __y * __y;
+ }
+ while (__r2 > 1.0 || __r2 == 0.0);
+
+ const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
+ _M_saved = __x * __mult;
+ _M_saved_available = true;
+ __ret = __y * __mult;
+ }
+
+ __ret = __ret * _M_sigma + _M_mean;
+ return __ret;
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const normal_distribution<_RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x._M_saved_available << __space
+ << __x.mean() << __space
+ << __x.sigma();
+ if (__x._M_saved_available)
+ __os << __space << __x._M_saved;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ normal_distribution<_RealType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ __is >> __x._M_saved_available >> __x._M_mean
+ >> __x._M_sigma;
+ if (__x._M_saved_available)
+ __is >> __x._M_saved;
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _RealType>
+ void
+ gamma_distribution<_RealType>::
+ _M_initialize()
+ {
+ if (_M_alpha >= 1)
+ _M_l_d = std::sqrt(2 * _M_alpha - 1);
+ else
+ _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha))
+ * (1 - _M_alpha));
+ }
+
+ /**
+ * Cheng's rejection algorithm GB for alpha >= 1 and a modification
+ * of Vaduva's rejection from Weibull algorithm due to Devroye for
+ * alpha < 1.
+ *
+ * References:
+ * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral
+ * Shape Parameter." Applied Statistics, 26, 71-75, 1977.
+ *
+ * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection
+ * and Composition Procedures." Math. Operationsforschung and Statistik,
+ * Series in Statistics, 8, 545-576, 1977.
+ *
+ * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
+ * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!).
+ */
+ template<typename _RealType>
+ template<class _UniformRandomNumberGenerator>
+ typename gamma_distribution<_RealType>::result_type
+ gamma_distribution<_RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ result_type __x;
+
+ bool __reject;
+ if (_M_alpha >= 1)
+ {
+ // alpha - log(4)
+ const result_type __b = _M_alpha
+ - result_type(1.3862943611198906188344642429163531L);
+ const result_type __c = _M_alpha + _M_l_d;
+ const result_type __1l = 1 / _M_l_d;
+
+ // 1 + log(9 / 2)
+ const result_type __k = 2.5040773967762740733732583523868748L;
+
+ do
+ {
+ const result_type __u = __urng();
+ const result_type __v = __urng();
+
+ const result_type __y = __1l * std::log(__v / (1 - __v));
+ __x = _M_alpha * std::exp(__y);
+
+ const result_type __z = __u * __v * __v;
+ const result_type __r = __b + __c * __y - __x;
+
+ __reject = __r < result_type(4.5) * __z - __k;
+ if (__reject)
+ __reject = __r < std::log(__z);
+ }
+ while (__reject);
+ }
+ else
+ {
+ const result_type __c = 1 / _M_alpha;
+
+ do
+ {
+ const result_type __z = -std::log(__urng());
+ const result_type __e = -std::log(__urng());
+
+ __x = std::pow(__z, __c);
+
+ __reject = __z + __e < _M_l_d + __x;
+ }
+ while (__reject);
+ }
+
+ return __x;
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const gamma_distribution<_RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__os.widen(' '));
+ __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10);
+
+ __os << __x.alpha();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+}
+}