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.1 by greg, Sat Feb 22 02:07:20 2003 UTC vs.
Revision 1.16 by greg, Thu Mar 24 22:26:50 2022 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  
40 < main(argc, argv)
41 < int  argc;
42 < char  *argv[];
40 > int
41 > main(
42 > int  argc,
43 > char  *argv[]
44 > )
45   {
46          int  status;
47          int  a;
# Line 49 | Line 59 | char  *argv[];
59                                          func = MULT;
60                                          break;
61                                  case 's':
52                                        func = ADD;
62                                          power = atof(argv[a]+2);
63                                          break;
64                                  case 'u':
# Line 64 | Line 73 | char  *argv[];
73                                  case 'r':
74                                          subtotal = !subtotal;
75                                          break;
76 <                                default:
76 >                                case 'i':
77 >                                        switch (argv[a][2]) {
78 >                                        case 'n':
79 >                                                incnt = atol(argv[++a]);
80 >                                                break;
81 >                                        case 'a':
82 >                                                nbicols = 0;
83 >                                                break;
84 >                                        case 'd':
85 >                                                if (isdigit(argv[a][3]))
86 >                                                        nbicols = atoi(argv[a]+3);
87 >                                                else
88 >                                                        nbicols = 1;
89 >                                                if (nbicols > MAXCOL) {
90 >                                                        fprintf(stderr,
91 >                                                        "%s: too many input columns\n",
92 >                                                                argv[0]);
93 >                                                        exit(1);
94 >                                                }
95 >                                                break;
96 >                                        case 'f':
97 >                                                if (isdigit(argv[a][3]))
98 >                                                        nbicols = -atoi(argv[a]+3);
99 >                                                else
100 >                                                        nbicols = -1;
101 >                                                if (-nbicols > MAXCOL) {
102 >                                                        fprintf(stderr,
103 >                                                        "%s: too many input columns\n",
104 >                                                                argv[0]);
105 >                                                        exit(1);
106 >                                                }
107 >                                                break;
108 >                                        default:
109 >                                                goto userr;
110 >                                        }
111 >                                        break;
112 >                                case 'o':
113 >                                        switch (argv[a][2]) {
114 >                                        case 'n':
115 >                                                outcnt = atol(argv[++a]);
116 >                                                break;
117 >                                        case 'a':
118 >                                                bocols = 0;
119 >                                                break;
120 >                                        case 'd':
121 >                                                bocols = 1;
122 >                                                break;
123 >                                        case 'f':
124 >                                                bocols = -1;
125 >                                                break;
126 >                                        default:
127 >                                                goto userr;
128 >                                        }
129 >                                        break;
130 >                                default:;
131 >                                userr:
132                                          fprintf(stderr,
133 <                "Usage: %s [-m][-sE|p|u|l][-tC][-count [-r]] [file..]\n",
133 > "Usage: %s [-m][-sE|p|u|l][-tC][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
134                                                          argv[0]);
135                                          exit(1);
136                                  }
137                  else
138                          break;
139 +        if ((power != 0.0) & (func != ADD)) {
140 +                fprintf(stderr, "%s: -sE option requires summation\n", argv[0]);
141 +                exit(1);
142 +        }
143          if (mean) {
144                  if (func == MAX) {
145                          fprintf(stderr, "%s: average maximum?!\n", argv[0]);
# Line 82 | Line 150 | char  *argv[];
150                          exit(1);
151                  }
152          }
153 +        if (bocols)
154 +                SET_FILE_BINARY(stdout);
155          status = 0;
156          if (a >= argc)
157                  status = execute(NULL) == -1 ? 1 : status;
158          else
159 <                for ( ; a < argc; a++)
159 >                for ( ; a < argc && (outcnt <= 0 || nrecsout < outcnt); a++)
160                          status = execute(argv[a]) == -1 ? 2 : status;
161          exit(status);
162   }
163  
164  
165 < execute(fname)                  /* compute result */
166 < char  *fname;
165 > static int
166 > getrecord(                      /* read next input record */
167 >        double field[MAXCOL],
168 >        FILE *fp
169 > )
170   {
98        double  result[MAXCOL];
171          char  buf[16*MAXCOL];
172 <        register char  *cp, *num;
173 <        register int  n;
174 <        double  d;
175 <        int  ncol;
172 >        char  *cp, *num;
173 >        int   nf;
174 >                                                /* reading binary input? */
175 >        if (nbicols > 0)
176 >                return(getbinary(field, sizeof(double), nbicols, fp));
177 >        if (nbicols < 0) {
178 >                float   *fbuf = (float *)buf;
179 >                int     i;
180 >                nf = getbinary(fbuf, sizeof(float), -nbicols, fp);
181 >                for (i = nf; i-- > 0; )
182 >                        field[i] = fbuf[i];
183 >                return(nf);
184 >        }
185 >                                                /* reading ASCII input */
186 >        cp = fgets(buf, sizeof(buf), fp);
187 >        if (cp == NULL)
188 >                return(0);
189 >        for (nf = 0; nf < MAXCOL; nf++) {
190 >                while (isspace(*cp))
191 >                        cp++;
192 >                if (!*cp)
193 >                        break;
194 >                num = cp;
195 >                while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc))
196 >                        cp++;
197 >                if (*cp)
198 >                        *cp++ = '\0';
199 >                if (!*num || isspace(*num))
200 >                        field[nf] = init_val[func];
201 >                else
202 >                        field[nf] = atof(num);
203 >        }
204 >        return(nf);
205 > }
206 >
207 >
208 > static void
209 > putrecord(                      /* write out results record */
210 >        const double *field,
211 >        int n,
212 >        FILE *fp
213 > )
214 > {
215 >                                                /* binary output? */
216 >        if (bocols > 0) {
217 >                putbinary(field, sizeof(double), n, fp);
218 >                return;
219 >        }
220 >        if (bocols < 0) {
221 >                float   fv;
222 >                while (n-- > 0) {
223 >                        fv = *field++;
224 >                        putbinary(&fv, sizeof(float), 1, fp);
225 >                }
226 >                return;
227 >        }
228 >                                                /* ASCII output */
229 >        while (n-- > 0) {
230 >                fprintf(fp, "%.9g", *field++);
231 >                if (n) fputc(tabc, fp);
232 >        }
233 >        fputc('\n', fp);
234 >        if (!subtotal)
235 >                fflush(fp);                     /* flush unless -r */
236 > }
237 >
238 >
239 > static int
240 > execute(                        /* compute result */
241 > char  *fname
242 > )
243 > {
244 >        double  inpval[MAXCOL];
245 >        double  tally[MAXCOL];
246 >        short   rsign[MAXCOL];
247 >        double  result[MAXCOL];
248 >        int  n;
249 >        int  nread, ncol;
250          long  nlin, ltotal;
251          FILE  *fp;
252                                                          /* open file */
# Line 110 | Line 256 | char  *fname;
256                  fprintf(stderr, "%s: cannot open\n", fname);
257                  return(-1);
258          }
259 +        if (nbicols)
260 +                SET_FILE_BINARY(fp);
261 + #ifdef getc_unlocked                            /* avoid lock/unlock overhead */
262 +        flockfile(fp);
263 + #endif
264 +
265          ltotal = 0;
266          while (!feof(fp)) {
267 <                if (ltotal == 0)                        /* initialize */
267 >                if (ltotal == 0) {                      /* initialize */
268                          if (func == MULT)       /* special case */
269 <                                for (n = 0; n < MAXCOL; n++)
270 <                                        result[n] = 0.0;
269 >                                for (n = 0; n < MAXCOL; n++) {
270 >                                        tally[n] = 0.0;
271 >                                        rsign[n] = 1;
272 >                                }
273                          else
274                                  for (n = 0; n < MAXCOL; n++)
275 <                                        result[n] = init_val[func];
275 >                                        tally[n] = init_val[func];
276 >                }
277                  ncol = 0;
278                  for (nlin = 0; (count <= 0 || nlin < count) &&
279 <                                (cp = fgets(buf, sizeof(buf), fp)) != NULL;
279 >                                (incnt <= 0 || nlin < incnt) &&
280 >                                (nread = getrecord(inpval, fp)) > 0;
281                                  nlin++) {
282                                                          /* compute */
283 <                        for (n = 0; n < MAXCOL; n++) {
128 <                                while (isspace(*cp))
129 <                                        cp++;
130 <                                if (!*cp)
131 <                                        break;
132 <                                num = cp;
133 <                                while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc))
134 <                                        cp++;
135 <                                if (*cp)
136 <                                        *cp++ = '\0';
137 <                                if (!*num || isspace(*num))
138 <                                        d = init_val[func];
139 <                                else
140 <                                        d = atof(num);
283 >                        for (n = 0; n < nread; n++)
284                                  switch (func) {
285                                  case ADD:
286 <                                        if (d == 0.0)
286 >                                        if (inpval[n] == 0.0)
287                                                  break;
288 <                                        if (power != 0.0)
289 <                                                result[n] += pow(fabs(d),power);
288 >                                        if (power == 0.0)
289 >                                                tally[n] += inpval[n];
290 >                                        else if (power == 1.0)
291 >                                                tally[n] += fabs(inpval[n]);
292 >                                        else if (power == -1.0)
293 >                                                tally[n] += 1.0/fabs(inpval[n]);
294                                          else
295 <                                                result[n] += d;
295 >                                                tally[n] += pow(fabs(inpval[n]), power);
296                                          break;
297                                  case MULT:
298 <                                        if (d == 0.0)
299 <                                                break;
300 <                                        result[n] += log(fabs(d));
298 >                                        if (inpval[n] == 0.0)
299 >                                                rsign[n] = 0;
300 >                                        else if (inpval[n] < 0.0) {
301 >                                                rsign[n] = -rsign[n];
302 >                                                inpval[n] = -inpval[n];
303 >                                        }
304 >                                        if (rsign[n])
305 >                                                tally[n] += log(inpval[n]);
306                                          break;
307                                  case MAX:
308 <                                        if (d > result[n])
309 <                                                result[n] = d;
308 >                                        if (inpval[n] > tally[n])
309 >                                                tally[n] = inpval[n];
310                                          break;
311                                  case MIN:
312 <                                        if (d < result[n])
313 <                                                result[n] = d;
312 >                                        if (inpval[n] < tally[n])
313 >                                                tally[n] = inpval[n];
314                                          break;
315                                  }
316 <                        }
317 <                        if (n > ncol)
166 <                                ncol = n;
316 >                        if (nread > ncol)
317 >                                ncol = nread;
318                  }
319                  if (nlin == 0)
320                          break;
321                                                  /* compute and print */
322                  ltotal += nlin;
323                  for (n = 0; n < ncol; n++) {
324 <                        d = result[n];
324 >                        result[n] = tally[n];
325                          if (mean) {
326 <                                d /= (double)ltotal;
327 <                                if (func == ADD && power != 0.0 && d != 0.0)
328 <                                        d = pow(d, 1.0/power);
326 >                                result[n] /= (double)ltotal;
327 >                                if (func == ADD && power != 0.0 && result[n] != 0.0)
328 >                                        result[n] = pow(result[n], 1.0/power);
329                          }
330                          if (func == MULT)
331 <                                d = exp(d);
181 <                        printf("%.9g%c", d, tabc);
331 >                                result[n] = rsign[n] * exp(result[n]);
332                  }
333 <                putchar('\n');
333 >                putrecord(result, ncol, stdout);
334 >                ++nrecsout;
335 >                if (outcnt > 0 && nrecsout >= outcnt)
336 >                        break;
337                  if (!subtotal)
338                          ltotal = 0;
339 +                if (incnt > 0 && nlin >= incnt)
340 +                        break;
341          }
342 <                                                        /* close file */
343 <        return(fclose(fp));
342 >                                                        /* close input */
343 >        return(fclose(fp) == EOF ? 1 : 0);
344   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines