8000 ENH: randomgen by mattip · Pull Request #13163 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: randomgen #13163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 139 commits into from
May 28, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
3102fc6
INIT: Initial commit with basic structure
bashtage Feb 20, 2018
fa3bef5
ENH: Add support for xoroshiro128
bashtage Feb 22, 2018
d59494c
ENH: Add entropy initialization to RNGS
bashtage Feb 23, 2018
8942968
ENH: Add seeding to generators
bashtage Feb 23, 2018
aa9060c
CLN: Simplify xoroshiro state
bashtage Feb 24, 2018
b353f87
REF: Add additional state
bashtage Feb 26, 2018
15cab3c
REF: Reactor filler to take a function
bashtage Feb 28, 2018
8367231
ENH: Add extra abstraction
bashtage Feb 28, 2018
d5dc576
ENH: Add float from double and std exponential
bashtage Feb 28, 2018
f4575d9
BUG: Fix bug in xoroshiro
bashtage Mar 1, 2018
c687b84
CLN: Fix warning in entropy
bashtage Mar 1, 2018
0d4eae3
REF: Add types to prng_t
bashtage Mar 1, 2018
27a96bb
ENH: Add Threefry generator
bashtage Mar 2, 2018
a5f17a5
ENH: Use Random123 threefry
bashtage Mar 2, 2018
56fd6e7
CLN: Remove unnecessary code from threefry
bashtage Mar 2, 2018
93b7edf
ENH: Add pickle support
bashtage Mar 3, 2018
d665138
DOC: Add list of TODOs
bashtage Mar 3, 2018
892d43f
BIG: Fix setting state in threee fry
bashtage Mar 3, 2018
ad79fe0
ENH: Add jump and advance to threefry
bashtage Mar 3, 2018
4b2afc2
ENH: Add PCG64
bashtage Mar 4, 2018
6b81fa0
ENH: Add advance and jump to PCG64
bashtage Mar 4, 2018
e150e1a
ENH: Add Philox
bashtage Mar 5, 2018
d6d3ac9
CLN: Remove splitmix64 as a visible PRNG
bashtage Mar 5, 2018
323616c
BUG: Fix bugs which prevented building on Linux
bashtage Mar 5, 2018
626a1a0
REF: Refactor distributions
bashtage Mar 5, 2018
5fe7572
ENH: Add std gamma
bashtage Mar 5, 2018
cecd56d
CLN: Clean random123 generators
bashtage Mar 6, 2018
a071378
CLN: Fix dsfmt import issues
bashtage Mar 7, 2018
eab3390
ENH: Enable Python 2.7 compatability
bashtage Mar 7, 2018
c3155db
ENH: Add jump to mt19937 and dsfmt
bashtage Mar 7, 2018
e9e0a8c
ENH: Add ctypes interface and examples
bashtage Mar 7, 2018
0e5ffae
CLN: Mix skipped nogils
bashtage Mar 7, 2018
5d274af
ENH: Add cffi interface
bashtage Mar 7, 2018
2f9b9c0
ENH: Add example using distributions
bashtage Mar 8, 2018
fcef7ae
ENH: Enable building distributions as a DLL
bashtage Mar 8, 2018
1235545
ENH: Port over external functions
bashtage Mar 8, 2018
7ca6e62
ENH: Add bounded intergers
bashtage Mar 9, 2018
cfe9e95
ENH: Add support for Philon on 32 bit Windows
bashtage Mar 11, 2018
390860a
ENH: Add support for ThreeFry32x4
bashtage Mar 12, 2018
8fa8c2b
BUG: Enable build to run on 32-bit Linux
bashtage Mar 12, 2018
644d883
ENH: Add PCG32
bashtage Mar 12, 2018
e81e93f
BUG: Fix variable declarations in dsfmt
bashtage Mar 12, 2018
76a31a9
ENH: Enable testing on OSX
bashtage Mar 12, 2018
c1f4fa0
REF: Drop Box-Muller
bashtage Mar 13, 2018
ee51dcf
REF: Remove binomial_t from prng
bashtage Mar 13, 2018
fde7742
ENH: Switch to int64
bashtage Mar 13, 2018
fb98ac5
DOC: Start documentation
bashtage Mar 14, 2018
cb24575
REF: Rename from Core PRNG to RandomGen
bashtage Mar 14, 2018
c722f44
DOC: Update docs
bashtage Mar 14, 2018
e69d24c
TST: Improve travis
bashtage Mar 14, 2018
a85ee48
BUG: Fix failing test
bashtage Mar 14, 2018
701326e
DOC: Fix location of tagged docs
bashtage Mar 14, 2018
9e18b77
BLD: Ensure emulated math is used in 32 bit platforms
bashtage Mar 16, 2018
3e69d17
CLN: Remove references to long
bashtage Mar 22, 2018
489015f
ENH: Add Box-Muller gauss
bashtage Mar 21, 2018
8711b32
DOC: Update multithreading doc
bashtage Mar 27, 2018
018faf7
CLN: Remove set/get state for system generator
bashtage Mar 27, 2018
75025d9
TST: Fix tailing test on 32bit platofrms
bashtage Mar 27, 2018
4f37499
CLN: Fix str for RandomGenerator
bashtage Mar 28, 2018
7d37f5f
DOC: Update legacy docs
bashtage Mar 28, 2018
a2e21e6
BUG: Fix pickle for LegacyGenerator
bashtage Mar 28, 2018
d13f398
DOC: Spelling changes
bashtage Apr 2, 2018
df1758d
CLN: Remove redeclared type
bashtage Apr 2, 2018
412e908
BLD: Enable no-sse2 flag
bashtage Apr 3, 2018
87b52f2
SYNC/CLN: Sync with upstream changes
bashtage Apr 16, 2018
db87d7d
BLD: Add lm flag for non-windows platforms
bashtage May 2, 2018
b41949e
ENH: Add dSFMT
bashtage Mar 5, 2018
a9cb58d
ENH: Add out, ziggurat for exponential
bashtage Mar 5, 2018
92a09f3
TST: Add test and benchmark code
bashtage Mar 6, 2018
f029ebb
ENH: Improve benchmark
bashtage Mar 6, 2018
8777c61
CLN: Reformat C files
bashtage Mar 7, 2018
784315e
ENH: Example numba example using external distributions
bashtage Mar 8, 2018
5b262ef
BUG: Precent GC of CorePRNG when using CFFI/CTypes
bashtage Mar 8, 2018
65ceada
TST: Add tests
bashtage Mar 9, 2018
3b7b1e4
DOC: Update readme
bashtage Mar 11, 2018
a8882b2
CLN: Remove small bugs and alter variable size
bashtage Mar 12, 2018
dc0c84b
BUG: Fix returned type
bashtage Mar 13, 2018
f060614
DOC: Update docs and building
bashtage Mar 14, 2018
5d3d955
ENH: Restore filler
bashtage Mar 15, 2018
ce30b74
TST: Improve testing and build
bashtage Mar 17, 2018
447e6b3
DOC: Update change-log and docs
bashtage Mar 17, 2018
50e7242
BUG: Restore nogil for fillers
bashtage Mar 21, 2018
799e20b
TST: Make test more verbose, clean up noise
bashtage Mar 28, 2018
80a3fe1
BUG: Fix absolute_import
bashtage Apr 2, 2018
d780f06
DOC: Fix doc and example error
pdebuyl May 22, 2018
fdd029f
REF: Rename min and max macros
bashtage Jun 14, 2018
3dba22d
MAINT: Sync with NumPy changes
bashtage Jun 19, 2018
f2ace10
ENH: Allow empty choice
bashtage Jul 3, 2018
d0cb154
DOC: Provide a better explanation of bounded int generation
bashtage Sep 22, 2018
8e6b69f
MAINT: Sync with recent upstream changes
bashtage Sep 22, 2018
99bf1a0
DOC: Update docs for 1.15 release [skip ci]
bashtage Sep 22, 2018
8dba0e9
ENH: Added an alternative interval generator using Lemire's algorithm.
bduvenhage Oct 3, 2018
13d8999
DOC: Add license files
bashtage Oct 5, 2018
707371d
REF: Add path using umul
bashtage Oct 5, 2018
15bebed
ENH: Added Lemire algorithms for generating random numbers
bduvenhage Oct 11, 2018
734fbfb
CLN: Add guards to headers
bashtage Oct 21, 2018
c4ed60e
ENH/BUG: Add Xoshiro256starstar generator
bashtage Oct 20, 2018
9dac6a5
MAINT: Sync with upstream changes
bashtage Nov 5, 2018
578889b
BUG: Ensure buffer_loc is reset in DSFMT
bashtage Feb 4, 2019
896f2e4
BUG: Raise on nan probabilities
bashtage Feb 4, 2019
fa8af41
BUILD: move files out of _randomgen
mattip Mar 20, 2019
7e8e19f
BUG: Correct handling of nans
bashtage Apr 8, 2019
c53b2eb
BENCH: convert bencmarks to asv format
mattip Apr 9, 2019
9578dcf
BUG: __dealloc__ can be called without __init__ in some error modes
mattip Apr 12, 2019
0f3dd06
ENH: Extend multinomial and fix zipf
bashtage Apr 11, 2019
8a3c11d
DOC: Add alias docstrings for sample and ranf
bashtage Apr 12, 2019
bb7abf2
ENH: add instance of RandomGenerator(Xoshiro512StarStar) as gen
mattip Apr 12, 2019
f11921d
MAINT: Simplify return types
bashtage Apr 12, 2019
0f931b3
BUG: Fix type in zipf
bashtage Apr 13, 2019
b2f9bea
ENH: Improvce choice without replacement
bashtage Apr 13, 2019
7a41794
DOC: fix doctests, move numpy.random -> numpy.random.gen in generator…
mattip Apr 13, 2019
edfd313
ENH: Finish hypergeometric 0
bashtage Apr 13, 2019
b9b9d70
MAINT: remove legacy, refactor legacy -> mtrand in docs
mattip Apr 14, 2019
2deddc8
MAINT: Remove Cython conditionals
bashtage Apr 14, 2019
d531f92
BUG: Protect gamma generation from 0 input
bashtage Feb 18, 2019
6e386c0
DOC/ENH: Update docstring and enhance logistic
bashtage Feb 19, 2019
8621229
DOC: tighten up documentation, add a table of comparison
mattip Apr 14, 2019
4f06779
ENH: Add fast path for randint broadcasting
bashtage Apr 15, 2019
ca9c542
BUG: Cast high to Python int to avoid overflow
bashtage Apr 15, 2019
dd77ce3
ENH: Add closed generator to randint
bashtage Apr 16, 2019
17e0070
MAINT: Implement API changes for randomgen-derived code
mattip May 13, 2019
b42a5ca
BUG: Ensure integer-type stream on 32bit
bashtage May 18, 2019
720a0a9
BLD: Use numpy detection of SSE
bashtage May 19, 2019
e058ae4
MAINT: remove unused file
mattip May 20, 2019
3d19ae9
MAINT: remove threefry32, xoroshiro128, xorshift1024 BitGenerators
mattip May 20, 2019
060c669
merge master into branch
mattip May 22, 2019
4e6a812
MAINT: remove pre-randomgen _mtrand
mattip May 23, 2019
19b48e2
BUG: test, fix missing return to deprecated function
mattip May 23, 2019
cdb2b0f
MAINT: remove tomaxint, random_sample from generator
mattip May 23, 2019
2c14e47
ENH: Split poisson_lam_max
bashtage May 23, 2019
457c6c5
MAINT: Remove test_against_numpy
bashtage May 23, 2019
9e5ae61
BUG: Change renamed attribute
bashtage May 23, 2019
7c52c28
DOC: Add __all__ and document lock
bashtage May 23, 2019
dabf42b
MAINT: Remove remnants of bit generators
bashtage May 23, 2019
3db5a77
BLD: Improve setup
bashtage May 23, 2019
58c0e72
Revert "MAINT: Implement API changes for randomgen-derived code"
bashtage May 24, 2019
23853d6
STY: Clean up code
bashtage May 24, 2019
9c261e6
PERF: Reorder header for philox (#34)
bashtage May 27, 2019
70d6293
MAINT: fix for dtype specification
mattip May 27, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ENH: Add support for xoroshiro128
Clean up splitmix64 to use external functions
Add xoroshiro128 to show use of additional PRNG
  • Loading branch information
bashtage committed May 20, 2019
commit fa3bef5639b2f3223eeee7c50155824b8df991e0
17 changes: 13 additions & 4 deletions _randomgen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,19 @@ python setup.py develop
```

```ipython
In [13]: import core_prng.generator
In [1]: import core_prng.generator

In [14]: rg = core_prng.generator.RandomGenerator()
# Default generator is Splitmix64
In [2]: rg = core_prng.generator.RandomGenerator()

In [15]: rg.random_integer()
Out[15]: 872337561037043212
In [3]: rg.random_integer()
Out[3]: 872337561037043212

In [4]: from core_prng.xoroshiro128 import Xoroshiro128

# Swap the generator
In [5]: rg = core_prng.generator.RandomGenerator(Xoroshiro128())

In [6]: rg.random_integer()
Out[6]: 13370384800127340062
```
Empty file removed _randomgen/core_prng/common.c
Empty file.
Empty file removed _randomgen/core_prng/common.h
Empty file.
14 changes: 10 additions & 4 deletions _randomgen/core_prng/generator.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cimport numpy as np
from cpython.pycapsule cimport PyCapsule_IsValid, PyCapsule_GetPointer
from common cimport *

from core_prng.core_prng import CorePRNG
from core_prng.splitmix64 import SplitMix64

np.import_array()

Expand All @@ -24,18 +24,24 @@ cdef class RandomGenerator:
"""
cdef public object __core_prng
cdef anon_func_state anon_rng_func_state
cdef random_uint64_anon next_uint64
cdef void *rng_state

def __init__(self, prng=None):
if prng is None:
prng = CorePRNG()
prng = SplitMix64()
self.__core_prng = prng

capsule = prng._anon_func_state
cdef const char *anon_name = "Anon CorePRNG func_state"
if not PyCapsule_IsValid(capsule, anon_name):
raise ValueError("Invalid pointer to anon_func_state")
self.anon_rng_func_state = (<anon_func_state *>PyCapsule_GetPointer(capsule, anon_name))[0]
self.next_uint64 = <random_uint64_anon>self.anon_rng_func_state.f
self.rng_state = self.anon_rng_func_state.state

def random_integer(self):
cdef random_uint64_anon f = <random_uint64_anon>self.anon_rng_func_state.f
return f(self.anon_rng_func_state.state)
return self.next_uint64(self.rng_state)

def random_double(self):
return (self.next_uint64(self.rng_state) >> 11) * (1.0 / 9007199254740992.0)
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,22 @@ from common cimport *

np.import_array()

cdef struct state:
uint64_t state
cdef extern from "src/splitmix64/splitmix64.h":

ctypedef state state_t
cdef struct s_splitmix64_state:
uint64_t state

ctypedef uint64_t (*random_uint64)(state_t *st)
ctypedef s_splitmix64_state splitmix64_state

cdef struct func_state:
state st
random_uint64 f
cdef uint64_t splitmix64_next(splitmix64_state* state) nogil

ctypedef func_state func_state_t

ctypedef uint64_t (*random_uint64)(splitmix64_state* state)

cdef uint64_t _splitmix64(state_t *st):
cdef uint64_t z
# TODO: Use literals -- PyCharm complains
cdef uint64_t c1 = 11400714819323198485
cdef uint64_t c2 = 13787848793156543929
cdef uint64_t c3 = 10723151780598845931
st[0].state += c1 # 0x9E3779B97F4A7C15
z = <uint64_t>st[0].state
z = (z ^ (z >> 30)) * c2 # 0xBF58476D1CE4E5B9
z = (z ^ (z >> 27)) * c3 # 0x94D049BB133111EB
return z ^ (z >> 31)
cdef uint64_t _splitmix64_anon(void* st) nogil:
return splitmix64_next(<splitmix64_state *>st)

cdef uint64_t _splitmix64_anon(void* st):
return _splitmix64(<state *> st)

cdef class CorePRNG:
cdef class SplitMix64:
"""
Prototype Core PRNG using directly implemented version of SplitMix64.

Expand All @@ -44,7 +30,7 @@ cdef class CorePRNG:
Exposes no user-facing API except `get_state` and `set_state`. Designed
for use in a `RandomGenerator` object.
"""
cdef state rng_state
cdef splitmix64_state rng_state
cdef anon_func_state anon_func_state
cdef public object _anon_func_state

Expand All @@ -70,7 +56,7 @@ cdef class CorePRNG:
-----
Testing only
"""
return _splitmix64(&self.rng_state)
return splitmix64_next(&self.rng_state)

def get_state(self):
"""Get PRNG state"""
Expand Down
25 changes: 25 additions & 0 deletions _randomgen/core_prng/src/splitmix64/splitmix64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Written in 2015 by Sebastiano Vigna (vigna@acm.org)

To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.

See <http://creativecommons.org/publicdomain/zero/1.0/>.

Modified 2018 by Kevin Sheppard. Modifications licensed under the NCSA
license.
*/

/* This is a fixed-increment version of Java 8's SplittableRandom generator
See http://dx.doi.org/10.1145/2714064.2660195 and
http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html

It is a very fast generator passing BigCrush, and it can be useful if
for some reason you absolutely want 64 bits of state; otherwise, we
rather suggest to use a xoroshiro128+ (for moderately parallel
computations) or xorshift1024* (for massively parallel computations)
generator. */

#include "splitmix64.h"

extern inline uint64_t splitmix64_next(splitmix64_state *state);
12 changes: 12 additions & 0 deletions _randomgen/core_prng/src/splitmix64/splitmix64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <stdint.h>

typedef struct s_splitmix64_state {
uint64_t state;
} splitmix64_state;

static inline uint64_t splitmix64_next(splitmix64_state *state) {
uint64_t z = (state->state += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
28 changes: 28 additions & 0 deletions _randomgen/core_prng/src/splitmix64/splitmix64.orig.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Written in 2015 by Sebastiano Vigna (vigna@acm.org)

To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.

See <http://creativecommons.org/publicdomain/zero/1.0/>. */

#include <stdint.h>

/* This is a fixed-increment version of Java 8's SplittableRandom generator
See http://dx.doi.org/10.1145/2714064.2660195 and
http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html

It is a very fast generator passing BigCrush, and it can be useful if
for some reason you absolutely want 64 bits of state; otherwise, we
rather suggest to use a xoroshiro128+ (for moderately parallel
computations) or xorshift1024* (for massively parallel computations)
generator. */

uint64_t x; /* The state can be seeded with any value. */

uint64_t next() {
uint64_t z = (x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
53 changes: 53 additions & 0 deletions _randomgen/core_prng/src/xoroshiro128/xoroshiro128.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)

To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.

See <http://creativecommons.org/publicdomain/zero/1.0/>. */

/* This is the successor to xorshift128+. It is the fastest full-period
generator passing BigCrush without systematic failures, but due to the
relatively short period it is acceptable only for applications with a
mild amount of parallelism; otherwise, use a xorshift1024* generator.

Beside passing BigCrush, this generator passes the PractRand test suite
up to (and included) 16TB, with the exception of binary rank tests, as
the lowest bit of this generator is an LFSR of degree 128. The next bit
can be described by an LFSR of degree 8256, but in the long run it will
fail linearity tests, too. The other bits needs a much higher degree to
be represented as LFSRs.

We suggest to use a sign test to extract a random Boolean value, and
right shifts to extract subsets of bits.

Note that the generator uses a simulated rotate operation, which most C
compilers will turn into a single instruction. In Java, you can use
Long.rotateLeft(). In languages that do not make low-level rotation
instructions accessible xorshift128+ could be faster.

The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s. */

#include "xoroshiro128.h"

extern inline uint64_t xoroshiro128_next(xoroshiro128_state *state);

void xoroshiro128_jump(xoroshiro128_state *state) {
static const uint64_t JUMP[] = {0xbeac0467eba5facb, 0xd86b048b86aa9922};

uint64_t s0 = 0;
uint64_t s1 = 0;
for (int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
for (int b = 0; b < 64; b++) {
if (JUMP[i] & UINT64_C(1) << b) {
s0 ^= state->s[0];
s1 ^= state->s[1];
}
xoroshiro128_next(state);
}

state->s[0] = s0;
state->s[1] = s1;
}
23 changes: 23 additions & 0 deletions _randomgen/core_prng/src/xoroshiro128/xoroshiro128.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <stdint.h>

typedef struct s_xoroshiro128_state {
uint64_t s[2];
} xoroshiro128_state;

static inline uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}

static inline uint64_t xoroshiro128_next(xoroshiro128_state *state) {
const uint64_t s0 = state->s[0];
uint64_t s1 = state->s[1];
const uint64_t result = s0 + s1;

s1 ^= s0;
state->s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
state->s[1] = rotl(s1, 36); // c

return result;
}

void xoroshiro128_jump(xoroshiro128_state *state);
74 changes: 74 additions & 0 deletions _randomgen/core_prng/src/xoroshiro128/xoroshiro128plus.orig.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)

To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.

See <http://creativecommons.org/publicdomain/zero/1.0/>. */

#include <stdint.h>

/* This is the successor to xorshift128+. It is the fastest full-period
generator passing BigCrush without systematic failures, but due to the
relatively short period it is acceptable only for applications with a
mild amount of parallelism; otherwise, use a xorshift1024* generator.

Beside passing BigCrush, this generator passes the PractRand test suite
up to (and included) 16TB, with the exception of binary rank tests, as
the lowest bit of this generator is an LFSR of degree 128. The next bit
can be described by an LFSR of degree 8256, but in the long run it will
fail linearity tests, too. The other bits needs a much higher degree to
be represented as LFSRs.

We suggest to use a sign test to extract a random Boolean value, and
right shifts to extract subsets of bits.

Note that the generator uses a simulated rotate operation, which most C
compilers will turn into a single instruction. In Java, you can use
Long.rotateLeft(). In languages that do not make low-level rotation
instructions accessible xorshift128+ could be faster.

The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s. */

uint64_t s[2];

static inline uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}

uint64_t next(void) {
const uint64_t s0 = s[0];
uint64_t s1 = s[1];
const uint64_t result = s0 + s1;

s1 ^= s0;
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
s[1] = rotl(s1, 36); // c

return result;
}


/* This is the jump function for the generator. It is equivalent
to 2^64 calls to next(); it can be used to generate 2^64
non-overlapping subsequences for parallel computations. */

void jump(void) {
static const uint64_t JUMP[] = { 0xbeac0467eba5facb, 0xd86b048b86aa9922 };

uint64_t s0 = 0;
uint64_t s1 = 0;
for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
for(int b = 0; b < 64; b++) {
if (JUMP[i] & UINT64_C(1) << b) {
s0 ^= s[0];
s1 ^= s[1];
}
next();
}

s[0] = s0;
s[1] = s1;
}
Loading
0