1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2024-11-12 21:09:01 +00:00

add C++14 constexpr version: random generator

This commit is contained in:
bolero-MURAKAMI 2013-11-05 17:39:11 +09:00
parent 2c9f0647f4
commit 230630b45b
6 changed files with 44 additions and 2 deletions

View file

@ -82,6 +82,14 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT {
return base1_type::modulus - 1; return base1_type::modulus - 1;
} }
SPROUT_CXX14_CONSTEXPR result_type operator()() {
result_type val1 = static_cast<result_type>(mlcg1_());
result_type val2 = static_cast<result_type>(mlcg2_());
return val2 < val1
? val1 - val2
: val1 - val2 + base1_type::modulus - 1
;
}
SPROUT_CONSTEXPR sprout::random::random_result<additive_combine_engine> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<additive_combine_engine> const operator()() const {
return generate(mlcg1_(), mlcg2_()); return generate(mlcg1_(), mlcg2_());
} }

View file

@ -79,6 +79,11 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT {
return static_max(); return static_max();
} }
SPROUT_CXX14_CONSTEXPR result_type operator()() {
typedef sprout::random::detail::const_mod<IntType, p> do_mod;
x_ = do_mod::mult_add(a, do_mod::invert(x_), b);
return x_;
}
SPROUT_CONSTEXPR sprout::random::random_result<inversive_congruential_engine> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<inversive_congruential_engine> const operator()() const {
typedef sprout::random::detail::const_mod<IntType, p> do_mod; typedef sprout::random::detail::const_mod<IntType, p> do_mod;
return generate(do_mod::mult_add(a, do_mod::invert(x_), b)); return generate(do_mod::mult_add(a, do_mod::invert(x_), b));

View file

@ -82,6 +82,10 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT {
return static_max(); return static_max();
} }
SPROUT_CXX14_CONSTEXPR result_type operator()() {
x_ = sprout::random::detail::const_mod<UIntType, m>::mult_add(a, x_, c);
return x_;
}
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> const operator()() const {
return generate(sprout::random::detail::const_mod<UIntType, m>::mult_add(a, x_, c)); return generate(sprout::random::detail::const_mod<UIntType, m>::mult_add(a, x_, c));
} }
@ -167,7 +171,7 @@ namespace sprout {
template<typename LcfResult> template<typename LcfResult>
SPROUT_CONSTEXPR sprout::random::random_result<rand48> generate(LcfResult const& lcf_result) const { SPROUT_CONSTEXPR sprout::random::random_result<rand48> generate(LcfResult const& lcf_result) const {
return sprout::random::random_result<rand48>( return sprout::random::random_result<rand48>(
lcf_result.result() >> 17, static_cast<result_type>(lcf_result.result()) >> 17,
rand48(lcf_result.engine(), private_construct_t()) rand48(lcf_result.engine(), private_construct_t())
); );
} }
@ -184,6 +188,9 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return static_max(); return static_max();
} }
SPROUT_CXX14_CONSTEXPR result_type operator()() {
return static_cast<result_type>(static_cast<result_type>(lcf_()) >> 17);
}
SPROUT_CONSTEXPR sprout::random::random_result<rand48> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<rand48> const operator()() const {
return generate(lcf_()); return generate(lcf_());
} }

View file

@ -78,6 +78,10 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT {
return static_max(); 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<linear_feedback_shift_engine> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<linear_feedback_shift_engine> const operator()() const {
return generate(((x_ & ((wordmask() << (w - k)) & wordmask())) << s) ^ ((((x_ << q) ^ x_) & wordmask()) >> (k - s))); return generate(((x_ & ((wordmask() << (w - k)) & wordmask())) << s) ^ ((((x_ << q) ^ x_) & wordmask()) >> (k - s)));
} }

View file

@ -124,7 +124,7 @@ namespace sprout {
: sprout::math::less(brange, sprout::numeric_limits<BaseUnsigned>::max() / k) ? BaseUnsigned(k * off / (brange + 1)) : sprout::math::less(brange, sprout::numeric_limits<BaseUnsigned>::max() / k) ? BaseUnsigned(k * off / (brange + 1))
: sprout::math::less(brange, sprout::numeric_limits<std::uintmax_t>::max() / k) : sprout::math::less(brange, sprout::numeric_limits<std::uintmax_t>::max() / k)
? static_cast<BaseUnsigned>(static_cast<std::uintmax_t>(off) * k / (static_cast<std::uintmax_t>(brange) + 1)) ? static_cast<BaseUnsigned>(static_cast<std::uintmax_t>(off) * k / (static_cast<std::uintmax_t>(brange) + 1))
//: static_cast<BaseUnsigned>(sprout::random::detail::muldiv(off, k, static_cast<std::uintmax_t>(brange) + 1)) // ??? // : static_cast<BaseUnsigned>(sprout::random::detail::muldiv(off, k, static_cast<std::uintmax_t>(brange) + 1)) // ???
: (SPROUT_ASSERT_MSG(0, "Sorry, not implemented."), sprout::random::random_result<shuffle_order_engine>()) : (SPROUT_ASSERT_MSG(0, "Sorry, not implemented."), sprout::random::random_result<shuffle_order_engine>())
); );
} }
@ -144,6 +144,21 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT {
return rng_.max(); return rng_.max();
} }
SPROUT_CXX14_CONSTEXPR result_type operator()() {
typedef typename std::make_unsigned<result_type>::type base_unsigned;
base_unsigned const brange = sprout::random::detail::subtract<result_type>()(max(), min());
base_unsigned const off = sprout::random::detail::subtract<result_type>()(y_, min());
base_unsigned j = k == 1 ? base_unsigned(0)
: sprout::math::less(brange, sprout::numeric_limits<base_unsigned>::max() / k) ? base_unsigned(k * off / (brange + 1))
: sprout::math::less(brange, sprout::numeric_limits<std::uintmax_t>::max() / k)
? static_cast<base_unsigned>(static_cast<std::uintmax_t>(off) * k / (static_cast<std::uintmax_t>(brange) + 1))
// : static_cast<base_unsigned>(sprout::random::detail::muldiv(off, k, static_cast<std::uintmax_t>(brange) + 1)) // ???
: (SPROUT_ASSERT_MSG(0, "Sorry, not implemented."), base_unsigned(0))
;
y_ = v_[j];
v_[j] = static_cast<result_type>(rng_());
return y_;
}
SPROUT_CONSTEXPR sprout::random::random_result<shuffle_order_engine> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<shuffle_order_engine> const operator()() const {
typedef typename std::make_unsigned<result_type>::type base_unsigned; typedef typename std::make_unsigned<result_type>::type base_unsigned;
return generate( return generate(

View file

@ -70,6 +70,9 @@ namespace sprout {
SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR result_type max() const SPROUT_NOEXCEPT {
return NS_SSCRISK_CEL_OR_SPROUT::max(rng1_.max(), rng2_.max()); return NS_SSCRISK_CEL_OR_SPROUT::max(rng1_.max(), rng2_.max());
} }
SPROUT_CXX14_CONSTEXPR result_type operator()() {
return (static_cast<result_type>(rng1_()) << s1) ^ (static_cast<result_type>(rng2_()) << s2);
}
SPROUT_CONSTEXPR sprout::random::random_result<xor_combine_engine> const operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<xor_combine_engine> const operator()() const {
return generate(rng1_(), rng2_()); return generate(rng1_(), rng2_());
} }