X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fnpar.c;h=1d369eca44a6b091451762c1dd16a61ce1ca576f;hb=a49b940e58f148bf111c647d9b4822025636ff80;hp=3260117d4f5e2fc71ebf20001dd7dea2f13f3c05;hpb=da1bf03a84fa10f04e8c5438f22b523f0480dd7d;p=pspp diff --git a/src/language/stats/npar.c b/src/language/stats/npar.c index 3260117d4f..1d369eca44 100644 --- a/src/language/stats/npar.c +++ b/src/language/stats/npar.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. -*-c-*- - Copyright (C) 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2006, 2008, 2009, 2010, 2011, 2016 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,6 +37,7 @@ #include "language/stats/ks-one-sample.h" #include "language/stats/cochran.h" #include "language/stats/friedman.h" +#include "language/stats/jonckheere-terpstra.h" #include "language/stats/kruskal-wallis.h" #include "language/stats/mann-whitney.h" #include "language/stats/mcnemar.h" @@ -95,6 +96,7 @@ struct cmd_npar_tests int mann_whitney; int mcnemar; int median; + int jonckheere_terpstra; int missing; int method; int statistics; @@ -138,6 +140,7 @@ static int npar_cochran (struct lexer *, struct dataset *, struct npar_specs *); static int npar_wilcoxon (struct lexer *, struct dataset *, struct npar_specs *); static int npar_sign (struct lexer *, struct dataset *, struct npar_specs *); static int npar_kruskal_wallis (struct lexer *, struct dataset *, struct npar_specs *); +static int npar_jonckheere_terpstra (struct lexer *, struct dataset *, struct npar_specs *); static int npar_mann_whitney (struct lexer *, struct dataset *, struct npar_specs *); static int npar_mcnemar (struct lexer *, struct dataset *, struct npar_specs *); static int npar_median (struct lexer *, struct dataset *, struct npar_specs *); @@ -152,21 +155,26 @@ static int parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests *npt, struct npar_specs *nps) { - npt->binomial = 0; npt->chisquare = 0; - npt->ks_one_sample = 0; npt->cochran = 0; + npt->binomial = 0; + npt->ks_one_sample = 0; + npt->wilcoxon = 0; + npt->sign = 0; + npt->runs = 0; npt->friedman = 0; + npt->kendall = 0; npt->kruskal_wallis = 0; npt->mann_whitney = 0; npt->mcnemar = 0; - npt->runs = 0; - npt->sign = 0; - npt->wilcoxon = 0; - npt->missing = 0; + npt->median = 0; + npt->jonckheere_terpstra = 0; + npt->miss = MISS_ANALYSIS; + npt->missing = 0; npt->method = 0; npt->statistics = 0; + memset (npt->a_statistics, 0, sizeof npt->a_statistics); for (;;) { @@ -288,6 +296,24 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests NOT_REACHED (); } } + else if (lex_match_phrase (lexer, "J-T") || + lex_match_phrase (lexer, "JONCKHEERE-TERPSTRA")) + { + lex_match (lexer, T_EQUALS); + npt->jonckheere_terpstra++; + switch (npar_jonckheere_terpstra (lexer, ds, nps)) + { + case 0: + goto lossage; + case 1: + break; + case 2: + lex_error (lexer, NULL); + goto lossage; + default: + NOT_REACHED (); + } + } else if (lex_match_phrase (lexer, "K-W") || lex_match_phrase (lexer, "KRUSKAL-WALLIS")) { @@ -472,7 +498,6 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests if (!lex_match (lexer, T_SLASH)) break; } - if (lex_token (lexer) != T_ENDCMD) { lex_error (lexer, _("expecting end of command")); @@ -508,13 +533,13 @@ npar_execute (struct casereader *input, const struct npar_test *test = specs->test[t]; if ( NULL == test->execute ) { - msg (SW, _("NPAR subcommand not currently implemented.")); + msg (SW, _("%s subcommand not currently implemented."), "NPAR"); continue; } test->execute (ds, casereader_clone (input), specs->filter, test, specs->exact, specs->timer); } - if ( specs->descriptives ) + if (specs->descriptives && specs->n_vars > 0) { summary_descriptives = xnmalloc (sizeof (*summary_descriptives), specs->n_vars); @@ -528,7 +553,8 @@ npar_execute (struct casereader *input, if ( (specs->descriptives || specs->quartiles) && !taint_has_tainted_successor (casereader_get_taint (input)) ) - do_summary_box (summary_descriptives, specs->vv, specs->n_vars ); + do_summary_box (summary_descriptives, specs->vv, specs->n_vars, + dict_get_weight_format (dataset_dict (ds))); free (summary_descriptives); casereader_destroy (input); @@ -576,7 +602,7 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds) } } - sort (npar_specs.vv, npar_specs.n_vars, sizeof (*npar_specs.vv), + sort (npar_specs.vv, npar_specs.n_vars, sizeof (*npar_specs.vv), compare_var_ptrs_by_name, NULL); if ( cmd.statistics ) @@ -662,12 +688,16 @@ npar_runs (struct lexer *lexer, struct dataset *ds, } else { - lex_error (lexer, _("Expecting MEAN, MEDIAN, MODE or number")); + lex_error (lexer, _("Expecting %s, %s, %s or a number."), "MEAN", "MEDIAN", "MODE"); return 0; } - - lex_force_match (lexer, T_RPAREN); - lex_force_match (lexer, T_EQUALS); + + if (! lex_force_match (lexer, T_RPAREN)) + return 2; + + if (! lex_force_match (lexer, T_EQUALS)) + return 2; + if (!parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), &tp->vars, &tp->n_vars, PV_NO_SCRATCH | PV_NO_DUPLICATE | PV_NUMERIC)) @@ -690,7 +720,7 @@ static int npar_friedman (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs) { - struct friedman_test *ft = pool_alloc (specs->pool, sizeof (*ft)); + struct friedman_test *ft = pool_alloc (specs->pool, sizeof (*ft)); struct one_sample_test *ost = &ft->parent; struct npar_test *nt = &ost->parent; @@ -721,7 +751,7 @@ static int npar_kendall (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs) { - struct friedman_test *kt = pool_alloc (specs->pool, sizeof (*kt)); + struct friedman_test *kt = pool_alloc (specs->pool, sizeof (*kt)); struct one_sample_test *ost = &kt->parent; struct npar_test *nt = &ost->parent; @@ -753,7 +783,7 @@ static int npar_cochran (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs) { - struct one_sample_test *ft = pool_alloc (specs->pool, sizeof (*ft)); + struct one_sample_test *ft = pool_alloc (specs->pool, sizeof (*ft)); struct npar_test *nt = &ft->parent; nt->execute = cochran_execute; @@ -804,11 +834,11 @@ npar_chisquare (struct lexer *lexer, struct dataset *ds, { cstp->ranged = true; if ( ! lex_force_num (lexer)) return 0; - cstp->lo = lex_integer (lexer); + cstp->lo = lex_number (lexer); lex_get (lexer); - lex_force_match (lexer, T_COMMA); + if (! lex_force_match (lexer, T_COMMA)) return 0; if (! lex_force_num (lexer) ) return 0; - cstp->hi = lex_integer (lexer); + cstp->hi = lex_number (lexer); if ( cstp->lo >= cstp->hi ) { msg (ME, @@ -825,8 +855,8 @@ npar_chisquare (struct lexer *lexer, struct dataset *ds, cstp->expected = NULL; if (lex_match_phrase (lexer, "/EXPECTED")) { - lex_force_match (lexer, T_EQUALS); - if ( ! lex_match_id (lexer, "EQUAL") ) + if (! lex_force_match (lexer, T_EQUALS)) return 0; + if (! lex_match_id (lexer, "EQUAL") ) { double f; int n; @@ -839,6 +869,8 @@ npar_chisquare (struct lexer *lexer, struct dataset *ds, if ( lex_match (lexer, T_ASTERISK)) { n = f; + if (!lex_force_num (lexer)) + return 0; f = lex_number (lexer); lex_get (lexer); } @@ -903,7 +935,8 @@ npar_binomial (struct lexer *lexer, struct dataset *ds, { btp->p = lex_number (lexer); lex_get (lexer); - lex_force_match (lexer, T_RPAREN); + if (!lex_force_match (lexer, T_RPAREN)) + return 0; } else return 0; @@ -911,35 +944,41 @@ npar_binomial (struct lexer *lexer, struct dataset *ds, else equals = true; - if (equals || lex_match (lexer, T_EQUALS) ) - { - if (parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), - &tp->vars, &tp->n_vars, - PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) - { - if (lex_match (lexer, T_LPAREN)) - { - lex_force_num (lexer); - btp->category1 = lex_number (lexer); - lex_get (lexer); - if ( lex_match (lexer, T_COMMA)) - { - if ( ! lex_force_num (lexer) ) return 2; - btp->category2 = lex_number (lexer); - lex_get (lexer); - } - else - { - btp->cutpoint = btp->category1; - } - - lex_force_match (lexer, T_RPAREN); - } - } - else - return 2; + if (!equals) + if (!lex_force_match (lexer, T_EQUALS)) + return 0; - } + { + if (parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), + &tp->vars, &tp->n_vars, + PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) + { + if (lex_match (lexer, T_LPAREN)) + { + if (! lex_force_num (lexer)) + return 2; + btp->category1 = lex_number (lexer); + lex_get (lexer); + if ( lex_match (lexer, T_COMMA)) + { + if ( ! lex_force_num (lexer) ) return 2; + btp->category2 = lex_number (lexer); + lex_get (lexer); + } + else + { + btp->cutpoint = btp->category1; + } + + if (! lex_force_match (lexer, T_RPAREN)) + return 0; + } + } + else + { + return 2; + } + } specs->n_tests++; specs->test = pool_realloc (specs->pool, @@ -1054,7 +1093,7 @@ parse_two_sample_related_test (struct lexer *lexer, if (!parse_variables_const_pool (lexer, pool, dict, &vlist1, &n_vlist1, - PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) + PV_NUMERIC | PV_NO_SCRATCH | PV_DUPLICATE) ) return false; if ( lex_match (lexer, T_WITH)) @@ -1062,7 +1101,7 @@ parse_two_sample_related_test (struct lexer *lexer, with = true; if ( !parse_variables_const_pool (lexer, pool, dict, &vlist2, &n_vlist2, - PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) + PV_NUMERIC | PV_NO_SCRATCH | PV_DUPLICATE) ) return false; paired = (lex_match (lexer, T_LPAREN) && @@ -1075,9 +1114,12 @@ parse_two_sample_related_test (struct lexer *lexer, if (paired) { if ( n_vlist1 != n_vlist2) - msg (SE, _("PAIRED was specified but the number of variables " + { + msg (SE, _("PAIRED was specified but the number of variables " "preceding WITH (%zu) did not match the number " "following (%zu)."), n_vlist1, n_vlist2); + return false; + } test_parameters->n_pairs = n_vlist1 ; } @@ -1159,6 +1201,8 @@ parse_n_sample_related_test (struct lexer *lexer, return false; nst->indep_var = parse_variable_const (lexer, dict); + if (!nst->indep_var) + return false; if ( ! lex_force_match (lexer, T_LPAREN)) return false; @@ -1244,12 +1288,12 @@ npar_median (struct lexer *lexer, mt->median = SYSMIS; - if ( lex_match (lexer, T_LPAREN)) + if ( lex_match (lexer, T_LPAREN) && lex_force_num (lexer)) { - lex_force_num (lexer); mt->median = lex_number (lexer); lex_get (lexer); - lex_force_match (lexer, T_RPAREN); + if (! lex_force_match (lexer, T_RPAREN)) + return 0; } lex_match (lexer, T_EQUALS); @@ -1317,6 +1361,30 @@ npar_mcnemar (struct lexer *lexer, struct dataset *ds, } +static int +npar_jonckheere_terpstra (struct lexer *lexer, struct dataset *ds, + struct npar_specs *specs) +{ + struct n_sample_test *tp = pool_alloc (specs->pool, sizeof (*tp)); + struct npar_test *nt = &tp->parent; + + nt->insert_variables = n_sample_insert_variables; + + nt->execute = jonckheere_terpstra_execute; + + if (!parse_n_sample_related_test (lexer, dataset_dict (ds), + tp, specs->pool) ) + return 0; + + specs->n_tests++; + specs->test = pool_realloc (specs->pool, + specs->test, + sizeof (*specs->test) * specs->n_tests); + specs->test[specs->n_tests - 1] = nt; + + return 1; +} + static int npar_kruskal_wallis (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs) @@ -1347,7 +1415,7 @@ insert_variable_into_map (struct hmapx *var_map, const struct variable *var) size_t hash = hash_pointer (var, 0); struct hmapx_node *node; const struct variable *v = NULL; - + HMAPX_FOR_EACH_WITH_HASH (v, node, hash, var_map) { if ( v == var) @@ -1386,7 +1454,7 @@ two_sample_insert_variables (const struct npar_test *test, } } -static void +static void n_sample_insert_variables (const struct npar_test *test, struct hmapx *var_map) { @@ -1413,12 +1481,13 @@ npar_method (struct lexer *lexer, struct npar_specs *specs) if ( lex_match (lexer, T_LPAREN)) { - if ( lex_force_num (lexer) ) + if (lex_force_num (lexer) ) { specs->timer = lex_number (lexer); lex_get (lexer); } - lex_force_match (lexer, T_RPAREN); + if (lex_force_match (lexer, T_RPAREN)) + return 0; } } }