psppire-var-sheet: Hard-code size of pixbuf cells.
[pspp] / src / language / stats / glm.c
index 92e35ccd27e1f5f4c1f8082d63d402e90f05ca4d..82ca9896e1a050828763c7362480a9881ceec96e 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -326,6 +326,7 @@ cmd_glm (struct lexer *lexer, struct dataset *ds)
   free (glm.factor_vars);
   for (i = 0 ; i < glm.n_interactions; ++i)
     interaction_destroy (glm.interactions[i]);
+
   free (glm.interactions);
   free (glm.dep_vars);
 
@@ -386,7 +387,7 @@ fill_submatrix (const gsl_matrix * cov, gsl_matrix * submatrix, bool *dropped_f)
 static void
 ssq_type1 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 {
-  gsl_matrix *cm = covariance_calculate_unnormalized (cov);
+  const gsl_matrix *cm = covariance_calculate_unnormalized (cov);
   size_t i;
   size_t k;
   bool *model_dropped = xcalloc (covariance_dim (cov), sizeof (*model_dropped));
@@ -446,7 +447,6 @@ ssq_type1 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 
   free (model_dropped);
   free (submodel_dropped);
-  gsl_matrix_free (cm);
 }
 
 /* 
@@ -456,7 +456,7 @@ ssq_type1 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 static void
 ssq_type2 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 {
-  gsl_matrix *cm = covariance_calculate_unnormalized (cov);
+  const gsl_matrix *cm = covariance_calculate_unnormalized (cov);
   size_t i;
   size_t k;
   bool *model_dropped = xcalloc (covariance_dim (cov), sizeof (*model_dropped));
@@ -510,7 +510,6 @@ ssq_type2 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 
   free (model_dropped);
   free (submodel_dropped);
-  gsl_matrix_free (cm);
 }
 
 /* 
@@ -520,7 +519,7 @@ ssq_type2 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 static void
 ssq_type3 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
 {
-  gsl_matrix *cm = covariance_calculate_unnormalized (cov);
+  const gsl_matrix *cm = covariance_calculate_unnormalized (cov);
   size_t i;
   size_t k;
   bool *model_dropped = xcalloc (covariance_dim (cov), sizeof (*model_dropped));
@@ -567,8 +566,6 @@ ssq_type3 (struct covariance *cov, gsl_vector *ssq, const struct glm_spec *cmd)
       gsl_matrix_free (model_cov);
     }
   free (model_dropped);
-
-  gsl_matrix_free (cm);
 }
 
 
@@ -590,8 +587,7 @@ run_glm (struct glm_spec *cmd, struct casereader *input,
   struct covariance *cov;
 
   ws.cats = categoricals_create (cmd->interactions, cmd->n_interactions,
-                                cmd->wv, cmd->exclude,
-                                NULL, NULL, NULL, NULL);
+                                cmd->wv, cmd->exclude, MV_ANY);
 
   cov = covariance_2pass_create (cmd->n_dep_vars, cmd->dep_vars,
                                 ws.cats, cmd->wv, cmd->exclude);
@@ -657,7 +653,9 @@ run_glm (struct glm_spec *cmd, struct casereader *input,
     }
 
   {
-    gsl_matrix *cm = covariance_calculate_unnormalized (cov);
+    const gsl_matrix *ucm = covariance_calculate_unnormalized (cov);
+    gsl_matrix *cm = gsl_matrix_alloc (ucm->size1, ucm->size2);
+    gsl_matrix_memcpy (cm, ucm);
 
     //    dump_matrix (cm);
 
@@ -686,7 +684,6 @@ run_glm (struct glm_spec *cmd, struct casereader *input,
        break;
       }
     //    dump_matrix (cm);
-
     gsl_matrix_free (cm);
   }
 
@@ -716,6 +713,8 @@ output_glm (const struct glm_spec *cmd, const struct glm_workspace *ws)
   const struct fmt_spec *wfmt =
     cmd->wv ? var_get_print_format (cmd->wv) : &F_8_0;
 
+  double intercept_ssq;
+  double ssq_effects;
   double n_total, mean;
   double df_corr = 1.0;
   double mse = 0;
@@ -767,9 +766,9 @@ output_glm (const struct glm_spec *cmd, const struct glm_workspace *ws)
 
   mse = gsl_vector_get (ws->ssq, 0) / (n_total - df_corr);
 
-  const double intercept_ssq = pow2 (mean * n_total) / n_total;
+  intercept_ssq = pow2 (mean * n_total) / n_total;
 
-  double ssq_effects = 0.0;
+  ssq_effects = 0.0;
   if (cmd->intercept)
     {
       const double df = 1.0;
@@ -790,6 +789,8 @@ output_glm (const struct glm_spec *cmd, const struct glm_workspace *ws)
       double df = categoricals_df (ws->cats, f);
 
       double ssq = gsl_vector_get (ws->ssq, f + 1);
+      double F;
+
       ssq_effects += ssq;
 
       if (! cmd->intercept) 
@@ -798,7 +799,7 @@ output_glm (const struct glm_spec *cmd, const struct glm_workspace *ws)
          ssq += intercept_ssq;
        }
 
-      const double F = ssq / df / mse;
+      F = ssq / df / mse;
       interaction_to_string (cmd->interactions[f], &str);
       tab_text (t, 0, r, TAB_LEFT | TAT_TITLE, ds_cstr (&str));
       ds_destroy (&str);
@@ -817,12 +818,14 @@ output_glm (const struct glm_spec *cmd, const struct glm_workspace *ws)
     /* Model / Corrected Model */
     double df = df_corr;
     double ssq = ws->total_ssq - gsl_vector_get (ws->ssq, 0);
