Actually implement the new procedure code and adapt all of its clients
[pspp-builds.git] / src / language / stats / examine.q
index b337131c9ef3ff32802c370a64f351d4140fae2e..e15d294975eb2ba26960db79b225d3ff8939635e 100644 (file)
@@ -1,7 +1,6 @@
 /* PSPP - EXAMINE data for normality . -*-c-*-
 
 Copyright (C) 2004 Free Software Foundation, Inc.
-Author: John Darrington 2004, 2006
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as
@@ -27,7 +26,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 #include <stdlib.h>
 
 #include <data/case.h>
-#include <data/casefile.h>
+#include <data/casegrouper.h>
+#include <data/casereader.h>
 #include <data/dictionary.h>
 #include <data/procedure.h>
 #include <data/value-labels.h>
@@ -85,7 +85,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
 static struct cmd_examine cmd;
 
-static struct variable **dependent_vars;
+static const struct variable **dependent_vars;
 
 static size_t n_dependent_vars;
 
@@ -117,19 +117,19 @@ static int examine_parse_independent_vars (struct lexer *lexer, const struct dic
 
 
 /* Output functions */
-static void show_summary (struct variable **dependent_var, int n_dep_var,
+static void show_summary (const struct variable **dependent_var, int n_dep_var,
                         const struct factor *f);
 
-static void show_extremes (struct variable **dependent_var,
+static void show_extremes (const struct variable **dependent_var,
                          int n_dep_var,
                          const struct factor *factor,
                          int n_extremities);
 
-static void show_descriptives (struct variable **dependent_var,
+static void show_descriptives (const struct variable **dependent_var,
                              int n_dep_var,
                              struct factor *factor);
 
-static void show_percentiles (struct variable **dependent_var,
+static void show_percentiles (const struct variable **dependent_var,
                             int n_dep_var,
                             struct factor *factor);
 
@@ -153,8 +153,8 @@ void box_plot_variables (const struct factor *fctr,
 
 
 /* Per Split function */
-static bool run_examine (const struct ccase *,
-                        const struct casefile *cf, void *cmd_, const struct dataset *);
+static void run_examine (struct cmd_examine *, struct casereader *,
+                         struct dataset *);
 
 static void output_examine (void);
 
@@ -179,9 +179,8 @@ const char *factor_to_string_concise (const struct factor *fctr,
 
 
 
-/* Function to use for testing for missing values */
-static var_is_missing_func *value_is_missing;
-
+/* Categories of missing values to exclude. */
+static enum mv_class exclude_values;
 
 /* PERCENTILES */
 
@@ -195,6 +194,8 @@ static short sbc_percentile;
 int
 cmd_examine (struct lexer *lexer, struct dataset *ds)
 {
+  struct casegrouper *grouper;
+  struct casereader *group;
   bool ok;
 
   subc_list_double_create (&percentile_list);
@@ -207,10 +208,7 @@ cmd_examine (struct lexer *lexer, struct dataset *ds)
     }
 
   /* If /MISSING=INCLUDE is set, then user missing values are ignored */
-  if (cmd.incl == XMN_INCLUDE )
-    value_is_missing = var_is_value_system_missing;
-  else
-    value_is_missing = var_is_value_missing;
+  exclude_values = cmd.incl == XMN_INCLUDE ? MV_SYSTEM : MV_ANY;
 
   if ( cmd.st_n == SYSMIS )
     cmd.st_n = 5;
@@ -227,7 +225,11 @@ cmd_examine (struct lexer *lexer, struct dataset *ds)
       subc_list_double_push (&percentile_list, 75);
     }
 
-  ok = multipass_procedure_with_splits (ds, run_examine, &cmd);
+  grouper = casegrouper_create_splits (proc_open (ds), dataset_dict (ds));
+  while (casegrouper_get_next_group (grouper, &group)) 
+    run_examine (&cmd, group, ds);
+  ok = casegrouper_destroy (grouper);
+  ok = proc_commit (ds) && ok;
 
   if ( totals )
     {
@@ -530,7 +532,7 @@ xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_examin
       return 2;
     }
 
-  if (!parse_variables (lexer, dict, &dependent_vars, &n_dependent_vars,
+  if (!parse_variables_const (lexer, dict, &dependent_vars, &n_dependent_vars,
                        PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
     {
       free (dependent_vars);
@@ -632,9 +634,6 @@ void populate_summary (struct tab_table *t, int col, int row,
 
 
 
-static bool bad_weight_warn = true;
-
-
 /* Perform calculations for the sub factors */
 void
 factor_calc (const struct ccase *c, int case_no, double weight,
@@ -649,13 +648,13 @@ factor_calc (const struct ccase *c, int case_no, double weight,
       union value *indep_vals[2] ;
 
       indep_vals[0] = value_dup (
-                                case_data (c, fctr->indep_var[0]->fv),
+                                case_data (c, fctr->indep_var[0]),
                                 var_get_width (fctr->indep_var[0])
                                 );
 
       if ( fctr->indep_var[1] )
        indep_vals[1] = value_dup (
-                                  case_data (c, fctr->indep_var[1]->fv),
+                                  case_data (c, fctr->indep_var[1]),
                                   var_get_width (fctr->indep_var[1])
                                   );
       else
@@ -692,11 +691,11 @@ factor_calc (const struct ccase *c, int case_no, double weight,
        {
          const struct variable *var = dependent_vars[v];
          union value *val = value_dup (
-                                       case_data (c, var->fv),
+                                       case_data (c, var),
                                        var_get_width (var)
                                        );
 
-         if ( value_is_missing (var, val) || case_missing )
+         if (case_missing || var_is_value_missing (var, val, exclude_values))
            {
              free (val);
              continue;
@@ -711,23 +710,28 @@ factor_calc (const struct ccase *c, int case_no, double weight,
     }
 }
 
-static bool
-run_examine (const struct ccase *first, const struct casefile *cf,
-           void *cmd_, const struct dataset *ds)
+static void
+run_examine (struct cmd_examine *cmd, struct casereader *input,
+             struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
-  struct casereader *r;
+  casenumber case_no;
   struct ccase c;
   int v;
-
-  const struct cmd_examine *cmd = (struct cmd_examine *) cmd_;
+  bool ok;
 
   struct factor *fctr;
 
-  output_split_file_values (ds, first);
+  if (!casereader_peek (input, 0, &c))
+    return;
+  output_split_file_values (ds, &c);
+  case_destroy (&c);
+
+  input = casereader_create_filter_weight (input, dict, NULL, NULL);
+  input = casereader_create_counter (input, &case_no, 0);
 
   /* Make sure we haven't got rubbish left over from a
-     previous split */
+     previous split. */
   fctr = factors;
   while (fctr)
     {
@@ -743,15 +747,10 @@ run_examine (const struct ccase *first, const struct casefile *cf,
   for ( v = 0 ; v < n_dependent_vars ; ++v )
     metrics_precalc (&totals[v]);
 
-  for (r = casefile_get_reader (cf, NULL);
-      casereader_read (r, &c) ;
-      case_destroy (&c) )
+  for (; casereader_read (input, &c); case_destroy (&c))
     {
-      int case_missing=0;
-      const int case_no = casereader_cnum (r);
-
-      const double weight =
-       dict_get_case_weight (dict, &c, &bad_weight_warn);
+      int case_missing = 0;
+      const double weight = dict_get_case_weight (dict, &c, NULL);
 
       if ( cmd->miss == XMN_LISTWISE )
        {
@@ -759,11 +758,11 @@ run_examine (const struct ccase *first, const struct casefile *cf,
            {
              const struct variable *var = dependent_vars[v];
              union value *val = value_dup (
-                                                 case_data (&c, var->fv),
+                                                 case_data (&c, var),
                                                  var_get_width (var)
                                                  );
 
-             if ( value_is_missing (var, val))
+             if ( var_is_value_missing (var, val, exclude_values))
                case_missing = 1;
 
              free (val);
@@ -774,11 +773,12 @@ run_examine (const struct ccase *first, const struct casefile *cf,
        {
          const struct variable *var = dependent_vars[v];
          union value *val = value_dup (
-                                       case_data (&c, var->fv),
+                                       case_data (&c, var),
                                        var_get_width (var)
                                        );
 
-         if ( value_is_missing (var, val) || case_missing )
+         if ( var_is_value_missing (var, val, exclude_values)
+               || case_missing )
            {
              free (val) ;
              continue ;
@@ -791,6 +791,7 @@ run_examine (const struct ccase *first, const struct casefile *cf,
 
       factor_calc (&c, case_no, weight, case_missing);
     }
+  ok = casereader_destroy (input);
 
   for ( v = 0 ; v < n_dependent_vars ; ++v)
     {
@@ -886,7 +887,8 @@ run_examine (const struct ccase *first, const struct casefile *cf,
       fctr = fctr->next;
     }
 
-  output_examine ();
+  if (ok)
+    output_examine ();
 
 
   if ( totals )
@@ -897,13 +899,11 @@ run_examine (const struct ccase *first, const struct casefile *cf,
          metrics_destroy (&totals[i]);
        }
     }
-
-  return true;
 }
 
 
 static void
-show_summary (struct variable **dependent_var, int n_dep_var,
+show_summary (const struct variable **dependent_var, int n_dep_var,
             const struct factor *fctr)
 {
   static const char *subtitle[]=
@@ -1059,8 +1059,8 @@ show_summary (struct variable **dependent_var, int n_dep_var,
                            (i * n_factors ) + count +
                            heading_rows,
                            TAB_LEFT | TAT_TITLE,
-                           value_to_string ((*fs)->id[0],
-                                            fctr->indep_var[0])
+                           var_get_value_name (fctr->indep_var[0],
+                                                (*fs)->id[0])
                            );
 
                  if (fctr->indep_var[1] && count > 0 )
@@ -1078,7 +1078,7 @@ show_summary (struct variable **dependent_var, int n_dep_var,
                          (i * n_factors ) + count +
                          heading_rows,
                          TAB_LEFT | TAT_TITLE,
-                         value_to_string ((*fs)->id[1], fctr->indep_var[1])
+                         var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
                          );
 
              populate_summary (tbl, heading_columns,
@@ -1128,7 +1128,7 @@ populate_summary (struct tab_table *t, int col, int row,
 
 
 static void
-show_extremes (struct variable **dependent_var, int n_dep_var,
+show_extremes (const struct variable **dependent_var, int n_dep_var,
              const struct factor *fctr, int n_extremities)
 {
   int i;
@@ -1234,7 +1234,8 @@ show_extremes (struct variable **dependent_var, int n_dep_var,
                  tab_text (tbl,
                            1, row,
                            TAB_LEFT | TAT_TITLE,
-                           value_to_string ((*fs)->id[0], fctr->indep_var[0])
+                           var_get_value_name (fctr->indep_var[0],
+                                                (*fs)->id[0])
                            );
                }
 
@@ -1246,7 +1247,7 @@ show_extremes (struct variable **dependent_var, int n_dep_var,
              if ( fctr->indep_var[1])
                tab_text (tbl, 2, row,
                          TAB_LEFT | TAT_TITLE,
-                         value_to_string ((*fs)->id[1], fctr->indep_var[1])
+                         var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
                          );
 
              populate_extremes (tbl, heading_columns - 2,
@@ -1364,7 +1365,7 @@ populate_extremes (struct tab_table *t,
 
 /* Show the descriptives table */
 void
-show_descriptives (struct variable **dependent_var,
+show_descriptives (const struct variable **dependent_var,
                  int n_dep_var,
                  struct factor *fctr)
 {
@@ -1471,7 +1472,8 @@ show_descriptives (struct variable **dependent_var,
                  tab_text (tbl,
                            1, row,
                            TAB_LEFT | TAT_TITLE,
-                           value_to_string ((*fs)->id[0], fctr->indep_var[0])
+                           var_get_value_name (fctr->indep_var[0],
+                                                (*fs)->id[0])
                            );
                }
 
@@ -1483,7 +1485,7 @@ show_descriptives (struct variable **dependent_var,
              if ( fctr->indep_var[1])
                tab_text (tbl, 2, row,
                          TAB_LEFT | TAT_TITLE,
-                         value_to_string ((*fs)->id[1], fctr->indep_var[1])
+                         var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
                          );
 
              populate_descriptives (tbl, heading_columns - 2,
@@ -1509,18 +1511,14 @@ show_descriptives (struct variable **dependent_var,
 }
 
 
-
-
 /* Fill in the descriptives data */
 void
 populate_descriptives (struct tab_table *tbl, int col, int row,
                      const struct metrics *m)
 {
-
-  const double t = gsl_cdf_tdist_Qinv (1 - cmd.n_cinterval[0]/100.0/2.0, \
+  const double t = gsl_cdf_tdist_Qinv ((1 - cmd.n_cinterval[0] / 100.0)/2.0,
                                      m->n -1);
 
-
   tab_text (tbl, col,
            row,
            TAB_LEFT | TAT_TITLE,
@@ -1949,7 +1947,7 @@ np_plot (const struct metrics *m, const char *factorname)
 
 /* Show the percentiles */
 void
-show_percentiles (struct variable **dependent_var,
+show_percentiles (const struct variable **dependent_var,
                 int n_dep_var,
                 struct factor *fctr)
 {
@@ -2097,7 +2095,8 @@ show_percentiles (struct variable **dependent_var,
                  tab_text (tbl,
                            1, row,
                            TAB_LEFT | TAT_TITLE,
-                           value_to_string ((*fs)->id[0], fctr->indep_var[0])
+                           var_get_value_name (fctr->indep_var[0],
+                                                (*fs)->id[0])
                            );
 
 
@@ -2111,7 +2110,7 @@ show_percentiles (struct variable **dependent_var,
              if ( fctr->indep_var[1])
                tab_text (tbl, 2, row,
                          TAB_LEFT | TAT_TITLE,
-                         value_to_string ((*fs)->id[1], fctr->indep_var[1])
+                         var_get_value_name (fctr->indep_var[1], (*fs)->id[1])
                          );
 
 
@@ -2213,7 +2212,7 @@ factor_to_string (const struct factor *fctr,
 
   snprintf (buf2, 100, "%s = %s",
           var_to_string (fctr->indep_var[0]),
-          value_to_string (fs->id[0], fctr->indep_var[0]));
+           var_get_value_name (fctr->indep_var[0], fs->id[0]));
 
   strcat (buf1, buf2);
 
@@ -2221,8 +2220,7 @@ factor_to_string (const struct factor *fctr,
     {
       sprintf (buf2, "; %s = %s)",
              var_to_string (fctr->indep_var[1]),
-             value_to_string (fs->id[1],
-                             fctr->indep_var[1]));
+              var_get_value_name (fctr->indep_var[1], fs->id[1]));
       strcat (buf1, buf2);
     }
   else
@@ -2247,11 +2245,12 @@ factor_to_string_concise (const struct factor *fctr,
   char buf2[100];
 
   snprintf (buf, 100, "%s",
-          value_to_string (fs->id[0], fctr->indep_var[0]));
+            var_get_value_name (fctr->indep_var[0], fs->id[0]));
 
   if ( fctr->indep_var[1] )
     {
-      sprintf (buf2, ",%s)", value_to_string (fs->id[1], fctr->indep_var[1]) );
+      sprintf (buf2, ",%s)", var_get_value_name (fctr->indep_var[1],
+                                                 fs->id[1]) );
       strcat (buf, buf2);
     }