Philox Counter-based RNG¶
-
class randomgen.philox.Philox(seed=
None
, *, counter=None
, key=None
, number=4
, width=64
, numpy_seed=False
, mode='sequence'
)¶ Container for the Philox family of pseudo-random number generators.
- Parameters:¶
- seed=
None
¶ Random seed initializing the pseudo-random number generator. Can be an integer in [0, 2**64), array of integers in [0, 2**64), a SeedSequence instance or
None
(the default). If seed isNone
, data will be read from/dev/urandom
(or the Windows analog) if available. If unavailable, a hash of the time and process ID is used.- counter=
None
¶ Counter to use in the Philox state. Can be either a Python int in [0, 2**(N*W)) where N is number of W is the width, or a M-element uint64 array where M = N*W // 64. If not provided, the counter is initialized at 0.
- key=
None
¶ Key to use in the Philox state. Unlike seed, which is run through another RNG before use, the value in key is directly set. Can be either a Python int in [0, 2**(N*W//2)) or a m-element uint64 array where m = N*W // (2 * 64). If number=2 and width=32, then the value must be in [0, 2**32) even if stored in a uint64 array. key and seed cannot both be used.
- number=
4
¶ Number of values to produce in a single call. Maps to N in the Philox variant naming scheme PhiloxNxW.
- width=
64
¶ Bit width the values produced. Maps to W in the Philox variant naming scheme PhiloxNxW.
- numpy_seed=
False
¶ Set to True to use the same seeding mechanism as NumPy and so matches NumPy exactly. To match NumPy, variant must be
xsl-rr
. When using “numpy”,inc
must beNone
.- mode=
'sequence'
¶ “sequence” uses a SeedSequence to transforms the seed into an initial state. “numpy” also uses a SeedSequence but seeds the generator in a way that is identical to NumPy. When using “numpy”,
inc
must beNone
. Additionally, to match NumPy, variant must bexsl-rr
(this is not checked).
- seed=
- lock¶
Lock instance that is shared so that the same bit git generator can be used in multiple Generators without corrupting the state. Code that generates values from a bit generator should hold the bit generator’s lock.
- Type:¶
- seed_seq¶
The SeedSequence instance used to initialize the generator if mode is “sequence” or is seed is a SeedSequence.
- Type:¶
{None, SeedSequence}
Notes
Philox is a 32 or 64-bit PRNG that uses a counter-based design based on weaker (and faster) versions of cryptographic functions [1]. Instances using different values of the key produce distinct sequences.
Philox
has a period of \(N*2^{N*W}\) and supports arbitrary advancing and jumping the sequence in increments of \(2^{N*W//2}\). These features allow multiple non-overlapping sequences to be generated.Philox
provides a capsule containing function pointers that produce doubles, and unsigned 32 and 64- bit integers. These are not directly consumable in Python and must be consumed by aGenerator
or similar object that supports low-level access.See
ThreeFry
for a closely related PRNG.State and Seeding
The Philox state vector consists of a (N*W)-bit value and a (N*W//2)-bit value. These are encoded as an n-element w-bit array. One is a counter which is incremented by 1 for every
n
w
-bit randoms produced. The second is a key which determines the sequence produced. Using different keys produces distinct sequences.Using a single 64-bit value for the seed can only initialize a small range of the possible initial state values.
Parallel Features
Philox
can be used in parallel applications by calling thejump
method to advances the state as-if \(2^{N*W//2}\) random numbers have been generated. Alternatively,advance
can be used to advance the counter for any positive step in [0, 2**N*W). When usingjump
, all generators should be initialized with the same seed to ensure that the segments come from the same sequence.>>> from numpy.random import Generator >>> from randomgen import Philox >>> rg = [Generator(Philox(1234)) for _ in range(10)] # Advance each Philox instance by i jumps >>> for i in range(10): ... rg[i].bit_generator.jump(i)
Alternatively,
Philox
can be used in parallel applications by using a sequence of distinct keys where each instance uses different key.>>> key = 2**196 + 2**132 + 2**65 + 2**33 + 2**17 + 2**9 >>> rg = [Generator(Philox(key=key+i)) for i in range(10)]
Compatibility Guarantee
Philox
makes a guarantee that a fixed seed and will always produce the same random integer stream.Examples
>>> from numpy.random import Generator >>> from randomgen import Philox >>> rg = Generator(Philox(1234)) >>> rg.standard_normal() 0.123 # random
References
Seeding and State¶
|
Seed the generator |
Get or set the PRNG state |
Parallel generation¶
|
Advance the underlying RNG as-if delta draws have occurred. |
|
Jumps the state as-if 2**(W*N/2) random numbers have been generated. |
|
Returns a new bit generator with the state jumped |
Extending¶
CFFI interface |
|
ctypes interface |
Testing¶
|
Return randoms as generated by the underlying BitGenerator |