Back to index

radiance  4R0+20100331
total.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: total.c,v 1.7 2010/01/29 17:21:43 greg Exp $";
00003 #endif
00004 /*
00005  *  total.c - program to reduce columns of data.
00006  *
00007  *     5/18/88
00008  */
00009 
00010 #include  <stdio.h>
00011 #include  <stdlib.h>
00012 #include  <ctype.h>
00013 #include  <math.h>
00014 #include  "platform.h"
00015 
00016 #define  MAXCOL             2048          /* maximum number of columns */
00017 
00018 #define  ADD         0             /* add numbers */
00019 #define  MULT        1             /* multiply numbers */
00020 #define  MAX         2             /* maximum */
00021 #define  MIN         3             /* minimum */
00022 
00023 double  init_val[] = {0., 1., -1e12, 1e12};      /* initial values */
00024 
00025 int  func = ADD;                   /* default function */
00026 double  power = 0.0;               /* power for sum */
00027 int  mean = 0;                            /* compute mean */
00028 int  count = 0;                           /* number to sum */
00029 int  nbicols = 0;                  /* number of binary input columns */
00030 int  bocols = 0;                   /* produce binary output columns */
00031 int  tabc = '\t';                  /* default separator */
00032 int  subtotal = 0;                 /* produce subtotals? */
00033 
00034 static int execute(char *fname);
00035 
00036 int
00037 main(
00038 int  argc,
00039 char  *argv[]
00040 )
00041 {
00042        int  status;
00043        int  a;
00044 
00045        for (a = 1; a < argc; a++)
00046               if (argv[a][0] == '-')
00047                      if (argv[a][1] >= '0' && argv[a][1] <= '9')
00048                             count = atoi(argv[a]+1);
00049                      else
00050                             switch (argv[a][1]) {
00051                             case 'm':
00052                                    mean = !mean;
00053                                    break;
00054                             case 'p':
00055                                    func = MULT;
00056                                    break;
00057                             case 's':
00058                                    func = ADD;
00059                                    power = atof(argv[a]+2);
00060                                    break;
00061                             case 'u':
00062                                    func = MAX;
00063                                    break;
00064                             case 'l':
00065                                    func = MIN;
00066                                    break;
00067                             case 't':
00068                                    tabc = argv[a][2];
00069                                    break;
00070                             case 'r':
00071                                    subtotal = !subtotal;
00072                                    break;
00073                             case 'i':
00074                                    switch (argv[a][2]) {
00075                                    case 'a':
00076                                           nbicols = 0;
00077                                           break;
00078                                    case 'd':
00079                                           if (isdigit(argv[a][3]))
00080                                                  nbicols = atoi(argv[a]+3);
00081                                           else
00082                                                  nbicols = 1;
00083                                           if (nbicols > MAXCOL) {
00084                                                  fprintf(stderr,
00085                                                  "%s: too many input columns\n",
00086                                                         argv[0]);
00087                                                  exit(1);
00088                                           }
00089                                           break;
00090                                    case 'f':
00091                                           if (isdigit(argv[a][3]))
00092                                                  nbicols = -atoi(argv[a]+3);
00093                                           else
00094                                                  nbicols = -1;
00095                                           if (-nbicols > MAXCOL) {
00096                                                  fprintf(stderr,
00097                                                  "%s: too many input columns\n",
00098                                                         argv[0]);
00099                                                  exit(1);
00100                                           }
00101                                           break;
00102                                    default:
00103                                           goto userr;
00104                                    }
00105                                    break;
00106                             case 'o':
00107                                    switch (argv[a][2]) {
00108                                    case 'a':
00109                                           bocols = 0;
00110                                           break;
00111                                    case 'd':
00112                                           bocols = 1;
00113                                           break;
00114                                    case 'f':
00115                                           bocols = -1;
00116                                           break;
00117                                    default:
00118                                           goto userr;
00119                                    }
00120                                    break;
00121                             default:;
00122                             userr:
00123                                    fprintf(stderr,
00124 "Usage: %s [-m][-sE|p|u|l][-tC][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
00125                                                  argv[0]);
00126                                    exit(1);
00127                             }
00128               else
00129                      break;
00130        if (mean) {
00131               if (func == MAX) {
00132                      fprintf(stderr, "%s: average maximum?!\n", argv[0]);
00133                      exit(1);
00134               }
00135               if (func == MIN) {
00136                      fprintf(stderr, "%s: average minimum?!\n", argv[0]);
00137                      exit(1);
00138               }
00139        }
00140        if (bocols)
00141               SET_FILE_BINARY(stdout);
00142        status = 0;
00143        if (a >= argc)
00144               status = execute(NULL) == -1 ? 1 : status;
00145        else
00146               for ( ; a < argc; a++)
00147                      status = execute(argv[a]) == -1 ? 2 : status;
00148        exit(status);
00149 }
00150 
00151 
00152 static int
00153 getrecord(                  /* read next input record */
00154        double field[MAXCOL],
00155        FILE *fp
00156 )
00157 {
00158        char  buf[16*MAXCOL];
00159        char  *cp, *num;
00160        int   nf;
00161                                           /* reading binary input? */
00162        if (nbicols > 0)
00163               return(fread(field, sizeof(double), nbicols, fp));
00164        if (nbicols < 0) {
00165               float  *fbuf = (float *)buf;
00166               int    i;
00167               nf = fread(fbuf, sizeof(float), -nbicols, fp);
00168               for (i = nf; i-- > 0; )
00169                      field[i] = fbuf[i];
00170               return(nf);
00171        }
00172                                           /* reading ASCII input */
00173        cp = fgets(buf, sizeof(buf), fp);
00174        if (cp == NULL)
00175               return(0);
00176        for (nf = 0; nf < MAXCOL; nf++) {
00177               while (isspace(*cp))
00178                      cp++;
00179               if (!*cp)
00180                      break;
00181               num = cp;
00182               while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc))
00183                      cp++;
00184               if (*cp)
00185                      *cp++ = '\0';
00186               if (!*num || isspace(*num))
00187                      field[nf] = init_val[func];
00188               else
00189                      field[nf] = atof(num);
00190        }
00191        return(nf);
00192 }
00193 
00194 
00195 static void
00196 putrecord(                  /* write out results record */
00197        const double *field,
00198        int n,
00199        FILE *fp
00200 )
00201 {
00202                                           /* binary output? */
00203        if (bocols > 0) {
00204               fwrite(field, sizeof(double), n, fp);
00205               return;
00206        }
00207        if (bocols < 0) {
00208               float  fv;
00209               while (n-- > 0) {
00210                      fv = *field++;
00211                      fwrite(&fv, sizeof(float), 1, fp);
00212               }
00213               return;
00214        }
00215                                           /* ASCII output */
00216        while (n-- > 0)
00217               fprintf(fp, "%.9g%c", *field++, tabc);
00218        fputc('\n', fp);
00219 }
00220 
00221 
00222 static int
00223 execute(                    /* compute result */
00224 char  *fname
00225 )
00226 {
00227        double inpval[MAXCOL];
00228        double tally[MAXCOL];
00229        short  rsign[MAXCOL];
00230        double  result[MAXCOL];
00231        int  n;
00232        int  nread, ncol;
00233        long  nlin, ltotal;
00234        FILE  *fp;
00235                                                  /* open file */
00236        if (fname == NULL)
00237               fp = stdin;
00238        else if ((fp = fopen(fname, "r")) == NULL) {
00239               fprintf(stderr, "%s: cannot open\n", fname);
00240               return(-1);
00241        }
00242        if (nbicols)
00243               SET_FILE_BINARY(fp);
00244        ltotal = 0;
00245        while (!feof(fp)) {
00246               if (ltotal == 0) {                 /* initialize */
00247                      if (func == MULT)    /* special case */
00248                             for (n = 0; n < MAXCOL; n++) {
00249                                    tally[n] = 0.0;
00250                                    rsign[n] = 1;
00251                             }
00252                      else
00253                             for (n = 0; n < MAXCOL; n++)
00254                                    tally[n] = init_val[func];
00255               }
00256               ncol = 0;
00257               for (nlin = 0; (count <= 0 || nlin < count) &&
00258                             (nread = getrecord(inpval, fp)) > 0;
00259                             nlin++) {
00260                                                  /* compute */
00261                      for (n = 0; n < nread; n++)
00262                             switch (func) {
00263                             case ADD:
00264                                    if (inpval[n] == 0.0)
00265                                           break;
00266                                    if (power != 0.0)
00267                                           tally[n] += pow(fabs(inpval[n]),power);
00268                                    else
00269                                           tally[n] += inpval[n];
00270                                    break;
00271                             case MULT:
00272                                    if (inpval[n] == 0.0)
00273                                           rsign[n] = 0;
00274                                    else if (inpval[n] < 0.0) {
00275                                           rsign[n] = -rsign[n];
00276                                           inpval[n] = -inpval[n];
00277                                    }
00278                                    if (rsign[n])
00279                                           tally[n] += log(inpval[n]);
00280                                    break;
00281                             case MAX:
00282                                    if (inpval[n] > tally[n])
00283                                           tally[n] = inpval[n];
00284                                    break;
00285                             case MIN:
00286                                    if (inpval[n] < tally[n])
00287                                           tally[n] = inpval[n];
00288                                    break;
00289                             }
00290                      if (nread > ncol)
00291                             ncol = nread;
00292               }
00293               if (nlin == 0)
00294                      break;
00295                                           /* compute and print */
00296               ltotal += nlin;
00297               for (n = 0; n < ncol; n++) {
00298                      result[n] = tally[n];
00299                      if (mean) {
00300                             result[n] /= (double)ltotal;
00301                             if (func == ADD && power != 0.0 && result[n] != 0.0)
00302                                    result[n] = pow(result[n], 1.0/power);
00303                      }
00304                      if (func == MULT)
00305                             result[n] = rsign[n] * exp(result[n]);
00306               }
00307               putrecord(result, ncol, stdout);
00308               if (!subtotal)
00309                      ltotal = 0;
00310        }
00311                                                  /* close input */
00312        return(fclose(fp));
00313 }