<tt>xoshiro
Loading...
Searching...
No Matches
xso::generator< State, Scrambler >

A pseudorandom number generator combining a State and a Scrambler. More...

#include <xoshiro.h>

Public Member Functions

Constructors:
constexpr generator ()
 The default constructor seeds the full underlying state randomly.
constexpr generator (word_type s)
 Construct a generator quickly but not well from a single unsigned integer value.
template<std::input_iterator Iter>
requires std::convertible_to<std::iter_value_t<Iter>, word_type>
constexpr generator (Iter b, Iter e)
 Construct and seed from an iteration of unsigned words which are all copied into the state.
Seeding methods:
constexpr void seed ()
 Seeds the full state to random starting values.
constexpr void seed (word_type seed)
 Seeds the generator quickly but probably not well from a single unsigned integer value.
template<std::input_iterator Src>
requires std::convertible_to<std::iter_value_t<Src>, word_type>
constexpr void seed (Src b, Src e)
 Seeds the generator from an iteration of unsigned words which are all copied into the state.
Advance and output methods:
constexpr void step ()
 Advances the state by one step.
constexpr result_type operator() ()
 Returns the next random value from the generator which is a result_type unsigned integer.
State access methods:
constexpr word_type operator[] (std::size_t i) const
 Returns the i'th state word.
template<std::output_iterator< word_type > Dst>
constexpr void get_state (Dst dst) const
 Copies the whole state into the destination iterator dst.
Sampling methods:
template<std::integral T>
constexpr T sample (T a, T b)
 Sampling method that returns a single integer value from a uniform distribution over [a, b].
template<std::floating_point T>
constexpr T sample (T a, T b)
 Sampling method that returns a single real value from a uniform distribution over [a, b).
template<std::integral T>
constexpr T index (T len)
 Sampling method that returns a single index from a uniform distribution over [0, len-1].
template<std::input_iterator T>
constexpr auto sample (T b, T e)
 Sampling method that returns a single value from an iteration – all elements are equally likely to be returned.
template<typename Container>
requires std::ranges::input_range<const Container> && std::ranges::common_range<const Container>
constexpr auto sample (const Container &container)
 Sampling method that returns a single value from a container – all elements are equally likely to be returned.
template<std::input_iterator Src, std::output_iterator< std::iter_value_t< Src > > Dst>
constexpr Dst sample (Src b, Src e, Dst dst, std::size_t n)
 Sampling method that picks n elements without replacement from an iteration [b, e) and puts them in dst.
template<typename Src, std::output_iterator< std::ranges::range_value_t< const Src > > Dst>
requires std::ranges::input_range<const Src> && std::ranges::common_range<const Src>
constexpr auto sample (const Src &src, Dst dst, std::size_t n)
 Sampling method that picks n elements without replacement from a container and puts them in dst.
constexpr auto sample (Distribution auto &dist)
 Sampling method that returns a single random variate drawn from a distribution.
template<typename Dst>
constexpr Dst sample (Distribution auto &dist, Dst dst, std::size_t n)
 Sampling method that takes n samples from a distribution and puts them into a destination iterator.
constexpr std::size_t roll (std::size_t n_sides=6)
 Sampling method that rolls a dice with an arbitrary number of sides (defaults to the usual 6).
constexpr bool flip (double p=0.5)
 Sampling method that flips a coin, where the probability of getting true is p (defaults to 0.5).
Shuffling methods:
template<std::random_access_iterator Iter>
constexpr void shuffle (Iter b, Iter e)
 This method shuffles the elements in an iteration.
template<typename Container>
requires std::ranges::random_access_range<Container> && std::ranges::common_range<Container>
constexpr void shuffle (Container &container)
 This method shuffles all the elements of a container.
Discard method:
void discard (std::uint64_t z)
 Discards the next z iterations in the random number sequence.
Extra method that uses the optional <tt>gf2</tt> library.
void jump (gf2::BitPolynomial< word_type > const &jump_poly)
 Jumps a state/generator ahead in its random number stream by J steps.

Type definitions and class methods:

using state_type = State
 The State used for by generator type – one of the two state classes defined below.
using scrambler_type = Scrambler
 The Scrambler used for by generator type – one of the scrambler classes defined below.
