@@ -25,6 +25,7 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "igt_core.h"
#include "igt_stats.h"
@@ -132,6 +133,73 @@ void igt_stats_init_with_size(igt_stats_t *stats, unsigned int capacity)
stats->max = 0;
}
+/* https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform */
+static double rand_normal(double mean, double stddev)
+{
+ static double n2 = 0.0;
+ static bool n2_cached = 0;
+ double d, n1;
+
+ if (!n2_cached) {
+ double x, y, r;
+
+ do {
+ x = 2.0 * rand() / RAND_MAX - 1;
+ y = 2.0 * rand() / RAND_MAX - 1;
+
+ r = x * x + y * y;
+ } while (r == 0.0 || r > 1.0);
+
+ d = sqrt(-2.0 * log(r) / r);
+ n1 = x * d;
+ n2 = y * d;
+
+ n2_cached = 1;
+ return n1 * stddev + mean;
+ } else {
+ n2_cached = 0;
+ return n2 * stddev + mean;
+ }
+}
+
+static double *
+igt_vector_normal(double mean, double sigma, unsigned int n_values)
+{
+ double *v;
+ unsigned int i;
+
+ v = malloc(n_values * sizeof(double));
+ srand(time(NULL));
+ for (i = 0; i < n_values; i++)
+ v[i] = rand_normal(mean, sigma);
+
+ return v;
+}
+
+/**
+ * igt_stats_init_normal:
+ * @stats: An #igt_stats_t instance
+ * @mean: Mean of the distribution
+ * @std_deviation: Standard deviation of the distribution
+ * @n_values: Number of values to generate
+ *
+ * Generates @n_values numbers following a normal distribution defined by
+ * (@mean, @std_deviation).
+ */
+void igt_stats_init_normal(igt_stats_t *stats,
+ double mean, double std_deviation,
+ unsigned int n_values)
+{
+ double *v;
+ unsigned int i;
+
+ v = igt_vector_normal(mean, std_deviation, n_values);
+ igt_stats_init_with_size(stats, n_values);
+ for (i = 0; i < n_values; i++)
+ igt_stats_push(stats, v[i]);
+ free(v);
+}
+
/**
* igt_stats_fini:
* @stats: An #igt_stats_t instance
@@ -49,6 +49,9 @@ typedef struct {
void igt_stats_init(igt_stats_t *stats);
void igt_stats_init_with_size(igt_stats_t *stats, unsigned int capacity);
+void igt_stats_init_normal(igt_stats_t *stats,
+ double mean, double std_deviation,
+ unsigned int n_values);
void igt_stats_fini(igt_stats_t *stats);
bool igt_stats_is_population(igt_stats_t *stats);
void igt_stats_set_population(igt_stats_t *stats, bool full_population);
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> --- lib/igt_stats.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/igt_stats.h | 3 +++ 2 files changed, 71 insertions(+)