Man Page addrans.3m
NAME
addrans - additive pseudo-random number generators
SYNOPSIS
cc [ flag ... ] file ... -lsunmath -lm [ library ... ]
#include <sunmath.h>
#define ADDRAN_SIZE 55
int i_addran_(void);
float r_addran_(void);
double d_addran_(void);
void i_addrans_(int *x, int *n, int *l, int *u);
void u_addrans_(unsigned *x, int *n, unsigned *l, unsigned
*u);
void r_addrans_(float *x, int *n, float *l, float *u);
void d_addrans_(double *x, int *n, double *l, double *u);
void i_get_addrans_(int *x);
void r_get_addrans_(float *x);
void d_get_addrans_(double *x);
void i_set_addrans_(int *x);
void r_set_addrans_(float *x);
void d_set_addrans_(double *x);
void i_init_addrans_(void);
void r_init_addrans_(void);
void d_init_addrans_(void);
DESCRIPTION
These functions provide uniform random variates, of types
integer or unsigned, single-precision floating-point, or
double-precision floating-point.
Additive variates are generated one at a time by
..._addran_() using the recurrence
addran_last = addran_table[i] - addran_table[(i-24) % ADDRAN_SIZE] ;
addran_table[i] = addran_last;
i = (i+1) % ADDRAN_SIZE ;
return addran_last;
addran_table is a table containing ADDRAN_SIZE elements of
type unsigned, float, or double. The variates are con-
strained to the following intervals (see table below) by
adding, when necessary, 4294967296 for integer and unsigned,
and 1.0 for float and double.
type | lower bound | upper bound
| name value| name value
________|___________________________|_____________________________________
unsigned| U_ADDRAN_LB 0| U_ADDRAN_UB 4294967295
integer | I_ADDRAN_LB -2147483648| I_ADDRAN_UB 2147483647
float | R_ADDRAN_LB 0| R_ADDRAN_UB 0.9999999403953552246
double | D_ADDRAN_LB 0| D_ADDRAN_UB 0.9999999999999998890
Thus any representable 32-bit integer or unsigned is an
equally likely result from i_addran_(); furthermore it
hardly matters that "additive" methods are implemented by
subtraction for efficiency.
Additive variates are generated *n at a time by
..._addrans_() using the recurrence
addran_last = addran_table_[i] - addran_table_[(i-24) % ADDRAN_SIZE] ;
addran_table[i] = addran_last;
i = (i+1) % ADDRAN_SIZE ;
return scale * (addran_last + offset)
where scale and offset are calculated from *l and *u so that
the computed variates are uniform in [*l,*u]. u_addrans_()
is available so that large unsigned bounds can be specified.
u_addrans_() uses the same addran_table as i_addrans_().
The state of the additive generator, an array of
ADDRAN_SIZE, may be obtained with ...get_addrans_() and set
with ...set_addrans_(), or restored to the initial state
with ...init_addrans_().
EXAMPLES
to generate 1000 double-precision random variates in [0,1)
double x[1000] ; int i, n = 1000 ; double lb = D_ADDRAN_LB, ub = D_ADDRAN_UB ;
for (i=0;i<n;i++) x[i] = d_addran_(); /* or... */
d_addrans_(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_addrans_(x, &n, &lb, &ub) ;
SEE ALSO
drand48(3), lcrans(3M), mwcrans(3M), rand(3C), rand(3C),
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(3C) 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).