@@ -13,39 +13,39 @@ or distributed).
13
13
------------------------
14
14
15
15
NumPy allows you to spawn new (with very high probability) independent
16
- `~ BitGenerator ` and `~ Generator ` instances via their ``spawn() `` method.
17
- This spawning is implemented by the `~ SeedSequence ` used for initializing
16
+ `BitGenerator ` and `Generator ` instances via their ``spawn() `` method.
17
+ This spawning is implemented by the `SeedSequence ` used for initializing
18
18
the bit generators random stream.
19
19
20
- `~ SeedSequence ` `implements an algorithm `_ to process a user-provided seed,
20
+ `SeedSequence ` `implements an algorithm `_ to process a user-provided seed,
21
21
typically as an integer of some size, and to convert it into an initial state for
22
- a `~ BitGenerator `. It uses hashing techniques to ensure that low-quality seeds
22
+ a `BitGenerator `. It uses hashing techniques to ensure that low-quality seeds
23
23
are turned into high quality initial states (at least, with very high
24
24
probability).
25
25
26
- For example, `MT19937 ` has a state consisting of 624
27
- ` uint32 ` integers. A naive way to take a 32-bit integer seed would be to just set
26
+ For example, `MT19937 ` has a state consisting of 624 `` uint32 ``
27
+ integers. A naive way to take a 32-bit integer seed would be to just set
28
28
the last element of the state to the 32-bit seed and leave the rest 0s. This is
29
29
a valid state for `MT19937 `, but not a good one. The Mersenne Twister
30
30
algorithm `suffers if there are too many 0s `_. Similarly, two adjacent 32-bit
31
31
integer seeds (i.e. ``12345 `` and ``12346 ``) would produce very similar
32
32
streams.
33
33
34
- `~ SeedSequence ` avoids these problems by using successions of integer hashes
34
+ `SeedSequence ` avoids these problems by using successions of integer hashes
35
35
with good `avalanche properties `_ to ensure that flipping any bit in the input
36
36
has about a 50% chance of flipping any bit in the output. Two input seeds that
37
37
are very close to each other will produce initial states that are very far
38
38
from each other (with very high probability). It is also constructed in such
39
39
a way that you can provide arbitrary-sized integers or lists of integers.
40
- `~ SeedSequence ` will take all of the bits that you provide and mix them
41
- together to produce however many bits the consuming `~ BitGenerator ` needs to
40
+ `SeedSequence ` will take all of the bits that you provide and mix them
41
+ together to produce however many bits the consuming `BitGenerator ` needs to
42
42
initialize itself.
43
43
44
44
These properties together mean that we can safely mix together the usual
45
- user-provided seed with simple incrementing counters to get `~ BitGenerator `
45
+ user-provided seed with simple incrementing counters to get `BitGenerator `
46
46
states that are (to very high probability) independent of each other. We can
47
47
wrap this together into an API that is easy to use and difficult to misuse.
48
- Note that while `~ SeedSequence ` attempts to solve many of the issues related to
48
+ Note that while `SeedSequence ` attempts to solve many of the issues related to
49
49
user-provided small seeds, we still :ref: `recommend<recommend-secrets-randbits> `
50
50
using :py:func: `secrets.randbits ` to generate seeds with 128 bits of entropy to
51
51
avoid the remaining biases introduced by human-chosen seeds.
@@ -62,7 +62,7 @@ avoid the remaining biases introduced by human-chosen seeds.
62
62
63
63
.. end_block
64
64
65
- For convenience the direct use of `~ SeedSequence ` is not necessary.
65
+ For convenience the direct use of `SeedSequence ` is not necessary.
66
66
The above ``streams `` can be spawned directly from a parent generator
67
67
via `~Generator.spawn `:
68
68
@@ -74,7 +74,7 @@ via `~Generator.spawn`:
74
74
.. end_block
75
75
76
76
Child objects can also spawn to make grandchildren, and so on.
77
- Each child has a `~ SeedSequence ` with its position in the tree of spawned
77
+ Each child has a `SeedSequence ` with its position in the tree of spawned
78
78
child objects mixed in with the user-provided seed to generate independent
79
79
(with very high probability) streams.
80
80
@@ -92,7 +92,7 @@ Python has increasingly-flexible mechanisms for parallelization available, and
92
92
this scheme fits in very well with that kind of use.
93
93
94
94
Using this scheme, an upper bound on the probability of a collision can be
95
- estimated if one knows the number of streams that you derive. `~ SeedSequence `
95
+ estimated if one knows the number of streams that you derive. `SeedSequence `
96
96
hashes its inputs, both the seed and the spawn-tree-path, down to a 128-bit
97
97
pool by default. The probability that there is a collision in
98
98
that pool, pessimistically-estimated ([1 ]_), will be about :math: `n^2 *2 ^{-128 }` where
@@ -110,7 +110,7 @@ territory ([2]_).
110
110
.. [2 ] In this calculation, we can mostly ignore the amount of numbers drawn from each
111
111
stream. See :ref: `upgrading-pcg64 ` for the technical details about
112
112
`PCG64 `. The other PRNGs we provide have some extra protection built in
113
- that avoids overlaps if the `~ SeedSequence ` pools differ in the
113
+ that avoids overlaps if the `SeedSequence ` pools differ in the
114
114
slightest bit. `PCG64DXSM ` has :math: `2 ^{127 }` separate cycles
115
115
determined by the seed in addition to the position in the
116
116
:math: `2 ^{128 }` long period for each cycle, so one has to both get on or
@@ -133,7 +133,7 @@ territory ([2]_).
133
133
Sequence of integer seeds
134
134
-------------------------
135
135
136
- As discussed in the previous section, `~ SeedSequence ` can not only take an
136
+ As discussed in the previous section, `SeedSequence ` can not only take an
137
137
integer seed, it can also take an arbitrary-length sequence of (non-negative)
138
138
integers. If one exercises a little care, one can use this feature to design
139
139
*ad hoc * schemes for getting safe parallel PRNG streams with similar safety
@@ -164,7 +164,7 @@ integer in a list.
164
164
This can be used to replace a number of unsafe strategies that have been used
165
165
in the past which try to combine the root seed and the ID back into a single
166
166
integer seed value. For example, it is common to see users add the worker ID to
167
- the root seed, especially with the legacy `~ RandomState ` code.
167
+ the root seed, especially with the legacy `RandomState ` code.
168
168
169
169
.. code-block :: python
170
170
@@ -253,13 +253,13 @@ are listed below.
253
253
+-----------------+-------------------------+-------------------------+-------------------------+
254
254
| BitGenerator | Period | Jump Size | Bits per Draw |
255
255
+=================+=========================+=========================+=========================+
256
- | MT19937 | :math: `2 ^{19937 }-1 ` | :math: `2 ^{128 }` | 32 |
256
+ | ` MT19937 ` | :math: `2 ^{19937 }-1 ` | :math: `2 ^{128 }` | 32 |
257
257
+-----------------+-------------------------+-------------------------+-------------------------+
258
- | PCG64 | :math: `2 ^{128 }` | :math: `~2 ^{127 }` ([3 ]_) | 64 |
258
+ | ` PCG64 ` | :math: `2 ^{128 }` | :math: `~2 ^{127 }` ([3 ]_) | 64 |
259
259
+-----------------+-------------------------+-------------------------+-------------------------+
260
- | PCG64DXSM | :math: `2 ^{128 }` | :math: `~2 ^{127 }` ([3 ]_) | 64 |
260
+ | ` PCG64DXSM ` | :math: `2 ^{128 }` | :math: `~2 ^{127 }` ([3 ]_) | 64 |
261
261
+-----------------+-------------------------+-------------------------+-------------------------+
262
- | Philox | :math: `2 ^{256 }` | :math: `2 ^{128 }` | 64 |
262
+ | ` Philox ` | :math: `2 ^{256 }` | :math: `2 ^{128 }` | 64 |
263
263
+-----------------+-------------------------+-------------------------+-------------------------+
264
264
265
265
.. [3 ] The jump size is :math: `(\phi -1 )*2 ^{128 }` where :math: `\phi ` is the
0 commit comments