| 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 |