- Timestamp:
- Dec 21, 2022, 9:21:15 PM (20 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- ae7a085c
- Parents:
- 6b608c7
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/random.hfa
r6b608c7 rb797d978 10 10 // Created On : Fri Jan 14 07:18:11 2022 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Dec 11 18:43:58202213 // Update Count : 17 112 // Last Modified On : Wed Dec 14 20:32:53 2022 13 // Update Count : 177 14 14 // 15 15 … … 24 24 #ifdef __x86_64__ // 64-bit architecture 25 25 // 64-bit generators 26 #define LEHMER6426 //#define LEHMER64 27 27 //#define XORSHIFT_12_25_27 28 //#define XOSHIRO256PP28 #define XOSHIRO256PP 29 29 //#define KISS_64 30 30 31 31 // 32-bit generators 32 #define XORSHIFT_6_21_733 //#define XOSHIRO128PP32 //#define XORSHIFT_6_21_7 33 #define XOSHIRO128PP 34 34 #else // 32-bit architecture 35 35 // 64-bit generators 36 #define XORSHIFT_13_7_17 36 //#define XORSHIFT_13_7_17 37 #define XOSHIRO256PP 37 38 38 39 // 32-bit generators 39 #define XORSHIFT_6_21_7 40 //#define XORSHIFT_6_21_7 41 #define XOSHIRO128PP 40 42 #endif // __x86_64__ 41 43 … … 47 49 #define PRNG_NAME_64 xoshiro256pp 48 50 #define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t) 49 typedef struct PRNG_STATE_64_T { uint64_t s [4]; } PRNG_STATE_64_T;51 typedef struct PRNG_STATE_64_T { uint64_t s0, s1, s2, s3; } PRNG_STATE_64_T; 50 52 #endif // XOSHIRO256PP 51 53 … … 53 55 #define PRNG_NAME_32 xoshiro128pp 54 56 #define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t) 55 typedef struct PRNG_STATE_32_T { uint32_t s [4]; } PRNG_STATE_32_T;57 typedef struct PRNG_STATE_32_T { uint32_t s0, s1, s2, s3; } PRNG_STATE_32_T; 56 58 #endif // XOSHIRO128PP 57 59 … … 110 112 111 113 // ALL PRNG ALGORITHMS ARE OPTIMIZED SO THAT THE PRNG LOGIC CAN HAPPEN IN PARALLEL WITH THE USE OF THE RESULT. 112 // Therefore, the set_seed routine primes the PRNG by calling it with the state so the seed is not return as the 113 // first random value. 114 // Specifically, the current random state is copied for returning, before computing the next value. As a consequence, 115 // the set_seed routine primes the PRNG by calling it with the state so the seed is not return as the first random 116 // value. 117 114 118 115 119 #ifdef __cforall // don't include in C code (invoke.h) … … 126 130 127 131 #ifndef XOSHIRO256PP 128 typedef struct xoshiro256pp_t { uint64_t s [4]; } xoshiro256pp_t;132 typedef struct xoshiro256pp_t { uint64_t s0, s1, s2, s3; } xoshiro256pp_t; 129 133 #endif // ! XOSHIRO256PP 130 134 131 135 static inline uint64_t xoshiro256pp( xoshiro256pp_t & rs ) with(rs) { 132 inline uint64_t rotl( const uint64_t x, int k) {136 inline uint64_t rotl( const uint64_t x, int k ) { 133 137 return (x << k) | (x >> (64 - k)); 134 138 } // rotl 135 139 136 const uint64_t result = rotl( s [0] + s[3], 23 ) + s[0];137 const uint64_t t = s [1]<< 17;138 139 s [2] ^= s[0];140 s [3] ^= s[1];141 s [1] ^= s[2];142 s [0] ^= s[3];143 s [2]^= t;144 s [3] = rotl( s[3], 45 );140 const uint64_t result = rotl( s0 + s3, 23 ) + s0; 141 const uint64_t t = s1 << 17; 142 143 s2 ^= s0; 144 s3 ^= s1; 145 s1 ^= s2; 146 s0 ^= s3; 147 s2 ^= t; 148 s3 = rotl( s3, 45 ); 145 149 return result; 146 150 } // xoshiro256pp 147 151 148 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, 149 state = (xoshiro256pp_t){ {seed, seed, seed, seed}};152 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) { 153 state = (xoshiro256pp_t){ seed, seed, seed, seed }; 150 154 xoshiro256pp( state ); 151 155 } // xoshiro256pp_set_seed … … 161 165 162 166 #ifndef XOSHIRO128PP 163 typedef struct xoshiro128pp_t { uint32_t s [4]; } xoshiro128pp_t;167 typedef struct xoshiro128pp_t { uint32_t s0, s1, s2, s3; } xoshiro128pp_t; 164 168 #endif // ! XOSHIRO128PP 165 169 … … 169 173 } // rotl 170 174 171 const uint32_t result = rotl( s [0] + s[3], 7 ) + s[0];172 const uint32_t t = s [1]<< 9;173 174 s [2] ^= s[0];175 s [3] ^= s[1];176 s [1] ^= s[2];177 s [0] ^= s[3];178 s [2]^= t;179 s [3] = rotl( s[3], 11 );175 const uint32_t result = rotl( s0 + s3, 7 ) + s0; 176 const uint32_t t = s1 << 9; 177 178 s2 ^= s0; 179 s3 ^= s1; 180 s1 ^= s2; 181 s0 ^= s3; 182 s2 ^= t; 183 s3 = rotl( s3, 11 ); 180 184 return result; 181 185 } // xoshiro128pp 182 186 183 187 static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) { 184 state = (xoshiro128pp_t){ {seed, seed, seed, seed}};188 state = (xoshiro128pp_t){ seed, seed, seed, seed }; 185 189 xoshiro128pp( state ); // prime 186 190 } // xoshiro128pp_set_seed 187 191 188 192 #ifdef __SIZEOF_INT128__ 189 // Pipelined to allow out-of-order overlap with reduced dependencies. Critically, the current random state is190 // returned (copied), and then compute and store the next random value.191 193 //-------------------------------------------------- 192 194 static inline uint64_t lehmer64( __uint128_t & state ) { … … 197 199 198 200 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 201 // The seed needs to be coprime with the 2^64 modulus to get the argest period, so no factors of 2 in the seed. 199 202 state = seed; 200 lehmer64( state ); 203 lehmer64( state ); // prime 201 204 } // lehmer64_set_seed 202 205 … … 272 275 #endif // ! KISS_64 273 276 274 static inline uint64_t kiss_64( kiss_64_t & state ) with(state) {275 kiss_64_t ret = state;277 static inline uint64_t kiss_64( kiss_64_t & rs ) with(rs) { 278 kiss_64_t ret = rs; 276 279 z = 36969 * (z & 65535) + (z >> 16); 277 280 w = 18000 * (w & 65535) + (w >> 16); 278 jsr ^= (jsr << 17);279 281 jsr ^= (jsr << 13); 282 jsr ^= (jsr >> 17); 280 283 jsr ^= (jsr << 5); 281 284 jcong = 69069 * jcong + 1234567; … … 283 286 } // kiss_64 284 287 285 static inline void kiss_64_set_seed( kiss_64_t & state, uint64_t seed ) with(state) {288 static inline void kiss_64_set_seed( kiss_64_t & rs, uint64_t seed ) with(rs) { 286 289 z = 1; w = 1; jsr = 4; jcong = seed; 287 kiss_64( state );// prime290 kiss_64( rs ); // prime 288 291 } // kiss_64_set_seed 289 292 … … 294 297 #endif // ! XORWOW 295 298 296 static inline uint32_t xorwow( xorwow_t & state ) with(state) {299 static inline uint32_t xorwow( xorwow_t & rs ) with(rs) { 297 300 // Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs". 298 301 uint32_t ret = a + counter; … … 312 315 } // xorwow 313 316 314 static inline void xorwow_set_seed( xorwow_t & state, uint32_t seed ) {315 state= (xorwow_t){ seed, seed, seed, seed, 0 };316 xorwow( state );// prime317 static inline void xorwow_set_seed( xorwow_t & rs, uint32_t seed ) { 318 rs = (xorwow_t){ seed, seed, seed, seed, 0 }; 319 xorwow( rs ); // prime 317 320 } // xorwow_set_seed 318 321 … … 326 329 327 330 // Bi-directional LCG random-number generator 328 static inline uint32_t LCGBI_fwd( uint64_t & state) {329 state = (A * state+ C) & (M - 1);330 return state>> D;331 static inline uint32_t LCGBI_fwd( uint64_t & rs ) { 332 rs = (A * rs + C) & (M - 1); 333 return rs >> D; 331 334 } // LCGBI_fwd 332 335 333 static inline uint32_t LCGBI_bck( uint64_t & state) {334 unsigned int r = state>> D;335 state = AI * (state- C) & (M - 1);336 static inline uint32_t LCGBI_bck( uint64_t & rs ) { 337 unsigned int r = rs >> D; 338 rs = AI * (rs - C) & (M - 1); 336 339 return r; 337 340 } // LCGBI_bck
Note: See TracChangeset
for help on using the changeset viewer.