ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/tabfunc.c
Revision: 1.10
Committed: Thu Mar 18 03:09:34 2021 UTC (3 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4
Changes since 1.9: +9 -8 lines
Log Message:
fix: repaired out-of-order function output for irregular abscissa

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.10 static const char RCSid[] = "$Id: tabfunc.c,v 1.9 2020/06/29 21:25:36 greg 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 <stdlib.h>
11     #include <math.h>
12     #include <ctype.h>
13 schorsch 1.2
14 schorsch 1.4 #include "rtprocess.h" /* getpid() */
15     #include "rtmath.h"
16     #include "rtio.h"
17 greg 1.1
18     #define isdelim(c) (isspace(c) || (c)==',')
19    
20 greg 1.7 #define MAXTAB 8192 /* maximum number of data rows */
21     #define MAXLINE 16384 /* maximum line width (characters) */
22 greg 1.1 #define OUTFMT "%.7g" /* output format conversion string */
23    
24     int interpolate = 0;
25     char *progname;
26     char **func;
27     int nfuncs;
28    
29 schorsch 1.3 RREAL abscissa[MAXTAB]; /* independent values (first column) */
30     RREAL (*ordinate)[MAXTAB]; /* dependent values (other columns) */
31 greg 1.1 int tabsize = 0; /* final table size (number of rows) */
32     char locID[16]; /* local identifier (for uniqueness) */
33    
34 schorsch 1.2 /*extern char *fgets(), *fskip(), *absc_exp();*/
35 greg 1.1
36 schorsch 1.2 static void load_data(FILE *fp);
37     static void print_funcs(char *xe);
38 schorsch 1.3 static void putlist(register RREAL *av, int al, register int pos);
39 schorsch 1.2 static char * absc_exp(void);
40    
41     int
42     main(
43     int argc,
44     char **argv
45     )
46 greg 1.1 {
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 schorsch 1.3 ordinate = (RREAL (*)[MAXTAB])malloc(nfuncs*MAXTAB*sizeof(RREAL));
64 greg 1.1 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 schorsch 1.2 static void
76     load_data( /* load tabular data from fp */
77     FILE *fp
78     )
79 greg 1.1 {
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 schorsch 1.2 static char *
124     absc_exp(void) /* produce expression for abscissa */
125 greg 1.1 {
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 greg 1.6 } else if (fabs(abscissa[0]) < eps)
152     sprintf(ourexp, "x/%g+1", step);
153     else
154 greg 1.1 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 greg 1.10 if (increasing)
160 greg 1.9 printf("fx2`%s(x,i):if(x-X`%s(i),\n", locID, locID);
161 greg 1.10 else
162     printf("fx2`%s(x,i):if(X`%s(i)-x,\n", locID, locID);
163     printf("\ti+(x-X`%s(i))/(X`%s(i+1)-X`%s(i)),\n",
164     locID, locID, locID);
165     printf("\tfx2`%s(x,i-1));\n", locID);
166     if (increasing)
167 greg 1.1 printf("fx`%s(x):if(x-%g,if(%g-x,fx2`%s(x,%d),%d),1);\n",
168     locID, abscissa[0], abscissa[tabsize-1],
169     locID, tabsize, tabsize);
170 greg 1.10 else
171 greg 1.1 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     sprintf(ourexp, "fx`%s(x)", locID);
175     }
176     return(ourexp);
177     }
178    
179    
180 schorsch 1.2 static void
181     print_funcs( /* print functions */
182     char *xe
183     )
184 greg 1.1 {
185     int xelen;
186     register int i;
187    
188     xelen = strlen(xe);
189     for (i = 0; i < nfuncs; i++) {
190 schorsch 1.5 if ((func[i][0] == '\0') | (func[i][0] == '0'))
191 greg 1.1 continue;
192     if (interpolate) {
193     printf("%s`%s(i):select(i,", func[i], locID);
194     putlist(ordinate[i], tabsize,
195     27+strlen(func[i]));
196     puts(");");
197     printf("%s(x):interp_arr`(%s,%s`%s);\n",
198     func[i], xe, func[i], locID);
199     } else {
200     printf("%s(x):select(%s,", func[i], xe);
201     putlist(ordinate[i], tabsize, strlen(func[i])+xelen+12);
202     puts(");");
203     }
204     }
205     }
206    
207    
208 schorsch 1.2 static void
209     putlist( /* put out array of values */
210 schorsch 1.3 register RREAL *av,
211 schorsch 1.2 int al,
212     register int pos
213     )
214 greg 1.1 {
215     char obuf[32];
216     int len;
217    
218     while (al--) {
219     sprintf(obuf, OUTFMT, *av++);
220     pos += (len = strlen(obuf)+1);
221     if (pos >= 64) {
222     putchar('\n');
223     pos = len;
224     }
225     fputs(obuf, stdout);
226     if (al)
227     putchar(',');
228     }
229     }