EMPIRE DA  v1.9.1
Data assimilation codes using EMPIRE communication
 All Classes Files Functions Variables Pages
driver3.f90
Go to the documentation of this file.
1 !
2 ! L-BFGS-B is released under the “New BSD License” (aka “Modified BSD License”
3 ! or “3-clause license”)
4 ! Please read attached file License.txt
5 !
6 ! DRIVER 3 in Fortran 90
7 ! --------------------------------------------------------------
8 ! TIME-CONTROLLED DRIVER FOR L-BFGS-B
9 ! --------------------------------------------------------------
10 !
11 ! L-BFGS-B is a code for solving large nonlinear optimization
12 ! problems with simple bounds on the variables.
13 !
14 ! The code can also be used for unconstrained problems and is
15 ! as efficient for these problems as the earlier limited memory
16 ! code L-BFGS.
17 !
18 ! This driver shows how to terminate a run after some prescribed
19 ! CPU time has elapsed, and how to print the desired information
20 ! before exiting.
21 !
22 ! References:
23 !
24 ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
25 ! memory algorithm for bound constrained optimization'',
26 ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
27 !
28 ! [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
29 ! Subroutines for Large Scale Bound Constrained Optimization''
30 ! Tech. Report, NAM-11, EECS Department, Northwestern University,
31 ! 1994.
32 !
33 !
34 ! (Postscript files of these papers are available via anonymous
35 ! ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
36 !
37 ! * * *
38 !
39 ! February 2011 (latest revision)
40 ! Optimization Center at Northwestern University
41 ! Instituto Tecnologico Autonomo de Mexico
42 !
43 ! Jorge Nocedal and Jose Luis Morales
44 !
45 ! **************
46 
47  program driver
48 
49 ! This time-controlled driver shows that it is possible to terminate
50 ! a run by elapsed CPU time, and yet be able to print all desired
51 ! information. This driver also illustrates the use of two
52 ! stopping criteria that may be used in conjunction with a limit
53 ! on execution time. The sample problem used here is the same as in
54 ! driver1 and driver2 (the extended Rosenbrock function with bounds
55 ! on the variables).
56 
57  implicit none
58 
59 ! We specify a limit on the CPU time (tlimit = 10 seconds)
60 !
61 ! We suppress the default output (iprint = -1). The user could
62 ! also elect to use the default output by choosing iprint >= 0.)
63 ! We suppress the code-supplied stopping tests because we will
64 ! provide our own termination conditions
65 ! We specify the dimension n of the sample problem and the number
66 ! m of limited memory corrections stored.
67 
68  integer, parameter :: n = 1000, m = 10, iprint = -1
69  integer, parameter :: dp = kind(1.0d0)
70  real(dp), parameter :: factr = 0.0d0, pgtol = 0.0d0, &
71  tlimit = 10.0d0
72 !
73  character(len=60) :: task, csave
74  logical :: lsave(4)
75  integer :: isave(44)
76  real(dp) :: f
77  real(dp) :: dsave(29)
78  integer, allocatable :: nbd(:), iwa(:)
79  real(dp), allocatable :: x(:), l(:), u(:), g(:), wa(:)
80 !
81  real(dp) :: t1, t2, time1, time2
82  integer :: i, j
83 
84  allocate ( nbd(n), x(n), l(n), u(n), g(n) )
85  allocate ( iwa(3*n) )
86  allocate ( wa(2*m*n + 5*n + 11*m*m + 8*m) )
87 
88 ! This time-controlled driver shows that it is possible to terminate
89 ! a run by elapsed CPU time, and yet be able to print all desired
90 ! information. This driver also illustrates the use of two
91 ! stopping criteria that may be used in conjunction with a limit
92 ! on execution time. The sample problem used here is the same as in
93 ! driver1 and driver2 (the extended Rosenbrock function with bounds
94 ! on the variables).
95 
96 ! We now specify nbd which defines the bounds on the variables:
97 ! l specifies the lower bounds,
98 ! u specifies the upper bounds.
99 
100 ! First set bounds on the odd-numbered variables.
101 
102  do 10 i=1, n,2
103  nbd(i)=2
104  l(i)=1.0d0
105  u(i)=1.0d2
106  10 continue
107 
108 ! Next set bounds on the even-numbered variables.
109 
110  do 12 i=2, n,2
111  nbd(i)=2
112  l(i)=-1.0d2
113  u(i)=1.0d2
114  12 continue
115 
116 ! We now define the starting point.
117 
118  do 14 i=1, n
119  x(i)=3.0d0
120  14 continue
121 
122 ! We now write the heading of the output.
123 
124  write (6,16)
125  16 format(/,5x, 'Solving sample problem.',&
126  /,5x, ' (f = 0.0 at the optimal solution.)',/)
127 
128 ! We start the iteration by initializing task.
129 
130  task = 'START'
131 
132 ! ------- the beginning of the loop ----------
133 
134 ! We begin counting the CPU time.
135 
136  call timer(time1)
137 
138  do while( task(1:2).eq.'FG'.or.task.eq.'NEW_X'.or. &
139  task.eq.'START')
140 
141 ! This is the call to the L-BFGS-B code.
142 
143  call setulb(n,m,x,l,u,nbd,f,g,factr,pgtol,wa,iwa, &
144  task,iprint, csave,lsave,isave,dsave)
145 
146  if (task(1:2) .eq. 'FG') then
147 
148 ! the minimization routine has returned to request the
149 ! function f and gradient g values at the current x.
150 ! Before evaluating f and g we check the CPU time spent.
151 
152  call timer(time2)
153  if (time2-time1 .gt. tlimit) then
154  task='STOP: CPU EXCEEDING THE TIME LIMIT.'
155 
156 ! Note: Assigning task(1:4)='STOP' will terminate the run;
157 ! setting task(7:9)='CPU' will restore the information at
158 ! the latest iterate generated by the code so that it can
159 ! be correctly printed by the driver.
160 
161 ! In this driver we have chosen to disable the
162 ! printing options of the code (we set iprint=-1);
163 ! instead we are using customized output: we print the
164 ! latest value of x, the corresponding function value f and
165 ! the norm of the projected gradient |proj g|.
166 
167 ! We print out the information contained in task.
168 
169  write (6,*) task
170 
171 ! We print the latest iterate contained in wa(j+1:j+n), where
172 
173  j = 3*n+2*m*n+11*m**2
174  write (6,*) 'Latest iterate X ='
175  write (6,'((1x,1p, 6(1x,d11.4)))') (wa(i),i = j+1,j+n)
176 
177 ! We print the function value f and the norm of the projected
178 ! gradient |proj g| at the last iterate; they are stored in
179 ! dsave(2) and dsave(13) respectively.
180 
181  write (6,'(a,1p,d12.5,4x,a,1p,d12.5)') &
182  'At latest iterate f =',dsave(2),'|proj g| =',dsave(13)
183  else
184 
185 ! The time limit has not been reached and we compute
186 ! the function value f for the sample problem.
187 
188  f=.25d0*(x(1)-1.d0)**2
189  do 20 i=2, n
190  f=f+(x(i)-x(i-1)**2)**2
191  20 continue
192  f=4.d0*f
193 
194 ! Compute gradient g for the sample problem.
195 
196  t1 = x(2) - x(1)**2
197  g(1) = 2.d0*(x(1)-1.d0)-1.6d1*x(1)*t1
198  do 22 i=2,n-1
199  t2=t1
200  t1=x(i+1)-x(i)**2
201  g(i)=8.d0*t2-1.6d1*x(i)*t1
202  22 continue
203  g(n)=8.d0*t1
204  endif
205 
206 ! go back to the minimization routine.
207  else
208 
209  if (task(1:5) .eq. 'NEW_X') then
210 
211 ! the minimization routine has returned with a new iterate.
212 ! The time limit has not been reached, and we test whether
213 ! the following two stopping tests are satisfied:
214 
215 ! 1) Terminate if the total number of f and g evaluations
216 ! exceeds 900.
217 
218  if (isave(34) .ge. 900) &
219  task='STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
220 
221 ! 2) Terminate if |proj g|/(1+|f|) < 1.0d-10.
222 
223  if (dsave(13) .le. 1.d-10*(1.0d0 + abs(f))) &
224  task='STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
225 
226 ! We wish to print the following information at each iteration:
227 ! 1) the current iteration number, isave(30),
228 ! 2) the total number of f and g evaluations, isave(34),
229 ! 3) the value of the objective function f,
230 ! 4) the norm of the projected gradient, dsve(13)
231 !
232 ! See the comments at the end of driver1 for a description
233 ! of the variables isave and dsave.
234 
235  write (6,'(2(a,i5,4x),a,1p,d12.5,4x,a,1p,d12.5)') 'Iterate' &
236  ,isave(30),'nfg =',isave(34),'f =',f,'|proj g| =',dsave(13)
237 
238 ! If the run is to be terminated, we print also the information
239 ! contained in task as well as the final value of x.
240 
241  if (task(1:4) .eq. 'STOP') then
242  write (6,*) task
243  write (6,*) 'Final X='
244  write (6,'((1x,1p, 6(1x,d11.4)))') (x(i),i = 1,n)
245  endif
246 
247  endif
248  end if
249  end do
250 
251 ! If task is neither FG nor NEW_X we terminate execution.
252 
253  end program driver
254 
255 !======================= The end of driver3 ============================
256 
program driver
Definition: driver1.f90:190