Last active
March 6, 2024 06:56
-
-
Save nikhilr612/6838b5627a63e1cf8e8c6e651a7fedc0 to your computer and use it in GitHub Desktop.
Collatz-Weyl Chaotic Pseudo-random number generator (64-bit)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "cw_prng.h" | |
#include <stdio.h> | |
uint64_t cw_g64(struct CW_Rng* rng) { | |
rng -> weyl += rng -> s; | |
uint64_t out = rng -> xbits; | |
rng -> abits += out; | |
out = (out >> 1)*(rng -> abits | 1); | |
out ^= rng -> weyl; | |
rng -> xbits = out; | |
out ^= rng -> abits >> 48; | |
return out; | |
} | |
void cw_init(struct CW_Rng* rng, uint64_t seed) { | |
// Set these to zero, as they are affected by s immediately after first pass. | |
rng -> abits = 0; | |
rng -> weyl = 0; | |
// Initial state, and increment s are determined by seed | |
// Use splitmix64 for x bits ... | |
seed += 0x9e3779b97f4a7c15; | |
uint64_t x = seed; | |
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; | |
x = (x ^ (x >> 27)) * 0x94d049bb133111eb; | |
x = x ^ (x >> 31); | |
// .. and splitmix63 for s | |
seed += 0x9e3779b97f4a7c15; | |
uint64_t z = seed & 0x7fffffffffffffff; | |
z = ((z ^ (z >> 30)) * 0xbf58476d1ce4e5b9) & 0x7fffffffffffffff; | |
z = ((z ^ (z >> 27)) * 0x94d049bb133111eb) & 0x7fffffffffffffff; | |
z = z ^ (z >> 31); | |
rng -> s = (z << 1) | 1; | |
rng -> xbits = x; | |
} | |
int main() { | |
// Test | |
struct CW_Rng rng; | |
cw_init(&rng, 612); | |
for(size_t i = 0; i < 100; i++) { | |
printf("%u\n", cw_g64(&rng)); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CW_PRNG | |
#include <stdint.h> | |
#define CW_PRNG | |
/* | |
* A simple C-implementation of the Collatz-Weyl Pseudo-random number generator. | |
*/ | |
struct CW_Rng { | |
// 'Main' sequence of bits to be operated on by CW-scheme. | |
uint64_t xbits; | |
// 'Auxiliary' sequence of bits | |
uint64_t abits; | |
uint64_t weyl; | |
// Odd number used to update Weyl bits. | |
uint64_t s; | |
}; | |
/** | |
* Generate 64 random bits. | |
*/ | |
uint64_t cw_g64(struct CW_Rng* rng); | |
/** | |
* Initialize the Random number generator using the provided seed. | |
*/ | |
void cw_init(struct CW_Rng* rng, uint64_t seed); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment