1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2011, 2012 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "data/case.h"
20 #include "interaction.h"
22 #include "data/value.h"
23 #include "data/variable.h"
24 #include "libpspp/str.h"
26 #include "gl/xalloc.h"
32 An interaction is a structure containing a "product" of other
33 variables. The variables can be either string or numeric.
35 Interaction is commutative. That means, that from a mathematical point of
36 view, the order of the variables is irrelevant. However, for display
37 purposes, and for matching with an interaction's value the order is
40 Therefore, when using these functions, make sure the orders of variables
41 and values match when appropriate.
46 interaction_create (const struct variable *v)
48 struct interaction *i = xmalloc (sizeof *i);
49 i->vars = xmalloc (sizeof *i->vars);
59 /* Deep copy an interaction */
61 interaction_clone (const struct interaction *iact)
64 struct interaction *i = xmalloc (sizeof *i);
65 i->vars = xcalloc (iact->n_vars, sizeof *i->vars);
66 i->n_vars = iact->n_vars;
68 for (v = 0; v < iact->n_vars; ++v)
70 i->vars[v] = iact->vars[v];
78 interaction_destroy (struct interaction *i)
88 interaction_add_variable (struct interaction *i, const struct variable *v)
90 i->vars = xrealloc (i->vars, sizeof (*i->vars) * ++i->n_vars);
91 i->vars[i->n_vars - 1] = v;
96 Do the variables in X->VARS constitute a proper
97 subset of the variables in Y->VARS?
100 interaction_is_proper_subset (const struct interaction *x, const struct interaction *y)
102 if (x->n_vars >= y->n_vars)
105 return interaction_is_subset (x, y);
109 Do the variables in X->VARS constitute a
110 subset (proper or otherwise) of the variables in Y->VARS?
113 interaction_is_subset (const struct interaction *x, const struct interaction *y)
119 /* By definition, a subset cannot have more members than its superset */
120 if (x->n_vars > y->n_vars)
123 /* Count the number of values which are members of both sets */
124 for (i = 0; i < x->n_vars; i++)
126 for (j = 0; j < y->n_vars; j++)
128 if (x->vars [i] == y->vars [j])
135 /* If ALL the members of X were also found in Y, then this must be a subset */
146 interaction_dump (const struct interaction *i)
151 printf ("(empty)\n");
154 printf ("%s", var_get_name (i->vars[v]));
155 for (v = 1; v < i->n_vars; ++v)
156 printf (" * %s", var_get_name (i->vars[v]));
160 /* Appends STR with a representation of the interaction, suitable for user
163 STR must have been initialised prior to calling this function.
166 interaction_to_string (const struct interaction *iact, struct string *str)
169 if ( iact->n_vars == 0)
171 ds_put_cstr (str, var_to_string (iact->vars[v]));
172 for (v = 1; v < iact->n_vars; ++v)
174 ds_put_cstr (str, " * ");
175 ds_put_cstr (str, var_to_string (iact->vars[v]));
180 interaction_case_hash (const struct interaction *iact, const struct ccase *c, unsigned int base)
184 for (i = 0; i < iact->n_vars; ++i)
186 const struct variable *var = iact->vars[i];
187 const union value *val = case_data (c, var);
188 hash = value_hash (val, var_get_width (var), hash);
194 interaction_case_equal (const struct interaction *iact, const struct ccase *c1, const struct ccase *c2)
199 for (i = 0; i < iact->n_vars; ++i)
201 const struct variable *var = iact->vars[i];
202 if ( ! value_equal (case_data (c1, var), case_data (c2, var), var_get_width (var)))
214 interaction_case_cmp_3way (const struct interaction *iact, const struct ccase *c1, const struct ccase *c2)
219 for (i = 0; i < iact->n_vars; ++i)
221 const struct variable *var = iact->vars[i];
222 result = value_compare_3way (case_data (c1, var), case_data (c2, var), var_get_width (var));
232 interaction_case_is_missing (const struct interaction *iact, const struct ccase *c, enum mv_class exclude)
235 bool missing = false;
237 for (i = 0; i < iact->n_vars; ++i)
239 if ( var_is_value_missing (iact->vars[i], case_data (c, iact->vars[i]), exclude))