--- ray/src/cal/histo.c 2003/02/22 02:07:20 1.1 +++ ray/src/cal/histo.c 2003/12/14 16:33:37 1.4 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: histo.c,v 1.1 2003/02/22 02:07:20 greg Exp $"; +static const char RCSid[] = "$Id: histo.c,v 1.4 2003/12/14 16:33:37 greg Exp $"; #endif /* * Compute a histogram from input data @@ -9,6 +9,7 @@ static const char RCSid[] = "$Id: histo.c,v 1.1 2003/0 #include #include +#include #include #include @@ -20,60 +21,23 @@ static const char RCSid[] = "$Id: histo.c,v 1.1 2003/0 char *progname; int cumulative = 0; +int percentile = 0; +long outrange[MAXCOL][2]; long histo[MAXCOL][MAXDIV]; +long ctotal[MAXCOL]; double minv, maxv; int ndiv; int ncols; -main(argc, argv) -int argc; -char *argv[]; +static void +readinp(void) /* gather statistics on input */ { - progname = argv[0]; - if (argc > 1 && !strcmp(argv[1], "-c")) { - cumulative++; - argc--; argv++; - } - if (argc < 3) - goto userr; - minv = atof(argv[1]); - maxv = atof(argv[2]); - if (argc == 4) - ndiv = atoi(argv[3]); - else { - if (argc > 4 || !isint(minv) || !isint(maxv)) - goto userr; - maxv += 0.5; - minv -= 0.5; - ndiv = maxv - minv + 0.5; - } - if (minv >= maxv | ndiv <= 0) - goto userr; - if (ndiv > MAXDIV) { - fprintf(stderr, "%s: maximum number of divisions: %d\n", - progname, MAXDIV); - goto userr; - } - readinp(); - if (cumulative) - printcumul(); - else - printhisto(); - exit(0); -userr: - fprintf(stderr, "Usage: %s [-c] min max n\n", progname); - fprintf(stderr, " Or: %s [-c] imin imax\n", progname); - exit(1); -} - - -readinp() /* gather statistics on input */ -{ char buf[16*MAXCOL]; double d; + int i; register int c; register char *cp; @@ -86,42 +50,115 @@ readinp() /* gather statistics on input */ d = atof(cp); while (*cp && !isspace(*cp)) cp++; - if (d >= minv && d < maxv) + if (d <= minv) + outrange[c][0]++; + else if (d >= maxv) + outrange[c][1]++; + else histo[c][(int)(ndiv*(d-minv)/(maxv-minv))]++; } if (c > ncols) ncols = c; } + for (c = 0; c < ncols; c++) { + ctotal[c] += outrange[c][0] + outrange[c][1]; + for (i = 0; i < ndiv; i++) + ctotal[c] += histo[c][i]; + } } -printcumul() /* print cumulative histogram results */ +static void +printcumul( /* print cumulative histogram results */ +int pctl +) { - long ctot[MAXCOL]; + long csum[MAXCOL]; register int i, c; for (c = ncols; c--; ) - ctot[c] = 0L; + csum[c] = outrange[c][0]; - for (i = 0; i < ndiv; i++) { - printf("%g", minv + (maxv-minv)*(i+1)/ndiv); + for (i = 0; i <= ndiv; i++) { + printf("%g", minv + (maxv-minv)*i/ndiv); for (c = 0; c < ncols; c++) { - ctot[c] += histo[c][i]; - printf("\t%ld", ctot[c]); + if (pctl) + printf("\t%f", 100.*csum[c]/ctotal[c]); + else + printf("\t%ld", csum[c]); + if (i < ndiv) + csum[c] += histo[c][i]; } putchar('\n'); } } -printhisto() /* print histogram results */ +static void +printhisto( /* print histogram results */ +int pctl +) { register int i, c; for (i = 0; i < ndiv; i++) { printf("%g", minv + (maxv-minv)*(i+.5)/ndiv); for (c = 0; c < ncols; c++) - printf("\t%ld", histo[c][i]); + if (pctl) + printf("\t%f", 100.*histo[c][i]/ctotal[c]); + else + printf("\t%ld", histo[c][i]); putchar('\n'); } } + + +int +main( +int argc, +char *argv[] +) +{ + progname = argv[0]; + while (argc > 1 && argv[1][0] == '-') { + if (argv[1][1] == 'c') + cumulative++; + else if (argv[1][1] == 'p') + percentile++; + else + break; + argc--; argv++; + } + if (argc < 3) + goto userr; + minv = atof(argv[1]); + maxv = atof(argv[2]); + if (argc == 4) + ndiv = atoi(argv[3]); + else { + if (argc > 4 || !isint(minv) || !isint(maxv)) + goto userr; + maxv += 0.5; + minv -= 0.5; + ndiv = maxv - minv + 0.5; + } + if ((minv >= maxv) | (ndiv <= 0)) + goto userr; + if (ndiv > MAXDIV) { + fprintf(stderr, "%s: maximum number of divisions: %d\n", + progname, MAXDIV); + goto userr; + } + readinp(); + if (cumulative) + printcumul(percentile); + else + printhisto(percentile); + exit(0); +userr: + fprintf(stderr, "Usage: %s [-c][-p] min max n\n", progname); + fprintf(stderr, " Or: %s [-c][-p] imin imax\n", progname); + exit(1); +} + +