28 Numerics library [numerics]

28.5 Random number generation [rand]

28.5.4 Random number engine class templates [rand.eng]

28.5.4.5 Class template philox_engine [rand.eng.philox]

A philox_engine random number engine produces unsigned integer random numbers in the closed interval [0, m], where and the template parameter w defines the range of the produced numbers.
The state of a philox_engine object consists of a sequence X of n unsigned integer values of width w, a sequence K of values of result_type, a sequence Y of n values of result_type, and a scalar i, where
  • X is the interpretation of the unsigned integer counter value of bits,
  • K are keys, which are generated once from the seed (see constructors below) and remain constant unless the seed function ([rand.req.eng]) is invoked,
  • Y stores a batch of output values, and
  • i is an index for an element of the sequence Y.
The generation algorithm returns , the value stored in the element of Y after applying the transition algorithm.
The state transition is performed as if by the following algorithm: i = i + 1 if (i == n) { Y = Philox(K, X) // see below Z = Z + 1 i = 0 }
The Philox function maps the length- sequence K and the length-n sequence X into a length-n output sequence Y.
Philox applies an r-round substitution-permutation network to the values in X.
A single round of the generation algorithm performs the following steps:
  • The output sequence of the previous round (X in case of the first round) is permuted to obtain the intermediate state V: where and is defined in Table 101.
    Table 101: Values for the word permutation [tab:rand.eng.philox.f]
    j
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    n
    2
    0
    1
    4
    0
    3
    2
    1
    8
    2
    1
    4
    7
    6
    5
    0
    3
    16
    0
    9
    2
    13
    6
    11
    4
    15
    10
    7
    12
    3
    14
    5
    8
    1
    [Note 1: 
    For the sequence is not permuted.
    — end note]
  • The following computations are applied to the elements of the V sequence: where:
    • mullo(a, b, w) is the low half of the modular multiplication of a and b: ,
    • mulhi(a, b, w) is the high half of the modular multiplication of a and b: ,
    • is the index in the sequences,
    • is the index of the round,
    • is the round key for round q, ,
    • are the elements of the key sequence K,
    • is multipliers[k], and
    • is round_consts[k].
After r applications of the single-round function, Philox returns the sequence .
namespace std { template<class UIntType, size_t w, size_t n, size_t r, UIntType... consts> class philox_engine { static constexpr size_t array-size = n / 2; // exposition only public: // types using result_type = UIntType; // engine characteristics static constexpr size_t word_size = w; static constexpr size_t word_count = n; static constexpr size_t round_count = r; static constexpr array<result_type, array-size> multipliers; static constexpr array<result_type, array-size> round_consts; static constexpr result_type min() { return 0; } static constexpr result_type max() { return m - 1; } static constexpr result_type default_seed = 20111115u; // constructors and seeding functions philox_engine() : philox_engine(default_seed) {} explicit philox_engine(result_type value); template<class Sseq> explicit philox_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> void seed(Sseq& q); void set_counter(const array<result_type, n>& counter); // equality operators friend bool operator==(const philox_engine& x, const philox_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractors template<class charT, class traits> friend basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const philox_engine& x); template<class charT, class traits> friend basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, philox_engine& x); }; }
Mandates:
  • sizeof...(consts) == n is true, and
  • n == 2 || n == 4 || n == 8 || n == 16 is true, and
  • 0 < r is true, and
  • 0 < w && w <= numeric_limits<UIntType>​::​digits is true.
The template parameter pack consts represents the and constants which are grouped as follows: .
The textual representation consists of the values of , in that order.
[Note 2: 
The stream extraction operator can reconstruct Y from K and X, as needed.
— end note]
explicit philox_engine(result_type value);
Effects: Sets the element of sequence K to .
All elements of sequences X and K (except ) are set to 0.
The value of i is set to .
template<class Sseq> explicit philox_engine(Sseq& q);
Effects: With and an array (or equivalent) a of length , invokes q.generate(a + 0, a + n / 2 * p) and then iteratively for , sets to .
All elements of sequence X are set to 0.
The value of i is set to .
void set_counter(const array<result_type, n>& c);
Effects: For sets to .
The value of i is set to .
[Note 3: 
The counter is the value Z introduced at the beginning of this subclause.
— end note]