What is the best way to generate pseudo uniform random numbers (a double in [0, 1)) that is:
- Cross platform (ideally with same same sample sequence)
- Thread safe (explicit passing of the mutated state of the prng or using a thread-local state internally)
- Without GIL lock
- Easily wrappable in Cython
There was a similar post over 3 years ago about this but a lot of the answers don't meet all criteria. For example, drand48
is POSIX-specific.
The only method I'm aware of, which seems (but not sure) to meet all some criteria is:
from libc.stdlib cimport rand, RAND_MAX
random = rand() / (RAND_MAX + 1.0)
Note @ogrisel asked the same question about 3 years ago.
Edit
Calling rand is not thread safe. Thanks for pointing that out @DavidW.
I think the easiest way to do this is to use the C++11 standard library which provides nice encapsulated random number generators and ways to use them. This is of course not the only options, and you could wrap pretty much any suitable C/C++ library (one good option might be to use whatever library numpy uses, since that's most likely already installed).
My general advice is to only wrap the bits you need and not bother with the full hierarchy and all the optional template parameters. By way of example I've shown one of the default generators, fed into a uniform float distribution.
(The
-std=c++11
at the start is for GCC. For other compilers you may need to tweak this. Increasingly c++11 is a default anyway, so you can drop it)With reference to your criteria:
mt19937
object (each thread should have its ownmt19937
).Edit: about using
discrete_distribution
.This is a bit harder because the constructors for
discrete_distribution
are less obvious how to wrap (they involve iterators). I think the easiest thing to do is to go via a C++ vector since support for that is built into Cython and it is readily convertable to/from a Python listObviously that's a bit more involved than the uniform distribution, but it's not impossibly complicated (and the nasty bits could be hidden inside a Cython function).