X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fcategoricals.c;h=4e6d8dad7ad942c633c7dc79820b93bc43d01ea6;hb=74709d3f6d7c102bb3226f7f132c8be78ce8e8c2;hp=92bb3d1d3270bfa4878ed2498d72fce799c6c2d6;hpb=e3fd4bdef26f6d5442dfce636965e721c7a6e349;p=pspp diff --git a/src/math/categoricals.c b/src/math/categoricals.c index 92bb3d1d32..4e6d8dad7a 100644 --- a/src/math/categoricals.c +++ b/src/math/categoricals.c @@ -59,6 +59,7 @@ struct variable_node 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 @@ -74,10 +75,11 @@ compare_value_node_3way (const void *vn1_, const void *vn2_, const void *aux) } 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; @@ -274,6 +276,7 @@ categoricals_destroy (struct categoricals *cat) free (cat->iap[i].enc_sum); hmap_destroy (&cat->iap[i].ivmap); } + free (cat->iap); /* Interate over each variable and delete its value map. @@ -339,14 +342,14 @@ categoricals_create (struct interaction *const *inter, size_t n_inter, 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; } @@ -380,7 +383,7 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) { 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); } @@ -477,7 +480,7 @@ categoricals_done (const struct categoricals *cat_) 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) @@ -577,6 +580,23 @@ categoricals_done (const struct categoricals *cat_) 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) { @@ -704,6 +724,21 @@ categoricals_get_user_data_by_category_real (const struct categoricals *cat, 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,