X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Flevene.c;h=12ec312f17b7b57d8c40b11ad8a8a796ec42981c;hb=f5c108becd49d78f4898cab11352291f5689d24e;hp=105fc09303e5cce49bd797f1c9509a3278e77408;hpb=dcf9b154cbcaa35c3d8459a201b77eec8bcb30bd;p=pspp-builds.git diff --git a/src/math/levene.c b/src/math/levene.c index 105fc093..12ec312f 100644 --- a/src/math/levene.c +++ b/src/math/levene.c @@ -1,8 +1,7 @@ -/* This file is part of GNU PSPP +/* This file is part of GNU PSPP Computes Levene test statistic. Copyright (C) 2004 Free Software Foundation, Inc. - Written by John Darrington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -21,17 +20,17 @@ #include #include "levene.h" -#include "message.h" -#include "case.h" -#include "casefile.h" -#include "dictionary.h" +#include +#include +#include +#include #include "group-proc.h" -#include "hash.h" -#include "str.h" -#include "variable.h" -#include "procedure.h" -#include "alloc.h" -#include "misc.h" +#include +#include +#include +#include +#include +#include #include "group.h" #include @@ -65,215 +64,188 @@ struct levene_info struct t_test_proc **group_stats; /* The independent variable */ - struct variable *v_indep; + const struct variable *v_indep; /* Number of dependent variables */ size_t n_dep; /* The dependent variables */ - struct variable **v_dep; + const struct variable **v_dep; - /* How to treat missing values */ - enum lev_missing missing; + /* Filter for missing values */ + enum mv_class exclude; - /* Function to test for missing values */ - is_missing_func *is_missing; + /* An array of lz_stats for each variable */ + struct lz_stats *lz; + + /* The denominator for the expression for the Levene */ + double *lz_denominator; + +}; + +/* Per variable statistics */ +struct lz_stats +{ + /* Total of all lz */ + double grand_total; + + /* Mean of all lz */ + double grand_mean; + + /* The total number of cases */ + double total_n ; + + /* Number of groups */ + int n_groups; }; /* First pass */ static void levene_precalc (const struct levene_info *l); -static int levene_calc (const struct ccase *, void *); -static void levene_postcalc (void *); +static int levene_calc (const struct dictionary *dict, const struct ccase *, + const struct levene_info *l); +static void levene_postcalc (struct levene_info *); /* Second pass */ -static void levene2_precalc (void *); -static int levene2_calc (const struct ccase *, void *); -static void levene2_postcalc (void *); - - -void -levene(const struct casefile *cf, - struct variable *v_indep, size_t n_dep, struct variable **v_dep, - enum lev_missing missing, is_missing_func value_is_missing) +static void levene2_precalc (struct levene_info *l); +static int levene2_calc (const struct dictionary *, const struct ccase *, + struct levene_info *l); +static void levene2_postcalc (struct levene_info *); + + +void +levene(const struct dictionary *dict, + struct casereader *reader, + const struct variable *v_indep, size_t n_dep, + const struct variable **v_dep, + enum mv_class exclude) { - struct casereader *r; + struct casereader *pass1, *pass2; struct ccase c; struct levene_info l; l.n_dep = n_dep; l.v_indep = v_indep; l.v_dep = v_dep; - l.missing = missing; - l.is_missing = value_is_missing; - + l.exclude = exclude; + l.lz = xnmalloc (l.n_dep, sizeof *l.lz); + l.lz_denominator = xnmalloc (l.n_dep, sizeof *l.lz_denominator); + casereader_split (reader, &pass1, &pass2); - levene_precalc(&l); - for(r = casefile_get_reader (cf); - casereader_read (r, &c) ; - case_destroy (&c)) - { - levene_calc(&c,&l); - } - casereader_destroy (r); - levene_postcalc(&l); + levene_precalc (&l); + for (; casereader_read (pass1, &c); case_destroy (&c)) + levene_calc (dict, &c, &l); + casereader_destroy (pass1); + levene_postcalc (&l); levene2_precalc(&l); - for(r = casefile_get_reader (cf); - casereader_read (r, &c) ; - case_destroy (&c)) - { - levene2_calc(&c,&l); - } - casereader_destroy (r); - levene2_postcalc(&l); + for (; casereader_read (pass2, &c); case_destroy (&c)) + levene2_calc (dict, &c, &l); + casereader_destroy (pass2); + levene2_postcalc (&l); + free (l.lz_denominator); + free (l.lz); } -/* Internal variables used in calculating the Levene statistic */ - -/* Per variable statistics */ -struct lz_stats -{ - /* Total of all lz */ - double grand_total; - - /* Mean of all lz */ - double grand_mean; - - /* The total number of cases */ - double total_n ; - - /* Number of groups */ - int n_groups; -}; - -/* An array of lz_stats for each variable */ -static struct lz_stats *lz; - - -static void +static void levene_precalc (const struct levene_info *l) { size_t i; - lz = xnmalloc (l->n_dep, sizeof *lz); - - for(i = 0; i < l->n_dep ; ++i ) + for(i = 0; i < l->n_dep ; ++i ) { - struct variable *var = l->v_dep[i]; + const struct variable *var = l->v_dep[i]; struct group_proc *gp = group_proc_get (var); struct group_statistics *gs; struct hsh_iterator hi; - lz[i].grand_total = 0; - lz[i].total_n = 0; - lz[i].n_groups = gp->n_groups ; + l->lz[i].grand_total = 0; + l->lz[i].total_n = 0; + l->lz[i].n_groups = gp->n_groups ; + - for ( gs = hsh_first(gp->group_hash, &hi); gs != 0; gs = hsh_next(gp->group_hash, &hi)) { gs->lz_total = 0; } - + } } -static int -levene_calc (const struct ccase *c, void *_l) +static int +levene_calc (const struct dictionary *dict, const struct ccase *c, + const struct levene_info *l) { size_t i; - int warn = 0; - struct levene_info *l = (struct levene_info *) _l; - const union value *gv = case_data (c, l->v_indep->fv); + bool warn = false; + const union value *gv = case_data (c, l->v_indep); struct group_statistics key; - double weight = dict_get_case_weight(default_dict,c,&warn); - - /* Skip the entire case if /MISSING=LISTWISE is set */ - if ( l->missing == LEV_LISTWISE ) - { - for (i = 0; i < l->n_dep; ++i) - { - struct variable *v = l->v_dep[i]; - const union value *val = case_data (c, v->fv); + double weight = dict_get_case_weight (dict, c, &warn); - if (l->is_missing (&v->miss, val) ) - { - return 0; - } - } - } - - key.id = *gv; - for (i = 0; i < l->n_dep; ++i) + for (i = 0; i < l->n_dep; ++i) { - struct variable *var = l->v_dep[i]; + const struct variable *var = l->v_dep[i]; struct group_proc *gp = group_proc_get (var); double levene_z; - const union value *v = case_data (c, var->fv); + const union value *v = case_data (c, var); struct group_statistics *gs; gs = hsh_find(gp->group_hash,(void *) &key ); - if ( 0 == gs ) + if ( 0 == gs ) continue ; - if ( ! l->is_missing(&var->miss, v)) + if ( !var_is_value_missing (var, v, l->exclude)) { levene_z= fabs(v->f - gs->mean); - lz[i].grand_total += levene_z * weight; - lz[i].total_n += weight; + l->lz[i].grand_total += levene_z * weight; + l->lz[i].total_n += weight; gs->lz_total += levene_z * weight; } - } return 0; } -static void -levene_postcalc (void *_l) +static void +levene_postcalc (struct levene_info *l) { size_t v; - struct levene_info *l = (struct levene_info *) _l; - - for (v = 0; v < l->n_dep; ++v) + for (v = 0; v < l->n_dep; ++v) { /* This is Z_LL */ - lz[v].grand_mean = lz[v].grand_total / lz[v].total_n ; + l->lz[v].grand_mean = l->lz[v].grand_total / l->lz[v].total_n ; } - + } -/* The denominator for the expression for the Levene */ -static double *lz_denominator; -static void -levene2_precalc (void *_l) +static void +levene2_precalc (struct levene_info *l) { size_t v; - struct levene_info *l = (struct levene_info *) _l; - - lz_denominator = xnmalloc (l->n_dep, sizeof *lz_denominator); /* This stuff could go in the first post calc . . . */ - for (v = 0; v < l->n_dep; ++v) + for (v = 0; + v < l->n_dep; + ++v) { struct hsh_iterator hi; struct group_statistics *g; - struct variable *var = l->v_dep[v] ; + const struct variable *var = l->v_dep[v] ; struct hsh_table *hash = group_proc_get (var)->group_hash; @@ -283,56 +255,40 @@ levene2_precalc (void *_l) { g->lz_mean = g->lz_total / g->n ; } - lz_denominator[v] = 0; + l->lz_denominator[v] = 0; } } -static int -levene2_calc (const struct ccase *c, void *_l) +static int +levene2_calc (const struct dictionary *dict, const struct ccase *c, + struct levene_info *l) { size_t i; - int warn = 0; - - struct levene_info *l = (struct levene_info *) _l; + bool warn = false; - double weight = dict_get_case_weight(default_dict,c,&warn); + double weight = dict_get_case_weight (dict, c, &warn); - const union value *gv = case_data (c, l->v_indep->fv); + const union value *gv = case_data (c, l->v_indep); struct group_statistics key; - /* Skip the entire case if /MISSING=LISTWISE is set */ - if ( l->missing == LEV_LISTWISE ) - { - for (i = 0; i < l->n_dep; ++i) - { - struct variable *v = l->v_dep[i]; - const union value *val = case_data (c, v->fv); - - if (l->is_missing(&v->miss, val) ) - { - return 0; - } - } - } - key.id = *gv; - for (i = 0; i < l->n_dep; ++i) + for (i = 0; i < l->n_dep; ++i) { double levene_z; - struct variable *var = l->v_dep[i] ; - const union value *v = case_data (c, var->fv); + const struct variable *var = l->v_dep[i] ; + const union value *v = case_data (c, var); struct group_statistics *gs; gs = hsh_find(group_proc_get (var)->group_hash,(void *) &key ); - if ( 0 == gs ) + if ( 0 == gs ) continue; - if ( ! l->is_missing (&var->miss, v) ) + if ( !var_is_value_missing (var, v, l->exclude)) { - levene_z = fabs(v->f - gs->mean); - lz_denominator[i] += weight * pow2(levene_z - gs->lz_mean); + levene_z = fabs(v->f - gs->mean); + l->lz_denominator[i] += weight * pow2 (levene_z - gs->lz_mean); } } @@ -340,20 +296,18 @@ levene2_calc (const struct ccase *c, void *_l) } -static void -levene2_postcalc (void *_l) +static void +levene2_postcalc (struct levene_info *l) { size_t v; - struct levene_info *l = (struct levene_info *) _l; - - for (v = 0; v < l->n_dep; ++v) + for (v = 0; v < l->n_dep; ++v) { double lz_numerator = 0; struct hsh_iterator hi; struct group_statistics *g; - struct variable *var = l->v_dep[v] ; + const struct variable *var = l->v_dep[v] ; struct group_proc *gp = group_proc_get (var); struct hsh_table *hash = gp->group_hash; @@ -361,18 +315,14 @@ levene2_postcalc (void *_l) g != 0 ; g = (struct group_statistics *) hsh_next(hash,&hi) ) { - lz_numerator += g->n * pow2(g->lz_mean - lz[v].grand_mean ); + lz_numerator += g->n * pow2(g->lz_mean - l->lz[v].grand_mean ); } lz_numerator *= ( gp->ugs.n - gp->n_groups ); - lz_denominator[v] *= (gp->n_groups - 1); + l->lz_denominator[v] *= (gp->n_groups - 1); - gp->levene = lz_numerator / lz_denominator[v] ; + gp->levene = lz_numerator / l->lz_denominator[v] ; } - - /* Now clear up after ourselves */ - free(lz_denominator); - free(lz); }