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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: total.c,v 1.12 2016/03/24 19:00:54 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 #include "rtio.h"
16
17 #define MAXCOL 8192 /* maximum number of columns */
18
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 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
41 int
42 main(
43 int argc,
44 char *argv[]
45 )
46 {
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 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][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
136 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 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 && (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 int n;
245 int nread, ncol;
246 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 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 tally[n] = 0.0;
267 rsign[n] = 1;
268 }
269 else
270 for (n = 0; n < MAXCOL; n++)
271 tally[n] = init_val[func];
272 }
273 ncol = 0;
274 for (nlin = 0; (count <= 0 || nlin < count) &&
275 (incnt <= 0 || nlin < incnt) &&
276 (nread = getrecord(inpval, fp)) > 0;
277 nlin++) {
278 /* compute */
279 for (n = 0; n < nread; n++)
280 switch (func) {
281 case ADD:
282 if (inpval[n] == 0.0)
283 break;
284 if (power != 0.0)
285 tally[n] += pow(fabs(inpval[n]),power);
286 else
287 tally[n] += inpval[n];
288 break;
289 case MULT:
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 (inpval[n] > tally[n])
301 tally[n] = inpval[n];
302 break;
303 case MIN:
304 if (inpval[n] < tally[n])
305 tally[n] = inpval[n];
306 break;
307 }
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 result[n] = tally[n];
317 if (mean) {
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 result[n] = rsign[n] * exp(result[n]);
324 }
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 input */
335 return(fclose(fp));
336 }