This time-controlled driver shows that it is possible to terminate a run by elapsed CPU time, and yet be able to print all desired information. This driver also illustrates the use of two stopping criteria that may be used in conjunction with a limit on execution time. The sample problem used here is the same as in driver1 and driver2 (the extended Rosenbrock function with bounds on the variables). (Fortran-77 version)
54 use json_writer,
only: json_write_aggregate
65 parameter(nmax=1024,mmax=17)
73 character*60 task, csave
76 + nbd(nmax), iwa(3*nmax), isave(44)
77 double precision f, factr, pgtol,
78 + x(nmax), l(nmax), u(nmax), g(nmax), dsave(29),
79 + wa(2*mmax*nmax+5*nmax+11*mmax*mmax+8*mmax)
84 double precision t1, t2, time1, time2, tlimit
90 character*512 lbfgsb_json
91 character*64 env_tlimit
97 call get_environment_variable(
'LBFGSB_TLIMIT', env_tlimit)
98 if (len_trim(env_tlimit) .gt. 0)
read(env_tlimit, *) tlimit
147 16
format(/,5x,
'Solving sample problem.',
148 + /,5x,
' (f = 0.0 at the optimal solution.)',/)
155 call get_environment_variable(
'LBFGSB_JSON_OUTPUT', lbfgsb_json)
156 json_active = (len_trim(lbfgsb_json) .gt. 0)
168 call setulb(n,m,x,l,u,nbd,f,g,factr,pgtol,wa,iwa,task,iprint,
169 + csave,lsave,isave,dsave)
171 if (task(1:2) .eq.
'FG')
then
177 if (time2-time1 .gt. tlimit)
then
178 task=
'STOP: CPU EXCEEDING THE TIME LIMIT.'
197 j = 3*n+2*m*n+11*m**2
198 write (6,*)
'Latest iterate X ='
199 write (6,
'((1x,1p, 6(1x,d11.4)))') (wa(i),i = j+1,j+n)
205 write (6,
'(a,1p,d12.5,4x,a,1p,d12.5)')
206 +
'At latest iterate f =',dsave(2),
'|proj g| =',dsave(13)
213 f=.25d0*(x(1)-1.d0)**2
215 f=f+(x(i)-x(i-1)**2)**2
222 g(1)=2.d0*(x(1)-1.d0)-1.6d1*x(1)*t1
226 g(i)=8.d0*t2-1.6d1*x(i)*t1
236 if (task(1:5) .eq.
'NEW_X')
then
244 if (isave(34) .ge. 900)
245 + task=
'STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
249 if (dsave(13) .le. 1.d-10*(1.0d0 + abs(f)))
250 + task=
'STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
262 write (6,
'(2(a,i5,4x),a,1p,d12.5,4x,a,1p,d12.5)')
'Iterate'
263 + ,isave(30),
'nfg =',isave(34),
'f =',f,
'|proj g| =',dsave(13)
269 if (task(1:4) .eq.
'STOP')
then
271 write (6,*)
'Final X='
272 write (6,
'((1x,1p, 6(1x,d11.4)))') (x(i),i = 1,n)
284 if (json_active)
then
285 call json_write_aggregate(trim(lbfgsb_json), task, f,
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...
subroutine timer(ttime)
This routine computes cpu time in double precision.