X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fnpar.q;h=535797227b2a23974e6a13da5ed265b0a8c419b2;hb=c75794cffb05769b71a346af8513a3e8dde55f94;hp=eff5c9195f3eb7f7e7190b4ed65aa363783c1491;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp diff --git a/src/language/stats/npar.q b/src/language/stats/npar.q index eff5c9195f..535797227b 100644 --- a/src/language/stats/npar.q +++ b/src/language/stats/npar.q @@ -1,25 +1,22 @@ -/* PSPP - NPAR TESTS. -*-c-*- +/* PSPP - a program for statistical analysis. -*-c-*- + Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc. -Copyright (C) 2006 Free Software Foundation, Inc. -Author: John Darrington , + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. -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 the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include + #include #include @@ -34,6 +31,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA #include #include #include +#include +#include +#include #include #include #include @@ -57,7 +57,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +friedman=varlist; +kendall=varlist; missing=miss:!analysis/listwise, - incl:include/!exclude; + incl:include/!exclude; + method=custom; +statistics[st_]=descriptives,quartiles,all. */ /* (declarations) */ @@ -74,17 +75,25 @@ struct npar_specs size_t n_tests; const struct variable ** vv; /* Compendium of all variables - (those mentioned on ANY subcommand */ + (those mentioned on ANY subcommand */ int n_vars; /* Number of variables in vv */ enum mv_class filter; /* Missing values to filter. */ bool descriptives; /* Descriptive statistics should be calculated */ bool quartiles; /* Quartiles should be calculated */ + + bool exact; /* Whether exact calculations have been requested */ + double timer; /* Maximum time (in minutes) to wait for exact calculations */ }; -void one_sample_insert_variables (const struct npar_test *test, - struct const_hsh_table *variables); +static void one_sample_insert_variables (const struct npar_test *test, + struct const_hsh_table *variables); + +static void two_sample_insert_variables (const struct npar_test *test, + struct const_hsh_table *variables); + + static void npar_execute(struct casereader *input, @@ -102,7 +111,7 @@ npar_execute(struct casereader *input, msg (SW, _("NPAR subcommand not currently implemented.")); continue; } - test->execute (ds, casereader_clone (input), specs->filter, test); + test->execute (ds, casereader_clone (input), specs->filter, test, specs->exact, specs->timer); } if ( specs->descriptives ) @@ -125,12 +134,13 @@ npar_execute(struct casereader *input, casereader_destroy (input); } + int cmd_npar_tests (struct lexer *lexer, struct dataset *ds) { bool ok; int i; - struct npar_specs npar_specs = {0, 0, 0, 0, 0, 0, 0, 0}; + struct npar_specs npar_specs = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; struct const_hsh_table *var_hash; struct casegrouper *grouper; struct casereader *input, *group; @@ -138,8 +148,8 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds) npar_specs.pool = pool_create (); var_hash = const_hsh_create_pool (npar_specs.pool, 0, - compare_vars_by_name, hash_var_by_name, - NULL, NULL); + compare_vars_by_name, hash_var_by_name, + NULL, NULL); if ( ! parse_npar_tests (lexer, ds, &cmd, &npar_specs) ) { @@ -153,7 +163,7 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds) test->insert_variables (test, var_hash); } - npar_specs.vv = (const struct variable **) const_hsh_data (var_hash); + npar_specs.vv = (const struct variable **) const_hsh_sort (var_hash); npar_specs.n_vars = const_hsh_count (var_hash); if ( cmd.sbc_statistics ) @@ -187,10 +197,14 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds) input = proc_open (ds); if ( cmd.miss == NPAR_LISTWISE ) - input = casereader_create_filter_missing (input, - npar_specs.vv, - npar_specs.n_vars, - npar_specs.filter, NULL); + { + input = casereader_create_filter_missing (input, + npar_specs.vv, + npar_specs.n_vars, + npar_specs.filter, + NULL, NULL); + } + grouper = casegrouper_create_splits (input, dataset_dict (ds)); while (casegrouper_get_next_group (grouper, &group)) @@ -206,19 +220,21 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds) } int -npar_custom_chisquare(struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests *cmd UNUSED, void *aux ) +npar_custom_chisquare (struct lexer *lexer, struct dataset *ds, + struct cmd_npar_tests *cmd UNUSED, void *aux ) { struct npar_specs *specs = aux; struct chisquare_test *cstp = pool_alloc(specs->pool, sizeof(*cstp)); - struct one_sample_test *tp = (struct one_sample_test *) cstp; + struct one_sample_test *tp = &cstp->parent; + struct npar_test *nt = &tp->parent; - ((struct npar_test *)tp)->execute = chisquare_execute; - ((struct npar_test *)tp)->insert_variables = one_sample_insert_variables; + nt->execute = chisquare_execute; + nt->insert_variables = one_sample_insert_variables; if (!parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), - &tp->vars, &tp->n_vars, - PV_NO_SCRATCH | PV_NO_DUPLICATE)) + &tp->vars, &tp->n_vars, + PV_NO_SCRATCH | PV_NO_DUPLICATE)) { return 2; } @@ -304,25 +320,29 @@ npar_custom_chisquare(struct lexer *lexer, struct dataset *ds, struct cmd_npar_t specs->test, sizeof(*specs->test) * specs->n_tests); - specs->test[specs->n_tests - 1] = (struct npar_test *) tp; + specs->test[specs->n_tests - 1] = nt; return 1; } int -npar_custom_binomial(struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests *cmd UNUSED, void *aux) +npar_custom_binomial (struct lexer *lexer, struct dataset *ds, + struct cmd_npar_tests *cmd UNUSED, void *aux) { struct npar_specs *specs = aux; struct binomial_test *btp = pool_alloc(specs->pool, sizeof(*btp)); - struct one_sample_test *tp = (struct one_sample_test *) btp; + struct one_sample_test *tp = &btp->parent; + struct npar_test *nt = &tp->parent; - ((struct npar_test *)tp)->execute = binomial_execute; - ((struct npar_test *)tp)->insert_variables = one_sample_insert_variables; + nt->execute = binomial_execute; + nt->insert_variables = one_sample_insert_variables; btp->category1 = btp->category2 = btp->cutpoint = SYSMIS; - if ( lex_match(lexer, '(') ) + btp->p = 0.5; + + if ( lex_match (lexer, '(') ) { if ( lex_force_num (lexer) ) { @@ -333,37 +353,39 @@ npar_custom_binomial(struct lexer *lexer, struct dataset *ds, struct cmd_npar_te else return 0; } + else + /* Kludge: q2c swallows the '=' so put it back here */ + lex_put_back (lexer, '='); + if ( lex_match (lexer, '=') ) { if (parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), - &tp->vars, &tp->n_vars, - PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) + &tp->vars, &tp->n_vars, + PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) { if ( lex_match (lexer, '(')) { lex_force_num (lexer); btp->category1 = lex_number (lexer); - lex_get (lexer); - if ( ! lex_force_match (lexer, ',')) return 2; - if ( ! lex_force_num (lexer) ) return 2; - btp->category2 = lex_number (lexer); - lex_get (lexer); + lex_get (lexer); + if ( lex_match (lexer, ',')) + { + if ( ! lex_force_num (lexer) ) return 2; + btp->category2 = lex_number (lexer); + lex_get (lexer); + } + else + { + btp->cutpoint = btp->category1; + } + lex_force_match (lexer, ')'); } } else return 2; - } - else - { - if ( lex_match (lexer, '(') ) - { - lex_force_num (lexer); - btp->cutpoint = lex_number (lexer); - lex_get (lexer); - lex_force_match (lexer, ')'); - } + } specs->n_tests++; @@ -371,7 +393,7 @@ npar_custom_binomial(struct lexer *lexer, struct dataset *ds, struct cmd_npar_te specs->test, sizeof(*specs->test) * specs->n_tests); - specs->test[specs->n_tests - 1] = (struct npar_test *) tp; + specs->test[specs->n_tests - 1] = nt; return 1; } @@ -402,18 +424,20 @@ parse_two_sample_related_test (struct lexer *lexer, const struct variable **vlist2; size_t n_vlist2; + test_parameters->parent.insert_variables = two_sample_insert_variables; + if (!parse_variables_const_pool (lexer, pool, - dict, - &vlist1, &n_vlist1, - PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) + dict, + &vlist1, &n_vlist1, + PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) return false; if ( lex_match(lexer, T_WITH)) { with = true; if ( !parse_variables_const_pool (lexer, pool, dict, - &vlist2, &n_vlist2, - PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) + &vlist2, &n_vlist2, + PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) ) return false; paired = (lex_match (lexer, '(') && @@ -427,8 +451,8 @@ parse_two_sample_related_test (struct lexer *lexer, { if ( n_vlist1 != n_vlist2) msg (SE, _("PAIRED was specified but the number of variables " - "preceding WITH (%d) did not match the number " - "following (%d)."), (int) n_vlist1, (int) n_vlist2); + "preceding WITH (%zu) did not match the number " + "following (%zu)."), n_vlist1, n_vlist2); test_parameters->n_pairs = n_vlist1 ; } @@ -453,8 +477,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][0] = vlist1[i]; - test_parameters->pairs[n][1] = vlist2[i]; + test_parameters->pairs[n][1] = vlist1[i]; + test_parameters->pairs[n][0] = vlist2[i]; n++; } } @@ -465,8 +489,8 @@ parse_two_sample_related_test (struct lexer *lexer, { for ( j = 0 ; j < n_vlist2; ++j ) { - test_parameters->pairs[n][0] = vlist1[i]; - test_parameters->pairs[n][1] = vlist2[j]; + test_parameters->pairs[n][1] = vlist1[i]; + test_parameters->pairs[n][0] = vlist2[j]; n++; } } @@ -480,8 +504,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][0] = vlist1[i]; - test_parameters->pairs[n][1] = vlist1[j]; + test_parameters->pairs[n][1] = vlist1[i]; + test_parameters->pairs[n][0] = vlist1[j]; n++; } } @@ -499,8 +523,9 @@ npar_custom_wilcoxon (struct lexer *lexer, { struct npar_specs *specs = aux; - struct two_sample_test *tp = pool_alloc(specs->pool, sizeof(*tp)); - ((struct npar_test *)tp)->execute = NULL; + struct two_sample_test *tp = pool_alloc (specs->pool, sizeof(*tp)); + struct npar_test *nt = &tp->parent; + nt->execute = wilcoxon_execute; if (!parse_two_sample_related_test (lexer, dataset_dict (ds), cmd, tp, specs->pool) ) @@ -510,7 +535,7 @@ npar_custom_wilcoxon (struct lexer *lexer, specs->test = pool_realloc (specs->pool, specs->test, sizeof(*specs->test) * specs->n_tests); - specs->test[specs->n_tests - 1] = (struct npar_test *) tp; + specs->test[specs->n_tests - 1] = nt; return 1; } @@ -523,7 +548,8 @@ npar_custom_mcnemar (struct lexer *lexer, struct npar_specs *specs = aux; struct two_sample_test *tp = pool_alloc(specs->pool, sizeof(*tp)); - ((struct npar_test *)tp)->execute = NULL; + struct npar_test *nt = &tp->parent; + nt->execute = NULL; if (!parse_two_sample_related_test (lexer, dataset_dict (ds), @@ -534,7 +560,7 @@ npar_custom_mcnemar (struct lexer *lexer, specs->test = pool_realloc (specs->pool, specs->test, sizeof(*specs->test) * specs->n_tests); - specs->test[specs->n_tests - 1] = (struct npar_test *) tp; + specs->test[specs->n_tests - 1] = nt; return 1; } @@ -546,8 +572,9 @@ npar_custom_sign (struct lexer *lexer, struct dataset *ds, struct npar_specs *specs = aux; struct two_sample_test *tp = pool_alloc(specs->pool, sizeof(*tp)); - ((struct npar_test *)tp)->execute = NULL; + struct npar_test *nt = &tp->parent; + nt->execute = sign_execute; if (!parse_two_sample_related_test (lexer, dataset_dict (ds), cmd, tp, specs->pool) ) @@ -557,20 +584,67 @@ npar_custom_sign (struct lexer *lexer, struct dataset *ds, specs->test = pool_realloc (specs->pool, specs->test, sizeof(*specs->test) * specs->n_tests); - specs->test[specs->n_tests - 1] = (struct npar_test *) tp; + specs->test[specs->n_tests - 1] = nt; return 1; } /* Insert the variables for TEST into VAR_HASH */ -void +static void one_sample_insert_variables (const struct npar_test *test, - struct const_hsh_table *var_hash) + struct const_hsh_table *var_hash) { int i; - struct one_sample_test *ost = (struct one_sample_test *) test; + struct one_sample_test *ost = UP_CAST (test, struct one_sample_test, parent); for ( i = 0 ; i < ost->n_vars ; ++i ) const_hsh_insert (var_hash, ost->vars[i]); } +static void +two_sample_insert_variables (const struct npar_test *test, + struct const_hsh_table *var_hash) +{ + int i; + + const struct two_sample_test *tst = (const struct two_sample_test *) test; + + for ( i = 0 ; i < tst->n_pairs ; ++i ) + { + variable_pair *pair = &tst->pairs[i]; + + const_hsh_insert (var_hash, (*pair)[0]); + const_hsh_insert (var_hash, (*pair)[1]); + } + +} + + +static int +npar_custom_method (struct lexer *lexer, struct dataset *ds UNUSED, + struct cmd_npar_tests *test UNUSED, void *aux) +{ + struct npar_specs *specs = aux; + + if ( lex_match_id (lexer, "EXACT") ) + { + specs->exact = true; + specs->timer = 0.0; + if (lex_match_id (lexer, "TIMER")) + { + specs->timer = 5.0; + + if ( lex_match (lexer, '(')) + { + if ( lex_force_num (lexer) ) + { + specs->timer = lex_number (lexer); + lex_get (lexer); + } + lex_force_match (lexer, ')'); + } + } + } + + return 1; +}