Categoricals: Sort the reverse value map.
[pspp] / src / math / categoricals.c
index 1968b332f8257229d0d9cd25d4c601a3ed764426..c8b337e452012f03c2d16f5229f2253441a16b21 100644 (file)
@@ -26,6 +26,7 @@
 #include <data/value.h>
 #include <libpspp/hmap.h>
 #include <libpspp/pool.h>
+#include <libpspp/array.h>
 
 #include <libpspp/str.h>
 
@@ -41,7 +42,6 @@ struct value_node
                                 Can be used as an index into an array */
 };
 
-
 struct var_params
 {
   /* A map indexed by a union values */
@@ -62,6 +62,18 @@ struct var_params
 };
 
 
+/* Comparison function to sort the reverse_value_map in ascending order */
+static int
+compare_value_node (const void *vn1_, const void *vn2_, const void *aux)
+{
+  const struct value_node * const *vn1 = vn1_;
+  const struct value_node * const *vn2 = vn2_;
+  const struct var_params *vp = aux;
+
+  return value_compare_3way (&(*vn1)->value, &(*vn2)->value, var_get_width (vp->var));
+}
+
+
 struct categoricals
 {
   /* The weight variable */
@@ -88,16 +100,12 @@ struct categoricals
   /* Missing values to be excluded */
   enum mv_class exclude;
 
-
-
   /* Function to be called on each update */
   update_func *update;
 
-
   /* Function specified by the caller to create user_data */
   user_data_create_func *user_data_create;
 
-
   /* Auxilliary data to be passed to update and user_data_create_func*/
   void *aux1;
   void *aux2;
@@ -280,7 +288,7 @@ categoricals_update (struct categoricals *cat, const struct ccase *c)
       cat->vp[i].cc += weight;
 
       if (cat->update)
-       cat->update (node->user_data, cat->wv, var, c, cat->aux1, cat->aux2);
+       cat->update (node->user_data, cat->exclude, cat->wv, var, c, cat->aux1, cat->aux2);
     }
 }
 
@@ -334,6 +342,10 @@ categoricals_done (struct categoricals *cat)
          vp->reverse_value_map[vn->subscript] = vn;
        }
 
+      /* For some purposes (eg CONTRASTS in ONEWAY) the values need to be sorted */
+      sort (vp->reverse_value_map, vp->n_cats, sizeof (const struct value_node *),
+           compare_value_node, vp);
+
       /* Populate the reverse variable map.
        */
       for (i = 0; i < vp->n_cats; ++i)
@@ -341,6 +353,7 @@ categoricals_done (struct categoricals *cat)
     }
 
   assert (cat->n_vars <= cat->n_vp);
+
 }