kwutil.util_random module¶
Implements a version of ensure_rng that does not require on numpy (but allows for it). This mirrors :kwarray:`ensure_rng`, which is a numpy-first implementation.
- kwutil.util_random._npstate_to_pystate(npstate)[source]¶
Convert state of a NumPy RandomState object to a state that can be used by Python’s Random. Derived from [SO44313620].
References
Example
>>> # xdoctest: +REQUIRES(module:numpy) >>> import numpy as np >>> py_rng = random.Random(0) >>> np_rng = np.random.RandomState(seed=0) >>> npstate = np_rng.get_state() >>> pystate = _npstate_to_pystate(npstate) >>> py_rng.setstate(pystate) >>> assert np_rng.rand() == py_rng.random()
- kwutil.util_random._pystate_to_npstate(pystate)[source]¶
Convert state of a Python Random object to state usable by NumPy RandomState. Derived from [SO44313620].
References
Example
>>> # xdoctest: +REQUIRES(module:numpy) >>> import numpy as np >>> py_rng = random.Random(0) >>> np_rng = np.random.RandomState(seed=0) >>> pystate = py_rng.getstate() >>> npstate = _pystate_to_npstate(pystate) >>> np_rng.set_state(npstate) >>> assert np_rng.rand() == py_rng.random()
- kwutil.util_random._coerce_rng_type(rng)[source]¶
Internal method that transforms input seeds into an integer form.
- kwutil.util_random.ensure_rng(rng=None, api='python')[source]¶
Coerces input into a random number generator.
This function is useful for ensuring that your code uses a controlled internal random state that is independent of other modules.
If the input is None, then a global random state is returned.
If the input is a numeric value, then that is used as a seed to construct a random state.
If the input is a random number generator, then another random number generator with the same state is returned. Depending on the api, this random state is either return as-is, or used to construct an equivalent random state with the requested api.
- Parameters:
rng (int | float | None | numpy.random.RandomState | random.Random) – if None, then defaults to the global rng. Otherwise this can be an integer or a RandomState class. Defaults to the global random.
api (str) – specify the type of random number generator to use. This can either be ‘numpy’ for a
numpy.random.RandomStateobject or ‘python’ for arandom.Randomobject. Defaults to numpy.
- Returns:
rng - either a numpy or python random number generator, depending on the setting of
api.- Return type:
Example
>>> # xdoctest: +REQUIRES(module:numpy) >>> from kwutil.util_random import * # NOQA >>> from kwutil.util_random import ensure_rng >>> rng = ensure_rng(None) >>> ensure_rng(0, 'python').randint(0, 1000) 864 >>> # xdoctest: +REQUIRES(module:numpy) >>> import numpy as np >>> ensure_rng(np.random.RandomState(1)).randint(0, 1000) 427
Example
>>> from kwutil.util_random import * # NOQA >>> from kwutil.util_random import ensure_rng >>> num = 4 >>> print('--- Python as PYTHON ---') >>> py_rng = random.Random(0) >>> pp_nums = [py_rng.random() for _ in range(num)] >>> print(pp_nums) >>> print('--- Numpy as PYTHON ---') >>> # xdoctest: +REQUIRES(module:numpy) >>> import numpy as np >>> np_rng = ensure_rng(random.Random(0), api='numpy') >>> np_nums = [np_rng.rand() for _ in range(num)] >>> print(np_nums) >>> print('--- Numpy as NUMPY---') >>> np_rng = np.random.RandomState(seed=0) >>> nn_nums = [np_rng.rand() for _ in range(num)] >>> print(nn_nums) >>> print('--- Python as NUMPY---') >>> py_rng = ensure_rng(np.random.RandomState(seed=0), api='python') >>> pn_nums = [py_rng.random() for _ in range(num)] >>> print(pn_nums) >>> assert np_nums == pp_nums >>> assert pn_nums == nn_nums
Example
>>> # Test that random modules can be coerced >>> # xdoctest: +REQUIRES(module:numpy) >>> from kwutil.util_random import * # NOQA >>> import random >>> import numpy as np >>> ensure_rng(random, api='python') >>> ensure_rng(random, api='numpy') >>> ensure_rng(np.random, api='python') >>> ensure_rng(np.random, api='numpy')