From: John Darrington Date: Thu, 24 Sep 2009 18:43:42 +0000 (+0200) Subject: Merge commit 'origin/stable' X-Git-Tag: build40 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp-builds.git;a=commitdiff_plain;h=bd17d2af982332ee1791998361b1ac6731fe14fa Merge commit 'origin/stable' Conflicts: AUTHORS NEWS configure.ac lib/gtksheet/gtkitementry.c po/LINGUAS po/nl.po src/data/file-name.c src/data/sys-file-writer.c src/language/stats/crosstabs.q src/language/stats/examine.q src/language/stats/t-test.q src/output/charts/box-whisker.c src/output/charts/plot-hist.c src/ui/gui/output-viewer.c src/ui/gui/psppire.c src/ui/gui/psppire.h src/ui/terminal/main.c --- bd17d2af982332ee1791998361b1ac6731fe14fa diff --cc NEWS index df10031e,61a49386..1798fdd3 --- a/NEWS +++ b/NEWS @@@ -5,27 -5,91 +5,113 @@@ See the end for copying conditions Please send PSPP bug reports to bug-gnu-pspp@gnu.org. +Changes from 0.7.1 to 0.7.2: + + * Updated Perl module interface. + + * Value labels for long string variables are now supported. + + * Missing values for long string variables are now supported. + +Changes from 0.7.0 to 0.7.1: + + * Added a perl module to facilitate reading and writing of pspp system + files from perl programs. + - Changes from 0.6.1 to 0.7.0: ++Changes from 0.6.2-pre6 to 0.7.0: + + * Custom variable and data file attributes are now supported. + Commands VARIABLE ATTRIBUTE and DATAFILE ATTRIBUTE have been added + for setting and clear attributes. Support for attributes has also + been added to commands that read and write system files, such as + SAVE and GET, as well as to the DISPLAY command. + + Changes from 0.6.1 to 0.6.2-pre6: + + * New translations: + + - Dutch, thanks to Harry Thijssen. + + - Brazilian Portuguese, thanks to Michel Boaventura. + + Thanks for translations are also due to the coordinators at + translationproject.org. + + * Statistical bug fixes: + + - REGRESSION: Report correct standard error of the estimate (bug + #25677). + + - T-TEST: Report correct significance of paired sample T-test in + the common case (bug #26936) and corner cases. Thanks to Mike + Griffiths and Matej Cepl for reporting these bugs. + + * Build fixes and changes: + + - Make running "make" after running "configure" with different + settings reliably rebuild version.c. + + - Cygwin and MinGW build fixes. + + - Fixes for building with recent gnulib. + + - The Makefile now honors two new variables, PSPP_LDFLAGS and + PSPPIRE_LDFLAGS, that affect linking of the PSPP and PSPPIRE + binaries, respectively. This makes building easier for some + packagers. + + - Fixes for "configure --enable-relocatable" (bug #25508). + + * Data file bug fixes and changes: + + - Fix reading text data files that contain a mix of white space + and commas. Now "a ,b" is treated as two fields containing "a" + and "b"; previously it was treated as three, with an empty field + in the middle. + + - Fix writing corrupted .sav files on Windows. + + - Fix writing corrupted .por files (bug #26034). + + - Fix reading .por files whose initial lines are not padded out + with spaces as expected. + + - PSPP will no longer issue warnings about some .sav file records + or values that it does not understand. These warnings were + harmless, but needlessly alarmed some users. + + - Fix crash reading empty string fields from PostgreSQL databases. + + * Bug fixes that affect PSPP and PSPPIRE: + + - Users may now control precision of output statistics. Instead + of hard coding the width and decimals of output numbers, respect + the default format in most instances. Counts are now normally + displayed with the format of the weight variable, if any. + + - Fix crash when an INSERT command specifies the name of a file + that does not exist (bug #24569). + + - Fix crash when CROSSTABS specifies a long-string variable (bugs + #24557 and #26131). + + - Fix crash drawing pie charts with many segments. + + - Fix crash when NUMERIC specifies an invalid format. + + * PSPPIRE bug fixes and changes: + + - On Windows, write the output file to the user's home directory + instead of the current directory, to better match user + expectations. + + - Some data editor fixes. + + * Documentation: + + - Fix typo in BINOMIAL section of user manual (bug #25892). ++>>>>>>> origin/stable:NEWS + Changes from 0.6.0 to 0.6.1: * Statistical bug fixes: diff --cc po/automake.mk index 1f5ca31b,00000000..56715e1e mode 100644,000000..100644 --- a/po/automake.mk +++ b/po/automake.mk @@@ -1,54 -1,0 +1,54 @@@ +include $(top_srcdir)/po/Makevars + +XGETTEXT=xgettext +MSGMERGE=msgmerge +MSGFMT=msgfmt + - POFILES=po/en_GB.po po/nl.po ++POFILES=po/en_GB.po po/nl.po po/pt_BR.po + +POTFILE=po/$(DOMAIN).pot + +TRANSLATABLE_FILES = $(DIST_SOURCES) $(all_q_sources) + +$(POTFILE): $(TRANSLATABLE_FILES) + @$(MKDIR_P) po + $(XGETTEXT) --directory=$(top_srcdir) $(TRANSLATABLE_FILES) \ + $(XGETTEXT_OPTIONS) \ + --copyright-holder="$(COPYRIGHT_HOLDER)" \ + --package-name=$(PACKAGE) \ + --package-version=$(VERSION) \ + --msgid-bugs-address=$(MSGID_BUGS_ADDRESS) \ + --add-comments='TRANSLATORS:' \ + -o $(POTFILE) + + +$(POFILES): $(POTFILE) + $(MSGMERGE) $(top_srcdir)/$* $< -o $@ + +.po.gmo: + @$(MKDIR_P) `dirname $@` + $(MSGFMT) $< -o $@ + + +GMOFILES = $(POFILES:.po=.gmo) + +ALL_LOCAL += $(GMOFILES) + +install-data-hook: $(GMOFILES) + for f in $(GMOFILES); do \ + lang=`echo $$f | sed -e 's%po/\(.*\)\.gmo%\1%' ` ; \ + $(INSTALL) -D $$f $(DESTDIR)$(prefix)/share/locale/$$lang/LC_MESSAGES/$(DOMAIN).mo ; \ + done + + +uninstall-hook: + for f in $(GMOFILES); do \ + lang=`echo $$f | sed -e 's%po/\(.*\)\.gmo%\1%' ` ; \ + $(RM) $(DESTDIR)$(prefix)/share/locale/$$lang/LC_MESSAGES/$(DOMAIN).mo ; \ + done + + +EXTRA_DIST += $(POFILES) $(POTFILE) + +CLEANFILES += $(POFILES) $(GMOFILES) $(POTFILE) + diff --cc src/data/file-name.c index 601afd55,6be5ef0a..91229595 --- a/src/data/file-name.c +++ b/src/data/file-name.c @@@ -476,7 -476,7 +476,6 @@@ default_output_path (void const char *home_drive = getenv ("HOMEDRIVE"); const char *home_path = getenv ("HOMEPATH"); -- if (home_drive != NULL && home_path != NULL) home_dir = xasprintf ("%s%s", home_drive, home_path); @@@ -485,9 -485,16 +484,15 @@@ if (home_dir == NULL) home_dir = "c:/users/default"; /* poor default */ - path = xasprintf ("%s%c", home_dir, '/'); - + /* Copy home_dir into path. Add a slash at the end but + only if there isn't already one there, because Windows + treats // specially. */ + if (home_dir[0] == '\0' + || strchr ("/\\", home_dir[strlen (home_dir) - 1]) == NULL) + path = xasprintf ("%s%c", home_dir, '/'); + else + path = xstrdup (home_dir); - for(i = 0; i < strlen (path); i++) if (path[i] == '\\') path[i] = '/'; } diff --cc src/data/sys-file-writer.c index 3fed2e05,001b78f1..5daea89d --- a/src/data/sys-file-writer.c +++ b/src/data/sys-file-writer.c @@@ -461,12 -435,11 +461,12 @@@ write_variable (struct sfm_writer *w, c /* Value label. */ if (var_has_label (v)) { -- const char *label = var_get_label (v); - char *l = recode_string (dict_get_encoding (dict), UTF8, label, -1); - size_t padded_len = ROUND_UP (MIN (strlen (l), 255), 4); - write_int (w, padded_len); - write_string (w, l, padded_len); - free (l); ++ char *label = recode_string (dict_get_encoding (dict), UTF8, var_get_label (v), -1); + size_t label_len = MIN (strlen (label), 255); + size_t padded_len = ROUND_UP (label_len, 4); + write_int (w, label_len); + write_string (w, label, padded_len); ++ free (label); } /* Write the missing values, if any, range first. */ diff --cc src/language/stats/examine.q index e8333b1c,592bb56b..08077942 --- a/src/language/stats/examine.q +++ b/src/language/stats/examine.q @@@ -1803,205 -1453,605 +1803,204 @@@ show_extremes (const struct variable ** 0, 0, n_cols - 1, n_rows - 1); - tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows ); - tab_vline (tbl, TAL_1, heading_columns, 0, n_rows - 1); - tab_vline (tbl, TAL_2, n_cols - 2, 0, n_rows - 1); + tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows ); + tab_hline (tbl, TAL_2, 1, n_cols - 1, heading_rows ); tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows - 1); - tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, _ ("Statistic")); - tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, _ ("Std. Error")); + if ( fctr->indep_var[0]) + tab_text (tbl, 1, 0, TAT_TITLE, var_to_string (fctr->indep_var[0])); - tab_title (tbl, _ ("Descriptives")); + if ( fctr->indep_var[1]) + tab_text (tbl, 2, 0, TAT_TITLE, var_to_string (fctr->indep_var[1])); - - for ( i = 0 ; i < n_dep_var ; ++i ) + for (v = 0 ; v < n_dep_var ; ++v ) { - const int row = heading_rows + i * n_stat_rows * n_factors ; - - if ( i > 0 ) - tab_hline (tbl, TAL_1, 0, n_cols - 1, row ); + struct ll *ll; + int i = 0; + const int row_var_start = v * cmd.st_n * 2 * ll_count(&fctr->result_list); - tab_text (tbl, 0, - i * n_stat_rows * n_factors + heading_rows, + tab_text (tbl, + 0, + heading_rows + row_var_start, TAB_LEFT | TAT_TITLE, - var_to_string (dependent_var[i]) + var_to_string (dependent_var[v]) ); - - if ( fctr ) + for (ll = ll_head (&fctr->result_list); + ll != ll_null (&fctr->result_list); i++, ll = ll_next (ll)) { - const union value *prev = NULL; + int e ; + struct ll *min_ll; + struct ll *max_ll; + const int row_result_start = i * cmd.st_n * 2; - struct factor_statistics **fs = fctr->fs; - int count = 0; + const struct factor_result *result = + ll_data (ll, struct factor_result, ll); - tab_text (tbl, 1, heading_rows - 1, TAB_CENTER | TAT_TITLE, - var_to_string (fctr->indep_var[0])); + if (i > 0 || v > 0) + tab_hline (tbl, TAL_1, 1, n_cols - 1, + heading_rows + row_var_start + row_result_start); + tab_hline (tbl, TAL_1, heading_columns - 2, n_cols - 1, + heading_rows + row_var_start + row_result_start + cmd.st_n); - if ( fctr->indep_var[1]) - tab_text (tbl, 2, heading_rows - 1, TAB_CENTER | TAT_TITLE, - var_to_string (fctr->indep_var[1])); - - while ( *fs ) + for ( e = 1; e <= cmd.st_n; ++e ) { - const int row = heading_rows + n_stat_rows * - ( ( i * n_factors ) + count ); - - - if ( !prev || 0 != compare_values (prev, (*fs)->id[0], - var_get_width (fctr->indep_var[0]))) - { - struct string vstr; - ds_init_empty (&vstr); - var_append_value_name (fctr->indep_var[0], - (*fs)->id[0], &vstr); + tab_text_format (tbl, n_cols - 3, + heading_rows + row_var_start + row_result_start + e - 1, + TAB_RIGHT, + "%d", e); + + tab_text_format (tbl, n_cols - 3, + heading_rows + row_var_start + row_result_start + cmd.st_n + e - 1, + TAB_RIGHT, + "%d", e); + } - if ( count > 0 ) - tab_hline (tbl, TAL_1, 1, n_cols - 1, row); - tab_text (tbl, - 1, row, - TAB_LEFT | TAT_TITLE, - ds_cstr (&vstr) - ); + min_ll = ll_head (extrema_list (result->metrics[v].minima)); + for (e = 0; e < cmd.st_n;) + { + struct extremum *minimum = ll_data (min_ll, struct extremum, ll); + double weight = minimum->weight; - ds_destroy (&vstr); + while (weight-- > 0 && e < cmd.st_n) + { + tab_double (tbl, n_cols - 1, + heading_rows + row_var_start + row_result_start + cmd.st_n + e, + TAB_RIGHT, + minimum->value, + NULL); + + + tab_fixed (tbl, n_cols - 2, + heading_rows + row_var_start + + row_result_start + cmd.st_n + e, + TAB_RIGHT, + minimum->location, + 10, 0); + ++e; } - prev = (*fs)->id[0]; + min_ll = ll_next (min_ll); + } - - if (fctr->indep_var[1] && count > 0 ) - tab_hline (tbl, TAL_1, 2, n_cols - 1, row); + max_ll = ll_head (extrema_list (result->metrics[v].maxima)); + for (e = 0; e < cmd.st_n;) + { + struct extremum *maximum = ll_data (max_ll, struct extremum, ll); + double weight = maximum->weight; - if ( fctr->indep_var[1]) + while (weight-- > 0 && e < cmd.st_n) { - struct string vstr; - ds_init_empty (&vstr); - var_append_value_name (fctr->indep_var[1], (*fs)->id[1], &vstr); - - tab_text (tbl, 2, row, - TAB_LEFT | TAT_TITLE, - ds_cstr (&vstr) - ); - - ds_destroy (&vstr); + tab_double (tbl, n_cols - 1, + heading_rows + row_var_start + + row_result_start + e, + TAB_RIGHT, + maximum->value, + NULL); + + + tab_fixed (tbl, n_cols - 2, + heading_rows + row_var_start + + row_result_start + e, + TAB_RIGHT, + maximum->location, + 10, 0); + ++e; } - populate_descriptives (tbl, heading_columns - 2, - row, - dependent_var[i], - & (*fs)->m[i]); - - count++ ; - fs++; + max_ll = ll_next (max_ll); } - } - - else - { - - populate_descriptives (tbl, heading_columns - 2, - i * n_stat_rows * n_factors + heading_rows, - dependent_var[i], - &totals[i]); - } - } - - tab_submit (tbl); -} - - -/* Fill in the descriptives data */ -static void -populate_descriptives (struct tab_table *tbl, int col, int row, - const struct variable *var, - const struct metrics *m) -{ - const double t = gsl_cdf_tdist_Qinv ((1 - cmd.n_cinterval[0] / 100.0)/2.0, - m->n -1); - - tab_text (tbl, col, - row, - TAB_LEFT | TAT_TITLE, - _ ("Mean")); - - tab_double (tbl, col + 2, - row, - TAB_CENTER, - m->mean, - NULL); - - tab_double (tbl, col + 3, - row, - TAB_CENTER, - m->se_mean, - NULL); - - - tab_text (tbl, col, - row + 1, - TAB_LEFT | TAT_TITLE | TAT_PRINTF, - _ ("%g%% Confidence Interval for Mean"), cmd.n_cinterval[0]); - - - tab_text (tbl, col + 1, - row + 1, - TAB_LEFT | TAT_TITLE, - _ ("Lower Bound")); - - tab_double (tbl, col + 2, - row + 1, - TAB_CENTER, - m->mean - t * m->se_mean, - NULL); - - tab_text (tbl, col + 1, - row + 2, - TAB_LEFT | TAT_TITLE, - _ ("Upper Bound")); - - - tab_double (tbl, col + 2, - row + 2, - TAB_CENTER, - m->mean + t * m->se_mean, - NULL); - - tab_text (tbl, col, - row + 3, - TAB_LEFT | TAT_TITLE | TAT_PRINTF, - _ ("5%% Trimmed Mean")); - - tab_double (tbl, col + 2, - row + 3, - TAB_CENTER, - m->trimmed_mean, - NULL); - - tab_text (tbl, col, - row + 4, - TAB_LEFT | TAT_TITLE, - _ ("Median")); - - { - struct percentile *p; - double d = 50; - - p = hsh_find (m->ptile_hash, &d); - - assert (p); - - - tab_double (tbl, col + 2, - row + 4, - TAB_CENTER, - p->v, - NULL); - } - - - tab_text (tbl, col, - row + 5, - TAB_LEFT | TAT_TITLE, - _ ("Variance")); - - tab_double (tbl, col + 2, - row + 5, - TAB_CENTER, - m->var, - NULL); - - - tab_text (tbl, col, - row + 6, - TAB_LEFT | TAT_TITLE, - _ ("Std. Deviation")); - - - tab_double (tbl, col + 2, - row + 6, - TAB_CENTER, - m->stddev, - NULL); - - - tab_text (tbl, col, - row + 7, - TAB_LEFT | TAT_TITLE, - _ ("Minimum")); - - tab_double (tbl, col + 2, - row + 7, - TAB_CENTER, - m->min, var_get_print_format (var)); - - tab_text (tbl, col, - row + 8, - TAB_LEFT | TAT_TITLE, - _ ("Maximum")); - - tab_double (tbl, col + 2, - row + 8, - TAB_CENTER, - m->max, var_get_print_format (var)); - - tab_text (tbl, col, - row + 9, - TAB_LEFT | TAT_TITLE, - _ ("Range")); - - - tab_double (tbl, col + 2, - row + 9, - TAB_CENTER, - m->max - m->min, - NULL); - - tab_text (tbl, col, - row + 10, - TAB_LEFT | TAT_TITLE, - _ ("Interquartile Range")); - - { - struct percentile *p1; - struct percentile *p2; - - double d = 75; - p1 = hsh_find (m->ptile_hash, &d); - - d = 25; - p2 = hsh_find (m->ptile_hash, &d); - - assert (p1); - assert (p2); - - tab_double (tbl, col + 2, - row + 10, - TAB_CENTER, - p1->v - p2->v, - NULL); - } - - tab_text (tbl, col, - row + 11, - TAB_LEFT | TAT_TITLE, - _ ("Skewness")); - - - tab_double (tbl, col + 2, - row + 11, - TAB_CENTER, - m->skewness, - NULL); - - /* stderr of skewness */ - tab_double (tbl, col + 3, - row + 11, - TAB_CENTER, - calc_seskew (m->n), - NULL); - - tab_text (tbl, col, - row + 12, - TAB_LEFT | TAT_TITLE, - _ ("Kurtosis")); - - - tab_double (tbl, col + 2, - row + 12, - TAB_CENTER, - m->kurtosis, - NULL); - - /* stderr of kurtosis */ - tab_double (tbl, col + 3, - row + 12, - TAB_CENTER, - calc_sekurt (m->n), - NULL); -} - - - -void -box_plot_variables (const struct factor *fctr, - const struct variable **vars, int n_vars, - const struct variable *id) -{ - - int i; - struct factor_statistics **fs ; - - if ( ! fctr ) - { - box_plot_group (fctr, vars, n_vars, id); - return; - } - - for ( fs = fctr->fs ; *fs ; ++fs ) - { - struct string str; - double y_min = DBL_MAX; - double y_max = -DBL_MAX; - struct chart *ch = chart_create (); - if (ch == NULL) - break; - - ds_init_empty (&str); - factor_to_string (fctr, *fs, 0, &str ); - - chart_write_title (ch, "%s", ds_cstr (&str)); - - for ( i = 0 ; i < n_vars ; ++i ) - { - y_max = MAX (y_max, (*fs)->m[i].max); - y_min = MIN (y_min, (*fs)->m[i].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) - / (n_vars * 2.0 ) ; - - const double box_centre = ( i * 2 + 1) * box_width - + ch->data_left; - - boxplot_draw_boxplot (ch, - box_centre, box_width, - & (*fs)->m[i], - var_to_string (vars[i])); - - } - - chart_submit (ch); - ds_destroy (&str); - } -} - - - -/* Do a box plot, grouping all factors into one plot ; - each dependent variable has its own plot. -*/ -void -box_plot_group (const struct factor *fctr, - const struct variable **vars, - int n_vars, - const struct variable *id UNUSED) -{ - - int i; - - for ( i = 0 ; i < n_vars ; ++i ) - { - struct factor_statistics **fs ; - struct chart *ch; - - ch = chart_create (); - if (ch == NULL) - break; - - 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; - - 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 ) + if ( fctr->indep_var[0]) { - struct string str; - 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; - - ds_init_empty (&str); - factor_to_string_concise (fctr, *fs, &str); + struct string vstr; + ds_init_empty (&vstr); + var_append_value_name (fctr->indep_var[0], + &result->value[0], &vstr); + + tab_text (tbl, 1, + heading_rows + row_var_start + row_result_start, + TAB_LEFT, + ds_cstr (&vstr) + ); - boxplot_draw_boxplot (ch, - box_centre, box_width, - & (*fs)->m[i], - ds_cstr (&str)); - ds_destroy (&str); + ds_destroy (&vstr); } - } - 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; - chart_write_title (ch, _ ("Boxplot")); - boxplot_draw_boxplot (ch, - box_centre, box_width, - &totals[i], - var_to_string (vars[i]) ); + tab_text (tbl, n_cols - 4, + heading_rows + row_var_start + row_result_start, + TAB_RIGHT, + _("Highest")); + tab_text (tbl, n_cols - 4, + heading_rows + row_var_start + row_result_start + cmd.st_n, + TAB_RIGHT, + _("Lowest")); } - - chart_submit (ch); } -} - - -/* Plot the normal and detrended normal plots for m - Label the plots with factorname */ -void -np_plot (const struct metrics *m, const char *factorname) -{ - int i; - double yfirst=0, ylast=0; - - /* Normal Plot */ - struct chart *np_chart; - - /* Detrended Normal Plot */ - struct chart *dnp_chart; - - /* The slope and intercept of the ideal normal probability line */ - const double slope = 1.0 / m->stddev; - const double intercept = - m->mean / m->stddev; - - /* Cowardly refuse to plot an empty data set */ - if ( m->n_data == 0 ) - return ; - - np_chart = chart_create (); - dnp_chart = chart_create (); - - if ( !np_chart || ! dnp_chart ) - return ; - - 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")); - - 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)); - - - { - /* Need to make sure that both the scatter plot and the ideal fit into the - plot */ - double x_lower = MIN (m->min, (yfirst - intercept) / slope) ; - 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 (dnp_chart, m->min, m->max, 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 = xnmalloc (m->n_data, sizeof *d_data); - 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)); + tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1); - chart_datum (np_chart, 0, m->wvp[i]->v.f, ns); - d_data[i] = (m->wvp[i]->v.f - m->mean) / m->stddev - ns; + tab_title (tbl, _("Extreme Values")); - 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]); + tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, + _("Case Number")); - 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); + tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, + _("Value")); - chart_submit (np_chart); - chart_submit (dnp_chart); + tab_submit (tbl); } +#define PERCENTILE_ROWS 2 - - -/* Show the percentiles */ -void +static void show_percentiles (const struct variable **dependent_var, - int n_dep_var, - struct factor *fctr) + int n_dep_var, + const struct xfactor *fctr) { - struct tab_table *tbl; int i; + int v; + int heading_columns = 2; + int n_cols; + const int n_percentiles = subc_list_double_count (&percentile_list); + const int heading_rows = 2; + struct tab_table *tbl; - int n_cols, n_rows; - int n_factors; - - struct hsh_table *ptiles ; - - int n_heading_columns; - const int n_heading_rows = 2; - const int n_stat_rows = 2; + int n_rows ; + n_rows = n_dep_var; - int n_ptiles ; + assert (fctr); - if ( fctr ) + if ( fctr->indep_var[0] ) { - struct factor_statistics **fs = fctr->fs ; - n_heading_columns = 3; - n_factors = hsh_count (fctr->fstats); - - ptiles = (*fs)->m[0].ptile_hash; + heading_columns = 3; if ( fctr->indep_var[1] ) - n_heading_columns = 4; - } - else - { - n_factors = 1; - n_heading_columns = 2; - - ptiles = totals[0].ptile_hash; + { + heading_columns = 4; + } } - n_ptiles = hsh_count (ptiles); - - n_rows = n_heading_rows + n_dep_var * n_stat_rows * n_factors; + n_rows *= ll_count (&fctr->result_list) * PERCENTILE_ROWS; + n_rows += heading_rows; - n_cols = n_heading_columns + n_ptiles ; + n_cols = heading_columns + n_percentiles; tbl = tab_create (n_cols, n_rows, 0); + tab_headers (tbl, heading_columns, 0, heading_rows, 0); - tab_headers (tbl, n_heading_columns + 1, 0, n_heading_rows, 0); - - tab_dim (tbl, tab_natural_dimensions); + tab_dim (tbl, tab_natural_dimensions, NULL); - /* Outline the box and have no internal lines*/ + /* Outline the box */ tab_box (tbl, TAL_2, TAL_2, -1, -1, diff --cc src/language/stats/t-test.q index d25477cd,ba7e9388..c448d52e --- a/src/language/stats/t-test.q +++ b/src/language/stats/t-test.q @@@ -47,8 -45,7 +47,9 @@@ #include #include ++#include "minmax.h" #include "xalloc.h" +#include "xmemdup0.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@@ -1091,40 -1411,49 +1092,44 @@@ pscbox (struct t_test_proc *proc struct tab_table *table; - table = tab_create (cols,rows,0); + table = tab_create (cols, rows, 0); tab_columns (table, SOM_COL_DOWN, 1); - tab_headers (table,0,0,1,0); - tab_box (table, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols -1, rows -1 ); + tab_headers (table, 0, 0, 1, 0); + tab_box (table, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols - 1, rows - 1); tab_hline (table, TAL_2, 0, cols - 1, 1); tab_vline (table, TAL_2, 2, 0, rows - 1); - tab_dim (table, tab_natural_dimensions); - tab_title (table, _ ("Paired Samples Correlations")); + tab_dim (table, tab_natural_dimensions, NULL); + tab_title (table, _("Paired Samples Correlations")); /* column headings */ - tab_text (table, 2,0, TAB_CENTER | TAT_TITLE, _ ("N")); - tab_text (table, 3,0, TAB_CENTER | TAT_TITLE, _ ("Correlation")); - tab_text (table, 4,0, TAB_CENTER | TAT_TITLE, _ ("Sig.")); + tab_text (table, 2, 0, TAB_CENTER | TAT_TITLE, _("N")); + tab_text (table, 3, 0, TAB_CENTER | TAT_TITLE, _("Correlation")); + tab_text (table, 4, 0, TAB_CENTER | TAT_TITLE, _("Sig.")); - for (i=0; i < n_pairs; ++i) + for (i = 0; i < proc->n_pairs; i++) { - double p,q; - - double df = pairs[i].n -2; + struct pair *pair = &proc->pairs[i]; ++ double df = pair->n - 2; + double p, q; - double df = pair->n -2; - double correlation_t = (pair->correlation * sqrt (df) / - sqrt (1 - pow2 (pair->correlation))); + + /* corr2 will mathematically always be in the range [0, 1.0]. Inaccurate + calculations sometimes cause it to be slightly greater than 1.0, so + force it into the correct range to avoid NaN from sqrt(). */ - double corr2 = MIN (1.0, pow2 (pairs[i].correlation)); - double correlation_t = - pairs[i].correlation * sqrt (df) / - sqrt (1 - corr2); - ++ double corr2 = MIN (1.0, pow2 (pair->correlation)); ++ double correlation_t = pair->correlation * sqrt (df) / sqrt (1 - corr2); /* row headings */ - tab_text (table, 0,i+1, TAB_LEFT | TAT_TITLE | TAT_PRINTF, - _ ("Pair %d"), i); - - tab_text (table, 1,i+1, TAB_LEFT | TAT_TITLE | TAT_PRINTF, - _ ("%s & %s"), - var_get_name (pairs[i].v[0]), - var_get_name (pairs[i].v[1])); - + tab_text_format (table, 0, i + 1, TAB_LEFT | TAT_TITLE, + _("Pair %d"), i); + tab_text_format (table, 1, i + 1, TAB_LEFT | TAT_TITLE, + _("%s & %s"), + var_get_name (pair->v[0]), + var_get_name (pair->v[1])); /* row data */ - tab_double (table, 2, i+1, TAB_RIGHT, pairs[i].n, wfmt); - tab_double (table, 3, i+1, TAB_RIGHT, pairs[i].correlation, NULL); + tab_double (table, 2, i + 1, TAB_RIGHT, pair->n, &proc->weight_format); + tab_double (table, 3, i + 1, TAB_RIGHT, pair->correlation, NULL); p = gsl_cdf_tdist_P (correlation_t, df); q = gsl_cdf_tdist_Q (correlation_t, df); diff --cc src/output/charts/box-whisker.c index c3641580,8bcad494..33c445b0 --- a/src/output/charts/box-whisker.c +++ b/src/output/charts/box-whisker.c @@@ -1,5 -1,5 +1,5 @@@ /* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2008 Free Software Foundation, Inc. - Copyright (C) 2004, 2009 Free Software Foundation, Inc. ++ Copyright (C) 2004, 2008, 2009 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 @@@ -134,26 -182,37 +134,26 @@@ boxplot_draw_boxplot (struct chart *ch box_centre, box_bottom); /* (top half) */ - pl_fline_r(ch->lp, + pl_fline_r (ch->lp, box_centre, top_whisker, box_centre, box_top); - } - /* Draw outliers */ - for ( i = 0 ; i < n_data ; ++i ) + outliers = box_whisker_outliers (bw); + for (ll = ll_head (outliers); + ll != ll_null (outliers); ll = ll_next (ll)) { - if ( wvp[i]->v.f >= hinge[2] + step ) - draw_outlier(ch, box_centre, wvp, i, - ( wvp[i]->v.f > hinge[2] + 2 * step ) - ); - - if ( wvp[i]->v.f <= hinge[0] - step ) - draw_outlier(ch, box_centre, wvp, i, - ( wvp[i]->v.f < hinge[0] - 2 * step ) - ); + const struct outlier *outlier = ll_data (ll, struct outlier, ll); + draw_case (ch, box_centre, outlier); } - /* Draw tick mark on x axis */ - draw_tick(ch, TICK_ABSCISSA, box_centre - ch->data_left, name); + draw_tick(ch, TICK_ABSCISSA, box_centre - ch->data_left, "%s", name); pl_restorestate_r(ch->lp); - } - - void -boxplot_draw_yscale(struct chart *ch , double y_max, double y_min) +boxplot_draw_yscale (struct chart *ch, double y_max, double y_min) { double y_tick; double d; diff --cc src/output/charts/plot-hist.c index 4b11618a,88ad0899..fbf1925e --- a/src/output/charts/plot-hist.c +++ b/src/output/charts/plot-hist.c @@@ -97,14 -96,10 +97,10 @@@ hist_draw_bar (struct chart *ch, const x_pos, 0, x_pos + width, height); - pl_restorestate_r(ch->lp); + pl_restorestate_r (ch->lp); - { - char buf[5]; - snprintf (buf,5,"%g", (upper + lower) / 2.0); - draw_tick (ch, TICK_ABSCISSA, - x_pos + width / 2.0, buf); - } + draw_tick (ch, TICK_ABSCISSA, + x_pos + width / 2.0, "%g", (upper + lower) / 2.0); } } diff --cc src/ui/gui/psppire.c index 3555463f,a7b22037..1cd7ee80 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@@ -89,10 -75,14 +89,9 @@@ initialize (struct command_line_process { PsppireDict *dictionary = 0; - /* gtk_init messes with the locale. - So unset the bits we want to control ourselves */ - setlocale (LC_NUMERIC, "C"); - - bindtextdomain (PACKAGE, relocate (locale_dir)); -- + i18n_init (); - glade_init (); + preregister_widgets (); gsl_set_error_handler_off (); fn_init (); diff --cc src/ui/gui/psppire.h index cfe49e91,815de4a0..27a633f2 --- a/src/ui/gui/psppire.h +++ b/src/ui/gui/psppire.h @@@ -17,16 -17,9 +17,16 @@@ #ifndef PSPPIRE_H #define PSPPIRE_H +#include -void initialize (void); +struct command_line_processor ; +extern const struct argp non_option_argp ; + +void initialize (struct command_line_processor *, int argc, char **argv); void de_initialize (void); ++ +void psppire_quit (void); + const char * output_file_name (void); - #endif /* PSPPIRE_H */ diff --cc src/ui/terminal/main.c index af8f7f2d,8acbdc2d..7ad162fc --- a/src/ui/terminal/main.c +++ b/src/ui/terminal/main.c @@@ -166,6 -141,21 +167,7 @@@ main (int argc, char **argv return any_errors (); } -static void -i18n_init (void) -{ -#if ENABLE_NLS -#if HAVE_LC_MESSAGES - setlocale (LC_MESSAGES, ""); -#endif -#if HAVE_LC_PAPER - setlocale (LC_PAPER, ""); -#endif - bindtextdomain (PACKAGE, relocate (locale_dir)); - textdomain (PACKAGE); -#endif /* ENABLE_NLS */ -} + static void fpu_init (void) {