source: libcfa/src/bits/random.hfa

Last change on this file was e57de69, checked in by Peter A. Buhr <pabuhr@…>, 6 days ago

formatting

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