User-defined Bit Generators

Most bit generators use Cython to wrap an implementation in C. While this method leads to best case performance, it is necessarily involved. UserBitGenerator allows bit generators to be written in Python (slow) or numba (fast) or for existing PRNGs to be wrapped. The bit generator can then be used with a Generator. See the demonstration notebook for examples.

class randomgen.wrapper.UserBitGenerator(next_raw, bits=64, next_64=None, next_32=None, next_double=None, state=None, state_getter=None, state_setter=None)

Construct a bit generator from Python functions

Parameters:
next_raw

A callable that returns either 64 or 32 random bits. It must accept a single input which is a void pointer to a memory address.

bits=64

The number of bits output by the next_raw callable. Must be either 32 or 64.

next_64=None

A callable with the same signature as as next_raw that always return 64 bits. If not provided, this function is constructed using next_raw.

next_32=None

A callable with the same signature as as next_raw that always return 32 bits. If not provided, this function is constructed using next_raw.

next_double=None

A callable with the same signature as as next_raw that always return a random double in [0,1). If not provided, this function is constructed using next_raw.

state=None

A ctypes pointer to pass into the next functions. In most cases this should be None, in which case the null pointer is passed.

state_getter=None

A callable that returns the state of the bit generator. If not provided, getting the state property will raise NotImplementedError.

state_setter=None

A callable that sets the state of the bit generator. Must take a single input. If not provided, getting the state property will raise NotImplementedError.

Notes

There is one key caveat when using a UserBitGenerator. The callable must run without exceptions.

Warning

It is essential that the callable function runs without producing an Exception. Exceptions will be silently ignored and the generator will produce incorrect results.

Examples

A generator that rotates across 4 values from random.org.

>>> import numpy as np
>>> rv = np.array([ 7713239619832409074, 17318243661941184039,
...                14412717025735663865, 521015634160378615, 0],
...                dtype=np.uint64)
>>> def next_raw(voidp):
...     idx = int(rv[-1] % 4)
...     out = rv[idx]
...     rv[-1] += 1
...     return int(out)
>>> bg = UserBitGenerator(next_raw)

See the documentation for a more realistic example.

From Low-level Objects

from_cfunc(next_raw, next_64, next_32, ...)

from_cfunc(next_raw, next_64, next_32, next_double, state,

from_ctypes(next_raw, next_64, next_32, ...)

from_ctypes(next_raw, next_64, next_32, next_double, state,

State

state

Get or set the state

Extending

cffi

CFFI interface

ctypes

ctypes interface

Testing

random_raw([size, output])

Return randoms as generated by the underlying BitGenerator