libpsrand - portable, simple, pseudo-random generator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

libpsrand implements different 32 bit, reentrant pseudo-random generators.

Reentrancy means no global variables are used, all states are stored in a
caller supplied buffer. This allows the caller to have deterministic
pseudo-random numbers taken from different, dedicated "heaps" of random
numbers for each parallel task. This includes lock-free thread safety.

Portable means the whole library is written in pure/strict C89, without
any external dependency. When the library is compiled on different computers
but initialized with the same seed, the same numbers shall be generated.

Usage
~~~~~

There are different algorithms implemented, each in an own pair of
psr_FOO.c/psr_FOO.h. Different algorithms will work in a very similar
way but are not direct substitute of each other. The common aspects are:

 - #include <libpsrand/FOO.h>
 - the state structure is called psr_FOO_t
 - initialization of a new state is psr_FOO_init(state, seed);
   the type of the seed is algorithm-specific (usually 32 bit integer)
 - generating the next random number: psr_FOO_rand(state);
   return type is algorithm-specific (usually 32 bit integer)
 - a macro psr_FOO_rand01(state) is provided to generate a random number
   as a double, in rang of [0..1)
 - if the return type of the rand() function is integer, macro PSR_FOO_MAX
   represents the largest possible value



Algorithms
~~~~~~~~~~
minstd         - MISTD (16807 Lehmer RNG)
mtw            - Mersenne Twister
xorshift       - George Marsaglia's "xor128"



Example
~~~~~~~
Using the Mersenne Twister algorithm to generate 3 reproducible pseudo-random
numbers:

#include <stdio.h>
#include <libpsrand/mtw.h>

int main(int argc, char argv)
{
	psr_mtw_t st;

	psr_mtw_init(&st, 42);

	printf("#1: %lu\n", (unsigned long)psr_mtw_rand(&st));
	printf("#2: %lu\n", (unsigned long)psr_mtw_rand(&st));
	printf("#3: %lu\n", (unsigned long)psr_mtw_rand(&st));

	return 0;
}
