struct hmap_node node; /* In struct categorical's 'varmap'. */
const struct variable *var; /* The variable. */
struct hmap valmap; /* Contains "struct value_node"s. */
+ union value *values; /* Values in valmap, as a sorted array. */
};
static int
}
static struct variable_node *
-lookup_variable (const struct hmap *map, const struct variable *var, unsigned int hash)
+lookup_variable (const struct hmap *map, const struct variable *var)
{
struct variable_node *vn;
- HMAP_FOR_EACH_WITH_HASH (vn, struct variable_node, node, hash, map)
+ HMAP_FOR_EACH_WITH_HASH (vn, struct variable_node, node,
+ hash_pointer (var, 0), map)
if (vn->var == var)
return vn;
return NULL;
free (cat->iap[i].enc_sum);
hmap_destroy (&cat->iap[i].ivmap);
}
+ free (cat->iap);
/* Interate over each variable and delete its value map.
categoricals_create (struct interaction *const *inter, size_t n_inter,
const struct variable *wv, enum mv_class fctr_excl)
{
- struct categoricals *cat = xzalloc (sizeof *cat);
+ struct categoricals *cat = XZALLOC (struct categoricals);
cat->iap = pool_calloc (cat->pool, n_inter, sizeof *cat->iap);
cat->n_iap = n_inter;
cat->wv = wv;
for (size_t v = 0; v < inter[i]->n_vars; ++v)
{
const struct variable *var = inter[i]->vars[v];
- unsigned int hash = hash_pointer (var, 0);
- struct variable_node *vn = lookup_variable (&cat->varmap, var, hash);
+ struct variable_node *vn = lookup_variable (&cat->varmap, var);
if (!vn)
{
vn = pool_malloc (cat->pool, sizeof *vn);
vn->var = var;
+ vn->values = NULL;
hmap_init (&vn->valmap);
- hmap_insert (&cat->varmap, &vn->node, hash);
+ hmap_insert (&cat->varmap, &vn->node, hash_pointer (var, 0));
}
iap->varnodes[v] = vn;
}
assert (!cat->cat_to_iact);
double weight;
- weight = cat->wv ? case_data (c, cat->wv)->f : 1.0;
+ weight = cat->wv ? case_num (c, cat->wv) : 1.0;
weight = var_force_valid_weight (cat->wv, weight, NULL);
/* Update the frequency table for each variable. */
{
valn = pool_malloc (cat->pool, sizeof *valn);
valn->index = -1;
- value_init (&valn->val, width);
+ value_init_pool (cat->pool, &valn->val, width);
value_copy (&valn->val, val, width);
hmap_insert (&vn->valmap, &valn->node, hash);
}
return;
}
- struct value_node **nodes = xcalloc (sizeof *nodes, n_vals);
+ struct value_node **nodes = XCALLOC (n_vals, struct value_node *);
int x = 0;
struct value_node *valnd;
HMAP_FOR_EACH (valnd, struct value_node, node, &vn->valmap)
cat->sane = true;
}
+union value *
+categoricals_get_var_values (const struct categoricals *cat,
+ const struct variable *var, size_t *np)
+{
+ struct variable_node *vn = lookup_variable (&cat->varmap, var);
+ *np = hmap_count (&vn->valmap);
+ if (!vn->values)
+ {
+ vn->values = pool_nalloc (cat->pool, *np, sizeof *vn->values);
+
+ struct value_node *valnd;
+ HMAP_FOR_EACH (valnd, struct value_node, node, &vn->valmap)
+ vn->values[valnd->index] = valnd->val;
+ }
+ return vn->values;
+}
+
static struct interact_params *
df_to_iap (const struct categoricals *cat, int subscript)
{
return n < hmap_count (&iap->ivmap) ? iap->ivs[n]->user_data : NULL;
}
+int
+categoricals_get_value_index_by_category_real (const struct categoricals *cat,
+ int iact_idx, int cat_idx,
+ int var_idx)
+{
+ const struct interact_params *iap = &cat->iap[iact_idx];
+ const struct interaction_value *ivn = iap->ivs[cat_idx];
+ const struct variable *var = iap->iact->vars[var_idx];
+ const struct variable_node *vn = iap->varnodes[var_idx];
+ const union value *val = case_data (ivn->ccase, var);
+ int width = var_get_width (var);
+ unsigned int hash = value_hash (val, width, 0);
+ return lookup_value (&vn->valmap, val, hash, width)->index;
+}
+
/* Return a case containing the set of values corresponding to CAT_INDEX. */
const struct ccase *
categoricals_get_case_by_category (const struct categoricals *cat,