void get_state ( int *cg1, int *cg2 ) /******************************************************************************/ /* Purpose: GET_STATE returns the state of the current generator. Licensing: This code is distributed under the GNU LGPL license. Modified: 30 March 2013 Author: Original Pascal version by Pierre L'Ecuyer, Serge Cote. C version by John Burkardt. Reference: Pierre LEcuyer, Serge Cote, Implementing a Random Number Package with Splitting Facilities, ACM Transactions on Mathematical Software, Volume 17, Number 1, March 1991, pages 98-111. Parameters: Output, int *CG1, *CG2, the CG values for the current generator. */ { int g; /* Check whether the package must be initialized. */ if ( ! initialized_get ( ) ) { printf ( "\n" ); printf ( "GET_STATE - Note:\n" ); printf ( " Initializing RNGLIB package.\n" ); initialize ( ); } /* Get the current generator index. */ g = cgn_get ( ); /* Retrieve the seed values for this generator. */ cg_get ( g, cg1, cg2 ); return; }
void advance_state(int k) /******************************************************************************/ /* Purpose: ADVANCE_STATE advances the state of the current generator. Discussion: This procedure advances the state of the current generator by 2^K values and resets the initial seed to that value. Licensing: This code is distributed under the GNU LGPL license. Modified: 30 March 2013 Author: Original Pascal version by Pierre L'Ecuyer, Serge Cote. C version by John Burkardt. Reference: Pierre LEcuyer, Serge Cote, Implementing a Random Number Package with Splitting Facilities, ACM Transactions on Mathematical Software, Volume 17, Number 1, March 1991, pages 98-111. Parameters: Input, int K, indicates that the generator is to be advanced by 2^K values. 0 <= K. */ { const int a1 = 40014; const int a2 = 40692; int b1; int b2; int cg1; int cg2; int g; int i; const int m1 = 2147483563; const int m2 = 2147483399; if (k < 0) { fprintf(stderr, "\n"); fprintf(stderr, "ADVANCE_STATE - Fatal error!\n"); fprintf(stderr, " Input exponent K is out of bounds.\n"); exit(1); } /* Check whether the package must be initialized. */ if (!initialized_get()) { initialize(); } /* Get the current generator index. */ g = cgn_get(); b1 = a1; b2 = a2; for (i = 1; i <= k; k++) { b1 = multmod(b1, b1, m1); b2 = multmod(b2, b2, m2); } cg_get(g, &cg1, &cg2); cg1 = multmod(b1, cg1, m1); cg2 = multmod(b2, cg2, m2); cg_set(g, cg1, cg2); return; }
int i4_uni() /******************************************************************************/ /* Purpose: I4_UNI generates a random positive integer. Discussion: This procedure returns a random integer following a uniform distribution over (1, 2147483562) using the current generator. The original name of this function was "random()", but this conflicts with a standard library function name in C. Licensing: This code is distributed under the GNU LGPL license. Modified: 05 August 2013 Author: Original Pascal version by Pierre L'Ecuyer, Serge Cote. C version by John Burkardt. Reference: Pierre LEcuyer, Serge Cote, Implementing a Random Number Package with Splitting Facilities, ACM Transactions on Mathematical Software, Volume 17, Number 1, March 1991, pages 98-111. Parameters: Output, int I4_UNI, the random integer. */ { const int a1 = 40014; const int a2 = 40692; int cg1; int cg2; int g; int k; const int m1 = 2147483563; const int m2 = 2147483399; int value; int z; /* Check whether the package must be initialized. */ if (!initialized_get()) { initialize(); } /* Get the current generator index. */ g = cgn_get(); /* Retrieve the current seeds. */ cg_get(g, &cg1, &cg2); /* Update the seeds. */ k = cg1 / 53668; cg1 = a1 * (cg1 - k * 53668) - k * 12211; if (cg1 < 0) { cg1 = cg1 + m1; } k = cg2 / 52774; cg2 = a2 * (cg2 - k * 52774) - k * 3791; if (cg2 < 0) { cg2 = cg2 + m2; } /* Store the updated seeds. */ cg_set(g, cg1, cg2); /* Form the random integer. */ z = cg1 - cg2; if (z < 1) { z = z + m1 - 1; } /* If the generator is antithetic, reflect the value. */ value = antithetic_get(); if (value) { z = m1 - z; } return z; }