ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/tabfunc.c
Revision: 1.2
Committed: Sun Jun 8 12:03:09 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.1: +39 -17 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.2 static const char RCSid[] = "$Id: tabfunc.c,v 1.1 2003/02/22 02:07:20 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * Put tabular data into functions suitable for cal programs.
6     *
7     * 2/2/95 Greg Ward
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12 schorsch 1.2 #include <string.h>
13 greg 1.1 #include <math.h>
14     #include <ctype.h>
15 schorsch 1.2 #ifdef _WIN32
16     #include <process.h> /* getpid() */
17     #else
18     #include <sys/types.h>
19     #include <unistd.h>
20     #endif
21    
22     #include "standard.h"
23     #include "platform.h"
24 greg 1.1
25     #define isdelim(c) (isspace(c) || (c)==',')
26    
27     #define MAXTAB 1024 /* maximum number of data rows */
28     #define MAXLINE 4096 /* maximum line width (characters) */
29 schorsch 1.2 /*#define FLOAT float */ /* real type (precision) */
30 greg 1.1 #define OUTFMT "%.7g" /* output format conversion string */
31    
32     int interpolate = 0;
33     char *progname;
34     char **func;
35     int nfuncs;
36    
37     FLOAT abscissa[MAXTAB]; /* independent values (first column) */
38     FLOAT (*ordinate)[MAXTAB]; /* dependent values (other columns) */
39     int tabsize = 0; /* final table size (number of rows) */
40     char locID[16]; /* local identifier (for uniqueness) */
41    
42 schorsch 1.2 /*extern char *fgets(), *fskip(), *absc_exp();*/
43 greg 1.1
44 schorsch 1.2 static void load_data(FILE *fp);
45     static void print_funcs(char *xe);
46     static void putlist(register FLOAT *av, int al, register int pos);
47     static char * absc_exp(void);
48    
49     int
50     main(
51     int argc,
52     char **argv
53     )
54 greg 1.1 {
55     progname = argv[0];
56     argv++;
57     argc--;
58     if (argc && !strcmp(argv[0], "-i")) {
59     interpolate++;
60     puts("interp_arr2`(i,x,f):(i+1-x)*f(i)+(x-i)*f(i+1);");
61     puts("interp_arr`(x,f):if(x-1,if(f(0)-x,interp_arr2`(floor(x),x,f),f(f(0))),f(1));");
62     argv++;
63     argc--;
64     }
65     if (!argc || argv[0][0] == '-') {
66     fprintf(stderr, "Usage: %s [-i] func1 [func2 ..]\n", progname);
67     exit(1);
68     }
69     func = argv;
70     nfuncs = argc;
71     ordinate = (FLOAT (*)[MAXTAB])malloc(nfuncs*MAXTAB*sizeof(FLOAT));
72     if (ordinate == NULL) {
73     fprintf(stderr, "%s: not enough memory\n", progname);
74     exit(1);
75     }
76     sprintf(locID, "p%d", getpid());
77     load_data(stdin);
78     print_funcs(absc_exp());
79     exit(0);
80     }
81    
82    
83 schorsch 1.2 static void
84     load_data( /* load tabular data from fp */
85     FILE *fp
86     )
87 greg 1.1 {
88     int lineno;
89     char *err;
90     char inpbuf[MAXLINE];
91     register char *cp;
92     register int i;
93    
94     tabsize = lineno = 0;
95     inpbuf[MAXLINE-2] = '\n';
96     while (fgets(inpbuf, MAXLINE, fp) != NULL) {
97     lineno++;
98     if (inpbuf[MAXLINE-2] != '\n') {
99     err = "line too long";
100     goto fatal;
101     }
102     if (tabsize >= MAXTAB-1) {
103     err = "too many rows";
104     goto fatal;
105     }
106     if ((cp = fskip(inpbuf)) == NULL)
107     continue; /* skip non-data lines */
108     abscissa[tabsize] = atof(inpbuf);
109     for (i = 0; i < nfuncs; i++) {
110     while (isdelim(*cp))
111     cp++;
112     if (!*cp) {
113     err = "too few columns";
114     goto fatal;
115     }
116     ordinate[i][tabsize] = atof(cp);
117     if ((cp = fskip(cp)) == NULL) {
118     err = "bad floating-point format";
119     goto fatal;
120     }
121     }
122     tabsize++;
123     }
124     return;
125     fatal:
126     fprintf(stderr, "%s: input line %d: %s\n", progname, lineno, err);
127     exit(1);
128     }
129    
130    
131 schorsch 1.2 static char *
132     absc_exp(void) /* produce expression for abscissa */
133 greg 1.1 {
134     static char ourexp[64];
135     double step, eps;
136     int uniform, increasing;
137     register int i;
138    
139     if (tabsize < 2)
140     return("1");
141     step = abscissa[1] - abscissa[0];
142     eps = ((increasing = (step > 0)) ? 1e-3 : -1e-3) * step;
143     uniform = 1;
144     for (i = 2; i < tabsize; i++) {
145     if (uniform && fabs((abscissa[i]-abscissa[i-1]) - step) > eps)
146     uniform = 0;
147     if (!uniform && (abscissa[i-1] < abscissa[i]) != increasing) {
148     fprintf(stderr, "%s: input not a function\n",
149     progname);
150     exit(1);
151     }
152     }
153     if (uniform) {
154     if (increasing && fabs(step - 1) < eps) {
155     if (fabs(abscissa[0] - 1) < eps)
156     strcpy(ourexp, "x");
157     else
158     sprintf(ourexp, "x-%g", abscissa[0]-1);
159     } else
160     sprintf(ourexp, "(x-%g)/%g+1", abscissa[0], step);
161     } else {
162     printf("X`%s(i):select(i,", locID);
163     putlist(abscissa, tabsize, 20);
164     puts(");");
165     if (increasing) {
166     printf("fx`%s(x):if(x-%g,if(%g-x,fx2`%s(x,%d),%d),1);\n",
167     locID, abscissa[0], abscissa[tabsize-1],
168     locID, tabsize, tabsize);
169     printf("fx2`%s(x,i):if(x-X`%s(i),\n", locID, locID);
170     } else {
171     printf("fx`%s(x):if(%g-x,if(x-%g,fx2`%s(x,%d),%d),1);\n",
172     locID, abscissa[0], abscissa[tabsize-1],
173     locID, tabsize, tabsize);
174     printf("fx2`%s(x,i):if(X`%s(i)-x,\n", locID, locID);
175     }
176     printf("\ti+(x-X`%s(i))/(X`%s(i+1)-X`%s(i)),\n",
177     locID, locID, locID);
178     printf("\tfx2`%s(x,i-1));\n", locID);
179     sprintf(ourexp, "fx`%s(x)", locID);
180     }
181     return(ourexp);
182     }
183    
184    
185 schorsch 1.2 static void
186     print_funcs( /* print functions */
187     char *xe
188     )
189 greg 1.1 {
190     int xelen;
191     register int i;
192    
193     xelen = strlen(xe);
194     for (i = 0; i < nfuncs; i++) {
195     if (func[i][0] == '\0' | func[i][0] == '0')
196     continue;
197     if (interpolate) {
198     printf("%s`%s(i):select(i,", func[i], locID);
199     putlist(ordinate[i], tabsize,
200     27+strlen(func[i]));
201     puts(");");
202     printf("%s(x):interp_arr`(%s,%s`%s);\n",
203     func[i], xe, func[i], locID);
204     } else {
205     printf("%s(x):select(%s,", func[i], xe);
206     putlist(ordinate[i], tabsize, strlen(func[i])+xelen+12);
207     puts(");");
208     }
209     }
210     }
211    
212    
213 schorsch 1.2 static void
214     putlist( /* put out array of values */
215     register FLOAT *av,
216     int al,
217     register int pos
218     )
219 greg 1.1 {
220     char obuf[32];
221     int len;
222    
223     while (al--) {
224     sprintf(obuf, OUTFMT, *av++);
225     pos += (len = strlen(obuf)+1);
226     if (pos >= 64) {
227     putchar('\n');
228     pos = len;
229     }
230     fputs(obuf, stdout);
231     if (al)
232     putchar(',');
233     }
234     }