Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/random.hfa

    r90fb672 r12b006c  
    1010// Created On       : Fri Jan 14 07:18:11 2022
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar 20 21:45:24 2023
    13 // Update Count     : 186
     12// Last Modified On : Mon Mar 20 10:01:40 2023
     13// Update Count     : 180
    1414//
    1515
     
    131131#ifdef __cforall                                                                                // don't include in C code (invoke.h)
    132132
     133// Splitmix64
    133134// 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.                             
    138138static inline uint64_t splitmix64( uint64_t & state ) {
    139139    state += 0x9e3779b97f4a7c15;
     
    149149} // splitmix64_set_seed
    150150
     151// Splitmix32
    151152// 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 states
    154 // 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
    156157static inline uint32_t splitmix32( uint32_t & state ) {
    157158    state += 0x9e3779b9;
     
    168169
    169170#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
    197195#endif // __SIZEOF_INT128__
    198196
     
    229227
    230228static 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 );
    233233    uint64_t seed2 = splitmix64( seed );
    234234    uint64_t seed3 = splitmix64( seed );
    235235    uint64_t seed4 = splitmix64( seed );
    236236        state = (xoshiro256pp_t){ seed1, seed2, seed3, seed4 };
     237        xoshiro256pp( state );                                                          // prime
    237238} // xoshiro256pp_set_seed
    238239
     
    268269
    269270static 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 );
    272275    uint32_t seed2 = splitmix32( seed );
    273276    uint32_t seed3 = splitmix32( seed );
    274277    uint32_t seed4 = splitmix32( seed );
    275278        state = (xoshiro128pp_t){ seed1, seed2, seed3, seed4 };
     279        xoshiro128pp( state );                                                          // prime
    276280} // xoshiro128pp_set_seed
    277281
     
    286290
    287291static 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
    289294} // xorshift_13_7_17_set_seed
    290295
     
    303308
    304309static 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
    306312} // xorshift_6_21_7_set_seed
    307313
     
    317323
    318324static 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
    320327} // xorshift_12_25_27_set_seed
    321328
     
    338345
    339346static 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
    341349} // kiss_64_set_seed
    342350
     
    366374
    367375static 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 );
    370380    uint32_t seed2 = splitmix32( seed );
    371381    uint32_t seed3 = splitmix32( seed );
    372382    uint32_t seed4 = splitmix32( seed );
    373383        rs = (xorwow_t){ seed1, seed2, seed3, seed4, 0 };
     384        xorwow( rs );                                                                           // prime
    374385} // xorwow_set_seed
    375386
     
    377388// Used in __tls_rand_fwd
    378389#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)
    381392#define C  (11_l64u)
    382393#define D  (16_l64u)
Note: See TracChangeset for help on using the changeset viewer.