X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcharts%2Fplot-hist.c;h=fbf1925e635e165c3c096d119bace8123fa0d5bc;hb=bd17d2af982332ee1791998361b1ac6731fe14fa;hp=88ad0899199d939dd5411cfb8fb2656368e395a4;hpb=f5d9f9911bd04682a7edfb48521a12202e561e0a;p=pspp-builds.git diff --git a/src/output/charts/plot-hist.c b/src/output/charts/plot-hist.c index 88ad0899..fbf1925e 100644 --- a/src/output/charts/plot-hist.c +++ b/src/output/charts/plot-hist.c @@ -4,7 +4,7 @@ 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 the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -30,73 +30,74 @@ #include #include #include +#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) /* Write the legend of the chart */ -void -histogram_write_legend(struct chart *ch, const struct normal_curve *norm) +static void +histogram_write_legend (struct chart *ch, double n, double mean, double stddev) { char buf[100]; - if ( !ch ) + + if (!ch) return ; - pl_savestate_r(ch->lp); + pl_savestate_r (ch->lp); - sprintf(buf,"N = %.2f",norm->N); - pl_move_r(ch->lp, ch->legend_left, ch->data_bottom); - pl_alabel_r(ch->lp,0,'b',buf); + sprintf (buf, "N = %.2f", n); + pl_move_r (ch->lp, ch->legend_left, ch->data_bottom); + pl_alabel_r (ch->lp, 0, 'b', buf); - sprintf(buf,"Mean = %.1f",norm->mean); - pl_fmove_r(ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5); - pl_alabel_r(ch->lp,0,'b',buf); + sprintf (buf, "Mean = %.1f", mean); + pl_fmove_r (ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5); + pl_alabel_r (ch->lp, 0, 'b', buf); - sprintf(buf,"Std. Dev = %.2f",norm->stddev); - pl_fmove_r(ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5 * 2); - pl_alabel_r(ch->lp,0,'b',buf); + sprintf (buf, "Std. Dev = %.2f", stddev); + pl_fmove_r (ch->lp, ch->legend_left, ch->data_bottom + ch->font_size * 1.5 * 2); + pl_alabel_r (ch->lp, 0, 'b', buf); - pl_restorestate_r(ch->lp); + pl_restorestate_r (ch->lp); } -static void hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar); +static void hist_draw_bar (struct chart *ch, const struct histogram *hist, int bar); static void -hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar) +hist_draw_bar (struct chart *ch, const struct histogram *hist, int bar) { - if ( !ch ) + if (!ch) return ; - { double upper; double lower; double height; - const size_t bins = gsl_histogram_bins(hist); + const size_t bins = gsl_histogram_bins (hist->gsl_hist); const double x_pos = (ch->data_right - ch->data_left) * bar / (double) bins ; const double width = (ch->data_right - ch->data_left) / (double) bins ; + assert ( 0 == gsl_histogram_get_range (hist->gsl_hist, bar, &lower, &upper)); - assert ( 0 == gsl_histogram_get_range(hist, bar, &lower, &upper)); - - assert( upper >= lower); + assert ( upper >= lower); - height = gsl_histogram_get(hist, bar) * - (ch->data_top - ch->data_bottom) / gsl_histogram_max_val(hist); + height = gsl_histogram_get (hist->gsl_hist, bar) * + (ch->data_top - ch->data_bottom) / gsl_histogram_max_val (hist->gsl_hist); - pl_savestate_r(ch->lp); - pl_move_r(ch->lp,ch->data_left, ch->data_bottom); - pl_fillcolorname_r(ch->lp, ch->fill_colour); - pl_filltype_r(ch->lp,1); + pl_savestate_r (ch->lp); + pl_move_r (ch->lp,ch->data_left, ch->data_bottom); + pl_fillcolorname_r (ch->lp, ch->fill_colour); + pl_filltype_r (ch->lp,1); - pl_fboxrel_r(ch->lp, + pl_fboxrel_r (ch->lp, x_pos, 0, x_pos + width, height); - pl_restorestate_r(ch->lp); + pl_restorestate_r (ch->lp); draw_tick (ch, TICK_ABSCISSA, x_pos + width / 2.0, "%g", (upper + lower) / 2.0); @@ -105,76 +106,87 @@ hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar) +void +histogram_plot (const struct histogram *hist, + const char *label, + const struct moments1 *m) +{ + double mean, var, n; + + moments1_calculate (m, &n, &mean, &var, NULL, NULL); + + histogram_plot_n (hist, label, n, mean, sqrt(var), m); +} + +/* This function is deprecated. Don't use it in new code */ void -histogram_plot(const gsl_histogram *hist, - const char *factorname, - const struct normal_curve *norm, short show_normal) +histogram_plot_n (const struct histogram *hist, + const char *label, + double n, double mean, double stddev, + bool show_normal) { int i; int bins; - struct chart *ch; - - ch = chart_create(); - if (ch == NULL) - return; + struct chart *ch = chart_create (); - chart_write_title(ch, _("HISTOGRAM")); + chart_write_title (ch, _("HISTOGRAM")); - chart_write_ylabel(ch, _("Frequency")); - chart_write_xlabel(ch, factorname); + chart_write_ylabel (ch, _("Frequency")); + chart_write_xlabel (ch, label); if ( ! hist ) /* If this happens, probably all values are SYSMIS */ { - chart_submit(ch); - return ; + chart_submit (ch); + return; } else { - bins = gsl_histogram_bins(hist); + bins = gsl_histogram_bins (hist->gsl_hist); } - chart_write_yscale(ch, 0, gsl_histogram_max_val(hist), 5); + chart_write_yscale (ch, 0, gsl_histogram_max_val (hist->gsl_hist), 5); for ( i = 0 ; i < bins ; ++i ) - hist_draw_bar(ch, hist, i); + hist_draw_bar (ch, hist, i); - histogram_write_legend(ch, norm); + histogram_write_legend (ch, n, mean, stddev); - if ( show_normal ) - { - /* Draw the normal curve */ - - double d ; - double x_min, x_max, not_used ; - double abscissa_scale ; - double ordinate_scale ; - double range ; - - gsl_histogram_get_range(hist, 0, &x_min, ¬_used); - range = not_used - x_min; - gsl_histogram_get_range(hist, bins - 1, ¬_used, &x_max); - - abscissa_scale = (ch->data_right - ch->data_left) / (x_max - x_min); - ordinate_scale = (ch->data_top - ch->data_bottom) / - gsl_histogram_max_val(hist) ; - - pl_move_r(ch->lp, ch->data_left, ch->data_bottom); - for( d = ch->data_left; - d <= ch->data_right ; - d += (ch->data_right - ch->data_left) / 100.0) - { - const double x = (d - ch->data_left) / abscissa_scale + x_min ; - const double y = norm->N * range * - gsl_ran_gaussian_pdf(x - norm->mean, norm->stddev); - - pl_fcont_r(ch->lp, d, ch->data_bottom + y * ordinate_scale); - - } - pl_endpath_r(ch->lp); + if (show_normal) + { + /* Draw the normal curve */ + + double d ; + double x_min, x_max, not_used ; + double abscissa_scale ; + double ordinate_scale ; + double range ; + + gsl_histogram_get_range (hist->gsl_hist, 0, &x_min, ¬_used); + range = not_used - x_min; + gsl_histogram_get_range (hist->gsl_hist, bins - 1, ¬_used, &x_max); + + abscissa_scale = (ch->data_right - ch->data_left) / (x_max - x_min); + ordinate_scale = (ch->data_top - ch->data_bottom) / + gsl_histogram_max_val (hist->gsl_hist) ; + + pl_move_r (ch->lp, ch->data_left, ch->data_bottom); + for ( d = ch->data_left; + d <= ch->data_right ; + d += (ch->data_right - ch->data_left) / 100.0) + { + const double x = (d - ch->data_left) / abscissa_scale + x_min ; + const double y = n * range * + gsl_ran_gaussian_pdf (x - mean, stddev); + + pl_fcont_r (ch->lp, d, ch->data_bottom + y * ordinate_scale); + + } + pl_endpath_r (ch->lp); + } - } - chart_submit(ch); + chart_submit (ch); } +