From 970789e054086189cb8d83b8c80f6c10318bbeef Mon Sep 17 00:00:00 2001 From: John Darrington Date: Sat, 14 Jan 2012 12:54:51 +0100 Subject: [PATCH] Categoricals cleanup: New structure 'payload' which reduces the number of arguments to categoricals_create --- src/language/stats/glm.c | 5 +-- src/language/stats/oneway.c | 27 +++++++----- src/math/categoricals.c | 85 +++++++++++++++++++++++++------------ src/math/categoricals.h | 34 +++++++++------ src/math/interaction.c | 4 +- 5 files changed, 100 insertions(+), 55 deletions(-) diff --git a/src/language/stats/glm.c b/src/language/stats/glm.c index 5df61c3e..f5ee149a 100644 --- a/src/language/stats/glm.c +++ b/src/language/stats/glm.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -590,8 +590,7 @@ run_glm (struct glm_spec *cmd, struct casereader *input, struct covariance *cov; ws.cats = categoricals_create (cmd->interactions, cmd->n_interactions, - cmd->wv, cmd->exclude, - NULL, NULL, NULL, NULL); + cmd->wv, cmd->exclude); cov = covariance_2pass_create (cmd->n_dep_vars, cmd->dep_vars, ws.cats, cmd->wv, cmd->exclude); diff --git a/src/language/stats/oneway.c b/src/language/stats/oneway.c index 199d6252..480bbb91 100644 --- a/src/language/stats/oneway.c +++ b/src/language/stats/oneway.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -575,7 +575,7 @@ dd_destroy (struct descriptive_data *dd) } static void * -makeit (void *aux1, void *aux2 UNUSED) +makeit (const void *aux1, void *aux2 UNUSED) { const struct variable *var = aux1; @@ -585,12 +585,9 @@ makeit (void *aux1, void *aux2 UNUSED) } static void -updateit (void *user_data, - enum mv_class exclude, - const struct variable *wv, - const struct variable *catvar UNUSED, - const struct ccase *c, - void *aux1, void *aux2) +updateit (const void *aux1, void *aux2, void *user_data, + const struct ccase *c, enum mv_class exclude, + const struct variable *wv) { struct descriptive_data *dd = user_data; @@ -653,10 +650,18 @@ run_oneway (const struct oneway_spec *cmd, for (v = 0; v < cmd->n_vars; ++v) { struct interaction *inter = interaction_create (cmd->indep_var); + + struct payload payload; + payload.create = makeit; + payload.update = updateit; + ws.vws[v].cat = categoricals_create (&inter, 1, cmd->wv, - cmd->exclude, makeit, updateit, - CONST_CAST (struct variable *, cmd->vars[v]), - ws.dd_total[v]); + cmd->exclude); + + categoricals_set_payload (ws.vws[v].cat, &payload, + CONST_CAST (struct variable *, cmd->vars[v]), + ws.dd_total[v]); + ws.vws[v].cov = covariance_2pass_create (1, &cmd->vars[v], ws.vws[v].cat, diff --git a/src/math/categoricals.c b/src/math/categoricals.c index d8606031..b78fe9bf 100644 --- a/src/math/categoricals.c +++ b/src/math/categoricals.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -178,15 +178,10 @@ struct categoricals /* Missing values to be excluded */ enum mv_class exclude; - /* Function to be called on each update */ - update_func *update; - - /* Function specified by the caller to create user_data */ - user_data_create_func *user_data_create; - - /* Auxilliary data to be passed to update and user_data_create_func*/ - void *aux1; + const void *aux1; void *aux2; + + const struct payload *payload; }; #if 0 @@ -262,6 +257,10 @@ 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 case_unref (iv->ccase); } @@ -305,10 +304,7 @@ lookup_case (const struct hmap *map, const struct interaction *iact, const struc struct categoricals * categoricals_create (struct interaction *const*inter, size_t n_inter, - const struct variable *wv, enum mv_class exclude, - user_data_create_func *udf, - update_func *update, void *aux1, void *aux2 - ) + const struct variable *wv, enum mv_class exclude) { size_t i; struct categoricals *cat = xmalloc (sizeof *cat); @@ -321,11 +317,8 @@ categoricals_create (struct interaction *const*inter, size_t n_inter, cat->reverse_variable_map_long = NULL; cat->pool = pool_create (); cat->exclude = exclude; - cat->update = update; - cat->user_data_create = udf; - - cat->aux1 = aux1; - cat->aux2 = aux2; + cat->payload = NULL; + cat->aux2 = NULL; cat->iap = pool_calloc (cat->pool, cat->n_iap, sizeof *cat->iap); @@ -391,11 +384,14 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) { const struct interaction *iact = cat->iap[i].iact; - // if ( interaction_case_is_missing (iact, c, cat->exclude)) - // continue; + size_t hash; + struct interaction_value *node; + + if ( interaction_case_is_missing (iact, c, cat->exclude)) + continue; - size_t hash = interaction_case_hash (iact, c, 0); - struct interaction_value *node = lookup_case (&cat->iap[i].ivmap, iact, c); + hash = interaction_case_hash (iact, c, 0); + node = lookup_case (&cat->iap[i].ivmap, iact, c); if ( NULL == node) { @@ -406,8 +402,10 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) hmap_insert (&cat->iap[i].ivmap, &node->node, hash); - if (cat->user_data_create) - node->user_data = cat->user_data_create (cat->aux1, cat->aux2); + if (cat->payload) + { + node->user_data = cat->payload->create (cat->aux1, cat->aux2); + } } else { @@ -415,8 +413,9 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) } cat->iap[i].cc += weight; - if (cat->update) - cat->update (node->user_data, cat->exclude, cat->wv, NULL, c, cat->aux1, cat->aux2); + if (cat->payload) + cat->payload->update (cat->aux1, cat->aux2, node->user_data, c, cat->exclude, cat->wv); + } } @@ -689,6 +688,30 @@ categoricals_get_n_variables (const struct categoricals *cat) return cat->n_vars; } + +/* Return a case containing the set of values corresponding to + the Nth Category of the IACTth interaction */ +const struct ccase * +categoricals_get_case_by_category_real (const struct categoricals *cat, int iact, int n) +{ + const struct interact_params *vp = &cat->iap[iact]; + const struct interaction_value *vn = vp->reverse_interaction_value_map [n]; + + return vn->ccase; +} + +/* Return a the user data corresponding to the Nth Category of the IACTth interaction. */ +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]; + + return iv->user_data; +} + + + /* Return a case containing the set of values corresponding to SUBSCRIPT */ const struct ccase * categoricals_get_case_by_category (const struct categoricals *cat, int subscript) @@ -711,5 +734,13 @@ categoricals_get_user_data_by_category (const struct categoricals *cat, int subs } + - +void +categoricals_set_payload (struct categoricals *cat, const struct payload *p, + const void *aux1, void *aux2) +{ + cat->payload = p; + cat->aux1 = aux1; + cat->aux2 = aux2; +} diff --git a/src/math/categoricals.h b/src/math/categoricals.h index 2ea47d51..4826227e 100644 --- a/src/math/categoricals.h +++ b/src/math/categoricals.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,19 +28,8 @@ struct interaction; union value ; -typedef void update_func (void *user_data, - enum mv_class exclude, - const struct variable *wv, - const struct variable *catvar, - const struct ccase *c, - void *aux1, void *aux2); - -typedef void *user_data_create_func (void *aux1, void *aux2); - struct categoricals *categoricals_create (struct interaction *const *, size_t n_int, - const struct variable *wv, enum mv_class exclude, - user_data_create_func *udf, - update_func *update, void *aux1, void *aux2); + const struct variable *wv, enum mv_class exclude); void categoricals_destroy (struct categoricals *); @@ -99,9 +88,28 @@ double categoricals_get_code_for_case (const struct categoricals *cat, int subsc /* Return the value corresponding to the N'th category */ const union value * categoricals_get_value_by_category (const struct categoricals *cat, int n); +const struct ccase * +categoricals_get_case_by_category_real (const struct categoricals *cat, int iact, int n); + +void * +categoricals_get_user_data_by_category_real (const struct categoricals *cat, int iact, int n); + + void * categoricals_get_user_data_by_category (const struct categoricals *cat, int category); const struct ccase * categoricals_get_case_by_category (const struct categoricals *cat, int subscript); +struct payload +{ + void* (*create) (const void *aux1, void *aux2); + void (*update) (const void *aux1, void *aux2, void *user_data, + const struct ccase *, enum mv_class, const struct variable *wv); + void (*destroy) (const void *aux1, void *aux2, void *user_data); +}; + + +void categoricals_set_payload (struct categoricals *cats, const struct payload *p, const void *aux1, void *aux2); + + #endif diff --git a/src/math/interaction.c b/src/math/interaction.c index 4e4134f0..70609247 100644 --- a/src/math/interaction.c +++ b/src/math/interaction.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2011 Free Software Foundation, Inc. + Copyright (C) 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -163,6 +163,8 @@ void interaction_to_string (const struct interaction *iact, struct string *str) { int v = 0; + if ( iact->n_vars == 0) + return; ds_put_cstr (str, var_to_string (iact->vars[v])); for (v = 1; v < iact->n_vars; ++v) { -- 2.30.2