X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fcrosstabs.q;h=b137e284968372f2c0580774522c994362252ad4;hb=3c9825c825998664d992841d851e23a0adf8af6e;hp=5695ed6478b64490095ea0c8abde83873fb38030;hpb=cb586666724d5fcbdb658ce471b85484f0a7babe;p=pspp-builds.git diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q index 5695ed64..b137e284 100644 --- a/src/language/stats/crosstabs.q +++ b/src/language/stats/crosstabs.q @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009, 2010 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 @@ -56,8 +56,7 @@ #include #include #include -#include -#include +#include #include "minmax.h" #include "xalloc.h" @@ -201,12 +200,6 @@ struct crosstabs_proc unsigned int statistics; /* Bit k is 1 if statistic k is requested. */ }; -/* Auxiliary data structure for tab_dim. */ -struct crosstabs_dim_aux - { - enum mv_class exclude; - }; - static void init_proc (struct crosstabs_proc *proc, struct dataset *ds) { @@ -249,8 +242,7 @@ static void tabulate_general_case (struct pivot_table *, const struct ccase *, static void tabulate_integer_case (struct pivot_table *, const struct ccase *, double weight); static void postcalc (struct crosstabs_proc *); -static void submit (struct crosstabs_proc *, struct pivot_table *, - struct tab_table *); +static void submit (struct pivot_table *, struct tab_table *); /* Parse and execute CROSSTABS, then clean up. */ int @@ -353,6 +345,10 @@ internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds, case_unref (c); } + /* Initialize hash tables. */ + for (pt = &proc->pivots[0]; pt < &proc->pivots[proc->n_pivots]; pt++) + hmap_init (&pt->data); + /* Tabulate. */ for (; (c = casereader_read (group)) != NULL; case_unref (c)) for (pt = &proc->pivots[0]; pt < &proc->pivots[proc->n_pivots]; pt++) @@ -452,9 +448,6 @@ crs_custom_tables (struct lexer *lexer, struct dataset *ds, pt->n_consts = 0; pt->const_vars = NULL; pt->const_values = NULL; - hmap_init (&pt->data); - pt->entries = NULL; - pt->n_entries = 0; for (j = 0; j < n_by; j++) pt->vars[j] = by[j][by_iter[j]]; @@ -661,9 +654,7 @@ tabulate_general_case (struct pivot_table *pt, const struct ccase *c, for (j = 0; j < pt->n_vars; j++) { const struct variable *var = pt->vars[j]; - int width = var_get_width (var); - value_init (&te->values[j], width); - value_copy (&te->values[j], case_data (c, var), width); + value_clone (&te->values[j], case_data (c, var), var_get_width (var)); } hmap_insert (&pt->data, &te->node, hash); } @@ -897,7 +888,7 @@ make_summary_table (struct crosstabs_proc *proc) } ds_destroy (&name); - submit (proc, NULL, summary); + submit (NULL, summary); } /* Output. */ @@ -920,8 +911,6 @@ static void display_symmetric (struct crosstabs_proc *, struct pivot_table *, static void display_risk (struct pivot_table *, struct tab_table *); static void display_directional (struct crosstabs_proc *, struct pivot_table *, struct tab_table *); -static void crosstabs_dim (struct tab_rendering *, void *aux); -static void crosstabs_dim_free (void *aux); static void table_value_missing (struct crosstabs_proc *proc, struct tab_table *table, int c, int r, unsigned char opt, const union value *v, @@ -1029,18 +1018,18 @@ output_pivot_table (struct crosstabs_proc *proc, struct pivot_table *pt) free (x.col_tot); } - submit (proc, NULL, table); + submit (NULL, table); if (chisq) { if (!showed_fisher) tab_resize (chisq, 4 + (pt->n_vars - 2), -1); - submit (proc, pt, chisq); + submit (pt, chisq); } - submit (proc, pt, sym); - submit (proc, pt, risk); - submit (proc, pt, direct); + submit (pt, sym); + submit (pt, risk); + submit (pt, direct); free (pt->cols); } @@ -1150,42 +1139,46 @@ create_crosstab_table (struct crosstabs_proc *proc, struct pivot_table *pt) struct tab_table *table; struct string title; + struct pivot_table x; + int i; - table = tab_create (pt->n_consts + 1 + pt->n_cols + 1, - (pt->n_entries / pt->n_cols) * 3 / 2 * proc->n_cells + 10); - tab_headers (table, pt->n_consts + 1, 0, 2, 0); + make_pivot_table_subset (pt, 0, 0, &x); + + table = tab_create (x.n_consts + 1 + x.n_cols + 1, + (x.n_entries / x.n_cols) * 3 / 2 * proc->n_cells + 10); + tab_headers (table, x.n_consts + 1, 0, 2, 0); /* First header line. */ - tab_joint_text (table, pt->n_consts + 1, 0, - (pt->n_consts + 1) + (pt->n_cols - 1), 0, - TAB_CENTER | TAT_TITLE, var_get_name (pt->vars[COL_VAR])); + tab_joint_text (table, x.n_consts + 1, 0, + (x.n_consts + 1) + (x.n_cols - 1), 0, + TAB_CENTER | TAT_TITLE, var_get_name (x.vars[COL_VAR])); - tab_hline (table, TAL_1, pt->n_consts + 1, - pt->n_consts + 2 + pt->n_cols - 2, 1); + tab_hline (table, TAL_1, x.n_consts + 1, + x.n_consts + 2 + x.n_cols - 2, 1); /* Second header line. */ - for (i = 2; i < pt->n_consts + 2; i++) - tab_joint_text (table, pt->n_consts + 2 - i - 1, 0, - pt->n_consts + 2 - i - 1, 1, - TAB_RIGHT | TAT_TITLE, var_to_string (pt->vars[i])); - tab_text (table, pt->n_consts + 2 - 2, 1, TAB_RIGHT | TAT_TITLE, - var_get_name (pt->vars[ROW_VAR])); - for (i = 0; i < pt->n_cols; i++) - table_value_missing (proc, table, pt->n_consts + 2 + i - 1, 1, TAB_RIGHT, - &pt->cols[i], pt->vars[COL_VAR]); - tab_text (table, pt->n_consts + 2 + pt->n_cols - 1, 1, TAB_CENTER, _("Total")); - - tab_hline (table, TAL_1, 0, pt->n_consts + 2 + pt->n_cols - 1, 2); - tab_vline (table, TAL_1, pt->n_consts + 2 + pt->n_cols - 1, 0, 1); + for (i = 2; i < x.n_consts + 2; i++) + tab_joint_text (table, x.n_consts + 2 - i - 1, 0, + x.n_consts + 2 - i - 1, 1, + TAB_RIGHT | TAT_TITLE, var_to_string (x.vars[i])); + tab_text (table, x.n_consts + 2 - 2, 1, TAB_RIGHT | TAT_TITLE, + var_get_name (x.vars[ROW_VAR])); + for (i = 0; i < x.n_cols; i++) + table_value_missing (proc, table, x.n_consts + 2 + i - 1, 1, TAB_RIGHT, + &x.cols[i], x.vars[COL_VAR]); + tab_text (table, x.n_consts + 2 + x.n_cols - 1, 1, TAB_CENTER, _("Total")); + + tab_hline (table, TAL_1, 0, x.n_consts + 2 + x.n_cols - 1, 2); + tab_vline (table, TAL_1, x.n_consts + 2 + x.n_cols - 1, 0, 1); /* Title. */ ds_init_empty (&title); - for (i = 0; i < pt->n_consts + 2; i++) + for (i = 0; i < x.n_consts + 2; i++) { if (i) ds_put_cstr (&title, " * "); - ds_put_cstr (&title, var_get_name (pt->vars[i])); + ds_put_cstr (&title, var_get_name (x.vars[i])); } for (i = 0; i < pt->n_consts; i++) { @@ -1348,10 +1341,8 @@ delete_missing (struct pivot_table *pt) /* Prepare table T for submission, and submit it. */ static void -submit (struct crosstabs_proc *proc, struct pivot_table *pt, - struct tab_table *t) +submit (struct pivot_table *pt, struct tab_table *t) { - struct crosstabs_dim_aux *aux; int i; if (t == NULL) @@ -1360,7 +1351,7 @@ submit (struct crosstabs_proc *proc, struct pivot_table *pt, tab_resize (t, -1, 0); if (tab_nr (t) == tab_t (t)) { - tab_destroy (t); + table_unref (&t->table); return; } tab_offset (t, 0, 0); @@ -1375,63 +1366,9 @@ submit (struct crosstabs_proc *proc, struct pivot_table *pt, tab_nr (t) - 1); tab_vline (t, TAL_2, tab_l (t), 0, tab_nr (t) - 1); - aux = xmalloc (sizeof *aux); - aux->exclude = proc->exclude; - tab_dim (t, crosstabs_dim, crosstabs_dim_free, aux); - tab_submit (t); } -/* Sets the widths of all the columns and heights of all the rows in - table T for driver D. */ -static void -crosstabs_dim (struct tab_rendering *r, void *aux_) -{ - const struct tab_table *t = r->table; - struct outp_driver *d = r->driver; - struct crosstabs_dim_aux *aux = aux_; - int i; - - /* Width of a numerical column. */ - int c = outp_string_width (d, "0.000000", OUTP_PROPORTIONAL); - if (aux->exclude == MV_NEVER) - c += outp_string_width (d, "M", OUTP_PROPORTIONAL); - - /* Set width for header columns. */ - if (tab_l (t) != 0) - { - size_t i; - int w; - - w = d->width - c * (tab_nc (t) - tab_l (t)); - for (i = 0; i <= tab_nc (t); i++) - w -= r->wrv[i]; - w /= tab_l (t); - - if (w < d->prop_em_width * 8) - w = d->prop_em_width * 8; - - if (w > d->prop_em_width * 15) - w = d->prop_em_width * 15; - - for (i = 0; i < tab_l (t); i++) - r->w[i] = w; - } - - for (i = tab_l (t); i < tab_nc (t); i++) - r->w[i] = c; - - for (i = 0; i < tab_nr (t); i++) - r->h[i] = tab_natural_height (r, i); -} - -static void -crosstabs_dim_free (void *aux_) -{ - struct crosstabs_dim_aux *aux = aux_; - free (aux); -} - static bool find_crosstab (struct pivot_table *pt, size_t *row0p, size_t *row1p) { @@ -1556,10 +1493,10 @@ static void display_dimensions (struct crosstabs_proc *proc, struct pivot_table *pt, struct tab_table *table, int first_difference) { - tab_hline (table, TAL_1, pt->n_vars - first_difference - 1, tab_nc (table) - 1, 0); + tab_hline (table, TAL_1, pt->n_consts + pt->n_vars - first_difference - 1, tab_nc (table) - 1, 0); for (; first_difference >= 2; first_difference--) - table_value_missing (proc, table, pt->n_vars - first_difference - 1, 0, + table_value_missing (proc, table, pt->n_consts + pt->n_vars - first_difference - 1, 0, TAB_RIGHT, &pt->entries[0]->values[first_difference], pt->vars[first_difference]); } @@ -1601,15 +1538,16 @@ display_crosstabulation (struct crosstabs_proc *proc, struct pivot_table *pt, double *mp; for (r = 0; r < pt->n_rows; r++) - table_value_missing (proc, table, pt->n_vars - 2, r * proc->n_cells, - TAB_RIGHT, &pt->rows[r], pt->vars[ROW_VAR]); + table_value_missing (proc, table, pt->n_consts + pt->n_vars - 2, + r * proc->n_cells, TAB_RIGHT, &pt->rows[r], + pt->vars[ROW_VAR]); tab_text (table, pt->n_vars - 2, pt->n_rows * proc->n_cells, TAB_LEFT, _("Total")); /* Put in the actual cells. */ mp = pt->mat; - tab_offset (table, pt->n_vars - 1, -1); + tab_offset (table, pt->n_consts + pt->n_vars - 1, -1); for (r = 0; r < pt->n_rows; r++) { if (proc->n_cells > 1)