using word_type = typename State::word_type
 This generator type packs its state into words of this type (in practice, 32 or 64 bit unsigneds).
using array_type = typename State::array_type
 A convenience container type to hold the full state of this generator, jump polynomial coefficients, etc.
static constexpr std::size_t word_count ()
 Class method that returns the number of words of state for this type of generator.
static constexpr std::size_t bit_count ()
 Class method that returns the number of bits of state for this type of generator.
static constexpr auto type_string ()
 Class method that returns a name for this type of generator — combining State and Scrambler names.

Items required for the std::uniform_random_bit_generator concept:

using result_type = word_type
 The unsigned integer type returned by the generator's operator()() method.
static constexpr result_type min () noexcept
 Returns the smallest value this generator can produce.
static constexpr result_type max () noexcept
 Returns the largest value this generator can produce.

Jump methods:

template<std::output_iterator< word_type > Dst>
static constexpr void characteristic_coefficients (Dst dst)
 Class method that fills a destination iterator with the state's precomputed characteristic polynomial coefficients.
static constexpr auto characteristic_coefficients ()
 Class method that returns the state's precomputed characteristic polynomial coefficients packed into an array of words.
constexpr auto jump (std::size_t n, bool n_is_log2=false)
 Jumps the generator's state forward by J steps where J is either n or 2^n to accommodate huge jumps that do not fit into the usual integer range.
constexpr void jump (const array_type &jump_coefficients)
 Efficiently jumps the generator's state forward by J steps where J can be huge (e.g. 2^100).

Detailed Description

template<typename State, typename Scrambler>
class xso::generator< State, Scrambler >

A pseudorandom number generator combining a State and a Scrambler.

Template Parameters
StateStores the generator state, and has a step method to advance it.
ScramblerA functor to reduce the State to a single output word (a 32 or 64 bit unsigned).

Note

Most users will not use this directly but instead reference one of the type aliased generators below.

Member Typedef Documentation

◆ result_type

template<typename State, typename Scrambler>
using xso::generator< State, Scrambler >::result_type = word_type

The unsigned integer type returned by the generator's operator()() method.

Note

  • This typename is required to satisfy the std::uniform_random_bit_generator concept.
  • For our generators this is always identical to the word_type used to store the state.

Constructor & Destructor Documentation

◆ generator() [1/3]

template<typename State, typename Scrambler>
xso::generator< State, Scrambler >::generator ( )
inlineconstexpr

The default constructor seeds the full underlying state randomly.

This will produce a high quality stream of random outputs that are different on each run.

Example

assert(rng() != rng()); // Very, very unlucky if they are equal!
rng64 rng
The recommended default generator for most usage – used as xso::rng.
Definition xoshiro.h:1211

◆ generator() [2/3]

template<typename State, typename Scrambler>
xso::generator< State, Scrambler >::generator ( word_type s)
inlineexplicitconstexpr

Construct a generator quickly but not well from a single unsigned integer value.

Seeding from a single unsigned value is an easy way to get repeatable random streams.

Example

xso::rng rng0{0x12345678};
xso::rng rng1{0x12345678};
assert_eq(rng0(), rng1()); // Same seed => same stream

◆ generator() [3/3]

template<typename State, typename Scrambler>
template<std::input_iterator Iter>
requires std::convertible_to<std::iter_value_t<Iter>, word_type>
xso::generator< State, Scrambler >::generator ( Iter b,
Iter e )
inlineexplicitconstexpr

Construct and seed from an iteration of unsigned words which are all copied into the state.

  • The values in the iteration must be convertible to the generator's word_type.
  • The number of words provided must match the number of words in the generator's state.

Note: The words shouldn't all be zeros as that is a fixed point for all xoshiro/xoroshiro generators.

Example

xso::rng::array_type seed_words = {0x12345678, 0x9abcdef0, 0x13579bdf, 0x2468ace0};
xso::rng rng0{seed_words.cbegin(), seed_words.cend()};
xso::rng rng1{seed_words.cbegin(), seed_words.cend()};
assert_eq(rng0(), rng1()); // Same seed => same stream
xso::rng::array_type zero_words = {0, 0, 0, 0};
xso::rng rng2{zero_words.cbegin(), zero_words.cend()}; // Bad: all zero seed!
for (auto i = 0uz; i < 40; ++i) assert_eq(rng2(), 0); // Will always produce zeros!
typename xoshiro_4x64::array_type array_type
Definition xoshiro.h:84

