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

Basic API to construct non-uniform random number generators and stochastic algorithms. Non-uniform and uniform random variable can be found at mir.random.variable.

Generation functions

Function Name Description
rand Generates real, integral, boolean, and enumerated uniformly distributed values.
randIndex Generates uniformly distributed index.
randGeometric Generates geometric distribution with p = 1/2.
randExponential2 Generates scaled Exponential distribution.

Phobos Compatibility

Template Name Description
PhobosRandom Extends a Mir random number engine to meet Phobos std.random interface
isPhobosUniformRNG Tests if type is a Phobos-style uniform RNG
Publicly includes mir.random.engine.
Authors:
Ilya Yaroshenko, Nathan Sashihara
T rand(T, G)(ref scope G gen)
if (isSaturatedRandomEngine!G && isIntegral!T && !is(T == enum));

T rand(T, G)(scope G* gen)
if (isSaturatedRandomEngine!G && isIntegral!T && !is(T == enum));

T rand(T)()
if (isIntegral!T && !is(T == enum));
Parameters:
G gen saturated random number generator
Returns:
Uniformly distributed integer for interval [T.min .. T.max].
Examples:
auto s = rand!short;
auto n = rand!ulong;
Examples:
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
auto s = gen.rand!short;
auto n = gen.rand!ulong;
bool rand(T : bool, G)(ref scope G gen)
if (isSaturatedRandomEngine!G);

bool rand(T : bool, G)(scope G* gen)
if (isSaturatedRandomEngine!G);

bool rand(T : bool)();
Parameters:
G gen saturated random number generator
Returns:
Uniformly distributed boolean.
Examples:
auto s = rand!bool;
Examples:
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
auto s = gen.rand!bool;
T rand(T, G)(ref scope G gen)
if (isSaturatedRandomEngine!G && is(T == enum));

T rand(T, G)(scope G* gen)
if (isSaturatedRandomEngine!G && is(T == enum));

T rand(T)()
if (is(T == enum));
Parameters:
G gen saturated random number generator
Returns:
Uniformly distributed enumeration.
Examples:
enum A { a, b, c }
auto e = rand!A;
Examples:
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
enum A { a, b, c }
auto e = gen.rand!A;
Examples:
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
enum A : dchar { a, b, c }
auto e = gen.rand!A;
Examples:
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
enum A : string { a = "a", b = "b", c = "c" }
auto e = gen.rand!A;
T rand(T, G)(ref scope G gen, sizediff_t boundExp = 0)
if (isSaturatedRandomEngine!G && isFloatingPoint!T);

T rand(T, G)(scope G* gen, sizediff_t boundExp = 0)
if (isSaturatedRandomEngine!G && isFloatingPoint!T);

T rand(T)(sizediff_t boundExp = 0)
if (isFloatingPoint!T);
Parameters:
G gen saturated random number generator
sizediff_t boundExp bound exponent (optional). boundExp must be less or equal to T.max_exp.
Returns:
Uniformly distributed real for interval (-2^^boundExp , 2^^boundExp).

Note fabs can be used to get a value from positive interval [0, 2^^boundExp).

Examples:
import mir.math.common: fabs;

auto a = rand!float;
assert(-1 < a && a < +1);

auto b = rand!double(4);
assert(-16 < b && b < +16);

auto c = rand!double(-2);
assert(-0.25 < c && c < +0.25);

auto d = rand!real.fabs;
assert(0.0L <= d && d < 1.0L);
Examples:
import mir.math.common: fabs;
import mir.random.engine.xorshift;
auto gen = Xorshift(1);

auto a = gen.rand!float;
assert(-1 < a && a < +1);

auto b = gen.rand!double(4);
assert(-16 < b && b < +16);

auto c = gen.rand!double(-2);
assert(-0.25 < c && c < +0.25);

auto d = gen.rand!real.fabs;
assert(0.0L <= d && d < 1.0L);
Examples:
Subnormal numbers
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
auto x = gen.rand!double(double.min_exp-1);
assert(-double.min_normal < x && x < double.min_normal);
T randIndex(T, G)(ref scope G gen, T _m)
if (isSaturatedRandomEngine!G && isUnsigned!T);

T randIndex(T, G)(scope G* gen, T m)
if (isSaturatedRandomEngine!G && isUnsigned!T);

T randIndex(T)(T m)
if (isUnsigned!T);
Parameters:
G gen uniform random number generator
T m positive module
Returns:
Uniformly distributed integer for interval [0 .. m).
Examples:
auto s = randIndex(100u);
auto n = randIndex!ulong(-100);
Examples:
import mir.random;
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
auto s = gen.randIndex!uint(100);
auto n = gen.randIndex!ulong(-100);
size_t randGeometric(G)(ref scope G gen)
if (isSaturatedRandomEngine!G);

size_t randGeometric(G)(scope G* gen)
if (isSaturatedRandomEngine!G);

size_t randGeometric()();
Returns:
n >= 0 such that P(n) := 1 / (2^^(n + 1)).
Examples:
size_t s = randGeometric;
Examples:
import mir.random.engine.xoshiro;
auto gen = Xoroshiro128Plus(1);

size_t s = gen.randGeometric;
T randExponential2(T, G)(ref scope G gen)
if (isSaturatedRandomEngine!G && isFloatingPoint!T);

T randExponential2(T, G)(scope G* gen)
if (isSaturatedRandomEngine!G && isFloatingPoint!T);

T randExponential2(T)()
if (isFloatingPoint!T);
Parameters:
G gen saturated random number generator
Returns:
X ~ Exp(1) / log(2).

Note fabs can be used to get a value from positive interval [0, 2^^boundExp).

Examples:
auto v = randExponential2!double;
Examples:
import mir.random.engine.xorshift;
auto gen = Xorshift(1);
auto v = gen.randExponential2!double();
enum bool isPhobosUniformRNG(T);
struct PhobosRandom(Engine) if (isRandomEngine!Engine && !isPhobosUniformRNG!Engine);

template PhobosRandom(Engine) if (isRandomEngine!Engine && isPhobosUniformRNG!Engine)
Extends a Mir-style random number generator to also be a Phobos-style uniform RNG. If Engine is already a Phobos-style uniform RNG, PhobosRandom is just an alias for Engine.
Examples:
import mir.random.engine.xorshift: Xorshift1024StarPhi;
import std.random: isSeedable, isPhobosUniformRNG = isUniformRNG;
import std.range.primitives: isForwardRange;

alias RNG = PhobosRandom!Xorshift1024StarPhi;

//Phobos interface
static assert(isPhobosUniformRNG!(RNG, ulong));
static assert(isSeedable!(RNG, ulong));
static assert(isForwardRange!RNG);
//Mir interface
static assert(isSaturatedRandomEngine!RNG);
static assert(is(EngineReturnType!RNG == ulong));

auto gen = Xorshift1024StarPhi(1);
auto rng = RNG(1);
assert(gen() == rng.front);
rng.popFront();
assert(gen() == rng.front);
rng.popFront();
assert(gen() == rng());

gen.__ctor(1);
rng.seed(1);
assert(gen() == rng());
this();
Default constructor and copy constructor are disabled.
this(A...)(auto ref A args)
if (is(typeof(Engine(args))));
Forward constructor arguments to Engine.
enum bool isUniformRandom;

enum Uint min;

enum Uint max;

enum bool empty;

const @property Uint front()();

void popFront()();

void seed(A...)(auto ref A args)
if (is(typeof(Engine(args))));

const @property @trusted typeof(this) save()();
Phobos-style random interface.
save is only available when the underlying Engine has no indirections and has pure @safe opCall() and doesn't have an impure or @system destructor.
enum bool isRandomEngine;

enum bool preferHighBits;

Uint opCall()();
Retain support for Mir-style random interface.
inout pure nothrow @nogc @property ref @safe inout(Engine) engine()();