randomGeneralDiscrete

Generates pseudorandom numbers from a general discrete distribution using an alias method or optionally a table lookup method.

Synopsis

randomGeneralDiscrete (nRandom, imin, nmass, probs)

Required Arguments

int nRandom (Input)
Number of random numbers to generate.
int imin (Input)

Smallest value the random deviate can assume.

This is the value corresponding to the probability in probs[0].

int nmass (Input)
Number of mass points in the discrete distribution.
float probs[] (Input)

Array of length nmass containing probabilities associated with the individual mass points. The elements of probs must be nonnegative and must sum to 1.0.

If the optional argument table is used, then probs is a vector of length at least nmass + 1 containing in the first nmass positions the cumulative probabilities and, possibly, indexes to speed access to the probabilities. PyIMSL function discreteTableSetup can be used to initialize probs properly. If no elements of probs are used as indexes, probs [nmass] is 0.0 on input. The value in probs[0] is the probability of imin. The value in probs [nmass-1] must be exactly 1.0 (since this is the CDF at the upper range of the distribution.)

Return Value

An integer array of length nRandom containing the random discrete deviates.

Optional Arguments

getIndexVectors, iwk, wk (Output)
Retrieve indexing vectors that can be used to increase efficiency when multiple calls will be made to randomGeneralDiscrete with the same values in probs.
setIndexVectors, iwk, wk (Input)
Arrays of length nmass that can be used to increase efficiency when multiple calls will be made to randomGeneralDiscrete with the same values in probs. These arrays are obtained by using one of the options getIndexVectors in the first call to randomGeneralDiscrete.
table, (Input)
Generate pseudorandom numbers from a general discrete distribution using a table lookup method. If this option is used, then probs is a vector of length at least nmass + 1 containing in the first nmass positions the cumulative probabilities and, possibly, indexes to speed access to the probabilities.

Description

Function randomGeneralDiscrete generates pseudorandom numbers from a discrete distribution with probability function given in the vector probs; that is

\[Pr(X = i) = p_j\]

for \(i=i_{min},i_{min}+1,\ldots,i_{min}+n_m-1\) where \(j=i-i_{min}+1\), \(p_j\) = probs[j-1], \(i_{min}\) = imin, and \(n_m\) = nmass.

The algorithm is the alias method, due to Walker (1974), with modifications suggested by Kronmal and Peterson (1979). The method involves a setup phase, in which the vectors iwk and wk are filled. After the vectors are filled, the generation phase is very fast. To increase efficiency, the first call to randomGeneralDiscrete can retrieve the arrays iwk and wk using the optional argument getIndexVectors, then subsequent calls can be made using the optional argument setIndexVectors.

If the optional argument table is used, randomGeneralDiscrete generates pseudorandom deviates from a discrete distribution, using the table probs, which contains the cumulative probabilities of the distribution and, possibly, indexes to speed the search of the table. The function discreteTableSetup can be used to set up the table probs. randomGeneralDiscrete uses the inverse CDF method to generate the variates.

Examples

Example 1

In this example, randomGeneralDiscrete is used to generate five pseudorandom variates from the discrete distribution:

\[Pr(X = 1) = .05\]
\[Pr(X = 2) = .45\]
\[Pr(X = 3) = .31\]
\[Pr(X = 4) = .04\]
\[Pr(X = 5) = .15\]

When randomGeneralDiscrete is called the first time, getIndexVectors is used to initialize the index vectors iwk and wk. In the next call, getIndexVectors is used, so the setup phase is bypassed.

from numpy import *
from pyimsl.stat.randomGeneralDiscrete import randomGeneralDiscrete
from pyimsl.stat.randomSeedSet import randomSeedSet
from pyimsl.stat.writeMatrix import writeMatrix

n_random = 5
nmass = 5
iopt = 0
imin = 1
probs = [.05, .45, .31, .04, .15]
indexVectors = {}

randomSeedSet(123457)

ir = randomGeneralDiscrete(n_random, imin, nmass, probs,
                           getIndexVectors=indexVectors)

iwk = indexVectors['iwk']
wk = indexVectors['wk']
writeMatrix("Random deviates", ir, noColLabels=True)

ir = randomGeneralDiscrete(n_random, imin, nmass, probs,
                           setIndexVectors={'iwk': indexVectors['iwk'], 'wk': indexVectors['wk']})

writeMatrix("Random deviates", ir, noColLabels=True)

Output

 
                        Random deviates
          3            2            2            3            5
 
                        Random deviates
          1            3            4            5            3

Example 2

In this example, discreteTableSetup is used to set up a table and then randomGeneralDiscrete is used to generate five pseudorandom variates from the binomial distribution with parameters 20 and 0.5.

from numpy import *
from pyimsl.stat.randomGeneralDiscrete import randomGeneralDiscrete
from pyimsl.stat.discreteTableSetup import discreteTableSetup
from pyimsl.stat.binomialPdf import binomialPdf
from pyimsl.stat.randomSeedSet import randomSeedSet
from pyimsl.stat.writeMatrix import writeMatrix


def prf(ix):
    n = 20
    p = 0.5
    return binomialPdf(ix, n, p)


nndx = 12
imin = [0]
nmass = [21]
n_random = 5
delta = 0.00001

cumpr = discreteTableSetup(prf, delta, nndx, imin, nmass)

randomSeedSet(123457)

ir = randomGeneralDiscrete(n_random, imin[0], nmass[0], cumpr, table=True)

writeMatrix("Binomial (20, 0.5) random deviates", ir, noColLabels=True)

Output

1 19
 
              Binomial (20, 0.5) random deviates
         14            9           12           10           12