1 /*
2 * Copyright (c) 1996-2000 Lucent Technologies.
3 * See README file for details.
4 */
5
6 #include <ctype.h>
7 #include "local.h"
8
9 #ifdef CVERSION
10
11 extern lfit lf;
12 extern int ar_setfunction();
13
vadd(double e1,double e2)14 double vadd(double e1,double e2) { return(e1+e2); }
vsub(double e1,double e2)15 double vsub(double e1,double e2) { return(e1-e2); }
vmul(double e1,double e2)16 double vmul(double e1,double e2) { return(e1*e2); }
vdiv(double e1,double e2)17 double vdiv(double e1,double e2) { return(e1/e2); }
vpow(double e1,double e2)18 double vpow(double e1,double e2)
19 { if (e2==2) return(e1*e1);
20 if (e1<=0) return(0.0);
21 return(exp(e2*log(e1)));
22 }
vgt(double e1,double e2)23 double vgt(double e1,double e2) { return((double)(e1>e2)); }
vlt(double e1,double e2)24 double vlt(double e1,double e2) { return((double)(e1<e2)); }
vge(double e1,double e2)25 double vge(double e1,double e2) { return((double)(e1>=e2)); }
vle(double e1,double e2)26 double vle(double e1,double e2) { return((double)(e1<=e2)); }
veq(double e1,double e2)27 double veq(double e1,double e2) { return((double)(e1==e2)); }
vne(double e1,double e2)28 double vne(double e1,double e2) { return((double)(e1!=e2)); }
29
30 arstruct art;
31
lf_exp(double x)32 double lf_exp(double x) { return (x<700.0) ? exp(x) : exp(700.0); }
33
vseq(double a,double b,int i,int n)34 double vseq(double a,double b,int i,int n) { return(a+(b-a)*i/(n-1)); }
35
rsample(v)36 double rsample(v)
37 vari *v;
38 { int i;
39 i = (int)( runif() * vlength(v) );
40 return( vitem(v,i) );
41 }
42
vrep(v1,v2)43 vari *vrep(v1,v2)
44 vari *v1, *v2;
45 { int i, j, k, m, n;
46 vari *v;
47 n = 0;
48 for (i=0; i<vlength(v1); i++) n += vitem(v2,i);
49 v = createvar("_vrep",STHIDDEN,n,VDOUBLE);
50 k = 0;
51 if (vlength(v2)==1)
52 { m = vitem(v2,0);
53 for (i=0; i<m; i++)
54 for (j=0; j<vlength(v1); j++)
55 vassn(v,k++,vitem(v1,j));
56 }
57 else
58 { for (i=0; i<vlength(v1); i++)
59 { m = vitem(v2,i);
60 for (j=0; j<m; j++) vassn(v,k++,vitem(v1,i));
61 }
62 }
63 deleteifhidden(v1);
64 deleteifhidden(v2);
65 return(v);
66 }
67
68 /*
69 Set the arguments on arith structures.
70 Argument number p (0,1,2; max args = 3)
71 n is the index of source arstruct.
72 k is the index of the argument arstruct.
73 */
setnext(va,n,p,k)74 void setnext(va,n,p,k)
75 vari *va;
76 int n, p, k;
77 { arstruct *rt;
78 rt = viptr(va,n);
79 if (p>=3)
80 { ERROR(("Too many function arguments"));
81 return;
82 }
83 rt->nx[p] = k;
84 }
85
prars(v,i)86 void prars(v,i)
87 vari *v;
88 int i;
89 { arstruct *ars;
90 ars = (arstruct *)viptr(v,i);
91 printf("%d %c\n",i,ars->cmd);
92 }
93
cmdptr(v,i)94 arstruct *cmdptr(v,i)
95 vari *v;
96 int i;
97 { return((arstruct *)viptr(v,i));
98 }
99
isstring(z,i1,i2)100 int isstring(z,i1,i2)
101 char *z;
102 int i1, i2;
103 { int i;
104 if ((z[i1] != '"') | (z[i2] != '"')) return(0);
105 for (i=i1+1; i<i2; i++) if (z[i]=='"') return(0);
106 return(1);
107 }
108
isname(z,i1,i2)109 int isname(z,i1,i2)
110 char *z;
111 int i1, i2;
112 { int i;
113 if (!isalpha(z[i1])) return(0);
114 for (i=i1+1; i<=i2; i++)
115 if (!isalnum(z[i])) return(0);
116 return(1);
117 }
118
isfunction(z,i1,i2)119 int isfunction(z,i1,i2)
120 char *z;
121 int i1, i2;
122 { int i;
123 if (z[i2] != ')') return(0);
124 i = matchlf(z,i1,i2,'(',')');
125 if (lf_error) return(0);
126 return(isname(z,i1,i-1));
127 }
128
issubset(z,i1,i2)129 int issubset(z,i1,i2)
130 char *z;
131 int i1, i2;
132 { int i;
133 if (z[i2] != ']') return(0);
134 i = matchlf(z,i1,i2,'[',']');
135 if (lf_error) return(0);
136 return(isname(z,i1,i-1));
137 }
138
isNumber(z,i1,i2,val)139 int isNumber(z,i1,i2,val)
140 char *z;
141 int i1, i2;
142 double *val;
143 { char *end;
144 *val = strtod(&z[i1],&end);
145 return(end==&z[i2+1]);
146 }
147
isoperator(z,i1,i2)148 int isoperator(z,i1,i2)
149 char *z;
150 int i1, i2;
151 { int i;
152
153 i = checkrtol(z,i1,i2,",");
154 if (i >= i1) return(i);
155
156 i = checkrtol(z,i1,i2,"=<>");
157 if (i > i1) return(i);
158
159 i = checkrtol(z,i1,i2,"+-");
160 while ((i>i1) && (strchr("+-*/:^",z[i-1])!=NULL))
161 i = checkrtol(z,i1+1,i-1,"+-");
162 if (i>i1) return(i);
163
164 i = checkrtol(z,i1,i2,"*/");
165 if (i >= i1) return(i);
166
167 /* looks like a weird priority for : (sequence) but seems to match S. */
168 i = checkrtol(z,i1,i2,":");
169 if (i >= i1) return(i);
170
171 i = checkrtol(z,i1,i2,"^");
172 if (i >= i1) return(i);
173
174 return(-1);
175 }
176
arbuild(z,i1,i2,va,k,dum)177 vari *arbuild(z,i1,i2,va,k,dum) /* k=0/1 search variable names? */
178 char *z; /* dum: are dummies x0, x1 etc allowed? */
179 INT i1, i2, k, dum;
180 vari *va;
181 { INT al, ar, i, j, n, nargs, rargs, inum;
182 vari *v;
183 arstruct *rt;
184 char tmp;
185 double val;
186
187 if (va==NULL)
188 { va = createvar("_varith",STSYSTEM,10,VARC);
189 if (lf_error || va == NULL)
190 {
191 return(NULL);
192 }
193 else
194 {
195 vlength(va) = 0;
196 }
197 }
198
199 n = vlength(va);
200 if (vbytes(n+1,VARC)>va->bytes) /* need to grow */
201 { v = va;
202 setvarname(va,"_ovarith");
203 va = createvar("_varith",STSYSTEM,n+5,VARC);
204 vlength(va) = n;
205 memcpy(vdptr(va),vdptr(v),vbytes(n,VARC));
206 deletevar(v);
207 }
208 inum = n;
209 vlength(va) = n+1;
210
211 while ((z[i1]=='(') && (matchrt(z,i1,i2,'(',')')==i2)) { i1++; i2--; }
212
213 if (isNumber(z,i1,i2,&val))
214 { rt = cmdptr(va,inum);
215 rt->cmd = 'D';
216 rt->x = val;
217 return(va);
218 }
219
220 if (isstring(z,i1,i2))
221 { rt = cmdptr(va,inum);
222 rt->cmd = 's';
223 rt->vv = createvar("_string",STHIDDEN,i2-i1,VCHAR);
224 for (i=0; i<i2-i1-1; i++) ((char *)vdptr(rt->vv))[i] = z[i1+i+1];
225 ((char *)vdptr(rt->vv))[i2-i1-1] = '\0';
226 return(va);
227 }
228
229 if (isname(z,i1,i2))
230 { tmp = z[i2+1]; z[i2+1] = '\0';
231 if (dum) /* search for dummies */
232 { for (j=0; j<lf.mi[MDIM]; j++)
233 if (strcmp(&z[i1],lf.xname[j])==0)
234 { rt = cmdptr(va,inum);
235 rt->cmd = 'x';
236 rt->m = j;
237 z[i2+1] = tmp;
238 return(va);
239 }
240 }
241 n = 0;
242 v = findvar(&z[i1],1,&n);
243 z[i2+1] = tmp;
244 if (v==NULL) return(va);
245 rt = cmdptr(va,inum);
246 rt->cmd = 'v';
247 rt->vv = v;
248 return(va);
249 }
250
251 if (isfunction(z,i1,i2))
252 {
253 /* build the argument list */
254 ar = i2;
255 al = matchlf(z,i1,i2,'(',')');
256 j = al+1;
257 nargs = 0;
258
259 if (ar>al+1)
260 { i = al;
261 while (j<=ar)
262 { if (z[j]=='(') j = matchrt(z,j,ar-1,'(',')')+1;
263 if (z[j]=='[') j = matchrt(z,j,ar-1,'[',']')+1;
264 if (lf_error) return(va);
265 if ((z[j]==')') | (z[j]==','))
266 { setnext(va,n,nargs,vlength(va));
267 va = arbuild(z,i+1,j-1,va,k,dum);
268 nargs++; i = j;
269 }
270 j++;
271 }
272 }
273 rt = cmdptr(va,inum);
274 rt->m = nargs;
275
276 rargs = ar_setfunction(rt,&z[i1],al-i1);
277 if (rargs != nargs)
278 ERROR(("arbuild: wrong number of arguments, %s",&z[i1]));
279 return(va);
280 }
281
282 rt = cmdptr(va,inum);
283
284 if (issubset(z,i1,i2))
285 { rt->cmd = 'U';
286 al = matchlf(z,i1,i2,'[',']');
287 setnext(va,n,0,vlength(va));
288 va = arbuild(z,i1,al-1,va,k,dum);
289 if (lf_error) return(va);
290 setnext(va,n,1,vlength(va));
291 va = arbuild(z,al+1,i2-1,va,k,dum);
292 return(va);
293 }
294
295 /* that leaves operators */
296
297 i = isoperator(z,i1,i2);
298 if (i >= i1)
299 { rt->cmd = 'O';
300 rt->f = NULL;
301 al = i-1; ar = i+1;
302 if (z[i]==',') rt->cmd = 'C';
303 if (z[i]=='>')
304 { rt->f = vgt;
305 if (z[i-1]=='<') { rt->f = vne; al--; }
306 }
307 if (z[i]=='<') rt->f = vlt;
308 if (z[i]=='=')
309 { rt->f = veq;
310 if (z[i-1]=='=') al--;
311 if (z[i-1]=='<') { rt->f = vle; al--; }
312 if (z[i-1]=='>') { rt->f = vge; al--; }
313 if (z[i-1]=='!') { rt->f = vne; al--; }
314 }
315 if (z[i]=='+') rt->f = vadd;
316 if (z[i]=='-') rt->f = vsub;
317 if (z[i]=='*') rt->f = vmul;
318 if (z[i]=='/') rt->f = vdiv;
319 if (z[i]==':') rt->cmd = ':';
320 if (z[i]=='^') rt->f = vpow;
321
322 setnext(va,n,0,vlength(va));
323 va = arbuild(z,i1,al,va,k,dum);
324 if (lf_error) return(va);
325 setnext(va,n,1,vlength(va));
326 va = arbuild(z,ar,i2,va,k,dum);
327 return(va);
328 }
329
330 ERROR(("arbuild: unknown expression %s",z));
331 return(va);
332 }
333
vevop(l,r,f)334 vari *vevop(l,r,f)
335 vari *l, *r;
336 double (*f)();
337 { INT i, n;
338 vari *v;
339 double z;
340 if ((l==NULL) | (r==NULL)) return(NULL);
341 n = vlength(l);
342 if (n<vlength(r)) n = vlength(r);
343 v = createvar("_vevop",STHIDDEN,n,VDOUBLE);
344 if (lf_error) return(NULL);
345 for (i=0; i<n; i++)
346 { z = f(vitem(l,i),vitem(r,i));
347 vassn(v,i,z);
348 }
349 deleteifhidden(l);
350 deleteifhidden(r);
351 return(v);
352 }
353
vcat(v1,v2)354 vari *vcat(v1,v2)
355 vari *v1, *v2;
356 { INT i, n;
357 vari *v;
358 n = vlength(v1) + vlength(v2);
359 v = createvar("_vcat",STHIDDEN,n,VDOUBLE);
360 if (lf_error) return(NULL);
361 for (i=0; i<vlength(v1); i++) vassn(v,i,vitem(v1,i));
362 for (i=0; i<vlength(v2); i++) vassn(v,i+vlength(v1),vitem(v2,i));
363 deleteifhidden(v1);
364 deleteifhidden(v2);
365 return(v);
366 }
367
vrvec(v1,f)368 vari *vrvec(v1,f)
369 vari *v1;
370 double (*f)();
371 { vari *v;
372 INT i, n;
373 n = (INT)vitem(v1,0);
374 v = createvar("_vrvec",STHIDDEN,n,VDOUBLE);
375 if (lf_error) return(NULL);
376 for (i=0; i<n; i++) vassn(v,i,f());
377 deleteifhidden(v1);
378 return(v);
379 }
380
vrsca(v,f)381 vari *vrsca(v,f)
382 vari *v;
383 double (*f)();
384 { vari *z;
385 if (v==NULL) return(NULL);
386 z = createvar("_vrsca",STHIDDEN,1,VDOUBLE);
387 if (lf_error) return(NULL);
388 vassn(z,(INT)0,f(v));
389 deleteifhidden(v);
390 return(z);
391 }
392
vrve2(v1,a1,f)393 vari *vrve2(v1,a1,f)
394 vari *v1, *a1;
395 double (*f)();
396 { vari *v;
397 int i, n;
398 n = vitem(v1,0);
399 v = createvar("_vrvec",STHIDDEN,n,VDOUBLE);
400 if (lf_error) return(NULL);
401 for (i=0; i<n; i++) vassn(v,i,f(vitem(a1,i)));
402 //deleteifhidden(v1,a1);
403 return(v);
404 }
405
vvec1(l,f)406 vari *vvec1(l,f)
407 vari *l;
408 double (*f)();
409 { vari *v;
410 INT i;
411 if (l==NULL)
412 {
413 ERROR(("vvec1 recieved NULL variable\n"));
414 return NULL;
415 }
416 v = createvar("_vvec1",STHIDDEN,l->n,VDOUBLE);
417 if (lf_error) return(NULL);
418 for (i=0; i<vlength(l); i++) vassn(v,i,f(vitem(l,i)));
419 deleteifhidden(l);
420 return(v);
421 }
422
vrsamp(v1,v2)423 vari *vrsamp(v1,v2)
424 vari *v1, *v2;
425 { vari *v;
426 int i, n;
427 n = vitem(v2,0);
428 v = createvar("_vrsamp",STHIDDEN,n,VDOUBLE);
429 if (lf_error) return(NULL);
430 for (i=0; i<n; i++) vassn(v,i,rsample(v1));
431 deleteifhidden(v1);
432 deleteifhidden(v2);
433 return(v);
434 }
435
vrseq(v1,v2,v3)436 vari *vrseq(v1,v2,v3)
437 vari *v1, *v2, *v3;
438 { vari *v;
439 double beg, end;
440 int i, n;
441 n = vitem(v3,0);
442 v = createvar("_vrseq",STHIDDEN,n,VDOUBLE);
443 if (lf_error) return(NULL);
444 beg = vitem(v1,0);
445 end = vitem(v2,0);
446 for (i=0; i<n; i++) vassn(v,i,vseq(beg,end,i,n));
447 deleteifhidden(v1);
448 deleteifhidden(v2);
449 deleteifhidden(v3);
450 return(v);
451 }
452
vrse2(v1,v2)453 vari *vrse2(v1,v2)
454 vari *v1, *v2;
455 { vari *v;
456 double beg, end;
457 int i, n;
458 beg = vitem(v1,0);
459 end = vitem(v2,0);
460 n = (beg<=end) ? end-beg+1 : beg-end+1;
461 v = createvar("_vrse2",STHIDDEN,n,VDOUBLE);
462 if (lf_error) return(NULL);
463 if (beg<=end) for (i=0; i<n; i++) vassn(v,i,beg+i);
464 else for (i=0; i<n; i++) vassn(v,i,beg-i);
465 deleteifhidden(v1);
466 deleteifhidden(v2);
467 return(v);
468 }
469
vsubset(v1,v2)470 vari *vsubset(v1,v2)
471 vari *v1, *v2;
472 { vari *v;
473 int i, n;
474 n = v2->n;
475 v = createvar("_vsubs",STHIDDEN,n,VDOUBLE);
476 for (i=0; i<n; i++) vassn(v,i,vitem(v1,vitem(v2,i)-1));
477 deleteifhidden(v1);
478 deleteifhidden(v2);
479 return(v);
480 }
481
vareval(v,k)482 vari *vareval(v,k)
483 vari *v;
484 INT k;
485 { INT n;
486 arstruct *rt;
487 rt = viptr(v,k);
488 switch (rt->cmd)
489 { case 'e': return(NULL);
490 case 'v': return(rt->vv);
491 case 'O': return(vevop(vareval(v,rt->nx[0]),vareval(v,rt->nx[1]),rt->f));
492 case 'C': return(vcat(vareval(v,rt->nx[0]),vareval(v,rt->nx[1])));
493 case 'D':
494 n = 1;
495 rt->vv = createvar("_vevcon",STHIDDEN,n,VDOUBLE);
496 if (lf_error) return(NULL);
497 vassn(rt->vv,0,rt->x);
498 return(rt->vv);
499 case 'G': return(vrvec(vareval(v,rt->nx[0]),rt->f));
500 case 'H': return(vrve2(vareval(v,rt->nx[0]),vareval(v,rt->nx[1]),rt->f));
501 case 'f': return(vvec1(vareval(v,rt->nx[0]),rt->f));
502 case 'M': return(vrsamp(vareval(v,rt->nx[0]),vareval(v,rt->nx[1])));
503 case 'Q': return(vrseq(vareval(v,rt->nx[0]),vareval(v,rt->nx[1]),
504 vareval(v,rt->nx[2])));
505 case ':': return(vrse2(vareval(v,rt->nx[0]),vareval(v,rt->nx[1])));
506 case 'S': return(vrsca(vareval(v,rt->nx[0]),rt->f));
507 case 'U': return(vsubset(vareval(v,rt->nx[0]),vareval(v,rt->nx[1])));
508 case 'R': return(vrep(vareval(v,rt->nx[0]),vareval(v,rt->nx[1])));
509 case 'Z': return(vfitted(RMEAN));
510 case 'Y': return(vfitted(RDEV));
511 case 's': return(rt->vv);
512 case 'x':
513 ERROR(("Dummy in vareval"));
514 return(NULL);
515 default : ERROR(("vareval: unknown command %c",rt->cmd));
516 }
517 return(NULL);
518 }
519
saveresult(v,name,status)520 vari *saveresult(v,name,status)
521 vari *v;
522 int status;
523 char *name;
524 { vari *vr;
525 if (v==NULL) return(NULL);
526
527 vr = v;
528 if (v->stat != STHIDDEN)
529 { vr = createvar("_result",STHIDDEN,vlength(v),vmode(v));
530 memcpy(vdptr(vr),vdptr(v),vbytes(vlength(v),vmode(v)));
531 }
532
533 if (name!=NULL)
534 { setvarname(vr,name);
535 vr->stat = status;
536 }
537 return(vr);
538 }
539
varith(z,name,status)540 vari *varith(z,name,status)
541 char *z, *name;
542 int status;
543 { vari *v, *va;
544 va = arbuild(z,0,strlen(z)-1,NULL,1,0);
545 if (lf_error) return(NULL);
546 v = vareval(va,0);
547 deletevar(va);
548
549 v = saveresult(v,name,status);
550 return(v);
551 }
552
dareval(v,k,x)553 double dareval(v,k,x)
554 vari *v;
555 INT k;
556 double *x;
557 { arstruct *rt;
558 rt = viptr(v,k);
559 switch (rt->cmd)
560 { case 'e': return(0.0);
561 case 'v': return(vitem(rt->vv,0));
562 case 'O': return(rt->f(dareval(v,rt->nx[0],x),dareval(v,rt->nx[1],x)));
563 case 'P': return(rt->f(0.0,dareval(v,rt->nx[1],x)));
564 case 'D': return(rt->x);
565 case 'G': return(rt->f());
566 case 'H': return(rt->f(dareval(v,rt->nx[1],x)));
567 case 'f': return(rt->f(dareval(v,rt->nx[0],x)));
568 case 'M': return(rsample(vareval(v,rt->nx[0])));
569 case 'x': return(x[rt->m]);
570 case 'U': return(vitem(vareval(v,rt->nx[0]),(int)dareval(v,rt->nx[1],x)-1));
571 case 'Q': ERROR(("sequence in dareval"));
572 return(0.0);
573 default : ERROR(("dareval: unknown command %c",rt->cmd));
574 }
575 return(0.0);
576 }
577
darith(z)578 double darith(z)
579 char *z;
580 { vari *va;
581 double y;
582 va = arbuild(z,0,strlen(z)-1,NULL,1,0);
583 y = dareval(va,0,NULL);
584 deletevar(va);
585 return(y);
586 }
587
arvect(z,res,c,a)588 INT arvect(z,res,c,a) /* c = no of items to read */
589 char *z;
590 INT c, a;
591 double *res;
592 { INT i;
593 vari *v;
594
595 if (z==NULL) return(0);
596
597 v = varith(z,"arvect",STPLOTVAR);
598 if (v==NULL || lf_error)
599 {
600 return(0);
601 }
602 deletevar(v);
603
604 for (i=0; (i<c) & (i<vlength(v)); i++) res[i] = vitem(v,i);
605 if (i<c) /* insufficient items */
606 { switch(a)
607 { case 0: /* pad */
608 for (; i<c; i++) res[i] = res[0];
609 return(c);
610 case 1: return(i); /* ignore */
611 case 2:
612 ERROR(("Insufficient items: %s",z));
613 return(i);
614 }
615 }
616 return(i);
617 }
618
619 #endif
620