Warning, file /include/boost/random/xoshiro.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_RANDOM_XOSHIRO_HPP
0013 #define BOOST_RANDOM_XOSHIRO_HPP
0014
0015 #include <boost/random/detail/config.hpp>
0016 #include <boost/random/detail/xoshiro_base.hpp>
0017 #include <boost/core/bit.hpp>
0018 #include <array>
0019 #include <cstdint>
0020
0021 namespace boost {
0022 namespace random {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 class xoshiro256pp final : public detail::xoshiro_base<xoshiro256pp, 4>
0033 {
0034 private:
0035
0036 using Base = detail::xoshiro_base<xoshiro256pp, 4>;
0037
0038 public:
0039
0040 using Base::Base;
0041
0042 inline result_type next() noexcept
0043 {
0044 const std::uint64_t result = boost::core::rotl(state_[0] + state_[3], 23) + state_[0];
0045 const std::uint64_t t = state_[1] << 17;
0046
0047 state_[2] ^= state_[0];
0048 state_[3] ^= state_[1];
0049 state_[1] ^= state_[2];
0050 state_[0] ^= state_[3];
0051
0052 state_[2] ^= t;
0053
0054 state_[3] = boost::core::rotl(state_[3], 45);
0055
0056 return result;
0057 }
0058 };
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 class xoshiro256d final : public detail::xoshiro_base<xoshiro256d, 4, double>
0071 {
0072 private:
0073
0074 using Base = detail::xoshiro_base<xoshiro256d, 4, double>;
0075
0076 public:
0077
0078 using Base::Base;
0079
0080 inline std::uint64_t next_int() noexcept
0081 {
0082 const std::uint64_t result = state_[0] + state_[3];
0083 const std::uint64_t t = state_[1] << 17;
0084
0085 state_[2] ^= state_[0];
0086 state_[3] ^= state_[1];
0087 state_[1] ^= state_[2];
0088 state_[0] ^= state_[3];
0089
0090 state_[2] ^= t;
0091
0092 state_[3] = boost::core::rotl(state_[3], 45);
0093
0094 return result;
0095 }
0096
0097 inline result_type next() noexcept
0098 {
0099 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0100 return static_cast<double>((next_int() >> 11)) * 0x1.0p-53;
0101 #else
0102 return static_cast<double>((next_int() >> 11)) * 1.11022302462515654e-16;
0103 #endif
0104 }
0105
0106 static constexpr result_type (min)() noexcept
0107 {
0108 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0109 return static_cast<double>((std::numeric_limits<std::uint64_t>::min)() >> 11) * 0x1.0p-53;
0110 #else
0111 return static_cast<double>((std::numeric_limits<std::uint64_t>::min)() >> 11) * 1.11022302462515654e-16;
0112 #endif
0113 }
0114
0115 static constexpr result_type (max)() noexcept
0116 {
0117 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0118 return static_cast<double>((std::numeric_limits<std::uint64_t>::max)()) * 0x1.0p-53;
0119 #else
0120 return static_cast<double>((std::numeric_limits<std::uint64_t>::max)()) * 1.11022302462515654e-16;
0121 #endif
0122 }
0123 };
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 class xoshiro256mm final : public detail::xoshiro_base<xoshiro256mm, 4>
0135 {
0136 private:
0137
0138 using Base = detail::xoshiro_base<xoshiro256mm, 4>;
0139
0140 public:
0141
0142 using Base::Base;
0143
0144 inline result_type next() noexcept
0145 {
0146 const std::uint64_t result = boost::core::rotl(state_[1] * 5, 7) * 9U;
0147 const std::uint64_t t = state_[1] << 17;
0148
0149 state_[2] ^= state_[0];
0150 state_[3] ^= state_[1];
0151 state_[1] ^= state_[2];
0152 state_[0] ^= state_[3];
0153
0154 state_[2] ^= t;
0155
0156 state_[3] = boost::core::rotl(state_[3], 45);
0157
0158 return result;
0159 }
0160 };
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 class xoshiro512pp final : public detail::xoshiro_base<xoshiro512pp, 8>
0176 {
0177 private:
0178
0179 using Base = detail::xoshiro_base<xoshiro512pp, 8>;
0180
0181 public:
0182
0183 using Base::Base;
0184
0185 inline result_type next() noexcept
0186 {
0187 const std::uint64_t result = boost::core::rotl(state_[0] + state_[2], 17) + state_[2];
0188
0189 const std::uint64_t t = state_[1] << 11;
0190
0191 state_[2] ^= state_[0];
0192 state_[5] ^= state_[1];
0193 state_[1] ^= state_[2];
0194 state_[7] ^= state_[3];
0195 state_[3] ^= state_[4];
0196 state_[4] ^= state_[5];
0197 state_[0] ^= state_[6];
0198 state_[6] ^= state_[7];
0199
0200 state_[6] ^= t;
0201
0202 state_[7] = boost::core::rotl(state_[7], 21);
0203
0204 return result;
0205 }
0206 };
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 class xoshiro512mm final : public detail::xoshiro_base<xoshiro512mm, 8>
0222 {
0223 private:
0224
0225 using Base = detail::xoshiro_base<xoshiro512mm, 8>;
0226
0227 public:
0228
0229 using Base::Base;
0230
0231 inline result_type next() noexcept
0232 {
0233 const std::uint64_t result = boost::core::rotl(state_[1] * 5, 7) * 9;
0234
0235 const std::uint64_t t = state_[1] << 11;
0236
0237 state_[2] ^= state_[0];
0238 state_[5] ^= state_[1];
0239 state_[1] ^= state_[2];
0240 state_[7] ^= state_[3];
0241 state_[3] ^= state_[4];
0242 state_[4] ^= state_[5];
0243 state_[0] ^= state_[6];
0244 state_[6] ^= state_[7];
0245
0246 state_[6] ^= t;
0247
0248 state_[7] = boost::core::rotl(state_[7], 21);
0249
0250 return result;
0251 }
0252 };
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 class xoshiro512d final : public detail::xoshiro_base<xoshiro512d, 8, double>
0272 {
0273 private:
0274
0275 using Base = detail::xoshiro_base<xoshiro512d, 8, double>;
0276
0277 public:
0278
0279 using Base::Base;
0280
0281 inline std::uint64_t next_int() noexcept
0282 {
0283 const std::uint64_t result = state_[0] + state_[2];
0284
0285 const std::uint64_t t = state_[1] << 11;
0286
0287 state_[2] ^= state_[0];
0288 state_[5] ^= state_[1];
0289 state_[1] ^= state_[2];
0290 state_[7] ^= state_[3];
0291 state_[3] ^= state_[4];
0292 state_[4] ^= state_[5];
0293 state_[0] ^= state_[6];
0294 state_[6] ^= state_[7];
0295
0296 state_[6] ^= t;
0297
0298 state_[7] = boost::core::rotl(state_[7], 21);
0299
0300 return result;
0301 }
0302
0303 inline result_type next() noexcept
0304 {
0305 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0306 return static_cast<double>((next_int() >> 11)) * 0x1.0p-53;
0307 #else
0308 return static_cast<double>((next_int() >> 11)) * 1.11022302462515654e-16;
0309 #endif
0310 }
0311
0312 static constexpr result_type (min)() noexcept
0313 {
0314 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0315 return static_cast<double>((std::numeric_limits<std::uint64_t>::min)() >> 11) * 0x1.0p-53;
0316 #else
0317 return static_cast<double>((std::numeric_limits<std::uint64_t>::min)() >> 11) * 1.11022302462515654e-16;
0318 #endif
0319 }
0320
0321 static constexpr result_type (max)() noexcept
0322 {
0323 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0324 return static_cast<double>((std::numeric_limits<std::uint64_t>::max)() >> 11) * 0x1.0p-53;
0325 #else
0326 return static_cast<double>((std::numeric_limits<std::uint64_t>::max)() >> 11) * 1.11022302462515654e-16;
0327 #endif
0328 }
0329 };
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 class xoshiro128pp final : public detail::xoshiro_base<xoshiro128pp, 4, std::uint32_t, std::uint32_t>
0343 {
0344 private:
0345
0346 using Base = detail::xoshiro_base<xoshiro128pp, 4, std::uint32_t, std::uint32_t>;
0347
0348 public:
0349
0350 using Base::Base;
0351
0352 inline result_type next() noexcept
0353 {
0354 const std::uint32_t result = boost::core::rotl(state_[0] + state_[3], 7) + state_[0];
0355
0356 const std::uint32_t t = state_[1] << 9;
0357
0358 state_[2] ^= state_[0];
0359 state_[3] ^= state_[1];
0360 state_[1] ^= state_[2];
0361 state_[0] ^= state_[3];
0362
0363 state_[2] ^= t;
0364
0365 state_[3] = boost::core::rotl(state_[3], 11);
0366
0367 return result;
0368 }
0369 };
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 class xoshiro128mm final : public detail::xoshiro_base<xoshiro128mm, 4, std::uint32_t, std::uint32_t>
0386 {
0387 private:
0388
0389 using Base = detail::xoshiro_base<xoshiro128mm, 4, std::uint32_t, std::uint32_t>;
0390
0391 public:
0392
0393 using Base::Base;
0394
0395 inline result_type next() noexcept
0396 {
0397 const std::uint32_t result = boost::core::rotl(state_[1] * 5, 7) * 9;
0398
0399 const std::uint32_t t = state_[1] << 9;
0400
0401 state_[2] ^= state_[0];
0402 state_[3] ^= state_[1];
0403 state_[1] ^= state_[2];
0404 state_[0] ^= state_[3];
0405
0406 state_[2] ^= t;
0407
0408 state_[3] = boost::core::rotl(state_[3], 11);
0409
0410 return result;
0411 }
0412 };
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 class xoshiro128f final : public detail::xoshiro_base<xoshiro128f, 4, float, std::uint32_t>
0430 {
0431 private:
0432
0433 using Base = detail::xoshiro_base<xoshiro128f, 4, float, std::uint32_t>;
0434
0435 public:
0436
0437 using Base::Base;
0438
0439 inline std::uint32_t next_int() noexcept
0440 {
0441 const std::uint32_t result = state_[0] + state_[3];
0442
0443 const std::uint32_t t = state_[1] << 9;
0444
0445 state_[2] ^= state_[0];
0446 state_[3] ^= state_[1];
0447 state_[1] ^= state_[2];
0448 state_[0] ^= state_[3];
0449
0450 state_[2] ^= t;
0451
0452 state_[3] = boost::core::rotl(state_[3], 11);
0453
0454 return result;
0455 }
0456
0457 inline result_type next() noexcept
0458 {
0459 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0460 return static_cast<float>((next_int() >> 8)) * 0x1.0p-24f;
0461 #else
0462 return static_cast<float>((next_int() >> 8)) * 5.9604645e-08f;
0463 #endif
0464 }
0465
0466 static constexpr result_type (min)() noexcept
0467 {
0468 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0469 return static_cast<float>((std::numeric_limits<std::uint32_t>::min)() >> 8) * 0x1.0p-24f;
0470 #else
0471 return static_cast<float>((std::numeric_limits<std::uint64_t>::min)() >> 8) * 5.9604645e-08f;
0472 #endif
0473 }
0474
0475 static constexpr result_type (max)() noexcept
0476 {
0477 #ifdef BOOST_RANDOM_HAS_HEX_FLOAT
0478 return static_cast<float>((std::numeric_limits<std::uint32_t>::max)() >> 8) * 0x1.0p-24f;
0479 #else
0480 return static_cast<float>((std::numeric_limits<std::uint64_t>::max)() >> 8) * 5.9604645e-08f;
0481 #endif
0482 }
0483 };
0484
0485 }
0486 }
0487
0488 #endif