| 0 | 1 /* | 
|  | 2  * Copyright 1996-2006 Catherine Loader. | 
|  | 3  */ | 
|  | 4 | 
|  | 5 #include "mex.h" | 
|  | 6 /* | 
|  | 7  * Copyright 1996-2006 Catherine Loader. | 
|  | 8  */ | 
|  | 9 #include "lfev.h" | 
|  | 10 | 
|  | 11 extern void fitoptions(); | 
|  | 12 | 
|  | 13 static double hmin, gmin, sig2, pen, vr, tb; | 
|  | 14 static lfit *blf; | 
|  | 15 static design *bdes; | 
|  | 16 | 
|  | 17 int procvbind(des,lf,v) | 
|  | 18 design *des; | 
|  | 19 lfit *lf; | 
|  | 20 int v; | 
|  | 21 { double s0, s1, bi; | 
|  | 22   int i, ii, k; | 
|  | 23   k = procv_var(des,lf,v); | 
|  | 24   wdiag(&lf->lfd, &lf->sp, des,des->wd,&lf->dv,0,1,0); | 
|  | 25   s0 = s1 = 0.0; | 
|  | 26   for (i=0; i<des->n; i++) | 
|  | 27   { ii = des->ind[i]; | 
|  | 28     s0+= prwt(&lf->lfd,ii)*des->wd[i]*des->wd[i]; | 
|  | 29     bi = prwt(&lf->lfd,ii)*fabs(des->wd[i]*ipower(dist(des,ii),deg(&lf->sp)+1)); | 
|  | 30     s1+= bi*bi; | 
|  | 31   } | 
|  | 32   vr += s0; | 
|  | 33   tb += s1; | 
|  | 34   return(k); | 
|  | 35 } | 
|  | 36 | 
|  | 37 double bcri(h,c,cri) | 
|  | 38 double h; | 
|  | 39 int c, cri; | 
|  | 40 { double num, den, res[10]; | 
|  | 41   int (*pv)(); | 
|  | 42   if (c==DALP) | 
|  | 43     blf->sp.nn = h; | 
|  | 44   else | 
|  | 45     blf->sp.fixh = h; | 
|  | 46   if ((cri&63)==BIND) | 
|  | 47   { pv = procvbind; | 
|  | 48     vr = tb = 0.0; | 
|  | 49   } | 
|  | 50   else pv = procvstd; | 
|  | 51   if (cri<64) startlf(bdes,blf,pv,0); | 
|  | 52   switch(cri&63) | 
|  | 53   { case BGCV: | 
|  | 54       ressumm(blf,bdes,res); | 
|  | 55       num = -2*blf->lfd.n*res[0]; | 
|  | 56       den = blf->lfd.n-res[1]; | 
|  | 57       return(num/(den*den)); | 
|  | 58     case BCP: | 
|  | 59       ressumm(blf,bdes,res); | 
|  | 60       return(-2*res[0]/sig2-blf->lfd.n+pen*res[1]); | 
|  | 61     case BIND: | 
|  | 62       return(vr+pen*pen*tb); | 
|  | 63   } | 
|  | 64   LERR(("bcri: unknown criterion")); | 
|  | 65   return(0.0); | 
|  | 66 } | 
|  | 67 | 
|  | 68 void bsel2(h0,g0,ifact,c,cri) | 
|  | 69 double h0, g0, ifact; | 
|  | 70 int c, cri; | 
|  | 71 { int done, inc; | 
|  | 72   double h1, g1; | 
|  | 73   h1 = h0; g1 = g0; | 
|  | 74   done = inc = 0; | 
|  | 75   while (!done) | 
|  | 76   { h1 *= 1+ifact; | 
|  | 77     g0 = g1; | 
|  | 78     g1 = bcri(h1,c,cri); | 
|  | 79     if (g1<gmin) { hmin = h1; gmin = g1; } | 
|  | 80     if (g1>g0) inc++; else inc = 0; | 
|  | 81     switch(cri) | 
|  | 82     { case BIND: | 
|  | 83         done = (inc>=4) & (vr<blf->fp.nv); | 
|  | 84         break; | 
|  | 85       default: | 
|  | 86         done = (inc>=4); | 
|  | 87     } | 
|  | 88   } | 
|  | 89 } | 
|  | 90 | 
|  | 91 void bsel3(h0,g0,ifact,c,cri) | 
|  | 92 double h0, g0, ifact; | 
|  | 93 int c, cri; | 
|  | 94 { double h1, g1; | 
|  | 95   int i; | 
|  | 96   hmin = h0; gmin = g0; | 
|  | 97   for (i=-1; i<=1; i++) if (i!=0) | 
|  | 98   { h1 = h0*(1+i*ifact); | 
|  | 99     g1 = bcri(h1,c,cri); | 
|  | 100     if (g1<gmin) { hmin = h1; gmin = g1; } | 
|  | 101   } | 
|  | 102   return; | 
|  | 103 } | 
|  | 104 | 
|  | 105 void bselect(lf,des,c,cri,pn) | 
|  | 106 lfit *lf; | 
|  | 107 design *des; | 
|  | 108 int c, cri; | 
|  | 109 double pn; | 
|  | 110 { double h0, g0, ifact; | 
|  | 111   int i; | 
|  | 112   pen = pn; | 
|  | 113   blf = lf; | 
|  | 114   bdes = des; | 
|  | 115   if (cri==BIND) pen /= factorial(deg(&lf->sp)+1); | 
|  | 116   hmin = h0 = (c==DFXH) ? fixh(&lf->sp) : nn(&lf->sp); | 
|  | 117   if (h0==0) LERR(("bselect: initial bandwidth is 0")); | 
|  | 118   if (lf_error) return; | 
|  | 119   sig2 = 1.0; | 
|  | 120 | 
|  | 121   gmin = g0 = bcri(h0,c,cri); | 
|  | 122   if (cri==BCP) | 
|  | 123   { sig2 = rv(&lf->fp); | 
|  | 124     g0 = gmin = bcri(h0,c,cri+64); | 
|  | 125   } | 
|  | 126 | 
|  | 127   ifact = 0.3; | 
|  | 128   bsel2(h0,g0,ifact,c,cri); | 
|  | 129 | 
|  | 130   for (i=0; i<5; i++) | 
|  | 131   { ifact = ifact/2; | 
|  | 132     bsel3(hmin,gmin,ifact,c,cri); | 
|  | 133   } | 
|  | 134   if (c==DFXH) | 
|  | 135     fixh(&lf->sp) = hmin; | 
|  | 136   else | 
|  | 137     nn(&lf->sp) = hmin; | 
|  | 138   startlf(des,lf,procvstd,0); | 
|  | 139   ressumm(lf,des,lf->fp.kap); | 
|  | 140 } | 
|  | 141 | 
|  | 142 double compsda(x,h,n) | 
|  | 143 double *x, h; | 
|  | 144 int n; | 
|  | 145 /* n/(n-1) * int( fhat''(x)^2 dx ); bandwidth h */ | 
|  | 146 { int i, j; | 
|  | 147   double ik, sd, z; | 
|  | 148   ik = wint(1,NULL,0,WGAUS); | 
|  | 149   sd = 0; | 
|  | 150 | 
|  | 151   for (i=0; i<n; i++) | 
|  | 152     for (j=i; j<n; j++) | 
|  | 153     { z = (x[i]-x[j])/h; | 
|  | 154       sd += (2-(i==j))*Wconv4(z,WGAUS)/(ik*ik); | 
|  | 155     } | 
|  | 156   sd = sd/(n*(n-1)*h*h*h*h*h); | 
|  | 157   return(sd); | 
|  | 158 } | 
|  | 159 | 
|  | 160 double widthsj(x,lambda,n) | 
|  | 161 double *x, lambda; | 
|  | 162 int n; | 
|  | 163 { double ik, a, b, td, sa, z, c, c1, c2, c3; | 
|  | 164   int i, j; | 
|  | 165   a = GFACT*0.920*lambda*exp(-log((double)n)/7)/SQRT2; | 
|  | 166   b = GFACT*0.912*lambda*exp(-log((double)n)/9)/SQRT2; | 
|  | 167   ik = wint(1,NULL,0,WGAUS); | 
|  | 168 | 
|  | 169   td = 0; | 
|  | 170   for (i=0; i<n; i++) | 
|  | 171     for (j=i; j<n; j++) | 
|  | 172     { z = (x[i]-x[j])/b; | 
|  | 173       td += (2-(i==j))*Wconv6(z,WGAUS)/(ik*ik); | 
|  | 174     } | 
|  | 175 | 
|  | 176   td = -td/(n*(n-1)); | 
|  | 177   j = 2.0; | 
|  | 178   c1 = Wconv4(0.0,WGAUS); | 
|  | 179   c2 = wint(1,&j,1,WGAUS); | 
|  | 180   c3 = Wconv(0.0,WGAUS);  /* (2*c1/(c2*c3))^(1/7)=1.357 */ | 
|  | 181   sa = compsda(x,a,n); | 
|  | 182   c = b*exp(log(c1*ik/(c2*c3*GFACT*GFACT*GFACT*GFACT)*sa/td)/7)*SQRT2; | 
|  | 183   return(c); | 
|  | 184 } | 
|  | 185 | 
|  | 186 void kdecri(x,h,res,c,k,ker,n) | 
|  | 187 double *x, h, *res, c; | 
|  | 188 int k, ker, n; | 
|  | 189 { int i, j; | 
|  | 190   double degfree, dfd, pen, s, r0, r1, d0, d1, ik, wij; | 
|  | 191 | 
|  | 192   if (h<=0) WARN(("kdecri, h = %6.4f",h)); | 
|  | 193 | 
|  | 194   res[0] = res[1] = 0.0; | 
|  | 195   ik = wint(1,NULL,0,ker); | 
|  | 196   switch(k) | 
|  | 197   { case 1: /* aic */ | 
|  | 198       pen = 2.0; | 
|  | 199       for (i=0; i<n; i++) | 
|  | 200       { r0 = d0 = 0.0; | 
|  | 201         for (j=0; j<n; j++) | 
|  | 202         { s = (x[i]-x[j])/h; | 
|  | 203           r0 += W(s,ker); | 
|  | 204           d0 += s*s*Wd(s,ker); | 
|  | 205         } | 
|  | 206         d0 = -(d0+r0)/(n*h*h*ik);  /* d0 = d/dh fhat(xi) */ | 
|  | 207         r0 /= n*h*ik;              /* r0 = fhat(xi) */ | 
|  | 208         res[0] += -2*log(r0)+pen*W(0.0,ker)/(n*h*ik*r0); | 
|  | 209         res[1] += -2*d0/r0-pen*W(0.0,ker)/(n*h*ik*r0)*(d0/r0+1.0/h); | 
|  | 210       } | 
|  | 211       return; | 
|  | 212     case 2: /* ocv */ | 
|  | 213       for (i=0; i<n; i++) | 
|  | 214       { r0 = 0.0; d0 = 0.0; | 
|  | 215         for (j=0; j<n; j++) if (i!=j) | 
|  | 216         { s = (x[i]-x[j])/h; | 
|  | 217           r0 += W(s,ker); | 
|  | 218           d0 += s*s*Wd(s,ker); | 
|  | 219         } | 
|  | 220         d0 = -(d0+r0)/((n-1)*h*h); | 
|  | 221         r0 = r0/((n-1)*h); | 
|  | 222         res[0] -= log(r0); | 
|  | 223         res[1] -= d0/r0; | 
|  | 224       } | 
|  | 225       return; | 
|  | 226     case 3: /* lscv */ | 
|  | 227       r0 = r1 = d0 = d1 = degfree = 0.0; | 
|  | 228       for (i=0; i<n; i++) | 
|  | 229       { dfd = 0.0; | 
|  | 230         for (j=0; j<n; j++) | 
|  | 231         { s = (x[i]-x[j])/h; | 
|  | 232           wij = W(s,ker); | 
|  | 233           dfd += wij; | 
|  | 234 /* | 
|  | 235  *  r0 = \int fhat * fhat = sum_{i,j} W*W( (Xi-Xj)/h ) / n^2 h. | 
|  | 236  *  d0 is it's derivative wrt h. | 
|  | 237  * | 
|  | 238  *  r1 = 1/n sum( f_{-i}(X_i) ). | 
|  | 239  *  d1 is  it's derivative wrt h. | 
|  | 240  * | 
|  | 241  *  degfree = sum_i ( W_0 / sum_j W( (Xi-Xj)/h ) ) is fitted d.f. | 
|  | 242  */ | 
|  | 243           r0 += Wconv(s,ker); | 
|  | 244           d0 += -s*s*Wconv1(s,ker); | 
|  | 245           if (i != j) | 
|  | 246           { r1 += wij; | 
|  | 247             d1 += -s*s*Wd(s,ker); | 
|  | 248           } | 
|  | 249         } | 
|  | 250         degfree += 1.0/dfd; | 
|  | 251       } | 
|  | 252       d1 -= r1; | 
|  | 253       d0 -= r0; | 
|  | 254       res[0] = r0/(n*n*h*ik*ik)   - 2*r1/(n*(n-1)*h*ik); | 
|  | 255       res[1] = d0/(n*n*h*h*ik*ik) - 2*d1/(n*(n-1)*h*h*ik); | 
|  | 256       res[2] = degfree; | 
|  | 257       return; | 
|  | 258     case 4: /* bcv */ | 
|  | 259       r0 = d0 = 0.0; | 
|  | 260       for (i=0; i<n; i++) | 
|  | 261         for (j=i+1; j<n; j++) | 
|  | 262         { s = (x[i]-x[j])/h; | 
|  | 263           r0 += 2*Wconv4(s,ker); | 
|  | 264           d0 += 2*s*Wconv5(s,ker); | 
|  | 265         } | 
|  | 266       d0 = (-d0-r0)/(n*n*h*h*ik*ik); | 
|  | 267       r0 = r0/(n*n*h*ik*ik); | 
|  | 268       j = 2.0; | 
|  | 269       d1 = wint(1,&j,1,ker); | 
|  | 270       r1 = Wconv(0.0,ker); | 
|  | 271       res[0] = (d1*d1*r0/4+r1/(n*h))/(ik*ik); | 
|  | 272       res[1] = (d1*d1*d0/4-r1/(n*h*h))/(ik*ik); | 
|  | 273       return; | 
|  | 274     case 5: /* sjpi */ | 
|  | 275       s = c*exp(5*log(h)/7)/SQRT2; | 
|  | 276       d0 = compsda(x,s,n); | 
|  | 277       res[0] = d0; /* this is S(alpha) in SJ */ | 
|  | 278       res[1] = exp(log(Wikk(WGAUS,0)/(d0*n))/5)-h; | 
|  | 279       return; | 
|  | 280     case 6: /* gas-k-k */ | 
|  | 281       s = exp(log(1.0*n)/10)*h; | 
|  | 282       d0 = compsda(x,s,n); | 
|  | 283       res[0] = d0; | 
|  | 284       res[1] = exp(log(Wikk(WGAUS,0)/(d0*n))/5)-h; | 
|  | 285       return; | 
|  | 286   } | 
|  | 287   LERR(("kdecri: what???")); | 
|  | 288   return; | 
|  | 289 } | 
|  | 290 | 
|  | 291 double esolve(x,j,h0,h1,k,c,ker,n) | 
|  | 292 double *x, h0, h1, c; | 
|  | 293 int j, k, ker, n; | 
|  | 294 { double h[7], d[7], r[7], res[4], min, minh, fact; | 
|  | 295   int i, nc; | 
|  | 296   min = 1.0e30; minh = 0.0; | 
|  | 297   fact = 1.00001; | 
|  | 298   h[6] = h0; kdecri(x,h[6],res,c,j,ker,n); | 
|  | 299   r[6] = res[0]; d[6] = res[1]; | 
|  | 300   if (lf_error) return(0.0); | 
|  | 301   nc = 0; | 
|  | 302   for (i=0; i<k; i++) | 
|  | 303   { h[5] = h[6]; r[5] = r[6]; d[5] = d[6]; | 
|  | 304     h[6] = h0*exp((i+1)*log(h1/h0)/k); | 
|  | 305     kdecri(x,h[6],res,c,j,ker,n); | 
|  | 306     r[6] = res[0]; d[6] = res[1]; | 
|  | 307     if (lf_error) return(0.0); | 
|  | 308     if (d[5]*d[6]<0) | 
|  | 309     { h[2] = h[0] = h[5]; d[2] = d[0] = d[5]; r[2] = r[0] = r[5]; | 
|  | 310       h[3] = h[1] = h[6]; d[3] = d[1] = d[6]; r[3] = r[1] = r[6]; | 
|  | 311       while ((h[3]>fact*h[2])|(h[2]>fact*h[3])) | 
|  | 312       { h[4] = h[3]-d[3]*(h[3]-h[2])/(d[3]-d[2]); | 
|  | 313         if ((h[4]<h[0]) | (h[4]>h[1])) h[4] = (h[0]+h[1])/2; | 
|  | 314         kdecri(x,h[4],res,c,j,ker,n); | 
|  | 315         r[4] = res[0]; d[4] = res[1]; | 
|  | 316         if (lf_error) return(0.0); | 
|  | 317         h[2] = h[3]; h[3] = h[4]; | 
|  | 318         d[2] = d[3]; d[3] = d[4]; | 
|  | 319         r[2] = r[3]; r[3] = r[4]; | 
|  | 320         if (d[4]*d[0]>0) { h[0] = h[4]; d[0] = d[4]; r[0] = r[4]; } | 
|  | 321                     else { h[1] = h[4]; d[1] = d[4]; r[1] = r[4]; } | 
|  | 322       } | 
|  | 323       if (j>=4) return(h[4]); /* first min for BCV etc */ | 
|  | 324       if (r[4]<=min) { min = r[4]; minh = h[4]; } | 
|  | 325       nc++; | 
|  | 326     } | 
|  | 327   } | 
|  | 328   if (nc==0) minh = (r[5]<r[6]) ? h0 : h1; | 
|  | 329   return(minh); | 
|  | 330 } | 
|  | 331 | 
|  | 332 void kdeselect(band,x,ind,h0,h1,meth,nm,ker,n) | 
|  | 333 double h0, h1, *band, *x; | 
|  | 334 int *ind, nm, ker, n, *meth; | 
|  | 335 { double scale, c; | 
|  | 336   int i, k; | 
|  | 337   k = n/4; | 
|  | 338   for (i=0; i<n; i++) ind[i] = i; | 
|  | 339   scale = kordstat(x,n+1-k,n,ind) - kordstat(x,k,n,ind); | 
|  | 340   c = widthsj(x,scale,n); | 
|  | 341   for (i=0; i<nm; i++) | 
|  | 342     band[i] = esolve(x,meth[i],h0,h1,10,c,ker,n); | 
|  | 343 } | 
|  | 344 /* | 
|  | 345  * Copyright 1996-2006 Catherine Loader. | 
|  | 346  */ | 
|  | 347 /* | 
|  | 348  *   The function dens_integrate(lf,des,z) is used to integrate a density | 
|  | 349  *   estimate (z=1) or the density squared (z=2). This is used to renormalize | 
|  | 350  *   the estimate (function dens_renorm) or in the computation of LSCV | 
|  | 351  *   (in modlscv.c). The implementation is presently for d=1. | 
|  | 352  * | 
|  | 353  *   The computation orders the fit points selected by locfit, and | 
|  | 354  *   integrates analytically over each interval. For the log-link, | 
|  | 355  *   the interpolant used is peicewise quadratic (with one knot in | 
|  | 356  *   the middle of each interval); this differs from the cubic interpolant | 
|  | 357  *   used elsewhere in Locfit. | 
|  | 358  * | 
|  | 359  *   TODO: allow for xlim. What can be done simply in >=2 dimensions? | 
|  | 360  */ | 
|  | 361 | 
|  | 362 #include "lfev.h" | 
|  | 363 | 
|  | 364 /* | 
|  | 365  * Finds the order of observations in the array x, and | 
|  | 366  * stores in integer array ind. | 
|  | 367  * At input, lset l=0 and r=length(x)-1. | 
|  | 368  * At output, x[ind[0]] <= x[ind[1]] <= ... | 
|  | 369  */ | 
|  | 370 void lforder(ind,x,l,r) | 
|  | 371 int *ind, l, r; | 
|  | 372 double *x; | 
|  | 373 { double piv; | 
|  | 374   int i, i0, i1; | 
|  | 375   piv = (x[ind[l]]+x[ind[r]])/2; | 
|  | 376   i0 = l; i1 = r; | 
|  | 377   while (i0<=i1) | 
|  | 378   { while ((i0<=i1) && (x[ind[i0]]<=piv)) i0++; | 
|  | 379     while ((i0<=i1) && (x[ind[i1]]>piv))  i1--; | 
|  | 380     if (i0<i1) | 
|  | 381     { ISWAP(ind[i0],ind[i1]); | 
|  | 382       i0++; i1--; | 
|  | 383     } | 
|  | 384   } | 
|  | 385   /* now, x[ind[l..i1]] <= piv < x[ind[i0..r]]. | 
|  | 386      put the ties in the middle */ | 
|  | 387   while ((i1>=l) && (x[ind[i1]]==piv)) i1--; | 
|  | 388   for (i=l; i<=i1; i++) | 
|  | 389     if (x[ind[i]]==piv) | 
|  | 390     { ISWAP(ind[i],ind[i1]); | 
|  | 391       while (x[ind[i1]]==piv) i1--; | 
|  | 392     } | 
|  | 393 | 
|  | 394   if (l<i1) lforder(ind,x,l,i1); | 
|  | 395   if (i0<r) lforder(ind,x,i0,r); | 
|  | 396 } | 
|  | 397 | 
|  | 398 /* | 
|  | 399  *  estdiv integrates the density between fit points x0 and x1. | 
|  | 400  *  f0, f1 are function values, d0, d1 are derivatives. | 
|  | 401  */ | 
|  | 402 double estdiv(x0,x1,f0,f1,d0,d1,lin) | 
|  | 403 double x0, x1, f0, f1, d0, d1; | 
|  | 404 int lin; | 
|  | 405 { double cf[4], I[2], dlt, e0, e1; | 
|  | 406 | 
|  | 407   if (x0==x1) return(0.0); | 
|  | 408 | 
|  | 409   if (lin==LIDENT) | 
|  | 410   { | 
|  | 411 /* cf are integrals of hermite polynomials. | 
|  | 412  * Then adjust for x1-x0. | 
|  | 413  */ | 
|  | 414     cf[0] = cf[1] = 0.5; | 
|  | 415     cf[2] = 1.0/12.0; cf[3] = -cf[2]; | 
|  | 416     return( (cf[0]*f0+cf[1]*f1)*(x1-x0) | 
|  | 417           + (cf[2]*d0+cf[3]*d1)*(x1-x0)*(x1-x0) ); | 
|  | 418   } | 
|  | 419 | 
|  | 420 /* | 
|  | 421  * this is for LLOG | 
|  | 422  */ | 
|  | 423 | 
|  | 424   dlt = (x1-x0)/2; | 
|  | 425   cf[0] = f0; | 
|  | 426   cf[1] = d0; | 
|  | 427   cf[2] = ( 2*(f1-f0) - dlt*(d1+3*d0) )/(4*dlt*dlt); | 
|  | 428   recurint(0.0,dlt,cf,I,0,WRECT); | 
|  | 429   e0 = I[0]; | 
|  | 430 | 
|  | 431   cf[0] = f1; | 
|  | 432   cf[1] = -d1; | 
|  | 433   cf[2] = ( 2*(f0-f1) + dlt*(d0+3*d1) )/( 4*dlt*dlt ); | 
|  | 434   recurint(0.0,dlt,cf,I,0,WRECT); | 
|  | 435   e1 = I[0]; | 
|  | 436 | 
|  | 437   return(e0+e1); | 
|  | 438 } | 
|  | 439 | 
|  | 440 /* | 
|  | 441  *   Evaluate the integral of the density estimate to the power z. | 
|  | 442  *   This would be severely messed up, if I ever implement parcomp | 
|  | 443  *   for densities. | 
|  | 444  */ | 
|  | 445 double dens_integrate(lf,des,z) | 
|  | 446 lfit *lf; | 
|  | 447 design *des; | 
|  | 448 int z; | 
|  | 449 { int has_deriv, i, i0, i1, nv, *ind; | 
|  | 450   double *xev, *fit, *deriv, sum, term; | 
|  | 451   double d0, d1, f0, f1; | 
|  | 452   fitpt *fp; | 
|  | 453 | 
|  | 454   fp = &lf->fp; | 
|  | 455 | 
|  | 456   if (fp->d >= 2) | 
|  | 457   { WARN(("dens_integrate requires d=1")); | 
|  | 458     return(0.0); | 
|  | 459   } | 
|  | 460 | 
|  | 461   has_deriv = (deg(&lf->sp) > 0); /* not right? */ | 
|  | 462   fit = fp->coef; | 
|  | 463   if (has_deriv) | 
|  | 464     deriv = &fit[fp->nvm]; | 
|  | 465   xev = evp(fp); | 
|  | 466 | 
|  | 467   /* | 
|  | 468    * order the vertices | 
|  | 469    */ | 
|  | 470   nv = fp->nv; | 
|  | 471   if (lf->lfd.n<nv) return(0.0); | 
|  | 472   ind = des->ind; | 
|  | 473   for (i=0; i<nv; i++) ind[i] = i; | 
|  | 474   lforder(ind,xev,0,nv-1); | 
|  | 475   sum = 0.0; | 
|  | 476 | 
|  | 477   /* | 
|  | 478    * Estimate the contribution of the boundaries. | 
|  | 479    * should really check flim here. | 
|  | 480    */ | 
|  | 481   i0 = ind[0]; i1 = ind[1]; | 
|  | 482   f1 = fit[i0]; | 
|  | 483   d1 = (has_deriv) ? deriv[i0] : | 
|  | 484          (fit[i1]-fit[i0])/(xev[i1]-xev[i0]); | 
|  | 485   if (d1 <= 0) WARN(("dens_integrate - ouch!")); | 
|  | 486   if (z==2) | 
|  | 487   { if (link(&lf->sp)==LLOG) | 
|  | 488     { f1 *= 2; d1 *= 2; } | 
|  | 489     else | 
|  | 490     { d1 = 2*d1*f1; f1 = f1*f1; } | 
|  | 491   } | 
|  | 492   term = (link(&lf->sp)==LIDENT) ? f1*f1/(2*d1) : exp(f1)/d1; | 
|  | 493   sum += term; | 
|  | 494 | 
|  | 495   i0 = ind[nv-2]; i1 = ind[nv-1]; | 
|  | 496   f0 = fit[i1]; | 
|  | 497   d0 = (has_deriv) ? deriv[i1] : | 
|  | 498          (fit[i1]-fit[i0])/(xev[i1]-xev[i0]); | 
|  | 499   if (d0 >= 0) WARN(("dens_integrate - ouch!")); | 
|  | 500   if (z==2) | 
|  | 501   { if (link(&lf->sp)==LLOG) | 
|  | 502     { f0 *= 2; d0 *= 2; } | 
|  | 503     else | 
|  | 504     { d0 = 2*d0*f0; f0 = f0*f0; } | 
|  | 505   } | 
|  | 506   term = (link(&lf->sp)==LIDENT) ? -f0*f0/(2*d0) : exp(f0)/d0; | 
|  | 507   sum += term; | 
|  | 508 | 
|  | 509   for (i=1; i<nv; i++) | 
|  | 510   { i0 = ind[i-1]; i1 = ind[i]; | 
|  | 511     f0 = fit[i0]; f1 = fit[i1]; | 
|  | 512     d0 = (has_deriv) ? deriv[i0] : | 
|  | 513               (f1-f0)/(xev[i1]-xev[i0]); | 
|  | 514     d1 = (has_deriv) ? deriv[i1] : d0; | 
|  | 515     if (z==2) | 
|  | 516     { if (link(&lf->sp)==LLOG) | 
|  | 517       { f0 *= 2; f1 *= 2; d0 *= 2; d1 *= 2; } | 
|  | 518       else | 
|  | 519       { d0 *= 2*f0; d1 *= 2*f1; f0 = f0*f0; f1 = f1*f1; } | 
|  | 520     } | 
|  | 521     term = estdiv(xev[i0],xev[i1],f0,f1,d0,d1,link(&lf->sp)); | 
|  | 522     sum += term; | 
|  | 523   } | 
|  | 524 | 
|  | 525   return(sum); | 
|  | 526 } | 
|  | 527 | 
|  | 528 void dens_renorm(lf,des) | 
|  | 529 lfit *lf; | 
|  | 530 design *des; | 
|  | 531 { int i; | 
|  | 532   double sum; | 
|  | 533   sum = dens_integrate(lf,des,1); | 
|  | 534   if (sum==0.0) return; | 
|  | 535   sum = log(sum); | 
|  | 536   for (i=0; i<lf->fp.nv; i++) lf->fp.coef[i] -= sum; | 
|  | 537 } | 
|  | 538 /* | 
|  | 539  * Copyright 1996-2006 Catherine Loader. | 
|  | 540  */ | 
|  | 541 /* | 
|  | 542  *   This file contains functions for constructing and | 
|  | 543  *   interpolating the adaptive tree structure. This is | 
|  | 544  *   the default evaluation structure used by Locfit. | 
|  | 545  */ | 
|  | 546 | 
|  | 547 #include "lfev.h" | 
|  | 548 | 
|  | 549 /* | 
|  | 550   Guess the number of fitting points. | 
|  | 551   Needs improving! | 
|  | 552 */ | 
|  | 553 void atree_guessnv(evs,nvm,ncm,vc,d,alp) | 
|  | 554 evstruc *evs; | 
|  | 555 double alp; | 
|  | 556 int *nvm, *ncm, *vc, d; | 
|  | 557 { double a0, cu, ifl; | 
|  | 558   int i, nv, nc; | 
|  | 559 | 
|  | 560   *ncm = 1<<30; *nvm = 1<<30; | 
|  | 561   *vc = 1 << d; | 
|  | 562 | 
|  | 563   if (alp>0) | 
|  | 564   { a0 = (alp > 1) ? 1 : 1/alp; | 
|  | 565     if (cut(evs)<0.01) | 
|  | 566     { WARN(("guessnv: cut too small.")); | 
|  | 567       cut(evs) = 0.01; | 
|  | 568     } | 
|  | 569     cu = 1; | 
|  | 570     for (i=0; i<d; i++) cu *= MIN(1.0,cut(evs)); | 
|  | 571     nv = (int)((5*a0/cu)**vc);   /* this allows 10*a0/cu splits */ | 
|  | 572     nc = (int)(10*a0/cu+1);      /* and 10*a0/cu cells */ | 
|  | 573     if (nv<*nvm) *nvm = nv; | 
|  | 574     if (nc<*ncm) *ncm = nc; | 
|  | 575   } | 
|  | 576 | 
|  | 577   if (*nvm == 1<<30) /* by default, allow 100 splits */ | 
|  | 578   { *nvm = 102**vc; | 
|  | 579     *ncm = 201; | 
|  | 580   } | 
|  | 581 | 
|  | 582   /* inflation based on mk */ | 
|  | 583   ifl = mk(evs)/100.0; | 
|  | 584   *nvm = *vc+(int)(ifl**nvm); | 
|  | 585   *ncm = (int)(ifl**ncm); | 
|  | 586 | 
|  | 587 } | 
|  | 588 | 
|  | 589 /* | 
|  | 590   Determine whether a cell in the tree needs splitting. | 
|  | 591   If so, return the split variable (0..d-1). | 
|  | 592   Otherwise, return -1. | 
|  | 593 */ | 
|  | 594 int atree_split(lf,ce,le,ll,ur) | 
|  | 595 lfit *lf; | 
|  | 596 int *ce; | 
|  | 597 double *le, *ll, *ur; | 
|  | 598 { int d, vc, i, is; | 
|  | 599   double h, hmin, score[MXDIM]; | 
|  | 600   d = lf->fp.d; vc = 1<<d; | 
|  | 601 | 
|  | 602   hmin = 0.0; | 
|  | 603   for (i=0; i<vc; i++) | 
|  | 604   { h = lf->fp.h[ce[i]]; | 
|  | 605     if ((h>0) && ((hmin==0)|(h<hmin))) hmin = h; | 
|  | 606   } | 
|  | 607 | 
|  | 608   is = 0; | 
|  | 609   for (i=0; i<d; i++) | 
|  | 610   { le[i] = (ur[i]-ll[i])/lf->lfd.sca[i]; | 
|  | 611     if ((lf->lfd.sty[i]==STCPAR) || (hmin==0)) | 
|  | 612       score[i] = 2*(ur[i]-ll[i])/(lf->evs.fl[i+d]-lf->evs.fl[i]); | 
|  | 613     else | 
|  | 614       score[i] = le[i]/hmin; | 
|  | 615     if (score[i]>score[is]) is = i; | 
|  | 616   } | 
|  | 617   if (cut(&lf->evs)<score[is]) return(is); | 
|  | 618   return(-1); | 
|  | 619 } | 
|  | 620 | 
|  | 621 /* | 
|  | 622   recursively grow the tree structure, begining with the parent cell. | 
|  | 623 */ | 
|  | 624 void atree_grow(des,lf,ce,ct,term,ll,ur) | 
|  | 625 design *des; | 
|  | 626 lfit *lf; | 
|  | 627 int *ce, *ct, *term; | 
|  | 628 double *ll, *ur; | 
|  | 629 { int nce[1<<MXDIM]; | 
|  | 630   int i, i0, i1, d, vc, pv, tk, ns; | 
|  | 631   double le[MXDIM], z; | 
|  | 632   d = lf->fp.d; vc = 1<<d; | 
|  | 633 | 
|  | 634   /* does this cell need splitting? | 
|  | 635      If not, wrap up and return. | 
|  | 636   */ | 
|  | 637   ns = atree_split(lf,ce,le,ll,ur); | 
|  | 638   if (ns==-1) | 
|  | 639   { if (ct != NULL) /* reconstructing terminal cells */ | 
|  | 640     { for (i=0; i<vc; i++) term[*ct*vc+i] = ce[i]; | 
|  | 641       (*ct)++; | 
|  | 642     } | 
|  | 643     return; | 
|  | 644   } | 
|  | 645 | 
|  | 646   /* split the cell at the midpoint on side ns */ | 
|  | 647   tk = 1<<ns; | 
|  | 648   for (i=0; i<vc; i++) | 
|  | 649   { if ((i&tk)==0) nce[i] = ce[i]; | 
|  | 650     else | 
|  | 651     { i0 = ce[i]; | 
|  | 652       i1 = ce[i-tk]; | 
|  | 653       pv = (lf->lfd.sty[i]!=STCPAR) && | 
|  | 654            (le[ns] < (cut(&lf->evs)*MIN(lf->fp.h[i0],lf->fp.h[i1]))); | 
|  | 655       nce[i] = newsplit(des,lf,i0,i1,pv); | 
|  | 656       if (lf_error) return; | 
|  | 657     } | 
|  | 658   } | 
|  | 659   z = ur[ns]; ur[ns] = (z+ll[ns])/2; | 
|  | 660   atree_grow(des,lf,nce,ct,term,ll,ur); | 
|  | 661   if (lf_error) return; | 
|  | 662   ur[ns] = z; | 
|  | 663   for (i=0; i<vc; i++) | 
|  | 664     nce[i] = ((i&tk)== 0) ? nce[i+tk] : ce[i]; | 
|  | 665   z = ll[ns]; ll[ns] = (z+ur[ns])/2; | 
|  | 666   atree_grow(des,lf,nce,ct,term,ll,ur); | 
|  | 667   if (lf_error) return; | 
|  | 668   ll[ns] = z; | 
|  | 669 } | 
|  | 670 | 
|  | 671 void atree_start(des,lf) | 
|  | 672 design *des; | 
|  | 673 lfit *lf; | 
|  | 674 { int d, i, j, k, vc, ncm, nvm; | 
|  | 675   double ll[MXDIM], ur[MXDIM]; | 
|  | 676 | 
|  | 677   if (lf_debug>1) mut_printf(" In atree_start\n"); | 
|  | 678   d = lf->fp.d; | 
|  | 679   atree_guessnv(&lf->evs,&nvm,&ncm,&vc,d,nn(&lf->sp)); | 
|  | 680   if (lf_debug>2) mut_printf(" atree_start: nvm %d ncm %d\n",nvm,ncm); | 
|  | 681   trchck(lf,nvm,ncm,vc); | 
|  | 682 | 
|  | 683   /* Set the lower left, upper right limits. */ | 
|  | 684   for (j=0; j<d; j++) | 
|  | 685   { ll[j] = lf->evs.fl[j]; | 
|  | 686     ur[j] = lf->evs.fl[j+d]; | 
|  | 687   } | 
|  | 688 | 
|  | 689   /* Set the initial cell; fit at the vertices. */ | 
|  | 690   for (i=0; i<vc; i++) | 
|  | 691   { j = i; | 
|  | 692     for (k=0; k<d; ++k) | 
|  | 693     { evptx(&lf->fp,i,k) = (j%2) ? ur[k] : ll[k]; | 
|  | 694       j >>= 1; | 
|  | 695     } | 
|  | 696     lf->evs.ce[i] = i; | 
|  | 697     PROC_VERTEX(des,lf,i); | 
|  | 698     if (lf_error) return; | 
|  | 699     lf->evs.s[i] = 0; | 
|  | 700   } | 
|  | 701   lf->fp.nv = vc; | 
|  | 702 | 
|  | 703   /* build the tree */ | 
|  | 704   atree_grow(des,lf,lf->evs.ce,NULL,NULL,ll,ur); | 
|  | 705   lf->evs.nce = 1; | 
|  | 706 } | 
|  | 707 | 
|  | 708 double atree_int(lf,x,what) | 
|  | 709 lfit *lf; | 
|  | 710 double *x; | 
|  | 711 int what; | 
|  | 712 { double vv[64][64], *ll, *ur, h, xx[MXDIM]; | 
|  | 713   int lo, tk, ns, nv, nc, d, i, vc; | 
|  | 714   int ce[64]; | 
|  | 715   fitpt *fp; | 
|  | 716   evstruc *evs; | 
|  | 717 | 
|  | 718   fp = &lf->fp; | 
|  | 719   evs= &lf->evs; | 
|  | 720   d = fp->d; | 
|  | 721   vc = 1<<d; | 
|  | 722 | 
|  | 723   for (i=0; i<vc; i++) | 
|  | 724   { setzero(vv[i],vc); | 
|  | 725     nc = exvval(fp,vv[i],i,d,what,1); | 
|  | 726     ce[i] = evs->ce[i]; | 
|  | 727   } | 
|  | 728   ns = 0; | 
|  | 729   while(ns!=-1) | 
|  | 730   { ll = evpt(fp,ce[0]); ur = evpt(fp,ce[vc-1]); | 
|  | 731     ns = atree_split(lf,ce,xx,ll,ur); | 
|  | 732     if (ns!=-1) | 
|  | 733     { tk = 1<<ns; | 
|  | 734       h = ur[ns]-ll[ns]; | 
|  | 735       lo = (2*(x[ns]-ll[ns])) < h; | 
|  | 736       for (i=0; i<vc; i++) if ((tk&i)==0) | 
|  | 737       { nv = findpt(fp,evs,(int)ce[i],(int)ce[i+tk]); | 
|  | 738         if (nv==-1) LERR(("Descend tree problem")); | 
|  | 739         if (lf_error) return(0.0); | 
|  | 740         if (lo) | 
|  | 741         { ce[i+tk] = nv; | 
|  | 742           if (evs->s[nv]) exvvalpv(vv[i+tk],vv[i],vv[i+tk],d,ns,h,nc); | 
|  | 743                     else exvval(fp,vv[i+tk],nv,d,what,1); | 
|  | 744         } | 
|  | 745         else | 
|  | 746         { ce[i] = nv; | 
|  | 747           if (evs->s[nv]) exvvalpv(vv[i],vv[i],vv[i+tk],d,ns,h,nc); | 
|  | 748                     else exvval(fp,vv[i],nv,d,what,1); | 
|  | 749       } } | 
|  | 750   } } | 
|  | 751   ll = evpt(fp,ce[0]); ur = evpt(fp,ce[vc-1]); | 
|  | 752   return(rectcell_interp(x,vv,ll,ur,d,nc)); | 
|  | 753 } | 
|  | 754 /* | 
|  | 755  * Copyright 1996-2006 Catherine Loader. | 
|  | 756  */ | 
|  | 757 #include "lfev.h" | 
|  | 758 | 
|  | 759 double linear_interp(h,d,f0,f1) | 
|  | 760 double h, d, f0, f1; | 
|  | 761 { if (d==0) return(f0); | 
|  | 762   return( ( (d-h)*f0 + h*f1 ) / d ); | 
|  | 763 } | 
|  | 764 | 
|  | 765 void hermite2(x,z,phi) | 
|  | 766 double x, z, *phi; | 
|  | 767 { double h; | 
|  | 768   if (z==0) | 
|  | 769   { phi[0] = 1.0; phi[1] = phi[2] = phi[3] = 0.0; | 
|  | 770     return; | 
|  | 771   } | 
|  | 772   h = x/z; | 
|  | 773   if (h<0) | 
|  | 774   { phi[0] = 1; phi[1] = 0; | 
|  | 775     phi[2] = h; phi[3] = 0; | 
|  | 776     return; | 
|  | 777   } | 
|  | 778   if (h>1) | 
|  | 779   { phi[0] = 0; phi[1] = 1; | 
|  | 780     phi[2] = 0; phi[3] = h-1; | 
|  | 781     return; | 
|  | 782   } | 
|  | 783   phi[1] = h*h*(3-2*h); | 
|  | 784   phi[0] = 1-phi[1]; | 
|  | 785   phi[2] = h*(1-h)*(1-h); | 
|  | 786   phi[3] = h*h*(h - 1); | 
|  | 787 } | 
|  | 788 | 
|  | 789 double cubic_interp(h,f0,f1,d0,d1) | 
|  | 790 double h, f0, f1, d0, d1; | 
|  | 791 { double phi[4]; | 
|  | 792   hermite2(h,1.0,phi); | 
|  | 793   return(phi[0]*f0+phi[1]*f1+phi[2]*d0+phi[3]*d1); | 
|  | 794 } | 
|  | 795 | 
|  | 796 double cubintd(h,f0,f1,d0,d1) | 
|  | 797 double h, f0, f1, d0, d1; | 
|  | 798 { double phi[4]; | 
|  | 799   phi[1] = 6*h*(1-h); | 
|  | 800   phi[0] = -phi[1]; | 
|  | 801   phi[2] = (1-h)*(1-3*h); | 
|  | 802   phi[3] = h*(3*h-2); | 
|  | 803   return(phi[0]*f0+phi[1]*f1+phi[2]*d0+phi[3]*d1); | 
|  | 804 } | 
|  | 805 | 
|  | 806 /* | 
|  | 807   interpolate over a rectangular cell. | 
|  | 808     x = interpolation point. | 
|  | 809     vv = array of vertex values. | 
|  | 810     ll = lower left corner. | 
|  | 811     ur = upper right corner. | 
|  | 812     d = dimension. | 
|  | 813     nc = no of coefficients. | 
|  | 814 */ | 
|  | 815 double rectcell_interp(x,vv,ll,ur,d,nc) | 
|  | 816 double *x, vv[64][64], *ll, *ur; | 
|  | 817 int d, nc; | 
|  | 818 { double phi[4]; | 
|  | 819   int i, j, k, tk; | 
|  | 820 | 
|  | 821   tk = 1<<d; | 
|  | 822   for (i=0; i<tk; i++) if (vv[i][0]==NOSLN) return(NOSLN); | 
|  | 823 | 
|  | 824   /* no derivatives - use multilinear interpolation */ | 
|  | 825   if (nc==1) | 
|  | 826   { for (i=d-1; i>=0; i--) | 
|  | 827     { tk = 1<<i; | 
|  | 828       for (j=0; j<tk; j++) | 
|  | 829         vv[j][0] = linear_interp(x[i]-ll[i],ur[i]-ll[i],vv[j][0],vv[j+tk][0]); | 
|  | 830     } | 
|  | 831     return(vv[0][0]); | 
|  | 832   } | 
|  | 833 | 
|  | 834   /* with derivatives -- use cubic */ | 
|  | 835   if (nc==d+1) | 
|  | 836   { for (i=d-1; i>=0; i--) | 
|  | 837     { hermite2(x[i]-ll[i],ur[i]-ll[i],phi); | 
|  | 838       tk = 1<<i; | 
|  | 839       phi[2] *= ur[i]-ll[i]; | 
|  | 840       phi[3] *= ur[i]-ll[i]; | 
|  | 841       for (j=0; j<tk; j++) | 
|  | 842       { vv[j][0] = phi[0]*vv[j][0] + phi[1]*vv[j+tk][0] | 
|  | 843                  + phi[2]*vv[j][i+1] + phi[3]*vv[j+tk][i+1]; | 
|  | 844         for (k=1; k<=i; k++) | 
|  | 845           vv[j][k] = phi[0]*vv[j][k] + phi[1]*vv[j+tk][k]; | 
|  | 846       } | 
|  | 847     } | 
|  | 848     return(vv[0][0]); | 
|  | 849   } | 
|  | 850 | 
|  | 851   /* with all coefs -- use multicubic */ | 
|  | 852   for (i=d-1; i>=0; i--) | 
|  | 853   { hermite2(x[i]-ll[i],ur[i]-ll[i],phi); | 
|  | 854     tk = 1<<i; | 
|  | 855     phi[2] *= ur[i]-ll[i]; | 
|  | 856     phi[3] *= ur[i]-ll[i]; | 
|  | 857     for (j=0; j<tk; j++) | 
|  | 858       for (k=0; k<tk; k++) | 
|  | 859         vv[j][k] = phi[0]*vv[j][k] + phi[1]*vv[j+tk][k] | 
|  | 860                  + phi[2]*vv[j][k+tk] + phi[3]*vv[j+tk][k+tk]; | 
|  | 861   } | 
|  | 862   return(vv[0][0]); | 
|  | 863 } | 
|  | 864 | 
|  | 865 int exvval(fp,vv,nv,d,what,z) | 
|  | 866 fitpt *fp; | 
|  | 867 double *vv; | 
|  | 868 int nv, d, z, what; | 
|  | 869 { int i, k; | 
|  | 870   double *values; | 
|  | 871 | 
|  | 872   k = (z) ? 1<<d : d+1; | 
|  | 873   for (i=1; i<k; i++) vv[i] = 0.0; | 
|  | 874   switch(what) | 
|  | 875   { case PCOEF: | 
|  | 876       values = fp->coef; | 
|  | 877       break; | 
|  | 878     case PVARI: | 
|  | 879     case PNLX: | 
|  | 880       values = fp->nlx; | 
|  | 881       break; | 
|  | 882     case PT0: | 
|  | 883       values = fp->t0; | 
|  | 884       break; | 
|  | 885     case PBAND: | 
|  | 886       vv[0] = fp->h[nv]; | 
|  | 887       return(1); | 
|  | 888     case PDEGR: | 
|  | 889       vv[0] = fp->deg[nv]; | 
|  | 890       return(1); | 
|  | 891     case PLIK: | 
|  | 892       vv[0] = fp->lik[nv]; | 
|  | 893       return(1); | 
|  | 894     case PRDF: | 
|  | 895       vv[0] = fp->lik[2*fp->nvm+nv]; | 
|  | 896       return(1); | 
|  | 897     default: | 
|  | 898       LERR(("Invalid what in exvval")); | 
|  | 899       return(0); | 
|  | 900   } | 
|  | 901   vv[0] = values[nv]; | 
|  | 902   if (!fp->hasd) return(1); | 
|  | 903   if (z) | 
|  | 904   { for (i=0; i<d; i++) vv[1<<i] = values[(i+1)*fp->nvm+nv]; | 
|  | 905     return(1<<d); | 
|  | 906   } | 
|  | 907   else | 
|  | 908   { for (i=1; i<=d; i++) vv[i] = values[i*fp->nvm+nv]; | 
|  | 909     return(d+1); | 
|  | 910   } | 
|  | 911 } | 
|  | 912 | 
|  | 913 void exvvalpv(vv,vl,vr,d,k,dl,nc) | 
|  | 914 double *vv, *vl, *vr, dl; | 
|  | 915 int d, k, nc; | 
|  | 916 { int i, tk, td; | 
|  | 917   double f0, f1; | 
|  | 918   if (nc==1) | 
|  | 919   { vv[0] = (vl[0]+vr[0])/2; | 
|  | 920     return; | 
|  | 921   } | 
|  | 922   tk = 1<<k; | 
|  | 923   td = 1<<d; | 
|  | 924   for (i=0; i<td; i++) if ((i&tk)==0) | 
|  | 925   { f0 = (vl[i]+vr[i])/2 + dl*(vl[i+tk]-vr[i+tk])/8; | 
|  | 926     f1 = 1.5*(vr[i]-vl[i])/dl - (vl[i+tk]+vr[i+tk])/4; | 
|  | 927     vv[i] = f0; | 
|  | 928     vv[i+tk] = f1; | 
|  | 929   } | 
|  | 930 } | 
|  | 931 | 
|  | 932 double grid_int(fp,evs,x,what) | 
|  | 933 fitpt *fp; | 
|  | 934 evstruc *evs; | 
|  | 935 double *x; | 
|  | 936 int what; | 
|  | 937 { int d, i, j, jj, nc, sk, v[MXDIM], vc, z0, nce[1<<MXDIM], *mg; | 
|  | 938   double *ll, *ur, vv[64][64], z; | 
|  | 939 | 
|  | 940   d = fp->d; | 
|  | 941   ll = evpt(fp,0); ur = evpt(fp,fp->nv-1); | 
|  | 942   mg = mg(evs); | 
|  | 943 | 
|  | 944   z0 = 0; vc = 1<<d; | 
|  | 945   for (j=d-1; j>=0; j--) | 
|  | 946   { v[j] = (int)((mg[j]-1)*(x[j]-ll[j])/(ur[j]-ll[j])); | 
|  | 947     if (v[j]<0) v[j]=0; | 
|  | 948     if (v[j]>=mg[j]-1) v[j] = mg[j]-2; | 
|  | 949     z0 = z0*mg[j]+v[j]; | 
|  | 950   } | 
|  | 951   nce[0] = z0; nce[1] = z0+1; sk = jj = 1; | 
|  | 952   for (i=1; i<d; i++) | 
|  | 953   { sk *= mg[i-1]; | 
|  | 954     jj<<=1; | 
|  | 955     for (j=0; j<jj; j++) | 
|  | 956       nce[j+jj] = nce[j]+sk; | 
|  | 957   } | 
|  | 958   for (i=0; i<vc; i++) | 
|  | 959     nc = exvval(fp,vv[i],nce[i],d,what,1); | 
|  | 960   ll = evpt(fp,nce[0]); | 
|  | 961   ur = evpt(fp,nce[vc-1]); | 
|  | 962   z = rectcell_interp(x,vv,ll,ur,d,nc); | 
|  | 963   return(z); | 
|  | 964 } | 
|  | 965 | 
|  | 966 double fitp_int(fp,x,what,i) | 
|  | 967 fitpt *fp; | 
|  | 968 double *x; | 
|  | 969 int what, i; | 
|  | 970 { double vv[1+MXDIM]; | 
|  | 971   exvval(fp,vv,i,fp->d,what,0); | 
|  | 972   return(vv[0]); | 
|  | 973 } | 
|  | 974 | 
|  | 975 double xbar_int(fp,x,what) | 
|  | 976 fitpt *fp; | 
|  | 977 double *x; | 
|  | 978 int what; | 
|  | 979 { int i, nc; | 
|  | 980   double vv[1+MXDIM], f; | 
|  | 981   nc = exvval(fp,vv,0,fp->d,what,0); | 
|  | 982   f = vv[0]; | 
|  | 983   if (nc>1) | 
|  | 984     for (i=0; i<fp->d; i++) | 
|  | 985       f += vv[i+1]*(x[i]-evptx(fp,0,i)); | 
|  | 986   return(f); | 
|  | 987 } | 
|  | 988 | 
|  | 989 double dointpoint(lf,x,what,ev,j) | 
|  | 990 lfit *lf; | 
|  | 991 double *x; | 
|  | 992 int what, ev, j; | 
|  | 993 { double xf, f, link[LLEN]; | 
|  | 994   int i, rt; | 
|  | 995   fitpt *fp; | 
|  | 996   evstruc *evs; | 
|  | 997 | 
|  | 998   fp = &lf->fp; evs = &lf->evs; | 
|  | 999   for (i=0; i<fp->d; i++) if (lf->lfd.sty[i]==STANGL) | 
|  | 1000   { xf = floor(x[i]/(2*PI*lf->lfd.sca[i])); | 
|  | 1001     x[i] -= xf*2*PI*lf->lfd.sca[i]; | 
|  | 1002   } | 
|  | 1003   if (what > 64) | 
|  | 1004   { rt = what-64; | 
|  | 1005     what = PCOEF; | 
|  | 1006   } | 
|  | 1007   else rt = 0; | 
|  | 1008 | 
|  | 1009   switch(ev) | 
|  | 1010   { case EGRID: f = grid_int(fp,evs,x,what); break; | 
|  | 1011     case EKDTR: f = kdtre_int(fp,evs,x,what); break; | 
|  | 1012     case ETREE: f = atree_int(lf,x,what); break; | 
|  | 1013     case EPHULL: f = triang_int(lf,x,what); break; | 
|  | 1014     case EFITP: f = fitp_int(fp,x,what,j); break; | 
|  | 1015     case EXBAR: f = xbar_int(fp,x,what); break; | 
|  | 1016     case ENONE: f = 0; break; | 
|  | 1017     case ESPHR: f = sphere_int(lf,x,what); break; | 
|  | 1018     default: LERR(("dointpoint: cannot interpolate structure %d",ev)); | 
|  | 1019   } | 
|  | 1020   if (((what==PT0)|(what==PNLX)) && (f<0)) f = 0.0; | 
|  | 1021   f += addparcomp(lf,x,what); | 
|  | 1022 | 
|  | 1023   if (rt>0) | 
|  | 1024   { | 
|  | 1025     stdlinks(link,&lf->lfd,&lf->sp,j,f,rsc(fp)); | 
|  | 1026     f = resid(resp(&lf->lfd,j),prwt(&lf->lfd,j),f,fam(&lf->sp),rt,link); | 
|  | 1027   } | 
|  | 1028 | 
|  | 1029   return(f); | 
|  | 1030 } | 
|  | 1031 /* | 
|  | 1032  * Copyright 1996-2006 Catherine Loader. | 
|  | 1033  */ | 
|  | 1034 /* | 
|  | 1035  *   Routines for building and interpolating the kd tree. | 
|  | 1036  *   Initially, this started from the loess code. | 
|  | 1037  * | 
|  | 1038  *   Todo: EKDCE isn't working. | 
|  | 1039  */ | 
|  | 1040 | 
|  | 1041 #include "lfev.h" | 
|  | 1042 | 
|  | 1043 void newcell(); | 
|  | 1044 static int nterm; | 
|  | 1045 | 
|  | 1046 void kdtre_guessnv(evs,nvm,ncm,vc,n,d,alp) | 
|  | 1047 evstruc *evs; | 
|  | 1048 double alp; | 
|  | 1049 int *nvm, *ncm, *vc, n, d; | 
|  | 1050 { int k; | 
|  | 1051   if (ev(evs) == EKDTR) | 
|  | 1052   { nterm = (int)(cut(evs)/4 * n * MIN(alp,1.0) ); | 
|  | 1053     k = 2*n/nterm; | 
|  | 1054     *vc = 1<<d; | 
|  | 1055     *ncm = 2*k+1; | 
|  | 1056     *nvm = (k+2)**vc/2; | 
|  | 1057     return; | 
|  | 1058   } | 
|  | 1059   if (ev(evs) == EKDCE) | 
|  | 1060   { nterm = (int)(n * alp); | 
|  | 1061     *vc = 1; | 
|  | 1062     *nvm = 1+(int)(2*n/nterm); | 
|  | 1063     *ncm = 2**nvm+1; | 
|  | 1064     return; | 
|  | 1065   } | 
|  | 1066   *nvm = *ncm = *vc = 0; | 
|  | 1067   return; | 
|  | 1068 } | 
|  | 1069 | 
|  | 1070 /* | 
|  | 1071   Split x[pi[l..r]] into two equal sized sets. | 
|  | 1072 | 
|  | 1073   Let m=(l+r)/2. | 
|  | 1074   At return, | 
|  | 1075     x[pi[l..m]] < x[pi[m+1..r]]. | 
|  | 1076     Assuming no ties: | 
|  | 1077       If l+r is odd, the sets have the same size. | 
|  | 1078       If l+r is even, the low set is larger by 1. | 
|  | 1079     If there are ties, all ties go in the low set. | 
|  | 1080 */ | 
|  | 1081 int ksmall(l, r, m, x, pi) | 
|  | 1082 int l, r, m, *pi; | 
|  | 1083 double *x; | 
|  | 1084 { | 
|  | 1085   int il, ir, jl, jr; | 
|  | 1086   double t; | 
|  | 1087 | 
|  | 1088 | 
|  | 1089   while(l<r) | 
|  | 1090   { t = x[pi[m]]; | 
|  | 1091 | 
|  | 1092     /* | 
|  | 1093       permute the observations so that | 
|  | 1094         x[pi[l..il]] < t <= x[pi[ir..r]]. | 
|  | 1095     */ | 
|  | 1096     ir = l; il = r; | 
|  | 1097     while (ir<il) | 
|  | 1098     { while ((ir<=r) && (x[pi[ir]] < t)) ir++; | 
|  | 1099       while ((il>=l) && (x[pi[il]]>= t)) il--; | 
|  | 1100       if (ir<il) ISWAP(pi[ir],pi[il]); | 
|  | 1101     } | 
|  | 1102 | 
|  | 1103     /* | 
|  | 1104       move  = t to the middle: | 
|  | 1105         x[pi[l..il]]  < t | 
|  | 1106         x[pi[jl..jr]] = t | 
|  | 1107         x[pi[ir..r]] > t | 
|  | 1108     */ | 
|  | 1109     jl = ir; jr = r; | 
|  | 1110     while (ir<jr) | 
|  | 1111     { while ((ir<=r)  && (x[pi[ir]]== t)) ir++; | 
|  | 1112       while ((jr>=jl) && (x[pi[jr]] > t)) jr--; | 
|  | 1113       if (ir<jr) ISWAP(pi[ir],pi[jr]); | 
|  | 1114     } | 
|  | 1115 | 
|  | 1116     /* | 
|  | 1117       we're done if m is in the middle, jl <= m <= jr. | 
|  | 1118     */ | 
|  | 1119     if ((jl<=m) & (jr>=m)) return(jr); | 
|  | 1120 | 
|  | 1121     /* | 
|  | 1122       update l or r. | 
|  | 1123     */ | 
|  | 1124     if (m>=ir) l = ir; | 
|  | 1125     if (m<=il) r = il; | 
|  | 1126   } | 
|  | 1127   if (l==r) return(l); | 
|  | 1128   LERR(("ksmall failure")); | 
|  | 1129   return(0); | 
|  | 1130 } | 
|  | 1131 | 
|  | 1132 int terminal(lf,p,pi,fc,d,m,split_val) | 
|  | 1133 lfit *lf; | 
|  | 1134 int p, d, fc, *m, *pi; | 
|  | 1135 double *split_val; | 
|  | 1136 { int i, k, lo, hi, split_var; | 
|  | 1137   double max, min, score, max_score, t; | 
|  | 1138 | 
|  | 1139   /* | 
|  | 1140     if there are fewer than fc points in the cell, this cell | 
|  | 1141     is terminal. | 
|  | 1142   */ | 
|  | 1143   lo = lf->evs.lo[p]; hi = lf->evs.hi[p]; | 
|  | 1144   if (hi-lo < fc) return(-1); | 
|  | 1145 | 
|  | 1146   /* determine the split variable */ | 
|  | 1147   max_score = 0.0; split_var = 0; | 
|  | 1148   for (k=0; k<d; k++) | 
|  | 1149   { max = min = datum(&lf->lfd, k, pi[lo]); | 
|  | 1150     for (i=lo+1; i<=hi; i++) | 
|  | 1151     { t = datum(&lf->lfd,k,pi[i]); | 
|  | 1152       if (t<min) min = t; | 
|  | 1153       if (t>max) max = t; | 
|  | 1154     } | 
|  | 1155     score = (max-min) / lf->lfd.sca[k]; | 
|  | 1156     if (score > max_score) | 
|  | 1157     { max_score = score; | 
|  | 1158       split_var = k; | 
|  | 1159     } | 
|  | 1160   } | 
|  | 1161   if (max_score==0) /* all points in the cell are equal */ | 
|  | 1162     return(-1); | 
|  | 1163 | 
|  | 1164   *m = ksmall(lo,hi,(lo+hi)/2, dvari(&lf->lfd,split_var), pi); | 
|  | 1165   *split_val = datum(&lf->lfd, split_var, pi[*m]); | 
|  | 1166 | 
|  | 1167   if (*m==hi) /* all observations go lo */ | 
|  | 1168     return(-1); | 
|  | 1169   return(split_var); | 
|  | 1170 } | 
|  | 1171 | 
|  | 1172 void kdtre_start(des,lf) | 
|  | 1173 design *des; | 
|  | 1174 lfit *lf; | 
|  | 1175 { | 
|  | 1176   int i, j, vc, d, nc, nv, ncm, nvm, k, m, n, p, *pi; | 
|  | 1177   double sv; | 
|  | 1178   d = lf->lfd.d; n = lf->lfd.n; pi = des->ind; | 
|  | 1179   kdtre_guessnv(&lf->evs,&nvm,&ncm,&vc,n,d,nn(&lf->sp)); | 
|  | 1180   trchck(lf,nvm,ncm,vc); | 
|  | 1181 | 
|  | 1182   nv = 0; | 
|  | 1183   if (ev(&lf->evs) != EKDCE) | 
|  | 1184   { for (i=0; i<vc; i++) | 
|  | 1185     { j = i; | 
|  | 1186       for (k=0; k<d; ++k) | 
|  | 1187       { evptx(&lf->fp,i,k) = lf->evs.fl[d*(j%2)+k]; | 
|  | 1188         j >>= 1; | 
|  | 1189       } | 
|  | 1190     } | 
|  | 1191     nv = vc; | 
|  | 1192     for (j=0; j<vc; j++) lf->evs.ce[j] = j; | 
|  | 1193   } | 
|  | 1194 | 
|  | 1195   for (i=0; i<n; i++) pi[i] = i; | 
|  | 1196   p = 0; nc = 1; | 
|  | 1197   lf->evs.lo[p] = 0; lf->evs.hi[p] = n-1; | 
|  | 1198   lf->evs.s[p] = -1; | 
|  | 1199   while (p<nc) | 
|  | 1200   { k = terminal(lf,p,pi,nterm,d,&m,&sv); | 
|  | 1201     if (k>=0) | 
|  | 1202     { | 
|  | 1203       if ((ncm<nc+2) | (2*nvm<2*nv+vc)) | 
|  | 1204       { WARN(("Insufficient space for full tree")); | 
|  | 1205         lf->evs.nce = nc; lf->fp.nv = nv; | 
|  | 1206         return; | 
|  | 1207       } | 
|  | 1208 | 
|  | 1209       /* new lo cell has obsn's lo[p]..m */ | 
|  | 1210       lf->evs.lo[nc] = lf->evs.lo[p]; | 
|  | 1211       lf->evs.hi[nc] = m; | 
|  | 1212       lf->evs.s[nc] = -1; | 
|  | 1213 | 
|  | 1214       /* new hi cell has obsn's m+1..hi[p] */ | 
|  | 1215       lf->evs.lo[nc+1] = m+1; | 
|  | 1216       lf->evs.hi[nc+1] = lf->evs.hi[p]; | 
|  | 1217       lf->evs.s[nc+1] = -1; | 
|  | 1218 | 
|  | 1219       /* cell p is split on variable k, value sv */ | 
|  | 1220       lf->evs.s[p] = k; | 
|  | 1221       lf->evs.sv[p] = sv; | 
|  | 1222       lf->evs.lo[p] = nc; lf->evs.hi[p] = nc+1; | 
|  | 1223 | 
|  | 1224       nc=nc+2; i = nv; | 
|  | 1225 | 
|  | 1226       /* now compute the new vertices. */ | 
|  | 1227       if (ev(&lf->evs) != EKDCE) | 
|  | 1228         newcell(&nv,vc,evp(&lf->fp), d, k, sv, | 
|  | 1229              &lf->evs.ce[p*vc], &lf->evs.ce[(nc-2)*vc], &lf->evs.ce[(nc-1)*vc]); | 
|  | 1230 | 
|  | 1231     } | 
|  | 1232     else if (ev(&lf->evs)==EKDCE) /* new vertex at cell center */ | 
|  | 1233     { sv = 0; | 
|  | 1234       for (i=0; i<d; i++) evptx(&lf->fp,nv,i) = 0; | 
|  | 1235       for (j=lf->evs.lo[p]; j<=lf->evs.hi[p]; j++) | 
|  | 1236       { sv += prwt(&lf->lfd,(int)pi[j]); | 
|  | 1237         for (i=0; i<d; i++) | 
|  | 1238           evptx(&lf->fp,nv,i) += datum(&lf->lfd,i,pi[j])*prwt(&lf->lfd,(int)pi[j]); | 
|  | 1239       } | 
|  | 1240       for (i=0; i<d; i++) evptx(&lf->fp,nv,i) /= sv; | 
|  | 1241       lf->lfd.n = lf->evs.hi[p] - lf->evs.lo[p] + 1; | 
|  | 1242       des->ind = &pi[lf->evs.lo[p]]; /* why? */ | 
|  | 1243       PROC_VERTEX(des,lf,nv); | 
|  | 1244       lf->lfd.n = n; des->ind = pi; | 
|  | 1245       nv++; | 
|  | 1246     } | 
|  | 1247     p++; | 
|  | 1248   } | 
|  | 1249 | 
|  | 1250   /* We've built the tree. Now do the fitting. */ | 
|  | 1251   if (ev(&lf->evs)==EKDTR) | 
|  | 1252     for (i=0; i<nv; i++) PROC_VERTEX(des,lf,i); | 
|  | 1253 | 
|  | 1254   lf->evs.nce = nc; lf->fp.nv = nv; | 
|  | 1255   return; | 
|  | 1256 } | 
|  | 1257 | 
|  | 1258 void newcell(nv,vc,xev, d, k, split_val, cpar, clef, crig) | 
|  | 1259 double *xev, split_val; | 
|  | 1260 int *cpar, *clef, *crig; | 
|  | 1261 int *nv, vc, d, k; | 
|  | 1262 { int i, ii, j, j2, tk, match; | 
|  | 1263   tk = 1<<k; | 
|  | 1264   for (i=0; i<vc; i++) | 
|  | 1265   { if ((i&tk) == 0) | 
|  | 1266     { for (j=0; j<d; j++) xev[*nv*d+j] = xev[d*cpar[i]+j]; | 
|  | 1267       xev[*nv*d+k] = split_val; | 
|  | 1268       match = 0; j = vc; /* no matches in first vc points */ | 
|  | 1269       while ((j<*nv) && (!match)) | 
|  | 1270       { j2 = 0; | 
|  | 1271         while ((j2<d) && (xev[*nv*d+j2] == xev[j*d+j2])) j2++; | 
|  | 1272         match = (j2==d); | 
|  | 1273         if (!match) j++; | 
|  | 1274       } | 
|  | 1275       ii = i+tk; | 
|  | 1276       clef[i] = cpar[i]; | 
|  | 1277       clef[ii]= crig[i] = j; | 
|  | 1278       crig[ii]= cpar[ii]; | 
|  | 1279       if (!match) (*nv)++; | 
|  | 1280     } | 
|  | 1281   } | 
|  | 1282   return; | 
|  | 1283 } | 
|  | 1284 | 
|  | 1285 extern void hermite2(); | 
|  | 1286 | 
|  | 1287 double blend(fp,evs,s,x,ll,ur,j,nt,t,what) | 
|  | 1288 fitpt *fp; | 
|  | 1289 evstruc *evs; | 
|  | 1290 double s, *x, *ll, *ur; | 
|  | 1291 int j, nt, *t, what; | 
|  | 1292 { | 
|  | 1293   int *ce, k, k1, m, nc, j0, j1; | 
|  | 1294   double v0, v1, xibar, g0[3], g1[3], gg[4], gp[4], phi[4]; | 
|  | 1295   ce = evs->ce; | 
|  | 1296   for (k=0; k<4; k++)  /* North South East West */ | 
|  | 1297   { k1 = (k>1); | 
|  | 1298     v0 = ll[k1]; v1 = ur[k1]; | 
|  | 1299     j0 = ce[j+2*(k==0)+(k==2)]; | 
|  | 1300     j1 = ce[j+3-2*(k==1)-(k==3)]; | 
|  | 1301     xibar = (k%2==0) ? ur[k<2] : ll[k<2]; | 
|  | 1302     m = nt; | 
|  | 1303     while ((m>=0) && ((evs->s[t[m]] != (k<=1)) | (evs->sv[t[m]] != xibar))) m--; | 
|  | 1304     if (m >= 0) | 
|  | 1305     { m = (k%2==1) ? evs->lo[t[m]] : evs->hi[t[m]]; | 
|  | 1306       while (evs->s[m] != -1) | 
|  | 1307         m = (x[evs->s[m]] < evs->sv[m]) ? evs->lo[m] : evs->hi[m]; | 
|  | 1308       if (v0 < evptx(fp,ce[4*m+2*(k==1)+(k==3)],k1)) | 
|  | 1309       { j0 = ce[4*m+2*(k==1)+(k==3)]; | 
|  | 1310         v0 = evptx(fp,j0,k1); | 
|  | 1311       } | 
|  | 1312       if (evptx(fp,ce[4*m+3-2*(k==0)-(k==2)],k1) < v1) | 
|  | 1313       { j1 = ce[4*m+3-2*(k==0)-(k==2)]; | 
|  | 1314         v1 = evptx(fp,j1,k1); | 
|  | 1315       } | 
|  | 1316     } | 
|  | 1317     nc = exvval(fp,g0,j0,2,what,0); | 
|  | 1318     nc = exvval(fp,g1,j1,2,what,0); | 
|  | 1319     if (nc==1) | 
|  | 1320       gg[k] = linear_interp((x[(k>1)]-v0),v1-v0,g0[0],g1[0]); | 
|  | 1321     else | 
|  | 1322     { hermite2(x[(k>1)]-v0,v1-v0,phi); | 
|  | 1323       gg[k] = phi[0]*g0[0]+phi[1]*g1[0]+(phi[2]*g0[1+k1]+phi[3]*g1[1+k1])*(v1-v0); | 
|  | 1324       gp[k] = phi[0]*g0[2-k1] + phi[1]*g1[2-k1]; | 
|  | 1325     } | 
|  | 1326   } | 
|  | 1327   s = -s; | 
|  | 1328   if (nc==1) | 
|  | 1329     for (k=0; k<2; k++) | 
|  | 1330       s += linear_interp(x[k]-ll[k],ur[k]-ll[k],gg[3-2*k],gg[2-2*k]); | 
|  | 1331     else | 
|  | 1332     for (k=0; k<2; k++) /* EW NS */ | 
|  | 1333     { hermite2(x[k]-ll[k],ur[k]-ll[k],phi); | 
|  | 1334       s += phi[0]*gg[3-2*k] + phi[1]*gg[2-2*k] | 
|  | 1335           +(phi[2]*gp[3-2*k] + phi[3]*gp[2-2*k]) * (ur[k]-ll[k]); | 
|  | 1336     } | 
|  | 1337   return(s); | 
|  | 1338 } | 
|  | 1339 | 
|  | 1340 double kdtre_int(fp,evs,x,what) | 
|  | 1341 fitpt *fp; | 
|  | 1342 evstruc *evs; | 
|  | 1343 double *x; | 
|  | 1344 int what; | 
|  | 1345 { | 
|  | 1346   int *ce, k, vc, t[20], nt, nc, j, d; | 
|  | 1347   double *ll, *ur, ff, vv[64][64]; | 
|  | 1348   d = fp->d; | 
|  | 1349   vc = 1<<d; | 
|  | 1350   if (d > 6) { LERR(("d too large in kdint")); return(NOSLN); } | 
|  | 1351 | 
|  | 1352   /* descend the tree to find the terminal cell */ | 
|  | 1353   nt = 0; t[nt] = 0; k = 0; | 
|  | 1354   while (evs->s[k] != -1) | 
|  | 1355   { nt++; | 
|  | 1356     if (nt>=20) { LERR(("Too many levels in kdint")); return(NOSLN); } | 
|  | 1357     k = t[nt] = (x[evs->s[k]] < evs->sv[k]) ? evs->lo[k] : evs->hi[k]; | 
|  | 1358   } | 
|  | 1359 | 
|  | 1360   ce = &evs->ce[k*vc]; | 
|  | 1361   ll = evpt(fp,ce[0]); | 
|  | 1362   ur = evpt(fp,ce[vc-1]); | 
|  | 1363   nc = 0; | 
|  | 1364   for (j=0; j<vc; j++) nc = exvval(fp,vv[j],(int)ce[j],d,what,0); | 
|  | 1365   ff = rectcell_interp(x,vv,ll,ur,d,nc); | 
|  | 1366 | 
|  | 1367   if (d==2) ff = blend(fp,evs,ff,x,ll,ur,k*vc,nt,t,what); | 
|  | 1368   return(ff); | 
|  | 1369 } | 
|  | 1370 /* | 
|  | 1371  * Copyright 1996-2006 Catherine Loader. | 
|  | 1372  */ | 
|  | 1373 #include "lfev.h" | 
|  | 1374 | 
|  | 1375 /* | 
|  | 1376  * convert eval. structure string to numeric code. | 
|  | 1377  */ | 
|  | 1378 #define NETYPE 11 | 
|  | 1379 static char *etype[NETYPE]= { "tree",     "phull", "data", "grid", "kdtree", | 
|  | 1380                           "kdcenter", "cross", "preset", "xbar", "none", | 
|  | 1381                           "sphere" }; | 
|  | 1382 static int   evals[NETYPE]= { ETREE, EPHULL, EDATA, EGRID, EKDTR, | 
|  | 1383                           EKDCE, ECROS,  EPRES, EXBAR, ENONE, ESPHR }; | 
|  | 1384 int lfevstr(char *z) | 
|  | 1385 { return(pmatch(z, etype, evals, NETYPE, -1)); | 
|  | 1386 } | 
|  | 1387 | 
|  | 1388 void evstruc_init(evs) | 
|  | 1389 evstruc *evs; | 
|  | 1390 { int i; | 
|  | 1391   ev(evs) = ETREE; | 
|  | 1392   mk(evs) = 100; | 
|  | 1393   cut(evs) = 0.8; | 
|  | 1394   for (i=0; i<MXDIM; i++) | 
|  | 1395   { evs->fl[i] = evs->fl[i+MXDIM] = 0.0; | 
|  | 1396     evs->mg[i] = 10; | 
|  | 1397   } | 
|  | 1398   evs->nce = evs->ncm = 0; | 
|  | 1399 } | 
|  | 1400 | 
|  | 1401 int evstruc_reqi(nvm,ncm,vc) | 
|  | 1402 int nvm, ncm, vc; | 
|  | 1403 { return(ncm*vc+3*MAX(ncm,nvm)); | 
|  | 1404 } | 
|  | 1405 | 
|  | 1406 /* al=1: allows dynamic allocation. | 
|  | 1407  * al=0: inhibit. use with caution. | 
|  | 1408  */ | 
|  | 1409 void evstruc_alloc(evs,nvm,ncm,vc,al) | 
|  | 1410 evstruc *evs; | 
|  | 1411 int nvm, ncm, vc, al; | 
|  | 1412 { int rw, *k; | 
|  | 1413 | 
|  | 1414   if (al) | 
|  | 1415   { rw = evstruc_reqi(nvm,ncm,vc); | 
|  | 1416     if (evs->liw<rw) | 
|  | 1417     { evs->iwk = (int *)calloc(rw,sizeof(int)); | 
|  | 1418     if ( evs->iwk == NULL ) { | 
|  | 1419       printf("Problem allocating memory for evs->iwk\n");fflush(stdout); | 
|  | 1420     } | 
|  | 1421       evs->liw = rw; | 
|  | 1422     } | 
|  | 1423   } | 
|  | 1424   k = evs->iwk; | 
|  | 1425   evs->ce = k; k += vc*ncm; | 
|  | 1426   evs->s  = k; k += MAX(ncm,nvm); | 
|  | 1427   evs->lo = k; k += MAX(ncm,nvm); | 
|  | 1428   evs->hi = k; k += MAX(ncm,nvm); | 
|  | 1429 } | 
|  | 1430 | 
|  | 1431 void guessnv(evs,sp,mdl,n,d,lw,nvc) | 
|  | 1432 evstruc *evs; | 
|  | 1433 smpar *sp; | 
|  | 1434 module *mdl; | 
|  | 1435 int n, d, *lw, *nvc; | 
|  | 1436 { int i, nvm, ncm, vc; | 
|  | 1437 | 
|  | 1438   npar(sp) = calcp(sp,d); | 
|  | 1439   switch(ev(evs)) | 
|  | 1440   { case ETREE: | 
|  | 1441       atree_guessnv(evs,&nvm,&ncm,&vc,d,nn(sp)); | 
|  | 1442       break; | 
|  | 1443     case EPHULL: | 
|  | 1444       nvm = ncm = mk(evs)*d; | 
|  | 1445       vc = d+1; | 
|  | 1446       break; | 
|  | 1447     case EDATA: | 
|  | 1448     case ECROS: | 
|  | 1449       nvm = n; | 
|  | 1450       ncm = vc = 0; | 
|  | 1451       break; | 
|  | 1452     case EKDTR: | 
|  | 1453     case EKDCE: | 
|  | 1454       kdtre_guessnv(evs,&nvm,&ncm,&vc,n,d,nn(sp)); | 
|  | 1455       break; | 
|  | 1456     case EGRID: | 
|  | 1457       nvm = 1; | 
|  | 1458       for (i=0; i<d; i++) nvm *= evs->mg[i]; | 
|  | 1459       ncm = 0; | 
|  | 1460       vc = 1<<d; | 
|  | 1461       break; | 
|  | 1462     case EXBAR: | 
|  | 1463     case ENONE: | 
|  | 1464       nvm = 1; | 
|  | 1465       ncm = vc = 0; | 
|  | 1466       break; | 
|  | 1467     case EPRES: | 
|  | 1468       nvm = evs->mg[0]; | 
|  | 1469       ncm = vc = 0; | 
|  | 1470       break; | 
|  | 1471     default: | 
|  | 1472       LERR(("guessnv: I don't know this evaluation structure.")); | 
|  | 1473       nvm = ncm = vc = 0; | 
|  | 1474   } | 
|  | 1475 | 
|  | 1476   lw[0] = des_reqd(n,npar(sp)); | 
|  | 1477   lw[1] = lfit_reqd(d,nvm,ncm,mdl); | 
|  | 1478   lw[2] = evstruc_reqi(nvm,ncm,vc); | 
|  | 1479   lw[6] = des_reqi(n,npar(sp)); | 
|  | 1480   lw[3] = pc_reqd(d,npar(sp)); | 
|  | 1481   lw[4] = mdl->keepv; | 
|  | 1482   lw[5] = mdl->keepc; | 
|  | 1483 | 
|  | 1484   if (nvc==NULL) return; | 
|  | 1485   nvc[0] = nvm; | 
|  | 1486   nvc[1] = ncm; | 
|  | 1487   nvc[2] = vc; | 
|  | 1488   nvc[3] = nvc[4] = 0; | 
|  | 1489 } | 
|  | 1490 | 
|  | 1491 /* | 
|  | 1492  * trchck checks the working space on the lfit structure | 
|  | 1493  * has space for nvm vertices and ncm cells. | 
|  | 1494  */ | 
|  | 1495 void lfit_alloc(lf) | 
|  | 1496 lfit *lf; | 
|  | 1497 { lf->fp.lwk = lf->fp.lev = lf->evs.liw = lf->pc.lwk = 0; | 
|  | 1498   lf->lf_init_id = LF_INIT_ID; | 
|  | 1499 } | 
|  | 1500 int lfit_reqd(d,nvm,ncm,mdl) | 
|  | 1501 int d, nvm, ncm; | 
|  | 1502 module *mdl; | 
|  | 1503 { int z; | 
|  | 1504   z = mdl->keepv; | 
|  | 1505   return(nvm*z+ncm); | 
|  | 1506 } | 
|  | 1507 | 
|  | 1508 void trchck(lf,nvm,ncm,vc) | 
|  | 1509 lfit *lf; | 
|  | 1510 int nvm, ncm, vc; | 
|  | 1511 { int rw, d, *k; | 
|  | 1512   double *z; | 
|  | 1513 | 
|  | 1514   if (lf->lf_init_id != LF_INIT_ID) lfit_alloc(lf); | 
|  | 1515 | 
|  | 1516   lf->fp.nvm = nvm; lf->evs.ncm = ncm; | 
|  | 1517   d = lf->lfd.d; | 
|  | 1518 | 
|  | 1519   if (lf->fp.lev < d*nvm) | 
|  | 1520   { lf->fp.xev = (double *)calloc(d*nvm,sizeof(double)); | 
|  | 1521     if ( lf->fp.xev == NULL ) { | 
|  | 1522       printf("Problem allocating memory for lf->fp.xev\n");fflush(stdout); | 
|  | 1523     } | 
|  | 1524     lf->fp.lev = d*nvm; | 
|  | 1525   } | 
|  | 1526 | 
|  | 1527   rw = lfit_reqd(d,nvm,ncm,&lf->mdl); | 
|  | 1528   if (lf->fp.lwk < rw) | 
|  | 1529   { | 
|  | 1530     lf->fp.coef = (double *)calloc(rw,sizeof(double)); | 
|  | 1531     if ( lf->fp.coef == NULL ) { | 
|  | 1532       printf("Problem allocating memory for lf->fp.coef\n");fflush(stdout); | 
|  | 1533     } | 
|  | 1534     lf->fp.lwk = rw; | 
|  | 1535   } | 
|  | 1536   z = lf->fp.wk = lf->fp.coef; | 
|  | 1537 | 
|  | 1538   lf->fp.h = NULL; | 
|  | 1539   if (!lf->mdl.isset) mut_printf("module not set.\n"); | 
|  | 1540   else | 
|  | 1541   { if (lf->mdl.alloc!=NULL) lf->mdl.alloc(lf); | 
|  | 1542     z += KEEPV(lf) * nvm; | 
|  | 1543   } | 
|  | 1544   lf->evs.sv = z; z += ncm; | 
|  | 1545 | 
|  | 1546   evstruc_alloc(&lf->evs,nvm,ncm,vc,1); | 
|  | 1547 } | 
|  | 1548 | 
|  | 1549 void data_guessnv(nvm,ncm,vc,n) | 
|  | 1550 int *nvm, *ncm, *vc, n; | 
|  | 1551 { *nvm = n; | 
|  | 1552   *ncm = *vc = 0; | 
|  | 1553 } | 
|  | 1554 | 
|  | 1555 void dataf(des,lf) | 
|  | 1556 design *des; | 
|  | 1557 lfit *lf; | 
|  | 1558 { | 
|  | 1559   int d, i, j, ncm, nv, vc; | 
|  | 1560 | 
|  | 1561   d = lf->lfd.d; | 
|  | 1562   data_guessnv(&nv,&ncm,&vc,lf->lfd.n); | 
|  | 1563   trchck(lf,nv,ncm,vc); | 
|  | 1564 | 
|  | 1565   for (i=0; i<nv; i++) | 
|  | 1566     for (j=0; j<d; j++) evptx(&lf->fp,i,j) = datum(&lf->lfd,j,i); | 
|  | 1567   for (i=0; i<nv; i++) | 
|  | 1568   { | 
|  | 1569     PROC_VERTEX(des,lf,i); | 
|  | 1570     lf->evs.s[i] = 0; | 
|  | 1571   } | 
|  | 1572   lf->fp.nv = lf->fp.nvm = nv; lf->evs.nce = 0; | 
|  | 1573 } | 
|  | 1574 | 
|  | 1575 void xbar_guessnv(nvm,ncm,vc) | 
|  | 1576 int *nvm, *ncm, *vc; | 
|  | 1577 { *nvm = 1; | 
|  | 1578   *ncm = *vc = 0; | 
|  | 1579   return; | 
|  | 1580 } | 
|  | 1581 | 
|  | 1582 void xbarf(des,lf) | 
|  | 1583 design *des; | 
|  | 1584 lfit *lf; | 
|  | 1585 { int i, d, nvm, ncm, vc; | 
|  | 1586   d = lf->lfd.d; | 
|  | 1587   xbar_guessnv(&nvm,&ncm,&vc); | 
|  | 1588   trchck(lf,1,0,0); | 
|  | 1589   for (i=0; i<d; i++) evptx(&lf->fp,0,i) = lf->pc.xbar[i]; | 
|  | 1590   PROC_VERTEX(des,lf,0); | 
|  | 1591   lf->evs.s[0] = 0; | 
|  | 1592   lf->fp.nv = 1; lf->evs.nce = 0; | 
|  | 1593 } | 
|  | 1594 | 
|  | 1595 void preset(des,lf) | 
|  | 1596 design *des; | 
|  | 1597 lfit *lf; | 
|  | 1598 { int i, nv; | 
|  | 1599 | 
|  | 1600   nv = lf->fp.nvm; | 
|  | 1601   trchck(lf,nv,0,0); | 
|  | 1602   for (i=0; i<nv; i++) | 
|  | 1603   { | 
|  | 1604     PROC_VERTEX(des,lf,i); | 
|  | 1605     lf->evs.s[i] = 0; | 
|  | 1606   } | 
|  | 1607   lf->fp.nv = nv; lf->evs.nce = 0; | 
|  | 1608 } | 
|  | 1609 | 
|  | 1610 void crossf(des,lf) | 
|  | 1611 design *des; | 
|  | 1612 lfit *lf; | 
|  | 1613 { int d, i, j, n, nv, ncm, vc; | 
|  | 1614   double w; | 
|  | 1615 | 
|  | 1616   n = lf->lfd.n; d = lf->lfd.d; | 
|  | 1617   data_guessnv(&nv,&ncm,&vc,n); | 
|  | 1618   trchck(lf,nv,ncm,vc); | 
|  | 1619 | 
|  | 1620   if (lf->lfd.w==NULL) LERR(("crossf() needs prior weights")); | 
|  | 1621   for (i=0; i<n; i++) | 
|  | 1622     for (j=0; j<d; j++) evptx(&lf->fp,i,j) = datum(&lf->lfd,j,i); | 
|  | 1623   for (i=0; i<n; i++) | 
|  | 1624   { lf->evs.s[i] = 0; | 
|  | 1625     w = prwt(&lf->lfd,i); | 
|  | 1626     lf->lfd.w[i] = 0; | 
|  | 1627     PROC_VERTEX(des,lf,i); | 
|  | 1628     lf->lfd.w[i] = w; | 
|  | 1629   } | 
|  | 1630   lf->fp.nv = n; lf->evs.nce = 0; | 
|  | 1631 } | 
|  | 1632 | 
|  | 1633 void gridf(des,lf) | 
|  | 1634 design *des; | 
|  | 1635 lfit *lf; | 
|  | 1636 { int d, i, j, nv, u0, u1, z; | 
|  | 1637   nv = 1; d = lf->lfd.d; | 
|  | 1638   for (i=0; i<d; i++) | 
|  | 1639   { if (lf->evs.mg[i]==0) | 
|  | 1640       lf->evs.mg[i] = 2+(int)((lf->evs.fl[i+d]-lf->evs.fl[i])/(lf->lfd.sca[i]*cut(&lf->evs))); | 
|  | 1641     nv *= lf->evs.mg[i]; | 
|  | 1642   } | 
|  | 1643   trchck(lf,nv,0,1<<d); | 
|  | 1644   for (i=0; i<nv; i++) | 
|  | 1645   { z = i; | 
|  | 1646     for (j=0; j<d; j++) | 
|  | 1647     { u0 = z%lf->evs.mg[j]; | 
|  | 1648       u1 = lf->evs.mg[j]-1-u0; | 
|  | 1649       evptx(&lf->fp,i,j) = (lf->evs.mg[j]==1) ? lf->evs.fl[j] : | 
|  | 1650                       (u1*lf->evs.fl[j]+u0*lf->evs.fl[j+d])/(lf->evs.mg[j]-1); | 
|  | 1651       z = z/lf->evs.mg[j]; | 
|  | 1652     } | 
|  | 1653     lf->evs.s[i] = 0; | 
|  | 1654     PROC_VERTEX(des,lf,i); | 
|  | 1655   } | 
|  | 1656   lf->fp.nv = nv; lf->evs.nce = 0; | 
|  | 1657 } | 
|  | 1658 | 
|  | 1659 int findpt(fp,evs,i0,i1) | 
|  | 1660 fitpt *fp; | 
|  | 1661 evstruc *evs; | 
|  | 1662 int i0, i1; | 
|  | 1663 { int i; | 
|  | 1664   if (i0>i1) ISWAP(i0,i1); | 
|  | 1665   for (i=i1+1; i<fp->nv; i++) | 
|  | 1666     if ((evs->lo[i]==i0) && (evs->hi[i]==i1)) return(i); | 
|  | 1667   return(-1); | 
|  | 1668 } | 
|  | 1669 | 
|  | 1670 /* | 
|  | 1671   add a new vertex at the midpoint of (x[i0],x[i1]). | 
|  | 1672   return the vertex number. | 
|  | 1673 */ | 
|  | 1674 int newsplit(des,lf,i0,i1,pv) | 
|  | 1675 design *des; | 
|  | 1676 lfit *lf; | 
|  | 1677 int i0, i1, pv; | 
|  | 1678 { int i, nv; | 
|  | 1679 | 
|  | 1680   i = findpt(&lf->fp,&lf->evs,i0,i1); | 
|  | 1681   if (i>=0) return(i); | 
|  | 1682 | 
|  | 1683   if (i0>i1) ISWAP(i0,i1); | 
|  | 1684   nv = lf->fp.nv; | 
|  | 1685 | 
|  | 1686   /* the point is new. Now check we have space for the new point. */ | 
|  | 1687   if (nv>=lf->fp.nvm) | 
|  | 1688   { | 
|  | 1689     LERR(("newsplit: out of vertex space")); | 
|  | 1690     return(-1); | 
|  | 1691   } | 
|  | 1692 | 
|  | 1693   /* compute the new point, and evaluate the fit */ | 
|  | 1694   lf->evs.lo[nv] = i0; | 
|  | 1695   lf->evs.hi[nv] = i1; | 
|  | 1696   for (i=0; i<lf->fp.d; i++) | 
|  | 1697     evptx(&lf->fp,nv,i) = (evptx(&lf->fp,i0,i)+evptx(&lf->fp,i1,i))/2; | 
|  | 1698   if (pv) /* pseudo vertex */ | 
|  | 1699   { lf->fp.h[nv] = (lf->fp.h[i0]+lf->fp.h[i1])/2; | 
|  | 1700     lf->evs.s[nv] = 1; /* pseudo-vertex */ | 
|  | 1701   } | 
|  | 1702   else /* real vertex */ | 
|  | 1703   { | 
|  | 1704     PROC_VERTEX(des,lf,nv); | 
|  | 1705     lf->evs.s[nv] = 0; | 
|  | 1706   } | 
|  | 1707   lf->fp.nv++; | 
|  | 1708 | 
|  | 1709   return(nv); | 
|  | 1710 } | 
|  | 1711 /* | 
|  | 1712  * Copyright 1996-2006 Catherine Loader. | 
|  | 1713  */ | 
|  | 1714 /* | 
|  | 1715  *   Functions for constructing the fit and | 
|  | 1716  *   interpolating on the circle/sphere. d=2 only. | 
|  | 1717  */ | 
|  | 1718 | 
|  | 1719 #include "lfev.h" | 
|  | 1720 | 
|  | 1721 /* | 
|  | 1722  * Guess the number of fitting points. | 
|  | 1723  */ | 
|  | 1724 void sphere_guessnv(nvm,ncm,vc,mg) | 
|  | 1725 int *nvm, *ncm, *vc, *mg; | 
|  | 1726 { *nvm = mg[1]*(mg[0]+1); | 
|  | 1727   *ncm = 0; | 
|  | 1728   *vc = 0; | 
|  | 1729 } | 
|  | 1730 | 
|  | 1731 void sphere_start(des,lf) | 
|  | 1732 design *des; | 
|  | 1733 lfit *lf; | 
|  | 1734 { int d, i, j, ct, nv, ncm, vc, *mg; | 
|  | 1735   double rmin, rmax, *orig, r, th, c, s; | 
|  | 1736 | 
|  | 1737   mg = mg(&lf->evs); | 
|  | 1738   sphere_guessnv(&nv,&ncm,&vc,mg); | 
|  | 1739   trchck(lf,nv,0,0); | 
|  | 1740   d = lf->lfd.d; | 
|  | 1741 | 
|  | 1742   rmin = lf->evs.fl[0]; | 
|  | 1743   rmax = lf->evs.fl[1]; | 
|  | 1744   orig = &lf->evs.fl[2]; | 
|  | 1745 rmin = 0; rmax = 1; orig[0] = orig[1] = 0.0; | 
|  | 1746 | 
|  | 1747   ct = 0; | 
|  | 1748   for (i=0; i<mg[1]; i++) | 
|  | 1749   { th = 2*PI*i/mg[1]; | 
|  | 1750     c = cos(th); | 
|  | 1751     s = sin(th); | 
|  | 1752     for (j=0; j<=mg[0]; j++) | 
|  | 1753     { r = rmin + (rmax-rmin)*j/mg[0]; | 
|  | 1754       evptx(&lf->fp,ct,0) = orig[0] + r*c; | 
|  | 1755       evptx(&lf->fp,ct,1) = orig[1] + r*s; | 
|  | 1756       PROC_VERTEX(des,lf,ct); | 
|  | 1757       ct++; | 
|  | 1758     } | 
|  | 1759   } | 
|  | 1760   lf->fp.nv = ct; | 
|  | 1761   lf->evs.nce = 0; | 
|  | 1762 } | 
|  | 1763 | 
|  | 1764 double sphere_int(lf,x,what) | 
|  | 1765 lfit *lf; | 
|  | 1766 double *x; | 
|  | 1767 int what; | 
|  | 1768 { double rmin, rmax, *orig, dx, dy, r, th, th0, th1; | 
|  | 1769   double v[64][64], c0, c1, s0, s1, r0, r1, d0, d1; | 
|  | 1770   double ll[2], ur[2], xx[2]; | 
|  | 1771   int i0, j0, i1, j1, *mg, nc, ce[4]; | 
|  | 1772 | 
|  | 1773   rmin = lf->evs.fl[0]; | 
|  | 1774   rmax = lf->evs.fl[1]; | 
|  | 1775   orig = &lf->evs.fl[2]; | 
|  | 1776 rmin = 0; rmax = 1; orig[0] = orig[1] = 0.0; | 
|  | 1777   mg = mg(&lf->evs); | 
|  | 1778 | 
|  | 1779   dx = x[0] - orig[0]; | 
|  | 1780   dy = x[1] - orig[1]; | 
|  | 1781   r = sqrt(dx*dx+dy*dy); | 
|  | 1782   th = atan2(dy,dx); /* between -pi and pi */ | 
|  | 1783 | 
|  | 1784   i0 = (int)floor(mg[1]*th/(2*PI)) % mg[1]; | 
|  | 1785   j0 = (int)(mg[0]*(r-rmin)/(rmax-rmin)); | 
|  | 1786 | 
|  | 1787   i1 = (i0+1) % mg[1]; | 
|  | 1788   j1 = j0+1; if (j1>mg[0]) { j0 = mg[0]-1; j1 = mg[0]; } | 
|  | 1789 | 
|  | 1790   ce[0] = i0*(mg[0]+1)+j0; | 
|  | 1791   ce[1] = i0*(mg[0]+1)+j1; | 
|  | 1792   ce[2] = i1*(mg[0]+1)+j0; | 
|  | 1793   ce[3] = i1*(mg[0]+1)+j1; | 
|  | 1794   nc = exvval(&lf->fp,v[0],ce[0],2,what,1); | 
|  | 1795   nc = exvval(&lf->fp,v[1],ce[1],2,what,1); | 
|  | 1796   nc = exvval(&lf->fp,v[2],ce[2],2,what,1); | 
|  | 1797   nc = exvval(&lf->fp,v[3],ce[3],2,what,1); | 
|  | 1798 | 
|  | 1799   th0 = 2*PI*i0/mg[1]; c0 = cos(th0); s0 = sin(th0); | 
|  | 1800   th1 = 2*PI*i1/mg[1]; c1 = cos(th1); s1 = sin(th1); | 
|  | 1801   r0 = rmin + j0*(rmax-rmin)/mg[0]; | 
|  | 1802   r1 = rmin + j1*(rmax-rmin)/mg[0]; | 
|  | 1803 | 
|  | 1804   d0 = c0*v[0][1] + s0*v[0][2]; | 
|  | 1805   d1 = r0*(c0*v[0][2]-s0*v[0][1]); | 
|  | 1806   v[0][1] = d0; v[0][2] = d1; | 
|  | 1807 | 
|  | 1808   d0 = c0*v[1][1] + s0*v[1][2]; | 
|  | 1809   d1 = r1*(c0*v[1][2]-s0*v[1][1]); | 
|  | 1810   v[1][1] = d0; v[1][2] = d1; | 
|  | 1811 | 
|  | 1812   d0 = c1*v[2][1] + s1*v[2][2]; | 
|  | 1813   d1 = r0*(c1*v[2][2]-s1*v[2][1]); | 
|  | 1814   v[2][1] = d0; v[2][2] = d1; | 
|  | 1815 | 
|  | 1816   d0 = c1*v[3][1] + s1*v[3][2]; | 
|  | 1817   d1 = r1*(c1*v[3][2]-s1*v[3][1]); | 
|  | 1818   v[3][1] = d0; v[3][2] = d1; | 
|  | 1819 | 
|  | 1820   xx[0] = r; xx[1] = th; | 
|  | 1821   ll[0] = r0; ll[1] = th0; | 
|  | 1822   ur[0] = r1; ur[1] = th1; | 
|  | 1823   return(rectcell_interp(xx,v,ll,ur,2,nc)); | 
|  | 1824 } | 
|  | 1825 /* | 
|  | 1826  * Copyright 1996-2006 Catherine Loader. | 
|  | 1827  */ | 
|  | 1828 #include "lfev.h" | 
|  | 1829 | 
|  | 1830 void solve(A,b,d) /* this is crude! A organized by column. */ | 
|  | 1831 double *A, *b; | 
|  | 1832 int d; | 
|  | 1833 { int i, j, k; | 
|  | 1834   double piv; | 
|  | 1835   for (i=0; i<d; i++) | 
|  | 1836   { piv = A[(d+1)*i]; | 
|  | 1837     for (j=i; j<d; j++) A[j*d+i] /= piv; | 
|  | 1838     b[i] /= piv; | 
|  | 1839     for (j=0; j<d; j++) if (j != i) | 
|  | 1840     { piv = A[i*d+j]; | 
|  | 1841       A[i*d+j] = 0; | 
|  | 1842       for (k=i+1; k<d; k++) | 
|  | 1843         A[k*d+j] -= piv*A[k*d+i]; | 
|  | 1844       b[j] -= piv*b[i]; | 
|  | 1845     } | 
|  | 1846   } | 
|  | 1847 } | 
|  | 1848 | 
|  | 1849 void triang_guessnv(nvm,ncm,vc,d,mk) | 
|  | 1850 int *nvm, *ncm, *vc, d, mk; | 
|  | 1851 { *nvm = *ncm = mk*d; | 
|  | 1852   *vc = d+1; | 
|  | 1853   return; | 
|  | 1854 } | 
|  | 1855 | 
|  | 1856 int triang_split(lf,ce,le) | 
|  | 1857 lfit *lf; | 
|  | 1858 double *le; | 
|  | 1859 int *ce; | 
|  | 1860 { int d, i, j, k, nts, vc; | 
|  | 1861   double di, dfx[MXDIM]; | 
|  | 1862   nts = 0; d = lf->fp.d; vc = d+1; | 
|  | 1863   for (i=0; i<d; i++) | 
|  | 1864     for (j=i+1; j<=d; j++) | 
|  | 1865     { for (k=0; k<d; k++) | 
|  | 1866         dfx[k] = evptx(&lf->fp,ce[i],k)-evptx(&lf->fp,ce[j],k); | 
|  | 1867       di = rho(dfx,lf->lfd.sca,d,KSPH,NULL); | 
|  | 1868       le[i*vc+j] = le[j*vc+i] = di/MIN(lf->fp.h[ce[i]],lf->fp.h[ce[j]]); | 
|  | 1869       nts = nts || le[i*vc+j]>cut(&lf->evs); | 
|  | 1870     } | 
|  | 1871   return(nts); | 
|  | 1872 } | 
|  | 1873 | 
|  | 1874 void resort(pv,xev,dig) | 
|  | 1875 double *xev; | 
|  | 1876 int *pv, *dig; | 
|  | 1877 { double d0, d1, d2; | 
|  | 1878   int i; | 
|  | 1879   d0 = d1 = d2 = 0; | 
|  | 1880   for (i=0; i<3; i++) | 
|  | 1881   { d0 += (xev[3*pv[11]+i]-xev[3*pv[1]+i])*(xev[3*pv[11]+i]-xev[3*pv[1]+i]); | 
|  | 1882     d1 += (xev[3*pv[ 7]+i]-xev[3*pv[2]+i])*(xev[3*pv[ 7]+i]-xev[3*pv[2]+i]); | 
|  | 1883     d2 += (xev[3*pv[ 6]+i]-xev[3*pv[3]+i])*(xev[3*pv[ 6]+i]-xev[3*pv[3]+i]); | 
|  | 1884   } | 
|  | 1885   if ((d0<=d1) & (d0<=d2)) | 
|  | 1886   { dig[0] = pv[1]; dig[1] = pv[11]; | 
|  | 1887     dig[2] = pv[2]; dig[3] = pv[7]; | 
|  | 1888     dig[4] = pv[3]; dig[5] = pv[6]; | 
|  | 1889   } | 
|  | 1890   else if (d1<=d2) | 
|  | 1891   { dig[0] = pv[2]; dig[1] = pv[7]; | 
|  | 1892     dig[2] = pv[1]; dig[3] = pv[11]; | 
|  | 1893     dig[4] = pv[3]; dig[5] = pv[6]; | 
|  | 1894   } | 
|  | 1895   else | 
|  | 1896   { dig[0] = pv[3]; dig[1] = pv[6]; | 
|  | 1897     dig[2] = pv[2]; dig[3] = pv[7]; | 
|  | 1898     dig[4] = pv[1]; dig[5] = pv[11]; | 
|  | 1899   } | 
|  | 1900 } | 
|  | 1901 | 
|  | 1902 void triang_grow(des,lf,ce,ct,term) | 
|  | 1903 design *des; | 
|  | 1904 lfit *lf; | 
|  | 1905 int *ce, *ct, *term; | 
|  | 1906 { double le[(1+MXDIM)*(1+MXDIM)], ml; | 
|  | 1907   int d, i, j, im, jm, vc, pv[(1+MXDIM)*(1+MXDIM)], dig[6]; | 
|  | 1908   int nce[1+MXDIM]; | 
|  | 1909   if (lf_error) return; | 
|  | 1910   d = lf->fp.d; vc = d+1; | 
|  | 1911   if (!triang_split(lf,ce,le)) | 
|  | 1912   { if (ct != NULL) | 
|  | 1913     { for (i=0; i<vc; i++) term[*ct*vc+i] = ce[i]; | 
|  | 1914       (*ct)++; | 
|  | 1915     } | 
|  | 1916     return; | 
|  | 1917   } | 
|  | 1918   if (d>3) | 
|  | 1919   { ml = 0; | 
|  | 1920     for (i=0; i<d; i++) | 
|  | 1921       for (j=i+1; j<vc; j++) | 
|  | 1922         if (le[i*vc+j]>ml) { ml = le[i*vc+j]; im = i; jm = j; } | 
|  | 1923     pv[0] = newsplit(des,lf,(int)ce[im],(int)ce[jm],0); | 
|  | 1924     for (i=0; i<vc; i++) nce[i] = ce[i]; | 
|  | 1925     nce[im] = pv[0]; triang_grow(des,lf,nce,ct,term); nce[im] = ce[im]; | 
|  | 1926     nce[jm] = pv[0]; triang_grow(des,lf,nce,ct,term); | 
|  | 1927     return; | 
|  | 1928   } | 
|  | 1929 | 
|  | 1930   for (i=0; i<d; i++) | 
|  | 1931     for (j=i+1; j<=d; j++) | 
|  | 1932       pv[i*vc+j] = pv[j*vc+i] | 
|  | 1933         = newsplit(des,lf,(int)ce[i],(int)ce[j],le[i*vc+j]<=cut(&lf->evs)); | 
|  | 1934   for (i=0; i<=d; i++) /* corners */ | 
|  | 1935   { for (j=0; j<=d; j++) nce[j] = (j==i) ? ce[i] : pv[i*vc+j]; | 
|  | 1936     triang_grow(des,lf,nce,ct,term); | 
|  | 1937   } | 
|  | 1938 | 
|  | 1939   if (d==2) /* center for d=2 */ | 
|  | 1940   { nce[0] = pv[5]; nce[1] = pv[2]; nce[2] = pv[1]; | 
|  | 1941     triang_grow(des,lf,nce,ct,term); | 
|  | 1942   } | 
|  | 1943   if (d==3) /* center for d=3 */ | 
|  | 1944   { resort(pv,evp(&lf->fp),dig); | 
|  | 1945     nce[0] = dig[0]; nce[1] = dig[1]; | 
|  | 1946     nce[2] = dig[2]; nce[3] = dig[4]; triang_grow(des,lf,nce,ct,term); | 
|  | 1947     nce[2] = dig[5]; nce[3] = dig[3]; triang_grow(des,lf,nce,ct,term); | 
|  | 1948     nce[2] = dig[2]; nce[3] = dig[5]; triang_grow(des,lf,nce,ct,term); | 
|  | 1949     nce[2] = dig[4]; nce[3] = dig[3]; triang_grow(des,lf,nce,ct,term); | 
|  | 1950   } | 
|  | 1951 } | 
|  | 1952 | 
|  | 1953 void triang_descend(tr,xa,ce) | 
|  | 1954 lfit *tr; | 
|  | 1955 double *xa; | 
|  | 1956 int *ce; | 
|  | 1957 { double le[(1+MXDIM)*(1+MXDIM)], ml; | 
|  | 1958   int d, vc, i, j, im, jm, pv[(1+MXDIM)*(1+MXDIM)]; | 
|  | 1959   design *des; | 
|  | 1960   des = NULL; | 
|  | 1961   if (!triang_split(tr,ce,le)) return; | 
|  | 1962   d = tr->fp.d; vc = d+1; | 
|  | 1963 | 
|  | 1964   if (d>3) /* split longest edge */ | 
|  | 1965   { ml = 0; | 
|  | 1966     for (i=0; i<d; i++) | 
|  | 1967       for (j=i+1; j<vc; j++) | 
|  | 1968         if (le[i*vc+j]>ml) { ml = le[i*vc+j]; im = i; jm = j; } | 
|  | 1969     pv[0] = newsplit(des,tr,(int)ce[im],(int)ce[jm],0); | 
|  | 1970     if (xa[im]>xa[jm]) | 
|  | 1971     { xa[im] -= xa[jm]; xa[jm] *= 2; ce[jm] = pv[0]; } | 
|  | 1972     else | 
|  | 1973     { xa[jm] -= xa[im]; xa[im] *= 2; ce[im] = pv[0]; } | 
|  | 1974     triang_descend(tr,xa,ce); | 
|  | 1975     return; | 
|  | 1976   } | 
|  | 1977 | 
|  | 1978   for (i=0; i<d; i++) | 
|  | 1979     for (j=i+1; j<=d; j++) | 
|  | 1980       pv[i*vc+j] = pv[j*vc+i] | 
|  | 1981         = newsplit(des,tr,(int)ce[i],(int)ce[j],le[i*d+j]<=cut(&tr->evs)); | 
|  | 1982   for (i=0; i<=d; i++) if (xa[i]>=0.5) /* in corner */ | 
|  | 1983   { for (j=0; j<=d; j++) | 
|  | 1984     { if (i!=j) ce[j] = pv[i*vc+j]; | 
|  | 1985       xa[j] = 2*xa[j]; | 
|  | 1986     } | 
|  | 1987     xa[i] -= 1; | 
|  | 1988     triang_descend(tr,xa,ce); | 
|  | 1989     return; | 
|  | 1990   } | 
|  | 1991   if (d==1) { LERR(("weights sum to < 1")); } | 
|  | 1992   if (d==2) /* center */ | 
|  | 1993   { ce[0] = pv[5]; xa[0] = 1-2*xa[0]; | 
|  | 1994     ce[1] = pv[2]; xa[1] = 1-2*xa[1]; | 
|  | 1995     ce[2] = pv[1]; xa[2] = 1-2*xa[2]; | 
|  | 1996     triang_descend(tr,xa,ce); | 
|  | 1997   } | 
|  | 1998   if (d==3) /* center */ | 
|  | 1999   { double z; int dig[6]; | 
|  | 2000     resort(pv,evp(&tr->fp),dig); | 
|  | 2001     ce[0] = dig[0]; ce[1] = dig[1]; | 
|  | 2002     xa[0] *= 2; xa[1] *= 2; xa[2] *= 2; xa[3] *= 2; | 
|  | 2003     if (xa[0]+xa[2]>=1) | 
|  | 2004     { if (xa[0]+xa[3]>=1) | 
|  | 2005       { ce[2] = dig[2]; ce[3] = dig[4]; | 
|  | 2006         z = xa[0]; | 
|  | 2007         xa[3] += z-1; xa[2] += z-1; xa[0] = xa[1]; xa[1] = 1-z; | 
|  | 2008       } | 
|  | 2009       else | 
|  | 2010       { ce[2] = dig[2]; ce[3] = dig[5]; | 
|  | 2011         z = xa[3]; xa[3] = xa[1]+xa[2]-1; xa[1] = z; | 
|  | 2012         z = xa[2]; xa[2] += xa[0]-1; xa[0] = 1-z; | 
|  | 2013     } } | 
|  | 2014     else | 
|  | 2015     { if (xa[1]+xa[2]>=1) | 
|  | 2016       { ce[2] = dig[5]; ce[3] = dig[3]; | 
|  | 2017         xa[1] = 1-xa[1]; xa[2] -= xa[1]; xa[3] -= xa[1]; | 
|  | 2018       } | 
|  | 2019       else | 
|  | 2020       { ce[2] = dig[4]; ce[3] = dig[3]; | 
|  | 2021         z = xa[3]; xa[3] += xa[1]-1; xa[1] = xa[2]; | 
|  | 2022         xa[2] = z+xa[0]-1; xa[0] = 1-z; | 
|  | 2023     } } | 
|  | 2024     triang_descend(tr,xa,ce); | 
|  | 2025 } } | 
|  | 2026 | 
|  | 2027 void covrofdata(lfd,V,mn) /* covar of data; mean in mn */ | 
|  | 2028 lfdata *lfd; | 
|  | 2029 double *V, *mn; | 
|  | 2030 { int d, i, j, k; | 
|  | 2031   double s; | 
|  | 2032   s = 0; d = lfd->d; | 
|  | 2033   for (i=0; i<d*d; i++) V[i] = 0; | 
|  | 2034   for (i=0; i<lfd->n; i++) | 
|  | 2035   { s += prwt(lfd,i); | 
|  | 2036     for (j=0; j<d; j++) | 
|  | 2037       for (k=0; k<d; k++) | 
|  | 2038         V[j*d+k] += prwt(lfd,i)*(datum(lfd,j,i)-mn[j])*(datum(lfd,k,i)-mn[k]); | 
|  | 2039   } | 
|  | 2040   for (i=0; i<d*d; i++) V[i] /= s; | 
|  | 2041 } | 
|  | 2042 | 
|  | 2043 int intri(x,w,xev,xa,d) /* is x in triangle bounded by xd[0..d-1]? */ | 
|  | 2044 double *x, *xev, *xa; | 
|  | 2045 int *w, d; | 
|  | 2046 { int i, j; | 
|  | 2047   double eps, *r, xd[MXDIM*MXDIM]; | 
|  | 2048   eps = 1.0e-10; | 
|  | 2049   r = &xev[w[d]*d]; | 
|  | 2050   for (i=0; i<d; i++) | 
|  | 2051   { xa[i] = x[i]-r[i]; | 
|  | 2052     for (j=0; j<d; j++) xd[i*d+j] = xev[w[i]*d+j]-r[j]; | 
|  | 2053   } | 
|  | 2054   solve(xd,xa,d); | 
|  | 2055   xa[d] = 1.0; | 
|  | 2056   for (i=0; i<d; i++) xa[d] -= xa[i]; | 
|  | 2057   for (i=0; i<=d; i++) if ((xa[i]<-eps) | (xa[i]>1+eps)) return(0); | 
|  | 2058   return(1); | 
|  | 2059 } | 
|  | 2060 | 
|  | 2061 void triang_start(des,lf) /* Triangulation with polyhedral start */ | 
|  | 2062 design *des; | 
|  | 2063 lfit *lf; | 
|  | 2064 { | 
|  | 2065   int i, j, k, n, d, nc, nvm, ncm, vc; | 
|  | 2066   int *ce, ed[1+MXDIM]; | 
|  | 2067   double V[MXDIM*MXDIM], P[MXDIM*MXDIM], sigma, z[MXDIM], xa[1+MXDIM], *xev; | 
|  | 2068   xev = evp(&lf->fp); | 
|  | 2069   d = lf->lfd.d; n = lf->lfd.n; | 
|  | 2070   lf->fp.nv = nc = 0; | 
|  | 2071 | 
|  | 2072   triang_guessnv(&nvm,&ncm,&vc,d,mk(&lf->evs)); | 
|  | 2073   trchck(lf,nvm,ncm,vc); | 
|  | 2074 | 
|  | 2075   ce = lf->evs.ce; | 
|  | 2076   for (j=0; j<d; j++) xev[j] = lf->pc.xbar[j]; | 
|  | 2077   lf->fp.nv = 1; | 
|  | 2078   covrofdata(&lf->lfd,V,xev); /* fix this with scaling */ | 
|  | 2079   eig_dec(V,P,d); | 
|  | 2080 | 
|  | 2081   for (i=0; i<d; i++) /* add vertices +- 2sigma*eigenvect */ | 
|  | 2082   { sigma = sqrt(V[i*(d+1)]); | 
|  | 2083     for (j=0; j<d; j++) | 
|  | 2084       xev[lf->fp.nv*d+j] = xev[j]-2*sigma*P[j*d+i]; | 
|  | 2085     lf->fp.nv++; | 
|  | 2086     for (j=0; j<d; j++) | 
|  | 2087       xev[lf->fp.nv*d+j] = xev[j]+2*sigma*P[j*d+i]; | 
|  | 2088     lf->fp.nv++; | 
|  | 2089   } | 
|  | 2090 | 
|  | 2091   for (i=0; i<n; i++) /* is point i inside? */ | 
|  | 2092   { ed[0] = 0; | 
|  | 2093     for (j=0; j<d; j++) | 
|  | 2094     { z[j] = 0; | 
|  | 2095       for (k=0; k<d; k++) z[j] += P[k*d+j]*(datum(&lf->lfd,k,i)-xev[k]); | 
|  | 2096       ed[j+1] = 2*j+1+(z[j]>0); | 
|  | 2097       for (k=0; k<d; k++) z[j] = datum(&lf->lfd,j,i); | 
|  | 2098     } | 
|  | 2099     k = intri(z,ed,xev,xa,d); | 
|  | 2100     if (xa[0]<0) | 
|  | 2101     { for (j=1; j<=d; j++) | 
|  | 2102         for (k=0; k<d; k++) | 
|  | 2103           xev[ed[j]*d+k] = xa[0]*xev[k]+(1-xa[0])*xev[ed[j]*d+k]; | 
|  | 2104     } | 
|  | 2105   } | 
|  | 2106 | 
|  | 2107   nc = 1<<d; /* create initial cells */ | 
|  | 2108   for (i=0; i<nc; i++) | 
|  | 2109   { ce[i*vc] = 0; k = i; | 
|  | 2110     for (j=0; j<d; j++) | 
|  | 2111     { ce[i*vc+j+1] = 2*j+(k%2)+1; | 
|  | 2112       k>>=1; | 
|  | 2113     } | 
|  | 2114   } | 
|  | 2115 | 
|  | 2116   for (i=0; i<lf->fp.nv; i++) | 
|  | 2117   { PROC_VERTEX(des,lf,i); | 
|  | 2118     if (lf_error) return; | 
|  | 2119     lf->evs.s[i] = 0; | 
|  | 2120   } | 
|  | 2121   for (i=0; i<nc; i++) | 
|  | 2122     triang_grow(des,lf,&ce[i*vc],NULL,NULL); | 
|  | 2123   lf->evs.nce = nc; | 
|  | 2124 } | 
|  | 2125 | 
|  | 2126 double triang_cubicint(v,vv,w,d,nc,xxa) | 
|  | 2127 double *v, *vv, *xxa; | 
|  | 2128 int *w, d, nc; | 
|  | 2129 { double sa, lb, *vert0, *vert1, *vals0, *vals1, deriv0, deriv1; | 
|  | 2130   int i, j, k; | 
|  | 2131   if (nc==1) /* linear interpolate */ | 
|  | 2132   { sa = 0; | 
|  | 2133     for (i=0; i<=d; i++) sa += xxa[i]*vv[i]; | 
|  | 2134     return(sa); | 
|  | 2135   } | 
|  | 2136   sa = 1.0; | 
|  | 2137   for (j=d; j>0; j--)  /* eliminate v[w[j]] */ | 
|  | 2138   { lb = xxa[j]/sa; | 
|  | 2139     for (k=0; k<j; k++) /* Interpolate edge v[w[k]],v[w[j]] */ | 
|  | 2140     { vert0 = &v[w[k]*d]; | 
|  | 2141       vert1 = &v[w[j]*d]; | 
|  | 2142       vals0 = &vv[k*nc]; | 
|  | 2143       vals1 = &vv[j*nc]; | 
|  | 2144       deriv0 = deriv1 = 0; | 
|  | 2145       for (i=0; i<d; i++) | 
|  | 2146       { deriv0 += (vert1[i]-vert0[i])*vals0[i+1]; | 
|  | 2147         deriv1 += (vert1[i]-vert0[i])*vals1[i+1]; | 
|  | 2148       } | 
|  | 2149       vals0[0] = cubic_interp(lb,vals0[0],vals1[0],deriv0,deriv1); | 
|  | 2150       for (i=1; i<=d; i++) | 
|  | 2151         vals0[i] = (1-lb)*((1-lb)*vals0[i]+lb*vals1[i]); | 
|  | 2152     } | 
|  | 2153     sa -= xxa[j]; | 
|  | 2154     if (sa<=0) j = 0; | 
|  | 2155   } | 
|  | 2156   return(vals0[0]); | 
|  | 2157 } | 
|  | 2158 | 
|  | 2159 double triang_clotoch(xev,vv,ce,p,xxa) | 
|  | 2160 double *xev, *vv, *xxa; | 
|  | 2161 int *ce, p; | 
|  | 2162 { double cfo[3], cfe[3], cg[9], *va, *vb, *vc, | 
|  | 2163     l0, nm[3], na, nb, nc, *xl, *xr, *xz, d0, d1, lb, dlt, gam; | 
|  | 2164   int i, w[3], cfl, cfr; | 
|  | 2165   if (p==1) | 
|  | 2166     return(xxa[0]*vv[0]+xxa[1]*vv[1]+xxa[2]*vv[2]); | 
|  | 2167   if (xxa[2]<=MIN(xxa[0],xxa[1])) | 
|  | 2168   { va = &xev[2*ce[0]]; vb = &xev[2*ce[1]]; vc = &xev[2*ce[2]]; | 
|  | 2169     w[0] = 0; w[1] = 3; w[2] = 6; | 
|  | 2170   } | 
|  | 2171   else | 
|  | 2172   if (xxa[1]<xxa[0]) | 
|  | 2173   { w[0] = 0; w[1] = 6; w[2] = 3; | 
|  | 2174     va = &xev[2*ce[0]]; vb = &xev[2*ce[2]]; vc = &xev[2*ce[1]]; | 
|  | 2175     lb = xxa[1]; xxa[1] = xxa[2]; xxa[2] = lb; | 
|  | 2176   } | 
|  | 2177   else | 
|  | 2178   { w[0] = 6; w[1] = 3; w[2] = 0; | 
|  | 2179     va = &xev[2*ce[2]]; vb = &xev[2*ce[1]]; vc = &xev[2*ce[0]]; | 
|  | 2180     lb = xxa[0]; xxa[0] = xxa[2]; xxa[2] = lb; | 
|  | 2181   } | 
|  | 2182 | 
|  | 2183 /* set cg to values and derivatives on standard triangle */ | 
|  | 2184   for (i=0; i<3; i++) | 
|  | 2185   { cg[3*i] = vv[w[i]]; | 
|  | 2186     cg[3*i+1] = ((vb[0]-va[0])*vv[w[i]+1] | 
|  | 2187                 +(vb[1]-va[1])*vv[w[i]+2])/2;  /* df/dx */ | 
|  | 2188     cg[3*i+2] = ((2*vc[0]-vb[0]-va[0])*vv[w[i]+1] | 
|  | 2189                 +(2*vc[1]-vb[1]-va[1])*vv[w[i]+2])/2.0; /* sqrt{3} df/dy */ | 
|  | 2190   } | 
|  | 2191   dlt = (vb[0]-va[0])*(vc[1]-va[1])-(vc[0]-va[0])*(vb[1]-va[1]); | 
|  | 2192   /* Twice area; +ve if abc antic.wise  -ve is abc c.wise */ | 
|  | 2193   cfo[0] = (cg[0]+cg[3]+cg[6])/3; | 
|  | 2194   cfo[1] = (2*cg[0]-cg[3]-cg[6])/4; | 
|  | 2195   cfo[2] = (2*cg[3]-cg[0]-cg[6])/4; | 
|  | 2196   na = -cg[1]+cg[2];  /* perp. deriv, rel. length 2 */ | 
|  | 2197   nb = -cg[4]-cg[5]; | 
|  | 2198   nc = 2*cg[7]; | 
|  | 2199   cfo[1] += (nb-nc)/16; | 
|  | 2200   cfo[2] += (nc-na)/16; | 
|  | 2201   na = -cg[1]-cg[2]/3.0;  /* derivatives back to origin */ | 
|  | 2202   nb =  cg[4]-cg[5]/3.0; | 
|  | 2203   nc =        cg[8]/1.5; | 
|  | 2204   cfo[0] -= (na+nb+nc)*7/54; | 
|  | 2205   cfo[1] += 13*(nb+nc-2*na)/144; | 
|  | 2206   cfo[2] += 13*(na+nc-2*nb)/144; | 
|  | 2207   for (i=0; i<3; i++) | 
|  | 2208   { /* Outward normals by linear interpolation on original triangle. | 
|  | 2209        Convert to outward normals on standard triangle. | 
|  | 2210        Actually, computed to opposite corner */ | 
|  | 2211     switch(i) | 
|  | 2212     { case 0: xl = vc; xr = vb; xz = va; cfl = w[2]; cfr = w[1]; | 
|  | 2213               break; | 
|  | 2214       case 1: xl = va; xr = vc; xz = vb; cfl = w[0]; cfr = w[2]; | 
|  | 2215               break; | 
|  | 2216       case 2: xl = vb; xr = va; xz = vc; cfl = w[1]; cfr = w[0]; | 
|  | 2217               break; | 
|  | 2218     } | 
|  | 2219     na = xr[0]-xl[0]; nb = xr[1]-xl[1]; | 
|  | 2220     lb = na*na+nb*nb; | 
|  | 2221     d0 = 1.5*(vv[cfr]-vv[cfl]) - 0.25*(na*(vv[cfl+1]+vv[cfr+1]) | 
|  | 2222          +nb*(vv[cfl+2]+vv[cfr+2])); | 
|  | 2223     d1 = 0.5*( na*(vv[cfl+2]+vv[cfr+2])-nb*(vv[cfl+1]+vv[cfr+1]) ); | 
|  | 2224     l0 = (xz[0]-xl[0])*na+(xz[1]-xl[1])*nb-lb/2; | 
|  | 2225     nm[i] = (d1*dlt-l0*d0)/lb; | 
|  | 2226   } | 
|  | 2227   cfo[0] -= (nm[0]+nm[1]+nm[2])*4/81; | 
|  | 2228   cfo[1] += (2*nm[0]-nm[1]-nm[2])/27; | 
|  | 2229   cfo[2] += (2*nm[1]-nm[0]-nm[2])/27; | 
|  | 2230 | 
|  | 2231   gam = xxa[0]+xxa[1]-2*xxa[2]; | 
|  | 2232   if (gam==0) return(cfo[0]); | 
|  | 2233   lb = (xxa[0]-xxa[2])/gam; | 
|  | 2234   d0 = -2*cg[4]; d1 = -2*cg[1]; | 
|  | 2235   cfe[0] = cubic_interp(lb,cg[3],cg[0],d0,d1); | 
|  | 2236   cfe[1] = cubintd(lb,cg[3],cg[0],d0,d1); | 
|  | 2237   cfe[2] = -(1-lb)*(1-2*lb)*cg[5] + 4*lb*(1-lb)*nm[2] - lb*(2*lb-1)*cg[2]; | 
|  | 2238   d0 = 2*(lb*cfo[1]+(1-lb)*cfo[2]); | 
|  | 2239   d1 = (lb-0.5)*cfe[1]+cfe[2]/3.0; | 
|  | 2240   return(cubic_interp(gam,cfo[0],cfe[0],d0,d1)); | 
|  | 2241 } | 
|  | 2242 | 
|  | 2243 int triang_getvertexvals(fp,evs,vv,i,what) | 
|  | 2244 fitpt *fp; | 
|  | 2245 evstruc *evs; | 
|  | 2246 double *vv; | 
|  | 2247 int i, what; | 
|  | 2248 { double dx, P, le, vl[1+MXDIM], vh[1+MXDIM]; | 
|  | 2249   int d, il, ih, j, nc; | 
|  | 2250   d = fp->d; | 
|  | 2251   if (evs->s[i]==0) return(exvval(fp,vv,i,d,what,0)); | 
|  | 2252 | 
|  | 2253   il = evs->lo[i]; nc = triang_getvertexvals(fp,evs,vl,il,what); | 
|  | 2254   ih = evs->hi[i]; nc = triang_getvertexvals(fp,evs,vh,ih,what); | 
|  | 2255   vv[0] = (vl[0]+vh[0])/2; | 
|  | 2256   if (nc==1) return(nc); | 
|  | 2257   P = 1.5*(vh[0]-vl[0]); | 
|  | 2258   le = 0.0; | 
|  | 2259   for (j=0; j<d; j++) | 
|  | 2260   { dx = evptx(fp,ih,j)-evptx(fp,il,j); | 
|  | 2261     vv[0] += dx*(vl[j+1]-vh[j+1])/8; | 
|  | 2262     vv[j+1] = (vl[j+1]+vh[j+1])/2; | 
|  | 2263     P -= 1.5*dx*vv[j+1]; | 
|  | 2264     le += dx*dx; | 
|  | 2265   } | 
|  | 2266   for (j=0; j<d; j++) | 
|  | 2267     vv[j+1] += P*(evptx(fp,ih,j)-evptx(fp,il,j))/le; | 
|  | 2268   return(nc); | 
|  | 2269 } | 
|  | 2270 | 
|  | 2271 double triang_int(lf,x,what) | 
|  | 2272 lfit *lf; | 
|  | 2273 double *x; | 
|  | 2274 int what; | 
|  | 2275 { | 
|  | 2276   int d, i, j, k, vc, nc; | 
|  | 2277   int *ce, nce[1+MXDIM]; | 
|  | 2278   double xa[1+MXDIM], vv[(1+MXDIM)*(1+MXDIM)], lb; | 
|  | 2279 fitpt *fp; | 
|  | 2280 evstruc *evs; | 
|  | 2281 fp = &lf->fp; | 
|  | 2282 evs= &lf->evs; | 
|  | 2283 | 
|  | 2284   d = fp->d; vc = d+1; | 
|  | 2285   ce = evs->ce; | 
|  | 2286   i = 0; | 
|  | 2287   while ((i<evs->nce) && (!intri(x,&ce[i*vc],evp(fp),xa,d))) i++; | 
|  | 2288   if (i==evs->nce) return(NOSLN); | 
|  | 2289   i *= vc; | 
|  | 2290   for (j=0; j<vc; j++) nce[j] = ce[i+j]; | 
|  | 2291   triang_descend(lf,xa,nce); | 
|  | 2292 | 
|  | 2293   /* order the vertices -- needed for asymmetric interptr */ | 
|  | 2294   do | 
|  | 2295   { k=0; | 
|  | 2296     for (i=0; i<d; i++) | 
|  | 2297       if (nce[i]>nce[i+1]) | 
|  | 2298       { j=nce[i]; nce[i]=nce[i+1]; nce[i+1]=j; k=1; | 
|  | 2299         lb = xa[i]; xa[i] = xa[i+1]; xa[i+1] = lb; | 
|  | 2300       } | 
|  | 2301   } while(k); | 
|  | 2302   nc = 0; | 
|  | 2303   for (i=0; i<vc; i++) | 
|  | 2304     nc =  triang_getvertexvals(fp,evs,&vv[i*nc],nce[i],what); | 
|  | 2305   return((d==2) ? triang_clotoch(evp(fp),vv,nce,nc,xa) : | 
|  | 2306                  triang_cubicint(evp(fp),vv,nce,d,nc,xa)); | 
|  | 2307 } | 
|  | 2308 /* | 
|  | 2309  * Copyright 1996-2006 Catherine Loader. | 
|  | 2310  */ | 
|  | 2311 /* | 
|  | 2312  * Functions for computing residuals and fitted values from | 
|  | 2313  * the locfit object. | 
|  | 2314  * | 
|  | 2315  * fitted(lf,fit,what,cv,ty) computes fitted values from the | 
|  | 2316  *   fit structure in lf. | 
|  | 2317  * resid(y,c,w,th,mi,ty) converts fitted values to residuals | 
|  | 2318 */ | 
|  | 2319 | 
|  | 2320 #include "lfev.h" | 
|  | 2321 | 
|  | 2322 #define NRT 8 | 
|  | 2323 static char *rtype[NRT] = { "deviance", "d2",    "pearson", "raw", | 
|  | 2324                           "ldot",     "lddot", "fit",     "mean" }; | 
|  | 2325 static int   rvals[NRT] = { RDEV, RDEV2, RPEAR, RRAW, RLDOT, RLDDT, RFIT, RMEAN}; | 
|  | 2326 int restyp(z) | 
|  | 2327 char *z; | 
|  | 2328 { int val; | 
|  | 2329 | 
|  | 2330   val = pmatch(z, rtype, rvals, NRT, -1); | 
|  | 2331   if (val==-1) LERR(("Unknown type = %s",z)); | 
|  | 2332   return(val); | 
|  | 2333 } | 
|  | 2334 | 
|  | 2335 double resid(y,w,th,fam,ty,res) | 
|  | 2336 int fam, ty; | 
|  | 2337 double y, w, th, *res; | 
|  | 2338 { double raw; | 
|  | 2339 | 
|  | 2340   fam = fam & 63; | 
|  | 2341   if ((fam==TGAUS) | (fam==TROBT) | (fam==TCAUC)) | 
|  | 2342     raw = y-res[ZMEAN]; | 
|  | 2343   else | 
|  | 2344     raw = y-w*res[ZMEAN]; | 
|  | 2345   switch(ty) | 
|  | 2346   { case RDEV: | 
|  | 2347       if (res[ZDLL]>0) return(sqrt(-2*res[ZLIK])); | 
|  | 2348             else return(-sqrt(-2*res[ZLIK])); | 
|  | 2349     case RPEAR: | 
|  | 2350       if (res[ZDDLL]<=0) | 
|  | 2351       { if (res[ZDLL]==0) return(0); | 
|  | 2352         return(NOSLN); | 
|  | 2353       } | 
|  | 2354       return(res[ZDLL]/sqrt(res[ZDDLL])); | 
|  | 2355     case RRAW:  return(raw); | 
|  | 2356     case RLDOT: return(res[ZDLL]); | 
|  | 2357     case RDEV2: return(-2*res[ZLIK]); | 
|  | 2358     case RLDDT: return(res[ZDDLL]); | 
|  | 2359     case RFIT:  return(th); | 
|  | 2360     case RMEAN: return(res[ZMEAN]); | 
|  | 2361     default: LERR(("resid: unknown residual type %d",ty)); | 
|  | 2362   } | 
|  | 2363   return(0.0); | 
|  | 2364 } | 
|  | 2365 | 
|  | 2366 double studentize(res,inl,var,ty,link) | 
|  | 2367 double res, inl, var, *link; | 
|  | 2368 int ty; | 
|  | 2369 { double den; | 
|  | 2370   inl *= link[ZDDLL]; | 
|  | 2371   var = var*var*link[ZDDLL]; | 
|  | 2372   if (inl>1) inl = 1; | 
|  | 2373   if (var>inl) var = inl; | 
|  | 2374   den = 1-2*inl+var; | 
|  | 2375   if (den<0) return(0.0); | 
|  | 2376   switch(ty) | 
|  | 2377   { case RDEV: | 
|  | 2378     case RPEAR: | 
|  | 2379     case RRAW: | 
|  | 2380     case RLDOT: | 
|  | 2381       return(res/sqrt(den)); | 
|  | 2382     case RDEV2: | 
|  | 2383       return(res/den); | 
|  | 2384     default: return(res); | 
|  | 2385   } | 
|  | 2386 } | 
|  | 2387 | 
|  | 2388 void fitted(lf,fit,what,cv,st,ty) | 
|  | 2389 lfit *lf; | 
|  | 2390 double *fit; | 
|  | 2391 int what, cv, st, ty; | 
|  | 2392 { int i, j, d, n, evo; | 
|  | 2393   double xx[MXDIM], th, inl, var, link[LLEN]; | 
|  | 2394   n = lf->lfd.n; | 
|  | 2395   d = lf->lfd.d; | 
|  | 2396   evo = ev(&lf->evs); | 
|  | 2397   cv &= (evo!=ECROS); | 
|  | 2398   if ((evo==EDATA)|(evo==ECROS)) evo = EFITP; | 
|  | 2399   setfamily(&lf->sp); | 
|  | 2400 | 
|  | 2401   for (i=0; i<n; i++) | 
|  | 2402   { for (j=0; j<d; j++) xx[j] = datum(&lf->lfd,j,i); | 
|  | 2403     th = dointpoint(lf,xx,what,evo,i); | 
|  | 2404     if ((what==PT0)|(what==PVARI)) th = th*th; | 
|  | 2405     if (what==PCOEF) | 
|  | 2406     { | 
|  | 2407       th += base(&lf->lfd,i); | 
|  | 2408       stdlinks(link,&lf->lfd,&lf->sp,i,th,rsc(&lf->fp)); | 
|  | 2409       if ((cv)|(st)) | 
|  | 2410       { inl = dointpoint(lf,xx,PT0,evo,i); | 
|  | 2411         inl = inl*inl; | 
|  | 2412         if (cv) | 
|  | 2413         { th -= inl*link[ZDLL]; | 
|  | 2414           stdlinks(link,&lf->lfd,&lf->sp,i,th,rsc(&lf->fp)); | 
|  | 2415         } | 
|  | 2416         if (st) var = dointpoint(lf,xx,PNLX,evo,i); | 
|  | 2417       } | 
|  | 2418       fit[i] = resid(resp(&lf->lfd,i),prwt(&lf->lfd,i),th,fam(&lf->sp),ty,link); | 
|  | 2419       if (st) fit[i] = studentize(fit[i],inl,var,ty,link); | 
|  | 2420     } else fit[i] = th; | 
|  | 2421     if (lf_error) return; | 
|  | 2422   } | 
|  | 2423 } | 
|  | 2424 /* | 
|  | 2425  * Copyright 1996-2006 Catherine Loader. | 
|  | 2426  */ | 
|  | 2427 #include "lfev.h" | 
|  | 2428 | 
|  | 2429 extern double robscale; | 
|  | 2430 | 
|  | 2431 /* special version of ressumm to estimate sigma^2, with derivative estimation */ | 
|  | 2432 void ressummd(lf) | 
|  | 2433 lfit *lf; | 
|  | 2434 { int i; | 
|  | 2435   double s0, s1; | 
|  | 2436   s0 = s1 = 0.0; | 
|  | 2437   if ((fam(&lf->sp)&64)==0) | 
|  | 2438   { rv(&lf->fp) = 1.0; | 
|  | 2439     return; | 
|  | 2440   } | 
|  | 2441   for (i=0; i<lf->fp.nv; i++) | 
|  | 2442   { s0 += lf->fp.lik[2*lf->fp.nvm+i]; | 
|  | 2443     s1 += lf->fp.lik[i]; | 
|  | 2444   } | 
|  | 2445   if (s0==0.0) | 
|  | 2446     rv(&lf->fp) = 0.0; | 
|  | 2447   else | 
|  | 2448     rv(&lf->fp) = -2*s1/s0; | 
|  | 2449 } | 
|  | 2450 | 
|  | 2451 /* | 
|  | 2452  * res[0] = log-likelihood. | 
|  | 2453  * res[1] = df0 = tr(H) | 
|  | 2454  * res[2] = df0 = tr(H'H) | 
|  | 2455  * res[3] = s^2. | 
|  | 2456  * res[5] = robustscale. | 
|  | 2457  */ | 
|  | 2458 void ressumm(lf,des,res) | 
|  | 2459 lfit *lf; | 
|  | 2460 design *des; | 
|  | 2461 double *res; | 
|  | 2462 { int i, j, evo, tg; | 
|  | 2463   double *oy, pw, r1, r2, rdf, t0, t1, u[MXDIM], link[LLEN]; | 
|  | 2464   fitpt *fp; | 
|  | 2465 | 
|  | 2466   res[0] = res[1] = res[2] = 0.0; | 
|  | 2467 | 
|  | 2468   evo = ev(&lf->evs); | 
|  | 2469   if ((evo==EKDCE) | (evo==EPRES)) | 
|  | 2470   { res[3] = 1.0; | 
|  | 2471     return; | 
|  | 2472   } | 
|  | 2473   if (lf->dv.nd>0) | 
|  | 2474   { ressummd(lf); | 
|  | 2475     return; | 
|  | 2476   } | 
|  | 2477 | 
|  | 2478   r1 = r2 = 0.0; | 
|  | 2479   if ((evo==EDATA) | (evo==ECROS)) evo = EFITP; | 
|  | 2480 | 
|  | 2481   for (i=0; i<lf->lfd.n; i++) | 
|  | 2482   { for (j=0; j<lf->lfd.d; j++) u[j] = datum(&lf->lfd,j,i); | 
|  | 2483     fitv(des,i) = base(&lf->lfd,i)+dointpoint(lf,u,PCOEF,evo,i); | 
|  | 2484     des->wd[i] = resp(&(lf->lfd),i) - fitv(des,i); | 
|  | 2485     wght(des,i) = 1.0; | 
|  | 2486     des->ind[i] = i; | 
|  | 2487   } | 
|  | 2488 | 
|  | 2489   tg = fam(&lf->sp); | 
|  | 2490   res[5] = 1.0; | 
|  | 2491   if ((tg==TROBT+64) | (tg==TCAUC+64)) /* global robust scale */ | 
|  | 2492   { oy = lf->lfd.y; lf->lfd.y = des->wd; | 
|  | 2493     des->xev = lf->pc.xbar; | 
|  | 2494     locfit(&lf->lfd,des,&lf->sp,1,0,0); | 
|  | 2495     lf->lfd.y = oy; | 
|  | 2496     res[5] = robscale; | 
|  | 2497   } | 
|  | 2498 | 
|  | 2499   for (i=0; i<lf->lfd.n; i++) | 
|  | 2500   { for (j=0; j<lf->lfd.d; j++) u[j] = datum(&lf->lfd,j,i); | 
|  | 2501     t0 = dointpoint(lf,u,PT0,evo,i); | 
|  | 2502     t1 = dointpoint(lf,u,PNLX,evo,i); | 
|  | 2503     stdlinks(link,&lf->lfd,&lf->sp,i,fitv(des,i),res[5]); | 
|  | 2504     t1 = t1*t1*link[ZDDLL]; | 
|  | 2505     t0 = t0*t0*link[ZDDLL]; | 
|  | 2506     if (t1>1) t1 = 1; | 
|  | 2507     if (t0>1) t0 = 1; /* no observation gives >1 deg.free */ | 
|  | 2508     res[0] += link[ZLIK]; | 
|  | 2509     res[1] += t0; | 
|  | 2510     res[2] += t1; | 
|  | 2511     pw = prwt(&lf->lfd,i); | 
|  | 2512     if (pw>0) | 
|  | 2513     { r1 += link[ZDLL]*link[ZDLL]/pw; | 
|  | 2514       r2 += link[ZDDLL]/pw; | 
|  | 2515     } | 
|  | 2516   } | 
|  | 2517 | 
|  | 2518   res[3] = 1.0; | 
|  | 2519   if ((fam(&lf->sp)&64)==64) /* quasi family */ | 
|  | 2520   { rdf = lf->lfd.n-2*res[1]+res[2]; | 
|  | 2521     if (rdf<1.0) | 
|  | 2522     { WARN(("Estimated rdf < 1.0; not estimating variance")); | 
|  | 2523     } | 
|  | 2524     else | 
|  | 2525       res[3] = r1/r2 * lf->lfd.n / rdf; | 
|  | 2526   } | 
|  | 2527 | 
|  | 2528   /* try to ensure consistency for family="circ"! */ | 
|  | 2529   if (((fam(&lf->sp)&63)==TCIRC) & (lf->lfd.d==1)) | 
|  | 2530   { int *ind, nv; | 
|  | 2531     double dlt, th0, th1; | 
|  | 2532     ind = des->ind; | 
|  | 2533     nv = fp->nv; | 
|  | 2534     for (i=0; i<nv; i++) ind[i] = i; | 
|  | 2535     lforder(ind,evp(fp),0,nv-1); | 
|  | 2536     for (i=1; i<nv; i++) | 
|  | 2537     { dlt = evptx(fp,ind[i],0)-evptx(fp,ind[i-1],0); | 
|  | 2538       th0 = fp->coef[ind[i]]-dlt*fp->coef[ind[i]+nv]-fp->coef[ind[i-1]]; | 
|  | 2539       th1 = fp->coef[ind[i]]-dlt*fp->coef[ind[i-1]+nv]-fp->coef[ind[i-1]]; | 
|  | 2540       if ((th0>PI)&(th1>PI)) | 
|  | 2541       { for (j=0; j<i; j++) | 
|  | 2542           fp->coef[ind[j]] += 2*PI; | 
|  | 2543         i--; | 
|  | 2544       } | 
|  | 2545       if ((th0<(-PI))&(th1<(-PI))) | 
|  | 2546       { for (j=0; j<i; j++) | 
|  | 2547           fp->coef[ind[j]] -= 2*PI; | 
|  | 2548         i--; | 
|  | 2549       } | 
|  | 2550     } | 
|  | 2551   } | 
|  | 2552 | 
|  | 2553 } | 
|  | 2554 | 
|  | 2555 double rss(lf,des,df) | 
|  | 2556 lfit *lf; | 
|  | 2557 design *des; | 
|  | 2558 double *df; | 
|  | 2559 { double ss, res[10]; | 
|  | 2560   ss = 0; | 
|  | 2561   ressumm(lf,des,res); | 
|  | 2562   *df = lf->lfd.n - 2*res[1] + res[2]; | 
|  | 2563   return(-2*res[0]); | 
|  | 2564 } | 
|  | 2565 /* | 
|  | 2566  * Copyright 1996-2006 Catherine Loader. | 
|  | 2567  */ | 
|  | 2568 /* | 
|  | 2569  * | 
|  | 2570  *   Derivative corrections. The local slopes are not the derivatives | 
|  | 2571  *   of the local likelihood estimate; the function dercor() computes | 
|  | 2572  *   the adjustment to get the correct derivatives under the assumption | 
|  | 2573  *   that h is constant. | 
|  | 2574  * | 
|  | 2575  *   By differentiating the local likelihood equations, one obtains | 
|  | 2576  * | 
|  | 2577  *     d ^      ^       T      -1   T  d    .       ^ | 
|  | 2578  *    -- a   =  a  -  (X W V X)    X  -- W  l( Y, X a) | 
|  | 2579  *    dx  0      1                    dx | 
|  | 2580  */ | 
|  | 2581 | 
|  | 2582 #include "lfev.h" | 
|  | 2583 extern double robscale; | 
|  | 2584 | 
|  | 2585 void dercor(lfd,sp,des,coef) | 
|  | 2586 lfdata *lfd; | 
|  | 2587 smpar *sp; | 
|  | 2588 design *des; | 
|  | 2589 double *coef; | 
|  | 2590 { double s1, dc[MXDIM], wd, link[LLEN]; | 
|  | 2591   int i, ii, j, m, d, p; | 
|  | 2592   if (fam(sp)<=THAZ) return; | 
|  | 2593   if (ker(sp)==WPARM) return; | 
|  | 2594 | 
|  | 2595   d = lfd->d; | 
|  | 2596   p = des->p; m = des->n; | 
|  | 2597 | 
|  | 2598   if (lf_debug>1) mut_printf("  Correcting derivatives\n"); | 
|  | 2599   fitfun(lfd, sp, des->xev,des->xev,des->f1,NULL); | 
|  | 2600   jacob_solve(&des->xtwx,des->f1); | 
|  | 2601   setzero(dc,d); | 
|  | 2602 | 
|  | 2603   /* correction term is e1^T (XTWVX)^{-1} XTW' ldot. */ | 
|  | 2604   for (i=0; i<m; i++) | 
|  | 2605   { s1 = innerprod(des->f1,d_xi(des,i),p); | 
|  | 2606     ii = des->ind[i]; | 
|  | 2607     stdlinks(link,lfd,sp,ii,fitv(des,ii),robscale); | 
|  | 2608     for (j=0; j<d; j++) | 
|  | 2609     { wd = wght(des,ii)*weightd(datum(lfd,j,ii)-des->xev[j],lfd->sca[j], | 
|  | 2610         d,ker(sp),kt(sp),des->h,lfd->sty[j],dist(des,ii)); | 
|  | 2611       dc[j] += s1*wd*link[ZDLL]; | 
|  | 2612     } | 
|  | 2613 | 
|  | 2614   } | 
|  | 2615   for (j=0; j<d; j++) coef[j+1] += dc[j]; | 
|  | 2616 } | 
|  | 2617 /* | 
|  | 2618  * Copyright 1996-2006 Catherine Loader. | 
|  | 2619  */ | 
|  | 2620 #include "lfev.h" | 
|  | 2621 | 
|  | 2622 void allocallcf(lf) | 
|  | 2623 lfit *lf; | 
|  | 2624 { lf->fp.coef = VVEC(lf,0); | 
|  | 2625   lf->fp.h    = VVEC(lf,NPAR(lf)); | 
|  | 2626 } | 
|  | 2627 | 
|  | 2628 int procvallcf(des,lf,v) | 
|  | 2629 design *des; | 
|  | 2630 lfit *lf; | 
|  | 2631 int v; | 
|  | 2632 { int i, p, lf_status; | 
|  | 2633 | 
|  | 2634   lf_status = procv_nov(des,lf,v); | 
|  | 2635   if (lf_error) return(lf_status); | 
|  | 2636 | 
|  | 2637   p = NPAR(lf); | 
|  | 2638   for (i=0; i<p; i++) VVAL(lf,v,i) = des->cf[i]; | 
|  | 2639   lf->fp.h[v] = des->h; | 
|  | 2640 | 
|  | 2641   return(0); | 
|  | 2642 } | 
|  | 2643 | 
|  | 2644 void initallcf(lf) | 
|  | 2645 lfit *lf; | 
|  | 2646 { PROCV(lf) = procvallcf; | 
|  | 2647   ALLOC(lf) = allocallcf; | 
|  | 2648   PPROC(lf) = NULL; | 
|  | 2649   KEEPV(lf) = NPAR(lf)+1; | 
|  | 2650   KEEPC(lf) = 0; | 
|  | 2651   NOPC(lf)  = 1; | 
|  | 2652 } | 
|  | 2653 /* | 
|  | 2654  * Copyright 1996-2006 Catherine Loader. | 
|  | 2655  */ | 
|  | 2656 #include "lfev.h" | 
|  | 2657 | 
|  | 2658 void pprocgam(lf,des,res) | 
|  | 2659 lfit *lf; | 
|  | 2660 design *des; | 
|  | 2661 double *res; | 
|  | 2662 { int i, j, n, evo, op; | 
|  | 2663   double *fv, *vr, df, t0, t1, u[MXDIM], link[LLEN]; | 
|  | 2664 | 
|  | 2665   n = lf->lfd.n; | 
|  | 2666   fv = res; | 
|  | 2667   vr = &res[n]; | 
|  | 2668   df = 0.0; | 
|  | 2669 | 
|  | 2670   evo = ev(&lf->evs); | 
|  | 2671   if (evo==EDATA) evo = EFITP; | 
|  | 2672 | 
|  | 2673   for (i=0; i<n; i++) | 
|  | 2674   { for (j=0; j<lf->lfd.d; j++)  u[j] = datum(&lf->lfd,j,i); | 
|  | 2675     fitv(des,i) = base(&lf->lfd,i)+dointpoint(lf,u,PCOEF,evo,i); | 
|  | 2676     lf->lfd.y[i] -= fitv(des,i); | 
|  | 2677     wght(des,i) = 1.0; | 
|  | 2678     des->ind[i] = i; | 
|  | 2679 | 
|  | 2680     t0 = dointpoint(lf,u,PT0,evo,i); | 
|  | 2681     t1 = dointpoint(lf,u,PNLX,evo,i); | 
|  | 2682     stdlinks(link,&lf->lfd,&lf->sp,i,fitv(des,i),1.0); | 
|  | 2683     t0 = t0*t0*link[ZDDLL]; | 
|  | 2684     t1 = t1*t1*link[ZDDLL]; | 
|  | 2685     if (t0>1) t0 = 1; /* no observation gives >1 deg.free */ | 
|  | 2686     if (t1>1) t1 = 1; /* no observation gives >1 deg.free */ | 
|  | 2687     vr[i] = t1; | 
|  | 2688     df += t0; | 
|  | 2689   } | 
|  | 2690 | 
|  | 2691   des->n = n; | 
|  | 2692   deg(&lf->sp) = 1; | 
|  | 2693   op = npar(&lf->sp); | 
|  | 2694   npar(&lf->sp) = des->p = 1+lf->lfd.d; | 
|  | 2695   des->xev = lf->pc.xbar; | 
|  | 2696   locfit(&lf->lfd,des,&lf->sp,1,0,0); | 
|  | 2697 | 
|  | 2698   for (i=0; i<n; i++) fv[i] = resp(&lf->lfd,i) - fitv(des,i); | 
|  | 2699   for (i=0; i<=lf->lfd.d; i++) | 
|  | 2700     lf->pc.coef[i] += des->cf[i]; | 
|  | 2701   res[2*n] = df-2; | 
|  | 2702   npar(&lf->sp) = op; | 
|  | 2703 } | 
|  | 2704 | 
|  | 2705 void initgam(lf) | 
|  | 2706 lfit *lf; | 
|  | 2707 { initstd(lf); | 
|  | 2708   PPROC(lf) = pprocgam; | 
|  | 2709   KEEPC(lf) = 2*NOBS(lf)+1; | 
|  | 2710 } | 
|  | 2711 /* | 
|  | 2712  * Copyright 1996-2006 Catherine Loader. | 
|  | 2713  */ | 
|  | 2714 #include "lfev.h" | 
|  | 2715 | 
|  | 2716 int procvhatm(des,lf,v) | 
|  | 2717 design *des; | 
|  | 2718 lfit *lf; | 
|  | 2719 int v; | 
|  | 2720 { int k; | 
|  | 2721   double *l; | 
|  | 2722   l = &lf->fp.coef[v*lf->lfd.n]; | 
|  | 2723   if ((ker(&lf->sp)!=WPARM) | (!haspc(&lf->pc))) | 
|  | 2724   { k = procv_nov(des,lf,v); | 
|  | 2725     wdiag(&lf->lfd,&lf->sp,des,l,&lf->dv,0,1,1); | 
|  | 2726   } | 
|  | 2727   else | 
|  | 2728     wdiagp(&lf->lfd,&lf->sp,des,l,&lf->pc,&lf->dv,0,1,1); | 
|  | 2729   lf->fp.h[v] = des->h; | 
|  | 2730   return(k); | 
|  | 2731 } | 
|  | 2732 | 
|  | 2733 void allochatm(lf) | 
|  | 2734 lfit *lf; | 
|  | 2735 { lf->fp.coef = VVEC(lf,0); | 
|  | 2736   lf->fp.h    = VVEC(lf,NOBS(lf)); | 
|  | 2737 } | 
|  | 2738 | 
|  | 2739 void pprochatm(lf,des,res) | 
|  | 2740 lfit *lf; | 
|  | 2741 design *des; | 
|  | 2742 double *res; | 
|  | 2743 { transpose(lf->fp.coef,lf->fp.nvm,lf->lfd.n); | 
|  | 2744 } | 
|  | 2745 | 
|  | 2746 void inithatm(lf) | 
|  | 2747 lfit *lf; | 
|  | 2748 { PROCV(lf) = procvhatm; | 
|  | 2749   ALLOC(lf) = allochatm; | 
|  | 2750   PPROC(lf) = pprochatm; | 
|  | 2751   KEEPV(lf) = NOBS(lf)+1; | 
|  | 2752   KEEPC(lf) = 1; | 
|  | 2753   NOPC(lf) = 1; /* could use pc if mi[MKER] == WPARM */ | 
|  | 2754 } | 
|  | 2755 /* | 
|  | 2756  * Copyright 1996-2006 Catherine Loader. | 
|  | 2757  */ | 
|  | 2758 #include "lfev.h" | 
|  | 2759 | 
|  | 2760 static lfit *lf_scb; | 
|  | 2761 static lfdata *lfd_scb; | 
|  | 2762 static smpar  *scb_sp; | 
|  | 2763 static design *des_scb; | 
|  | 2764 | 
|  | 2765 int scbfitter(x,l,reqd) | 
|  | 2766 double *x, *l; | 
|  | 2767 int reqd; | 
|  | 2768 { | 
|  | 2769   int m; | 
|  | 2770   des_scb->xev = x; | 
|  | 2771   if ((ker(scb_sp)!=WPARM) | (!haspc(&lf_scb->pc))) | 
|  | 2772   { locfit(lfd_scb,des_scb,&lf_scb->sp,1,1,0); | 
|  | 2773     m = wdiag(lfd_scb, scb_sp, des_scb,l,&lf_scb->dv,reqd,2,0); | 
|  | 2774   } | 
|  | 2775   else | 
|  | 2776     m = wdiagp(lfd_scb, scb_sp, des_scb,l,&lf_scb->pc,&lf_scb->dv,reqd,2,0); | 
|  | 2777   return(m); | 
|  | 2778 } | 
|  | 2779 | 
|  | 2780 int constants(lf,des,res) | 
|  | 2781 lfit *lf; | 
|  | 2782 design *des; | 
|  | 2783 double *res; | 
|  | 2784 { | 
|  | 2785   int d, m, nt; | 
|  | 2786   double *wk; | 
|  | 2787   evstruc *evs; | 
|  | 2788 | 
|  | 2789   lf_scb = lf; | 
|  | 2790   des_scb = des; | 
|  | 2791   lfd_scb = &lf->lfd; | 
|  | 2792   scb_sp  = &lf->sp; | 
|  | 2793 | 
|  | 2794   evs = &lf->evs; | 
|  | 2795   d = lfd_scb->d; | 
|  | 2796   m = lfd_scb->n; | 
|  | 2797   trchck(lf,0,0,0); | 
|  | 2798 | 
|  | 2799   if (lf_error) return(0); | 
|  | 2800   if ((ker(scb_sp) != WPARM) && (lf->sp.nn>0)) | 
|  | 2801     WARN(("constants are approximate for varying h")); | 
|  | 2802   npar(scb_sp) = calcp(scb_sp,lf->lfd.d); | 
|  | 2803   des_init(des,m,npar(scb_sp)); | 
|  | 2804   set_scales(&lf->lfd); | 
|  | 2805   set_flim(&lf->lfd,&lf->evs); | 
|  | 2806   compparcomp(des,&lf->lfd,&lf->sp,&lf->pc,ker(scb_sp)!=WPARM); | 
|  | 2807 | 
|  | 2808   wk = &res[d+1]; | 
|  | 2809   nt = tube_constants(scbfitter,d,m,ev(evs),mg(evs),evs->fl, | 
|  | 2810     res,wk,(d>3) ? 4 : d+1,0); | 
|  | 2811   lf->evs.nce = nt;   /* cheat way to return it to S. */ | 
|  | 2812   return(nt); | 
|  | 2813 } | 
|  | 2814 | 
|  | 2815 void initkappa(lf) | 
|  | 2816 lfit *lf; | 
|  | 2817 { PROCV(lf) = NULL; | 
|  | 2818   ALLOC(lf) = NULL; | 
|  | 2819   PPROC(lf) = (void *)constants; | 
|  | 2820   KEEPV(lf) = 0; | 
|  | 2821   KEEPC(lf) = NVAR(lf)+1+k0_reqd(NVAR(lf),NOBS(lf),0); | 
|  | 2822   NOPC(lf) = 0; | 
|  | 2823 } | 
|  | 2824 /* | 
|  | 2825  * Copyright 1996-2006 Catherine Loader. | 
|  | 2826  */ | 
|  | 2827 #include "lfev.h" | 
|  | 2828 | 
|  | 2829 /*  fix df computation for link=IDENT. */ | 
|  | 2830 void pproclscv(lf,des,res) | 
|  | 2831 lfit *lf; | 
|  | 2832 design *des; | 
|  | 2833 double *res; | 
|  | 2834 { double df, fh, fh_cv, infl, z0, z1, x[MXDIM]; | 
|  | 2835   int i, n, j, evo; | 
|  | 2836   z1 = df = 0.0; | 
|  | 2837   evo = ev(&lf->evs); | 
|  | 2838   n = lf->lfd.n; | 
|  | 2839   if ((evo==EDATA) | (evo==ECROS)) evo = EFITP; | 
|  | 2840 | 
|  | 2841   z0 = dens_integrate(lf,des,2); | 
|  | 2842 | 
|  | 2843   for (i=0; i<n; i++) | 
|  | 2844   { for (j=0; j<lf->lfd.d; j++) x[j] = datum(&lf->lfd,j,i); | 
|  | 2845     fh = base(&lf->lfd,i)+dointpoint(lf,x,PCOEF,evo,i); | 
|  | 2846     if (link(&lf->sp)==LLOG) fh = exp(fh); | 
|  | 2847     infl = dointpoint(lf,x,PT0,evo,i); | 
|  | 2848     infl = infl * infl; | 
|  | 2849     if (infl>1) infl = 1; | 
|  | 2850     fh_cv = (link(&lf->sp) == LIDENT) ? | 
|  | 2851        (n*fh - infl) / (n-1.0) : fh*(1-infl)*n/(n-1.0); | 
|  | 2852     z1 += fh_cv; | 
|  | 2853     df += infl; | 
|  | 2854   } | 
|  | 2855 | 
|  | 2856   res[0] = z0-2*z1/n; | 
|  | 2857   res[1] = df; | 
|  | 2858 } | 
|  | 2859 | 
|  | 2860 void initlscv(lf) | 
|  | 2861 lfit *lf; | 
|  | 2862 { initstd(lf); | 
|  | 2863   KEEPC(lf) = 2; | 
|  | 2864   PPROC(lf) = pproclscv; | 
|  | 2865   NOPC(lf) = 1; | 
|  | 2866 } | 
|  | 2867 /* | 
|  | 2868  * Copyright 1996-2006 Catherine Loader. | 
|  | 2869  */ | 
|  | 2870 #include "lfev.h" | 
|  | 2871 | 
|  | 2872 static double pen, sig2; | 
|  | 2873 | 
|  | 2874 void goldensec(f,des,tr,eps,xm,ym,meth) | 
|  | 2875 double (*f)(), eps, *xm, *ym; | 
|  | 2876 int meth; | 
|  | 2877 design *des; | 
|  | 2878 lfit *tr; | 
|  | 2879 { double x[4], y[4], xx[11], yy[11]; | 
|  | 2880   int i, im; | 
|  | 2881   xx[0] = tr->sp.fixh; | 
|  | 2882   if (xx[0]<=0) | 
|  | 2883   { LERR(("regband: initialize h>0")); | 
|  | 2884     return; | 
|  | 2885   } | 
|  | 2886   for (i=0; i<=10; i++) | 
|  | 2887   { if (i>0) xx[i] = (1+gold_rat)*xx[i-1]; | 
|  | 2888     yy[i] = f(xx[i],des,tr,meth); | 
|  | 2889     if ((i==0) || (yy[i]<yy[im])) im = i; | 
|  | 2890   } | 
|  | 2891   if (im==0) im = 1; | 
|  | 2892   if (im==10)im = 9; | 
|  | 2893   x[0] = xx[im-1]; y[0] = yy[im-1]; | 
|  | 2894   x[1] = xx[im];   y[1] = yy[im]; | 
|  | 2895   x[3] = xx[im+1]; y[3] = yy[im+1]; | 
|  | 2896   x[2] = gold_rat*x[3]+(1-gold_rat)*x[0]; | 
|  | 2897   y[2] = f(x[2],des,tr,meth); | 
|  | 2898   while (x[3]-x[0]>eps) | 
|  | 2899   { if (y[1]<y[2]) | 
|  | 2900     { x[3] = x[2]; y[3] = y[2]; | 
|  | 2901       x[2] = x[1]; y[2] = y[1]; | 
|  | 2902       x[1] = gold_rat*x[0]+(1-gold_rat)*x[3]; | 
|  | 2903       y[1] = f(x[1],des,tr,meth); | 
|  | 2904     } | 
|  | 2905     else | 
|  | 2906     { x[0] = x[1]; y[0] = y[1]; | 
|  | 2907       x[1] = x[2]; y[1] = y[2]; | 
|  | 2908       x[2] = gold_rat*x[3]+(1-gold_rat)*x[0]; | 
|  | 2909       y[2] = f(x[2],des,tr,meth); | 
|  | 2910     } | 
|  | 2911   } | 
|  | 2912   im = 0; | 
|  | 2913   for (i=1; i<4; i++) if (y[i]<y[im]) im = i; | 
|  | 2914   *xm = x[im]; *ym = y[im]; | 
|  | 2915 } | 
|  | 2916 | 
|  | 2917 double dnk(x,k) | 
|  | 2918 double x; | 
|  | 2919 int k; | 
|  | 2920 { double f; | 
|  | 2921   switch(k) | 
|  | 2922   { case 0: f = 1; break; | 
|  | 2923     case 1: f = -x; break; | 
|  | 2924     case 2: f = x*x-1; break; | 
|  | 2925     case 3: f = x*(x*x-3); break; | 
|  | 2926     case 4: f = 3-x*x*(6-x*x); break; | 
|  | 2927     case 5: f = -x*(15-x*x*(10-x*x)); break; | 
|  | 2928     case 6: f = -15+x*x*(45-x*x*(15-x*x)); break; | 
|  | 2929     default: LERR(("dnk: k=%d too large",k)); return(0.0); | 
|  | 2930   } | 
|  | 2931   return(f*exp(-x*x/2)/S2PI); | 
|  | 2932 } | 
|  | 2933 | 
|  | 2934 double locai(h,des,lf) | 
|  | 2935 double h; | 
|  | 2936 design *des; | 
|  | 2937 lfit *lf; | 
|  | 2938 { double cp, res[10]; | 
|  | 2939   nn(&lf->sp) = h; | 
|  | 2940   lf->mdl.procv = procvstd; | 
|  | 2941   nstartlf(des,lf); | 
|  | 2942   ressumm(lf,des,res); | 
|  | 2943   cp = -2*res[0] + pen*res[1]; | 
|  | 2944   return(cp); | 
|  | 2945 } | 
|  | 2946 | 
|  | 2947 static int fc; | 
|  | 2948 | 
|  | 2949 double loccp(h,des,lf,m) /* m=1: cp    m=2: gcv */ | 
|  | 2950 double h; | 
|  | 2951 design *des; | 
|  | 2952 lfit *lf; | 
|  | 2953 int m; | 
|  | 2954 { double cp, res[10]; | 
|  | 2955   int dg, n; | 
|  | 2956 | 
|  | 2957   n = lf->lfd.n; | 
|  | 2958   nn(&lf->sp) = 0; | 
|  | 2959   fixh(&lf->sp) = h; | 
|  | 2960   lf->mdl.procv = procvstd; | 
|  | 2961   nstartlf(des,lf); | 
|  | 2962   ressumm(lf,des,res); | 
|  | 2963   if (m==1) | 
|  | 2964   { if (fc) sig2 = res[3]; /* first call - set sig2 */ | 
|  | 2965     cp = -2*res[0]/sig2 - n + 2*res[1]; | 
|  | 2966   } | 
|  | 2967   else | 
|  | 2968     cp = -2*n*res[0]/((n-res[1])*(n-res[1])); | 
|  | 2969   fc = 0; | 
|  | 2970   return(cp); | 
|  | 2971 } | 
|  | 2972 | 
|  | 2973 double cp(des,lf,meth) | 
|  | 2974 design *des; | 
|  | 2975 lfit *lf; | 
|  | 2976 int meth; | 
|  | 2977 { double hm, ym; | 
|  | 2978   fc = 1; | 
|  | 2979   goldensec(loccp,des,lf,0.001,&hm,&ym,meth); | 
|  | 2980   return(hm); | 
|  | 2981 } | 
|  | 2982 | 
|  | 2983 double gkk(des,lf) | 
|  | 2984 design *des; | 
|  | 2985 lfit *lf; | 
|  | 2986 { double h, h5, nf, th; | 
|  | 2987   int i, j, n, dg0, dg1; | 
|  | 2988   ev(&lf->evs)= EDATA; | 
|  | 2989   nn(&lf->sp) = 0; | 
|  | 2990   n = lf->lfd.n; | 
|  | 2991   dg0 = deg0(&lf->sp);     /* target degree */ | 
|  | 2992   dg1 = dg0+1+(dg0%2==0);  /* pilot degree */ | 
|  | 2993   nf = exp(log(1.0*n)/10); /* bandwidth inflation factor */ | 
|  | 2994   h = lf->sp.fixh;         /* start bandwidth */ | 
|  | 2995   for (i=0; i<=10; i++) | 
|  | 2996   { deg(&lf->sp) = dg1; | 
|  | 2997     lf->sp.fixh = h*nf; | 
|  | 2998     lf->mdl.procv = procvstd; | 
|  | 2999     nstartlf(des,lf); | 
|  | 3000     th = 0; | 
|  | 3001     for (j=10; j<n-10; j++) | 
|  | 3002       th += lf->fp.coef[dg1*n+j]*lf->fp.coef[dg1*n+j]; | 
|  | 3003 th *= n/(n-20.0); | 
|  | 3004     h5 = sig2 * Wikk(ker(&lf->sp),dg0) / th; | 
|  | 3005     h = exp(log(h5)/(2*dg1+1)); | 
|  | 3006     if (lf_error) return(0.0); | 
|  | 3007 /* mut_printf("pilot %8.5f  sel %8.5f\n",lf->sp.fixh,h); */ | 
|  | 3008   } | 
|  | 3009   return(h); | 
|  | 3010 } | 
|  | 3011 | 
|  | 3012 double rsw(des,lf) | 
|  | 3013 design *des; | 
|  | 3014 lfit *lf; | 
|  | 3015 { int i, j, k, nmax, nvm, n, mk, evo, dg0, dg1; | 
|  | 3016   double rss[6], cp[6], th22, dx, d2, hh; | 
|  | 3017   nmax = 5; | 
|  | 3018   evo = ev(&lf->evs); ev(&lf->evs) = EGRID; | 
|  | 3019   mk = ker(&lf->sp);  ker(&lf->sp) = WRECT; | 
|  | 3020   dg0 = deg0(&lf->sp); | 
|  | 3021   dg1 = 1 + dg0 + (dg0%2==0); | 
|  | 3022   deg(&lf->sp) = 4; | 
|  | 3023   for (k=nmax; k>0; k--) | 
|  | 3024   { lf->evs.mg[0] = k; | 
|  | 3025     lf->evs.fl[0] = 1.0/(2*k); | 
|  | 3026     lf->evs.fl[1] = 1-1.0/(2*k); | 
|  | 3027     nn(&lf->sp) = 0; | 
|  | 3028     fixh(&lf->sp) = 1.0/(2*k); | 
|  | 3029     lf->mdl.procv = procvstd; | 
|  | 3030     nstartlf(des,lf); | 
|  | 3031     nvm = lf->fp.nvm; | 
|  | 3032     rss[k] = 0; | 
|  | 3033     for (i=0; i<k; i++) rss[k] += -2*lf->fp.lik[i]; | 
|  | 3034   } | 
|  | 3035   n = lf->lfd.n; k = 1; | 
|  | 3036   for (i=1; i<=nmax; i++) | 
|  | 3037   { /* cp[i] = (n-5*nmax)*rss[i]/rss[nmax]-(n-10*i); */ | 
|  | 3038     cp[i] = rss[i]/sig2-(n-10*i); | 
|  | 3039     if (cp[i]<cp[k]) k = i; | 
|  | 3040   } | 
|  | 3041   lf->evs.mg[0] = k; | 
|  | 3042   lf->evs.fl[0] = 1.0/(2*k); | 
|  | 3043   lf->evs.fl[1] = 1-1.0/(2*k); | 
|  | 3044   nn(&lf->sp) = 0; | 
|  | 3045   fixh(&lf->sp) = 1.0/(2*k); | 
|  | 3046   lf->mdl.procv = procvstd; | 
|  | 3047   nstartlf(des,lf); | 
|  | 3048   ker(&lf->sp) = mk; ev(&lf->evs) = evo; | 
|  | 3049   nvm = lf->fp.nvm; | 
|  | 3050   th22 = 0; | 
|  | 3051   for (i=10; i<n-10; i++) | 
|  | 3052   { j = floor(k*datum(&lf->lfd,0,i)); | 
|  | 3053     if (j>=k) j = k-1; | 
|  | 3054     dx = datum(&lf->lfd,0,i)-evptx(&lf->fp,0,j); | 
|  | 3055     if (dg1==2) | 
|  | 3056       d2 = lf->fp.coef[2*nvm+j]+dx*lf->fp.coef[3*nvm+j]+dx*dx*lf->fp.coef[4*nvm+j]/2; | 
|  | 3057     else d2 = lf->fp.coef[4*nvm+j]; | 
|  | 3058     th22 += d2*d2; | 
|  | 3059   } | 
|  | 3060   hh = Wikk(mk,dg0)*sig2/th22*(n-20.0)/n; | 
|  | 3061   return(exp(log(hh)/(2*dg1+1))); | 
|  | 3062 } | 
|  | 3063 | 
|  | 3064 #define MAXMETH 10 | 
|  | 3065 | 
|  | 3066 void rband(lf,des,hhat) | 
|  | 3067 lfit *lf; | 
|  | 3068 design *des; | 
|  | 3069 double *hhat; | 
|  | 3070 { int i, dg, nmeth, meth[MAXMETH]; | 
|  | 3071   double h0, res[10]; | 
|  | 3072 | 
|  | 3073   nmeth = lf->dv.nd; | 
|  | 3074   for (i=0; i<nmeth; i++) meth[i] = lf->dv.deriv[i]; | 
|  | 3075   lf->dv.nd = 0; | 
|  | 3076 | 
|  | 3077 /* first, estimate sigma^2. | 
|  | 3078  * this is ridiculously bad. lf->sp.fixh = 0.05???? | 
|  | 3079  */ | 
|  | 3080 /*  dg = deg(&lf->sp); deg(&lf->sp) = 2; | 
|  | 3081   h0 = lf->sp.fixh;  lf->sp.fixh = 0.05; | 
|  | 3082   lf->mdl.procv = procvstd; | 
|  | 3083   nstartlf(des,lf); | 
|  | 3084   ressumm(lf,des,res); | 
|  | 3085   deg(&lf->sp) = dg; lf->sp.fixh = h0; | 
|  | 3086   sig2 = res[3];  */ | 
|  | 3087 | 
|  | 3088   for (i=0; i<nmeth; i++) | 
|  | 3089   { | 
|  | 3090     switch(meth[i]) | 
|  | 3091     { case 0: hhat[i] = cp(des,lf,1); | 
|  | 3092               break; | 
|  | 3093       case 1: hhat[i] = cp(des,lf,2); | 
|  | 3094               break; | 
|  | 3095       case 2: hhat[i] = gkk(des,lf); | 
|  | 3096               break; | 
|  | 3097       case 3: hhat[i] = rsw(des,lf); | 
|  | 3098               break; | 
|  | 3099       default: hhat[i] = 0; | 
|  | 3100               mut_printf("Unknown method %d\n",meth[i]); | 
|  | 3101     } | 
|  | 3102     if (lf_error) i = nmeth; | 
|  | 3103   } | 
|  | 3104   lf->dv.nd = nmeth; | 
|  | 3105 } | 
|  | 3106 | 
|  | 3107 void initrband(lf) | 
|  | 3108 lfit *lf; | 
|  | 3109 { | 
|  | 3110   initstd(lf); | 
|  | 3111   KEEPC(lf) = MAXMETH; | 
|  | 3112   PROCV(lf) = NULL; | 
|  | 3113   PPROC(lf) = rband; | 
|  | 3114 } | 
|  | 3115 /* | 
|  | 3116  * Copyright 1996-2006 Catherine Loader. | 
|  | 3117  */ | 
|  | 3118 #include "lfev.h" | 
|  | 3119 static double scb_crit, *x, c[10], kap[5], kaq[5], max_p2; | 
|  | 3120 static int side, type; | 
|  | 3121 design *scb_des; | 
|  | 3122 | 
|  | 3123 double covar_par(lf,des,x1,x2) | 
|  | 3124 lfit *lf; | 
|  | 3125 design *des; | 
|  | 3126 double x1, x2; | 
|  | 3127 { double *v1, *v2, *wk; | 
|  | 3128   paramcomp *pc; | 
|  | 3129   int i, j, p, ispar; | 
|  | 3130 | 
|  | 3131   v1 = des->f1; v2 = des->ss; wk = des->oc; | 
|  | 3132   ispar = (ker(&lf->sp)==WPARM) && (haspc(&lf->pc)); | 
|  | 3133   p = npar(&lf->sp); | 
|  | 3134 | 
|  | 3135 /*  for parametric models, the covariance is | 
|  | 3136  *  A(x1)^T (X^T W V X)^{-1} A(x2) | 
|  | 3137  *  which we can find easily from the parametric component. | 
|  | 3138  */ | 
|  | 3139   if (ispar) | 
|  | 3140   { pc = &lf->pc; | 
|  | 3141     fitfun(&lf->lfd, &lf->sp, &x1,pc->xbar,v1,NULL); | 
|  | 3142     fitfun(&lf->lfd, &lf->sp, &x2,pc->xbar,v2,NULL); | 
|  | 3143     jacob_hsolve(&lf->pc.xtwx,v1); | 
|  | 3144     jacob_hsolve(&lf->pc.xtwx,v2); | 
|  | 3145   } | 
|  | 3146 | 
|  | 3147 /*  for non-parametric models, we must use the cholseky decomposition | 
|  | 3148  *  of M2 = X^T W^2 V X. Courtesy of lf_vcov caclulations, should have | 
|  | 3149  *  des->P = M2^{1/2} M1^{-1}. | 
|  | 3150  */ | 
|  | 3151   if (!ispar) | 
|  | 3152   { fitfun(&lf->lfd, &lf->sp, &x1,des->xev,wk,NULL); | 
|  | 3153     for (i=0; i<p; i++) | 
|  | 3154     { v1[i] = 0; | 
|  | 3155       for (j=0; j<p; j++) v1[i] += des->P[i*p+j]*wk[j]; | 
|  | 3156     } | 
|  | 3157     fitfun(&lf->lfd, &lf->sp, &x2,des->xev,wk,NULL); | 
|  | 3158     for (i=0; i<p; i++) | 
|  | 3159     { v2[i] = 0; | 
|  | 3160       for (j=0; j<p; j++) v2[i] += des->P[i*p+j]*wk[j]; | 
|  | 3161     } | 
|  | 3162   } | 
|  | 3163 | 
|  | 3164   return(innerprod(v1,v2,p)); | 
|  | 3165 } | 
|  | 3166 | 
|  | 3167 void cumulant(lf,des,sd) | 
|  | 3168 lfit *lf; | 
|  | 3169 design *des; | 
|  | 3170 double sd; | 
|  | 3171 { double b2i, b3i, b3j, b4i; | 
|  | 3172   double ss, si, sj, uii, uij, ujj, k1; | 
|  | 3173   int ii, i, j, jj; | 
|  | 3174   for (i=1; i<10; i++) c[i] = 0.0; | 
|  | 3175   k1 = 0; | 
|  | 3176 | 
|  | 3177   /* ss = sd*sd; */ | 
|  | 3178   ss = covar_par(lf,des,des->xev[0],des->xev[0]); | 
|  | 3179 | 
|  | 3180 /* | 
|  | 3181  * this isn't valid for nonparametric models. At a minimum, | 
|  | 3182  * the sums would have to include weights. Still have to work | 
|  | 3183  * out the right way. | 
|  | 3184  */ | 
|  | 3185   for (i=0; i<lf->lfd.n; i++) | 
|  | 3186   { ii = des->ind[i]; | 
|  | 3187     b2i = b2(fitv(des,ii),fam(&lf->sp),prwt(&lf->lfd,ii)); | 
|  | 3188     b3i = b3(fitv(des,ii),fam(&lf->sp),prwt(&lf->lfd,ii)); | 
|  | 3189     b4i = b4(fitv(des,ii),fam(&lf->sp),prwt(&lf->lfd,ii)); | 
|  | 3190     si = covar_par(lf,des,des->xev[0],datum(&lf->lfd,0,ii)); | 
|  | 3191     uii= covar_par(lf,des,datum(&lf->lfd,0,ii),datum(&lf->lfd,0,ii)); | 
|  | 3192     if (lf_error) return; | 
|  | 3193 | 
|  | 3194     c[2] += b4i*si*si*uii; | 
|  | 3195     c[6] += b4i*si*si*si*si; | 
|  | 3196     c[7] += b3i*si*uii; | 
|  | 3197     c[8] += b3i*si*si*si; | 
|  | 3198     /* c[9] += b2i*si*si*si*si; | 
|  | 3199        c[9] += b2i*b2i*si*si*si*si; */ | 
|  | 3200     k1 += b3i*si*(si*si/ss-uii); | 
|  | 3201 | 
|  | 3202     /* i=j components */ | 
|  | 3203     c[1] += b3i*b3i*si*si*uii*uii; | 
|  | 3204     c[3] += b3i*b3i*si*si*si*si*uii; | 
|  | 3205     c[4] += b3i*b3i*si*si*uii*uii; | 
|  | 3206 | 
|  | 3207     for (j=i+1; j<lf->lfd.n; j++) | 
|  | 3208     { jj = des->ind[j]; | 
|  | 3209       b3j = b3(fitv(des,ii),fam(&lf->sp),prwt(&lf->lfd,jj)); | 
|  | 3210       sj = covar_par(lf,des,des->xev[0],datum(&lf->lfd,0,jj)); | 
|  | 3211       uij= covar_par(lf,des,datum(&lf->lfd,0,ii),datum(&lf->lfd,0,jj)); | 
|  | 3212       ujj= covar_par(lf,des,datum(&lf->lfd,0,jj),datum(&lf->lfd,0,jj)); | 
|  | 3213 | 
|  | 3214       c[1] += 2*b3i*b3j*si*sj*uij*uij; | 
|  | 3215       c[3] += 2*b3i*b3j*si*si*sj*sj*uij; | 
|  | 3216       c[4] += b3i*b3j*uij*(si*si*ujj+sj*sj*uii); | 
|  | 3217       if (lf_error) return; | 
|  | 3218     } | 
|  | 3219   } | 
|  | 3220   c[5] = c[1]; | 
|  | 3221   c[7] = c[7]*c[8]; | 
|  | 3222   c[8] = c[8]*c[8]; | 
|  | 3223 | 
|  | 3224   c[1] /= ss; c[2] /= ss; c[3] /= ss*ss; c[4] /= ss; | 
|  | 3225   c[5] /= ss; c[6] /= ss*ss; c[7] /= ss*ss; | 
|  | 3226   c[8] /= ss*ss*ss; c[9] /= ss*ss; | 
|  | 3227 | 
|  | 3228 /* constants used in p(x,z) computation */ | 
|  | 3229   kap[1] = k1/(2*sqrt(ss)); | 
|  | 3230   kap[2] = 1 + 0.5*(c[1]-c[2]+c[4]-c[7]) - 3*c[3] + c[6] + 1.75*c[8]; | 
|  | 3231   kap[4] = -9*c[3] + 3*c[6] + 6*c[8] + 3*c[9]; | 
|  | 3232 | 
|  | 3233 /* constants used in q(x,u) computation */ | 
|  | 3234   kaq[2] = c[3] - 1.5*c[8] - c[5] - c[4] + 0.5*c[7] + c[6] - c[2]; | 
|  | 3235   kaq[4] = -3*c[3] - 6*c[4] - 6*c[5] + 3*c[6] + 3*c[7] - 3*c[8] + 3*c[9]; | 
|  | 3236 } | 
|  | 3237 | 
|  | 3238 /* q2(u) := u+q2(x,u) in paper */ | 
|  | 3239 double q2(u) | 
|  | 3240 double u; | 
|  | 3241 { return(u-u*(36.0*kaq[2] + 3*kaq[4]*(u*u-3) + c[8]*((u*u-10)*u*u+15))/72.0); | 
|  | 3242 } | 
|  | 3243 | 
|  | 3244 /*  p2(u) := p2(x,u) in paper */ | 
|  | 3245 double p2(u) | 
|  | 3246 double u; | 
|  | 3247 { return( -u*( 36*(kap[2]-1+kap[1]*kap[1]) | 
|  | 3248      + 3*(kap[4]+4*kap[1]*sqrt(kap[3]))*(u*u-3) | 
|  | 3249      + c[8]*((u*u-10)*u*u+15) ) / 72 ); | 
|  | 3250 } | 
|  | 3251 | 
|  | 3252 extern int likereg(); | 
|  | 3253 double gldn_like(a) | 
|  | 3254 double a; | 
|  | 3255 { int err; | 
|  | 3256 | 
|  | 3257   scb_des->fix[0] = 1; | 
|  | 3258   scb_des->cf[0] = a; | 
|  | 3259   max_nr(likereg, scb_des->cf, scb_des->oc, scb_des->res, scb_des->f1, | 
|  | 3260     &scb_des->xtwx, scb_des->p, lf_maxit, 1.0e-6, &err); | 
|  | 3261   scb_des->fix[0] = 0; | 
|  | 3262 | 
|  | 3263   return(scb_des->llk); | 
|  | 3264 } | 
|  | 3265 | 
|  | 3266 /* v1/v2 is correct for deg=0 only */ | 
|  | 3267 void get_gldn(fp,des,lo,hi,v) | 
|  | 3268 fitpt *fp; | 
|  | 3269 design *des; | 
|  | 3270 double *lo, *hi; | 
|  | 3271 int v; | 
|  | 3272 { double v1, v2, c, tlk; | 
|  | 3273   int err; | 
|  | 3274 | 
|  | 3275   v1 = fp->nlx[v]; | 
|  | 3276   v2 = fp->t0[v]; | 
|  | 3277   c = scb_crit * v1 / v2; | 
|  | 3278   tlk = des->llk - c*c/2; | 
|  | 3279 mut_printf("v %8.5f %8.5f  c %8.5f  tlk %8.5f   llk %8.5f\n",v1,v2,c,tlk,des->llk); | 
|  | 3280 | 
|  | 3281   /* want: { a : l(a) >= l(a-hat) - c*c/2 } */ | 
|  | 3282   lo[v] = fp->coef[v] - scb_crit*v1; | 
|  | 3283   hi[v] = fp->coef[v] + scb_crit*v1; | 
|  | 3284 | 
|  | 3285   err = 0; | 
|  | 3286 | 
|  | 3287 mut_printf("lo %2d\n",v); | 
|  | 3288   lo[v] = solve_secant(gldn_like,tlk,lo[v],fp->coef[v],1e-8,BDF_EXPLEFT,&err); | 
|  | 3289   if (err>0) mut_printf("solve_secant error\n"); | 
|  | 3290 mut_printf("hi %2d\n",v); | 
|  | 3291   hi[v] = solve_secant(gldn_like,tlk,fp->coef[v],hi[v],1e-8,BDF_EXPRIGHT,&err); | 
|  | 3292   if (err>0) mut_printf("solve_secant error\n"); | 
|  | 3293 } | 
|  | 3294 | 
|  | 3295 int procvscb2(des,lf,v) | 
|  | 3296 design *des; | 
|  | 3297 lfit *lf; | 
|  | 3298 int v; | 
|  | 3299 { double thhat, sd, *lo, *hi, u; | 
|  | 3300   int err, st, tmp; | 
|  | 3301   x = des->xev = evpt(&lf->fp,v); | 
|  | 3302   tmp = haspc(&lf->pc); | 
|  | 3303   /* if ((ker(&lf->sp)==WPARM) && (haspc(&lf->pc))) | 
|  | 3304   { lf->coef[v] = thhat = addparcomp(lf,des->xev,PCOEF); | 
|  | 3305     lf->nlx[v] = lf->t0[v] = sd = addparcomp(lf,des->xev,PNLX); | 
|  | 3306   } | 
|  | 3307   else */ | 
|  | 3308   { haspc(&lf->pc) = 0; | 
|  | 3309     st = procvstd(des,lf,v); | 
|  | 3310     thhat = lf->fp.coef[v]; | 
|  | 3311     sd = lf->fp.nlx[v]; | 
|  | 3312   } | 
|  | 3313   if ((type==GLM2) | (type==GLM3) | (type==GLM4)) | 
|  | 3314   { if (ker(&lf->sp) != WPARM) | 
|  | 3315       WARN(("nonparametric fit; correction is invalid")); | 
|  | 3316     cumulant(lf,des,sd); | 
|  | 3317   } | 
|  | 3318   haspc(&lf->pc) = tmp; | 
|  | 3319   lo = lf->fp.t0; | 
|  | 3320   hi = &lo[lf->fp.nvm]; | 
|  | 3321   switch(type) | 
|  | 3322   { | 
|  | 3323     case GLM1: | 
|  | 3324       return(st); | 
|  | 3325     case GLM2: /* centered scr */ | 
|  | 3326       lo[v] = kap[1]; | 
|  | 3327       hi[v] = sqrt(kap[2]); | 
|  | 3328       return(st); | 
|  | 3329     case GLM3: /* corrected 2 */ | 
|  | 3330       lo[v] = solve_secant(q2,scb_crit,0.0,2*scb_crit,0.000001,BDF_NONE,&err); | 
|  | 3331       return(st); | 
|  | 3332     case GLM4: /* corrected 2' */ | 
|  | 3333       u = fabs(p2(scb_crit)); | 
|  | 3334       max_p2 = MAX(max_p2,u); | 
|  | 3335       return(st); | 
|  | 3336     case GLDN: | 
|  | 3337       get_gldn(&lf->fp,des,lo,hi,v); | 
|  | 3338       return(st); | 
|  | 3339   } | 
|  | 3340   LERR(("procvscb2: invalid type")); | 
|  | 3341   return(st); | 
|  | 3342 } | 
|  | 3343 | 
|  | 3344 void scb(lf,des,res) | 
|  | 3345 lfit *lf; | 
|  | 3346 design *des; | 
|  | 3347 double *res; | 
|  | 3348 { double k1, k2, *lo, *hi, sig, thhat, nlx, rss[10]; | 
|  | 3349   int i, nterms; | 
|  | 3350 | 
|  | 3351   scb_des= des; | 
|  | 3352 | 
|  | 3353   npar(&lf->sp) = calcp(&lf->sp,lf->lfd.d); | 
|  | 3354   des_init(des,lf->lfd.n,npar(&lf->sp)); | 
|  | 3355 | 
|  | 3356   type = geth(&lf->fp); | 
|  | 3357 | 
|  | 3358   if (type >= 80) /* simultaneous */ | 
|  | 3359   { | 
|  | 3360     nterms = constants(lf,des,res); | 
|  | 3361     scb_crit = critval(0.05,res,nterms,lf->lfd.d,TWO_SIDED,0.0,GAUSS); | 
|  | 3362     type -= 10; | 
|  | 3363   } | 
|  | 3364   else /* pointwise */ | 
|  | 3365   { res[0] = 1; | 
|  | 3366     scb_crit = critval(0.05,res,1,lf->lfd.d,TWO_SIDED,0.0,GAUSS); | 
|  | 3367   } | 
|  | 3368 | 
|  | 3369   max_p2 = 0.0; | 
|  | 3370   lf->mdl.procv = procvscb2; | 
|  | 3371   nstartlf(des,lf); | 
|  | 3372 | 
|  | 3373   if ((fam(&lf->sp)&64)==64) | 
|  | 3374   { i = haspc(&lf->pc); haspc(&lf->pc) = 0; | 
|  | 3375     ressumm(lf,des,rss); | 
|  | 3376     haspc(&lf->pc) = i; | 
|  | 3377     sig = sqrt(rss[3]); | 
|  | 3378   } | 
|  | 3379   else sig = 1.0; | 
|  | 3380 | 
|  | 3381   lo = lf->fp.t0; | 
|  | 3382   hi = &lo[lf->fp.nvm]; | 
|  | 3383   for (i=0; i<lf->fp.nv; i++) | 
|  | 3384   { thhat = lf->fp.coef[i]; | 
|  | 3385     nlx = lf->fp.nlx[i]; | 
|  | 3386     switch(type) | 
|  | 3387     { | 
|  | 3388       case GLM1:  /* basic scb */ | 
|  | 3389         lo[i] = thhat - scb_crit * sig * nlx; | 
|  | 3390         hi[i] = thhat + scb_crit * sig * nlx; | 
|  | 3391         break; | 
|  | 3392       case GLM2: | 
|  | 3393         k1 = lo[i]; | 
|  | 3394         k2 = hi[i]; | 
|  | 3395         lo[i] = thhat - k1*nlx - scb_crit*nlx*k2; | 
|  | 3396         hi[i] = thhat - k1*nlx + scb_crit*nlx*k2; | 
|  | 3397         break; | 
|  | 3398       case GLM3: | 
|  | 3399         k1 = lo[i]; | 
|  | 3400         lo[i] = thhat - k1*nlx; | 
|  | 3401         hi[i] = thhat + k1*nlx; | 
|  | 3402       case GLM4:  /* corrected 2' */ | 
|  | 3403         lo[i] = thhat - (scb_crit-max_p2)*lf->fp.nlx[i]; | 
|  | 3404         hi[i] = thhat + (scb_crit-max_p2)*lf->fp.nlx[i]; | 
|  | 3405         break; | 
|  | 3406       case GLDN: | 
|  | 3407         break; | 
|  | 3408     } | 
|  | 3409   } | 
|  | 3410 } | 
|  | 3411 | 
|  | 3412 void initscb(lf) | 
|  | 3413 lfit *lf; | 
|  | 3414 { initstd(lf); | 
|  | 3415   PROCV(lf) = NULL; | 
|  | 3416   KEEPC(lf) = NVAR(lf)+1+k0_reqd(NVAR(lf),NOBS(lf),0); | 
|  | 3417   PPROC(lf) = scb; | 
|  | 3418 } | 
|  | 3419 /* | 
|  | 3420  * Copyright 1996-2006 Catherine Loader. | 
|  | 3421  */ | 
|  | 3422 #include "lfev.h" | 
|  | 3423 | 
|  | 3424 int procvsimple(des,lf,v) | 
|  | 3425 design *des; | 
|  | 3426 lfit *lf; | 
|  | 3427 int v; | 
|  | 3428 { int lf_status; | 
|  | 3429   lf_status = procv_nov(des,lf,v); | 
|  | 3430   VVAL(lf,v,0) = des->cf[cfn(des,0)]; | 
|  | 3431   return(lf_status); | 
|  | 3432 } | 
|  | 3433 | 
|  | 3434 void allocsimple(lf) | 
|  | 3435 lfit *lf; | 
|  | 3436 { lf->fp.coef = VVEC(lf,0); | 
|  | 3437   lf->fp.h = NULL; | 
|  | 3438 } | 
|  | 3439 | 
|  | 3440 void initsimple(lf) | 
|  | 3441 lfit *lf; | 
|  | 3442 { | 
|  | 3443   PROCV(lf) = procvsimple; | 
|  | 3444   ALLOC(lf) = allocsimple; | 
|  | 3445   PPROC(lf) = NULL; | 
|  | 3446   KEEPV(lf) = 1; | 
|  | 3447   KEEPC(lf) = 1; | 
|  | 3448   NOPC(lf)  = 1; | 
|  | 3449 } | 
|  | 3450 /* | 
|  | 3451  * Copyright 1996-2006 Catherine Loader. | 
|  | 3452  */ | 
|  | 3453 #include "lfev.h" | 
|  | 3454 | 
|  | 3455 /* 3d+8 variables to keep: | 
|  | 3456  * d+1 coef+derivs. | 
|  | 3457  * d+1 sd's + derivs. | 
|  | 3458  * d+1 infl + derivs. | 
|  | 3459  *   3 likelihood and d.f's. | 
|  | 3460  *   1 bandwidth h | 
|  | 3461  *   1 degree. | 
|  | 3462  */ | 
|  | 3463 | 
|  | 3464 void allocstd(lf) | 
|  | 3465 lfit *lf; | 
|  | 3466 { int d; | 
|  | 3467   d = NVAR(lf); | 
|  | 3468   lf->fp.coef = VVEC(lf,0); | 
|  | 3469   lf->fp.nlx  = VVEC(lf,d+1); | 
|  | 3470   lf->fp.t0   = VVEC(lf,2*d+2); | 
|  | 3471   lf->fp.lik  = VVEC(lf,3*d+3); | 
|  | 3472   lf->fp.h    = VVEC(lf,3*d+6); | 
|  | 3473   lf->fp.deg  = VVEC(lf,3*d+7); | 
|  | 3474 } | 
|  | 3475 | 
|  | 3476 int procvstd(des,lf,v) | 
|  | 3477 design *des; | 
|  | 3478 lfit *lf; | 
|  | 3479 int v; | 
|  | 3480 { int d, p, nvm, i, k; | 
|  | 3481   double t0[1+MXDIM], vari[1+MXDIM]; | 
|  | 3482   k = procv_var(des,lf,v); | 
|  | 3483   if (lf_error) return(k); | 
|  | 3484 | 
|  | 3485   d = lf->lfd.d; | 
|  | 3486   p = npar(&lf->sp); | 
|  | 3487   nvm = lf->fp.nvm; | 
|  | 3488 | 
|  | 3489   if (k != LF_OK) lf_status_msg(k); | 
|  | 3490 | 
|  | 3491   lf->fp.lik[v] = des->llk; | 
|  | 3492   lf->fp.lik[nvm+v] = des->tr2; | 
|  | 3493   lf->fp.lik[2*nvm+v] = des->tr0 - des->tr2; | 
|  | 3494 | 
|  | 3495   for (i=0; i<des->ncoef; i++) | 
|  | 3496     vari[i] = des->V[p*cfn(des,0) + cfn(des,i)]; | 
|  | 3497   vari[0] = sqrt(vari[0]); | 
|  | 3498   if (vari[0]>0) for (i=1; i<des->ncoef; i++) vari[i] /= vari[0]; | 
|  | 3499 | 
|  | 3500   t0[0] = sqrt(des->f1[0]); | 
|  | 3501   if (t0[0]>0) for (i=1; i<des->ncoef; i++) t0[i] = des->f1[i]/t0[0]; | 
|  | 3502 | 
|  | 3503   if (dc(&lf->fp)) dercor(&lf->lfd,&lf->sp,des,des->cf); | 
|  | 3504   subparcomp(des,lf,des->cf); | 
|  | 3505   for (i=0; i<des->ncoef; i++) | 
|  | 3506     lf->fp.coef[i*lf->fp.nvm+v] =  des->cf[cfn(des,i)]; | 
|  | 3507 | 
|  | 3508   subparcomp2(des,lf,vari,t0); | 
|  | 3509   for (i=0; i<des->ncoef; i++) | 
|  | 3510   { lf->fp.nlx[i*nvm+v] = vari[i]; | 
|  | 3511     lf->fp.t0[i*nvm+v]  = t0[i]; | 
|  | 3512   } | 
|  | 3513 | 
|  | 3514   lf->fp.deg[v] = deg(&lf->sp); | 
|  | 3515   return(k); | 
|  | 3516 } | 
|  | 3517 | 
|  | 3518 void pprocstd(lf,des,res) | 
|  | 3519 lfit *lf; | 
|  | 3520 design *des; | 
|  | 3521 double *res; | 
|  | 3522 { | 
|  | 3523   ressumm(lf,des,res); | 
|  | 3524 } | 
|  | 3525 | 
|  | 3526 void initstd(lf) | 
|  | 3527 lfit *lf; | 
|  | 3528 { PROCV(lf) = procvstd; | 
|  | 3529   ALLOC(lf) = allocstd; | 
|  | 3530   PPROC(lf) = pprocstd; | 
|  | 3531   KEEPV(lf) = 3*NVAR(lf) + 8; | 
|  | 3532   KEEPC(lf) = 6; | 
|  | 3533   NOPC(lf)  = 0; | 
|  | 3534 } | 
|  | 3535 /* | 
|  | 3536  * Copyright 1996-2006 Catherine Loader. | 
|  | 3537  */ | 
|  | 3538 #include "lfev.h" | 
|  | 3539 | 
|  | 3540 extern void procstd(), allocstd(); | 
|  | 3541 extern double robscale; | 
|  | 3542 | 
|  | 3543 double vocri(lk,t0,t2,pen) | 
|  | 3544 double lk, t0, t2, pen; | 
|  | 3545 { if (pen==0) return(-2*t0*lk/((t0-t2)*(t0-t2))); | 
|  | 3546   return((-2*lk+pen*t2)/t0); | 
|  | 3547 } | 
|  | 3548 | 
|  | 3549 double intvo(des,lf,c0,c1,a,p,t0,t20,t21) | 
|  | 3550 design *des; | 
|  | 3551 lfit *lf; | 
|  | 3552 double *c0, *c1, a, t0, t20, t21; | 
|  | 3553 int p; | 
|  | 3554 { double th, lk, link[LLEN]; | 
|  | 3555   int i, ii; | 
|  | 3556   lk = 0; | 
|  | 3557   for (i=0; i<des->n; i++) | 
|  | 3558   { ii = des->ind[i]; | 
|  | 3559     th = (1-a)*innerprod(c0,d_xi(des,i),p) + a*innerprod(c1,d_xi(des,i),p); | 
|  | 3560     stdlinks(link,&lf->lfd,&lf->sp,ii,th,robscale); | 
|  | 3561     lk += wght(des,ii)*link[ZLIK]; | 
|  | 3562   } | 
|  | 3563   des->llk = lk; | 
|  | 3564   return(vocri(des->llk,t0,(1-a)*t20+a*t21,pen(&lf->sp))); | 
|  | 3565 } | 
|  | 3566 | 
|  | 3567 int procvvord(des,lf,v) | 
|  | 3568 design *des; | 
|  | 3569 lfit *lf; | 
|  | 3570 int v; | 
|  | 3571 { double tr[6], gcv, g0, ap, coef[4][10], t2[4], th, md; | 
|  | 3572   int i, j, k, d1, i0, p1, ip; | 
|  | 3573   des->xev = evpt(&lf->fp,v); | 
|  | 3574 | 
|  | 3575   ap = pen(&lf->sp); | 
|  | 3576   if ((ap==0) & ((fam(&lf->sp)&63)!=TGAUS)) ap = 2.0; | 
|  | 3577   d1 = deg(&lf->sp); p1 = npar(&lf->sp); | 
|  | 3578   for (i=0; i<p1; i++) coef[0][i] = coef[1][i] = coef[2][i] = coef[3][i] = 0.0; | 
|  | 3579   i0 = 0; g0 = 0; | 
|  | 3580   ip = 1; | 
|  | 3581 | 
|  | 3582   for (i=deg0(&lf->sp); i<=d1; i++) | 
|  | 3583   { deg(&lf->sp) = i; | 
|  | 3584     des->p = npar(&lf->sp) = calcp(&lf->sp,lf->lfd.d); | 
|  | 3585     k = locfit(&lf->lfd,des,&lf->sp,0, i==deg0(&lf->sp),0); | 
|  | 3586 | 
|  | 3587     local_df(&lf->lfd,&lf->sp,des,tr); | 
|  | 3588     gcv = vocri(des->llk,tr[0],tr[2],ap); | 
|  | 3589     if ((i==deg0(&lf->sp)) || (gcv<g0)) { i0 = i; g0 = gcv; md = i; } | 
|  | 3590 | 
|  | 3591     for (j=0; j<des->p; j++) coef[i][j] = des->cf[j]; | 
|  | 3592     t2[i] = tr[2]; | 
|  | 3593 | 
|  | 3594 #ifdef RESEARCH | 
|  | 3595     if ((ip) && (i>deg0(&lf->sp))) | 
|  | 3596     { for (j=1; j<10; j++) | 
|  | 3597       { gcv = intvo(des,lf,coef[i-1],coef[i],j/10.0,des->p,tr[0],t2[i-1],t2[i]); | 
|  | 3598         if (gcv<g0) { g0 = gcv; md = i-1+j/10.0; } | 
|  | 3599       } | 
|  | 3600     } | 
|  | 3601 #endif | 
|  | 3602   } | 
|  | 3603   lf->fp.h[v] = des->h; | 
|  | 3604   if (lf->fp.h[v]<=0) WARN(("zero bandwidth in procvvord")); | 
|  | 3605 | 
|  | 3606   if (i0<d1) /* recompute the best fit */ | 
|  | 3607   { deg(&lf->sp) = i0; | 
|  | 3608     des->p = npar(&lf->sp) = calcp(&lf->sp,lf->lfd.d); | 
|  | 3609     k = locfit(&lf->lfd,des,&lf->sp,0,0,0); | 
|  | 3610     for (i=npar(&lf->sp); i<p1; i++) des->cf[i] = 0.0; | 
|  | 3611     i0 = md; if (i0==d1) i0--; | 
|  | 3612     th = md-i0; | 
|  | 3613     for (i=0; i<p1; i++) des->cf[i] = (1-th)*coef[i0][i]+th*coef[i0+1][i]; | 
|  | 3614     deg(&lf->sp) = d1; npar(&lf->sp) = p1; | 
|  | 3615   } | 
|  | 3616 | 
|  | 3617   for (i=0; i<p1; i++) lf->fp.coef[i*lf->fp.nvm+v] = des->cf[i]; | 
|  | 3618   lf->fp.deg[v] = md; | 
|  | 3619   return(k); | 
|  | 3620 } | 
|  | 3621 | 
|  | 3622 void initvord(lf) | 
|  | 3623 lfit *lf; | 
|  | 3624 { initstd(lf); | 
|  | 3625   PROCV(lf) = procvvord; | 
|  | 3626   ALLOC(lf) = allocstd; | 
|  | 3627   PPROC(lf) = NULL; | 
|  | 3628   KEEPC(lf) = 0; | 
|  | 3629   NOPC(lf)  = 1; | 
|  | 3630 } | 
|  | 3631 /* | 
|  | 3632  * Copyright 1996-2006 Catherine Loader. | 
|  | 3633  */ | 
|  | 3634 /* | 
|  | 3635  * functions for computing and subtracting, adding the | 
|  | 3636  * parametric component | 
|  | 3637  */ | 
|  | 3638 | 
|  | 3639 #include "lfev.h" | 
|  | 3640 | 
|  | 3641 int noparcomp(sp) | 
|  | 3642 smpar *sp; | 
|  | 3643 { int tg; | 
|  | 3644   if (ubas(sp)) return(1); | 
|  | 3645   tg = fam(sp) & 63; | 
|  | 3646   if (tg<=THAZ) return(1); | 
|  | 3647   if (tg==TROBT) return(1); | 
|  | 3648   if (tg==TCAUC) return(1); | 
|  | 3649   if (tg==TQUANT) return(1); | 
|  | 3650   return(0); | 
|  | 3651 } | 
|  | 3652 | 
|  | 3653 int pc_reqd(d,p) | 
|  | 3654 int d, p; | 
|  | 3655 { return(d + 2*p + jac_reqd(p)); | 
|  | 3656 } | 
|  | 3657 | 
|  | 3658 void pcchk(pc,d,p,lc) | 
|  | 3659 paramcomp *pc; | 
|  | 3660 int d, p, lc; | 
|  | 3661 { int rw; | 
|  | 3662   double *z; | 
|  | 3663 | 
|  | 3664   rw = pc_reqd(d,p); | 
|  | 3665   if (pc->lwk < rw) | 
|  | 3666   { pc->wk = (double *)calloc(rw,sizeof(double)); | 
|  | 3667     if ( pc->wk == NULL ) { | 
|  | 3668       printf("Problem allocating memory for pc->wk\n");fflush(stdout); | 
|  | 3669     } | 
|  | 3670     pc->lwk= rw; | 
|  | 3671   } | 
|  | 3672   z = pc->wk; | 
|  | 3673 | 
|  | 3674   pc->xbar = z; z += d; | 
|  | 3675   pc->coef = z; z += p; | 
|  | 3676   pc->f    = z; z += p; | 
|  | 3677 | 
|  | 3678   z = jac_alloc(&pc->xtwx,p,z); | 
|  | 3679   pc->xtwx.p = p; | 
|  | 3680 } | 
|  | 3681 | 
|  | 3682 void compparcomp(des,lfd,sp,pc,nopc) | 
|  | 3683 design *des; | 
|  | 3684 lfdata *lfd; | 
|  | 3685 smpar *sp; | 
|  | 3686 paramcomp *pc; | 
|  | 3687 int nopc; | 
|  | 3688 { int i, j, k, p; | 
|  | 3689   double wt, sw; | 
|  | 3690 | 
|  | 3691   if (lf_debug>1) mut_printf(" compparcomp:\n"); | 
|  | 3692   p = des->p; | 
|  | 3693   pcchk(pc,lfd->d,p,1); | 
|  | 3694 | 
|  | 3695   for (i=0; i<lfd->d; i++) pc->xbar[i] = 0.0; | 
|  | 3696   sw = 0.0; | 
|  | 3697   for (i=0; i<lfd->n; i++) | 
|  | 3698   { | 
|  | 3699     wt = prwt(lfd,i); | 
|  | 3700     sw += wt; | 
|  | 3701     for (j=0; j<lfd->d; j++) | 
|  | 3702       pc->xbar[j] += datum(lfd,j,i)*wt; | 
|  | 3703     des->ind[i] = i; | 
|  | 3704     wght(des,i) = 1.0; | 
|  | 3705   } | 
|  | 3706   for (i=0; i<lfd->d; i++) pc->xbar[i] /= sw; | 
|  | 3707   if ((nopc) || noparcomp(sp)) | 
|  | 3708   { haspc(pc) = 0; | 
|  | 3709     return; | 
|  | 3710   } | 
|  | 3711   haspc(pc) = 1; | 
|  | 3712   des->xev = pc->xbar; | 
|  | 3713   k = locfit(lfd,des,sp,0,0,0); | 
|  | 3714   if (k != LF_OK) lf_status_msg(k); | 
|  | 3715   if (lf_error) return; | 
|  | 3716   switch(k) | 
|  | 3717   { case LF_NOPT: return; | 
|  | 3718     case LF_INFA: return; | 
|  | 3719     case LF_NCON: return; | 
|  | 3720     case LF_OOB: return; | 
|  | 3721     case LF_NSLN: return; | 
|  | 3722     case LF_PF: | 
|  | 3723       WARN(("compparcomp: perfect fit")); | 
|  | 3724     case LF_OK: | 
|  | 3725     case LF_DONE: | 
|  | 3726       for (i=0; i<p; i++) | 
|  | 3727       { pc->coef[i] = des->cf[i]; | 
|  | 3728         pc->xtwx.dg[i] = des->xtwx.dg[i]; | 
|  | 3729         pc->xtwx.wk[i] = des->xtwx.wk[i]; | 
|  | 3730       } | 
|  | 3731       for (i=0; i<p*p; i++) | 
|  | 3732       { pc->xtwx.Z[i] = des->xtwx.Z[i]; | 
|  | 3733         pc->xtwx.Q[i] = des->xtwx.Q[i]; | 
|  | 3734       } | 
|  | 3735       pc->xtwx.sm = des->xtwx.sm; | 
|  | 3736       pc->xtwx.st = des->xtwx.st; | 
|  | 3737       return; | 
|  | 3738     default: | 
|  | 3739       LERR(("compparcomp: locfit unknown return status %d",k)); | 
|  | 3740       return; | 
|  | 3741   } | 
|  | 3742 } | 
|  | 3743 | 
|  | 3744 void subparcomp(des,lf,coef) | 
|  | 3745 design *des; | 
|  | 3746 lfit *lf; | 
|  | 3747 double *coef; | 
|  | 3748 { int i, nd; | 
|  | 3749   deriv *dv; | 
|  | 3750   paramcomp *pc; | 
|  | 3751 | 
|  | 3752   pc = &lf->pc; | 
|  | 3753   if (!haspc(pc)) return; | 
|  | 3754 | 
|  | 3755   dv = &lf->dv; nd = dv->nd; | 
|  | 3756   fitfun(&lf->lfd, &lf->sp, des->xev,pc->xbar,des->f1,dv); | 
|  | 3757   coef[0] -= innerprod(pc->coef,des->f1,pc->xtwx.p); | 
|  | 3758   if (des->ncoef == 1) return; | 
|  | 3759 | 
|  | 3760   dv->nd = nd+1; | 
|  | 3761   for (i=0; i<lf->lfd.d; i++) | 
|  | 3762   { dv->deriv[nd] = i; | 
|  | 3763     fitfun(&lf->lfd, &lf->sp, des->xev,pc->xbar,des->f1,dv); | 
|  | 3764     coef[i+1] -= innerprod(pc->coef,des->f1,pc->xtwx.p); | 
|  | 3765   } | 
|  | 3766   dv->nd = nd; | 
|  | 3767 } | 
|  | 3768 | 
|  | 3769 void subparcomp2(des,lf,vr,il) | 
|  | 3770 design *des; | 
|  | 3771 lfit *lf; | 
|  | 3772 double *vr, *il; | 
|  | 3773 { double t0, t1; | 
|  | 3774   int i, nd; | 
|  | 3775   deriv *dv; | 
|  | 3776   paramcomp *pc; | 
|  | 3777 | 
|  | 3778   pc = &lf->pc; | 
|  | 3779   if (!haspc(pc)) return; | 
|  | 3780 | 
|  | 3781   dv = &lf->dv; nd = dv->nd; | 
|  | 3782 | 
|  | 3783   fitfun(&lf->lfd, &lf->sp, des->xev,pc->xbar,des->f1,dv); | 
|  | 3784   for (i=0; i<npar(&lf->sp); i++) pc->f[i] = des->f1[i]; | 
|  | 3785   jacob_solve(&pc->xtwx,des->f1); | 
|  | 3786   t0 = sqrt(innerprod(pc->f,des->f1,pc->xtwx.p)); | 
|  | 3787   vr[0] -= t0; | 
|  | 3788   il[0] -= t0; | 
|  | 3789   if ((t0==0) | (des->ncoef==1)) return; | 
|  | 3790 | 
|  | 3791   dv->nd = nd+1; | 
|  | 3792   for (i=0; i<lf->lfd.d; i++) | 
|  | 3793   { dv->deriv[nd] = i; | 
|  | 3794     fitfun(&lf->lfd, &lf->sp, des->xev,pc->xbar,pc->f,dv); | 
|  | 3795     t1 = innerprod(pc->f,des->f1,pc->xtwx.p)/t0; | 
|  | 3796     vr[i+1] -= t1; | 
|  | 3797     il[i+1] -= t1; | 
|  | 3798   } | 
|  | 3799   dv->nd = nd; | 
|  | 3800 } | 
|  | 3801 | 
|  | 3802 double addparcomp(lf,x,c) | 
|  | 3803 lfit *lf; | 
|  | 3804 double *x; | 
|  | 3805 int c; | 
|  | 3806 { double y; | 
|  | 3807   paramcomp *pc; | 
|  | 3808 | 
|  | 3809   pc = &lf->pc; | 
|  | 3810   if (!haspc(pc)) return(0.0); | 
|  | 3811   fitfun(&lf->lfd, &lf->sp, x,pc->xbar,pc->f,&lf->dv); | 
|  | 3812   if (c==PCOEF) return(innerprod(pc->coef,pc->f,pc->xtwx.p)); | 
|  | 3813   if ((c==PNLX)|(c==PT0)|(c==PVARI)) | 
|  | 3814   { y = sqrt(jacob_qf(&pc->xtwx,pc->f)); | 
|  | 3815     return(y); | 
|  | 3816   } | 
|  | 3817   return(0.0); | 
|  | 3818 } | 
|  | 3819 /* | 
|  | 3820  * Copyright 1996-2006 Catherine Loader. | 
|  | 3821  */ | 
|  | 3822 #include "lfev.h" | 
|  | 3823 | 
|  | 3824 /* | 
|  | 3825   preplot():  interpolates the fit to a new set of points. | 
|  | 3826   lf  -- the fit structure. | 
|  | 3827   x   -- the points to predict at. | 
|  | 3828   f   -- vector to return the predictions. | 
|  | 3829   se  -- vector to return std errors (NULL if not req'd) | 
|  | 3830   band-- char for conf band type. ('n'=none, 'g'=global etc.) | 
|  | 3831   n   -- no of predictions (or vector of margin lengths for grid) | 
|  | 3832   where -- where to predict: | 
|  | 3833            1 = points in the array x. | 
|  | 3834            2 = grid defined by margins in x. | 
|  | 3835            3 = data points from lf (ignore x). | 
|  | 3836            4 = fit points from lf (ignore x). | 
|  | 3837   what -- what to predict. | 
|  | 3838            (PCOEF etc; see lfcons.h file) | 
|  | 3839 | 
|  | 3840 */ | 
|  | 3841 | 
|  | 3842 #define NWH 8 | 
|  | 3843 static char *whtyp[NWH] = { "coef", "nlx", "infl", "band", | 
|  | 3844                           "degr", "like", "rdf", "vari" }; | 
|  | 3845 static int   whval[NWH] = { PCOEF, PNLX, PT0, PBAND, PDEGR, PLIK, PRDF, PVARI }; | 
|  | 3846 int ppwhat(z) | 
|  | 3847 char *z; | 
|  | 3848 { int val; | 
|  | 3849 | 
|  | 3850   val = pmatch(z, whtyp, whval, NWH, -1); | 
|  | 3851   if (val==-1) LERR(("Unknown what = %s",z)); | 
|  | 3852   return(val); | 
|  | 3853 } | 
|  | 3854 | 
|  | 3855 static char cb; | 
|  | 3856 double *sef, *fit, sigmahat; | 
|  | 3857 | 
|  | 3858 void predptall(lf,x,what,ev,i) | 
|  | 3859 lfit *lf; | 
|  | 3860 double *x; | 
|  | 3861 int what, ev, i; | 
|  | 3862 { double lik, rdf; | 
|  | 3863   fit[i] = dointpoint(lf,x,what,ev,i); | 
|  | 3864   if (cb=='n') return; | 
|  | 3865   sef[i] = dointpoint(lf,x,PNLX,ev,i); | 
|  | 3866   if (cb=='g') | 
|  | 3867   { sef[i] *= sigmahat; | 
|  | 3868     return; | 
|  | 3869   } | 
|  | 3870   if (cb=='l') | 
|  | 3871   { lik = dointpoint(lf,x,PLIK,ev,i); | 
|  | 3872     rdf = dointpoint(lf,x,PRDF,ev,i); | 
|  | 3873     sef[i] *= sqrt(-2*lik/rdf); | 
|  | 3874     return; | 
|  | 3875   } | 
|  | 3876   if (cb=='p') | 
|  | 3877   { sef[i] = sigmahat*sqrt(1+sef[i]*sef[i]); | 
|  | 3878     return; | 
|  | 3879   } | 
|  | 3880 } | 
|  | 3881 | 
|  | 3882 void predptdir(lf,des,x,what,i) | 
|  | 3883 lfit *lf; | 
|  | 3884 design *des; | 
|  | 3885 double *x; | 
|  | 3886 int what, i; | 
|  | 3887 { int needcv; | 
|  | 3888   des->xev = x; | 
|  | 3889   needcv = (what==PVARI) | (what==PNLX) | (what==PT0) | (what==PRDF); | 
|  | 3890   locfit(&lf->lfd,des,&lf->sp,0,1,needcv); | 
|  | 3891   switch(what) | 
|  | 3892   { case PCOEF: fit[i] = des->cf[0]; break; | 
|  | 3893     case PVARI: fit[i] = des->V[0]; break; | 
|  | 3894     case PNLX:  fit[i] = sqrt(des->V[0]); break; | 
|  | 3895     case PT0:   fit[i] = des->f1[0]; break; | 
|  | 3896     case PBAND: fit[i] = des->h; break; | 
|  | 3897     case PDEGR: fit[i] = deg(&lf->sp); break; | 
|  | 3898     case PLIK:  fit[i] = des->llk; break; | 
|  | 3899     case PRDF:  fit[i] = des->tr0 - des->tr2; break; | 
|  | 3900     default: LERR(("unknown what in predptdir")); | 
|  | 3901   } | 
|  | 3902 } | 
|  | 3903 | 
|  | 3904 void prepvector(lf,des,x,n,what,dir) /* interpolate a vector */ | 
|  | 3905 lfit *lf; | 
|  | 3906 design *des; | 
|  | 3907 double **x; | 
|  | 3908 int n, what, dir; | 
|  | 3909 { int i, j; | 
|  | 3910   double xx[MXDIM]; | 
|  | 3911   for (i=0; i<n; i++) | 
|  | 3912   { for (j=0; j<lf->fp.d; j++) xx[j] = x[j][i]; | 
|  | 3913     if (dir) | 
|  | 3914       predptdir(lf,des,xx,what,i); | 
|  | 3915     else | 
|  | 3916       predptall(lf,xx,what,ev(&lf->evs),i); | 
|  | 3917     if (lf_error) return; | 
|  | 3918   } | 
|  | 3919 } | 
|  | 3920 | 
|  | 3921 void prepfitp(lf,what) | 
|  | 3922 lfit *lf; | 
|  | 3923 int what; | 
|  | 3924 { int  i; | 
|  | 3925   for (i=0; i<lf->fp.nv; i++) | 
|  | 3926   { predptall(lf,evpt(&lf->fp,i),what,EFITP,i); | 
|  | 3927     if (lf_error) return; | 
|  | 3928   } | 
|  | 3929 } | 
|  | 3930 | 
|  | 3931 void prepgrid(lf,des,x,mg,n,what,dir) /* interpolate a grid given margins */ | 
|  | 3932 lfit *lf; | 
|  | 3933 design *des; | 
|  | 3934 double **x; | 
|  | 3935 int *mg, dir, n, what; | 
|  | 3936 { int i, ii, j, d; | 
|  | 3937   double xv[MXDIM]; | 
|  | 3938   d = lf->fp.d; | 
|  | 3939   for (i=0; i<n; i++) | 
|  | 3940   { ii = i; | 
|  | 3941     for (j=0; j<d; j++) | 
|  | 3942     { xv[j] = x[j][ii%mg[j]]; | 
|  | 3943       ii /= mg[j]; | 
|  | 3944     } | 
|  | 3945     if (dir) | 
|  | 3946       predptdir(lf,des,xv,what,i); | 
|  | 3947     else | 
|  | 3948       predptall(lf,xv,what,ev(&lf->evs),i); | 
|  | 3949     if (lf_error) return; | 
|  | 3950   } | 
|  | 3951 } | 
|  | 3952 | 
|  | 3953 void preplot(lf,x,f,se,band,mg,where,what,dir) | 
|  | 3954 lfit *lf; | 
|  | 3955 double **x, *f, *se; | 
|  | 3956 int *mg, where, what, dir; | 
|  | 3957 char band; | 
|  | 3958 { int d, i, n; | 
|  | 3959   double *xx[MXDIM]; | 
|  | 3960   design ppdes; | 
|  | 3961   d = lf->fp.d; | 
|  | 3962   fit = f; | 
|  | 3963   sef = se; | 
|  | 3964   cb = band; | 
|  | 3965   if (cb!='n') sigmahat = sqrt(rv(&lf->fp)); | 
|  | 3966   if (dir) des_init(&ppdes,lf->lfd.n,npar(&lf->sp)); | 
|  | 3967 | 
|  | 3968   switch(where) | 
|  | 3969   { case 1: /* vector */ | 
|  | 3970       n = mg[0]; | 
|  | 3971       prepvector(lf,&ppdes,x,n,what,dir); | 
|  | 3972       break; | 
|  | 3973     case 2: /* grid */ | 
|  | 3974       n = 1; | 
|  | 3975       for (i=0; i<d; i++) n *= mg[i]; | 
|  | 3976       prepgrid(lf,&ppdes,x,mg,n,what,dir); | 
|  | 3977       break; | 
|  | 3978     case 3: /* data */ | 
|  | 3979       n = lf->lfd.n; | 
|  | 3980       if ((ev(&lf->evs)==EDATA) | (ev(&lf->evs)==ECROS)) | 
|  | 3981       { prepfitp(lf,what); | 
|  | 3982         dir = 0; | 
|  | 3983       } | 
|  | 3984       else | 
|  | 3985       { for (i=0; i<d; i++) xx[i] = dvari(&lf->lfd,i); | 
|  | 3986         prepvector(lf,&ppdes,xx,n,what,dir); | 
|  | 3987       } | 
|  | 3988       break; | 
|  | 3989     case 4: /* fit points */ | 
|  | 3990       n = lf->fp.nv; dir = 0; | 
|  | 3991       prepfitp(lf,what); | 
|  | 3992       break; | 
|  | 3993     default: | 
|  | 3994       LERR(("unknown where in preplot")); | 
|  | 3995   } | 
|  | 3996 | 
|  | 3997   if ((!dir) && ((what==PT0)|(what==PVARI))) | 
|  | 3998     for (i=0; i<n; i++) f[i] = f[i]*f[i]; | 
|  | 3999 } | 
|  | 4000 /* | 
|  | 4001  * Copyright 1996-2006 Catherine Loader. | 
|  | 4002  */ | 
|  | 4003 #include "lfev.h" | 
|  | 4004 | 
|  | 4005 int procv_nov(des,lf,v) | 
|  | 4006 design *des; | 
|  | 4007 lfit *lf; | 
|  | 4008 int v; | 
|  | 4009 { int lf_status; | 
|  | 4010 | 
|  | 4011   if (lf_debug>1) mut_printf(" procveraw: %d\n",v); | 
|  | 4012   des->xev = evpt(&lf->fp,v); | 
|  | 4013 | 
|  | 4014   if (acri(&lf->sp)==ANONE) | 
|  | 4015     lf_status = locfit(&lf->lfd,des,&lf->sp,0,1,0); | 
|  | 4016   else | 
|  | 4017     lf_status = alocfit(&lf->lfd,&lf->sp,&lf->dv,des,0); | 
|  | 4018   if (lf->fp.h != NULL) lf->fp.h[v] = des->h; | 
|  | 4019 | 
|  | 4020   return(lf_status); | 
|  | 4021 } | 
|  | 4022 | 
|  | 4023 int procv_var(des,lf,v) | 
|  | 4024 design *des; | 
|  | 4025 lfit *lf; | 
|  | 4026 int v; | 
|  | 4027 { int i, lf_status; | 
|  | 4028 | 
|  | 4029   if (lf_debug>1) mut_printf(" procvraw: %d\n",v); | 
|  | 4030   des->xev = evpt(&lf->fp,v); | 
|  | 4031 | 
|  | 4032   if (acri(&lf->sp)==ANONE) | 
|  | 4033     lf_status = locfit(&lf->lfd,des,&lf->sp,0,1,1); | 
|  | 4034   else | 
|  | 4035     lf_status = alocfit(&lf->lfd,&lf->sp,&lf->dv,des,1); | 
|  | 4036   if (lf->fp.h != NULL) lf->fp.h[v] = des->h; | 
|  | 4037 | 
|  | 4038   return(lf_status); | 
|  | 4039 } | 
|  | 4040 /* | 
|  | 4041  * Copyright 1996-2006 Catherine Loader. | 
|  | 4042  */ | 
|  | 4043 /* | 
|  | 4044  * startmodule(lf,des,mod,dir) -- the standard entry point. | 
|  | 4045  *   des and lf are pointers to the design and fit structures. | 
|  | 4046  *   mod - module name. Set to NULL if the module is already | 
|  | 4047  *         initialized. | 
|  | 4048  *   dir - for dynamic modules, the directory. | 
|  | 4049  * | 
|  | 4050  * initmodule(mdl,mod,dir,lf) | 
|  | 4051  *   direct call for module initialization. | 
|  | 4052  * | 
|  | 4053  */ | 
|  | 4054 | 
|  | 4055 #include "lfev.h" | 
|  | 4056 | 
|  | 4057 #ifdef WINDOWS | 
|  | 4058 | 
|  | 4059 #define DIRSEP '\\' | 
|  | 4060 #define PATHSEP ';' | 
|  | 4061 | 
|  | 4062 #else | 
|  | 4063 | 
|  | 4064 #define DIRSEP '/' | 
|  | 4065 #define PATHSEP ':' | 
|  | 4066 | 
|  | 4067 #endif | 
|  | 4068 | 
|  | 4069 | 
|  | 4070 #ifdef ALLOW_MODULES | 
|  | 4071 | 
|  | 4072 #ifdef WINDOWS | 
|  | 4073 #include <windows.h> | 
|  | 4074 #define DLEXT "dll" | 
|  | 4075 #define DLOPEN(x) LoadLibrary(x) | 
|  | 4076 #define DLSYM GetProcAddress | 
|  | 4077 | 
|  | 4078 #else | 
|  | 4079 | 
|  | 4080 #include <dlfcn.h> | 
|  | 4081 #define DLEXT "so" | 
|  | 4082 #define DLOPEN(x) dlopen(x,RTLD_LAZY) | 
|  | 4083 #define DLSYM dlsym | 
|  | 4084 #endif | 
|  | 4085 | 
|  | 4086 #endif | 
|  | 4087 | 
|  | 4088 static double fpkap[6]; | 
|  | 4089 void fitpt_init(fp) | 
|  | 4090 fitpt *fp; | 
|  | 4091 { | 
|  | 4092   dc(fp) = 0; | 
|  | 4093   geth(fp) = GSTD; | 
|  | 4094   fp->nv = fp->nvm = 0; | 
|  | 4095   if (fp->kap==NULL) fp->kap = fpkap; | 
|  | 4096 } | 
|  | 4097 | 
|  | 4098 void lfit_init(lf) | 
|  | 4099 lfit *lf; | 
|  | 4100 { | 
|  | 4101   lfdata_init(&lf->lfd); | 
|  | 4102   evstruc_init(&lf->evs); | 
|  | 4103   smpar_init(&lf->sp,&lf->lfd); | 
|  | 4104   deriv_init(&lf->dv); | 
|  | 4105   fitpt_init(&lf->fp); | 
|  | 4106   lf->mdl.np = 0; | 
|  | 4107 } | 
|  | 4108 | 
|  | 4109 void fitdefault(lf) | 
|  | 4110 lfit *lf; | 
|  | 4111 { WARN(("fitdefault deprecated -- use lfit_init()")); | 
|  | 4112   lfit_init(lf); | 
|  | 4113 } | 
|  | 4114 | 
|  | 4115 void set_flim(lfd,evs) | 
|  | 4116 lfdata *lfd; | 
|  | 4117 evstruc *evs; | 
|  | 4118 { int i, j, d, n; | 
|  | 4119   double z, mx, mn, *bx; | 
|  | 4120 | 
|  | 4121   if (ev(evs)==ESPHR) return; | 
|  | 4122   d = lfd->d; n = lfd->n; | 
|  | 4123   bx = evs->fl; | 
|  | 4124   for (i=0; i<d; i++) | 
|  | 4125     if (bx[i]==bx[i+d]) | 
|  | 4126     { if (lfd->sty[i]==STANGL) | 
|  | 4127       { bx[i] = 0.0; bx[i+d] = 2*PI*lfd->sca[i]; | 
|  | 4128       } | 
|  | 4129       else | 
|  | 4130       { mx = mn = datum(lfd,i,0); | 
|  | 4131         for (j=1; j<n; j++) | 
|  | 4132         { mx = MAX(mx,datum(lfd,i,j)); | 
|  | 4133           mn = MIN(mn,datum(lfd,i,j)); | 
|  | 4134         } | 
|  | 4135         if (lfd->xl[i]<lfd->xl[i+d]) /* user set xlim; maybe use them. */ | 
|  | 4136         { z = mx-mn; | 
|  | 4137           if (mn-0.2*z < lfd->xl[i]) mn = lfd->xl[i]; | 
|  | 4138           if (mx+0.2*z > lfd->xl[i+d]) mx = lfd->xl[i+d]; | 
|  | 4139         } | 
|  | 4140         bx[i] = mn; | 
|  | 4141         bx[i+d] = mx; | 
|  | 4142       } | 
|  | 4143     } | 
|  | 4144 } | 
|  | 4145 | 
|  | 4146 double vvari(v,n) | 
|  | 4147 double *v; | 
|  | 4148 int n; | 
|  | 4149 { int i; | 
|  | 4150   double xb, s2; | 
|  | 4151   xb = s2 = 0.0; | 
|  | 4152   for (i=0; i<n; i++) xb += v[i]; | 
|  | 4153   xb /= n; | 
|  | 4154   for (i=0; i<n; i++) s2 += SQR(v[i]-xb); | 
|  | 4155   return(s2/(n-1)); | 
|  | 4156 } | 
|  | 4157 | 
|  | 4158 void set_scales(lfd) | 
|  | 4159 lfdata *lfd; | 
|  | 4160 { int i; | 
|  | 4161   for (i=0; i<lfd->d; i++) | 
|  | 4162     if (lfd->sca[i]<=0) /* set automatic scales */ | 
|  | 4163     { if (lfd->sty[i]==STANGL) | 
|  | 4164         lfd->sca[i] = 1.0; | 
|  | 4165       else lfd->sca[i] = sqrt(vvari(lfd->x[i],lfd->n)); | 
|  | 4166     } | 
|  | 4167 } | 
|  | 4168 | 
|  | 4169 void nstartlf(des,lf) | 
|  | 4170 design *des; | 
|  | 4171 lfit *lf; | 
|  | 4172 { int i, d, n; | 
|  | 4173 | 
|  | 4174   if (lf_debug>0) mut_printf("nstartlf\n"); | 
|  | 4175   n = lf->lfd.n; | 
|  | 4176   d = lf->lfd.d; | 
|  | 4177   npar(&lf->sp) = calcp(&lf->sp,d); | 
|  | 4178 | 
|  | 4179   des_init(des,n,npar(&lf->sp)); | 
|  | 4180   set_scales(&lf->lfd); | 
|  | 4181   set_flim(&lf->lfd,&lf->evs); | 
|  | 4182   compparcomp(des,&lf->lfd,&lf->sp,&lf->pc,lf->mdl.nopc); | 
|  | 4183   if (lf_error) return; | 
|  | 4184   makecfn(&lf->sp,des,&lf->dv,lf->lfd.d); | 
|  | 4185 | 
|  | 4186   lf->lfd.ord = 0; | 
|  | 4187   if ((d==1) && (lf->lfd.sty[0]!=STANGL)) | 
|  | 4188   { i = 1; | 
|  | 4189     while ((i<n) && (datum(&lf->lfd,0,i)>=datum(&lf->lfd,0,i-1))) i++; | 
|  | 4190     lf->lfd.ord = (i==n); | 
|  | 4191   } | 
|  | 4192   for (i=0; i<npar(&lf->sp); i++) des->fix[i] = 0; | 
|  | 4193 | 
|  | 4194   lf->fp.d = lf->lfd.d; | 
|  | 4195   lf->fp.hasd = (des->ncoef==(1+lf->fp.d)); | 
|  | 4196   lf->fp.nv = lf->evs.nce = 0; | 
|  | 4197 | 
|  | 4198   if (lf_debug>1) mut_printf("call eval structure %d\n",ev(&lf->evs)); | 
|  | 4199   switch(ev(&lf->evs)) | 
|  | 4200   { case EPHULL: triang_start(des,lf); break; | 
|  | 4201     case EDATA:  dataf(des,lf); break; | 
|  | 4202     case ECROS:  crossf(des,lf); break; | 
|  | 4203     case EGRID:  gridf(des,lf); break; | 
|  | 4204     case ETREE:  atree_start(des,lf); break; | 
|  | 4205     case EKDCE:  kt(&lf->sp) = KCE; | 
|  | 4206     case EKDTR:  kdtre_start(des,lf); break; | 
|  | 4207     case EPRES:  preset(des,lf); break; | 
|  | 4208     case EXBAR:  xbarf(des,lf); break; | 
|  | 4209     case ENONE:  return; | 
|  | 4210     case ESPHR:  sphere_start(des,lf); break; | 
|  | 4211     case ESPEC:  lf->evs.espec(des,lf); break; | 
|  | 4212     default: LERR(("startlf: Invalid evaluation structure %d",ev(&lf->evs))); | 
|  | 4213   } | 
|  | 4214 | 
|  | 4215   /* renormalize for family=density */ | 
|  | 4216   if ((de_renorm) && (fam(&lf->sp)==TDEN)) dens_renorm(lf,des); | 
|  | 4217 } | 
|  | 4218 | 
|  | 4219 /* | 
|  | 4220  * getnextdir() gets the next dir from a string dirpath="dir1:dir2:dir3:..." | 
|  | 4221  *   (;-separated on windows). | 
|  | 4222  *   The directory is returned through dirnext, and the function returns | 
|  | 4223  *   a pointer to the next string. | 
|  | 4224  *   typical usage is recursive, dirpath = getnextdir(dirpath,dirnext). | 
|  | 4225  *   with the above example, this sets dirnext="dir1" and dirpath="dir2:dir3:...". | 
|  | 4226  * if the input dirpath has no :, then it is copied to dirnext, and return is "". | 
|  | 4227  * if input dirpath is "", dirnext is set to "", and null pointer returned. | 
|  | 4228  */ | 
|  | 4229 char *getnextdir(dirpath,dirnext) | 
|  | 4230 char *dirpath, *dirnext; | 
|  | 4231 { char *z; | 
|  | 4232   if (strlen(dirpath)==0) | 
|  | 4233   { sprintf(dirnext,""); | 
|  | 4234     return(NULL); | 
|  | 4235   } | 
|  | 4236 | 
|  | 4237   z = strchr(dirpath,PATHSEP); | 
|  | 4238   if (z==NULL) | 
|  | 4239   { sprintf(dirnext,"%s%c",dirpath,DIRSEP); | 
|  | 4240     return(&dirpath[strlen(dirnext)]); | 
|  | 4241   } | 
|  | 4242 | 
|  | 4243   *z = '\0'; | 
|  | 4244   sprintf(dirnext,"%s%c",dirpath,DIRSEP); | 
|  | 4245   return(++z); | 
|  | 4246 } | 
|  | 4247 | 
|  | 4248 int initmodule(mdl, mod, dir, lf) | 
|  | 4249 module *mdl; | 
|  | 4250 lfit *lf; | 
|  | 4251 char *mod, *dir; | 
|  | 4252 { int n, d, p; | 
|  | 4253 #ifdef ALLOW_MODULES | 
|  | 4254 #ifdef WINDOWS | 
|  | 4255 HINSTANCE res; | 
|  | 4256 typedef void (CALLBACK* DLLFN)(); | 
|  | 4257 DLLFN init; | 
|  | 4258 #else | 
|  | 4259 void *res; | 
|  | 4260 void (*init)(); | 
|  | 4261 #endif | 
|  | 4262   char distname[500]; | 
|  | 4263 #endif | 
|  | 4264 | 
|  | 4265   n = lf->lfd.n; | 
|  | 4266   d = lf->lfd.d; | 
|  | 4267   p = npar(&lf->sp) = calcp(&lf->sp,d); | 
|  | 4268 | 
|  | 4269   mdl->isset = 1; | 
|  | 4270   PPROC(lf) = NULL; | 
|  | 4271   if (strcmp(mod,"std")==0)    { initstd(lf); return(1); } | 
|  | 4272   if (strcmp(mod,"simple")==0) { initsimple(lf); return(1); } | 
|  | 4273   if (strcmp(mod,"allcf")==0)  { initallcf(lf); return(1); } | 
|  | 4274   if (strcmp(mod,"hatm")==0)   { inithatm(lf); return(1); } | 
|  | 4275   if (strcmp(mod,"kappa")==0)  { initkappa(lf); return(1); } | 
|  | 4276   if (strcmp(mod,"lscv")==0)   { initlscv(lf); return(1); } | 
|  | 4277   if (strcmp(mod,"gamf")==0)   { initgam(lf); return(1); } | 
|  | 4278   if (strcmp(mod,"gamp")==0)   { initgam(lf); return(1); } | 
|  | 4279   if (strcmp(mod,"rband")==0)  { initrband(lf); return(1); } | 
|  | 4280   if (strcmp(mod,"scb")==0)    { initscb(lf); return(1); } | 
|  | 4281   if (strcmp(mod,"vord")==0)   { initvord(lf); return(1); } | 
|  | 4282 | 
|  | 4283 #ifdef ALLOW_MODULES | 
|  | 4284   while (dir != NULL) | 
|  | 4285   { | 
|  | 4286     dir = getnextdir(dir,distname); | 
|  | 4287     sprintf(&distname[strlen(distname)],"mod%s.%s",mod,DLEXT); | 
|  | 4288     res = DLOPEN(distname); | 
|  | 4289     if (res==NULL) | 
|  | 4290     { | 
|  | 4291 #ifdef WINDOWS | 
|  | 4292       mut_printf("LoadLibrary failed: %s, %d\n",distname,GetLastError()); | 
|  | 4293 #else | 
|  | 4294       mut_printf("dlopen failed: %s\n",dlerror()); | 
|  | 4295 #endif | 
|  | 4296     } | 
|  | 4297     else | 
|  | 4298     { | 
|  | 4299 #ifdef WINDOWS | 
|  | 4300       mut_printf("LoadLibrary success: %s\n",distname); | 
|  | 4301 #else | 
|  | 4302       mut_printf("dlopen success: %s\n",distname); | 
|  | 4303 #endif | 
|  | 4304       sprintf(distname,"init%s",mod); | 
|  | 4305       init = (void *)DLSYM(res,distname); | 
|  | 4306       if (init==NULL) | 
|  | 4307       { mut_printf("I can't find %s() function.\n",distname); | 
|  | 4308         mdl->isset = 0; | 
|  | 4309         return(0); | 
|  | 4310       } | 
|  | 4311       init(lf); | 
|  | 4312       return(1); | 
|  | 4313     } | 
|  | 4314   } | 
|  | 4315 #endif | 
|  | 4316 | 
|  | 4317   mdl->isset = 0; | 
|  | 4318   return(0); | 
|  | 4319 } | 
|  | 4320 | 
|  | 4321 /* | 
|  | 4322  * startmodule is the entry point to launch the fit. | 
|  | 4323  * if mod is provided, will first initialize the module. | 
|  | 4324  * if mod==NULL, assumes the module has been initialized separately. | 
|  | 4325  */ | 
|  | 4326 void startmodule(lf,des,mod,dir) | 
|  | 4327 lfit *lf; | 
|  | 4328 design *des; | 
|  | 4329 char *mod, *dir; | 
|  | 4330 { int z; | 
|  | 4331 | 
|  | 4332   if (mod != NULL) | 
|  | 4333   { z = initmodule(&lf->mdl,mod,dir,lf); | 
|  | 4334     if (!z) return; | 
|  | 4335   } | 
|  | 4336 | 
|  | 4337   lf->fp.nv = lf->evs.nce = 0; | 
|  | 4338   if (lf_error) return; | 
|  | 4339   if (PROCV(lf) != NULL) nstartlf(des,lf); | 
|  | 4340   if (lf_error) return; | 
|  | 4341   if (PPROC(lf) != NULL) PPROC(lf)(lf,des,lf->fp.kap); | 
|  | 4342 } | 
|  | 4343 | 
|  | 4344 /* for compatability, more or less. */ | 
|  | 4345 void startlf(des,lf,vfun,nopc) | 
|  | 4346 design *des; | 
|  | 4347 lfit *lf; | 
|  | 4348 int (*vfun)(), nopc; | 
|  | 4349 { int z; | 
|  | 4350   z = initmodule(&lf->mdl,"std",NULL,lf); | 
|  | 4351   if (!z) return; | 
|  | 4352   lf->mdl.procv = vfun; | 
|  | 4353   lf->mdl.nopc = nopc; | 
|  | 4354   nstartlf(des,lf); | 
|  | 4355 } |