GNU Radio Manual and C++ API Reference  3.7.13.4
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 instruction
38  */
39 static inline uint64_t rotl(const uint64_t x, const int k) {
40  return (x << k) | (x >> (64 - k));
41 }
42 
43 
44 /*! \brief generate the next random number and update the state.
45  * This is the workhorse, here!
46  */
47 static inline uint64_t xoroshiro128p_next(uint64_t *state) {
48  const uint64_t s0 = state[0];
49  uint64_t s1 = state[1];
50  const uint64_t result = s0 + s1;
51 
52  s1 ^= s0;
53  state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
54  state[1] = rotl(s1, 36); // c
55 
56  return result;
57 }
58 
59 
60 /*! \brief Advance the internal state by 2^64 steps; useful when coordinating multiple independent RNGs
61  This is the jump function for the generator. It is equivalent
62  to 2^64 calls to next(); it can be used to generate 2^64
63  non-overlapping subsequences for parallel computations. */
64 static inline void xoroshiro128p_jump(uint64_t *state) {
65  static const uint64_t JUMP[] = { 0xbeac0467eba5facb, 0xd86b048b86aa9922 };
66 
67  uint64_t s0 = 0;
68  uint64_t s1 = 0;
69  for(unsigned int i = 0; i < sizeof (JUMP) / sizeof (*JUMP); ++i) {
70  for(unsigned int b = 0; b < 64; ++b) {
71  if (JUMP[i] & UINT64_C(1) << b) {
72  s0 ^= state[0];
73  s1 ^= state[1];
74  }
75  xoroshiro128p_next(state);
76  }
77  }
78 
79  state[0] = s0;
80  state[1] = s1;
81 }
82 
83 /*! \brief step of the SPLITMIX64 RNG; only used internally for seeding
84  * This RNG isn't as good as XOROSHIRO128+, so it's only used to initialize a 128 bit state from a seed.
85  */
86 static inline uint64_t splitmix64_next(uint64_t *state) {
87  uint64_t z = (*state += 0x9e3779b97f4a7c15);
88  z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
89  z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
90  return z ^ (z >> 31);
91 }
92 
93 /*! \brief Seed the 128 bit state from a 64 bit seed
94  */
95 static inline void xoroshiro128p_seed(uint64_t *state, const uint64_t seed) {
96  state[0] = seed;
97  state[1] = splitmix64_next(state);
98  xoroshiro128p_jump(state);
99 }
100 #ifdef __cplusplus
101 }
102 #endif
103 #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:86
static void xoroshiro128p_seed(uint64_t *state, const uint64_t seed)
Seed the 128 bit state from a 64 bit seed.
Definition: xoroshiro128p.h:95
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:39
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:47
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:64