[gnumeric] sstest: add framework for testing random number generators.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] sstest: add framework for testing random number generators.
- Date: Fri, 3 Feb 2012 19:31:29 +0000 (UTC)
commit d0e184d0dcaf83228c80ab4f482c59825857e561
Author: Morten Welinder <terra gnome org>
Date: Fri Feb 3 14:31:06 2012 -0500
sstest: add framework for testing random number generators.
ChangeLog | 3 +
src/sstest.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 210 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 33681f1..0b84c24 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2012-02-03 Morten Welinder <terra gnome org>
+ * src/sstest.c (main): Add framework for testing random number
+ functions.
+
* src/wbc-gtk-actions.c (permanent_actions): Get rid of UndoLast
and RedoLast.
diff --git a/src/sstest.c b/src/sstest.c
index 3431d09..d6a16a0 100644
--- a/src/sstest.c
+++ b/src/sstest.c
@@ -411,6 +411,212 @@ test_nonascii_numbers (void)
/*-------------------------------------------------------------------------- */
+static void
+define_cell (Sheet *sheet, int c, int r, const char *expr)
+{
+ GnmCell *cell = sheet_cell_fetch (sheet, c, r);
+ sheet_cell_set_text (cell, expr, NULL);
+}
+
+static gnm_float *
+test_random_1 (int N, const char *expr,
+ gnm_float *mean, gnm_float *var,
+ gnm_float *skew, gnm_float *kurt)
+{
+ Workbook *wb = workbook_new ();
+ Sheet *sheet = workbook_sheet_add
+ (wb, -1, GNM_DEFAULT_COLS, GNM_DEFAULT_ROWS);
+ gnm_float *res = g_new (gnm_float, N);
+ int i;
+ char *s;
+
+ g_printerr ("Testing %s\n", expr);
+
+ for (i = 0; i < N; i++)
+ define_cell (sheet, 0, i, expr);
+
+ s = g_strdup_printf ("=average(a1:a%d)", N);
+ define_cell (sheet, 1, 0, s);
+ g_free (s);
+
+ s = g_strdup_printf ("=var(a1:a%d)", N);
+ define_cell (sheet, 1, 1, s);
+ g_free (s);
+
+ s = g_strdup_printf ("=skew(a1:a%d)", N);
+ define_cell (sheet, 1, 2, s);
+ g_free (s);
+
+ s = g_strdup_printf ("=kurt(a1:a%d)", N);
+ define_cell (sheet, 1, 3, s);
+ g_free (s);
+
+ workbook_recalc (sheet->workbook);
+ for (i = 0; i < N; i++)
+ res[i] = value_get_as_float (sheet_cell_get (sheet, 0, i)->value);
+ *mean = value_get_as_float (sheet_cell_get (sheet, 1, 0)->value);
+ g_printerr ("Mean: %.10" GNM_FORMAT_g "\n", *mean);
+
+ *var = value_get_as_float (sheet_cell_get (sheet, 1, 1)->value);
+ g_printerr ("Var: %.10" GNM_FORMAT_g "\n", *var);
+
+ *skew = value_get_as_float (sheet_cell_get (sheet, 1, 2)->value);
+ g_printerr ("Skew: %.10" GNM_FORMAT_g "\n", *skew);
+
+ *kurt = value_get_as_float (sheet_cell_get (sheet, 1, 3)->value);
+ g_printerr ("Kurt: %.10" GNM_FORMAT_g "\n", *kurt);
+
+ g_object_unref (wb);
+ return res;
+}
+
+static void
+test_random_rand (int N)
+{
+ gnm_float mean, var, skew, kurt;
+ gnm_float *vals;
+ int i;
+ gboolean ok;
+ gnm_float T;
+
+ vals = test_random_1 (N, "=RAND()", &mean, &var, &skew, &kurt);
+ ok = TRUE;
+ for (i = 0; i < N; i++) {
+ gnm_float r = vals[i];
+ if (!(r >= 0 && r <= 1)) {
+ g_printerr ("Range failure.\n");
+ ok = FALSE;
+ break;
+ }
+ }
+ g_free (vals);
+
+ T = 0.5;
+ if (gnm_abs (mean - T) > 0.01) {
+ g_printerr ("Mean failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ T = 1.0 / 12;
+ if (gnm_abs (var - T) > 0.01) {
+ g_printerr ("Var failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ T = 0;
+ if (gnm_abs (skew - T) > 0.05) {
+ g_printerr ("Skew failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ T = -6.0 / 5;
+ if (gnm_abs (kurt - T) > 0.05) {
+ g_printerr ("Kurt failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ if (ok)
+ g_printerr ("OK\n");
+ g_printerr ("\n");
+}
+
+static void
+test_random_randbernoulli (int N)
+{
+ gnm_float mean, var, skew, kurt;
+ gnm_float *vals;
+ int i;
+ gboolean ok;
+ gnm_float p = 0.3;
+ gnm_float q = 1 - p;
+ char *expr;
+ gnm_float T;
+
+ expr = g_strdup_printf ("=RANDBERNOULLI(%.10" GNM_FORMAT_g ")", p);
+ vals = test_random_1 (N, expr, &mean, &var, &skew, &kurt);
+ g_free (expr);
+
+ ok = TRUE;
+ for (i = 0; i < N; i++) {
+ gnm_float r = vals[i];
+ if (!(r == 0 || r == 1)) {
+ g_printerr ("Range failure.\n");
+ ok = FALSE;
+ break;
+ }
+ }
+ g_free (vals);
+
+ T = p;
+ if (gnm_abs (mean - p) > 0.01) {
+ g_printerr ("Mean failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ T = p * (1 - p);
+ if (gnm_abs (var - T) > 0.01) {
+ g_printerr ("Var failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ T = (q - p) / gnm_sqrt (p * q);
+ if (gnm_abs (skew - T) > 0.05) {
+ g_printerr ("Skew failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ T = (1 - 6 * p * q) / (p * q);
+ if (gnm_abs (kurt - T) > 0.10) {
+ g_printerr ("Kurt failure [%.10" GNM_FORMAT_g "]\n", T);
+ ok = FALSE;
+ }
+ if (ok)
+ g_printerr ("OK\n");
+ g_printerr ("\n");
+}
+
+static void
+test_random (void)
+{
+ const char *test_name = "test_random";
+ const int N = 10000;
+
+ mark_test_start (test_name);
+ test_random_rand (N);
+ test_random_randbernoulli (N);
+#if 0
+ test_random_randbernoulli (N);
+ test_random_randbeta (N);
+ test_random_randbetween (N);
+ test_random_randbinom (N);
+ test_random_randcauchy (N);
+ test_random_randchisq (N);
+ test_random_randdiscrete (N);
+ test_random_randexp (N);
+ test_random_randexppow (N);
+ test_random_randfdist (N);
+ test_random_randgamma (N);
+ test_random_randnormtail (N);
+ test_random_randgeom (N);
+ test_random_randgumbel (N);
+ test_random_randhyperg (N);
+ test_random_randlandau (N);
+ test_random_randlaplace (N);
+ test_random_randlevy (N);
+ test_random_randlog (N);
+ test_random_randlogistic (N);
+ test_random_randlognorm (N);
+ test_random_randnegbinom (N);
+ test_random_randnorm (N);
+ test_random_randpareto (N);
+ test_random_randpoisson (N);
+ test_random_randrayleigh (N);
+ test_random_randrayleightail (N);
+ test_random_randsnorm (N);
+ test_random_randstdist (N);
+ test_random_randtdist (N);
+ test_random_randuniform (N);
+ test_random_randweibull (N);
+#endif
+
+ mark_test_end (test_name);
+}
+
+/*-------------------------------------------------------------------------- */
+
#define MAYBE_DO(name) if (strcmp (testname, "all") != 0 && strcmp (testname, (name)) != 0) { } else
int
@@ -463,6 +669,7 @@ main (int argc, char const **argv)
MAYBE_DO ("test_insdel_rowcol_names") test_insdel_rowcol_names ();
MAYBE_DO ("test_func_help") test_func_help ();
MAYBE_DO ("test_nonascii_numbers") test_nonascii_numbers ();
+ MAYBE_DO ("test_random") test_random ();
/* ---------------------------------------- */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]