Member Function Documentation

◆ bit_count()

template<typename State, typename Scrambler>
constexpr std::size_t xso::generator< State, Scrambler >::bit_count ( )
inlinestaticconstexpr

Class method that returns the number of bits of state for this type of generator.

Example

assert_eq(xso::rng::bit_count(), 256);
static constexpr std::size_t bit_count()
Definition xoshiro.h:100

◆ characteristic_coefficients() [1/2]

template<typename State, typename Scrambler>
constexpr auto xso::generator< State, Scrambler >::characteristic_coefficients ( )
inlinestaticconstexpr

Class method that returns the state's precomputed characteristic polynomial coefficients packed into an array of words.

For the purpose of analysis, we note that the state advance algorithm can be represented by the linear transformation \(\mathbf{s} \leftarrow T \cdot \mathbf{s},\) where \(\mathbf{s}\) is the state vector, and \(T\) is an \(n \times n\) full-rank matrix over GF(2).

The characteristic polynomial \(c(x)\) for the transition matrix \(T\) can be written as \(c(x) = x^n + p(x)\) where \(p(x) = p_0 + p_1 x + ... + p_{n-1} x^{n-1}\).

The polynomial \(p(x)\) can be represented by its \(n\) bit coefficients. Those coefficients are precomputed and stored in word form for efficiency.

Panics

In practice, we have precomputed the characteristic polynomial for just a few xoshiro/xoroshiro's with specific parameters. If the State has no precomputed characteristic coefficients this method will throw an exception.

◆ characteristic_coefficients() [2/2]

template<typename State, typename Scrambler>
template<std::output_iterator< word_type > Dst>
constexpr void xso::generator< State, Scrambler >::characteristic_coefficients ( Dst dst)
inlinestaticconstexpr

Class method that fills a destination iterator with the state's precomputed characteristic polynomial coefficients.

For the purpose of analysis, we note that the state advance algorithm can be represented by the linear transformation \(\mathbf{s} \leftarrow T \cdot \mathbf{s},\) where \(\mathbf{s}\) is the state vector, and \(T\) is an \(n \times n\) full-rank matrix over GF(2).

The characteristic polynomial \(c(x)\) for the transition matrix \(T\) can be written as \(c(x) = x^n + p(x)\) where \(p(x) = p_0 + p_1 x + ... + p_{n-1} x^{n-1}\).

The polynomial \(p(x)\) can be represented by its \(n\) bit coefficients. Those coefficients are precomputed and stored in word form for efficiency.

Note: The destination iterator must be able to accept word_count() values of type word_type.

Panics

In practice, we have precomputed the characteristic polynomial for just a few xoshiro/xoroshiro's with specific parameters. If the State has no precomputed characteristic coefficients this method will throw an exception.

◆ discard()

template<typename State, typename Scrambler>
void xso::generator< State, Scrambler >::discard ( std::uint64_t z)
inline

Discards the next z iterations in the random number sequence.

This is equivalent to calling step() z times and is the typical way used to discard random values in the standard library. It is here for compatibility with that interface but is basically rubbish.

Note: We can do much better for large z by using one of the jump methods.

◆ flip()

template<typename State, typename Scrambler>
bool xso::generator< State, Scrambler >::flip ( double p = 0.5)
inlineconstexpr

Sampling method that flips a coin, where the probability of getting true is p (defaults to 0.5).

Example

std::size_t true_count = 0;
std::size_t n_trials = 1'000'000;
for (auto i = 0uz; i < n_trials; ++i) if (rng.flip()) ++true_count;
double true_fraction = static_cast<double>(true_count) / static_cast<double>(n_trials);
assert(true_fraction > 0.49 && true_fraction < 0.51); // Should be close to 0.5

◆ get_state()

template<typename State, typename Scrambler>
template<std::output_iterator< word_type > Dst>
void xso::generator< State, Scrambler >::get_state ( Dst dst) const
inlineconstexpr

Copies the whole state into the destination iterator dst.

  • The iterator's value type must be convertible from the generator's word_type.
  • The iterator must be able to accept word_count() values.

◆ index()

template<typename State, typename Scrambler>
template<std::integral T>
T xso::generator< State, Scrambler >::index ( T len)
inlineconstexpr

