Add scratch file handles.
[pspp-builds.git] / src / regression.q
index eb8ff34f76ad353740f843c20f129ce7e807b9ce..23ba49a6e3e160036683d8038eb3cbb060b9f665 100644 (file)
@@ -91,6 +91,7 @@ struct file_handle *model_file;
 int pspp_reg_rc = CMD_SUCCESS;
 
 static void run_regression (const struct casefile *, void *);
+
 /* 
    STATISTICS subcommand output functions.
  */
@@ -161,9 +162,14 @@ reg_stats_coeff (pspp_linreg_cache * c)
   double std_err;
   double beta;
   const char *label;
+  char *tmp;
+  const struct variable *v;
+  const union value *val;
+  const char *val_s;
   struct tab_table *t;
 
   assert (c != NULL);
+  tmp = xnmalloc (MAX_STRING, sizeof (*tmp));
   n_rows = c->n_coeffs + 2;
 
   t = tab_create (n_cols, n_rows, 0);
@@ -193,8 +199,24 @@ reg_stats_coeff (pspp_linreg_cache * c)
   for (j = 1; j <= c->n_indeps; j++)
     {
       i = indep_vars[j];
-      label = var_to_string (c->coeff[j].v);
-      tab_text (t, 1, j + 1, TAB_CENTER, label);
+      v = pspp_linreg_coeff_get_var (c->coeff + j, 0);
+      label = var_to_string (v);
+      /* Do not overwrite the variable's name. */
+      strncpy (tmp, label, MAX_STRING);
+      if (v->type == ALPHA)
+       {
+         /*
+            Append the value associated with this coefficient.
+            This makes sense only if we us the usual binary encoding
+            for that value.
+          */
+
+         val = pspp_linreg_coeff_get_value (c->coeff + j, v);
+         val_s = value_to_string (val, v);
+         strncat (tmp, val_s, MAX_STRING);
+       }
+
+      tab_text (t, 1, j + 1, TAB_CENTER, tmp);
       /*
          Regression coefficients.
        */
@@ -226,6 +248,7 @@ reg_stats_coeff (pspp_linreg_cache * c)
     }
   tab_title (t, 0, _("Coefficients"));
   tab_submit (t);
+  free (tmp);
 }
 
 /*
@@ -474,7 +497,7 @@ subcommand_statistics (int *keywords, pspp_linreg_cache * c)
   statistics_keyword_output (reg_stats_selection, keywords[selection], c);
 }
 static int
-reg_inserted (struct variable *v, struct variable **varlist, int n_vars)
+reg_inserted (const struct variable *v, struct variable **varlist, int n_vars)
 {
   int i;
 
@@ -494,7 +517,8 @@ reg_print_categorical_encoding (FILE * fp, pspp_linreg_cache * c)
   size_t j;
   int n_vars = 0;
   struct variable **varlist;
-  struct pspp_linreg_coeff coeff;
+  struct pspp_linreg_coeff *coeff;
+  const struct variable *v;
   union value *val;
 
   fprintf (fp, "%s", reg_export_categorical_encode_1);
@@ -502,14 +526,15 @@ reg_print_categorical_encoding (FILE * fp, pspp_linreg_cache * c)
   varlist = xnmalloc (c->n_indeps, sizeof (*varlist));
   for (i = 1; i < c->n_indeps; i++)    /* c->coeff[0] is the intercept. */
     {
-      coeff = c->coeff[i];
-      if (coeff.v->type == ALPHA)
+      coeff = c->coeff + i;
+      v = pspp_linreg_coeff_get_var (coeff, 0);
+      if (v->type == ALPHA)
        {
-         if (!reg_inserted (coeff.v, varlist, n_vars))
+         if (!reg_inserted (v, varlist, n_vars))
            {
              fprintf (fp, "struct pspp_reg_categorical_variable %s;\n\t",
-                      coeff.v->name);
-             varlist[n_vars] = coeff.v;
+                      v->name);
+             varlist[n_vars] = (struct variable *) v;
              n_vars++;
            }
        }
