Changeset 4020f09 for libcfa/src/bits


Ignore:
Timestamp:
Dec 5, 2022, 1:23:03 PM (17 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
d4c8b59
Parents:
aadb0c8
Message:

formatting, switch to typedef for PRNG complex state

File:
1 edited

Legend:

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

    raadb0c8 r4020f09  
    1010// Created On       : Fri Jan 14 07:18:11 2022
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec  1 11:52:08 2022
    13 // Update Count     : 115
     12// Last Modified On : Mon Dec  5 13:13:14 2022
     13// Update Count     : 128
    1414//
    1515
     
    3030#define XORSHIFT_13_7_17
    3131#define XORSHIFT_6_21_7
    32 //#define XOSHIRO256PP
    33 //#define XOSHIRO128PP
    3432#endif // __x86_64__
    3533
    36 // C/CFA PRNG name and random-state.
     34// Define C/CFA PRNG name and random-state.
     35
     36// SKULLDUGGERY: typedefs name struct and typedef with the same name to deal with CFA typedef numbering problem.
    3737
    3838#ifdef LEHMER64
     
    5353#ifdef XOSHIRO256PP
    5454#define PRNG_NAME_64 xoshiro256pp
    55 #define PRNG_STATE_64_T struct GLUE(PRNG_NAME_64,_t)
    56 PRNG_STATE_64_T { uint64_t s[4]; };
     55#define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t)
     56typedef struct PRNG_STATE_64_T { uint64_t s[4]; } PRNG_STATE_64_T;
    5757#endif // XOSHIRO256PP
    5858
    5959#ifdef XOSHIRO128PP
    6060#define PRNG_NAME_32 xoshiro128pp
    61 #define PRNG_STATE_32_T struct GLUE(PRNG_NAME_32,_t)
    62 PRNG_STATE_32_T { uint32_t s[4]; };
     61#define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t)
     62typedef struct PRNG_STATE_32_T { uint32_t s[4]; } PRNG_STATE_32_T;
     63#endif // XOSHIRO128PP
     64
     65#ifdef XORWOW
     66#define PRNG_NAME_32 xorwow
     67#define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t)
     68typedef struct PRNG_STATE_32_T { uint32_t a, b, c, d, counter; } PRNG_STATE_32_T;
    6369#endif // XOSHIRO128PP
    6470
     
    8187#ifdef __cforall                                                                                // don't include in C code (invoke.h)
    8288
     89// https://prng.di.unimi.it/xoshiro256starstar.c
     90//
     91// This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.  It has excellent (sub-ns) speed, a state
     92// (256 bits) that is large enough for any parallel application, and it passes all tests we are aware of.
     93//
     94// For generating just floating-point numbers, xoshiro256+ is even faster.
     95//
     96// The state must be seeded so that it is not everywhere zero. If you have a 64-bit seed, we suggest to seed a
     97// splitmix64 generator and use its output to fill s.
     98
     99#ifndef XOSHIRO256PP
     100typedef struct xoshiro256pp_t { uint64_t s[4]; } xoshiro256pp_t;
     101#endif // ! XOSHIRO256PP
     102
     103static inline uint64_t xoshiro256pp( xoshiro256pp_t & rs ) with(rs) {
     104        inline uint64_t rotl(const uint64_t x, int k) {
     105                return (x << k) | (x >> (64 - k));
     106        } // rotl
     107
     108        const uint64_t result = rotl( s[0] + s[3], 23 ) + s[0];
     109        const uint64_t t = s[1] << 17;
     110
     111        s[2] ^= s[0];
     112        s[3] ^= s[1];
     113        s[1] ^= s[2];
     114        s[0] ^= s[3];
     115        s[2] ^= t;
     116        s[3] = rotl( s[3], 45 );
     117        return result;
     118} // xoshiro256pp
     119
     120static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state,  uint64_t seed ) {
     121        state = (xoshiro256pp_t){ {seed, seed, seed, seed} };
     122} // xoshiro256pp_set_seed
     123
    83124// https://prng.di.unimi.it/xoshiro128plusplus.c
    84125//
     
    91132
    92133#ifndef XOSHIRO128PP
    93 struct xoshiro128pp_t { uint32_t s[4]; };
     134typedef struct xoshiro128pp_t { uint32_t s[4]; } xoshiro128pp_t;
    94135#endif // ! XOSHIRO128PP
    95136
     
    97138        inline uint32_t rotl( const uint32_t x, int k ) {
    98139                return (x << k) | (x >> (32 - k));
    99         }
     140        } // rotl
    100141
    101142        const uint32_t result = rotl( s[0] + s[3], 7 ) + s[0];
     
    109150        s[3] = rotl( s[3], 11 );
    110151        return result;
    111 }
     152} // xoshiro128pp
    112153
    113154static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) {
    114155        state = (xoshiro128pp_t){ {seed, seed, seed, seed} };
    115156} // xoshiro128pp_set_seed
    116 
    117 // This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.  It has excellent (sub-ns) speed, a state
    118 // (256 bits) that is large enough for any parallel application, and it passes all tests we are aware of.
    119 //
    120 // For generating just floating-point numbers, xoshiro256+ is even faster.
    121 //
    122 // The state must be seeded so that it is not everywhere zero. If you have a 64-bit seed, we suggest to seed a
    123 // splitmix64 generator and use its output to fill s.
    124 
    125 #ifndef XOSHIRO256PP
    126 struct xoshiro256pp_t { uint64_t s[4]; };
    127 #endif // ! XOSHIRO256PP
    128 
    129 static inline uint64_t xoshiro256pp( xoshiro256pp_t & rs ) with(rs) {
    130         inline uint64_t rotl(const uint64_t x, int k) {
    131                 return (x << k) | (x >> (64 - k));
    132         }
    133 
    134         const uint64_t result = rotl( s[0] + s[3], 23 ) + s[0];
    135         const uint64_t t = s[1] << 17;
    136 
    137         s[2] ^= s[0];
    138         s[3] ^= s[1];
    139         s[1] ^= s[2];
    140         s[0] ^= s[3];
    141         s[2] ^= t;
    142         s[3] = rotl( s[3], 45 );
    143         return result;
    144 }
    145 
    146 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state,  uint64_t seed ) {
    147         state = (xoshiro256pp_t){ {seed, seed, seed, seed} };
    148 } // xoshiro256pp_set_seed
    149157
    150158#ifdef __SIZEOF_INT128__
     
    185193        state ^= state << 17;
    186194        return ret;
    187 }
     195} // xorshift_13_7_17
    188196
    189197static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint32_t seed ) {
    190198        state = seed;
    191 }
    192 
    193 //--------------------------------------------------
     199} // xorshift_13_7_17_set_seed
     200
     201//--------------------------------------------------
     202// Marsaglia shift-XOR PRNG with thread-local state
     203// Period is 4G-1
     204// 0 is absorbing and must be avoided
     205// Low-order bits are not particularly random
    194206static inline uint32_t xorshift_6_21_7( uint32_t & state ) {
    195207        uint32_t ret = state;
     
    202214static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) {
    203215        state = seed;
    204 }
    205 
    206 //--------------------------------------------------
    207 typedef struct {
    208         uint32_t a, b, c, d;
    209         uint32_t counter;
    210 } xorwow__state_t;
    211 
    212 // The state array must be initialized to not be all zero in the first four words.
    213 static inline uint32_t xorwow( xorwow__state_t & state ) {
     216} // xorshift_6_21_7_set_seed
     217
     218//--------------------------------------------------
     219// The state array must be initialized to non-zero in the first four words.
     220#ifndef XORWOW
     221typedef struct xorwow_t { uint32_t a, b, c, d, counter; } xorwow_t;
     222#endif // ! XORWOW
     223
     224static inline uint32_t xorwow( xorwow_t & state ) {
    214225        // Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs".
    215226        uint32_t ret = state.a + state.counter;
     
    228239        state.counter += 362437;
    229240        return ret;
    230 }
    231 
     241} // xorwow
     242
     243static inline void xorwow_set_seed( xorwow_t & state, uint32_t seed ) {
     244        state = (xorwow_t){ seed, seed, seed, seed, 0 };
     245} // xorwow_set_seed
     246
     247//--------------------------------------------------
    232248// Used in __tls_rand_fwd
    233 //--------------------------------------------------
    234249#define M  (1_l64u << 48_l64u)
    235250#define A  (25214903917_l64u)
     
    242257        state = (A * state + C) & (M - 1);
    243258        return state >> D;
    244 }
     259} // LCGBI_fwd
    245260
    246261static inline uint32_t LCGBI_bck( uint64_t & state ) {
     
    248263        state = AI * (state - C) & (M - 1);
    249264        return r;
    250 }
     265} // LCGBI_bck
    251266
    252267#undef M
Note: See TracChangeset for help on using the changeset viewer.