32 #ifndef VSMC_RNG_SEED_HPP 33 #define VSMC_RNG_SEED_HPP 38 #define VSMC_STATIC_ASSERT_RNG_SEED_GENERATOR_RESULT_TYPE(T) \ 39 VSMC_STATIC_ASSERT((std::is_unsigned<T>::value), \ 40 "**SeedGenerator** USED WITH ResultType NOT AN UNSIGNED INTEGER") 42 #define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem) \ 43 VSMC_RUNTIME_ASSERT((div > rem), \ 44 "**SeedGenerator::modulo** " \ 45 "REMAINDER IS NOT SMALLER THAN THE DIVISOR") 47 #define VSMC_RUNTIME_WARNING_RNG_SEED_GENERATOR_MODULO(div, rem) \ 48 VSMC_RUNTIME_WARNING((div == 1 && rem == 0), \ 49 "**SeedGenerator::modulo** " \ 50 "COUNTER TYPE SEED DOES NOT SUPPORT MODULO") 52 #define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(seed_max) \ 53 VSMC_RUNTIME_ASSERT((seed_max > 1), \ 54 "**SeedGenerator::modulo** " \ 55 "THE MAXIMUM OF THE INTERNAL SEED IS NO LARGER THAN 1") 59 #ifndef VSMC_SEED_RESULT_TYPE 60 #define VSMC_SEED_RESULT_TYPE unsigned 88 template <
typename ID,
typename ResultType = VSMC_SEED_RESULT_TYPE>
108 template <
typename RNGType>
122 return seed_ * divisor_ + remainder_;
154 seed_max_ = std::numeric_limits<skip_type>::max
VSMC_MNE();
155 seed_max_ -= seed_max_ % divisor_;
156 seed_max_ /= divisor_;
168 seed_ = incr <= diff ? (seed_ + incr) : (incr - diff);
174 if (seed_ < seed_max_)
180 template <
typename CharT,
typename Traits>
182 std::basic_ostream<CharT, Traits> &os,
188 os << sg.seed_ <<
' ';
189 os << sg.divisor_ <<
' ';
195 template <
typename CharT,
typename Traits>
197 std::basic_istream<CharT, Traits> &is,
207 is >> std::ws >>
div;
208 is >> std::ws >> rem;
219 std::atomic<result_type> seed_;
224 SeedGenerator() : seed_(0), seed_max_(0), divisor_(1), remainder_(0)
228 modulo(divisor_, remainder_);
252 template <
typename ID,
typename T, std::
size_t K>
277 template <
typename RNGType>
280 seed_rng_dispatch(rng,
281 std::integral_constant<
bool,
288 std::lock_guard<std::mutex> lock_(mtx_);
298 for (std::size_t k = 0; k != K; ++k)
302 return std::get<0>(s2);
327 seed_max_.fill(std::numeric_limits<skip_type>::max
VSMC_MNE());
336 template <
typename CharT,
typename Traits>
338 std::basic_ostream<CharT, Traits> &os,
344 os << sg.seed_ <<
' ';
345 os << sg.divisor_ <<
' ';
346 os << sg.remainder_ <<
' ';
351 template <
typename CharT,
typename Traits>
353 std::basic_istream<CharT, Traits> &is,
363 is >> std::ws >>
div;
364 is >> std::ws >> rem;
387 modulo(divisor_, remainder_);
390 template <
typename RNGType>
391 void seed_rng_dispatch(RNGType &rng, std::true_type)
396 template <
typename RNGType>
397 void seed_rng_dispatch(RNGType &rng, std::false_type)
409 #endif // VSMC_RNG_SEED_HPP static SeedGenerator< ID, ResultType > & instance()
std::array< T, K > result_type
skip_type remainder() const
void skip(skip_type steps)
Skip the internal seed by a given steps.
void increment(std::array< T, K > &ctr)
Increment a counter by one.
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, SeedGenerator< ID, ResultType > &sg)
void set(result_type seed)
Set the internal seed.
void seed_rng(RNGType &rng)
Equivalent to rng.seed(get())
skip_type divisor() const
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, SeedGenerator< ID, std::array< T, K >> &sg)
result_type seed_max() const
The maximum of the internal seed integer.
SeedGenerator< ID, ResultType > & operator=(const SeedGenerator< ID, ResultType > &)=delete
typename KeyTypeTrait< T >::type KeyType
skip_type divisor() const
The divisor of the output seed.
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const SeedGenerator< ID, std::array< T, K >> &sg)
skip_type remainder() const
The remainder of the output seed.
#define VSMC_RUNTIME_WARNING_RNG_SEED_GENERATOR_MODULO(div, rem)
#define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem)
result_type seed_max() const
void div(std::size_t n, const float *a, const float *b, float *y)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const SeedGenerator< ID, ResultType > &sg)
#define VSMC_STATIC_ASSERT_RNG_SEED_GENERATOR_RESULT_TYPE(T)
result_type seed() const
The current internal seed.
void skip(skip_type steps)
void modulo(skip_type div, skip_type rem)
Set the divisor and the remainder.
static SeedGenerator< ID, std::array< T, K > > & instance()
void seed_rng(RNGType &rng)
Equivalent to rng.seed(get()) or rng.seed(std::get<0>(get())).
#define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(seed_max)
void modulo(skip_type div, skip_type rem)
void skip()
Skip the internal seed by 1 step.