kerep sources
This commit is contained in:
72
kerep/src/random/krandom.h
Normal file
72
kerep/src/random/krandom.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../base/std.h"
|
||||
#include "splitmix64/splitmix64.h"
|
||||
#include "xoroshiro/xoroshiro.h"
|
||||
#include "xoshiro/xoshiro.h"
|
||||
|
||||
/*
|
||||
You can choose any algorithm that has required functions:
|
||||
|
||||
some_alg32_statePtr some_alg32_init(u32 seed);
|
||||
u32 some_alg32_next(some_alg32_statePtr);
|
||||
void some_alg32_free(some_alg32_statePtr);
|
||||
|
||||
#define KRAND_ALG32_init some_alg32_init
|
||||
#define KRAND_ALG32_next some_alg32_next
|
||||
#define KRAND_ALG32_free some_alg32_free
|
||||
#include "kerep/random/krandom.h"
|
||||
|
||||
The same way it works for 64-bit RNGs
|
||||
*/
|
||||
|
||||
// default rng_next function
|
||||
#ifndef KRAND_ALG32_next
|
||||
#define KRAND_ALG32_next xoshiro128plus##_next
|
||||
#endif
|
||||
#ifndef KRAND_ALG32_init
|
||||
#define KRAND_ALG32_init xoshiro128plus##_init
|
||||
#endif
|
||||
#ifndef KRAND_ALG32_free
|
||||
#define KRAND_ALG32_free xoshiro128plus##_free
|
||||
#endif
|
||||
#ifndef KRAND_ALG64_next
|
||||
#define KRAND_ALG64_next xoshiro256plus##_next
|
||||
#endif
|
||||
#ifndef KRAND_ALG64_init
|
||||
#define KRAND_ALG64_init xoshiro256plus##_init
|
||||
#endif
|
||||
#ifndef KRAND_ALG64_free
|
||||
#define KRAND_ALG64_free xoshiro256plus##_free
|
||||
#endif
|
||||
|
||||
typedef void* krand_statePtr;
|
||||
#define KRAND_ALG32_initFromTime xoshiro128plus##_initFromTime
|
||||
#define KRAND_ALG64_initFromTime xoshiro256plus##_initFromTime
|
||||
|
||||
#define __krand_next_definition(VALUE_SIZE) { return from+KRAND_ALG##VALUE_SIZE##_next(state)%(to-from); }
|
||||
|
||||
// ready-to-use functions
|
||||
static inline i8 krand_next8 (krand_statePtr state, i8 from, i8 to) __krand_next_definition(32)
|
||||
static inline i16 krand_next16(krand_statePtr state, i16 from, i16 to) __krand_next_definition(32)
|
||||
static inline i32 krand_next32(krand_statePtr state, i32 from, i32 to) __krand_next_definition(32)
|
||||
static inline i64 krand_next64(krand_statePtr state, i64 from, i64 to) __krand_next_definition(64)
|
||||
|
||||
// divides random number by 2^64 to return a value between 0 and 1
|
||||
static inline f32 krand_nextFloat32(krand_statePtr state) {return (u32)KRAND_ALG32_next(state)/0xffffffff; }
|
||||
static inline f64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; }
|
||||
|
||||
|
||||
///@param chance (0-1.0) is probability of success
|
||||
static inline bool fate(krand_statePtr state,float chance){
|
||||
i32 limit=1/chance + 0.01f;
|
||||
return KRAND_ALG32_next(state)%limit == 0;
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
34
kerep/src/random/splitmix64/splitmix64.c
Normal file
34
kerep/src/random/splitmix64/splitmix64.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "splitmix64.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.
|
||||
*/
|
||||
|
||||
// The state can be seeded with any (upto) 64 bit integer value.
|
||||
|
||||
void* splitmix64_init(u64 seed){
|
||||
splitmix64_state* state=malloc(sizeof(splitmix64_state));
|
||||
*state=seed;
|
||||
return state;
|
||||
}
|
||||
|
||||
u64 splitmix64_next(void* _state) {
|
||||
splitmix64_state* state=_state;
|
||||
// increment the state variable
|
||||
*state += 0x9e3779b97f4a7c15;
|
||||
// copy the state to a working variable
|
||||
u64 z = *state;
|
||||
// xor the variable with the variable right bit shifted 30 then multiply by a constant
|
||||
z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9;
|
||||
// xor the variable with the variable right bit shifted 27 then multiply by a constant
|
||||
z = (z ^ (z>>27)) * 0x94d049bb133111eb;
|
||||
// return the variable xored with itself right bit shifted 31
|
||||
return z ^ (z>>31);
|
||||
}
|
||||
22
kerep/src/random/splitmix64/splitmix64.h
Normal file
22
kerep/src/random/splitmix64/splitmix64.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../base/base.h"
|
||||
|
||||
typedef u64 splitmix64_state;
|
||||
typedef void* splitmix64_statePtr;
|
||||
|
||||
splitmix64_statePtr splitmix64_init(u64 seed);
|
||||
static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); }
|
||||
|
||||
u64 splitmix64_next(splitmix64_statePtr);
|
||||
static inline void splitmix64_free(splitmix64_statePtr state) {
|
||||
free(state);
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
35
kerep/src/random/xoroshiro/32bitValue/xoroshiro64.h
Normal file
35
kerep/src/random/xoroshiro/32bitValue/xoroshiro64.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../../base/std.h"
|
||||
#include "../../splitmix64/splitmix64.h"
|
||||
|
||||
typedef union {
|
||||
u64 merged;
|
||||
u32 s[2];
|
||||
} xoroshiro64_state;
|
||||
typedef void* xoroshiro64_statePtr;
|
||||
|
||||
xoroshiro64_statePtr xoroshiro64_init(u64 seed);
|
||||
#define xoroshiro64star_init xoroshiro64_init
|
||||
#define xoroshiro64starstar_init xoroshiro64_init
|
||||
|
||||
static inline xoroshiro64_statePtr xoroshiro64_initFromTime(void) { return xoroshiro64_init(time(NULL)); }
|
||||
#define xoroshiro64star_initFromTime xoroshiro64_initFromTime
|
||||
#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
|
||||
|
||||
u32 xoroshiro64star_next(xoroshiro64_statePtr);
|
||||
u32 xoroshiro64starstar_next(xoroshiro64_statePtr);
|
||||
|
||||
static inline void xoroshiro64_free(xoroshiro64_statePtr state) {
|
||||
free(state);
|
||||
}
|
||||
#define xoroshiro64star_free xoroshiro64_free
|
||||
#define xoroshiro64starstar_free xoroshiro64_free
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
49
kerep/src/random/xoroshiro/32bitValue/xoroshiro64star.c
Normal file
49
kerep/src/random/xoroshiro/32bitValue/xoroshiro64star.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* 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 "xoroshiro64.h"
|
||||
|
||||
/*
|
||||
This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
|
||||
generator for 32-bit floating-poi32 numbers. We suggest to use its
|
||||
upper bits for floating-poi32 generation, as it is slightly faster than
|
||||
xoroshiro64**. It passes all tests we are aware of except for linearity
|
||||
tests, as the lowest six bits have low linear complexity, so if low
|
||||
linear complexity is not considered an issue (as it is usually the
|
||||
case) it can be used to generate 32-bit outputs, too.
|
||||
|
||||
We suggest to use a sign test to extract a random Boolean value, and
|
||||
right shifts to extract subsets of bits.
|
||||
|
||||
The state must be seeded so that it is not everywhere zero.
|
||||
*/
|
||||
|
||||
static inline u32 rotl(const u32 x, i32 k) {
|
||||
return (x << k) | (x >> (32 - k));
|
||||
}
|
||||
|
||||
u32 xoroshiro64star_next(void* _state) {
|
||||
xoroshiro64_state* state=_state;
|
||||
const u32 s0 = state->s[0];
|
||||
u32 s1 = state->s[1];
|
||||
const u32 result = s0 * 0x9E3779BB;
|
||||
|
||||
s1 ^= s0;
|
||||
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
|
||||
state->s[1] = rotl(s1, 13); // c
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* xoroshiro64_init(u64 seed){
|
||||
xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state));
|
||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||
state->merged=splitmix64_next(splitmix);
|
||||
splitmix64_free(splitmix);
|
||||
return state;
|
||||
}
|
||||
37
kerep/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c
Normal file
37
kerep/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Written in 2018 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 "xoroshiro64.h"
|
||||
|
||||
/* This is xoroshiro64** 1.0, our 32-bit all-purpose, rock-solid,
|
||||
small-state generator. It is extremely fast and it passes all tests we
|
||||
are aware of, but its state space is not large enough for any parallel
|
||||
application.
|
||||
|
||||
For generating just single-precision (i.e., 32-bit) floating-point
|
||||
numbers, xoroshiro64* is even faster.
|
||||
|
||||
The state must be seeded so that it is not everywhere zero. */
|
||||
|
||||
|
||||
static inline u32 rotl(const u32 x, i32 k) {
|
||||
return (x << k) | (x >> (32 - k));
|
||||
}
|
||||
|
||||
u32 xoroshiro64starstar_next(void* _state) {
|
||||
xoroshiro64_state* state=_state;
|
||||
const u32 s0 = state->s[0];
|
||||
u32 s1 = state->s[1];
|
||||
const u32 result = rotl(s0 * 0x9E3779BB, 5) * 5;
|
||||
|
||||
s1 ^= s0;
|
||||
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
|
||||
state->s[1] = rotl(s1, 13); // c
|
||||
|
||||
return result;
|
||||
}
|
||||
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128.h
Normal file
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../../base/std.h"
|
||||
#include "../../splitmix64/splitmix64.h"
|
||||
|
||||
|
||||
typedef union {
|
||||
u32 s[2];
|
||||
} xoroshiro128_state;
|
||||
typedef void* xoroshiro128_statePtr;
|
||||
|
||||
xoroshiro128_statePtr xoroshiro128_init(u64 seed);
|
||||
#define xoroshiro128plus_init xoroshiro128_init
|
||||
#define xoroshiro128plusplus_init xoroshiro128_init
|
||||
#define xoroshiro128starstar_init xoroshiro128_init
|
||||
|
||||
static inline xoroshiro128_statePtr xoroshiro128_initFromTime(void) { return xoroshiro128_init(time(NULL)); }
|
||||
#define xoroshiro128plus_initFromTime xoroshiro128_initFromTime
|
||||
#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime
|
||||
#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
|
||||
|
||||
u64 xoroshiro128plus_next(xoroshiro128_statePtr);
|
||||
u64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
|
||||
u64 xoroshiro128starstar_next(xoroshiro128_statePtr);
|
||||
|
||||
static inline void xoroshiro128_free(xoroshiro128_statePtr state) {
|
||||
free(state);
|
||||
}
|
||||
#define xoroshiro128plus_free xoroshiro128_free
|
||||
#define xoroshiro128plusplus_free xoroshiro128_free
|
||||
#define xoroshiro128starstar_free xoroshiro128_free
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
59
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plus.c
Normal file
59
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plus.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Written in 2016-2018 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 "xoroshiro128.h"
|
||||
|
||||
/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
|
||||
for floating-poi32 numbers, but its state space is large enough only
|
||||
for mild parallelism. We suggest to use its upper bits for
|
||||
floating-poi32 generation, as it is slightly faster than
|
||||
xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
|
||||
except for the four lower bits, which might fail linearity tests (and
|
||||
just those), so if low linear complexity is not considered an issue (as
|
||||
it is usually the case) it can be used to generate 64-bit outputs, too;
|
||||
moreover, this generator has a very mild Hamming-weight dependency
|
||||
making our test (http://prng.di.unimi.it/hwd.php) fail after 5 TB of
|
||||
output; we believe this slight bias cannot affect any application. If
|
||||
you are concerned, use xoroshiro128++, xoroshiro128** or xoshiro256+.
|
||||
|
||||
We suggest to use a sign test to extract a random Boolean value, and
|
||||
right shifts to extract subsets of bits.
|
||||
|
||||
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.
|
||||
|
||||
NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
|
||||
better results in our test than the 2016 version (a=55, b=14, c=36).
|
||||
*/
|
||||
|
||||
static inline u64 rotl(const u64 x, i32 k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
u64 xoroshiro128plus_next(void* _state){
|
||||
xoroshiro128_state* state=_state;
|
||||
const u64 s0 = state->s[0];
|
||||
u64 s1 = state->s[1];
|
||||
const u64 result = s0 + s1;
|
||||
|
||||
s1 ^= s0;
|
||||
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
||||
state->s[1] = rotl(s1, 37); // c
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* xoroshiro128_init(u64 seed){
|
||||
xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state));
|
||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||
state->s[0]=splitmix64_next(splitmix);
|
||||
state->s[1]=splitmix64_next(splitmix);
|
||||
splitmix64_free(splitmix);
|
||||
return state;
|
||||
}
|
||||
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c
Normal file
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Written in 2019 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 "xoroshiro128.h"
|
||||
|
||||
/* This is xoroshiro128++ 1.0, one of our all-purpose, rock-solid,
|
||||
small-state generators. It is extremely (sub-ns) fast and it passes all
|
||||
tests we are aware of, but its state space is large enough only for
|
||||
mild parallelism.
|
||||
|
||||
For generating just floating-poi32 numbers, xoroshiro128+ is even
|
||||
faster (but it has a very mild bias, see notes in the comments).
|
||||
|
||||
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. */
|
||||
|
||||
|
||||
static inline u64 rotl(const u64 x, i32 k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
u64 xoroshiro128plusplus_next(void* _state){
|
||||
xoroshiro128_state* state=_state;
|
||||
const u64 s0 = state->s[0];
|
||||
u64 s1 = state->s[1];
|
||||
const u64 result = rotl(s0 + s1, 17) + s0;
|
||||
|
||||
s1 ^= s0;
|
||||
state->s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
|
||||
state->s[1] = rotl(s1, 28); // c
|
||||
|
||||
return result;
|
||||
}
|
||||
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c
Normal file
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Written in 2018 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 "xoroshiro128.h"
|
||||
|
||||
/* This is xoroshiro128** 1.0, one of our all-purpose, rock-solid,
|
||||
small-state generators. It is extremely (sub-ns) fast and it passes all
|
||||
tests we are aware of, but its state space is large enough only for
|
||||
mild parallelism.
|
||||
|
||||
For generating just floating-poi32 numbers, xoroshiro128+ is even
|
||||
faster (but it has a very mild bias, see notes in the comments).
|
||||
|
||||
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. */
|
||||
|
||||
|
||||
static inline u64 rotl(const u64 x, i32 k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
u64 xoroshiro128starstar_next(void* _state){
|
||||
xoroshiro128_state* state=_state;
|
||||
const u64 s0 = state->s[0];
|
||||
u64 s1 = state->s[1];
|
||||
const u64 result = rotl(s0 * 5, 7) * 9;
|
||||
|
||||
s1 ^= s0;
|
||||
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
||||
state->s[1] = rotl(s1, 37); // c
|
||||
|
||||
return result;
|
||||
}
|
||||
2
kerep/src/random/xoroshiro/xoroshiro.h
Normal file
2
kerep/src/random/xoroshiro/xoroshiro.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "32bitValue/xoroshiro64.h"
|
||||
#include "64bitValue/xoroshiro128.h"
|
||||
24
kerep/src/random/xoshiro-xoroshiro.md
Normal file
24
kerep/src/random/xoshiro-xoroshiro.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Xoshiro/Xoroshiro RNG algorithms
|
||||
There are a bunch of versions of xoshiro/xoroshiro algorithms, which are created by [David Blackman and Sebastiano Vigna](https://prng.di.unimi.it/)
|
||||
|
||||
|
||||
```
|
||||
xoroshiro
|
||||
├── 32bitValue
|
||||
| ├── xoroshiro64star.c
|
||||
| └── xoroshiro64starstar.c
|
||||
└── 64bitValue
|
||||
├── xoroshiro128plus.c
|
||||
├── xoroshiro128plusplus.c
|
||||
└── xoroshiro128starstar.c
|
||||
|
||||
xoshiro
|
||||
├── 32bitValue
|
||||
│ ├── xoshiro128plus.c
|
||||
│ ├── xoshiro128plusplus.c
|
||||
│ └── xoshiro128starstar.c
|
||||
└── 64bitValue
|
||||
├── xoshiro256plus.c
|
||||
├── xoshiro256plusplus.c
|
||||
└── xoshiro256starstar.c
|
||||
```
|
||||
40
kerep/src/random/xoshiro/32bitValue/xoshiro128.h
Normal file
40
kerep/src/random/xoshiro/32bitValue/xoshiro128.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../../base/std.h"
|
||||
#include "../../splitmix64/splitmix64.h"
|
||||
|
||||
|
||||
typedef union {
|
||||
u64 merged[2];
|
||||
u32 s[4];
|
||||
} xoshiro128_state;
|
||||
typedef void* xoshiro128_statePtr;
|
||||
|
||||
xoshiro128_statePtr xoshiro128_init(u64 seed);
|
||||
#define xoshiro128plus_init xoshiro128_init
|
||||
#define xoshiro128plusplus_init xoshiro128_init
|
||||
#define xoshiro128starstar_init xoshiro128_init
|
||||
|
||||
static inline xoshiro128_statePtr xoshiro128_initFromTime(void) { return xoshiro128_init(time(NULL)); }
|
||||
#define xoshiro128plus_initFromTime xoshiro128_initFromTime
|
||||
#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime
|
||||
#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
|
||||
|
||||
u32 xoshiro128plus_next(xoshiro128_statePtr);
|
||||
u32 xoshiro128plusplus_next(xoshiro128_statePtr);
|
||||
u32 xoshiro128starstar_next(xoshiro128_statePtr);
|
||||
|
||||
static inline void xoshiro128_free(xoshiro128_statePtr state) {
|
||||
free(state);
|
||||
}
|
||||
#define xoshiro128plus_free xoshiro128_free
|
||||
#define xoshiro128plusplus_free xoshiro128_free
|
||||
#define xoshiro128starstar_free xoshiro128_free
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
54
kerep/src/random/xoshiro/32bitValue/xoshiro128plus.c
Normal file
54
kerep/src/random/xoshiro/32bitValue/xoshiro128plus.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Written in 2018 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 "xoshiro128.h"
|
||||
|
||||
/* This is xoshiro128+ 1.0, our best and fastest 32-bit generator for 32-bit
|
||||
floating-poi32 numbers. We suggest to use its upper bits for
|
||||
floating-poi32 generation, as it is slightly faster than xoshiro128**.
|
||||
It passes all tests we are aware of except for
|
||||
linearity tests, as the lowest four bits have low linear complexity, so
|
||||
if low linear complexity is not considered an issue (as it is usually
|
||||
the case) it can be used to generate 32-bit outputs, too.
|
||||
|
||||
We suggest to use a sign test to extract a random Boolean value, and
|
||||
right shifts to extract subsets of bits.
|
||||
|
||||
The state must be seeded so that it is not everywhere zero. */
|
||||
|
||||
|
||||
static inline u32 rotl(const u32 x, i32 k) {
|
||||
return (x << k) | (x >> (32 - k));
|
||||
}
|
||||
|
||||
u32 xoshiro128plus_next(void* _state){
|
||||
xoshiro128_state* state=_state;
|
||||
const u32 result = state->s[0] + state->s[3];
|
||||
|
||||
const u32 t = state->s[1] << 9;
|
||||
|
||||
state->s[2] ^= state->s[0];
|
||||
state->s[3] ^= state->s[1];
|
||||
state->s[1] ^= state->s[2];
|
||||
state->s[0] ^= state->s[3];
|
||||
|
||||
state->s[2] ^= t;
|
||||
|
||||
state->s[3] = rotl(state->s[3], 11);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* xoshiro128_init(u64 seed){
|
||||
xoshiro128_state* state=malloc(sizeof(xoshiro128_state));
|
||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||
state->merged[0]=splitmix64_next(splitmix);
|
||||
state->merged[1]=splitmix64_next(splitmix);
|
||||
splitmix64_free(splitmix);
|
||||
return state;
|
||||
}
|
||||
42
kerep/src/random/xoshiro/32bitValue/xoshiro128plusplus.c
Normal file
42
kerep/src/random/xoshiro/32bitValue/xoshiro128plusplus.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Written in 2019 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 "xoshiro128.h"
|
||||
|
||||
/* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid
|
||||
generators. It has excellent speed, a state size (128 bits) that is
|
||||
large enough for mild parallelism, and it passes all tests we are aware
|
||||
of.
|
||||
|
||||
For generating just single-precision (i.e., 32-bit) floating-point
|
||||
numbers, xoshiro128+ is even faster.
|
||||
|
||||
The state must be seeded so that it is not everywhere zero. */
|
||||
|
||||
|
||||
static inline u32 rotl(const u32 x, i32 k) {
|
||||
return (x << k) | (x >> (32 - k));
|
||||
}
|
||||
|
||||
u32 xoshiro128plusplus_next(void* _state){
|
||||
xoshiro128_state* state=_state;
|
||||
const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
|
||||
|
||||
const u32 t = state->s[1] << 9;
|
||||
|
||||
state->s[2] ^= state->s[0];
|
||||
state->s[3] ^= state->s[1];
|
||||
state->s[1] ^= state->s[2];
|
||||
state->s[0] ^= state->s[3];
|
||||
|
||||
state->s[2] ^= t;
|
||||
|
||||
state->s[3] = rotl(state->s[3], 11);
|
||||
|
||||
return result;
|
||||
}
|
||||
45
kerep/src/random/xoshiro/32bitValue/xoshiro128starstar.c
Normal file
45
kerep/src/random/xoshiro/32bitValue/xoshiro128starstar.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Written in 2018 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 "xoshiro128.h"
|
||||
|
||||
/* This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid
|
||||
generators. It has excellent speed, a state size (128 bits) that is
|
||||
large enough for mild parallelism, and it passes all tests we are aware
|
||||
of.
|
||||
|
||||
Note that version 1.0 had mistakenly state->s[0] instead of state->s[1] as state
|
||||
word passed to the scrambler.
|
||||
|
||||
For generating just single-precision (i.e., 32-bit) floating-point
|
||||
numbers, xoshiro128+ is even faster.
|
||||
|
||||
The state must be seeded so that it is not everywhere zero. */
|
||||
|
||||
|
||||
static inline u32 rotl(const u32 x, i32 k) {
|
||||
return (x << k) | (x >> (32 - k));
|
||||
}
|
||||
|
||||
u32 xoshiro128starstar_next(void* _state){
|
||||
xoshiro128_state* state=_state;
|
||||
const u32 result = rotl(state->s[1] * 5, 7) * 9;
|
||||
|
||||
const u32 t = state->s[1] << 9;
|
||||
|
||||
state->s[2] ^= state->s[0];
|
||||
state->s[3] ^= state->s[1];
|
||||
state->s[1] ^= state->s[2];
|
||||
state->s[0] ^= state->s[3];
|
||||
|
||||
state->s[2] ^= t;
|
||||
|
||||
state->s[3] = rotl(state->s[3], 11);
|
||||
|
||||
return result;
|
||||
}
|
||||
39
kerep/src/random/xoshiro/64bitValue/xoshiro256.h
Normal file
39
kerep/src/random/xoshiro/64bitValue/xoshiro256.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../../base/std.h"
|
||||
#include "../../splitmix64/splitmix64.h"
|
||||
|
||||
|
||||
typedef union {
|
||||
u64 s[4];
|
||||
} xoshiro256_state;
|
||||
typedef void* xoshiro256_statePtr;
|
||||
|
||||
xoshiro256_statePtr xoshiro256_init(u64 seed);
|
||||
#define xoshiro256plus_init xoshiro256_init
|
||||
#define xoshiro256plusplus_init xoshiro256_init
|
||||
#define xoshiro256starstar_init xoshiro256_init
|
||||
|
||||
static inline xoshiro256_statePtr xoshiro256_initFromTime(void) { return xoshiro256_init(time(NULL)); }
|
||||
#define xoshiro256plus_initFromTime xoshiro256_initFromTime
|
||||
#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime
|
||||
#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
|
||||
|
||||
u64 xoshiro256plus_next(xoshiro256_statePtr);
|
||||
u64 xoshiro256plusplus_next(xoshiro256_statePtr);
|
||||
u64 xoshiro256starstar_next(xoshiro256_statePtr);
|
||||
|
||||
static inline void xoshiro256_free(xoshiro256_statePtr state) {
|
||||
free(state);
|
||||
}
|
||||
#define xoshiro256plus_free xoshiro256_free
|
||||
#define xoshiro256plusplus_free xoshiro256_free
|
||||
#define xoshiro256starstar_free xoshiro256_free
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
58
kerep/src/random/xoshiro/64bitValue/xoshiro256plus.c
Normal file
58
kerep/src/random/xoshiro/64bitValue/xoshiro256plus.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Written in 2018 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 "xoshiro256.h"
|
||||
|
||||
/* This is xoshiro256+ 1.0, our best and fastest generator for floating-point
|
||||
numbers. We suggest to use its upper bits for floating-point
|
||||
generation, as it is slightly faster than xoshiro256++/xoshiro256**. It
|
||||
passes all tests we are aware of except for the lowest three bits,
|
||||
which might fail linearity tests (and just those), so if low linear
|
||||
complexity is not considered an issue (as it is usually the case) it
|
||||
can be used to generate 64-bit outputs, too.
|
||||
|
||||
We suggest to use a sign test to extract a random Boolean value, and
|
||||
right shifts to extract subsets of bits.
|
||||
|
||||
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. */
|
||||
|
||||
|
||||
static inline u64 rotl(const u64 x, i32 k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
u64 xoshiro256plus_next(void* _state){
|
||||
xoshiro256_state* state=_state;
|
||||
const u64 result = state->s[0] + state->s[3];
|
||||
|
||||
const u64 t = state->s[1] << 17;
|
||||
|
||||
state->s[2] ^= state->s[0];
|
||||
state->s[3] ^= state->s[1];
|
||||
state->s[1] ^= state->s[2];
|
||||
state->s[0] ^= state->s[3];
|
||||
|
||||
state->s[2] ^= t;
|
||||
|
||||
state->s[3] = rotl(state->s[3], 45);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* xoshiro256_init(u64 seed){
|
||||
xoshiro256_state* state=malloc(sizeof(xoshiro256_state));
|
||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||
state->s[0]=splitmix64_next(splitmix);
|
||||
state->s[1]=splitmix64_next(splitmix);
|
||||
state->s[2]=splitmix64_next(splitmix);
|
||||
state->s[3]=splitmix64_next(splitmix);
|
||||
splitmix64_free(splitmix);
|
||||
return state;
|
||||
}
|
||||
37
kerep/src/random/xoshiro/64bitValue/xoshiro256plusplus.c
Normal file
37
kerep/src/random/xoshiro/64bitValue/xoshiro256plusplus.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Written in 2019 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 "xoshiro256.h"
|
||||
|
||||
/* This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
|
||||
It has excellent (sub-ns) speed, a state (256 bits) that is large
|
||||
enough for any parallel application, and it passes all tests we are
|
||||
aware of.
|
||||
|
||||
For generating just floating-poi32 numbers, xoshiro256+ is even 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. */
|
||||
|
||||
static inline u64 rotl(const u64 x, i32 k) {
|
||||
return (x << k) | (x>>(64 - k));
|
||||
}
|
||||
|
||||
u64 xoshiro256plusplus_next(void* _state) {
|
||||
xoshiro256_state* state=_state;
|
||||
const u64 result=rotl(state->s[0] + state->s[3], 23) + state->s[0];
|
||||
const u64 t=state->s[1] << 17;
|
||||
state->s[2] ^= state->s[0];
|
||||
state->s[3] ^= state->s[1];
|
||||
state->s[1] ^= state->s[2];
|
||||
state->s[0] ^= state->s[3];
|
||||
state->s[2] ^= t;
|
||||
state->s[3]=rotl(state->s[3], 45);
|
||||
return result;
|
||||
}
|
||||
42
kerep/src/random/xoshiro/64bitValue/xoshiro256starstar.c
Normal file
42
kerep/src/random/xoshiro/64bitValue/xoshiro256starstar.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Written in 2018 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 "xoshiro256.h"
|
||||
|
||||
/* This is xoshiro256** 1.0, one of our all-purpose, rock-solid
|
||||
generators. It has excellent (sub-ns) speed, a state (256 bits) that is
|
||||
large enough for any parallel application, and it passes all tests we
|
||||
are aware of.
|
||||
|
||||
For generating just floating-poi32 numbers, xoshiro256+ is even 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. */
|
||||
|
||||
static inline u64 rotl(const u64 x, i32 k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
u64 xoshiro256starstar_next(void* _state){
|
||||
xoshiro256_state* state=_state;
|
||||
const u64 result = rotl(state->s[1] * 5, 7) * 9;
|
||||
|
||||
const u64 t = state->s[1] << 17;
|
||||
|
||||
state->s[2] ^= state->s[0];
|
||||
state->s[3] ^= state->s[1];
|
||||
state->s[1] ^= state->s[2];
|
||||
state->s[0] ^= state->s[3];
|
||||
|
||||
state->s[2] ^= t;
|
||||
|
||||
state->s[3] = rotl(state->s[3], 45);
|
||||
|
||||
return result;
|
||||
}
|
||||
2
kerep/src/random/xoshiro/xoshiro.h
Normal file
2
kerep/src/random/xoshiro/xoshiro.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "32bitValue/xoshiro128.h"
|
||||
#include "64bitValue/xoshiro256.h"
|
||||
Reference in New Issue
Block a user