Skip to main content
`Ctrl`+`K`

# Philox counter-based RNG

class numpy.random.Philox(seed=None, counter=None, key=None)

  Container for the Philox (4x64) pseudo-random number generator.

  Parameters:
    seed{None, int, array_like[ints], SeedSequence}, optional

      A seed to initialize the `BitGenerator`. If None, then fresh, unpredictable entropy will be pulled from the OS. If an `int` or `array_like[ints]` is passed, then it will be passed to `SeedSequence` to derive the initial `BitGenerator` state. One may also pass in a `SeedSequence` instance.

    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 4-element 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 2-element uint64 array. key and `seed` cannot both be used.

  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.

  Notes

  Philox is a 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 independent sequences. Philox has a period of \(2^{256} - 1\) and supports arbitrary advancing and jumping the sequence in increments of \(2^{128}\). 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 a `Generator` or similar object that supports low-level access.

  State and Seeding

  The `Philox` state vector consists of a 256-bit value encoded as a 4-element uint64 array and a 128-bit value encoded as a 2-element uint64 array. The former is a counter which is incremented by 1 for every 4 64-bit 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` and `counter` 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 the `jumped` method to advance the state as-if \(2^{128}\) random numbers have been generated. Alternatively, `advance` can be used to advance the counter for any positive step in [0, 2**256). When using `jumped`, 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

## State

`state` | Get or set the PRNG state

## Parallel generation

`advance`(delta) | Advance the underlying RNG as-if delta draws have occurred.
`jumped`([jumps]) | Returns a new bit generator with the state jumped

## Extending

`cffi` | CFFI interface
`ctypes` | ctypes interface