#include "data/variable.h"
#include "libpspp/assertion.h"
#include "libpspp/hmap.h"
+#include "libpspp/bt.h"
#include "libpspp/message.h"
#include "libpspp/misc.h"
#include "math/sort.h"
struct rank_entry
{
struct hmap_node node;
+ struct bt_node btn;
union value group;
double sum_of_ranks;
double n;
};
+
+static int
+compare_rank_entries_3way (const struct bt_node *a,
+ const struct bt_node *b,
+ const void *aux)
+{
+ const struct variable *var = aux;
+ const struct rank_entry *rea = bt_data (a, struct rank_entry, btn);
+ const struct rank_entry *reb = bt_data (b, struct rank_entry, btn);
+
+ return value_compare_3way (&rea->group, &reb->group, var_get_width (var));
+}
+
+
/* Return the entry with the key GROUP or null if there is no such entry */
static struct rank_entry *
find_rank_entry (const struct hmap *map, const union value *group, size_t width)
if (0 == value_compare_3way (group, &re->group, width))
return re;
}
-
+
return re;
}
struct kw *kw = xcalloc (nst->n_vars, sizeof *kw);
/* If the independent variable is missing, then we ignore the case */
- input = casereader_create_filter_missing (input,
+ input = casereader_create_filter_missing (input,
&nst->indep_var, 1,
exclude,
NULL, NULL);
input = casereader_create_filter_weight (input, dict, &warn, NULL);
/* Remove all those cases which are outside the range (val1, val2) */
- input = casereader_create_filter_func (input, include_func, NULL,
+ input = casereader_create_filter_func (input, include_func, NULL,
CONST_CAST (struct n_sample_test *, nst), NULL);
proto = casereader_get_proto (input);
exclude,
NULL, NULL);
- rr = casereader_create_append_rank (r,
+ rr = casereader_create_append_rank (r,
nst->vars[i],
dict_get_weight (dict),
&rerr,
{
const union value *group = case_data (c, nst->indep_var);
const size_t group_var_width = var_get_width (nst->indep_var);
- struct rank_entry *rank = find_rank_entry (&kw[i].map, group, group_var_width);
+ struct rank_entry *rank = find_rank_entry (&kw[i].map, group, group_var_width);
if ( NULL == rank)
{
rank->n += dict_get_case_weight (dict, c, &warn);
/* If this assertion fires, then either the data wasn't sorted or some other
- problem occured */
+ problem occurred */
assert (rerr == 0);
}
total_n_groups ++;
}
kw[i].h *= 12 / (n * ( n + 1));
- kw[i].h -= 3 * (n + 1) ;
+ kw[i].h -= 3 * (n + 1) ;
kw[i].h /= 1 - tiebreaker/ (pow3 (n) - n);
}
}
casereader_destroy (input);
-
+
show_ranks_box (nst, kw, total_n_groups);
show_sig_box (nst, kw);
tab_box (table, TAL_2, TAL_2, -1, -1,
0, 0, tab_nc (table) - 1, tab_nr (table) - 1 );
- tab_text (table, 1, 0, TAT_TITLE,
+ tab_text (table, 1, 0, TAT_TITLE,
var_to_string (nst->indep_var)
);
for (i = 0 ; i < nst->n_vars ; ++i)
{
int tot = 0;
- const struct rank_entry *re;
+ struct rank_entry *re_x;
+ struct bt_node *bt_n = NULL;
+ struct bt bt;
if (i > 0)
tab_hline (table, TAL_1, 0, tab_nc (table) -1, row);
-
+
tab_text (table, 0, row,
TAT_TITLE, var_to_string (nst->vars[i]));
- HMAP_FOR_EACH (re, const struct rank_entry, node, &kw[i].map)
+ /* Sort the rank entries, by iteratin the hash and putting the entries
+ into a binary tree. */
+ bt_init (&bt, compare_rank_entries_3way, nst->vars[i]);
+ HMAP_FOR_EACH (re_x, struct rank_entry, node, &kw[i].map)
{
+ bt_insert (&bt, &re_x->btn);
+ }
+
+ /* Report the rank entries in sorted order. */
+ for (bt_n = bt_first (&bt);
+ bt_n != NULL;
+ bt_n = bt_next (&bt, bt_n) )
+ {
+ const struct rank_entry *re =
+ bt_data (bt_n, const struct rank_entry, btn);
+
struct string str;
ds_init_empty (&str);
var_append_value_name (nst->indep_var, &re->group, &str);
tab_text (table, 1, row, TAB_LEFT, ds_cstr (&str));
- tab_double (table, 2, row, TAB_LEFT, re->n, &F_8_0);
- tab_double (table, 3, row, TAB_LEFT, re->sum_of_ranks / re->n, 0);
+ tab_double (table, 2, row, TAB_LEFT, re->n, NULL, RC_INTEGER);
+ tab_double (table, 3, row, TAB_LEFT, re->sum_of_ranks / re->n, NULL, RC_OTHER);
tot += re->n;
row++;
ds_destroy (&str);
}
+
tab_double (table, 2, row, TAB_LEFT,
- tot, &F_8_0);
+ tot, NULL, RC_INTEGER);
tab_text (table, 1, row++, TAB_LEFT, _("Total"));
}
for (i = 0 ; i < nst->n_vars; ++i)
{
const double df = hmap_count (&kw[i].map) - 1;
- tab_text (table, column_headers + 1 + i, 0, TAT_TITLE,
+ tab_text (table, column_headers + 1 + i, 0, TAT_TITLE,
var_to_string (nst->vars[i])
);
tab_double (table, column_headers + 1 + i, 1, 0,
- kw[i].h, 0);
+ kw[i].h, NULL, RC_OTHER);
tab_double (table, column_headers + 1 + i, 2, 0,
- df, &F_8_0);
+ df, NULL, RC_INTEGER);
tab_double (table, column_headers + 1 + i, 3, 0,
gsl_cdf_chisq_Q (kw[i].h, df),
- 0);
+ NULL, RC_PVALUE);
}
tab_submit (table);