32 #ifndef VSMC_RNG_XORSHIFT_HPP
33 #define VSMC_RNG_XORSHIFT_HPP
37 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_ORDER(K) \
38 VSMC_STATIC_ASSERT((K != 0), USE_XorshiftEngine_WITH_ORDER_EUQAL_TO_ZERO)
40 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_UNSIGNED(ResultType) \
41 VSMC_STATIC_ASSERT((cxx11::is_unsigned<ResultType>::value), \
42 USE_XorshiftEngine_WITH_A_ResultType_NOT_AN_UNSIGNED_INTEGER_TYPE)
44 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_UINT_SIZE(ResultType) \
45 VSMC_STATIC_ASSERT((sizeof(ResultType) >= sizeof(uint32_t)), \
46 USE_XorshiftEngine_WITH_A_ResultType_SMALLER_THAN_32_BITS)
48 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_INDEX(I, K) \
49 VSMC_STATIC_ASSERT((I != 0 || K == 1), \
50 USE_XorshiftEngine_WITH_INDEX_##I##_EQUAL_TO_ZERO)
52 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_INDEX_ORDER(R, S, K) \
53 VSMC_STATIC_ASSERT((R > S || K == 1), \
54 USE_XorshiftEngine_WITH_INDEX_##R##_NOT_LARGER_THAN_##S)
56 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS(A) \
57 VSMC_STATIC_ASSERT((A != 0), \
58 USE_XorshiftEngine_WITH_SHIFT_BITS_##A##_EQUAL_TO_ZERO);
60 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS_C(C, K) \
61 VSMC_STATIC_ASSERT((C != 0 || K != 1), \
62 USE_XorshiftEngine_WITH_SHIFT_BITS_##C##_EQUAL_TO_ZERO);
64 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS_D(D, K) \
65 VSMC_STATIC_ASSERT((D != 0 || K == 1), \
66 USE_XorshiftEngine_WITH_SHIFT_BITS_##A##_EQUAL_TO_ZERO);
68 #define VSMC_STATIC_ASSERT_RNG_XORSHIFT \
69 VSMC_STATIC_ASSERT_RNG_XORSHIFT_ORDER(K); \
70 VSMC_STATIC_ASSERT_RNG_XORSHIFT_UNSIGNED(ResultType); \
71 VSMC_STATIC_ASSERT_RNG_XORSHIFT_UINT_SIZE(ResultType); \
72 VSMC_STATIC_ASSERT_RNG_XORSHIFT_INDEX(R, K); \
73 VSMC_STATIC_ASSERT_RNG_XORSHIFT_INDEX(S, K); \
74 VSMC_STATIC_ASSERT_RNG_XORSHIFT_INDEX_ORDER(R, S, K); \
75 VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS(A); \
76 VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS(B); \
77 VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS_C(C, K); \
78 VSMC_STATIC_ASSERT_RNG_XORSHIFT_SHIFT_BITS_D(D, K);
86 template <
typename ResultType>
113 template <
bool,
typename ResultType,
unsigned>
115 {
static ResultType
shift (ResultType x) {
return x;}};
117 template <
typename ResultType,
unsigned A>
119 {
static ResultType
shift (ResultType x) {
return x^(x<<A);}};
121 template <
bool,
typename ResultType,
unsigned>
123 {
static ResultType
shift (ResultType x) {
return x;}};
125 template <
typename ResultType,
unsigned A>
127 {
static ResultType
shift (ResultType x) {
return x^(x>>A);}};
129 template <
typename ResultType, std::size_t K, std::size_t R, std::size_t
S,
131 (K <= traits::XorshiftEngineTrait<ResultType>::max_loop_unroll)>
141 {rng_array_left_shift<K, 1, false>(state);}
144 template <
typename ResultType, std::
size_t K, std::
size_t R, std::
size_t S>
151 std::size_t
r () {
return (K - R + iter_) % K;}
152 std::size_t
s () {
return (K - S + iter_) % K;}
153 std::size_t
k () {
return (K - 1 + iter_) % K;}
156 {iter_ = (iter_ + 1) % K;}
163 template <
unsigned A,
unsigned B,
unsigned C, unsigned,
164 typename ResultType, std::size_t R, std::size_t S>
172 return state.
front();
175 template <
unsigned A,
unsigned B,
unsigned C,
unsigned D,
176 typename ResultType, std::size_t K, std::size_t R, std::size_t S>
180 ResultType xr = state[index.
r()];
184 ResultType xs = state[index.
s()];
190 return state[index.
k()] = xs^xr;
211 template <
typename ResultType, std::size_t K,
212 unsigned A,
unsigned B,
unsigned C,
unsigned D,
213 std::size_t R, std::size_t
S>
228 template <
typename SeedSeq>
242 seed.
front() =
static_cast<uint32_t
>(s % uint32_t_max_);
244 for (std::size_t i = 0; i != K; ++i)
245 state_[i] = internal::xorshift<13, 17, 5, 0>(seed, index);
249 template <
typename SeedSeq>
256 seq.generate(state_.
begin(), state_.
end());
261 {
return internal::xorshift<A, B, C, D>(state_, index_);}
265 for (std::size_t i = 0; i != nskip; ++i)
271 ~(
static_cast<result_type
>(0)));
279 {
return eng1.state_ == eng2.state_;}
284 {
return !(eng1 == eng2);}
286 template <
typename CharT,
typename Traits>
287 friend inline std::basic_ostream<CharT, Traits> &
operator<< (
288 std::basic_ostream<CharT, Traits> &os,
299 template <
typename CharT,
typename Traits>
300 friend inline std::basic_istream<CharT, Traits> &
operator>> (
301 std::basic_istream<CharT, Traits> &is,
308 is >> std::ws >> tmp;
311 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
327 static_cast<result_type
>(
static_cast<uint32_t
>(
328 ~(
static_cast<uint32_t
>(0))));
336 template <
typename Eng,
337 typename Eng::result_type D = 362437,
338 typename Eng::result_type DInit = 6615241>
348 template <
typename SeedSeq>
360 template <
typename SeedSeq>
371 {
return eng_() + (weyl_ += D);}
381 ~(
static_cast<result_type
>(0)));
389 {
return eng1.eng_ == eng2.eng_ && eng1.weyl_ == eng2.weyl_;}
394 {
return !(eng1 == eng2);}
396 template <
typename CharT,
typename Traits>
397 friend inline std::basic_ostream<CharT, Traits> &
operator<< (
398 std::basic_ostream<CharT, Traits> &os,
404 os << eng.eng_ <<
' ' << eng.weyl_;
409 template <
typename CharT,
typename Traits>
410 friend inline std::basic_istream<CharT, Traits> &
operator>> (
411 std::basic_istream<CharT, Traits> &is,
418 result_type weyl_tmp = 0;
419 is >> std::ws >> eng_tmp;
420 is >> std::ws >> weyl_tmp;
423 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
428 eng.weyl_ = weyl_tmp;
578 #endif // VSMC_RNG_XORSHIFT_HPP
XorshiftEngine< uint32_t, 4, 15, 14, 12, 17, 4, 3 > Xorshift4x32
Xorshift RNG engine generating 32-bits integers.
static constexpr const result_type _Min
friend bool operator==(const XorshiftEngine< ResultType, K, A, B, C, D, R, S > &eng1, const XorshiftEngine< ResultType, K, A, B, C, D, R, S > &eng2)
static ResultType shift(ResultType x)
Xorshift128x32 Xorshift
The default 32-bits Xorshift RNG engine.
static constexpr const std::size_t max_loop_unroll
Maximum number of states (e.g., 4 in Xorshift4x64) that an unrolled loop will be used.
void discard(std::size_t nskip)
XorshiftEngine< uint32_t, 2, 17, 14, 12, 19, 2, 1 > Xorshift2x32
Xorshift RNG engine generating 32-bits integers.
XorwowEngine< Xorshift4x32 > Xorwow4x32
Xorwow RNG engine using Xorshfit 32-bits integers.
XorshiftEngine< uint64_t, 1, 13, 7, 17, 0, 0, 0 > Xorshift1x64
Xorshift RNG engine generating 64-bits integers.
#define VSMC_CONSTEXPR
constexpr
XorwowEngine< Xorshift8x32 > Xorwow8x32
Xorwow RNG engine using Xorshfit 32-bits integers.
XorshiftEngine< uint32_t, 64, 19, 12, 14, 15, 64, 59 > Xorshift64x32
Xorshift RNG engine generating 32-bits integers.
XorshiftEngine< uint32_t, 1, 13, 17, 5, 0, 0, 0 > Xorshift1x32
Xorshift RNG engine generating 32-bits integers.
static constexpr const result_type _Max
XorwowEngine< Xorshift2x64 > Xorwow2x64
Xorwow RNG engine using Xorshfit 64-bits integers.
XorshiftEngine< uint64_t, 2, 33, 31, 28, 29, 2, 1 > Xorshift2x64
Xorshift RNG engine generating 64-bits integers.
static constexpr std::size_t r()
XorwowEngine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, XorwowEngine< Eng, D, DInit > >::value >::type *=nullptr)
XorwowEngine< Xorshift8x64 > Xorwow8x64
Xorwow RNG engine using Xorshfit 64-bits integers.
XorwowEngine< Xorshift16x32 > Xorwow16x32
Xorwow RNG engine using Xorshfit 32-bits integers.
static void shift(Array< ResultType, K > &state)
friend bool operator!=(const XorshiftEngine< ResultType, K, A, B, C, D, R, S > &eng1, const XorshiftEngine< ResultType, K, A, B, C, D, R, S > &eng2)
XorwowEngine< Xorshift1x32 > Xorwow1x32
Xorwow RNG engine using Xorshfit 32-bits integers.
XorshiftEngine(result_type s=1)
ResultType xorshift(Array< ResultType, 1 > &state, XorshiftIndex< ResultType, 1, R, S > &)
XorshiftEngine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, XorshiftEngine< ResultType, K, A, B, C, D, R, S > >::value >::type *=nullptr)
XorwowEngine< Xorshift32x32 > Xorwow32x32
Xorwow RNG engine using Xorshfit 32-bits integers.
Xorwow128x32 Xorwow
The default 32-bits Xorwow RNG engine.
XorshiftEngine< uint32_t, 16, 17, 15, 13, 14, 16, 1 > Xorshift16x32
Xorshift RNG engine generating 32-bits integers.
XorshiftEngine< uint32_t, 32, 19, 11, 13, 16, 32, 15 > Xorshift32x32
Xorshift RNG engine generating 32-bits integers.
XorshiftEngine< uint64_t, 4, 37, 27, 29, 33, 4, 3 > Xorshift4x64
Xorshift RNG engine generating 64-bits integers.
Xorshift64x64 Xorshift_64
The default 64-bits Xorshift RNG engine.
static constexpr std::size_t s()
XorwowEngine< Xorshift32x64 > Xorwow32x64
Xorwow RNG engine using Xorshfit 64-bits integers.
static constexpr result_type min()
static constexpr const result_type _Max
XorwowEngine(result_type s=1)
void seed(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, XorshiftEngine< ResultType, K, A, B, C, D, R, S > >::value >::type *=nullptr)
static constexpr const result_type _Min
friend bool operator!=(const XorwowEngine< Eng, D, DInit > &eng1, const XorwowEngine< Eng, D, DInit > &eng2)
void shift(Array< ResultType, K > &)
XorwowEngine< Xorshift16x64 > Xorwow16x64
Xorwow RNG engine using Xorshfit 64-bits integers.
XorwowEngine< Xorshift4x64 > Xorwow4x64
Xorwow RNG engine using Xorshfit 64-bits integers.
XorshiftEngine< uint32_t, 128, 17, 12, 13, 15, 128, 95 > Xorshift128x32
Xorshift RNG engine generating 32-bits integers.
void discard(std::size_t nskip)
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, XorshiftEngine< ResultType, K, A, B, C, D, R, S > &eng)
static constexpr std::size_t k()
XorshiftEngine< uint64_t, 32, 35, 27, 26, 37, 32, 1 > Xorshift32x64
Xorshift RNG engine generating 64-bits integers.
XorshiftEngine< uint64_t, 64, 33, 26, 27, 29, 64, 53 > Xorshift64x64
Xorshift RNG engine generating 64-bits integers.
static constexpr result_type max()
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const XorshiftEngine< ResultType, K, A, B, C, D, R, S > &eng)
remove_reference< T >::type && move(T &&t) noexcept
XorshiftEngine< uint64_t, 16, 34, 29, 25, 31, 16, 7 > Xorshift16x64
Xorshift RNG engine generating 64-bits integers.
#define VSMC_STATIC_ASSERT_RNG_XORSHIFT
Traits of XorshiftEngine.
XorshiftEngine< uint64_t, 8, 37, 26, 29, 34, 8, 1 > Xorshift8x64
Xorshift RNG engine generating 64-bits integers.
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const XorwowEngine< Eng, D, DInit > &eng)
static ResultType shift(ResultType x)
#define VSMC_NULLPTR
nullptr
Xorwow64x64 Xorwow_64
The default 64-bits Xorwow RNG engine.
static ResultType shift(ResultType x)
XorwowEngine< Xorshift64x64 > Xorwow64x64
Xorwow RNG engine using Xorshfit 64-bits integers.
static constexpr result_type min()
friend bool operator==(const XorwowEngine< Eng, D, DInit > &eng1, const XorwowEngine< Eng, D, DInit > &eng2)
XorwowEngine< Xorshift2x32 > Xorwow2x32
Xorwow RNG engine using Xorshfit 32-bits integers.
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, XorwowEngine< Eng, D, DInit > &eng)
XorwowEngine< Xorshift128x32 > Xorwow128x32
Xorwow RNG engine using Xorshfit 32-bits integers.
static ResultType shift(ResultType x)
static constexpr result_type max()
XorwowEngine< Xorshift1x64 > Xorwow1x64
Xorwow RNG engine using Xorshfit 64-bits integers.
XorwowEngine< Xorshift64x32 > Xorwow64x32
Xorwow RNG engine using Xorshfit 32-bits integers.
XorshiftEngine< uint32_t, 8, 18, 13, 14, 15, 8, 3 > Xorshift8x32
Xorshift RNG engine generating 32-bits integers.
Eng::result_type result_type
void seed(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, XorwowEngine< Eng, D, DInit > >::value >::type *=nullptr)