Back to index

radiance  4R0+20100331
histo.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: histo.c,v 1.5 2008/04/18 16:32:27 greg Exp $";
00003 #endif
00004 /*
00005  * Compute a histogram from input data
00006  *
00007  *     9/5/96 Greg Ward
00008  */
00009 
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 #include <math.h>
00014 #include <ctype.h>
00015 
00016 #define MAXCOL              2048          /* maximum number of input columns */
00017 #define MAXDIV              1024
00018 
00019 #define isint(x)     (floor((x)+1e-6) != floor((x)-1e-6))
00020 
00021 char   *progname;
00022 
00023 int    cumulative = 0;
00024 int    percentile = 0;
00025 
00026 long   outrange[MAXCOL][2];
00027 long   histo[MAXCOL][MAXDIV];
00028 long   ctotal[MAXCOL];
00029 double minv, maxv;
00030 int    ndiv;
00031 
00032 int    ncols;
00033 
00034 
00035 static void
00036 readinp(void)               /* gather statistics on input */
00037 {
00038        char   buf[16*MAXCOL];
00039        double d;
00040        int    i;
00041        register int  c;
00042        register char *cp;
00043 
00044        while ((cp = fgets(buf, sizeof(buf), stdin)) != NULL) {
00045               for (c = 0; c < MAXCOL; c++) {
00046                      while (isspace(*cp))
00047                             cp++;
00048                      if (!*cp)
00049                             break;
00050                      d = atof(cp);
00051                      while (*cp && !isspace(*cp))
00052                             cp++;
00053                      if (d <= minv)
00054                             outrange[c][0]++;
00055                      else if (d >= maxv)
00056                             outrange[c][1]++;
00057                      else
00058                             histo[c][(int)(ndiv*(d-minv)/(maxv-minv))]++;
00059               }
00060               if (c > ncols)
00061                      ncols = c;
00062        }
00063        for (c = 0; c < ncols; c++) {
00064               ctotal[c] += outrange[c][0] + outrange[c][1];
00065               for (i = 0; i < ndiv; i++)
00066                      ctotal[c] += histo[c][i];
00067        }
00068 }
00069 
00070 
00071 static void
00072 printcumul(                 /* print cumulative histogram results */
00073 int    pctl
00074 )
00075 {
00076        long          csum[MAXCOL];
00077        register int  i, c;
00078 
00079        for (c = ncols; c--; )
00080               csum[c] = outrange[c][0];
00081 
00082        for (i = 0; i <= ndiv; i++) {
00083               printf("%g", minv + (maxv-minv)*i/ndiv);
00084               for (c = 0; c < ncols; c++) {
00085                      if (pctl)
00086                             printf("\t%f", 100.*csum[c]/ctotal[c]);
00087                      else
00088                             printf("\t%ld", csum[c]);
00089                      if (i < ndiv)
00090                             csum[c] += histo[c][i];
00091               }
00092               putchar('\n');
00093        }
00094 }
00095 
00096 
00097 static void
00098 printhisto(                 /* print histogram results */
00099 int    pctl
00100 )
00101 {
00102        register int  i, c;
00103 
00104        for (i = 0; i < ndiv; i++) {
00105               printf("%g", minv + (maxv-minv)*(i+.5)/ndiv);
00106               for (c = 0; c < ncols; c++)
00107                      if (pctl)
00108                             printf("\t%f", 100.*histo[c][i]/ctotal[c]);
00109                      else
00110                             printf("\t%ld", histo[c][i]);
00111               putchar('\n');
00112        }
00113 }
00114 
00115 
00116 int
00117 main(
00118 int    argc,
00119 char   *argv[]
00120 )
00121 {
00122        progname = argv[0];
00123        while (argc > 1 && argv[1][0] == '-') {
00124               if (argv[1][1] == 'c')
00125                      cumulative++;
00126               else if (argv[1][1] == 'p')
00127                      percentile++;
00128               else
00129                      break;
00130               argc--; argv++;
00131        }
00132        if (argc < 3)
00133               goto userr;
00134        minv = atof(argv[1]);
00135        maxv = atof(argv[2]);
00136        if (argc == 4)
00137               ndiv = atoi(argv[3]);
00138        else {
00139               if (argc > 4 || !isint(minv) || !isint(maxv))
00140                      goto userr;
00141               maxv += 0.5;
00142               minv -= 0.5;
00143               ndiv = maxv - minv + 0.5;
00144        }
00145        if ((minv >= maxv) | (ndiv <= 0))
00146               goto userr;
00147        if (ndiv > MAXDIV) {
00148               fprintf(stderr, "%s: maximum number of divisions: %d\n",
00149                             progname, MAXDIV);
00150               goto userr;
00151        }
00152        readinp();
00153        if (cumulative)
00154               printcumul(percentile);
00155        else
00156               printhisto(percentile);
00157        exit(0);
00158 userr:
00159        fprintf(stderr, "Usage: %s [-c][-p] min max n\n", progname);
00160        fprintf(stderr, "   Or: %s [-c][-p] imin imax\n", progname);
00161        exit(1);
00162 }
00163 
00164