hexsample.rng
— Random numbers#
This module is an attempt to move away from the legacy numpy RandomState and use the best practices described in the numpy random documentation and in NEP 19.
Although the bottomline of the numpy documentation is not to have a global state, never seed an existing generator, and create the desired generator at the beginning of the program and then just pass the object around, we deemed changing constructors (or the signature of the relevant class methods) for all the classes that need to throw random number too intrusive. Instead, we created this module that has a global Generator object.
The basic usage of the module is as follows
from hexsample import rng
rng.initialize()
z = rng.generator.normal()
and any attempt to do something with the rng.generator
object will raise a
RuntimeError
if the module is not properly initialized. The initialization
function initialize()
is the place where the
particular algorithm for the random number generation, as well as the seed, can be set.
This should be normally called once at the beginning of the program, and then the
global rng.generator
object will be available from everywhere in the package.
The default undelrying bit generator object that we use is the SFC64 Small Fast Chaotic PRNG, that is known to be very fast and have good statistical properties.
Module documentation#
Application-wide pseudo-random number generator.
- class hexsample.rng.UninitializedGenerator#
Mock class raising an exception at any attempt at an interaction.
This is a poor-man trick not to let the user forget that the they have to call the initialize() function below before being able to draw any random number.
- hexsample.rng.reset() None #
Set the generator global object to the uninitialized state.
- hexsample.rng.initialize(bit_generator_class: type = <class 'numpy.random._sfc64.SFC64'>, seed: int = None) None #
Create a random generator from a given underlying bit generator and a given seed and set the global
generator
object.This is using the recommended constructor for the random number class Generator, and goes toward the philosophy that it is better to create a new generator rather than seed one multiple times.
The available bit generators are:
MT19937
PCG64
PCG64DXSM
Philox
SFC64
along with the old RandomState that is kept for compatibility reasons.
The merits and demerits and the performance of the various methods are briefly discussed at: https://numpy.org/doc/stable/reference/random/performance.html
The recommended generator for general use is PCG64 or its upgraded variant PCG64DXSM for heavily-parallel use cases. They are statistically high quality, full-featured, and fast on most platforms, but somewhat slow when compiled for 32-bit processes.
Philox is fairly slow, but its statistical properties have very high quality, and it is easy to get an assuredly-independent stream by using unique keys.
SFC64 is statistically high quality and very fast. However, it lacks jumpability. If you are not using that capability and want lots of speed, even on 32-bit processes, this is your choice.
MT19937 fails some statistical tests and is not especially fast compared to modern PRNGs. For these reasons, we mostly do not recommend using it on its own, only through the legacy RandomState for reproducing old results. That said, it has a very long history as a default in many systems.
- Parameters:
bit_generator_class (type) – The class for the underlying bit generator.
seed (int) – The initial seed (default to None).