Skip to content

Commit

Permalink
ENH: np.random.default_gen() (#13840)
Browse files Browse the repository at this point in the history
* ENH: Rename seed_seq argument to seed and replace Generator() with default_gen()
  • Loading branch information
rkern authored and mattip committed Jun 28, 2019
1 parent defafbf commit 0ec7f12
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 214 deletions.
2 changes: 2 additions & 0 deletions doc/source/reference/random/generator.rst
Expand Up @@ -12,6 +12,8 @@ random values from useful distributions. The default BitGenerator used by
can be changed by passing an instantized BitGenerator to ``Generator``.


.. autofunction:: default_gen

.. autoclass:: Generator
:exclude-members:

Expand Down
7 changes: 4 additions & 3 deletions doc/source/reference/random/index.rst
Expand Up @@ -48,9 +48,10 @@ the random values are generated by `~.PCG64`. The

.. code-block:: python
# As replacement for RandomState()
from numpy.random import Generator
rg = Generator()
# As replacement for RandomState(); default_gen() instantiates Generator with
# the default PCG64 BitGenerator.
from numpy.random import default_gen
rg = default_gen()
rg.standard_normal()
rg.bit_generator
Expand Down
16 changes: 8 additions & 8 deletions doc/source/reference/random/new-or-different.rst
Expand Up @@ -19,15 +19,15 @@ Quick comparison of legacy `mtrand <legacy>`_ to the new `Generator`
================== ==================== =============
Feature Older Equivalent Notes
------------------ -------------------- -------------
`Generator` `RandomState` ``Generator`` requires a stream
`~.Generator` `~.RandomState` ``Generator`` requires a stream
source, called a `BitGenerator
<bit_generators>` A number of these
are provided. ``RandomState`` uses
only the Box- Muller method.
only the Mersenne Twister.
------------------ -------------------- -------------
``np.random.`` ``np.random.`` Access the values in a BitGenerator,
``Generator().`` ``random_sample()`` convert them to ``float64`` in the
``random()`` interval ``[0.0.,`` `` 1.0)``.
``random`` ``random_sample`` Access the values in a BitGenerator,
convert them to ``float64`` in the
interval ``[0.0.,`` `` 1.0)``.
In addition to the ``size`` kwarg, now
supports ``dtype='d'`` or ``dtype='f'``,
and an ``out`` kwarg to fill a user-
Expand All @@ -36,8 +36,8 @@ Feature Older Equivalent Notes
Many other distributions are also
supported.
------------------ -------------------- -------------
``Generator().`` ``randint``, Use the ``endpoint`` kwarg to adjust
``integers()`` ``random_integers`` the inclusion or exclution of the
``integers`` ``randint``, Use the ``endpoint`` kwarg to adjust
``random_integers`` the inclusion or exclution of the
``high`` interval endpoint
================== ==================== =============

Expand All @@ -56,7 +56,7 @@ And in more detail:
random numbers from a discrete uniform distribution. The ``rand`` and
``randn`` methods are only available through the legacy `~.RandomState`.
This replaces both ``randint`` and the deprecated ``random_integers``.
* The Box-Muller used to produce NumPy's normals is no longer available.
* The Box-Muller method used to produce NumPy's normals is no longer available.
* All bit generators can produce doubles, uint64s and
uint32s via CTypes (`~PCG64.ctypes`) and CFFI (`~PCG64.cffi`).
This allows these bit generators to be used in numba.
Expand Down
54 changes: 33 additions & 21 deletions numpy/random/__init__.py
Expand Up @@ -3,16 +3,42 @@
Random Number Generation
========================
Instantiate a BitGenerator and wrap it in a Generator
which will convert the uniform stream to a number of distributions. The "bare"
functions are kept for legacy code, they should be called with the newer API
via ``np.random.Generator().function`` instead
Use ``default_gen()`` to create a `Generator` and call its methods.
=============== =========================================================
Generator
--------------- ---------------------------------------------------------
Generator Class implementing all of the random number distributions
default_gen Default constructor for ``Generator``
=============== =========================================================
============================================= ===
BitGenerator Streams that work with Generator
--------------------------------------------- ---
MT19937
PCG64
Philox
SFC64
============================================= ===
============================================= ===
Getting entropy to initialize a BitGenerator
--------------------------------------------- ---
SeedSequence
============================================= ===
Legacy
------
For backwards compatibility with previous versions of numpy before 1.17, the
various aliases to the global `RandomState` methods are left alone and do not
use the new `Generator` API.
==================== =========================================================
Utility functions
-------------------- ---------------------------------------------------------
random Uniformly distributed floats over ``[0, 1)``
integers Uniformly distributed integers, replaces ``randint``
bytes Uniformly distributed random bytes.
permutation Randomly permute a sequence / generate a random sequence.
shuffle Randomly permute a sequence in place.
Expand Down Expand Up @@ -94,20 +120,6 @@
set_state Set state of generator.
==================== =========================================================
============================================= ===
BitGenerator Streams that work with Generator
--------------------------------------------- ---
MT19937
PCG64
Philox
SFC64
============================================= ===
============================================= ===
Getting entropy to initialize a BitGenerator
--------------------------------------------- ---
SeedSequence
============================================= ===
"""
from __future__ import division, absolute_import, print_function
Expand Down Expand Up @@ -167,7 +179,7 @@

from . import mtrand
from .mtrand import *
from .generator import Generator
from .generator import Generator, default_gen
from .bit_generator import SeedSequence
from .mt19937 import MT19937
from .pcg64 import PCG64
Expand All @@ -176,7 +188,7 @@
from .mtrand import RandomState

__all__ += ['Generator', 'RandomState', 'SeedSequence', 'MT19937',
'Philox', 'PCG64', 'SFC64']
'Philox', 'PCG64', 'SFC64', 'default_gen']


def __RandomState_ctor():
Expand Down
1 change: 0 additions & 1 deletion numpy/random/bit_generator.pxd
Expand Up @@ -13,7 +13,6 @@ cdef class BitGenerator():

cdef class SeedSequence():
cdef readonly object entropy
cdef readonly object program_entropy
cdef readonly tuple spawn_key
cdef readonly int pool_size
cdef readonly object pool
Expand Down
23 changes: 13 additions & 10 deletions numpy/random/bit_generator.pyx
Expand Up @@ -116,7 +116,7 @@ def _coerce_to_uint32_array(x):
Examples
--------
>>> import numpy as np
>>> from seed_seq import _coerce_to_uint32_array
>>> from np.random.bit_generator import _coerce_to_uint32_array
>>> _coerce_to_uint32_array(12345)
array([12345], dtype=uint32)
>>> _coerce_to_uint32_array('12345')
Expand Down Expand Up @@ -473,17 +473,20 @@ ISpawnableSeedSequence.register(SeedSequence)

cdef class BitGenerator():
"""
BitGenerator(seed_seq=None)
BitGenerator(seed=None)
Base Class for generic BitGenerators, which provide a stream
of random bits based on different algorithms. Must be overridden.
Parameters
----------
seed_seq : {None, ISeedSequence, int, sequence[int]}, optional
A ISeedSequence to initialize the BitGenerator. If None, one will be
created. If an int or a sequence of ints, it will be used as the
entropy for creating a SeedSequence.
seed : {None, int, array_like[ints], ISeedSequence}, optional
A seed to initialize the `BitGenerator`. If None, then fresh,
unpredictable entropy will be pulled from the OS. If an ``int`` or
``array_like[ints]`` is passed, then it will be passed to
`SeedSequence` to derive the initial `BitGenerator` state. One may also
pass in an implementor of the `ISeedSequence` interface like
`SeedSequence`.
Attributes
----------
Expand All @@ -498,7 +501,7 @@ cdef class BitGenerator():
SeedSequence
"""

def __init__(self, seed_seq=None):
def __init__(self, seed=None):
self.lock = Lock()
self._bitgen.state = <void *>0
if type(self) is BitGenerator:
Expand All @@ -509,9 +512,9 @@ cdef class BitGenerator():

cdef const char *name = "BitGenerator"
self.capsule = PyCapsule_New(<void *>&self._bitgen, name, NULL)
if not isinstance(seed_seq, ISeedSequence):
seed_seq = SeedSequence(seed_seq)
self._seed_seq = seed_seq
if not isinstance(seed, ISeedSequence):
seed = SeedSequence(seed)
self._seed_seq = seed

# Pickling support:
def __getstate__(self):
Expand Down

0 comments on commit 0ec7f12

Please sign in to comment.