 Algorithmique Numérique Distribuée Public GIT Repository
2 #include "surf/random_mgr.h"
3 #include "xbt/sysdep.h"
5 #ifdef WIN32
6 static double drand48(void)
7 {
8    THROW_UNIMPLEMENTED;
9    return -1;
10 }
12 static double rand_r(unsigned int* seed)
13 {
14         THROW_UNIMPLEMENTED;
15    return -1;
16 }
18 #endif
20 static double custom_random(Generator generator, long int *seed){
21    switch(generator) {
22    case DRAND48:
23      return drand48();
24    case RAND:
25      return (double)rand_r((unsigned int*)seed)/RAND_MAX;
26    default: return drand48();
27    }
28 }
30 /* Generate numbers between min and max with a given mean and standard deviation */
31 double random_generate(random_data_t random){
32   double x1, x2, w, y;
34   if (random == NULL) return 0.0f;
36   do {
37     /* Apply the polar form of the Box-Muller Transform to map the two uniform random numbers to a pair of numbers from a normal distribution.
38        It is good for speed because it does not call math functions many times. Another way would be to simply:
39          y1 = sqrt( - 2 * log(x1) ) * cos( 2 * pi * x2 )
40     */
41     do {
42       x1 = 2.0 * custom_random(random->generator,&(random->seed)) - 1.0;
43       x2 = 2.0 * custom_random(random->generator,&(random->seed)) - 1.0;
44       w = x1 * x1 + x2 * x2;
45     } while ( w >= 1.0 );
47     w = sqrt( (-2.0 * log( w ) ) / w );
48     y = x1 * w;
50     /* Multiply the Box-Muller value by the standard deviation and add the mean */
51     y = y * random->stdDeviation + random->mean;
52   } while (!(random->min <= y && y <= random->max));
54   return y;
55 }
57 random_data_t random_new(Generator generator, long int seed,
58                          double min, double max, double mean,
59                          double stdDeviation){
60   random_data_t random = xbt_new0(s_random_data_t, 1);
61   random->generator = generator;
62   random->seed = seed;
63   random->min = min;
64   random->max = max;
65   random->mean = mean;
66   random->stdDeviation = stdDeviation;
67   return random;
68 }