1 /* PSPP - computes sample statistics.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 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, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <data/caseinit.h>
27 #include <data/case.h>
28 #include <data/dictionary.h>
29 #include <data/value.h>
30 #include <data/variable.h>
31 #include <libpspp/array.h>
32 #include <libpspp/assertion.h>
33 #include <libpspp/compiler.h>
45 struct init_value *values;
56 init_list_create (struct init_list *list)
63 init_list_clear (struct init_list *list)
66 init_list_create (list);
70 init_list_destroy (struct init_list *list)
72 init_list_clear (list);
76 compare_init_values (const void *a_, const void *b_, const void *aux UNUSED)
78 const struct init_value *a = a_;
79 const struct init_value *b = b_;
81 return a->case_index < b->case_index ? -1 : a->case_index > b->case_index;
85 init_list_includes (const struct init_list *list, size_t case_index)
87 struct init_value value;
88 value.case_index = case_index;
89 return binary_search (list->values, list->cnt, sizeof *list->values,
90 &value, compare_init_values, NULL) != NULL;
94 init_list_mark (struct init_list *list, const struct init_list *exclude,
95 enum leave_class include, const struct dictionary *d)
97 size_t var_cnt = dict_get_var_cnt (d);
100 assert (list != exclude);
101 list->values = xnrealloc (list->values,
102 list->cnt + dict_get_next_value_idx (d),
103 sizeof *list->values);
104 for (i = 0; i < var_cnt; i++)
106 struct variable *v = dict_get_var (d, i);
107 size_t case_index = var_get_case_index (v);
110 /* Only include the correct class. */
111 if (!(include & (var_get_leave (v) ? LEAVE_LEFT : LEAVE_REINIT)))
114 /* Don't include those to be excluded. */
115 if (exclude != NULL && init_list_includes (exclude, case_index))
121 struct init_value *iv = &list->values[list->cnt++];
122 iv->case_index = case_index++;
123 if (var_is_numeric (v))
124 iv->value.f = var_get_leave (v) ? 0 : SYSMIS;
126 memset (iv->value.s, ' ', sizeof iv->value.s);
128 offset += sizeof iv->value.s;
130 while (offset < var_get_width (v));
133 /* Drop duplicates. */
134 list->cnt = sort_unique (list->values, list->cnt, sizeof *list->values,
135 compare_init_values, NULL);
140 init_list_init (const struct init_list *list, struct ccase *c)
144 for (i = 0; i < list->cnt; i++)
146 const struct init_value *value = &list->values[i];
147 *case_data_rw_idx (c, value->case_index) = value->value;
152 init_list_update (const struct init_list *list, const struct ccase *c)
156 for (i = 0; i < list->cnt; i++)
158 struct init_value *value = &list->values[i];
159 value->value = *case_data_idx (c, value->case_index);
165 struct init_list preinited_values;
166 struct init_list reinit_values;
167 struct init_list left_values;
171 caseinit_create (void)
173 struct caseinit *ci = xmalloc (sizeof *ci);
174 init_list_create (&ci->preinited_values);
175 init_list_create (&ci->reinit_values);
176 init_list_create (&ci->left_values);
181 caseinit_clear (struct caseinit *ci)
183 init_list_clear (&ci->preinited_values);
184 init_list_clear (&ci->reinit_values);
185 init_list_clear (&ci->left_values);
189 caseinit_destroy (struct caseinit *ci)
193 init_list_destroy (&ci->preinited_values);
194 init_list_destroy (&ci->reinit_values);
195 init_list_destroy (&ci->left_values);
201 caseinit_mark_as_preinited (struct caseinit *ci, const struct dictionary *d)
203 init_list_mark (&ci->preinited_values, NULL, LEAVE_REINIT | LEAVE_LEFT, d);
207 caseinit_mark_for_init (struct caseinit *ci, const struct dictionary *d)
209 init_list_mark (&ci->reinit_values, &ci->preinited_values, LEAVE_REINIT, d);
210 init_list_mark (&ci->left_values, &ci->preinited_values, LEAVE_LEFT, d);
214 caseinit_init_reinit_vars (const struct caseinit *ci, struct ccase *c)
216 init_list_init (&ci->reinit_values, c);
219 void caseinit_init_left_vars (const struct caseinit *ci, struct ccase *c)
221 init_list_init (&ci->left_values, c);
225 caseinit_update_left_vars (struct caseinit *ci, const struct ccase *c)
227 init_list_update (&ci->left_values, c);