source: libcfa/src/bits/random.hfa @ 611f29d

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since 611f29d was 611f29d, checked in by Peter A. Buhr <pabuhr@…>, 2 years ago

consolidate random-number generators

  • Property mode set to 100644
File size: 2.5 KB
Line 
1#pragma once
2
3#include <stdint.h>
4
5// Pipelined to allow out-of-order overlap with reduced dependencies. Critically, return the current value, and compute
6// and store the next value.
7
8//--------------------------------------------------
9#if defined(__SIZEOF_INT128__)
10        static inline uint64_t lehmer64( __uint128_t & state ) {
11                __uint128_t ret = state;
12                state *= 0xda942042e4dd58b5;
13                return ret >> 64;
14        }
15
16//--------------------------------------------------
17        static inline uint64_t wyhash64( uint64_t & state ) {
18                state += 0x60bee2bee120fc15;
19                __uint128_t tmp;
20                tmp = (__uint128_t) state * 0xa3b195354a39b70d;
21                uint64_t m1 = (tmp >> 64) ^ tmp;
22                tmp = (__uint128_t)m1 * 0x1b03738712fad5c9;
23                uint64_t m2 = (tmp >> 64) ^ tmp;
24                return m2;
25        }
26#endif
27
28//--------------------------------------------------
29static inline uint64_t xorshift_13_7_17( uint64_t & state ) {
30        uint64_t ret = state;
31        state ^= state << 13;
32        state ^= state >> 7;
33        state ^= state << 17;
34        return ret;
35}
36
37//--------------------------------------------------
38static inline uint32_t xorshift_6_21_7( uint32_t & state ) {
39        uint32_t ret = state;
40        state ^= state << 6;
41        state ^= state >> 21;
42        state ^= state << 7;
43        return ret;
44} // xorshift_6_21_7
45
46//--------------------------------------------------
47typedef struct {
48  uint32_t a, b, c, d;
49  uint32_t counter;
50} xorwow__state_t;
51
52/* The state array must be initialized to not be all zero in the first four words */
53static inline uint32_t xorwow( xorwow__state_t & state ) {
54        /* Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs" */
55        uint32_t ret = state.a + state.counter;
56        uint32_t t = state.d;
57
58        uint32_t const s = state.a;
59        state.d = state.c;
60        state.c = state.b;
61        state.b = s;
62
63        t ^= t >> 2;
64        t ^= t << 1;
65        t ^= s ^ (s << 4);
66        state.a = t;
67
68        state.counter += 362437;
69        return ret;
70}
71
72//--------------------------------------------------
73static inline uint32_t LCG( uint32_t & state ) {                // linear congruential generator
74        uint32_t ret = state;
75        state = 36969 * (state & 65535) + (state >> 16);        // 36969 is NOT prime! No not change it!
76        return ret;
77} // LCG
78
79//--------------------------------------------------
80#define M  (1_l64u << 48_l64u)
81#define A  (25214903917_l64u)
82#define AI (18446708753438544741_l64u)
83#define C  (11_l64u)
84#define D  (16_l64u)
85
86static inline uint32_t LCGBI_fwd( uint64_t & state ) {
87        state = (A * state + C) & (M - 1);
88        return state >> D;
89}
90
91static inline uint32_t LCGBI_bck( uint64_t & state ) {
92        unsigned int r = state >> D;
93        state = AI * (state - C) & (M - 1);
94        return r;
95}
96
97#undef M
98#undef A
99#undef AI
100#undef C
101#undef D
Note: See TracBrowser for help on using the repository browser.