32 #ifndef VSMC_RNG_SEED_HPP 33 #define VSMC_RNG_SEED_HPP 38 #define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem) \ 39 VSMC_RUNTIME_ASSERT((div > rem), \ 40 "**SeedGenerator::modulo** " \ 41 "REMAINDER IS NOT SMALLER THAN THE DIVISOR") 43 #define VSMC_RUNTIME_WARNING_RNG_SEED_GENERATOR_MODULO(div, rem) \ 44 VSMC_RUNTIME_WARNING((div == 1 && rem == 0), \ 45 "**SeedGenerator::modulo** " \ 46 "COUNTER TYPE SEED DOES NOT SUPPORT MODULO") 48 #define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(seed_max) \ 49 VSMC_RUNTIME_ASSERT((seed_max > 1), \ 50 "**SeedGenerator::modulo** " \ 51 "THE MAXIMUM OF THE INTERNAL SEED IS NO LARGER THAN 1") 55 #ifndef VSMC_SEED_RESULT_TYPE 56 #define VSMC_SEED_RESULT_TYPE unsigned 84 template <
typename ID,
typename ResultType = VSMC_SEED_RESULT_TYPE>
87 static_assert(std::is_unsigned<ResultType>::value,
88 "**SeedGenerator** USED WITH ResultType OTHER THAN UNSIGEND INTEGER " 108 template <
typename RNGType>
122 return seed_ * divisor_ + remainder_;
154 seed_max_ = std::numeric_limits<skip_type>::max();
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)
226 modulo(divisor_, remainder_);
250 template <
typename ID,
typename ResultType, std::
size_t K>
253 static_assert(std::is_unsigned<ResultType>::value,
254 "**SeedGenerator** USED WITH ResultType OTHER THAN UNSIGEND INTEGER " 262 const SeedGenerator<ID, std::array<ResultType, K>> &) =
delete;
265 const SeedGenerator<ID, std::array<ResultType, K>> &) =
delete;
280 template <
typename RNGType>
283 seed_rng_dispatch(rng,
284 std::integral_constant<
bool,
291 std::lock_guard<std::mutex> lock_(mtx_);
301 for (std::size_t k = 0; k != K; ++k)
305 return std::get<0>(s2);
308 void set(ResultType s)
330 seed_max_.fill(std::numeric_limits<skip_type>::max());
339 template <
typename CharT,
typename Traits>
341 std::basic_ostream<CharT, Traits> &os,
347 os << sg.seed_ <<
' ';
348 os << sg.divisor_ <<
' ';
349 os << sg.remainder_ <<
' ';
354 template <
typename CharT,
typename Traits>
356 std::basic_istream<CharT, Traits> &is,
366 is >> std::ws >>
div;
367 is >> std::ws >> rem;
388 modulo(divisor_, remainder_);
391 template <
typename RNGType>
392 void seed_rng_dispatch(RNGType &rng, std::true_type)
397 template <
typename RNGType>
398 void seed_rng_dispatch(RNGType &rng, std::false_type)
410 #endif // VSMC_RNG_SEED_HPP
static SeedGenerator< ID, ResultType > & instance()
result_type seed_max() 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 remainder() const
result_type seed_max() const
The maximum of the internal seed integer.
static SeedGenerator< ID, std::array< ResultType, K > > & instance()
SeedGenerator< ID, ResultType > & operator=(const SeedGenerator< ID, ResultType > &)=delete
typename KeyTypeTrait< T >::type KeyType
skip_type divisor() const
The divisor of the output seed.
skip_type divisor() const
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const SeedGenerator< ID, std::array< ResultType, K >> &sg)
skip_type remainder() const
The remainder of the output seed.
#define VSMC_RUNTIME_WARNING_RNG_SEED_GENERATOR_MODULO(div, rem)
void modulo(skip_type div, skip_type rem)
#define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, SeedGenerator< ID, std::array< ResultType, K >> &sg)
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)
result_type seed() const
The current internal seed.
void modulo(skip_type div, skip_type rem)
Set the divisor and the remainder.
void skip(skip_type steps)
#define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(seed_max)
void seed_rng(RNGType &rng)
Equivalent to rng.seed(get()) or rng.seed(std::get<0>(get())).
void skip()
Skip the internal seed by 1 step.
std::array< ResultType, K > result_type