ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/total.c
Revision: 1.12
Committed: Thu Mar 24 19:00:54 2016 UTC (8 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +3 -1 lines
Log Message:
I guess I can't count...

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: total.c,v 1.11 2016/03/24 18:48:28 greg Exp $";
3 #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 #include "platform.h"
15
16 #define MAXCOL 8192 /* maximum number of columns */
17
18 #define ADD 0 /* add numbers */
19 #define MULT 1 /* multiply numbers */
20 #define MAX 2 /* maximum */
21 #define MIN 3 /* minimum */
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 int
41 main(
42 int argc,
43 char *argv[]
44 )
45 {
46 int status;
47 int a;
48
49 for (a = 1; a < argc; a++)
50 if (argv[a][0] == '-')
51 if (argv[a][1] >= '0' && argv[a][1] <= '9')
52 count = atoi(argv[a]+1);
53 else
54 switch (argv[a][1]) {
55 case 'm':
56 mean = !mean;
57 break;
58 case 'p':
59 func = MULT;
60 break;
61 case 's':
62 func = ADD;
63 power = atof(argv[a]+2);
64 break;
65 case 'u':
66 func = MAX;
67 break;
68 case 'l':
69 func = MIN;
70 break;
71 case 't':
72 tabc = argv[a][2];
73 break;
74 case 'r':
75 subtotal = !subtotal;
76 break;
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][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
135 argv[0]);
136 exit(1);
137 }
138 else
139 break;
140 if (mean) {
141 if (func == MAX) {
142 fprintf(stderr, "%s: average maximum?!\n", argv[0]);
143 exit(1);
144 }
145 if (func == MIN) {
146 fprintf(stderr, "%s: average minimum?!\n", argv[0]);
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 && (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(fread(field, sizeof(double), nbicols, fp));
174 if (nbicols < 0) {
175 float *fbuf = (float *)buf;
176 int i;
177 nf = fread(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 fwrite(field, sizeof(double), n, fp);
215 return;
216 }
217 if (bocols < 0) {
218 float fv;
219 while (n-- > 0) {
220 fv = *field++;
221 fwrite(&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 int n;
244 int nread, ncol;
245 long nlin, ltotal;
246 FILE *fp;
247 /* open file */
248 if (fname == NULL)
249 fp = stdin;
250 else if ((fp = fopen(fname, "r")) == NULL) {
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 tally[n] = 0.0;
266 rsign[n] = 1;
267 }
268 else
269 for (n = 0; n < MAXCOL; n++)
270 tally[n] = init_val[func];
271 }
272 ncol = 0;
273 for (nlin = 0; (count <= 0 || nlin < count) &&
274 (incnt <= 0 || nlin < incnt) &&
275 (nread = getrecord(inpval, fp)) > 0;
276 nlin++) {
277 /* compute */
278 for (n = 0; n < nread; n++)
279 switch (func) {
280 case ADD:
281 if (inpval[n] == 0.0)
282 break;
283 if (power != 0.0)
284 tally[n] += pow(fabs(inpval[n]),power);
285 else
286 tally[n] += inpval[n];
287 break;
288 case MULT:
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 (inpval[n] > tally[n])
300 tally[n] = inpval[n];
301 break;
302 case MIN:
303 if (inpval[n] < tally[n])
304 tally[n] = inpval[n];
305 break;
306 }
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 result[n] = tally[n];
316 if (mean) {
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 result[n] = rsign[n] * exp(result[n]);
323 }
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 input */
334 return(fclose(fp));
335 }