X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fcategoricals.c;h=d8606031c943b0925a1edc953e454693a9d8de8c;hb=refs%2Fbuilds%2F20111223030502%2Fpspp;hp=fbc23ab0f6191c4fcde9895220341a41e30d69d4;hpb=4fd6cfba4b3c066da520d4b1c7a7f64d9fd19d3f;p=pspp diff --git a/src/math/categoricals.c b/src/math/categoricals.c index fbc23ab0f6..d8606031c9 100644 --- a/src/math/categoricals.c +++ b/src/math/categoricals.c @@ -32,7 +32,7 @@ #include "gl/xalloc.h" -#define EFFECTS_CODING 0 +#define EFFECTS_CODING 1 struct value_node { @@ -264,6 +264,9 @@ categoricals_destroy (struct categoricals *cat) { case_unref (iv->ccase); } + + free (cat->iap[i].enc_sum); + free (cat->iap[i].df_prod); hmap_destroy (&cat->iap[i].ivmap); } @@ -437,7 +440,8 @@ categoricals_df (const struct categoricals *cat, size_t n) size_t categoricals_n_total (const struct categoricals *cat) { - assert (cat->reverse_variable_map_long); + if (!categoricals_is_complete (cat)) + return 0; return cat->n_cats_total; } @@ -448,9 +452,16 @@ categoricals_df_total (const struct categoricals *cat) return cat->df_sum; } +bool +categoricals_is_complete (const struct categoricals *cat) +{ + return (NULL != cat->reverse_variable_map_short); +} + + /* This function must be called *before* any call to categoricals_get_*_by subscript and *after* all calls to categoricals_update */ -void +bool categoricals_done (const struct categoricals *cat_) { /* Implementation Note: Whilst this function is O(n) in cat->n_cats_total, in most @@ -483,6 +494,9 @@ 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->iap[i].df_prod[v] = df * (hmap_count (&vn->valmap) - 1); df = cat->iap[i].df_prod[v]; @@ -558,11 +572,13 @@ categoricals_done (const struct categoricals *cat_) struct interaction_value *iv = iap->reverse_interaction_value_map[y]; for (x = iap->base_subscript_short; x < iap->base_subscript_short + df ;++x) { - const double bin = categoricals_get_binary_by_subscript (cat, x, iv->ccase); \ + const double bin = categoricals_get_code_for_case (cat, x, iv->ccase); \ iap->enc_sum [x - iap->base_subscript_short] += bin * iv->cc; } } } + + return true; } @@ -596,21 +612,6 @@ categoricals_get_interaction_by_subscript (const struct categoricals *cat, int s return cat->iap[index].iact; } -/* Return the case corresponding to SUBSCRIPT */ -static const struct ccase * -categoricals_get_case_by_subscript (const struct categoricals *cat, int subscript) -{ - int vindex = reverse_variable_lookup_short (cat, subscript); - const struct interact_params *vp = &cat->iap[vindex]; - const struct interaction_value *vn = vp->reverse_interaction_value_map [subscript - vp->base_subscript_short]; - - if ( vn == NULL) - return NULL; - - return vn->ccase; -} - - double categoricals_get_weight_by_subscript (const struct categoricals *cat, int subscript) { @@ -632,8 +633,7 @@ categoricals_get_sum_by_subscript (const struct categoricals *cat, int subscript /* Returns unity if the value in case C at SUBSCRIPT is equal to the category for that subscript */ double -categoricals_get_binary_by_subscript (const struct categoricals *cat, - int subscript, +categoricals_get_code_for_case (const struct categoricals *cat, int subscript, const struct ccase *c) { const struct interaction *iact = categoricals_get_interaction_by_subscript (cat, subscript); @@ -647,6 +647,7 @@ categoricals_get_binary_by_subscript (const struct categoricals *cat, const struct interact_params *iap = &cat->iap[i]; + double dfp = 1.0; for (v = 0; v < iact->n_vars; ++v) { const struct variable *var = iact->vars[v]; @@ -660,13 +661,14 @@ categoricals_get_binary_by_subscript (const struct categoricals *cat, double bin = 1.0; + const double df = iap->df_prod[v] / dfp; + /* Translate the subscript into an index for the individual variable */ - int index = (subscript - base_index) % iap->df_prod[v]; - if ( v > 0) - index /= iap->df_prod[v - 1]; + const int index = ((subscript - base_index) % iap->df_prod[v] ) / dfp; + dfp = iap->df_prod [v]; #if EFFECTS_CODING - if ( valn->index == 0) + if ( valn->index == df ) bin = -1.0; else #endif