Implement ZLIB compressed system file reader and writer.
[pspp] / src / language / stats / logistic.c
index e3a66f4de004c81d1c18bd5b80f358fa27465a0b..eb200fe37889c54c04596068614167735faa13d1 100644 (file)
@@ -478,6 +478,11 @@ initial_pass (const struct lr_spec *cmd, struct lr_result *res, struct casereade
       double weight = dict_get_case_weight (cmd->dict, c, &res->warn_bad_weight);
       const union value *depval = case_data (c, cmd->dep_var);
 
+      if (var_is_value_missing (cmd->dep_var, depval, cmd->exclude))
+       {
+         missing = true;
+       }
+      else 
       for (v = 0; v < cmd->n_indep_vars; ++v)
        {
          const union value *val = case_data (c, cmd->indep_vars[v]);
@@ -518,6 +523,7 @@ initial_pass (const struct lr_spec *cmd, struct lr_result *res, struct casereade
              )
            {
              msg (ME, _("Dependent variable's values are not dichotomous."));
+              case_unref (c);
              goto error;
            }
        }
@@ -589,11 +595,12 @@ run_lr (const struct lr_spec *cmd, struct casereader *input,
   work.warn_bad_weight = true;
   work.cats = NULL;
   work.beta_hat = NULL;
+  work.hessian = NULL;
 
   /* Get the initial estimates of \beta and their standard errors.
      And perform other auxilliary initialisation.  */
   if (! initial_pass (cmd, &work, input))
-    return false;
+    goto error;
   
   for (i = 0; i < cmd->n_cat_predictors; ++i)
     {
@@ -607,7 +614,7 @@ run_lr (const struct lr_spec *cmd, struct casereader *input,
          msg (ME, _("Category %s does not have at least two distinct values. Logistic regression will not be run."),
               ds_cstr(&str));
          ds_destroy (&str);
-         return false;
+         goto error;
        }
     }
 
@@ -623,6 +630,12 @@ run_lr (const struct lr_spec *cmd, struct casereader *input,
                                            NULL,
                                            NULL);
 
+  input = casereader_create_filter_missing (input,
+                                           &cmd->dep_var,
+                                           1,
+                                           cmd->exclude,
+                                           NULL,
+                                           NULL);
 
   work.hessian = gsl_matrix_calloc (work.beta_hat->size, work.beta_hat->size);
 
@@ -681,7 +694,7 @@ run_lr (const struct lr_spec *cmd, struct casereader *input,
       if (converged)
        break;
     }
-  casereader_destroy (input);
+
 
 
   if ( ! converged) 
@@ -696,12 +709,20 @@ run_lr (const struct lr_spec *cmd, struct casereader *input,
   output_classification_table (cmd, &work);
   output_variables (cmd, &work);
 
+  casereader_destroy (input);
   gsl_matrix_free (work.hessian);
   gsl_vector_free (work.beta_hat); 
-  
   categoricals_destroy (work.cats);
 
   return true;
+
+ error:
+  casereader_destroy (input);
+  gsl_matrix_free (work.hessian);
+  gsl_vector_free (work.beta_hat); 
+  categoricals_destroy (work.cats);
+
+  return false;
 }
 
 struct variable_node
@@ -730,6 +751,7 @@ lookup_variable (const struct hmap *map, const struct variable *var, unsigned in
 int
 cmd_logistic (struct lexer *lexer, struct dataset *ds)
 {
+  int i;
   /* Temporary location for the predictor variables.
      These may or may not include the categorical predictors */
   const struct variable **pred_vars;
@@ -1081,6 +1103,10 @@ cmd_logistic (struct lexer *lexer, struct dataset *ds)
     ok = proc_commit (ds) && ok;
   }
 
+  for (i = 0 ; i < lr.n_cat_predictors; ++i)
+    {
+      interaction_destroy (lr.cat_predictors[i]);
+    }
   free (lr.predictor_vars);
   free (lr.cat_predictors);
   free (lr.indep_vars);
@@ -1089,6 +1115,10 @@ cmd_logistic (struct lexer *lexer, struct dataset *ds)
 
  error:
 
+  for (i = 0 ; i < lr.n_cat_predictors; ++i)
+    {
+      interaction_destroy (lr.cat_predictors[i]);
+    }
   free (lr.predictor_vars);
   free (lr.cat_predictors);
   free (lr.indep_vars);
@@ -1289,10 +1319,14 @@ output_variables (const struct lr_spec *cmd,
 
       if (cmd->print & PRINT_CI)
        {
+         int last_ci = nr;
          double wc = gsl_cdf_ugaussian_Pinv (0.5 + cmd->confidence / 200.0);
          wc *= sqrt (sigma2);
 
-         if (idx < cmd->n_predictor_vars)
+         if (cmd->constant)
+           last_ci--;
+
+         if (row < last_ci)
            {
              tab_double (t, 8, row, 0, exp (b - wc), 0);
              tab_double (t, 9, row, 0, exp (b + wc), 0);