This is a library and generic interface for alternative random generators in Python and Numpy.
Features
- Immediate drop in replacement for NumPy's RandomState
# import numpy.random as rnd
import randomstate as rnd
x = rnd.standard_normal(100)
y = rnd.random_sample(100)
z = rnd.randn(10,10)- Default random generator is identical to NumPy's RandomState (i.e., same seed, same random numbers).
- Support for random number generators that support independent streams and jumping ahead so that substreams can be generated
- Faster random number generations, especially for Normals using the Ziggurat method
import randomstate as rnd
w = rnd.standard_normal(10000, method='zig')This modules includes a number of alternative random number generators in addition to the MT19937 that is included in NumPy. The RNGs include:
- MT19937, the NumPy rng
- dSFMT a SSE2-aware version of the MT19937 generator that is especially fast at generating doubles
- xorshift128+, xoroshiro128+ xorshift1024*
- PCG32 and PCG64
- MRG32K3A
- A multiplicative lagged fibonacci generator (LFG(63, 1279, 861, *))
standard_normal,normal,randnandmultivariate_normalall support an additionalmethodkeyword argument which can bebmorzigwherebmcorresponds to the current method andziguses the much faster (100%+) ziggurat method.
random_entropy- Read from the system entropy provider, which is commonly used in cryptographic applicationsrandom_uintegers- unsigned integers[0, 2**64-1]random_raw- Direct access to the values produced by the underlying PRNG.
The range of the values returned depends on the specifics of the PRNG implementation.jump- Jumps RNGs that support it.jumpmoves the state a great distance. Only available if supported by the RNG.advance- Advanced the core RNG 'as-if' a number of draws were made, without actually drawing the numbers. Only available if supported by the RNG.
- Complete drop-in replacement for
numpy.random.RandomState. Themt19937generator is identical tonumpy.random.RandomState, and will produce an identical sequence of random numbers for a given seed. - Builds and passes all tests on:
- Linux 32/64 bit, Python 2.6, 2.7, 3.3, 3.4, 3.5
- PC-BSD (FreeBSD) 64-bit, Python 2.7
- OSX 64-bit, Python 2.7
- Windows 32/64 bit (only tested on Python 2.7 and 3.5, but should work on 3.3/3.4)
The version matched the latest version of NumPy where
randomstate.prng.mt19937 passes all NumPy test.
An occasionally updated build of the documentation is available on my github pages.
This module is essentially complete. There are a few rough edges that need to be smoothed.
- Stream support for MLFG
- Creation of additional streams from a RandomState where supported (i.e.
a
next_stream()method)
Building requires:
- Numpy (1.9, 1.10, 1.11)
- Cython (0.22, 0.23, 0.24)
- Python (2.6, 2.7, 3.3, 3.4, 3.5)
Note: it might work with other versions but only tested with these versions.
All development has been on 64-bit Linux, and it is regularly tested on Travis-CI. The library is occasionally tested on Linux 32-bit, OSX 10.10, PC-BSD 10.2 (should also work on Free BSD) and Windows (Python 2.7/3.5, both 32 and 64-bit).
Basic tests are in place for all RNGs. The MT19937 is tested against NumPy's implementation for identical results. It also passes NumPy's test suite.
python setup.py installdSFTM makes use of SSE2 by default. If you have a very old computer or are
building on non-x86, you can install using:
python setup.py install --no-sse2Either use a binary installer or if building from scratch using Python 3.5 and
the free Visual Studio 2015 Community Edition. It can also be build using
Microsoft Visual C++ Compiler for Python 2.7 and Python 2.7, although some
modifications are needed to distutils to find the compiler.
The separate generators are importable from randomstate.prng.
import randomstate
rs = randomstate.prng.xorshift128.RandomState()
rs.random_sample(100)
rs = randomstate.prng.pcg64.RandomState()
rs.random_sample(100)
# Identical to NumPy
rs = randomstate.prng.mt19937.RandomState()
rs.random_sample(100)Like NumPy, randomstate also exposes a single instance of the mt19937
generator directly at the module level so that commands like
import randomstate
randomstate.standard_normal()
randomstate.exponential(1.0, 1.0, size=10)will work.
Standard NCSA, plus sub licenses for components.
Performance is promising, and even the mt19937 seems to be faster than NumPy's mt19937.
Speed-up relative to NumPy (Box-Muller)
************************************************************
randomstate.prng-dsfmt-standard_normal 30.2%
randomstate.prng-mlfg_1279_861-standard_normal 24.7%
randomstate.prng-mrg32k3a-standard_normal -17.8%
randomstate.prng-mt19937-standard_normal 11.2%
randomstate.prng-pcg32-standard_normal 22.0%
randomstate.prng-pcg64-standard_normal 21.8%
randomstate.prng-xoroshiro128plus-standard_normal 26.5%
randomstate.prng-xorshift1024-standard_normal 20.2%
randomstate.prng-xorshift128-standard_normal 23.5%
Speed-up relative to NumPy (Ziggurat)
************************************************************
randomstate.prng-dsfmt-standard_normal 494.2%
randomstate.prng-mlfg_1279_861-standard_normal 464.2%
randomstate.prng-mrg32k3a-standard_normal 103.8%
randomstate.prng-mt19937-standard_normal 362.6%
randomstate.prng-pcg32-standard_normal 539.6%
randomstate.prng-pcg64-standard_normal 407.7%
randomstate.prng-xoroshiro128plus-standard_normal 722.8%
randomstate.prng-xorshift1024-standard_normal 506.1%
randomstate.prng-xorshift128-standard_normal 686.3%