This package contains replacements for the NumPy
`RandomState`

object that allows the core random number
generator be be changed.

Like `numpy.random`

, RandomGen can be used at the module level.
This uses the default `RandomGenerator`

which
uses normals provided by `Xoroshiro128`

.

```
# As replacement for numpy.random
import randomgen.generator as random
random.standard_normal()
```

`RandomGenerator`

can also be used as a
replacement for `RandomState`

, although the random
values are generated by `Xoroshiro128`

. It
also isn’t possible to directly seed a
`RandomGenerator`

.

```
# As replacement for RandomState()
from randomgen import RandomGenerator
rg = RandomGenerator()
rg.standard_normal()
```

Seeds can be passed to any of the basic RNGs. Here `MT19937`

is used and the `RandomGenerator`

is accessed via
the property `generator`

.

```
from randomgen import MT19937
rg = MT19937(12345).generator
rg.standard_normal()
```

RandomGen takes a different approach to producing random numbers from the
`numpy.random.RandomState`

object used in NumPy. Random number
generation is separated into two components, a basic RNG and a random
generator.

The basic RNG has a limited set of responsibilities – it manages the underlying RNG state and provides functions to produce random doubles and random unsigned 32- and 64-bit values. The basic random generator also handles all seeding since this varies when using alternative basic RNGs.

The random generator (`RandomGenerator`

) takes the
basic RNG-provided functions and transforms them into more useful
distributions, e.g., simulated normal random values. This structure allows
alternative basic RNGs to be used without code duplication.

The `RandomGenerator`

is the user-facing object
that is nearly identical to `RandomState`

. The canonical
method to initialize a generator passes a basic RNG –
`MT19937`

, the underlying RNG in NumPy – as the
sole argument. Note that the basic RNG must be instantized.

```
from randomgen import RandomGenerator, MT19937
rg = RandomGenerator(MT19937())
rg.random_sample()
```

Seed information is directly passed to the basic RNG.

```
rg = RandomGenerator(MT19937(12345))
rg.random_sample()
```

A shorthand method is also available which uses the
`generator()`

property from a basic RNG to
access an embedded random generator.

```
rg = MT19937(12345).generator
rg.random_sample()
```

Warning

The Box-Muller method used to produce NumPy’s normals is no longer available
in `RandomGenerator`

. It is not possible to
reproduce the random values using `RandomGenerator`

for the normal distribution or any other distribution that relies on the
normal such as the gamma or student’s t. If you require backward compatibility, a
legacy generator, `LegacyGenerator`

, has been created
which can fully reproduce the sequence produced by NumPy.

- The normal, exponential and gamma generators use 256-step Ziggurat methods which are 2-10 times faster than NumPy’s Box-Muller or inverse CDF implementations.
- Optional
`dtype`

argument that accepts`np.float32`

or`np.float64`

to produce either single or double prevision uniform random variables for select distributions - Optional
`out`

argument that allows existing arrays to be filled for select distributions - Simulate from the complex normal distribution
(
`complex_normal()`

) `random_entropy()`

provides access to the system source of randomness that is used in cryptographic applications (e.g.,`/dev/urandom`

on Unix).- All basic random generators functions to produce doubles, uint64s and
uint32s via CTypes (
`ctypes()`

) and CFFI (`cffi()`

). This allows these basic RNGs to be used in numba. - The basic random number generators can be used in downstream projects via Cython.
- Support for Lemire’s method [Lemire] of generating uniform integers on an
arbitrary interval by setting
`use_masked=True`

in (`randint()`

).

See What’s New or Different for a complete list of improvements and differences.

The included generators can be used in parallel, distributed applications in one of two ways:

The main innovation is the inclusion of a number of alternative pseudo-random number generators, ‘in addition’ to the standard PRNG in NumPy. The included PRNGs are:

- MT19937 - The standard NumPy generator. Produces identical results to NumPy
using the same seed/state. Adds a jump function that advances the generator
as-if 2**128 draws have been made (
`jump()`

). See NumPy’s documentation. - dSFMT - SSE2 enabled versions of the MT19937 generator. Theoretically
the same, but with a different state and so it is not possible to produce a
sequence identical to MT19937. Supports
`jump`

and so can be used in parallel applications. See the dSFMT authors’ page. - XoroShiro128+ - Improved version of XorShift128+ with better performance
and statistical quality. Like the XorShift generators, it can be jumped
to produce multiple streams in parallel applications. See
`jump()`

for details. More information about this PRNG is available at the xorshift, xoroshiro and xoshiro authors’ page. - XorShift1024*φ - Fast fast generator based on the XSadd
generator. Supports
`jump`

and so can be used in parallel applications. See the documentation for`jump()`

for details. More information about these PRNGs is available at the xorshift, xoroshiro and xoshiro authors’ page. - Xorshiro256** and Xorshiro512** - The most recently introduced XOR,
shift, and rotate generator. Supports
`jump`

and so can be used in parallel applications. See the documentation for`jump()`

for details. More information about these PRNGs is available at the xorshift, xoroshiro and xoshiro authors’ page. - PCG-64 - Fast generator that support many parallel streams and
can be advanced by an arbitrary amount. See the documentation for
`advance()`

. PCG-64 has a period of \(2^{128}\). See the PCG author’s page for more details about this class of PRNG. - ThreeFry and Philox - counter-based generators capable of being advanced an arbitrary number of steps or generating independent streams. See the Random123 page for more details about this class of PRNG.