X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fcategoricals.c;h=b9748c759ed8f114969728743c84d3880ce033df;hb=7dfbf1beae10727cc07213b2c74a991859f9fcbc;hp=ea5b31060e7cb0946bc2d5b66738cbb2cdaead5f;hpb=10c30668020c8157685867e902f6554806ffcfc3;p=pspp diff --git a/src/math/categoricals.c b/src/math/categoricals.c index ea5b31060e..b9748c759e 100644 --- a/src/math/categoricals.c +++ b/src/math/categoricals.c @@ -78,18 +78,6 @@ struct variable_node int n_vals; /* Number of values for this variable */ }; -static void -dump_interaction (const struct interaction *iact) -{ - if (CATEGORICALS_DEBUG) - { - struct string str = DS_EMPTY_INITIALIZER; - interaction_to_string (iact, &str); - printf ("Interaction: %s\n", ds_cstr (&str)); - ds_destroy (&str); - } -} - static struct variable_node * lookup_variable (const struct hmap *map, const struct variable *var, unsigned int hash) { @@ -111,7 +99,7 @@ struct interact_params /* A map indexed by a interaction_value */ struct hmap ivmap; - const struct interaction *iact; + struct interaction *iact; int base_subscript_short; int base_subscript_long; @@ -177,12 +165,17 @@ struct categoricals struct pool *pool; - /* Missing values to be excluded */ - enum mv_class exclude; + /* Missing values in the dependent varirable to be excluded */ + enum mv_class dep_excl; + + /* Missing values in the factor variables to be excluded */ + enum mv_class fctr_excl; const void *aux1; void *aux2; + bool sane; + const struct payload *payload; }; @@ -260,16 +253,15 @@ categoricals_destroy (struct categoricals *cat) /* Interate over each interaction value, and unref any cases that we reffed */ HMAP_FOR_EACH (iv, struct interaction_value, node, &cat->iap[i].ivmap) { -#if 0 - if (cat->payload) - cat->payload->destroy (cat->aux1, iv->user_data); -#endif + if (cat->payload && cat->payload->destroy) + cat->payload->destroy (cat->aux1, cat->aux2, iv->user_data); case_unref (iv->ccase); } free (cat->iap[i].enc_sum); free (cat->iap[i].df_prod); hmap_destroy (&cat->iap[i].ivmap); + interaction_destroy (cat->iap[i].iact); } /* Interate over each variable and delete its value map */ @@ -304,10 +296,15 @@ lookup_case (const struct hmap *map, const struct interaction *iact, const struc return iv; } +bool +categoricals_sane (const struct categoricals *cat) +{ + return cat->sane; +} struct categoricals * categoricals_create (struct interaction *const*inter, size_t n_inter, - const struct variable *wv, enum mv_class exclude) + const struct variable *wv, enum mv_class dep_excl, enum mv_class fctr_excl) { size_t i; struct categoricals *cat = xmalloc (sizeof *cat); @@ -319,9 +316,11 @@ categoricals_create (struct interaction *const*inter, size_t n_inter, cat->reverse_variable_map_short = NULL; cat->reverse_variable_map_long = NULL; cat->pool = pool_create (); - cat->exclude = exclude; + cat->dep_excl = dep_excl; + cat->fctr_excl = fctr_excl; cat->payload = NULL; cat->aux2 = NULL; + cat->sane = false; cat->iap = pool_calloc (cat->pool, cat->n_iap, sizeof *cat->iap); @@ -390,7 +389,7 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) size_t hash; struct interaction_value *node; - if ( interaction_case_is_missing (iact, c, cat->exclude)) + if ( interaction_case_is_missing (iact, c, cat->fctr_excl)) continue; hash = interaction_case_hash (iact, c, 0); @@ -466,7 +465,7 @@ categoricals_is_complete (const struct categoricals *cat) /* This function must be called *before* any call to categoricals_get_*_by subscript and *after* all calls to categoricals_update */ -bool +void categoricals_done (const struct categoricals *cat_) { /* Implementation Note: Whilst this function is O(n) in cat->n_cats_total, in most @@ -500,7 +499,10 @@ categoricals_done (const struct categoricals *cat_) struct variable_node *vn = lookup_variable (&cat->varmap, var, hash_pointer (var, 0)); if (hmap_count (&vn->valmap) == 0) - return false; + { + cat->sane = false; + return; + } cat->iap[i].df_prod[v] = df * (hmap_count (&vn->valmap) - 1); df = cat->iap[i].df_prod[v]; @@ -540,6 +542,7 @@ categoricals_done (const struct categoricals *cat_) HMAP_FOR_EACH (ivn, struct interaction_value, node, &iap->ivmap) { iap->reverse_interaction_value_map[x++] = ivn; + } assert (x <= iap->n_cats); @@ -565,7 +568,7 @@ categoricals_done (const struct categoricals *cat_) assert (cat->n_vars <= cat->n_iap); - // categoricals_dump (cat); + categoricals_dump (cat); /* Tally up the sums for all the encodings */ for (i = 0 ; i < cat->n_iap; ++i) @@ -586,10 +589,12 @@ categoricals_done (const struct categoricals *cat_) const double bin = categoricals_get_code_for_case (cat, x, iv->ccase); \ iap->enc_sum [x - iap->base_subscript_short] += bin * iv->cc; } + if (cat->payload && cat->payload->calculate) + cat->payload->calculate (cat->aux1, cat->aux2, iv->user_data); } } - return true; + cat->sane = true; } @@ -706,8 +711,14 @@ categoricals_get_n_variables (const struct categoricals *cat) const struct ccase * categoricals_get_case_by_category_real (const struct categoricals *cat, int iact, int n) { + const struct interaction_value *vn; + const struct interact_params *vp = &cat->iap[iact]; - const struct interaction_value *vn = vp->reverse_interaction_value_map [n]; + + if ( n >= hmap_count (&vp->ivmap)) + return NULL; + + vn = vp->reverse_interaction_value_map [n]; return vn->ccase; } @@ -717,7 +728,12 @@ void * categoricals_get_user_data_by_category_real (const struct categoricals *cat, int iact, int n) { const struct interact_params *vp = &cat->iap[iact]; - const struct interaction_value *iv = vp->reverse_interaction_value_map [n]; + const struct interaction_value *iv ; + + if ( n >= hmap_count (&vp->ivmap)) + return NULL; + + iv = vp->reverse_interaction_value_map [n]; return iv->user_data; }