Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.random.engine.xoshiro

Generators

Generator name Description
Xoshiro256StarStar xoshiro256**: all-purpose, rock-solid generator
Xoshiro128StarStar_32 xoshiro128** (32-bit): 32-bit-oriented parameterization of xoshiro**
Xoroshiro128Plus xoroshiro128+: fast, small, and high-quality

Generic Templates

Template name Description
XoshiroEngine xoshiro** generator.
Authors:
Masahiro Nakagawa, Ilya Yaroshenko (rework), Nathan Sashihara
alias Xoshiro256StarStar = XoshiroEngine!(ulong, 256u, "**", 17u, 45u, 1u, 7u, 5LU, 9LU).XoshiroEngine;
xoshiro256** (XOR/shift/rotate) as described in Scrambled linear pseudorandom number generators (Blackman and Vigna, 2018). 64 bit output. 256 bits of state. Period of 2^^256-1. 4-dimensionally equidistributed. It is 15% slower than xoroshiro128+ but none of its bits fail binary rank tests and it passes tests for Hamming-weight dependencies introduced in the linked paper. From the authors:
This is xoshiro256** 1.0, our all-purpose, rock-solid generator. It has excellent (sub-ns) speed, a state (256 bits) that is large enough for any parallel application, and it passes all tests we are aware of.
A jump() function is included that skips ahead by 2^^128 calls, to generate non-overlapping subsequences for parallel computations.
Public domain reference implementation: xoshiro.di.unimi.it/xoshiro256starstar.c.
Examples:
import mir.random /+: isSaturatedRandomEngine, rand+/;
import mir.random.engine.xoshiro : Xoshiro256StarStar;
import mir.math.common: fabs;

static assert(isRandomEngine!Xoshiro256StarStar);
static assert(isSaturatedRandomEngine!Xoshiro256StarStar);
auto gen = Xoshiro256StarStar(1234u);//Seed with constant.
assert(gen.rand!double.fabs == 0x1.b45d9a0e3ae53p-2);//Generate number from 0 inclusive to 1 exclusive.
assert(gen.rand!ulong == 15548185570577040190UL);
//Xoshiro256StarStar has a jump function that is equivalent
//to 2 ^^ 128 invocations of opCall.
gen.jump();
assert(gen.rand!ulong == 10759542936515257968UL);
alias Xoshiro128StarStar_32 = XoshiroEngine!(uint, 128u, "**", 9u, 11u, 0u, 7u, 5u, 9u).XoshiroEngine;
32-bit-oriented xoshiro** with 128 bits of state. In general Xoshiro256StarStar is preferable except if you are tight on space and know that the generator's output will be consumed 32 bits at a time. (If you need a generator with 128 bits of state that is geared towards producing 64 bits at a time, Xoroshiro128Plus is an option.) 32 bit output. 128 bits of state. Period of 2^^128-1. 4-dimensionally equidistributed. None of its bits fail binary rank tests and it passes tests for Hamming-weight dependencies introduced in the xoshiro paper. From the authors:
This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator. It has excellent (sub-ns) speed, a state size (128 bits) that is large enough for mild parallelism, and it passes all tests we are aware of.
A jump() function is included that skips ahead by 2^^64 calls, to generate non-overlapping subsequences for parallel computations.
Public domain reference implementation: xoshiro.di.unimi.it/xoshiro128starstar.c.
Examples:
import mir.random : isSaturatedRandomEngine, rand;
import mir.random.engine.xoshiro : Xoshiro128StarStar_32;

static assert(isSaturatedRandomEngine!Xoshiro128StarStar_32);
auto gen = Xoshiro128StarStar_32(1234u);//Seed with constant.
assert(gen.rand!uint == 1751597702U);
//Xoshiro128StarStar_32 has a jump function that is equivalent
//to 2 ^^ 64 invocations of opCall.
gen.jump();
assert(gen.rand!uint == 1248004684U);
struct XoshiroEngine(UIntType, uint nbits, string scrambler, uint A, uint B, uint I, uint R, UIntType S, UIntType T) if ((is(UIntType == uint) || is(UIntType == ulong)) && ("**" == scrambler) && (UIntType.sizeof * 8 * 4 == nbits || UIntType.sizeof * 8 * 8 == nbits));
Template for the xoshiro family of generators. See the paper introducing xoshiro and xoroshiro.
Xoshiro256StarStar and Xoshiro128StarStar_32 are aliases for XoshiroEngine instantiated with recommended parameters for 64-bit and 32-bit architectures, respectively.
Parameters:
UIntType uint or ulong
nbits number of bits (128, 256, 512; must be 4x or 8x bit size of UIntType)
scrambler "**" (in the future "+" may be added)
A state xor-lshift
B state rotate left
I index of element used for output
R output scramble rotate left
S output scramble pre-rotate multiplier (must be odd)
T output scramble post-rotate multiplier (must be odd)
enum auto isRandomEngine;
enum UIntType max;
Largest generated value.
UIntType[nbits / (UIntType.sizeof * 8)] s;
State must not be entirely zero. The constructor ensures this condition is met.
pure nothrow @nogc @safe this()(UIntType x0);
Initializes the generator with a seed.
pure nothrow @nogc @safe UIntType opCall()();
Advances the random sequence.
Returns:
A uniformly-distributed integer in the closed range [0, UIntType.max].
pure nothrow @nogc @safe void jump()();
Jump functions are defined for certain UIntType, A, B combinations:
UIntTypenbitsABNum. calls skipped
ulong25617452^^128
ulong51211212^^256
uint1289112^^64
These can be used to generate non-overlapping subsequences for parallel computations.
enum bool isUniformRandom;

enum typeof(this.max) min;

enum bool empty;

const @property UIntType front()();

void popFront()();

void seed()(UIntType x0);

const @property typeof(this) save()();
Compatibility with Phobos library methods. Presents this RNG as an InputRange.
This struct disables its default copy constructor and so will only work with Phobos functions that "do the right thing" and take RNGs by reference and do not accidentally make implicit copies.
struct Xoroshiro128Plus;
xoroshiro128+ (XOR/rotate/shift/rotate) generator. 64 bit output. 128 bits of state. Period of (2 ^^ 128) - 1.
Created in 2016 by David Blackman and Sebastiano Vigna as the successor to Vigna's extremely popular xorshift128+ generator used in the JavaScript engines of Google Chrome, Mozilla Firefox, Safari, and Microsoft Edge. From the authors:
This is the successor to xorshift128+. It is the fastest full-period generator passing BigCrush without systematic failures, but due to the relatively short period it is acceptable only for applications with a mild amount of parallelism; otherwise, use a xorshift1024* generator.
Beside passing BigCrush, this generator passes the PractRand test suite up to (and included) 16TB, with the exception of binary rank tests, as the lowest bit of this generator is an LFSR. The next bit is not an LFSR, but in the long run it will fail binary rank tests, too. The other bits have no LFSR artifacts.
We suggest to use a sign test to extract a random Boolean value, and right shifts to extract subsets of bits.
Public domain reference implementation: xoroshiro.di.unimi.it/xoroshiro128plus.c.
Examples:
import mir.random.engine : isSaturatedRandomEngine;
static assert(isSaturatedRandomEngine!Xoroshiro128Plus);
auto gen = Xoroshiro128Plus(1234u);//Seed with constant.
assert(gen() == 5968561782418604543);//Generate number.
foreach (i; 0 .. 8)
    gen();
assert(gen() == 8335647863237943914uL);
//Xoroshiro128Plus has a jump function that is equivalent
//to 2 ^^ 64 invocations of opCall.
gen.jump();
auto n = gen();
enum bool isRandomEngine;
enum ulong max;
Largest generated value.
ulong[2] s;
State must not be entirely zero. The constructor ensures this condition is met.
enum bool preferHighBits;
The lowest bit of this generator is an LFSR. The next bit is not an LFSR, but in the long run it will fail binary rank tests, too. The other bits have no LFSR artifacts. To provide some context, every bit of a Mersenne Twister generator (either the 32-bit or 64-bit variant) is an LFSR.
The rand!T functions in mir.random automatically will discard the low bits when generating output smaller than ulong due to this generator having preferHighBits defined true.
pure nothrow @nogc @safe this()(ulong x0);
Constructs an Xoroshiro128Plus generator seeded with x0.
ulong opCall()();
Advances the random sequence.
pure nothrow @nogc @safe void jump()();
This is the jump function for the generator. It is equivalent to 2^^64 calls to opCall(); it can be used to generate 2^^64 non-overlapping subsequences for parallel computations.
enum bool isUniformRandom;

enum typeof(this.max) min;

enum bool empty;

const @property ulong front()();

void popFront()();

void seed()(ulong x0);

const @property typeof(this) save()();
Compatibility with Phobos library methods. Presents this RNG as an InputRange.
This struct disables its default copy constructor and so will only work with Phobos functions that "do the right thing" and take RNGs by reference and do not accidentally make implicit copies.