.. default-domain:: chpl .. module:: Random :synopsis: Support for pseudorandom number generation. Random ====== **Usage** .. code-block:: chapel use Random; or .. code-block:: chapel import Random; **Submodules** .. toctree:: :maxdepth: 1 :glob: Random/* Support for pseudorandom number generation. This module defines a :record:`randomStream` type (based upon the PCG algorithm) that can be used to generate pseudorandom numbers in parallel. The ``randomStream`` type can be used to generate individual random numbers via :proc:`randomStream.getNext` or to fill an array with random numbers via :proc:`randomStream.fill`. There are also several other methods available for manipulating arrays, parallel iteration, or adjusting the stream's position. This module contains a few top-level procedures that can be used for manipulating arrays: * :proc:`fillRandom` fills an array with random numbers in parallel * :proc:`shuffle` randomly re-arranges the elements of an array * :proc:`permutation` creates a random permutation of an array's domain (*unstable*). Seed Generation --------------- The :record:`randomStream` type can be initialized with a seed value. When not provided explicitly, a seed will be generated in an implementation specific manner based on the current time. This behavior is currently unstable and may change in the future. Additionally, the standalone methods in this module that generate their own seed values are currently unstable. Prior to Chapel 1.33, seed values could be generated with the now deprecated ``RandomSupport.SeedGenerator`` type. For a non-deprecated replacement, see :proc:`~NPBRandom.oddTimeSeed`. Note that the ``NPBRandom`` module is not stable. Note About Deprecations and Future Work --------------------------------------- Before Chapel 1.33, this module was unstable. It defined an abstract random stream interface (:class:`RandomStreamInterface`) and two implementations of that interface (based on the PCG and NPB algorithms). As of Chapel 1.33, this module is partially stable and defines a single :record:`randomStream` type that is based on the PCG algorithm. The NPB algorithm is still available via the :mod:`NPBRandom` package module. The ``RandomStreamInterface`` is now deprecated. Various symbols used to switch between the two algorithms have also been deprecated. These include: * :proc:`createRandomStream` * :type:`RNG` * :param:`defaultRNG` * :type:`RandomStream` * overloads of the top-level methods that accept an ``algorithm`` argument In a future release, we intend to use Chapel's interface features to define one or more interfaces for random streams. At that point, the :record:`randomStream` type will be an implementation of the interface(s) for generating a seedable stream of random numbers. .. type:: type RNG = _RNG .. warning:: 'RNG' is deprecated; please use the PCG algorithm via the :record:`randomStream` type or the NPB algorithm via the :mod:`NPBRandom` package module Select between different supported RNG algorithms. See :mod:`PCGRandom` and :mod:`NPBRandom` for details on these algorithms. .. data:: param defaultRNG = _defaultRNG .. warning:: 'defaultRNG' is deprecated; please use the PCG algorithm via the :record:`randomStream` type or the NPB algorithm via the :mod:`NPBRandom` package module The default RNG. The current default is PCG - see :mod:`PCGRandom`. .. type:: type RandomStream = if _defaultRNG == _RNG.PCG then PCGRandomStreamInternal else NPBRandom.NPBRandomStream .. warning:: the RandomStream class is deprecated; please use the :record:`randomStream` record instead .. function:: proc fillRandom(ref arr: [], seed: int(64) = _SeedGenerator.oddCurrentTime, param algorithm = _defaultRNG) where isNumericOrBoolType(arr.eltType) .. warning:: The overload of `fillRandom` that accepts an 'algorithm' argument is deprecated; please remove the 'algorithm' argument .. function:: proc fillRandom(ref arr: [] ?t, seed: int) where isNumericOrBoolType(t) && arr.isRectangular() Fill a rectangular array of numeric values with pseudorandom values in parallel using a new :record:`randomStream`. 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. :arg arr: An array of numeric values :arg seed: The seed to use to create the ``randomStream`` .. function:: proc fillRandom(ref arr: [] ?t) where isNumericOrBoolType(t) && arr.isRectangular() .. warning:: the overload of fillRandom that generates its own seed is unstable Fill a rectangular array of numeric values with pseudorandom values in parallel using a new :record:`randomStream`. 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:: a seed will be generated in an implementation specific manner that depends on the current time. :arg arr: An array of numeric values .. function:: proc fillRandom(ref arr: [] ?t, min: t, max: t, seed: int) where isNumericOrBoolType(t) && arr.isRectangular() Fill a rectangular array of numeric values with pseudorandom values in the range [``min``, ``max``] (inclusive) in parallel using a new :record:`randomStream`. 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. :arg arr: An array of numeric values :arg min: The (inclusive) lower bound for the random values :arg max: The (inclusive) upper bound for the random values :arg seed: The seed to use to create the ``randomStream`` .. function:: proc fillRandom(ref arr: [] ?t, min: t, max: t) where isNumericOrBoolType(t) && arr.isRectangular() .. warning:: the overload of fillRandom that generates its own seed is unstable Fill a rectangular array of numeric values with pseudorandom values in the range [``min``, ``max``] (inclusive) in parallel using a new :record:`randomStream`. 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:: a seed will be generated in an implementation specific manner that depends on the current time. :arg arr: An array of numeric values :arg min: The (inclusive) lower bound for the random values :arg max: The (inclusive) upper bound for the random values .. function:: proc shuffle(ref arr: [], seed: int(64) = _SeedGenerator.oddCurrentTime, param algorithm = _RNG.PCG) .. warning:: The overload of 'shuffle' that accepts an 'algorithm' argument is deprecated; please remove the 'algorithm' argument Shuffle the elements of a rectangular array into a random order. :arg arr: a rectangular 1-D non-strided array :arg seed: the seed to use when shuffling. Defaults to `oddCurrentTime` from :type:`RandomSupport.SeedGenerator`. :arg algorithm: A param indicating which algorithm to use. Defaults to PCG. :type algorithm: :type:`RNG` .. function:: proc shuffle(ref arr: [?d], seed: int) where is1DRectangularDomain(d) Use a new :record:`randomStream` to shuffle an array in place. :arg arr: A non-strided default rectangular 1D array :arg seed: The seed to initialize a ``randomStream`` with .. function:: proc shuffle(ref arr: [?d]) where is1DRectangularDomain(d) .. warning:: the overload of shuffle that generates its own seed is unstable Use a new :record:`randomStream` to shuffle an array in place. .. note:: a seed will be generated in an implementation specific manner that depends on the current time. :arg arr: A non-strided default rectangular 1D array .. function:: proc permutation(ref arr: [], seed: int(64) = _SeedGenerator.oddCurrentTime, param algorithm = _RNG.PCG) .. warning:: The overload of 'permutation' that accepts an 'algorithm' argument is deprecated; please remove the 'algorithm' argument 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. :arg arr: a rectangular 1-D non-strided array :arg seed: the seed to use when creating the permutation. Defaults to `oddCurrentTime` from :type:`RandomSupport.SeedGenerator`. :arg algorithm: A param indicating which algorithm to use. Defaults to PCG. :type algorithm: :type:`RNG` .. function:: proc permutation(ref arr: [?d] ?t, seed: int) where isCoercible(d.idxType, t) && is1DRectangularDomain(d) .. warning:: 'permutation' is unstable and subject to change Use a new :record:`randomStream` to produce a random permutation of an array's domain. The values ``d.dim(0).low..d.dim(0).high`` will appear exactly once in the array in a pseudo-random order. :arg arr: The array to store the permutation in :arg seed: The seed to use when creating the ``randomStream`` .. function:: proc permutation(ref arr: [?d] ?t) where isCoercible(d.idxType, t) && is1DRectangularDomain(d) .. warning:: 'permutation' is unstable and subject to change Use a new :record:`randomStream` to produce a random permutation of an array's domain. The values ``d.dim(0).low..d.dim(0).high`` will appear exactly once in the array in a pseudo-random order. .. note:: a seed will be generated in an implementation specific manner that depends on the current time. :arg arr: The array to store the permutation in .. record:: randomStream : writeSerializable A :record:`randomStream` represents a stream of pseudorandom numbers of a particular type. Numeric and bool types are supported. Conceptually it can be thought of as an indexed sequence of numbers ranging from 0 to infinity. Each index in the sequence corresponds to a random number of the specified type. This allows for the generation of random numbers in parallel, where each task involved in the parallel iteration can request random numbers within a particular range and traverse that range of the sequence independently of other tasks (see :proc:`randomStream.iterate` (*unstable*)). Although parallel iteration is supported via the ``iterate`` method, the type itself is not thread-safe. In particular, it is not safe to call methods such as ``getNext`` or ``fill`` on a ``randomStream`` from multiple tasks concurrently. Several high-level methods are provided to generate random numbers or to manipulate arrays using random numbers: * :proc:`randomStream.fill` to fill an array with random numbers * :proc:`randomStream.shuffle` to randomly re-arrange the elements of an array * :proc:`randomStream.permutation` to create a random permutation of an arrays domain, and store it in the array (*unstable*) * :proc:`randomStream.choice` to randomly sample from an array or range (*unstable*) Note that these methods have top-level counterparts that will internally create a ``randomStream`` and then call the corresponding method on it. These can be convenient for one-off uses, but if you are generating many random numbers, it is generally more efficient to create a ``randomStream`` and use it repeatedly. An individual random number can be requested using :proc:`randomStream.getNext` which will advance the stream to the next position and return the value at that position. The position of the stream can also be manipulated using: * :proc:`randomStream.skipToNth` to skip to a particular position in the stream * :proc:`randomStream.getNth` to skip to a particular position in the stream and return the value at that position (*unstable*) A ``randomStream`` can be initialized with a seed value. When not provided explicitly, a seed will be generated in an implementation specific manner that depends upon the current time (*this behavior is currently unstable*). When copied, the ``randomStream``'s seed, state, and position will also be copied. This means that the copy will produce the same sequence of random numbers as the original without affecting the original. .. note:: **Implementation Details:** This stream is implemented using the PCG random number generator algorithm. See http://www.pcg-random.org/ and the paper, `PCG: A Family of Simple Fast Space-Efficient Statistically Good Algorithms for Random Number Generation` by M.E. O'Neill. This record builds upon the :record:`~PCGRandomLib.pcg_setseq_64_xsh_rr_32_rng` PCG RNG which has 64 bits of state and 32 bits of output. While the PCG RNG used here is believed to have good statistical properties, it is not suitable for generating key material for encryption since the output of this RNG may be predictable. Additionally, if statistical properties of the random numbers are very important, another strategy may be required. We have good confidence that the random numbers generated by this record match the C PCG reference implementation and have specifically verified equal output given the same seed. However, this implementation differs from the C PCG reference implementation in how it produces random integers within particular bounds (with :proc:`randomStream.getNext` using ``min`` and ``max`` arguments). In addition, this implementation directly supports the generation of random ``real`` values, unlike the C PCG implementation. Smaller numbers, such as ``uint(8)`` or ``uint(16)``, are generated from the high-order bits of the 32-bit output. To generate larger numbers, several 32-bit-output RNGs are composed together. Each of these 32-bit RNGs has a different sequence constant and so will be independent and uncorrelated. For example, to generate 128-bit complex numbers, this RNG will use four 32-bit PCG RNGs with different sequence constants. One impact of this approach is that this implementation will only generate 2**64 different complex numbers with a given seed (for example). This record also supports generating integers within particular bounds. When that is required, it uses a strategy different from the PCG reference implementation to support efficient parallel iteration. In particular, when more than 1 random value is required as part of generating a value in a range, conceptually it uses more composed RNGs (as with the 32x2 strategy). Each new value beyond the first that is computed will be computed with a different RNG. This strategy is meant to avoid statistical bias. While we have tested this strategy to our satisfaction, it has not been subject to rigorous analysis and may have undesirable statistical properties. When generating a real, imaginary, or complex number, this implementation uses the strategy of generating a 64-bit unsigned integer and then multiplying it by 2.0**-64 in order to convert it to a floating point number. While this does construct a uniform distribution on rounded floating point values, it leaves out many possible real values (for example, 2**-128). We believe that this strategy has reasonable statistical properties. One side effect of this strategy is that the real number 1.0 can be generated because of rounding. The real number 0.0 can be generated because PCG can produce the value 0 as a random integer. We have tested this implementation with TestU01 (available at http://simul.iro.umontreal.ca/testu01/tu01.html ). We measured our implementation with TestU01 1.2.3 and the Crush suite, which consists of 144 statistical tests. The results were: * no failures for generating uniform reals * 1 failure for generating 32-bit values (which is also true for the reference version of PCG with the same configuration) * 0 failures for generating 64-bit values (which we provided to TestU01 as 2 different 32-bit values since it only accepts 32 bits at a time) * 0 failures for generating bounded integers (which we provided to TestU01 by requesting values in [0..,2**31+2**30+1) until we had two values < 2**31, removing the top 0 bit, and then combining the top 16 bits into the value provided to TestU01). .. attribute:: type eltType Specifies the type of value generated by the random stream. Currently, numeric and bool types are supported. .. attribute:: const seed: int The seed value for the PCG random number generator. When not provided explicitly, a seed will be generated in an implementation specific manner that depends upon the current time. .. method:: proc init(type eltType, seed: int) where isNumericOrBoolType(eltType) Create a new ``randomStream`` using the specified seed. .. method:: proc init(type eltType) where isNumericOrBoolType(eltType) .. warning:: The :record:`randomStream` initializer that generates a seed is unstable and subject to change Create a new ``randomStream``. A seed value will be generated in an implementation specific manner that depends on the current time. .. method:: proc ref fill(ref arr: []) where arr.isRectangular() Fill the array with pseudorandom values sampled from this stream. :arg arr: The rectangular array to be filled .. method:: proc ref fill(ref arr: [] ?t, min: t, max: t) where arr.isRectangular() Fill the array with pseudorandom values within a particular range. Each array element is set to a number in [``min``, ``max``] (inclusive) sampled from this stream. :arg arr: The rectangular array to be filled :arg min: The minimum value to sample :arg max: The maximum value to sample .. method:: proc ref fillRandom(ref arr: []) .. warning:: 'randomStream.fillRandom' is deprecated; please use 'fill' instead .. method:: proc ref fillRandom(ref arr: [], min, max) .. warning:: 'randomStream.fillRandom' is deprecated; please use 'fill' instead .. method:: proc ref shuffle(ref arr: [?d]) where is1DRectangularDomain(d) && isCoercible(this.eltType, d.idxType) Randomly rearrange a 1D array using values from this random stream. :arg arr: The array to shuffle. Its domain's ``idxType`` should be coercible to this stream's :type:`eltType`. .. method:: proc ref permutation(ref arr: [?d] ?t) where isCoercible(this.eltType, d.idxType) && isCoercible(d.idxType, t) && is1DRectangularDomain(d) .. warning:: 'permutation' is unstable and subject to change Produce a random permutation of an array's domain. The values ``d.dim(0).low..d.dim(0).high`` will appear exactly once in the array in a pseudo-random order. :arg arr: The array to store the permutation in .. method:: proc ref choice(const x: [?d], size: ?sizeType = none, replace = true, prob: ?probType = none) throws where is1DRectangularDomain(d) && isCoercible(this.eltType, d.idxType) .. warning:: 'choice' is unstable and subject to change Return a random sample from a given 1D array, ``x``. :arg x: The array to take a sample from. :arg 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. :arg 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``. :arg prob: an optional 1D array that contains probabilities of choosing each element of ``x``, 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 size must be equal to that of ``x.domain``. :return: An element chosen from ``x`` if ``size == 1``, or an array of elements chosen from ``x`` if ``size > 1`` or ``size`` is a domain. :throws IllegalArgumentError: if ``x.size == 0``, if ``x.size != prob.size``, if ``prob`` contains a negative value, if ``prob`` has no non-zero values, if ``size < 1 || size.size < 1``, if ``replace=false`` and ``size > x.size || size.size > x.size`` .. method:: proc ref choice(x: range(?), size: ?sizeType = none, replace = true, prob: ?probType = none) throws where isCoercible(this.eltType, x.idxType) .. warning:: 'choice' is unstable and subject to change Return a random sample from a given bounded range, ``x``. :arg x: a bounded range with values that will be sampled from. :arg 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. :arg 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``. :arg prob: an optional 1D array that contains probabilities of choosing each element of ``x``, 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 size must be equal to that of ``x``. :return: An element chosen from ``x`` if ``size == 1``, or an array of element chosen from ``x`` if ``size > 1`` or ``size`` is a domain. :throws IllegalArgumentError: if ``x.size == 0``, if ``x.size != prob.size``, if ``prob`` contains a negative value, if ``prob`` has no non-zero values, if ``size < 1 || size.size < 1``, if ``replace=false`` and ``size > x.size || size.size > x.size`` .. method:: proc ref choice(x: domain, size: ?sizeType = none, replace = true, prob: ?probType = none) throws where is1DRectangularDomain(x) && isCoercible(this.eltType, x.idxType) .. warning:: 'choice' is unstable and subject to change Return a random sample from a given 1D domain, ``x``. :arg x: a 1D domain with values that will be sampled from. :arg 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. :arg 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``. :arg prob: an optional 1D array that contains probabilities of choosing each element of ``x``, 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 size must be equal to that of ``x``. :return: An element chosen from ``x`` if ``size == 1``, or an array of element chosen from ``x`` if ``size > 1`` or ``size`` is a domain. :throws IllegalArgumentError: if ``x.size == 0``, if ``x.size != prob.size``, if ``prob`` contains a negative value, if ``prob`` has no non-zero values, if ``size < 1 || size.size < 1``, if ``replace=false`` and ``size > x.size || size.size > x.size``. .. method:: proc ref getNext(): eltType Get the next value in the random stream and advance its position by one. .. method:: proc ref getNext(min: eltType, max: eltType): eltType Get the next random value from the stream within a given range. Returns a number in [``min``, ``max``] (inclusive). This method will halt if checks are enabled and ``min > max``. .. note:: For integers, this type uses a strategy for generating a value in a particular range that has not been subject to rigorous study and may have statistical problems. For real numbers, this type generates a random value in [max, min] by computing a random value in [0,1] and scaling and shifting that value. Note that not all possible floating point values in the interval [`min`, `max`] can be constructed in this way. :arg min: The minimum value to sample :arg max: The maximum value to sample .. method:: proc ref skipToNth(n: integral) throws .. warning:: 'skipToNth' is unstable and subject to change Advance or rewind the random stream to the ``n``-th position in the pseudorandom sequence (where ``n=0`` is the starting position) :arg n: The position to skip to :throws IllegalArgumentError: Thrown if ``n`` is negative .. method:: proc ref getNth(n: integral): eltType throws .. warning:: 'getNth' is unstable and subject to change Advance or rewind the random stream to the ``n``-th position in the pseudorandom sequence and return the value. This is equivalent to :proc:`skipToNth` followed by :proc:`getNext`. :arg n: The position to skip to and retrieve (must be greater than zero) :throws IllegalArgumentError: Thrown if ``n`` is negative .. method:: proc ref iterate(D: domain) .. warning:: 'iterate' is unstable and subject to change .. method:: proc ref iterate(D: domain, min: eltType, max: eltType) .. warning:: 'iterate' is unstable and subject to change .. method:: proc serialize(writer, ref serializer) throws serialize the ``randomStream`` as a record with two fields: ``eltType`` and ``seed``. .. function:: proc createRandomStream(type eltType, seed: int(64) = _SeedGenerator.oddCurrentTime, param parSafe: bool = true, param algorithm = _defaultRNG) .. warning:: 'createRandomStream' is deprecated; please use 'new randomStream' instead 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 :mod:`NPBRandom` RNG will halt if provided an even seed. :mod:`PCGRandom` has no restrictions on the provided seed value. :arg eltType: The element type to be generated. :type eltType: `type` :arg seed: The seed to use for the PRNG. Defaults to `oddCurrentTime` from :type:`RandomSupport.SeedGenerator`. :type seed: `int(64)` :arg parSafe: The parallel safety setting. Defaults to `true`. :type parSafe: `bool` :arg algorithm: A param indicating which algorithm to use. Defaults to :param:`defaultRNG`. :type algorithm: :type:`RNG` :returns: an owned RandomStream .. class:: RandomStreamInterface : writeSerializable .. warning:: 'RandomStreamInterface' is deprecated Models a stream of pseudorandom numbers. This class is defined for documentation purposes and should not be instantiated. See :mod:`PCGRandom` and :mod:`NPBRandom` for RNGs that can be instantiated. To create a random stream, use :proc:`createRandomStream`. .. 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 :mod:`PCGRandom` but not by :mod:`NPBRandom`). .. note:: We plan to support general serial and parallel iterator methods on :class:`RandomStreamInterface`; however, providing the full suite of iterators is not possible with our current parallel iterator framework. Specifically, if :class:`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 :class:`RandomStreamInterface`, but this effort has not yet been taken on. .. note:: The :class:`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. .. attribute:: type eltType = real(64) Specifies the type of value generated by the RandomStream. Not all RandomStream implementations support all types. .. attribute:: 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. .. attribute:: const seed: int(64) The seed value for the PRNG. There may be constraints upon legal values depending on the specific RNG. .. method:: proc getNext(): eltType Returns the next value in the random stream. :returns: The next value in the random stream as type :type:`eltType`. .. method:: proc skipToNth(n: integral) throws Advances/rewinds the stream to the `n`-th value in the sequence. The first value corresponds to n=0. n must be >= 0, otherwise an IllegalArgumentError is thrown. :arg n: The position in the stream to skip to. Must be >= 0. :type n: `integral` :throws IllegalArgumentError: When called with negative `n` value. .. method:: 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 :proc:`skipToNth()` followed by :proc:`getNext()`. :arg n: The position in the stream to skip to. Must be >= 0. :type n: `integral` :returns: The `n`-th value in the random stream as type :type:`eltType`. :throws IllegalArgumentError: When called with negative `n` value. .. method:: proc fillRandom(ref arr: [] eltType) Fill the argument array with pseudorandom values. This method is identical to the standalone :proc:`fillRandom` procedure, except that it consumes random values from the :class:`RandomStreamInterface` object on which it's invoked rather than creating a new stream for the purpose of the call. :arg arr: The array to be filled :type arr: [] :type:`eltType` .. method:: proc choice(const x: [], size: ?sizeType = none, replace = true, prob: ?probType = none) throws Returns a random sample from a given 1-D array, ``x``. :arg x: a 1-D array with values that will be sampled from. :arg 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. :arg 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``. :arg prob: an optional 1-D array that contains probabilities of choosing each element of ``x``, 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 size must be equal to that of ``x.domain``. :return: An element chosen from ``x`` if ``size == 1``, or an array of element chosen from ``x`` if ``size > 1`` or ``size`` is a domain. :throws IllegalArgumentError: if ``x.size == 0``, if ``x.size != prob.size``, if ``prob`` contains a negative value, if ``prob`` has no non-zero values, if ``size < 1 || size.size < 1``, if ``replace=false`` and ``size > x.size || size.size > x.size`` .. method:: proc choice(x: range(strides = ?), size: ?sizeType = none, replace = true, prob: ?probType = none) throws Returns a random sample from a given bounded range, ``x``. :arg x: a bounded range with values that will be sampled from. :arg 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. :arg 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``. :arg prob: an optional 1-D array that contains probabilities of choosing each element of ``x``, 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 size must be equal to that of ``x``. :return: An element chosen from ``x`` if ``size == 1``, or an array of element chosen from ``x`` if ``size > 1`` or ``size`` is a domain. :throws IllegalArgumentError: if ``x.size == 0``, if ``x.size != prob.size``, if ``prob`` contains a negative value, if ``prob`` has no non-zero values, if ``size < 1 || size.size < 1``, if ``replace=false`` and ``size > x.size || size.size > x.size``. .. method:: proc choice(x: domain, size: ?sizeType = none, replace = true, prob: ?probType = none) throws Returns a random sample from a given 1-D domain, ``x``. :arg x: a 1-D dom with values that will be sampled from. :arg 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. :arg 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``. :arg prob: an optional 1-D array that contains probabilities of choosing each element of ``x``, 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 size must be equal to that of ``x``. :return: An element chosen from ``x`` if ``size == 1``, or an array of element chosen from ``x`` if ``size > 1`` or ``size`` is a domain. :throws IllegalArgumentError: if ``x.size == 0``, if ``x.size != prob.size``, if ``prob`` contains a negative value, if ``prob`` has no non-zero values, if ``size < 1 || size.size < 1``, if ``replace=false`` and ``size > x.size || size.size > x.size``. .. method:: proc iterate(D: domain, type resultType = eltType) Returns an iterable expression for generating `D.size` random numbers. The RNG state will be immediately advanced by `D.size` 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. :arg D: a domain :arg resultType: the type of number to yield :return: an iterable expression yielding random `resultType` values