From 230630b45b88977e891cefa6029d021f4aa9e6bb Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 5 Nov 2013 17:39:11 +0900 Subject: [PATCH] add C++14 constexpr version: random generator --- sprout/random/additive_combine.hpp | 8 ++++++++ sprout/random/inversive_congruential.hpp | 5 +++++ sprout/random/linear_congruential.hpp | 9 ++++++++- sprout/random/linear_feedback_shift.hpp | 4 ++++ sprout/random/shuffle_order.hpp | 17 ++++++++++++++++- sprout/random/xor_combine.hpp | 3 +++ 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/sprout/random/additive_combine.hpp b/sprout/random/additive_combine.hpp index ac411b87..cb4b21d2 100644 --- a/sprout/random/additive_combine.hpp +++ b/sprout/random/additive_combine.hpp @@ -82,6 +82,14 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { return base1_type::modulus - 1; } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + result_type val1 = static_cast(mlcg1_()); + result_type val2 = static_cast(mlcg2_()); + return val2 < val1 + ? val1 - val2 + : val1 - val2 + base1_type::modulus - 1 + ; + } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { return generate(mlcg1_(), mlcg2_()); } diff --git a/sprout/random/inversive_congruential.hpp b/sprout/random/inversive_congruential.hpp index 8699acce..b8ee8825 100644 --- a/sprout/random/inversive_congruential.hpp +++ b/sprout/random/inversive_congruential.hpp @@ -79,6 +79,11 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { return static_max(); } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + 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; return generate(do_mod::mult_add(a, do_mod::invert(x_), b)); diff --git a/sprout/random/linear_congruential.hpp b/sprout/random/linear_congruential.hpp index 07d7ea1f..338fb383 100644 --- a/sprout/random/linear_congruential.hpp +++ b/sprout/random/linear_congruential.hpp @@ -82,6 +82,10 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { return static_max(); } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + 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)); } @@ -167,7 +171,7 @@ namespace sprout { template SPROUT_CONSTEXPR sprout::random::random_result generate(LcfResult const& lcf_result) const { return sprout::random::random_result( - lcf_result.result() >> 17, + static_cast(lcf_result.result()) >> 17, rand48(lcf_result.engine(), private_construct_t()) ); } @@ -184,6 +188,9 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const { return static_max(); } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + return static_cast(static_cast(lcf_()) >> 17); + } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { return generate(lcf_()); } diff --git a/sprout/random/linear_feedback_shift.hpp b/sprout/random/linear_feedback_shift.hpp index 67657b19..599d6d95 100644 --- a/sprout/random/linear_feedback_shift.hpp +++ b/sprout/random/linear_feedback_shift.hpp @@ -78,6 +78,10 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { return static_max(); } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + x_ = ((x_ & ((wordmask() << (w - k)) & wordmask())) << s) ^ ((((x_ << q) ^ x_) & wordmask()) >> (k - s)); + return x_; + } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { return generate(((x_ & ((wordmask() << (w - k)) & wordmask())) << s) ^ ((((x_ << q) ^ x_) & wordmask()) >> (k - s))); } diff --git a/sprout/random/shuffle_order.hpp b/sprout/random/shuffle_order.hpp index 58165774..d1923373 100644 --- a/sprout/random/shuffle_order.hpp +++ b/sprout/random/shuffle_order.hpp @@ -124,7 +124,7 @@ namespace sprout { : sprout::math::less(brange, sprout::numeric_limits::max() / k) ? BaseUnsigned(k * off / (brange + 1)) : sprout::math::less(brange, sprout::numeric_limits::max() / k) ? static_cast(static_cast(off) * k / (static_cast(brange) + 1)) - //: static_cast(sprout::random::detail::muldiv(off, k, static_cast(brange) + 1)) // ??? +// : static_cast(sprout::random::detail::muldiv(off, k, static_cast(brange) + 1)) // ??? : (SPROUT_ASSERT_MSG(0, "Sorry, not implemented."), sprout::random::random_result()) ); } @@ -144,6 +144,21 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { return rng_.max(); } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + typedef typename std::make_unsigned::type base_unsigned; + base_unsigned const brange = sprout::random::detail::subtract()(max(), min()); + base_unsigned const off = sprout::random::detail::subtract()(y_, min()); + base_unsigned j = k == 1 ? base_unsigned(0) + : sprout::math::less(brange, sprout::numeric_limits::max() / k) ? base_unsigned(k * off / (brange + 1)) + : sprout::math::less(brange, sprout::numeric_limits::max() / k) + ? static_cast(static_cast(off) * k / (static_cast(brange) + 1)) +// : static_cast(sprout::random::detail::muldiv(off, k, static_cast(brange) + 1)) // ??? + : (SPROUT_ASSERT_MSG(0, "Sorry, not implemented."), base_unsigned(0)) + ; + y_ = v_[j]; + v_[j] = static_cast(rng_()); + return y_; + } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { typedef typename std::make_unsigned::type base_unsigned; return generate( diff --git a/sprout/random/xor_combine.hpp b/sprout/random/xor_combine.hpp index b678474f..e5dcf165 100644 --- a/sprout/random/xor_combine.hpp +++ b/sprout/random/xor_combine.hpp @@ -70,6 +70,9 @@ namespace sprout { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { return NS_SSCRISK_CEL_OR_SPROUT::max(rng1_.max(), rng2_.max()); } + SPROUT_CXX14_CONSTEXPR result_type operator()() { + return (static_cast(rng1_()) << s1) ^ (static_cast(rng2_()) << s2); + } SPROUT_CONSTEXPR sprout::random::random_result const operator()() const { return generate(rng1_(), rng2_()); }