1*10086Ssam #ifndef lint 2*10086Ssam static char sccsid[] = "@(#)random.c 4.2 (Berkeley) 83/01/02"; 3*10086Ssam #endif 49316Smckusick 59316Smckusick #include <stdio.h> 69316Smckusick 79316Smckusick /* 89316Smckusick * random.c: 99316Smckusick * An improved random number generation package. In addition to the standard 109316Smckusick * rand()/srand() like interface, this package also has a special state info 119316Smckusick * interface. The initstate() routine is called with a seed, an array of 129316Smckusick * bytes, and a count of how many bytes are being passed in; this array is then 139316Smckusick * initialized to contain information for random number generation with that 149316Smckusick * much state information. Good sizes for the amount of state information are 159316Smckusick * 32, 64, 128, and 256 bytes. The state can be switched by calling the 169316Smckusick * setstate() routine with the same array as was initiallized with initstate(). 179316Smckusick * By default, the package runs with 128 bytes of state information and 189316Smckusick * generates far better random numbers than a linear congruential generator. 199316Smckusick * If the amount of state information is less than 32 bytes, a simple linear 209316Smckusick * congruential R.N.G. is used. 219316Smckusick * Internally, the state information is treated as an array of longs; the 229316Smckusick * zeroeth element of the array is the type of R.N.G. being used (small 239316Smckusick * integer); the remainder of the array is the state information for the 249316Smckusick * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of 259316Smckusick * state information, which will allow a degree seven polynomial. (Note: the 269316Smckusick * zeroeth word of state information also has some other information stored 279316Smckusick * in it -- see setstate() for details). 289316Smckusick * The random number generation technique is a linear feedback shift register 299316Smckusick * approach, employing trinomials (since there are fewer terms to sum up that 309316Smckusick * way). In this approach, the least significant bit of all the numbers in 319316Smckusick * the state table will act as a linear feedback shift register, and will have 329316Smckusick * period 2^deg - 1 (where deg is the degree of the polynomial being used, 339316Smckusick * assuming that the polynomial is irreducible and primitive). The higher 349316Smckusick * order bits will have longer periods, since their values are also influenced 359316Smckusick * by pseudo-random carries out of the lower bits. The total period of the 369316Smckusick * generator is approximately deg*(2**deg - 1); thus doubling the amount of 379316Smckusick * state information has a vast influence on the period of the generator. 389316Smckusick * Note: the deg*(2**deg - 1) is an approximation only good for large deg, 399316Smckusick * when the period of the shift register is the dominant factor. With deg 409316Smckusick * equal to seven, the period is actually much longer than the 7*(2**7 - 1) 419316Smckusick * predicted by this formula. 429316Smckusick */ 439316Smckusick 449316Smckusick 459316Smckusick 469316Smckusick /* 479316Smckusick * For each of the currently supported random number generators, we have a 489316Smckusick * break value on the amount of state information (you need at least this 499316Smckusick * many bytes of state info to support this random number generator), a degree 509316Smckusick * for the polynomial (actually a trinomial) that the R.N.G. is based on, and 519316Smckusick * the separation between the two lower order coefficients of the trinomial. 529316Smckusick */ 539316Smckusick 549316Smckusick #define TYPE_0 0 /* linear congruential */ 559316Smckusick #define BREAK_0 8 569316Smckusick #define DEG_0 0 579316Smckusick #define SEP_0 0 589316Smckusick 599316Smckusick #define TYPE_1 1 /* x**7 + x**3 + 1 */ 609316Smckusick #define BREAK_1 32 619316Smckusick #define DEG_1 7 629316Smckusick #define SEP_1 3 639316Smckusick 649316Smckusick #define TYPE_2 2 /* x**15 + x + 1 */ 659316Smckusick #define BREAK_2 64 669316Smckusick #define DEG_2 15 679316Smckusick #define SEP_2 1 689316Smckusick 699316Smckusick #define TYPE_3 3 /* x**31 + x**3 + 1 */ 709316Smckusick #define BREAK_3 128 719316Smckusick #define DEG_3 31 729316Smckusick #define SEP_3 3 739316Smckusick 749316Smckusick #define TYPE_4 4 /* x**63 + x + 1 */ 759316Smckusick #define BREAK_4 256 769316Smckusick #define DEG_4 63 779316Smckusick #define SEP_4 1 789316Smckusick 799316Smckusick 809316Smckusick /* 819316Smckusick * Array versions of the above information to make code run faster -- relies 829316Smckusick * on fact that TYPE_i == i. 839316Smckusick */ 849316Smckusick 859316Smckusick #define MAX_TYPES 5 /* max number of types above */ 869316Smckusick 879316Smckusick static int degrees[ MAX_TYPES ] = { DEG_0, DEG_1, DEG_2, 889316Smckusick DEG_3, DEG_4 }; 899316Smckusick 909316Smckusick static int seps[ MAX_TYPES ] = { SEP_0, SEP_1, SEP_2, 919316Smckusick SEP_3, SEP_4 }; 929316Smckusick 939316Smckusick 949316Smckusick 959316Smckusick /* 969316Smckusick * Initially, everything is set up as if from : 979316Smckusick * initstate( 1, &randtbl, 128 ); 989316Smckusick * Note that this initialization takes advantage of the fact that srandom() 999316Smckusick * advances the front and rear pointers 10*rand_deg times, and hence the 1009316Smckusick * rear pointer which starts at 0 will also end up at zero; thus the zeroeth 1019316Smckusick * element of the state information, which contains info about the current 1029316Smckusick * position of the rear pointer is just 1039316Smckusick * MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3. 1049316Smckusick */ 1059316Smckusick 1069316Smckusick static long randtbl[ DEG_3 + 1 ] = { TYPE_3, 1079316Smckusick 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 1089316Smckusick 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 1099316Smckusick 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 1109316Smckusick 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 1119316Smckusick 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, 1129316Smckusick 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 1139316Smckusick 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 1149316Smckusick 0xf5ad9d0e, 0x8999220b, 0x27fb47b9 }; 1159316Smckusick 1169316Smckusick /* 1179316Smckusick * fptr and rptr are two pointers into the state info, a front and a rear 1189316Smckusick * pointer. These two pointers are always rand_sep places aparts, as they cycle 1199316Smckusick * cyclically through the state information. (Yes, this does mean we could get 1209316Smckusick * away with just one pointer, but the code for random() is more efficient this 1219316Smckusick * way). The pointers are left positioned as they would be from the call 1229316Smckusick * initstate( 1, randtbl, 128 ) 1239316Smckusick * (The position of the rear pointer, rptr, is really 0 (as explained above 1249316Smckusick * in the initialization of randtbl) because the state table pointer is set 1259316Smckusick * to point to randtbl[1] (as explained below). 1269316Smckusick */ 1279316Smckusick 1289316Smckusick static long *fptr = &randtbl[ SEP_3 + 1 ]; 1299316Smckusick static long *rptr = &randtbl[ 1 ]; 1309316Smckusick 1319316Smckusick 1329316Smckusick 1339316Smckusick /* 1349316Smckusick * The following things are the pointer to the state information table, 1359316Smckusick * the type of the current generator, the degree of the current polynomial 1369316Smckusick * being used, and the separation between the two pointers. 1379316Smckusick * Note that for efficiency of random(), we remember the first location of 1389316Smckusick * the state information, not the zeroeth. Hence it is valid to access 1399316Smckusick * state[-1], which is used to store the type of the R.N.G. 1409316Smckusick * Also, we remember the last location, since this is more efficient than 1419316Smckusick * indexing every time to find the address of the last element to see if 1429316Smckusick * the front and rear pointers have wrapped. 1439316Smckusick */ 1449316Smckusick 1459316Smckusick static long *state = &randtbl[ -1 ]; 1469316Smckusick 1479316Smckusick static int rand_type = TYPE_3; 1489316Smckusick static int rand_deg = DEG_3; 1499316Smckusick static int rand_sep = SEP_3; 1509316Smckusick 1519316Smckusick static long *end_ptr = &randtbl[ DEG_3 + 1 ]; 1529316Smckusick 1539316Smckusick 1549316Smckusick 1559316Smckusick /* 1569316Smckusick * srandom: 1579316Smckusick * Initialize the random number generator based on the given seed. If the 1589316Smckusick * type is the trivial no-state-information type, just remember the seed. 1599316Smckusick * Otherwise, initializes state[] based on the given "seed" via a linear 1609316Smckusick * congruential generator. Then, the pointers are set to known locations 1619316Smckusick * that are exactly rand_sep places apart. Lastly, it cycles the state 1629316Smckusick * information a given number of times to get rid of any initial dependencies 1639316Smckusick * introduced by the L.C.R.N.G. 1649316Smckusick * Note that the initialization of randtbl[] for default usage relies on 1659316Smckusick * values produced by this routine. 1669316Smckusick */ 1679316Smckusick 1689316Smckusick srandom( x ) 1699316Smckusick 1709316Smckusick unsigned x; 1719316Smckusick { 1729316Smckusick register int i, j; 1739316Smckusick 1749316Smckusick if( rand_type == TYPE_0 ) { 1759316Smckusick state[ 0 ] = x; 1769316Smckusick } 1779316Smckusick else { 1789316Smckusick j = 1; 1799316Smckusick state[ 0 ] = x; 1809316Smckusick for( i = 1; i < rand_deg; i++ ) { 1819316Smckusick state[i] = 1103515245*state[i - 1] + 12345; 1829316Smckusick } 1839316Smckusick fptr = &state[ rand_sep ]; 1849316Smckusick rptr = &state[ 0 ]; 1859316Smckusick for( i = 0; i < 10*rand_deg; i++ ) random(); 1869316Smckusick } 1879316Smckusick } 1889316Smckusick 1899316Smckusick 1909316Smckusick 1919316Smckusick /* 1929316Smckusick * initstate: 1939316Smckusick * Initialize the state information in the given array of n bytes for 1949316Smckusick * future random number generation. Based on the number of bytes we 1959316Smckusick * are given, and the break values for the different R.N.G.'s, we choose 1969316Smckusick * the best (largest) one we can and set things up for it. srandom() is 1979316Smckusick * then called to initialize the state information. 1989316Smckusick * Note that on return from srandom(), we set state[-1] to be the type 1999316Smckusick * multiplexed with the current value of the rear pointer; this is so 2009316Smckusick * successive calls to initstate() won't lose this information and will 2019316Smckusick * be able to restart with setstate(). 2029316Smckusick * Note: the first thing we do is save the current state, if any, just like 2039316Smckusick * setstate() so that it doesn't matter when initstate is called. 2049316Smckusick * Returns a pointer to the old state. 2059316Smckusick */ 2069316Smckusick 2079316Smckusick char * 2089316Smckusick initstate( seed, arg_state, n ) 2099316Smckusick 2109316Smckusick unsigned seed; /* seed for R. N. G. */ 2119316Smckusick char *arg_state; /* pointer to state array */ 2129316Smckusick int n; /* # bytes of state info */ 2139316Smckusick { 2149316Smckusick register char *ostate = (char *)( &state[ -1 ] ); 2159316Smckusick 2169316Smckusick if( rand_type == TYPE_0 ) state[ -1 ] = rand_type; 2179316Smckusick else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type; 2189316Smckusick if( n < BREAK_1 ) { 2199316Smckusick if( n < BREAK_0 ) { 2209316Smckusick fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n" ); 2219316Smckusick return; 2229316Smckusick } 2239316Smckusick rand_type = TYPE_0; 2249316Smckusick rand_deg = DEG_0; 2259316Smckusick rand_sep = SEP_0; 2269316Smckusick } 2279316Smckusick else { 2289316Smckusick if( n < BREAK_2 ) { 2299316Smckusick rand_type = TYPE_1; 2309316Smckusick rand_deg = DEG_1; 2319316Smckusick rand_sep = SEP_1; 2329316Smckusick } 2339316Smckusick else { 2349316Smckusick if( n < BREAK_3 ) { 2359316Smckusick rand_type = TYPE_2; 2369316Smckusick rand_deg = DEG_2; 2379316Smckusick rand_sep = SEP_2; 2389316Smckusick } 2399316Smckusick else { 2409316Smckusick if( n < BREAK_4 ) { 2419316Smckusick rand_type = TYPE_3; 2429316Smckusick rand_deg = DEG_3; 2439316Smckusick rand_sep = SEP_3; 2449316Smckusick } 2459316Smckusick else { 2469316Smckusick rand_type = TYPE_4; 2479316Smckusick rand_deg = DEG_4; 2489316Smckusick rand_sep = SEP_4; 2499316Smckusick } 2509316Smckusick } 2519316Smckusick } 2529316Smckusick } 2539316Smckusick state = &( ( (long *)arg_state )[1] ); /* first location */ 2549316Smckusick end_ptr = &state[ rand_deg ]; /* must set end_ptr before srandom */ 2559316Smckusick srandom( seed ); 2569316Smckusick if( rand_type == TYPE_0 ) state[ -1 ] = rand_type; 2579316Smckusick else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type; 2589316Smckusick return( ostate ); 2599316Smckusick } 2609316Smckusick 2619316Smckusick 2629316Smckusick 2639316Smckusick /* 2649316Smckusick * setstate: 2659316Smckusick * Restore the state from the given state array. 2669316Smckusick * Note: it is important that we also remember the locations of the pointers 2679316Smckusick * in the current state information, and restore the locations of the pointers 2689316Smckusick * from the old state information. This is done by multiplexing the pointer 2699316Smckusick * location into the zeroeth word of the state information. 2709316Smckusick * Note that due to the order in which things are done, it is OK to call 2719316Smckusick * setstate() with the same state as the current state. 2729316Smckusick * Returns a pointer to the old state information. 2739316Smckusick */ 2749316Smckusick 2759316Smckusick char * 2769316Smckusick setstate( arg_state ) 2779316Smckusick 2789316Smckusick char *arg_state; 2799316Smckusick { 2809316Smckusick register long *new_state = (long *)arg_state; 2819316Smckusick register int type = new_state[0]%MAX_TYPES; 2829316Smckusick register int rear = new_state[0]/MAX_TYPES; 2839316Smckusick char *ostate = (char *)( &state[ -1 ] ); 2849316Smckusick 2859316Smckusick if( rand_type == TYPE_0 ) state[ -1 ] = rand_type; 2869316Smckusick else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type; 2879316Smckusick switch( type ) { 2889316Smckusick case TYPE_0: 2899316Smckusick case TYPE_1: 2909316Smckusick case TYPE_2: 2919316Smckusick case TYPE_3: 2929316Smckusick case TYPE_4: 2939316Smckusick rand_type = type; 2949316Smckusick rand_deg = degrees[ type ]; 2959316Smckusick rand_sep = seps[ type ]; 2969316Smckusick break; 2979316Smckusick 2989316Smckusick default: 2999316Smckusick fprintf( stderr, "setstate: state info has been munged; not changed.\n" ); 3009316Smckusick } 3019316Smckusick state = &new_state[ 1 ]; 3029316Smckusick if( rand_type != TYPE_0 ) { 3039316Smckusick rptr = &state[ rear ]; 3049316Smckusick fptr = &state[ (rear + rand_sep)%rand_deg ]; 3059316Smckusick } 3069316Smckusick end_ptr = &state[ rand_deg ]; /* set end_ptr too */ 3079316Smckusick return( ostate ); 3089316Smckusick } 3099316Smckusick 3109316Smckusick 3119316Smckusick 3129316Smckusick /* 3139316Smckusick * random: 3149316Smckusick * If we are using the trivial TYPE_0 R.N.G., just do the old linear 3159316Smckusick * congruential bit. Otherwise, we do our fancy trinomial stuff, which is the 3169316Smckusick * same in all ther other cases due to all the global variables that have been 3179316Smckusick * set up. The basic operation is to add the number at the rear pointer into 3189316Smckusick * the one at the front pointer. Then both pointers are advanced to the next 3199316Smckusick * location cyclically in the table. The value returned is the sum generated, 3209316Smckusick * reduced to 31 bits by throwing away the "least random" low bit. 3219316Smckusick * Note: the code takes advantage of the fact that both the front and 3229316Smckusick * rear pointers can't wrap on the same call by not testing the rear 3239316Smckusick * pointer if the front one has wrapped. 3249316Smckusick * Returns a 31-bit random number. 3259316Smckusick */ 3269316Smckusick 3279316Smckusick long 3289316Smckusick random() 3299316Smckusick { 3309316Smckusick long i; 3319316Smckusick 3329316Smckusick if( rand_type == TYPE_0 ) { 3339316Smckusick i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff; 3349316Smckusick } 3359316Smckusick else { 3369316Smckusick *fptr += *rptr; 3379316Smckusick i = (*fptr >> 1)&0x7fffffff; /* chucking least random bit */ 3389316Smckusick if( ++fptr >= end_ptr ) { 3399316Smckusick fptr = state; 3409316Smckusick ++rptr; 3419316Smckusick } 3429316Smckusick else { 3439316Smckusick if( ++rptr >= end_ptr ) rptr = state; 3449316Smckusick } 3459316Smckusick } 3469316Smckusick return( i ); 3479316Smckusick } 3489316Smckusick 349