File indexing completed on 2025-01-18 09:51:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
0017 #define BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
0018
0019 #include <iosfwd>
0020 #include <stdexcept>
0021 #include <boost/assert.hpp>
0022 #include <boost/config.hpp>
0023 #include <boost/cstdint.hpp>
0024 #include <boost/random/detail/config.hpp>
0025 #include <boost/random/detail/const_mod.hpp>
0026 #include <boost/random/detail/seed.hpp>
0027 #include <boost/random/detail/operators.hpp>
0028 #include <boost/random/detail/seed_impl.hpp>
0029
0030 #include <boost/random/detail/disable_warnings.hpp>
0031
0032 namespace boost {
0033 namespace random {
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template<class IntType, IntType a, IntType b, IntType p>
0066 class inversive_congruential_engine
0067 {
0068 public:
0069 typedef IntType result_type;
0070 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
0071
0072 BOOST_STATIC_CONSTANT(result_type, multiplier = a);
0073 BOOST_STATIC_CONSTANT(result_type, increment = b);
0074 BOOST_STATIC_CONSTANT(result_type, modulus = p);
0075 BOOST_STATIC_CONSTANT(IntType, default_seed = 1);
0076
0077 static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return b == 0 ? 1 : 0; }
0078 static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return p-1; }
0079
0080
0081
0082
0083
0084 inversive_congruential_engine() { seed(); }
0085
0086
0087
0088
0089 BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(inversive_congruential_engine,
0090 IntType, x0)
0091 { seed(x0); }
0092
0093
0094
0095
0096
0097 BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(inversive_congruential_engine,
0098 SeedSeq, seq)
0099 { seed(seq); }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 template<class It> inversive_congruential_engine(It& first, It last)
0110 { seed(first, last); }
0111
0112
0113
0114
0115 void seed() { seed(default_seed); }
0116
0117
0118
0119
0120
0121
0122
0123 BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(inversive_congruential_engine, IntType, x0)
0124 {
0125
0126 if(modulus == 0) {
0127 _value = x0;
0128 } else {
0129 _value = x0 % modulus;
0130 }
0131
0132 if(_value < 0) {
0133 _value += modulus;
0134 }
0135
0136 if(increment == 0 && _value == 0) {
0137 _value = 1;
0138 }
0139 BOOST_ASSERT(_value >= (min)());
0140 BOOST_ASSERT(_value <= (max)());
0141 }
0142
0143
0144
0145
0146 BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(inversive_congruential_engine, SeedSeq, seq)
0147 { seed(detail::seed_one_int<IntType, modulus>(seq)); }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 template<class It> void seed(It& first, It last)
0158 { seed(detail::get_one_int<IntType, modulus>(first, last)); }
0159
0160
0161 IntType operator()()
0162 {
0163 typedef const_mod<IntType, p> do_mod;
0164 _value = do_mod::mult_add(a, do_mod::invert(_value), b);
0165 return _value;
0166 }
0167
0168
0169 template<class Iter>
0170 void generate(Iter first, Iter last)
0171 { detail::generate_from_int(*this, first, last); }
0172
0173
0174 void discard(boost::uintmax_t z)
0175 {
0176 for(boost::uintmax_t j = 0; j < z; ++j) {
0177 (*this)();
0178 }
0179 }
0180
0181
0182
0183
0184 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, inversive_congruential_engine, x)
0185 {
0186 os << x._value;
0187 return os;
0188 }
0189
0190
0191
0192
0193 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, inversive_congruential_engine, x)
0194 {
0195 is >> x._value;
0196 return is;
0197 }
0198
0199
0200
0201
0202
0203 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(inversive_congruential_engine, x, y)
0204 { return x._value == y._value; }
0205
0206
0207
0208
0209
0210 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(inversive_congruential_engine)
0211
0212 private:
0213 IntType _value;
0214 };
0215
0216 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
0217
0218 template<class IntType, IntType a, IntType b, IntType p>
0219 const bool inversive_congruential_engine<IntType, a, b, p>::has_fixed_range;
0220 template<class IntType, IntType a, IntType b, IntType p>
0221 const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::multiplier;
0222 template<class IntType, IntType a, IntType b, IntType p>
0223 const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::increment;
0224 template<class IntType, IntType a, IntType b, IntType p>
0225 const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::modulus;
0226 template<class IntType, IntType a, IntType b, IntType p>
0227 const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::default_seed;
0228 #endif
0229
0230
0231
0232
0233 template<class IntType, IntType a, IntType b, IntType p, IntType val = 0>
0234 class inversive_congruential : public inversive_congruential_engine<IntType, a, b, p>
0235 {
0236 typedef inversive_congruential_engine<IntType, a, b, p> base_type;
0237 public:
0238 inversive_congruential(IntType x0 = 1) : base_type(x0) {}
0239 template<class It>
0240 inversive_congruential(It& first, It last) : base_type(first, last) {}
0241 };
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 typedef inversive_congruential_engine<uint32_t, 9102, 2147483647-36884165,
0256 2147483647> hellekalek1995;
0257
0258 }
0259
0260 using random::hellekalek1995;
0261
0262 }
0263
0264 #include <boost/random/detail/enable_warnings.hpp>
0265
0266 #endif