Categoricals cleanup: New structure 'payload' which reduces the
[pspp-builds.git] / src / language / stats / oneway.c
index 9671328031d69f72ecd922bae0edc8dec0ffacdb..480bbb91379be3dd162c239b03b941b0b5e30ff7 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012 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
@@ -575,7 +575,7 @@ dd_destroy (struct descriptive_data *dd)
 }
 
 static void *
-makeit (void *aux1, void *aux2 UNUSED)
+makeit (const void *aux1, void *aux2 UNUSED)
 {
   const struct variable *var = aux1;
 
@@ -585,12 +585,9 @@ makeit (void *aux1, void *aux2 UNUSED)
 }
 
 static void 
-updateit (void *user_data, 
-         enum mv_class exclude,
-         const struct variable *wv, 
-         const struct variable *catvar UNUSED,
-         const struct ccase *c,
-         void *aux1, void *aux2)
+updateit (const void *aux1, void *aux2, void *user_data,
+           const struct ccase *c, enum mv_class exclude,
+           const struct variable *wv)
 {
   struct descriptive_data *dd = user_data;
 
@@ -652,12 +649,19 @@ run_oneway (const struct oneway_spec *cmd,
 
   for (v = 0; v < cmd->n_vars; ++v)
     {
-      const struct interaction *inter = interaction_create (cmd->indep_var);
+      struct interaction *inter = interaction_create (cmd->indep_var);
+
+      struct payload payload;
+      payload.create = makeit;
+      payload.update = updateit;
+
       ws.vws[v].cat = categoricals_create (&inter, 1, cmd->wv,
-                                           cmd->exclude, makeit, updateit,
-                                           CONST_CAST (struct variable *,
-                                                       cmd->vars[v]),
-                                           ws.dd_total[v]);
+                                           cmd->exclude);
+
+      categoricals_set_payload (ws.vws[v].cat, &payload, 
+                               CONST_CAST (struct variable *, cmd->vars[v]),
+                               ws.dd_total[v]);
+
 
       ws.vws[v].cov = covariance_2pass_create (1, &cmd->vars[v],
                                               ws.vws[v].cat, 
@@ -756,9 +760,20 @@ run_oneway (const struct oneway_spec *cmd,
 
   for (v = 0; v < cmd->n_vars; ++v)
     {
+      gsl_matrix *cm;
       struct per_var_ws *pvw = &ws.vws[v];
-      gsl_matrix *cm = covariance_calculate_unnormalized (pvw->cov);
       const struct categoricals *cats = covariance_get_categoricals (pvw->cov);
+      const bool ok = categoricals_done (cats);
+
+      if ( ! ok)
+       {
+         msg (MW, 
+              _("Dependent variable %s has no non-missing values.  No analysis for this variable will be done."),
+              var_get_name (cmd->vars[v]));
+         continue;
+       }
+
+      cm = covariance_calculate_unnormalized (pvw->cov);
 
       moments1_calculate (ws.dd_total[v]->mom, &pvw->n, NULL, NULL, NULL, NULL);
 
@@ -770,7 +785,7 @@ run_oneway (const struct oneway_spec *cmd,
 
       pvw->ssa = pvw->sst - pvw->sse;
 
-      pvw->n_groups = categoricals_total (cats);
+      pvw->n_groups = categoricals_n_total (cats);
 
       pvw->mse = (pvw->sst - pvw->ssa) / (pvw->n - pvw->n_groups);
 
@@ -781,10 +796,13 @@ run_oneway (const struct oneway_spec *cmd,
     {
       const struct categoricals *cats = covariance_get_categoricals (ws.vws[v].cov);
 
-      categoricals_done (cats);
-      
-      if (categoricals_total (cats) > ws.actual_number_of_groups)
-       ws.actual_number_of_groups = categoricals_total (cats);
+      if ( ! categoricals_is_complete (cats))
+       {
+         continue;
+       }
+
+      if (categoricals_n_total (cats) > ws.actual_number_of_groups)
+       ws.actual_number_of_groups = categoricals_n_total (cats);
     }
 
   casereader_destroy (input);
@@ -827,7 +845,7 @@ output_oneway (const struct oneway_spec *cmd, struct oneway_workspace *ws)
       if (ll_count (cl) != ws->actual_number_of_groups)
        {
          msg (SW,
-              _("In contrast list %zu, the number of coefficients (%d) does not equal the number of groups (%d). This contrast list will be ignored."),
+              _("In contrast list %zu, the number of coefficients (%zu) does not equal the number of groups (%d). This contrast list will be ignored."),
               i, ll_count (cl), ws->actual_number_of_groups);
 
          ll_remove (&coeff_list->ll);
@@ -859,7 +877,12 @@ output_oneway (const struct oneway_spec *cmd, struct oneway_workspace *ws)
     {
       int v;
       for (v = 0 ; v < cmd->n_vars; ++v)
-       show_comparisons (cmd, ws, v);
+       {
+         const struct categoricals *cats = covariance_get_categoricals (ws->vws[v].cov);
+
+         if ( categoricals_is_complete (cats))
+           show_comparisons (cmd, ws, v);
+       }
     }
 }
 
@@ -1015,7 +1038,7 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace
       if ( v > 0)
        tab_hline (t, TAL_1, 0, n_cols - 1, row);
 
-      for (count = 0; count < categoricals_total (cats); ++count)
+      for (count = 0; count < categoricals_n_total (cats); ++count)
        {
          double T;
          double n, mean, variance;
@@ -1068,6 +1091,7 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace
          tab_double (t, 9, row + count, 0,  dd->maximum, fmt);
        }
 
+      if (categoricals_is_complete (cats))
       {
        double T;
        double n, mean, variance;
@@ -1099,12 +1123,13 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace
        tab_double (t, 7, row + count, 0,
                    mean + T * std_error, NULL);
 
+
        /* Min and Max */
        tab_double (t, 8, row + count, 0,  ws->dd_total[v]->minimum, fmt);
        tab_double (t, 9, row + count, 0,  ws->dd_total[v]->maximum, fmt);
       }
 
-      row += categoricals_total (cats) + 1;
+      row += categoricals_n_total (cats) + 1;
     }
 
   tab_submit (t);
@@ -1537,12 +1562,13 @@ show_comparisons (const struct oneway_spec *cmd, const struct oneway_workspace *
              double std_err;
              double weight_j, mean_j, var_j;
              double half_range;
+             const struct ccase *cc;
              struct descriptive_data *dd_j = categoricals_get_user_data_by_category (cat, j);
              if (j == i)
                continue;
 
              ds_clear (&vstr);
-             const struct ccase *cc = categoricals_get_case_by_category (cat, j);
+             cc = categoricals_get_case_by_category (cat, j);
              var_append_value_name (cmd->indep_var, case_data (cc, cmd->indep_var), &vstr);
              tab_text (t, 2, r + rx, TAB_LEFT | TAT_TITLE, ds_cstr (&vstr));