Sampling method that returns a single index from a uniform distribution over [0, len-1].

This is a convenience method for sampling an index into an array or container of length len. It is equivalent to calling sample(0, len-1).

Note: No error checking is done and the behaviour is undefined if len == 0.

Example

std::vector<int> vec = {10, 20, 30, 40, 50};
auto idx = rng.index(vec.size());
assert(idx >= 0 && idx < vec.size());

◆ jump() [1/3]

template<typename State, typename Scrambler>
void xso::generator< State, Scrambler >::jump ( const array_type & jump_coefficients)
inlineconstexpr

Efficiently jumps the generator's state forward by J steps where J can be huge (e.g. 2^100).

This jump method must be passed pre-computed jump polynomial coefficients which can be calculated using the xso::jump_coefficients<State>() free function. This is the preferred way to jump the state forward by a large number of steps when you need to do it often as the jump polynomial can be computed once and reused many times.

Example

xso::rng r1 = r0;
auto J = 1'000'000uz;
r1.discard(J);
for (auto i = 0uz; i < xso::rng::word_count(); ++i) assert_eq(r0[i], r1[i]);
assert_eq(r0(), r1());
static constexpr std::size_t word_count()
Definition xoshiro.h:92
void discard(std::uint64_t z)
Discards the next z iterations in the random number sequence.
Definition xoshiro.h:614
constexpr auto jump(std::size_t n, bool n_is_log2=false)
Jumps the generator's state forward by J steps where J is either n or 2^n to accommodate huge jumps t...
Definition xoshiro.h:642
constexpr auto jump_coefficients(std::size_t J, bool J_is_log2=false)
Returns the coefficients of the jump polynomial that can be used to jump a generator/state ahead by ...
Definition xoshiro.h:1301

◆ jump() [2/3]

template<typename State, typename Scrambler>
void xso::generator< State, Scrambler >::jump ( gf2::BitPolynomial< word_type > const & jump_poly)
inline

Jumps a state/generator ahead in its random number stream by J steps.

This method must be passed a precomputed jump polynomial as a bit-polynomial from the jump_polynomial method.

◆ jump() [3/3]

template<typename State, typename Scrambler>
auto xso::generator< State, Scrambler >::jump ( std::size_t n,
bool n_is_log2 = false )
inlineconstexpr

Jumps the generator's state forward by J steps where J is either n or 2^n to accommodate huge jumps that do not fit into the usual integer range.

This method also returns the jump polynomial coefficients used to perform the jump. These coefficients can be reused to efficiently and repeatedly jump by the same number of steps using the alternate jump() method below.

Example

xso::rng r1 = r0;
auto J = 1'000'000uz;
auto jump_coeffs = r0.jump(J);
r1.discard(J);
for (auto i = 0uz; i < xso::rng::word_count(); ++i) assert_eq(r0[i], r1[i]);
assert_eq(r0(), r1());
r0.jump(jump_coeffs); // Jump again by same amount but more efficiently
r1.discard(J);
for (auto i = 0uz; i < xso::rng::word_count(); ++i) assert_eq(r0[i], r1[i]);
assert_eq(r0(), r1());

◆ max()

template<typename State, typename Scrambler>
constexpr result_type xso::generator< State, Scrambler >::max ( )
inlinestaticconstexprnoexcept

Returns the largest value this generator can produce.

Note

This method is required by the std::uniform_random_bit_generator concept.

Example

assert_eq(xso::rng::max(), std::numeric_limits<typename xso::rng::result_type>::max());
static constexpr result_type max() noexcept
Definition xoshiro.h:147

◆ min()

template<typename State, typename Scrambler>
constexpr result_type xso::generator< State, Scrambler >::min ( )
inlinestaticconstexprnoexcept

Returns the smallest value this generator can produce.

Note

This method is required by the std::uniform_random_bit_generator concept.

Example

assert_eq(xso::rng::min(), 0);
static constexpr result_type min() noexcept
Definition xoshiro.h:136

◆ operator()()

template<typename State, typename Scrambler>
result_type xso::generator< State, Scrambler >::operator() ( )
inlineconstexpr

Returns the next random value from the generator which is a result_type unsigned integer.

This scrambles the state to produce a single output, then advances the state to prepare for the next call.

