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, 10 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: tabfunc.c,v 1.1 2003/02/22 02:07:20 greg Exp $";
3 #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 #include <string.h>
13 #include <math.h>
14 #include <ctype.h>
15 #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
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 /*#define FLOAT float */ /* real type (precision) */
30 #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 /*extern char *fgets(), *fskip(), *absc_exp();*/
43
44 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 {
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 static void
84 load_data( /* load tabular data from fp */
85 FILE *fp
86 )
87 {
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 static char *
132 absc_exp(void) /* produce expression for abscissa */
133 {
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 static void
186 print_funcs( /* print functions */
187 char *xe
188 )
189 {
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 static void
214 putlist( /* put out array of values */
215 register FLOAT *av,
216 int al,
217 register int pos
218 )
219 {
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 }