Changes in libcfa/src/bits/random.hfa [90fb672:12b006c]
- File:
-
- 1 edited
-
libcfa/src/bits/random.hfa (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/random.hfa
r90fb672 r12b006c 10 10 // Created On : Fri Jan 14 07:18:11 2022 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 20 21:45:24202313 // Update Count : 18 612 // Last Modified On : Mon Mar 20 10:01:40 2023 13 // Update Count : 180 14 14 // 15 15 … … 131 131 #ifdef __cforall // don't include in C code (invoke.h) 132 132 133 // Splitmix64 133 134 // https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64 134 // 135 // Splitmix64 is not recommended for demanding random number requirements, but is often used to calculate initial states 136 // for other more complex pseudo-random number generators (see https://prng.di.unimi.it). 137 // Also https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64. 135 // Splitmix64 is not recommended for demanding random number requirements, 136 // but is often used to calculate initial states for other more complex 137 // pseudo-random number generators. 138 138 static inline uint64_t splitmix64( uint64_t & state ) { 139 139 state += 0x9e3779b97f4a7c15; … … 149 149 } // splitmix64_set_seed 150 150 151 // Splitmix32 151 152 // https://github.com/bryc/code/blob/master/jshash/PRNGs.md#splitmix32 152 // 153 // Splitmix32 is not recommended for demanding random number requirements, but is often used to calculate initial states154 // for other more complex pseudo-random number generators (see https://prng.di.unimi.it).155 153 // Splitmix32 is not recommended for demanding random number requirements, 154 // but is often used to calculate initial states for other more complex 155 // pseudo-random number generators. 156 // SplitMix32 is a 32 bit variant of Splitmix64 156 157 static inline uint32_t splitmix32( uint32_t & state ) { 157 158 state += 0x9e3779b9; … … 168 169 169 170 #ifdef __SIZEOF_INT128__ 170 //-------------------------------------------------- 171 static inline uint64_t lehmer64( __uint128_t & state ) { 172 __uint128_t ret = state; 173 state *= 0x_da94_2042_e4dd_58b5; 174 return ret >> 64; 175 } // lehmer64 176 177 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 178 // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed. 179 state = splitmix64( seed ); // prime 180 } // lehmer64_set_seed 181 182 //-------------------------------------------------- 183 static inline uint64_t wyhash64( uint64_t & state ) { 184 uint64_t ret = state; 185 state += 0x_60be_e2be_e120_fc15; 186 __uint128_t tmp; 187 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d; 188 uint64_t m1 = (tmp >> 64) ^ tmp; 189 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9; 190 uint64_t m2 = (tmp >> 64) ^ tmp; 191 return m2; 192 } // wyhash64 193 194 static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) { 195 state = splitmix64( seed ); // prime 196 } // wyhash64_set_seed 171 //-------------------------------------------------- 172 static inline uint64_t lehmer64( __uint128_t & state ) { 173 __uint128_t ret = state; 174 state *= 0x_da94_2042_e4dd_58b5; 175 return ret >> 64; 176 } // lehmer64 177 178 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 179 // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed. 180 state = seed; 181 lehmer64( state ); // prime 182 } // lehmer64_set_seed 183 184 //-------------------------------------------------- 185 static inline uint64_t wyhash64( uint64_t & state ) { 186 uint64_t ret = state; 187 state += 0x_60be_e2be_e120_fc15; 188 __uint128_t tmp; 189 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d; 190 uint64_t m1 = (tmp >> 64) ^ tmp; 191 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9; 192 uint64_t m2 = (tmp >> 64) ^ tmp; 193 return m2; 194 } // wyhash64 197 195 #endif // __SIZEOF_INT128__ 198 196 … … 229 227 230 228 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) { 231 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 232 uint64_t seed1 = splitmix64( seed ); // prime 229 // these are done explicitly in this order to attain repeatable seeding. 230 // do not call splitmix64 directly in the state init since order of argument evaluation 231 // may not be consistent leading to irreproducible seeding 232 uint64_t seed1 = splitmix64( seed ); 233 233 uint64_t seed2 = splitmix64( seed ); 234 234 uint64_t seed3 = splitmix64( seed ); 235 235 uint64_t seed4 = splitmix64( seed ); 236 236 state = (xoshiro256pp_t){ seed1, seed2, seed3, seed4 }; 237 xoshiro256pp( state ); // prime 237 238 } // xoshiro256pp_set_seed 238 239 … … 268 269 269 270 static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) { 270 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 271 uint32_t seed1 = splitmix32( seed ); // prime 271 // these are done explicitly in this order to attain repeatable seeding. 272 // do not call splitmix32 directly in the state init since order of argument evaluation 273 // may not be consistent leading to irreproducible seeding 274 uint32_t seed1 = splitmix32( seed ); 272 275 uint32_t seed2 = splitmix32( seed ); 273 276 uint32_t seed3 = splitmix32( seed ); 274 277 uint32_t seed4 = splitmix32( seed ); 275 278 state = (xoshiro128pp_t){ seed1, seed2, seed3, seed4 }; 279 xoshiro128pp( state ); // prime 276 280 } // xoshiro128pp_set_seed 277 281 … … 286 290 287 291 static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint64_t seed ) { 288 state = splitmix64( seed ); // prime 292 state = seed; 293 xorshift_13_7_17( state ); // prime 289 294 } // xorshift_13_7_17_set_seed 290 295 … … 303 308 304 309 static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) { 305 state = splitmix32( seed ); // prime 310 state = seed; 311 xorshift_6_21_7( state ); // prime 306 312 } // xorshift_6_21_7_set_seed 307 313 … … 317 323 318 324 static inline void xorshift_12_25_27_set_seed( uint64_t & state, uint64_t seed ) { 319 state = splitmix64( seed ); // prime 325 state = seed; 326 xorshift_12_25_27( state ); // prime 320 327 } // xorshift_12_25_27_set_seed 321 328 … … 338 345 339 346 static inline void kiss_64_set_seed( kiss_64_t & rs, uint64_t seed ) with(rs) { 340 z = 1; w = 1; jsr = 4; jcong = splitmix64( seed ); // prime 347 z = 1; w = 1; jsr = 4; jcong = seed; 348 kiss_64( rs ); // prime 341 349 } // kiss_64_set_seed 342 350 … … 366 374 367 375 static inline void xorwow_set_seed( xorwow_t & rs, uint32_t seed ) { 368 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 369 uint32_t seed1 = splitmix32( seed ); // prime 376 // these are done explicitly in this order to attain repeatable seeding. 377 // do not call splitmix32 directly in the state init since order of argument evaluation 378 // may not be consistent leading to irreproducible seeding 379 uint32_t seed1 = splitmix32( seed ); 370 380 uint32_t seed2 = splitmix32( seed ); 371 381 uint32_t seed3 = splitmix32( seed ); 372 382 uint32_t seed4 = splitmix32( seed ); 373 383 rs = (xorwow_t){ seed1, seed2, seed3, seed4, 0 }; 384 xorwow( rs ); // prime 374 385 } // xorwow_set_seed 375 386 … … 377 388 // Used in __tls_rand_fwd 378 389 #define M (1_l64u << 48_l64u) 379 #define A (25 _214_903_917_l64u)380 #define AI (18 _446_708_753_438_544_741_l64u)390 #define A (25214903917_l64u) 391 #define AI (18446708753438544741_l64u) 381 392 #define C (11_l64u) 382 393 #define D (16_l64u)
Note:
See TracChangeset
for help on using the changeset viewer.