random_general_discrete

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

Synopsis

#include <imsls.h>

int *imsls_f_random_general_discrete (int n_random, int imin, int nmass, float probs[], 0)

The type double function is imsls_d_random_general_discrete.

Required Arguments

int n_random (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 IMSLS_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. IMSL function imsls_f_discrete_table_setup 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 n_random containing the random discrete deviates. To release this space, use imsls_free.

Synopsis with Optional Arguments

#include <imsls.h>

int *imsls_f_random_general_discrete (int n_random, int imin, int nmass, float probs[],
IMSLS_GET_INDEX_VECTORS, int **iwk, float **wk,
IMSLS_GET_INDEX_VECTORS_USER, int iwk[], float wk[],
IMSLS_SET_INDEX_VECTORS, int iwk[], float wk[],
IMSLS_RETURN_USER, int ir[],
IMSLS_TABLE,
0)

Optional Arguments

IMSLS_GET_INDEX_VECTORS, int **iwk, float **wk (Output)
Retrieve indexing vectors that can be used to increase efficiency when multiple calls will be made to imsls_f_random_general_discrete with the same values in probs.

IMSLS_GET_INDEX_VECTORS_USER, int iwk[], float wk[] (Output)
User-supplied arrays of length nmass used to retrieve indexing vectors that can be used to increase efficiency when multiple calls will be made to imsls_f_random_general_discrete with the same values in probs.

IMSLS_SET_INDEX_VECTORS, int *iwk, float *wk (Input)
Arrays of length nmass that can be used to increase efficiency when multiple calls will be made to imsls_f_random_general_discrete with the same values in probs. These arrays are obtained by using one of the options IMSLS_GET_INDEX_VECTORS or IMSLS_GET_INDEX_VECTORS_USER in the first call to imsls_f_random_general_discrete.

IMSLS_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.

IMSLS_RETURN_USER, int ir[] (Output)
User-supplied array of length n_random containing the random discrete deviates.

Description

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

Pr(X = i) = pj

for i = imin, imin + 1, …, imin + nm - 1 where j = i - imin + 1, pj = probs[j-1], imin = imin, and nm = 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 imsls_f_random_general_discrete can retrieve the arrays iwk and wk using the optional arguments IMSLS_GET_INDEX_VECTORS or IMSLS_GET_INDEX_VECTORS_USER , then subsequent calls can be made using the optional argument IMSLS_SET_INDEX_VECTORS.

If the optional argument IMSLS_TABLE is used, imsls_f_random_general_discrete 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 imsls_f_discrete_table_setup can be used to set up the table probs. imsls_f_random_general_discrete uses the inverse CDF method to generate the variates.

Examples

Example 1

In this example, imsls_f_random_general_discrete 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 imsls_f_random_general_discrete is called the first time, IMSLS_GET_INDEX_VECTORS is used to initialize the index vectors iwk and wk. In the next call, IMSLS_GET_INDEX_VECTORS is used, so the setup phase is bypassed.

 

#include <imsls.h>

 

int main()

{

int nr = 5, nmass = 5, iopt = 0, imin = 1, *iwk, *ir;

float probs[] = {.05, .45, .31, .04, .15};

float *wk;

 

imsls_random_seed_set(123457);

 

ir = imsls_f_random_general_discrete(nr, imin, nmass, probs,

IMSLS_GET_INDEX_VECTORS, &iwk, &wk,

0);

 

imsls_i_write_matrix("Random deviates", 1, 5, ir,

IMSLS_NO_COL_LABELS,

0);

 

imsls_free(ir);

 

ir = imsls_f_random_general_discrete(nr, imin, nmass, probs,

IMSLS_SET_INDEX_VECTORS, iwk, wk,

0);

 

imsls_i_write_matrix("Random deviates", 1, 5, ir,

IMSLS_NO_COL_LABELS,

0);

}

Output

 

Random deviates

3 2 2 3 5

 

Random deviates

1 3 4 5 3

 

Example 2

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

 

#include <imsls.h>

#include <stdlib.h>

 

float prf(int ix);

 

int main()

{

int nndx = 12, imin = 0, nmass = 21, nr = 5;

float del = 0.00001, *cumpr;

 

int *ir = NULL;

 

cumpr = imsls_f_discrete_table_setup (prf, del, nndx, &imin,

&nmass,

0);

 

imsls_random_seed_set(123457);

 

ir = imsls_f_random_general_discrete(nr, imin, nmass, cumpr,

IMSLS_TABLE,

0);

 

imsls_i_write_matrix("Binomial (20, 0.5) random deviates", 1, 5, ir,

IMSLS_NO_COL_LABELS,

0);

}

 

float prf(int ix)

{

int n = 20;

float p = .5;

 

return imsls_f_binomial_pdf (ix, n, p);

}

Output

 

Binomial (20, 0.5) random deviates

14 9 12 10 12