Philox Counterbased RNG¶

class
numpy.random.
Philox
(seed=None, counter=None, key=None)¶ Container for the Philox (4x64) pseudorandom number generator.
Parameters:  seed : {None, int, array_like[ints], ISeedSequence}, optional
A seed to initialize the BitGenerator. If None, then fresh, unpredictable entropy will be pulled from the OS. If an
int
orarray_like[ints]
is passed, then it will be passed toSeedSequence
to derive the initial BitGenerator state. One may also pass in an implementor of the ISeedSequence interface likeSeedSequence
. counter : {None, int, array_like}, optional
Counter to use in the Philox state. Can be either a Python int (long in 2.x) in [0, 2**256) or a 4element uint64 array. If not provided, the RNG is initialized at 0.
 key : {None, int, array_like}, optional
Key to use in the Philox state. Unlike seed, the value in key is directly set. Can be either a Python int in [0, 2**128) or a 2element uint64 array. key and
seed
cannot both be used.
Notes
Philox is a 64bit PRNG that uses a counterbased design based on weaker (and faster) versions of cryptographic functions [1]. Instances using different values of the key produce independent sequences. Philox has a period of and supports arbitrary advancing and jumping the sequence in increments of . These features allow multiple nonoverlapping 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 lowlevel access.State and Seeding
The
Philox
state vector consists of a 256bit value encoded as a 4element uint64 array and a 128bit value encoded as a 2element uint64 array. The former is a counter which is incremented by 1 for every 4 64bit randoms produced. The second is a key which determined the sequence produced. Using different keys produces independent sequences.The input seed is processed by
SeedSequence
to generate the key. The counter is set to 0.Alternately, one can omit the seed parameter and set the
key
andcounter
directly.Parallel Features
The preferred way to use a BitGenerator in parallel applications is to use the
SeedSequence.spawn
method to obtain entropy values, and to use these to generate new BitGenerators:>>> from numpy.random import Generator, Philox, SeedSequence >>> sg = SeedSequence(1234) >>> rg = [Generator(Philox(s)) for s in sg.spawn(10)]
Philox
can be used in parallel applications by calling thejumped
method to advances the state asif random numbers have been generated. Alternatively,advance
can be used to advance the counter for any positive step in [0, 2**256). When usingjumped
, all generators should be chained to ensure that the segments come from the same sequence.>>> from numpy.random import Generator, Philox >>> bit_generator = Philox(1234) >>> rg = [] >>> for _ in range(10): ... rg.append(Generator(bit_generator)) ... bit_generator = bit_generator.jumped()
Alternatively,
Philox
can be used in parallel applications by using a sequence of distinct keys where each instance uses different key.>>> key = 2**96 + 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 will always produce the same random integer stream.References
[1] John K. Salmon, Mark A. Moraes, Ron O. Dror, and David E. Shaw, “Parallel Random Numbers: As Easy as 1, 2, 3,” Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis (SC11), New York, NY: ACM, 2011. Examples
>>> from numpy.random import Generator, Philox >>> rg = Generator(Philox(1234)) >>> rg.standard_normal() 0.123 # random
Attributes:  lock: threading.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.