Categoricals cleanup: New structure 'payload' which reduces the
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 14 Jan 2012 11:54:51 +0000 (12:54 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 14 Jan 2012 11:54:51 +0000 (12:54 +0100)
number of arguments to categoricals_create

src/language/stats/glm.c
src/language/stats/oneway.c
src/math/categoricals.c
src/math/categoricals.h
src/math/interaction.c

index 5df61c3e0e7b2721f010a1b597e56441a452e0bf..f5ee149af017627a4b03a51a5c2d1d061c3d774f 100644 (file)
@@ -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);
index 199d6252c55fa024f90275f81c219affb3dd10b5..480bbb91379be3dd162c239b03b941b0b5e30ff7 100644 (file)
@@ -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, 
index d8606031c943b0925a1edc953e454693a9d8de8c..b78fe9bf68e66dd89e03de3dc128599f8c2a2414 100644 (file)
@@ -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
 }
 
 
+\f
 
-
+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;
+}
index 2ea47d516a770bb7115df2ddca987f0e14abc99d..4826227ea34a8ff49d26b9bbe6d71606de529868 100644 (file)
@@ -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
index 4e4134f0ffcceb0b1ac79b5a8e0b583a3924be41..706092476ec2b3bb8f3f391de37338ffe2ccdbed 100644 (file)
@@ -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)
     {