diff --git a/examples/Makefile.am b/examples/Makefile.am index d50d8ed..ef2ef36 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -2,5 +2,7 @@ exdir = ${prefix}/share/TestU01/examples ex_DATA = bat1.res bat2.res birth1.res ex3.res excel.dat vax.bin my16807.h \ bat1.c bat2.c bat3.c birth1.c birth2.c ex1.c ex3.c ex4.c ex7.c \ - fcoll.c fbirth.c scat.c scat2.c my16807.c mrg32k3a.c xorshift.c \ + fcoll.c fbirth.c scat.c scat2.c my16807.c mrg32k3a.c pcg32.c speedpcg32.c \ + speedxoshiro128plusplus.c testpcg32.c testxoshiro128plusplus.c \ + xorshift.c xoshiro128plusplus.c \ fbirth.res1.tex fbirth.res2.tex fcoll.res1.tex fcoll.res2.tex diff --git a/examples/pcg32.c b/examples/pcg32.c new file mode 100644 index 0000000..936a766 --- /dev/null +++ b/examples/pcg32.c @@ -0,0 +1,27 @@ +#include "stdint.h" + +// This random number generation algorithm is taken from +// M.E. O'Neil "PCG: A Family of Simple Fast Space-Efficient" +// "Statistically Good Algorithms for Random Number" +// "Generation" +// https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf +// https://www.pcg-random.org/download.html +// +// *Really* minimal PCG32 code +// (c) 2014 M.E. O'Neill +// pcg-random.org +// Licensed under Apache License 2.0 (NO WARRANTY, etc. see website) + +static uint64_t state = 5342; +static uint64_t inc = 521; +uint32_t pcg32_random_r(void) +{ + uint64_t oldstate = state; + // Advance internal state + state = oldstate * 6364136223846793005ULL + (inc|1); + // Calculate output function (XSH RR), uses old state for + // maximum instruction level parallelism + uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; + uint32_t rot = oldstate >> 59u; + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +} diff --git a/examples/speedpcg32.c b/examples/speedpcg32.c new file mode 100644 index 0000000..aed44c7 --- /dev/null +++ b/examples/speedpcg32.c @@ -0,0 +1,21 @@ +/* After compiling TESTU01 and adding the libraries to your paths, + * compile this program with + * cc -O3 speedpcg32.c pcg32.c -o speedpcg32 -ltestu01 -lprobdist -lmylib -lm + * then run it using ./speedpcg32.c + */ + +#include "unif01.h" +#include "ulec.h" + +uint32_t pcg32_random_r (void); + +int main (void) +{ + unif01_Gen *gen; + + gen = unif01_CreateExternGenBits("pcg32_random_r", pcg32_random_r); + unif01_TimerSumGenWr (gen, 100000000, FALSE); + ulec_DeleteGen (gen); + + return 0; +} diff --git a/examples/speedxoshiro128plusplus.c b/examples/speedxoshiro128plusplus.c new file mode 100644 index 0000000..59aa284 --- /dev/null +++ b/examples/speedxoshiro128plusplus.c @@ -0,0 +1,22 @@ +/* After compiling TESTU01 and adding the libraries to your paths, + * compile this program with + * cc -O3 speedxoshiro128plusplus.c xoshiro128plusplus.c \ + * -o speedxoshiro128plusplus -ltestu01 -lprobdist -lmylib -lm + * then run it using ./speedxoshiro128plusplus.c + */ + +#include "unif01.h" +#include "ulec.h" + +uint32_t xoshiro128plusplus (void); + +int main (void) +{ + unif01_Gen *gen; + + gen = unif01_CreateExternGenBits("xoshiro128plusplus", xoshiro128plusplus); + unif01_TimerSumGenWr (gen, 100000000, FALSE); + ulec_DeleteGen (gen); + + return 0; +} diff --git a/examples/testpcg32.c b/examples/testpcg32.c new file mode 100644 index 0000000..eb8efad --- /dev/null +++ b/examples/testpcg32.c @@ -0,0 +1,23 @@ +/* After compiling TESTU01 and adding the libraries to your paths, + * compile this program with + * cc -O3 testpcg32.c pcg32.c -o testpcg32 -ltestu01 -lprobdist -lmylib -lm + * then run it using ./testpcg32.c + * You can change the code to replace bbattery_SmallCrush, with + * bbattery_Crush and bbattery_BigCrush + */ + +#include "unif01.h" +#include "bbattery.h" + +uint32_t pcg32_random_r (void); + +int main (void) +{ + unif01_Gen *gen; + + gen = unif01_CreateExternGenBits("pcg32_random_r", pcg32_random_r); + bbattery_SmallCrush (gen); + unif01_DeleteExternGenBits (gen); + + return 0; +} diff --git a/examples/testxoshiro128plusplus.c b/examples/testxoshiro128plusplus.c new file mode 100644 index 0000000..90aed1c --- /dev/null +++ b/examples/testxoshiro128plusplus.c @@ -0,0 +1,24 @@ +/* After compiling TESTU01 and adding the libraries to your paths, + * compile this program with + * cc -O3 testxoshiro128plusplus.c xoshiro128plusplus.c -o \ + * testxoshiro128plusplus -ltestu01 -lprobdist -lmylib -lm + * then run it using ./testxoshiro128plusplus + * You can change the code to replace bbattery_SmallCrush, with + * bbattery_Crush and bbattery_BigCrush + */ + +#include "unif01.h" +#include "bbattery.h" + +uint32_t xoshiro128plusplus (void); + +int main (void) +{ + unif01_Gen *gen; + + gen = unif01_CreateExternGenBits("xoshiro128plusplus", xoshiro128plusplus); + bbattery_SmallCrush (gen); + unif01_DeleteExternGenBits (gen); + + return 0; +} diff --git a/examples/xoshiro128plusplus.c b/examples/xoshiro128plusplus.c new file mode 100644 index 0000000..82def93 --- /dev/null +++ b/examples/xoshiro128plusplus.c @@ -0,0 +1,51 @@ +/* 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 . + +Original source is available at: + +https://prng.di.unimi.it/ + +Modified by Benson Muite in 2022 for use with TestU01 + +Jump functions removed */ +#include + +/* 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 uint32_t rotl(const uint32_t x, int k) { + return (x << k) | (x >> (32 - k)); +} + +static uint32_t s[4] = {53, 30301, 71423, 49323}; + +uint32_t xoshiro128plusplus(void) { + const uint32_t result = rotl(s[0] + s[3], 7) + s[0]; + + const uint32_t t = s[1] << 9; + + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + + s[2] ^= t; + + s[3] = rotl(s[3], 11); + + return result; +} +