MEANS: Improve error messages and coding style.
[pspp] / src / language / stats / means.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2019 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 #include <config.h>
18
19 #include "data/case.h"
20 #include "data/casegrouper.h"
21 #include "data/casereader.h"
22 #include "data/dataset.h"
23 #include "data/dictionary.h"
24 #include "data/format.h"
25 #include "data/variable.h"
26
27 #include "libpspp/hmap.h"
28 #include "libpspp/bt.h"
29 #include "libpspp/hash-functions.h"
30 #include "libpspp/misc.h"
31 #include "libpspp/pool.h"
32
33 #include "language/command.h"
34 #include "language/lexer/lexer.h"
35
36 #include "count-one-bits.h"
37 #include "count-leading-zeros.h"
38
39 #include "output/pivot-table.h"
40
41 #include "means.h"
42
43
44 #include "gettext.h"
45 #define _(msgid) gettext (msgid)
46 #define N_(msgid) (msgid)
47
48
49 /* A "cell" in this procedure represents a distinct value of the
50    procedure's categorical variables,  and a set of summary statistics
51    of all cases which whose categorical variables have that set of
52    values.   For example,  the dataset
53
54    v1    v2    cat1     cat2
55    100   202      0     1
56    100   202      0     2
57    100   202      1     0
58    100   202      0     1
59
60
61    has three cells in layer 0 and two cells in layer 1  in addition
62    to a "grand summary" cell to which all (non-missing) cases
63    contribute.
64
65    The cells form a n-ary tree structure with the "grand summary"
66    cell at the root.
67 */
68 struct cell
69 {
70   struct hmap_node hmap_node; /* Element in hash table. */
71   struct bt_node  bt_node;    /* Element in binary tree */
72
73   int n_children;
74   struct cell_container *children;
75
76   /* The statistics to be calculated for the cell.  */
77   struct statistic **stat;
78
79   /* The parent of this cell, or NULL if this is the root cell.  */
80   const struct cell *parent_cell;
81
82   /* A bit-field variable which indicates which control variables
83      are allocated a fixed value (for this cell),  and which are
84      "wildcards".
85
86      A one indicates a fixed value.  A zero indicates a wildcard.
87      Wildcard values are used to calculate totals and sub-totals.
88   */
89   unsigned int not_wild;
90
91   /* The value(s). */
92   union value *values;
93
94   /* The variables corresponding to the above values.  */
95   const struct variable **vars;
96 };
97
98 /*  A structure used to find the union of all values used
99     within a layer, and to sort those values.  */
100 struct instance
101 {
102   struct hmap_node hmap_node; /* Element in hash table. */
103   struct bt_node  bt_node;    /* Element in binary tree */
104
105   /* A unique, consecutive, zero based index identifying this
106      instance.  */
107   int index;
108
109   /* The top level value of this instance.  */
110   union value value;
111   const struct variable *var;
112 };
113
114
115 static void
116 destroy_workspace (const struct mtable *mt, struct workspace *ws)
117 {
118   for (int l = 0; l < mt->n_layers; ++l)
119     {
120       struct cell_container *instances = ws->instances + l;
121       struct instance *inst;
122       struct instance *next;
123       HMAP_FOR_EACH_SAFE (inst, next, struct instance, hmap_node,
124                           &instances->map)
125         {
126           int width = var_get_width (inst->var);
127           value_destroy (&inst->value, width);
128           free (inst);
129         }
130       hmap_destroy (&instances->map);
131     }
132   free (ws->control_idx);
133   free (ws->instances);
134 }
135
136 /* Destroy CELL.  */
137 static void
138 destroy_cell (const struct means *means,
139               const struct mtable *mt, struct cell *cell)
140 {
141   int idx = 0;
142   for (int i = 0; i < mt->n_layers; ++i)
143     {
144       if (0 == ((cell->not_wild >> i) & 0x1))
145         continue;
146
147       const struct layer *layer = mt->layers[i];
148       for (int cmb = 0; cmb < mt->n_combinations; ++cmb)
149       {
150         struct workspace *ws = mt->ws + cmb;
151         const struct variable *var
152           = layer->factor_vars[ws->control_idx[i]];
153
154         int width = var_get_width (var);
155         value_destroy (&cell->values[idx++], width);
156       }
157     }
158   for (int i = 0; i < cell->n_children; ++i)
159     {
160       struct cell_container *container = cell->children + i;
161       hmap_destroy (&container->map);
162     }
163
164   for (int v = 0; v < mt->n_dep_vars; ++v)
165     {
166       for (int s = 0; s < means->n_statistics; ++s)
167         {
168           stat_destroy *des = cell_spec[means->statistics[s]].sf;
169           des (cell->stat[s + v * means->n_statistics]);
170         }
171     }
172   free (cell->stat);
173
174   free (cell->children);
175   free (cell->values);
176   free (cell->vars);
177   free (cell);
178 }
179
180
181 /* Walk the tree in postorder starting from CELL and destroy all the
182    cells.  */
183 static void
184 means_destroy_cells (const struct means *means, struct cell *cell,
185                      const struct mtable *table)
186 {
187   for (int i = 0; i < cell->n_children; ++i)
188     {
189       struct cell_container *container = cell->children + i;
190       struct cell *sub_cell;
191       struct cell *next;
192       HMAP_FOR_EACH_SAFE (sub_cell,  next, struct cell, hmap_node,
193                           &container->map)
194         {
195           means_destroy_cells (means, sub_cell, table);
196         }
197     }
198
199   destroy_cell (means, table, cell);
200 }
201
202 #if 0
203
204 static void
205 dump_cell (const struct cell *cell, const struct mtable *mt, int level)
206 {
207   for (int l = 0; l < level; ++l)
208     putchar (' ');
209   printf ("%p: ", cell);
210   for (int i = 0; i < mt->n_layers; ++i)
211     {
212       putchar (((cell->not_wild >> i) & 0x1) ? 'w' : '.');
213     }
214   printf (" - ");
215   int x = 0;
216   for (int i = 0; i < mt->n_layers; ++i)
217     {
218       if ((cell->not_wild >> i) & 0x1)
219         {
220           printf ("%s: ", var_get_name (cell->vars[x]));
221           printf ("%g ", cell->values[x++].f);
222         }
223       else
224         printf ("x ");
225     }
226   stat_get *sg = cell_spec[MEANS_N].sd;
227   printf ("--- S1: %g", sg (cell->stat[0]));
228
229   printf ("--- N Children: %d", cell->n_children);
230   //  printf ("--- Level: %d", level);
231   printf ("--- Parent: %p", cell->parent_cell);
232   printf ("\n");
233 }
234
235 static void
236 dump_indeces (const size_t *indexes, int n)
237 {
238   for (int i = 0; i < n; ++i)
239     {
240       printf ("%ld; ", indexes[i]);
241     }
242   printf ("\n");
243 }
244
245 /* Dump the tree in pre-order.  */
246 static void
247 dump_tree (const struct cell *cell, const struct mtable *table,
248            int level, const struct cell *parent)
249 {
250   assert (cell->parent_cell == parent);
251   dump_cell (cell, table, level);
252
253   for (int i = 0; i < cell->n_children; ++i)
254     {
255       struct cell_container *container = cell->children + i;
256       struct cell *sub_cell;
257       BT_FOR_EACH (sub_cell, struct cell, bt_node, &container->bt)
258         {
259           dump_tree (sub_cell, table, level + 1, cell);
260         }
261     }
262 }
263
264 #endif
265
266 /* Generate a hash based on the values of the N variables in
267    the array VARS which are taken from the case C.  */
268 static unsigned int
269 generate_hash (const struct mtable *mt,
270                const struct ccase *c,
271                unsigned int not_wild,
272                const struct workspace *ws)
273 {
274   unsigned int hash = 0;
275   for (int i = 0; i < mt->n_layers; ++i)
276     {
277       if (0 == ((not_wild >> i) & 0x1))
278         continue;
279
280       const struct layer *layer = mt->layers[i];
281       const struct variable *var = layer->factor_vars[ws->control_idx[i]];
282       const union value *vv = case_data (c, var);
283       int width = var_get_width (var);
284       hash = hash_int (i, hash);
285       hash = value_hash (vv, width, hash);
286     }
287
288   return hash;
289 }
290
291 /* Create a cell based on the N variables in the array VARS,
292    which are indeces into the case C.
293    The caller is responsible for destroying this cell when
294    no longer needed. */
295 static struct cell *
296 generate_cell (const struct means *means,
297                const struct mtable *mt,
298                const struct ccase *c,
299                unsigned int not_wild,
300                const struct cell *pcell,
301                const struct workspace *ws)
302 {
303   int n_vars = count_one_bits (not_wild);
304   struct cell *cell = XZALLOC (struct cell);
305   cell->values = xcalloc (n_vars, sizeof *cell->values);
306   cell->vars = xcalloc (n_vars, sizeof *cell->vars);
307   cell->not_wild = not_wild;
308
309   cell->parent_cell = pcell;
310   cell->n_children = mt->n_layers -
311     (sizeof (cell->not_wild) * CHAR_BIT) +
312     count_leading_zeros (cell->not_wild);
313
314   int idx = 0;
315   for (int i = 0; i < mt->n_layers; ++i)
316     {
317       if (0 == ((not_wild >> i) & 0x1))
318         continue;
319
320       const struct layer *layer = mt->layers[i];
321       const struct variable *var = layer->factor_vars[ws->control_idx[i]];
322       const union value *vv = case_data (c, var);
323       int width = var_get_width (var);
324       cell->vars[idx] = var;
325       value_clone (&cell->values[idx++], vv, width);
326     }
327   assert (idx == n_vars);
328
329   cell->children = xcalloc (cell->n_children, sizeof *cell->children);
330   for (int i = 0; i < cell->n_children; ++i)
331     {
332       struct cell_container *container = cell->children + i;
333       hmap_init (&container->map);
334     }
335
336   cell->stat = xcalloc (means->n_statistics * mt->n_dep_vars, sizeof *cell->stat);
337   for (int v = 0; v < mt->n_dep_vars; ++v)
338     {
339       for (int stat = 0; stat < means->n_statistics; ++stat)
340         {
341           stat_create *sc = cell_spec[means->statistics[stat]].sc;
342
343           cell->stat[stat + v * means->n_statistics] = sc (means->pool);
344         }
345     }
346   return cell;
347 }
348
349
350 /* If a  cell based on the N variables in the array VARS,
351    which are indeces into the case C and whose hash is HASH,
352    exists in HMAP, then return that cell.
353    Otherwise, return NULL.  */
354 static struct cell *
355 lookup_cell (const struct mtable *mt,
356              struct hmap *hmap,  unsigned int hash,
357              const struct ccase *c,
358              unsigned int not_wild,
359              const struct workspace *ws)
360 {
361   struct cell *cell = NULL;
362   HMAP_FOR_EACH_WITH_HASH (cell, struct cell, hmap_node, hash, hmap)
363     {
364       bool match = true;
365       int idx = 0;
366       if (cell->not_wild != not_wild)
367         continue;
368       for (int i = 0; i < mt->n_layers; ++i)
369         {
370           if (0 == ((cell->not_wild >> i) & 0x1))
371             continue;
372
373           const struct layer *layer = mt->layers[i];
374           const struct variable *var = layer->factor_vars[ws->control_idx[i]];
375           const union value *vv = case_data (c, var);
376           int width = var_get_width (var);
377           assert (var == cell->vars[idx]);
378           if (!value_equal (vv, &cell->values[idx++], width))
379             {
380               match = false;
381               break;
382             }
383         }
384       if (match)
385         return cell;
386     }
387   return NULL;
388 }
389
390
391 /*  A comparison function used to sort cells in a binary tree.
392     Only the innermost value needs to be compared, because no
393     two cells with similar outer values will appear in the same
394     tree/map.   */
395 static int
396 cell_compare_3way (const struct bt_node *a,
397                    const struct bt_node *b,
398                    const void *aux UNUSED)
399 {
400   const struct cell *fa = BT_DATA (a, struct cell, bt_node);
401   const struct cell *fb = BT_DATA (b, struct cell, bt_node);
402
403   assert (fa->not_wild == fb->not_wild);
404   int vidx = count_one_bits (fa->not_wild) - 1;
405   assert (fa->vars[vidx] == fb->vars[vidx]);
406
407   return value_compare_3way (&fa->values[vidx],
408                              &fb->values[vidx],
409                              var_get_width (fa->vars[vidx]));
410 }
411
412 /*  A comparison function used to sort cells in a binary tree.  */
413 static int
414 compare_instance_3way (const struct bt_node *a,
415                        const struct bt_node *b,
416                        const void *aux UNUSED)
417 {
418   const struct instance *fa = BT_DATA (a, struct instance, bt_node);
419   const struct instance *fb = BT_DATA (b, struct instance, bt_node);
420
421   assert (fa->var == fb->var);
422
423   return  value_compare_3way (&fa->value,
424                               &fb->value,
425                               var_get_width (fa->var));
426 }
427
428
429 static void arrange_cells (struct workspace *ws,
430                            struct cell *cell, const struct mtable *table);
431
432
433 /* Iterate CONTAINER's map inserting a copy of its elements into
434    CONTAINER's binary tree.    Also, for each layer in TABLE, create
435    an instance container, containing the union of all elements in
436    CONTAINER.  */
437 static void
438 arrange_cell (struct workspace *ws, struct cell_container *container,
439               const struct mtable *mt)
440 {
441   struct bt *bt = &container->bt;
442   struct hmap *map = &container->map;
443   bt_init (bt, cell_compare_3way, NULL);
444
445   struct cell *cell;
446   HMAP_FOR_EACH (cell, struct cell, hmap_node, map)
447     {
448       bt_insert (bt, &cell->bt_node);
449
450       int idx = 0;
451       for (int i = 0; i < mt->n_layers; ++i)
452         {
453           if (0 == ((cell->not_wild >> i) & 0x1))
454             continue;
455
456           struct cell_container *instances = ws->instances + i;
457           const struct variable *var = cell->vars[idx];
458           int width = var_get_width (var);
459           unsigned int hash
460             = value_hash (&cell->values[idx], width, 0);
461
462           struct instance *inst = NULL;
463           struct instance *next = NULL;
464           HMAP_FOR_EACH_WITH_HASH_SAFE (inst, next, struct instance,
465                                         hmap_node,
466                                         hash, &instances->map)
467             {
468               assert (cell->vars[idx] == var);
469               if (value_equal (&inst->value,
470                                &cell->values[idx],
471                                width))
472                 {
473                   break;
474                 }
475             }
476
477           if (!inst)
478             {
479               inst = xzalloc (sizeof *inst);
480               inst->index = -1;
481               inst->var = var;
482               value_clone (&inst->value, &cell->values[idx],
483                            width);
484               hmap_insert (&instances->map, &inst->hmap_node, hash);
485             }
486
487           idx++;
488         }
489
490       arrange_cells (ws, cell, mt);
491     }
492 }
493
494 /* Arrange the children and then all the subtotals.  */
495 static void
496 arrange_cells (struct workspace *ws, struct cell *cell,
497                const struct mtable *table)
498 {
499   for (int i = 0; i < cell->n_children; ++i)
500     {
501       struct cell_container *container = cell->children + i;
502       arrange_cell (ws, container, table);
503     }
504 }
505
506
507 \f
508
509 /*  If the top level value in CELL, has an instance in the L_IDX'th layer,
510     then return that instance.  Otherwise return NULL.  */
511 static const struct instance *
512 lookup_instance (const struct mtable *mt, const struct workspace *ws,
513                  int l_idx, const struct cell *cell)
514 {
515   const struct layer *layer = mt->layers[l_idx];
516   int n_vals = count_one_bits (cell->not_wild);
517   const struct variable *var = layer->factor_vars[ws->control_idx[l_idx]];
518   const union value *val = cell->values + n_vals - 1;
519   int width = var_get_width (var);
520   unsigned int hash = value_hash (val, width, 0);
521   const struct cell_container *instances = ws->instances + l_idx;
522   struct instance *inst = NULL;
523   struct instance *next;
524   HMAP_FOR_EACH_WITH_HASH_SAFE (inst, next,
525                                 struct instance, hmap_node,
526                                 hash, &instances->map)
527     {
528       if (value_equal (val, &inst->value, width))
529         break;
530     }
531   return inst;
532 }
533
534 /* Enter the values into PT.  */
535 static void
536 populate_table (const struct means *means, const struct mtable *mt,
537                 const struct workspace *ws,
538                 const struct cell *cell,
539                 struct pivot_table *pt)
540 {
541   size_t *indexes = XCALLOC (pt->n_dimensions, size_t);
542   for (int v = 0; v < mt->n_dep_vars; ++v)
543     {
544       for (int s = 0; s < means->n_statistics; ++s)
545         {
546           int i = 0;
547           if (mt->n_dep_vars > 1)
548             indexes[i++] = v;
549           indexes[i++] = s;
550           int stat = means->statistics[s];
551           stat_get *sg = cell_spec[stat].sd;
552           {
553             const struct cell *pc = cell;
554             for (; i < pt->n_dimensions; ++i)
555               {
556                 int l_idx = pt->n_dimensions - i - 1;
557                 const struct cell_container *instances = ws->instances + l_idx;
558                 if (0 == (cell->not_wild >> l_idx & 0x1U))
559                   {
560                     indexes [i] = hmap_count (&instances->map);
561                   }
562                 else
563                   {
564                     assert (pc);
565                     const struct instance *inst
566                       = lookup_instance (mt, ws, l_idx, pc);
567                     assert (inst);
568                     indexes [i] = inst->index;
569                     pc = pc->parent_cell;
570                   }
571               }
572           }
573
574           int idx = s + v * means->n_statistics;
575           struct pivot_value *pv
576             = pivot_value_new_number (sg (cell->stat[idx]));
577           if (NULL == cell_spec[stat].rc)
578             {
579               const struct variable *dv = mt->dep_vars[v];
580               pv->numeric.format = * var_get_print_format (dv);
581             }
582           pivot_table_put (pt, indexes, pt->n_dimensions, pv);
583         }
584     }
585   free (indexes);
586
587   for (int i = 0; i < cell->n_children; ++i)
588     {
589       struct cell_container *container = cell->children + i;
590       struct cell *child = NULL;
591       BT_FOR_EACH (child, struct cell, bt_node, &container->bt)
592         {
593           populate_table (means, mt, ws, child, pt);
594         }
595     }
596 }
597
598 static void
599 create_table_structure (const struct mtable *mt, struct pivot_table *pt,
600                         const struct workspace *ws)
601 {
602   int * lindexes = ws->control_idx;
603   /* The inner layers are situated rightmost in the table.
604      So this iteration is in reverse order.  */
605   for (int l = mt->n_layers - 1; l >= 0; --l)
606     {
607       const struct layer *layer = mt->layers[l];
608       const struct cell_container *instances = ws->instances + l;
609       const struct variable *var = layer->factor_vars[lindexes[l]];
610       struct pivot_dimension *dim_layer
611         = pivot_dimension_create (pt, PIVOT_AXIS_ROW,
612                                   var_to_string (var));
613       dim_layer->root->show_label = true;
614
615       /* Place the values of the control variables as table headings.  */
616       {
617         struct instance *inst = NULL;
618         BT_FOR_EACH (inst, struct instance, bt_node, &instances->bt)
619           {
620             struct substring space = SS_LITERAL_INITIALIZER ("\t ");
621             struct string str;
622             ds_init_empty (&str);
623             var_append_value_name (var,
624                                    &inst->value,
625                                    &str);
626
627             ds_ltrim (&str, space);
628
629             pivot_category_create_leaf (dim_layer->root,
630                                         pivot_value_new_text (ds_cstr (&str)));
631
632             ds_destroy (&str);
633           }
634       }
635
636       pivot_category_create_leaf (dim_layer->root,
637                                   pivot_value_new_text ("Total"));
638     }
639 }
640
641 /* Initialise C_DES with a string describing the control variable
642    relating to MT, LINDEXES.  */
643 static void
644 layers_to_string (const struct mtable *mt, const int *lindexes,
645                   struct string *c_des)
646 {
647   for (int l = 0; l < mt->n_layers; ++l)
648     {
649       const struct layer *layer = mt->layers[l];
650       const struct variable *ctrl_var = layer->factor_vars[lindexes[l]];
651       if (l > 0)
652         ds_put_cstr (c_des, " * ");
653       ds_put_cstr (c_des, var_get_name (ctrl_var));
654     }
655 }
656
657 static void
658 populate_case_processing_summary (struct pivot_category *pc,
659                                   const struct mtable *mt,
660                                   const int *lindexes)
661 {
662   struct string ds;
663   ds_init_empty (&ds);
664   int l = 0;
665   for (l = 0; l < mt->n_layers; ++l)
666     {
667       const struct layer *layer = mt->layers[l];
668       const struct variable *ctrl_var = layer->factor_vars[lindexes[l]];
669       if (l > 0)
670         ds_put_cstr (&ds, " * ");
671       ds_put_cstr (&ds, var_get_name (ctrl_var));
672     }
673   for (int dv = 0; dv < mt->n_dep_vars; ++dv)
674     {
675       struct string dss;
676       ds_init_empty (&dss);
677       ds_put_cstr (&dss, var_get_name (mt->dep_vars[dv]));
678       if (mt->n_layers > 0)
679         {
680           ds_put_cstr (&dss, " * ");
681           ds_put_substring (&dss, ds.ss);
682         }
683       pivot_category_create_leaf (pc,
684                                   pivot_value_new_text (ds_cstr (&dss)));
685       ds_destroy (&dss);
686     }
687
688   ds_destroy (&ds);
689 }
690
691 /* Create the "Case Processing Summary" table.  */
692 static void
693 means_case_processing_summary (const struct mtable *mt)
694 {
695   struct pivot_table *pt = pivot_table_create (N_("Case Processing Summary"));
696
697   struct pivot_dimension *dim_cases =
698     pivot_dimension_create (pt, PIVOT_AXIS_COLUMN, N_("Cases"));
699   dim_cases->root->show_label = true;
700
701   struct pivot_category *cats[3];
702   cats[0] = pivot_category_create_group (dim_cases->root,
703                                          N_("Included"), NULL);
704   cats[1] = pivot_category_create_group (dim_cases->root,
705                                          N_("Excluded"), NULL);
706   cats[2] = pivot_category_create_group (dim_cases->root,
707                                          N_("Total"), NULL);
708   for (int i = 0; i < 3; ++i)
709     {
710       pivot_category_create_leaf_rc (cats[i],
711                                      pivot_value_new_text (N_("N")),
712                                      PIVOT_RC_COUNT);
713       pivot_category_create_leaf_rc (cats[i],
714                                      pivot_value_new_text (N_("Percent")),
715                                      PIVOT_RC_PERCENT);
716     }
717
718   struct pivot_dimension *rows =
719     pivot_dimension_create (pt, PIVOT_AXIS_ROW, N_("Variables"));
720
721   for (int cmb = 0; cmb < mt->n_combinations; ++cmb)
722     {
723       const struct workspace *ws = mt->ws + cmb;
724       populate_case_processing_summary (rows->root, mt, ws->control_idx);
725       for (int dv = 0; dv < mt->n_dep_vars; ++dv)
726         {
727           int idx = cmb * mt->n_dep_vars + dv;
728           const struct summary *summ = mt->summ + idx;
729           double n_included = summ->n_total - summ->n_missing;
730           pivot_table_put2 (pt, 5, idx,
731                             pivot_value_new_number (100.0 * summ->n_total / summ->n_total));
732           pivot_table_put2 (pt, 4, idx,
733                             pivot_value_new_number (summ->n_total));
734
735           pivot_table_put2 (pt, 3, idx,
736                             pivot_value_new_number (100.0 * summ->n_missing / summ->n_total));
737           pivot_table_put2 (pt, 2, idx,
738                             pivot_value_new_number (summ->n_missing));
739
740           pivot_table_put2 (pt, 1, idx,
741                             pivot_value_new_number (100.0 * n_included / summ->n_total));
742           pivot_table_put2 (pt, 0, idx,
743                             pivot_value_new_number (n_included));
744         }
745     }
746
747   pivot_table_submit (pt);
748 }
749
750 static void
751 means_shipout_single (const struct mtable *mt, const struct means *means,
752                       const struct workspace *ws)
753 {
754   struct pivot_table *pt = pivot_table_create (N_("Report"));
755
756   struct pivot_dimension *dim_cells =
757     pivot_dimension_create (pt, PIVOT_AXIS_COLUMN, N_("Statistics"));
758
759   /* Set the statistics headings, eg "Mean", "Std. Dev" etc.  */
760   for (int i = 0; i < means->n_statistics; ++i)
761     {
762       const struct cell_spec *cs = cell_spec + means->statistics[i];
763       pivot_category_create_leaf_rc
764         (dim_cells->root,
765          pivot_value_new_text (gettext (cs->title)), cs->rc);
766     }
767
768   create_table_structure (mt, pt, ws);
769   populate_table (means, mt, ws, ws->root_cell, pt);
770   pivot_table_submit (pt);
771 }
772
773
774 static void
775 means_shipout_multivar (const struct mtable *mt, const struct means *means,
776                         const struct workspace *ws)
777 {
778   struct string dss;
779   ds_init_empty (&dss);
780   for (int dv = 0; dv < mt->n_dep_vars; ++dv)
781     {
782       if (dv > 0)
783         ds_put_cstr (&dss, " * ");
784       ds_put_cstr (&dss, var_get_name (mt->dep_vars[dv]));
785     }
786
787   for (int l = 0; l < mt->n_layers; ++l)
788     {
789       ds_put_cstr (&dss, " * ");
790       const struct layer *layer = mt->layers[l];
791       const struct variable *var = layer->factor_vars[ws->control_idx[l]];
792       ds_put_cstr (&dss, var_get_name (var));
793     }
794
795   struct pivot_table *pt = pivot_table_create (ds_cstr (&dss));
796   ds_destroy (&dss);
797
798   struct pivot_dimension *dim_cells =
799     pivot_dimension_create (pt, PIVOT_AXIS_COLUMN, N_("Variables"));
800
801   for (int i = 0; i < mt->n_dep_vars; ++i)
802     {
803       pivot_category_create_leaf
804         (dim_cells->root,
805          pivot_value_new_variable (mt->dep_vars[i]));
806     }
807
808   struct pivot_dimension *dim_stats
809     = pivot_dimension_create (pt, PIVOT_AXIS_ROW,
810                               N_ ("Statistics"));
811   dim_stats->root->show_label = false;
812
813   for (int i = 0; i < means->n_statistics; ++i)
814     {
815       const struct cell_spec *cs = cell_spec + means->statistics[i];
816       pivot_category_create_leaf_rc
817         (dim_stats->root,
818          pivot_value_new_text (gettext (cs->title)), cs->rc);
819     }
820
821   create_table_structure (mt, pt, ws);
822   populate_table (means, mt, ws, ws->root_cell, pt);
823   pivot_table_submit (pt);
824 }
825
826 static void
827 means_shipout (const struct mtable *mt, const struct means *means)
828 {
829   for (int cmb = 0; cmb < mt->n_combinations; ++cmb)
830     {
831       const struct workspace *ws = mt->ws + cmb;
832       if (ws->root_cell == NULL)
833         {
834           struct string des;
835           ds_init_empty (&des);
836           layers_to_string (mt, ws->control_idx, &des);
837           msg (MW, _("The table \"%s\" has no non-empty control variables."
838                      "  No result for this table will be displayed."),
839                ds_cstr (&des));
840           ds_destroy (&des);
841           continue;
842         }
843       if (mt->n_dep_vars > 1)
844         means_shipout_multivar (mt, means, ws);
845       else
846         means_shipout_single (mt, means, ws);
847     }
848 }
849
850
851 \f
852
853 static bool
854 control_var_missing (const struct means *means,
855                      const struct mtable *mt,
856                      unsigned int not_wild UNUSED,
857                      const struct ccase *c,
858                      const struct workspace *ws)
859 {
860   bool miss = false;
861   for (int l = 0; l < mt->n_layers; ++l)
862     {
863       /* if (0 == ((not_wild >> l) & 0x1)) */
864       /* { */
865       /*   continue; */
866       /* } */
867
868       const struct layer *layer = mt->layers[l];
869       const struct variable *var = layer->factor_vars[ws->control_idx[l]];
870       const union value *vv = case_data (c, var);
871
872       miss = (var_is_value_missing (var, vv) & means->ctrl_exclude) != 0;
873       if (miss)
874         break;
875     }
876
877   return miss;
878 }
879
880 /* Lookup the set of control variables described by MT, C and NOT_WILD,
881    in the hash table MAP.  If there is no such entry, then create a
882    cell with these paremeters and add is to MAP.
883    If the generated cell has childen, repeat for all the children.
884    Returns the root cell.
885 */
886 static struct cell *
887 service_cell_map (const struct means *means, const struct mtable *mt,
888                  const struct ccase *c,
889                  unsigned int not_wild,
890                  struct hmap *map,
891                  const struct cell *pcell,
892                  int level,
893                  const struct workspace *ws)
894 {
895   struct cell *cell = NULL;
896   if (map)
897     {
898       if (!control_var_missing (means, mt, not_wild, c, ws))
899         {
900           /* Lookup this set of values in the cell's hash table.  */
901           unsigned int hash = generate_hash (mt, c, not_wild, ws);
902           cell = lookup_cell (mt, map, hash, c, not_wild, ws);
903
904           /* If it has not been seen before, then create a new
905              subcell, with this set of values, and insert it
906              into the table.  */
907           if (cell == NULL)
908             {
909               cell = generate_cell (means, mt, c, not_wild, pcell, ws);
910               hmap_insert (map, &cell->hmap_node, hash);
911             }
912         }
913     }
914   else
915     {
916       /* This condition should only happen in the root node case. */
917       cell = ws->root_cell;
918       if (cell == NULL &&
919           !control_var_missing (means, mt, not_wild, c, ws))
920         cell = generate_cell (means, mt, c, not_wild, pcell, ws);
921     }
922
923   if (cell)
924     {
925       /* Here is where the business really happens!   After
926          testing for missing values, the cell's statistics
927          are accumulated.  */
928       if (!control_var_missing (means, mt, not_wild, c, ws))
929         {
930           for (int v = 0; v < mt->n_dep_vars; ++v)
931             {
932               const struct variable *dep_var = mt->dep_vars[v];
933               const union value *vv = case_data (c, dep_var);
934               if (var_is_value_missing (dep_var, vv) & means->dep_exclude)
935                 continue;
936
937               for (int stat = 0; stat < means->n_statistics; ++stat)
938                 {
939                   const double weight = dict_get_case_weight (means->dict, c,
940                                                               NULL);
941                   stat_update *su = cell_spec[means->statistics[stat]].su;
942                   su (cell->stat[stat + v * means->n_statistics], weight,
943                       case_num (c, dep_var));
944                 }
945             }
946         }
947
948       /* Recurse into all the children (if there are any).  */
949       for (int i = 0; i < cell->n_children; ++i)
950         {
951           struct cell_container *cc = cell->children + i;
952           service_cell_map (means, mt, c,
953                            not_wild | (0x1U << (i + level)),
954                            &cc->map, cell, level + i + 1, ws);
955         }
956     }
957
958   return cell;
959 }
960
961 /*  Do all the necessary preparation and pre-calculation that
962     needs to be done before iterating the data.  */
963 static void
964 prepare_means (struct means *cmd)
965 {
966   for (int t = 0; t < cmd->n_tables; ++t)
967     {
968       struct mtable *mt = cmd->table + t;
969
970       for (int i = 0; i < mt->n_combinations; ++i)
971         {
972           struct workspace *ws = mt->ws + i;
973           ws->root_cell = NULL;
974           ws->control_idx = xcalloc (mt->n_layers, sizeof *ws->control_idx);
975           ws->instances = xcalloc (mt->n_layers, sizeof *ws->instances);
976           int cmb = i;
977           for (int l = mt->n_layers - 1; l >= 0; --l)
978             {
979               struct cell_container *instances = ws->instances + l;
980               const struct layer *layer = mt->layers[l];
981               ws->control_idx[l] = cmb % layer->n_factor_vars;
982               cmb /= layer->n_factor_vars;
983               hmap_init (&instances->map);
984             }
985         }
986     }
987 }
988
989
990 /* Do all the necessary calculations that occur AFTER iterating
991    the data.  */
992 static void
993 post_means (struct means *cmd)
994 {
995   for (int t = 0; t < cmd->n_tables; ++t)
996     {
997       struct mtable *mt = cmd->table + t;
998       for (int cmb = 0; cmb < mt->n_combinations; ++cmb)
999         {
1000           struct workspace *ws = mt->ws + cmb;
1001           if (ws->root_cell == NULL)
1002             continue;
1003           arrange_cells (ws, ws->root_cell, mt);
1004           /*  The root cell should have no parent.  */
1005           assert (ws->root_cell->parent_cell == 0);
1006
1007           for (int l = 0; l < mt->n_layers; ++l)
1008             {
1009               struct cell_container *instances = ws->instances + l;
1010               bt_init (&instances->bt, compare_instance_3way, NULL);
1011
1012               /* Iterate the instance hash table, and insert each instance
1013                  into the binary tree BT.  */
1014               struct instance *inst;
1015               HMAP_FOR_EACH (inst, struct instance, hmap_node,
1016                              &instances->map)
1017                 {
1018                   bt_insert (&instances->bt, &inst->bt_node);
1019                 }
1020
1021               /* Iterate the binary tree (in order) and assign the index
1022                  member accordingly.  */
1023               int index = 0;
1024               BT_FOR_EACH (inst, struct instance, bt_node, &instances->bt)
1025                 {
1026                   inst->index = index++;
1027                 }
1028             }
1029         }
1030     }
1031 }
1032
1033
1034 /* Update the summary information (the missings and the totals).  */
1035 static void
1036 update_summaries (const struct means *means, struct mtable *mt,
1037                   const struct ccase *c, double weight)
1038 {
1039   for (int dv = 0; dv < mt->n_dep_vars; ++dv)
1040     {
1041       for (int cmb = 0; cmb < mt->n_combinations; ++cmb)
1042         {
1043           struct workspace *ws = mt->ws + cmb;
1044           struct summary *summ = mt->summ
1045             + cmb * mt->n_dep_vars + dv;
1046
1047           summ->n_total += weight;
1048           const struct variable *var = mt->dep_vars[dv];
1049           const union value *vv = case_data (c, var);
1050           /* First check if the dependent variable is missing.  */
1051           if (var_is_value_missing (var, vv) & means->dep_exclude)
1052             summ->n_missing += weight;
1053           /* If the dep var is not missing, then check each
1054              control variable.  */
1055           else
1056             for (int l = 0; l < mt->n_layers; ++l)
1057               {
1058                 const struct layer *layer = mt->layers [l];
1059                 const struct variable *var
1060                   = layer->factor_vars[ws->control_idx[l]];
1061                 const union value *vv = case_data (c, var);
1062                 if (var_is_value_missing (var, vv) & means->ctrl_exclude)
1063                   {
1064                     summ->n_missing += weight;
1065                     break;
1066                   }
1067               }
1068         }
1069     }
1070 }
1071
1072
1073 void
1074 run_means (struct means *cmd, struct casereader *input,
1075            const struct dataset *ds UNUSED)
1076 {
1077   struct ccase *c = NULL;
1078   struct casereader *reader;
1079
1080   prepare_means (cmd);
1081
1082   for (reader = input;
1083        (c = casereader_read (reader)) != NULL; case_unref (c))
1084     {
1085       const double weight
1086         = dict_get_case_weight (cmd->dict, c, NULL);
1087       for (int t = 0; t < cmd->n_tables; ++t)
1088         {
1089           struct mtable *mt = cmd->table + t;
1090           update_summaries (cmd, mt, c, weight);
1091
1092           for (int cmb = 0; cmb < mt->n_combinations; ++cmb)
1093             {
1094               struct workspace *ws = mt->ws + cmb;
1095
1096               ws->root_cell = service_cell_map (cmd, mt, c,
1097                                                 0U, NULL, NULL, 0, ws);
1098             }
1099         }
1100     }
1101   casereader_destroy (reader);
1102
1103   post_means (cmd);
1104 }
1105
1106 int
1107 cmd_means (struct lexer *lexer, struct dataset *ds)
1108 {
1109   struct means means = {
1110     .pool = pool_create (),
1111     .ctrl_exclude = MV_ANY,
1112     .dep_exclude = MV_ANY,
1113     .dict = dataset_dict (ds),
1114   };
1115   means_set_default_statistics (&means);
1116
1117   if (!means_parse (lexer, &means))
1118     goto error;
1119
1120   /* Calculate some constant data for each table.  */
1121   for (int t = 0; t < means.n_tables; ++t)
1122     {
1123       struct mtable *mt = means.table + t;
1124       mt->n_combinations = 1;
1125       for (int l = 0; l < mt->n_layers; ++l)
1126         mt->n_combinations *= mt->layers[l]->n_factor_vars;
1127     }
1128
1129   struct casegrouper *grouper
1130     = casegrouper_create_splits (proc_open (ds), means.dict);
1131   struct casereader *group;
1132   while (casegrouper_get_next_group (grouper, &group))
1133     {
1134       /* Allocate the workspaces.  */
1135       for (int t = 0; t < means.n_tables; ++t)
1136         {
1137           struct mtable *mt = means.table + t;
1138           mt->summ = xcalloc (mt->n_combinations * mt->n_dep_vars,
1139                               sizeof *mt->summ);
1140           mt->ws = xcalloc (mt->n_combinations, sizeof *mt->ws);
1141         }
1142       run_means (&means, group, ds);
1143       for (int t = 0; t < means.n_tables; ++t)
1144         {
1145           const struct mtable *mt = means.table + t;
1146
1147           means_case_processing_summary (mt);
1148           means_shipout (mt, &means);
1149
1150           for (int i = 0; i < mt->n_combinations; ++i)
1151             {
1152               struct workspace *ws = mt->ws + i;
1153               if (ws->root_cell)
1154                 means_destroy_cells (&means, ws->root_cell, mt);
1155             }
1156         }
1157
1158       /* Destroy the workspaces.  */
1159       for (int t = 0; t < means.n_tables; ++t)
1160         {
1161           struct mtable *mt = means.table + t;
1162           free (mt->summ);
1163           for (int i = 0; i < mt->n_combinations; ++i)
1164             {
1165               struct workspace *ws = mt->ws + i;
1166               destroy_workspace (mt, ws);
1167             }
1168           free (mt->ws);
1169         }
1170     }
1171
1172   bool ok = casegrouper_destroy (grouper);
1173   ok = proc_commit (ds) && ok;
1174   if (!ok)
1175     goto error;
1176
1177   pool_destroy (means.pool);
1178   return CMD_SUCCESS;
1179
1180  error:
1181   pool_destroy (means.pool);
1182   return CMD_FAILURE;
1183 }