diff --git a/server/include/utils.h b/server/include/utils.h index e91bfeab9..9148443a9 100644 --- a/server/include/utils.h +++ b/server/include/utils.h @@ -81,6 +81,17 @@ struct timespec; */ extern pthread_t _mtid; +/** Normal random variate generator using the Box-Muller method + * + * @param m Mean + * @param s Standard deviation + * @return Normal variate random variable (Gaussian) + */ +double box_muller(float m, float s); + +/** Double precission uniform random variable */ +double randf(); + /** Safely append a format string to an existing string. * * This function is similar to strlcat() from BSD. diff --git a/server/src/utils.c b/server/src/utils.c index 3d49990b9..3b1b0a950 100644 --- a/server/src/utils.c +++ b/server/src/utils.c @@ -27,6 +27,38 @@ pthread_t _mtid; +double box_muller(float m, float s) +{ + double x1, x2, y1; + static double y2; + static int use_last = 0; + + if (use_last) { /* use value from previous call */ + y1 = y2; + use_last = 0; + } + else { + double w; + do { + x1 = 2.0 * randf() - 1.0; + x2 = 2.0 * randf() - 1.0; + w = x1*x1 + x2*x2; + } while (w >= 1.0); + + w = sqrt(-2.0 * log(w) / w); + y1 = x1 * w; + y2 = x2 * w; + use_last = 1; + } + + return m + y1 * s; +} + +double randf() +{ + return (double) random() / RAND_MAX; +} + void die() { if (pthread_equal(_mtid, pthread_self()))