Changeset 08be4a4 in mainline
- Timestamp:
- 2018-07-05T21:41:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e7a4f41
- Parents:
- 3f3514aa
- git-author:
- Dzejrou <dzejrou@…> (2018-05-02 17:33:18)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/random.hpp
r3f3514aa r08be4a4 89 89 static constexpr result_type modulus = m; 90 90 91 static constexpr min()91 static constexpr result_type min() 92 92 { 93 93 return c == 0U ? 1U : 0U; 94 94 } 95 95 96 static constexpr max()96 static constexpr result_type max() 97 97 { 98 98 return m - 1U; … … 133 133 ) 134 134 { 135 size_t k = static_cast<size_t>(aux::ceil(aux::log2(modulus_) / 32)); 136 auto arr = new result_type[k + 3]; 137 138 q.generate(arr, arr + k + 3); 135 q.generate(arr_, arr_ + k_ + 3); 139 136 140 137 result_type s{}; 141 for (size_t j = 0; j < k ; ++j)142 s += a [j + 3] * aux::pow2(32U * j);138 for (size_t j = 0; j < k_; ++j) 139 s += arr_[j + 3] * aux::pow2(32U * j); 143 140 s = s % modulus_; 144 141 … … 201 198 (m == 0) ? (numeric_limits<result_type>::max() + 1) : m; 202 199 200 /** 201 * We use constexpr builtins to keep this array 202 * between calls to seed(Seq&), which means we don't 203 * have to keep allocating and deleting it. 204 */ 205 static constexpr size_t k_ = static_cast<size_t>(aux::ceil(aux::log2(modulus_) / 32)); 206 result_type arr_[k_ + 3]; 207 203 208 void transition_() 204 209 { … … 223 228 UIntType b, size_t t, UIntType c, size_t l, UIntType f 224 229 > 225 class mersenne_twister_engine; 230 class mersenne_twister_engine 231 { 232 // TODO: fix these 233 /* static_assert(0 < m && m <= n); */ 234 /* static_assert(2 * u < w); */ 235 /* static_assert(r <= w && u <= w && s <= w && t <= w && l <= w); */ 236 /* /1* static_assert(w <= numeric_limits<UIntType>::digits); *1/ */ 237 /* static_assert(a <= (1U << w) - 1U); */ 238 /* static_assert(b <= (1U << w) - 1U); */ 239 /* static_assert(c <= (1U << w) - 1U); */ 240 /* static_assert(d <= (1U << w) - 1U); */ 241 /* static_assert(f <= (1U << w) - 1U); */ 242 243 public: 244 using result_type = UIntType; 245 246 static constexpr size_t word_size = w; 247 static constexpr size_t state_size = n; 248 static constexpr size_t shift_size = m; 249 static constexpr size_t mask_bits = r; 250 static constexpr UIntType xor_mask = a; 251 252 static constexpr size_t tempering_u = u; 253 static constexpr UIntType tempering_d = d; 254 static constexpr size_t tempering_s = s; 255 static constexpr UIntType tempering_b = b; 256 static constexpr size_t tempering_t = t; 257 static constexpr UIntType tempering_c = c; 258 static constexpr size_t tempering_l = l; 259 260 static constexpr UIntType initialization_multiplier = f; 261 262 static constexpr result_type min() 263 { 264 return result_type{}; 265 } 266 267 static constexpr result_type max() 268 { 269 return static_cast<result_type>(aux::pow2(w)) - 1U; 270 } 271 272 static constexpr result_type default_seed = 5489U; 273 274 explicit mersenne_twister_engine(result_type value = default_seed) 275 : state_{}, i_{} 276 { 277 seed(value); 278 } 279 280 template<class Seq> 281 explicit mersenne_twister_engine( 282 enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q 283 ) 284 : state_{}, i_{} 285 { 286 seed(q); 287 } 288 289 void seed(result_type value = default_seed) 290 { 291 state_[idx_(-n)] = value % aux::pow2u(w);; 292 293 for (long long i = 1 - n; i <= -1; ++i) 294 { 295 state_[idx_(i)] = (f * (state_[idx_(i - 1)] ^ 296 (state_[idx_(i - 1)] >> (w - 2))) + 1 % n) % aux::pow2u(w); 297 } 298 } 299 300 template<class Seq> 301 void seed( 302 enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q 303 ) 304 { 305 q.generate(arr_, arr_ + n * k_); 306 307 for (long long i = -n; i <= -1; ++i) 308 { 309 state_[idx_(i)] = result_type{}; 310 for (long long j = 0; j < k_; ++j) 311 state_[idx_(i)] += arr_[k_ * (i + n) + j] * aux::pow2(32 * j); 312 state_[idx_(i)] %= aux::pow2(w); 313 } 314 } 315 316 result_type operator()() 317 { 318 return generate_(); 319 } 320 321 void discard(unsigned long long z) 322 { 323 for (unsigned long long i = 0ULL; i < z; ++i) 324 transition_(); 325 } 326 327 bool operator==(const mersenne_twister_engine& rhs) const 328 { 329 for (size_t i = 0; i < n; ++i) 330 { 331 if (state_[i] != rhs.state_[i]) 332 return false; 333 } 334 335 return true; 336 } 337 338 bool operator!=(const mersenne_twister_engine& rhs) const 339 { 340 return !(*this == rhs); 341 } 342 343 template<class Char, class Traits> 344 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const 345 { 346 auto flags = os.flags(); 347 os.flags(ios_base::dec | ios_base::left); 348 349 for (size_t j = n + 1; j > 1; --j) 350 { 351 os << state_[idx_(i_ - j - 1)]; 352 353 if (j > 2) 354 os << os.widen(' '); 355 } 356 357 os.flags(flags); 358 return os; 359 } 360 361 template<class Char, class Traits> 362 basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const 363 { 364 auto flags = is.flags(); 365 is.flags(ios_base::dec); 366 367 for (size_t j = n + 1; j > 1; --j) 368 { 369 if (!(is >> state_[idx_(i_ - j - 1)])) 370 { 371 is.setstate(ios::failbit); 372 break; 373 } 374 } 375 376 is.flags(flags); 377 return is; 378 } 379 380 private: 381 result_type state_[n]; 382 size_t i_; 383 384 static constexpr size_t k_ = static_cast<size_t>(w / 32); 385 result_type arr_[n * k_]; 386 387 void transition_() 388 { 389 auto mask = (result_type{1} << r) - 1; 390 auto y = (state_[idx_(i_ - n)] & ~mask) | (state_[idx_(i_ + 1 - n)] & mask); 391 auto alpha = a * (y & 1); 392 state_[i_] = state_[idx_(i_ + m - n)] ^ (y >> 1) ^ alpha; 393 394 i_ = (i_ + 1) % n; 395 } 396 397 result_type generate_() 398 { 399 auto z1 = state_[i_] ^ ((state_[i_] >> u) & d); 400 auto z2 = z1 ^ (lshift_(z1, s) & b); 401 auto z3 = z2 ^ (lshift_(z2, t) & c); 402 auto z4 = z3 ^ (z3 >> l); 403 404 transition_(); 405 406 return z4; 407 } 408 409 size_t idx_(size_t idx) const 410 { 411 return idx % n; 412 } 413 414 result_type lshift_(result_type val, size_t count) 415 { 416 return (val << count) % aux::pow2u(w); 417 } 418 }; 226 419 227 420 /**
Note:
See TracChangeset
for help on using the changeset viewer.