swh:1:snp:3aec91c51d538d62f3f51f6a0af59fe452f330ab
Raw File
Tip revision: 4754e52c04d2199c16471856fef1d35529877b63 authored by Zhu Wang on 27 February 2019, 15:50:03 UTC
version 0.3-7
Tip revision: 4754e52
outloop.f
C     outer loop: decrement lambda
C     input:
C     mu: a vector
C     output
C     b: beta
C     bz: b0
C     resdev: residual deviance
C     ypre: yhat

      subroutine outloop(x,y,weights, wt, n,m, penalty, nlambda, lam, 
     +     alpha,gam,theta,rescale,mu,eta, offset,
     #family,standardize, nulldev, 
     +     thresh, maxit, innermaxit, eps, trace, start, startv,b, bz,
     +     resdev,ypre, convout, satu, good, ep, outpll)

      implicit none
      integer n,m,i,j,k,kk,penalty, nlambda, family, standardize, maxit,
     +     innermaxit, trace,convmid,convout(nlambda), startv, rescale, 
     +     satu,good,convact,fullset(m),activeset(m),activesetold(m),jk
      double precision x(n,m), y(n), wt(n), lam(m, nlambda),alpha,
     +     gam, theta,mu(n),eta(n), nulldev,thresh, eps, b(m,nlambda),
     +     bz(nlambda),xold(n,m), yold(n), start(m+1), resdev(nlambda), 
     +     v(n), ypre(n,nlambda), lamk(m), beta(m), b0,dev,
     +     weights(n),yhat(n),ep, pll(maxit), outpll(maxit, nlambda),
     +     normx(m),xd(m),avg, offset(n) 

      if(family .NE. 1)then
         call preprocess(x, y, n, m, weights, family, standardize,
     +        normx, xd, avg)
      endif
C     keep a copy of x and y in case x and y will be changed in subroutine lmnet if standardize = 1
      do 100 j=1, m
         do 110 i=1, n
            xold(i,j)=x(i,j)
 110     continue
 100  continue
      call DCOPY(n, y, 1, yold, 1)
      if(startv .EQ. 0)then
         b0 = eta(1)
         do j=1, m
            beta(j) = 0
         enddo
      else 
         b0 = start(1)
         do j=1, m
            beta(j) = start(j+1)
         enddo
      endif

      k = 1
      satu = 0

 1000 if(k .LE. nlambda .AND. satu .EQ. 0)then
         if(trace.EQ.1)then
            call dblepr("", -1, 1,0)
            call dblepr("Outer loop: Decrement lambda", -1, 1,0)
            call intpr("  lambda iteration", -1, k, 1)
            call dblepr("  lambda value", -1, lam(1,k), 1)
         endif
         do 10 j=1,m
            lamk(j) = lam(j,k)
 10      continue
C     active set here only applies for family!=1. For family=1, active set
C     is implemented in lmnetGaus
C     70: begin if the block 
         if(family .EQ. 1)then
            call midloop(n,m,x,y, xold,yold,weights,mu, eta, offset,
     + family, 
     +           penalty,lamk,alpha,gam,theta,rescale,standardize, eps,
     +           innermaxit, maxit, thresh, nulldev, wt, beta, b0, yhat,
     +           dev, trace, convmid,satu,ep,pll,normx,xd,avg)
         else 
            do 401 j=1, m
               activeset(j)=j
               fullset(j)=j
 401        continue
            convact=0
C     some loop, if no change to the active set, stop
            kk = 1
            do 2000 while (kk .LT. 100 .AND. convact .EQ. 0)
            do 501 j=1, m
                  activesetold(j)=activeset(j)
 501           continue
C     set maxit=1, and have a complete cycle through all the variables
               call midloopGLM(n,m,x,y,xold,yold,weights,mu,eta,offset,
     +              family, 
     +              penalty,lamk,alpha,gam,theta,rescale,standardize,
     +              eps,innermaxit,1,thresh,nulldev,wt,beta,b0,yhat, 
     +              dev,trace,convmid,satu,ep,pll,normx,xd,avg,fullset,
     +              m)
C     determine the active set with only non-zero coefficients 
C     jk: number of variables in active set
               jk = 0
               do 601 j=1, m
                  if(dabs(beta(j)) .GT. eps)then
                     jk=jk+1
                     activeset(jk)=j
                  endif
 601           continue
C     it is possible, jk=0 if beta=0, like intercept-only model for
C     large lambda value
C               if(jk .EQ. 0)then
C                  convact=1
C                  exit
C               endif
C     check if the active set was changed--begin
               if(kk .GT. 1)then
                  do 901 j=1, m
                     if(activesetold(j) .NE. activeset(j))then
                        exit
                     endif
                       if(j .EQ. m)then
                               convact = 1
                       endif
 901              continue
                  if(convact .EQ. 1)then
                     exit
                  endif
               endif
C     check if the active set was changed--end
C     now cycle through only the active set
               call midloopGLM(n,m,x,y,xold,yold,weights,mu,eta,offset,
     +              family, 
     +              penalty,lamk,alpha,gam,theta,rescale,standardize,
     +              eps,innermaxit,maxit,thresh,nulldev,wt,beta,b0,yhat,
     +              dev,trace,convmid,satu,ep,pll,normx,xd,avg,
     +              activeset, jk)
               kk=kk+1
 2000       continue
         endif
C     70: end if the block
         if(satu .EQ. 1)then
            good = k - 1
         endif
         convout(k)=convmid
         if(family .NE. 1)then
            do 15 i=1, maxit
               outpll(i,k) = pll(i)
 15         continue
         endif
         
         do 20 j=1, m
            b(j, k) = beta(j)
 20      continue
         bz(k) = b0
         resdev(k) = dev
         call linkinv(n, yhat, family, v)
         do 30 i=1, n
            ypre(i,k) = v(i)
 30      continue
         k = k + 1
         if(k .LE. nlambda .AND. satu .EQ. 0)then
            do 40 j=1,m
               b(j, k) = b(j, k-1)
 40         continue
         endif
         goto 1000
      endif
      
      return
      end  

back to top