X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fcategoricals.c;h=83326c3f006789814c4930feed8d85d15db95155;hb=7b7d1e6fbf05cf190814b1f64d8ee363203d7499;hp=92bb3d1d3270bfa4878ed2498d72fce799c6c2d6;hpb=e3fd4bdef26f6d5442dfce636965e721c7a6e349;p=pspp diff --git a/src/math/categoricals.c b/src/math/categoricals.c index 92bb3d1d32..83326c3f00 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. @@ -320,7 +323,7 @@ struct categoricals * 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; @@ -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; } @@ -364,7 +367,7 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) 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. */ @@ -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,