imate
C++/CUDA Reference
Loading...
Searching...
No Matches
xoshiro_256_star_star.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: Copyright 2021, Siavash Ameli <sameli@berkeley.edu>
3 * SPDX-License-Identifier: BSD-3-Clause
4 * SPDX-FileType: SOURCE
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the license found in the LICENSE.txt file in the root
8 * directory of this source tree.
9 */
10
11
12// =======
13// Headers
14// =======
15
17#include <cstdlib> // NULL
18#include "./split_mix_64.h" // SplitMix64
19
20// stdint.h in old compilers (e.g. gcc 4.4.7) does not declare UINT64_C macro.
21#ifndef UINT64_C
22 #define UINT64_C(c) static_cast<uint64_t>(c)
23#endif
24
25
26// ===========
27// Constructor
28// ===========
29
34 state(NULL)
35{
36 // Allocate state
37 this->state = new uint64_t[4];
38
39 // Initializing SplitMix64 random generator
40 SplitMix64 split_mix_64(seed);
41
42 for (int i=0; i < 4; ++i)
43 {
44 this->state[i] = split_mix_64.next();
45 }
46}
47
48
49// ==========
50// Destructor
51// ==========
52
55
57{
58 if (this->state != NULL)
59 {
60 delete[] this->state;
61 this->state = NULL;
62 }
63}
64
65
66// ====
67// next
68// ====
69
72
74{
75 const uint64_t result = this->rotation_left(this->state[1] * 5, 7) * 9;
76
77 const uint64_t t = this->state[1] << 17;
78
79 this->state[2] ^= this->state[0];
80 this->state[3] ^= this->state[1];
81 this->state[1] ^= this->state[2];
82 this->state[0] ^= this->state[3];
83
84 this->state[2] ^= t;
85
86 this->state[3] = this->rotation_left(this->state[3], 45);
87
88 return result;
89}
90
91
92// ====
93// jump
94// ====
95
99
101{
102 static const uint64_t JUMP[] = {
103 0x180ec6d33cfd0aba,
104 0xd5a61266f0c9392c,
105 0xa9582618e03fc9aa,
106 0x39abdc4529b1661c};
107
108 uint64_t s0 = 0;
109 uint64_t s1 = 0;
110 uint64_t s2 = 0;
111 uint64_t s3 = 0;
112
113 for (unsigned int i = 0; i < sizeof(JUMP) / sizeof(*JUMP); ++i)
114 {
115 for (int b = 0; b < 64; ++b)
116 {
117 if (JUMP[i] & UINT64_C(1) << b)
118 {
119 s0 ^= this->state[0];
120 s1 ^= this->state[1];
121 s2 ^= this->state[2];
122 s3 ^= this->state[3];
123 }
124
125 this->next();
126 }
127 }
128
129 this->state[0] = s0;
130 this->state[1] = s1;
131 this->state[2] = s2;
132 this->state[3] = s3;
133}
134
135
136// =========
137// long jump
138// =========
139
144
146{
147 static const uint64_t LONG_JUMP[] = {
148 0x76e15d3efefdcbbf,
149 0xc5004e441c522fb3,
150 0x77710069854ee241,
151 0x39109bb02acbe635};
152
153 uint64_t s0 = 0;
154 uint64_t s1 = 0;
155 uint64_t s2 = 0;
156 uint64_t s3 = 0;
157
158 for (unsigned int i = 0; i < sizeof(LONG_JUMP) / sizeof(*LONG_JUMP); ++i)
159 {
160 for (int b = 0; b < 64; ++b)
161 {
162 if (LONG_JUMP[i] & UINT64_C(1) << b)
163 {
164 s0 ^= this->state[0];
165 s1 ^= this->state[1];
166 s2 ^= this->state[2];
167 s3 ^= this->state[3];
168 }
169
170 this->next();
171 }
172 }
173
174 this->state[0] = s0;
175 this->state[1] = s1;
176 this->state[2] = s2;
177 this->state[3] = s3;
178}
179
180
181// ===========
182// rotate left
183// ===========
184
191
193 const uint64_t x,
194 int k)
195{
196 return (x << k) | (x >> (64 - k));
197}
Pseudo-random integer generator. This class generates 64-bit integer using SplitMix64 algorithm.
uint64_t next()
Generates the next presudo-random number in the sequence.
Xoshiro256StarStar(const int64_t seed)
Constructor. It initializes the state variable with random integers using splitmix64 pseudo-random ge...
static uint64_t rotation_left(const uint64_t x, int k)
Rotates the bits of a 64 bit integer toward left.
void long_jump()
Long jump function for the generator. It is equivalent to 2^192 calls to next(). It can be used to ge...
uint64_t next()
Generates the next presudo-random number.
void jump()
Jump function for the generator. It is equivalent to 2^128 calls to next(); it can be used to generat...
#define UINT64_C(c)