Example #1
0
long ignuin(lua_RNG *o,long low,long high)
/*
**********************************************************************
               GeNerate Uniform INteger
                              Function
     Generates an integer uniformly distributed between LOW and HIGH.
                              Arguments
     low --> Low bound (inclusive) on integer value to be generated
     high --> High bound (inclusive) on integer value to be generated
                              Note
     If (HIGH-LOW) > maxnum prints error message on * unit and
     stops the program.
**********************************************************************
     IGNLGI generates integers between 1 and 2147483648
     MAXNUM is 1 less than maximum generable value
*/
{
#define maxnum 2147483647L
static unsigned long ignuin,ign,maxnow,range,ranp1;

    if(!(low > high)) goto S10;
    fputs(" low > high in ignuin - ABORT",stderr);
    exit(1);

S10:
    range = high-low;
    if(!(range > maxnum)) goto S20;
    fputs(" high - low too large in ignuin - ABORT",stderr);
    exit(1);

S20:
    if(!(low == high)) goto S30;
    ignuin = low;
    return ignuin;

S30:
/*
     Number to be generated should be in range 0..RANGE
     Set MAXNOW so that the number of integers in 0..MAXNOW is an
     integral multiple of the number in 0..RANGE
*/
    ranp1 = range+1;
    maxnow = maxnum/ranp1*ranp1;
S40:
    ign = ignlgi(o);
    if(!(ign <= maxnow)) goto S50;
    ignuin = low+ign%ranp1;
    return ignuin;
S50:
    goto S40;
#undef maxnum
#undef err1
#undef err2
}
Example #2
0
/*--------------------------------------------------------------------------*/
double C2F(ignuin)(double *a, double *b)
{
    /*  random deviate from Ui[a,b]
    *  it is assumed that : (i)  a and b are integers (stored in double)
    *                       (ii) b-a+1 <= RngMaxInt[current_gen]
    *  (these verif are done at the calling level)
    *
    *  We use the classic method with a minor difference : to choose
    *  uniformly an int in [a,b] (ie d=b-a+1 numbers) with a generator
    *  which provides uniformly integers in [0,RngMaxInt] (ie m=RngMaxInt+1
    *  numbers) we do the Euclidian division :
    *                                           m = q d + r,   r in [0,d-1]
    *
    *  and accept only numbers l in [0, qd-1], then the output is k = a + (l mod d)
    *  (ie numbers falling in [qd , RngMaxInt] are rejected).
    *  The problem is that RngMaxInt is 2^32-1 for mt and kiss so that RngMaxInt+1 = 0
    *  with the 32 bits unsigned int arithmetic. So in place of rejected r
    *  numbers we reject r+1 by using RngMaxInt in place of m. The constraint is
    *  then that (b-a+1) <= RngMaxInt and if we doesn't want to deal we each generator
    *  we take (b-a+1) <= Min RngMaxInt =  2147483561 (clcg2)
    */

    // all the generators provided integers in [0, RngMaxInt] :
    unsigned long RngMaxInt[NbGenInScilab] =
    {
        4294967295ul,  // mt
        4294967295ul,  // kiss
        2147483646ul,  // clcg4
        2147483561ul,  // clcg2
        2147483647ul,  // urand
        4294967295ul
    }; // fsultra

    int current_gen = ConfigVariable::getCurrentBaseGen();

    unsigned long k, d = (unsigned long)((*b - *a) + 1), qd;

    if (d == 1)
    {
        return (*a);
    }

    qd = RngMaxInt[current_gen] - RngMaxInt[current_gen] % d;

    do
    {
        k = (unsigned long)ignlgi();
    }
    while (k >= qd);

    return (*a + (double)(k % d));
}