/* * Basic support for random number distributions. * Discrete event simulations require reproducible random * numbers. Using drand48_r/srand48_r, this header library * implements uniform and an exponential distribution. * * @author gback, Spring '24 */ #include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" /* uniformly dist. pseudo random floating point nrs over [0.0, 1.0) */ struct rnd { struct drand48_data state; }; static void rnd_init(struct rnd *r, long seedval) { srand48_r(seedval, &r->state); } static double rnd_fdraw(struct rnd *r) { double result; drand48_r(&r->state, &result); return result; } /* uniformly dist. pseudo random integers over [low, high] */ struct urnd { struct rnd base; int low; int high; double range; }; static void urnd_init(struct urnd *r, int low, int high, long seedval) { rnd_init(&r->base, seedval); r->low = low; r->high = high; r->range = (double)(high-low+1); } /* draw from [low, high] */ static int urnd_draw(struct urnd *r) { return r->low+(int)(r->range*rnd_fdraw(&r->base)); } /* exponentially dist. pseudo random nrs (float or int) */ struct ernd { struct rnd base; double lambda; /* mean */ }; static void ernd_init(struct ernd *r, double lambda, long seedval) { rnd_init(&r->base, seedval); r->lambda = lambda; } static double ernd_fdraw(struct ernd *r) /* draw a double */ { return (double)(-log((double)(rnd_fdraw(&r->base)))*r->lambda); } static int ernd_draw(struct ernd *r) /* draw an int */ { return (int)round(ernd_fdraw(r)); } #pragma GCC diagnostic pop