sl@0: // (C) Copyright John Maddock 2005. sl@0: // (C) Copyright Henry S. Warren 2005. sl@0: // Use, modification and distribution are subject to the sl@0: // Boost Software License, Version 1.0. (See accompanying file sl@0: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: #ifndef BOOST_TR1_RANDOM_HPP_INCLUDED sl@0: # define BOOST_TR1_RANDOM_HPP_INCLUDED sl@0: # include sl@0: sl@0: #ifdef BOOST_HAS_TR1_RANDOM sl@0: # include BOOST_TR1_HEADER(random) sl@0: #else sl@0: // Boost.Random: sl@0: #include sl@0: #ifndef __SUNPRO_CC sl@0: // Sunpros linker complains if we so much as include this... sl@0: # include sl@0: #endif sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace std { namespace tr1{ sl@0: sl@0: using ::boost::variate_generator; sl@0: sl@0: template sl@0: class linear_congruential sl@0: { sl@0: private: sl@0: typedef ::boost::random::linear_congruential impl_type; sl@0: public: sl@0: // types sl@0: typedef UIntType result_type; sl@0: // parameter values sl@0: BOOST_STATIC_CONSTANT(UIntType, multiplier = a); sl@0: BOOST_STATIC_CONSTANT(UIntType, increment = c); sl@0: BOOST_STATIC_CONSTANT(UIntType, modulus = m); sl@0: // constructors and member function sl@0: explicit linear_congruential(unsigned long x0 = 1) sl@0: : m_gen(x0){} sl@0: linear_congruential(const linear_congruential& that) sl@0: : m_gen(that.m_gen){} sl@0: template linear_congruential(Gen& g) sl@0: { sl@0: init1(g, ::boost::is_same()); sl@0: } sl@0: void seed(unsigned long x0 = 1) sl@0: { m_gen.seed(x0); } sl@0: template void seed(Gen& g) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.min)(); } sl@0: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.max)(); } sl@0: result_type operator()() sl@0: { sl@0: return m_gen(); sl@0: } sl@0: bool operator==(const linear_congruential& that)const sl@0: { return m_gen == that.m_gen; } sl@0: bool operator!=(const linear_congruential& that)const sl@0: { return m_gen != that.m_gen; } sl@0: sl@0: #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) sl@0: template sl@0: friend std::basic_ostream& sl@0: operator<<(std::basic_ostream& os, sl@0: const linear_congruential& lcg) sl@0: { sl@0: return os << lcg.m_gen; sl@0: } sl@0: sl@0: template sl@0: friend std::basic_istream& sl@0: operator>>(std::basic_istream& is, sl@0: linear_congruential& lcg) sl@0: { sl@0: return is >> lcg.m_gen; sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: template sl@0: void init1(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen = g.m_gen; sl@0: } sl@0: template sl@0: void init1(Gen& g, const ::boost::false_type&) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen.seed(static_cast(g)); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::false_type&) sl@0: { sl@0: //typedef typename Gen::result_type gen_rt; sl@0: boost::tr1_details::functor2iterator f1(g), f2; sl@0: m_gen.seed(f1, f2); sl@0: } sl@0: impl_type m_gen; sl@0: }; sl@0: sl@0: template sl@0: class mersenne_twister sl@0: { sl@0: typedef ::boost::random::mersenne_twister sl@0: imp_type; sl@0: public: sl@0: // types sl@0: typedef UIntType result_type; sl@0: // parameter values sl@0: BOOST_STATIC_CONSTANT(int, word_size = w); sl@0: BOOST_STATIC_CONSTANT(int, state_size = n); sl@0: BOOST_STATIC_CONSTANT(int, shift_size = m); sl@0: BOOST_STATIC_CONSTANT(int, mask_bits = r); sl@0: BOOST_STATIC_CONSTANT(UIntType, parameter_a = a); sl@0: BOOST_STATIC_CONSTANT(int, output_u = u); sl@0: BOOST_STATIC_CONSTANT(int, output_s = s); sl@0: BOOST_STATIC_CONSTANT(UIntType, output_b = b); sl@0: BOOST_STATIC_CONSTANT(int, output_t = t); sl@0: BOOST_STATIC_CONSTANT(UIntType, output_c = c); sl@0: BOOST_STATIC_CONSTANT(int, output_l = l); sl@0: // constructors and member function sl@0: mersenne_twister(){} sl@0: explicit mersenne_twister(unsigned long value) sl@0: : m_gen(value == 0 ? 4357UL : value){} sl@0: template mersenne_twister(Gen& g) sl@0: { sl@0: init1(g, ::boost::is_same()); sl@0: } sl@0: void seed() sl@0: { m_gen.seed(); } sl@0: void seed(unsigned long value) sl@0: { m_gen.seed(value == 0 ? 5489UL : value); } sl@0: template void seed(Gen& g) sl@0: { init2(g, ::boost::is_fundamental()); } sl@0: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.min)(); } sl@0: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.max)(); } sl@0: result_type operator()() sl@0: { return m_gen(); } sl@0: bool operator==(const mersenne_twister& that)const sl@0: { return m_gen == that.m_gen; } sl@0: bool operator!=(const mersenne_twister& that)const sl@0: { return m_gen != that.m_gen; } sl@0: sl@0: #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) sl@0: template sl@0: friend std::basic_ostream& sl@0: operator<<(std::basic_ostream& os, sl@0: const mersenne_twister& lcg) sl@0: { sl@0: return os << lcg.m_gen; sl@0: } sl@0: sl@0: template sl@0: friend std::basic_istream& sl@0: operator>>(std::basic_istream& is, sl@0: mersenne_twister& lcg) sl@0: { sl@0: return is >> lcg.m_gen; sl@0: } sl@0: #endif sl@0: private: sl@0: template sl@0: void init1(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen = g.m_gen; sl@0: } sl@0: template sl@0: void init1(Gen& g, const ::boost::false_type&) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen.seed(static_cast(g == 0 ? 4357UL : g)); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::false_type&) sl@0: { sl@0: m_gen.seed(g); sl@0: } sl@0: imp_type m_gen; sl@0: }; sl@0: sl@0: template sl@0: class subtract_with_carry sl@0: { sl@0: public: sl@0: // types sl@0: typedef IntType result_type; sl@0: // parameter values sl@0: BOOST_STATIC_CONSTANT(IntType, modulus = m); sl@0: BOOST_STATIC_CONSTANT(int, long_lag = r); sl@0: BOOST_STATIC_CONSTANT(int, short_lag = s); sl@0: sl@0: // constructors and member function sl@0: subtract_with_carry(){} sl@0: explicit subtract_with_carry(unsigned long value) sl@0: : m_gen(value == 0 ? 19780503UL : value){} sl@0: template subtract_with_carry(Gen& g) sl@0: { init1(g, ::boost::is_same >()); } sl@0: void seed(unsigned long value = 19780503ul) sl@0: { m_gen.seed(value == 0 ? 19780503UL : value); } sl@0: template void seed(Gen& g) sl@0: { init2(g, ::boost::is_fundamental()); } sl@0: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.min)(); } sl@0: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.max)(); } sl@0: result_type operator()() sl@0: { return m_gen(); } sl@0: bool operator==(const subtract_with_carry& that)const sl@0: { return m_gen == that.m_gen; } sl@0: bool operator!=(const subtract_with_carry& that)const sl@0: { return m_gen != that.m_gen; } sl@0: sl@0: #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) sl@0: template sl@0: friend std::basic_ostream& sl@0: operator<<(std::basic_ostream& os, sl@0: const subtract_with_carry& lcg) sl@0: { sl@0: return os << lcg.m_gen; sl@0: } sl@0: sl@0: template sl@0: friend std::basic_istream& sl@0: operator>>(std::basic_istream& is, sl@0: subtract_with_carry& lcg) sl@0: { sl@0: return is >> lcg.m_gen; sl@0: } sl@0: #endif sl@0: private: sl@0: template sl@0: void init1(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen = g.m_gen; sl@0: } sl@0: template sl@0: void init1(Gen& g, const ::boost::false_type&) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen.seed(static_cast(g == 0 ? 19780503UL : g)); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::false_type&) sl@0: { sl@0: m_gen.seed(g); sl@0: } sl@0: ::boost::random::subtract_with_carry m_gen; sl@0: }; sl@0: sl@0: template sl@0: class subtract_with_carry_01 sl@0: { sl@0: public: sl@0: // types sl@0: typedef RealType result_type; sl@0: // parameter values sl@0: BOOST_STATIC_CONSTANT(int, word_size = w); sl@0: BOOST_STATIC_CONSTANT(int, long_lag = r); sl@0: BOOST_STATIC_CONSTANT(int, short_lag = s); sl@0: sl@0: // constructors and member function sl@0: subtract_with_carry_01(){} sl@0: explicit subtract_with_carry_01(unsigned long value) sl@0: : m_gen(value == 0 ? 19780503UL : value){} sl@0: template subtract_with_carry_01(Gen& g) sl@0: { init1(g, ::boost::is_same >()); } sl@0: void seed(unsigned long value = 19780503UL) sl@0: { m_gen.seed(value == 0 ? 19780503UL : value); } sl@0: template void seed(Gen& g) sl@0: { init2(g, ::boost::is_fundamental()); } sl@0: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.min)(); } sl@0: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return (m_gen.max)(); } sl@0: result_type operator()() sl@0: { return m_gen(); } sl@0: bool operator==(const subtract_with_carry_01& that)const sl@0: { return m_gen == that.m_gen; } sl@0: bool operator!=(const subtract_with_carry_01& that)const sl@0: { return m_gen != that.m_gen; } sl@0: sl@0: #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) sl@0: template sl@0: friend std::basic_ostream& sl@0: operator<<(std::basic_ostream& os, sl@0: const subtract_with_carry_01& lcg) sl@0: { sl@0: return os << lcg.m_gen; sl@0: } sl@0: sl@0: template sl@0: friend std::basic_istream& sl@0: operator>>(std::basic_istream& is, sl@0: subtract_with_carry_01& lcg) sl@0: { sl@0: return is >> lcg.m_gen; sl@0: } sl@0: #endif sl@0: private: sl@0: template sl@0: void init1(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen = g.m_gen; sl@0: } sl@0: template sl@0: void init1(Gen& g, const ::boost::false_type&) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_gen.seed(static_cast(g == 0 ? 19780503UL : g)); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::false_type&) sl@0: { sl@0: //typedef typename Gen::result_type gen_rt; sl@0: boost::tr1_details::functor2iterator f1(g), f2; sl@0: m_gen.seed(f1, f2); sl@0: } sl@0: ::boost::random::subtract_with_carry_01 m_gen; sl@0: }; sl@0: sl@0: using ::boost::random::discard_block; sl@0: sl@0: template sl@0: class xor_combine sl@0: { sl@0: public: sl@0: // types sl@0: typedef UniformRandomNumberGenerator1 base1_type; sl@0: typedef UniformRandomNumberGenerator2 base2_type; sl@0: typedef unsigned long result_type; sl@0: // parameter values sl@0: BOOST_STATIC_CONSTANT(int, shift1 = s1); sl@0: BOOST_STATIC_CONSTANT(int, shift2 = s2); sl@0: // constructors and member function sl@0: xor_combine(){ init_minmax(); } sl@0: xor_combine(const base1_type & rng1, const base2_type & rng2) sl@0: : m_b1(rng1), m_b2(rng2) { init_minmax(); } sl@0: xor_combine(unsigned long s) sl@0: : m_b1(s), m_b2(s+1) { init_minmax(); } sl@0: template xor_combine(Gen& g) sl@0: { sl@0: init_minmax(); sl@0: init1(g, ::boost::is_same >()); sl@0: } sl@0: void seed() sl@0: { sl@0: m_b1.seed(); sl@0: m_b2.seed(); sl@0: } sl@0: void seed(unsigned long s) sl@0: { sl@0: m_b1.seed(s); sl@0: m_b2.seed(s+1); sl@0: } sl@0: template void seed(Gen& g) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: sl@0: const base1_type& base1() const sl@0: { return m_b1; } sl@0: const base2_type& base2() const sl@0: { return m_b2; } sl@0: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return m_min; } sl@0: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const sl@0: { return m_max; } sl@0: result_type operator()() sl@0: { return (m_b1() << s1) ^ (m_b2() << s2); } sl@0: sl@0: bool operator == (const xor_combine& that)const sl@0: { return (m_b1 == that.m_b1) && (m_b2 == that.m_b2); } sl@0: bool operator != (const xor_combine& that)const sl@0: { return !(*this == that); } sl@0: sl@0: #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) sl@0: template sl@0: friend std::basic_ostream& sl@0: operator<<(std::basic_ostream& os, sl@0: const xor_combine& lcg) sl@0: { sl@0: return os << lcg.m_b1 << " " << lcg.m_b2; sl@0: } sl@0: sl@0: template sl@0: friend std::basic_istream& sl@0: operator>>(std::basic_istream& is, sl@0: xor_combine& lcg) sl@0: { sl@0: return is >> lcg.m_b1 >> lcg.m_b2; sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: void init_minmax(); sl@0: base1_type m_b1; sl@0: base2_type m_b2; sl@0: result_type m_min; sl@0: result_type m_max; sl@0: sl@0: template sl@0: void init1(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_b1 = g.m_b1; sl@0: m_b2 = g.m_b2; sl@0: } sl@0: template sl@0: void init1(Gen& g, const ::boost::false_type&) sl@0: { sl@0: init2(g, ::boost::is_fundamental()); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::true_type&) sl@0: { sl@0: m_b1.seed(static_cast(g)); sl@0: m_b2.seed(static_cast(g)); sl@0: } sl@0: template sl@0: void init2(Gen& g, const ::boost::false_type&) sl@0: { sl@0: m_b1.seed(g); sl@0: m_b2.seed(g); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: void xor_combine::init_minmax() sl@0: { sl@0: // sl@0: // The following code is based on that given in "Hacker's Delight" sl@0: // by Henry S. Warren, (Addison-Wesley, 2003), and at sl@0: // http://www.hackersdelight.org/index.htm. sl@0: // Used here by permission. sl@0: // sl@0: // calculation of minimum value: sl@0: // sl@0: result_type a = (m_b1.min)() << s1; sl@0: result_type b = (m_b1.max)() << s1; sl@0: result_type c = (m_b2.min)() << s2; sl@0: result_type d = (m_b2.max)() << s2; sl@0: result_type m, temp; sl@0: sl@0: m = 0x1uL << ((sizeof(result_type) * CHAR_BIT) - 1); sl@0: while (m != 0) { sl@0: if (~a & c & m) { sl@0: temp = (a | m) & (static_cast(0u) - m); sl@0: if (temp <= b) a = temp; sl@0: } sl@0: else if (a & ~c & m) { sl@0: temp = (c | m) & (static_cast(0u) - m); sl@0: if (temp <= d) c = temp; sl@0: } sl@0: m >>= 1; sl@0: } sl@0: m_min = a ^ c; sl@0: sl@0: // sl@0: // calculation of maximum value: sl@0: // sl@0: if((((std::numeric_limits::max)() >> s1) < (m_b1.max)()) sl@0: || ((((std::numeric_limits::max)()) >> s2) < (m_b2.max)())) sl@0: { sl@0: m_max = (std::numeric_limits::max)(); sl@0: return; sl@0: } sl@0: a = (m_b1.min)() << s1; sl@0: b = (m_b1.max)() << s1; sl@0: c = (m_b2.min)() << s2; sl@0: d = (m_b2.max)() << s2; sl@0: sl@0: m = 0x1uL << ((sizeof(result_type) * CHAR_BIT) - 1); sl@0: sl@0: while (m != 0) { sl@0: if (b & d & m) { sl@0: temp = (b - m) | (m - 1); sl@0: if (temp >= a) b = temp; sl@0: else { sl@0: temp = (d - m) | (m - 1); sl@0: if (temp >= c) d = temp; sl@0: } sl@0: } sl@0: m = m >> 1; sl@0: } sl@0: m_max = b ^ d; sl@0: } sl@0: sl@0: typedef linear_congruential< ::boost::int32_t, 16807, 0, 2147483647> minstd_rand0; sl@0: typedef linear_congruential< ::boost::int32_t, 48271, 0, 2147483647> minstd_rand; sl@0: typedef mersenne_twister< ::boost::uint32_t, 32,624,397,31,0x9908b0df,11,7,0x9d2c5680,15,0xefc60000,18> mt19937; sl@0: typedef subtract_with_carry_01 ranlux_base_01; sl@0: typedef subtract_with_carry_01 ranlux64_base_01; sl@0: typedef discard_block, 223, 24> ranlux3; sl@0: typedef discard_block, 389, 24> ranlux4; sl@0: typedef discard_block, 223, 24> ranlux3_01; sl@0: typedef discard_block, 389, 24> ranlux4_01; sl@0: sl@0: #ifndef __SUNPRO_CC sl@0: using ::boost::random_device; sl@0: #endif sl@0: using ::boost::uniform_int; sl@0: sl@0: class bernoulli_distribution sl@0: { sl@0: public: sl@0: // types sl@0: typedef int input_type; sl@0: typedef bool result_type; sl@0: // constructors and member function sl@0: explicit bernoulli_distribution(double p = 0.5) sl@0: : m_dist(p){} sl@0: double p() const sl@0: { return m_dist.p(); } sl@0: void reset() sl@0: { m_dist.reset(); } sl@0: template sl@0: result_type operator()(UniformRandomNumberGenerator& urng) sl@0: { sl@0: return m_dist(urng); sl@0: } sl@0: #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) sl@0: template sl@0: friend std::basic_ostream& sl@0: operator<<(std::basic_ostream& os, sl@0: const bernoulli_distribution& lcg) sl@0: { sl@0: return os << lcg.m_dist; sl@0: } sl@0: sl@0: template sl@0: friend std::basic_istream& sl@0: operator>>(std::basic_istream& is, sl@0: bernoulli_distribution& lcg) sl@0: { sl@0: return is >> lcg.m_dist; sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: ::boost::bernoulli_distribution m_dist; sl@0: }; sl@0: //using ::boost::bernoulli_distribution; sl@0: using ::boost::geometric_distribution; sl@0: using ::boost::poisson_distribution; sl@0: using ::boost::binomial_distribution; sl@0: using ::boost::uniform_real; sl@0: using ::boost::exponential_distribution; sl@0: using ::boost::normal_distribution; sl@0: using ::boost::gamma_distribution; sl@0: sl@0: } } sl@0: sl@0: #endif sl@0: sl@0: #endif sl@0: