C C Modified from the SMART package by J.H. Friedman, 10/10/84 C Main change is to add spline smoothing modified from BRUTO, C calling code written for smooth.spline in S. C C B.D. Ripley (ripley@stats.ox.ac.uk) 1994-7. C C subroutine smart(m,mu,p,q,n, w,x,y,ww,smod,nsmod, & sp,nsp,dp,ndp,edf) integer m,mu,p,q,n, nsmod, nsp,ndp double precision x(p,n),y(q,n),w(n),ww(q),smod(nsmod), & sp(nsp),edf(m),dp(ndp) smod(1)=m smod(2)=p smod(3)=q smod(4)=n call smart1(m,mu,p,q,n, w,x,y,ww, smod(6),smod(q+6), & smod(q+7),smod(q+7+p*m),smod(q+7+m*(p+q)), & smod(q+7+m*(p+q+n)),smod(q+7+m*(p+q+2*n)), & sp,sp(q*n+1),sp(n*(q+15)+1),sp(n*(q+15)+q+1), & dp,smod(5),edf) return end subroutine smart1(m,mu,p,q,n, w,x,y,ww, yb,ys, & a,b,f, & t,asr, & r,sc,bt,g, & dp,flm,edf) integer m,mu,p,q,n double precision w(n),x(p,n),y(*),ww(q), yb(q), ys double precision a(p,m),b(q,m),f(n,m),t(n,m), asr(15),asr1 double precision r(q,n),sc(n,15),bt(q),g(p,3) double precision dp(*), flm,edf(m) C ^^^ really (ndb) of smart(.) integer i,j,l, lm double precision sw,s c Common Vars double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj sw=0d0 do j=1,n sw=sw+w(j) end do do j=1,n do i=1,q r(i,j)=y(q*(j-1)+i) end do end do do i=1,q s=0d0 do j=1,n s=s+w(j)*r(i,j) end do yb(i)=s/sw end do c yb is vector of means do j=1,n do i=1,q r(i,j)=r(i,j)-yb(i) end do end do ys=0.d0 do i=1,q s=0.d0 do j=1,n s=s+w(j)*r(i,j)**2 end do ys=ys+ww(i)*s/sw end do if(ys .gt. 0d0) goto 311 c ys is the overall standard deviation -- quit if zero return 311 continue ys=sqrt(ys) s=1.d0/ys do j=1,n do i=1,q r(i,j)=r(i,j)*s end do end do c r is now standardized residuals c subfit adds up to m terms one at time; lm is the number fitted. call subfit(m,p,q,n,w,sw,x,r,ww,lm,a,b,f,t,asr(1),sc,bt,g,dp,edf) if(lf.le.0) go to 9999 call fulfit(lm,lf,p,q,n,w,sw,x,r,ww,a,b,f,t,asr,sc,bt,g,dp,edf) C REPEAT 371 continue do l=1,lm sc(l,1)=l+0.1d0 s=0d0 do i=1,q s=s+ww(i)*abs(b(i,l)) end do sc(l,2)=-s end do call sort(sc(1,2),sc,1,lm) do j=1,n do i=1,q r(i,j)=y(q*(j-1)+i) end do end do do i=1,q do j=1,n r(i,j)=r(i,j)-yb(i) s=0.d0 do l=1,lm s=s+b(i,l)*f(j,l) end do r(i,j)=r(i,j)/ys-s end do end do if(lm.le.mu) goto 9999 c back to integer: l=int(sc(lm,1)) asr1=0d0 do j=1,n do i=1,q r(i,j)=r(i,j)+b(i,l)*f(j,l) asr1=asr1+w(j)*ww(i)*r(i,j)**2 end do end do asr1=asr1/sw asr(1)=asr1 if(l .ge. lm) goto 591 do i=1,p a(i,l)=a(i,lm) end do do i=1,q b(i,l)=b(i,lm) end do do j=1,n f(j,l)=f(j,lm) t(j,l)=t(j,lm) end do 591 continue lm=lm-1 call fulfit(lm,lf,p,q,n,w,sw,x,r,ww,a,b,f,t,asr,sc,bt,g,dp,edf) goto 371 C END REPEAT 9999 continue flm=lm return end subroutine subfit(m,p,q,n,w,sw,x,r,ww,lm,a,b,f,t,asr,sc, & bt,g,dp,edf) c Args integer m,p,q,n, lm double precision w(n),sw, x(p,n),r(q,n),ww(q),a(p,m),b(q,m), & f(n,m), t(n,m), asr(15), sc(n,15), bt(q), g(p,3), edf(m) double precision dp(*) c Var integer i,j,l, iflsv double precision asrold c Common Vars double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj asr(1)=big lm=0 do 100 l=1,m call rchkusr() lm=lm+1 asrold=asr(1) call newb(lm,q,ww,b) c does 'edf' mean 'edf(1)' or 'edf(l)'? call onetrm(0,p,q,n,w,sw,x,r,ww,a(1,lm),b(1,lm), & f(1,lm),t(1,lm),asr(1),sc,g,dp,edf(1)) do 20 j=1,n do 10 i=1,q r(i,j)=r(i,j)-b(i,lm)*f(j,lm) 10 continue 20 continue if(lm.eq.1) goto 100 if(lf.gt.0) then if(lm.eq.m) return iflsv=ifl ifl=0 call fulfit(lm,1,p,q,n,w,sw,x,r,ww,a,b,f,t,asr,sc,bt, & g,dp, edf) ifl=iflsv endif if(asr(1).le.0d0.or.(asrold-asr(1))/asrold.lt.conv) return 100 continue return end subroutine fulfit(lm,lbf,p,q,n,w,sw,x,r,ww,a,b,f,t, & asr,sc,bt,g,dp,edf) c Args integer lm,lbf,p,q,n double precision w(n),sw,x(p,n),r(q,n),ww(q),a(p,lm),b(q,lm), & f(n,lm),t(n,lm),asr(1+lm), sc(n,15),bt(q),g(p,3), edf(lm) double precision dp(*) c Var double precision asri, fsv, asrold integer i,j,iter,lp,isv c Common Vars double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj if(lbf.le.0) return asri=asr(1) fsv=cutmin isv=mitone if(lbf .lt. 3) then cutmin=1d0 mitone=lbf-1 endif iter=0 C Outer loop: 1000 continue asrold=asri iter=iter+1 do 100 lp=1,lm do 10 i=1,q bt(i)=b(i,lp) 10 continue do 20 i=1,p g(i,3)=a(i,lp) 20 continue do 35 j=1,n do 30 i=1,q r(i,j)=r(i,j)+bt(i)*f(j,lp) 30 continue 35 continue call onetrm(1,p,q,n,w,sw,x,r,ww,g(1,3),bt,sc(1,14),sc(1,15), & asri,sc,g,dp,edf(lp)) if(asri .lt. asrold) then do 40 i=1,q b(i,lp)=bt(i) 40 continue do 50 i=1,p a(i,lp)=g(i,3) 50 continue do 60 j=1,n f(j,lp)=sc(j,14) t(j,lp)=sc(j,15) 60 continue else asri=asrold endif do 85 j=1,n do 80 i=1,q r(i,j)=r(i,j)-b(i,lp)*f(j,lp) 80 continue 85 continue 100 continue if((iter .le. maxit) .and. ((asri .gt. 0d0) & .and. ((asrold-asri)/asrold .ge. conv))) goto 1000 cutmin=fsv mitone=isv if(ifl .gt. 0) then asr(1+lm) = asri asr(1) = asri endif return end subroutine onetrm(jfl,p,q,n,w,sw,x,y,ww,a,b,f,t,asr, & sc,g,dp,edf) c Args integer jfl,p,q,n double precision w(n),sw, x(p,n),y(q,n),ww(q),a(p),b(q),f(n),t(n), & asr, sc(n,13),g(p,2), edf double precision dp(*) c Var double precision asrold,s integer i,j,iter c Common Vars double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj iter=0 asr=big C REPEAT 1000 continue iter=iter+1 asrold=asr do 11 j=1,n s=0d0 do 21 i=1,q s=s+ww(i)*b(i)*y(i,j) 21 continue sc(j,13)=s 11 continue call oneone(max0(jfl,iter-1),p,n,w,sw,sc(1,13),x,a,f,t, & asr,sc,g,dp,edf) do 31 i=1,q s=0d0 do 41 j=1,n s=s+w(j)*y(i,j)*f(j) 41 continue b(i)=s/sw 31 continue asr=0d0 do 51 i=1,q s=0d0 do 61 j=1,n s=s+w(j)*(y(i,j)-b(i)*f(j))**2 61 continue asr=asr+ww(i)*s/sw 51 continue if((q .ne. 1) .and. (iter .le. maxit) .and. (asr .gt. 0d0) & .and. (asrold-asr)/asrold .ge. conv) goto 1000 return end subroutine oneone(ist,p,n, w,sw,y,x,a,f,t,asr,sc,g,dp,edf) c Args integer ist,p,n double precision w(n),sw,y(n),x(p,n),a(p),f(n),t(n),asr, & sc(n,12), g(p,2), edf, dp(*) c Var integer i,j,k,iter double precision sml, s,v,cut,asrold c Common Vars double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj sml=1d0/big if(ist .le. 0) then if(p .le. 1) a(1)=1d0 do 10 j=1,n sc(j,2)=1d0 10 continue call pprdir(p,n,w,sw,y,x,sc(1,2),a,dp) endif s=0d0 do 20 i=1,p g(i,1)=0d0 s=s+a(i)**2 20 continue s=1d0/sqrt(s) do 30 i=1,p a(i)=a(i)*s 30 continue iter=0 asr=big cut=1d0 C REPEAT ----------------------------- 100 continue iter=iter+1 asrold=asr C REPEAT [inner loop] ----- 60 continue s=0d0 do 70 i=1,p g(i,2)=a(i)+g(i,1) s=s+g(i,2)**2 70 continue s=1.d0/sqrt(s) do 80 i=1,p g(i,2)=g(i,2)*s 80 continue do 90 j=1,n sc(j,1)=j+0.1d0 s=0.d0 do 91 i=1,p s=s+g(i,2)*x(i,j) 91 continue sc(j,11)=s 90 continue call sort(sc(1,11),sc,1,n) do 110 j=1,n k=int(sc(j,1)) sc(j,2)=y(k) sc(j,3)=max(w(k),sml) 110 continue call supsmu(n,sc(1,11),sc(1,2),sc(1,3),1,span,alpha, & sc(1,12),sc(1,4), edf) s=0d0 do 120 j=1,n s=s+sc(j,3)*(sc(j,2)-sc(j,12))**2 120 continue s=s/sw if(s .lt. asr) goto 140 cut=cut*0.5d0 if(cut.lt.cutmin) goto 199 do 150 i=1,p g(i,1)=g(i,1)*cut 150 continue go to 60 C -------- 140 continue asr=s cut=1d0 do 160 i=1,p a(i)=g(i,2) 160 continue do 170 j=1,n k=int(sc(j,1)) t(k)=sc(j,11) f(k)=sc(j,12) 170 continue if(asr.le.0d0.or.(asrold-asr)/asrold.lt.conv) goto 199 if(iter.gt.mitone.or.p.le.1) goto 199 call pprder(n,sc(1,11),sc(1,12),sc(1,3),fdel,sc(1,4),sc(1,5)) do 180 j=1,n k=int(sc(j,1)) sc(j,5)=y(j)-f(j) sc(k,6)=sc(j,4) 180 continue call pprdir(p,n,w,sw,sc(1,5),x,sc(1,6),g,dp) goto 100 c-------------- 199 continue c-------------- s=0d0 v=s do 210 j=1,n s=s+w(j)*f(j) 210 continue s=s/sw do 220 j=1,n f(j)=f(j)-s v=v+w(j)*f(j)**2 220 continue if(v .gt. 0d0) then v=1d0/sqrt(v/sw) do 230 j=1,n f(j)=f(j)*v 230 continue endif return end subroutine pprdir(p,n,w,sw,r,x,d,e,g) integer p,n double precision w(n),sw,r(n),x(p,n),d(n),e(p), g(*) double precision s integer i,j,k,l,m1,m2 double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj do 10 i=1,p s=0d0 do 15 j=1,n s=s+w(j)*d(j)*x(i,j) 15 continue e(i)=s/sw 10 continue k=0 m1=p*(p+1)/2 m2=m1+p do 20 j=1,p s=0d0 do 22 l=1,n s=s+w(l)*r(l)*(d(l)*x(j,l)-e(j)) 22 continue g(m1+j)=s/sw do 25 i=1,j s=0d0 do 27 l=1,n s=s+w(l)*(d(l)*x(i,l)-e(i))*(d(l)*x(j,l)-e(j)) 27 continue k=k+1 g(k)=s/sw 25 continue 20 continue call ppconj(p,g,g(m1+1),g(m2+1),cjeps,mitcj,g(m2+p+1)) do 30 i=1,p e(i)=g(m2+i) 30 continue return end subroutine ppconj(p,g,c,x,eps,maxit,sc) integer p,maxit double precision g(*),c(p),x(p),eps,sc(p,4) integer i,j,im1,iter,nit double precision beta,h,s,alpha,t do 1 i=1,p x(i)=0d0 sc(i,2)=0d0 1 continue nit=0 C REPEAT 11321 continue nit=nit+1 h=0d0 beta=0d0 do 11331 i=1,p sc(i,4)=x(i) s=g(i*(i-1)/2+i)*x(i) im1=i-1 j=1 goto 11343 11341 j=j+1 11343 if(j.gt.im1) goto 11342 s=s+g(i*(i-1)/2+j)*x(j) goto 11341 11342 continue j=i+1 goto 11353 11351 j=j+1 11353 if(j.gt.p) goto 11352 s=s+g(j*(j-1)/2+i)*x(j) goto 11351 11352 continue sc(i,1)=s-c(i) h=h+sc(i,1)**2 11331 continue if(h.le.0d0) goto 11322 do 11361 iter=1,p do 11371 i=1,p sc(i,2)=beta*sc(i,2)-sc(i,1) 11371 continue t=0d0 do 11381 i=1,p s=g(i*(i-1)/2+i)*sc(i,2) im1=i-1 j=1 goto 11393 11391 j=j+1 11393 if(j.gt.im1) goto 11392 s=s+g(i*(i-1)/2+j)*sc(j,2) goto 11391 11392 continue j=i+1 goto 11403 11401 j=j+1 11403 if(j.gt.p) goto 11402 s=s+g(j*(j-1)/2+i)*sc(j,2) goto 11401 11402 continue sc(i,3)=s t=t+s*sc(i,2) 11381 continue alpha=h/t s=0d0 do 11411 i=1,p x(i)=x(i)+alpha*sc(i,2) sc(i,1)=sc(i,1)+alpha*sc(i,3) s=s+sc(i,1)**2 11411 continue if(s.le.0d0) goto 11362 beta=s/h h=s 11361 continue 11362 continue s=0d0 do 11421 i=1,p s=dmax1(s,dabs(x(i)-sc(i,4))) 11421 continue if((s .ge. eps) .and. (nit .lt. maxit)) goto 11321 11322 continue return end subroutine pprder (n,x,s,w,fdel,d,sc) integer n double precision x(n),s(n),w(n), fdel, d(n),sc(n,3) integer i,j,bl,el,bc,ec,br,er double precision scale, del c c unnecessary initialization of bl el ec to keep g77 -Wall happy c bl = 0 el = 0 ec = 0 c if(x(n) .gt. x(1)) goto 11441 do 11451 j=1,n d(j)=0d0 11451 continue return 11441 continue i=n/4 j=3*i scale=x(j)-x(i) 11461 if(scale.gt.0d0) goto 11462 if(j.lt.n) j=j+1 if(i.gt.1) i=i-1 scale=x(j)-x(i) goto 11461 11462 continue del=fdel*scale*2d0 do 11471 j=1,n sc(j,1)=x(j) sc(j,2)=s(j) sc(j,3)=w(j) 11471 continue call pool (n,sc,sc(1,2),sc(1,3),del) bc=0 br=bc er=br 11481 continue br=er+1 er=br 11491 if(er .ge. n) goto 11492 if(sc(br,1) .ne. sc(er+1,1)) goto 11511 er=er+1 goto 11521 11511 continue goto 11492 11521 continue goto 11491 11492 continue if(br .ne. 1) goto 11541 bl=br el=er goto 11481 11541 continue if(bc .ne. 0) goto 11561 bc=br ec=er do 11571 j=bl,el d(j)=(sc(bc,2)-sc(bl,2))/(sc(bc,1)-sc(bl,1)) 11571 continue goto 11481 11561 continue c sanity check needed for PR#13517 if(br.gt.n) call rexit('br is too large') do 11581 j=bc,ec d(j)=(sc(br,2)-sc(bl,2))/(sc(br,1)-sc(bl,1)) 11581 continue if(er .ne. n) goto 11601 do 11611 j=br,er d(j)=(sc(br,2)-sc(bc,2))/(sc(br,1)-sc(bc,1)) 11611 continue goto 11482 11601 continue bl=bc el=ec bc=br ec=er goto 11481 11482 continue return end subroutine pool (n,x,y,w,del) integer n double precision x(n),y(n),w(n),del integer i,bb,eb,br,er,bl,el double precision px, py, pw bb=0 eb=bb 11621 if(eb.ge.n) goto 11622 bb=eb+1 eb=bb 11631 if(eb .ge. n) goto 11632 if(x(bb) .ne. x(eb+1)) goto 11651 eb=eb+1 goto 11661 11651 continue goto 11632 11661 continue goto 11631 11632 continue if(eb .ge. n) goto 11681 if(x(eb+1)-x(eb) .ge. del) goto 11701 br=eb+1 er=br 11711 if(er .ge. n) goto 11712 if(x(er+1) .ne. x(br)) goto 11731 er=er+1 goto 11741 11731 continue goto 11712 11741 continue goto 11711 11712 continue C avoid bounds error: this was .and. but order is not guaranteed if(er.lt.n) then if(x(er+1)-x(er).lt.x(eb+1)-x(eb)) goto 11621 endif eb=er pw=w(bb)+w(eb) px=(x(bb)*w(bb)+x(eb)*w(eb))/pw py=(y(bb)*w(bb)+y(eb)*w(eb))/pw do 11751 i=bb,eb x(i)=px y(i)=py w(i)=pw 11751 continue 11701 continue 11681 continue 11761 continue if(bb.le.1) goto 11762 if(x(bb)-x(bb-1).ge.del) goto 11762 bl=bb-1 el=bl 11771 if(bl .le. 1) goto 11772 if(x(bl-1) .ne. x(el)) goto 11791 bl=bl-1 goto 11801 11791 continue goto 11772 11801 continue goto 11771 11772 continue bb=bl pw=w(bb)+w(eb) px=(x(bb)*w(bb)+x(eb)*w(eb))/pw py=(y(bb)*w(bb)+y(eb)*w(eb))/pw do 11811 i=bb,eb x(i)=px y(i)=py w(i)=pw 11811 continue goto 11761 11762 continue goto 11621 11622 continue return end subroutine newb(lm,q,ww,b) integer lm, q double precision ww(q),b(q,lm) integer i,lm1,l,l1 double precision s,t,sml c Common double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big sml=1d0/big if(q .ne. 1) goto 11831 b(1,lm)=1d0 return 11831 continue if(lm .ne. 1) goto 11851 do 11861 i=1,q b(i,lm)=i 11861 continue return 11851 continue lm1=lm-1 do 11871 i=1,q b(i,lm)=0d0 11871 continue t=0d0 do 11881 i=1,q s=0d0 do 11891 l=1,lm1 s=s+abs(b(i,l)) 11891 continue b(i,lm)=s t=t+s 11881 continue do 11901 i=1,q b(i,lm)=ww(i)*(t-b(i,lm)) 11901 continue l1=1 if(lm.gt.q) l1=lm-q+1 do 11911 l=l1,lm1 s=0d0 t=s do 11921 i=1,q s=s+ww(i)*b(i,lm)*b(i,l) t=t+ww(i)*b(i,l)**2 11921 continue s=s/sqrt(t) do 11931 i=1,q b(i,lm)=b(i,lm)-s*b(i,l) 11931 continue 11911 continue do 11941 i=2,q if(abs(b(i-1,lm)-b(i,lm)).gt.sml) return 11941 continue do 11951 i=1,q b(i,lm)=i 11951 continue return end block data bkppr c Common Vars double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision conv, cutmin,fdel,cjeps integer maxit,mitone, mitcj common /pprz01/ conv,maxit,mitone,cutmin,fdel,cjeps,mitcj double precision df, gcvpen integer ismethod logical trace common /spsmooth/ df, gcvpen, ismethod, trace data df, gcvpen, ismethod, trace /4d0, 1d0, 0, .false./ data ifl,maxit, conv, mitone, cutmin, fdel, & span,alpha, big, cjeps, mitcj, lf & /6, 20, .005, 20, 0.1, 0.02, & 0.0, 0.0,1.0e20,0.001, 1, 2/ end subroutine setppr(span1, alpha1, optlevel, ism, df1, gcvpen1) c Put 'parameters' into Common blocks integer optlevel,ism double precision span1,alpha1, df1, gcvpen1 double precision span,alpha,big integer ifl,lf common /pprpar/ ifl,lf,span,alpha,big double precision df, gcvpen integer ismethod logical trace common /spsmooth/ df, gcvpen, ismethod, trace span = span1 lf = optlevel alpha = alpha1 if(ism .ge. 0) then ismethod = ism trace = .false. else ismethod = -(ism+1) trace = .true. end if df = df1 gcvpen = gcvpen1 return end subroutine fsort(mu,n,f,t,sp) c integer mu, n double precision f(n,mu),t(n,mu),sp(n,2) c integer l,j,k do 100 l=1,mu do 10 j=1,n sp(j,1)=j+0.1d0 sp(j,2)=f(j,l) 10 continue call sort(t(1,l),sp,1,n) do 20 j=1,n k=int(sp(j,1)) f(j,l)=sp(k,2) 20 continue 100 continue return end subroutine pppred(np,x,smod,y,sc) integer np double precision x(np,*),y(np,*),smod(*), sc(*) integer p,q, place,low,high, i,j,l,m,n, + inp,ja,jb,jf,jt,jfl,jfh,jtl,jth, mu double precision ys, s, t m= int(smod(1)+0.1d0) p= int(smod(2)+0.1d0) q= int(smod(3)+0.1d0) n= int(smod(4)+0.1d0) mu=int(smod(5)+0.1d0) ys=smod(q+6) ja=q+6 jb=ja+p*m jf=jb+m*q jt=jf+n*m call fsort(mu,n,smod(jf+1),smod(jt+1),sc) do 100 inp = 1, np ja=q+6 jb=ja+p*m jf=jb+m*q jt=jf+n*m do 81 i=1,q y(inp,i)=0d0 81 continue do 91 l=1,mu s=0d0 do 12201 j=1,p s=s+smod(ja+j)*x(inp,j) 12201 continue if(s .gt. smod(jt+1)) goto 12221 place=1 go to 12230 12221 continue if(s .lt. smod(jt+n)) goto 12251 place=n go to 12230 12251 continue low=0 high=n+1 C WHILE 12261 if(low+1.ge.high) goto 12262 place=(low+high)/2 t=smod(jt+place) if(s.eq.t) goto 12230 if(s .lt. t) then high=place else low=place endif goto 12261 C END 12262 continue jfl=jf+low jfh=jf+high jtl=jt+low jth=jt+high t=smod(jfl)+(smod(jfh)-smod(jfl))*(s-smod(jtl)) / & (smod(jth)-smod(jtl)) go to 12300 12230 continue t=smod(jf+place) 12300 continue do 12311 i=1,q y(inp,i)=y(inp,i)+smod(jb+i)*t 12311 continue ja=ja+p jb=jb+q jf=jf+n jt=jt+n 91 continue do 12321 i=1,q y(inp,i)=ys*y(inp,i)+smod(i+5) 12321 continue 100 continue return end c Called from R's supsmu() subroutine setsmu (tr) integer tr double precision df, gcvpen integer ismethod logical trace common /spsmooth/ df, gcvpen, ismethod, trace ismethod = 0 trace = tr .ne. 0 return end subroutine supsmu (n,x,y,w,iper,span,alpha,smo,sc,edf) c c------------------------------------------------------------------ c c super smoother (Friedman, 1984). c c version 10/10/84 c c coded and copywrite (c) 1984 by: c c Jerome H. Friedman c department of statistics c and c stanford linear accelerator center c stanford university c c all rights reserved. c c c input: c n : number of observations (x,y - pairs). c x(n) : ordered abscissa values. c y(n) : corresponding ordinate (response) values. c w(n) : weight for each (x,y) observation. c iper : periodic variable flag. c iper=1 => x is ordered interval variable. c iper=2 => x is a periodic variable with values c in the range (0.0,1.0) and period 1.0. c span : smoother span (fraction of observations in window). c span=0.0 <=> "cv" : automatic (variable) span selection. c alpha : controls high frequency (small span) penality c used with automatic span selection (bass tone control). c (alpha.le.0.0 or alpha.gt.10.0 => no effect.) c output: c smo(n) : smoothed ordinate (response) values. c scratch: c sc(n,7) : internal working storage. c c note: c for small samples (n < 40) or if there are substantial serial c correlations between observations close in x - value, then c a prespecified fixed span smoother (span > 0) should be c used. reasonable span values are 0.2 to 0.4. c c------------------------------------------------------------------ c Args integer n, iper double precision x(n),y(n),w(n), smo(n),sc(n,7) double precision span, alpha, edf c Var double precision sy,sw, a,h(n),f, scale,vsmlsq,resmin integer i,j, jper double precision spans(3), big,sml,eps common /spans/ spans /consts/ big,sml,eps double precision df, gcvpen integer ismethod logical trace common /spsmooth/ df, gcvpen, ismethod, trace c Called from R's supsmu(), ismethod = 0, always (but not when called from ppr) if (x(n).gt.x(1)) go to 30 c x(n) <= x(1) : boundary case: smo[.] := weighted mean( y ) sy=0d0 sw=sy do 10 j=1,n sy=sy+w(j)*y(j) sw=sw+w(j) 10 continue a=0d0 if (sw.gt.0d0) a=sy/sw do 20 j=1,n smo(j)=a 20 continue return C Normal Case 30 continue if (ismethod .ne. 0) then ! possible only when called from ppr() call spline(n, x, y, w, smo, edf, sc) else i=n/4 j=3*i scale=x(j)-x(i) ! = IQR(x) 40 if (scale.gt.0d0) go to 50 if (j.lt.n) j=j+1 if (i.gt.1) i=i-1 scale=x(j)-x(i) go to 40 50 vsmlsq=(eps*scale)**2 jper=iper if (iper.eq.2.and.(x(1).lt.0d0.or.x(n).gt.1d0)) jper=1 if (jper.lt.1.or.jper.gt.2) jper=1 if (span .gt. 0d0) then call smooth (n,x,y,w,span,jper,vsmlsq,smo,sc) return end if C else "cv" (crossvalidation) from three spans[] do 70 i=1,3 call smooth (n,x,y,w,spans(i),jper,vsmlsq, & sc(1,2*i-1),sc(1,7)) call smooth (n,x,sc(1,7),w,spans(2),-jper,vsmlsq, & sc(1,2*i),h) 70 continue do 90 j=1,n resmin=big do 80 i=1,3 if (sc(j,2*i).ge.resmin) go to 80 resmin=sc(j,2*i) sc(j,7)=spans(i) 80 continue if (alpha.gt.0d0 .and. alpha.le.10d0 .and. & resmin.lt.sc(j,6) .and. resmin.gt.0d0) & sc(j,7)= sc(j,7)+(spans(3)-sc(j,7)) * & max(sml,resmin/sc(j,6))**(10d0-alpha) 90 continue call smooth (n,x,sc(1,7),w,spans(2),-jper,vsmlsq,sc(1,2),h) do 110 j=1,n if (sc(j,2).le.spans(1)) sc(j,2)=spans(1) if (sc(j,2).ge.spans(3)) sc(j,2)=spans(3) f=sc(j,2)-spans(2) if (f.ge.0d0) go to 100 f=-f/(spans(2)-spans(1)) sc(j,4)=(1d0-f)*sc(j,3)+f*sc(j,1) go to 110 100 f=f/(spans(3)-spans(2)) sc(j,4)=(1d0-f)*sc(j,3)+f*sc(j,5) 110 continue call smooth (n,x,sc(1,4),w,spans(1),-jper,vsmlsq,smo,h) edf = 0 endif return end subroutine smooth (n,x,y,w,span,iper,vsmlsq,smo,acvr) c Args integer n, iper double precision x(n),y(n),w(n), span,vsmlsq, smo(n),acvr(n) c Var integer i,j, in,out, jper,ibw,it, j0 double precision xm,ym,var,cvar, fbw,fbo,xti,xto,tmp, a,h,sy,wt c will use 'trace': double precision df, gcvpen integer ismethod logical trace common /spsmooth/ df, gcvpen, ismethod, trace xm=0d0 ym=xm var=ym cvar=var fbw=cvar jper=iabs(iper) ibw=int(0.5d0*span*n+0.5d0) if (ibw.lt.2) ibw=2 it=2*ibw+1 if (it .gt. n) it = n do i=1,it j=i if (jper.eq.2) j=i-ibw-1 if (j.ge.1) then xti=x(j) else ! if (j.lt.1) then j=n+j xti=x(j)-1d0 end if wt=w(j) fbo=fbw fbw=fbw+wt if (fbw.gt.0d0) xm=(fbo*xm+wt*xti)/fbw if (fbw.gt.0d0) ym=(fbo*ym+wt*y(j))/fbw tmp=0d0 if (fbo.gt.0d0) tmp=fbw*wt*(xti-xm)/fbo var =var +tmp*(xti-xm) cvar=cvar+tmp*(y(j)-ym) end do do 80 j=1,n out=j-ibw-1 in=j+ibw if ((jper.ne.2) .and. (out.lt.1.or.in.gt.n)) go to 60 if (out .lt. 1) then out=n+out xto=x(out)-1d0 xti=x(in) else if (in .gt. n) then in=in-n xti=x(in)+1d0 xto=x(out) else xto=x(out) xti=x(in) end if wt=w(out) fbo=fbw fbw=fbw-wt tmp=0d0 if (fbw.gt.0d0) tmp=fbo*wt*(xto-xm)/fbw var = var-tmp*(xto-xm) cvar=cvar-tmp*(y(out)-ym) if (fbw.gt.0d0) xm=(fbo*xm-wt*xto)/fbw if (fbw.gt.0d0) ym=(fbo*ym-wt*y(out))/fbw wt=w(in) fbo=fbw fbw=fbw+wt if (fbw.gt.0d0) xm=(fbo*xm+wt*xti)/fbw if (fbw.gt.0d0) ym=(fbo*ym+wt*y(in))/fbw tmp=0d0 if (fbo.gt.0d0) tmp=fbw*wt*(xti-xm)/fbo var = var+tmp*(xti-xm) cvar=cvar+tmp*(y(in)-ym) 60 a=0d0 if (var.gt.vsmlsq) a=cvar/var smo(j)=a*(x(j)-xm)+ym if (iper.gt.0) then h=0d0 if (fbw.gt.0d0) h=1d0/fbw if (var.gt.vsmlsq) h=h+(x(j)-xm)**2/var acvr(j)=0d0 a=1d0-w(j)*h if (a.gt.0d0) then acvr(j)=abs(y(j)-smo(j))/a else if (j.gt.1) then acvr(j)=acvr(j-1) end if end if 80 continue if(trace) call smoothprt(span, iper, var, cvar) ! -> ./ksmooth.c c-- Recompute fitted values smo(j) as weighted mean for non-unique x(.) values: j=1 90 j0=j sy=smo(j)*w(j) fbw=w(j) if (j.ge.n) go to 110 100 if (x(j+1).le.x(j)) then j=j+1 sy=sy+w(j)*smo(j) fbw=fbw+w(j) if (j.lt.n) go to 100 end if 110 if (j.gt.j0) then a=0d0 if (fbw.gt.0d0) a=sy/fbw do i=j0,j smo(i)=a end do end if j=j+1 if (j.le.n) go to 90 return end block data bksupsmu double precision spans(3), big,sml,eps common /spans/ spans /consts/ big,sml,eps data spans, big,sml,eps /0.05,0.2,0.5, 1.0e20,1.0e-7,1.0e-3/ end c--------------------------------------------------------------- c c this sets the compile time (default) values for various c internal parameters : c c spans : span values for the three running linear smoothers. c spans(1) : tweeter span. c spans(2) : midrange span. c spans(3) : woofer span. c (these span values should be changed only with care.) c big : a large representable floating point number. c sml : a small number. should be set so that (sml)**(10.0) does c not cause floating point underflow. c eps : used to numerically stabilize slope calculations for c running linear fits. c c these parameter values can be changed by declaring the c relevant labeled common in the main program and resetting c them with executable statements. c c Only for ppr(*, ismethod != 0): Compute "smoothing" spline c (rather, a penalized regression spline with at most 15 (inner) knots): c----------------------------------------------------------------- c subroutine spline (n, x, y, w, smo, edf, sc) c c------------------------------------------------------------------ c c input: c n : number of observations. c x(n) : ordered abscissa values. c y(n) : corresponding ordinate (response) values. c w(n) : weight for each (x,y) observation. c work space: c sc(n,7) : used for dx(n), dy(n), dw(n), dsmo(n), lev(n) c output: c smo(n) : smoothed ordinate (response) values. c edf : equivalent degrees of freedom c c------------------------------------------------------------------ c Args integer n double precision x(n), y(n), w(n), smo(n), edf, sc(n,7) call splineAA(n, x, y, w, smo, edf, + sc(n,1), ! dx + sc(n,2), ! dy + sc(n,3), ! dw + sc(n,4), ! dsmo + sc(n,5)) ! lev return end subroutine splineAA(n, x, y, w, smo, edf, dx, dy, dw, dsmo, lev) c c Workhorse of spline() above c------------------------------------------------------------------ c c Additional input variables (no extra output, work): c dx : c dy : c dw : c dsmo: c lev : "leverages", i.e., diagonal entries S_{i,i} of the smoother matrix c c------------------------------------------------------------------ c Args integer n double precision x(n), y(n), w(n), smo(n), edf, + dx(n), dy(n), dw(n), dsmo(n), lev(n) c Var double precision knot(29), coef(25), work((17+25)*25) double precision param(5), df1, lambda, crit, p, s integer iparms(4), i, nk, ip, ier double precision df, gcvpen integer ismethod logical trace common /spsmooth/ df, gcvpen, ismethod, trace c__no-more__ if (n .gt. 2500) call bdrsplerr() do i = 1,n dx(i) = (x(i)-x(1))/(x(n)-x(1)) dy(i) = y(i) dw(i) = w(i) end do nk = min(n,15) knot(1) = dx(1) knot(2) = dx(1) knot(3) = dx(1) knot(4) = dx(1) knot(nk+1) = dx(n) knot(nk+2) = dx(n) knot(nk+3) = dx(n) knot(nk+4) = dx(n) do i = 5, nk p = (n-1)*real(i-4)/real(nk-3) ip = int(p) p = p-ip knot(i) = (1-p)*dx(ip+1) + p*dx(ip+2) end do c call dblepr('knots', 5, knot, nk+4) C iparms(1:2) := (icrit, ispar) for ./sbart.c if (ismethod .eq. 1) then iparms(1) = 3 df1 = df else iparms(1) = 1 df1 = 0d0 endif c iparms(2) = 0 ! ispar := 0 <==> estimate `spar' iparms(3) = 500 ! maxit = 500 iparms(4) = 0 ! spar (!= lambda) c param(1) = 0d0 ! = lspar : min{spar} param(2) = 1.5d0 ! = uspar : max{spar} c tol for 'spar' estimation: param(3) = 1d-2 c 'eps' (~= 2^-12 = sqrt(2^-24) ?= sqrt(machine eps)) in ./sbart.c : param(4) = .000244 ier = 1 call rbart(gcvpen,df1,dx,dy,dw,0.0d0,n,knot,nk,coef,dsmo,lev, & crit,iparms,lambda,param, work,4,1,ier) if(ier .gt. 0) call intpr('spline(.) TROUBLE:', 18, ier, 1) do i = 1,n smo(i) = dsmo(i) end do c call dblepr('smoothed',8, dsmo, n) s = 0 do i = 1, n s = s + lev(i) end do edf = s if(trace) call splineprt(df,gcvpen,ismethod, lambda, edf) return end *********************************************************************** C=== This was 'sort()' in gamfit's mysort.f [or sortdi() in sortdi.f ] : C C=== FIXME: Translate to C and add to ../../../main/sort.c <<<<< C C a[] is double precision because the caller reuses a double (sometimes v[] itself!) subroutine sort (v,a, ii,jj) c c Puts into a the permutation vector which sorts v into c increasing order. Only elements from ii to jj are considered. c Arrays iu(k) and il(k) permit sorting up to 2**(k+1)-1 elements c c This is a modification of CACM algorithm #347 by R. C. Singleton, c which is a modified Hoare quicksort. c integer ii,jj double precision v(*), a(jj) c integer iu(20),il(20) integer t,tt, m,i,j,ij,k,l double precision vt, vtt m=1 i=ii j=jj 10 if (i.ge.j) go to 80 20 k=i ij=(j+i)/2 t=int(a(ij)) vt=v(ij) if (v(i).le.vt) go to 30 a(ij)=a(i) a(i)=t t=int(a(ij)) v(ij)=v(i) v(i)=vt vt=v(ij) 30 l=j if (v(j).ge.vt) go to 50 a(ij)=a(j) a(j)=t t=int(a(ij)) v(ij)=v(j) v(j)=vt vt=v(ij) if (v(i).le.vt) go to 50 a(ij)=a(i) a(i)=t t=int(a(ij)) v(ij)=v(i) v(i)=vt vt=v(ij) go to 50 40 a(l)=a(k) a(k)=tt v(l)=v(k) v(k)=vtt 50 l=l-1 if (v(l).gt.vt) go to 50 tt=int(a(l)) vtt=v(l) 60 k=k+1 if (v(k).lt.vt) go to 60 if (k.le.l) go to 40 if (l-i.le.j-k) go to 70 il(m)=i iu(m)=l i=k m=m+1 go to 90 70 il(m)=k iu(m)=j j=l m=m+1 go to 90 80 m=m-1 if (m.eq.0) return i=il(m) j=iu(m) 90 if (j-i.gt.10) go to 20 if (i.eq.ii) go to 10 i=i-1 100 i=i+1 if (i.eq.j) go to 80 t=int(a(i+1)) vt=v(i+1) if (v(i).le.vt) go to 100 k=i 110 a(k+1)=a(k) v(k+1)=v(k) k=k-1 if (vt.lt.v(k)) go to 110 a(k+1)=t v(k+1)=vt go to 100 end