ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/total.c
Revision: 1.5
Committed: Sat Oct 8 04:18:16 2005 UTC (18 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R8
Changes since 1.4: +2 -2 lines
Log Message:
Bug fix in combination of -p and -m options in total that broke compamb

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.5 static const char RCSid[] = "$Id: total.c,v 1.4 2005/06/02 04:47:27 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.1
16     #define MAXCOL 256 /* 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     int func = ADD; /* default function */
26     double power = 0.0; /* power for sum */
27     int mean = 0; /* compute mean */
28     int count = 0; /* number to sum */
29 greg 1.4 int nbicols = 0; /* number of binary input columns */
30     int bocols = 0; /* produce binary output columns */
31 greg 1.1 int tabc = '\t'; /* default separator */
32     int subtotal = 0; /* produce subtotals? */
33    
34 schorsch 1.2 static int execute(char *fname);
35 greg 1.1
36 schorsch 1.2 int
37     main(
38     int argc,
39     char *argv[]
40     )
41 greg 1.1 {
42     int status;
43     int a;
44    
45     for (a = 1; a < argc; a++)
46     if (argv[a][0] == '-')
47     if (argv[a][1] >= '0' && argv[a][1] <= '9')
48     count = atoi(argv[a]+1);
49     else
50     switch (argv[a][1]) {
51     case 'm':
52     mean = !mean;
53     break;
54     case 'p':
55     func = MULT;
56     break;
57     case 's':
58     func = ADD;
59     power = atof(argv[a]+2);
60     break;
61     case 'u':
62     func = MAX;
63     break;
64     case 'l':
65     func = MIN;
66     break;
67     case 't':
68     tabc = argv[a][2];
69     break;
70     case 'r':
71     subtotal = !subtotal;
72     break;
73 greg 1.4 case 'i':
74     switch (argv[a][2]) {
75     case 'a':
76     nbicols = 0;
77     break;
78     case 'd':
79     if (isdigit(argv[a][3]))
80     nbicols = atoi(argv[a]+3);
81     else
82     nbicols = 1;
83     if (nbicols > MAXCOL) {
84     fprintf(stderr,
85     "%s: too many input columns\n",
86     argv[0]);
87     exit(1);
88     }
89     break;
90     case 'f':
91     if (isdigit(argv[a][3]))
92     nbicols = -atoi(argv[a]+3);
93     else
94     nbicols = -1;
95     if (-nbicols > MAXCOL) {
96     fprintf(stderr,
97     "%s: too many input columns\n",
98     argv[0]);
99     exit(1);
100     }
101     break;
102     default:
103     goto userr;
104     }
105     break;
106     case 'o':
107     switch (argv[a][2]) {
108     case 'a':
109     bocols = 0;
110     break;
111     case 'd':
112     bocols = 1;
113     break;
114     case 'f':
115     bocols = -1;
116     break;
117     default:
118     goto userr;
119     }
120     break;
121     default:;
122     userr:
123 greg 1.1 fprintf(stderr,
124 greg 1.4 "Usage: %s [-m][-sE|p|u|l][-tC][-i{f|d}[N]][-o{f|d}][-count [-r]] [file..]\n",
125 greg 1.1 argv[0]);
126     exit(1);
127     }
128     else
129     break;
130     if (mean) {
131     if (func == MAX) {
132     fprintf(stderr, "%s: average maximum?!\n", argv[0]);
133     exit(1);
134     }
135     if (func == MIN) {
136     fprintf(stderr, "%s: average minimum?!\n", argv[0]);
137     exit(1);
138     }
139     }
140 greg 1.4 if (bocols)
141     SET_FILE_BINARY(stdout);
142 greg 1.1 status = 0;
143     if (a >= argc)
144     status = execute(NULL) == -1 ? 1 : status;
145     else
146     for ( ; a < argc; a++)
147     status = execute(argv[a]) == -1 ? 2 : status;
148     exit(status);
149     }
150    
151    
152 schorsch 1.2 static int
153 greg 1.4 getrecord( /* read next input record */
154     double field[MAXCOL],
155     FILE *fp
156     )
157     {
158     char buf[16*MAXCOL];
159     char *cp, *num;
160     int nf;
161     /* reading binary input? */
162     if (nbicols > 0)
163     return(fread(field, sizeof(double), nbicols, fp));
164     if (nbicols < 0) {
165     float *fbuf = (float *)buf;
166     int i;
167     nf = fread(fbuf, sizeof(float), -nbicols, fp);
168     for (i = nf; i-- > 0; )
169     field[i] = fbuf[i];
170     return(nf);
171     }
172     /* reading ASCII input */
173     cp = fgets(buf, sizeof(buf), fp);
174     if (cp == NULL)
175     return(0);
176     for (nf = 0; nf < MAXCOL; nf++) {
177     while (isspace(*cp))
178     cp++;
179     if (!*cp)
180     break;
181     num = cp;
182     while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc))
183     cp++;
184     if (*cp)
185     *cp++ = '\0';
186     if (!*num || isspace(*num))
187     field[nf] = init_val[func];
188     else
189     field[nf] = atof(num);
190     }
191     return(nf);
192     }
193    
194    
195     static void
196     putrecord( /* write out results record */
197     const double *field,
198     int n,
199     FILE *fp
200     )
201     {
202     /* binary output? */
203     if (bocols > 0) {
204     fwrite(field, sizeof(double), n, fp);
205     return;
206     }
207     if (bocols < 0) {
208     float fv;
209     while (n-- > 0) {
210     fv = *field++;
211     fwrite(&fv, sizeof(float), 1, fp);
212     }
213     return;
214     }
215     /* ASCII output */
216     while (n-- > 0)
217     fprintf(fp, "%.9g%c", *field++, tabc);
218     fputc('\n', fp);
219     }
220    
221    
222     static int
223 schorsch 1.2 execute( /* compute result */
224     char *fname
225     )
226 greg 1.1 {
227 greg 1.4 double inpval[MAXCOL];
228     double tally[MAXCOL];
229 greg 1.1 double result[MAXCOL];
230     register int n;
231 greg 1.4 int nread, ncol;
232 greg 1.1 long nlin, ltotal;
233     FILE *fp;
234     /* open file */
235     if (fname == NULL)
236     fp = stdin;
237     else if ((fp = fopen(fname, "r")) == NULL) {
238     fprintf(stderr, "%s: cannot open\n", fname);
239     return(-1);
240     }
241 greg 1.4 if (nbicols)
242     SET_FILE_BINARY(fp);
243 greg 1.1 ltotal = 0;
244     while (!feof(fp)) {
245 schorsch 1.3 if (ltotal == 0) { /* initialize */
246 greg 1.1 if (func == MULT) /* special case */
247     for (n = 0; n < MAXCOL; n++)
248 greg 1.4 tally[n] = 0.0;
249 greg 1.1 else
250     for (n = 0; n < MAXCOL; n++)
251 greg 1.4 tally[n] = init_val[func];
252 schorsch 1.3 }
253 greg 1.1 ncol = 0;
254     for (nlin = 0; (count <= 0 || nlin < count) &&
255 greg 1.4 (nread = getrecord(inpval, fp)) > 0;
256 greg 1.1 nlin++) {
257     /* compute */
258 greg 1.4 for (n = 0; n < nread; n++)
259 greg 1.1 switch (func) {
260     case ADD:
261 greg 1.4 if (inpval[n] == 0.0)
262 greg 1.1 break;
263     if (power != 0.0)
264 greg 1.4 tally[n] += pow(fabs(inpval[n]),power);
265 greg 1.1 else
266 greg 1.4 tally[n] += inpval[n];
267 greg 1.1 break;
268     case MULT:
269 greg 1.4 if (inpval[n] == 0.0)
270 greg 1.1 break;
271 greg 1.4 tally[n] += log(fabs(inpval[n]));
272 greg 1.1 break;
273     case MAX:
274 greg 1.4 if (inpval[n] > tally[n])
275     tally[n] = inpval[n];
276 greg 1.1 break;
277     case MIN:
278 greg 1.4 if (inpval[n] < tally[n])
279     tally[n] = inpval[n];
280 greg 1.1 break;
281     }
282 greg 1.4 if (nread > ncol)
283     ncol = nread;
284 greg 1.1 }
285     if (nlin == 0)
286     break;
287     /* compute and print */
288     ltotal += nlin;
289     for (n = 0; n < ncol; n++) {
290 greg 1.4 result[n] = tally[n];
291 greg 1.1 if (mean) {
292 greg 1.4 result[n] /= (double)ltotal;
293     if (func == ADD && power != 0.0 && result[n] != 0.0)
294     result[n] = pow(result[n], 1.0/power);
295 greg 1.1 }
296     if (func == MULT)
297 greg 1.5 result[n] = exp(result[n]);
298 greg 1.1 }
299 greg 1.4 putrecord(result, ncol, stdout);
300 greg 1.1 if (!subtotal)
301     ltotal = 0;
302     }
303 greg 1.4 /* close input */
304 greg 1.1 return(fclose(fp));
305     }