Chapter 12: Random Number Generation

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 routine
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 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 for 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  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

Routine 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 routine 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.

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 <stdio.h>

#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);

  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 <stdio.h>

#include <imsls.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


Visual Numerics, Inc.
Visual Numerics - Developers of IMSL and PV-WAVE
http://www.vni.com/
PHONE: 713.784.3131
FAX:713.781.9260