Note

This method signature is required by the std::uniform_random_bit_generator concept.

◆ roll()

template<typename State, typename Scrambler>
std::size_t xso::generator< State, Scrambler >::roll ( std::size_t n_sides = 6)
inlineconstexpr

Sampling method that rolls a dice with an arbitrary number of sides (defaults to the usual 6).

Example

std::size_t n_rolls = 1'000'000;
std::array<std::size_t, 6> counts = {0};
for (auto i = 0uz; i < n_rolls; ++i) { ++counts[rng.roll() - 1]; }
for (auto c : counts) {
double fraction = static_cast<double>(c) / static_cast<double>(n_rolls);
assert(fraction > 0.16 && fraction < 0.18); // Each side should come up about 1/6 of the time
}

◆ sample() [1/8]

template<typename State, typename Scrambler>
template<typename Container>
requires std::ranges::input_range<const Container> && std::ranges::common_range<const Container>
auto xso::generator< State, Scrambler >::sample ( const Container & container)
inlineconstexpr

Sampling method that returns a single value from a container – all elements are equally likely to be returned.

The "container" can be any type that supports std::ranges::cbegin() and std::ranges::cend().

Note: No error checking is done and the behaviour is undefined if the container is empty.

Example

std::vector<int> vec = {0, 1, 2, 3, 4, 5};
std::size_t n_trials = 1'000'000;
std::array<std::size_t, 6> counts = {0};
for (auto i = 0uz; i < n_trials; ++i) { ++counts[static_cast<std::size_t>(rng.sample(vec))]; }
for (auto c : counts) {
double fraction = static_cast<double>(c) / static_cast<double>(n_trials);
assert(fraction > 0.16 && fraction < 0.18); // Each element should be chosen about 1/6 of the time
}
constexpr T sample(T a, T b)
Sampling method that returns a single integer value from a uniform distribution over [a,...
Definition xoshiro.h:343

◆ sample() [2/8]

template<typename State, typename Scrambler>
template<typename Src, std::output_iterator< std::ranges::range_value_t< const Src > > Dst>
requires std::ranges::input_range<const Src> && std::ranges::common_range<const Src>
auto xso::generator< State, Scrambler >::sample ( const Src & src,
Dst dst,
std::size_t n )
inlineconstexpr

Sampling method that picks n elements without replacement from a container and puts them in dst.

Selects n elements at random from the src container and copies them to the destination iterator dst. This is done without replacement so each element can only be selected once.

The "container" can be any type that supports std::ranges::cbegin() and std::ranges::cend().

The destination iterator dst must be able to accept at least n elements of the type stored in the iteration. The output elements in dst are in the order they were selected, which is random.

Note: No error checking is done and the behaviour is undefined if the container is empty.

Example

std::vector<int> vec = {10, 20, 30, 40, 50};
std::vector<int> samples;
rng.sample(vec, std::back_inserter(samples), 3);
assert_eq(samples.size(), 3);
for (auto v : samples) assert(std::find(vec.cbegin(), vec.cend(), v) != vec.cend());
auto sorted = samples;
std::sort(sorted.begin(), sorted.end());
assert(std::adjacent_find(sorted.cbegin(), sorted.cend()) == sorted.cend());

◆ sample() [3/8]

template<typename State, typename Scrambler>
auto xso::generator< State, Scrambler >::sample ( Distribution auto & dist)
inlineconstexpr

Sampling method that returns a single random variate drawn from a distribution.

The distribution must satisfy the xso::Distribution concept, which is true of all standard distributions.

Example

std::normal_distribution<double> dist{0.0, 1.0};
std::size_t n_samples = 1'000'000;
double sum = 0.0;
for (auto i = 0uz; i < n_samples; ++i) sum += rng.sample(dist);
double mean = sum / static_cast<double>(n_samples);
assert(mean > -0.01 && mean < 0.01); // Should be close to 0.0

◆ sample() [4/8]

template<typename State, typename Scrambler>
template<typename Dst>
Dst xso::generator< State, Scrambler >::sample ( Distribution auto & dist,
Dst dst,
std::size_t n )
inlineconstexpr

Sampling method that takes n samples from a distribution and puts them into a destination iterator.

Note

  • The distribution must satisfy the xso::Distribution concept, which is true of all standard distributions.
  • The destination iterator dst must be able to accept at least n elements of the type produced by the distribution.

Example

std::normal_distribution<double> dist{0.0, 1.0};
std::size_t n_samples = 1'000'000;
std::vector<double> samples;
rng.sample(dist, std::back_inserter(samples), n_samples);
double sum = 0.0;
for (auto v : samples) sum += v;
double mean = sum / static_cast<double>(n_samples);
assert(mean > -0.01 && mean < 0.01); //

◆ sample() [5/8]

template<typename State, typename Scrambler>
template<std::input_iterator Src, std::output_iterator< std::iter_value_t< Src > > Dst>
Dst xso::generator< State, Scrambler >::sample ( Src b,
Src e,
Dst dst,
std::size_t n )
inlineconstexpr

Sampling method that picks n elements without replacement from an iteration [b, e) and puts them in dst.

Selects n elements at random from the iteration defined by [b, e) and copies them to the destination iterator dst. This is done without replacement so each element can only be selected once.

The destination iterator dst must be able to accept at least n elements of the type stored in the iteration. The output elements in dst are in the order they were selected, which is random.

Note: No error checking is done and the behaviour is undefined if e < b.

Example

std::vector<int> vec = {10, 20, 30, 40, 50};
std::vector<int> samples;
rng.sample(vec.cbegin(), vec.cend(), std::back_inserter(samples), 3);
assert_eq(samples.size(), 3);
for (auto v : samples) assert(std::find(vec.cbegin(), vec.cend(), v) != vec.cend());
auto sorted = samples;
std::sort(sorted.begin(), sorted.end());
assert(std::adjacent_find(sorted.cbegin(), sorted.cend()) == sorted.cend());

◆ sample() [6/8]

template<typename State, typename Scrambler>
template<std::floating_point T>
T xso::generator< State, Scrambler >::sample ( T a,
T b )
inlineconstexpr

Sampling method that returns a single real value from a uniform distribution over [a, b).

Note: No error checking is done and the behaviour is undefined if a > b.

Example

double b = 3, a = -b;
double mean = 0;
std::size_t n_trials = 1'000'000;
for (auto i = 0uz; i < n_trials; ++i) mean += rng.sample(a, b);
mean /= static_cast<double>(n_trials);
assert(mean > -0.1 && mean < 0.1); // Should be close to 0.0

◆ sample() [7/8]

template<typename State, typename Scrambler>
template<std::integral T>
T xso::generator< State, Scrambler >::sample ( T a,
T b )
inlineconstexpr

Sampling method that returns a single integer value from a uniform distribution over [a, b].

Note: No error checking is done and the behaviour is undefined if a > b.

Example

int b = 3, a = -b;
double mean = 0;
std::size_t n_trials = 1'000'000;
for (auto i = 0uz; i < n_trials; ++i) mean += rng.sample(a, b);
mean /= static_cast<double>(n_trials);
assert(mean > -0.1 && mean < 0.1); // Should be close to 0.0

◆ sample() [8/8]

template<typename State, typename Scrambler>
template<std::input_iterator T>
auto xso::generator< State, Scrambler >::sample ( T b,
T e )
inlineconstexpr

Sampling method that returns a single value from an iteration – all elements are equally likely to be returned.

Note: No error checking is done and the behaviour is undefined if b > e.

Example

std::vector<std::size_t> vec = {0, 1, 2, 3, 4, 5};
std::size_t n_trials = 1'000'000;
std::array<std::size_t, 6> counts = {0};
for (auto i = 0uz; i < n_trials; ++i) { ++counts[rng.sample(vec.cbegin(), vec.cend())]; }
for (auto c : counts) {
double fraction = static_cast<double>(c) / static_cast<double>(n_trials);
assert(fraction > 0.16 && fraction < 0.18); // Each element should be chosen about 1/6 of the time
}

◆ seed() [1/3]

template<typename State, typename Scrambler>
void xso::generator< State, Scrambler >::seed ( )
inlineconstexpr

Seeds the full state to random starting values.

This will produce a high quality stream of random outputs that are different on each run.

Example

xso::rng rng0{0x12345678};
xso::rng rng1{0x12345678};
assert_eq(rng0(), rng1()); // Same seed => same stream
assert_eq(rng0(), rng1()); // Same seed => same stream
rng0.seed(); // Now reseed randomly
assert(rng0() != rng1()); // Very, very unlucky if they are equal!
constexpr void seed()
Seeds the full state to random starting values.
Definition xoshiro.h:216

◆ seed() [2/3]

template<typename State, typename Scrambler>
template<std::input_iterator Src>
requires std::convertible_to<std::iter_value_t<Src>, word_type>
void xso::generator< State, Scrambler >::seed ( Src b,
Src e )
inlineconstexpr

Seeds the generator from an iteration of unsigned words which are all copied into the state.

  • The values in the iteration must be convertible to the generator's word_type.
  • The number of words provided must match the number of words in the generator's state.

Note: The words shouldn't all be zeros as that is a fixed point for all xoshiro/xoroshiro generators.

Example

xso::rng rng0, rng1;
assert(rng0() != rng1()); // Very, very unlucky if they are equal!
xso::rng::array_type seed_words = {0x12345678, 0x9abcdef0, 0x13579bdf, 0x2468ace0};
rng0.seed(seed_words.cbegin(), seed_words.cend());
rng1.seed(seed_words.cbegin(), seed_words.cend());
assert_eq(rng0(), rng1()); // Same seed => same stream
xso::rng::array_type zero_words = {0, 0, 0, 0};
rng0.seed(zero_words.cbegin(), zero_words.cend()); // Bad: all zero seed!
for (auto i = 0uz; i < 40; ++i) assert_eq(rng0(), 0); // Will always produce zeros!

◆ seed() [3/3]

template<typename State, typename Scrambler>
void xso::generator< State, Scrambler >::seed ( word_type seed)
inlineconstexpr

Seeds the generator quickly but probably not well from a single unsigned integer value.

Seeding from a single unsigned value is an easy way to get repeatable random streams.

Example

xso::rng rng0, rng1;
assert(rng0() != rng1()); // Very, very unlucky if they are equal!
rng0.seed(0x12345678);
rng1.seed(0x12345678);
assert_eq(rng0(), rng1()); // Same seed => same stream

◆ shuffle() [1/2]

template<typename State, typename Scrambler>
template<typename Container>
requires std::ranges::random_access_range<Container> && std::ranges::common_range<Container>
void xso::generator< State, Scrambler >::shuffle ( Container & container)
inlineconstexpr

This method shuffles all the elements of a container.

Note: No error checking is done and the behaviour is undefined if the container is empty.

Example

std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
rng.shuffle(vec);
assert(vec != std::vector<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); // Very, very unlucky if they are equal!
std::sort(vec.begin(), vec.end());
assert(vec == std::vector<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); // Should be back in order now

◆ shuffle() [2/2]

template<typename State, typename Scrambler>
template<std::random_access_iterator Iter>
void xso::generator< State, Scrambler >::shuffle ( Iter b,
Iter e )
inlineconstexpr

This method shuffles the elements in an iteration.

Note: No error checking is done and the behaviour is undefined if e < b.

Example

std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
rng.shuffle(vec.begin(), vec.end());
assert(vec != std::vector<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); // Very, very unlucky if they are equal!
std::sort(vec.begin(), vec.end());
assert(vec == std::vector<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); // Should be back in order now

◆ type_string()

template<typename State, typename Scrambler>
constexpr auto xso::generator< State, Scrambler >::type_string ( )
inlinestaticconstexpr

Class method that returns a name for this type of generator — combining State and Scrambler names.

The returned string is for the generator type as a whole, combining both the State and Scrambler type names. There is no instance specific information in the returned string (i.e. no seed/state data).

For example: xoshiro<4x64,17,45>star_star<5,7,1> for an xoshiro generator with four 64-bit state words, using parameters 17 and 45 to step the state, combined with the "**" scrambler using parameters 5, 7 and 1.

Example

assert_eq(xso::rng::type_string(), "xoshiro<4x64,17,45>star_star<5,7,1>");
static constexpr auto type_string()
Definition xoshiro.h:114

◆ word_count()

template<typename State, typename Scrambler>
constexpr std::size_t xso::generator< State, Scrambler >::word_count ( )
inlinestaticconstexpr

Class method that returns the number of words of state for this type of generator.

Example

assert_eq(xso::rng::word_count(), 4);