src/util/rand/lib.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../alias/others/lib.hpp" | ||
| 4 | #include "../consts/lib.hpp" | ||
| 5 | |||
| 6 | namespace tifa_libs { | ||
| 7 | |||
| 8 | template <class T> | ||
| 9 | requires std::is_arithmetic_v<T> | ||
| 10 | class rand_gen { | ||
| 11 | using res_t = std::conditional_t<sizeof(T) <= 4, u32, u64>; | ||
| 12 | using res_wt = std::conditional_t<sizeof(T) <= 4, u64, u128>; | ||
| 13 | // clang-format off | ||
| 14 | struct mt19937_param { static CEXP u32 w = 32, n = 624, m = 397, r = 31, a = 0x9908b0df, u = 11, d = 0xffffffff, s = 7, b = 0x9d2c5680, t = 15, c = 0xefc60000, l = 18, f = 1812433253; }; | ||
| 15 | struct mt19937_64_param { static CEXP u64 w = 64, n = 312, m = 156, r = 31, a = 0xb5026f5aa96619e9, u = 29, d = 0x5555555555555555, s = 17, b = 0x71d67fffeda60000, t = 37, c = 0xfff7eee000000000, l = 43, f = 6364136223846793005; }; | ||
| 16 | using pm = std::conditional_t<std::is_same_v<res_t, u32>, mt19937_param, mt19937_64_param>; | ||
| 17 | // clang-format on | ||
| 18 | T a_, b_; | ||
| 19 | |||
| 20 | arr<res_t, pm::n> x_; | ||
| 21 | u32 p_; | ||
| 22 | 487848 | CEXP void gen_() NE { | |
| 23 | 487848 | CEXP res_t um = (~res_t()) << pm::r, lm = ~um; | |
| 24 | res_t _; | ||
| 25 |
48/48tifa_libs::rand_gen<char>::gen_():
✓ Branch 3 taken 3565792 times.
✓ Branch 4 taken 3567002 times.
✓ Branch 6 taken 7132794 times.
✓ Branch 7 taken 31422 times.
tifa_libs::rand_gen<double>::gen_():
✓ Branch 3 taken 2500854 times.
✓ Branch 4 taken 2501130 times.
✓ Branch 6 taken 5001984 times.
✓ Branch 7 taken 32064 times.
tifa_libs::rand_gen<float>::gen_():
✓ Branch 3 taken 1817547 times.
✓ Branch 4 taken 1820355 times.
✓ Branch 6 taken 3637902 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<int>::gen_():
✓ Branch 3 taken 4516994 times.
✓ Branch 4 taken 4523281 times.
✓ Branch 6 taken 9040275 times.
✓ Branch 7 taken 39825 times.
tifa_libs::rand_gen<long double>::gen_():
✓ Branch 3 taken 2501210 times.
✓ Branch 4 taken 2500618 times.
✓ Branch 6 taken 5001828 times.
✓ Branch 7 taken 32063 times.
tifa_libs::rand_gen<long>::gen_():
✓ Branch 3 taken 2500543 times.
✓ Branch 4 taken 2500037 times.
✓ Branch 6 taken 5000580 times.
✓ Branch 7 taken 32055 times.
tifa_libs::rand_gen<short>::gen_():
✓ Branch 3 taken 1819507 times.
✓ Branch 4 taken 1818395 times.
✓ Branch 6 taken 3637902 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<signed char>::gen_():
✓ Branch 3 taken 1819849 times.
✓ Branch 4 taken 1818053 times.
✓ Branch 6 taken 3637902 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<unsigned char>::gen_():
✓ Branch 3 taken 1818675 times.
✓ Branch 4 taken 1819227 times.
✓ Branch 6 taken 3637902 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<unsigned int>::gen_():
✓ Branch 3 taken 10884718 times.
✓ Branch 4 taken 10875502 times.
✓ Branch 6 taken 21760220 times.
✓ Branch 7 taken 95860 times.
tifa_libs::rand_gen<unsigned long>::gen_():
✓ Branch 3 taken 11270488 times.
✓ Branch 4 taken 11260436 times.
✓ Branch 6 taken 22530924 times.
✓ Branch 7 taken 144429 times.
tifa_libs::rand_gen<unsigned short>::gen_():
✓ Branch 3 taken 1818668 times.
✓ Branch 4 taken 1819234 times.
✓ Branch 6 taken 3637902 times.
✓ Branch 7 taken 16026 times.
|
94145963 | flt_ (res_t, i, p_ = 0, pm::n - pm::m) _ = ((x_[i] & um) | (x_[i + 1] & lm)), x_[i] = (x_[i + pm::m] ^ (_ >> 1) ^ ((_ & 1) ? pm::a : 0)); |
| 26 |
48/48tifa_libs::rand_gen<char>::gen_():
✓ Branch 3 taken 6221374 times.
✓ Branch 4 taken 6221738 times.
✓ Branch 6 taken 12443112 times.
✓ Branch 7 taken 31422 times.
tifa_libs::rand_gen<double>::gen_():
✓ Branch 3 taken 2483695 times.
✓ Branch 4 taken 2486225 times.
✓ Branch 6 taken 4969920 times.
✓ Branch 7 taken 32064 times.
tifa_libs::rand_gen<float>::gen_():
✓ Branch 3 taken 3172370 times.
✓ Branch 4 taken 3173926 times.
✓ Branch 6 taken 6346296 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<int>::gen_():
✓ Branch 3 taken 7892976 times.
✓ Branch 4 taken 7877724 times.
✓ Branch 6 taken 15770700 times.
✓ Branch 7 taken 39825 times.
tifa_libs::rand_gen<long double>::gen_():
✓ Branch 3 taken 2485620 times.
✓ Branch 4 taken 2484145 times.
✓ Branch 6 taken 4969765 times.
✓ Branch 7 taken 32063 times.
tifa_libs::rand_gen<long>::gen_():
✓ Branch 3 taken 2482974 times.
✓ Branch 4 taken 2485551 times.
✓ Branch 6 taken 4968525 times.
✓ Branch 7 taken 32055 times.
tifa_libs::rand_gen<short>::gen_():
✓ Branch 3 taken 3174490 times.
✓ Branch 4 taken 3171806 times.
✓ Branch 6 taken 6346296 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<signed char>::gen_():
✓ Branch 3 taken 3172548 times.
✓ Branch 4 taken 3173748 times.
✓ Branch 6 taken 6346296 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<unsigned char>::gen_():
✓ Branch 3 taken 3175050 times.
✓ Branch 4 taken 3171246 times.
✓ Branch 6 taken 6346296 times.
✓ Branch 7 taken 16026 times.
tifa_libs::rand_gen<unsigned int>::gen_():
✓ Branch 3 taken 18977119 times.
✓ Branch 4 taken 18983441 times.
✓ Branch 6 taken 37960560 times.
✓ Branch 7 taken 95860 times.
tifa_libs::rand_gen<unsigned long>::gen_():
✓ Branch 3 taken 11198784 times.
✓ Branch 4 taken 11187711 times.
✓ Branch 6 taken 22386495 times.
✓ Branch 7 taken 144429 times.
tifa_libs::rand_gen<unsigned short>::gen_():
✓ Branch 3 taken 3172450 times.
✓ Branch 4 taken 3173846 times.
✓ Branch 6 taken 6346296 times.
✓ Branch 7 taken 16026 times.
|
135688405 | flt_ (res_t, i, pm::n - pm::m, pm::n - 1) _ = ((x_[i] & um) | (x_[i + 1] & lm)), x_[i] = (x_[i + (pm::m - pm::n)] ^ (_ >> 1) ^ ((_ & 1) ? pm::a : 0)); |
| 27 |
24/24tifa_libs::rand_gen<char>::gen_():
✓ Branch 3 taken 15493 times.
✓ Branch 4 taken 15929 times.
tifa_libs::rand_gen<double>::gen_():
✓ Branch 3 taken 15958 times.
✓ Branch 4 taken 16106 times.
tifa_libs::rand_gen<float>::gen_():
✓ Branch 3 taken 7935 times.
✓ Branch 4 taken 8091 times.
tifa_libs::rand_gen<int>::gen_():
✓ Branch 3 taken 19824 times.
✓ Branch 4 taken 20001 times.
tifa_libs::rand_gen<long double>::gen_():
✓ Branch 3 taken 16035 times.
✓ Branch 4 taken 16028 times.
tifa_libs::rand_gen<long>::gen_():
✓ Branch 3 taken 16086 times.
✓ Branch 4 taken 15969 times.
tifa_libs::rand_gen<short>::gen_():
✓ Branch 3 taken 7929 times.
✓ Branch 4 taken 8097 times.
tifa_libs::rand_gen<signed char>::gen_():
✓ Branch 3 taken 7976 times.
✓ Branch 4 taken 8050 times.
tifa_libs::rand_gen<unsigned char>::gen_():
✓ Branch 3 taken 7987 times.
✓ Branch 4 taken 8039 times.
tifa_libs::rand_gen<unsigned int>::gen_():
✓ Branch 3 taken 47559 times.
✓ Branch 4 taken 48301 times.
tifa_libs::rand_gen<unsigned long>::gen_():
✓ Branch 3 taken 71888 times.
✓ Branch 4 taken 72541 times.
tifa_libs::rand_gen<unsigned short>::gen_():
✓ Branch 3 taken 8035 times.
✓ Branch 4 taken 7991 times.
|
487848 | _ = ((x_[pm::n - 1] & um) | (x_[0] & lm)), x_[pm::n - 1] = (x_[pm::m - 1] ^ (_ >> 1) ^ ((_ & 1) ? pm::a : 0)); |
| 28 | 487848 | } | |
| 29 | |||
| 30 | public: | ||
| 31 |
6/20tifa_libs::rand_gen<double>::rand_gen(double, double, unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
tifa_libs::rand_gen<int>::rand_gen(int, int, unsigned int):
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<long double>::rand_gen(long double, long double, unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
tifa_libs::rand_gen<long>::rand_gen(long, long, unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<unsigned int>::rand_gen(unsigned int, unsigned int, unsigned int):
✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<unsigned long>::rand_gen(unsigned long, unsigned long, unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
272 | CEXPE rand_gen(T a = std::numeric_limits<T>::min(), T b = std::numeric_limits<T>::max(), res_t sd = (res_t)TIME) NE : a_(a), b_(b) { assert(a < b || (std::is_integral_v<T> && a == b)), seed(sd); } |
| 32 | |||
| 33 |
12/42tifa_libs::rand_gen<char>::range(char, char):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<double>::range(double, double):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
tifa_libs::rand_gen<float>::range(float, float):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
tifa_libs::rand_gen<int>::range(int, int):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<long double>::range(long double, long double):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
tifa_libs::rand_gen<long>::range(long, long):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<short>::range(short, short):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<signed char>::range(signed char, signed char):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<unsigned char>::range(unsigned char, unsigned char):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<unsigned int>::range(unsigned int, unsigned int):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<unsigned long>::range(unsigned long, unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 98559 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::rand_gen<unsigned short>::range(unsigned short, unsigned short):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
98570 | CEXP void range(T min, T max) NE { assert(min < max || (std::is_integral_v<T> && min == max)), a_ = min, b_ = max; } |
| 34 | 19055 | void seed() NE { seed((res_t)std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); } | |
| 35 | 19349 | CEXP void seed(res_t sd) NE { | |
| 36 | 19349 | x_[0] = sd & gen_max(); | |
| 37 |
24/24tifa_libs::rand_gen<char>::seed(unsigned int):
✓ Branch 4 taken 623 times.
✓ Branch 5 taken 1 time.
tifa_libs::rand_gen<double>::seed(unsigned long):
✓ Branch 4 taken 4043 times.
✓ Branch 5 taken 13 times.
tifa_libs::rand_gen<float>::seed(unsigned int):
✓ Branch 4 taken 623 times.
✓ Branch 5 taken 1 time.
tifa_libs::rand_gen<int>::seed(unsigned int):
✓ Branch 4 taken 36134 times.
✓ Branch 5 taken 58 times.
tifa_libs::rand_gen<long double>::seed(unsigned long):
✓ Branch 4 taken 3732 times.
✓ Branch 5 taken 12 times.
tifa_libs::rand_gen<long>::seed(unsigned long):
✓ Branch 4 taken 1244 times.
✓ Branch 5 taken 4 times.
tifa_libs::rand_gen<short>::seed(unsigned int):
✓ Branch 4 taken 623 times.
✓ Branch 5 taken 1 time.
tifa_libs::rand_gen<signed char>::seed(unsigned int):
✓ Branch 4 taken 623 times.
✓ Branch 5 taken 1 time.
tifa_libs::rand_gen<unsigned char>::seed(unsigned int):
✓ Branch 4 taken 623 times.
✓ Branch 5 taken 1 time.
tifa_libs::rand_gen<unsigned int>::seed(unsigned int):
✓ Branch 4 taken 94696 times.
✓ Branch 5 taken 152 times.
tifa_libs::rand_gen<unsigned long>::seed(unsigned long):
✓ Branch 4 taken 5941344 times.
✓ Branch 5 taken 19104 times.
tifa_libs::rand_gen<unsigned short>::seed(unsigned int):
✓ Branch 4 taken 623 times.
✓ Branch 5 taken 1 time.
|
6104280 | flt_ (res_t, i, 1, p_ = pm::n) x_[i] = ((x_[i - 1] ^ (x_[i - 1] >> (pm::w - 2))) * pm::f + i % pm::n) & gen_max(); |
| 38 | 19349 | } | |
| 39 | ND CEXP res_t gen_min() CNE { return 0; } | ||
| 40 | 21105606 | ND CEXP res_t gen_max() CNE { | |
| 41 | 21105606 | if CEXP (sizeof(res_t) * 8 == pm::w) return ~res_t(); | |
| 42 | else return ((res_t)1 << pm::w) - 1; | ||
| 43 | } | ||
| 44 | 228987306 | CEXP res_t next() NE { | |
| 45 |
24/24tifa_libs::rand_gen<char>::next():
✓ Branch 0 taken 31422 times.
✓ Branch 1 taken 19574868 times.
tifa_libs::rand_gen<double>::next():
✓ Branch 0 taken 32064 times.
✓ Branch 1 taken 9968656 times.
tifa_libs::rand_gen<float>::next():
✓ Branch 0 taken 16026 times.
✓ Branch 1 taken 9983974 times.
tifa_libs::rand_gen<int>::next():
✓ Branch 0 taken 39825 times.
✓ Branch 1 taken 24785992 times.
tifa_libs::rand_gen<long double>::next():
✓ Branch 0 taken 32063 times.
✓ Branch 1 taken 9968543 times.
tifa_libs::rand_gen<long>::next():
✓ Branch 0 taken 32055 times.
✓ Branch 1 taken 9967993 times.
tifa_libs::rand_gen<short>::next():
✓ Branch 0 taken 16026 times.
✓ Branch 1 taken 9983974 times.
tifa_libs::rand_gen<signed char>::next():
✓ Branch 0 taken 16026 times.
✓ Branch 1 taken 9983974 times.
tifa_libs::rand_gen<unsigned char>::next():
✓ Branch 0 taken 16026 times.
✓ Branch 1 taken 9983974 times.
tifa_libs::rand_gen<unsigned int>::next():
✓ Branch 0 taken 95860 times.
✓ Branch 1 taken 59502429 times.
tifa_libs::rand_gen<unsigned long>::next():
✓ Branch 0 taken 144429 times.
✓ Branch 1 taken 44811107 times.
tifa_libs::rand_gen<unsigned short>::next():
✓ Branch 0 taken 16026 times.
✓ Branch 1 taken 9983974 times.
|
228987306 | if (p_ >= pm::n) gen_(); |
| 46 | 228987306 | res_t _ = x_[p_++]; | |
| 47 | 228987306 | _ ^= (_ >> pm::u) & pm::d, _ ^= (_ << pm::s) & pm::b, _ ^= (_ << pm::t) & pm::c, _ ^= (_ >> pm::l); | |
| 48 | 228987306 | return _; | |
| 49 | } | ||
| 50 | 163712279 | CEXP T operator()() NE { | |
| 51 | if CEXP (std::integral<T>) { | ||
| 52 | 148710953 | const res_wt r = (res_wt)b_ - (res_wt)a_ + 1; | |
| 53 | 148710953 | res_wt p = r * next(); | |
| 54 |
6/8tifa_libs::rand_gen<char>::operator()():
✗ Branch 0 not taken.
✓ Branch 1 taken 95180 times.
tifa_libs::rand_gen<int>::operator()():
✓ Branch 0 taken 14820801 times.
✗ Branch 1 not taken.
tifa_libs::rand_gen<unsigned int>::operator()():
✓ Branch 0 taken 27284531 times.
✓ Branch 1 taken 10230201 times.
tifa_libs::rand_gen<unsigned long>::operator()():
✓ Branch 0 taken 4783163 times.
✓ Branch 1 taken 195968 times.
|
148710953 | if (auto l = (res_t)p, _ = res_t(res_wt(-(res_t)r) % r); l < r) |
| 55 |
5/8tifa_libs::rand_gen<char>::operator()():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
tifa_libs::rand_gen<int>::operator()():
✗ Branch 1 not taken.
✓ Branch 2 taken 14820801 times.
tifa_libs::rand_gen<unsigned int>::operator()():
✓ Branch 1 taken 75490 times.
✓ Branch 2 taken 27284531 times.
tifa_libs::rand_gen<unsigned long>::operator()():
✓ Branch 1 taken 623 times.
✓ Branch 2 taken 4783163 times.
|
58635996 | while (l < _) l = res_t(p = r * next()); |
| 56 | 148710953 | return T((res_t)(p >> pm::w) + (res_t)a_); | |
| 57 | 15001326 | } else return T(next() / (f128)((u128)gen_max() + 1) * (b_ - a_) + a_); | |
| 58 | } | ||
| 59 | }; | ||
| 60 | |||
| 61 | } // namespace tifa_libs | ||
| 62 |