358 lines
14 KiB
FortranFixed
358 lines
14 KiB
FortranFixed
|
|
c DRIVER 2
|
|
c --------------------------------------------------------------
|
|
c CUSTOMIZED DRIVER FOR L-BFGS-B (version 2.4)
|
|
c --------------------------------------------------------------
|
|
c
|
|
c L-BFGS-B is a code for solving large nonlinear optimization
|
|
c problems with simple bounds on the variables.
|
|
c
|
|
c The code can also be used for unconstrained problems and is
|
|
c as efficient for these problems as the earlier limited memory
|
|
c code L-BFGS.
|
|
c
|
|
c This driver illustrates how to control the termination of the
|
|
c run and how to design customized output.
|
|
c
|
|
c References:
|
|
c
|
|
c [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
|
|
c memory algorithm for bound constrained optimization'',
|
|
c SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
|
|
c
|
|
c [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
|
|
c Subroutines for Large Scale Bound Constrained Optimization''
|
|
c Tech. Report, NAM-11, EECS Department, Northwestern University,
|
|
c 1994.
|
|
c
|
|
c (Postscript files of these papers are available via anonymous
|
|
c ftp to ece.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
|
|
c
|
|
c * * *
|
|
c
|
|
c NEOS, November 1994. (Latest revision April 1997.)
|
|
c Optimization Technology Center.
|
|
c Argonne National Laboratory and Northwestern University.
|
|
c Written by
|
|
c Ciyou Zhu
|
|
c in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
|
|
c
|
|
c
|
|
c **************
|
|
|
|
subroutine Lbfgsb_2_4(n,x,f,l,u,nbd,funkminfjac,
|
|
& pgtol,info)
|
|
implicit none
|
|
|
|
! info =0, best parameters on output
|
|
! info =1, output may not be best parameters
|
|
! info <0: parameter out of bounds. |info| denotes the out-of-bound parameter
|
|
! info =11: the correlation matrix is not postitive definite (the determinant is negative)
|
|
|
|
c This driver shows how to replace the default stopping test
|
|
c by other termination criteria. It also illustrates how to
|
|
c print the values of several parameters during the course of
|
|
c the iteration. The sample problem used here is the same as in
|
|
c DRIVER1 (the extended Rosenbrock function with bounds on the
|
|
c variables).
|
|
|
|
integer nmax, mmax, lenwa
|
|
parameter (nmax = 1024, mmax = 17)
|
|
parameter (lenwa = 2*mmax*nmax + 4*nmax
|
|
+ + 11*mmax*mmax + 8*mmax)
|
|
|
|
c nmax is the dimension of the largest problem to be solved.
|
|
c mmax is the maximum number of limited memory corrections.
|
|
c lenwa is the corresponding real workspace required.
|
|
|
|
c Declare the variables needed by the code.
|
|
c A description of all these variables is given at the end of
|
|
c driver1.
|
|
|
|
character*60 task, csave
|
|
logical lsave(4)
|
|
integer n, m, iprint, maxiter,info,idogradient,
|
|
+ nbd(nmax), iwa(3*nmax), isave(44)
|
|
double precision f, factr, pgtol,
|
|
+ x(nmax), l(nmax), u(nmax), g(nmax), dsave(29),
|
|
+ wa(lenwa)
|
|
parameter(maxiter=2000)
|
|
external funkminfjac
|
|
|
|
c Declare a few additional local variables.
|
|
|
|
integer i
|
|
|
|
c We suppress the default output.
|
|
|
|
iprint = -1
|
|
|
|
c We suppress both code-supplied stopping tests because the
|
|
c user is providing his own stopping criteria.
|
|
|
|
factr = 1.0d+1
|
|
|
|
! require funkminfjac to do function value and derivative calculations together
|
|
idogradient=1
|
|
|
|
c We specify the number
|
|
c m of limited memory corrections stored. (n and m should not
|
|
c exceed the limits nmax and mmax respectively.)
|
|
|
|
m = 5
|
|
|
|
c All variables have both lower and upper bounds
|
|
|
|
! do 10 i = 1, n
|
|
! nbd(i) = 2
|
|
! 10 continue
|
|
|
|
c We now define the starting point.
|
|
|
|
c We start the iteration by initializing task.
|
|
|
|
task = 'START'
|
|
info=0
|
|
|
|
c ------- The beginning of the loop ----------
|
|
111 continue
|
|
|
|
c 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
|
|
|
|
c The minimization routine has returned to request the
|
|
c function f and gradient g values at the current x.
|
|
|
|
c Compute the cost function value f
|
|
|
|
! call funkmin(n,x,f)
|
|
|
|
c Compute gradient g of the cost function at x
|
|
|
|
! call fjac(n,x,f,g)
|
|
|
|
call funkminfjac(n,x,idogradient,f,g,info)
|
|
|
|
if(info.lt.0.or.info.eq.11)return
|
|
|
|
c Go back to the minimization routine.
|
|
goto 111
|
|
|
|
elseif (task(1:5) .eq. 'NEW_X') then
|
|
c
|
|
c The minimization routine has returned with a new iterate.
|
|
c At this point have the opportunity of stopping the iteration
|
|
c or observing the values of certain parameters
|
|
c
|
|
c First are two examples of stopping tests.
|
|
|
|
c Note: task(1:4) must be assigned the value 'STOP' to terminate
|
|
c the iteration and ensure that the final results are
|
|
c printed in the default format. The rest of the character
|
|
c string task may be used to store other information.
|
|
|
|
c 1) Terminate if the total number of f and g evaluations
|
|
c exceeds maxiter.
|
|
|
|
if (isave(34) .ge. maxiter)
|
|
+ task='STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
|
|
|
|
c 2) Terminate if |proj g|/(1 + |f|) < pgtol, where
|
|
c "proj g" denoted the projected gradient
|
|
|
|
if (dsave(13) .le. pgtol*(1.0d0 + dabs(f)))
|
|
+ task='STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
|
|
|
|
c We now wish to get the following information at each
|
|
c iteration:
|
|
c
|
|
c 1) the current iteration number, isave(30),
|
|
c 2) the total number of f and g evaluations, isave(34),
|
|
c 3) the value of the objective function f,
|
|
c 4) the norm of the projected gradient, dsve(13)
|
|
c
|
|
c See the comments at the end of driver1 for a description
|
|
c of the variables isave and dsave.
|
|
c Go back to the minimization routine.
|
|
goto 111
|
|
|
|
else
|
|
|
|
c We terminate execution when task is neither FG nor NEW_X.
|
|
c We print the information contained in the string task
|
|
c if the default output is not used and the execution is
|
|
c not stopped intentionally by the user. In this case the last
|
|
! x and f may not be the best
|
|
|
|
if (task(1:4).eq.'ERROR')info=1
|
|
|
|
endif
|
|
|
|
c ---------- the end of the loop -------------
|
|
|
|
return
|
|
|
|
end subroutine Lbfgsb_2_4
|
|
|
|
c======================= The end of Lbfgsb_2_4 ============================
|
|
|
|
c --------------------------------------------------------------
|
|
c DESCRIPTION OF THE VARIABLES IN L-BFGS-B
|
|
c --------------------------------------------------------------
|
|
c
|
|
c n is an INTEGER variable that must be set by the user to the
|
|
c number of variables. It is not altered by the routine.
|
|
c
|
|
c m is an INTEGER variable that must be set by the user to the
|
|
c number of corrections used in the limited memory matrix.
|
|
c It is not altered by the routine. Values of m < 3 are
|
|
c not recommended, and large values of m can result in excessive
|
|
c computing time. The range 3 <= m <= 20 is recommended.
|
|
c
|
|
c x is a DOUBLE PRECISION array of length n. On initial entry
|
|
c it must be set by the user to the values of the initial
|
|
c estimate of the solution vector. Upon successful exit, it
|
|
c contains the values of the variables at the best point
|
|
c found (usually an approximate solution).
|
|
c
|
|
c l is a DOUBLE PRECISION array of length n that must be set by
|
|
c the user to the values of the lower bounds on the variables. If
|
|
c the i-th variable has no lower bound, l(i) need not be defined.
|
|
c
|
|
c u is a DOUBLE PRECISION array of length n that must be set by
|
|
c the user to the values of the upper bounds on the variables. If
|
|
c the i-th variable has no upper bound, u(i) need not be defined.
|
|
c
|
|
c nbd is an INTEGER array of dimension n that must be set by the
|
|
c user to the type of bounds imposed on the variables:
|
|
c nbd(i)=0 if x(i) is unbounded,
|
|
c 1 if x(i) has only a lower bound,
|
|
c 2 if x(i) has both lower and upper bounds,
|
|
c 3 if x(i) has only an upper bound.
|
|
c
|
|
c f is a DOUBLE PRECISION variable. If the routine setulb returns
|
|
c with task(1:2)= 'FG', then f must be set by the user to
|
|
c contain the value of the function at the point x.
|
|
c
|
|
c g is a DOUBLE PRECISION array of length n. If the routine setulb
|
|
c returns with taskb(1:2)= 'FG', then g must be set by the user to
|
|
c contain the components of the gradient at the point x.
|
|
c
|
|
c factr is a DOUBLE PRECISION variable that must be set by the user.
|
|
c It is a tolerance in the termination test for the algorithm.
|
|
c The iteration will stop when
|
|
c
|
|
c (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr*epsmch
|
|
c
|
|
c where epsmch is the machine precision which is automatically
|
|
c generated by the code. Typical values for factr on a computer
|
|
c with 15 digits of accuracy in double precision are:
|
|
c factr=1.d+12 for low accuracy;
|
|
c 1.d+7 for moderate accuracy;
|
|
c 1.d+1 for extremely high accuracy.
|
|
c The user can suppress this termination test by setting factr=0.
|
|
c
|
|
c pgtol is a double precision variable.
|
|
c On entry pgtol >= 0 is specified by the user. The iteration
|
|
c will stop when
|
|
c
|
|
c max{|proj g_i | i = 1, ..., n} <= pgtol
|
|
c
|
|
c where pg_i is the ith component of the projected gradient.
|
|
c The user can suppress this termination test by setting pgtol=0.
|
|
c
|
|
c wa is a DOUBLE PRECISION array of length
|
|
c (2mmax + 4)nmax + 11mmax^2 + 8mmax used as workspace.
|
|
c This array must not be altered by the user.
|
|
c
|
|
c iwa is an INTEGER array of length 3nmax used as
|
|
c workspace. This array must not be altered by the user.
|
|
c
|
|
c task is a CHARACTER string of length 60.
|
|
c On first entry, it must be set to 'START'.
|
|
c On a return with task(1:2)='FG', the user must evaluate the
|
|
c function f and gradient g at the returned value of x.
|
|
c On a return with task(1:5)='NEW_X', an iteration of the
|
|
c algorithm has concluded, and f and g contain f(x) and g(x)
|
|
c respectively. The user can decide whether to continue or stop
|
|
c the iteration.
|
|
c When
|
|
c task(1:4)='CONV', the termination test in L-BFGS-B has been
|
|
c satisfied;
|
|
c task(1:4)='ABNO', the routine has terminated abnormally
|
|
c without being able to satisfy the termination conditions,
|
|
c x contains the best approximation found,
|
|
c f and g contain f(x) and g(x) respectively;
|
|
c task(1:5)='ERROR', the routine has detected an error in the
|
|
c input parameters;
|
|
c On exit with task = 'CONV', 'ABNO' or 'ERROR', the variable task
|
|
c contains additional information that the user can print.
|
|
c This array should not be altered unless the user wants to
|
|
c stop the run for some reason. See driver2 or driver3
|
|
c for a detailed explanation on how to stop the run
|
|
c by assigning task(1:4)='STOP' in the driver.
|
|
c
|
|
c iprint is an INTEGER variable that must be set by the user.
|
|
c It controls the frequency and type of output generated:
|
|
c iprint<0 no output is generated;
|
|
c iprint=0 print only one line at the last iteration;
|
|
c 0<iprint<99 print also f and |proj g| every iprint iterations;
|
|
c iprint=99 print details of every iteration except n-vectors;
|
|
c iprint=100 print also the changes of active set and final x;
|
|
c iprint>100 print details of every iteration including x and g;
|
|
c When iprint > 0, the file iterate.dat will be created to
|
|
c summarize the iteration.
|
|
c
|
|
c csave is a CHARACTER working array of length 60.
|
|
c
|
|
c lsave is a LOGICAL working array of dimension 4.
|
|
c On exit with task = 'NEW_X', the following information is
|
|
c available:
|
|
c lsave(1) = .true. the initial x did not satisfy the bounds;
|
|
c lsave(2) = .true. the problem contains bounds;
|
|
c lsave(3) = .true. each variable has upper and lower bounds.
|
|
c
|
|
c isave is an INTEGER working array of dimension 44.
|
|
c On exit with task = 'NEW_X', it contains information that
|
|
c the user may want to access:
|
|
c isave(30) = the current iteration number;
|
|
c isave(34) = the total number of function and gradient
|
|
c evaluations;
|
|
c isave(36) = the number of function value or gradient
|
|
c evaluations in the current iteration;
|
|
c isave(38) = the number of free variables in the current
|
|
c iteration;
|
|
c isave(39) = the number of active constraints at the current
|
|
c iteration;
|
|
c
|
|
c See the subroutine setulb.f for a description of other
|
|
c information contained in isave.
|
|
c
|
|
c dsave is a DOUBLE PRECISION working array of dimension 29.
|
|
c On exit with task = 'NEW_X', it contains information that
|
|
c the user may want to access:
|
|
c dsave(2) = the value of f at the previous iteration;
|
|
c dsave(5) = the machine precision epsmch generated by the code;
|
|
c dsave(13) = the infinity norm of the projected gradient;
|
|
c
|
|
c See the subroutine setulb.f for a description of other
|
|
c information contained in dsave.
|
|
c
|
|
c --------------------------------------------------------------
|
|
c END OF THE DESCRIPTION OF THE VARIABLES IN L-BFGS-B
|
|
c --------------------------------------------------------------
|
|
c
|
|
c << An example of subroutine 'timer' for AIX Version 3.2 >>
|
|
c
|
|
c subroutine timer(ttime)
|
|
c double precision ttime
|
|
c integer itemp, integer mclock
|
|
c
|
|
c itemp = mclock()
|
|
c ttime = dble(itemp)*1.0d-2
|
|
c return
|
|
c end
|
|
c----------------------------------------------------------------------- |