@@ -525,7 +550,7 @@ reg_print_categorical_encoding (FILE * fp, pspp_linreg_cache * c)
 
   for (i = 0; i < n_vars; i++)
     {
-      coeff = c->coeff[i];
+      coeff = c->coeff + i;
       fprintf (fp, "%s.name = \"%s\";\n\t", varlist[i]->name,
               varlist[i]->name);
       fprintf (fp, "%s.n_vals = %d;\n\t", varlist[i]->name,
@@ -545,16 +570,19 @@ static void
 reg_print_depvars (FILE * fp, pspp_linreg_cache * c)
 {
   int i;
-  struct pspp_linreg_coeff coeff;
+  struct pspp_linreg_coeff *coeff;
+  const struct variable *v;
 
   fprintf (fp, "char *model_depvars[%d] = {", c->n_indeps);
   for (i = 1; i < c->n_indeps; i++)
     {
-      coeff = c->coeff[i];
-      fprintf (fp, "\"%s\",\n\t\t", coeff.v->name);
+      coeff = c->coeff + i;
+      v = pspp_linreg_coeff_get_var (coeff, 0);
+      fprintf (fp, "\"%s\",\n\t\t", v->name);
     }
-  coeff = c->coeff[i];
-  fprintf (fp, "\"%s\"};\n\t", coeff.v->name);
+  coeff = c->coeff + i;
+  v = pspp_linreg_coeff_get_var (coeff, 0);
+  fprintf (fp, "\"%s\"};\n\t", v->name);
 }
 static void
 reg_print_getvar (FILE * fp, pspp_linreg_cache * c)
@@ -570,7 +598,6 @@ reg_print_getvar (FILE * fp, pspp_linreg_cache * c)
 static void
 subcommand_export (int export, pspp_linreg_cache * c)
 {
-  FILE *fp;
   size_t i;
   size_t j;
   int n_quantiles = 100;
@@ -580,10 +607,11 @@ subcommand_export (int export, pspp_linreg_cache * c)
 
   if (export)
     {
+      FILE *fp;
       assert (c != NULL);
       assert (model_file != NULL);
       assert (fp != NULL);
-      fp = fopen (handle_get_filename (model_file), "w");
+      fp = fopen (fh_get_filename (model_file), "w");
       fprintf (fp, "%s", reg_preamble);
       reg_print_getvar (fp, c);
       reg_print_categorical_encoding (fp, c);
@@ -659,7 +687,7 @@ regression_custom_export (struct cmd_regression *cmd)
     model_file = NULL;
   else
     {
-      model_file = fh_parse ();
+      model_file = fh_parse (FH_REF_FILE);
       if (model_file == NULL)
        return 0;
     }
@@ -706,12 +734,12 @@ is_depvar (size_t k)
  */
 static size_t
 mark_missing_cases (const struct casefile *cf, struct variable *v,
-                   double *is_missing_case, double n_data)
+                   int *is_missing_case, double n_data)
 {
   struct casereader *r;
   struct ccase c;
   size_t row;
-  union value *val;
+  const union value *val;
 
   for (r = casefile_get_reader (cf);
        casereader_read (r, &c); case_destroy (&c))
@@ -734,6 +762,7 @@ mark_missing_cases (const struct casefile *cf, struct variable *v,
 
   return n_data;
 }
+
 static void
 run_regression (const struct casefile *cf, void *cmd_ UNUSED)
 {
@@ -822,6 +851,10 @@ run_regression (const struct casefile *cf, void *cmd_ UNUSED)
       X =
        design_matrix_create (n_indep, (const struct variable **) indep_vars,
                              n_data);
+      for (i = 0; i < X->m->size2; i++)
+       {
+         lopts.get_indep_mean_std[i] = 1;
+       }
       lcache = pspp_linreg_cache_alloc (X->m->size1, X->m->size2);
       lcache->indep_means = gsl_vector_alloc (X->m->size2);
       lcache->indep_std = gsl_vector_alloc (X->m->size2);
@@ -869,7 +902,6 @@ run_regression (const struct casefile *cf, void *cmd_ UNUSED)
                        {
                          design_matrix_set_numeric (X, row, v, val);
                        }
-                     lopts.get_indep_mean_std[i] = 1;
                    }
                }
              val = case_data (&c, depvar->fv);
@@ -882,14 +914,7 @@ run_regression (const struct casefile *cf, void *cmd_ UNUSED)
          and store pointers to the variables that correspond to the
          coefficients.
        */
-      lcache->coeff = xnmalloc (X->m->size2 + 1, sizeof (*lcache->coeff));
-      for (i = 0; i < X->m->size2; i++)
-       {
-         j = i + 1;            /* The first coeff is the intercept. */
-         lcache->coeff[j].v =
-           (const struct variable *) design_matrix_col_to_var (X, i);
-         assert (lcache->coeff[j].v != NULL);
-       }
+      pspp_linreg_coeff_init (lcache, X);
 
       /* 
          Find the least-squares estimates and other statistics.