Traits
|
isSeedable
isUniformRNG
Disclaimer:
The random number generators and API provided in this
module are not designed to be cryptographically secure, and are therefore
unsuitable for cryptographic or security-related purposes such as generating
authentication tokens or network sequence numbers. For such needs, please use a
reputable cryptographic library instead.
The new-style generator objects hold their own state so they are
immune of threading issues. The generators feature a number of
well-known and well-documented methods of generating random
numbers. An overall fast and reliable means to generate random numbers
is the
Mt19937
generator, which derives its name from
"
Mersenne Twister
with a period of 2 to the power of
19937". In memory-constrained situations,
linear congruential generators
such as
MinstdRand0
and
MinstdRand
might be
useful. The standard library provides an alias
Random
for
whichever generator it considers the most fit for the target
environment.
In addition to random number generators, this module features
distributions, which skew a generator's output statistical
distribution in various ways. So far the uniform distribution for
integers and real numbers have been implemented.
Source
std/random.d
License:
Boost License 1.0
.
Authors:
Andrei Alexandrescu
Masahiro Nakagawa (Xorshift random generator)
Joseph Rushton Wakeling
(Algorithm D for random sampling)
Ilya Yaroshenko (Mersenne Twister implementation, adapted from
mir-random
)
Credits
The entire random number library architecture is derived from the
excellent
C++0X
random number facility proposed by Jens Maurer and contributed to by
researchers at the Fermi laboratory (excluding Xorshift).
Examples:
import std.algorithm.comparison : among, equal;
import std.range : iota;
auto rnd = Random(42);
auto i = uniform(0, 15, rnd);
assert(i >= 0 && i < 15);
auto r = uniform(0.0L, 100.0L, rnd);
assert(r >= 0 && r < 100);
enum Fruit { apple, mango, pear }
auto f = rnd.uniform!Fruit;
with(Fruit)
assert(f.among(apple, mango, pear));
auto u = uniform!uint(rnd);
static assert(is(typeof(u) == uint));
auto u2 = uniform01(rnd);
assert(u2 >= 0 && u2 < 1);
auto el = 10.iota.choice(rnd);
assert(0 <= el && el < 10);
auto val = rnd.dice(0.2, 0.1, 0.6);
assert(0 <= val && val <= 2);
auto rnd2 = MinstdRand0(42);
assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9]));
version (D_LP64) assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1]));
version (D_LP64) assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1]));
enum bool isUniformRNG (Rng, ElementType);
enum bool isUniformRNG (Rng);
Test if Rng is a random-number generator. The overload
taking a ElementType also makes sure that the Rng generates
values of that type.
A random-number generator has at least the following features:
- it's an InputRange
- it has a 'bool isUniformRandom' field readable in CTFE
Examples: struct NoRng
@property uint front() {return 0;}
@property bool empty() {return false;}
void popFront() {}
static assert(!isUniformRNG!(NoRng));
struct validRng
@property uint front() {return 0;}
@property bool empty() {return false;}
void popFront() {}
enum isUniformRandom = true;
static assert(isUniformRNG!(validRng, uint));
static assert(isUniformRNG!(validRng));
Test if Rng is seedable. The overload
taking a SeedType also makes sure that the Rng can be seeded with SeedType.
A seedable random-number generator has the following additional features:
- it has a 'seed(ElementType)' function
Examples: struct validRng
@property uint front() {return 0;}
@property bool empty() {return false;}
void popFront() {}
enum isUniformRandom = true;
static assert(!isSeedable!(validRng, uint));
static assert(!isSeedable!(validRng));
struct seedRng
@property uint front() {return 0;}
@property bool empty() {return false;}
void popFront() {}
void seed(uint val){}
enum isUniformRandom = true;
static assert(isSeedable!(seedRng, uint));
static assert(!isSeedable!(seedRng, ulong));
static assert(isSeedable!(seedRng));
struct LinearCongruentialEngine (UIntType, UIntType a, UIntType c, UIntType m) if (isUnsigned!UIntType);
Linear Congruential generator. When m = 0, no modulus is used. Examples: Declare your own linear congruential engine
alias CPP11LCG = LinearCongruentialEngine!(uint, 48271, 0, 2_147_483_647);
auto rnd = CPP11LCG(42);
auto n = rnd.front; writeln(n);
|