X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fexamine.q;h=33498d85e05ffdb89f4f70f71fe748af0ca17d18;hb=1f8dd363d6c20d07fcca14cb948018465fa5ed8b;hp=5cb89af2ab58cdb368da64f154d1d77999376862;hpb=46cc6dd316280579f5b03dfd39d01bc7daf88df7;p=pspp-builds.git diff --git a/src/examine.q b/src/examine.q index 5cb89af2..33498d85 100644 --- a/src/examine.q +++ b/src/examine.q @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include #include @@ -44,12 +44,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "moments.h" #include "percentiles.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + /* (headers) */ #include "chart.h" /* (specification) "EXAMINE" (xmn_): - *variables=custom; + *^variables=custom; +total=custom; +nototal=custom; +missing=miss:pairwise/!listwise, @@ -116,8 +120,8 @@ static void show_descriptives(struct variable **dependent_var, struct factor *factor); static void show_percentiles(struct variable **dependent_var, - int n_dep_var, - struct factor *factor); + int n_dep_var, + struct factor *factor); @@ -132,7 +136,7 @@ void box_plot_group(const struct factor *fctr, void box_plot_variables(const struct factor *fctr, - struct variable **vars, int n_vars, + const struct variable **vars, int n_vars, const struct variable *id ); @@ -151,8 +155,8 @@ void factor_calc(struct ccase *c, int case_no, /* Represent a factor as a string, so it can be printed in a human readable fashion */ const char * factor_to_string(const struct factor *fctr, - struct factor_statistics *fs, - const struct variable *var); + struct factor_statistics *fs, + const struct variable *var); /* Represent a factor as a string, so it can be @@ -165,7 +169,7 @@ const char *factor_to_string_concise(const struct factor *fctr, /* Function to use for testing for missing values */ -static is_missing_func value_is_missing; +static is_missing_func *value_is_missing; /* PERCENTILES */ @@ -189,9 +193,9 @@ cmd_examine(void) /* If /MISSING=INCLUDE is set, then user missing values are ignored */ if (cmd.incl == XMN_INCLUDE ) - value_is_missing = is_system_missing; + value_is_missing = mv_is_value_system_missing; else - value_is_missing = is_missing; + value_is_missing = mv_is_value_missing; if ( cmd.st_n == SYSMIS ) cmd.st_n = 5; @@ -211,7 +215,25 @@ cmd_examine(void) multipass_procedure_with_splits (run_examine, &cmd); if ( totals ) - free(totals); + { + free( totals ); + } + + if ( dependent_vars ) + free (dependent_vars); + + { + struct factor *f = factors ; + while ( f ) + { + struct factor *ff = f; + + f = f->next; + free ( ff->fs ); + hsh_destroy ( ff->fstats ) ; + free ( ff ) ; + } + } subc_list_double_destroy(&percentile_list); @@ -354,6 +376,8 @@ output_examine(void) } +/* Create a hash table of percentiles and their values from the list of + percentiles */ static struct hsh_table * list_to_ptile_hash(const subc_list_double *l) { @@ -373,6 +397,7 @@ list_to_ptile_hash(const subc_list_double *l) struct percentile *p = xmalloc (sizeof (struct percentile)); p->p = subc_list_double_at(l,i); + p->v = SYSMIS; hsh_insert(h, p); @@ -392,9 +417,9 @@ xmn_custom_percentiles(struct cmd_examine *p UNUSED) lex_match('('); - while ( lex_double_p() ) + while ( lex_is_number() ) { - subc_list_double_push(&percentile_list,lex_double()); + subc_list_double_push(&percentile_list,lex_number()); lex_get(); @@ -464,16 +489,18 @@ xmn_custom_nototal(struct cmd_examine *p) -/* Parser for the variables sub command */ +/* Parser for the variables sub command + Returns 1 on success */ static int xmn_custom_variables(struct cmd_examine *cmd ) { - lex_match('='); if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL) && token != T_ALL) - return 2; + { + return 2; + } if (!parse_variables (default_dict, &dependent_vars, &n_dependent_vars, PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) ) @@ -488,7 +515,13 @@ xmn_custom_variables(struct cmd_examine *cmd ) if ( lex_match(T_BY)) { - return examine_parse_independent_vars(cmd); + int success ; + success = examine_parse_independent_vars(cmd); + if ( success != 1 ) { + free (dependent_vars); + free (totals) ; + } + return success; } return 1; @@ -500,12 +533,15 @@ xmn_custom_variables(struct cmd_examine *cmd ) static int examine_parse_independent_vars(struct cmd_examine *cmd) { - + int success; struct factor *sf = xmalloc(sizeof(struct factor)); if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL) && token != T_ALL) - return 2; + { + free ( sf ) ; + return 2; + } sf->indep_var[0] = parse_variable(); @@ -518,7 +554,10 @@ examine_parse_independent_vars(struct cmd_examine *cmd) if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL) && token != T_ALL) - return 2; + { + free ( sf ) ; + return 2; + } sf->indep_var[1] = parse_variable(); @@ -539,7 +578,12 @@ examine_parse_independent_vars(struct cmd_examine *cmd) if ( token == '.' || token == '/' ) return 1; - return examine_parse_independent_vars(cmd); + success = examine_parse_independent_vars(cmd); + + if ( success != 1 ) + free ( sf ) ; + + return success; } @@ -572,6 +616,7 @@ factor_calc(struct ccase *c, int case_no, double weight, int case_missing) while ( fctr) { + struct factor_statistics **foo ; union value indep_vals[2] ; indep_vals[0] = * case_data(c, fctr->indep_var[0]->fv); @@ -583,7 +628,7 @@ factor_calc(struct ccase *c, int case_no, double weight, int case_missing) assert(fctr->fstats); - struct factor_statistics **foo = ( struct factor_statistics ** ) + foo = ( struct factor_statistics ** ) hsh_probe(fctr->fstats, (void *) &indep_vals); if ( !*foo ) @@ -605,7 +650,7 @@ factor_calc(struct ccase *c, int case_no, double weight, int case_missing) const struct variable *var = dependent_vars[v]; const union value *val = case_data (c, var->fv); - if ( value_is_missing(val,var) || case_missing ) + if ( value_is_missing (&var->miss, val) || case_missing ) val = 0; metrics_calc( &(*foo)->m[v], val, weight, case_no); @@ -667,7 +712,7 @@ run_examine(const struct casefile *cf, void *cmd_ ) const struct variable *var = dependent_vars[v]; const union value *val = case_data (&c, var->fv); - if ( value_is_missing(val,var)) + if ( value_is_missing(&var->miss, val)) case_missing = 1; } @@ -678,7 +723,7 @@ run_examine(const struct casefile *cf, void *cmd_ ) const struct variable *var = dependent_vars[v]; const union value *val = case_data (&c, var->fv); - if ( value_is_missing(val,var) || case_missing ) + if ( value_is_missing(&var->miss, val) || case_missing ) val = 0; metrics_calc(&totals[v], val, weight, case_no); @@ -786,8 +831,15 @@ run_examine(const struct casefile *cf, void *cmd_ ) output_examine(); - for ( v = 0 ; v < n_dependent_vars ; ++v ) - hsh_destroy(totals[v].ordered_data); + + if ( totals ) + { + int i; + for ( i = 0 ; i < n_dependent_vars ; ++i ) + { + metrics_destroy(&totals[i]); + } + } } @@ -819,7 +871,7 @@ show_summary(struct variable **dependent_var, int n_dep_var, n_rows = n_dep_var * n_factors ; if ( fctr->indep_var[1] ) - heading_columns = 3; + heading_columns = 3; } else { @@ -944,17 +996,17 @@ show_summary(struct variable **dependent_var, int n_dep_var, if ( 0 != compare_values(&prev, &(*fs)->id[0], fctr->indep_var[0]->width)) { - tab_text (tbl, - 1, - (i * n_factors ) + count + - heading_rows, - TAB_LEFT | TAT_TITLE, - value_to_string(&(*fs)->id[0], fctr->indep_var[0]) - ); - - if (fctr->indep_var[1] && count > 0 ) - tab_hline(tbl, TAL_1, 1, n_cols - 1, - (i * n_factors ) + count + heading_rows); + tab_text (tbl, + 1, + (i * n_factors ) + count + + heading_rows, + TAB_LEFT | TAT_TITLE, + value_to_string(&(*fs)->id[0], fctr->indep_var[0]) + ); + + if (fctr->indep_var[1] && count > 0 ) + tab_hline(tbl, TAL_1, 1, n_cols - 1, + (i * n_factors ) + count + heading_rows); } @@ -1037,7 +1089,7 @@ show_extremes(struct variable **dependent_var, int n_dep_var, n_rows = n_dep_var * 2 * n_extremities * n_factors; if ( fctr->indep_var[1] ) - heading_columns = 3; + heading_columns = 3; } else { @@ -1214,7 +1266,7 @@ populate_extremes(struct tab_table *t, cn->num, 8, 0); if ( cn->next ) - cn = cn->next; + cn = cn->next; } @@ -1243,7 +1295,7 @@ populate_extremes(struct tab_table *t, cn->num, 8, 0); if ( cn->next ) - cn = cn->next; + cn = cn->next; } @@ -1278,7 +1330,7 @@ show_descriptives(struct variable **dependent_var, n_rows = n_dep_var * n_stat_rows * n_factors; if ( fctr->indep_var[1] ) - heading_columns = 5; + heading_columns = 5; } else { @@ -1378,7 +1430,7 @@ show_descriptives(struct variable **dependent_var, ); populate_descriptives(tbl, heading_columns - 2, - row, &(*fs)->m[i]); + row, &(*fs)->m[i]); count++ ; fs++; @@ -1461,8 +1513,8 @@ populate_descriptives(struct tab_table *tbl, int col, int row, tab_text (tbl, col, row + 3, - TAB_LEFT | TAT_TITLE, - _("5% Trimmed Mean")); + TAB_LEFT | TAT_TITLE | TAT_PRINTF, + _("5%% Trimmed Mean")); tab_float (tbl, col + 2, row + 3, @@ -1483,12 +1535,14 @@ populate_descriptives(struct tab_table *tbl, int col, int row, assert(p); + tab_float (tbl, col + 2, row + 4, TAB_CENTER, p->v, 8, 2); } + tab_text (tbl, col, row + 5, @@ -1623,9 +1677,10 @@ populate_descriptives(struct tab_table *tbl, int col, int row, void box_plot_variables(const struct factor *fctr, - struct variable **vars, int n_vars, + const struct variable **vars, int n_vars, const struct variable *id) { + int i; struct factor_statistics **fs ; @@ -1639,13 +1694,10 @@ box_plot_variables(const struct factor *fctr, { double y_min = DBL_MAX; double y_max = -DBL_MAX; - struct chart ch; - - chart_initialise(&ch); - + struct chart *ch = chart_create(); const char *s = factor_to_string(fctr, *fs, 0 ); - chart_write_title(&ch, s); + chart_write_title(ch, s); for ( i = 0 ; i < n_vars ; ++i ) { @@ -1653,18 +1705,18 @@ box_plot_variables(const struct factor *fctr, y_min = min(y_min, (*fs)->m[i].min); } - boxplot_draw_yscale(&ch, y_max, y_min); + boxplot_draw_yscale(ch, y_max, y_min); for ( i = 0 ; i < n_vars ; ++i ) { - const double box_width = (ch.data_right - ch.data_left) + const double box_width = (ch->data_right - ch->data_left) / (n_vars * 2.0 ) ; const double box_centre = ( i * 2 + 1) * box_width - + ch.data_left; + + ch->data_left; - boxplot_draw_boxplot(&ch, + boxplot_draw_boxplot(ch, box_centre, box_width, &(*fs)->m[i], var_to_string(vars[i])); @@ -1672,10 +1724,9 @@ box_plot_variables(const struct factor *fctr, } - chart_finalise(&ch); + chart_submit(ch); } - } @@ -1687,27 +1738,28 @@ void box_plot_group(const struct factor *fctr, const struct variable **vars, int n_vars, - const struct variable *id) + const struct variable *id UNUSED) { + int i; for ( i = 0 ; i < n_vars ; ++i ) { struct factor_statistics **fs ; - struct chart ch; + struct chart *ch; - chart_initialise(&ch); + ch = chart_create(); - boxplot_draw_yscale(&ch, totals[i].max, totals[i].min); + boxplot_draw_yscale(ch, totals[i].max, totals[i].min); if ( fctr ) { int n_factors = 0; int f=0; for ( fs = fctr->fs ; *fs ; ++fs ) - ++n_factors; + ++n_factors; - chart_write_title(&ch, _("Boxplot of %s vs. %s"), + chart_write_title(ch, _("Boxplot of %s vs. %s"), var_to_string(vars[i]), var_to_string(fctr->indep_var[0]) ); for ( fs = fctr->fs ; *fs ; ++fs ) @@ -1715,35 +1767,34 @@ box_plot_group(const struct factor *fctr, const char *s = factor_to_string_concise(fctr, *fs); - const double box_width = (ch.data_right - ch.data_left) + const double box_width = (ch->data_right - ch->data_left) / (n_factors * 2.0 ) ; const double box_centre = ( f++ * 2 + 1) * box_width - + ch.data_left; + + ch->data_left; - boxplot_draw_boxplot(&ch, + boxplot_draw_boxplot(ch, box_centre, box_width, &(*fs)->m[i], s); } } - else + else if ( ch ) { - const double box_width = (ch.data_right - ch.data_left) / 3.0; - const double box_centre = (ch.data_right + ch.data_left) / 2.0; + const double box_width = (ch->data_right - ch->data_left) / 3.0; + const double box_centre = (ch->data_right + ch->data_left) / 2.0; - chart_write_title(&ch, _("Boxplot")); + chart_write_title(ch, _("Boxplot")); - boxplot_draw_boxplot(&ch, + boxplot_draw_boxplot(ch, box_centre, box_width, &totals[i], var_to_string(vars[i]) ); } - chart_finalise(&ch); + chart_submit(ch); } - } @@ -1756,10 +1807,10 @@ np_plot(const struct metrics *m, const char *factorname) double yfirst=0, ylast=0; /* Normal Plot */ - struct chart np_chart; + struct chart *np_chart; /* Detrended Normal Plot */ - struct chart dnp_chart; + struct chart *dnp_chart; /* The slope and intercept of the ideal normal probability line */ const double slope = 1.0 / m->stddev; @@ -1769,16 +1820,21 @@ np_plot(const struct metrics *m, const char *factorname) if ( m->n_data == 0 ) return ; - chart_initialise(&np_chart); - chart_write_title(&np_chart, _("Normal Q-Q Plot of %s"), factorname); - chart_write_xlabel(&np_chart, _("Observed Value")); - chart_write_ylabel(&np_chart, _("Expected Normal")); + np_chart = chart_create(); + dnp_chart = chart_create(); + + if ( !np_chart || ! dnp_chart ) + return ; - chart_initialise(&dnp_chart); - chart_write_title(&dnp_chart, _("Detrended Normal Q-Q Plot of %s"), + chart_write_title(np_chart, _("Normal Q-Q Plot of %s"), factorname); + chart_write_xlabel(np_chart, _("Observed Value")); + chart_write_ylabel(np_chart, _("Expected Normal")); + + + chart_write_title(dnp_chart, _("Detrended Normal Q-Q Plot of %s"), factorname); - chart_write_xlabel(&dnp_chart, _("Observed Value")); - chart_write_ylabel(&dnp_chart, _("Dev from Normal")); + chart_write_xlabel(dnp_chart, _("Observed Value")); + chart_write_ylabel(dnp_chart, _("Dev from Normal")); yfirst = gsl_cdf_ugaussian_Pinv (m->wvp[0]->rank / ( m->n + 1)); ylast = gsl_cdf_ugaussian_Pinv (m->wvp[m->n_data-1]->rank / ( m->n + 1)); @@ -1791,46 +1847,44 @@ np_plot(const struct metrics *m, const char *factorname) double x_upper = max(m->max, (ylast - intercept) / slope) ; double slack = (x_upper - x_lower) * 0.05 ; - chart_write_xscale(&np_chart, x_lower - slack, x_upper + slack, 5); + chart_write_xscale(np_chart, x_lower - slack, x_upper + slack, 5); - chart_write_xscale(&dnp_chart, m->min, m->max, 5); + chart_write_xscale(dnp_chart, m->min, m->max, 5); } - chart_write_yscale(&np_chart, yfirst, ylast, 5); + chart_write_yscale(np_chart, yfirst, ylast, 5); { - /* We have to cache the detrended data, beacause we need to - find its limits before we can plot it */ - double *d_data; - d_data = xmalloc (m->n_data * sizeof(double)); - double d_max = -DBL_MAX; - double d_min = DBL_MAX; - for ( i = 0 ; i < m->n_data; ++i ) - { - const double ns = gsl_cdf_ugaussian_Pinv (m->wvp[i]->rank / ( m->n + 1)); + /* We have to cache the detrended data, beacause we need to + find its limits before we can plot it */ + double *d_data = xmalloc (m->n_data * sizeof(double)); + double d_max = -DBL_MAX; + double d_min = DBL_MAX; + for ( i = 0 ; i < m->n_data; ++i ) + { + const double ns = gsl_cdf_ugaussian_Pinv (m->wvp[i]->rank / ( m->n + 1)); - chart_datum(&np_chart, 0, m->wvp[i]->v.f, ns); + chart_datum(np_chart, 0, m->wvp[i]->v.f, ns); - d_data[i] = (m->wvp[i]->v.f - m->mean) / m->stddev - ns; + d_data[i] = (m->wvp[i]->v.f - m->mean) / m->stddev - ns; - if ( d_data[i] < d_min ) d_min = d_data[i]; - if ( d_data[i] > d_max ) d_max = d_data[i]; - } - chart_write_yscale(&dnp_chart, d_min, d_max, 5); + if ( d_data[i] < d_min ) d_min = d_data[i]; + if ( d_data[i] > d_max ) d_max = d_data[i]; + } + chart_write_yscale(dnp_chart, d_min, d_max, 5); - for ( i = 0 ; i < m->n_data; ++i ) - chart_datum(&dnp_chart, 0, m->wvp[i]->v.f, d_data[i]); + for ( i = 0 ; i < m->n_data; ++i ) + chart_datum(dnp_chart, 0, m->wvp[i]->v.f, d_data[i]); - free(d_data); + free(d_data); } - chart_line(&np_chart, slope, intercept, yfirst, ylast , CHART_DIM_Y); - chart_line(&dnp_chart, 0, 0, m->min, m->max , CHART_DIM_X); - - chart_finalise(&np_chart); - chart_finalise(&dnp_chart); + chart_line(np_chart, slope, intercept, yfirst, ylast , CHART_DIM_Y); + chart_line(dnp_chart, 0, 0, m->min, m->max , CHART_DIM_X); + chart_submit(np_chart); + chart_submit(dnp_chart); } @@ -1839,8 +1893,8 @@ np_plot(const struct metrics *m, const char *factorname) /* Show the percentiles */ void show_percentiles(struct variable **dependent_var, - int n_dep_var, - struct factor *fctr) + int n_dep_var, + struct factor *fctr) { struct tab_table *tbl; int i; @@ -1865,7 +1919,7 @@ show_percentiles(struct variable **dependent_var, ptiles = (*fs)->m[0].ptile_hash; if ( fctr->indep_var[1] ) - n_heading_columns = 4; + n_heading_columns = 4; } else { @@ -2007,7 +2061,7 @@ show_percentiles(struct variable **dependent_var, populate_percentiles(tbl, n_heading_columns - 1, - row, &(*fs)->m[i]); + row, &(*fs)->m[i]); count++ ; @@ -2019,8 +2073,8 @@ show_percentiles(struct variable **dependent_var, else { populate_percentiles(tbl, n_heading_columns - 1, - i * n_stat_rows * n_factors + n_heading_rows, - &totals[i]); + i * n_stat_rows * n_factors + n_heading_rows, + &totals[i]); } @@ -2129,7 +2183,7 @@ factor_to_string(const struct factor *fctr, const char * factor_to_string_concise(const struct factor *fctr, - struct factor_statistics *fs) + struct factor_statistics *fs) {