X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Foneway.c;h=a67493ec4a048b1ec5398c9a93722c4f55a03a7b;hb=2fa50c14e54abe7095b53f6a790f19d90f20987b;hp=1c80c2ba98e7f5f8aa41674e8601a4db2be35cdb;hpb=4010cd95ae15efa542a324c4c2081b19ab10b902;p=pspp diff --git a/src/language/stats/oneway.c b/src/language/stats/oneway.c index 1c80c2ba98..a67493ec4a 100644 --- a/src/language/stats/oneway.c +++ b/src/language/stats/oneway.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -164,6 +164,9 @@ df_individual (const struct per_var_ws *pvw UNUSED, const struct moments1 *mom_i moments1_calculate (mom_i, &n_i, NULL, &var_i, 0, 0); moments1_calculate (mom_j, &n_j, NULL, &var_j, 0, 0); + + if ( n_i <= 1.0 || n_j <= 1.0) + return SYSMIS; nom = pow2 (var_i/n_i + var_j/n_j); denom = pow2 (var_i/n_i) / (n_i - 1) + pow2 (var_j/n_j) / (n_j - 1); @@ -191,6 +194,9 @@ static double sidak_pinv (double std_err, double alpha, double df, int k, const static double tukey_pinv (double std_err, double alpha, double df, int k, const struct moments1 *mom_i UNUSED, const struct moments1 *mom_j UNUSED) { + if ( k < 2 || df < 2) + return SYSMIS; + return std_err / sqrt (2.0) * qtukey (1 - alpha, 1.0, k, df, 1, 0); } @@ -211,6 +217,9 @@ static double gh_pinv (double std_err UNUSED, double alpha, double df, int k, co m = sqrt ((var_i/n_i + var_j/n_j) / 2.0); + if ( k < 2 || df < 2) + return SYSMIS; + return m * qtukey (1 - alpha, 1.0, k, df, 1, 0); } @@ -224,6 +233,8 @@ multiple_comparison_sig (double std_err, int k = pvw->n_groups; double df = ph->dff (pvw, dd_i->mom, dd_j->mom); double ts = ph->tsf (k, dd_i->mom, dd_j->mom, std_err); + if ( df == SYSMIS) + return SYSMIS; return ph->p1f (ts, k - 1, df); } @@ -232,13 +243,20 @@ mc_half_range (const struct oneway_spec *cmd, const struct per_var_ws *pvw, doub { int k = pvw->n_groups; double df = ph->dff (pvw, dd_i->mom, dd_j->mom); + if ( df == SYSMIS) + return SYSMIS; return ph->pinv (std_err, cmd->alpha, df, k, dd_i->mom, dd_j->mom); } static double tukey_1tailsig (double ts, double df1, double df2) { - double twotailedsig = 1.0 - ptukey (ts, 1.0, df1 + 1, df2, 1, 0); + double twotailedsig; + + if (df2 < 2 || df1 < 1) + return SYSMIS; + + twotailedsig = 1.0 - ptukey (ts, 1.0, df1 + 1, df2, 1, 0); return twotailedsig / 2.0; } @@ -575,7 +593,7 @@ dd_destroy (struct descriptive_data *dd) } static void * -makeit (void *aux1, void *aux2 UNUSED) +makeit (const void *aux1, void *aux2 UNUSED) { const struct variable *var = aux1; @@ -585,12 +603,8 @@ makeit (void *aux1, void *aux2 UNUSED) } static void -updateit (void *user_data, - enum mv_class exclude, - const struct variable *wv, - const struct variable *catvar UNUSED, - const struct ccase *c, - void *aux1, void *aux2) +updateit (const void *aux1, void *aux2, void *user_data, + const struct ccase *c, double weight) { struct descriptive_data *dd = user_data; @@ -600,13 +614,6 @@ updateit (void *user_data, struct descriptive_data *dd_total = aux2; - double weight; - - if ( var_is_value_missing (varp, valx, exclude)) - return; - - weight = wv != NULL ? case_data (c, wv)->f : 1.0; - moments1_add (dd->mom, valx->f, weight); if (valx->f < dd->minimum) dd->minimum = valx->f; @@ -653,10 +660,19 @@ run_oneway (const struct oneway_spec *cmd, for (v = 0; v < cmd->n_vars; ++v) { struct interaction *inter = interaction_create (cmd->indep_var); + + struct payload payload; + payload.create = makeit; + payload.update = updateit; + payload.destroy = NULL; + ws.vws[v].cat = categoricals_create (&inter, 1, cmd->wv, - cmd->exclude, makeit, updateit, - CONST_CAST (struct variable *, cmd->vars[v]), - ws.dd_total[v]); + cmd->exclude); + + categoricals_set_payload (ws.vws[v].cat, &payload, + CONST_CAST (struct variable *, cmd->vars[v]), + ws.dd_total[v]); + ws.vws[v].cov = covariance_2pass_create (1, &cmd->vars[v], ws.vws[v].cat, @@ -758,7 +774,15 @@ run_oneway (const struct oneway_spec *cmd, gsl_matrix *cm; struct per_var_ws *pvw = &ws.vws[v]; const struct categoricals *cats = covariance_get_categoricals (pvw->cov); - categoricals_done (cats); + const bool ok = categoricals_done (cats); + + if ( ! ok) + { + msg (MW, + _("Dependent variable %s has no non-missing values. No analysis for this variable will be done."), + var_get_name (cmd->vars[v])); + continue; + } cm = covariance_calculate_unnormalized (pvw->cov); @@ -783,6 +807,11 @@ run_oneway (const struct oneway_spec *cmd, { const struct categoricals *cats = covariance_get_categoricals (ws.vws[v].cov); + if ( ! categoricals_is_complete (cats)) + { + continue; + } + if (categoricals_n_total (cats) > ws.actual_number_of_groups) ws.actual_number_of_groups = categoricals_n_total (cats); } @@ -827,7 +856,7 @@ output_oneway (const struct oneway_spec *cmd, struct oneway_workspace *ws) if (ll_count (cl) != ws->actual_number_of_groups) { msg (SW, - _("In contrast list %zu, the number of coefficients (%d) does not equal the number of groups (%d). This contrast list will be ignored."), + _("In contrast list %zu, the number of coefficients (%zu) does not equal the number of groups (%d). This contrast list will be ignored."), i, ll_count (cl), ws->actual_number_of_groups); ll_remove (&coeff_list->ll); @@ -859,7 +888,12 @@ output_oneway (const struct oneway_spec *cmd, struct oneway_workspace *ws) { int v; for (v = 0 ; v < cmd->n_vars; ++v) - show_comparisons (cmd, ws, v); + { + const struct categoricals *cats = covariance_get_categoricals (ws->vws[v].cov); + + if ( categoricals_is_complete (cats)) + show_comparisons (cmd, ws, v); + } } } @@ -1068,6 +1102,7 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace tab_double (t, 9, row + count, 0, dd->maximum, fmt); } + if (categoricals_is_complete (cats)) { double T; double n, mean, variance; @@ -1099,6 +1134,7 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace tab_double (t, 7, row + count, 0, mean + T * std_error, NULL); + /* Min and Max */ tab_double (t, 8, row + count, 0, ws->dd_total[v]->minimum, fmt); tab_double (t, 9, row + count, 0, ws->dd_total[v]->maximum, fmt);