+ return cat->n_cats_total;
+}
+
+
+/* This function must be called *before* any call to categoricals_get_*_by subscript an
+ *after* all calls to categoricals_update */
+void
+categoricals_done (struct categoricals *cat)
+{
+ /* Implementation Note: Whilst this function is O(n) in cat->n_cats_total, in most
+ uses it will be more efficient that using a tree based structure, since it
+ is called only once, and means that subsequent lookups will be O(1).
+
+ 1 call of O(n) + 10^9 calls of O(1) is better than 10^9 calls of O(log n).
+ */
+ int v;
+ int idx = 0;
+ cat->reverse_variable_map = pool_calloc (cat->pool, sizeof *cat->reverse_variable_map, cat->n_cats_total);
+
+ for (v = 0 ; v < cat->n_vars; ++v)
+ {
+ int i;
+ struct var_params *vp = &cat->vp[v];
+ int n_cats_total = categoricals_n_count (cat, v);
+ struct hmap_node *node ;
+
+ vp->reverse_value_map = pool_calloc (cat->pool, sizeof *vp->reverse_value_map, n_cats_total);
+
+ vp->base_subscript = idx;
+
+ for (node = hmap_first (&vp->map); node; node = hmap_next (&vp->map, node))
+ {
+ const struct value_node *vn = HMAP_DATA (node, struct value_node, node);
+ vp->reverse_value_map[vn->subscript] = vn;
+ }
+
+ for (i = 0; i < vp->n_cats; ++i)
+ cat->reverse_variable_map[idx++] = v;
+ }
+}
+
+
+
+/* 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];
+
+ return cat->vars[index];