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, 1 month 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

# User Rev Content
1 greg 1.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     }