L-BFGS-B  3.0
Large-scale Bound-constrained Optimization
driver2.f90

This driver shows how to replace the default stopping test by other termination criteria. It also illustrates how to print the values of several parameters during the course of the iteration. The sample problem used here is the same as in DRIVER1 (the extended Rosenbrock function with bounds on the variables). (Fortran-90 version)

1 !> \file driver2.f90
2 
3 !
4 ! L-BFGS-B is released under the "New BSD License" (aka "Modified BSD License"
5 ! or "3-clause license")
6 ! Please read attached file License.txt
7 !
8 !
9 ! DRIVER 2 in Fortran 90
10 ! --------------------------------------------------------------
11 ! CUSTOMIZED DRIVER FOR L-BFGS-B
12 ! --------------------------------------------------------------
13 !
14 ! L-BFGS-B is a code for solving large nonlinear optimization
15 ! problems with simple bounds on the variables.
16 !
17 ! The code can also be used for unconstrained problems and is
18 ! as efficient for these problems as the earlier limited memory
19 ! code L-BFGS.
20 !
21 ! This driver illustrates how to control the termination of the
22 ! run and how to design customized output.
23 !
24 ! References:
25 !
26 ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
27 ! memory algorithm for bound constrained optimization'',
28 ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
29 !
30 ! [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
31 ! Subroutines for Large Scale Bound Constrained Optimization''
32 ! Tech. Report, NAM-11, EECS Department, Northwestern University,
33 ! 1994.
34 !
35 !
36 ! (Postscript files of these papers are available via anonymous
37 ! ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
38 !
39 ! * * *
40 !
41 ! February 2011 (latest revision)
42 ! Optimization Center at Northwestern University
43 ! Instituto Tecnologico Autonomo de Mexico
44 !
45 ! Jorge Nocedal and Jose Luis Morales
46 !
47 ! **************
48  program driver
49  use json_writer, only: json_write_aggregate
50 
51 ! This driver shows how to replace the default stopping test
52 ! by other termination criteria. It also illustrates how to
53 ! print the values of several parameters during the course of
54 ! the iteration. The sample problem used here is the same as in
55 ! DRIVER1 (the extended Rosenbrock function with bounds on the
56 ! variables).
57 
58  implicit none
59 
60 ! Declare variables and parameters needed by the code.
61 !
62 ! Note that we suppress the default output (iprint = -1)
63 ! We suppress both code-supplied stopping tests because the
64 ! user is providing his/her own stopping criteria.
65 
66  integer, parameter :: n = 25, m = 5, iprint = -1
67  integer, parameter :: dp = kind(1.0d0)
68  real(dp), parameter :: factr = 0.0d0, pgtol = 0.0d0
69 
70  character(len=60) :: task, csave
71  logical :: lsave(4)
72  integer :: isave(44)
73  real(dp) :: f
74  real(dp) :: dsave(29)
75  integer, allocatable :: nbd(:), iwa(:)
76  real(dp), allocatable :: x(:), l(:), u(:), g(:), wa(:)
77 !
78  real(dp) :: t1, t2
79  integer :: i
80 
81 ! Test instrumentation: dump aggregate end-of-run state to JSON when
82 ! the environment variable LBFGSB_JSON_OUTPUT is set. No-op otherwise.
83 ! LBFGSB_NFG_LIMIT optionally overrides the nfg stopping threshold.
84  character(len=512) :: lbfgsb_json
85  character(len=64) :: env_nfg_limit
86  logical :: json_active
87  integer :: nfg_limit
88 
89  allocate ( nbd(n), x(n), l(n), u(n), g(n) )
90  allocate ( iwa(3*n) )
91  allocate ( wa(2*m*n + 5*n + 11*m*m + 8*m) )
92 !
93 ! This driver shows how to replace the default stopping test
94 ! by other termination criteria. It also illustrates how to
95 ! print the values of several parameters during the course of
96 ! the iteration. The sample problem used here is the same as in
97 ! DRIVER1 (the extended Rosenbrock function with bounds on the
98 ! variables).
99 ! We now specify nbd which defines the bounds on the variables:
100 ! l specifies the lower bounds,
101 ! u specifies the upper bounds.
102 
103 ! First set bounds on the odd numbered variables.
104 
105  do 10 i=1, n,2
106  nbd(i)=2
107  l(i)=1.0d0
108  u(i)=1.0d2
109  10 continue
110 
111 ! Next set bounds on the even numbered variables.
112 
113  do 12 i=2, n,2
114  nbd(i)=2
115  l(i)=-1.0d2
116  u(i)=1.0d2
117  12 continue
118 
119 ! We now define the starting point.
120 
121  do 14 i=1, n
122  x(i)=3.0d0
123  14 continue
124 
125 ! We now write the heading of the output.
126 
127  write (6,16)
128  16 format(/,5x, 'Solving sample problem.', &
129  /,5x, ' (f = 0.0 at the optimal solution.)',/)
130 
131 
132 ! We start the iteration by initializing task.
133 !
134  task = 'START'
135 
136 ! Test instrumentation: enabled when LBFGSB_JSON_OUTPUT is set.
137  call get_environment_variable('LBFGSB_JSON_OUTPUT', lbfgsb_json)
138  json_active = (len_trim(lbfgsb_json) > 0)
139  nfg_limit = 99
140  call get_environment_variable('LBFGSB_NFG_LIMIT', env_nfg_limit)
141  if (len_trim(env_nfg_limit) > 0) read(env_nfg_limit, *) nfg_limit
142 
143 ! ------- the beginning of the loop ----------
144 
145  do while( task(1:2).eq.'FG'.or.task.eq.'NEW_X'.or. &
146  task.eq.'START')
147 
148 ! This is the call to the L-BFGS-B code.
149 
150  call setulb(n,m,x,l,u,nbd,f,g,factr,pgtol,wa,iwa,task,iprint, &
151  csave,lsave,isave,dsave)
152 
153  if (task(1:2) .eq. 'FG') then
154 
155 ! the minimization routine has returned to request the
156 ! function f and gradient g values at the current x.
157 
158 ! Compute function value f for the sample problem.
159 
160  f =.25d0*(x(1) - 1.d0)**2
161  do 20 i=2,n
162  f = f + (x(i) - x(i-1)**2)**2
163  20 continue
164  f = 4.d0*f
165 
166 ! Compute gradient g for the sample problem.
167 
168  t1 = x(2) - x(1)**2
169  g(1) = 2.d0*(x(1) - 1.d0) - 1.6d1*x(1)*t1
170  do 22 i= 2,n-1
171  t2 = t1
172  t1 = x(i+1) - x(i)**2
173  g(i) = 8.d0*t2 - 1.6d1*x(i)*t1
174  22 continue
175  g(n)=8.d0*t1
176 !
177  else
178 !
179  if (task(1:5) .eq. 'NEW_X') then
180 !
181 ! the minimization routine has returned with a new iterate.
182 ! At this point have the opportunity of stopping the iteration
183 ! or observing the values of certain parameters
184 !
185 ! First are two examples of stopping tests.
186 
187 ! Note: task(1:4) must be assigned the value 'STOP' to terminate
188 ! the iteration and ensure that the final results are
189 ! printed in the default format. The rest of the character
190 ! string TASK may be used to store other information.
191 
192 ! 1) Terminate if the total number of f and g evaluations
193 ! exceeds 99.
194 
195  if (isave(34) .ge. nfg_limit) &
196  task='STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
197 
198 ! 2) Terminate if |proj g|/(1+|f|) < 1.0d-10, where
199 ! "proj g" denoted the projected gradient
200 
201  if (dsave(13) .le. 1.d-10*(1.0d0 + abs(f))) &
202  task='STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
203 
204 ! We now wish to print the following information at each
205 ! iteration:
206 !
207 ! 1) the current iteration number, isave(30),
208 ! 2) the total number of f and g evaluations, isave(34),
209 ! 3) the value of the objective function f,
210 ! 4) the norm of the projected gradient, dsve(13)
211 !
212 ! See the comments at the end of driver1 for a description
213 ! of the variables isave and dsave.
214 
215  write (6,'(2(a,i5,4x),a,1p,d12.5,4x,a,1p,d12.5)') 'Iterate' &
216  , isave(30),'nfg =',isave(34),'f =',f,'|proj g| =',dsave(13)
217 
218 ! If the run is to be terminated, we print also the information
219 ! contained in task as well as the final value of x.
220 
221  if (task(1:4) .eq. 'STOP') then
222  write (6,*) task
223  write (6,*) 'Final X='
224  write (6,'((1x,1p, 6(1x,d11.4)))') (x(i),i = 1,n)
225  end if
226 
227  end if
228  end if
229 
230  end do
231 ! ---------- the end of the loop -------------
232 
233 ! If task is neither FG nor NEW_X we terminate execution.
234 
235  if (json_active) &
236  call json_write_aggregate(trim(lbfgsb_json), task, f, dsave(13), n, x)
237 
238  end program driver
239 
240 !======================= The end of driver2 ============================
241 
subroutine setulb(n, m, x, l, u, nbd, f, g, factr, pgtol, wa, iwa, task, iprint, csave, lsave, isave, dsave)
This subroutine partitions the working arrays wa and iwa, and then uses the limited memory BFGS metho...
Definition: setulb.f:190