+typedef unsigned int hash_func (const struct levene *, const union value *v);
+typedef bool cmp_func (const struct levene *, const union value *v0, const union value *v1);
+
+struct levene
+{
+ /* Width of the categorical variable */
+ int gvw ;
+
+ /* The value dividing the groups. Valid only for dichotomous categorical variable.*/
+ const union value *cutpoint;
+
+
+ /* A hashtable of struct lev objects indexed by union value */
+ struct hmap hmap;
+
+ hash_func *hash;
+ cmp_func *cmp;
+
+
+ /* A state variable indicating how many passes have been done */
+ int pass;
+
+ double grand_n;
+ double z_grand_mean;
+
+ double denominator;
+};
+
+
+static unsigned int
+unique_hash (const struct levene *nl, const union value *val)
+{
+ return value_hash (val, nl->gvw, 0);
+}
+
+static bool
+unique_cmp (const struct levene *nl, const union value *val0, const union value *val1)
+{
+ return value_equal (val0, val1, nl->gvw);
+}
+
+static unsigned int
+cutpoint_hash (const struct levene *nl, const union value *val)
+{
+ int x = value_compare_3way (val, nl->cutpoint, nl->gvw);
+
+ return (x < 0);
+}
+
+static bool
+cutpoint_cmp (const struct levene *nl, const union value *val0, const union value *val1)
+{
+ int x = value_compare_3way (val0, nl->cutpoint, nl->gvw);
+
+ int y = value_compare_3way (val1, nl->cutpoint, nl->gvw);
+
+ if (x == 0) x = 1;
+ if (y == 0) y = 1;
+
+ return (x == y);
+}
+
+