+    double F;
+
     if ( cmd->intercept )
       df --;
     else
       ssq += intercept_ssq;
 
-    const double F = ssq / df / mse;
+    F = ssq / df / mse;
     tab_double (t, 1, heading_rows, 0, ssq, NULL);
     tab_double (t, 2, heading_rows, 0, df, wfmt);
     tab_double (t, 3, heading_rows, 0, ssq / df, NULL);
@@ -880,71 +883,11 @@ dump_matrix (const gsl_matrix * m)
 
 
 \f
-
-/* Match a variable.
-   If the match succeeds, the variable will be placed in VAR.
-   Returns true if successful */
-static bool
-lex_match_variable (struct lexer *lexer, const struct glm_spec *glm, const struct variable **var)
-{
-  if (lex_token (lexer) !=  T_ID)
-    return false;
-
-  *var = parse_variable_const  (lexer, glm->dict);
-
-  if ( *var == NULL)
-    return false;
-  return true;
-}
-
-/* An interaction is a variable followed by {*, BY} followed by an interaction */
-static bool
-parse_design_interaction (struct lexer *lexer, struct glm_spec *glm, struct interaction **iact)
-{
-  const struct variable *v = NULL;
-  assert (iact);
-
-  switch  (lex_next_token (lexer, 1))
-    {
-    case T_ENDCMD:
-    case T_SLASH:
-    case T_COMMA:
-    case T_ID:
-    case T_BY:
-    case T_ASTERISK:
-      break;
-    default:
-      return false;
-      break;
-    }
-
-  if (! lex_match_variable (lexer, glm, &v))
-    {
-      interaction_destroy (*iact);
-      *iact = NULL;
-      return false;
-    }
-  
-  assert (v);
-
-  if ( *iact == NULL)
-    *iact = interaction_create (v);
-  else
-    interaction_add_variable (*iact, v);
-
-  if ( lex_match (lexer, T_ASTERISK) || lex_match (lexer, T_BY))
-    {
-      return parse_design_interaction (lexer, glm, iact);
-    }
-
-  return true;
-}
-
 static bool
 parse_nested_variable (struct lexer *lexer, struct glm_spec *glm)
 {
   const struct variable *v = NULL;
-  if ( ! lex_match_variable (lexer, glm, &v))
+  if ( ! lex_match_variable (lexer, glm->dict, &v))
     return false;
 
   if (lex_match (lexer, T_LPAREN))
@@ -965,7 +908,7 @@ static bool
 parse_design_term (struct lexer *lexer, struct glm_spec *glm)
 {
   struct interaction *iact = NULL;
-  if (parse_design_interaction (lexer, glm, &iact))
+  if (parse_design_interaction (lexer, glm->dict, &iact))
     {
       /* Interaction parsing successful.  Add to list of interactions */
       glm->interactions = xrealloc (glm->interactions, sizeof *glm->interactions * ++glm->n_interactions);