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