Example #1
0
void antithetic_memory ( int i, int *value )

/******************************************************************************/
/*
  Purpose:

    ANTITHETIC_MEMORY stores the antithetic value for all generators.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    01 April 2013

  Author:

    John Burkardt

  Parameters:

    Input, int I, the desired action.
    -1, get a value.
    0, initialize all values.
    1, set a value.

    Input/output, int *VALUE.  For I = -1, VALUE is an output
    quantity.  If I = +1, then VALUE is an input quantity.
*/
{
# define G_MAX 32

  static int a_save[G_MAX];
  int g;
  const int g_max = 32;
  int j;

  if ( i < 0 )
  {
    g = cgn_get ( );
    *value = a_save[g];
  }
  else if ( i == 0 )
  {
    for ( j = 0; j < g_max; j++ )
    {
      a_save[j] = 0;
    }
  }
  else if ( 0 < i )
  {
    g = cgn_get ( );
    a_save[g] = *value;
  }

  return;
# undef G_MAX
}
Example #2
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 #3
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 #4
0
void init_generator(int t)

/******************************************************************************/
/*
  Purpose:

    INIT_GENERATOR sets the state of generator G to initial, last or new seed.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    01 April 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 T, the seed type:
    0, use the seed chosen at initialization time.
    1, use the last seed.
    2, use a new seed set 2^30 values away.
*/
{
    const int a1_w = 1033780774;
    const int a2_w = 1494757890;
    int cg1;
    int cg2;
    int g;
    int ig1;
    int ig2;
    int lg1;
    int lg2;
    const int m1 = 2147483563;
    const int m2 = 2147483399;
/*
  Check whether the package must be initialized.
*/
    if (!initialized_get()) {
        initialize();
    }
/*
  Get the current generator index.
*/
    g = cgn_get();
/*
  0: restore the initial seed.
*/
    if (t == 0) {
        ig_get(g, &ig1, &ig2);
        lg1 = ig1;
        lg2 = ig2;
        lg_set(g, lg1, lg2);
    }
/*
  1: restore the last seed.
*/
    else if (t == 1) {
        lg_get(g, &lg1, &lg2);
    }
/*
  2: advance to a new seed.
*/
    else if (t == 2) {
        lg_get(g, &lg1, &lg2);
        lg1 = multmod(a1_w, lg1, m1);
        lg2 = multmod(a2_w, lg2, m2);
        lg_set(g, lg1, lg2);
    } else {
        fprintf(stderr, "\n");
        fprintf(stderr, "INIT_GENERATOR - Fatal error!\n");
        fprintf(stderr, "  Input parameter T out of bounds.\n");
        exit(1);
    }
/*
  Store the new seed.
*/
    cg1 = lg1;
    cg2 = lg2;
    cg_set(g, cg1, cg2);

    return;
}
Example #5
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;
}
Example #6
0
void set_seed(int cg1, int cg2)

/******************************************************************************/
/*
  Purpose:

    SET_SEED resets the initial seed and the state of generator G.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    01 April 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 CG1, CG2, the CG values for generator G.
    1 <= CG1 < 2147483563
    1 <= CG2 < 2147483399
*/
{
    int g;
    //int i;
    const int m1 = 2147483563;
    const int m2 = 2147483399;
    int t;

    if (cg1 < 1 || m1 <= cg1) {
        fprintf(stderr, "\n");
        fprintf(stderr, "SET_SEED - Fatal error!\n");
        fprintf(stderr, "  Input parameter CG1 out of bounds.\n");
        exit(1);
    }

    if (cg2 < 1 || m2 <= cg2) {
        fprintf(stderr, "\n");
        fprintf(stderr, "SET_SEED - Fatal error!\n");
        fprintf(stderr, "  Input parameter CG2 out of bounds.\n");
        exit(1);
    }
/*
  Check whether the package must be initialized.
*/
    if (!initialized_get()) {
        initialize();
    }
/*
  Retrieve the current generator index.
*/
    g = cgn_get();
/*
  Set the seeds.
*/
    cg_set(g, cg1, cg2);
/*
  Initialize the generator.
*/
    t = 0;
    init_generator(t);

    return;
}