ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/total.c
(Generate patch)

Comparing ray/src/cal/total.c (file contents):
Revision 1.3 by schorsch, Mon Jul 21 22:30:17 2003 UTC vs.
Revision 1.14 by greg, Sat Dec 28 18:05:13 2019 UTC

# Line 7 | Line 7 | static const char      RCSid[] = "$Id$";
7   *      5/18/88
8   */
9  
10 #include  <stdio.h>
10   #include  <stdlib.h>
11   #include  <ctype.h>
12   #include  <math.h>
13 + #include  "platform.h"
14 + #include  "rtio.h"
15  
16 < #define  MAXCOL         256             /* maximum number of columns */
16 > #define  MAXCOL         8192            /* maximum number of columns */
17  
18   #define  ADD            0               /* add numbers */
19   #define  MULT           1               /* multiply numbers */
# Line 21 | Line 22 | static const char      RCSid[] = "$Id$";
22  
23   double  init_val[] = {0., 1., -1e12, 1e12};     /* initial values */
24  
25 + long  incnt = 0;                        /* limit number of input records? */
26 + long  outcnt = 0;                       /* limit number of output records? */
27 +
28   int  func = ADD;                        /* default function */
29   double  power = 0.0;                    /* power for sum */
30   int  mean = 0;                          /* compute mean */
31   int  count = 0;                         /* number to sum */
32 + int  nbicols = 0;                       /* number of binary input columns */
33 + int  bocols = 0;                        /* produce binary output columns */
34   int  tabc = '\t';                       /* default separator */
35   int  subtotal = 0;                      /* produce subtotals? */
36 + int  nrecsout = 0;                      /* number of records produced */
37  
38   static int execute(char *fname);
39  
# Line 67 | Line 74 | char  *argv[]
74                                  case 'r':
75                                          subtotal = !subtotal;
76                                          break;
77 <                                default:
77 >                                case 'i':
78 >                                        switch (argv[a][2]) {
79 >                                        case 'n':
80 >                                                incnt = atol(argv[++a]);
81 >                                                break;
82 >                                        case 'a':
83 >                                                nbicols = 0;
84 >                                                break;
85 >                                        case 'd':
86 >                                                if (isdigit(argv[a][3]))
87 >                                                        nbicols = atoi(argv[a]+3);
88 >                                                else
89 >                                                        nbicols = 1;
90 >                                                if (nbicols > MAXCOL) {
91 >                                                        fprintf(stderr,
92 >                                                        "%s: too many input columns\n",
93 >                                                                argv[0]);
94 >                                                        exit(1);
95 >                                                }
96 >                                                break;
97 >                                        case 'f':
98 >                                                if (isdigit(argv[a][3]))
99 >                                                        nbicols = -atoi(argv[a]+3);
100 >                                                else
101 >                                                        nbicols = -1;
102 >                                                if (-nbicols > MAXCOL) {
103 >                                                        fprintf(stderr,
104 >                                                        "%s: too many input columns\n",
105 >                                                                argv[0]);
106 >                                                        exit(1);
107 >                                                }
108 >                                                break;
109 >                                        default:
110 >                                                goto userr;
111 >                                        }
112 >                                        break;
113 >                                case 'o':
114 >                                        switch (argv[a][2]) {
115 >                                        case 'n':
116 >                                                outcnt = atol(argv[++a]);
117 >                                                break;
118 >                                        case 'a':
119 >                                                bocols = 0;
120 >                                                break;
121 >                                        case 'd':
122 >                                                bocols = 1;
123 >                                                break;
124 >                                        case 'f':
125 >                                                bocols = -1;
126 >                                                break;
127 >                                        default:
128 >                                                goto userr;
129 >                                        }
130 >                                        break;
131 >                                default:;
132 >                                userr:
133                                          fprintf(stderr,
134 <                "Usage: %s [-m][-sE|p|u|l][-tC][-count [-r]] [file..]\n",
134 > "Usage: %s [-m][-sE|p|u|l][-tC][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
135                                                          argv[0]);
136                                          exit(1);
137                                  }
# Line 85 | Line 147 | char  *argv[]
147                          exit(1);
148                  }
149          }
150 +        if (bocols)
151 +                SET_FILE_BINARY(stdout);
152          status = 0;
153          if (a >= argc)
154                  status = execute(NULL) == -1 ? 1 : status;
155          else
156 <                for ( ; a < argc; a++)
156 >                for ( ; a < argc && (outcnt <= 0 || nrecsout < outcnt); a++)
157                          status = execute(argv[a]) == -1 ? 2 : status;
158          exit(status);
159   }
160  
161  
162   static int
163 + getrecord(                      /* read next input record */
164 +        double field[MAXCOL],
165 +        FILE *fp
166 + )
167 + {
168 +        char  buf[16*MAXCOL];
169 +        char  *cp, *num;
170 +        int   nf;
171 +                                                /* reading binary input? */
172 +        if (nbicols > 0)
173 +                return(getbinary(field, sizeof(double), nbicols, fp));
174 +        if (nbicols < 0) {
175 +                float   *fbuf = (float *)buf;
176 +                int     i;
177 +                nf = getbinary(fbuf, sizeof(float), -nbicols, fp);
178 +                for (i = nf; i-- > 0; )
179 +                        field[i] = fbuf[i];
180 +                return(nf);
181 +        }
182 +                                                /* reading ASCII input */
183 +        cp = fgets(buf, sizeof(buf), fp);
184 +        if (cp == NULL)
185 +                return(0);
186 +        for (nf = 0; nf < MAXCOL; nf++) {
187 +                while (isspace(*cp))
188 +                        cp++;
189 +                if (!*cp)
190 +                        break;
191 +                num = cp;
192 +                while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc))
193 +                        cp++;
194 +                if (*cp)
195 +                        *cp++ = '\0';
196 +                if (!*num || isspace(*num))
197 +                        field[nf] = init_val[func];
198 +                else
199 +                        field[nf] = atof(num);
200 +        }
201 +        return(nf);
202 + }
203 +
204 +
205 + static void
206 + putrecord(                      /* write out results record */
207 +        const double *field,
208 +        int n,
209 +        FILE *fp
210 + )
211 + {
212 +                                                /* binary output? */
213 +        if (bocols > 0) {
214 +                putbinary(field, sizeof(double), n, fp);
215 +                return;
216 +        }
217 +        if (bocols < 0) {
218 +                float   fv;
219 +                while (n-- > 0) {
220 +                        fv = *field++;
221 +                        putbinary(&fv, sizeof(float), 1, fp);
222 +                }
223 +                return;
224 +        }
225 +                                                /* ASCII output */
226 +        while (n-- > 0) {
227 +                fprintf(fp, "%.9g", *field++);
228 +                if (n) fputc(tabc, fp);
229 +        }
230 +        fputc('\n', fp);
231 + }
232 +
233 +
234 + static int
235   execute(                        /* compute result */
236   char  *fname
237   )
238   {
239 +        double  inpval[MAXCOL];
240 +        double  tally[MAXCOL];
241 +        short   rsign[MAXCOL];
242          double  result[MAXCOL];
243 <        char  buf[16*MAXCOL];
244 <        register char  *cp, *num;
106 <        register int  n;
107 <        double  d;
108 <        int  ncol;
243 >        int  n;
244 >        int  nread, ncol;
245          long  nlin, ltotal;
246          FILE  *fp;
247                                                          /* open file */
# Line 115 | Line 251 | char  *fname
251                  fprintf(stderr, "%s: cannot open\n", fname);
252                  return(-1);
253          }
254 +        if (nbicols)
255 +                SET_FILE_BINARY(fp);
256 + #ifdef getc_unlocked                            /* avoid lock/unlock overhead */
257 +        flockfile(fp);
258 + #endif
259 +
260          ltotal = 0;
261          while (!feof(fp)) {
262                  if (ltotal == 0) {                      /* initialize */
263                          if (func == MULT)       /* special case */
264 <                                for (n = 0; n < MAXCOL; n++)
265 <                                        result[n] = 0.0;
264 >                                for (n = 0; n < MAXCOL; n++) {
265 >                                        tally[n] = 0.0;
266 >                                        rsign[n] = 1;
267 >                                }
268                          else
269                                  for (n = 0; n < MAXCOL; n++)
270 <                                        result[n] = init_val[func];
270 >                                        tally[n] = init_val[func];
271                  }
272                  ncol = 0;
273                  for (nlin = 0; (count <= 0 || nlin < count) &&
274 <                                (cp = fgets(buf, sizeof(buf), fp)) != NULL;
274 >                                (incnt <= 0 || nlin < incnt) &&
275 >                                (nread = getrecord(inpval, fp)) > 0;
276                                  nlin++) {
277                                                          /* compute */
278 <                        for (n = 0; n < MAXCOL; n++) {
134 <                                while (isspace(*cp))
135 <                                        cp++;
136 <                                if (!*cp)
137 <                                        break;
138 <                                num = cp;
139 <                                while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc))
140 <                                        cp++;
141 <                                if (*cp)
142 <                                        *cp++ = '\0';
143 <                                if (!*num || isspace(*num))
144 <                                        d = init_val[func];
145 <                                else
146 <                                        d = atof(num);
278 >                        for (n = 0; n < nread; n++)
279                                  switch (func) {
280                                  case ADD:
281 <                                        if (d == 0.0)
281 >                                        if (inpval[n] == 0.0)
282                                                  break;
283                                          if (power != 0.0)
284 <                                                result[n] += pow(fabs(d),power);
284 >                                                tally[n] += pow(fabs(inpval[n]),power);
285                                          else
286 <                                                result[n] += d;
286 >                                                tally[n] += inpval[n];
287                                          break;
288                                  case MULT:
289 <                                        if (d == 0.0)
290 <                                                break;
291 <                                        result[n] += log(fabs(d));
289 >                                        if (inpval[n] == 0.0)
290 >                                                rsign[n] = 0;
291 >                                        else if (inpval[n] < 0.0) {
292 >                                                rsign[n] = -rsign[n];
293 >                                                inpval[n] = -inpval[n];
294 >                                        }
295 >                                        if (rsign[n])
296 >                                                tally[n] += log(inpval[n]);
297                                          break;
298                                  case MAX:
299 <                                        if (d > result[n])
300 <                                                result[n] = d;
299 >                                        if (inpval[n] > tally[n])
300 >                                                tally[n] = inpval[n];
301                                          break;
302                                  case MIN:
303 <                                        if (d < result[n])
304 <                                                result[n] = d;
303 >                                        if (inpval[n] < tally[n])
304 >                                                tally[n] = inpval[n];
305                                          break;
306                                  }
307 <                        }
308 <                        if (n > ncol)
172 <                                ncol = n;
307 >                        if (nread > ncol)
308 >                                ncol = nread;
309                  }
310                  if (nlin == 0)
311                          break;
312                                                  /* compute and print */
313                  ltotal += nlin;
314                  for (n = 0; n < ncol; n++) {
315 <                        d = result[n];
315 >                        result[n] = tally[n];
316                          if (mean) {
317 <                                d /= (double)ltotal;
318 <                                if (func == ADD && power != 0.0 && d != 0.0)
319 <                                        d = pow(d, 1.0/power);
317 >                                result[n] /= (double)ltotal;
318 >                                if (func == ADD && power != 0.0 && result[n] != 0.0)
319 >                                        result[n] = pow(result[n], 1.0/power);
320                          }
321                          if (func == MULT)
322 <                                d = exp(d);
187 <                        printf("%.9g%c", d, tabc);
322 >                                result[n] = rsign[n] * exp(result[n]);
323                  }
324 <                putchar('\n');
324 >                putrecord(result, ncol, stdout);
325 >                ++nrecsout;
326 >                if (outcnt > 0 && nrecsout >= outcnt)
327 >                        break;
328                  if (!subtotal)
329                          ltotal = 0;
330 +                if (incnt > 0 && nlin >= incnt)
331 +                        break;
332          }
333 <                                                        /* close file */
333 >                                                        /* close input */
334          return(fclose(fp));
335   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines