You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
O'Neill makes the point that this API is flexible, but hard to use correctly, and proposes an alternative interface. IMO it's a nice API that provides safe defaults but is still very flexible for those who want flexibility.
Provides a monadic generator interface for Marsaglia's MWC256 (a.k.a. MWC8222) multiply-with-carry generator, a way to access system randomness, and a way to draw from a number of random distributions. Does not provide a way to split/spawn generators or seeds.
Defines the MonadRandom typeclass, an interface for random number generation. One aim of our effort here should be to make random-source unnecessary (see #4 (comment)).
Implements a splittable PRNG implementing the old random's RandomGen, provides alternative interfaces, and a way to access system randomness. Based on ThreeFish.
The API split between randomness sources and random distributions is apparent in every API I looked at:
Randomness source: Source in Go, RngCore and Rng (automatically derived from RngCore) in Rust, UniformRandomBitGenerator in C++, BitGenerator in numpy. These can be given a seed, and they generate random bits/bytes/words.
Drawing from a distribution: Rand in Go, implementors of the Distribution trait in Rust, components implementing RandomNumberDistribution in C++, Generator in numpy. These use a randomness source to draw from a distribution.
Note that drawing from a distribution is what random-fu exists for in the Haskell world. I believe it is worth understanding if and what changes would be required to make random-fu work with the new random. Apart from that, it seems to cover the issue of drawing from a distribution well, so we can concentrate on building a solid API for randomness sources and seeding here.
Seeding
Seeding is handled a bit differently from API to API.
Rust's rand has the SeedableRng trait, whose associated Seed type must be convertible to byte slices.
RNGs can be seeded directly, from an integer value (which is mixed to increase entropy), or from another RNG (which appropriate warnings in the docs).
C++ has random_device to get randomness from the system and seed_seq to generate good seeds from low-entropy inputs, which can be used to instantiate randum number "engines" like the Mersenne Twister.
numpy works similarly to C++, where the relevant class is called SeedSequence, but with a nicer API and fewer footguns.
Prior art in "standard" libraries
Go
Golang has two APIs, one for non-crypto PRNGs and one for cryptographically random bytes:
Rust
Rust has a family of packages for PRNGs. The basic interfaces are defined in
rand_core
.C++
The C++ standard defines a set of highly templated classes which together form the PRNG API.
O'Neill makes the point that this API is flexible, but hard to use correctly, and proposes an alternative interface. IMO it's a nice API that provides safe defaults but is still very flexible for those who want flexibility.
numpy.random
Inspired by O'Neill.
Prior art in Haskell libraries
splitmix
Pure, splittable SplitMix implementation.
mwc-random
Provides a monadic generator interface for Marsaglia's MWC256 (a.k.a. MWC8222) multiply-with-carry generator, a way to access system randomness, and a way to draw from a number of random distributions. Does not provide a way to split/spawn generators or seeds.
random-source
Defines the
MonadRandom
typeclass, an interface for random number generation. One aim of our effort here should be to makerandom-source
unnecessary (see #4 (comment)).random-fu
Provides a way to draw from a number of random distributions. The randomness source is pluggable AFAICT.
tf-random
Implements a splittable PRNG implementing the old
random
'sRandomGen
, provides alternative interfaces, and a way to access system randomness. Based on ThreeFish.More prior art
Common concepts
The API split between randomness sources and random distributions is apparent in every API I looked at:
Source
in Go,RngCore
andRng
(automatically derived fromRngCore
) in Rust,UniformRandomBitGenerator
in C++,BitGenerator
in numpy. These can be given a seed, and they generate random bits/bytes/words.Rand
in Go, implementors of theDistribution
trait in Rust, components implementingRandomNumberDistribution
in C++,Generator
in numpy. These use a randomness source to draw from a distribution.Note that drawing from a distribution is what
random-fu
exists for in the Haskell world. I believe it is worth understanding if and what changes would be required to makerandom-fu
work with the newrandom
. Apart from that, it seems to cover the issue of drawing from a distribution well, so we can concentrate on building a solid API for randomness sources and seeding here.Seeding
Seeding is handled a bit differently from API to API.
rand
has theSeedableRng
trait, whose associatedSeed
type must be convertible to byte slices.RNGs can be seeded directly, from an integer value (which is mixed to increase entropy), or from another RNG (which appropriate warnings in the docs).
random_device
to get randomness from the system andseed_seq
to generate good seeds from low-entropy inputs, which can be used to instantiate randum number "engines" like the Mersenne Twister.SeedSequence
, but with a nicer API and fewer footguns.Rand.Seed
function.The text was updated successfully, but these errors were encountered: