Random

Usage

use Random;

Submodules

Support for pseudorandom number generation

This module defines an abstraction for a stream of pseudorandom numbers, RandomStreamInterface. Use makeRandomStream to create such an stream. Each stream supports methods to get the next random number in the stream (getNext), to fast-forward to a specific value in the stream (skipToNth and getNth), to iterate over random values possibly in parallel (iterate), or to fill an array with random numbers in parallel (fillRandom).

The module also provides several standalone convenience functions that can be used without manually creating a RandomStreamInterface object.

  • fillRandom fills an array with random numbers in parallel
  • shuffle randomly re-arranges the elements of an array
  • permutation creates a random permutation and stores it in an array.

In these and other methods, generated integer values are uniformly distributed from min(T) to max(T), where T is the integral type and the boundaries are included. Generated floating point values are uniformly distributed in [0.0, 1.0] with the caveat that it currently depends on the RNG whether the boundary values 0.0 and 1.0 can be produced.

Use makeRandomStream or the constructor for a specific RNG implementation to get a RandomStream. See the documentation for each RNG implementation for more information:

Note

Right now, NPBRandomStream and RandomStream are available (where RandomStream implements the PCG algorithm). In the future, we expect that PCGRandomStream will be available as another name for the PCG RNG stream. At that point, RandomStream will change to a type alias for the default RNG. The function makeRandomStream is available to avoid compatibility problems from this naming change. Programs that need to specifically request PCG should do so with makeRandomStream until the name PCGRandomStream is available..

Note

The RandomStream API (RandomStreamInterface) is expected to change.

enum RNG { PCG = 1, NPB = 2 }

Select between different supported RNG algorithms. See PCGRandom and NPBRandom for details on these algorithms.

param defaultRNG = RNG.PCG

The default RNG. The current default is PCG - see PCGRandom.

proc fillRandom(arr: [], seed: int(64) = SeedGenerator.oddCurrentTime, param algorithm = defaultRNG)

Fill an array of numeric elements with pseudorandom values in parallel using a new stream implementing RandomStreamInterface created specifically for this call. The first arr.size values from the stream will be assigned to the array's elements in row-major order. The parallelization strategy is determined by the array.

Note

NPBRandom only supports real(64), imag(64), and complex(128) numeric types. PCGRandom supports all primitive numeric types.

Arguments:
  • arr : [] T -- The array to be filled, where T is a primitive numeric type
  • seed : int(64) -- The seed to use for the PRNG. Defaults to oddCurrentTime from RandomSupport.SeedGenerator.
  • algorithm : RNG -- A param indicating which algorithm to use. Defaults to defaultRNG.
proc shuffle(arr: [], seed: int(64) = SeedGenerator.oddCurrentTime, param algorithm = RNG.PCG)

Shuffle the elements of an array into a random order.

Arguments:
  • arr -- a 1-D non-strided array
  • seed -- the seed to use when shuffling. Defaults to oddCurrentTime from RandomSupport.SeedGenerator.
  • algorithm : RNG -- A param indicating which algorithm to use. Defaults to PCG.
proc permutation(arr: [], seed: int(64) = SeedGenerator.oddCurrentTime, param algorithm = RNG.PCG)

Produce a random permutation, storing it in a 1-D array. The resulting array will include each value from low..high exactly once, where low and high refer to the array's domain.

Arguments:
  • arr -- a 1-D non-strided array
  • seed -- the seed to use when creating the permutation. Defaults to oddCurrentTime from RandomSupport.SeedGenerator.
  • algorithm : RNG -- A param indicating which algorithm to use. Defaults to PCG.
proc makeRandomStream(type eltType, seed: int(64) = SeedGenerator.oddCurrentTime, param parSafe: bool = true, param algorithm = defaultRNG)

Constructs a new stream of random numbers using the specified seed and parallel safety. Ensures that the seed value meets the PRNG's constraints.

Note

The NPBRandom RNG will halt if provided an even seed. PCGRandom has no restrictions on the provided seed value.

Arguments:
  • eltType : type -- The element type to be generated.
  • seed : int(64) -- The seed to use for the PRNG. Defaults to oddCurrentTime from RandomSupport.SeedGenerator.
  • parSafe : bool -- The parallel safety setting. Defaults to true.
  • algorithm : RNG -- A param indicating which algorithm to use. Defaults to defaultRNG.
Returns:

an owned RandomStream

class RandomStreamInterface

Models a stream of pseudorandom numbers. This class is defined for documentation purposes and should not be instantiated. See PCGRandom and NPBRandom for RNGs that can be instantiated. To create a random stream, use makeRandomStream.

Note

This RandomStreamInterface is expected to change.

Note

At present, different implementations of this interface can vary in whether or not they can generate 0.0 and/or 1.0. (e.g. They can be generated by PCGRandom but not by NPBRandom).

Note

We plan to support general serial and parallel iterator methods on RandomStreamInterface; however, providing the full suite of iterators is not possible with our current parallel iterator framework. Specifically, if RandomStreamInterface is a follower in a zippered iteration context, there is no way for it to update the total number of random numbers generated in a safe/sane/coordinated way. We are exploring a revised leader-follower iterator framework that would support this idiom (and other cursor-based ones). With Chapel's recent support for standalone parallel iterators, one could define a standalone parallel iterator for RandomStreamInterface, but this effort has not yet been taken on.

Note

The RandomStreamInterface is included here only for documentation and does not help with compilation in any way. In the future, we hope to turn it into an interface.

type eltType = real(64)

Specifies the type of value generated by the RandomStream. Not all RandomStream implementations support all types.

param parSafe: bool = true

Indicates whether or not the RandomStream needs to be parallel-safe by default. If multiple tasks interact with it in an uncoordinated fashion, this must be set to true. If it will only be called from a single task, or if only one task will call into it at a time, setting to false will reduce overhead related to ensuring mutual exclusion.

const seed: int(64)

The seed value for the PRNG. There may be constraints upon legal values depending on the specific RNG.

proc getNext(): eltType

Returns the next value in the random stream.

Returns:The next value in the random stream as type eltType.
proc skipToNth(n: integral) throws

Advances/rewinds the stream to the n-th value in the sequence. The first value is with n=1. n must be > 0, otherwise an IllegalArgumentError is thrown.

Arguments:n : integral -- The position in the stream to skip to. Must be > 0.
proc getNth(n: integral): eltType throws

Advance/rewind the stream to the n-th value and return it (advancing the stream by one). n must be > 0, otherwise an IllegalArgumentError is thrown. This is equivalent to skipToNth() followed by getNext().

Arguments:n : integral -- The position in the stream to skip to. Must be > 0.
Returns:The n-th value in the random stream as type eltType.
proc fillRandom(arr: [] eltType)

Fill the argument array with pseudorandom values. This method is identical to the standalone fillRandom procedure, except that it consumes random values from the RandomStreamInterface object on which it's invoked rather than creating a new stream for the purpose of the call.

Arguments:arr : [] eltType -- The array to be filled
proc choice(arr: [], size: ?sizeType = _void, replace = true, prob: ?probType = _void) throws

Returns a random sample from a given 1-D array, arr.

Arguments:
  • arr -- a 1-D array with values that will be sampled from.
  • size -- An optional integral value specifying the number of elements to choose, or a domain specifying the dimensions of the sampled array to be filled, otherwise a single element will be chosen.
  • replace -- an optional bool specifying whether or not to sample with replacement, i.e. elements will only be chosen up to one time when replace=false.
  • prob -- an optional 1-D array that contains probabilities of choosing each element of arr, otherwise elements will be chosen over a uniform distribution. prob must have integral or real element type, with no negative values and at least one non-zero value. The domain must be equal to that of arr.domain.
Returns:

An element chosen from arr is size == 1, or an array of element chosen from arr if size > 1 or size is a domain.

Throws IllegalArgumentError:
 

if arr.size == 0, if arr contains a negative value, if arr has no non-zero values., if arr.domain != prob.domain, if size < 1 || size.size < 1, if replace=false and size > arr.size || size.size > arr.size

proc iterate(D: domain, type resultType = eltType)

Returns an iterable expression for generating D.numIndices random numbers. The RNG state will be immediately advanced by D.numIndices before the iterable expression yields any values.

The returned iterable expression is useful in parallel contexts, including standalone and zippered iteration. The domain will determine the parallelization strategy.

Arguments:
  • D -- a domain
  • resultType -- the type of number to yield
Returns:

an iterable expression yielding random resultType values