Set categoricals to NULL in one-pass covariance; avoid freeing NULL in categoricals_d...
[pspp-builds.git] / src / math / categoricals.c
index b7e51751a5b8492fe1a5057d5b5c254577ecb879..33e3b51c62f99cc2290ce7918dbba6aedb111878 100644 (file)
@@ -91,11 +91,14 @@ void
 categoricals_destroy ( struct categoricals *cat)
 {
   int i;
-  for (i = 0 ; i < cat->n_vp; ++i)
-    hmap_destroy (&cat->vp[i].map);
-
-  pool_destroy (cat->pool);
-  free (cat);
+  if (cat != NULL)
+    {
+      for (i = 0 ; i < cat->n_vp; ++i)
+       hmap_destroy (&cat->vp[i].map);
+      
+      pool_destroy (cat->pool);
+      free (cat);
+    }
 }
 
 
@@ -145,6 +148,12 @@ categoricals_dump (const struct categoricals *cat)
   printf ("Number of categorical variables: %d\n", cat->n_vp);
   printf ("Number of non-empty categorical variables: %d\n", cat->n_vars);
   printf ("Total number of categories: %d\n", cat->n_cats_total);
+
+  printf ("\nReverse variable map:\n");
+
+  for (v = 0 ; v < cat->n_cats_total - cat->n_vars; ++v)
+    printf ("%d ", cat->reverse_variable_map[v]);
+  printf ("\n");
 }
 
 
@@ -271,7 +280,9 @@ categoricals_done (struct categoricals *cat)
   */
   int v;
   int idx = 0;
-  cat->reverse_variable_map = pool_calloc (cat->pool, cat->n_cats_total, sizeof *cat->reverse_variable_map);
+  cat->reverse_variable_map = pool_calloc (cat->pool,
+                                          cat->n_cats_total - cat->n_vars,
+                                          sizeof *cat->reverse_variable_map);
   
   for (v = 0 ; v < cat->n_vp; ++v)
     {
@@ -290,7 +301,10 @@ categoricals_done (struct categoricals *cat)
          vp->reverse_value_map[vn->subscript] = vn;
        }
 
-      for (i = 0; i < vp->n_cats; ++i)
+      /* Populate the reverse variable map.
+        This implementation considers the first value of each categorical variable
+        as the basis.  Therefore, this loop starts from 1 instead of 0 */
+      for (i = 1; i < vp->n_cats; ++i)
        cat->reverse_variable_map[idx++] = v;
     }
 
@@ -298,26 +312,31 @@ categoricals_done (struct categoricals *cat)
 }
 
 
+static int
+reverse_variable_lookup (const struct categoricals *cat, int subscript)
+{
+  assert (cat->reverse_variable_map);
+  assert (subscript >= 0);
+  assert (subscript < cat->n_cats_total - cat->n_vars);
+
+  return cat->reverse_variable_map[subscript];
+}
+
 
 /* Return the categorical variable corresponding to SUBSCRIPT */
 const struct variable *
 categoricals_get_variable_by_subscript (const struct categoricals *cat, int subscript)
 {
-  int index;
-
-  assert (cat->reverse_variable_map);
-  
-  index = cat->reverse_variable_map[subscript];
+  int index = reverse_variable_lookup (cat, subscript);
 
   return cat->vp[index].var;
 }
 
-
 /* Return the value corresponding to SUBSCRIPT */
 const union value *
 categoricals_get_value_by_subscript (const struct categoricals *cat, int subscript)
 {
-  int vindex = cat->reverse_variable_map[subscript];
+  int vindex = reverse_variable_lookup (cat, subscript);
   const struct var_params *vp = &cat->vp[vindex];
   const struct value_node *vn = vp->reverse_value_map [subscript - vp->base_subscript];
 
@@ -328,7 +347,7 @@ categoricals_get_value_by_subscript (const struct categoricals *cat, int subscri
 double
 categoricals_get_weight_by_subscript (const struct categoricals *cat, int subscript)
 {
-  int vindex = cat->reverse_variable_map[subscript];
+  int vindex = reverse_variable_lookup (cat, subscript);
   const struct var_params *vp = &cat->vp[vindex];
 
   return vp->cc;
@@ -337,7 +356,7 @@ categoricals_get_weight_by_subscript (const struct categoricals *cat, int subscr
 double
 categoricals_get_sum_by_subscript (const struct categoricals *cat, int subscript)
 {
-  int vindex = cat->reverse_variable_map[subscript];
+  int vindex = reverse_variable_lookup (cat, subscript);
   const struct var_params *vp = &cat->vp[vindex];
 
   const struct value_node *vn = vp->reverse_value_map [subscript - vp->base_subscript];