Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}