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/case-ordering.h>
27 #include <data/dictionary.h>
28 #include <data/variable.h>
32 /* One key used for sorting. */
35 const struct variable *var; /* Variable. */
36 enum sort_direction dir; /* Sort direction. */
39 /* A set of criteria for ordering cases. */
42 size_t value_cnt; /* Number of `union value's per case. */
45 struct sort_key *keys;
49 /* Creates and returns a new case ordering for comparing cases
50 that represent dictionary DICT. The case ordering initially
51 contains no variables, so that all cases will compare as
53 struct case_ordering *
54 case_ordering_create (const struct dictionary *dict)
56 struct case_ordering *co = xmalloc (sizeof *co);
57 co->value_cnt = dict_get_next_value_idx (dict);
63 /* Creates and returns a clone of case ordering ORIG. */
64 struct case_ordering *
65 case_ordering_clone (const struct case_ordering *orig)
67 struct case_ordering *co = xmalloc (sizeof *co);
68 co->value_cnt = orig->value_cnt;
69 co->keys = xmemdup (orig->keys, orig->key_cnt * sizeof *orig->keys);
70 co->key_cnt = orig->key_cnt;
74 /* Destroys case ordering CO. */
76 case_ordering_destroy (struct case_ordering *co)
85 /* Returns the number of `union value's in the cases that case
86 ordering CO compares (taken from the dictionary used to
89 case_ordering_get_value_cnt (const struct case_ordering *co)
94 /* Compares cases A and B given case ordering CO and returns a
95 strcmp()-type result. */
97 case_ordering_compare_cases (const struct ccase *a, const struct ccase *b,
98 const struct case_ordering *co)
102 for (i = 0; i < co->key_cnt; i++)
104 const struct sort_key *key = &co->keys[i];
105 int width = var_get_width (key->var);
110 double af = case_num (a, key->var);
111 double bf = case_num (b, key->var);
114 cmp = af > bf ? 1 : -1;
118 const char *as = case_str (a, key->var);
119 const char *bs = case_str (b, key->var);
120 cmp = memcmp (as, bs, width);
125 return key->dir == SRT_ASCEND ? cmp : -cmp;
130 /* Adds VAR to case ordering CO as an additional sort key in sort
131 direction DIR. Returns true if successful, false if VAR was
132 already part of the ordering for CO. */
134 case_ordering_add_var (struct case_ordering *co,
135 const struct variable *var, enum sort_direction dir)
137 struct sort_key *key;
140 for (i = 0; i < co->key_cnt; i++)
141 if (var_get_case_index (co->keys[i].var) == var_get_case_index (var))
144 co->keys = xnrealloc (co->keys, co->key_cnt + 1, sizeof *co->keys);
145 key = &co->keys[co->key_cnt++];
151 /* Returns the number of variables used for ordering within
154 case_ordering_get_var_cnt (const struct case_ordering *co)
159 /* Returns sort variable IDX within CO. An IDX of 0 returns the
160 primary sort key (the one added first), an IDX of 1 returns
161 the secondary sort key, and so on. IDX must be less than the
162 number of sort variables. */
163 const struct variable *
164 case_ordering_get_var (const struct case_ordering *co, size_t idx)
166 assert (idx < co->key_cnt);
167 return co->keys[idx].var;
170 /* Returns the sort direction for sort variable IDX within CO. */
172 case_ordering_get_direction (const struct case_ordering *co, size_t idx)
174 assert (idx < co->key_cnt);
175 return co->keys[idx].dir;
178 /* Stores an array listing all of the variables used for sorting
179 within CO into *VARS and the number of variables into
180 *VAR_CNT. The caller is responsible for freeing *VARS when it
181 is no longer needed. */
183 case_ordering_get_vars (const struct case_ordering *co,
184 const struct variable ***vars, size_t *var_cnt)
188 *var_cnt = co->key_cnt;
189 *vars = xnmalloc (*var_cnt, sizeof **vars);
190 for (i = 0; i < co->key_cnt; i++)
191 (*vars)[i] = co->keys[i].var;