I have implemented a working prototype of a pluggable RandomState.  The
repo is located at https://github.com/bashtage/core-prng.

The main design has a small PRNG (currently only SplitMix64 and
Xoroshiro128 are implemented) that does not have any public functions
available to generate random numbers.  These objects only expose methods to
get and set state and to jump the PRNG.

The random number generator is exposed via an opaque structure wrapped in a
PyCapsule.  This structure has two void pointers, one to the state and one
to the function that generates the next uint 64.  I think in the long-run
it might make sense to expose a few additional interfaces, such as the next
random double (makes sense for dSFMT) or the next random uint32 (makes
sense for MT19937).  For now, I have deliberately kept it simple.

The user-facing object is called `RandomGenerator` and it can be
initialized using the syntax `RandomGenerator` or
`RandomGenerator(Xoroshiro128())`.  The object exposes user-facing methods
(currently only `random_integer` and `random_double`).

A basic demo:

from core_prng.generator import RandomGenerator
# Splitmix 64 for now
RandomGenerator().random_integer()

from core_prng.xoroshiro128 import Xoroshiro128
RandomGenerator(Xoroshiro128()).random_integer()

A few questions that have come up:

   1. Should a passed core PRNG be initialized or not. The syntax
RandomGenerator(Xoroshiro128)
   looks nicer than RandomGenerator(Xoroshiro128())
   2. Which low-level methods should be part of the core PRNG?  These would
   all be scalar generators that would be consumed by RandomGenerator and
   exposed through void *. I could imagine some subset of the following:
      - uint64
      - uint32
      - double
      - float
      - uint53 (applicable to PRNGs that use doubles as default type)
   3. Since RandomState is taken, a new name is needed for the user-facing
   object.  RandomGenerator is a placeholder but ideally, something meaningful
   could be chosen.
   4. I can't see how locking can be usefully implemented in the core PRNGs
   without a large penalty. This means that these are not threadsafe.  This
   isn't a massive problem but they do access the state (get or set) although
   with GIL.
   5. Should state be a property -- this isn't Java...


Other feedback is of course also welcome.

Kevin
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion

Reply via email to