X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fnpar.c;h=bfeaf8f76fd67c90efb75390fca1bd9f1bb6311b;hb=32ee0e0402d6d56674f53a47d879ec5c07dabe09;hp=73db1ad0b369fbe63889931220d1403d4f0ba97e;hpb=ced729f41f90e56a7c8ec12f6497f61c9b73b779;p=pspp diff --git a/src/language/stats/npar.c b/src/language/stats/npar.c index 73db1ad0b3..bfeaf8f76f 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 Free Software Foundation, Inc. + Copyright (C) 2006, 2008, 2009, 2010, 2011 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 @@ -16,44 +16,46 @@ #include -#include -#include "npar-summary.h" +#include "language/stats/npar.h" #include #include -#include "xalloc.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "data/case.h" +#include "data/casegrouper.h" +#include "data/casereader.h" +#include "data/dataset.h" +#include "data/dictionary.h" +#include "data/settings.h" +#include "data/variable.h" +#include "language/command.h" +#include "language/lexer/lexer.h" +#include "language/lexer/value-parser.h" +#include "language/lexer/variable-parser.h" +#include "language/stats/binomial.h" +#include "language/stats/chisquare.h" +#include "language/stats/ks-one-sample.h" +#include "language/stats/cochran.h" +#include "language/stats/friedman.h" +#include "language/stats/kruskal-wallis.h" +#include "language/stats/mann-whitney.h" +#include "language/stats/mcnemar.h" +#include "language/stats/npar-summary.h" +#include "language/stats/runs.h" +#include "language/stats/sign.h" +#include "language/stats/wilcoxon.h" +#include "libpspp/array.h" +#include "libpspp/assertion.h" +#include "libpspp/cast.h" +#include "libpspp/hash-functions.h" +#include "libpspp/hmapx.h" +#include "libpspp/message.h" +#include "libpspp/pool.h" +#include "libpspp/str.h" +#include "libpspp/taint.h" +#include "math/moments.h" + +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -82,6 +84,7 @@ struct cmd_npar_tests int chisquare; int cochran; int binomial; + int ks_one_sample; int wilcoxon; int sign; int runs; @@ -89,6 +92,7 @@ struct cmd_npar_tests int kendall; int kruskal_wallis; int mann_whitney; + int mcnemar; int missing; int method; int statistics; @@ -124,6 +128,7 @@ struct npar_specs /* Prototype for custom subcommands of NPAR TESTS. */ static int npar_chisquare (struct lexer *, struct dataset *, struct npar_specs *); static int npar_binomial (struct lexer *, struct dataset *, struct npar_specs *); +static int npar_ks_one_sample (struct lexer *, struct dataset *, struct npar_specs *); static int npar_runs (struct lexer *, struct dataset *, struct npar_specs *); static int npar_friedman (struct lexer *, struct dataset *, struct npar_specs *); static int npar_kendall (struct lexer *, struct dataset *, struct npar_specs *); @@ -132,6 +137,7 @@ 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_mann_whitney (struct lexer *, struct dataset *, struct npar_specs *); +static int npar_mcnemar (struct lexer *, struct dataset *, struct npar_specs *); static int npar_method (struct lexer *, struct npar_specs *); /* Command parsing functions. */ @@ -144,10 +150,12 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests { npt->binomial = 0; npt->chisquare = 0; + npt->ks_one_sample = 0; npt->cochran = 0; npt->friedman = 0; npt->kruskal_wallis = 0; npt->mann_whitney = 0; + npt->mcnemar = 0; npt->runs = 0; npt->sign = 0; npt->wilcoxon = 0; @@ -235,6 +243,8 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests case 2: lex_error (lexer, NULL); goto lossage; + case 3: + continue; default: NOT_REACHED (); } @@ -256,8 +266,26 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests NOT_REACHED (); } } - else if (lex_match_hyphenated_word (lexer, "K-W") || - lex_match_hyphenated_word (lexer, "KRUSKAL-WALLIS")) + else if (lex_match_phrase (lexer, "K-S") || + lex_match_phrase (lexer, "KOLMOGOROV-SMIRNOV")) + { + lex_match (lexer, T_EQUALS); + npt->ks_one_sample++; + switch (npar_ks_one_sample (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")) { lex_match (lexer, T_EQUALS); npt->kruskal_wallis++; @@ -274,8 +302,25 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests NOT_REACHED (); } } - else if (lex_match_hyphenated_word (lexer, "M-W") || - lex_match_hyphenated_word (lexer, "MANN-WHITNEY")) + else if (lex_match_phrase (lexer, "MCNEMAR")) + { + lex_match (lexer, T_EQUALS); + npt->mcnemar++; + switch (npar_mcnemar (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, "M-W") || + lex_match_phrase (lexer, "MANN-WHITNEY")) { lex_match (lexer, T_EQUALS); npt->mann_whitney++; @@ -720,7 +765,7 @@ npar_chisquare (struct lexer *lexer, struct dataset *ds, struct chisquare_test *cstp = pool_alloc (specs->pool, sizeof (*cstp)); struct one_sample_test *tp = &cstp->parent; struct npar_test *nt = &tp->parent; - + int retval = 1; nt->execute = chisquare_execute; nt->insert_variables = one_sample_insert_variables; @@ -757,44 +802,39 @@ npar_chisquare (struct lexer *lexer, struct dataset *ds, cstp->n_expected = 0; cstp->expected = NULL; - if ( lex_match (lexer, T_SLASH) ) + if (lex_match_phrase (lexer, "/EXPECTED")) { - if ( lex_match_id (lexer, "EXPECTED") ) - { - lex_force_match (lexer, T_EQUALS); - if ( ! lex_match_id (lexer, "EQUAL") ) - { - double f; - int n; - while ( lex_is_number (lexer) ) - { - int i; - n = 1; - f = lex_number (lexer); - lex_get (lexer); - if ( lex_match (lexer, T_ASTERISK)) - { - n = f; - f = lex_number (lexer); - lex_get (lexer); - } - lex_match (lexer, T_COMMA); - - cstp->n_expected += n; - cstp->expected = pool_realloc (specs->pool, - cstp->expected, - sizeof (double) * - cstp->n_expected); - for ( i = cstp->n_expected - n ; - i < cstp->n_expected; - ++i ) - cstp->expected[i] = f; + lex_force_match (lexer, T_EQUALS); + if ( ! lex_match_id (lexer, "EQUAL") ) + { + double f; + int n; + while ( lex_is_number (lexer) ) + { + int i; + n = 1; + f = lex_number (lexer); + lex_get (lexer); + if ( lex_match (lexer, T_ASTERISK)) + { + n = f; + f = lex_number (lexer); + lex_get (lexer); + } + lex_match (lexer, T_COMMA); - } - } - } - else - lex_put_back (lexer, T_SLASH); + cstp->n_expected += n; + cstp->expected = pool_realloc (specs->pool, + cstp->expected, + sizeof (double) * + cstp->n_expected); + for ( i = cstp->n_expected - n ; + i < cstp->n_expected; + ++i ) + cstp->expected[i] = f; + + } + } } if ( cstp->ranged && cstp->n_expected > 0 && @@ -815,7 +855,7 @@ npar_chisquare (struct lexer *lexer, struct dataset *ds, specs->test[specs->n_tests - 1] = nt; - return 1; + return retval; } @@ -826,7 +866,7 @@ npar_binomial (struct lexer *lexer, struct dataset *ds, struct binomial_test *btp = pool_alloc (specs->pool, sizeof (*btp)); struct one_sample_test *tp = &btp->parent; struct npar_test *nt = &tp->parent; - bool equals; + bool equals = false; nt->execute = binomial_execute; nt->insert_variables = one_sample_insert_variables; @@ -891,20 +931,93 @@ npar_binomial (struct lexer *lexer, struct dataset *ds, } -static bool -parse_two_sample_related_test (struct lexer *lexer, - const struct dictionary *dict, - struct two_sample_test *test_parameters, - struct pool *pool - ); + +static void +ks_one_sample_parse_params (struct lexer *lexer, struct ks_one_sample_test *kst, int params) +{ + assert (params == 1 || params == 2); + + if (lex_is_number (lexer)) + { + kst->p[0] = lex_number (lexer); + + lex_get (lexer); + if ( params == 2) + { + lex_match (lexer, T_COMMA); + if (lex_force_num (lexer)) + { + kst->p[1] = lex_number (lexer); + lex_get (lexer); + } + } + } +} + +static int +npar_ks_one_sample (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs) +{ + struct ks_one_sample_test *kst = pool_alloc (specs->pool, sizeof (*kst)); + struct one_sample_test *tp = &kst->parent; + struct npar_test *nt = &tp->parent; + + nt->execute = ks_one_sample_execute; + nt->insert_variables = one_sample_insert_variables; + + kst->p[0] = kst->p[1] = SYSMIS; + + if (! lex_force_match (lexer, T_LPAREN)) + return 2; + + if (lex_match_id (lexer, "NORMAL")) + { + kst->dist = KS_NORMAL; + ks_one_sample_parse_params (lexer, kst, 2); + } + else if (lex_match_id (lexer, "POISSON")) + { + kst->dist = KS_POISSON; + ks_one_sample_parse_params (lexer, kst, 1); + } + else if (lex_match_id (lexer, "UNIFORM")) + { + kst->dist = KS_UNIFORM; + ks_one_sample_parse_params (lexer, kst, 2); + } + else if (lex_match_id (lexer, "EXPONENTIAL")) + { + kst->dist = KS_EXPONENTIAL; + ks_one_sample_parse_params (lexer, kst, 1); + } + else + return 2; + + if (! lex_force_match (lexer, T_RPAREN)) + return 2; + + 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) ) + return 2; + + specs->n_tests++; + specs->test = pool_realloc (specs->pool, + specs->test, + sizeof (*specs->test) * specs->n_tests); + + specs->test[specs->n_tests - 1] = kst; + + return 1; +} static bool parse_two_sample_related_test (struct lexer *lexer, const struct dictionary *dict, struct two_sample_test *test_parameters, - struct pool *pool - ) + struct pool *pool) { int n = 0; bool paired = false; @@ -968,8 +1081,8 @@ parse_two_sample_related_test (struct lexer *lexer, assert (n_vlist1 == n_vlist2); for ( i = 0 ; i < n_vlist1; ++i ) { - test_parameters->pairs[n][1] = vlist1[i]; - test_parameters->pairs[n][0] = vlist2[i]; + test_parameters->pairs[n][0] = vlist1[i]; + test_parameters->pairs[n][1] = vlist2[i]; n++; } } @@ -980,8 +1093,8 @@ parse_two_sample_related_test (struct lexer *lexer, { for ( j = 0 ; j < n_vlist2; ++j ) { - test_parameters->pairs[n][1] = vlist1[i]; - test_parameters->pairs[n][0] = vlist2[j]; + test_parameters->pairs[n][0] = vlist1[i]; + test_parameters->pairs[n][1] = vlist2[j]; n++; } } @@ -995,8 +1108,8 @@ parse_two_sample_related_test (struct lexer *lexer, for ( j = i + 1 ; j < n_vlist1; ++j ) { assert ( n < test_parameters->n_pairs); - test_parameters->pairs[n][1] = vlist1[i]; - test_parameters->pairs[n][0] = vlist1[j]; + test_parameters->pairs[n][0] = vlist1[i]; + test_parameters->pairs[n][1] = vlist1[j]; n++; } } @@ -1030,7 +1143,7 @@ parse_n_sample_related_test (struct lexer *lexer, return false; value_init (&nst->val1, var_get_width (nst->indep_var)); - if ( ! parse_value (lexer, &nst->val1, var_get_width (nst->indep_var))) + if ( ! parse_value (lexer, &nst->val1, nst->indep_var)) { value_destroy (&nst->val1, var_get_width (nst->indep_var)); return false; @@ -1039,7 +1152,7 @@ parse_n_sample_related_test (struct lexer *lexer, lex_match (lexer, T_COMMA); value_init (&nst->val2, var_get_width (nst->indep_var)); - if ( ! parse_value (lexer, &nst->val2, var_get_width (nst->indep_var))) + if ( ! parse_value (lexer, &nst->val2, nst->indep_var)) { value_destroy (&nst->val2, var_get_width (nst->indep_var)); return false; @@ -1056,8 +1169,6 @@ npar_wilcoxon (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs ) { - - struct two_sample_test *tp = pool_alloc (specs->pool, sizeof (*tp)); struct npar_test *nt = &tp->parent; nt->execute = wilcoxon_execute; @@ -1101,6 +1212,8 @@ npar_mann_whitney (struct lexer *lexer, } + + static int npar_sign (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs) @@ -1123,6 +1236,30 @@ npar_sign (struct lexer *lexer, struct dataset *ds, return 1; } + +static int +npar_mcnemar (struct lexer *lexer, struct dataset *ds, + struct npar_specs *specs) +{ + struct two_sample_test *tp = pool_alloc (specs->pool, sizeof (*tp)); + struct npar_test *nt = &tp->parent; + + nt->execute = mcnemar_execute; + + if (!parse_two_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)