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)
64 parameter(nmax=1024,mmax=17)
72 character*60 task, csave
75 + nbd(nmax), iwa(3*nmax), isave(44)
76 double precision f, factr, pgtol,
77 + x(nmax), l(nmax), u(nmax), g(nmax), dsave(29),
78 + wa(2*mmax*nmax+5*nmax+11*mmax*mmax+8*mmax)
83 double precision t1, t2, time1, time2, tlimit
137 16
format(/,5x,
'Solving sample problem.',
138 + /,5x,
' (f = 0.0 at the optimal solution.)',/)
154 call setulb(n,m,x,l,u,nbd,f,g,factr,pgtol,wa,iwa,task,iprint,
155 + csave,lsave,isave,dsave)
157 if (task(1:2) .eq.
'FG')
then
163 if (time2-time1 .gt. tlimit)
then
164 task=
'STOP: CPU EXCEEDING THE TIME LIMIT.'
183 j = 3*n+2*m*n+11*m**2
184 write (6,*)
'Latest iterate X ='
185 write (6,
'((1x,1p, 6(1x,d11.4)))') (wa(i),i = j+1,j+n)
191 write (6,
'(a,1p,d12.5,4x,a,1p,d12.5)')
192 +
'At latest iterate f =',dsave(2),
'|proj g| =',dsave(13)
199 f=.25d0*(x(1)-1.d0)**2
201 f=f+(x(i)-x(i-1)**2)**2
208 g(1)=2.d0*(x(1)-1.d0)-1.6d1*x(1)*t1
212 g(i)=8.d0*t2-1.6d1*x(i)*t1
222 if (task(1:5) .eq.
'NEW_X')
then
230 if (isave(34) .ge. 900)
231 + task=
'STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
235 if (dsave(13) .le. 1.d-10*(1.0d0 + abs(f)))
236 + task=
'STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
248 write (6,
'(2(a,i5,4x),a,1p,d12.5,4x,a,1p,d12.5)')
'Iterate'
249 + ,isave(30),
'nfg =',isave(34),
'f =',f,
'|proj g| =',dsave(13)
255 if (task(1:4) .eq.
'STOP')
then
257 write (6,*)
'Final X='
258 write (6,
'((1x,1p, 6(1x,d11.4)))') (x(i),i = 1,n)
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.