ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/tabfunc.c
Revision: 1.1
Committed: Sat Feb 22 02:07:20 2003 UTC (21 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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