GNU Radio Manual and C++ API Reference  3.8.1.0
The Free & Open Software Radio Ecosystem
xoroshiro128p.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Free Software Foundation, Inc.
3  *
4  * This file is part of GNU Radio
5  *
6  * GNU Radio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU Radio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GNU Radio; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 // Built on XOROSHIRO128+ by David Blackman and Sebastiano Vigna who put this
23 // under CC-0, colloquially known as "public domain (or as close you get to that
24 // in your local legislation)" see
25 // http://xoroshiro.di.unimi.it/xoroshiro128plus.c
26 // Conversion to a local state (original used global state) done by Marcus
27 // Müller, 2018.
28 #ifndef INCLUDED_XOROSHIRO128P_H
29 #define INCLUDED_XOROSHIRO128P_H
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 #include <stdint.h>
35 
36 /*! \brief rotating left shift helper
37  * According to the original authors, this will on most platforms reduce to a single
38  * instruction
39  */
40 static inline uint64_t rotl(const uint64_t x, const int k)
41 {
42  return (x << k) | (x >> (64 - k));
43 }
44 
45 
46 /*! \brief generate the next random number and update the state.
47  * This is the workhorse, here!
48  */
49 static inline uint64_t xoroshiro128p_next(uint64_t* state)
50 {
51  const uint64_t s0 = state[0];
52  uint64_t s1 = state[1];
53  const uint64_t result = s0 + s1;
54 
55  s1 ^= s0;
56  state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
57  state[1] = rotl(s1, 36); // c
58 
59  return result;
60 }
61 
62 
63 /*! \brief Advance the internal state by 2^64 steps; useful when coordinating multiple
64  independent RNGs This is the jump function for the generator. It is equivalent to 2^64
65  calls to next(); it can be used to generate 2^64 non-overlapping subsequences for
66  parallel computations. */
67 static inline void xoroshiro128p_jump(uint64_t* state)
68 {
69  static const uint64_t JUMP[] = { 0xbeac0467eba5facb, 0xd86b048b86aa9922 };
70 
71  uint64_t s0 = 0;
72  uint64_t s1 = 0;
73  for (unsigned int i = 0; i < sizeof(JUMP) / sizeof(*JUMP); ++i) {
74  for (unsigned int b = 0; b < 64; ++b) {
75  if (JUMP[i] & UINT64_C(1) << b) {
76  s0 ^= state[0];
77  s1 ^= state[1];
78  }
79  xoroshiro128p_next(state);
80  }
81  }
82 
83  state[0] = s0;
84  state[1] = s1;
85 }
86 
87 /*! \brief step of the SPLITMIX64 RNG; only used internally for seeding
88  * This RNG isn't as good as XOROSHIRO128+, so it's only used to initialize a 128 bit
89  * state from a seed.
90  */
91 static inline uint64_t splitmix64_next(uint64_t* state)
92 {
93  uint64_t z = (*state += 0x9e3779b97f4a7c15);
94  z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
95  z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
96  return z ^ (z >> 31);
97 }
98 
99 /*! \brief Seed the 128 bit state from a 64 bit seed
100  */
101 static inline void xoroshiro128p_seed(uint64_t* state, const uint64_t seed)
102 {
103  state[0] = seed;
104  state[1] = splitmix64_next(state);
105  xoroshiro128p_jump(state);
106 }
107 #ifdef __cplusplus
108 }
109 #endif
110 #endif // Include guard
static uint64_t splitmix64_next(uint64_t *state)
step of the SPLITMIX64 RNG; only used internally for seeding This RNG isn&#39;t as good as XOROSHIRO128+...
Definition: xoroshiro128p.h:91
static void xoroshiro128p_seed(uint64_t *state, const uint64_t seed)
Seed the 128 bit state from a 64 bit seed.
Definition: xoroshiro128p.h:101
static uint64_t rotl(const uint64_t x, const int k)
rotating left shift helper According to the original authors, this will on most platforms reduce to a...
Definition: xoroshiro128p.h:40
static uint64_t xoroshiro128p_next(uint64_t *state)
generate the next random number and update the state. This is the workhorse, here! ...
Definition: xoroshiro128p.h:49
static void xoroshiro128p_jump(uint64_t *state)
Advance the internal state by 2^64 steps; useful when coordinating multiple independent RNGs This is ...
Definition: xoroshiro128p.h:67