File indexing completed on 2025-01-30 09:59:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
0016 #define BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
0017
0018 #include <iosfwd>
0019 #include <stdexcept>
0020 #include <boost/config.hpp>
0021 #include <boost/cstdint.hpp>
0022 #include <boost/static_assert.hpp>
0023 #include <boost/integer/integer_mask.hpp>
0024 #include <boost/random/detail/config.hpp>
0025 #include <boost/random/detail/seed.hpp>
0026 #include <boost/random/detail/operators.hpp>
0027 #include <boost/random/detail/seed_impl.hpp>
0028
0029 namespace boost {
0030 namespace random {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 template<class UIntType, int w, int k, int q, int s>
0043 class linear_feedback_shift_engine
0044 {
0045 public:
0046 typedef UIntType result_type;
0047 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
0048 BOOST_STATIC_CONSTANT(int, word_size = w);
0049 BOOST_STATIC_CONSTANT(int, exponent1 = k);
0050 BOOST_STATIC_CONSTANT(int, exponent2 = q);
0051 BOOST_STATIC_CONSTANT(int, step_size = s);
0052 BOOST_STATIC_CONSTANT(UIntType, default_seed = 341);
0053
0054
0055 static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
0056
0057 static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
0058 { return wordmask(); }
0059
0060 BOOST_STATIC_ASSERT(w > 0);
0061 BOOST_STATIC_ASSERT(q > 0);
0062 BOOST_STATIC_ASSERT(k < w);
0063 BOOST_STATIC_ASSERT(0 < 2*q && 2*q < k);
0064 BOOST_STATIC_ASSERT(0 < s && s <= k-q);
0065
0066
0067 linear_feedback_shift_engine() { seed(); }
0068
0069
0070 BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_feedback_shift_engine,
0071 UIntType, s0)
0072 { seed(s0); }
0073
0074
0075 BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_feedback_shift_engine,
0076 SeedSeq, seq)
0077 { seed(seq); }
0078
0079
0080
0081
0082
0083 template<class It> linear_feedback_shift_engine(It& first, It last)
0084 { seed(first, last); }
0085
0086
0087 void seed() { seed(default_seed); }
0088
0089
0090 BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_feedback_shift_engine,
0091 UIntType, s0)
0092 {
0093 value = s0 & wordmask();
0094 if(value < (1 << (w-k))) {
0095 value += 1 << (w-k);
0096 }
0097 }
0098
0099
0100
0101
0102
0103 BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_feedback_shift_engine,
0104 SeedSeq, seq)
0105 { seed(detail::seed_one_int<UIntType, (UIntType(2) << (w - 1))>(seq)); }
0106
0107
0108
0109
0110
0111 template<class It> void seed(It& first, It last)
0112 {
0113 seed(detail::get_one_int<UIntType, (UIntType(2) << (w - 1))>(first, last));
0114 }
0115
0116
0117 result_type operator()()
0118 {
0119 const UIntType b = (((value << q) ^ value) & wordmask()) >> (k-s);
0120 const UIntType mask = (wordmask() << (w-k)) & wordmask();
0121 value = ((value & mask) << s) ^ b;
0122 return value;
0123 }
0124
0125
0126 template<class Iter>
0127 void generate(Iter first, Iter last)
0128 { detail::generate_from_int(*this, first, last); }
0129
0130
0131 void discard(boost::uintmax_t z)
0132 {
0133 for(boost::uintmax_t j = 0; j < z; ++j) {
0134 (*this)();
0135 }
0136 }
0137
0138
0139
0140
0141 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, linear_feedback_shift_engine, x)
0142 {
0143 os << x.value;
0144 return os;
0145 }
0146
0147
0148
0149
0150 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, linear_feedback_shift_engine, x)
0151 {
0152 is >> x.value;
0153 return is;
0154 }
0155
0156
0157
0158
0159
0160 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(linear_feedback_shift_engine, x, y)
0161 { return x.value == y.value; }
0162
0163
0164
0165
0166
0167 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(linear_feedback_shift_engine)
0168
0169 private:
0170
0171 static BOOST_CONSTEXPR UIntType wordmask() { return boost::low_bits_mask_t<w>::sig_bits; }
0172
0173 UIntType value;
0174 };
0175
0176 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
0177
0178 template<class UIntType, int w, int k, int q, int s>
0179 const bool linear_feedback_shift_engine<UIntType, w, k, q, s>::has_fixed_range;
0180 template<class UIntType, int w, int k, int q, int s>
0181 const int linear_feedback_shift_engine<UIntType, w, k, q, s>::word_size;
0182 template<class UIntType, int w, int k, int q, int s>
0183 const int linear_feedback_shift_engine<UIntType, w, k, q, s>::exponent1;
0184 template<class UIntType, int w, int k, int q, int s>
0185 const int linear_feedback_shift_engine<UIntType, w, k, q, s>::exponent2;
0186 template<class UIntType, int w, int k, int q, int s>
0187 const int linear_feedback_shift_engine<UIntType, w, k, q, s>::step_size;
0188 template<class UIntType, int w, int k, int q, int s>
0189 const UIntType linear_feedback_shift_engine<UIntType, w, k, q, s>::default_seed;
0190 #endif
0191
0192
0193
0194
0195 template<class UIntType, int w, int k, int q, int s, UIntType v = 0>
0196 class linear_feedback_shift :
0197 public linear_feedback_shift_engine<UIntType, w, k, q, s>
0198 {
0199 typedef linear_feedback_shift_engine<UIntType, w, k, q, s> base_type;
0200 public:
0201 linear_feedback_shift() {}
0202 BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_feedback_shift,
0203 SeedSeq, seq)
0204 { seed(seq); }
0205 BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_feedback_shift,
0206 UIntType, val)
0207 { seed(val); }
0208 template<class It>
0209 linear_feedback_shift(It& first, It last) : base_type(first, last) {}
0210 };
0211
0212
0213
0214 }
0215 }
0216
0217 #endif