summaryrefslogtreecommitdiff
path: root/doc/source/reference/random/new-or-different.rst
blob: 4b9ba72a4cb2791a31e7efdbd04f0b894400127d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
.. _new-or-different:

.. currentmodule:: numpy.random

What's New or Different
-----------------------

.. warning::

  The Box-Muller method used to produce NumPy's normals is no longer available
  in `Generator`.  It is not possible to reproduce the exact random
  values using ``Generator`` for the normal distribution or any other
  distribution that relies on the normal such as the `Generator.gamma` or
  `Generator.standard_t`. If you require bitwise backward compatible
  streams, use `RandomState`, i.e., `RandomState.gamma` or
  `RandomState.standard_t`.

Quick comparison of legacy `mtrand <legacy>`_ to the new `Generator`

================== ==================== =============
Feature            Older Equivalent     Notes
------------------ -------------------- -------------
`~.Generator`      `~.RandomState`      ``Generator`` requires a stream
                                        source, called a `BitGenerator`
                                        A number of these are provided.
                                        ``RandomState`` uses
                                        the Mersenne Twister `~.MT19937` by
                                        default, but can also be instantiated
                                        with any BitGenerator.
------------------ -------------------- -------------
``random``         ``random_sample``,   Access the values in a BitGenerator,
                   ``rand``             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-
                                        supplied array.

                                        Many other distributions are also
                                        supported.
------------------ -------------------- -------------
``integers``       ``randint``,         Use the ``endpoint`` kwarg to adjust
                   ``random_integers``  the inclusion or exclution of the
                                        ``high`` interval endpoint
================== ==================== =============

And in more detail:

* Simulate from the complex normal distribution
  (`~.Generator.complex_normal`)
* The normal, exponential and gamma generators use 256-step Ziggurat
  methods which are 2-10 times faster than NumPy's default implementation in
  `~.Generator.standard_normal`, `~.Generator.standard_exponential` or
  `~.Generator.standard_gamma`.
* `~.Generator.integers` is now the canonical way to generate integer
  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 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.
* The bit generators can be used in downstream projects via
  Cython.


.. ipython:: python

  from  numpy.random import Generator, PCG64
  import numpy.random
  rg = Generator(PCG64())
  %timeit rg.standard_normal(100000)
  %timeit numpy.random.standard_normal(100000)

.. ipython:: python

  %timeit rg.standard_exponential(100000)
  %timeit numpy.random.standard_exponential(100000)

.. ipython:: python

  %timeit rg.standard_gamma(3.0, 100000)
  %timeit numpy.random.standard_gamma(3.0, 100000)

* Optional ``dtype`` argument that accepts ``np.float32`` or ``np.float64``
  to produce either single or double prevision uniform random variables for
  select distributions

  * Uniforms (`~.Generator.random` and `~.Generator.integers`)
  * Normals (`~.Generator.standard_normal`)
  * Standard Gammas (`~.Generator.standard_gamma`)
  * Standard Exponentials (`~.Generator.standard_exponential`)

.. ipython:: python

  rg = Generator(PCG64(0))
  rg.random(3, dtype='d')
  rg.random(3, dtype='f')

* Optional ``out`` argument that allows existing arrays to be filled for
  select distributions

  * Uniforms (`~.Generator.random`)
  * Normals (`~.Generator.standard_normal`)
  * Standard Gammas (`~.Generator.standard_gamma`)
  * Standard Exponentials (`~.Generator.standard_exponential`)

  This allows multithreading to fill large arrays in chunks using suitable
  BitGenerators in parallel.

.. ipython:: python

  existing = np.zeros(4)
  rg.random(out=existing[:2])
  print(existing)

* Optional ``axis`` argument for methods like `~.Generator.choice` and
  `~.Generator.shuffle` to control which axis an operation is performed
  over for higher-dimensional arrays.

.. ipython:: python

  a = np.arange(12).reshape((3, 4))
  a
  rg.choice(a, axis=1, size=2)
  rg.shuffle(a, axis=1)        # Shuffle in-place
  a