Logistic Regression: Handle missing categoricals
[pspp] / src / language / stats / logistic.c
1 /* pspp - a program for statistical analysis.
2    Copyright (C) 2012 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17
18 /* 
19    References: 
20    1. "Coding Logistic Regression with Newton-Raphson", James McCaffrey
21    http://msdn.microsoft.com/en-us/magazine/jj618304.aspx
22
23    2. "SPSS Statistical Algorithms" Chapter LOGISTIC REGRESSION Algorithms
24
25
26    The Newton Raphson method finds successive approximations to $\bf b$ where 
27    approximation ${\bf b}_t$ is (hopefully) better than the previous ${\bf b}_{t-1}$.
28
29    $ {\bf b}_t = {\bf b}_{t -1} + ({\bf X}^T{\bf W}_{t-1}{\bf X})^{-1}{\bf X}^T({\bf y} - {\bf \pi}_{t-1})$
30    where:
31
32    $\bf X$ is the $n \times p$ design matrix, $n$ being the number of cases, 
33    $p$ the number of parameters, \par
34    $\bf W$ is the diagonal matrix whose diagonal elements are
35    $\hat{\pi}_0(1 - \hat{\pi}_0), \, \hat{\pi}_1(1 - \hat{\pi}_2)\dots \hat{\pi}_{n-1}(1 - \hat{\pi}_{n-1})$
36    \par
37
38 */
39
40 #include <config.h>
41
42 #include <gsl/gsl_blas.h> 
43
44 #include <gsl/gsl_linalg.h>
45 #include <gsl/gsl_cdf.h>
46 #include <gsl/gsl_matrix.h>
47 #include <gsl/gsl_vector.h>
48 #include <math.h>
49
50 #include "data/case.h"
51 #include "data/casegrouper.h"
52 #include "data/casereader.h"
53 #include "data/dataset.h"
54 #include "data/dictionary.h"
55 #include "data/format.h"
56 #include "data/value.h"
57 #include "language/command.h"
58 #include "language/dictionary/split-file.h"
59 #include "language/lexer/lexer.h"
60 #include "language/lexer/value-parser.h"
61 #include "language/lexer/variable-parser.h"
62 #include "libpspp/assertion.h"
63 #include "libpspp/ll.h"
64 #include "libpspp/message.h"
65 #include "libpspp/misc.h"
66 #include "math/categoricals.h"
67 #include "math/interaction.h"
68 #include "libpspp/hmap.h"
69 #include "libpspp/hash-functions.h"
70
71 #include "output/tab.h"
72
73 #include "gettext.h"
74 #define _(msgid) gettext (msgid)
75
76
77
78
79 #define   PRINT_EACH_STEP  0x01
80 #define   PRINT_SUMMARY    0x02
81 #define   PRINT_CORR       0x04
82 #define   PRINT_ITER       0x08
83 #define   PRINT_GOODFIT    0x10
84 #define   PRINT_CI         0x20
85
86
87 #define PRINT_DEFAULT (PRINT_SUMMARY | PRINT_EACH_STEP)
88
89 /*
90   The constant parameters of the procedure.
91   That is, those which are set by the user.
92 */
93 struct lr_spec
94 {
95   /* The dependent variable */
96   const struct variable *dep_var;
97
98   /* The predictor variables (excluding categorical ones) */
99   const struct variable **predictor_vars;
100   size_t n_predictor_vars;
101
102   /* The categorical predictors */
103   struct interaction **cat_predictors;
104   size_t n_cat_predictors;
105
106
107   /* The union of the categorical and non-categorical variables */
108   const struct variable **indep_vars;
109   size_t n_indep_vars;
110
111
112   /* Which classes of missing vars are to be excluded */
113   enum mv_class exclude;
114
115   /* The weight variable */
116   const struct variable *wv;
117
118   /* The dictionary of the dataset */
119   const struct dictionary *dict;
120
121   /* True iff the constant (intercept) is to be included in the model */
122   bool constant;
123
124   /* Ths maximum number of iterations */
125   int max_iter;
126
127   /* Other iteration limiting conditions */
128   double bcon;
129   double min_epsilon;
130   double lcon;
131
132   /* The confidence interval (in percent) */
133   int confidence;
134
135   /* What results should be presented */
136   unsigned int print;
137
138   double cut_point;
139 };
140
141
142 /* The results and intermediate result of the procedure.
143    These are mutated as the procedure runs. Used for
144    temporary variables etc.
145 */
146 struct lr_result
147 {
148   /* Used to indicate if a pass should flag a warning when 
149      invalid (ie negative or missing) weight values are encountered */
150   bool warn_bad_weight;
151
152   /* The two values of the dependent variable. */
153   union value y0;
154   union value y1;
155
156
157   /* The sum of caseweights */
158   double cc;
159
160   /* The number of missing and nonmissing cases */
161   casenumber n_missing;
162   casenumber n_nonmissing;
163
164
165   gsl_matrix *hessian;
166
167   /* The categoricals and their payload. Null if  the analysis has no
168    categorical predictors */
169   struct categoricals *cats;
170   struct payload cp;
171 };
172
173
174 /*
175   Convert INPUT into a dichotomous scalar, according to how the dependent variable's
176   values are mapped.
177   For simple cases, this is a 1:1 mapping
178   The return value is always either 0 or 1
179 */
180 static double
181 map_dependent_var (const struct lr_spec *cmd, const struct lr_result *res, const union value *input)
182 {
183   const int width = var_get_width (cmd->dep_var);
184   if (value_equal (input, &res->y0, width))
185     return 0;
186
187   if (value_equal (input, &res->y1, width))
188     return 1;
189
190   /* This should never happen.  If it does,  then y0 and/or y1 have probably not been set */
191   NOT_REACHED ();
192
193   return SYSMIS;
194 }
195
196
197 static void output_categories (const struct lr_spec *cmd, const struct lr_result *res);
198
199 static void output_depvarmap (const struct lr_spec *cmd, const struct lr_result *);
200
201 static void output_variables (const struct lr_spec *cmd, 
202                               const struct lr_result *,
203                               const gsl_vector *);
204
205 static void output_model_summary (const struct lr_result *,
206                                   double initial_likelihood, double likelihood);
207
208 static void case_processing_summary (const struct lr_result *);
209
210
211 /* Return the value of case C corresponding to the INDEX'th entry in the
212    model */
213 static double
214 predictor_value (const struct ccase *c, 
215                     const struct variable **x, size_t n_x, 
216                     const struct categoricals *cats,
217                     size_t index)
218 {
219   /* Values of the scalar predictor variables */
220   if (index < n_x) 
221     return case_data (c, x[index])->f;
222
223   /* Coded values of categorical predictor variables (or interactions) */
224   if (cats && index - n_x  < categoricals_df_total (cats))
225     {
226       double x = categoricals_get_dummy_code_for_case (cats, index - n_x, c);
227       return x;
228     }
229
230   /* The constant term */
231   return 1.0;
232 }
233
234
235 /*
236   Return the probability estimator (that is the estimator of logit(y) )
237   corresponding to the coefficient estimator beta_hat for case C
238 */
239 static double 
240 pi_hat (const struct lr_spec *cmd, 
241         struct lr_result *res,
242         const gsl_vector *beta_hat,
243         const struct variable **x, size_t n_x,
244         const struct ccase *c)
245 {
246   int v0;
247   double pi = 0;
248   size_t n_coeffs = beta_hat->size;
249
250   if (cmd->constant)
251     {
252       pi += gsl_vector_get (beta_hat, beta_hat->size - 1);
253       n_coeffs--;
254     }
255   
256   for (v0 = 0; v0 < n_coeffs; ++v0)
257     {
258       pi += gsl_vector_get (beta_hat, v0) * 
259         predictor_value (c, x, n_x, res->cats, v0);
260     }
261
262   pi = 1.0 / (1.0 + exp(-pi));
263
264   return pi;
265 }
266
267
268 /*
269   Calculates the Hessian matrix X' V  X,
270   where: X is the n by N_X matrix comprising the n cases in INPUT
271   V is a diagonal matrix { (pi_hat_0)(1 - pi_hat_0), (pi_hat_1)(1 - pi_hat_1), ... (pi_hat_{N-1})(1 - pi_hat_{N-1})} 
272   (the partial derivative of the predicted values)
273
274   If ALL predicted values derivatives are close to zero or one, then CONVERGED
275   will be set to true.
276 */
277 static void
278 hessian (const struct lr_spec *cmd, 
279          struct lr_result *res,
280          struct casereader *input,
281          const struct variable **x, size_t n_x,
282          const gsl_vector *beta_hat,
283          bool *converged)
284 {
285   struct casereader *reader;
286   struct ccase *c;
287
288   double max_w = -DBL_MAX;
289
290   gsl_matrix_set_zero (res->hessian);
291
292   for (reader = casereader_clone (input);
293        (c = casereader_read (reader)) != NULL; case_unref (c))
294     {
295       int v0, v1;
296       double pi = pi_hat (cmd, res, beta_hat, x, n_x, c);
297
298       double weight = dict_get_case_weight (cmd->dict, c, &res->warn_bad_weight);
299       double w = pi * (1 - pi);
300       if (w > max_w)
301         max_w = w;
302       w *= weight;
303
304       for (v0 = 0; v0 < beta_hat->size; ++v0)
305         {
306           double in0 = predictor_value (c, x, n_x, res->cats, v0);
307           for (v1 = 0; v1 < beta_hat->size; ++v1)
308             {
309               double in1 = predictor_value (c, x, n_x, res->cats, v1);
310               double *o = gsl_matrix_ptr (res->hessian, v0, v1);
311               *o += in0 * w * in1;
312             }
313         }
314     }
315   casereader_destroy (reader);
316
317   if ( max_w < cmd->min_epsilon)
318     {
319       *converged = true;
320       msg (MN, _("All predicted values are either 1 or 0"));
321     }
322 }
323
324
325 /* Calculates the value  X' (y - pi)
326    where X is the design model, 
327    y is the vector of observed independent variables
328    pi is the vector of estimates for y
329
330    As a side effect, the likelihood is stored in LIKELIHOOD
331 */
332 static gsl_vector *
333 xt_times_y_pi (const struct lr_spec *cmd,
334                struct lr_result *res,
335                struct casereader *input,
336                const struct variable **x, size_t n_x,
337                const struct variable *y_var,
338                const gsl_vector *beta_hat,
339                double *likelihood)
340 {
341   struct casereader *reader;
342   struct ccase *c;
343   gsl_vector *output = gsl_vector_calloc (beta_hat->size);
344
345   *likelihood = 1.0;
346   for (reader = casereader_clone (input);
347        (c = casereader_read (reader)) != NULL; case_unref (c))
348     {
349       int v0;
350       double pi = pi_hat (cmd, res, beta_hat, x, n_x, c);
351       double weight = dict_get_case_weight (cmd->dict, c, &res->warn_bad_weight);
352
353
354       double y = map_dependent_var (cmd, res, case_data (c, y_var));
355
356       *likelihood *= pow (pi, weight * y) * pow (1 - pi, weight * (1 - y));
357
358       for (v0 = 0; v0 < beta_hat->size; ++v0)
359         {
360           double in0 = predictor_value (c, x, n_x, res->cats, v0);
361           double *o = gsl_vector_ptr (output, v0);
362           *o += in0 * (y - pi) * weight;
363         }
364     }
365
366   casereader_destroy (reader);
367
368   return output;
369 }
370
371 \f
372
373 /* "payload" functions for the categoricals.
374    The only function is to accumulate the frequency of each
375    category.
376  */
377
378 static void *
379 frq_create  (const void *aux1 UNUSED, void *aux2 UNUSED)
380 {
381   return xzalloc (sizeof (double));
382 }
383
384 static void
385 frq_update  (const void *aux1 UNUSED, void *aux2 UNUSED,
386              void *ud, const struct ccase *c UNUSED , double weight)
387 {
388   double *freq = ud;
389   *freq += weight;
390 }
391
392 static void 
393 frq_destroy (const void *aux1 UNUSED, void *aux2 UNUSED, void *user_data UNUSED)
394 {
395   free (user_data);
396 }
397
398 \f
399
400 /* 
401    Makes an initial pass though the data, doing the following:
402
403    * Checks that the dependent variable is  dichotomous,
404    * Creates and initialises the categoricals,
405    * Accumulates summary results,
406    * Calculates necessary initial values.
407
408    Returns an initial value for \hat\beta the vector of estimators of \beta
409 */
410 static gsl_vector * 
411 beta_hat_initial (const struct lr_spec *cmd, struct lr_result *res, struct casereader *input)
412 {
413   const int width = var_get_width (cmd->dep_var);
414
415   struct ccase *c;
416   struct casereader *reader;
417   gsl_vector *b0 ;
418   double sum;
419   double sumA = 0.0;
420   double sumB = 0.0;
421
422   bool v0set = false;
423   bool v1set = false;
424
425   size_t n_coefficients = cmd->n_predictor_vars;
426   if (cmd->constant)
427     n_coefficients++;
428
429   /* Create categoricals if appropriate */
430   if (cmd->n_cat_predictors > 0)
431     {
432       res->cp.create = frq_create;
433       res->cp.update = frq_update;
434       res->cp.calculate = NULL;
435       res->cp.destroy = frq_destroy;
436
437       res->cats = categoricals_create (cmd->cat_predictors, cmd->n_cat_predictors,
438                                        cmd->wv, cmd->exclude, MV_ANY);
439
440       categoricals_set_payload (res->cats, &res->cp, cmd, res);
441     }
442
443   res->cc = 0;
444   for (reader = casereader_clone (input);
445        (c = casereader_read (reader)) != NULL; case_unref (c))
446     {
447       int v;
448       bool missing = false;
449       double weight = dict_get_case_weight (cmd->dict, c, &res->warn_bad_weight);
450       const union value *depval = case_data (c, cmd->dep_var);
451
452       for (v = 0; v < cmd->n_indep_vars; ++v)
453         {
454           const union value *val = case_data (c, cmd->indep_vars[v]);
455           if (var_is_value_missing (cmd->indep_vars[v], val, cmd->exclude))
456             {
457               missing = true;
458               break;
459             }
460         }
461
462       /* Accumulate the missing and non-missing counts */
463       if (missing)
464         {
465           res->n_missing++;
466           continue;
467         }
468       res->n_nonmissing++;
469
470       /* Find the values of the dependent variable */
471       if (!v0set)
472         {
473           value_clone (&res->y0, depval, width);
474           v0set = true;
475         }
476       else if (!v1set)
477         {
478           if ( !value_equal (&res->y0, depval, width))
479             {
480               value_clone (&res->y1, depval, width);
481               v1set = true;
482             }
483         }
484       else
485         {
486           if (! value_equal (&res->y0, depval, width)
487               &&
488               ! value_equal (&res->y1, depval, width)
489               )
490             {
491               msg (ME, _("Dependent variable's values are not dichotomous."));
492               goto error;
493             }
494         }
495
496       if (v0set && value_equal (&res->y0, depval, width))
497           sumA += weight;
498
499       if (v1set && value_equal (&res->y1, depval, width))
500           sumB += weight;
501
502
503       res->cc += weight;
504
505       categoricals_update (res->cats, c);
506     }
507   casereader_destroy (reader);
508
509   categoricals_done (res->cats);
510
511   sum = sumB;
512
513   /* Ensure that Y0 is less than Y1.  Otherwise the mapping gets
514      inverted, which is confusing to users */
515   if (var_is_numeric (cmd->dep_var) && value_compare_3way (&res->y0, &res->y1, width) > 0)
516     {
517       union value tmp;
518       value_clone (&tmp, &res->y0, width);
519       value_copy (&res->y0, &res->y1, width);
520       value_copy (&res->y1, &tmp, width);
521       value_destroy (&tmp, width);
522       sum = sumA;
523     }
524
525   n_coefficients += categoricals_df_total (res->cats);
526   b0 = gsl_vector_calloc (n_coefficients);
527
528   if ( cmd->constant)
529     {
530       double mean = sum / res->cc;
531       gsl_vector_set (b0, b0->size - 1, log (mean / (1 - mean)));
532     }
533
534   return b0;
535
536  error:
537   casereader_destroy (reader);
538   return NULL;
539 }
540
541
542
543 /* Start of the logistic regression routine proper */
544 static bool
545 run_lr (const struct lr_spec *cmd, struct casereader *input,
546         const struct dataset *ds UNUSED)
547 {
548   int i;
549
550   gsl_vector *beta_hat;
551
552   bool converged = false;
553
554   /* Set the likelihoods to a negative sentinel value */
555   double likelihood = -1;
556   double prev_likelihood = -1;
557   double initial_likelihood = -1;
558
559   struct lr_result work;
560   work.n_missing = 0;
561   work.n_nonmissing = 0;
562   work.warn_bad_weight = true;
563   work.cats = NULL;
564
565
566   /* Get the initial estimates of \beta and their standard errors */
567   beta_hat = beta_hat_initial (cmd, &work, input);
568   if (NULL == beta_hat)
569     return false;
570
571   
572   for (i = 0; i < cmd->n_cat_predictors; ++i)
573     {
574       if (1 >= categoricals_n_count (work.cats, i))
575         {
576           struct string str;
577           ds_init_empty (&str);
578           
579           interaction_to_string (cmd->cat_predictors[i], &str);
580
581           msg (ME, _("Category %s does not have at least two distinct values. Logistic regression will not be run."),
582                ds_cstr(&str));
583           ds_destroy (&str);
584           return false;
585         }
586     }
587
588   output_depvarmap (cmd, &work);
589
590   case_processing_summary (&work);
591
592
593   input = casereader_create_filter_missing (input,
594                                             cmd->indep_vars,
595                                             cmd->n_indep_vars,
596                                             cmd->exclude,
597                                             NULL,
598                                             NULL);
599
600
601   work.hessian = gsl_matrix_calloc (beta_hat->size, beta_hat->size);
602
603   /* Start the Newton Raphson iteration process... */
604   for( i = 0 ; i < cmd->max_iter ; ++i)
605     {
606       double min, max;
607       gsl_vector *v ;
608
609       
610       hessian (cmd, &work, input,
611                    cmd->predictor_vars, cmd->n_predictor_vars,
612                    beta_hat,
613                    &converged);
614
615       gsl_linalg_cholesky_decomp (work.hessian);
616       gsl_linalg_cholesky_invert (work.hessian);
617
618       v = xt_times_y_pi (cmd, &work, input,
619                          cmd->predictor_vars, cmd->n_predictor_vars,
620                          cmd->dep_var,
621                          beta_hat,
622                          &likelihood);
623
624       {
625         /* delta = M.v */
626         gsl_vector *delta = gsl_vector_alloc (v->size);
627         gsl_blas_dgemv (CblasNoTrans, 1.0, work.hessian, v, 0, delta);
628         gsl_vector_free (v);
629
630
631         gsl_vector_add (beta_hat, delta);
632
633         gsl_vector_minmax (delta, &min, &max);
634
635         if ( fabs (min) < cmd->bcon && fabs (max) < cmd->bcon)
636           {
637             msg (MN, _("Estimation terminated at iteration number %d because parameter estimates changed by less than %g"),
638                  i + 1, cmd->bcon);
639             converged = true;
640           }
641
642         gsl_vector_free (delta);
643       }
644
645       if ( prev_likelihood >= 0)
646         {
647           if (-log (likelihood) > -(1.0 - cmd->lcon) * log (prev_likelihood))
648             {
649               msg (MN, _("Estimation terminated at iteration number %d because Log Likelihood decreased by less than %g%%"), i + 1, 100 * cmd->lcon);
650               converged = true;
651             }
652         }
653       if (i == 0)
654         initial_likelihood = likelihood;
655       prev_likelihood = likelihood;
656
657       if (converged)
658         break;
659     }
660   casereader_destroy (input);
661   assert (initial_likelihood >= 0);
662
663   if ( ! converged) 
664     msg (MW, _("Estimation terminated at iteration number %d because maximum iterations has been reached"), i );
665
666
667   output_model_summary (&work, initial_likelihood, likelihood);
668
669   if (work.cats)
670     output_categories (cmd, &work);
671
672   output_variables (cmd, &work, beta_hat);
673
674   gsl_matrix_free (work.hessian);
675   gsl_vector_free (beta_hat); 
676   
677   categoricals_destroy (work.cats);
678
679   return true;
680 }
681
682 struct variable_node
683 {
684   struct hmap_node node;      /* Node in hash map. */
685   const struct variable *var; /* The variable */
686 };
687
688 static struct variable_node *
689 lookup_variable (const struct hmap *map, const struct variable *var, unsigned int hash)
690 {
691   struct variable_node *vn = NULL;
692   HMAP_FOR_EACH_WITH_HASH (vn, struct variable_node, node, hash, map)
693     {
694       if (vn->var == var)
695         break;
696       
697       fprintf (stderr, "Warning: Hash table collision\n");
698     }
699   
700   return vn;
701 }
702
703
704 /* Parse the LOGISTIC REGRESSION command syntax */
705 int
706 cmd_logistic (struct lexer *lexer, struct dataset *ds)
707 {
708   /* Temporary location for the predictor variables.
709      These may or may not include the categorical predictors */
710   const struct variable **pred_vars;
711   size_t n_pred_vars;
712
713   int v, x;
714   struct lr_spec lr;
715   lr.dict = dataset_dict (ds);
716   lr.n_predictor_vars = 0;
717   lr.predictor_vars = NULL;
718   lr.exclude = MV_ANY;
719   lr.wv = dict_get_weight (lr.dict);
720   lr.max_iter = 20;
721   lr.lcon = 0.0000;
722   lr.bcon = 0.001;
723   lr.min_epsilon = 0.00000001;
724   lr.cut_point = 0.5;
725   lr.constant = true;
726   lr.confidence = 95;
727   lr.print = PRINT_DEFAULT;
728   lr.cat_predictors = NULL;
729   lr.n_cat_predictors = 0;
730   lr.indep_vars = NULL;
731
732
733   if (lex_match_id (lexer, "VARIABLES"))
734     lex_match (lexer, T_EQUALS);
735
736   if (! (lr.dep_var = parse_variable_const (lexer, lr.dict)))
737     goto error;
738
739   lex_force_match (lexer, T_WITH);
740
741   if (!parse_variables_const (lexer, lr.dict,
742                               &pred_vars, &n_pred_vars,
743                               PV_NO_DUPLICATE))
744     goto error;
745
746
747   while (lex_token (lexer) != T_ENDCMD)
748     {
749       lex_match (lexer, T_SLASH);
750
751       if (lex_match_id (lexer, "MISSING"))
752         {
753           lex_match (lexer, T_EQUALS);
754           while (lex_token (lexer) != T_ENDCMD
755                  && lex_token (lexer) != T_SLASH)
756             {
757               if (lex_match_id (lexer, "INCLUDE"))
758                 {
759                   lr.exclude = MV_SYSTEM;
760                 }
761               else if (lex_match_id (lexer, "EXCLUDE"))
762                 {
763                   lr.exclude = MV_ANY;
764                 }
765               else
766                 {
767                   lex_error (lexer, NULL);
768                   goto error;
769                 }
770             }
771         }
772       else if (lex_match_id (lexer, "ORIGIN"))
773         {
774           lr.constant = false;
775         }
776       else if (lex_match_id (lexer, "NOORIGIN"))
777         {
778           lr.constant = true;
779         }
780       else if (lex_match_id (lexer, "NOCONST"))
781         {
782           lr.constant = false;
783         }
784       else if (lex_match_id (lexer, "EXTERNAL"))
785         {
786           /* This is for compatibility.  It does nothing */
787         }
788       else if (lex_match_id (lexer, "CATEGORICAL"))
789         {
790           lex_match (lexer, T_EQUALS);
791           do
792             {
793               lr.cat_predictors = xrealloc (lr.cat_predictors,
794                                   sizeof (*lr.cat_predictors) * ++lr.n_cat_predictors);
795               lr.cat_predictors[lr.n_cat_predictors - 1] = 0;
796             }
797           while (parse_design_interaction (lexer, lr.dict, 
798                                            lr.cat_predictors + lr.n_cat_predictors - 1));
799           lr.n_cat_predictors--;
800         }
801       else if (lex_match_id (lexer, "PRINT"))
802         {
803           lex_match (lexer, T_EQUALS);
804           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
805             {
806               if (lex_match_id (lexer, "DEFAULT"))
807                 {
808                   lr.print |= PRINT_DEFAULT;
809                 }
810               else if (lex_match_id (lexer, "SUMMARY"))
811                 {
812                   lr.print |= PRINT_SUMMARY;
813                 }
814 #if 0
815               else if (lex_match_id (lexer, "CORR"))
816                 {
817                   lr.print |= PRINT_CORR;
818                 }
819               else if (lex_match_id (lexer, "ITER"))
820                 {
821                   lr.print |= PRINT_ITER;
822                 }
823               else if (lex_match_id (lexer, "GOODFIT"))
824                 {
825                   lr.print |= PRINT_GOODFIT;
826                 }
827 #endif
828               else if (lex_match_id (lexer, "CI"))
829                 {
830                   lr.print |= PRINT_CI;
831                   if (lex_force_match (lexer, T_LPAREN))
832                     {
833                       if (! lex_force_int (lexer))
834                         {
835                           lex_error (lexer, NULL);
836                           goto error;
837                         }
838                       lr.confidence = lex_integer (lexer);
839                       lex_get (lexer);
840                       if ( ! lex_force_match (lexer, T_RPAREN))
841                         {
842                           lex_error (lexer, NULL);
843                           goto error;
844                         }
845                     }
846                 }
847               else if (lex_match_id (lexer, "ALL"))
848                 {
849                   lr.print = ~0x0000;
850                 }
851               else
852                 {
853                   lex_error (lexer, NULL);
854                   goto error;
855                 }
856             }
857         }
858       else if (lex_match_id (lexer, "CRITERIA"))
859         {
860           lex_match (lexer, T_EQUALS);
861           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
862             {
863               if (lex_match_id (lexer, "BCON"))
864                 {
865                   if (lex_force_match (lexer, T_LPAREN))
866                     {
867                       if (! lex_force_num (lexer))
868                         {
869                           lex_error (lexer, NULL);
870                           goto error;
871                         }
872                       lr.bcon = lex_number (lexer);
873                       lex_get (lexer);
874                       if ( ! lex_force_match (lexer, T_RPAREN))
875                         {
876                           lex_error (lexer, NULL);
877                           goto error;
878                         }
879                     }
880                 }
881               else if (lex_match_id (lexer, "ITERATE"))
882                 {
883                   if (lex_force_match (lexer, T_LPAREN))
884                     {
885                       if (! lex_force_int (lexer))
886                         {
887                           lex_error (lexer, NULL);
888                           goto error;
889                         }
890                       lr.max_iter = lex_integer (lexer);
891                       lex_get (lexer);
892                       if ( ! lex_force_match (lexer, T_RPAREN))
893                         {
894                           lex_error (lexer, NULL);
895                           goto error;
896                         }
897                     }
898                 }
899               else if (lex_match_id (lexer, "LCON"))
900                 {
901                   if (lex_force_match (lexer, T_LPAREN))
902                     {
903                       if (! lex_force_num (lexer))
904                         {
905                           lex_error (lexer, NULL);
906                           goto error;
907                         }
908                       lr.lcon = lex_number (lexer);
909                       lex_get (lexer);
910                       if ( ! lex_force_match (lexer, T_RPAREN))
911                         {
912                           lex_error (lexer, NULL);
913                           goto error;
914                         }
915                     }
916                 }
917               else if (lex_match_id (lexer, "EPS"))
918                 {
919                   if (lex_force_match (lexer, T_LPAREN))
920                     {
921                       if (! lex_force_num (lexer))
922                         {
923                           lex_error (lexer, NULL);
924                           goto error;
925                         }
926                       lr.min_epsilon = lex_number (lexer);
927                       lex_get (lexer);
928                       if ( ! lex_force_match (lexer, T_RPAREN))
929                         {
930                           lex_error (lexer, NULL);
931                           goto error;
932                         }
933                     }
934                 }
935               else
936                 {
937                   lex_error (lexer, NULL);
938                   goto error;
939                 }
940             }
941         }
942       else
943         {
944           lex_error (lexer, NULL);
945           goto error;
946         }
947     }
948
949   /* Copy the predictor variables from the temporary location into the 
950      final one, dropping any categorical variables which appear there.
951      FIXME: This is O(NxM).
952   */
953
954   {
955   struct variable_node *vn, *next;
956   struct hmap allvars;
957   hmap_init (&allvars);
958   for (v = x = 0; v < n_pred_vars; ++v)
959     {
960       bool drop = false;
961       const struct variable *var = pred_vars[v];
962       int cv = 0;
963
964       unsigned int hash = hash_pointer (var, 0);
965       struct variable_node *vn = lookup_variable (&allvars, var, hash);
966       if (vn == NULL)
967         {
968           vn = xmalloc (sizeof *vn);
969           vn->var = var;
970           hmap_insert (&allvars, &vn->node,  hash);
971         }
972
973       for (cv = 0; cv < lr.n_cat_predictors ; ++cv)
974         {
975           int iv;
976           const struct interaction *iact = lr.cat_predictors[cv];
977           for (iv = 0 ; iv < iact->n_vars ; ++iv)
978             {
979               const struct variable *ivar = iact->vars[iv];
980               unsigned int hash = hash_pointer (ivar, 0);
981               struct variable_node *vn = lookup_variable (&allvars, ivar, hash);
982               if (vn == NULL)
983                 {
984                   vn = xmalloc (sizeof *vn);
985                   vn->var = ivar;
986                   
987                   hmap_insert (&allvars, &vn->node,  hash);
988                 }
989
990               if (var == ivar)
991                 {
992                   drop = true;
993                 }
994             }
995         }
996
997       if (drop)
998         continue;
999
1000       lr.predictor_vars = xrealloc (lr.predictor_vars, sizeof *lr.predictor_vars * (x + 1));
1001       lr.predictor_vars[x++] = var;
1002       lr.n_predictor_vars++;
1003     }
1004   free (pred_vars);
1005
1006   lr.n_indep_vars = hmap_count (&allvars);
1007   lr.indep_vars = xmalloc (lr.n_indep_vars * sizeof *lr.indep_vars);
1008
1009   /* Interate over each variable and push it into the array */
1010   x = 0;
1011   HMAP_FOR_EACH_SAFE (vn, next, struct variable_node, node, &allvars)
1012     {
1013       lr.indep_vars[x++] = vn->var;
1014       free (vn);
1015     }
1016   hmap_destroy (&allvars);
1017   }  
1018
1019
1020   /* logistical regression for each split group */
1021   {
1022     struct casegrouper *grouper;
1023     struct casereader *group;
1024     bool ok;
1025
1026     grouper = casegrouper_create_splits (proc_open (ds), lr.dict);
1027     while (casegrouper_get_next_group (grouper, &group))
1028       ok = run_lr (&lr, group, ds);
1029     ok = casegrouper_destroy (grouper);
1030     ok = proc_commit (ds) && ok;
1031   }
1032
1033   free (lr.predictor_vars);
1034   free (lr.cat_predictors);
1035   free (lr.indep_vars);
1036
1037   return CMD_SUCCESS;
1038
1039  error:
1040
1041   free (lr.predictor_vars);
1042   free (lr.cat_predictors);
1043   free (lr.indep_vars);
1044
1045   return CMD_FAILURE;
1046 }
1047
1048
1049 \f
1050
1051 /* Show the Dependent Variable Encoding box.
1052    This indicates how the dependent variable
1053    is mapped to the internal zero/one values.
1054 */
1055 static void
1056 output_depvarmap (const struct lr_spec *cmd, const struct lr_result *res)
1057 {
1058   const int heading_columns = 0;
1059   const int heading_rows = 1;
1060   struct tab_table *t;
1061   struct string str;
1062
1063   const int nc = 2;
1064   int nr = heading_rows + 2;
1065
1066   t = tab_create (nc, nr);
1067   tab_title (t, _("Dependent Variable Encoding"));
1068
1069   tab_headers (t, heading_columns, 0, heading_rows, 0);
1070
1071   tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1);
1072
1073   tab_hline (t, TAL_2, 0, nc - 1, heading_rows);
1074   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1075
1076   tab_text (t,  0, 0, TAB_CENTER | TAT_TITLE, _("Original Value"));
1077   tab_text (t,  1, 0, TAB_CENTER | TAT_TITLE, _("Internal Value"));
1078
1079
1080
1081   ds_init_empty (&str);
1082   var_append_value_name (cmd->dep_var, &res->y0, &str);
1083   tab_text (t,  0, 0 + heading_rows,  0, ds_cstr (&str));
1084
1085   ds_clear (&str);
1086   var_append_value_name (cmd->dep_var, &res->y1, &str);
1087   tab_text (t,  0, 1 + heading_rows,  0, ds_cstr (&str));
1088
1089
1090   tab_double (t, 1, 0 + heading_rows, 0, map_dependent_var (cmd, res, &res->y0), &F_8_0);
1091   tab_double (t, 1, 1 + heading_rows, 0, map_dependent_var (cmd, res, &res->y1), &F_8_0);
1092   ds_destroy (&str);
1093
1094   tab_submit (t);
1095 }
1096
1097
1098 /* Show the Variables in the Equation box */
1099 static void
1100 output_variables (const struct lr_spec *cmd, 
1101                   const struct lr_result *res,
1102                   const gsl_vector *beta)
1103 {
1104   int row = 0;
1105   const int heading_columns = 1;
1106   int heading_rows = 1;
1107   struct tab_table *t;
1108
1109   int nc = 8;
1110   int nr ;
1111   int i = 0;
1112   int ivar = 0;
1113   int idx_correction = 0;
1114
1115   if (cmd->print & PRINT_CI)
1116     {
1117       nc += 2;
1118       heading_rows += 1;
1119       row++;
1120     }
1121   nr = heading_rows + cmd->n_predictor_vars;
1122   if (cmd->constant)
1123     nr++;
1124
1125   if (res->cats)
1126     nr += categoricals_df_total (res->cats) + cmd->n_cat_predictors;
1127
1128   t = tab_create (nc, nr);
1129   tab_title (t, _("Variables in the Equation"));
1130
1131   tab_headers (t, heading_columns, 0, heading_rows, 0);
1132
1133   tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1);
1134
1135   tab_hline (t, TAL_2, 0, nc - 1, heading_rows);
1136   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1137
1138   tab_text (t,  0, row + 1, TAB_CENTER | TAT_TITLE, _("Step 1"));
1139
1140   tab_text (t,  2, row, TAB_CENTER | TAT_TITLE, _("B"));
1141   tab_text (t,  3, row, TAB_CENTER | TAT_TITLE, _("S.E."));
1142   tab_text (t,  4, row, TAB_CENTER | TAT_TITLE, _("Wald"));
1143   tab_text (t,  5, row, TAB_CENTER | TAT_TITLE, _("df"));
1144   tab_text (t,  6, row, TAB_CENTER | TAT_TITLE, _("Sig."));
1145   tab_text (t,  7, row, TAB_CENTER | TAT_TITLE, _("Exp(B)"));
1146
1147   if (cmd->print & PRINT_CI)
1148     {
1149       tab_joint_text_format (t, 8, 0, 9, 0,
1150                              TAB_CENTER | TAT_TITLE, _("%d%% CI for Exp(B)"), cmd->confidence);
1151
1152       tab_text (t,  8, row, TAB_CENTER | TAT_TITLE, _("Lower"));
1153       tab_text (t,  9, row, TAB_CENTER | TAT_TITLE, _("Upper"));
1154     }
1155  
1156   for (row = heading_rows ; row < nr; ++row)
1157     {
1158       const int idx = row - heading_rows - idx_correction;
1159
1160       const double b = gsl_vector_get (beta, idx);
1161       const double sigma2 = gsl_matrix_get (res->hessian, idx, idx);
1162       const double wald = pow2 (b) / sigma2;
1163       const double df = 1;
1164
1165       if (idx < cmd->n_predictor_vars)
1166         {
1167           tab_text (t, 1, row, TAB_LEFT | TAT_TITLE, 
1168                     var_to_string (cmd->predictor_vars[idx]));
1169         }
1170       else if (i < cmd->n_cat_predictors)
1171         {
1172           double wald;
1173           bool summary = false;
1174           struct string str;
1175           const struct interaction *cat_predictors = cmd->cat_predictors[i];
1176           const int df = categoricals_df (res->cats, i);
1177
1178           ds_init_empty (&str);
1179           interaction_to_string (cat_predictors, &str);
1180
1181           if (ivar == 0)
1182             {
1183               /* Calculate the Wald statistic,
1184                  which is \beta' C^-1 \beta .
1185                  where \beta is the vector of the coefficient estimates comprising this
1186                  categorial variable. and C is the corresponding submatrix of the 
1187                  hessian matrix.
1188               */
1189               gsl_matrix_const_view mv =
1190                 gsl_matrix_const_submatrix (res->hessian, idx, idx, df, df);
1191               gsl_matrix *subhessian = gsl_matrix_alloc (mv.matrix.size1, mv.matrix.size2);
1192               gsl_vector_const_view vv = gsl_vector_const_subvector (beta, idx, df);
1193               gsl_vector *temp = gsl_vector_alloc (df);
1194
1195               gsl_matrix_memcpy (subhessian, &mv.matrix);
1196               gsl_linalg_cholesky_decomp (subhessian);
1197               gsl_linalg_cholesky_invert (subhessian);
1198
1199               gsl_blas_dgemv (CblasTrans, 1.0, subhessian, &vv.vector, 0, temp);
1200               gsl_blas_ddot (temp, &vv.vector, &wald);
1201
1202               tab_double (t, 4, row, 0, wald, 0);
1203               tab_double (t, 5, row, 0, df, &F_8_0);
1204               tab_double (t, 6, row, 0, gsl_cdf_chisq_Q (wald, df), 0);
1205
1206               idx_correction ++;
1207               summary = true;
1208               gsl_matrix_free (subhessian);
1209               gsl_vector_free (temp);
1210             }
1211           else
1212             {
1213               ds_put_format (&str, "(%d)", ivar);
1214             }
1215
1216           tab_text (t, 1, row, TAB_LEFT | TAT_TITLE, ds_cstr (&str));
1217           if (ivar++ == df)
1218             {
1219               ++i; /* next interaction */
1220               ivar = 0;
1221             }
1222
1223           ds_destroy (&str);
1224
1225           if (summary)
1226             continue;
1227         }
1228       else
1229         {
1230           tab_text (t, 1, row, TAB_LEFT | TAT_TITLE, _("Constant"));
1231         }
1232
1233       tab_double (t, 2, row, 0, b, 0);
1234       tab_double (t, 3, row, 0, sqrt (sigma2), 0);
1235       tab_double (t, 4, row, 0, wald, 0);
1236       tab_double (t, 5, row, 0, df, &F_8_0);
1237       tab_double (t, 6, row, 0, gsl_cdf_chisq_Q (wald, df), 0);
1238       tab_double (t, 7, row, 0, exp (b), 0);
1239
1240       if (cmd->print & PRINT_CI)
1241         {
1242           double wc = gsl_cdf_ugaussian_Pinv (0.5 + cmd->confidence / 200.0);
1243           wc *= sqrt (sigma2);
1244
1245           if (idx < cmd->n_predictor_vars)
1246             {
1247               tab_double (t, 8, row, 0, exp (b - wc), 0);
1248               tab_double (t, 9, row, 0, exp (b + wc), 0);
1249             }
1250         }
1251     }
1252
1253   tab_submit (t);
1254 }
1255
1256
1257 /* Show the model summary box */
1258 static void
1259 output_model_summary (const struct lr_result *res,
1260                       double initial_likelihood, double likelihood)
1261 {
1262   const int heading_columns = 0;
1263   const int heading_rows = 1;
1264   struct tab_table *t;
1265
1266   const int nc = 4;
1267   int nr = heading_rows + 1;
1268   double cox;
1269
1270   t = tab_create (nc, nr);
1271   tab_title (t, _("Model Summary"));
1272
1273   tab_headers (t, heading_columns, 0, heading_rows, 0);
1274
1275   tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1);
1276
1277   tab_hline (t, TAL_2, 0, nc - 1, heading_rows);
1278   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1279
1280   tab_text (t,  0, 0, TAB_LEFT | TAT_TITLE, _("Step 1"));
1281   tab_text (t,  1, 0, TAB_CENTER | TAT_TITLE, _("-2 Log likelihood"));
1282   tab_double (t,  1, 1, 0, -2 * log (likelihood), 0);
1283
1284
1285   tab_text (t,  2, 0, TAB_CENTER | TAT_TITLE, _("Cox & Snell R Square"));
1286   cox =  1.0 - pow (initial_likelihood /likelihood, 2 / res->cc);
1287   tab_double (t,  2, 1, 0, cox, 0);
1288
1289   tab_text (t,  3, 0, TAB_CENTER | TAT_TITLE, _("Nagelkerke R Square"));
1290   tab_double (t,  3, 1, 0, cox / ( 1.0 - pow (initial_likelihood, 2 / res->cc)), 0);
1291
1292
1293   tab_submit (t);
1294 }
1295
1296 /* Show the case processing summary box */
1297 static void
1298 case_processing_summary (const struct lr_result *res)
1299 {
1300   const int heading_columns = 1;
1301   const int heading_rows = 1;
1302   struct tab_table *t;
1303
1304   const int nc = 3;
1305   const int nr = heading_rows + 3;
1306   casenumber total;
1307
1308   t = tab_create (nc, nr);
1309   tab_title (t, _("Case Processing Summary"));
1310
1311   tab_headers (t, heading_columns, 0, heading_rows, 0);
1312
1313   tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1);
1314
1315   tab_hline (t, TAL_2, 0, nc - 1, heading_rows);
1316   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1317
1318   tab_text (t,  0, 0, TAB_LEFT | TAT_TITLE, _("Unweighted Cases"));
1319   tab_text (t,  1, 0, TAB_CENTER | TAT_TITLE, _("N"));
1320   tab_text (t,  2, 0, TAB_CENTER | TAT_TITLE, _("Percent"));
1321
1322
1323   tab_text (t,  0, 1, TAB_LEFT | TAT_TITLE, _("Included in Analysis"));
1324   tab_text (t,  0, 2, TAB_LEFT | TAT_TITLE, _("Missing Cases"));
1325   tab_text (t,  0, 3, TAB_LEFT | TAT_TITLE, _("Total"));
1326
1327   tab_double (t,  1, 1, 0, res->n_nonmissing, &F_8_0);
1328   tab_double (t,  1, 2, 0, res->n_missing, &F_8_0);
1329
1330   total = res->n_nonmissing + res->n_missing;
1331   tab_double (t,  1, 3, 0, total , &F_8_0);
1332
1333   tab_double (t,  2, 1, 0, 100 * res->n_nonmissing / (double) total, 0);
1334   tab_double (t,  2, 2, 0, 100 * res->n_missing / (double) total, 0);
1335   tab_double (t,  2, 3, 0, 100 * total / (double) total, 0);
1336
1337   tab_submit (t);
1338 }
1339
1340 static void
1341 output_categories (const struct lr_spec *cmd, const struct lr_result *res)
1342 {
1343   const struct fmt_spec *wfmt =
1344     cmd->wv ? var_get_print_format (cmd->wv) : &F_8_0;
1345
1346   int cumulative_df;
1347   int i = 0;
1348   const int heading_columns = 2;
1349   const int heading_rows = 2;
1350   struct tab_table *t;
1351
1352   int nc ;
1353   int nr ;
1354
1355   int v;
1356   int r = 0;
1357
1358   int max_df = 0;
1359   int total_cats = 0;
1360   for (i = 0; i < cmd->n_cat_predictors; ++i)
1361     {
1362       size_t n = categoricals_n_count (res->cats, i);
1363       size_t df = categoricals_df (res->cats, i);
1364       if (max_df < df)
1365         max_df = df;
1366       total_cats += n;
1367     }
1368
1369   nc = heading_columns + 1 + max_df;
1370   nr = heading_rows + total_cats;
1371
1372   t = tab_create (nc, nr);
1373   tab_title (t, _("Categorical Variables' Codings"));
1374
1375   tab_headers (t, heading_columns, 0, heading_rows, 0);
1376
1377   tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1);
1378
1379   tab_hline (t, TAL_2, 0, nc - 1, heading_rows);
1380   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1381
1382
1383   tab_text (t, heading_columns, 1, TAB_CENTER | TAT_TITLE, _("Frequency"));
1384
1385   tab_joint_text_format (t, heading_columns + 1, 0, nc - 1, 0,
1386                          TAB_CENTER | TAT_TITLE, _("Parameter coding"));
1387
1388
1389   for (i = 0; i < max_df; ++i)
1390     {
1391       int c = heading_columns + 1 + i;
1392       tab_text_format (t,  c, 1, TAB_CENTER | TAT_TITLE, _("(%d)"), i + 1);
1393     }
1394
1395   cumulative_df = 0;
1396   for (v = 0; v < cmd->n_cat_predictors; ++v)
1397     {
1398       int cat;
1399       const struct interaction *cat_predictors = cmd->cat_predictors[v];
1400       int df =  categoricals_df (res->cats, v);
1401       struct string str;
1402       ds_init_empty (&str);
1403
1404       interaction_to_string (cat_predictors, &str);
1405
1406       tab_text (t, 0, heading_rows + r, TAB_LEFT | TAT_TITLE, ds_cstr (&str) );
1407
1408       ds_destroy (&str);
1409
1410       for (cat = 0; cat < categoricals_n_count (res->cats, v) ; ++cat)
1411         {
1412           struct string str;
1413           const struct ccase *c = categoricals_get_case_by_category_real (res->cats, v, cat);
1414           const double *freq = categoricals_get_user_data_by_category_real (res->cats, v, cat);
1415           
1416           int x;
1417           ds_init_empty (&str);
1418
1419           for (x = 0; x < cat_predictors->n_vars; ++x)
1420             {
1421               const union value *val = case_data (c, cat_predictors->vars[x]);
1422               var_append_value_name (cat_predictors->vars[x], val, &str);
1423
1424               if (x < cat_predictors->n_vars - 1)
1425                 ds_put_cstr (&str, " ");
1426             }
1427           
1428           tab_text   (t, 1, heading_rows + r, 0, ds_cstr (&str));
1429           ds_destroy (&str);
1430           tab_double (t, 2, heading_rows + r, 0, *freq, wfmt);
1431
1432           for (x = 0; x < df; ++x)
1433             {
1434               tab_double (t, heading_columns + 1 + x, heading_rows + r, 0, (cat == x), &F_8_0);
1435             }
1436           ++r;
1437         }
1438       cumulative_df += df;
1439     }
1440
1441   tab_submit (t);
1442
1443 }