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"
30 /* Creates and returns an interaction. If V is nonnull, then the interaction
31 initially contains V, otherwise it is initially empty. */
33 interaction_create (const struct variable
*v
)
35 struct interaction
*iact
= xmalloc (sizeof *iact
);
36 iact
->vars
= xmalloc (sizeof *iact
->vars
);
46 /* Returns a (deep) copy of interaction SRC. */
48 interaction_clone (const struct interaction
*src
)
50 struct interaction
*dst
= xmalloc (sizeof *dst
);
51 dst
->vars
= xmemdup (src
->vars
, src
->n_vars
* sizeof *src
->vars
);
52 dst
->n_vars
= src
->n_vars
;
58 interaction_destroy (struct interaction
*iact
)
67 /* Appends variable V to IACT.
69 V must not already be in IACT. */
71 interaction_add_variable (struct interaction
*iact
, const struct variable
*v
)
73 iact
->vars
= xrealloc (iact
->vars
, (iact
->n_vars
+ 1) * sizeof *iact
->vars
);
74 iact
->vars
[iact
->n_vars
++] = v
;
77 /* Returns true iff the variables in X->VARS are a proper subset of the
78 variables in Y->VARS. */
80 interaction_is_proper_subset (const struct interaction
*x
,
81 const struct interaction
*y
)
83 return x
->n_vars
>= y
->n_vars
&& interaction_is_subset (x
, y
);
87 interaction_contains (const struct interaction
*iact
, const struct variable
*v
)
89 for (size_t i
= 0; i
< iact
->n_vars
; i
++)
90 if (iact
->vars
[i
] == v
)
95 /* Returns true iff the variables in X->VARS are a subset (proper or otherwise)
96 of the variables in Y->VARS. */
98 interaction_is_subset (const struct interaction
*x
,
99 const struct interaction
*y
)
101 if (x
->n_vars
> y
->n_vars
)
104 for (size_t i
= 0; i
< x
->n_vars
; i
++)
105 if (!interaction_contains (y
, x
->vars
[i
]))
111 /* Prints the variables in IACT on stdout, for debugging purposes. */
113 interaction_dump (const struct interaction
*iact
)
115 if (iact
->n_vars
== 0)
116 printf ("(empty)\n");
119 for (size_t v
= 0; v
< iact
->n_vars
; ++v
)
121 printf ("%s", var_get_name (iact
->vars
[v
]));
122 if (v
+ 1 < iact
->n_vars
)
129 /* Appends STR with a representation of the interaction, suitable for user
132 STR must have been initialised prior to calling this function. */
134 interaction_to_string (const struct interaction
*iact
, struct string
*str
)
136 for (size_t v
= 0; v
< iact
->n_vars
; ++v
)
138 ds_put_cstr (str
, var_to_string (iact
->vars
[v
]));
139 if (v
+ 1 < iact
->n_vars
)
140 ds_put_cstr (str
, " × ");
144 /* Returns a hash of the values in C given by variables in IACT, using BASE as
145 a basis for the hash. */
147 interaction_case_hash (const struct interaction
*iact
,
148 const struct ccase
*c
, unsigned int base
)
151 for (size_t i
= 0; i
< iact
->n_vars
; ++i
)
153 const struct variable
*var
= iact
->vars
[i
];
154 const union value
*val
= case_data (c
, var
);
155 hash
= value_hash (val
, var_get_width (var
), hash
);
160 /* Returns true iff all the variables in IACT have equal values in C1 and
163 interaction_case_equal (const struct interaction
*iact
,
164 const struct ccase
*c1
, const struct ccase
*c2
)
166 for (size_t i
= 0; i
< iact
->n_vars
; ++i
)
168 const struct variable
*var
= iact
->vars
[i
];
169 if (!value_equal (case_data (c1
, var
), case_data (c2
, var
),
170 var_get_width (var
)))
177 /* Returns a strcmp()-like comparison result for the variables in IACT and
178 their values in C1 and C2. */
180 interaction_case_cmp_3way (const struct interaction
*iact
,
181 const struct ccase
*c1
, const struct ccase
*c2
)
183 for (size_t i
= 0; i
< iact
->n_vars
; ++i
)
185 const struct variable
*var
= iact
->vars
[i
];
186 int cmp
= value_compare_3way (case_data (c1
, var
), case_data (c2
, var
),
187 var_get_width (var
));
195 /* Returns true iff any of the variables in IACT have a missing value in C,
196 using EXCLUDE to decide which kinds of missing values to count. */
198 interaction_case_is_missing (const struct interaction
*iact
,
199 const struct ccase
*c
, enum mv_class exclude
)
201 for (size_t i
= 0; i
< iact
->n_vars
; ++i
)
202 if (var_is_value_missing (iact
->vars
[i
], case_data (c
, iact
->vars
[i
]))