This commit is contained in:
timerix 2023-06-08 15:15:50 +06:00
parent c5585bbb0c
commit 080bbb28fd
22 changed files with 124 additions and 239 deletions

27
src/random/RANDOM.md Normal file
View File

@ -0,0 +1,27 @@
# Random
This directory contains some popular random functions. I recommend you using `splitmix64` initialized with `random_seedFromTime` for fast rng, hoshiro128plus for more accurate 32-bit rng and hoshiro256plus for 64-bit.
## 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
```

View File

@ -1,72 +0,0 @@
#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

33
src/random/random.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/std.h"
#include "splitmix64/splitmix64.h"
#include "xoroshiro/32bitValue/xoroshiro64.h"
#include "xoroshiro/64bitValue/xoroshiro128.h"
#include "xoshiro/32bitValue/xoshiro128.h"
#include "xoshiro/64bitValue/xoshiro256.h"
#define random_seedFromTime() time(NULL)
/// divides random number by 2^32
/// @return value between 0 and 1
static inline f32 random_toFloat32(u32 random_value) { return (f32)random_value / (f32)0xffff; }
/// divides random number by 2^64
/// @return value between 0 and 1
static inline f64 random_nextFloat64(u64 random_value) { return (f64)random_value / (f64)0xffffffff; }
///@param probability (0-1.0) probability of success
///@return is action sucsessfull or not
static inline bool random_probability(u32 random_value, float probability){
i32 limit=1.0f/probability + 0.0002f;
return random_value%limit == 0;
}
#if __cplusplus
}
#endif

View File

@ -11,20 +11,11 @@ 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;
u64 splitmix64_next(splitmix64_state* state_ptr) {
// increment the state variable
*state += 0x9e3779b97f4a7c15;
*state_ptr += 0x9e3779b97f4a7c15;
// copy the state to a working variable
u64 z = *state;
u64 z = *state_ptr;
// 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

View File

@ -7,16 +7,13 @@ extern "C" {
#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);
static inline void splitmix64_construct(splitmix64_state* state, u64 seed){
*state=seed;
}
u64 splitmix64_next(splitmix64_state* state_ptr);
#if __cplusplus
}
#endif

View File

@ -4,31 +4,17 @@
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
void xoroshiro64_construct(xoroshiro64_state* state_ptr, u64 seed);
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
u32 xoroshiro64star_next(xoroshiro64_state*);
u32 xoroshiro64starstar_next(xoroshiro64_state*);
#if __cplusplus
}

View File

@ -27,8 +27,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
u32 xoroshiro64star_next(void* _state) {
xoroshiro64_state* state=_state;
u32 xoroshiro64star_next(xoroshiro64_state* state) {
const u32 s0 = state->s[0];
u32 s1 = state->s[1];
const u32 result = s0 * 0x9E3779BB;
@ -40,10 +39,8 @@ u32 xoroshiro64star_next(void* _state) {
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;
void xoroshiro64_construct(xoroshiro64_state* state, u64 seed){
splitmix64_state sm_state;
splitmix64_construct(&sm_state, seed);
state->merged=splitmix64_next(&sm_state);
}

View File

@ -23,8 +23,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
u32 xoroshiro64starstar_next(void* _state) {
xoroshiro64_state* state=_state;
u32 xoroshiro64starstar_next(xoroshiro64_state* state) {
const u32 s0 = state->s[0];
u32 s1 = state->s[1];
const u32 result = rotl(s0 * 0x9E3779BB, 5) * 5;

View File

@ -4,35 +4,17 @@
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
void xoroshiro128_construct(xoroshiro128_state* state, u64 seed);
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
u64 xoroshiro128plus_next(xoroshiro128_state*);
u64 xoroshiro128plusplus_next(xoroshiro128_state*);
u64 xoroshiro128starstar_next(xoroshiro128_state*);
#if __cplusplus
}

View File

@ -36,8 +36,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
u64 xoroshiro128plus_next(void* _state){
xoroshiro128_state* state=_state;
u64 xoroshiro128plus_next(xoroshiro128_state* state){
const u64 s0 = state->s[0];
u64 s1 = state->s[1];
const u64 result = s0 + s1;
@ -49,11 +48,9 @@ u64 xoroshiro128plus_next(void* _state){
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;
void xoroshiro128_construct(xoroshiro128_state* state, u64 seed){
splitmix64_state sm_state;
splitmix64_construct(&sm_state, seed);
state->s[0]=splitmix64_next(&sm_state);
state->s[1]=splitmix64_next(&sm_state);
}

View File

@ -25,8 +25,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
u64 xoroshiro128plusplus_next(void* _state){
xoroshiro128_state* state=_state;
u64 xoroshiro128plusplus_next(xoroshiro128_state* state){
const u64 s0 = state->s[0];
u64 s1 = state->s[1];
const u64 result = rotl(s0 + s1, 17) + s0;

View File

@ -25,8 +25,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
u64 xoroshiro128starstar_next(void* _state){
xoroshiro128_state* state=_state;
u64 xoroshiro128starstar_next(xoroshiro128_state* state){
const u64 s0 = state->s[0];
u64 s1 = state->s[1];
const u64 result = rotl(s0 * 5, 7) * 9;

View File

@ -1,2 +0,0 @@
#include "32bitValue/xoroshiro64.h"
#include "64bitValue/xoroshiro128.h"

View File

@ -4,36 +4,18 @@
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
void xoshiro128_construct(xoshiro128_state* state, u64 seed);
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
u32 xoshiro128plus_next(xoshiro128_state*);
u32 xoshiro128plusplus_next(xoshiro128_state*);
u32 xoshiro128starstar_next(xoshiro128_state*);
#if __cplusplus
}

View File

@ -26,8 +26,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
u32 xoshiro128plus_next(void* _state){
xoshiro128_state* state=_state;
u32 xoshiro128plus_next(xoshiro128_state* state){
const u32 result = state->s[0] + state->s[3];
const u32 t = state->s[1] << 9;
@ -44,11 +43,9 @@ u32 xoshiro128plus_next(void* _state){
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;
void xoshiro128_construct(xoshiro128_state* state, u64 seed){
splitmix64_state sm_state;
splitmix64_construct(&sm_state, seed);
state->merged[0]=splitmix64_next(&sm_state);
state->merged[1]=splitmix64_next(&sm_state);
}

View File

@ -23,8 +23,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
u32 xoshiro128plusplus_next(void* _state){
xoshiro128_state* state=_state;
u32 xoshiro128plusplus_next(xoshiro128_state* state){
const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
const u32 t = state->s[1] << 9;

View File

@ -26,8 +26,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
u32 xoshiro128starstar_next(void* _state){
xoshiro128_state* state=_state;
u32 xoshiro128starstar_next(xoshiro128_state* state){
const u32 result = rotl(state->s[1] * 5, 7) * 9;
const u32 t = state->s[1] << 9;

View File

@ -4,35 +4,17 @@
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
void xoshiro256_construct(xoshiro256_state* state, u64 seed);
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
u64 xoshiro256plus_next(xoshiro256_state*);
u64 xoshiro256plusplus_next(xoshiro256_state*);
u64 xoshiro256starstar_next(xoshiro256_state*);
#if __cplusplus
}

View File

@ -28,8 +28,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
u64 xoshiro256plus_next(void* _state){
xoshiro256_state* state=_state;
u64 xoshiro256plus_next(xoshiro256_state* state){
const u64 result = state->s[0] + state->s[3];
const u64 t = state->s[1] << 17;
@ -46,13 +45,11 @@ u64 xoshiro256plus_next(void* _state){
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;
void xoshiro256_construct(xoshiro256_state* state, u64 seed){
splitmix64_state sm_state;
splitmix64_construct(&sm_state, seed);
state->s[0]=splitmix64_next(&sm_state);
state->s[1]=splitmix64_next(&sm_state);
state->s[2]=splitmix64_next(&sm_state);
state->s[3]=splitmix64_next(&sm_state);
}

View File

@ -23,8 +23,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x>>(64 - k));
}
u64 xoshiro256plusplus_next(void* _state) {
xoshiro256_state* state=_state;
u64 xoshiro256plusplus_next(xoshiro256_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];

View File

@ -23,8 +23,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
u64 xoshiro256starstar_next(void* _state){
xoshiro256_state* state=_state;
u64 xoshiro256starstar_next(xoshiro256_state* state){
const u64 result = rotl(state->s[1] * 5, 7) * 9;
const u64 t = state->s[1] << 17;

View File

@ -1,2 +0,0 @@
#include "32bitValue/xoshiro128.h"
#include "64bitValue/xoshiro256.h"