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.13 by greg, Thu Aug 18 00:52:47 2016 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines