'\" t .\" @(#)addrans.3m 1.19 98/02/04 SMI; .TH addrans 3M "1 Sep 1993" .SH NAME addrans \- additive pseudo-random number generators .SH SYNOPSIS .LP .B cc .RI "[ " "flag" " \|.\|.\|. ] " "file" " \|.\|.\|." .B \-lsunmath -lm .RI "[ " "library" " \|.\|.\|. ]" .LP .B #include .LP .B #define ADDRAN_SIZE 55 .LP .B int i_addran_(void); .LP .B float r_addran_(void); .LP .B double d_addran_(void); .LP .BI "void i_addrans_(int *" "x" , .BI "int *" "n" , .BI "int *" "l" , .BI "int *" "u" ); .LP .BI "void u_addrans_(unsigned *" "x" , .BI "int *" n , .BI "unsigned *" "l" , .BI "unsigned *" "u" ); .LP .BI "void r_addrans_(float *" "x" , .BI "int *" "n" , .BI "float *" "l" , .BI "float *" "u" ); .LP .BI "void d_addrans_(double *" "x" , .BI "int *" "n" , .BI "double *" "l" , .BI "double *" "u" ); .LP .BI "void i_get_addrans_(int *" "x" ); .LP .BI "void r_get_addrans_(float *" "x" ); .LP .BI "void d_get_addrans_(double *" "x" ); .LP .BI "void i_set_addrans_(int *" "x" ); .LP .BI "void r_set_addrans_(float *" "x" ); .LP .BI "void d_set_addrans_(double *" "x" ); .LP .B void i_init_addrans_(void); .LP .B void r_init_addrans_(void); .LP .B void d_init_addrans_(void); .SH DESCRIPTION .IX "_1st_index_term_" "_2nd_index_term_" "_format_of_1st_" "_format_of_2nd_" .LP These functions provide uniform random variates, of types integer or unsigned, single-precision floating-point, or double-precision floating-point. .LP Additive variates are generated one at a time by .B ..._addran_(\|) using the recurrence .ft I .nf addran_last = addran_table[i] - addran_table[(i-24) % ADDRAN_SIZE] ; addran_table[i] = addran_last; i = (i+1) % \fBADDRAN_SIZE\fP ; return addran_last; .fi .ft R .I addran_table is a table containing .B ADDRAN_SIZE elements of type unsigned, float, or double. The variates are constrained to the following intervals (see table below) by adding, when necessary, 4294967296 for integer and unsigned, and 1.0 for float and double. .TS center; l | l r | l r. 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 .TE Thus any representable 32-bit integer or unsigned is an equally likely result from .BR i_addran_(\|) ; furthermore it hardly matters that "additive" methods are implemented by subtraction for efficiency. .LP Additive variates are generated .I *n at a time by .B ..._addrans_(\|) using the recurrence .ft I .nf addran_last = addran_table_[i] - addran_table_[(i-24) % \fBADDRAN_SIZE\fP] ; addran_table[i] = addran_last; i = (i+1) % \fBADDRAN_SIZE\fP ; return scale * (addran_last + offset) .fi .ft R where .I scale and .I offset are calculated from .I *l and .I *u so that the computed variates are uniform in .RI [ *l , *u ]. .B u_addrans_(\|) is available so that large unsigned bounds can be specified. .B u_addrans_(\|) uses the same .I addran_table as .B i_addrans_(\|). .LP The state of the additive generator, an array of .BR ADDRAN_SIZE , may be obtained with .B ...get_addrans_(\|) and set with .BR ...set_addrans_(\|) , or restored to the initial state with .BR ...init_addrans_(\|) . .SH EXAMPLES .SS to\0generate 1000 double-precision\0random\0variates\0in\0[0,1) .LP .RS .ft B .nf double x[1000] ; int i, n = 1000 ; double lb = D_ADDRAN_LB, ub = D_ADDRAN_UB ; for (i=0;i