Covariance matrix interface change.
[pspp] / src / language / stats / glm.q
index a6622ce88d096cd9c350b2175b3fb31253db4685..13b097f3b8fce021c9004184b2427f9602e94643 100644 (file)
@@ -23,7 +23,6 @@
 #include <stdlib.h>
 
 #include <data/case.h>
-#include <data/category.h>
 #include <data/casegrouper.h>
 #include <data/casereader.h>
 #include <data/dictionary.h>
 #include <language/data-io/file-handle.h>
 #include <language/lexer/lexer.h>
 #include <libpspp/compiler.h>
-#include <libpspp/hash.h>
 #include <libpspp/message.h>
 #include <math/covariance.h>
-#include <math/coefficient.h>
+#include <math/categoricals.h>
 #include <math/linreg.h>
 #include <math/moments.h>
-#include <output/table.h>
+#include <output/tab.h>
 
 #include "xalloc.h"
 #include "gettext.h"
@@ -228,18 +226,22 @@ glm_custom_dependent (struct lexer *lexer, struct dataset *ds,
                      struct cmd_glm *cmd UNUSED, void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
+  size_t i;
 
   if ((lex_token (lexer) != T_ID
        || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
       && lex_token (lexer) != T_ALL)
     return 2;
 
-  if (!parse_variables_const
-      (lexer, dict, &v_dependent, &n_dependent, PV_NONE))
+  if (!parse_variables_const (lexer, dict, &v_dependent, &n_dependent, PV_NONE))
     {
       free (v_dependent);
       return 0;
     }
+  for (i = 0; i < n_dependent; i++)
+    {
+      assert (var_is_numeric (v_dependent[i]));
+    }
   assert (n_dependent);
   if (n_dependent > 1)
     msg (SE, _("Multivariate GLM not yet supported"));
@@ -248,26 +250,13 @@ glm_custom_dependent (struct lexer *lexer, struct dataset *ds,
   return 1;
 }
 
-/*
-  COV is the covariance matrix for variables included in the
-  model. That means the dependent variable is in there, too.
- */
-static void
-coeff_init (pspp_linreg_cache * c, const struct design_matrix *cov)
-{
-  c->coeff = xnmalloc (cov->m->size2, sizeof (*c->coeff));
-  c->n_coeffs = cov->m->size2 - 1;
-  pspp_coeff_init (c->coeff, cov);
-}
-
-
-static pspp_linreg_cache *
+static linreg *
 fit_model (const struct covariance *cov,
           const struct variable *dep_var, 
           const struct variable ** indep_vars, 
           size_t n_data, size_t n_indep)
 {
-  pspp_linreg_cache *result = NULL;
+  linreg *result = NULL;
   
   return result;
 }
@@ -281,7 +270,7 @@ run_glm (struct casereader *input,
   const struct variable **numerics = NULL;
   const struct variable **categoricals = NULL;
   int n_indep = 0;
-  pspp_linreg_cache *model = NULL; 
+  linreg *model = NULL; 
   pspp_linreg_opts lopts;
   struct ccase *c;
   size_t i;
@@ -311,7 +300,18 @@ run_glm (struct casereader *input,
   lopts.get_indep_mean_std = xnmalloc (n_dependent, sizeof (int));
 
 
-  n_numerics = cmd->n_with + n_dependent;
+  n_numerics = n_dependent;
+  for (i = 0; i < cmd->n_with; i++)
+    {
+      if (var_is_alpha (cmd->v_with[i]))
+       {
+         n_categoricals++;
+       }
+      else
+       {
+         n_numerics++;
+       }
+    }
   for (i = 0; i < cmd->n_by; i++)
     {
       if (var_is_alpha (cmd->v_by[i]))
@@ -323,33 +323,49 @@ run_glm (struct casereader *input,
          n_numerics++;
        }
     }
-  numerics = xnmalloc (n_categoricals, sizeof *numerics);
+  numerics = xnmalloc (n_numerics, sizeof *numerics);
   categoricals = xnmalloc (n_categoricals, sizeof (*categoricals));
+  size_t j = 0;
   size_t k = 0;
   for (i = 0; i < cmd->n_by; i++)
     {
       if (var_is_alpha (cmd->v_by[i]))
        {
-         categoricals[k] = cmd->v_by[i];
+         categoricals[j] = cmd->v_by[i];
+         j++;
        }
       else
        {
-         numerics[i] = cmd->v_by[i];
+         numerics[k] = cmd->v_by[i];
          k++;
        }
     }
-  for (i = 0; i < n_dependent; i++)
+  for (i = 0; i < cmd->n_with; i++)
     {
-      k++;
-      numerics[k] = v_dependent[i];
+      if (var_is_alpha (cmd->v_with[i]))
+       {
+         categoricals[j] = cmd->v_with[i];
+         j++;
+       }
+      else
+       {
+         numerics[k] = cmd->v_with[i];
+         k++;
+       }
     }
-  for (i = 0; i < cmd->n_with; i++)
+  for (i = 0; i < n_dependent; i++)
     {
-      k++;
       numerics[k] = v_dependent[i];
+      k++;
     }
 
-  covariance_2pass_create (n_numerics, numerics, n_categoricals, categoricals, NULL, MV_NEVER);
+  struct categoricals *cats = categoricals_create (categoricals,
+                                                  n_categoricals,
+                                                  NULL, MV_NEVER);
+
+  cov = covariance_2pass_create (n_numerics, numerics,
+                                cats,
+                                NULL, MV_NEVER);
 
   reader = casereader_clone (input);
   reader = casereader_create_filter_missing (reader, numerics, n_numerics,
@@ -366,8 +382,9 @@ run_glm (struct casereader *input,
     }
   for (; (c = casereader_read (r)) != NULL; case_unref (c))
     {
-      covariance_accumulate_pass1 (cov, c);
+      covariance_accumulate_pass2 (cov, c);
     }
+
   covariance_destroy (cov);
   casereader_destroy (reader);
   casereader_destroy (r);