From b60a7aca9c29a196414dcb8b27e612e31f12f239 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 9 Nov 2013 17:39:57 +0900 Subject: [PATCH] [sprout.random] add Sseq version: constructor, seed --- sprout/detail/integer/static_log2.hpp | 12 ++- sprout/random/additive_combine.hpp | 68 +++++++++--- sprout/random/detail/seed_impl.hpp | 114 ++++++++++++++++++++ sprout/random/inversive_congruential.hpp | 72 ++++++++++--- sprout/random/linear_congruential.hpp | 82 ++++++++++---- sprout/random/linear_feedback_shift.hpp | 54 ++++++++-- sprout/random/mersenne_twister.hpp | 130 +++++++++++------------ sprout/random/shuffle_order.hpp | 53 +++++++-- sprout/random/taus88.hpp | 6 +- sprout/random/xor_combine.hpp | 56 ++++++++-- 10 files changed, 495 insertions(+), 152 deletions(-) create mode 100644 sprout/random/detail/seed_impl.hpp diff --git a/sprout/detail/integer/static_log2.hpp b/sprout/detail/integer/static_log2.hpp index 634cecb4..d8e4dda8 100644 --- a/sprout/detail/integer/static_log2.hpp +++ b/sprout/detail/integer/static_log2.hpp @@ -9,6 +9,7 @@ #define SPROUT_DETAIL_INTEGER_STATIC_LOG2_HPP #include +#include #include namespace sprout { @@ -56,11 +57,12 @@ namespace sprout { } // namespace static_log2_impl template - struct static_log2 { - SPROUT_STATIC_CONSTEXPR sprout::detail::static_log2_result_type value - = sprout::detail::static_log2_impl::static_log2_impl::value - ; - }; + struct static_log2 + : public std::integral_constant< + sprout::detail::static_log2_result_type, + sprout::detail::static_log2_impl::static_log2_impl::value + > + {}; template<> struct static_log2<0> {}; } // namespace detail diff --git a/sprout/random/additive_combine.hpp b/sprout/random/additive_combine.hpp index cb4b21d2..7040c542 100644 --- a/sprout/random/additive_combine.hpp +++ b/sprout/random/additive_combine.hpp @@ -42,12 +42,10 @@ namespace sprout { base2_type mlcg2_; private: SPROUT_CONSTEXPR additive_combine_engine( - base1_type const& mlcg1, - base2_type const& mlcg2, + base1_type const& mlcg1, base2_type const& mlcg2, private_construct_t ) - : mlcg1_(mlcg1) - , mlcg2_(mlcg2) + : mlcg1_(mlcg1), mlcg2_(mlcg2) {} template SPROUT_CONSTEXPR sprout::random::random_result generate(Random1 const& rnd1, Random2 const& rnd2) const { @@ -57,25 +55,63 @@ namespace sprout { : rnd1.result() - rnd2.result() + base1_type::modulus - 1 , additive_combine_engine( - rnd1.engine(), - rnd2.engine(), + rnd1.engine(), rnd2.engine(), private_construct_t() ) ); } public: SPROUT_CONSTEXPR additive_combine_engine() - : mlcg1_() - , mlcg2_() + : mlcg1_(), mlcg2_() {} - explicit SPROUT_CONSTEXPR additive_combine_engine(result_type const& seed) - : mlcg1_(seed) - , mlcg2_(seed) + explicit SPROUT_CONSTEXPR additive_combine_engine(result_type seed) + : mlcg1_(seed), mlcg2_(seed) {} - SPROUT_CONSTEXPR additive_combine_engine(typename MLCG1::result_type seed1, typename MLCG2::result_type seed2) - : mlcg1_(seed1) - , mlcg2_(seed2) + template + explicit SPROUT_CXX14_CONSTEXPR additive_combine_engine(Sseq& seq) + : mlcg1_(seq), mlcg2_(seq) {} + template + explicit SPROUT_CONSTEXPR additive_combine_engine(Sseq const& seq) + : mlcg1_(seq), mlcg2_(seq) + {} + template + SPROUT_CONSTEXPR additive_combine_engine(ForwardIterator first, ForwardIterator last) + : mlcg1_(first, last), mlcg2_(first, last) + {} + SPROUT_CONSTEXPR additive_combine_engine(typename base1_type::result_type seed1, typename base2_type::result_type seed2) + : mlcg1_(seed1), mlcg2_(seed2) + {} + SPROUT_CONSTEXPR additive_combine_engine(base1_type const& rng1, base2_type const& rng2) + : mlcg1_(rng1), mlcg2_(rng2) + {} + SPROUT_CXX14_CONSTEXPR void seed() { + mlcg1_.seed(); + mlcg2_.seed(); + } + SPROUT_CXX14_CONSTEXPR void seed(result_type seed) { + mlcg1_.seed(seed); + mlcg2_.seed(seed); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq& seq) { + mlcg1_.seed(seq); + mlcg2_.seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq const& seq) { + mlcg1_.seed(seq); + mlcg2_.seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(ForwardIterator first, ForwardIterator last) { + mlcg1_.seed(first, last); + mlcg2_.seed(first, last); + } + SPROUT_CXX14_CONSTEXPR void seed(typename base1_type::result_type seed1, typename base2_type::result_type seed2) { + mlcg1_.seed(seed1); + mlcg2_.seed(seed2); + } SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT { return 1; } @@ -127,8 +163,8 @@ namespace sprout { // ecuyer1988 // typedef sprout::random::additive_combine_engine< - sprout::random::linear_congruential_engine, - sprout::random::linear_congruential_engine + sprout::random::linear_congruential_engine, + sprout::random::linear_congruential_engine > ecuyer1988; } // namespace random diff --git a/sprout/random/detail/seed_impl.hpp b/sprout/random/detail/seed_impl.hpp new file mode 100644 index 00000000..9fee0f53 --- /dev/null +++ b/sprout/random/detail/seed_impl.hpp @@ -0,0 +1,114 @@ +/*============================================================================= + Copyright (c) 2011-2013 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_RANDOM_DETAIL_SEED_IMPL_HPP +#define SPROUT_RANDOM_DETAIL_SEED_IMPL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + namespace detail { + template + struct seed_log + : public std::conditional< + m == 0, + std::integral_constant::digits>, + std::integral_constant::value> + >::type + {}; + template + struct seed_k + : public std::integral_constant< + int, + (log + ((~(IntType(2) << (log - 1)) & m)? 32 : 31)) / 32 + > + {}; + + template + inline SPROUT_CONSTEXPR IntType + seed_one_int_impl(Array const& arr, IntType s, int j) { + return j < k ? sprout::random::detail::seed_one_int_impl( + arr, + sprout::random::detail::const_mod::mult_add( + IntType(1) << 32 * j, + sprout::random::detail::const_mod::apply(IntType(arr[j + 3])), + s + ), + j + 1 + ) + : s + ; + } + template + inline SPROUT_CONSTEXPR IntType + seed_one_int(Sseq const& seq) { + typedef typename sprout::random::detail::seed_log::type log_t; + typedef typename sprout::random::detail::seed_k::type k_t; + return sprout::random::detail::seed_one_int_impl( + seq.generate(sprout::pit >()), + 0, 0 + ); + } + template + inline SPROUT_CXX14_CONSTEXPR IntType + seed_one_int(Sseq& seq) { + typedef typename sprout::random::detail::seed_log::type log_t; + typedef typename sprout::random::detail::seed_k::type k_t; + sprout::array arr{{}}; + seq.generate(arr.begin(), arr.begin() + (k_t::value + 3)); + IntType s = 0; + for (int j = 0; j < k_t::value; ++j) { + IntType digit = sprout::random::detail::const_mod::apply(IntType(arr[j + 3])); + IntType mult = IntType(1) << 32 * j; + s = sprout::random::detail::const_mod::mult_add(mult, digit, s); + } + return s; + } + + template + inline SPROUT_CONSTEXPR IntType + get_one_int_impl(InputIterator first, InputIterator last, IntType s, int j) { + return j < k + ? first != last + ? sprout::random::detail::get_one_int_impl( + sprout::next(first), last, + sprout::random::detail::const_mod::mult_add( + IntType(1) << 32 * j, + sprout::random::detail::const_mod::apply(IntType(*first)), + s + ), + j + 1 + ) + : throw std::invalid_argument("Not enough elements in call to seed.") + : s + ; + } + template + inline SPROUT_CONSTEXPR IntType + get_one_int(InputIterator first, InputIterator last) { + typedef typename sprout::random::detail::seed_log::type log_t; + typedef typename sprout::random::detail::seed_k::type k_t; + return sprout::random::detail::get_one_int_impl( + first, last, + 0, 0 + ); + } + } // namespace detail + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_DETAIL_SEED_IMPL_HPP diff --git a/sprout/random/inversive_congruential.hpp b/sprout/random/inversive_congruential.hpp index b8ee8825..92c9a05e 100644 --- a/sprout/random/inversive_congruential.hpp +++ b/sprout/random/inversive_congruential.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,33 +31,45 @@ namespace sprout { private: struct private_construct_t {}; public: - SPROUT_STATIC_CONSTEXPR IntType multiplier = a; - SPROUT_STATIC_CONSTEXPR IntType increment = b; - SPROUT_STATIC_CONSTEXPR IntType modulus = p; - SPROUT_STATIC_CONSTEXPR IntType default_seed = 1; + SPROUT_STATIC_CONSTEXPR result_type multiplier = a; + SPROUT_STATIC_CONSTEXPR result_type increment = b; + SPROUT_STATIC_CONSTEXPR result_type modulus = p; + SPROUT_STATIC_CONSTEXPR result_type default_seed = 1; public: static SPROUT_CONSTEXPR result_type static_min() SPROUT_NOEXCEPT { - return b == 0 ? 1 : 0; + return increment == 0 ? 1 : 0; } static SPROUT_CONSTEXPR result_type static_max() SPROUT_NOEXCEPT { return modulus - 1; } - static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_3(result_type x0) { return SPROUT_ASSERT(sprout::math::greater_equal(x0, static_min())), SPROUT_ASSERT(x0 <= static_max()), x0; } - static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_2(result_type x0) { return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0); } - static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_1(result_type x0) { return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0); } - static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed(result_type x0 = default_seed) { return init_seed_1(modulus == 0 ? x0 : x0 % modulus); } + template + static SPROUT_CXX14_CONSTEXPR result_type init_seed(Sseq& seq) { + return init_seed(sprout::random::detail::seed_one_int(seq)); + } + template + static SPROUT_CONSTEXPR result_type init_seed(Sseq const& seq) { + return init_seed(sprout::random::detail::seed_one_int(seq)); + } + template + static SPROUT_CONSTEXPR result_type init_seed(InputIterator first, InputIterator last) { + return init_seed(sprout::random::detail::get_one_int(first, last)); + } private: - IntType x_; + result_type x_; private: - SPROUT_CONSTEXPR inversive_congruential_engine(IntType const& x, private_construct_t) + SPROUT_CONSTEXPR inversive_congruential_engine(result_type x, private_construct_t) : x_(x) {} SPROUT_CONSTEXPR sprout::random::random_result @@ -70,9 +83,36 @@ namespace sprout { SPROUT_CONSTEXPR inversive_congruential_engine() : x_(init_seed(default_seed)) {} - explicit SPROUT_CONSTEXPR inversive_congruential_engine(IntType const& x0) + explicit SPROUT_CONSTEXPR inversive_congruential_engine(result_type x0) : x_(init_seed(x0)) {} + template + explicit SPROUT_CXX14_CONSTEXPR inversive_congruential_engine(Sseq& seq) + : x_(init_seed(seq)) + {} + template + explicit SPROUT_CONSTEXPR inversive_congruential_engine(Sseq const& seq) + : x_(init_seed(seq)) + {} + template + SPROUT_CONSTEXPR inversive_congruential_engine(InputIterator first, InputIterator last) + : x_(init_seed(first, last)) + {} + SPROUT_CXX14_CONSTEXPR void seed(result_type x0 = default_seed) { + x_ = init_seed(x0); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq& seq) { + x_ = init_seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq const& seq) { + x_ = init_seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(InputIterator first, InputIterator last) { + x_ = init_seed(first, last); + } SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT { return static_min(); } @@ -80,12 +120,12 @@ namespace sprout { return static_max(); } SPROUT_CXX14_CONSTEXPR result_type operator()() { - typedef sprout::random::detail::const_mod do_mod; + typedef sprout::random::detail::const_mod do_mod; x_ = do_mod::mult_add(a, do_mod::invert(x_), b); return x_; } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { - typedef sprout::random::detail::const_mod do_mod; + typedef sprout::random::detail::const_mod do_mod; return generate(do_mod::mult_add(a, do_mod::invert(x_), b)); } friend SPROUT_CONSTEXPR bool operator==(inversive_congruential_engine const& lhs, inversive_congruential_engine const& rhs) SPROUT_NOEXCEPT { @@ -100,7 +140,7 @@ namespace sprout { inversive_congruential_engine& rhs ) { - IntType x; + result_type x; if (lhs >> x) { if (sprout::math::greater_equal(x, static_min()) && x <= static_max()) { rhs.x_ = x; @@ -131,7 +171,7 @@ namespace sprout { // // hellekalek1995 // - typedef sprout::random::inversive_congruential_engine hellekalek1995; + typedef sprout::random::inversive_congruential_engine hellekalek1995; } // namespace random using sprout::random::inversive_congruential_engine; diff --git a/sprout/random/linear_congruential.hpp b/sprout/random/linear_congruential.hpp index 338fb383..ce364dc8 100644 --- a/sprout/random/linear_congruential.hpp +++ b/sprout/random/linear_congruential.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -33,34 +34,46 @@ namespace sprout { private: struct private_construct_t {}; public: - SPROUT_STATIC_CONSTEXPR UIntType multiplier = a; - SPROUT_STATIC_CONSTEXPR UIntType increment = c; - SPROUT_STATIC_CONSTEXPR UIntType modulus = m; - SPROUT_STATIC_CONSTEXPR UIntType default_seed = 1; + SPROUT_STATIC_CONSTEXPR result_type multiplier = a; + SPROUT_STATIC_CONSTEXPR result_type increment = c; + SPROUT_STATIC_CONSTEXPR result_type modulus = m; + SPROUT_STATIC_CONSTEXPR result_type default_seed = 1; public: static SPROUT_CONSTEXPR result_type static_min() SPROUT_NOEXCEPT { - return c == 0 ? 1 : 0; + return increment == 0 ? 1 : 0; } static SPROUT_CONSTEXPR result_type static_max() SPROUT_NOEXCEPT { - return m - 1; + return modulus - 1; } private: - static SPROUT_CONSTEXPR UIntType init_seed_3(UIntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_3(result_type x0) { return SPROUT_ASSERT(sprout::math::greater_equal(x0, static_min())), SPROUT_ASSERT(x0 <= static_max()), x0; } - static SPROUT_CONSTEXPR UIntType init_seed_2(UIntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_2(result_type x0) { return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0); } - static SPROUT_CONSTEXPR UIntType init_seed_1(UIntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_1(result_type x0) { return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0); } - static SPROUT_CONSTEXPR UIntType init_seed(UIntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed(result_type x0 = default_seed) { return init_seed_1(modulus == 0 ? x0 : x0 % modulus); } + template + static SPROUT_CXX14_CONSTEXPR result_type init_seed(Sseq& seq) { + return init_seed(sprout::random::detail::seed_one_int(seq)); + } + template + static SPROUT_CONSTEXPR result_type init_seed(Sseq const& seq) { + return init_seed(sprout::random::detail::seed_one_int(seq)); + } + template + static SPROUT_CONSTEXPR result_type init_seed(InputIterator first, InputIterator last) { + return init_seed(sprout::random::detail::get_one_int(first, last)); + } private: - UIntType x_; + result_type x_; private: - SPROUT_CONSTEXPR linear_congruential_engine(UIntType const& x, private_construct_t) + SPROUT_CONSTEXPR linear_congruential_engine(result_type x, private_construct_t) : x_(x) {} SPROUT_CONSTEXPR sprout::random::random_result generate(result_type result) const { @@ -71,11 +84,38 @@ namespace sprout { } public: SPROUT_CONSTEXPR linear_congruential_engine() - : x_(init_seed(default_seed)) + : x_(init_seed()) {} - explicit SPROUT_CONSTEXPR linear_congruential_engine(UIntType const& x0) + explicit SPROUT_CONSTEXPR linear_congruential_engine(result_type x0) : x_(init_seed(x0)) {} + template + explicit SPROUT_CXX14_CONSTEXPR linear_congruential_engine(Sseq& seq) + : x_(init_seed(seq)) + {} + template + explicit SPROUT_CONSTEXPR linear_congruential_engine(Sseq const& seq) + : x_(init_seed(seq)) + {} + template + SPROUT_CONSTEXPR linear_congruential_engine(InputIterator first, InputIterator last) + : x_(init_seed(first, last)) + {} + SPROUT_CXX14_CONSTEXPR void seed(result_type x0 = default_seed) { + x_ = init_seed(x0); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq& seq) { + x_ = init_seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq const& seq) { + x_ = init_seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(InputIterator first, InputIterator last) { + x_ = init_seed(first, last); + } SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT { return static_min(); } @@ -83,11 +123,11 @@ namespace sprout { return static_max(); } SPROUT_CXX14_CONSTEXPR result_type operator()() { - x_ = sprout::random::detail::const_mod::mult_add(a, x_, c); + x_ = sprout::random::detail::const_mod::mult_add(a, x_, c); return x_; } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { - return generate(sprout::random::detail::const_mod::mult_add(a, x_, c)); + return generate(sprout::random::detail::const_mod::mult_add(a, x_, c)); } friend SPROUT_CONSTEXPR bool operator==(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) SPROUT_NOEXCEPT { return lhs.x_ == rhs.x_; @@ -101,7 +141,7 @@ namespace sprout { linear_congruential_engine& rhs ) { - UIntType x; + result_type x; if (lhs >> x) { if (sprout::math::greater_equal(x, static_min()) && x <= static_max()) { rhs.x_ = x; @@ -131,12 +171,10 @@ namespace sprout { // // minstd_rand0 - // - typedef sprout::random::linear_congruential_engine minstd_rand0; - // // minstd_rand // - typedef sprout::random::linear_congruential_engine minstd_rand; + typedef sprout::random::linear_congruential_engine minstd_rand0; + typedef sprout::random::linear_congruential_engine minstd_rand; // // rand48 @@ -179,7 +217,7 @@ namespace sprout { SPROUT_CONSTEXPR rand48() : lcf_(cnv(static_cast(1))) {} - explicit SPROUT_CONSTEXPR rand48(result_type const& x0) + explicit SPROUT_CONSTEXPR rand48(result_type x0) : lcf_(cnv(x0)) {} SPROUT_CONSTEXPR result_type min() const { diff --git a/sprout/random/linear_feedback_shift.hpp b/sprout/random/linear_feedback_shift.hpp index 599d6d95..a607e1b1 100644 --- a/sprout/random/linear_feedback_shift.hpp +++ b/sprout/random/linear_feedback_shift.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace sprout { @@ -29,7 +30,7 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR int exponent1 = k; SPROUT_STATIC_CONSTEXPR int exponent2 = q; SPROUT_STATIC_CONSTEXPR int step_size = s; - SPROUT_STATIC_CONSTEXPR UIntType default_seed = 341; + SPROUT_STATIC_CONSTEXPR result_type default_seed = 341; public: static_assert(w > 0, "w > 0"); static_assert(q > 0, "q > 0"); @@ -44,19 +45,31 @@ namespace sprout { return wordmask(); } private: - static SPROUT_CONSTEXPR UIntType wordmask() { + static SPROUT_CONSTEXPR result_type wordmask() { return sprout::detail::low_bits_mask_t::sig_bits; } - static SPROUT_CONSTEXPR UIntType init_seed_1(UIntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed_1(result_type x0) { return x0 < (1 << (w - k)) ? x0 + (1 << (w - k)) : x0; } - static SPROUT_CONSTEXPR UIntType init_seed(UIntType const& x0) { + static SPROUT_CONSTEXPR result_type init_seed(result_type x0 = default_seed) { return init_seed_1(x0 & wordmask()); } + template + static SPROUT_CXX14_CONSTEXPR result_type init_seed(Sseq& seq) { + return init_seed(sprout::random::detail::seed_one_int(seq)); + } + template + static SPROUT_CONSTEXPR result_type init_seed(Sseq const& seq) { + return init_seed(sprout::random::detail::seed_one_int(seq)); + } + template + static SPROUT_CONSTEXPR result_type init_seed(InputIterator first, InputIterator last) { + return init_seed(sprout::random::detail::get_one_int(first, last)); + } private: - UIntType x_; + result_type x_; private: - SPROUT_CONSTEXPR linear_feedback_shift_engine(UIntType const& x, private_construct_t) + SPROUT_CONSTEXPR linear_feedback_shift_engine(result_type x, private_construct_t) : x_(x) {} SPROUT_CONSTEXPR sprout::random::random_result generate(result_type result) const { @@ -69,9 +82,36 @@ namespace sprout { SPROUT_CONSTEXPR linear_feedback_shift_engine() : x_(init_seed(default_seed)) {} - explicit SPROUT_CONSTEXPR linear_feedback_shift_engine(UIntType const& x0) + explicit SPROUT_CONSTEXPR linear_feedback_shift_engine(result_type x0) : x_(init_seed(x0)) {} + template + explicit SPROUT_CXX14_CONSTEXPR linear_feedback_shift_engine(Sseq& seq) + : x_(init_seed(seq)) + {} + template + explicit SPROUT_CONSTEXPR linear_feedback_shift_engine(Sseq const& seq) + : x_(init_seed(seq)) + {} + template + SPROUT_CONSTEXPR linear_feedback_shift_engine(InputIterator first, InputIterator last) + : x_(init_seed(first, last)) + {} + SPROUT_CXX14_CONSTEXPR void seed(result_type x0 = default_seed) { + x_ = init_seed(x0); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq& seq) { + x_ = init_seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq const& seq) { + x_ = init_seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(InputIterator first, InputIterator last) { + x_ = init_seed(first, last); + } SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT { return static_min(); } diff --git a/sprout/random/mersenne_twister.hpp b/sprout/random/mersenne_twister.hpp index 968c4f0a..1844b34c 100644 --- a/sprout/random/mersenne_twister.hpp +++ b/sprout/random/mersenne_twister.hpp @@ -37,19 +37,19 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR std::size_t state_size = n; SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m; SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r; - SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a; + SPROUT_STATIC_CONSTEXPR result_type xor_mask = a; SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u; - SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d; + SPROUT_STATIC_CONSTEXPR result_type tempering_d = d; SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s; - SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b; + SPROUT_STATIC_CONSTEXPR result_type tempering_b = b; SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t; - SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c; + SPROUT_STATIC_CONSTEXPR result_type tempering_c = c; SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l; - SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f; - SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u; + SPROUT_STATIC_CONSTEXPR result_type initialization_multiplier = f; + SPROUT_STATIC_CONSTEXPR result_type default_seed = 5489u; private: - SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast(0)) << r; - SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask; + SPROUT_STATIC_CONSTEXPR result_type upper_mask = (~static_cast(0)) << r; + SPROUT_STATIC_CONSTEXPR result_type lower_mask = ~upper_mask; SPROUT_STATIC_CONSTEXPR std::size_t unroll_factor = 6; SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra1 = (n - m) % unroll_factor; SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor; @@ -64,78 +64,78 @@ namespace sprout { template static SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) + 1 == n, - sprout::array - >::type init_seed_1(UIntType const& value, Args const&... args) { - return sprout::array{{args..., value}}; + sprout::array + >::type init_seed_1(result_type value, Args const&... args) { + return sprout::array{{args..., value}}; } template static SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) + 1 < n, - sprout::array - >::type init_seed_1(UIntType const& value, Args const&... args) { + sprout::array + >::type init_seed_1(result_type value, Args const&... args) { return init_seed_1( (f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(), args..., value ); } - static SPROUT_CONSTEXPR sprout::array init_seed(UIntType const& value) { + static SPROUT_CONSTEXPR sprout::array init_seed(result_type value = default_seed) { return init_seed_1(value & static_max()); } private: - sprout::array x_; + sprout::array x_; std::size_t i_; private: - SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array const& x, std::size_t i, private_construct_t) + SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array const& x, std::size_t i, private_construct_t) : x_(x) , i_(i) {} - SPROUT_CONSTEXPR UIntType - rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const { + SPROUT_CONSTEXPR result_type + rewind_find_1(result_type const* last, std::size_t size, std::size_t index) const { return index < n - size ? x_[index] : *(last - (n - 1 - index)) ; } - SPROUT_CONSTEXPR UIntType - rewind_find(UIntType const* last, std::size_t size, std::size_t i) const { + SPROUT_CONSTEXPR result_type + rewind_find(result_type const* last, std::size_t size, std::size_t i) const { return rewind_find_1(last, size, (i + n - size + n - 1) % n); } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) == n, - sprout::array + sprout::array >::type - rewind_finish_1(sprout::array const&, Args const&... args) const { - return sprout::array{{args...}}; + rewind_finish_1(sprout::array const&, Args const&... args) const { + return sprout::array{{args...}}; } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) < n, - sprout::array + sprout::array >::type - rewind_finish_1(sprout::array const& data, Args const&... args) const { + rewind_finish_1(sprout::array const& data, Args const&... args) const { return rewind_finish_1(data, args..., data[sizeof...(args)]); } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) == n, - sprout::array + sprout::array >::type rewind_finish( - sprout::array const&, UIntType const*, std::size_t, std::size_t, + sprout::array const&, result_type const*, std::size_t, std::size_t, Args const&... args ) const { - return sprout::array{{args...}}; + return sprout::array{{args...}}; } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) < n, - sprout::array + sprout::array >::type rewind_finish( - sprout::array const& data, UIntType const* last, std::size_t z, std::size_t i, + sprout::array const& data, result_type const* last, std::size_t z, std::size_t i, Args const&... args ) const { @@ -147,22 +147,22 @@ namespace sprout { template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) == n, - sprout::array + sprout::array >::type rewind_4( - sprout::array const&, UIntType const*, std::size_t, UIntType, UIntType, std::size_t, + sprout::array const&, result_type const*, std::size_t, result_type, result_type, std::size_t, Args const&... args ) const { - return sprout::array{{args...}}; + return sprout::array{{args...}}; } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) < n, - sprout::array + sprout::array >::type rewind_4( - sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, + sprout::array const& data, result_type const* last, std::size_t z, result_type y0, result_type y1, std::size_t i, Args const&... args ) const { @@ -174,28 +174,28 @@ namespace sprout { template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) == n, - sprout::array + sprout::array >::type rewind_3( - sprout::array const&, UIntType const*, std::size_t, UIntType, UIntType, std::size_t, + sprout::array const&, result_type const*, std::size_t, result_type, result_type, std::size_t, Args const&... args ) const { - return sprout::array{{args...}}; + return sprout::array{{args...}}; } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) < n, - sprout::array + sprout::array >::type rewind_3( - sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, + sprout::array const& data, result_type const* last, std::size_t z, result_type y0, result_type y1, std::size_t i, Args const&... args ) const { return rewind_4( data, last, z, y0, - y1 & (static_cast(1) << (w - 1)) + y1 & (static_cast(1) << (w - 1)) ? ((y1 ^ a) << 1) | 1 : y1 << 1 , @@ -206,22 +206,22 @@ namespace sprout { template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) == n, - sprout::array + sprout::array >::type rewind_2( - sprout::array const&, UIntType const*, std::size_t, UIntType, std::size_t, + sprout::array const&, result_type const*, std::size_t, result_type, std::size_t, Args const&... args ) const { - return sprout::array{{args...}}; + return sprout::array{{args...}}; } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) < n, - sprout::array + sprout::array >::type rewind_2( - sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, + sprout::array const& data, result_type const* last, std::size_t z, result_type y0, std::size_t i, Args const&... args ) const { @@ -230,25 +230,25 @@ namespace sprout { : rewind_finish(data, last, z, 0, args...) ; } - SPROUT_CONSTEXPR sprout::array - rewind_1(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0) const { + SPROUT_CONSTEXPR sprout::array + rewind_1(sprout::array const& data, result_type const* last, std::size_t z, result_type y0) const { return rewind_2( data, last, z, - y0 & (static_cast(1) << (w - 1)) + y0 & (static_cast(1) << (w - 1)) ? ((y0 ^ a) << 1) | 1 : y0 << 1 , 0 ); } - SPROUT_CONSTEXPR sprout::array - rewind(sprout::array const& data, UIntType const* last, std::size_t z) const { + SPROUT_CONSTEXPR sprout::array + rewind(sprout::array const& data, result_type const* last, std::size_t z) const { return rewind_1(data, last, z, x_[m - 1] ^ x_[n - 1]); } SPROUT_CONSTEXPR bool - equal_impl_2(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { + equal_impl_2(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { return i < offset ? back[i + n - offset] != other.x_[i] ? false @@ -257,7 +257,7 @@ namespace sprout { ; } SPROUT_CONSTEXPR bool - equal_impl_1(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { + equal_impl_1(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { return i + offset < n ? x_[i] != other.x_[i + offset] ? false @@ -267,21 +267,21 @@ namespace sprout { } SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const { - return equal_impl_1(other, sprout::array(), other.i_ - i_); + return equal_impl_1(other, sprout::array(), other.i_ - i_); } - SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const { + SPROUT_CONSTEXPR result_type generate_impl_4(result_type z) const { return z ^ (z >> l); } - SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const { + SPROUT_CONSTEXPR result_type generate_impl_3(result_type z) const { return z ^ generate_impl_4((z << t) & c); } - SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const { + SPROUT_CONSTEXPR result_type generate_impl_2(result_type z) const { return z ^ generate_impl_3((z << s) & b); } - SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const { + SPROUT_CONSTEXPR result_type generate_impl_1(result_type z) const { return z ^ generate_impl_2((z >> u) & d); } - SPROUT_CONSTEXPR UIntType generate_impl() const { + SPROUT_CONSTEXPR result_type generate_impl() const { return generate_impl_1(x_[i_]); } SPROUT_CONSTEXPR sprout::random::random_result generate() const { @@ -297,7 +297,7 @@ namespace sprout { template SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const { return mersenne_twister_engine( - sprout::array{{ + sprout::array{{ args..., x_[m - 1] ^ ((x_[n - 1] & upper_mask) | (x_[0] & lower_mask) >> 1) ^ ((x_[0] & 1) * a) }}, 0, @@ -376,7 +376,7 @@ namespace sprout { : x_(init_seed(default_seed)) , i_(n) {} - explicit SPROUT_CONSTEXPR mersenne_twister_engine(UIntType const& value) + explicit SPROUT_CONSTEXPR mersenne_twister_engine(result_type value) : x_(init_seed(value)) , i_(n) {} @@ -419,7 +419,7 @@ namespace sprout { mersenne_twister_engine const& rhs ) { - sprout::array data; + sprout::array data; for(std::size_t i = 0; i < rhs.i_; ++i) { data[i + n - rhs.i_] = rhs.x_[i]; } @@ -550,7 +550,7 @@ namespace sprout { // mt11213b // typedef sprout::random::mersenne_twister_engine< - std::uint32_t, + std::uint_fast32_t, 32, 351, 175, @@ -569,7 +569,7 @@ namespace sprout { // mt19937 // typedef sprout::random::mersenne_twister_engine< - std::uint32_t, + std::uint_fast32_t, 32, 624, 397, @@ -588,7 +588,7 @@ namespace sprout { // mt19937_64 // typedef sprout::random::mersenne_twister_engine< - std::uint64_t, + std::uint_fast64_t, 64, 312, 156, diff --git a/sprout/random/shuffle_order.hpp b/sprout/random/shuffle_order.hpp index d1923373..c0446338 100644 --- a/sprout/random/shuffle_order.hpp +++ b/sprout/random/shuffle_order.hpp @@ -36,6 +36,13 @@ namespace sprout { base_type rng_; sprout::array v_; result_type y_; + public: + SPROUT_CXX14_CONSTEXPR shuffle_order_engine_member& operator=(shuffle_order_engine_member const& rhs) { + rng_ = rhs.rng_; + v_ = rhs.v_; + y_ = rhs.y_; + return *this; + } }; } // namespace detail // @@ -70,7 +77,7 @@ namespace sprout { private: template static SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == k, + (sizeof...(Args) == k), member_type >::type init_member_1(Random const& rnd, Args const&... args) { return member_type{ @@ -81,7 +88,7 @@ namespace sprout { } template static SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < k, + (sizeof...(Args) < k), member_type >::type init_member_1(Random const& rnd, Args const&... args) { return init_member_1(rnd(), args..., rnd.result()); @@ -97,7 +104,7 @@ namespace sprout { SPROUT_CONSTEXPR shuffle_order_engine( base_type const& rng, sprout::array const& v, - result_type const& y, + result_type y, private_construct_t ) : member_type{rng, v, y} @@ -132,12 +139,42 @@ namespace sprout { SPROUT_CONSTEXPR shuffle_order_engine() : member_type(init_member(base_type())) {} - explicit SPROUT_CONSTEXPR shuffle_order_engine(result_type const& s) - : member_type(init_member(base_type(s))) + explicit SPROUT_CONSTEXPR shuffle_order_engine(result_type seed) + : member_type(init_member(base_type(seed))) + {} + template + explicit SPROUT_CXX14_CONSTEXPR shuffle_order_engine(Sseq& seq) + : member_type(init_member(base_type(seq))) + {} + template + explicit SPROUT_CONSTEXPR shuffle_order_engine(Sseq const& seq) + : member_type(init_member(base_type(seq))) + {} + template + SPROUT_CONSTEXPR shuffle_order_engine(InputIterator first, InputIterator last) + : member_type(init_member(base_type(first, last))) {} explicit SPROUT_CONSTEXPR shuffle_order_engine(base_type const& rng) : member_type(init_member(rng)) {} + SPROUT_CXX14_CONSTEXPR void seed() { + member_type::operator=(init_member(base_type())); + } + SPROUT_CXX14_CONSTEXPR void seed(result_type seed) { + member_type::operator=(init_member(base_type(seed))); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq& seq) { + member_type::operator=(init_member(base_type(seq))); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq const& seq) { + member_type::operator=(init_member(base_type(seq))); + } + template + SPROUT_CXX14_CONSTEXPR void seed(InputIterator first, InputIterator last) { + member_type::operator=(init_member(base_type(first, last))); + } SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT { return rng_.min(); } @@ -209,12 +246,10 @@ namespace sprout { // // knuth_b - // - typedef sprout::random::shuffle_order_engine knuth_b; - // // kreutzer1986 // - typedef sprout::random::shuffle_order_engine, 97> kreutzer1986; + typedef sprout::random::shuffle_order_engine knuth_b; + typedef sprout::random::shuffle_order_engine, 97> kreutzer1986; } // namespace random using sprout::random::shuffle_order_engine; diff --git a/sprout/random/taus88.hpp b/sprout/random/taus88.hpp index aa96dcff..45b2f4e7 100644 --- a/sprout/random/taus88.hpp +++ b/sprout/random/taus88.hpp @@ -20,13 +20,13 @@ namespace sprout { // typedef sprout::random::xor_combine_engine< sprout::random::xor_combine_engine< - sprout::random::linear_feedback_shift_engine, + sprout::random::linear_feedback_shift_engine, 0, - sprout::random::linear_feedback_shift_engine, + sprout::random::linear_feedback_shift_engine, 0 >, 0, - sprout::random::linear_feedback_shift_engine, + sprout::random::linear_feedback_shift_engine, 0 > taus88; } // namespace random diff --git a/sprout/random/xor_combine.hpp b/sprout/random/xor_combine.hpp index e5dcf165..d863302a 100644 --- a/sprout/random/xor_combine.hpp +++ b/sprout/random/xor_combine.hpp @@ -46,24 +46,62 @@ namespace sprout { return sprout::random::random_result( (rnd1.result() << s1) ^ (rnd2.result() << s2), xor_combine_engine( - rnd1.engine(), - rnd2.engine() + rnd1.engine(), rnd2.engine() ) ); } public: SPROUT_CONSTEXPR xor_combine_engine() - : rng1_() - , rng2_() + : rng1_(), rng2_() {} - explicit SPROUT_CONSTEXPR xor_combine_engine(result_type const& seed) - : rng1_(seed) - , rng2_(seed) + explicit SPROUT_CONSTEXPR xor_combine_engine(result_type seed) + : rng1_(seed), rng2_(seed) + {} + template + explicit SPROUT_CXX14_CONSTEXPR xor_combine_engine(Sseq& seq) + : rng1_(seq), rng2_(seq) + {} + template + explicit SPROUT_CONSTEXPR xor_combine_engine(Sseq const& seq) + : rng1_(seq), rng2_(seq) + {} + template + SPROUT_CONSTEXPR xor_combine_engine(ForwardIterator first, ForwardIterator last) + : rng1_(first, last), rng2_(first, last) + {} + SPROUT_CONSTEXPR xor_combine_engine(typename base1_type::result_type seed1, typename base2_type::result_type seed2) + : rng1_(seed1), rng2_(seed2) {} SPROUT_CONSTEXPR xor_combine_engine(base1_type const& rng1, base2_type const& rng2) - : rng1_(rng1) - , rng2_(rng2) + : rng1_(rng1), rng2_(rng2) {} + SPROUT_CXX14_CONSTEXPR void seed() { + rng1_.seed(); + rng2_.seed(); + } + SPROUT_CXX14_CONSTEXPR void seed(result_type seed) { + rng1_.seed(seed); + rng2_.seed(seed); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq& seq) { + rng1_.seed(seq); + rng2_.seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(Sseq const& seq) { + rng1_.seed(seq); + rng2_.seed(seq); + } + template + SPROUT_CXX14_CONSTEXPR void seed(ForwardIterator first, ForwardIterator last) { + rng1_.seed(first, last); + rng2_.seed(first, last); + } + SPROUT_CXX14_CONSTEXPR void seed(typename base1_type::result_type seed1, typename base2_type::result_type seed2) { + rng1_.seed(seed1); + rng2_.seed(seed2); + } SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT { return NS_SSCRISK_CEL_OR_SPROUT::min(rng1_.min(), rng2_.min()); }