ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/total.c
Revision: 1.13
Committed: Thu Aug 18 00:52:47 2016 UTC (7 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad5R1
Changes since 1.12: +6 -5 lines
Log Message:
Switched over to more efficient fread/fwrite replacements getbinary/putbinary

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.13 static const char RCSid[] = "$Id: total.c,v 1.12 2016/03/24 19:00:54 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * total.c - program to reduce columns of data.
6     *
7     * 5/18/88
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <ctype.h>
13     #include <math.h>
14 greg 1.4 #include "platform.h"
15 greg 1.13 #include "rtio.h"
16 greg 1.1
17 greg 1.8 #define MAXCOL 8192 /* maximum number of columns */
18 greg 1.1
19     #define ADD 0 /* add numbers */
20     #define MULT 1 /* multiply numbers */
21     #define MAX 2 /* maximum */
22     #define MIN 3 /* minimum */
23    
24     double init_val[] = {0., 1., -1e12, 1e12}; /* initial values */
25    
26 greg 1.11 long incnt = 0; /* limit number of input records? */
27     long outcnt = 0; /* limit number of output records? */
28    
29 greg 1.1 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 greg 1.4 int nbicols = 0; /* number of binary input columns */
34     int bocols = 0; /* produce binary output columns */
35 greg 1.1 int tabc = '\t'; /* default separator */
36     int subtotal = 0; /* produce subtotals? */
37 greg 1.11 int nrecsout = 0; /* number of records produced */
38 greg 1.1
39 schorsch 1.2 static int execute(char *fname);
40 greg 1.1
41 schorsch 1.2 int
42     main(
43     int argc,
44     char *argv[]
45     )
46 greg 1.1 {
47     int status;
48     int a;
49    
50     for (a = 1; a < argc; a++)
51     if (argv[a][0] == '-')
52     if (argv[a][1] >= '0' && argv[a][1] <= '9')
53     count = atoi(argv[a]+1);
54     else
55     switch (argv[a][1]) {
56     case 'm':
57     mean = !mean;
58     break;
59     case 'p':
60     func = MULT;
61     break;
62     case 's':
63     func = ADD;
64     power = atof(argv[a]+2);
65     break;
66     case 'u':
67     func = MAX;
68     break;
69     case 'l':
70     func = MIN;
71     break;
72     case 't':
73     tabc = argv[a][2];
74     break;
75     case 'r':
76     subtotal = !subtotal;
77     break;
78 greg 1.4 case 'i':
79     switch (argv[a][2]) {
80 greg 1.11 case 'n':
81     incnt = atol(argv[++a]);
82     break;
83 greg 1.4 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 greg 1.11 case 'n':
117     outcnt = atol(argv[++a]);
118     break;
119 greg 1.4 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 greg 1.1 fprintf(stderr,
135 greg 1.4 "Usage: %s [-m][-sE|p|u|l][-tC][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
136 greg 1.1 argv[0]);
137     exit(1);
138     }
139     else
140     break;
141     if (mean) {
142     if (func == MAX) {
143     fprintf(stderr, "%s: average maximum?!\n", argv[0]);
144     exit(1);
145     }
146     if (func == MIN) {
147     fprintf(stderr, "%s: average minimum?!\n", argv[0]);
148     exit(1);
149     }
150     }
151 greg 1.4 if (bocols)
152     SET_FILE_BINARY(stdout);
153 greg 1.1 status = 0;
154     if (a >= argc)
155     status = execute(NULL) == -1 ? 1 : status;
156     else
157 greg 1.11 for ( ; a < argc && (outcnt <= 0 || nrecsout < outcnt); a++)
158 greg 1.1 status = execute(argv[a]) == -1 ? 2 : status;
159     exit(status);
160     }
161    
162    
163 schorsch 1.2 static int
164 greg 1.4 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 greg 1.13 return(getbinary(field, sizeof(double), nbicols, fp));
175 greg 1.4 if (nbicols < 0) {
176     float *fbuf = (float *)buf;
177     int i;
178 greg 1.13 nf = getbinary(fbuf, sizeof(float), -nbicols, fp);
179 greg 1.4 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 greg 1.13 putbinary(field, sizeof(double), n, fp);
216 greg 1.4 return;
217     }
218     if (bocols < 0) {
219     float fv;
220     while (n-- > 0) {
221     fv = *field++;
222 greg 1.13 putbinary(&fv, sizeof(float), 1, fp);
223 greg 1.4 }
224     return;
225     }
226     /* ASCII output */
227 greg 1.10 while (n-- > 0) {
228     fprintf(fp, "%.9g", *field++);
229     if (n) fputc(tabc, fp);
230     }
231 greg 1.4 fputc('\n', fp);
232     }
233    
234    
235     static int
236 schorsch 1.2 execute( /* compute result */
237     char *fname
238     )
239 greg 1.1 {
240 greg 1.4 double inpval[MAXCOL];
241     double tally[MAXCOL];
242 greg 1.7 short rsign[MAXCOL];
243 greg 1.1 double result[MAXCOL];
244 greg 1.7 int n;
245 greg 1.4 int nread, ncol;
246 greg 1.1 long nlin, ltotal;
247     FILE *fp;
248     /* open file */
249     if (fname == NULL)
250     fp = stdin;
251     else if ((fp = fopen(fname, "r")) == NULL) {
252     fprintf(stderr, "%s: cannot open\n", fname);
253     return(-1);
254     }
255 greg 1.4 if (nbicols)
256     SET_FILE_BINARY(fp);
257 greg 1.9 #ifdef getc_unlocked /* avoid lock/unlock overhead */
258     flockfile(fp);
259     #endif
260    
261 greg 1.1 ltotal = 0;
262     while (!feof(fp)) {
263 schorsch 1.3 if (ltotal == 0) { /* initialize */
264 greg 1.1 if (func == MULT) /* special case */
265 greg 1.7 for (n = 0; n < MAXCOL; n++) {
266 greg 1.4 tally[n] = 0.0;
267 greg 1.7 rsign[n] = 1;
268     }
269 greg 1.1 else
270     for (n = 0; n < MAXCOL; n++)
271 greg 1.4 tally[n] = init_val[func];
272 schorsch 1.3 }
273 greg 1.1 ncol = 0;
274     for (nlin = 0; (count <= 0 || nlin < count) &&
275 greg 1.11 (incnt <= 0 || nlin < incnt) &&
276 greg 1.4 (nread = getrecord(inpval, fp)) > 0;
277 greg 1.1 nlin++) {
278     /* compute */
279 greg 1.4 for (n = 0; n < nread; n++)
280 greg 1.1 switch (func) {
281     case ADD:
282 greg 1.4 if (inpval[n] == 0.0)
283 greg 1.1 break;
284     if (power != 0.0)
285 greg 1.4 tally[n] += pow(fabs(inpval[n]),power);
286 greg 1.1 else
287 greg 1.4 tally[n] += inpval[n];
288 greg 1.1 break;
289     case MULT:
290 greg 1.4 if (inpval[n] == 0.0)
291 greg 1.7 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 greg 1.1 break;
299     case MAX:
300 greg 1.4 if (inpval[n] > tally[n])
301     tally[n] = inpval[n];
302 greg 1.1 break;
303     case MIN:
304 greg 1.4 if (inpval[n] < tally[n])
305     tally[n] = inpval[n];
306 greg 1.1 break;
307     }
308 greg 1.4 if (nread > ncol)
309     ncol = nread;
310 greg 1.1 }
311     if (nlin == 0)
312     break;
313     /* compute and print */
314     ltotal += nlin;
315     for (n = 0; n < ncol; n++) {
316 greg 1.4 result[n] = tally[n];
317 greg 1.1 if (mean) {
318 greg 1.4 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 greg 1.1 }
322     if (func == MULT)
323 greg 1.7 result[n] = rsign[n] * exp(result[n]);
324 greg 1.1 }
325 greg 1.4 putrecord(result, ncol, stdout);
326 greg 1.11 ++nrecsout;
327     if (outcnt > 0 && nrecsout >= outcnt)
328     break;
329 greg 1.1 if (!subtotal)
330     ltotal = 0;
331 greg 1.12 if (incnt > 0 && nlin >= incnt)
332     break;
333 greg 1.1 }
334 greg 1.4 /* close input */
335 greg 1.1 return(fclose(fp));
336     }