fmin_bfgs.f90 Source File


Source Code

subroutine bfgs_with_grad(func,grad,x,l,u,nbd,factr,pgtol,iprint,nloop)
  interface
     function func(x)
       real(8),dimension(:) :: x
       real(8) :: func
     end function func
  end interface
  interface
     function grad(x)
       real(8),dimension(:) :: x
       real(8),dimension(size(x)) :: grad
     end function grad
  end interface
  integer                                   :: n,m = 5, iprint_ = -1
  integer,optional                          :: iprint,nloop
  real(8),optional                          :: factr, pgtol
  real(8)                                   :: factr_,pgtol_
  character(len=60)                         :: task, csave
  logical                                   :: lsave(4)
  integer                                   :: isave(44)
  real(8)                                   :: dsave(29),f
  integer,dimension(:),allocatable          :: iwa,nbd_
  integer,dimension(:),allocatable,optional :: nbd
  real(8),dimension(:),allocatable          :: x,l_,u_,g,wa
  real(8),dimension(:),allocatable,optional :: l,u
  !
  n=size(x)
  factr_  = 1.0d+7
  pgtol_  = 1.0d-5
  iprint_ = -1
  !
  allocate( g(n))
  allocate ( iwa(3*n) )
  allocate ( wa(2*m*n + 5*n + 11*m*m + 8*m) )
  task = 'START'
  if(present(factr))factr_=factr
  if(present(pgtol))pgtol_=pgtol
  if(present(iprint))iprint_=iprint
  if(present(nbd))then
     nbd_=nbd
     l_=l
     u_=u
  else
     allocate ( nbd_(n), l_(n), u_(n))
     nbd_=0
     l_=0.d0
     u_=0.d0
  endif
  !     The beginning of the loop
  do while(task(1:2).eq.'FG'.or.task.eq.'NEW_X'.or.task.eq.'START') 
     !    
     !     This is the call to the L-BFGS-B code.
     call setulb ( n, m, x, l_, u_, nbd_, f, g, factr_, pgtol_, &
          wa, iwa, task, iprint_,&
          csave, lsave, isave, dsave )
     if (task(1:2) .eq. 'FG') then  
        f=func(x)
        g=grad(x)
     endif
     if(present(nloop))then
        if(isave(30) .ge. nloop)task='STOP: TOTAL NO. OF LOOPS EXCEEDS LIMIT'
     endif
  end do
  deallocate (nbd_,l_,u_,iwa,wa,g)
end subroutine bfgs_with_grad



subroutine bfgs_no_grad(func,x,l,u,nbd,factr,pgtol,iprint,nloop)
  interface
     function func(x)
       real(8),dimension(:) :: x
       real(8) :: func
     end function func
  end interface
  integer                                   :: n,m = 5, iprint_ = -1
  integer,optional                          :: iprint,nloop
  real(8),optional                          :: factr, pgtol
  real(8)                                   :: factr_,pgtol_
  character(len=60)                         :: task, csave
  logical                                   :: lsave(4)
  integer                                   :: isave(44)
  real(8)                                   :: dsave(29),f
  integer,dimension(:),allocatable          :: iwa,nbd_
  integer,dimension(:),allocatable,optional :: nbd
  real(8),dimension(:),allocatable          :: x,l_,u_,g,wa
  real(8),dimension(:),allocatable,optional :: l,u
  !
  n=size(x)
  factr_  = 1.0d+7
  pgtol_  = 1.0d-5
  iprint_ = -1
  !
  allocate( g(n))
  allocate ( iwa(3*n) )
  allocate ( wa(2*m*n + 5*n + 11*m*m + 8*m) )
  task = 'START'
  if(present(factr))factr_=factr
  if(present(pgtol))pgtol_=pgtol
  if(present(iprint))iprint_=iprint
  if(present(nbd))then
     nbd_=nbd
     l_=l
     u_=u
  else
     allocate ( nbd_(n), l_(n), u_(n))
     nbd_=0
     l_=0.d0
     u_=0.d0
  endif
  !     The beginning of the loop
  do while(task(1:2).eq.'FG'.or.task.eq.'NEW_X'.or.task.eq.'START') 
     !     This is the call to the L-BFGS-B code.
     call setulb ( n, m, x, l_, u_, nbd_, f, g, factr_, pgtol_, &
          wa, iwa, task, iprint_,&
          csave, lsave, isave, dsave )
     if (task(1:2) .eq. 'FG') then  
        f=func(x)
        g=f_jac_1n_func(func,size(x),x)
     endif
     if(present(nloop))then
        if(isave(30) .ge. nloop)task='STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
     endif
  end do
  deallocate (nbd_,l_,u_,iwa,wa,g)
end subroutine bfgs_no_grad