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"
31 #include <gsf/gsf-input-stdio.h>
32 #include <gsf/gsf-input-textline.h>
33 #include <glib/gstdio.h>
34 #include <glib/gi18n.h>
38 static gboolean sstest_show_version
= FALSE
;
39 static gboolean sstest_fast
= FALSE
;
40 static gchar
*func_def_file
= NULL
;
41 static gchar
*func_state_file
= NULL
;
42 static gchar
*ext_refs_file
= NULL
;
43 static gchar
*samples_file
= NULL
;
45 static GOptionEntry
const sstest_options
[] = {
48 0, G_OPTION_ARG_NONE
, &sstest_fast
,
49 N_("Run fewer iterations"),
55 0, G_OPTION_ARG_FILENAME
, &func_def_file
,
56 N_("Dumps the function definitions"),
62 0, G_OPTION_ARG_FILENAME
, &func_state_file
,
63 N_("Dumps the function definitions"),
69 0, G_OPTION_ARG_FILENAME
, &ext_refs_file
,
70 N_("Dumps web page for function help"),
76 0, G_OPTION_ARG_FILENAME
, &samples_file
,
77 N_("Dumps list of samples in function help"),
83 0, G_OPTION_ARG_NONE
, &sstest_show_version
,
84 N_("Display program version"),
91 /* ------------------------------------------------------------------------- */
93 #define UNICODE_ELLIPSIS "\xe2\x80\xa6"
94 #define F2(func,s) dgettext ((func)->tdomain->str, (s))
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
const *fd
= g_ptr_array_index (defs
, ui
);
127 gboolean any
= FALSE
;
130 for (j
= 0; fd
->help
[j
].type
!= GNM_FUNC_HELP_END
; j
++) {
131 const char *s
= F2(fd
, fd
->help
[j
].text
);
133 switch (fd
->help
[j
].type
) {
134 case GNM_FUNC_HELP_EXTREF
:
137 fprintf (out
, "<!--#if expr=\"${QUERY_STRING} = %s\" -->", fd
->name
);
140 if (strncmp (s
, "wolfram:", 8) == 0) {
141 fprintf (out
, "<!--#set var=\"wolfram\" value=\"%s\" -->", s
+ 8);
143 if (strncmp (s
, "wiki:", 5) == 0) {
145 lang
= split_at_colon (s
+ 5, &page
);
146 fprintf (out
, "<!--#set var=\"wiki_lang\" value=\"%s\" -->", lang
);
147 fprintf (out
, "<!--#set var=\"wiki\" value=\"%s\" -->", page
);
157 fprintf (out
, "<!--#endif\n\n-->");
160 fprintf (out
, "<div class=\"floatflush\">\n");
161 fprintf (out
, "<h1>Online Documentation for \"<!--#echo var=\"QUERY_STRING\" -->\"</h1>\n");
162 fprintf (out
, "<p>When last checked, these sources provided useful information about\n");
163 fprintf (out
, "this function. However, since the links are not controlled by the\n");
164 fprintf (out
, "Gnumeric Team, we cannot guarantee that the links still work. If\n");
165 fprintf (out
, "you find that they do not work, please drop us a line.</p>\n");
166 fprintf (out
, "<ul>");
167 fprintf (out
, "<!--#if expr=\"${wolfram} != none\"-->");
168 fprintf (out
, "<li><a href=\"http://mathworld.wolfram.com/<!--#echo var=\"wolfram\" -->\">Wolfram Mathworld\nentry</a>.</li><!--#endif-->");
169 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-->");
170 fprintf (out
, "<li><a href=\"http://www.google.com/#q=<!--#echo var=\"QUERY_STRING\" -->\">Google Search</a>.</li>");
171 fprintf (out
, "</ul>");
172 fprintf (out
, "</div>\n");
174 fprintf (out
, "<!--#include virtual=\"footer.shtml\" -->\n");
178 csv_quoted_print (FILE *out
, const char *s
)
188 int len
= g_utf8_skip
[(unsigned char)*s
];
189 fprintf (out
, "%-.*s", len
, s
);
197 dump_samples (GPtrArray
*defs
, FILE *out
)
200 GnmFuncGroup
*last_group
= NULL
;
202 for (ui
= 0; ui
< defs
->len
; ui
++) {
203 GnmFunc
const *fd
= g_ptr_array_index (defs
, ui
);
205 const char *last
= NULL
;
206 gboolean has_sample
= FALSE
;
208 if (last_group
!= fd
->fn_group
) {
209 last_group
= fd
->fn_group
;
210 csv_quoted_print (out
, last_group
->display_name
->str
);
214 for (j
= 0; fd
->help
[j
].type
!= GNM_FUNC_HELP_END
; j
++) {
215 const char *s
= fd
->help
[j
].text
;
217 if (fd
->help
[j
].type
!= GNM_FUNC_HELP_EXAMPLES
)
223 * Some of the random numbers functions have duplicate
224 * samples. We don't want the duplicates here.
226 if (s
[0] != '=' || (last
&& strcmp (last
, s
) == 0))
231 csv_quoted_print (out
, fd
->name
);
235 csv_quoted_print (out
, s
);
240 g_printerr ("No samples for %s\n", fd
->name
);
245 cb_dump_usage (GnmFunc
const *fd
, FILE *out
)
247 if (fd
->usage_count
> 0)
248 fprintf (out
, "%d,%s\n", fd
->usage_count
, fd
->name
);
254 func_def_cmp (gconstpointer a
, gconstpointer b
)
256 GnmFunc
const *fda
= *(GnmFunc
const **)a
;
257 GnmFunc
const *fdb
= *(GnmFunc
const **)b
;
259 g_return_val_if_fail (fda
->name
!= NULL
, 0);
260 g_return_val_if_fail (fdb
->name
!= NULL
, 0);
262 if (fda
->fn_group
!= NULL
&& fdb
->fn_group
!= NULL
) {
263 int res
= go_string_cmp (fda
->fn_group
->display_name
,
264 fdb
->fn_group
->display_name
);
269 return g_ascii_strcasecmp (fda
->name
, fdb
->name
);
273 enumerate_functions (gboolean filter
)
275 GPtrArray
*res
= gnm_func_enumerate ();
278 for (ui
= 0; ui
< res
->len
; ui
++) {
279 GnmFunc
*fd
= g_ptr_array_index (res
, ui
);
283 strcmp (fd
->name
, "perl_adder") == 0 ||
284 strcmp (fd
->name
, "perl_date") == 0 ||
285 strcmp (fd
->name
, "perl_sed") == 0 ||
286 strcmp (fd
->name
, "py_capwords") == 0 ||
287 strcmp (fd
->name
, "py_printf") == 0 ||
288 strcmp (fd
->name
, "py_bitand") == 0)) {
289 g_ptr_array_remove_index_fast (res
, ui
);
293 gnm_func_load_if_stub (fd
);
296 g_ptr_array_sort (res
, func_def_cmp
);
302 * function_dump_defs :
306 * A generic utility routine to operate on all funtion defs
307 * in various ways. @dump_type will change/extend as needed
309 * 0 : www.gnumeric.org's function.shtml page
312 * 3 : dump function usage count
314 * 5 : all sample expressions
317 function_dump_defs (char const *filename
, int dump_type
)
323 GnmFuncGroup
const *group
= NULL
;
325 g_return_if_fail (filename
!= NULL
);
327 if ((output_file
= g_fopen (filename
, "w")) == NULL
){
328 g_printerr (_("Cannot create file %s\n"), filename
);
332 if (dump_type
== 3) {
333 GPtrArray
*funcs
= enumerate_functions (FALSE
);
334 g_ptr_array_foreach (funcs
, (GFunc
)cb_dump_usage
, output_file
);
335 g_ptr_array_free (funcs
, TRUE
);
336 fclose (output_file
);
340 /* TODO : Use the translated names and split by fn_group. */
341 ordered
= enumerate_functions (TRUE
);
343 if (dump_type
== 4) {
344 dump_externals (ordered
, output_file
);
345 g_ptr_array_free (ordered
, TRUE
);
346 fclose (output_file
);
350 if (dump_type
== 5) {
351 dump_samples (ordered
, output_file
);
352 g_ptr_array_free (ordered
, TRUE
);
353 fclose (output_file
);
357 if (dump_type
== 0) {
359 for (i
= 0; i
< ordered
->len
; i
++) {
360 GnmFunc
const *fd
= g_ptr_array_index (ordered
, i
);
361 switch (fd
->impl_status
) {
362 case GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
:
369 fprintf (output_file
,
370 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
371 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
372 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
373 "<!-- DEFINE current=Home -->\n"
374 "<!-- MARKER: start-header -->\n"
376 "<title>Gnumeric</title>\n"
377 "<link rel=\"stylesheet\" href=\"style/style.css\" type=\"text/css\" />\n"
378 "<link rel=\"icon\" type=\"image/png\" href=\"logo.png\" />\n"
379 "<style type=\"text/css\"><!--\n"
380 " div.functiongroup {\n"
381 " margin-top: 1em;\n"
382 " margin-bottom: 1em;\n"
384 " table.functiongroup {\n"
385 " border-style: solid;\n"
386 " border-width: 1px;\n"
387 " border-spacing: 0px;\n"
390 " font-weight: bold;\n"
391 " font-size: 14pt;\n"
392 " border-style: solid;\n"
393 " border-width: 1px;\n"
394 " text-align: center;\n"
396 " tr.function td {\n"
397 " border: solid 1px;\n"
399 " td.testing-unknown { background: #ffffff; }\n"
400 " td.testing-nosuite { background: #ff7662; }\n"
401 " td.testing-basic { background: #fff79d; }\n"
402 " td.testing-exhaustive { background: #aef8b5; }\n"
403 " td.testing-devel { background: #ff6c00; }\n"
404 " td.imp-exists { background: #ffffff; }\n"
405 " td.imp-no { background: #ff7662; }\n"
406 " td.imp-subset { background: #fff79d; }\n"
407 " td.imp-complete { background: #aef8b5; }\n"
408 " td.imp-superset { background: #16e49e; }\n"
409 " td.imp-subsetext { background: #59fff2; }\n"
410 " td.imp-devel { background: #ff6c00; }\n"
411 " td.imp-gnumeric { background: #44be18; }\n"
415 "<div id=\"wrap\">\n"
416 " <a href=\"/\"><div id=\"header\">\n"
417 " <h1 id=\"logo-text\"><span>Gnumeric</span></h1>\n"
418 " <p id=\"slogan\">Free, Fast, Accurate — Pick Any Three!</p>\n"
419 " <img id=\"logo\" src=\"gnumeric.png\" alt=\"logo\" class=\"float-right\"/>\n"
422 " <div id=\"nav\">\n"
424 " <li id=\"current\"><a href=\"/\">Home</a></li>\n"
425 " <li><a href=\"development.html\">Development</a></li>\n"
426 " <li><a href=\"contact.html\">Contact</a></li>\n"
430 " <div id=\"content-wrap\">\n"
431 " <!-- MARKER: start-main -->\n"
432 " <div id=\"main\">\n"
433 " <div class=\"generalitem\">\n"
434 " <h2><span class=\"gnumeric-bullet\"></span>Gnumeric Sheet Functions</h2>\n"
435 " <p>Gnumeric currently has %d functions for use in spreadsheets.\n"
436 " %d of these are unique to Gnumeric.</p>\n",
437 ordered
->len
, unique
);
440 for (i
= 0; i
< ordered
->len
; i
++) {
441 GnmFunc
const *fd
= g_ptr_array_index (ordered
, i
);
443 // Skip internal-use function
444 if (g_ascii_strcasecmp (fd
->name
, "TABLE") == 0)
447 // Skip demo function
448 if (g_ascii_strcasecmp (fd
->name
, "ATL_LAST") == 0)
451 if (dump_type
== 1) {
453 gboolean first_arg
= TRUE
;
454 GString
*syntax
= g_string_new (NULL
);
455 GString
*arg_desc
= g_string_new (NULL
);
456 GString
*desc
= g_string_new (NULL
);
457 GString
*odf
= g_string_new (NULL
);
458 GString
*excel
= g_string_new (NULL
);
459 GString
*note
= g_string_new (NULL
);
460 GString
*seealso
= g_string_new (NULL
);
463 fprintf (output_file
, "@CATEGORY=%s\n",
464 F2(fd
, fd
->fn_group
->display_name
->str
));
466 fd
->help
[i
].type
!= GNM_FUNC_HELP_END
;
468 switch (fd
->help
[i
].type
) {
469 case GNM_FUNC_HELP_NAME
: {
471 char *name
= split_at_colon (F2(fd
, fd
->help
[i
].text
), &short_desc
);
472 fprintf (output_file
,
475 fprintf (output_file
,
478 g_string_append (syntax
, name
);
479 g_string_append_c (syntax
, '(');
483 case GNM_FUNC_HELP_SEEALSO
:
484 if (seealso
->len
> 0)
485 g_string_append (seealso
, ",");
486 g_string_append (seealso
, F2(fd
, fd
->help
[i
].text
));
488 case GNM_FUNC_HELP_DESCRIPTION
:
490 g_string_append (desc
, "\n");
491 g_string_append (desc
, F2(fd
, fd
->help
[i
].text
));
493 case GNM_FUNC_HELP_NOTE
:
495 g_string_append (note
, " ");
496 g_string_append (note
, F2(fd
, fd
->help
[i
].text
));
498 case GNM_FUNC_HELP_ARG
: {
500 char *name
= split_at_colon (F2(fd
, fd
->help
[i
].text
), &argdesc
);
504 g_string_append_c (syntax
, go_locale_get_arg_sep ());
505 g_string_append (syntax
, name
);
507 g_string_append_printf (arg_desc
,
513 /* FIXME: Optional args? */
516 case GNM_FUNC_HELP_ODF
:
518 g_string_append (odf
, " ");
519 g_string_append (odf
, F2(fd
, fd
->help
[i
].text
));
521 case GNM_FUNC_HELP_EXCEL
:
523 g_string_append (excel
, " ");
524 g_string_append (excel
, F2(fd
, fd
->help
[i
].text
));
527 case GNM_FUNC_HELP_EXTREF
:
529 case GNM_FUNC_HELP_EXAMPLES
:
531 case GNM_FUNC_HELP_END
:
536 function_def_count_args (fd
, &min
, &max
);
538 fprintf (output_file
,
539 "@SYNTAX=%s," UNICODE_ELLIPSIS
")\n",
542 fprintf (output_file
, "@SYNTAX=%s)\n",
545 if (arg_desc
->len
> 0)
546 fprintf (output_file
, "@ARGUMENTDESCRIPTION=%s", arg_desc
->str
);
548 fprintf (output_file
, "@DESCRIPTION=%s\n", desc
->str
);
550 fprintf (output_file
, "@NOTE=%s\n", note
->str
);
552 fprintf (output_file
, "@EXCEL=%s\n", excel
->str
);
554 fprintf (output_file
, "@ODF=%s\n", odf
->str
);
555 if (seealso
->len
> 0)
556 fprintf (output_file
, "@SEEALSO=%s\n", seealso
->str
);
558 g_string_free (syntax
, TRUE
);
559 g_string_free (arg_desc
, TRUE
);
560 g_string_free (desc
, TRUE
);
561 g_string_free (odf
, TRUE
);
562 g_string_free (excel
, TRUE
);
563 g_string_free (note
, TRUE
);
564 g_string_free (seealso
, TRUE
);
566 fputc ('\n', output_file
);
567 } else if (dump_type
== 0) {
571 } const testing
[] = {
572 { "Unknown", "testing-unknown" },
573 { "No Testsuite", "testing-nosuite" },
574 { "Basic", "testing-basic" },
575 { "Exhaustive", "testing-exhaustive" },
576 { "Under Development", "testing-devel" }
581 } const implementation
[] = {
582 { "Exists", "imp-exists" },
583 { "Unimplemented", "imp-no" },
584 { "Subset", "imp-subset" },
585 { "Complete", "imp-complete" },
586 { "Superset", "imp-superset" },
587 { "Subset with_extensions", "imp-subsetext" },
588 { "Under development", "imp-devel" },
589 { "Unique to Gnumeric", "imp-gnumeric" },
591 if (group
!= fd
->fn_group
) {
592 if (group
) fprintf (output_file
, "</table></div>\n");
593 group
= fd
->fn_group
;
594 fprintf (output_file
,
596 "<div class=\"functiongroup\"><table class=\"functiongroup\">\n"
597 "<tr class=\"header\">"
599 "<td>Implementation</td>"
602 group
->display_name
->str
);
604 up
= g_ascii_strup (fd
->name
, -1);
605 catname
= g_strdup (group
->display_name
->str
);
606 while (strchr (catname
, ' '))
607 *strchr (catname
, ' ') = '_';
608 fprintf (output_file
, "<tr class=\"function\">\n");
609 fprintf (output_file
,
610 "<td><a href =\"https://help.gnome.org/users/gnumeric/stable/gnumeric.html#gnumeric-function-%s\">%s</a></td>\n",
614 fprintf (output_file
,
615 "<td class=\"%s\"><a href=\"mailto:gnumeric-list@gnome.org?subject=Re: %s implementation\">%s</a></td>\n",
616 implementation
[fd
->impl_status
].klass
,
618 implementation
[fd
->impl_status
].name
);
619 fprintf (output_file
,
620 "<td class=\"%s\"><a href=\"mailto:gnumeric-list@gnome.org?subject=Re: %s testing\">%s</a></td>\n",
621 testing
[fd
->test_status
].klass
,
623 testing
[fd
->test_status
].name
);
624 fprintf (output_file
,"</tr>\n");
627 if (dump_type
== 0) {
628 if (group
) fprintf (output_file
, "</table></div>\n");
629 fprintf (output_file
,
632 " <!-- MARKER: end-main -->\n"
633 " <!-- MARKER: start-sidebar -->\n"
634 " <!-- MARKER: end-sidebar -->\n"
641 g_ptr_array_free (ordered
, TRUE
);
642 fclose (output_file
);
645 /* ------------------------------------------------------------------------- */
648 mark_test_start (const char *name
)
650 g_printerr ("-----------------------------------------------------------------------------\nStart: %s\n-----------------------------------------------------------------------------\n\n", name
);
654 mark_test_end (const char *name
)
656 g_printerr ("End: %s\n\n", name
);
660 cb_collect_names (G_GNUC_UNUSED
const char *name
, GnmNamedExpr
*nexpr
, GSList
**names
)
662 *names
= g_slist_prepend (*names
, nexpr
);
666 fetch_cell (Sheet
*sheet
, const char *where
)
669 gboolean ok
= cellpos_parse (where
,
670 gnm_sheet_get_size (sheet
),
672 g_return_val_if_fail (ok
, NULL
);
673 return sheet_cell_fetch (sheet
, cp
.col
, cp
.row
);
677 set_cell (Sheet
*sheet
, const char *where
, const char *what
)
679 GnmCell
*cell
= fetch_cell (sheet
, where
);
681 gnm_cell_set_text (cell
, what
);
685 dump_sheet (Sheet
*sheet
, const char *header
)
687 GPtrArray
*cells
= sheet_cells (sheet
, NULL
);
691 g_printerr ("# %s\n", header
);
692 for (ui
= 0; ui
< cells
->len
; ui
++) {
693 GnmCell
*cell
= g_ptr_array_index (cells
, ui
);
694 char *txt
= gnm_cell_get_entered_text (cell
);
695 g_printerr ("%s: %s\n",
696 cellpos_as_string (&cell
->pos
), txt
);
699 g_ptr_array_free (cells
, TRUE
);
704 dump_names (Workbook
*wb
)
706 GSList
*l
, *names
= NULL
;
708 workbook_foreach_name (wb
, FALSE
, (GHFunc
)cb_collect_names
, &names
);
709 names
= g_slist_sort (names
, (GCompareFunc
)expr_name_cmp_by_name
);
711 g_printerr ("Dumping names...\n");
712 for (l
= names
; l
; l
= l
->next
) {
713 GnmNamedExpr
*nexpr
= l
->data
;
714 GnmConventionsOut out
;
716 out
.accum
= g_string_new (NULL
);
717 out
.pp
= &nexpr
->pos
;
718 out
.convs
= gnm_conventions_default
;
720 g_string_append (out
.accum
, "Scope=");
722 g_string_append (out
.accum
, out
.pp
->sheet
->name_quoted
);
724 g_string_append (out
.accum
, "Global");
726 g_string_append (out
.accum
, " Name=");
727 go_strescape (out
.accum
, expr_name_name (nexpr
));
729 g_string_append (out
.accum
, " Expr=");
730 gnm_expr_top_as_gstring (nexpr
->texpr
, &out
);
732 g_printerr ("%s\n", out
.accum
->str
);
733 g_string_free (out
.accum
, TRUE
);
735 g_printerr ("Dumping names... Done\n");
737 g_slist_free (names
);
741 define_name (const char *name
, const char *expr_txt
, gpointer scope
)
744 GnmExprTop
const *texpr
;
745 GnmNamedExpr
const *nexpr
;
746 GnmConventions
const *convs
;
748 if (IS_SHEET (scope
)) {
749 parse_pos_init_sheet (&pos
, scope
);
750 convs
= sheet_get_conventions (pos
.sheet
);
752 parse_pos_init (&pos
, WORKBOOK (scope
), NULL
, 0, 0);
753 convs
= gnm_conventions_default
;
756 texpr
= gnm_expr_parse_str (expr_txt
, &pos
,
757 GNM_EXPR_PARSE_DEFAULT
,
760 g_printerr ("Failed to parse %s for name %s\n",
765 nexpr
= expr_name_add (&pos
, name
, texpr
, NULL
, TRUE
, NULL
);
767 g_printerr ("Failed to add name %s\n", name
);
771 test_insdel_rowcol_names (void)
774 Sheet
*sheet1
,*sheet2
;
775 const char *test_name
= "test_insdel_rowcol_names";
779 mark_test_start (test_name
);
781 wb
= workbook_new ();
782 sheet1
= workbook_sheet_add (wb
, -1,
783 GNM_DEFAULT_COLS
, GNM_DEFAULT_ROWS
);
784 sheet2
= workbook_sheet_add (wb
, -1,
785 GNM_DEFAULT_COLS
, GNM_DEFAULT_ROWS
);
787 define_name ("Print_Area", "Sheet1!$A$1:$IV$65536", sheet1
);
788 define_name ("Print_Area", "Sheet2!$A$1:$IV$65536", sheet2
);
790 define_name ("NAMEGA1", "A1", wb
);
791 define_name ("NAMEG2", "$A$14+Sheet1!$A$14+Sheet2!$A$14", wb
);
793 define_name ("NAMEA1", "A1", sheet1
);
794 define_name ("NAMEA2", "A2", sheet1
);
795 define_name ("NAMEA1ABS", "$A$1", sheet1
);
796 define_name ("NAMEA2ABS", "$A$2", sheet1
);
800 for (i
= 3; i
>= 0; i
--) {
801 g_printerr ("About to insert before column %s on %s\n",
802 col_name (i
), sheet1
->name_unquoted
);
803 sheet_insert_cols (sheet1
, i
, 12, &undo
, NULL
);
805 g_printerr ("Undoing.\n");
806 go_undo_undo_with_data (undo
, NULL
);
807 g_object_unref (undo
);
808 g_printerr ("Done.\n");
811 for (i
= 3; i
>= 0; i
--) {
812 g_printerr ("About to insert before column %s on %s\n",
813 col_name (i
), sheet2
->name_unquoted
);
814 sheet_insert_cols (sheet2
, i
, 12, &undo
, NULL
);
816 g_printerr ("Undoing.\n");
817 go_undo_undo_with_data (undo
, NULL
);
818 g_object_unref (undo
);
819 g_printerr ("Done.\n");
822 for (i
= 3; i
>= 0; i
--) {
823 g_printerr ("About to delete column %s on %s\n",
824 col_name (i
), sheet1
->name_unquoted
);
825 sheet_delete_cols (sheet1
, i
, 1, &undo
, NULL
);
827 g_printerr ("Undoing.\n");
828 go_undo_undo_with_data (undo
, NULL
);
829 g_object_unref (undo
);
830 g_printerr ("Done.\n");
835 mark_test_end (test_name
);
838 /* ------------------------------------------------------------------------- */
841 test_insert_delete (void)
843 const char *test_name
= "test_insert_delete";
847 GOUndo
*u
= NULL
, *u1
;
849 mark_test_start (test_name
);
851 wb
= workbook_new ();
852 sheet1
= workbook_sheet_add (wb
, -1,
853 GNM_DEFAULT_COLS
, GNM_DEFAULT_ROWS
);
854 set_cell (sheet1
, "B2", "=D4+1");
855 set_cell (sheet1
, "D2", "=if(TRUE,B2,2)");
857 dump_sheet (sheet1
, "Init");
859 for (i
= 5; i
>= 0; i
--) {
860 g_printerr ("# About to insert column before %s\n",
862 sheet_insert_cols (sheet1
, i
, 1, &u1
, NULL
);
863 u
= go_undo_combine (u
, u1
);
864 dump_sheet (sheet1
, NULL
);
867 for (i
= 5; i
>= 0; i
--) {
868 g_printerr ("# About to insert row before %s\n",
870 sheet_insert_rows (sheet1
, i
, 1, &u1
, NULL
);
871 u
= go_undo_combine (u
, u1
);
872 dump_sheet (sheet1
, NULL
);
878 dump_sheet (sheet1
, "Undo the lot");
880 for (i
= 5; i
>= 0; i
--) {
881 g_printerr ("# About to delete column %s\n",
883 sheet_delete_cols (sheet1
, i
, 1, &u1
, NULL
);
884 u
= go_undo_combine (u
, u1
);
885 dump_sheet (sheet1
, NULL
);
888 for (i
= 5; i
>= 0; i
--) {
889 g_printerr ("# About to delete row %s\n",
891 sheet_delete_rows (sheet1
, i
, 1, &u1
, NULL
);
892 u
= go_undo_combine (u
, u1
);
893 dump_sheet (sheet1
, NULL
);
899 dump_sheet (sheet1
, "Undo the lot");
903 mark_test_end (test_name
);
906 /* ------------------------------------------------------------------------- */
908 /* ------------------------------------------------------------------------- */
911 check_help_expression (const char *text
, GnmFunc
const *fd
)
913 GnmConventions
const *convs
= gnm_conventions_default
;
915 GnmExprTop
const *texpr
;
919 /* Create a dummy workbook with no sheets for interesting effects. */
920 wb
= workbook_new ();
921 parse_pos_init (&pp
, wb
, NULL
, 0, 0);
923 parse_error_init (&perr
);
925 texpr
= gnm_expr_parse_str (text
, &pp
,
926 GNM_EXPR_PARSE_DEFAULT
,
930 g_printerr ("Error parsing %s: %s\n",
931 text
, perr
.err
->message
);
933 parse_error_free (&perr
);
939 gnm_expr_top_unref (texpr
);
944 check_argument_refs (const char *text
, GnmFunc
const *fd
)
946 if (fd
->fn_type
!= GNM_FUNC_TYPE_ARGS
)
950 const char *at
= strchr (text
, '@');
958 text
= strchr (at
+ 2, '}');
961 argname
= g_strndup (at
+ 2, text
- at
- 2);
963 for (i
= 0; TRUE
; i
++) {
964 char *thisarg
= function_def_get_arg_name (fd
, i
);
970 found
= strcmp (argname
, thisarg
) == 0;
981 gnm_func_sanity_check1 (GnmFunc
const *fd
)
983 GnmFuncHelp
const *h
;
984 int counts
[(int)GNM_FUNC_HELP_ODF
+ 1];
986 size_t nlen
= strlen (fd
->name
);
989 allargs
= g_hash_table_new_full
990 (g_str_hash
, g_str_equal
, (GDestroyNotify
)g_free
, NULL
);
992 memset (counts
, 0, sizeof (counts
));
993 for (h
= fd
->help
; h
->type
!= GNM_FUNC_HELP_END
; h
++) {
994 g_assert (h
->type
<= GNM_FUNC_HELP_ODF
);
997 if (!g_utf8_validate (h
->text
, -1, NULL
)) {
998 g_printerr ("%s: Invalid UTF-8 in type %i\n",
1005 case GNM_FUNC_HELP_NAME
:
1006 if (g_ascii_strncasecmp (fd
->name
, h
->text
, nlen
) ||
1007 h
->text
[nlen
] != ':') {
1008 g_printerr ("%s: Invalid NAME record\n",
1011 } else if (h
->text
[nlen
+ 1] == ' ') {
1012 g_printerr ("%s: Unwanted space in NAME record\n",
1015 } else if (h
->text
[strlen (h
->text
) - 1] == '.') {
1016 g_printerr ("%s: Unwanted period in NAME record\n",
1021 case GNM_FUNC_HELP_ARG
: {
1022 const char *aend
= strchr (h
->text
, ':');
1025 if (aend
== NULL
|| aend
== h
->text
) {
1026 g_printerr ("%s: Invalid ARG record\n",
1032 if (aend
[1] == ' ') {
1033 g_printerr ("%s: Unwanted space in ARG record\n",
1037 if (aend
[1] == '\0') {
1038 g_printerr ("%s: Empty ARG record\n",
1042 if (h
->text
[strlen (h
->text
) - 1] == '.') {
1043 g_printerr ("%s: Unwanted period in ARG record\n",
1047 if (check_argument_refs (aend
+ 1, fd
)) {
1048 g_printerr ("%s: Invalid argument reference in argument\n",
1052 argname
= g_strndup (h
->text
, aend
- h
->text
);
1053 if (g_hash_table_lookup (allargs
, argname
)) {
1054 g_printerr ("%s: Duplicate argument name %s\n",
1058 g_printerr ("%s\n", h
->text
);
1060 g_hash_table_insert (allargs
, argname
, argname
);
1063 case GNM_FUNC_HELP_DESCRIPTION
: {
1066 if (check_argument_refs (h
->text
, fd
)) {
1067 g_printerr ("%s: Invalid argument reference in description\n",
1073 while (g_ascii_isupper (*p
) ||
1074 (p
!= h
->text
&& (*p
== '_' ||
1076 g_ascii_isdigit (*p
))))
1080 strncmp (h
->text
, "CP1252", 6) != 0) {
1081 if (g_ascii_strncasecmp (h
->text
, fd
->name
, nlen
)) {
1082 g_printerr ("%s: Wrong function name in description\n",
1090 case GNM_FUNC_HELP_EXAMPLES
:
1091 if (h
->text
[0] == '=') {
1092 if (check_help_expression (h
->text
+ 1, fd
)) {
1093 g_printerr ("%s: Invalid EXAMPLES record\n",
1104 g_hash_table_destroy (allargs
);
1106 if (fd
->fn_type
== GNM_FUNC_TYPE_ARGS
) {
1107 int n
= counts
[GNM_FUNC_HELP_ARG
];
1108 if (n
!= fd
->fn
.args
.max_args
) {
1109 g_printerr ("%s: Help for %d args, but takes %d-%d\n",
1111 fd
->fn
.args
.min_args
, fd
->fn
.args
.max_args
);
1117 if (counts
[GNM_FUNC_HELP_DESCRIPTION
] != 1) {
1118 g_printerr ("%s: Help has %d descriptions.\n",
1119 fd
->name
, counts
[GNM_FUNC_HELP_DESCRIPTION
]);
1124 if (counts
[GNM_FUNC_HELP_NAME
] != 1) {
1125 g_printerr ("%s: Help has %d NAME records.\n",
1126 fd
->name
, counts
[GNM_FUNC_HELP_NAME
]);
1130 if (counts
[GNM_FUNC_HELP_EXCEL
] > 1) {
1131 g_printerr ("%s: Help has %d Excel notes.\n",
1132 fd
->name
, counts
[GNM_FUNC_HELP_EXCEL
]);
1136 if (counts
[GNM_FUNC_HELP_ODF
] > 1) {
1137 g_printerr ("%s: Help has %d ODF notes.\n",
1138 fd
->name
, counts
[GNM_FUNC_HELP_ODF
]);
1146 gnm_func_sanity_check (void)
1152 ordered
= enumerate_functions (TRUE
);
1154 for (ui
= 0; ui
< ordered
->len
; ui
++) {
1155 GnmFunc
const *fd
= g_ptr_array_index (ordered
, ui
);
1156 if (gnm_func_sanity_check1 (fd
))
1160 g_ptr_array_free (ordered
, TRUE
);
1166 test_func_help (void)
1168 const char *test_name
= "test_func_help";
1171 mark_test_start (test_name
);
1173 res
= gnm_func_sanity_check ();
1174 g_printerr ("Result = %d\n", res
);
1176 mark_test_end (test_name
);
1179 /* ------------------------------------------------------------------------- */
1182 test_strtol_ok (const char *s
, long l
, size_t expected_len
)
1188 l2
= gnm_utf8_strtol (s
, &end
);
1191 if (end
!= s
+ expected_len
) {
1192 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1196 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1199 if (save_errno
!= 0) {
1200 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1208 test_strtol_noconv (const char *s
)
1214 l
= gnm_utf8_strtol (s
, &end
);
1218 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1222 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1225 if (save_errno
!= 0) {
1226 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1234 test_strtol_overflow (const char *s
, gboolean pos
)
1239 size_t expected_len
= strlen (s
);
1241 l
= gnm_utf8_strtol (s
, &end
);
1244 if (end
!= s
+ expected_len
) {
1245 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1248 if (l
!= (pos
? LONG_MAX
: LONG_MIN
)) {
1249 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1252 if (save_errno
!= ERANGE
) {
1253 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1261 test_strtol_reverse (long l
)
1263 char buffer
[4*sizeof(l
) + 4];
1266 sprintf(buffer
, "%ld", l
);
1267 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
));
1269 sprintf(buffer
, " %ld", l
);
1270 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
));
1272 sprintf(buffer
, "\xc2\xa0\n\t%ld", l
);
1273 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
));
1275 sprintf(buffer
, " \t%ldx", l
);
1276 res
|= test_strtol_ok (buffer
, l
, strlen (buffer
) - 1);
1282 test_strtod_ok (const char *s
, double d
, size_t expected_len
)
1288 d2
= gnm_utf8_strto (s
, &end
);
1291 if (end
!= s
+ expected_len
) {
1292 g_printerr ("Unexpect conversion end of [%s]\n", s
);
1296 g_printerr ("Unexpect conversion result of [%s]\n", s
);
1299 if (save_errno
!= 0) {
1300 g_printerr ("Unexpect conversion errno of [%s]\n", s
);
1308 test_nonascii_numbers (void)
1310 const char *test_name
= "test_nonascii_numbers";
1313 mark_test_start (test_name
);
1315 res
|= test_strtol_reverse (0);
1316 res
|= test_strtol_reverse (1);
1317 res
|= test_strtol_reverse (-1);
1318 res
|= test_strtol_reverse (LONG_MIN
);
1319 res
|= test_strtol_reverse (LONG_MIN
+ 1);
1320 res
|= test_strtol_reverse (LONG_MAX
- 1);
1322 res
|= test_strtol_ok ("\xef\xbc\x8d\xef\xbc\x91", -1, 6);
1323 res
|= test_strtol_ok ("\xc2\xa0+1", 1, 4);
1325 res
|= test_strtol_ok ("000000000000000000000000000000", 0, 30);
1327 res
|= test_strtol_noconv ("");
1328 res
|= test_strtol_noconv (" ");
1329 res
|= test_strtol_noconv (" +");
1330 res
|= test_strtol_noconv (" -");
1331 res
|= test_strtol_noconv (" .00");
1332 res
|= test_strtol_noconv (" e0");
1333 res
|= test_strtol_noconv ("--0");
1334 res
|= test_strtol_noconv ("+-0");
1335 res
|= test_strtol_noconv ("+ 0");
1336 res
|= test_strtol_noconv ("- 0");
1339 char buffer
[4 * sizeof (long) + 2];
1341 sprintf (buffer
, "-%lu", 1 + (unsigned long)LONG_MIN
);
1342 res
|= test_strtol_overflow (buffer
, FALSE
);
1343 sprintf (buffer
, "-%lu", 10 + (unsigned long)LONG_MIN
);
1344 res
|= test_strtol_overflow (buffer
, FALSE
);
1346 sprintf (buffer
, "%lu", 1 + (unsigned long)LONG_MAX
);
1347 res
|= test_strtol_overflow (buffer
, TRUE
);
1348 sprintf (buffer
, "%lu", 10 + (unsigned long)LONG_MAX
);
1349 res
|= test_strtol_overflow (buffer
, TRUE
);
1352 /* -------------------- */
1354 res
|= test_strtod_ok ("0", 0, 1);
1355 res
|= test_strtod_ok ("1", 1, 1);
1356 res
|= test_strtod_ok ("-1", -1, 2);
1357 res
|= test_strtod_ok ("+1", 1, 2);
1358 res
|= test_strtod_ok (" +1", 1, 3);
1359 res
|= test_strtod_ok ("\xc2\xa0+1", 1, 4);
1360 res
|= test_strtod_ok ("\xc2\xa0+1x", 1, 4);
1361 res
|= test_strtod_ok ("\xc2\xa0+1e", 1, 4);
1362 res
|= test_strtod_ok ("\xc2\xa0+1e+", 1, 4);
1363 res
|= test_strtod_ok ("\xc2\xa0+1e+0", 1, 7);
1364 res
|= test_strtod_ok ("-1e1", -10, 4);
1365 res
|= test_strtod_ok ("100e-2", 1, 6);
1366 res
|= test_strtod_ok ("100e+2", 10000, 6);
1367 res
|= test_strtod_ok ("1x0p0", 1, 1);
1368 res
|= test_strtod_ok ("+inf", gnm_pinf
, 4);
1369 res
|= test_strtod_ok ("-inf", gnm_ninf
, 4);
1370 res
|= test_strtod_ok ("1.25", 1.25, 4);
1371 res
|= test_strtod_ok ("1.25e1", 12.5, 6);
1372 res
|= test_strtod_ok ("12.5e-1", 1.25, 7);
1374 g_printerr ("Result = %d\n", res
);
1376 mark_test_end (test_name
);
1379 /* ------------------------------------------------------------------------- */
1381 static char *random_summary
= NULL
;
1384 add_random_fail (const char *s
)
1386 if (random_summary
) {
1387 char *t
= g_strconcat (random_summary
, ", ", s
, NULL
);
1388 g_free (random_summary
);
1391 random_summary
= g_strdup (s
);
1395 define_cell (Sheet
*sheet
, int c
, int r
, const char *expr
)
1397 GnmCell
*cell
= sheet_cell_fetch (sheet
, c
, r
);
1398 sheet_cell_set_text (cell
, expr
, NULL
);
1401 #define GET_PROB(i_) ((i_) <= 0 ? 0 : ((i_) >= nf ? 1 : probs[(i_)]))
1404 rand_fractile_test (gnm_float
const *vals
, int N
, int nf
,
1405 gnm_float
const *fractiles
, gnm_float
const *probs
)
1407 gnm_float f
= 1.0 / nf
;
1408 int *fractilecount
= g_new (int, nf
+ 1);
1409 int *expected
= g_new (int, nf
+ 1);
1412 gboolean debug
= TRUE
;
1415 g_printerr ("Bin upper limit:");
1416 for (i
= 1; i
<= nf
; i
++) {
1417 gnm_float U
= (i
== nf
) ? gnm_pinf
: fractiles
[i
];
1418 g_printerr ("%s%" GNM_FORMAT_g
,
1419 (i
== 1) ? " " : ", ",
1425 if (debug
&& probs
) {
1426 g_printerr ("Cumulative probabilities:");
1427 for (i
= 1; i
<= nf
; i
++)
1428 g_printerr ("%s%.1" GNM_FORMAT_f
"%%",
1429 (i
== 1) ? " " : ", ", 100 * GET_PROB (i
));
1433 for (i
= 1; i
< nf
- 1; i
++) {
1434 if (!(fractiles
[i
] <= fractiles
[i
+ 1])) {
1435 g_printerr ("Severe fractile ordering problem.\n");
1439 if (probs
&& !(probs
[i
] <= probs
[i
+ 1])) {
1440 g_printerr ("Severe cumulative probabilities ordering problem.\n");
1444 if (probs
&& (probs
[1] < 0 || probs
[nf
- 1] > 1)) {
1445 g_printerr ("Severe cumulative probabilities range problem.\n");
1449 for (i
= 0; i
<= nf
; i
++)
1450 fractilecount
[i
] = 0;
1452 for (i
= 0; i
< N
; i
++) {
1453 gnm_float r
= vals
[i
];
1455 for (j
= 1; j
< nf
; j
++)
1456 if (r
<= fractiles
[j
])
1460 g_printerr ("Fractile counts:");
1461 for (i
= 1; i
<= nf
; i
++)
1462 g_printerr ("%s%d", (i
== 1) ? " " : ", ", fractilecount
[i
]);
1466 g_printerr ("Expected counts:");
1467 for (i
= 1; i
<= nf
; i
++) {
1468 gnm_float p
= GET_PROB (i
) - GET_PROB (i
-1);
1469 expected
[i
] = gnm_floor (p
* N
+ 0.5);
1470 g_printerr ("%s%d", (i
== 1) ? " " : ", ", expected
[i
]);
1474 gnm_float T
= f
* N
;
1475 g_printerr ("Expected count in each fractile: %.10" GNM_FORMAT_g
"\n", T
);
1476 for (i
= 0; i
<= nf
; i
++)
1480 for (i
= 1; i
<= nf
; i
++) {
1481 gnm_float T
= expected
[i
];
1482 if (!(gnm_abs (fractilecount
[i
] - T
) <= 4 * gnm_sqrt (T
))) {
1483 g_printerr ("Fractile test failure for bin %d.\n", i
);
1488 g_free (fractilecount
);
1497 test_random_1 (int N
, const char *expr
,
1498 gnm_float
*mean
, gnm_float
*var
,
1499 gnm_float
*skew
, gnm_float
*kurt
)
1501 Workbook
*wb
= workbook_new ();
1503 gnm_float
*res
= g_new (gnm_float
, N
);
1506 int cols
= 2, rows
= N
;
1508 g_printerr ("Testing %s\n", expr
);
1510 gnm_sheet_suggest_size (&cols
, &rows
);
1511 sheet
= workbook_sheet_add (wb
, -1, cols
, rows
);
1513 for (i
= 0; i
< N
; i
++)
1514 define_cell (sheet
, 0, i
, expr
);
1516 s
= g_strdup_printf ("=average(a1:a%d)", N
);
1517 define_cell (sheet
, 1, 0, s
);
1520 s
= g_strdup_printf ("=var(a1:a%d)", N
);
1521 define_cell (sheet
, 1, 1, s
);
1524 s
= g_strdup_printf ("=skew(a1:a%d)", N
);
1525 define_cell (sheet
, 1, 2, s
);
1528 s
= g_strdup_printf ("=kurt(a1:a%d)", N
);
1529 define_cell (sheet
, 1, 3, s
);
1532 /* Force recalc of all dirty cells even in manual mode. */
1533 workbook_recalc (sheet
->workbook
);
1535 for (i
= 0; i
< N
; i
++)
1536 res
[i
] = value_get_as_float (sheet_cell_get (sheet
, 0, i
)->value
);
1537 *mean
= value_get_as_float (sheet_cell_get (sheet
, 1, 0)->value
);
1538 g_printerr ("Mean: %.10" GNM_FORMAT_g
"\n", *mean
);
1540 *var
= value_get_as_float (sheet_cell_get (sheet
, 1, 1)->value
);
1541 g_printerr ("Var: %.10" GNM_FORMAT_g
"\n", *var
);
1543 *skew
= value_get_as_float (sheet_cell_get (sheet
, 1, 2)->value
);
1544 g_printerr ("Skew: %.10" GNM_FORMAT_g
"\n", *skew
);
1546 *kurt
= value_get_as_float (sheet_cell_get (sheet
, 1, 3)->value
);
1547 g_printerr ("Kurt: %.10" GNM_FORMAT_g
"\n", *kurt
);
1549 g_object_unref (wb
);
1554 test_random_normality (int N
, const char *expr
,
1555 gnm_float
*mean
, gnm_float
*var
,
1556 gnm_float
*adtest
, gnm_float
*cvmtest
,
1557 gnm_float
*lkstest
, gnm_float
*sftest
)
1559 Workbook
*wb
= workbook_new ();
1561 gnm_float
*res
= g_new (gnm_float
, N
);
1564 int cols
= 2, rows
= N
;
1566 g_printerr ("Testing %s\n", expr
);
1568 gnm_sheet_suggest_size (&cols
, &rows
);
1569 sheet
= workbook_sheet_add (wb
, -1, cols
, rows
);
1571 for (i
= 0; i
< N
; i
++)
1572 define_cell (sheet
, 0, i
, expr
);
1574 s
= g_strdup_printf ("=average(a1:a%d)", N
);
1575 define_cell (sheet
, 1, 0, s
);
1578 s
= g_strdup_printf ("=var(a1:a%d)", N
);
1579 define_cell (sheet
, 1, 1, s
);
1582 s
= g_strdup_printf ("=adtest(a1:a%d)", N
);
1583 define_cell (sheet
, 1, 2, s
);
1586 s
= g_strdup_printf ("=cvmtest(a1:a%d)", N
);
1587 define_cell (sheet
, 1, 3, s
);
1590 s
= g_strdup_printf ("=lkstest(a1:a%d)", N
);
1591 define_cell (sheet
, 1, 4, s
);
1594 s
= g_strdup_printf ("=sftest(a1:a%d)", N
> 5000 ? 5000 : N
);
1595 define_cell (sheet
, 1, 5, s
);
1598 /* Force recalc of all dirty cells even in manual mode. */
1599 workbook_recalc (sheet
->workbook
);
1601 for (i
= 0; i
< N
; i
++)
1602 res
[i
] = value_get_as_float (sheet_cell_get (sheet
, 0, i
)->value
);
1603 *mean
= value_get_as_float (sheet_cell_get (sheet
, 1, 0)->value
);
1604 g_printerr ("Mean: %.10" GNM_FORMAT_g
"\n", *mean
);
1606 *var
= value_get_as_float (sheet_cell_get (sheet
, 1, 1)->value
);
1607 g_printerr ("Var: %.10" GNM_FORMAT_g
"\n", *var
);
1609 *adtest
= value_get_as_float (sheet_cell_get (sheet
, 1, 2)->value
);
1610 g_printerr ("ADTest: %.10" GNM_FORMAT_g
"\n", *adtest
);
1612 *cvmtest
= value_get_as_float (sheet_cell_get (sheet
, 1, 3)->value
);
1613 g_printerr ("CVMTest: %.10" GNM_FORMAT_g
"\n", *cvmtest
);
1615 *lkstest
= value_get_as_float (sheet_cell_get (sheet
, 1, 4)->value
);
1616 g_printerr ("LKSTest: %.10" GNM_FORMAT_g
"\n", *lkstest
);
1618 *sftest
= value_get_as_float (sheet_cell_get (sheet
, 1, 5)->value
);
1619 g_printerr ("SFTest: %.10" GNM_FORMAT_g
"\n", *sftest
);
1621 g_object_unref (wb
);
1626 test_random_rand (int N
)
1628 gnm_float mean
, var
, skew
, kurt
;
1629 gnm_float mean_target
= 0.5;
1630 gnm_float var_target
= 1.0 / 12;
1631 gnm_float skew_target
= 0;
1632 gnm_float kurt_target
= -6.0 / 5;
1637 gnm_float fractiles
[10];
1638 const int nf
= G_N_ELEMENTS (fractiles
);
1640 vals
= test_random_1 (N
, "=RAND()", &mean
, &var
, &skew
, &kurt
);
1642 for (i
= 0; i
< N
; i
++) {
1643 gnm_float r
= vals
[i
];
1644 if (!(r
>= 0 && r
< 1)) {
1645 g_printerr ("Range failure.\n");
1652 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
1653 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1657 if (gnm_abs (var
- T
) > 0.01) {
1658 g_printerr ("Var failure.\n");
1662 if (gnm_abs (skew
- T
) > 0.05) {
1663 g_printerr ("Skew failure.\n");
1667 if (gnm_abs (kurt
- T
) > 0.05) {
1668 g_printerr ("Kurt failure.\n");
1673 for (i
= 1; i
< nf
; i
++)
1674 fractiles
[i
] = i
/ (double)nf
;
1675 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
1679 g_printerr ("OK\n");
1681 add_random_fail ("RAND");
1688 test_random_randuniform (int N
)
1690 gnm_float mean
, var
, skew
, kurt
;
1693 gnm_float lsign
= (random_01 () > 0.75 ? 1 : -1);
1694 gnm_float param_l
= lsign
* gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
1695 gnm_float param_h
= param_l
+ gnm_floor (1 / (0.0001 + gnm_pow (random_01 () / 2, 4)));
1696 gnm_float n
= param_h
- param_l
;
1697 gnm_float mean_target
= (param_l
+ param_h
) / 2;
1698 gnm_float var_target
= (n
* n
) / 12;
1699 gnm_float skew_target
= 0;
1700 gnm_float kurt_target
= -6 / 5.0;
1704 gnm_float fractiles
[10];
1705 const int nf
= G_N_ELEMENTS (fractiles
);
1707 expr
= g_strdup_printf ("=RANDUNIFORM(%.10" GNM_FORMAT_g
",%.10" GNM_FORMAT_g
")", param_l
, param_h
);
1708 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1712 for (i
= 0; i
< N
; i
++) {
1713 gnm_float r
= vals
[i
];
1714 if (!(r
>= param_l
&& r
< param_h
)) {
1715 g_printerr ("Range failure.\n");
1722 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1723 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
1724 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1729 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
1730 if (!(var
>= 0 && gnm_finite (var
))) {
1731 /* That is a very simplistic test! */
1732 g_printerr ("Var failure.\n");
1737 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
1738 if (!gnm_finite (skew
)) {
1739 /* That is a very simplistic test! */
1740 g_printerr ("Skew failure.\n");
1745 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
1746 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
1747 /* That is a very simplistic test! */
1748 g_printerr ("Kurt failure.\n");
1753 for (i
= 1; i
< nf
; i
++)
1754 fractiles
[i
] = param_l
+ n
* i
/ (double)nf
;
1755 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
1759 g_printerr ("OK\n");
1761 add_random_fail ("RANDUNIFORM");
1768 test_random_randbernoulli (int N
)
1771 gnm_float q
= 1 - p
;
1772 gnm_float mean
, var
, skew
, kurt
;
1773 gnm_float mean_target
= p
;
1774 gnm_float var_target
= p
* (1 - p
);
1775 gnm_float skew_target
= (q
- p
) / gnm_sqrt (p
* q
);
1776 gnm_float kurt_target
= (1 - 6 * p
* q
) / (p
* q
);
1783 expr
= g_strdup_printf ("=RANDBERNOULLI(%.10" GNM_FORMAT_g
")", p
);
1784 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1788 for (i
= 0; i
< N
; i
++) {
1789 gnm_float r
= vals
[i
];
1790 if (!(r
== 0 || r
== 1)) {
1791 g_printerr ("Range failure.\n");
1798 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1799 if (gnm_abs (mean
- p
) > 0.01) {
1800 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1805 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
1806 if (gnm_abs (var
- T
) > 0.01) {
1807 g_printerr ("Var failure.\n");
1812 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
1813 if (!(gnm_abs (skew
- T
) <= 0.10 * gnm_abs (T
))) {
1814 g_printerr ("Skew failure.\n");
1819 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
1820 if (!(gnm_abs (kurt
- T
) <= 0.15 * gnm_abs (T
))) {
1821 g_printerr ("Kurt failure.\n");
1825 g_printerr ("OK\n");
1827 add_random_fail ("RANDBERNOULLI");
1834 test_random_randdiscrete (int N
)
1836 gnm_float mean
, var
, skew
, kurt
;
1840 gnm_float mean_target
= 13;
1841 gnm_float var_target
= 156;
1842 gnm_float skew_target
= 0.6748;
1843 gnm_float kurt_target
= -0.9057;
1847 expr
= g_strdup_printf ("=RANDDISCRETE({0;1;4;9;16;25;36})");
1848 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1852 for (i
= 0; i
< N
; i
++) {
1853 gnm_float r
= vals
[i
];
1854 if (!(r
>= 0 && r
<= 36 && gnm_sqrt (r
) == gnm_floor (gnm_sqrt (r
)))) {
1855 g_printerr ("Range failure.\n");
1862 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
1863 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
1864 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1869 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
1870 if (!(var
>= 0 && gnm_finite (var
))) {
1871 /* That is a very simplistic test! */
1872 g_printerr ("Var failure.\n");
1877 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
1878 if (!gnm_finite (skew
)) {
1879 /* That is a very simplistic test! */
1880 g_printerr ("Skew failure.\n");
1885 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
1886 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
1887 /* That is a very simplistic test! */
1888 g_printerr ("Kurt failure.\n");
1893 g_printerr ("OK\n");
1895 add_random_fail ("RANDDISCRETE");
1902 test_random_randnorm (int N
)
1904 gnm_float mean
, var
, adtest
, cvmtest
, lkstest
, sftest
;
1905 gnm_float mean_target
= 0, var_target
= 1;
1911 gnm_float fractiles
[10];
1912 const int nf
= G_N_ELEMENTS (fractiles
);
1914 expr
= g_strdup_printf ("=RANDNORM(%.10" GNM_FORMAT_g
",%.10" GNM_FORMAT_g
")",
1915 mean_target
, var_target
);
1916 vals
= test_random_normality (N
, expr
, &mean
, &var
, &adtest
, &cvmtest
, &lkstest
, &sftest
);
1920 for (i
= 0; i
< N
; i
++) {
1921 gnm_float r
= vals
[i
];
1922 if (!gnm_finite (r
)) {
1923 g_printerr ("Range failure.\n");
1930 if (gnm_abs (mean
- T
) > 0.02) {
1931 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
1935 if (gnm_abs (var
- T
) > 0.02) {
1936 g_printerr ("Var failure.\n");
1941 for (i
= 1; i
< nf
; i
++)
1942 fractiles
[i
] = qnorm (i
/ (double)nf
, mean_target
, gnm_sqrt (var_target
), TRUE
, FALSE
);
1943 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
1946 if (adtest
< 0.01) {
1947 g_printerr ("Anderson Darling Test rejected [%.10" GNM_FORMAT_g
"]\n", adtest
);
1950 if (cvmtest
< 0.01) {
1951 g_printerr ("Cramér-von Mises Test rejected [%.10" GNM_FORMAT_g
"]\n", cvmtest
);
1954 if (lkstest
< 0.01) {
1955 g_printerr ("Lilliefors (Kolmogorov-Smirnov) Test rejected [%.10" GNM_FORMAT_g
"]\n",
1959 if (sftest
< 0.01) {
1960 g_printerr ("Shapiro-Francia Test rejected [%.10" GNM_FORMAT_g
"]\n", sftest
);
1965 g_printerr ("OK\n");
1967 add_random_fail ("RANDNORM");
1974 test_random_randsnorm (int N
)
1976 gnm_float mean
, var
, skew
, kurt
;
1979 gnm_float alpha
= 5;
1980 gnm_float delta
= alpha
/gnm_sqrt(1+alpha
*alpha
);
1981 gnm_float mean_target
= delta
* gnm_sqrt (2/M_PIgnum
);
1982 gnm_float var_target
= 1-mean_target
*mean_target
;
1987 expr
= g_strdup_printf ("=RANDSNORM(%.10" GNM_FORMAT_g
")", alpha
);
1988 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
1992 for (i
= 0; i
< N
; i
++) {
1993 gnm_float r
= vals
[i
];
1994 if (!gnm_finite (r
)) {
1995 g_printerr ("Range failure.\n");
2002 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2003 if (gnm_abs (mean
- T
) > 0.01) {
2004 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2009 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2010 if (gnm_abs (var
- T
) > 0.01) {
2011 g_printerr ("Var failure.\n");
2015 T
= mean_target
/gnm_sqrt(var_target
);
2016 T
= T
*T
*T
*(4-M_PIgnum
)/2;
2017 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2018 if (gnm_abs (skew
- T
) > 0.05) {
2019 g_printerr ("Skew failure.\n");
2023 T
= 2*(M_PIgnum
- 3)*mean_target
*mean_target
*mean_target
*mean_target
/(var_target
*var_target
);
2024 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2025 if (gnm_abs (kurt
- T
) > 0.15) {
2026 g_printerr ("Kurt failure.\n");
2031 g_printerr ("OK\n");
2033 add_random_fail ("RANDSNORM");
2040 test_random_randexp (int N
)
2042 gnm_float mean
, var
, skew
, kurt
;
2045 gnm_float param_l
= 1 / (0.0001 + gnm_pow (random_01 () / 2, 4));
2046 gnm_float mean_target
= param_l
;
2047 gnm_float var_target
= mean_target
* mean_target
;
2048 gnm_float skew_target
= 2;
2049 gnm_float kurt_target
= 6;
2053 gnm_float fractiles
[10];
2054 const int nf
= G_N_ELEMENTS (fractiles
);
2056 expr
= g_strdup_printf ("=RANDEXP(%.10" GNM_FORMAT_g
")", param_l
);
2057 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2061 for (i
= 0; i
< N
; i
++) {
2062 gnm_float r
= vals
[i
];
2063 if (!(r
>= 0 && gnm_finite (r
))) {
2064 g_printerr ("Range failure.\n");
2071 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2072 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2073 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2078 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2079 if (!(var
>= 0 && gnm_finite (var
))) {
2080 /* That is a very simplistic test! */
2081 g_printerr ("Var failure.\n");
2086 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2087 if (!gnm_finite (skew
)) {
2088 /* That is a very simplistic test! */
2089 g_printerr ("Skew failure.\n");
2094 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2095 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2096 /* That is a very simplistic test! */
2097 g_printerr ("Kurt failure.\n");
2102 for (i
= 1; i
< nf
; i
++)
2103 fractiles
[i
] = qexp (i
/ (double)nf
, param_l
, TRUE
, FALSE
);
2104 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2108 g_printerr ("OK\n");
2110 add_random_fail ("RANDEXP");
2117 test_random_randgamma (int N
)
2119 gnm_float mean
, var
, skew
, kurt
;
2122 gnm_float param_shape
= gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 6)));
2123 gnm_float param_scale
= 0.001 + gnm_pow (random_01 (), 4) * 1000;
2124 gnm_float mean_target
= param_shape
* param_scale
;
2125 gnm_float var_target
= mean_target
* param_scale
;
2126 gnm_float skew_target
= 2 / gnm_sqrt (param_shape
);
2127 gnm_float kurt_target
= 6 / param_shape
;
2131 gnm_float fractiles
[10];
2132 const int nf
= G_N_ELEMENTS (fractiles
);
2134 expr
= g_strdup_printf ("=RANDGAMMA(%.0" GNM_FORMAT_f
",%.10" GNM_FORMAT_g
")", param_shape
, param_scale
);
2135 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2139 for (i
= 0; i
< N
; i
++) {
2140 gnm_float r
= vals
[i
];
2141 if (!(r
> 0 && gnm_finite (r
))) {
2142 g_printerr ("Range failure.\n");
2149 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2150 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2151 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2156 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2157 if (!(var
>= 0 && gnm_finite (var
))) {
2158 /* That is a very simplistic test! */
2159 g_printerr ("Var failure.\n");
2164 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2165 if (!gnm_finite (skew
)) {
2166 /* That is a very simplistic test! */
2167 g_printerr ("Skew failure.\n");
2172 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2173 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2174 /* That is a very simplistic test! */
2175 g_printerr ("Kurt failure.\n");
2180 for (i
= 1; i
< nf
; i
++)
2181 fractiles
[i
] = qgamma (i
/ (double)nf
, param_shape
, param_scale
, TRUE
, FALSE
);
2182 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2186 g_printerr ("OK\n");
2188 add_random_fail ("RANDGAMMA");
2195 test_random_randbeta (int N
)
2197 gnm_float mean
, var
, skew
, kurt
;
2200 gnm_float param_a
= 1 / (0.0001 + gnm_pow (random_01 (), 6));
2201 gnm_float param_b
= 1 / (0.0001 + gnm_pow (random_01 (), 6));
2202 gnm_float s
= param_a
+ param_b
;
2203 gnm_float mean_target
= param_a
/ s
;
2204 gnm_float var_target
= mean_target
* param_b
/ (s
* (s
+ 1));
2205 gnm_float skew_target
=
2206 (2 * (param_b
- param_a
) * gnm_sqrt (s
+ 1))/
2207 ((s
+ 2) * gnm_sqrt (param_a
* param_b
));
2208 gnm_float kurt_target
= gnm_nan
; /* Complicated */
2212 gnm_float fractiles
[10];
2213 const int nf
= G_N_ELEMENTS (fractiles
);
2215 expr
= g_strdup_printf ("=RANDBETA(%.10" GNM_FORMAT_g
",%.10" GNM_FORMAT_g
")", param_a
, param_b
);
2216 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2220 for (i
= 0; i
< N
; i
++) {
2221 gnm_float r
= vals
[i
];
2222 if (!(r
>= 0 && r
<= 1)) {
2223 g_printerr ("Range failure.\n");
2230 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2231 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2232 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2237 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2238 if (!(var
>= 0 && gnm_finite (var
))) {
2239 /* That is a very simplistic test! */
2240 g_printerr ("Var failure.\n");
2245 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2246 if (!gnm_finite (skew
)) {
2247 /* That is a very simplistic test! */
2248 g_printerr ("Skew failure.\n");
2253 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2254 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2255 /* That is a very simplistic test! */
2256 g_printerr ("Kurt failure.\n");
2261 for (i
= 1; i
< nf
; i
++)
2262 fractiles
[i
] = qbeta (i
/ (double)nf
, param_a
, param_b
, TRUE
, FALSE
);
2263 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2267 g_printerr ("OK\n");
2269 add_random_fail ("RANDBETA");
2276 test_random_randtdist (int N
)
2278 gnm_float mean
, var
, skew
, kurt
;
2281 gnm_float param_df
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2282 gnm_float mean_target
= 0;
2283 gnm_float var_target
= param_df
> 2 ? param_df
/ (param_df
- 2) : gnm_nan
;
2284 gnm_float skew_target
= param_df
> 3 ? 0 : gnm_nan
;
2285 gnm_float kurt_target
= param_df
> 4 ? 6 / (param_df
- 4) : gnm_nan
;
2289 gnm_float fractiles
[10];
2290 const int nf
= G_N_ELEMENTS (fractiles
);
2292 expr
= g_strdup_printf ("=RANDTDIST(%.0" GNM_FORMAT_f
")", param_df
);
2293 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2297 for (i
= 0; i
< N
; i
++) {
2298 gnm_float r
= vals
[i
];
2299 if (!(gnm_finite (r
))) {
2300 g_printerr ("Range failure.\n");
2307 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2308 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2309 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2314 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2315 if (!(var
>= 0 && gnm_finite (var
))) {
2316 /* That is a very simplistic test! */
2317 g_printerr ("Var failure.\n");
2322 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2323 if (!gnm_finite (skew
)) {
2324 /* That is a very simplistic test! */
2325 g_printerr ("Skew failure.\n");
2330 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2331 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2332 /* That is a very simplistic test! */
2333 g_printerr ("Kurt failure.\n");
2338 for (i
= 1; i
< nf
; i
++)
2339 fractiles
[i
] = qt (i
/ (double)nf
, param_df
, TRUE
, FALSE
);
2340 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2344 g_printerr ("OK\n");
2346 add_random_fail ("RANDTDIST");
2353 test_random_randfdist (int N
)
2355 gnm_float mean
, var
, skew
, kurt
;
2358 gnm_float param_df1
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2359 gnm_float param_df2
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2360 gnm_float mean_target
= param_df2
> 2 ? param_df2
/ (param_df2
- 2) : gnm_nan
;
2361 gnm_float var_target
= param_df2
> 4
2362 ? (2 * param_df2
* param_df2
* (param_df1
+ param_df2
- 2) /
2363 (param_df1
* (param_df2
- 2) * (param_df2
- 2) * (param_df2
- 4)))
2365 gnm_float skew_target
= gnm_nan
; /* Complicated */
2366 gnm_float kurt_target
= gnm_nan
; /* Complicated */
2370 gnm_float fractiles
[10];
2371 const int nf
= G_N_ELEMENTS (fractiles
);
2373 expr
= g_strdup_printf ("=RANDFDIST(%.0" GNM_FORMAT_f
",%.0" GNM_FORMAT_f
")", param_df1
, param_df2
);
2374 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2378 for (i
= 0; i
< N
; i
++) {
2379 gnm_float r
= vals
[i
];
2380 if (!(r
>= 0 && gnm_finite (r
))) {
2381 g_printerr ("Range failure.\n");
2388 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2389 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2390 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2395 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2396 if (!(var
>= 0 && gnm_finite (var
))) {
2397 /* That is a very simplistic test! */
2398 g_printerr ("Var failure.\n");
2403 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2404 if (!gnm_finite (skew
)) {
2405 /* That is a very simplistic test! */
2406 g_printerr ("Skew failure.\n");
2411 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2412 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2413 /* That is a very simplistic test! */
2414 g_printerr ("Kurt failure.\n");
2419 for (i
= 1; i
< nf
; i
++)
2420 fractiles
[i
] = qf (i
/ (double)nf
, param_df1
, param_df2
, TRUE
, FALSE
);
2421 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2425 g_printerr ("OK\n");
2427 add_random_fail ("RANDFDIST");
2434 test_random_randchisq (int N
)
2436 gnm_float mean
, var
, skew
, kurt
;
2439 gnm_float param_df
= 1 + gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 6)));
2440 gnm_float mean_target
= param_df
;
2441 gnm_float var_target
= param_df
* 2;
2442 gnm_float skew_target
= gnm_sqrt (8 / param_df
);
2443 gnm_float kurt_target
= 12 / param_df
;
2447 gnm_float fractiles
[10];
2448 const int nf
= G_N_ELEMENTS (fractiles
);
2450 expr
= g_strdup_printf ("=RANDCHISQ(%.10" GNM_FORMAT_g
")", param_df
);
2451 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2455 for (i
= 0; i
< N
; i
++) {
2456 gnm_float r
= vals
[i
];
2457 if (!(r
>= 0 && gnm_finite (r
))) {
2458 g_printerr ("Range failure.\n");
2465 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2466 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2467 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2472 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2473 if (!(var
>= 0 && gnm_finite (var
))) {
2474 /* That is a very simplistic test! */
2475 g_printerr ("Var failure.\n");
2480 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2481 if (!gnm_finite (skew
)) {
2482 /* That is a very simplistic test! */
2483 g_printerr ("Skew failure.\n");
2488 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2489 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2490 /* That is a very simplistic test! */
2491 g_printerr ("Kurt failure.\n");
2496 for (i
= 1; i
< nf
; i
++)
2497 fractiles
[i
] = qchisq (i
/ (double)nf
, param_df
, TRUE
, FALSE
);
2498 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2502 g_printerr ("OK\n");
2504 add_random_fail ("RANDCHISQ");
2511 test_random_randcauchy (int N
)
2513 gnm_float mean
, var
, skew
, kurt
;
2516 gnm_float param_scale
= 0.001 + gnm_pow (random_01 (), 4) * 1000;
2517 gnm_float mean_target
= gnm_nan
;
2518 gnm_float var_target
= gnm_nan
;
2519 gnm_float skew_target
= gnm_nan
;
2520 gnm_float kurt_target
= gnm_nan
;
2524 gnm_float fractiles
[10];
2525 const int nf
= G_N_ELEMENTS (fractiles
);
2528 * The distribution has no mean, no variance, no skew, and no kurtosis.
2529 * The support is all reals.
2532 expr
= g_strdup_printf ("=RANDCAUCHY(%.10" GNM_FORMAT_g
")", param_scale
);
2533 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2537 for (i
= 0; i
< N
; i
++) {
2538 gnm_float r
= vals
[i
];
2539 if (!(gnm_finite (r
))) {
2540 g_printerr ("Range failure.\n");
2547 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2548 if (gnm_finite (var_target
) && !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2549 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2554 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2555 if (!(var
>= 0 && gnm_finite (var
))) {
2556 /* That is a very simplistic test! */
2557 g_printerr ("Var failure.\n");
2562 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2563 if (!gnm_finite (skew
)) {
2564 /* That is a very simplistic test! */
2565 g_printerr ("Skew failure.\n");
2570 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2571 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2572 /* That is a very simplistic test! */
2573 g_printerr ("Kurt failure.\n");
2578 for (i
= 1; i
< nf
; i
++)
2579 fractiles
[i
] = qcauchy (i
/ (double)nf
, 0.0, param_scale
, TRUE
, FALSE
);
2580 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
2584 g_printerr ("OK\n");
2586 add_random_fail ("RANDCAUCHY");
2593 test_random_randbinom (int N
)
2595 gnm_float mean
, var
, skew
, kurt
;
2598 gnm_float param_p
= random_01 ();
2599 gnm_float param_trials
= gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
2600 gnm_float mean_target
= param_trials
* param_p
;
2601 gnm_float var_target
= mean_target
* (1 - param_p
);
2602 gnm_float skew_target
= (1 - 2 * param_p
) / gnm_sqrt (var_target
);
2603 gnm_float kurt_target
= (1 - 6 * param_p
* (1 - param_p
)) / var_target
;
2607 gnm_float fractiles
[10], probs
[10];
2608 const int nf
= G_N_ELEMENTS (fractiles
);
2610 expr
= g_strdup_printf ("=RANDBINOM(%.10" GNM_FORMAT_g
",%.0" GNM_FORMAT_f
")", param_p
, param_trials
);
2611 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2615 for (i
= 0; i
< N
; i
++) {
2616 gnm_float r
= vals
[i
];
2617 if (!(r
>= 0 && r
<= param_trials
&& r
== gnm_floor (r
))) {
2618 g_printerr ("Range failure.\n");
2625 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2626 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2627 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2632 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2633 if (!(var
>= 0 && gnm_finite (var
))) {
2634 /* That is a very simplistic test! */
2635 g_printerr ("Var failure.\n");
2640 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2641 if (!gnm_finite (skew
)) {
2642 /* That is a very simplistic test! */
2643 g_printerr ("Skew failure.\n");
2648 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2649 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2650 /* That is a very simplistic test! */
2651 g_printerr ("Kurt failure.\n");
2656 for (i
= 1; i
< nf
; i
++) {
2657 fractiles
[i
] = qbinom (i
/ (double)nf
, param_trials
, param_p
, TRUE
, FALSE
);
2658 probs
[i
] = pbinom (fractiles
[i
], param_trials
, param_p
, TRUE
, FALSE
);
2660 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2664 g_printerr ("OK\n");
2666 add_random_fail ("RANDBINOM");
2673 test_random_randnegbinom (int N
)
2675 gnm_float mean
, var
, skew
, kurt
;
2678 gnm_float param_p
= random_01 ();
2679 gnm_float param_fails
= gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
2680 /* Warning: these differ from Wikipedia by swapping p and 1-p. */
2681 gnm_float mean_target
= param_fails
* (1 - param_p
) / param_p
;
2682 gnm_float var_target
= mean_target
/ param_p
;
2683 gnm_float skew_target
= (2 - param_p
) / gnm_sqrt (param_fails
* (1 - param_p
));
2684 gnm_float kurt_target
= 6 / param_fails
+ 1 / var_target
;
2688 gnm_float fractiles
[10], probs
[10];
2689 const int nf
= G_N_ELEMENTS (fractiles
);
2691 expr
= g_strdup_printf ("=RANDNEGBINOM(%.10" GNM_FORMAT_g
",%.0" GNM_FORMAT_f
")", param_p
, param_fails
);
2692 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2696 for (i
= 0; i
< N
; i
++) {
2697 gnm_float r
= vals
[i
];
2698 if (!(r
>= 0 && gnm_finite (r
) && r
== gnm_floor (r
))) {
2699 g_printerr ("Range failure.\n");
2706 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2707 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2708 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2713 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2714 if (!(var
>= 0 && gnm_finite (var
))) {
2715 /* That is a very simplistic test! */
2716 g_printerr ("Var failure.\n");
2721 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2722 if (!gnm_finite (skew
)) {
2723 /* That is a very simplistic test! */
2724 g_printerr ("Skew failure.\n");
2729 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2730 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2731 /* That is a very simplistic test! */
2732 g_printerr ("Kurt failure.\n");
2737 for (i
= 1; i
< nf
; i
++) {
2738 fractiles
[i
] = qnbinom (i
/ (double)nf
, param_fails
, param_p
, TRUE
, FALSE
);
2739 probs
[i
] = pnbinom (fractiles
[i
], param_fails
, param_p
, TRUE
, FALSE
);
2741 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2745 g_printerr ("OK\n");
2747 add_random_fail ("RANDNEGBINOM");
2754 test_random_randhyperg (int N
)
2756 gnm_float mean
, var
, skew
, kurt
;
2759 gnm_float param_nr
= gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 4)));
2760 gnm_float param_nb
= gnm_floor (1 / (0.01 + gnm_pow (random_01 (), 4)));
2761 gnm_float s
= param_nr
+ param_nb
;
2762 gnm_float param_n
= gnm_floor (random_01 () * (s
+ 1));
2763 gnm_float mean_target
= param_n
* param_nr
/ s
;
2764 gnm_float var_target
= s
> 1
2765 ? mean_target
* (param_nb
/ s
) * (s
- param_n
) / (s
- 1)
2767 gnm_float skew_target
= gnm_nan
; /* Complicated */
2768 gnm_float kurt_target
= gnm_nan
; /* Complicated */
2772 gnm_float fractiles
[10], probs
[10];
2773 const int nf
= G_N_ELEMENTS (fractiles
);
2775 expr
= g_strdup_printf ("=RANDHYPERG(%.10" GNM_FORMAT_g
",%.0" GNM_FORMAT_f
",%.0" GNM_FORMAT_f
")", param_nr
, param_nb
, param_n
);
2776 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2780 for (i
= 0; i
< N
; i
++) {
2781 gnm_float r
= vals
[i
];
2782 if (!(r
>= 0 && r
<= param_n
&& r
== gnm_floor (r
))) {
2783 g_printerr ("Range failure.\n");
2790 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2791 if (gnm_finite (var_target
) &&
2792 !(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2793 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2798 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2799 if (!(var
>= 0 && gnm_finite (var
))) {
2800 /* That is a very simplistic test! */
2801 g_printerr ("Var failure.\n");
2806 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2807 if (!gnm_finite (skew
)) {
2808 /* That is a very simplistic test! */
2809 g_printerr ("Skew failure.\n");
2814 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2815 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2816 /* That is a very simplistic test! */
2817 g_printerr ("Kurt failure.\n");
2822 for (i
= 1; i
< nf
; i
++) {
2823 fractiles
[i
] = qhyper (i
/ (double)nf
, param_nr
, param_nb
, param_n
, TRUE
, FALSE
);
2824 probs
[i
] = phyper (fractiles
[i
], param_nr
, param_nb
, param_n
, TRUE
, FALSE
);
2826 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2830 g_printerr ("OK\n");
2832 add_random_fail ("RANDHYPERG");
2839 test_random_randbetween (int N
)
2841 gnm_float mean
, var
, skew
, kurt
;
2844 gnm_float lsign
= (random_01 () > 0.75 ? 1 : -1);
2845 gnm_float param_l
= lsign
* gnm_floor (1 / (0.0001 + gnm_pow (random_01 (), 4)));
2846 gnm_float param_h
= param_l
+ gnm_floor (1 / (0.0001 + gnm_pow (random_01 () / 2, 4)));
2847 gnm_float n
= param_h
- param_l
+ 1;
2848 gnm_float mean_target
= (param_l
+ param_h
) / 2;
2849 gnm_float var_target
= (n
* n
- 1) / 12;
2850 gnm_float skew_target
= 0;
2851 gnm_float kurt_target
= (n
* n
+ 1) / (n
* n
- 1) * -6 / 5;
2856 expr
= g_strdup_printf ("=RANDBETWEEN(%.0" GNM_FORMAT_f
",%.0" GNM_FORMAT_f
")", param_l
, param_h
);
2857 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2861 for (i
= 0; i
< N
; i
++) {
2862 gnm_float r
= vals
[i
];
2863 if (!(r
>= param_l
&& r
<= param_h
&& r
== gnm_floor (r
))) {
2864 g_printerr ("Range failure.\n");
2871 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2872 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2873 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2878 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2879 if (!(var
>= 0 && gnm_finite (var
))) {
2880 /* That is a very simplistic test! */
2881 g_printerr ("Var failure.\n");
2886 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2887 if (!gnm_finite (skew
)) {
2888 /* That is a very simplistic test! */
2889 g_printerr ("Skew failure.\n");
2894 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2895 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2896 /* That is a very simplistic test! */
2897 g_printerr ("Kurt failure.\n");
2902 g_printerr ("OK\n");
2904 add_random_fail ("RANDBETWEEN");
2911 test_random_randpoisson (int N
)
2913 gnm_float mean
, var
, skew
, kurt
;
2916 gnm_float param_l
= 1 / (0.0001 + gnm_pow (random_01 () / 2, 4));
2917 gnm_float mean_target
= param_l
;
2918 gnm_float var_target
= param_l
;
2919 gnm_float skew_target
= 1 / gnm_sqrt (param_l
);
2920 gnm_float kurt_target
= 1 / param_l
;
2924 gnm_float fractiles
[10], probs
[10];
2925 const int nf
= G_N_ELEMENTS (fractiles
);
2927 expr
= g_strdup_printf ("=RANDPOISSON(%.10" GNM_FORMAT_g
")", param_l
);
2928 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
2932 for (i
= 0; i
< N
; i
++) {
2933 gnm_float r
= vals
[i
];
2934 if (!(r
>= 0 && gnm_finite (r
) && r
== gnm_floor (r
))) {
2935 g_printerr ("Range failure.\n");
2942 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
2943 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
2944 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
2949 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
2950 if (!(var
>= 0 && gnm_finite (var
))) {
2951 /* That is a very simplistic test! */
2952 g_printerr ("Var failure.\n");
2957 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
2958 if (!gnm_finite (skew
)) {
2959 /* That is a very simplistic test! */
2960 g_printerr ("Skew failure.\n");
2965 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
2966 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
2967 /* That is a very simplistic test! */
2968 g_printerr ("Kurt failure.\n");
2973 for (i
= 1; i
< nf
; i
++) {
2974 fractiles
[i
] = qpois (i
/ (double)nf
, param_l
, TRUE
, FALSE
);
2975 probs
[i
] = ppois (fractiles
[i
], param_l
, TRUE
, FALSE
);
2977 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
2981 g_printerr ("OK\n");
2983 add_random_fail ("RANDPOISSON");
2990 * Note: this geometric distribution is the only with support {0,1,2,...}
2993 test_random_randgeom (int N
)
2995 gnm_float mean
, var
, skew
, kurt
;
2998 gnm_float param_p
= random_01 ();
2999 gnm_float mean_target
= (1 - param_p
) / param_p
;
3000 gnm_float var_target
= (1 - param_p
) / (param_p
* param_p
);
3001 gnm_float skew_target
= (2 - param_p
) / gnm_sqrt (1 - param_p
);
3002 gnm_float kurt_target
= 6 + (param_p
* param_p
) / (1 - param_p
);
3006 gnm_float fractiles
[10], probs
[10];
3007 const int nf
= G_N_ELEMENTS (fractiles
);
3009 expr
= g_strdup_printf ("=RANDGEOM(%.10" GNM_FORMAT_g
")", param_p
);
3010 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3014 for (i
= 0; i
< N
; i
++) {
3015 gnm_float r
= vals
[i
];
3016 if (!(r
>= 0 && gnm_finite (r
) && r
== gnm_floor (r
))) {
3017 g_printerr ("Range failure.\n");
3024 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3025 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3026 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3031 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3032 if (!(var
>= 0 && gnm_finite (var
))) {
3033 /* That is a very simplistic test! */
3034 g_printerr ("Var failure.\n");
3039 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3040 if (!gnm_finite (skew
)) {
3041 /* That is a very simplistic test! */
3042 g_printerr ("Skew failure.\n");
3047 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3048 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3049 /* That is a very simplistic test! */
3050 g_printerr ("Kurt failure.\n");
3055 for (i
= 1; i
< nf
; i
++) {
3056 fractiles
[i
] = qgeom (i
/ (double)nf
, param_p
, TRUE
, FALSE
);
3057 probs
[i
] = pgeom (fractiles
[i
], param_p
, TRUE
, FALSE
);
3059 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, probs
))
3063 g_printerr ("OK\n");
3065 add_random_fail ("RANDGEOM");
3072 test_random_randlog (int N
)
3074 gnm_float mean
, var
, skew
, kurt
;
3077 gnm_float param_p
= random_01 ();
3078 gnm_float p
= param_p
;
3079 gnm_float l1mp
= gnm_log1p (-p
);
3080 gnm_float mean_target
= -p
/ (1 - p
) / l1mp
;
3081 gnm_float var_target
= -(p
* (p
+ l1mp
)) / gnm_pow ((1 - p
) * l1mp
, 2);
3082 /* See http://mathworld.wolfram.com/Log-SeriesDistribution.html */
3083 gnm_float skew_target
=
3085 (2 * p
* p
+ 3 * p
* l1mp
+ (1 + p
) * l1mp
* l1mp
) /
3086 (l1mp
* (p
+ l1mp
) * gnm_sqrt (-p
* (p
+ l1mp
)));
3087 gnm_float kurt_target
=
3090 p
* (7 + 4 * p
) * l1mp
* l1mp
+
3091 (1 + 4 * p
+ p
* p
) * l1mp
* l1mp
* l1mp
) /
3092 (p
* gnm_pow (p
+ l1mp
, 2));
3097 expr
= g_strdup_printf ("=RANDLOG(%.10" GNM_FORMAT_g
")", param_p
);
3098 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3102 for (i
= 0; i
< N
; i
++) {
3103 gnm_float r
= vals
[i
];
3104 if (!(r
>= 1 && gnm_finite (r
) && r
== gnm_floor (r
))) {
3105 g_printerr ("Range failure.\n");
3112 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3113 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3114 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3119 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3120 if (!(var
>= 0 && gnm_finite (var
))) {
3121 /* That is a very simplistic test! */
3122 g_printerr ("Var failure.\n");
3127 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3128 if (!gnm_finite (skew
)) {
3129 /* That is a very simplistic test! */
3130 g_printerr ("Skew failure.\n");
3135 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3136 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3137 /* That is a very simplistic test! */
3138 g_printerr ("Kurt failure.\n");
3143 g_printerr ("OK\n");
3145 add_random_fail ("RANDLOG");
3152 test_random_randweibull (int N
)
3154 gnm_float mean
, var
, skew
, kurt
;
3157 gnm_float shape
= 1 / (0.0001 + gnm_pow (random_01 () / 2, 2));
3158 gnm_float scale
= 2 * random_01 ();
3159 gnm_float mean_target
= scale
* gnm_gamma (1 + 1 / shape
);
3160 gnm_float var_target
= scale
* scale
*
3161 (gnm_gamma (1 + 2 / shape
) -
3162 gnm_pow (gnm_gamma (1 + 1 / shape
), 2));
3163 /* See https://en.wikipedia.org/wiki/Weibull_distribution */
3164 gnm_float skew_target
=
3165 (gnm_gamma (1 + 3 / shape
) * gnm_pow (scale
, 3) -
3166 3 * mean_target
* var_target
-
3167 gnm_pow (mean_target
, 3)) /
3168 gnm_pow (var_target
, 1.5);
3169 gnm_float kurt_target
= gnm_nan
; /* Complicated */
3173 gnm_float fractiles
[10];
3174 const int nf
= G_N_ELEMENTS (fractiles
);
3176 expr
= g_strdup_printf ("=RANDWEIBULL(%.10" GNM_FORMAT_f
",%.10" GNM_FORMAT_f
")", scale
, shape
);
3177 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3181 for (i
= 0; i
< N
; i
++) {
3182 gnm_float r
= vals
[i
];
3183 if (!(r
>= 0 && gnm_finite (r
))) {
3184 g_printerr ("Range failure.\n");
3191 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3192 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3193 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3198 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3199 if (!(var
>= 0 && gnm_finite (var
))) {
3200 /* That is a very simplistic test! */
3201 g_printerr ("Var failure.\n");
3206 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3207 if (!gnm_finite (skew
)) {
3208 /* That is a very simplistic test! */
3209 g_printerr ("Skew failure.\n");
3214 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3215 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3216 /* That is a very simplistic test! */
3217 g_printerr ("Kurt failure.\n");
3222 for (i
= 1; i
< nf
; i
++)
3223 fractiles
[i
] = qweibull (i
/ (double)nf
, shape
, scale
, TRUE
, FALSE
);
3224 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
3228 g_printerr ("OK\n");
3230 add_random_fail ("RANDWEIBULL");
3237 test_random_randlognorm (int N
)
3239 gnm_float mean
, var
, skew
, kurt
;
3242 gnm_float lm
= (random_01() - 0.5) / (0.1 + gnm_pow (random_01 () / 2, 2));
3243 gnm_float ls
= 1 / (1 + gnm_pow (random_01 () / 2, 2));
3244 gnm_float mean_target
= gnm_exp (lm
+ ls
* ls
/ 2);
3245 gnm_float var_target
= gnm_expm1 (ls
* ls
) * (mean_target
* mean_target
);
3246 /* See https://en.wikipedia.org/wiki/Log-normal_distribution */
3247 gnm_float skew_target
= (gnm_exp (ls
* ls
) + 2) *
3248 gnm_sqrt (gnm_expm1 (ls
* ls
));
3249 gnm_float kurt_target
= gnm_nan
; /* Complicated */
3253 gnm_float fractiles
[10];
3254 const int nf
= G_N_ELEMENTS (fractiles
);
3256 expr
= g_strdup_printf ("=RANDLOGNORM(%.10" GNM_FORMAT_f
",%.10" GNM_FORMAT_f
")", lm
, ls
);
3257 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3261 for (i
= 0; i
< N
; i
++) {
3262 gnm_float r
= vals
[i
];
3263 if (!(r
>= 0 && r
<= gnm_pinf
)) {
3264 g_printerr ("Range failure.\n");
3271 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3272 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3273 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3278 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3279 if (!(var
>= 0 && gnm_finite (var
))) {
3280 /* That is a very simplistic test! */
3281 g_printerr ("Var failure.\n");
3286 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3287 if (!gnm_finite (skew
)) {
3288 /* That is a very simplistic test! */
3289 g_printerr ("Skew failure.\n");
3294 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3295 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3296 /* That is a very simplistic test! */
3297 g_printerr ("Kurt failure.\n");
3302 for (i
= 1; i
< nf
; i
++)
3303 fractiles
[i
] = qlnorm (i
/ (double)nf
, lm
, ls
, TRUE
, FALSE
);
3304 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
3308 g_printerr ("OK\n");
3310 add_random_fail ("RANDLOGNORM");
3317 test_random_randrayleigh (int N
)
3319 gnm_float mean
, var
, skew
, kurt
;
3322 gnm_float ls
= 1 / (1 + gnm_pow (random_01 () / 2, 2));
3323 gnm_float mean_target
= ls
* gnm_sqrt (M_PIgnum
/ 2);
3324 gnm_float var_target
= (4 - M_PIgnum
) / 2 * ls
* ls
;
3325 gnm_float skew_target
= 2 * gnm_sqrt (M_PIgnum
) * (M_PIgnum
- 3) /
3326 gnm_pow (4 - M_PIgnum
, 1.5);
3327 gnm_float kurt_target
= gnm_nan
; /* Complicated */
3331 gnm_float fractiles
[10];
3332 const int nf
= G_N_ELEMENTS (fractiles
);
3334 expr
= g_strdup_printf ("=RANDRAYLEIGH(%.10" GNM_FORMAT_f
")", ls
);
3335 vals
= test_random_1 (N
, expr
, &mean
, &var
, &skew
, &kurt
);
3339 for (i
= 0; i
< N
; i
++) {
3340 gnm_float r
= vals
[i
];
3341 if (!(r
>= 0 && gnm_finite (r
))) {
3342 g_printerr ("Range failure.\n");
3349 g_printerr ("Expected mean: %.10" GNM_FORMAT_g
"\n", T
);
3350 if (!(gnm_abs (mean
- T
) <= 3 * gnm_sqrt (var_target
/ N
))) {
3351 g_printerr ("Mean failure [%.1" GNM_FORMAT_f
" stdev]\n", (mean
- T
) / gnm_sqrt (var_target
/ N
));
3356 g_printerr ("Expected var: %.10" GNM_FORMAT_g
"\n", T
);
3357 if (!(var
>= 0 && gnm_finite (var
))) {
3358 /* That is a very simplistic test! */
3359 g_printerr ("Var failure.\n");
3364 g_printerr ("Expected skew: %.10" GNM_FORMAT_g
"\n", T
);
3365 if (!gnm_finite (skew
)) {
3366 /* That is a very simplistic test! */
3367 g_printerr ("Skew failure.\n");
3372 g_printerr ("Expected kurt: %.10" GNM_FORMAT_g
"\n", T
);
3373 if (!(kurt
>= -3 && gnm_finite (kurt
))) {
3374 /* That is a very simplistic test! */
3375 g_printerr ("Kurt failure.\n");
3380 for (i
= 1; i
< nf
; i
++)
3381 fractiles
[i
] = qrayleigh (i
/ (double)nf
, ls
, TRUE
, FALSE
);
3382 if (!rand_fractile_test (vals
, N
, nf
, fractiles
, NULL
))
3386 g_printerr ("OK\n");
3388 add_random_fail ("RANDRAYLEIGH");
3397 const char *test_name
= "test_random";
3398 const int N
= sstest_fast
? 2000 : 20000;
3399 const int High_N
= N
* 10;
3400 const char *single
= g_getenv ("SSTEST_RANDOM");
3402 mark_test_start (test_name
);
3404 #define CHECK1(NAME,C) \
3405 do { if (!single || strcmp(single,#NAME) == 0) test_random_ ## NAME (C); } while (0)
3409 CHECK1 (randuniform
, N
);
3410 CHECK1 (randbeta
, N
);
3411 CHECK1 (randcauchy
, N
);
3412 CHECK1 (randchisq
, N
);
3413 CHECK1 (randexp
, N
);
3414 CHECK1 (randfdist
, N
);
3415 CHECK1 (randgamma
, N
);
3416 CHECK1 (randlog
, N
);
3417 CHECK1 (randlognorm
, N
);
3418 CHECK1 (randnorm
, High_N
);
3419 CHECK1 (randsnorm
, High_N
);
3420 CHECK1 (randtdist
, N
);
3421 CHECK1 (randweibull
, N
);
3422 CHECK1 (randrayleigh
, N
);
3424 CHECK1 (randexppow
, N
);
3425 CHECK1 (randgumbel
, N
);
3426 CHECK1 (randlandau
, N
);
3427 CHECK1 (randlaplace
, N
);
3428 CHECK1 (randlevy
, N
);
3429 CHECK1 (randlogistic
, N
);
3430 CHECK1 (randnormtail
, N
);
3431 CHECK1 (randpareto
, N
);
3432 CHECK1 (randrayleightail
, N
);
3433 CHECK1 (randstdist
, N
);
3437 CHECK1 (randbernoulli
, N
);
3438 CHECK1 (randbetween
, N
);
3439 CHECK1 (randbinom
, N
);
3440 CHECK1 (randdiscrete
, N
);
3441 CHECK1 (randgeom
, High_N
);
3442 CHECK1 (randhyperg
, High_N
);
3443 CHECK1 (randnegbinom
, High_N
);
3444 CHECK1 (randpoisson
, High_N
);
3450 g_printerr ("SUMMARY: FAIL for %s\n\n", random_summary
);
3452 g_printerr ("SUMMARY: OK\n\n");
3454 g_free (random_summary
);
3455 random_summary
= NULL
;
3457 mark_test_end (test_name
);
3460 /* ------------------------------------------------------------------------- */
3462 #define MAYBE_DO(name) if (strcmp (testname, "all") != 0 && strcmp (testname, (name)) != 0) { } else
3465 main (int argc
, char const **argv
)
3467 GOErrorInfo
*plugin_errs
;
3469 GOptionContext
*ocontext
;
3470 GError
*error
= NULL
;
3471 const char *testname
;
3473 /* No code before here, we need to init threads */
3474 argv
= gnm_pre_parse_init (argc
, argv
);
3476 ocontext
= g_option_context_new (_("[testname]"));
3477 g_option_context_add_main_entries (ocontext
, sstest_options
, GETTEXT_PACKAGE
);
3478 g_option_context_add_group (ocontext
, gnm_get_option_group ());
3479 g_option_context_parse (ocontext
, &argc
, (gchar
***)&argv
, &error
);
3480 g_option_context_free (ocontext
);
3483 g_printerr (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
3484 error
->message
, g_get_prgname ());
3485 g_error_free (error
);
3489 if (sstest_show_version
) {
3490 g_printerr (_("version '%s'\ndatadir := '%s'\nlibdir := '%s'\n"),
3491 GNM_VERSION_FULL
, gnm_sys_data_dir (), gnm_sys_lib_dir ());
3497 cc
= gnm_cmd_context_stderr_new ();
3498 gnm_plugins_init (GO_CMD_CONTEXT (cc
));
3499 go_plugin_db_activate_plugin_list (
3500 go_plugins_get_available_plugins (), &plugin_errs
);
3502 /* FIXME: What do we want to do here? */
3503 go_error_info_free (plugin_errs
);
3505 g_object_unref (cc
);
3508 if (func_state_file
) {
3509 function_dump_defs (func_state_file
, 0);
3512 if (func_def_file
) {
3513 function_dump_defs (func_def_file
, 1);
3516 if (ext_refs_file
) {
3517 function_dump_defs (ext_refs_file
, 4);
3521 function_dump_defs (samples_file
, 5);
3526 if (!testname
) testname
= "all";
3528 /* ---------------------------------------- */
3530 MAYBE_DO ("test_insdel_rowcol_names") test_insdel_rowcol_names ();
3531 MAYBE_DO ("test_insert_delete") test_insert_delete ();
3532 MAYBE_DO ("test_func_help") test_func_help ();
3533 MAYBE_DO ("test_nonascii_numbers") test_nonascii_numbers ();
3534 MAYBE_DO ("test_random") test_random ();
3536 /* ---------------------------------------- */
3539 gnm_pre_parse_shutdown ();