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