ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/tabfunc.c
Revision: 1.3
Committed: Thu Jun 26 00:58:09 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.2: +6 -7 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

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