source: libcfa/src/bits/random.hfa@ 9ee3f54

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 9ee3f54 was 611f29d, checked in by Peter A. Buhr <pabuhr@…>, 4 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.