ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/tabfunc.c
Revision: 1.8
Committed: Sat Dec 28 18:05:13 2019 UTC (4 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.7: +1 -4 lines
Log Message:
Removed redundant include files

File Contents

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