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-90 version)
50 use json_writer,
only: json_write_aggregate
71 integer,
parameter :: n = 1000, m = 10, iprint = -1
72 integer,
parameter :: dp = kind(1.0d0)
73 real(dp),
parameter :: factr = 0.0d0, pgtol = 0.0d0
76 character(len=60) :: task, csave
81 integer,
allocatable :: nbd(:), iwa(:)
82 real(dp),
allocatable :: x(:), l(:), u(:), g(:), wa(:)
84 real(dp) :: t1, t2, time1, time2
90 character(len=512) :: lbfgsb_json
91 character(len=64) :: env_tlimit
92 logical :: json_active
94 allocate ( nbd(n), x(n), l(n), u(n), g(n) )
96 allocate ( wa(2*m*n + 5*n + 11*m*m + 8*m) )
135 16
format(/,5x,
'Solving sample problem.',&
136 /,5x,
' (f = 0.0 at the optimal solution.)',/)
145 call get_environment_variable(
'LBFGSB_TLIMIT', env_tlimit)
146 if (len_trim(env_tlimit) > 0)
read(env_tlimit, *) tlimit
147 call get_environment_variable(
'LBFGSB_JSON_OUTPUT', lbfgsb_json)
148 json_active = (len_trim(lbfgsb_json) > 0)
156 do while( task(1:2).eq.
'FG'.or.task.eq.
'NEW_X'.or. &
161 call setulb(n,m,x,l,u,nbd,f,g,factr,pgtol,wa,iwa, &
162 task,iprint, csave,lsave,isave,dsave)
164 if (task(1:2) .eq.
'FG')
then
171 if (time2-time1 .gt. tlimit)
then
172 task=
'STOP: CPU EXCEEDING THE TIME LIMIT.'
191 j = 3*n+2*m*n+11*m**2
192 write (6,*)
'Latest iterate X ='
193 write (6,
'((1x,1p, 6(1x,d11.4)))') (wa(i),i = j+1,j+n)
199 write (6,
'(a,1p,d12.5,4x,a,1p,d12.5)') &
200 'At latest iterate f =',dsave(2),
'|proj g| =',dsave(13)
206 f=.25d0*(x(1)-1.d0)**2
208 f=f+(x(i)-x(i-1)**2)**2
215 g(1) = 2.d0*(x(1)-1.d0)-1.6d1*x(1)*t1
219 g(i)=8.d0*t2-1.6d1*x(i)*t1
227 if (task(1:5) .eq.
'NEW_X')
then
236 if (isave(34) .ge. 900) &
237 task=
'STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
241 if (dsave(13) .le. 1.d-10*(1.0d0 + abs(f))) &
242 task=
'STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
253 write (6,
'(2(a,i5,4x),a,1p,d12.5,4x,a,1p,d12.5)')
'Iterate'
254 ,isave(30),
'nfg =',isave(34),
'f =',f,
'|proj g| =',dsave(13)
259 if (task(1:4) .eq.
'STOP')
then
261 write (6,*)
'Final X='
262 write (6,
'((1x,1p, 6(1x,d11.4)))') (x(i),i = 1,n)
272 call json_write_aggregate(trim(lbfgsb_json), task, f, dsave(13)
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.