Signed-off-by: Damien Lespiau <damien.lesp...@intel.com>
---
 lib/igt_stats.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_stats.h |  3 +++
 2 files changed, 71 insertions(+)

diff --git a/lib/igt_stats.c b/lib/igt_stats.c
index 70650ec..37fcc23 100644
--- a/lib/igt_stats.c
+++ b/lib/igt_stats.c
@@ -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
diff --git a/lib/igt_stats.h b/lib/igt_stats.h
index 554ab15..e1757b7 100644
--- a/lib/igt_stats.h
+++ b/lib/igt_stats.h
@@ -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);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to