Parallel random number object

template<typename T>
class prng

Container class for parallel random number streams. This class does not do any actual running of random numbers (and nothing in parallel) but acts to hold together the state and ease some bookkeeping.

Template Parameters:

T – Random number state type to use

Public Types

using rng_state = T

The random number state type.

using int_type = typename rng_state::int_type

The underlying integer type used by rng_state

Public Functions

inline prng(const size_t n, const int seed, const bool deterministic = false)

Construct a new prng object from a single integer seed

Parameters:
  • n – The number of streams

  • seed – An integer to use as a seed

  • deterministic – Selects use of the “deterministic” generator

inline prng(const size_t n, const std::vector<int_type> &seed, const bool deterministic = false)

Construct a new prng object from a vector of seed data. We will consume as many items of seed as possible, then start jumping

Parameters:

seed – A vector of integers to seed the generator with

inline size_t size() const

The number of streams within the object.

inline void jump()

Jump all generators forward.

inline void long_jump()

Take a long jump for every generator.

inline rng_state &state(size_t i)

Return the ith state, as an rng_state reference. This is the workhorse method and the main one likely to be used once the object is constructed.

Parameters:

i – The index of the stream (0, 1, …, size() - 1)

inline std::vector<int_type> export_state()

Convert the random number state of all generators into a single vector. This can be used to save the state to restore using import_state()

inline void import_state(const std::vector<int_type> &state)

Import a vector of random number state, previously saved by export_state()

Parameters:

state – A vector of state

inline bool deterministic() const

Indicates if the generators are deterministic.

Example

#include <iostream>
#include <dust/random/random.hpp>

template <typename T>
void show_state(T& state, const char * label) {
  std::cout << label << std::endl;
  std::cout << std::hex;
  for (size_t i = 0; i < T::size(); ++i) {
    std::cout << state[i] << std::endl;
  }
}

int main() {
  // Using a small state so it's easier to see the output
  using rng_state_type = dust::random::xoroshiro128plus;

  // Create a prng object with 4 streams (and initial seed 42)
  auto obj = dust::random::prng<rng_state_type>(4, 42);
  show_state(obj.state(0), "first stream");

  // An equivalently created state
  auto cmp = dust::random::seed<rng_state_type>(42);
  show_state(cmp, "\nequivalent state");

  // The second stream
  show_state(obj.state(1), "\nsecond stream");

  // Jumping our state forward gets to the same place
  dust::random::jump(cmp);
  show_state(cmp, "\nequivalent state");
}
first stream
bdd732262feb6e95
57e1faba65107204

equivalent state
bdd732262feb6e95
57e1faba65107204

second stream
1b3c79462edc2ed4
871ea92fbd8aefdf

equivalent state
1b3c79462edc2ed4
871ea92fbd8aefdf