Exemple #1
0
double r8_uni_01()

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

    R8_UNI_01 returns a uniform random double in [0,1].

  Discussion:

    This procedure returns a random floating point number from a uniform 
    distribution over (0,1), not including the endpoint values, using the
    current random number generator.

  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, double R8_UNI_01, a uniform random value in [0,1].
*/
{
    int i;
    double value;
/*
  Check whether the package must be initialized.
*/
    if (!initialized_get()) {
        initialize();
    }
/*
  Get a random integer.
*/
    i = i4_uni();
/*
  Scale it to [0,1].
*/
    value = (double) (i) * 4.656613057E-10;

    return value;
}
Exemple #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;
}
Exemple #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;
}
Exemple #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;
}
Exemple #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;
}
Exemple #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;
}
Exemple #7
0
void set_initial_seed(int ig1, int ig2)

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

    SET_INITIAL_SEED resets the initial seed and state for all generators.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    28 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 IG1, IG2, the initial seed values 
    for the first generator.
    1 <= IG1 < 2147483563
    1 <= IG2 < 2147483399
*/
{
    const int a1_vw = 2082007225;
    const int a2_vw = 784306273;
    int g;
    const int g_max = 32;
    //int i;
    const int m1 = 2147483563;
    const int m2 = 2147483399;
    int t;

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

    if (ig2 < 1 || m2 <= ig2) {
        fprintf(stderr, "\n");
        fprintf(stderr, "SET_INITIAL_SEED - Fatal error!\n");
        fprintf(stderr, "  Input parameter IG2 out of bounds.\n");
        exit(1);
    }
/*
  Because INITIALIZE calls SET_INITIAL_SEED, it's not easy to correct
  the error that arises if SET_INITIAL_SEED is called before INITIALIZE.
  So don't bother trying.
*/
    if (!initialized_get()) {
        printf("\n");
        printf("SET_INITIAL_SEED - Fatal error!\n");
        printf("  The RNGLIB package has not been initialized.\n");
        exit(1);
    }
/*
  Set the initial seed, then initialize the first generator.
*/
    g = 0;
    cgn_set(g);

    ig_set(g, ig1, ig2);

    t = 0;
    init_generator(t);
/*
  Now do similar operations for the other generators.
*/
    for (g = 1; g < g_max; g++) {
        cgn_set(g);
        ig1 = multmod(a1_vw, ig1, m1);
        ig2 = multmod(a2_vw, ig2, m2);
        ig_set(g, ig1, ig2);
        init_generator(t);
    }
/*
  Now choose the first generator.
*/
    g = 0;
    cgn_set(g);

    return;
}