Fixed bug parsing binomial test.
[pspp-builds.git] / src / language / stats / npar.q
index 34e03677dc9bc145568a910c05a1ea83a063d4e5..535797227b2a23974e6a13da5ed265b0a8c419b2 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis. -*-c-*-
-   Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2008, 2009 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,6 +16,7 @@
 
 #include <config.h>
 
+
 #include <language/stats/npar.h>
 
 #include <math.h>
@@ -31,6 +32,8 @@
 #include <language/stats/binomial.h>
 #include <language/stats/chisquare.h>
 #include <language/stats/wilcoxon.h>
+#include <language/stats/sign.h>
+#include <libpspp/cast.h>
 #include <libpspp/hash.h>
 #include <libpspp/pool.h>
 #include <libpspp/taint.h>
@@ -131,6 +134,7 @@ npar_execute(struct casereader *input,
   casereader_destroy (input);
 }
 
+
 int
 cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
 {
@@ -159,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 )
@@ -222,10 +226,11 @@ npar_custom_chisquare (struct lexer *lexer, struct dataset *ds,
   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,
@@ -315,7 +320,7 @@ npar_custom_chisquare (struct lexer *lexer, struct dataset *ds,
                              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;
 }
@@ -327,14 +332,17 @@ npar_custom_binomial (struct lexer *lexer, struct dataset *ds,
 {
   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) )
        {
@@ -345,6 +353,10 @@ npar_custom_binomial (struct lexer *lexer, struct dataset *ds,
       else
        return 0;
     }
+  else
+    /* Kludge: q2c swallows the '=' so put it back here  */
+     lex_put_back (lexer, '=');
+
 
   if ( lex_match (lexer, '=') )
     {
@@ -356,26 +368,24 @@ npar_custom_binomial (struct lexer *lexer, struct dataset *ds,
            {
              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++;
@@ -383,7 +393,7 @@ npar_custom_binomial (struct lexer *lexer, struct dataset *ds,
                              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;
 }
@@ -414,7 +424,7 @@ parse_two_sample_related_test (struct lexer *lexer,
   const struct variable **vlist2;
   size_t n_vlist2;
 
-  ((struct npar_test *)test_parameters)->insert_variables = two_sample_insert_variables;
+  test_parameters->parent.insert_variables = two_sample_insert_variables;
 
   if (!parse_variables_const_pool (lexer, pool,
                                   dict,
@@ -514,7 +524,8 @@ 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 = wilcoxon_execute;
+  struct npar_test *nt = &tp->parent;
+  nt->execute = wilcoxon_execute;
 
   if (!parse_two_sample_related_test (lexer, dataset_dict (ds), cmd,
                                      tp, specs->pool) )
@@ -524,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;
 }
@@ -537,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),
@@ -548,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;
 }
@@ -560,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) )
@@ -571,7 +584,7 @@ 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;
 }
@@ -582,7 +595,7 @@ one_sample_insert_variables (const struct npar_test *test,
                             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]);