1 /* PSPP - a program for statistical analysis. -*-c-*-
2 Copyright (C) 2006, 2008, 2009, 2010, 2011, 2016 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "language/stats/npar.h"
24 #include "data/case.h"
25 #include "data/casegrouper.h"
26 #include "data/casereader.h"
27 #include "data/dataset.h"
28 #include "data/dictionary.h"
29 #include "data/settings.h"
30 #include "data/variable.h"
31 #include "language/command.h"
32 #include "language/lexer/lexer.h"
33 #include "language/lexer/value-parser.h"
34 #include "language/lexer/variable-parser.h"
35 #include "language/stats/binomial.h"
36 #include "language/stats/chisquare.h"
37 #include "language/stats/ks-one-sample.h"
38 #include "language/stats/cochran.h"
39 #include "language/stats/friedman.h"
40 #include "language/stats/jonckheere-terpstra.h"
41 #include "language/stats/kruskal-wallis.h"
42 #include "language/stats/mann-whitney.h"
43 #include "language/stats/mcnemar.h"
44 #include "language/stats/median.h"
45 #include "language/stats/npar-summary.h"
46 #include "language/stats/runs.h"
47 #include "language/stats/sign.h"
48 #include "language/stats/wilcoxon.h"
49 #include "libpspp/array.h"
50 #include "libpspp/assertion.h"
51 #include "libpspp/cast.h"
52 #include "libpspp/hash-functions.h"
53 #include "libpspp/hmapx.h"
54 #include "libpspp/message.h"
55 #include "libpspp/pool.h"
56 #include "libpspp/str.h"
57 #include "libpspp/taint.h"
58 #include "math/moments.h"
60 #include "gl/xalloc.h"
63 #define _(msgid) gettext (msgid)
65 /* Settings for subcommand specifiers. */
72 /* Array indices for STATISTICS subcommand. */
75 NPAR_ST_DESCRIPTIVES
= 0,
76 NPAR_ST_QUARTILES
= 1,
81 /* NPAR TESTS structure. */
84 /* Count variables indicating how many
85 of the subcommands have been given. */
99 int jonckheere_terpstra
;
104 /* How missing values should be treated */
107 /* Which statistics have been requested */
108 int a_statistics
[NPAR_ST_count
];
115 struct npar_test
**test
;
118 const struct variable
**vv
; /* Compendium of all variables
119 (those mentioned on ANY subcommand */
120 int n_vars
; /* Number of variables in vv */
122 enum mv_class filter
; /* Missing values to filter. */
124 bool descriptives
; /* Descriptive statistics should be calculated */
125 bool quartiles
; /* Quartiles should be calculated */
127 bool exact
; /* Whether exact calculations have been requested */
128 double timer
; /* Maximum time (in minutes) to wait for exact calculations */
132 /* Prototype for custom subcommands of NPAR TESTS. */
133 static int npar_chisquare (struct lexer
*, struct dataset
*, struct npar_specs
*);
134 static int npar_binomial (struct lexer
*, struct dataset
*, struct npar_specs
*);
135 static int npar_ks_one_sample (struct lexer
*, struct dataset
*, struct npar_specs
*);
136 static int npar_runs (struct lexer
*, struct dataset
*, struct npar_specs
*);
137 static int npar_friedman (struct lexer
*, struct dataset
*, struct npar_specs
*);
138 static int npar_kendall (struct lexer
*, struct dataset
*, struct npar_specs
*);
139 static int npar_cochran (struct lexer
*, struct dataset
*, struct npar_specs
*);
140 static int npar_wilcoxon (struct lexer
*, struct dataset
*, struct npar_specs
*);
141 static int npar_sign (struct lexer
*, struct dataset
*, struct npar_specs
*);
142 static int npar_kruskal_wallis (struct lexer
*, struct dataset
*, struct npar_specs
*);
143 static int npar_jonckheere_terpstra (struct lexer
*, struct dataset
*, struct npar_specs
*);
144 static int npar_mann_whitney (struct lexer
*, struct dataset
*, struct npar_specs
*);
145 static int npar_mcnemar (struct lexer
*, struct dataset
*, struct npar_specs
*);
146 static int npar_median (struct lexer
*, struct dataset
*, struct npar_specs
*);
148 static int npar_method (struct lexer
*, struct npar_specs
*);
150 /* Command parsing functions. */
151 static int parse_npar_tests (struct lexer
*lexer
, struct dataset
*ds
, struct cmd_npar_tests
*p
,
152 struct npar_specs
*npar_specs
);
155 parse_npar_tests (struct lexer
*lexer
, struct dataset
*ds
, struct cmd_npar_tests
*npt
,
156 struct npar_specs
*nps
)
161 npt
->ks_one_sample
= 0;
167 npt
->kruskal_wallis
= 0;
168 npt
->mann_whitney
= 0;
171 npt
->jonckheere_terpstra
= 0;
173 npt
->miss
= MISS_ANALYSIS
;
178 memset (npt
->a_statistics
, 0, sizeof npt
->a_statistics
);
181 if (lex_match_id (lexer
, "COCHRAN"))
184 switch (npar_cochran (lexer
, ds
, nps
))
191 lex_error (lexer
, NULL
);
197 else if (lex_match_id (lexer
, "FRIEDMAN"))
200 switch (npar_friedman (lexer
, ds
, nps
))
207 lex_error (lexer
, NULL
);
213 else if (lex_match_id (lexer
, "KENDALL"))
216 switch (npar_kendall (lexer
, ds
, nps
))
223 lex_error (lexer
, NULL
);
229 else if (lex_match_id (lexer
, "RUNS"))
232 switch (npar_runs (lexer
, ds
, nps
))
239 lex_error (lexer
, NULL
);
245 else if (lex_match_id (lexer
, "CHISQUARE"))
247 lex_match (lexer
, T_EQUALS
);
249 switch (npar_chisquare (lexer
, ds
, nps
))
256 lex_error (lexer
, NULL
);
264 else if (lex_match_id (lexer
, "BINOMIAL"))
266 lex_match (lexer
, T_EQUALS
);
268 switch (npar_binomial (lexer
, ds
, nps
))
275 lex_error (lexer
, NULL
);
281 else if (lex_match_phrase (lexer
, "K-S") ||
282 lex_match_phrase (lexer
, "KOLMOGOROV-SMIRNOV"))
284 lex_match (lexer
, T_EQUALS
);
285 npt
->ks_one_sample
++;
286 switch (npar_ks_one_sample (lexer
, ds
, nps
))
293 lex_error (lexer
, NULL
);
299 else if (lex_match_phrase (lexer
, "J-T") ||
300 lex_match_phrase (lexer
, "JONCKHEERE-TERPSTRA"))
302 lex_match (lexer
, T_EQUALS
);
303 npt
->jonckheere_terpstra
++;
304 switch (npar_jonckheere_terpstra (lexer
, ds
, nps
))
311 lex_error (lexer
, NULL
);
317 else if (lex_match_phrase (lexer
, "K-W") ||
318 lex_match_phrase (lexer
, "KRUSKAL-WALLIS"))
320 lex_match (lexer
, T_EQUALS
);
321 npt
->kruskal_wallis
++;
322 switch (npar_kruskal_wallis (lexer
, ds
, nps
))
329 lex_error (lexer
, NULL
);
335 else if (lex_match_phrase (lexer
, "MCNEMAR"))
337 lex_match (lexer
, T_EQUALS
);
339 switch (npar_mcnemar (lexer
, ds
, nps
))
346 lex_error (lexer
, NULL
);
352 else if (lex_match_phrase (lexer
, "M-W") ||
353 lex_match_phrase (lexer
, "MANN-WHITNEY"))
355 lex_match (lexer
, T_EQUALS
);
357 switch (npar_mann_whitney (lexer
, ds
, nps
))
364 lex_error (lexer
, NULL
);
370 else if (lex_match_phrase (lexer
, "MEDIAN"))
374 switch (npar_median (lexer
, ds
, nps
))
381 lex_error (lexer
, NULL
);
387 else if (lex_match_id (lexer
, "WILCOXON"))
389 lex_match (lexer
, T_EQUALS
);
391 switch (npar_wilcoxon (lexer
, ds
, nps
))
398 lex_error (lexer
, NULL
);
404 else if (lex_match_id (lexer
, "SIGN"))
406 lex_match (lexer
, T_EQUALS
);
408 switch (npar_sign (lexer
, ds
, nps
))
415 lex_error (lexer
, NULL
);
421 else if (lex_match_id (lexer
, "MISSING"))
423 lex_match (lexer
, T_EQUALS
);
425 if (npt
->missing
> 1)
427 lex_sbc_only_once ("MISSING");
430 while (lex_token (lexer
) != T_SLASH
&& lex_token (lexer
) != T_ENDCMD
)
432 if (lex_match_id (lexer
, "ANALYSIS"))
433 npt
->miss
= MISS_ANALYSIS
;
434 else if (lex_match_id (lexer
, "LISTWISE"))
435 npt
->miss
= MISS_LISTWISE
;
436 else if (lex_match_id (lexer
, "INCLUDE"))
437 nps
->filter
= MV_SYSTEM
;
438 else if (lex_match_id (lexer
, "EXCLUDE"))
439 nps
->filter
= MV_ANY
;
442 lex_error (lexer
, NULL
);
445 lex_match (lexer
, T_COMMA
);
448 else if (lex_match_id (lexer
, "METHOD"))
450 lex_match (lexer
, T_EQUALS
);
454 lex_sbc_only_once ("METHOD");
457 switch (npar_method (lexer
, nps
))
464 lex_error (lexer
, NULL
);
470 else if (lex_match_id (lexer
, "STATISTICS"))
472 lex_match (lexer
, T_EQUALS
);
474 while (lex_token (lexer
) != T_SLASH
&& lex_token (lexer
) != T_ENDCMD
)
476 if (lex_match_id (lexer
, "DESCRIPTIVES"))
477 npt
->a_statistics
[NPAR_ST_DESCRIPTIVES
] = 1;
478 else if (lex_match_id (lexer
, "QUARTILES"))
479 npt
->a_statistics
[NPAR_ST_QUARTILES
] = 1;
480 else if (lex_match (lexer
, T_ALL
))
481 npt
->a_statistics
[NPAR_ST_ALL
] = 1;
484 lex_error (lexer
, NULL
);
487 lex_match (lexer
, T_COMMA
);
490 else if ( settings_get_syntax () != COMPATIBLE
&& lex_match_id (lexer
, "ALGORITHM"))
492 lex_match (lexer
, T_EQUALS
);
493 if (lex_match_id (lexer
, "COMPATIBLE"))
494 settings_set_cmd_algorithm (COMPATIBLE
);
495 else if (lex_match_id (lexer
, "ENHANCED"))
496 settings_set_cmd_algorithm (ENHANCED
);
498 if (!lex_match (lexer
, T_SLASH
))
501 if (lex_token (lexer
) != T_ENDCMD
)
503 lex_error (lexer
, _("expecting end of command"));
514 static void one_sample_insert_variables (const struct npar_test
*test
,
517 static void two_sample_insert_variables (const struct npar_test
*test
,
520 static void n_sample_insert_variables (const struct npar_test
*test
,
524 npar_execute (struct casereader
*input
,
525 const struct npar_specs
*specs
,
526 const struct dataset
*ds
)
529 struct descriptives
*summary_descriptives
= NULL
;
531 for ( t
= 0 ; t
< specs
->n_tests
; ++t
)
533 const struct npar_test
*test
= specs
->test
[t
];
534 if ( NULL
== test
->execute
)
536 msg (SW
, _("%s subcommand not currently implemented."), "NPAR");
539 test
->execute (ds
, casereader_clone (input
), specs
->filter
, test
, specs
->exact
, specs
->timer
);
542 if (specs
->descriptives
&& specs
->n_vars
> 0)
544 summary_descriptives
= xnmalloc (sizeof (*summary_descriptives
),
547 npar_summary_calc_descriptives (summary_descriptives
,
548 casereader_clone (input
),
550 specs
->vv
, specs
->n_vars
,
554 if ( (specs
->descriptives
|| specs
->quartiles
)
555 && !taint_has_tainted_successor (casereader_get_taint (input
)) )
556 do_summary_box (summary_descriptives
, specs
->vv
, specs
->n_vars
);
558 free (summary_descriptives
);
559 casereader_destroy (input
);
563 cmd_npar_tests (struct lexer
*lexer
, struct dataset
*ds
)
565 struct cmd_npar_tests cmd
;
568 struct npar_specs npar_specs
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
569 struct casegrouper
*grouper
;
570 struct casereader
*input
, *group
;
571 struct hmapx var_map
= HMAPX_INITIALIZER (var_map
);
574 npar_specs
.pool
= pool_create ();
575 npar_specs
.filter
= MV_ANY
;
576 npar_specs
.n_vars
= -1;
577 npar_specs
.vv
= NULL
;
579 if ( ! parse_npar_tests (lexer
, ds
, &cmd
, &npar_specs
) )
581 pool_destroy (npar_specs
.pool
);
585 for (i
= 0; i
< npar_specs
.n_tests
; ++i
)
587 const struct npar_test
*test
= npar_specs
.test
[i
];
588 test
->insert_variables (test
, &var_map
);
592 struct hmapx_node
*node
;
593 struct variable
*var
;
594 npar_specs
.n_vars
= 0;
596 HMAPX_FOR_EACH (var
, node
, &var_map
)
598 npar_specs
.n_vars
++;
599 npar_specs
.vv
= pool_nrealloc (npar_specs
.pool
, npar_specs
.vv
, npar_specs
.n_vars
, sizeof (*npar_specs
.vv
));
600 npar_specs
.vv
[npar_specs
.n_vars
- 1] = var
;
604 sort (npar_specs
.vv
, npar_specs
.n_vars
, sizeof (*npar_specs
.vv
),
605 compare_var_ptrs_by_name
, NULL
);
607 if ( cmd
.statistics
)
611 for ( i
= 0 ; i
< NPAR_ST_count
; ++i
)
613 if ( cmd
.a_statistics
[i
] )
617 case NPAR_ST_DESCRIPTIVES
:
618 npar_specs
.descriptives
= true;
620 case NPAR_ST_QUARTILES
:
621 npar_specs
.quartiles
= true;
624 npar_specs
.quartiles
= true;
625 npar_specs
.descriptives
= true;
634 input
= proc_open (ds
);
635 if ( cmd
.miss
== MISS_LISTWISE
)
637 input
= casereader_create_filter_missing (input
,
645 grouper
= casegrouper_create_splits (input
, dataset_dict (ds
));
646 while (casegrouper_get_next_group (grouper
, &group
))
647 npar_execute (group
, &npar_specs
, ds
);
648 ok
= casegrouper_destroy (grouper
);
649 ok
= proc_commit (ds
) && ok
;
651 pool_destroy (npar_specs
.pool
);
652 hmapx_destroy (&var_map
);
654 return ok
? CMD_SUCCESS
: CMD_CASCADING_FAILURE
;
658 npar_runs (struct lexer
*lexer
, struct dataset
*ds
,
659 struct npar_specs
*specs
)
661 struct runs_test
*rt
= pool_alloc (specs
->pool
, sizeof (*rt
));
662 struct one_sample_test
*tp
= &rt
->parent
;
663 struct npar_test
*nt
= &tp
->parent
;
665 nt
->execute
= runs_execute
;
666 nt
->insert_variables
= one_sample_insert_variables
;
668 if ( lex_force_match (lexer
, T_LPAREN
) )
670 if ( lex_match_id (lexer
, "MEAN"))
672 rt
->cp_mode
= CP_MEAN
;
674 else if (lex_match_id (lexer
, "MEDIAN"))
676 rt
->cp_mode
= CP_MEDIAN
;
678 else if (lex_match_id (lexer
, "MODE"))
680 rt
->cp_mode
= CP_MODE
;
682 else if (lex_is_number (lexer
))
684 rt
->cutpoint
= lex_number (lexer
);
685 rt
->cp_mode
= CP_CUSTOM
;
690 lex_error (lexer
, _("Expecting %s, %s, %s or a number."), "MEAN", "MEDIAN", "MODE");
694 if (! lex_force_match (lexer
, T_RPAREN
))
697 if (! lex_force_match (lexer
, T_EQUALS
))
700 if (!parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
701 &tp
->vars
, &tp
->n_vars
,
702 PV_NO_SCRATCH
| PV_NO_DUPLICATE
| PV_NUMERIC
))
709 specs
->test
= pool_realloc (specs
->pool
,
711 sizeof (*specs
->test
) * specs
->n_tests
);
713 specs
->test
[specs
->n_tests
- 1] = nt
;
719 npar_friedman (struct lexer
*lexer
, struct dataset
*ds
,
720 struct npar_specs
*specs
)
722 struct friedman_test
*ft
= pool_alloc (specs
->pool
, sizeof (*ft
));
723 struct one_sample_test
*ost
= &ft
->parent
;
724 struct npar_test
*nt
= &ost
->parent
;
726 ft
->kendalls_w
= false;
727 nt
->execute
= friedman_execute
;
728 nt
->insert_variables
= one_sample_insert_variables
;
730 lex_match (lexer
, T_EQUALS
);
732 if (!parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
733 &ost
->vars
, &ost
->n_vars
,
734 PV_NO_SCRATCH
| PV_NO_DUPLICATE
| PV_NUMERIC
))
740 specs
->test
= pool_realloc (specs
->pool
,
742 sizeof (*specs
->test
) * specs
->n_tests
);
744 specs
->test
[specs
->n_tests
- 1] = nt
;
750 npar_kendall (struct lexer
*lexer
, struct dataset
*ds
,
751 struct npar_specs
*specs
)
753 struct friedman_test
*kt
= pool_alloc (specs
->pool
, sizeof (*kt
));
754 struct one_sample_test
*ost
= &kt
->parent
;
755 struct npar_test
*nt
= &ost
->parent
;
757 kt
->kendalls_w
= true;
758 nt
->execute
= friedman_execute
;
759 nt
->insert_variables
= one_sample_insert_variables
;
761 lex_match (lexer
, T_EQUALS
);
763 if (!parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
764 &ost
->vars
, &ost
->n_vars
,
765 PV_NO_SCRATCH
| PV_NO_DUPLICATE
| PV_NUMERIC
))
771 specs
->test
= pool_realloc (specs
->pool
,
773 sizeof (*specs
->test
) * specs
->n_tests
);
775 specs
->test
[specs
->n_tests
- 1] = nt
;
782 npar_cochran (struct lexer
*lexer
, struct dataset
*ds
,
783 struct npar_specs
*specs
)
785 struct one_sample_test
*ft
= pool_alloc (specs
->pool
, sizeof (*ft
));
786 struct npar_test
*nt
= &ft
->parent
;
788 nt
->execute
= cochran_execute
;
789 nt
->insert_variables
= one_sample_insert_variables
;
791 lex_match (lexer
, T_EQUALS
);
793 if (!parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
794 &ft
->vars
, &ft
->n_vars
,
795 PV_NO_SCRATCH
| PV_NO_DUPLICATE
| PV_NUMERIC
))
801 specs
->test
= pool_realloc (specs
->pool
,
803 sizeof (*specs
->test
) * specs
->n_tests
);
805 specs
->test
[specs
->n_tests
- 1] = nt
;
812 npar_chisquare (struct lexer
*lexer
, struct dataset
*ds
,
813 struct npar_specs
*specs
)
815 struct chisquare_test
*cstp
= pool_alloc (specs
->pool
, sizeof (*cstp
));
816 struct one_sample_test
*tp
= &cstp
->parent
;
817 struct npar_test
*nt
= &tp
->parent
;
820 nt
->execute
= chisquare_execute
;
821 nt
->insert_variables
= one_sample_insert_variables
;
823 if (!parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
824 &tp
->vars
, &tp
->n_vars
,
825 PV_NO_SCRATCH
| PV_NO_DUPLICATE
))
830 cstp
->ranged
= false;
832 if ( lex_match (lexer
, T_LPAREN
))
835 if ( ! lex_force_num (lexer
)) return 0;
836 cstp
->lo
= lex_number (lexer
);
838 if (! lex_force_match (lexer
, T_COMMA
)) return 0;
839 if (! lex_force_num (lexer
) ) return 0;
840 cstp
->hi
= lex_number (lexer
);
841 if ( cstp
->lo
>= cstp
->hi
)
844 _("The specified value of HI (%d) is "
845 "lower than the specified value of LO (%d)"),
850 if (! lex_force_match (lexer
, T_RPAREN
)) return 0;
853 cstp
->n_expected
= 0;
854 cstp
->expected
= NULL
;
855 if (lex_match_phrase (lexer
, "/EXPECTED"))
857 if (! lex_force_match (lexer
, T_EQUALS
)) return 0;
858 if (! lex_match_id (lexer
, "EQUAL") )
862 while ( lex_is_number (lexer
) )
866 f
= lex_number (lexer
);
868 if ( lex_match (lexer
, T_ASTERISK
))
871 if (!lex_force_num (lexer
))
873 f
= lex_number (lexer
);
876 lex_match (lexer
, T_COMMA
);
878 cstp
->n_expected
+= n
;
879 cstp
->expected
= pool_realloc (specs
->pool
,
883 for ( i
= cstp
->n_expected
- n
;
884 i
< cstp
->n_expected
;
886 cstp
->expected
[i
] = f
;
892 if ( cstp
->ranged
&& cstp
->n_expected
> 0 &&
893 cstp
->n_expected
!= cstp
->hi
- cstp
->lo
+ 1 )
896 _("%d expected values were given, but the specified "
897 "range (%d-%d) requires exactly %d values."),
898 cstp
->n_expected
, cstp
->lo
, cstp
->hi
,
899 cstp
->hi
- cstp
->lo
+1);
904 specs
->test
= pool_realloc (specs
->pool
,
906 sizeof (*specs
->test
) * specs
->n_tests
);
908 specs
->test
[specs
->n_tests
- 1] = nt
;
915 npar_binomial (struct lexer
*lexer
, struct dataset
*ds
,
916 struct npar_specs
*specs
)
918 struct binomial_test
*btp
= pool_alloc (specs
->pool
, sizeof (*btp
));
919 struct one_sample_test
*tp
= &btp
->parent
;
920 struct npar_test
*nt
= &tp
->parent
;
923 nt
->execute
= binomial_execute
;
924 nt
->insert_variables
= one_sample_insert_variables
;
926 btp
->category1
= btp
->category2
= btp
->cutpoint
= SYSMIS
;
930 if ( lex_match (lexer
, T_LPAREN
) )
933 if ( lex_force_num (lexer
) )
935 btp
->p
= lex_number (lexer
);
937 if (!lex_force_match (lexer
, T_RPAREN
))
947 if (!lex_force_match (lexer
, T_EQUALS
))
951 if (parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
952 &tp
->vars
, &tp
->n_vars
,
953 PV_NUMERIC
| PV_NO_SCRATCH
| PV_NO_DUPLICATE
) )
955 if (lex_match (lexer
, T_LPAREN
))
957 if (! lex_force_num (lexer
))
959 btp
->category1
= lex_number (lexer
);
961 if ( lex_match (lexer
, T_COMMA
))
963 if ( ! lex_force_num (lexer
) ) return 2;
964 btp
->category2
= lex_number (lexer
);
969 btp
->cutpoint
= btp
->category1
;
972 if (! lex_force_match (lexer
, T_RPAREN
))
983 specs
->test
= pool_realloc (specs
->pool
,
985 sizeof (*specs
->test
) * specs
->n_tests
);
987 specs
->test
[specs
->n_tests
- 1] = nt
;
995 ks_one_sample_parse_params (struct lexer
*lexer
, struct ks_one_sample_test
*kst
, int params
)
997 assert (params
== 1 || params
== 2);
999 if (lex_is_number (lexer
))
1001 kst
->p
[0] = lex_number (lexer
);
1006 lex_match (lexer
, T_COMMA
);
1007 if (lex_force_num (lexer
))
1009 kst
->p
[1] = lex_number (lexer
);
1017 npar_ks_one_sample (struct lexer
*lexer
, struct dataset
*ds
, struct npar_specs
*specs
)
1019 struct ks_one_sample_test
*kst
= pool_alloc (specs
->pool
, sizeof (*kst
));
1020 struct one_sample_test
*tp
= &kst
->parent
;
1021 struct npar_test
*nt
= &tp
->parent
;
1023 nt
->execute
= ks_one_sample_execute
;
1024 nt
->insert_variables
= one_sample_insert_variables
;
1026 kst
->p
[0] = kst
->p
[1] = SYSMIS
;
1028 if (! lex_force_match (lexer
, T_LPAREN
))
1031 if (lex_match_id (lexer
, "NORMAL"))
1033 kst
->dist
= KS_NORMAL
;
1034 ks_one_sample_parse_params (lexer
, kst
, 2);
1036 else if (lex_match_id (lexer
, "POISSON"))
1038 kst
->dist
= KS_POISSON
;
1039 ks_one_sample_parse_params (lexer
, kst
, 1);
1041 else if (lex_match_id (lexer
, "UNIFORM"))
1043 kst
->dist
= KS_UNIFORM
;
1044 ks_one_sample_parse_params (lexer
, kst
, 2);
1046 else if (lex_match_id (lexer
, "EXPONENTIAL"))
1048 kst
->dist
= KS_EXPONENTIAL
;
1049 ks_one_sample_parse_params (lexer
, kst
, 1);
1054 if (! lex_force_match (lexer
, T_RPAREN
))
1057 lex_match (lexer
, T_EQUALS
);
1059 if (! parse_variables_const_pool (lexer
, specs
->pool
, dataset_dict (ds
),
1060 &tp
->vars
, &tp
->n_vars
,
1061 PV_NUMERIC
| PV_NO_SCRATCH
| PV_NO_DUPLICATE
) )
1065 specs
->test
= pool_realloc (specs
->pool
,
1067 sizeof (*specs
->test
) * specs
->n_tests
);
1069 specs
->test
[specs
->n_tests
- 1] = nt
;
1076 parse_two_sample_related_test (struct lexer
*lexer
,
1077 const struct dictionary
*dict
,
1078 struct two_sample_test
*test_parameters
,
1082 bool paired
= false;
1084 const struct variable
**vlist1
;
1087 const struct variable
**vlist2
;
1090 test_parameters
->parent
.insert_variables
= two_sample_insert_variables
;
1092 if (!parse_variables_const_pool (lexer
, pool
,
1095 PV_NUMERIC
| PV_NO_SCRATCH
| PV_DUPLICATE
) )
1098 if ( lex_match (lexer
, T_WITH
))
1101 if ( !parse_variables_const_pool (lexer
, pool
, dict
,
1103 PV_NUMERIC
| PV_NO_SCRATCH
| PV_DUPLICATE
) )
1106 paired
= (lex_match (lexer
, T_LPAREN
) &&
1107 lex_match_id (lexer
, "PAIRED") && lex_match (lexer
, T_RPAREN
));
1115 if ( n_vlist1
!= n_vlist2
)
1117 msg (SE
, _("PAIRED was specified but the number of variables "
1118 "preceding WITH (%zu) did not match the number "
1119 "following (%zu)."), n_vlist1
, n_vlist2
);
1123 test_parameters
->n_pairs
= n_vlist1
;
1127 test_parameters
->n_pairs
= n_vlist1
* n_vlist2
;
1132 test_parameters
->n_pairs
= (n_vlist1
* (n_vlist1
- 1)) / 2 ;
1135 test_parameters
->pairs
=
1136 pool_alloc (pool
, sizeof ( variable_pair
) * test_parameters
->n_pairs
);
1143 assert (n_vlist1
== n_vlist2
);
1144 for ( i
= 0 ; i
< n_vlist1
; ++i
)
1146 test_parameters
->pairs
[n
][0] = vlist1
[i
];
1147 test_parameters
->pairs
[n
][1] = vlist2
[i
];
1154 for ( i
= 0 ; i
< n_vlist1
; ++i
)
1156 for ( j
= 0 ; j
< n_vlist2
; ++j
)
1158 test_parameters
->pairs
[n
][0] = vlist1
[i
];
1159 test_parameters
->pairs
[n
][1] = vlist2
[j
];
1168 for ( i
= 0 ; i
< n_vlist1
- 1; ++i
)
1170 for ( j
= i
+ 1 ; j
< n_vlist1
; ++j
)
1172 assert ( n
< test_parameters
->n_pairs
);
1173 test_parameters
->pairs
[n
][0] = vlist1
[i
];
1174 test_parameters
->pairs
[n
][1] = vlist1
[j
];
1180 assert ( n
== test_parameters
->n_pairs
);
1187 parse_n_sample_related_test (struct lexer
*lexer
,
1188 const struct dictionary
*dict
,
1189 struct n_sample_test
*nst
,
1193 if (!parse_variables_const_pool (lexer
, pool
,
1195 &nst
->vars
, &nst
->n_vars
,
1196 PV_NUMERIC
| PV_NO_SCRATCH
| PV_NO_DUPLICATE
) )
1199 if ( ! lex_force_match (lexer
, T_BY
))
1202 nst
->indep_var
= parse_variable_const (lexer
, dict
);
1203 if (!nst
->indep_var
)
1206 if ( ! lex_force_match (lexer
, T_LPAREN
))
1209 value_init (&nst
->val1
, var_get_width (nst
->indep_var
));
1210 if ( ! parse_value (lexer
, &nst
->val1
, nst
->indep_var
))
1212 value_destroy (&nst
->val1
, var_get_width (nst
->indep_var
));
1216 lex_match (lexer
, T_COMMA
);
1218 value_init (&nst
->val2
, var_get_width (nst
->indep_var
));
1219 if ( ! parse_value (lexer
, &nst
->val2
, nst
->indep_var
))
1221 value_destroy (&nst
->val2
, var_get_width (nst
->indep_var
));
1225 if ( ! lex_force_match (lexer
, T_RPAREN
))
1232 npar_wilcoxon (struct lexer
*lexer
,
1234 struct npar_specs
*specs
)
1236 struct two_sample_test
*tp
= pool_alloc (specs
->pool
, sizeof (*tp
));
1237 struct npar_test
*nt
= &tp
->parent
;
1238 nt
->execute
= wilcoxon_execute
;
1240 if (!parse_two_sample_related_test (lexer
, dataset_dict (ds
),
1245 specs
->test
= pool_realloc (specs
->pool
,
1247 sizeof (*specs
->test
) * specs
->n_tests
);
1248 specs
->test
[specs
->n_tests
- 1] = nt
;
1255 npar_mann_whitney (struct lexer
*lexer
,
1257 struct npar_specs
*specs
)
1259 struct n_sample_test
*tp
= pool_alloc (specs
->pool
, sizeof (*tp
));
1260 struct npar_test
*nt
= &tp
->parent
;
1262 nt
->insert_variables
= n_sample_insert_variables
;
1263 nt
->execute
= mann_whitney_execute
;
1265 if (!parse_n_sample_related_test (lexer
, dataset_dict (ds
),
1270 specs
->test
= pool_realloc (specs
->pool
,
1272 sizeof (*specs
->test
) * specs
->n_tests
);
1273 specs
->test
[specs
->n_tests
- 1] = nt
;
1280 npar_median (struct lexer
*lexer
,
1282 struct npar_specs
*specs
)
1284 struct median_test
*mt
= pool_alloc (specs
->pool
, sizeof (*mt
));
1285 struct n_sample_test
*tp
= &mt
->parent
;
1286 struct npar_test
*nt
= &tp
->parent
;
1288 mt
->median
= SYSMIS
;
1290 if ( lex_match (lexer
, T_LPAREN
) && lex_force_num (lexer
))
1292 mt
->median
= lex_number (lexer
);
1294 if (! lex_force_match (lexer
, T_RPAREN
))
1298 lex_match (lexer
, T_EQUALS
);
1300 nt
->insert_variables
= n_sample_insert_variables
;
1301 nt
->execute
= median_execute
;
1303 if (!parse_n_sample_related_test (lexer
, dataset_dict (ds
),
1308 specs
->test
= pool_realloc (specs
->pool
,
1310 sizeof (*specs
->test
) * specs
->n_tests
);
1311 specs
->test
[specs
->n_tests
- 1] = nt
;
1318 npar_sign (struct lexer
*lexer
, struct dataset
*ds
,
1319 struct npar_specs
*specs
)
1321 struct two_sample_test
*tp
= pool_alloc (specs
->pool
, sizeof (*tp
));
1322 struct npar_test
*nt
= &tp
->parent
;
1324 nt
->execute
= sign_execute
;
1326 if (!parse_two_sample_related_test (lexer
, dataset_dict (ds
),
1331 specs
->test
= pool_realloc (specs
->pool
,
1333 sizeof (*specs
->test
) * specs
->n_tests
);
1334 specs
->test
[specs
->n_tests
- 1] = nt
;
1341 npar_mcnemar (struct lexer
*lexer
, struct dataset
*ds
,
1342 struct npar_specs
*specs
)
1344 struct two_sample_test
*tp
= pool_alloc (specs
->pool
, sizeof (*tp
));
1345 struct npar_test
*nt
= &tp
->parent
;
1347 nt
->execute
= mcnemar_execute
;
1349 if (!parse_two_sample_related_test (lexer
, dataset_dict (ds
),
1354 specs
->test
= pool_realloc (specs
->pool
,
1356 sizeof (*specs
->test
) * specs
->n_tests
);
1357 specs
->test
[specs
->n_tests
- 1] = nt
;
1364 npar_jonckheere_terpstra (struct lexer
*lexer
, struct dataset
*ds
,
1365 struct npar_specs
*specs
)
1367 struct n_sample_test
*tp
= pool_alloc (specs
->pool
, sizeof (*tp
));
1368 struct npar_test
*nt
= &tp
->parent
;
1370 nt
->insert_variables
= n_sample_insert_variables
;
1372 nt
->execute
= jonckheere_terpstra_execute
;
1374 if (!parse_n_sample_related_test (lexer
, dataset_dict (ds
),
1379 specs
->test
= pool_realloc (specs
->pool
,
1381 sizeof (*specs
->test
) * specs
->n_tests
);
1382 specs
->test
[specs
->n_tests
- 1] = nt
;
1388 npar_kruskal_wallis (struct lexer
*lexer
, struct dataset
*ds
,
1389 struct npar_specs
*specs
)
1391 struct n_sample_test
*tp
= pool_alloc (specs
->pool
, sizeof (*tp
));
1392 struct npar_test
*nt
= &tp
->parent
;
1394 nt
->insert_variables
= n_sample_insert_variables
;
1396 nt
->execute
= kruskal_wallis_execute
;
1398 if (!parse_n_sample_related_test (lexer
, dataset_dict (ds
),
1403 specs
->test
= pool_realloc (specs
->pool
,
1405 sizeof (*specs
->test
) * specs
->n_tests
);
1406 specs
->test
[specs
->n_tests
- 1] = nt
;
1412 insert_variable_into_map (struct hmapx
*var_map
, const struct variable
*var
)
1414 size_t hash
= hash_pointer (var
, 0);
1415 struct hmapx_node
*node
;
1416 const struct variable
*v
= NULL
;
1418 HMAPX_FOR_EACH_WITH_HASH (v
, node
, hash
, var_map
)
1424 hmapx_insert (var_map
, CONST_CAST (struct variable
*, var
), hash
);
1427 /* Insert the variables for TEST into VAR_MAP */
1429 one_sample_insert_variables (const struct npar_test
*test
,
1430 struct hmapx
*var_map
)
1433 const struct one_sample_test
*ost
= UP_CAST (test
, const struct one_sample_test
, parent
);
1435 for ( i
= 0 ; i
< ost
->n_vars
; ++i
)
1436 insert_variable_into_map (var_map
, ost
->vars
[i
]);
1441 two_sample_insert_variables (const struct npar_test
*test
,
1442 struct hmapx
*var_map
)
1445 const struct two_sample_test
*tst
= UP_CAST (test
, const struct two_sample_test
, parent
);
1447 for ( i
= 0 ; i
< tst
->n_pairs
; ++i
)
1449 variable_pair
*pair
= &tst
->pairs
[i
];
1451 insert_variable_into_map (var_map
, (*pair
)[0]);
1452 insert_variable_into_map (var_map
, (*pair
)[1]);
1457 n_sample_insert_variables (const struct npar_test
*test
,
1458 struct hmapx
*var_map
)
1461 const struct n_sample_test
*tst
= UP_CAST (test
, const struct n_sample_test
, parent
);
1463 for ( i
= 0 ; i
< tst
->n_vars
; ++i
)
1464 insert_variable_into_map (var_map
, tst
->vars
[i
]);
1466 insert_variable_into_map (var_map
, tst
->indep_var
);
1471 npar_method (struct lexer
*lexer
, struct npar_specs
*specs
)
1473 if ( lex_match_id (lexer
, "EXACT") )
1475 specs
->exact
= true;
1477 if (lex_match_id (lexer
, "TIMER"))
1481 if ( lex_match (lexer
, T_LPAREN
))
1483 if (lex_force_num (lexer
) )
1485 specs
->timer
= lex_number (lexer
);
1488 if (lex_force_match (lexer
, T_RPAREN
))