citrineinformatics / sprandom   0.2.0

Apache License 2.0 GitHub

A splittable, serializable psuedorandom number generator in Scala.

Scala versions: 2.13

SpRandom

Splittable, serializable pseudorandom number generation in Scala.

The SpRandom package produces random numbers that are reproducible in a multi-threaded context. It also allows the random state to be serialized and deserialized.

SpRandom's Random class is built on top of the java.util.SplittableRandom class. It exposes the following features:

  • A zip method that facilitates reproducibility in a multi-threaded context
  • Serializability by persisting the underlying seed (SplittableRandom is not serializable)
  • Multiple, convenient ways to instantiate a random state
  • A variety of convenience methods to generate pseudorandom outcomes

Usage

A Random object can be instantiated from an integer seed, a long seed, or another Random object.

import io.citrine.random.Random

val rng = Random(17L)
val rng2 = rng.split() // an independent stream
val uniformRandom = rng.between(1.5, 2.5) // draw from a uniform distribution between 1.5 and 2.5
val normalRandom = rng.nextGaussian(mean = 5.0, stdDev = 0.1) // draw from a normal with mean 5.0 and standard deviation 0.1
val orderedVector = (1 to 10).toVector
val shuffledVector = rng.shuffle(orderedVector) // random permutation of the range (1 to 10)

To get reproducible results in a multi-threaded context, use .zip. Imagine that we have some sequence, items, that we want to process in parallel. Processing is done by the stochastic, reproducible method heavyStochasticComputation. The following call is then reproducible.

rng.zip(items).par.map { case (thisRng, item) => heavyStochasticComputation(item, thisRng) }