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.xorshift

Generators

Generator name Description
Xoroshiro128Plus xoroshiro128+: fast, small, and high-quality
Xorshift1024StarPhi xorshift1024*φ: when something larger than xoroshiro128+ is needed
Xorshift32 .. Xorshift160 Basic xorshift generator with n bits of state (32, 64, 96, 128, 160)
Xorshift192 Generator from Marsaglia's paper combining 160-bit xorshift with a counter
Xorshift An alias to one of the generators in this package

Generic Templates

Template name Description
XorshiftStarEngine xorshift* generator with any word size and any number of bits of state.
XorshiftEngine xorshift generator with 32 bit words and 32 to 160 bits of state.
Authors:
Masahiro Nakagawa, Ilya Yaroshenko (rework), Nathan Sashihara
struct XorshiftEngine(uint bits, uint a, uint b, uint c) if (isUnsigned!uint);
Xorshift generator using 32bit algorithm. Implemented according to Xorshift RNGs (Marsaglia, 2003).
bits period
32 2^32 - 1
64 2^64 - 1
96 2^96 - 1
128 2^128 - 1
160 2^160 - 1
192 2^192 - 2^32
enum auto isRandomEngine;
enum uint max;
Largest generated value.
pure nothrow @nogc @safe this(uint x0);
Constructs a XorshiftEngine generator seeded with x0.
pure nothrow @nogc @safe uint opCall();
Advances the random sequence.
alias Xorshift32 = XorshiftEngine!(32u, 13u, 17u, 15u).XorshiftEngine;

alias Xorshift64 = XorshiftEngine!(64u, 10u, 13u, 10u).XorshiftEngine;

alias Xorshift96 = XorshiftEngine!(96u, 10u, 5u, 26u).XorshiftEngine;

alias Xorshift128 = XorshiftEngine!(128u, 11u, 8u, 19u).XorshiftEngine;

alias Xorshift160 = XorshiftEngine!(160u, 2u, 1u, 4u).XorshiftEngine;

alias Xorshift192 = XorshiftEngine!(192u, 2u, 1u, 4u).XorshiftEngine;

alias Xorshift = XorshiftEngine!(128u, 11u, 8u, 19u).XorshiftEngine;
Define XorshiftEngine generators with well-chosen parameters. See each bits examples of "Xorshift RNGs". Xorshift is a Xorshift128's alias because 128bits implementation is mostly used.
Examples:
import mir.random.engine;
auto rnd = Xorshift(cast(uint)unpredictableSeed);
auto num = rnd();

import std.traits;
static assert(is(ReturnType!rnd == uint));
static assert(isSaturatedRandomEngine!Xorshift);
struct XorshiftStarEngine(StateUInt, uint nbits, uint a, uint b, uint c, StateUInt multiplier, OutputUInt = StateUInt) if (isIntegral!StateUInt && isIntegral!OutputUInt && StateUInt.sizeof >= OutputUInt.sizeof && nbits >= StateUInt.sizeof * 8 && nbits % (StateUInt.sizeof * 8) == 0);
Template for the xorshift* family of generators (Vigna, 2016; draft 2014).
enum auto isRandomEngine;
enum OutputUInt max;
Largest generated value.
enum bool preferHighBits;
Note that when StateUInt is the same size as OutputUInt the two lowest bits of this generator are LFSRs, and thus will fail binary rank tests. 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 OutputUInt due to this generator having preferHighBits defined true.
pure nothrow @nogc @safe this()(Unqual!StateUInt x0);
Constructs a XorshiftStarEngine generator seeded with x0.
pure nothrow @nogc @safe OutputUInt opCall()();
Advances the random sequence.
pure nothrow @nogc @safe void jump()();
This is the jump function for the standard 1024-bit generator. It is equivalent to 2 ^^ 512 invocations of opCall(); it can be used to generate 2 ^^ 512 non-overlapping subsequences for parallel computations. This function will only be defined if the shifts are the same as for Xorshift1024StarPhi.
alias Xorshift1024StarPhi = XorshiftStarEngine!(ulong, 1024u, 31u, 11u, 30u, 11400714819323198483LU, ulong).XorshiftStarEngine;
Define XorshiftStarEngine with well-chosen parameters for large simulations on 64-bit machines.
Period of (2 ^^ 1024) - 1, 16-dimensionally equidistributed, and faster and statistically superior to Mt19937_64 while occupying significantly less memory. This generator is recommended for random number generation on 64-bit systems except when 1024 + 32 bits of state are excessive.
As described by Vigna in the 2014 draft of his paper published in 2016 detailing the xorshift* family, except with a better multiplier recommended by the author as of 2017-10-08.
Public domain reference implementation: xoroshiro.di.unimi.it/xorshift1024star.c.
Examples:
import mir.random.engine : EngineReturnType, isSaturatedRandomEngine;
auto rnd = Xorshift1024StarPhi(12434UL);
auto num = rnd();
assert(num != rnd());

static assert(is(EngineReturnType!Xorshift1024StarPhi == ulong));
static assert(isSaturatedRandomEngine!Xorshift1024StarPhi);

//Xorshift1024StarPhi has a jump function that is equivalent
//to 2 ^^ 512 invocations of opCall.
rnd.jump();
num = rnd();
assert(num != rnd());
struct Xoroshiro128Plus;
xoroshiro128+ 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);
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.