2 * sstest.c: Test code for Gnumeric
4 * Copyright (C) 2009,2017 Morten Welinder (terra@gnome.org)
6 #include <gnumeric-config.h>
8 #include <libgnumeric.h>
9 #include <goffice/goffice.h>
10 #include <command-context-stderr.h>
11 #include <workbook-view.h>
14 #include <gnm-plugin.h>
15 #include <parse-util.h>
16 #include <expr-name.h>
23 #include <parse-util.h>
24 #include <sheet-object-cell-comment.h>
26 #include <gnm-random.h>
29 #include <rangefunc.h>
30 #include <gnumeric-conf.h>
32 #include <gsf/gsf-input-stdio.h>
33 #include <gsf/gsf-input-textline.h>
34 #include <glib/gstdio.h>
35 #include <glib/gi18n.h>
39 static gboolean sstest_show_version
= FALSE
;
40 static gboolean sstest_fast
= FALSE
;
41 static gchar
*func_def_file
= NULL
;
42 static gchar
*func_state_file
= NULL
;
43 static gchar
*ext_refs_file
= NULL
;
44 static gchar
*samples_file
= NULL
;
46 static GOptionEntry
const sstest_options
[] = {
49 0, G_OPTION_ARG_NONE
, &sstest_fast
,
50 N_("Run fewer iterations"),
56 0, G_OPTION_ARG_FILENAME
, &func_def_file
,
57 N_("Dumps the function definitions"),
63 0, G_OPTION_ARG_FILENAME
, &func_state_file
,
64 N_("Dumps the function definitions"),
70 0, G_OPTION_ARG_FILENAME
, &ext_refs_file
,
71 N_("Dumps web page for function help"),
77 0, G_OPTION_ARG_FILENAME
, &samples_file
,
78 N_("Dumps list of samples in function help"),
84 0, G_OPTION_ARG_NONE
, &sstest_show_version
,
85 N_("Display program version"),
92 /* ------------------------------------------------------------------------- */
94 #define UNICODE_ELLIPSIS "\xe2\x80\xa6"
97 split_at_colon (char const *s
, char **rest
)
99 char *dup
= g_strdup (s
);
100 char *colon
= strchr (dup
, ':');
103 if (rest
) *rest
= colon
+ 1;
105 if (rest
) *rest
= NULL
;
112 dump_externals (GPtrArray
*defs
, FILE *out
)
116 fprintf (out
, "<!--#set var=\"title\" value=\"Gnumeric Web Documentation\" -->");
117 fprintf (out
, "<!--#set var=\"rootdir\" value=\".\" -->");
118 fprintf (out
, "<!--#include virtual=\"header-begin.shtml\" -->");
119 fprintf (out
, "<link rel=\"stylesheet\" href=\"style/index.css\" type=\"text/css\"/>");
120 fprintf (out
, "<!--#include virtual=\"header-end.shtml\" -->");
121 fprintf (out
, "<!--#set var=\"wolfram\" value=\"none\" -->");
122 fprintf (out
, "<!--#set var=\"wiki\" value=\"none\" -->");
123 fprintf (out
, "<!--\n\n-->");
125 for (ui
= 0; ui
< defs
->len
; ui
++) {
126 GnmFunc
*fd
= g_ptr_array_index (defs
, ui
);
127 gboolean any
= FALSE
;
129 GnmFuncHelp
const *help
= gnm_func_get_help (fd
, &n
);
131 for (j
= 0; j
< n
; j
++) {
132 const char *s
= gnm_func_gettext (fd
, help
[j
].text
);
134 switch (help
[j
].type
) {
135 case GNM_FUNC_HELP_EXTREF
:
138 fprintf (out
, "<!--#if expr=\"${QUERY_STRING} = %s\" -->", fd
->name
);
141 if (strncmp (s
, "wolfram:", 8) == 0) {
142 fprintf (out
, "<!--#set var=\"wolfram\" value=\"%s\" -->", s
+ 8);
144 if (strncmp (s
, "wiki:", 5) == 0) {
146 lang
= split_at_colon (s
+ 5, &page
);
147 fprintf (out
, "<!--#set var=\"wiki_lang\" value=\"%s\" -->", lang
);
148 fprintf (out
, "<!--#set var=\"wiki\" value=\"%s\" -->", page
);
158 fprintf (out
, "<!--#endif\n\n-->");
161 fprintf (out
, "<div class=\"floatflush\">\n");
162 fprintf (out
, "<h1>Online Documentation for \"<!--#echo var=\"QUERY_STRING\" -->\"</h1>\n");
163 fprintf (out
, "<p>When last checked, these sources provided useful information about\n");
164 fprintf (out
, "this function. However, since the links are not controlled by the\n");
165 fprintf (out
, "Gnumeric Team, we cannot guarantee that the links still work. If\n");
166 fprintf (out
, "you find that they do not work, please drop us a line.</p>\n");
167 fprintf (out
, "<ul>");
168 fprintf (out
, "<!--#if expr=\"${wolfram} != none\"-->");
169 fprintf (out
, "<li><a href=\"http://mathworld.wolfram.com/<!--#echo var=\"wolfram\" -->\">Wolfram Mathworld\nentry</a>.</li><!--#endif-->");
170 fprintf (out
, "<!--#if expr=\"${wiki} != none\"--><li><a href=\"http://<!--#echo var=\"wiki_lang\" -->.wikipedia.org/wiki/<!--#echo var=\"wiki\" -->\">Wikipedia\nentry</a>.</li><!--#endif-->");
171 fprintf (out
, "<li><a href=\"http://www.google.com/#q=<!--#echo var=\"QUERY_STRING\" -->\">Google Search</a>.</li>");
172 fprintf (out
, "</ul>");
173 fprintf (out
, "</div>\n");
175 fprintf (out
, "<!--#include virtual=\"footer.shtml\" -->\n");
179 csv_quoted_print (FILE *out
, const char *s
)
189 int len
= g_utf8_skip
[(unsigned char)*s
];
190 fprintf (out
, "%-.*s", len
, s
);
198 dump_samples (GPtrArray
*defs
, FILE *out
)
201 GnmFuncGroup
*last_group
= NULL
;
203 for (ui
= 0; ui
< defs
->len
; ui
++) {
204 GnmFunc
*fd
= g_ptr_array_index (defs
, ui
);
206 const char *last
= NULL
;
207 gboolean has_sample
= FALSE
;
208 GnmFuncHelp
const *help
= gnm_func_get_help (fd
, &n
);
210 if (last_group
!= gnm_func_get_function_group (fd
)) {
211 last_group
= gnm_func_get_function_group (fd
);
212 csv_quoted_print (out
, last_group
->display_name
->str
);
216 for (j
= 0; j
< n
; j
++) {
217 const char *s
= help
[j
].text
;
219 if (help
[j
].type
!= GNM_FUNC_HELP_EXAMPLES
)
225 * Some of the random numbers functions have duplicate
226 * samples. We don't want the duplicates here.
228 if (s
[0] != '=' || (last
&& strcmp (last
, s
) == 0))
233 csv_quoted_print (out
, fd
->name
);
237 csv_quoted_print (out
, s
);
242 g_printerr ("No samples for %s\n", fd
->name
);
247 func_def_cmp (gconstpointer a
, gconstpointer b
)
249 GnmFunc
*fda
= *(GnmFunc
**)a
;
250 GnmFunc
*fdb
= *(GnmFunc
**)b
;
251 GnmFuncGroup
*ga
, *gb
;
253 g_return_val_if_fail (fda
->name
!= NULL
, 0);
254 g_return_val_if_fail (fdb
->name
!= NULL
, 0);
256 ga
= gnm_func_get_function_group (fda
);
257 gb
= gnm_func_get_function_group (fdb
);
260 int res
= go_string_cmp (ga
->display_name
, gb
->display_name
);
265 return g_ascii_strcasecmp (fda
->name
, fdb
->name
);
269 enumerate_functions (gboolean filter
)
271 GPtrArray
*res
= gnm_func_enumerate ();
274 for (ui
= 0; ui
< res
->len
; ui
++) {
275 GnmFunc
*fd
= g_ptr_array_index (res
, ui
);
279 strcmp (fd
->name
, "perl_adder") == 0 ||
280 strcmp (fd
->name
, "perl_date") == 0 ||
281 strcmp (fd
->name
, "perl_sed") == 0 ||
282 strcmp (fd
->name
, "py_capwords") == 0 ||
283 strcmp (fd
->name
, "py_printf") == 0 ||
284 strcmp (fd
->name
, "py_bitand") == 0)) {
285 g_ptr_array_remove_index_fast (res
, ui
);
289 gnm_func_load_if_stub (fd
);
292 g_ptr_array_sort (res
, func_def_cmp
);
298 * function_dump_defs:
302 * A generic utility routine to operate on all funtion defs
303 * in various ways. @dump_type will change/extend as needed
305 * 0 : www.gnumeric.org's function.shtml page
310 * 5 : all sample expressions
313 function_dump_defs (char const *filename
, int dump_type
)
319 GnmFuncGroup
const *group
= NULL
;
321 g_return_if_fail (filename
!= NULL
);
323 if ((output_file
= g_fopen (filename
, "w")) == NULL
){
324 g_printerr (_("Cannot create file %s\n"), filename
);
328 /* TODO : Use the translated names and split by function group. */
329 ordered
= enumerate_functions (TRUE
);
331 if (dump_type
== 4) {
332 dump_externals (ordered
, output_file
);
333 g_ptr_array_free (ordered
, TRUE
);
334 fclose (output_file
);
338 if (dump_type
== 5) {
339 dump_samples (ordered
, output_file
);
340 g_ptr_array_free (ordered
, TRUE
);
341 fclose (output_file
);
345 if (dump_type
== 0) {
347 for (i
= 0; i
< ordered
->len
; i
++) {
348 GnmFunc
*fd
= g_ptr_array_index (ordered
, i
);
349 switch (gnm_func_get_impl_status (fd
)) {
350 case GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
:
357 fprintf (output_file
,
358 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
359 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
360 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
361 "<!-- DEFINE current=Home -->\n"
362 "<!-- MARKER: start-header -->\n"
364 "<title>Gnumeric</title>\n"
365 "<link rel=\"stylesheet\" href=\"style/style.css\" type=\"text/css\" />\n"
366 "<link rel=\"icon\" type=\"image/png\" href=\"logo.png\" />\n"
367 "<style type=\"text/css\"><!--\n"
368 " div.functiongroup {\n"
369 " margin-top: 1em;\n"
370 " margin-bottom: 1em;\n"
372 " table.functiongroup {\n"
373 " border-style: solid;\n"
374 " border-width: 1px;\n"
375 " border-spacing: 0px;\n"
378 " font-weight: bold;\n"
379 " font-size: 14pt;\n"
380 " border-style: solid;\n"
381 " border-width: 1px;\n"
382 " text-align: center;\n"
384 " tr.function td {\n"
385 " border: solid 1px;\n"
387 " td.testing-unknown { background: #ffffff; }\n"
388 " td.testing-nosuite { background: #ff7662; }\n"
389 " td.testing-basic { background: #fff79d; }\n"
390 " td.testing-exhaustive { background: #aef8b5; }\n"
391 " td.testing-devel { background: #ff6c00; }\n"
392 " td.imp-exists { background: #ffffff; }\n"
393 " td.imp-no { background: #ff7662; }\n"
394 " td.imp-subset { background: #fff79d; }\n"
395 " td.imp-complete { background: #aef8b5; }\n"
396 " td.imp-superset { background: #16e49e; }\n"
397 " td.imp-subsetext { background: #59fff2; }\n"
398 " td.imp-devel { background: #ff6c00; }\n"
399 " td.imp-gnumeric { background: #44be18; }\n"
403 "<div id=\"wrap\">\n"
404 " <a href=\"/\"><div id=\"header\">\n"
405 " <h1 id=\"logo-text\"><span>Gnumeric</span></h1>\n"
406 " <p id=\"slogan\">Free, Fast, Accurate — Pick Any Three!</p>\n"
407 " <img id=\"logo\" src=\"gnumeric.png\" alt=\"logo\" class=\"float-right\"/>\n"
410 " <div id=\"nav\">\n"
412 " <li id=\"current\"><a href=\"/\">Home</a></li>\n"
413 " <li><a href=\"development.html\">Development</a></li>\n"
414 " <li><a href=\"contact.html\">Contact</a></li>\n"
418 " <div id=\"content-wrap\">\n"
419 " <!-- MARKER: start-main -->\n"
420 " <div id=\"main\">\n"
421 " <div class=\"generalitem\">\n"
422 " <h2><span class=\"gnumeric-bullet\"></span>Gnumeric Sheet Functions</h2>\n"
423 " <p>Gnumeric currently has %d functions for use in spreadsheets.\n"
424 " %d of these are unique to Gnumeric.</p>\n",
425 ordered
->len
, unique
);
428 for (i
= 0; i
< ordered
->len
; i
++) {
429 GnmFunc
*fd
= g_ptr_array_index (ordered
, i
);
431 // Skip internal-use function
432 if (g_ascii_strcasecmp (fd
->name
, "TABLE") == 0)
435 // Skip demo function
436 if (g_ascii_strcasecmp (fd
->name
, "ATL_LAST") == 0)
439 if (dump_type
== 1) {
441 gboolean first_arg
= TRUE
;
442 GString
*syntax
= g_string_new (NULL
);
443 GString
*arg_desc
= g_string_new (NULL
);
444 GString
*desc
= g_string_new (NULL
);
445 GString
*odf
= g_string_new (NULL
);
446 GString
*excel
= g_string_new (NULL
);
447 GString
*note
= g_string_new (NULL
);
448 GString
*seealso
= g_string_new (NULL
);
450 GnmFuncGroup
*group
= gnm_func_get_function_group (fd
);
452 GnmFuncHelp
const *help
= gnm_func_get_help (fd
, &n
);
454 fprintf (output_file
, "@CATEGORY=%s\n",
455 gnm_func_gettext (fd
, group
->display_name
->str
));
456 for (i
= 0; i
< n
; i
++) {
457 switch (help
[i
].type
) {
458 case GNM_FUNC_HELP_NAME
: {
460 char *name
= split_at_colon (gnm_func_gettext (fd
, help
[i
].text
), &short_desc
);
461 fprintf (output_file
,
464 fprintf (output_file
,
467 g_string_append (syntax
, name
);
468 g_string_append_c (syntax
, '(');
472 case GNM_FUNC_HELP_SEEALSO
:
473 if (seealso
->len
> 0)
474 g_string_append (seealso
, ",");
475 g_string_append (seealso
, gnm_func_gettext (fd
, help
[i
].text
));
477 case GNM_FUNC_HELP_DESCRIPTION
:
479 g_string_append (desc
, "\n");
480 g_string_append (desc
, gnm_func_gettext (fd
, help
[i
].text
));
482 case GNM_FUNC_HELP_NOTE
:
484 g_string_append (note
, " ");
485 g_string_append (note
, gnm_func_gettext (fd
, help
[i
].text
));
487 case GNM_FUNC_HELP_ARG
: {
489 char *name
= split_at_colon (gnm_func_gettext (fd
, help
[i
].text
), &argdesc
);
493 g_string_append_c (syntax
, go_locale_get_arg_sep ());
494 g_string_append (syntax
, name
);
496 g_string_append_printf (arg_desc
,
502 /* FIXME: Optional args? */
505 case GNM_FUNC_HELP_ODF
:
507 g_string_append (odf
, " ");
508 g_string_append (odf
, gnm_func_gettext (fd
, help
[i
].text
));
510 case GNM_FUNC_HELP_EXCEL
:
512 g_string_append (excel
, " ");
513 g_string_append (excel
, gnm_func_gettext (fd
, help
[i
].text
));
516 case GNM_FUNC_HELP_EXTREF
:
518 case GNM_FUNC_HELP_EXAMPLES
:
520 case GNM_FUNC_HELP_END
:
525 gnm_func_count_args (fd
, &min
, &max
);
527 fprintf (output_file
,
528 "@SYNTAX=%s," UNICODE_ELLIPSIS
")\n",
531 fprintf (output_file
, "@SYNTAX=%s)\n",
534 if (arg_desc
->len
> 0)
535 fprintf (output_file
, "@ARGUMENTDESCRIPTION=%s", arg_desc
->str
);
537 fprintf (output_file
, "@DESCRIPTION=%s\n", desc
->str
);
539 fprintf (output_file
, "@NOTE=%s\n", note
->str
);
541 fprintf (output_file
, "@EXCEL=%s\n", excel
->str
);
543 fprintf (output_file
, "@ODF=%s\n", odf
->str
);
544 if (seealso
->len
> 0)
545 fprintf (output_file
, "@SEEALSO=%s\n", seealso
->str
);
547 g_string_free (syntax
, TRUE
);
548 g_string_free (arg_desc
, TRUE
);
549 g_string_free (desc
, TRUE
);
550 g_string_free (odf
, TRUE
);
551 g_string_free (excel
, TRUE
);
552 g_string_free (note
, TRUE
);
553 g_string_free (seealso
, TRUE
);
555 fputc ('\n', output_file
);
556 } else if (dump_type
== 0) {
560 } const testing
[] = {
561 { "Unknown", "testing-unknown" },
562 { "No Testsuite", "testing-nosuite" },
563 { "Basic", "testing-basic" },
564 { "Exhaustive", "testing-exhaustive" },
565 { "Under Development", "testing-devel" }
570 } const implementation
[] = {
571 { "Exists", "imp-exists" },
572 { "Unimplemented", "imp-no" },
573 { "Subset", "imp-subset" },
574 { "Complete", "imp-complete" },
575 { "Superset", "imp-superset" },
576 { "Subset with_extensions", "imp-subsetext" },
577 { "Under development", "imp-devel" },
578 { "Unique to Gnumeric", "imp-gnumeric" },
580 GnmFuncImplStatus imst
= gnm_func_get_impl_status (fd
);
581 GnmFuncTestStatus test
= gnm_func_get_test_status (fd
);
583 if (group
!= gnm_func_get_function_group (fd
)) {
584 if (group
) fprintf (output_file
, "</table></div>\n");
585 group
= gnm_func_get_function_group (fd
);
586 fprintf (output_file
,
588 "<div class=\"functiongroup\"><table class=\"functiongroup\">\n"
589 "<tr class=\"header\">"
591 "<td>Implementation</td>"
594 group
->display_name
->str
);
596 up
= g_ascii_strup (fd
->name
, -1);
597 catname
= g_strdup (group
->display_name
->str
);
598 while (strchr (catname
, ' '))
599 *strchr (catname
, ' ') = '_';
600 fprintf (output_file
, "<tr class=\"function\">\n");
601 fprintf (output_file
,
602 "<td><a href =\"https://help.gnome.org/users/gnumeric/stable/gnumeric.html#gnumeric-function-%s\">%s</a></td>\n",
606 fprintf (output_file
,
607 "<td class=\"%s\"><a href=\"mailto:gnumeric-list@gnome.org?subject=Re: %s implementation\">%s</a></td>\n",
608 implementation
[imst
].klass
,
610 implementation
[imst
].name
);
611 fprintf (output_file
,
612 "<td class=\"%s\"><a href=\"mailto:gnumeric-list@gnome.org?subject=Re: %s testing\">%s</a></td>\n",
616 fprintf (output_file
,"</tr>\n");
619 if (dump_type
== 0) {
620 if (group
) fprintf (output_file
, "</table></div>\n");
621 fprintf (output_file
,
624 " <!-- MARKER: end-main -->\n"
625 " <!-- MARKER: start-sidebar -->\n"
626 " <!-- MARKER: end-sidebar -->\n"
633 g_ptr_array_free (ordered
, TRUE
);
634 fclose (output_file
);
637 /* ------------------------------------------------------------------------- */
640 mark_test_start (const char *name
)
642 g_printerr ("-----------------------------------------------------------------------------\nStart: %s\n-----------------------------------------------------------------------------\n\n", name
);
646 mark_test_end (const char *name
)
648 g_printerr ("End: %s\n\n", name
);
652 cb_collect_names (G_GNUC_UNUSED
const char *name
, GnmNamedExpr
*nexpr
, GSList
**names
)
654 *names
= g_slist_prepend (*names
, nexpr
);
658 fetch_cell (Sheet
*sheet
, const char *where
)
661 gboolean ok
= cellpos_parse (where
,
662 gnm_sheet_get_size (sheet
),
664 g_return_val_if_fail (ok
, NULL
);
665 return sheet_cell_fetch (sheet
, cp
.col
, cp
.row
);
669 set_cell (Sheet
*sheet
, const char *where
, const char *what
)
671 GnmCell
*cell
= fetch_cell (sheet
, where
);
673 gnm_cell_set_text (cell
, what
);
677 dump_sheet (Sheet
*sheet
, const char *header
)
679 GPtrArray
*cells
= sheet_cells (sheet
, NULL
);
683 g_printerr ("# %s\n", header
);
684 for (ui
= 0; ui
< cells
->len
; ui
++) {
685 GnmCell
*cell
= g_ptr_array_index (cells
, ui
);
686 char *txt
= gnm_cell_get_entered_text (cell
);
687 g_printerr ("%s: %s\n",
688 cellpos_as_string (&cell
->pos
), txt
);
691 g_ptr_array_free (cells
, TRUE
);
696 dump_names (Workbook
*wb
)
698 GSList
*l
, *names
= NULL
;
700 workbook_foreach_name (wb
, FALSE
, (GHFunc
)cb_collect_names
, &names
);
701 names
= g_slist_sort (names
, (GCompareFunc
)expr_name_cmp_by_name
);
703 g_printerr ("Dumping names...\n");
704 for (l
= names
; l
; l
= l
->next
) {
705 GnmNamedExpr
*nexpr
= l
->data
;
706 GnmConventionsOut out
;
708 out
.accum
= g_string_new (NULL
);
709 out
.pp
= &nexpr
->pos
;
710 out
.convs
= gnm_conventions_default
;
712 g_string_append (out
.accum
, "Scope=");
714 g_string_append (out
.accum
, out
.pp
->sheet
->name_quoted
);
716 g_string_append (out
.accum
, "Global");
718 g_string_append (out
.accum
, " Name=");
719 go_strescape (out
.accum
, expr_name_name (nexpr
));
721 g_string_append (out
.accum
, " Expr=");
722 gnm_expr_top_as_gstring (nexpr
->texpr
, &out
);
724 g_printerr ("%s\n", out
.accum
->str
);
725 g_string_free (out
.accum
, TRUE
);
727 g_printerr ("Dumping names... Done\n");
729 g_slist_free (names
);
733 define_name (const char *name
, const char *expr_txt
, gpointer scope
)
736 GnmExprTop
const *texpr
;
737 GnmNamedExpr
const *nexpr
;
738 GnmConventions
const *convs
;
740 if (IS_SHEET (scope
)) {
741 parse_pos_init_sheet (&pos
, scope
);
742 convs
= sheet_get_conventions (pos
.sheet
);
744 parse_pos_init (&pos
, WORKBOOK (scope
), NULL
, 0, 0);
745 convs
= gnm_conventions_default
;
748 texpr
= gnm_expr_parse_str (expr_txt
, &pos
,
749 GNM_EXPR_PARSE_DEFAULT
,
752 g_printerr ("Failed to parse %s for name %s\n",
757 nexpr
= expr_name_add (&pos
, name
, texpr
, NULL
, TRUE
, NULL
);
759 g_printerr ("Failed to add name %s\n", name
);
763 test_insdel_rowcol_names (void)
766 Sheet
*sheet1
,*sheet2
;
767 const char *test_name
= "test_insdel_rowcol_names";
771 mark_test_start (test_name
);
773 wb
= workbook_new ();
774 sheet1
= workbook_sheet_add (wb
, -1,
775 GNM_DEFAULT_COLS
, GNM_DEFAULT_ROWS
);
776 sheet2
= workbook_sheet_add (wb
, -1,
777 GNM_DEFAULT_COLS
, GNM_DEFAULT_ROWS
);
779 define_name ("Print_Area", "Sheet1!$A$1:$IV$65536", sheet1
);
780 define_name ("Print_Area", "Sheet2!$A$1:$IV$65536", sheet2
);
782 define_name ("NAMEGA1", "A1", wb
);
783 define_name ("NAMEG2", "$A$14+Sheet1!$A$14+Sheet2!$A$14", wb
);
785 define_name ("NAMEA1", "A1", sheet1
);
786 define_name ("NAMEA2", "A2", sheet1
);
787 define_name ("NAMEA1ABS", "$A$1", sheet1
);
788 define_name ("NAMEA2ABS", "$A$2", sheet1
);
792 for (i
= 3; i
>= 0; i
--) {
793 g_printerr ("About to insert before column %s on %s\n",
794 col_name (i
), sheet1
->name_unquoted
);
795 sheet_insert_cols (sheet1
, i
, 12, &undo
, NULL
);
797 g_printerr ("Undoing.\n");
798 go_undo_undo_with_data (undo
, NULL
);
799 g_object_unref (undo
);
800 g_printerr ("Done.\n");
803 for (i
= 3; i
>= 0; i
--) {
804 g_printerr ("About to insert before column %s on %s\n",
805 col_name (i
), sheet2
->name_unquoted
);
806 sheet_insert_cols (sheet2
, i
, 12, &undo
, NULL
);
808 g_printerr ("Undoing.\n");
809 go_undo_undo_with_data (undo
, NULL
);
810 g_object_unref (undo
);
811 g_printerr ("Done.\n");
814 for (i
= 3; i
>= 0; i
--) {
815 g_printerr ("About to delete column %s on %s\n",
816 col_name (i
), sheet1
->name_unquoted
);
817 sheet_delete_cols (sheet1
, i
, 1, &undo
, NULL
);
819 g_printerr ("Undoing.\n");
820 go_undo_undo_with_data (undo
, NULL
);
821 g_object_unref (undo
);
822 g_printerr ("Done.\n");
827 mark_test_end (test_name
);
830 /* ------------------------------------------------------------------------- */
833 test_insert_delete (void)
835 const char *test_name
= "test_insert_delete";
839 GOUndo
*u
= NULL
, *u1
;
841 mark_test_start (test_name
);
843 wb
= workbook_new ();
844 sheet1
= workbook_sheet_add (wb
, -1,
845 GNM_DEFAULT_COLS
, GNM_DEFAULT_ROWS
);
846 set_cell (sheet1
, "B2", "=D4+1");
847 set_cell (sheet1
, "D2", "=if(TRUE,B2,2)");
849 dump_sheet (sheet1
, "Init");
851 for (i
= 5; i
>= 0; i
--) {
852 g_printerr ("# About to insert column before %s\n",
854 sheet_insert_cols (sheet1
, i
, 1, &u1
, NULL
);
855 u
= go_undo_combine (u
, u1
);
856 dump_sheet (sheet1
, NULL
);
859 for (i
= 5; i
>= 0; i
--) {
860 g_printerr ("# About to insert row before %s\n",
862 sheet_insert_rows (sheet1
, i
, 1, &u1
, NULL
);
863 u
= go_undo_combine (u
, u1
);
864 dump_sheet (sheet1
, NULL
);
870 dump_sheet (sheet1
, "Undo the lot");
872 for (i
= 5; i
>= 0; i
--) {
873 g_printerr ("# About to delete column %s\n",
875 sheet_delete_cols (sheet1
, i
, 1, &u1
, NULL
);
876 u
= go_undo_combine (u
, u1
);
877 dump_sheet (sheet1
, NULL
);
880 for (i
= 5; i
>= 0; i
--) {
881 g_printerr ("# About to delete row %s\n",
883 sheet_delete_rows (sheet1
, i
, 1, &u1
, NULL
);
884 u
= go_undo_combine (u
, u1
);
885 dump_sheet (sheet1
, NULL
);
891 dump_sheet (sheet1
, "Undo the lot");
895 mark_test_end (test_name
);
898 /* ------------------------------------------------------------------------- */
900 /* ------------------------------------------------------------------------- */
903 check_help_expression (const char *text
, GnmFunc
const *fd
)
905 GnmConventions
const *convs
= gnm_conventions_default
;
907 GnmExprTop
const *texpr
;
911 /* Create a dummy workbook with no sheets for interesting effects. */
912 wb
= workbook_new ();
913 parse_pos_init (&pp
, wb
, NULL
, 0, 0);
915 parse_error_init (&perr
);
917 texpr
= gnm_expr_parse_str (text
, &pp
,
918 GNM_EXPR_PARSE_DEFAULT
,
922 g_printerr ("Error parsing %s: %s\n",
923 text
, perr
.err
->message
);
925 parse_error_free (&perr
);
931 gnm_expr_top_unref (texpr
);
936 check_argument_refs (const char *text
, GnmFunc
*fd
)
938 if (!gnm_func_is_fixargs (fd
))
942 const char *at
= strchr (text
, '@');
950 text
= strchr (at
+ 2, '}');
953 argname
= g_strndup (at
+ 2, text
- at
- 2);
955 for (i
= 0; TRUE
; i
++) {
956 char *thisarg
= gnm_func_get_arg_name (fd
, i
);
962 found
= strcmp (argname
, thisarg
) == 0;
973 gnm_func_sanity_check1 (GnmFunc
*fd
)
975 GnmFuncHelp
const *h
;
976 int counts
[(int)GNM_FUNC_HELP_ODF
+ 1];
978 size_t nlen
= strlen (fd
->name
);
981 GnmFuncHelp
const *help
= gnm_func_get_help (fd
, &n
);
983 allargs
= g_hash_table_new_full
984 (g_str_hash
, g_str_equal
, (GDestroyNotify
)g_free
, NULL
);
986 memset (counts
, 0, sizeof (counts
));
987 for (h
= help
; n
-- > 0; h
++) {
988 g_assert (h
->type
<= GNM_FUNC_HELP_ODF
);
991 if (!g_utf8_validate (h
->text
, -1, NULL
)) {
992 g_printerr ("%s: Invalid UTF-8 in type %i\n",
999 case GNM_FUNC_HELP_NAME
:
1000 if (g_ascii_strncasecmp (fd
->name
, h
->text
, nlen
) ||
1001 h
->text
[nlen
] != ':') {
1002 g_printerr ("%s: Invalid NAME record\n",
1005 } else if (h
->text
[nlen
+ 1] == ' ') {
1006 g_printerr ("%s: Unwanted space in NAME record\n",
1009 } else if (h
->text
[strlen (h
->text
) - 1] == '.') {
1010 g_printerr ("%s: Unwanted period in NAME record\n",
1015 case GNM_FUNC_HELP_ARG
: {
1016 const char *aend
= strchr (h
->text
, ':');
1019 if (aend
== NULL
|| aend
== h
->text
) {
1020 g_printerr ("%s: Invalid ARG record\n",
1026 if (aend
[1] == ' ') {
1027 g_printerr ("%s: Unwanted space in ARG record\n",
1031 if (aend
[1] == '\0') {
1032 g_printerr ("%s: Empty ARG record\n",
1036 if (h
->text
[strlen (h
->text
) - 1] == '.') {
1037 g_printerr ("%s: Unwanted period in ARG record\n",
1041 if (check_argument_refs (aend
+ 1, fd
)) {
1042 g_printerr ("%s: Invalid argument reference, %s, in argument\n",
1043 aend
+ 1, fd
->name
);
1046 argname
= g_strndup (h
->text
, aend
- h
->text
);
1047 if (g_hash_table_lookup (allargs
, argname
)) {
1048 g_printerr ("%s: Duplicate argument name %s\n",
1052 g_printerr ("%s\n", h
->text
);
1054 g_hash_table_insert (allargs
, argname
, argname
);
1057 case GNM_FUNC_HELP_DESCRIPTION
: {
1060 if (check_argument_refs (h
->text
, fd
)) {
1061 g_printerr ("%s: Invalid argument reference in description\n",
1067 while (g_ascii_isupper (*p
) ||
1068 (p
!= h
->text
&& (*p
== '_' ||
1070 g_ascii_isdigit (*p
))))
1074 strncmp (h
->text
, "CP1252", 6) != 0) {
1075 if (g_ascii_strncasecmp (h
->text
, fd
->name
, nlen
)) {
1076 g_printerr ("%s: Wrong function name in description\n",
1084 case GNM_FUNC_HELP_EXAMPLES
:
1085 if (h
->text
[0] == '=') {
1086 if (check_help_expression (h
->text
+ 1, fd
)) {
1087 g_printerr ("%s: Invalid EXAMPLES record\n",
1098 g_hash_table_destroy (allargs
);
1100 if (gnm_func_is_fixargs (fd
)) {
1101 int n
= counts
[GNM_FUNC_HELP_ARG
];
1103 gnm_func_count_args (fd
, &min
, &max
);
1105 g_printerr ("%s: Help for %d args, but takes %d-%d\n",
1106 fd
->name
, n
, min
, max
);
1112 if (counts
[GNM_FUNC_HELP_DESCRIPTION
] != 1) {
1113 g_printerr ("%s: Help has %d descriptions.\n",
1114 fd
->name
, counts
[GNM_FUNC_HELP_DESCRIPTION
]);
1119 if (counts
[GNM_FUNC_HELP_NAME
] != 1) {
1120 g_printerr ("%s: Help has %d NAME records.\n",
1121 fd
->name
, counts
[GNM_FUNC_HELP_NAME
]);
1125 if (counts
[GNM_FUNC_HELP_EXCEL
] > 1) {
1126 g_printerr ("%s: Help has %d Excel notes.\n",
1127 fd
->name
, counts
[GNM_FUNC_HELP_EXCEL
]);
1131 if (counts
[GNM_FUNC_HELP_ODF
] > 1) {
1132 g_printerr ("%s: Help has %d ODF notes.\n",
1133 fd
->name
, counts
[GNM_FUNC_HELP_ODF
]);
1141 gnm_func_sanity_check (void)
1147 ordered
= enumerate_functions (TRUE
);
1149 for (ui
= 0; ui
< ordered
->len
; ui
++) {
1150 GnmFunc
*fd
= g_ptr_array_index (ordered
, ui
);
1151 if (gnm_func_sanity_check1 (fd
))
1155 g_ptr_array_free (ordered
, TRUE
);
1161 test_func_help (void)
1163 const char *test_name
= "test_func_help";
1166 mark_test_start (test_name
);
1168 res
= gnm_func_sanity_check ();
1169 g_printerr ("Result = %d\n", res
);
1171 mark_test_end (test_name
);
1174 /* ------------------------------------------------------------------------- */
1177 test_strtol_ok (const char *s
, long l
, size_t expected_len
)
1183 l2
= gnm_utf8_strtol (s
, &end
);
1186 if (end
!= s
+ expected_len
) {
1187 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1191 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1194 if (save_errno
!= 0) {
1195 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1203 test_strtol_noconv (const char *s
)
1209 l
= gnm_utf8_strtol (s
, &end
);
1213 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1217 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1220 if (save_errno
!= 0) {
1221 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1229 test_strtol_overflow (const char *s
, gboolean pos
)
1234 size_t expected_len
= strlen (s
);
1236 l
= gnm_utf8_strtol (s
, &end
);
1239 if (end
!= s
+ expected_len
) {
1240 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1243 if (l
!= (pos
? LONG_MAX
: LONG_MIN
)) {
1244 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1247 if (save_errno
!= ERANGE
) {
1248 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1256 test_strtol_reverse (long l
)
1258 char buffer
[4*sizeof(l
) + 4];
1261 sprintf(buffer
, "%ld", l
);
1262 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
));
1264 sprintf(buffer
, " %ld", l
);
1265 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
));
1267 sprintf(buffer
, "\xc2\xa0\n\t%ld", l
);
1268 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
));
1270 sprintf(buffer
, " \t%ldx", l
);
1271 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
) - 1);
1277 test_strtod_ok (const char *s
, double d
, size_t expected_len
)
1283 d2
= gnm_utf8_strto (s
, &end
);
1286 if (end
!= s
+ expected_len
) {
1287 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1291 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1294 if (save_errno
!= 0) {
1295 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1303 test_nonascii_numbers (void)
1305 const char *test_name
= "test_nonascii_numbers";
1308 mark_test_start (test_name
);
1310 res
|= test_strtol_reverse (0);
1311 res
|= test_strtol_reverse (1);
1312 res
|= test_strtol_reverse (-1);
1313 res
|= test_strtol_reverse (LONG_MIN
);
1314 res
|= test_strtol_reverse (LONG_MIN
+ 1);
1315 res
|= test_strtol_reverse (LONG_MAX
- 1);
1317 res
|= test_strtol_ok ("\xef\xbc\x8d\xef\xbc\x91", -1, 6);
1318 res
|= test_strtol_ok ("\xc2\xa0+1", 1, 4);
1320 res
|= test_strtol_ok ("000000000000000000000000000000", 0, 30);
1322 res
|= test_strtol_noconv ("");
1323 res
|= test_strtol_noconv (" ");
1324 res
|= test_strtol_noconv (" +");
1325 res
|= test_strtol_noconv (" -");
1326 res
|= test_strtol_noconv (" .00");
1327 res
|= test_strtol_noconv (" e0");
1328 res
|= test_strtol_noconv ("--0");
1329 res
|= test_strtol_noconv ("+-0");
1330 res
|= test_strtol_noconv ("+ 0");
1331 res
|= test_strtol_noconv ("- 0");
1334 char buffer
[4 * sizeof (long) + 2];
1336 sprintf (buffer
, "-%lu", 1 + (unsigned long)LONG_MIN
);
1337 res
|= test_strtol_overflow (buffer
, FALSE
);
1338 sprintf (buffer
, "-%lu", 10 + (unsigned long)LONG_MIN
);
1339 res
|= test_strtol_overflow (buffer
, FALSE
);
1341 sprintf (buffer
, "%lu", 1 + (unsigned long)LONG_MAX
);
1342 res
|= test_strtol_overflow (buffer
, TRUE
);
1343 sprintf (buffer
, "%lu", 10 + (unsigned long)LONG_MAX
);
1344 res
|= test_strtol_overflow (buffer
, TRUE
);
1347 /* -------------------- */
1349 res
|= test_strtod_ok ("0", 0, 1);
1350 res
|= test_strtod_ok ("1", 1, 1);
1351 res
|= test_strtod_ok ("-1", -1, 2);
1352 res
|= test_strtod_ok ("+1", 1, 2);
1353 res
|= test_strtod_ok (" +1", 1, 3);
1354 res
|= test_strtod_ok ("\xc2\xa0+1", 1, 4);
1355 res
|= test_strtod_ok ("\xc2\xa0+1x", 1, 4);
1356 res
|= test_strtod_ok ("\xc2\xa0+1e", 1, 4);
1357 res
|= test_strtod_ok ("\xc2\xa0+1e+", 1, 4);
1358 res
|= test_strtod_ok ("\xc2\xa0+1e+0", 1, 7);
1359 res
|= test_strtod_ok ("-1e1", -10, 4);
1360 res
|= test_strtod_ok ("100e-2", 1, 6);
1361 res
|= test_strtod_ok ("100e+2", 10000, 6);
1362 res
|= test_strtod_ok ("1x0p0", 1, 1);
1363 res
|= test_strtod_ok ("+inf", gnm_pinf
, 4);
1364 res
|= test_strtod_ok ("-inf", gnm_ninf
, 4);
1365 res
|= test_strtod_ok ("1.25", 1.25, 4);
1366 res
|= test_strtod_ok ("1.25e1", 12.5, 6);
1367 res
|= test_strtod_ok ("12.5e-1", 1.25, 7);
1369 g_printerr ("Result = %d\n", res
);
1371 mark_test_end (test_name
);
1374 /* ------------------------------------------------------------------------- */
1376 static char *random_summary
= NULL
;
1379 add_random_fail (const char *s
)
1381 if (random_summary
) {
1382 char *t
= g_strconcat (random_summary
, ", ", s
, NULL
);
1383 g_free (random_summary
);
1386 random_summary
= g_strdup (s
);
1390 define_cell (Sheet
*sheet
, int c
, int r
, const char *expr
)
1392 GnmCell
*cell
= sheet_cell_fetch (sheet
, c
, r
);
1393 sheet_cell_set_text (cell
, expr
, NULL
);
1396 #define GET_PROB(i_) ((i_) <= 0 ? 0 : ((i_) >= nf ? 1 : probs[(i_)]))
1399 rand_fractile_test (gnm_float
const *vals
, int N
, int nf
,
1400 gnm_float
const *fractiles
, gnm_float
const *probs
)
1402 gnm_float f
= 1.0 / nf
;
1403 int *fractilecount
= g_new (int, nf
+ 1);
1404 int *expected
= g_new (int, nf
+ 1);
1407 gboolean debug
= TRUE
;
1410 g_printerr ("Bin upper limit:");
1411 for (i
= 1; i
<= nf
; i
++) {
1412 gnm_float U
= (i
== nf
) ? gnm_pinf
: fractiles
[i
];
1413 g_printerr ("%s%" GNM_FORMAT_g
,
1414 (i
== 1) ? " " : ", ",
1420 if (debug
&& probs
) {
1421 g_printerr ("Cumulative probabilities:");
1422 for (i
= 1; i
<= nf
; i
++)
1423 g_printerr ("%s%.1" GNM_FORMAT_f
"%%",
1424 (i
== 1) ? " " : ", ", 100 * GET_PROB (i
));
1428 for (i
= 1; i
< nf
- 1; i
++) {
1429 if (!(fractiles
[i
] <= fractiles
[i
+ 1])) {
1430 g_printerr ("Severe fractile ordering problem.\n");
1434 if (probs
&& !(probs
[i
] <= probs
[i
+ 1])) {
1435 g_printerr ("Severe cumulative probabilities ordering problem.\n");
1439 if (probs
&& (probs
[1] < 0 || probs
[nf
- 1] > 1)) {
1440 g_printerr ("Severe cumulative probabilities range problem.\n");
1444 for (i
= 0; i
<= nf
; i
++)
1445 fractilecount
[i
] = 0;
1447 for (i
= 0; i
< N
; i
++) {
1448 gnm_float r
= vals
[i
];
1450 for (j
= 1; j
< nf
; j
++)
1451 if (r
<= fractiles
[j
])
1455 g_printerr ("Fractile counts:");
1456 for (i
= 1; i
<= nf
; i
++)
1457 g_printerr ("%s%d", (i
== 1) ? " " : ", ", fractilecount
[i
]);
1461 g_printerr ("Expected counts:");
1462 for (i
= 1; i
<= nf
; i
++) {
1463 gnm_float p
= GET_PROB (i
) - GET_PROB (i
-1);
1464 expected
[i
] = gnm_floor (p
* N
+ 0.5);
1465 g_printerr ("%s%d", (i
== 1) ? " " : ", ", expected
[i
]);
1469 gnm_float T
= f
* N
;
1470 g_printerr ("Expected count in each fractile: %.10" GNM_FORMAT_g
"\n", T
);
1471 for (i
= 0; i
<= nf
; i
++)
1475 for (i
= 1; i
<= nf
; i
++) {
1476 gnm_float T
= expected
[i
];
1477 if (!(gnm_abs (fractilecount
[i
] - T
) <= 4 * gnm_sqrt (T
))) {
1478 g_printerr ("Fractile test failure for bin %d.\n", i
);
1483 g_free (fractilecount
);
1492 test_random_1 (int N
, const char *expr
,
1493 gnm_float
*mean
, gnm_float
*var
,
1494 gnm_float
*skew
, gnm_float
*kurt
)
1496 Workbook
*wb
= workbook_new ();
1498 gnm_float
*res
= g_new (gnm_float
, N
);
1501 int cols
= 2, rows
= N
;
1503 g_printerr ("Testing %s\n", expr
);
1505 gnm_sheet_suggest_size (&cols
, &rows
);
1506 sheet
= workbook_sheet_add (wb
, -1, cols
, rows
);
1508 for (i
= 0; i
< N
; i
++)
1509 define_cell (sheet
, 0, i
, expr
);
1511 s
= g_strdup_printf ("=average(a1:a%d)", N
);
1512 define_cell (sheet
, 1, 0, s
);
1515 s
= g_strdup_printf ("=var(a1:a%d)", N
);
1516 define_cell (sheet
, 1, 1, s
);
1519 s
= g_strdup_printf ("=skew(a1:a%d)", N
);
1520 define_cell (sheet
, 1, 2, s
);
1523 s
= g_strdup_printf ("=kurt(a1:a%d)", N
);
1524 define_cell (sheet
, 1, 3, s
);
1527 /* Force recalc of all dirty cells even in manual mode. */
1528 workbook_recalc (sheet
->workbook
);
1530 for (i
= 0; i
< N
; i
++)
1531 res
[i
] = value_get_as_float (sheet_cell_get (sheet
, 0, i
)->value
);
1532 *mean
= value_get_as_float (sheet_cell_get (sheet
, 1, 0)->value
);
1533 g_printerr ("Mean: %.10" GNM_FORMAT_g
"\n", *mean
);
1535 *var
= value_get_as_float (sheet_cell_get (sheet
, 1, 1)->value
);
1536 g_printerr ("Var: %.10" GNM_FORMAT_g
"\n", *var
);
1538 *skew
= value_get_as_float (sheet_cell_get (sheet
, 1, 2)->value
);
1539 g_printerr ("Skew: %.10" GNM_FORMAT_g
"\n", *skew
);
1541 *kurt
= value_get_as_float (sheet_cell_get (sheet
, 1, 3)->value
);
1542 g_printerr ("Kurt: %.10" GNM_FORMAT_g
"\n", *kurt
);
1544 g_object_unref (wb
);
1549 test_random_normality (int N
, const char *expr
,
1550 gnm_float
*mean
, gnm_float
*var
,
1551 gnm_float
*adtest
, gnm_float
*cvmtest
,
1552 gnm_float
*lkstest
, gnm_float
*sftest
)
1554 Workbook
*wb
= workbook_new ();
1556 gnm_float
*res
= g_new (gnm_float
, N
);
1559 int cols
= 2, rows
= N
;
1561 g_printerr ("Testing %s\n", expr
);
1563 gnm_sheet_suggest_size (&cols
, &rows
);
1564 sheet
= workbook_sheet_add (wb
, -1, cols
, rows
);
1566 for (i
= 0; i
< N
; i
++)
1567 define_cell (sheet
, 0, i
, expr
);
1569 s
= g_strdup_printf ("=average(a1:a%d)", N
);
1570 define_cell (sheet
, 1, 0, s
);
1573 s
= g_strdup_printf ("=var(a1:a%d)", N
);
1574 define_cell (sheet
, 1, 1, s
);
1577 s
= g_strdup_printf ("=adtest(a1:a%d)", N
);
1578 define_cell (sheet
, 1, 2, s
);
1581 s
= g_strdup_printf ("=cvmtest(a1:a%d)", N
);
1582 define_cell (sheet
, 1, 3, s
);
1585 s
= g_strdup_printf ("=lkstest(a1:a%d)", N
);
1586 define_cell (sheet
, 1, 4, s
);
1589 s
= g_strdup_printf ("=sftest(a1:a%d)", N
> 5000 ? 5000 : N
);
1590 define_cell (sheet
, 1, 5, s
);
1593 /* Force recalc of all dirty cells even in manual mode. */
1594 workbook_recalc (sheet
->workbook
);
1596 for (i
= 0; i
< N
; i
++)
1597 res
[i
] = value_get_as_float (sheet_cell_get (sheet
, 0, i
)->value
);
1598 *mean
= value_get_as_float (sheet_cell_get (sheet
, 1, 0)->value
);
1599 g_printerr ("Mean: %.10" GNM_FORMAT_g
"\n", *mean
);
1601 *var
= value_get_as_float (sheet_cell_get (sheet
, 1, 1)->value
);
1602 g_printerr ("Var: %.10" GNM_FORMAT_g
"\n", *var
);
1604 *adtest
= value_get_as_float (sheet_cell_get (sheet
, 1, 2)->value
);
1605 g_printerr ("ADTest: %.10" GNM_FORMAT_g
"\n", *adtest
);
1607 *cvmtest
= value_get_as_float (sheet_cell_get (sheet
, 1, 3)->value
);
1608 g_printerr ("CVMTest: %.10" GNM_FORMAT_g
"\n", *cvmtest
);
1610 *lkstest
= value_get_as_float (sheet_cell_get (sheet
, 1, 4)->value
);
1611 g_printerr ("LKSTest: %.10" GNM_FORMAT_g
"\n", *lkstest
);
1613 *sftest
= value_get_as_float (sheet_cell_get (sheet
, 1, 5)->value
);
1614 g_printerr ("SFTest: %.10" GNM_FORMAT_g
"\n", *sftest
);
1616 g_object_unref (wb
);
1621 test_random_rand (int N
)
1623 gnm_float mean
, var
, skew
, kurt
;
1624 gnm_float mean_target
= 0.5;
1625 gnm_float var_target
= 1.0 / 12;
1626 gnm_float skew_target
= 0;
1627 gnm_float kurt_target
= -6.0 / 5;
1632 gnm_float fractiles
[10];
1633 const int nf
= G_N_ELEMENTS (fractiles
);
1635 vals
= test_random_1 (N
, "=RAND()", &mean
, &var
, &skew
, &kurt
);
1637 for (i
= 0; i
< N
; i
++) {
1638 gnm_float r
= vals
[i
];
1639 if (!(r
>= 0 && r
< 1)) {
1640 g_printerr ("Range failure.\n");
1647 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
1648 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1652 if (gnm_abs (var
- T
) > 0.01) {
1653 g_printerr ("Var failure.\n");
1657 if (gnm_abs (skew
- T
) > 0.05) {
1658 g_printerr ("Skew failure.\n");
1662 if (gnm_abs (kurt
- T
) > 0.05) {
1663 g_printerr ("Kurt failure.\n");
1668 for (i
= 1; i
< nf
; i
++)
1669 fractiles
[i
] = i
/ (double)nf
;
1670 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
1674 g_printerr ("OK\n");
1676 add_random_fail ("RAND");
1683 test_random_randuniform (int N
)
1685 gnm_float mean
, var
, skew
, kurt
;
1688 gnm_float lsign
= (random_01 () > 0.75 ? 1 : -1);
1689 gnm_float param_l
= lsign
* gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
1690 gnm_float param_h
= param_l
+ gnm_floor (1 / (0.0001 + gnm_pow (random_01 () / 2, 4)));
1691 gnm_float n
= param_h
- param_l
;
1692 gnm_float mean_target
= (param_l
+ param_h
) / 2;
1693 gnm_float var_target
= (n
* n
) / 12;
1694 gnm_float skew_target
= 0;
1695 gnm_float kurt_target
= -6 / 5.0;
1699 gnm_float fractiles
[10];
1700 const int nf
= G_N_ELEMENTS (fractiles
);
1702 expr
= g_strdup_printf ("=RANDUNIFORM(%.10" GNM_FORMAT_g
",%.10" GNM_FORMAT_g
")", param_l
, param_h
);
1703 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1707 for (i
= 0; i
< N
; i
++) {
1708 gnm_float r
= vals
[i
];
1709 if (!(r
>= param_l
&& r
< param_h
)) {
1710 g_printerr ("Range failure.\n");
1717 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1718 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
1719 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1724 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
1725 if (!(var
>= 0 && gnm_finite (var
))) {
1726 /* That is a very simplistic test! */
1727 g_printerr ("Var failure.\n");
1732 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
1733 if (!gnm_finite (skew
)) {
1734 /* That is a very simplistic test! */
1735 g_printerr ("Skew failure.\n");
1740 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
1741 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
1742 /* That is a very simplistic test! */
1743 g_printerr ("Kurt failure.\n");
1748 for (i
= 1; i
< nf
; i
++)
1749 fractiles
[i
] = param_l
+ n
* i
/ (double)nf
;
1750 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
1754 g_printerr ("OK\n");
1756 add_random_fail ("RANDUNIFORM");
1763 test_random_randbernoulli (int N
)
1766 gnm_float q
= 1 - p
;
1767 gnm_float mean
, var
, skew
, kurt
;
1768 gnm_float mean_target
= p
;
1769 gnm_float var_target
= p
* (1 - p
);
1770 gnm_float skew_target
= (q
- p
) / gnm_sqrt (p
* q
);
1771 gnm_float kurt_target
= (1 - 6 * p
* q
) / (p
* q
);
1778 expr
= g_strdup_printf ("=RANDBERNOULLI(%.10" GNM_FORMAT_g
")", p
);
1779 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1783 for (i
= 0; i
< N
; i
++) {
1784 gnm_float r
= vals
[i
];
1785 if (!(r
== 0 || r
== 1)) {
1786 g_printerr ("Range failure.\n");
1793 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1794 if (gnm_abs (mean
- p
) > 0.01) {
1795 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1800 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
1801 if (gnm_abs (var
- T
) > 0.01) {
1802 g_printerr ("Var failure.\n");
1807 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
1808 if (!(gnm_abs (skew
- T
) <= 0.10 * gnm_abs (T
))) {
1809 g_printerr ("Skew failure.\n");
1814 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
1815 if (!(gnm_abs (kurt
- T
) <= 0.15 * gnm_abs (T
))) {
1816 g_printerr ("Kurt failure.\n");
1820 g_printerr ("OK\n");
1822 add_random_fail ("RANDBERNOULLI");
1829 test_random_randdiscrete (int N
)
1831 gnm_float mean
, var
, skew
, kurt
;
1835 gnm_float mean_target
= 13;
1836 gnm_float var_target
= 156;
1837 gnm_float skew_target
= 0.6748;
1838 gnm_float kurt_target
= -0.9057;
1842 expr
= g_strdup_printf ("=RANDDISCRETE({0;1;4;9;16;25;36})");
1843 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1847 for (i
= 0; i
< N
; i
++) {
1848 gnm_float r
= vals
[i
];
1849 if (!(r
>= 0 && r
<= 36 && gnm_sqrt (r
) == gnm_floor (gnm_sqrt (r
)))) {
1850 g_printerr ("Range failure.\n");
1857 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1858 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
1859 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1864 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
1865 if (!(var
>= 0 && gnm_finite (var
))) {
1866 /* That is a very simplistic test! */
1867 g_printerr ("Var failure.\n");
1872 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
1873 if (!gnm_finite (skew
)) {
1874 /* That is a very simplistic test! */
1875 g_printerr ("Skew failure.\n");
1880 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
1881 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
1882 /* That is a very simplistic test! */
1883 g_printerr ("Kurt failure.\n");
1888 g_printerr ("OK\n");
1890 add_random_fail ("RANDDISCRETE");
1897 test_random_randnorm (int N
)
1899 gnm_float mean
, var
, adtest
, cvmtest
, lkstest
, sftest
;
1900 gnm_float mean_target
= 0, var_target
= 1;
1906 gnm_float fractiles
[10];
1907 const int nf
= G_N_ELEMENTS (fractiles
);
1909 expr
= g_strdup_printf ("=RANDNORM(%.10" GNM_FORMAT_g
",%.10" GNM_FORMAT_g
")",
1910 mean_target
, var_target
);
1911 vals
= test_random_normality (N
, expr
, &mean
, &var
, &adtest
, &cvmtest
, &lkstest
, &sftest
);
1915 for (i
= 0; i
< N
; i
++) {
1916 gnm_float r
= vals
[i
];
1917 if (!gnm_finite (r
)) {
1918 g_printerr ("Range failure.\n");
1925 if (gnm_abs (mean
- T
) > 0.02) {
1926 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1930 if (gnm_abs (var
- T
) > 0.02) {
1931 g_printerr ("Var failure.\n");
1936 for (i
= 1; i
< nf
; i
++)
1937 fractiles
[i
] = qnorm (i
/ (double)nf
, mean_target
, gnm_sqrt (var_target
), TRUE
, FALSE
);
1938 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
1941 if (adtest
< 0.01) {
1942 g_printerr ("Anderson Darling Test rejected [%.10" GNM_FORMAT_g
"]\n", adtest
);
1945 if (cvmtest
< 0.01) {
1946 g_printerr ("Cramér-von Mises Test rejected [%.10" GNM_FORMAT_g
"]\n", cvmtest
);
1949 if (lkstest
< 0.01) {
1950 g_printerr ("Lilliefors (Kolmogorov-Smirnov) Test rejected [%.10" GNM_FORMAT_g
"]\n",
1954 if (sftest
< 0.01) {
1955 g_printerr ("Shapiro-Francia Test rejected [%.10" GNM_FORMAT_g
"]\n", sftest
);
1960 g_printerr ("OK\n");
1962 add_random_fail ("RANDNORM");
1969 test_random_randsnorm (int N
)
1971 gnm_float mean
, var
, skew
, kurt
;
1974 gnm_float alpha
= 5;
1975 gnm_float delta
= alpha
/gnm_sqrt(1+alpha
*alpha
);
1976 gnm_float mean_target
= delta
* gnm_sqrt (2/M_PIgnum
);
1977 gnm_float var_target
= 1-mean_target
*mean_target
;
1982 expr
= g_strdup_printf ("=RANDSNORM(%.10" GNM_FORMAT_g
")", alpha
);
1983 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1987 for (i
= 0; i
< N
; i
++) {
1988 gnm_float r
= vals
[i
];
1989 if (!gnm_finite (r
)) {
1990 g_printerr ("Range failure.\n");
1997 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1998 if (gnm_abs (mean
- T
) > 0.01) {
1999 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2004 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2005 if (gnm_abs (var
- T
) > 0.01) {
2006 g_printerr ("Var failure.\n");
2010 T
= mean_target
/gnm_sqrt(var_target
);
2011 T
= T
*T
*T
*(4-M_PIgnum
)/2;
2012 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2013 if (gnm_abs (skew
- T
) > 0.05) {
2014 g_printerr ("Skew failure.\n");
2018 T
= 2*(M_PIgnum
- 3)*mean_target
*mean_target
*mean_target
*mean_target
/(var_target
*var_target
);
2019 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2020 if (gnm_abs (kurt
- T
) > 0.15) {
2021 g_printerr ("Kurt failure.\n");
2026 g_printerr ("OK\n");
2028 add_random_fail ("RANDSNORM");
2035 test_random_randexp (int N
)
2037 gnm_float mean
, var
, skew
, kurt
;
2040 gnm_float param_l
= 1 / (0.0001 + gnm_pow (random_01 () / 2, 4));
2041 gnm_float mean_target
= param_l
;
2042 gnm_float var_target
= mean_target
* mean_target
;
2043 gnm_float skew_target
= 2;
2044 gnm_float kurt_target
= 6;
2048 gnm_float fractiles
[10];
2049 const int nf
= G_N_ELEMENTS (fractiles
);
2051 expr
= g_strdup_printf ("=RANDEXP(%.10" GNM_FORMAT_g
")", param_l
);
2052 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2056 for (i
= 0; i
< N
; i
++) {
2057 gnm_float r
= vals
[i
];
2058 if (!(r
>= 0 && gnm_finite (r
))) {
2059 g_printerr ("Range failure.\n");
2066 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2067 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2068 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2073 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2074 if (!(var
>= 0 && gnm_finite (var
))) {
2075 /* That is a very simplistic test! */
2076 g_printerr ("Var failure.\n");
2081 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2082 if (!gnm_finite (skew
)) {
2083 /* That is a very simplistic test! */
2084 g_printerr ("Skew failure.\n");
2089 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2090 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2091 /* That is a very simplistic test! */
2092 g_printerr ("Kurt failure.\n");
2097 for (i
= 1; i
< nf
; i
++)
2098 fractiles
[i
] = qexp (i
/ (double)nf
, param_l
, TRUE
, FALSE
);
2099 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2103 g_printerr ("OK\n");
2105 add_random_fail ("RANDEXP");
2112 test_random_randgamma (int N
)
2114 gnm_float mean
, var
, skew
, kurt
;
2117 gnm_float param_shape
= gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 6)));
2118 gnm_float param_scale
= 0.001 + gnm_pow (random_01 (), 4) * 1000;
2119 gnm_float mean_target
= param_shape
* param_scale
;
2120 gnm_float var_target
= mean_target
* param_scale
;
2121 gnm_float skew_target
= 2 / gnm_sqrt (param_shape
);
2122 gnm_float kurt_target
= 6 / param_shape
;
2126 gnm_float fractiles
[10];
2127 const int nf
= G_N_ELEMENTS (fractiles
);
2129 expr
= g_strdup_printf ("=RANDGAMMA(%.0" GNM_FORMAT_f
",%.10" GNM_FORMAT_g
")", param_shape
, param_scale
);
2130 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2134 for (i
= 0; i
< N
; i
++) {
2135 gnm_float r
= vals
[i
];
2136 if (!(r
> 0 && gnm_finite (r
))) {
2137 g_printerr ("Range failure.\n");
2144 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2145 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2146 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2151 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2152 if (!(var
>= 0 && gnm_finite (var
))) {
2153 /* That is a very simplistic test! */
2154 g_printerr ("Var failure.\n");
2159 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2160 if (!gnm_finite (skew
)) {
2161 /* That is a very simplistic test! */
2162 g_printerr ("Skew failure.\n");
2167 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2168 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2169 /* That is a very simplistic test! */
2170 g_printerr ("Kurt failure.\n");
2175 for (i
= 1; i
< nf
; i
++)
2176 fractiles
[i
] = qgamma (i
/ (double)nf
, param_shape
, param_scale
, TRUE
, FALSE
);
2177 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2181 g_printerr ("OK\n");
2183 add_random_fail ("RANDGAMMA");
2190 test_random_randbeta (int N
)
2192 gnm_float mean
, var
, skew
, kurt
;
2195 gnm_float param_a
= 1 / (0.0001 + gnm_pow (random_01 (), 6));
2196 gnm_float param_b
= 1 / (0.0001 + gnm_pow (random_01 (), 6));
2197 gnm_float s
= param_a
+ param_b
;
2198 gnm_float mean_target
= param_a
/ s
;
2199 gnm_float var_target
= mean_target
* param_b
/ (s
* (s
+ 1));
2200 gnm_float skew_target
=
2201 (2 * (param_b
- param_a
) * gnm_sqrt (s
+ 1))/
2202 ((s
+ 2) * gnm_sqrt (param_a
* param_b
));
2203 gnm_float kurt_target
= gnm_nan
; /* Complicated */
2207 gnm_float fractiles
[10];
2208 const int nf
= G_N_ELEMENTS (fractiles
);
2210 expr
= g_strdup_printf ("=RANDBETA(%.10" GNM_FORMAT_g
",%.10" GNM_FORMAT_g
")", param_a
, param_b
);
2211 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2215 for (i
= 0; i
< N
; i
++) {
2216 gnm_float r
= vals
[i
];
2217 if (!(r
>= 0 && r
<= 1)) {
2218 g_printerr ("Range failure.\n");
2225 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2226 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2227 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2232 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2233 if (!(var
>= 0 && gnm_finite (var
))) {
2234 /* That is a very simplistic test! */
2235 g_printerr ("Var failure.\n");
2240 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2241 if (!gnm_finite (skew
)) {
2242 /* That is a very simplistic test! */
2243 g_printerr ("Skew failure.\n");
2248 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2249 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2250 /* That is a very simplistic test! */
2251 g_printerr ("Kurt failure.\n");
2256 for (i
= 1; i
< nf
; i
++)
2257 fractiles
[i
] = qbeta (i
/ (double)nf
, param_a
, param_b
, TRUE
, FALSE
);
2258 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2262 g_printerr ("OK\n");
2264 add_random_fail ("RANDBETA");
2271 test_random_randtdist (int N
)
2273 gnm_float mean
, var
, skew
, kurt
;
2276 gnm_float param_df
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2277 gnm_float mean_target
= 0;
2278 gnm_float var_target
= param_df
> 2 ? param_df
/ (param_df
- 2) : gnm_nan
;
2279 gnm_float skew_target
= param_df
> 3 ? 0 : gnm_nan
;
2280 gnm_float kurt_target
= param_df
> 4 ? 6 / (param_df
- 4) : gnm_nan
;
2284 gnm_float fractiles
[10];
2285 const int nf
= G_N_ELEMENTS (fractiles
);
2287 expr
= g_strdup_printf ("=RANDTDIST(%.0" GNM_FORMAT_f
")", param_df
);
2288 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2292 for (i
= 0; i
< N
; i
++) {
2293 gnm_float r
= vals
[i
];
2294 if (!(gnm_finite (r
))) {
2295 g_printerr ("Range failure.\n");
2302 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2303 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2304 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2309 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2310 if (!(var
>= 0 && gnm_finite (var
))) {
2311 /* That is a very simplistic test! */
2312 g_printerr ("Var failure.\n");
2317 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2318 if (!gnm_finite (skew
)) {
2319 /* That is a very simplistic test! */
2320 g_printerr ("Skew failure.\n");
2325 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2326 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2327 /* That is a very simplistic test! */
2328 g_printerr ("Kurt failure.\n");
2333 for (i
= 1; i
< nf
; i
++)
2334 fractiles
[i
] = qt (i
/ (double)nf
, param_df
, TRUE
, FALSE
);
2335 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2339 g_printerr ("OK\n");
2341 add_random_fail ("RANDTDIST");
2348 test_random_randfdist (int N
)
2350 gnm_float mean
, var
, skew
, kurt
;
2353 gnm_float param_df1
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2354 gnm_float param_df2
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2355 gnm_float mean_target
= param_df2
> 2 ? param_df2
/ (param_df2
- 2) : gnm_nan
;
2356 gnm_float var_target
= param_df2
> 4
2357 ? (2 * param_df2
* param_df2
* (param_df1
+ param_df2
- 2) /
2358 (param_df1
* (param_df2
- 2) * (param_df2
- 2) * (param_df2
- 4)))
2360 gnm_float skew_target
= gnm_nan
; /* Complicated */
2361 gnm_float kurt_target
= gnm_nan
; /* Complicated */
2365 gnm_float fractiles
[10];
2366 const int nf
= G_N_ELEMENTS (fractiles
);
2368 expr
= g_strdup_printf ("=RANDFDIST(%.0" GNM_FORMAT_f
",%.0" GNM_FORMAT_f
")", param_df1
, param_df2
);
2369 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2373 for (i
= 0; i
< N
; i
++) {
2374 gnm_float r
= vals
[i
];
2375 if (!(r
>= 0 && gnm_finite (r
))) {
2376 g_printerr ("Range failure.\n");
2383 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2384 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2385 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2390 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2391 if (!(var
>= 0 && gnm_finite (var
))) {
2392 /* That is a very simplistic test! */
2393 g_printerr ("Var failure.\n");
2398 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2399 if (!gnm_finite (skew
)) {
2400 /* That is a very simplistic test! */
2401 g_printerr ("Skew failure.\n");
2406 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2407 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2408 /* That is a very simplistic test! */
2409 g_printerr ("Kurt failure.\n");
2414 for (i
= 1; i
< nf
; i
++)
2415 fractiles
[i
] = qf (i
/ (double)nf
, param_df1
, param_df2
, TRUE
, FALSE
);
2416 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2420 g_printerr ("OK\n");
2422 add_random_fail ("RANDFDIST");
2429 test_random_randchisq (int N
)
2431 gnm_float mean
, var
, skew
, kurt
;
2434 gnm_float param_df
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2435 gnm_float mean_target
= param_df
;
2436 gnm_float var_target
= param_df
* 2;
2437 gnm_float skew_target
= gnm_sqrt (8 / param_df
);
2438 gnm_float kurt_target
= 12 / param_df
;
2442 gnm_float fractiles
[10];
2443 const int nf
= G_N_ELEMENTS (fractiles
);
2445 expr
= g_strdup_printf ("=RANDCHISQ(%.10" GNM_FORMAT_g
")", param_df
);
2446 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2450 for (i
= 0; i
< N
; i
++) {
2451 gnm_float r
= vals
[i
];
2452 if (!(r
>= 0 && gnm_finite (r
))) {
2453 g_printerr ("Range failure.\n");
2460 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2461 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2462 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2467 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2468 if (!(var
>= 0 && gnm_finite (var
))) {
2469 /* That is a very simplistic test! */
2470 g_printerr ("Var failure.\n");
2475 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2476 if (!gnm_finite (skew
)) {
2477 /* That is a very simplistic test! */
2478 g_printerr ("Skew failure.\n");
2483 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2484 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2485 /* That is a very simplistic test! */
2486 g_printerr ("Kurt failure.\n");
2491 for (i
= 1; i
< nf
; i
++)
2492 fractiles
[i
] = qchisq (i
/ (double)nf
, param_df
, TRUE
, FALSE
);
2493 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2497 g_printerr ("OK\n");
2499 add_random_fail ("RANDCHISQ");
2506 test_random_randcauchy (int N
)
2508 gnm_float mean
, var
, skew
, kurt
;
2511 gnm_float param_scale
= 0.001 + gnm_pow (random_01 (), 4) * 1000;
2512 gnm_float mean_target
= gnm_nan
;
2513 gnm_float var_target
= gnm_nan
;
2514 gnm_float skew_target
= gnm_nan
;
2515 gnm_float kurt_target
= gnm_nan
;
2519 gnm_float fractiles
[10];
2520 const int nf
= G_N_ELEMENTS (fractiles
);
2523 * The distribution has no mean, no variance, no skew, and no kurtosis.
2524 * The support is all reals.
2527 expr
= g_strdup_printf ("=RANDCAUCHY(%.10" GNM_FORMAT_g
")", param_scale
);
2528 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2532 for (i
= 0; i
< N
; i
++) {
2533 gnm_float r
= vals
[i
];
2534 if (!(gnm_finite (r
))) {
2535 g_printerr ("Range failure.\n");
2542 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2543 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2544 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2549 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2550 if (!(var
>= 0 && gnm_finite (var
))) {
2551 /* That is a very simplistic test! */
2552 g_printerr ("Var failure.\n");
2557 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2558 if (!gnm_finite (skew
)) {
2559 /* That is a very simplistic test! */
2560 g_printerr ("Skew failure.\n");
2565 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2566 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2567 /* That is a very simplistic test! */
2568 g_printerr ("Kurt failure.\n");
2573 for (i
= 1; i
< nf
; i
++)
2574 fractiles
[i
] = qcauchy (i
/ (double)nf
, 0.0, param_scale
, TRUE
, FALSE
);
2575 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2579 g_printerr ("OK\n");
2581 add_random_fail ("RANDCAUCHY");
2588 test_random_randbinom (int N
)
2590 gnm_float mean
, var
, skew
, kurt
;
2593 gnm_float param_p
= random_01 ();
2594 gnm_float param_trials
= gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
2595 gnm_float mean_target
= param_trials
* param_p
;
2596 gnm_float var_target
= mean_target
* (1 - param_p
);
2597 gnm_float skew_target
= (1 - 2 * param_p
) / gnm_sqrt (var_target
);
2598 gnm_float kurt_target
= (1 - 6 * param_p
* (1 - param_p
)) / var_target
;
2602 gnm_float fractiles
[10], probs
[10];
2603 const int nf
= G_N_ELEMENTS (fractiles
);
2605 expr
= g_strdup_printf ("=RANDBINOM(%.10" GNM_FORMAT_g
",%.0" GNM_FORMAT_f
")", param_p
, param_trials
);
2606 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2610 for (i
= 0; i
< N
; i
++) {
2611 gnm_float r
= vals
[i
];
2612 if (!(r
>= 0 && r
<= param_trials
&& r
== gnm_floor (r
))) {
2613 g_printerr ("Range failure.\n");
2620 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2621 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2622 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2627 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2628 if (!(var
>= 0 && gnm_finite (var
))) {
2629 /* That is a very simplistic test! */
2630 g_printerr ("Var failure.\n");
2635 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2636 if (!gnm_finite (skew
)) {
2637 /* That is a very simplistic test! */
2638 g_printerr ("Skew failure.\n");
2643 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2644 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2645 /* That is a very simplistic test! */
2646 g_printerr ("Kurt failure.\n");
2651 for (i
= 1; i
< nf
; i
++) {
2652 fractiles
[i
] = qbinom (i
/ (double)nf
, param_trials
, param_p
, TRUE
, FALSE
);
2653 probs
[i
] = pbinom (fractiles
[i
], param_trials
, param_p
, TRUE
, FALSE
);
2655 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2659 g_printerr ("OK\n");
2661 add_random_fail ("RANDBINOM");
2668 test_random_randnegbinom (int N
)
2670 gnm_float mean
, var
, skew
, kurt
;
2673 gnm_float param_p
= random_01 ();
2674 gnm_float param_fails
= gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
2675 /* Warning: these differ from Wikipedia by swapping p and 1-p. */
2676 gnm_float mean_target
= param_fails
* (1 - param_p
) / param_p
;
2677 gnm_float var_target
= mean_target
/ param_p
;
2678 gnm_float skew_target
= (2 - param_p
) / gnm_sqrt (param_fails
* (1 - param_p
));
2679 gnm_float kurt_target
= 6 / param_fails
+ 1 / var_target
;
2683 gnm_float fractiles
[10], probs
[10];
2684 const int nf
= G_N_ELEMENTS (fractiles
);
2686 expr
= g_strdup_printf ("=RANDNEGBINOM(%.10" GNM_FORMAT_g
",%.0" GNM_FORMAT_f
")", param_p
, param_fails
);
2687 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2691 for (i
= 0; i
< N
; i
++) {
2692 gnm_float r
= vals
[i
];
2693 if (!(r
>= 0 && gnm_finite (r
) && r
== gnm_floor (r
))) {
2694 g_printerr ("Range failure.\n");
2701 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2702 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2703 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2708 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2709 if (!(var
>= 0 && gnm_finite (var
))) {
2710 /* That is a very simplistic test! */
2711 g_printerr ("Var failure.\n");
2716 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2717 if (!gnm_finite (skew
)) {
2718 /* That is a very simplistic test! */
2719 g_printerr ("Skew failure.\n");
2724 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2725 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2726 /* That is a very simplistic test! */
2727 g_printerr ("Kurt failure.\n");
2732 for (i
= 1; i
< nf
; i
++) {
2733 fractiles
[i
] = qnbinom (i
/ (double)nf
, param_fails
, param_p
, TRUE
, FALSE
);
2734 probs
[i
] = pnbinom (fractiles
[i
], param_fails
, param_p
, TRUE
, FALSE
);
2736 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2740 g_printerr ("OK\n");
2742 add_random_fail ("RANDNEGBINOM");
2749 test_random_randhyperg (int N
)
2751 gnm_float mean
, var
, skew
, kurt
;
2754 gnm_float param_nr
= gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 4)));
2755 gnm_float param_nb
= gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 4)));
2756 gnm_float s
= param_nr
+ param_nb
;
2757 gnm_float param_n
= gnm_floor (random_01 () * (s
+ 1));
2758 gnm_float mean_target
= param_n
* param_nr
/ s
;
2759 gnm_float var_target
= s
> 1
2760 ? mean_target
* (param_nb
/ s
) * (s
- param_n
) / (s
- 1)
2762 gnm_float skew_target
= gnm_nan
; /* Complicated */
2763 gnm_float kurt_target
= gnm_nan
; /* Complicated */
2767 gnm_float fractiles
[10], probs
[10];
2768 const int nf
= G_N_ELEMENTS (fractiles
);
2770 expr
= g_strdup_printf ("=RANDHYPERG(%.10" GNM_FORMAT_g
",%.0" GNM_FORMAT_f
",%.0" GNM_FORMAT_f
")", param_nr
, param_nb
, param_n
);
2771 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2775 for (i
= 0; i
< N
; i
++) {
2776 gnm_float r
= vals
[i
];
2777 if (!(r
>= 0 && r
<= param_n
&& r
== gnm_floor (r
))) {
2778 g_printerr ("Range failure.\n");
2785 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2786 if (gnm_finite (var_target
) &&
2787 !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2788 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2793 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2794 if (!(var
>= 0 && gnm_finite (var
))) {
2795 /* That is a very simplistic test! */
2796 g_printerr ("Var failure.\n");
2801 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2802 if (!gnm_finite (skew
)) {
2803 /* That is a very simplistic test! */
2804 g_printerr ("Skew failure.\n");
2809 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2810 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2811 /* That is a very simplistic test! */
2812 g_printerr ("Kurt failure.\n");
2817 for (i
= 1; i
< nf
; i
++) {
2818 fractiles
[i
] = qhyper (i
/ (double)nf
, param_nr
, param_nb
, param_n
, TRUE
, FALSE
);
2819 probs
[i
] = phyper (fractiles
[i
], param_nr
, param_nb
, param_n
, TRUE
, FALSE
);
2821 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2825 g_printerr ("OK\n");
2827 add_random_fail ("RANDHYPERG");
2834 test_random_randbetween (int N
)
2836 gnm_float mean
, var
, skew
, kurt
;
2839 gnm_float lsign
= (random_01 () > 0.75 ? 1 : -1);
2840 gnm_float param_l
= lsign
* gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
2841 gnm_float param_h
= param_l
+ gnm_floor (1 / (0.0001 + gnm_pow (random_01 () / 2, 4)));
2842 gnm_float n
= param_h
- param_l
+ 1;
2843 gnm_float mean_target
= (param_l
+ param_h
) / 2;
2844 gnm_float var_target
= (n
* n
- 1) / 12;
2845 gnm_float skew_target
= 0;
2846 gnm_float kurt_target
= (n
* n
+ 1) / (n
* n
- 1) * -6 / 5;
2851 expr
= g_strdup_printf ("=RANDBETWEEN(%.0" GNM_FORMAT_f
",%.0" GNM_FORMAT_f
")", param_l
, param_h
);
2852 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2856 for (i
= 0; i
< N
; i
++) {
2857 gnm_float r
= vals
[i
];
2858 if (!(r
>= param_l
&& r
<= param_h
&& r
== gnm_floor (r
))) {
2859 g_printerr ("Range failure.\n");
2866 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2867 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2868 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2873 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2874 if (!(var
>= 0 && gnm_finite (var
))) {
2875 /* That is a very simplistic test! */
2876 g_printerr ("Var failure.\n");
2881 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2882 if (!gnm_finite (skew
)) {
2883 /* That is a very simplistic test! */
2884 g_printerr ("Skew failure.\n");
2889 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2890 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2891 /* That is a very simplistic test! */
2892 g_printerr ("Kurt failure.\n");
2897 g_printerr ("OK\n");
2899 add_random_fail ("RANDBETWEEN");
2906 test_random_randpoisson (int N
)
2908 gnm_float mean
, var
, skew
, kurt
;
2911 gnm_float param_l
= 1 / (0.0001 + gnm_pow (random_01 () / 2, 4));
2912 gnm_float mean_target
= param_l
;
2913 gnm_float var_target
= param_l
;
2914 gnm_float skew_target
= 1 / gnm_sqrt (param_l
);
2915 gnm_float kurt_target
= 1 / param_l
;
2919 gnm_float fractiles
[10], probs
[10];
2920 const int nf
= G_N_ELEMENTS (fractiles
);
2922 expr
= g_strdup_printf ("=RANDPOISSON(%.10" GNM_FORMAT_g
")", param_l
);
2923 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2927 for (i
= 0; i
< N
; i
++) {
2928 gnm_float r
= vals
[i
];
2929 if (!(r
>= 0 && gnm_finite (r
) && r
== gnm_floor (r
))) {
2930 g_printerr ("Range failure.\n");
2937 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2938 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2939 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2944 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2945 if (!(var
>= 0 && gnm_finite (var
))) {
2946 /* That is a very simplistic test! */
2947 g_printerr ("Var failure.\n");
2952 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2953 if (!gnm_finite (skew
)) {
2954 /* That is a very simplistic test! */
2955 g_printerr ("Skew failure.\n");
2960 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2961 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2962 /* That is a very simplistic test! */
2963 g_printerr ("Kurt failure.\n");
2968 for (i
= 1; i
< nf
; i
++) {
2969 fractiles
[i
] = qpois (i
/ (double)nf
, param_l
, TRUE
, FALSE
);
2970 probs
[i
] = ppois (fractiles
[i
], param_l
, TRUE
, FALSE
);
2972 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2976 g_printerr ("OK\n");
2978 add_random_fail ("RANDPOISSON");
2985 * Note: this geometric distribution is the only with support {0,1,2,...}
2988 test_random_randgeom (int N
)
2990 gnm_float mean
, var
, skew
, kurt
;
2993 gnm_float param_p
= random_01 ();
2994 gnm_float mean_target
= (1 - param_p
) / param_p
;
2995 gnm_float var_target
= (1 - param_p
) / (param_p
* param_p
);
2996 gnm_float skew_target
= (2 - param_p
) / gnm_sqrt (1 - param_p
);
2997 gnm_float kurt_target
= 6 + (param_p
* param_p
) / (1 - param_p
);
3001 gnm_float fractiles
[10], probs
[10];
3002 const int nf
= G_N_ELEMENTS (fractiles
);
3004 expr
= g_strdup_printf ("=RANDGEOM(%.10" GNM_FORMAT_g
")", param_p
);
3005 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3009 for (i
= 0; i
< N
; i
++) {
3010 gnm_float r
= vals
[i
];
3011 if (!(r
>= 0 && gnm_finite (r
) && r
== gnm_floor (r
))) {
3012 g_printerr ("Range failure.\n");
3019 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3020 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3021 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3026 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3027 if (!(var
>= 0 && gnm_finite (var
))) {
3028 /* That is a very simplistic test! */
3029 g_printerr ("Var failure.\n");
3034 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3035 if (!gnm_finite (skew
)) {
3036 /* That is a very simplistic test! */
3037 g_printerr ("Skew failure.\n");
3042 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3043 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3044 /* That is a very simplistic test! */
3045 g_printerr ("Kurt failure.\n");
3050 for (i
= 1; i
< nf
; i
++) {
3051 fractiles
[i
] = qgeom (i
/ (double)nf
, param_p
, TRUE
, FALSE
);
3052 probs
[i
] = pgeom (fractiles
[i
], param_p
, TRUE
, FALSE
);
3054 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
3058 g_printerr ("OK\n");
3060 add_random_fail ("RANDGEOM");
3067 test_random_randlog (int N
)
3069 gnm_float mean
, var
, skew
, kurt
;
3072 gnm_float param_p
= random_01 ();
3073 gnm_float p
= param_p
;
3074 gnm_float l1mp
= gnm_log1p (-p
);
3075 gnm_float mean_target
= -p
/ (1 - p
) / l1mp
;
3076 gnm_float var_target
= -(p
* (p
+ l1mp
)) / gnm_pow ((1 - p
) * l1mp
, 2);
3077 /* See http://mathworld.wolfram.com/Log-SeriesDistribution.html */
3078 gnm_float skew_target
=
3080 (2 * p
* p
+ 3 * p
* l1mp
+ (1 + p
) * l1mp
* l1mp
) /
3081 (l1mp
* (p
+ l1mp
) * gnm_sqrt (-p
* (p
+ l1mp
)));
3082 gnm_float kurt_target
=
3085 p
* (7 + 4 * p
) * l1mp
* l1mp
+
3086 (1 + 4 * p
+ p
* p
) * l1mp
* l1mp
* l1mp
) /
3087 (p
* gnm_pow (p
+ l1mp
, 2));
3092 expr
= g_strdup_printf ("=RANDLOG(%.10" GNM_FORMAT_g
")", param_p
);
3093 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3097 for (i
= 0; i
< N
; i
++) {
3098 gnm_float r
= vals
[i
];
3099 if (!(r
>= 1 && gnm_finite (r
) && r
== gnm_floor (r
))) {
3100 g_printerr ("Range failure.\n");
3107 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3108 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3109 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3114 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3115 if (!(var
>= 0 && gnm_finite (var
))) {
3116 /* That is a very simplistic test! */
3117 g_printerr ("Var failure.\n");
3122 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3123 if (!gnm_finite (skew
)) {
3124 /* That is a very simplistic test! */
3125 g_printerr ("Skew failure.\n");
3130 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3131 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3132 /* That is a very simplistic test! */
3133 g_printerr ("Kurt failure.\n");
3138 g_printerr ("OK\n");
3140 add_random_fail ("RANDLOG");
3147 test_random_randweibull (int N
)
3149 gnm_float mean
, var
, skew
, kurt
;
3152 gnm_float shape
= 1 / (0.0001 + gnm_pow (random_01 () / 2, 2));
3153 gnm_float scale
= 2 * random_01 ();
3154 gnm_float mean_target
= scale
* gnm_gamma (1 + 1 / shape
);
3155 gnm_float var_target
= scale
* scale
*
3156 (gnm_gamma (1 + 2 / shape
) -
3157 gnm_pow (gnm_gamma (1 + 1 / shape
), 2));
3158 /* See https://en.wikipedia.org/wiki/Weibull_distribution */
3159 gnm_float skew_target
=
3160 (gnm_gamma (1 + 3 / shape
) * gnm_pow (scale
, 3) -
3161 3 * mean_target
* var_target
-
3162 gnm_pow (mean_target
, 3)) /
3163 gnm_pow (var_target
, 1.5);
3164 gnm_float kurt_target
= gnm_nan
; /* Complicated */
3168 gnm_float fractiles
[10];
3169 const int nf
= G_N_ELEMENTS (fractiles
);
3171 expr
= g_strdup_printf ("=RANDWEIBULL(%.10" GNM_FORMAT_f
",%.10" GNM_FORMAT_f
")", scale
, shape
);
3172 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3176 for (i
= 0; i
< N
; i
++) {
3177 gnm_float r
= vals
[i
];
3178 if (!(r
>= 0 && gnm_finite (r
))) {
3179 g_printerr ("Range failure.\n");
3186 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3187 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3188 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3193 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3194 if (!(var
>= 0 && gnm_finite (var
))) {
3195 /* That is a very simplistic test! */
3196 g_printerr ("Var failure.\n");
3201 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3202 if (!gnm_finite (skew
)) {
3203 /* That is a very simplistic test! */
3204 g_printerr ("Skew failure.\n");
3209 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3210 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3211 /* That is a very simplistic test! */
3212 g_printerr ("Kurt failure.\n");
3217 for (i
= 1; i
< nf
; i
++)
3218 fractiles
[i
] = qweibull (i
/ (double)nf
, shape
, scale
, TRUE
, FALSE
);
3219 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
3223 g_printerr ("OK\n");
3225 add_random_fail ("RANDWEIBULL");
3232 test_random_randlognorm (int N
)
3234 gnm_float mean
, var
, skew
, kurt
;
3237 gnm_float lm
= (random_01() - 0.5) / (0.1 + gnm_pow (random_01 () / 2, 2));
3238 gnm_float ls
= 1 / (1 + gnm_pow (random_01 () / 2, 2));
3239 gnm_float mean_target
= gnm_exp (lm
+ ls
* ls
/ 2);
3240 gnm_float var_target
= gnm_expm1 (ls
* ls
) * (mean_target
* mean_target
);
3241 /* See https://en.wikipedia.org/wiki/Log-normal_distribution */
3242 gnm_float skew_target
= (gnm_exp (ls
* ls
) + 2) *
3243 gnm_sqrt (gnm_expm1 (ls
* ls
));
3244 gnm_float kurt_target
= gnm_nan
; /* Complicated */
3248 gnm_float fractiles
[10];
3249 const int nf
= G_N_ELEMENTS (fractiles
);
3251 expr
= g_strdup_printf ("=RANDLOGNORM(%.10" GNM_FORMAT_f
",%.10" GNM_FORMAT_f
")", lm
, ls
);
3252 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3256 for (i
= 0; i
< N
; i
++) {
3257 gnm_float r
= vals
[i
];
3258 if (!(r
>= 0 && r
<= gnm_pinf
)) {
3259 g_printerr ("Range failure.\n");
3266 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3267 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3268 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3273 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3274 if (!(var
>= 0 && gnm_finite (var
))) {
3275 /* That is a very simplistic test! */
3276 g_printerr ("Var failure.\n");
3281 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3282 if (!gnm_finite (skew
)) {
3283 /* That is a very simplistic test! */
3284 g_printerr ("Skew failure.\n");
3289 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3290 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3291 /* That is a very simplistic test! */
3292 g_printerr ("Kurt failure.\n");
3297 for (i
= 1; i
< nf
; i
++)
3298 fractiles
[i
] = qlnorm (i
/ (double)nf
, lm
, ls
, TRUE
, FALSE
);
3299 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
3303 g_printerr ("OK\n");
3305 add_random_fail ("RANDLOGNORM");
3312 test_random_randrayleigh (int N
)
3314 gnm_float mean
, var
, skew
, kurt
;
3317 gnm_float ls
= 1 / (1 + gnm_pow (random_01 () / 2, 2));
3318 gnm_float mean_target
= ls
* gnm_sqrt (M_PIgnum
/ 2);
3319 gnm_float var_target
= (4 - M_PIgnum
) / 2 * ls
* ls
;
3320 gnm_float skew_target
= 2 * gnm_sqrt (M_PIgnum
) * (M_PIgnum
- 3) /
3321 gnm_pow (4 - M_PIgnum
, 1.5);
3322 gnm_float kurt_target
= gnm_nan
; /* Complicated */
3326 gnm_float fractiles
[10];
3327 const int nf
= G_N_ELEMENTS (fractiles
);
3329 expr
= g_strdup_printf ("=RANDRAYLEIGH(%.10" GNM_FORMAT_f
")", ls
);
3330 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3334 for (i
= 0; i
< N
; i
++) {
3335 gnm_float r
= vals
[i
];
3336 if (!(r
>= 0 && gnm_finite (r
))) {
3337 g_printerr ("Range failure.\n");
3344 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3345 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3346 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3351 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3352 if (!(var
>= 0 && gnm_finite (var
))) {
3353 /* That is a very simplistic test! */
3354 g_printerr ("Var failure.\n");
3359 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3360 if (!gnm_finite (skew
)) {
3361 /* That is a very simplistic test! */
3362 g_printerr ("Skew failure.\n");
3367 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3368 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3369 /* That is a very simplistic test! */
3370 g_printerr ("Kurt failure.\n");
3375 for (i
= 1; i
< nf
; i
++)
3376 fractiles
[i
] = qrayleigh (i
/ (double)nf
, ls
, TRUE
, FALSE
);
3377 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
3381 g_printerr ("OK\n");
3383 add_random_fail ("RANDRAYLEIGH");
3392 const char *test_name
= "test_random";
3393 const int N
= sstest_fast
? 2000 : 20000;
3394 const int High_N
= N
* 10;
3395 const char *single
= g_getenv ("SSTEST_RANDOM");
3397 mark_test_start (test_name
);
3399 #define CHECK1(NAME,C) \
3400 do { if (!single || strcmp(single,#NAME) == 0) test_random_ ## NAME (C); } while (0)
3404 CHECK1 (randuniform
, N
);
3405 CHECK1 (randbeta
, N
);
3406 CHECK1 (randcauchy
, N
);
3407 CHECK1 (randchisq
, N
);
3408 CHECK1 (randexp
, N
);
3409 CHECK1 (randfdist
, N
);
3410 CHECK1 (randgamma
, N
);
3411 CHECK1 (randlog
, N
);
3412 CHECK1 (randlognorm
, N
);
3413 CHECK1 (randnorm
, High_N
);
3414 CHECK1 (randsnorm
, High_N
);
3415 CHECK1 (randtdist
, N
);
3416 CHECK1 (randweibull
, N
);
3417 CHECK1 (randrayleigh
, N
);
3419 CHECK1 (randexppow
, N
);
3420 CHECK1 (randgumbel
, N
);
3421 CHECK1 (randlandau
, N
);
3422 CHECK1 (randlaplace
, N
);
3423 CHECK1 (randlevy
, N
);
3424 CHECK1 (randlogistic
, N
);
3425 CHECK1 (randnormtail
, N
);
3426 CHECK1 (randpareto
, N
);
3427 CHECK1 (randrayleightail
, N
);
3428 CHECK1 (randstdist
, N
);
3432 CHECK1 (randbernoulli
, N
);
3433 CHECK1 (randbetween
, N
);
3434 CHECK1 (randbinom
, N
);
3435 CHECK1 (randdiscrete
, N
);
3436 CHECK1 (randgeom
, High_N
);
3437 CHECK1 (randhyperg
, High_N
);
3438 CHECK1 (randnegbinom
, High_N
);
3439 CHECK1 (randpoisson
, High_N
);
3445 g_printerr ("SUMMARY: FAIL for %s\n\n", random_summary
);
3447 g_printerr ("SUMMARY: OK\n\n");
3449 g_free (random_summary
);
3450 random_summary
= NULL
;
3452 mark_test_end (test_name
);
3455 /* ------------------------------------------------------------------------- */
3457 #define MAYBE_DO(name) if (strcmp (testname, "all") != 0 && strcmp (testname, (name)) != 0) { } else
3460 main (int argc
, char const **argv
)
3462 GOErrorInfo
*plugin_errs
;
3464 GOptionContext
*ocontext
;
3465 GError
*error
= NULL
;
3466 const char *testname
;
3468 /* No code before here, we need to init threads */
3469 argv
= gnm_pre_parse_init (argc
, argv
);
3471 gnm_conf_set_persistence (FALSE
);
3473 ocontext
= g_option_context_new (_("[testname]"));
3474 g_option_context_add_main_entries (ocontext
, sstest_options
, GETTEXT_PACKAGE
);
3475 g_option_context_add_group (ocontext
, gnm_get_option_group ());
3476 g_option_context_parse (ocontext
, &argc
, (gchar
***)&argv
, &error
);
3477 g_option_context_free (ocontext
);
3480 g_printerr (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
3481 error
->message
, g_get_prgname ());
3482 g_error_free (error
);
3486 if (sstest_show_version
) {
3487 g_printerr (_("version '%s'\ndatadir := '%s'\nlibdir := '%s'\n"),
3488 GNM_VERSION_FULL
, gnm_sys_data_dir (), gnm_sys_lib_dir ());
3494 cc
= gnm_cmd_context_stderr_new ();
3495 gnm_plugins_init (GO_CMD_CONTEXT (cc
));
3496 go_plugin_db_activate_plugin_list (
3497 go_plugins_get_available_plugins (), &plugin_errs
);
3499 /* FIXME: What do we want to do here? */
3500 go_error_info_free (plugin_errs
);
3502 g_object_unref (cc
);
3505 if (func_state_file
) {
3506 function_dump_defs (func_state_file
, 0);
3509 if (func_def_file
) {
3510 function_dump_defs (func_def_file
, 1);
3513 if (ext_refs_file
) {
3514 function_dump_defs (ext_refs_file
, 4);
3518 function_dump_defs (samples_file
, 5);
3523 if (!testname
) testname
= "all";
3525 /* ---------------------------------------- */
3527 MAYBE_DO ("test_insdel_rowcol_names") test_insdel_rowcol_names ();
3528 MAYBE_DO ("test_insert_delete") test_insert_delete ();
3529 MAYBE_DO ("test_func_help") test_func_help ();
3530 MAYBE_DO ("test_nonascii_numbers") test_nonascii_numbers ();
3531 MAYBE_DO ("test_random") test_random ();
3533 /* ---------------------------------------- */
3536 gnm_pre_parse_shutdown ();