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

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-77 version)

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