Man Page lcrans.3m




NAME

     lcrans - linear congruential pseudo-random number generators


SYNOPSIS

     cc [ flag ... ] file ...  -lsunmath -lm [ library ... ]

     #include <sunmath.h>

     #define LCRAN_MULTIPLIER 16807

     #define LCRAN_MODULUS 2147483647L

     int i_lcran_(void);

     float r_lcran_(void);

     double d_lcran_(void);

     void i_lcrans_(int *x, int *n, int *l, int *u);

     void u_lcrans_(unsigned *x, int *n,  unsigned  *l,  unsigned
     *u);

     void r_lcrans_(float *x, int *n, float *l, float *u);

     void d_lcrans_(double *x, int *n, double *l, double *u);

     void i_get_lcrans_(int *x);

     void i_set_lcrans_(int *x);

     void i_init_lcrans_(void);


DESCRIPTION

     These functions provide uniform random  variates,  of  types
     integer,   single-precision   floating-point,   or   double-
     precision floating-point.

     Linear congruential variates are generated one at a time  by
     ..._lcran_() using the recurrence

          lcran_last = (LCRAN_MULTIPLIER * lcran_last) % LCRAN_MODULUS

     i_lcran_()  returns   lcran_last,   while   r_lcran_()   and
     d_lcran_()  return  lcran_last  / LCRAN_MODULUS, so that the
     variates are contained in the following intervals:







type | lower bound | upper bound

       |  name                             value|  name                          value

_______|________________________________________|_____________________________________


integer| I_LCRAN_LB 1| I_LCRAN_UB 2147483646


float | R_LCRAN_LB 4.656612873077392578E-10| R_LCRAN_UB 1


double | D_LCRAN_LB 4.656612875245796923E-10| D_LCRAN_UB 0.9999999995343387127


     lcran_last should satisfy 1 <= lcran_last <= 2147483646, but
     for efficiency ..._lcran_() does not check that.

     Linear congruential variates are generated *n at a  time  by
     ..._lcrans_() using the recurrence

            lcran_last = (lcran_multiplier * lcran_last) % LCRAN_MODULUS ;
            return scale * (lcran_last + offset) ;

     where scale and offset are calculated from *l and *u so that
     the computed variates are uniform in [*l,*u].  Thus changing
     lcran_multiplier   changes   the   variates   produced    by
     ..._lcrans_(),  but  for  efficiency  ..._lcran_()  uses the
     fixed   LCRAN_MULTIPLIER,   16807.    The   fixed    modulus
     LCRAN_MODULUS,  2147483647L, is intentionally not a power of
     two  to  avoid  the  defects   in   rand(3C).    On   entry,
     ..._lcrans_()  does check that 1 <= lcran_last <= 2147483646
     and modifies lcran_last if necessary.

     The state of the linear congruential generator (an array  of
     two  ints containing lcran_last and lcran_multiplier) may be
     obtained with i_get_lcrans_() and set with  i_set_lcrans_().
     The initial state may be restored with i_init_lcrans_().


EXAMPLES

  to generate 1000 double-precision random variates in (0,1)
          double x[1000] ; int i, n = 1000 ;
          double lb = D_LCRAN_LB, ub = D_LCRAN_UB ;

          for (i=0;i<n;i++) x[i] = d_lcran_();            /* or... */

          d_lcrans_(x, &n, &lb, &ub) ;                    /* same output, but more efficient */

  to generate 1000 integer random variates in [-10,+10]
          int x[1000] ; int n = 1000, lb = -10, ub = 10 ;

          i_lcrans_(x, &n, &lb, &ub) ;


SEE ALSO

     addrans(3M), drand48(3),  mwcrans(3M),  rand(3C),  rand(3V),
     random(3), shufrans(3M).

     Knuth, Seminumerical Algorithms, 1981, Addison-Wesley.


     Park and Miller, Random Number  Generators:  Good  Ones  are
     Hard to Find, Communications of the ACM, October 1988.


NOTES

     The number of times your program calls a random number  gen-
     erator  function  determines when it is more efficient (fas-
     ter) to use lcrans(3M) versus addrans(3M).  For  normal  use
     (more  than 50 calls), use addrans(3M), possibly in conjunc-
     tion with shufrans(3M), rather  than  calls  to  lcrans(3M),
     drand48(3),  rand(3C),  rand(3V)  and random(3).  For casual
     use  (less  than  50  calls),  use  lcrans(3M)  rather  than
     addrans(3M).   The reason for this is that the first call to
     addrans(3M) has the overhead cost of initializing a table of
     55 elements (defined by ADDRAN_SIZE).