Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief LBFGS-B routine (version 3.0, April 25, 2011)
10 : !> \note
11 : !> L-BFGS-B (version 3.0, April 25, 2011) converted to Fortran 90 module
12 : !> \par History
13 : !> 02.2005 Update to the new version 2.4 and deleting the blas part of
14 : !> the code (Teodoro Laino)
15 : !> 11.2012 New version 3.0 converted to Fortran 90 (Matthias Krack)
16 : !> 12.2020 Implementation of Space Group Symmetry (Pierre-André Cazade)
17 : !> \author Fawzi Mohamed (first version)
18 : ! **************************************************************************************************
19 : MODULE cp_lbfgs
20 : USE bibliography, ONLY: Byrd1995,&
21 : cite_reference
22 : USE cp_files, ONLY: open_file
23 : USE kinds, ONLY: dp
24 : USE machine, ONLY: default_output_unit,&
25 : m_walltime
26 : USE space_groups, ONLY: spgr_apply_rotations_coord,&
27 : spgr_apply_rotations_force
28 : USE space_groups_types, ONLY: spgr_type
29 : #include "../base/base_uses.f90"
30 :
31 : IMPLICIT NONE
32 :
33 : PRIVATE
34 :
35 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_lbfgs'
36 :
37 : PUBLIC :: setulb
38 :
39 : CONTAINS
40 :
41 : !=========== L-BFGS-B (version 3.0, April 25, 2011) ================
42 : !
43 : ! This is a modified version of L-BFGS-B.
44 : !
45 : ! Major changes are described in the accompanying paper:
46 : !
47 : ! Jorge Nocedal and Jose Luis Morales, Remark on "Algorithm 778:
48 : ! L-BFGS-B: Fortran Subroutines for Large-Scale Bound Constraine
49 : ! Optimization" (2011). To appear in ACM Transactions on
50 : ! Mathematical Software,
51 : !
52 : ! The paper describes an improvement and a correction to Algorithm 7
53 : ! It is shown that the performance of the algorithm can be improved
54 : ! significantly by making a relatively simple modication to the subs
55 : ! minimization phase. The correction concerns an error caused by the
56 : ! of routine dpmeps to estimate machine precision.
57 : !
58 : ! The total work space **wa** required by the new version is
59 : !
60 : ! 2*m*n + 11m*m + 5*n + 8*m
61 : !
62 : ! the old version required
63 : !
64 : ! 2*m*n + 12m*m + 4*n + 12*m
65 : !
66 : !
67 : ! J. Nocedal Department of Electrical Engineering and
68 : ! Computer Science.
69 : ! Northwestern University. Evanston, IL. USA
70 : !
71 : !
72 : ! J.L Morales Departamento de Matematicas,
73 : ! Instituto Tecnologico Autonomo de Mexico
74 : ! Mexico D.F. Mexico.
75 : !
76 : ! March 2011
77 : !
78 : !=======================================================================
79 : ! **************************************************************************************************
80 : !> \brief This subroutine partitions the working arrays wa and iwa, and
81 : !> then uses the limited memory BFGS method to solve the bound
82 : !> constrained optimization problem by calling mainlb.
83 : !> (The direct method will be used in the subspace minimization.)
84 : !> \param n n is the dimension of the problem.
85 : !> \param m m is the maximum number of variable metric corrections
86 : !> used to define the limited memory matrix.
87 : !> \param x On entry x is an approximation to the solution.
88 : !> On exit x is the current approximation.
89 : !> \param lower_bound the lower bound on x.
90 : !> \param upper_bound the upper bound on x.
91 : !> \param nbd nbd represents the type of bounds imposed on the
92 : !> variables, and must be specified as follows:
93 : !> nbd(i)=0 if x(i) is unbounded,
94 : !> 1 if x(i) has only a lower bound,
95 : !> 2 if x(i) has both lower and upper bounds, and
96 : !> 3 if x(i) has only an upper bound.
97 : !> \param f On first entry f is unspecified.
98 : !> On final exit f is the value of the function at x.
99 : !> \param g On first entry g is unspecified.
100 : !> On final exit g is the value of the gradient at x.
101 : !> \param factr factr >= 0 is specified by the user. The iteration
102 : !> will stop when
103 : !>
104 : !> (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr*epsmch
105 : !>
106 : !> where epsmch is the machine precision, which is automatically
107 : !> generated by the code. Typical values for factr: 1.d+12 for
108 : !> low accuracy; 1.d+7 for moderate accuracy; 1.d+1 for extremely
109 : !> high accuracy.
110 : !> \param pgtol pgtol >= 0 is specified by the user. The iteration
111 : !> will stop when
112 : !>
113 : !> max{|proj g_i | i = 1, ..., n} <= pgtol
114 : !>
115 : !> where pg_i is the ith component of the projected gradient.
116 : !> \param wa working array
117 : !> \param iwa integer working array
118 : !> \param task is a working string of characters of length 60 indicating
119 : !> the current job when entering and quitting this subroutine.
120 : !> \param iprint iprint is a variable that must be set by the user.
121 : !> It controls the frequency and type of output generated:
122 : !> iprint<0 no output is generated;
123 : !> iprint=0 print only one line at the last iteration;
124 : !> 0<iprint<99 print also f and |proj g| every iprint iterations;
125 : !> iprint=99 print details of every iteration except n-vectors;
126 : !> iprint=100 print also the changes of active set and final x;
127 : !> iprint>100 print details of every iteration including x and g;
128 : !> When iprint > 0, the file iterate.dat will be created to
129 : !> summarize the iteration.
130 : !> \param csave is a working string of characters
131 : !> \param lsave lsave is a working array
132 : !> On exit with 'task' = NEW_X, the following information is available:
133 : !> If lsave(1) = .true. then the initial X has been replaced by
134 : !> its projection in the feasible set
135 : !> If lsave(2) = .true. then the problem is constrained;
136 : !> If lsave(3) = .true. then each variable has upper and lower bounds;
137 : !> \param isave isave is a working array
138 : !> On exit with 'task' = NEW_X, the following information is available:
139 : !> isave(22) = the total number of intervals explored in the
140 : !> search of Cauchy points;
141 : !> isave(26) = the total number of skipped BFGS updates before the current iteration;
142 : !> isave(30) = the number of current iteration;
143 : !> isave(31) = the total number of BFGS updates prior the current iteration;
144 : !> isave(33) = the number of intervals explored in the search of
145 : !> Cauchy point in the current iteration;
146 : !> isave(34) = the total number of function and gradient evaluations;
147 : !> isave(36) = the number of function value or gradient
148 : !> evaluations in the current iteration;
149 : !> if isave(37) = 0 then the subspace argmin is within the box;
150 : !> if isave(37) = 1 then the subspace argmin is beyond the box;
151 : !> isave(38) = the number of free variables in the current iteration;
152 : !> isave(39) = the number of active constraints in the current iteration;
153 : !> n + 1 - isave(40) = the number of variables leaving the set of
154 : !> active constraints in the current iteration;
155 : !> isave(41) = the number of variables entering the set of active
156 : !> constraints in the current iteration.
157 : !> \param dsave dsave is a working array of dimension 29.
158 : !> On exit with 'task' = NEW_X, the following information is available:
159 : !> dsave(1) = current 'theta' in the BFGS matrix;
160 : !> dsave(2) = f(x) in the previous iteration;
161 : !> dsave(3) = factr*epsmch;
162 : !> dsave(4) = 2-norm of the line search direction vector;
163 : !> dsave(5) = the machine precision epsmch generated by the code;
164 : !> dsave(7) = the accumulated time spent on searching for Cauchy points;
165 : !> dsave(8) = the accumulated time spent on subspace minimization;
166 : !> dsave(9) = the accumulated time spent on line search;
167 : !> dsave(11) = the slope of the line search function at the current point of line search;
168 : !> dsave(12) = the maximum relative step length imposed in line search;
169 : !> dsave(13) = the infinity norm of the projected gradient;
170 : !> dsave(14) = the relative step length in the line search;
171 : !> dsave(15) = the slope of the line search function at the starting point of the line search;
172 : !> dsave(16) = the square of the 2-norm of the line search direction vector.
173 : !> \param trust_radius ...
174 : !> \param spgr ...
175 : !> \param iwunit User-specified write unit, if not set then WRITE statements
176 : !> write to default_output_unit by default
177 : !> \par History
178 : !> 12.2020 Implementation of Space Group Symmetry [pcazade]
179 : !> \author NEOS, November 1994. (Latest revision June 1996.)
180 : !> Optimization Technology Center.
181 : !> Argonne National Laboratory and Northwestern University.
182 : !> Written by
183 : !> Ciyou Zhu
184 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
185 : ! **************************************************************************************************
186 3181 : SUBROUTINE setulb(n, m, x, lower_bound, upper_bound, nbd, f, g, factr, pgtol, wa, iwa, &
187 : task, iprint, csave, lsave, isave, dsave, trust_radius, spgr, iwunit)
188 :
189 : INTEGER, INTENT(in) :: n, m
190 : REAL(KIND=dp), INTENT(inout) :: x(n)
191 : REAL(KIND=dp) :: lower_bound(n), upper_bound(n)
192 : INTEGER :: nbd(n)
193 : REAL(KIND=dp) :: f, g(n)
194 : REAL(KIND=dp), INTENT(in) :: factr, pgtol
195 : REAL(KIND=dp) :: wa(2*m*n + 5*n + 11*m*m + 8*m)
196 : INTEGER :: iwa(3*n)
197 : CHARACTER(LEN=60) :: task
198 : INTEGER :: iprint
199 : CHARACTER(LEN=60) :: csave
200 : LOGICAL :: lsave(4)
201 : INTEGER :: isave(44)
202 : REAL(KIND=dp) :: dsave(29)
203 : REAL(KIND=dp), INTENT(in) :: trust_radius
204 : TYPE(spgr_type), OPTIONAL, POINTER :: spgr
205 : INTEGER, OPTIONAL :: iwunit
206 :
207 : INTEGER :: i, ld, lr, lsnd, lss, lsy, lt, lwa, lwn, &
208 : lws, lwt, lwy, lxp, lz, wunit
209 :
210 : ! References:
211 : !
212 : ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
213 : ! memory algorithm for bound constrained optimization'',
214 : ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
215 : !
216 : ! [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: a
217 : ! limited memory FORTRAN code for solving bound constrained
218 : ! optimization problems'', Tech. Report, NAM-11, EECS Department,
219 : ! Northwestern University, 1994.
220 : !
221 : ! (Postscript files of these papers are available via anonymous
222 : ! ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
223 : !
224 : ! * * *
225 :
226 3181 : wunit = default_output_unit
227 3181 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
228 :
229 3181 : IF (task == 'START') THEN
230 45 : CALL cite_reference(Byrd1995)
231 45 : isave(1) = m*n
232 45 : isave(2) = m**2
233 45 : isave(3) = 4*m**2
234 : ! ws m*n
235 45 : isave(4) = 1
236 : ! wy m*n
237 45 : isave(5) = isave(4) + isave(1)
238 : ! wsy m**2
239 45 : isave(6) = isave(5) + isave(1)
240 : ! wss m**2
241 45 : isave(7) = isave(6) + isave(2)
242 : ! wt m**2
243 45 : isave(8) = isave(7) + isave(2)
244 : ! wn 4*m**2
245 45 : isave(9) = isave(8) + isave(2)
246 : ! wsnd 4*m**2
247 45 : isave(10) = isave(9) + isave(3)
248 : ! wz n
249 45 : isave(11) = isave(10) + isave(3)
250 : ! wr n
251 45 : isave(12) = isave(11) + n
252 : ! wd n
253 45 : isave(13) = isave(12) + n
254 : ! wt n
255 45 : isave(14) = isave(13) + n
256 : ! wxp n
257 45 : isave(15) = isave(14) + n
258 : ! wa 8*m
259 45 : isave(16) = isave(15) + n
260 : END IF
261 3181 : lws = isave(4)
262 3181 : lwy = isave(5)
263 3181 : lsy = isave(6)
264 3181 : lss = isave(7)
265 3181 : lwt = isave(8)
266 3181 : lwn = isave(9)
267 3181 : lsnd = isave(10)
268 3181 : lz = isave(11)
269 3181 : lr = isave(12)
270 3181 : ld = isave(13)
271 3181 : lt = isave(14)
272 3181 : lxp = isave(15)
273 3181 : lwa = isave(16)
274 :
275 : !in case we use a trust radius we set the boundaries to be one times the trust radius away from the current positions
276 : !the original implementation only allowed for boundaries that remain constant during the optimization.
277 : !This way of including a trust radius seems to work,
278 : !but the change of the boundaries during optimization might introduce some not yet discovered problems.
279 3181 : IF (trust_radius >= 0) THEN
280 81371 : DO i = 1, n
281 81318 : lower_bound(i) = x(i) - trust_radius
282 81318 : upper_bound(i) = x(i) + trust_radius
283 81371 : nbd(i) = 2
284 : END DO
285 : END IF
286 :
287 : ! passes spgr and wunit to mainlb
288 : CALL mainlb(n, m, x, lower_bound, upper_bound, nbd, f, g, factr, pgtol, &
289 : wa(lws), wa(lwy), wa(lsy), wa(lss), wa(lwt), &
290 : wa(lwn), wa(lsnd), wa(lz), wa(lr), wa(ld), wa(lt), wa(lxp), &
291 : wa(lwa), &
292 : iwa(1), iwa(n + 1), iwa(2*n + 1), task, iprint, &
293 3181 : csave, lsave, isave(22), dsave, spgr, wunit)
294 :
295 3181 : RETURN
296 :
297 : END SUBROUTINE setulb
298 :
299 : ! **************************************************************************************************
300 : !> \brief This subroutine solves bound constrained optimization problems by
301 : !> using the compact formula of the limited memory BFGS updates.
302 : !> \param n n is the number of variables
303 : !> \param m m is the maximum number of variable metric
304 : !> corrections allowed in the limited memory matrix.
305 : !> \param x On entry x is an approximation to the solution.
306 : !> On exit x is the current approximation.
307 : !> \param lower_bound lower_bound is the lower bound of x.
308 : !> \param upper_bound upper_bound is the upper bound of x.
309 : !> \param nbd nbd represents the type of bounds imposed on the
310 : !> variables, and must be specified as follows:
311 : !> nbd(i)=0 if x(i) is unbounded,
312 : !> 1 if x(i) has only a lower bound,
313 : !> 2 if x(i) has both lower and upper bounds,
314 : !> 3 if x(i) has only an upper bound.
315 : !> \param f On first entry f is unspecified.
316 : !> On final exit f is the value of the function at x.
317 : !> \param g On first entry g is unspecified.
318 : !> On final exit g is the value of the gradient at x.
319 : !> \param factr factr >= 0 is specified by the user. The iteration
320 : !> will stop when
321 : !>
322 : !> (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr*epsmch
323 : !>
324 : !> where epsmch is the machine precision, which is automatically
325 : !> generated by the code.
326 : !> \param pgtol pgtol >= 0 is specified by the user. The iteration
327 : !> will stop when
328 : !>
329 : !> max{|proj g_i | i = 1, ..., n} <= pgtol
330 : !>
331 : !> where pg_i is the ith component of the projected gradient.
332 : !> \param ws ws, wy, sy, and wt are working arrays used to store the following
333 : !> information defining the limited memory BFGS matrix:
334 : !> ws stores S, the matrix of s-vectors;
335 : !> \param wy stores Y, the matrix of y-vectors;
336 : !> \param sy stores S'Y;
337 : !> \param ss stores S'S;
338 : !> \param wt stores the Cholesky factorization of (theta*S'S+LD^(-1)L');
339 : !> see eq. (2.26) in [3].
340 : !> \param wn wn is a working array of dimension 2m x 2m
341 : !> used to store the LEL^T factorization of the indefinite matrix
342 : !> K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
343 : !> [L_a -R_z theta*S'AA'S ]
344 : !>
345 : !> where E = [-I 0]
346 : !> [ 0 I]
347 : !> \param snd is a working array of dimension 2m x 2m
348 : !> used to store the lower triangular part of
349 : !> N = [Y' ZZ'Y L_a'+R_z']
350 : !> [L_a +R_z S'AA'S ]
351 : !> \param z z(n),r(n),d(n),t(n), xp(n),wa(8*m) are working arrays
352 : !> z is used at different times to store the Cauchy point and
353 : !> the Newton point.
354 : !> \param r working array
355 : !> \param d working array
356 : !> \param t workign array
357 : !> \param xp xp is a workng array used to safeguard the projected Newton direction
358 : !> \param wa working array
359 : !> \param index In subroutine freev, index is used to store the free and fixed
360 : !> variables at the Generalized Cauchy Point (GCP).
361 : !> \param iwhere iwhere is an integer working array of dimension n used to record
362 : !> the status of the vector x for GCP computation.
363 : !> iwhere(i)=0 or -3 if x(i) is free and has bounds,
364 : !> 1 if x(i) is fixed at l(i), and l(i) .ne. u(i)
365 : !> 2 if x(i) is fixed at u(i), and u(i) .ne. l(i)
366 : !> 3 if x(i) is always fixed, i.e., u(i)=x(i)=l(i)
367 : !> -1 if x(i) is always free, i.e., no bounds on it.
368 : !> \param indx2 indx2 is a working array. Within subroutine cauchy, indx2 corresponds to the array iorder.
369 : !> In subroutine freev, a list of variables entering and leaving
370 : !> the free set is stored in indx2, and it is passed on to
371 : !> subroutine formk with this information
372 : !> \param task task is a working string of characters indicating
373 : !> the current job when entering and leaving this subroutine.
374 : !> \param iprint is an variable that must be set by the user.
375 : !> It controls the frequency and type of output generated:
376 : !> iprint<0 no output is generated;
377 : !> iprint=0 print only one line at the last iteration;
378 : !> 0<iprint<99 print also f and |proj g| every iprint iterations;
379 : !> iprint=99 print details of every iteration except n-vectors;
380 : !> iprint=100 print also the changes of active set and final x;
381 : !> iprint>100 print details of every iteration including x and g;
382 : !> When iprint > 0, the file iterate.dat will be created to summarize the iteration.
383 : !> \param csave csave is a working string of characters
384 : !> \param lsave lsave is a logical working array
385 : !> \param isave isave is an integer working array
386 : !> \param dsave is a double precision working array
387 : !> \param spgr ...
388 : !> \param iwunit User-specified write unit, if not set then WRITE statements
389 : !> write to default_output_unit by default
390 : !> \par History
391 : !> 12.2020 Implementation of Space Group Symmetry [pcazade]
392 : !> \author NEOS, November 1994. (Latest revision June 1996.)
393 : !> Optimization Technology Center.
394 : !> Argonne National Laboratory and Northwestern University.
395 : !> Written by
396 : !> Ciyou Zhu
397 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
398 : ! **************************************************************************************************
399 3181 : SUBROUTINE mainlb(n, m, x, lower_bound, upper_bound, nbd, f, g, factr, pgtol, ws, wy, &
400 3181 : sy, ss, wt, wn, snd, z, r, d, t, xp, wa, &
401 3181 : index, iwhere, indx2, task, &
402 : iprint, csave, lsave, isave, dsave, spgr, iwunit)
403 : INTEGER, INTENT(in) :: n, m
404 : REAL(KIND=dp), INTENT(inout) :: x(n)
405 : REAL(KIND=dp), INTENT(in) :: lower_bound(n), upper_bound(n)
406 : INTEGER :: nbd(n)
407 : REAL(KIND=dp) :: f, g(n), factr, pgtol, ws(n, m), wy(n, m), sy(m, m), ss(m, m), wt(m, m), &
408 : wn(2*m, 2*m), snd(2*m, 2*m), z(n), r(n), d(n), t(n), xp(n), wa(8*m)
409 : INTEGER :: INDEX(n), iwhere(n), indx2(n)
410 : CHARACTER(LEN=60) :: task
411 : INTEGER :: iprint
412 : CHARACTER(LEN=60) :: csave
413 : LOGICAL :: lsave(4)
414 : INTEGER :: isave(23)
415 : REAL(KIND=dp) :: dsave(29)
416 : TYPE(spgr_type), OPTIONAL, POINTER :: spgr
417 : INTEGER, OPTIONAL :: iwunit
418 :
419 : REAL(KIND=dp), PARAMETER :: one = 1.0_dp, zero = 0.0_dp
420 :
421 : CHARACTER(LEN=3) :: word
422 : INTEGER :: col, head, i, iback, ifun, ileave, info, &
423 : itail, iter, itfile, iupdat, iword, k, &
424 : nact, nenter, nfgv, nfree, nintol, &
425 : nseg, nskip, wunit
426 : LOGICAL :: boxed, constrained, first, &
427 : keep_space_group, updatd, wrk, &
428 : x_projected
429 : REAL(KIND=dp) :: cachyt, cpu1, cpu2, ddot, ddum, dnorm, dr, dtd, epsmch, fold, g_inf_norm, &
430 : gd, gdold, lnscht, rr, sbtime, step_max, stp, theta, time, time1, time2, tol, xstep
431 :
432 : ! References:
433 : !
434 : ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
435 : ! memory algorithm for bound constrained optimization'',
436 : ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
437 : !
438 : ! [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
439 : ! Subroutines for Large Scale Bound Constrained Optimization''
440 : ! Tech. Report, NAM-11, EECS Department, Northwestern University,
441 : ! 1994.
442 : !
443 : ! [3] R. Byrd, J. Nocedal and R. Schnabel "Representations of
444 : ! Quasi-Newton Matrices and their use in Limited Memory Methods'',
445 : ! Mathematical Programming 63 (1994), no. 4, pp. 129-156.
446 : !
447 : ! (Postscript files of these papers are available via anonymous
448 : ! ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
449 : !
450 : ! * * *
451 :
452 3181 : wunit = default_output_unit
453 3181 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
454 :
455 3181 : keep_space_group = .FALSE.
456 3181 : IF (PRESENT(spgr)) THEN
457 3136 : IF (ASSOCIATED(spgr)) keep_space_group = spgr%keep_space_group
458 : END IF
459 :
460 3181 : IF (task == 'START') THEN
461 :
462 45 : epsmch = EPSILON(one)
463 :
464 45 : CALL timer(time1)
465 :
466 : ! Initialize counters and scalars when task='START'.
467 :
468 : ! for the limited memory BFGS matrices:
469 45 : col = 0
470 45 : head = 1
471 45 : theta = one
472 45 : iupdat = 0
473 45 : updatd = .FALSE.
474 45 : iback = 0
475 45 : itail = 0
476 45 : iword = 0
477 45 : nact = 0
478 45 : ileave = 0
479 45 : nenter = 0
480 45 : fold = zero
481 45 : dnorm = zero
482 45 : cpu1 = zero
483 45 : gd = zero
484 45 : step_max = zero
485 45 : g_inf_norm = zero
486 45 : stp = zero
487 45 : gdold = zero
488 45 : dtd = zero
489 :
490 : ! for operation counts:
491 45 : iter = 0
492 45 : nfgv = 0
493 45 : nseg = 0
494 45 : nintol = 0
495 45 : nskip = 0
496 45 : nfree = n
497 45 : ifun = 0
498 : ! for stopping tolerance:
499 45 : tol = factr*epsmch
500 :
501 : ! for measuring running time:
502 45 : cachyt = 0
503 45 : sbtime = 0
504 45 : lnscht = 0
505 :
506 : ! 'word' records the status of subspace solutions.
507 45 : word = '---'
508 :
509 : ! 'info' records the termination information.
510 45 : info = 0
511 :
512 45 : itfile = 8
513 45 : IF (iprint >= 1) THEN
514 : ! open a summary file 'iterate.dat'
515 45 : CALL open_file(file_name='iterate.dat', unit_number=itfile, file_action='WRITE', file_status='UNKNOWN')
516 : END IF
517 :
518 : ! Check the input arguments for errors.
519 :
520 45 : CALL errclb(n, m, factr, lower_bound, upper_bound, nbd, task, info, k)
521 45 : IF (task(1:5) == 'ERROR') THEN
522 : CALL prn3lb(n, x, f, task, iprint, info, itfile, &
523 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
524 : zero, nseg, word, iback, stp, xstep, k, &
525 0 : cachyt, sbtime, lnscht, wunit)
526 0 : RETURN
527 : END IF
528 :
529 45 : CALL prn1lb(n, m, lower_bound, upper_bound, x, iprint, itfile, epsmch, wunit)
530 :
531 : ! Initialize iwhere & project x onto the feasible set.
532 :
533 45 : CALL active(n, lower_bound, upper_bound, nbd, x, iwhere, iprint, x_projected, constrained, boxed, wunit)
534 : ! applies rotation matrices to coordinates
535 45 : IF (keep_space_group) THEN
536 0 : CALL spgr_apply_rotations_coord(spgr, x)
537 : END IF
538 :
539 : ! The end of the initialization.
540 45 : task = 'FG_START'
541 : ! return to the driver to calculate f and g; reenter at 111.
542 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
543 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
544 45 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
545 45 : RETURN
546 : ELSE
547 : ! applies rotation matrices to coordinates
548 3136 : IF (keep_space_group) THEN
549 2 : CALL spgr_apply_rotations_coord(spgr, x)
550 2 : CALL spgr_apply_rotations_force(spgr, g)
551 : END IF
552 :
553 : ! restore local variables.
554 :
555 3136 : x_projected = lsave(1)
556 3136 : constrained = lsave(2)
557 3136 : boxed = lsave(3)
558 3136 : updatd = lsave(4)
559 :
560 3136 : nintol = isave(1)
561 3136 : itfile = isave(3)
562 3136 : iback = isave(4)
563 3136 : nskip = isave(5)
564 3136 : head = isave(6)
565 3136 : col = isave(7)
566 3136 : itail = isave(8)
567 3136 : iter = isave(9)
568 3136 : iupdat = isave(10)
569 3136 : nseg = isave(12)
570 3136 : nfgv = isave(13)
571 3136 : info = isave(14)
572 3136 : ifun = isave(15)
573 3136 : iword = isave(16)
574 3136 : nfree = isave(17)
575 3136 : nact = isave(18)
576 3136 : ileave = isave(19)
577 3136 : nenter = isave(20)
578 :
579 3136 : theta = dsave(1)
580 3136 : fold = dsave(2)
581 3136 : tol = dsave(3)
582 3136 : dnorm = dsave(4)
583 3136 : epsmch = dsave(5)
584 3136 : cpu1 = dsave(6)
585 3136 : cachyt = dsave(7)
586 3136 : sbtime = dsave(8)
587 3136 : lnscht = dsave(9)
588 3136 : time1 = dsave(10)
589 3136 : gd = dsave(11)
590 3136 : step_max = dsave(12)
591 3136 : g_inf_norm = dsave(13)
592 3136 : stp = dsave(14)
593 3136 : gdold = dsave(15)
594 3136 : dtd = dsave(16)
595 :
596 : ! After returning from the driver go to the point where execution
597 : ! is to resume.
598 :
599 3136 : IF (task(1:4) == 'STOP') THEN
600 0 : IF (task(7:9) == 'CPU') THEN
601 : ! restore the previous iterate.
602 0 : CALL dcopy(n, t, 1, x, 1)
603 0 : CALL dcopy(n, r, 1, g, 1)
604 0 : f = fold
605 : END IF
606 0 : CALL timer(time2)
607 0 : time = time2 - time1
608 : CALL prn3lb(n, x, f, task, iprint, info, itfile, &
609 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
610 : time, nseg, word, iback, stp, xstep, k, &
611 0 : cachyt, sbtime, lnscht, wunit)
612 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
613 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
614 0 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
615 0 : RETURN
616 : END IF
617 : END IF
618 :
619 3136 : IF (.NOT. (task(1:5) == 'FG_LN' .OR. task(1:5) == 'NEW_X')) THEN
620 :
621 : ! Compute f0 and g0.
622 44 : nfgv = 1
623 :
624 : ! Compute the infinity norm of the (-) projected gradient.
625 :
626 44 : CALL projgr(n, lower_bound, upper_bound, nbd, x, g, g_inf_norm)
627 :
628 44 : IF (iprint >= 1) THEN
629 44 : WRITE (wunit, 1002) iter, f, g_inf_norm
630 44 : WRITE (itfile, 1003) iter, nfgv, g_inf_norm, f
631 : END IF
632 44 : IF (g_inf_norm <= pgtol) THEN
633 : ! terminate the algorithm.
634 0 : task = 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
635 0 : CALL timer(time2)
636 0 : time = time2 - time1
637 : CALL prn3lb(n, x, f, task, iprint, info, itfile, &
638 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
639 : time, nseg, word, iback, stp, xstep, k, &
640 0 : cachyt, sbtime, lnscht, wunit)
641 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
642 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
643 0 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
644 0 : RETURN
645 : END IF
646 : END IF
647 :
648 : first = .TRUE.
649 : DO WHILE (.TRUE.)
650 4576 : IF (.NOT. first .OR. .NOT. (task(1:5) == 'FG_LN' .OR. task(1:5) == 'NEW_X')) THEN
651 1484 : IF (iprint >= 99) WRITE (wunit, 1001) iter + 1
652 1484 : iword = -1
653 : !
654 1484 : IF (.NOT. constrained .AND. col > 0) THEN
655 : ! skip the search for GCP.
656 1423 : CALL dcopy(n, x, 1, z, 1)
657 1423 : wrk = updatd
658 1423 : nseg = 0
659 : ELSE
660 :
661 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
662 : !
663 : ! Compute the Generalized Cauchy Point (GCP).
664 : !
665 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
666 :
667 61 : CALL timer(cpu1)
668 : CALL cauchy(n, x, lower_bound, upper_bound, nbd, g, indx2, iwhere, t, d, z, &
669 : m, wy, ws, sy, wt, theta, col, head, &
670 : wa(1), wa(2*m + 1), wa(4*m + 1), wa(6*m + 1), nseg, &
671 61 : iprint, g_inf_norm, info, epsmch, wunit)
672 : ! applies rotation matrices to coordinates
673 61 : IF (keep_space_group) THEN
674 1 : CALL spgr_apply_rotations_coord(spgr, z)
675 : END IF
676 61 : IF (info /= 0) THEN
677 : ! singular triangular system detected; refresh the lbfgs memory.
678 0 : IF (iprint >= 1) WRITE (wunit, 1005)
679 0 : info = 0
680 0 : col = 0
681 0 : head = 1
682 0 : theta = one
683 0 : iupdat = 0
684 0 : updatd = .FALSE.
685 0 : CALL timer(cpu2)
686 0 : cachyt = cachyt + cpu2 - cpu1
687 0 : first = .FALSE.
688 0 : CYCLE
689 : END IF
690 61 : CALL timer(cpu2)
691 61 : cachyt = cachyt + cpu2 - cpu1
692 61 : nintol = nintol + nseg
693 :
694 : ! Count the entering and leaving variables for iter > 0;
695 : ! find the index set of free and active variables at the GCP.
696 :
697 : CALL freev(n, nfree, index, nenter, ileave, indx2, &
698 61 : iwhere, wrk, updatd, constrained, iprint, iter, wunit)
699 61 : nact = n - nfree
700 :
701 : END IF
702 :
703 : ! If there are no free variables or B=theta*I, then
704 : ! skip the subspace minimization.
705 :
706 1484 : IF (.NOT. (nfree == 0 .OR. col == 0)) THEN
707 :
708 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
709 : !
710 : ! Subspace minimization.
711 : !
712 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
713 :
714 1436 : CALL timer(cpu1)
715 :
716 : ! Form the LEL^T factorization of the indefinite
717 : ! matrix K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
718 : ! [L_a -R_z theta*S'AA'S ]
719 : ! where E = [-I 0]
720 : ! [ 0 I]
721 :
722 1436 : IF (wrk) CALL formk(n, nfree, index, nenter, ileave, indx2, iupdat, &
723 1436 : updatd, wn, snd, m, ws, wy, sy, theta, col, head, info)
724 1436 : IF (info /= 0) THEN
725 : ! nonpositive definiteness in Cholesky factorization;
726 : ! refresh the lbfgs memory and restart the iteration.
727 0 : IF (iprint >= 1) WRITE (wunit, 1006)
728 0 : info = 0
729 0 : col = 0
730 0 : head = 1
731 0 : theta = one
732 0 : iupdat = 0
733 0 : updatd = .FALSE.
734 0 : CALL timer(cpu2)
735 0 : sbtime = sbtime + cpu2 - cpu1
736 0 : first = .FALSE.
737 0 : CYCLE
738 : END IF
739 :
740 : ! compute r=-Z'B(xcp-xk)-Z'g (using wa(2m+1)=W'(xcp-x)
741 : ! from 'cauchy').
742 : CALL cmprlb(n, m, x, g, ws, wy, sy, wt, z, r, wa, index, &
743 1436 : theta, col, head, nfree, constrained, info)
744 : ! applies rotation matrices to coordinates
745 1436 : IF (keep_space_group) THEN
746 0 : CALL spgr_apply_rotations_force(spgr, r)
747 : END IF
748 1436 : IF (info == 0) THEN
749 :
750 : ! call the direct method.
751 :
752 : CALL subsm(n, m, nfree, index, lower_bound, upper_bound, nbd, z, r, xp, ws, wy, &
753 1436 : theta, x, g, col, head, iword, wa, wn, iprint, info, wunit)
754 : ! applies rotation matrices to coordinates
755 1436 : IF (keep_space_group) THEN
756 0 : CALL spgr_apply_rotations_coord(spgr, z)
757 0 : CALL spgr_apply_rotations_force(spgr, r)
758 : END IF
759 : END IF
760 1436 : IF (info /= 0) THEN
761 : ! singular triangular system detected;
762 : ! refresh the lbfgs memory and restart the iteration.
763 0 : IF (iprint >= 1) WRITE (wunit, 1005)
764 0 : info = 0
765 0 : col = 0
766 0 : head = 1
767 0 : theta = one
768 0 : iupdat = 0
769 0 : updatd = .FALSE.
770 0 : CALL timer(cpu2)
771 0 : sbtime = sbtime + cpu2 - cpu1
772 0 : first = .FALSE.
773 0 : CYCLE
774 : END IF
775 :
776 1436 : CALL timer(cpu2)
777 1436 : sbtime = sbtime + cpu2 - cpu1
778 : END IF
779 :
780 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
781 : !
782 : ! Line search and optimality tests.
783 : !
784 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
785 :
786 : ! Generate the search direction d:=z-x.
787 : ! applies rotation matrices to coordinates
788 1484 : IF (keep_space_group) THEN
789 1 : CALL spgr_apply_rotations_coord(spgr, x)
790 1 : CALL spgr_apply_rotations_coord(spgr, z)
791 : END IF
792 866144 : DO i = 1, n
793 866144 : d(i) = z(i) - x(i)
794 : END DO
795 1484 : CALL timer(cpu1)
796 : END IF
797 4576 : IF (.NOT. first .OR. .NOT. (task(1:5) == 'NEW_X')) THEN
798 : ! applies rotation matrices to coordinates
799 3135 : IF (keep_space_group) THEN
800 2 : CALL spgr_apply_rotations_coord(spgr, x)
801 2 : CALL spgr_apply_rotations_coord(spgr, z)
802 2 : CALL spgr_apply_rotations_force(spgr, d)
803 2 : CALL spgr_apply_rotations_force(spgr, g)
804 2 : CALL spgr_apply_rotations_force(spgr, r)
805 : END IF
806 : CALL lnsrlb(n, lower_bound, upper_bound, nbd, x, f, fold, gd, gdold, g, d, r, t, z, stp, dnorm, &
807 : dtd, xstep, step_max, iter, ifun, iback, nfgv, info, task, &
808 3135 : boxed, constrained, csave, isave(22), dsave(17), wunit)
809 : ! applies rotation matrices to coordinates
810 3135 : IF (keep_space_group) THEN
811 2 : CALL spgr_apply_rotations_coord(spgr, x)
812 2 : CALL spgr_apply_rotations_force(spgr, g)
813 : END IF
814 3135 : IF (info /= 0 .OR. iback >= 20) THEN
815 : ! restore the previous iterate.
816 0 : CALL dcopy(n, t, 1, x, 1)
817 0 : CALL dcopy(n, r, 1, g, 1)
818 0 : f = fold
819 0 : IF (col == 0) THEN
820 : ! abnormal termination.
821 0 : IF (info == 0) THEN
822 0 : info = -9
823 : ! restore the actual number of f and g evaluations etc.
824 0 : nfgv = nfgv - 1
825 0 : ifun = ifun - 1
826 0 : iback = iback - 1
827 : END IF
828 0 : task = 'ABNORMAL_TERMINATION_IN_LNSRCH'
829 0 : iter = iter + 1
830 0 : CALL timer(time2)
831 0 : time = time2 - time1
832 : CALL prn3lb(n, x, f, task, iprint, info, itfile, &
833 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
834 : time, nseg, word, iback, stp, xstep, k, &
835 0 : cachyt, sbtime, lnscht, wunit)
836 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
837 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
838 0 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
839 0 : RETURN
840 : ELSE
841 : ! refresh the lbfgs memory and restart the iteration.
842 0 : IF (iprint >= 1) WRITE (wunit, 1008)
843 0 : IF (info == 0) nfgv = nfgv - 1
844 0 : info = 0
845 0 : col = 0
846 0 : head = 1
847 0 : theta = one
848 0 : iupdat = 0
849 0 : updatd = .FALSE.
850 0 : task = 'RESTART_FROM_LNSRCH'
851 0 : CALL timer(cpu2)
852 0 : lnscht = lnscht + cpu2 - cpu1
853 0 : first = .FALSE.
854 0 : CYCLE
855 : END IF
856 3135 : ELSE IF (task(1:5) == 'FG_LN') THEN
857 : ! return to the driver for calculating f and g; reenter at 666.
858 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
859 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
860 1651 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
861 1651 : RETURN
862 : ELSE
863 : ! calculate and print out the quantities related to the new X.
864 1484 : CALL timer(cpu2)
865 1484 : lnscht = lnscht + cpu2 - cpu1
866 1484 : iter = iter + 1
867 :
868 : ! Compute the infinity norm of the projected (-)gradient.
869 :
870 1484 : CALL projgr(n, lower_bound, upper_bound, nbd, x, g, g_inf_norm)
871 :
872 : ! Print iteration information.
873 :
874 : CALL prn2lb(n, x, f, g, iprint, itfile, iter, nfgv, nact, &
875 1484 : g_inf_norm, nseg, word, iword, iback, stp, xstep, wunit)
876 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
877 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
878 1484 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
879 2925 : RETURN
880 : END IF
881 : END IF
882 :
883 : ! Test for termination.
884 :
885 1441 : IF (g_inf_norm <= pgtol) THEN
886 : ! terminate the algorithm.
887 0 : task = 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
888 0 : CALL timer(time2)
889 0 : time = time2 - time1
890 : CALL prn3lb(n, x, f, task, iprint, info, itfile, &
891 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
892 : time, nseg, word, iback, stp, xstep, k, &
893 0 : cachyt, sbtime, lnscht, wunit)
894 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
895 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
896 0 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
897 0 : RETURN
898 : END IF
899 :
900 1441 : ddum = MAX(ABS(fold), ABS(f), one)
901 1441 : IF ((fold - f) <= tol*ddum) THEN
902 : ! terminate the algorithm.
903 1 : task = 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'
904 1 : IF (iback >= 10) info = -5
905 : ! i.e., to issue a warning if iback>10 in the line search.
906 1 : CALL timer(time2)
907 1 : time = time2 - time1
908 : CALL prn3lb(n, x, f, task, iprint, info, itfile, &
909 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
910 : time, nseg, word, iback, stp, xstep, k, &
911 1 : cachyt, sbtime, lnscht, wunit)
912 : CALL save_local(lsave, isave, dsave, x_projected, constrained, boxed, updatd, nintol, itfile, iback, nskip, head, col, itail, &
913 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, &
914 1 : cpu1, cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
915 1 : RETURN
916 : END IF
917 :
918 : ! Compute d=newx-oldx, r=newg-oldg, rr=y'y and dr=y's.
919 1440 : IF (keep_space_group) THEN
920 0 : CALL spgr_apply_rotations_force(spgr, g)
921 0 : CALL spgr_apply_rotations_force(spgr, r)
922 : END IF
923 837525 : DO i = 1, n
924 837525 : r(i) = g(i) - r(i)
925 : END DO
926 1440 : rr = ddot(n, r, 1, r, 1)
927 1440 : IF (stp == one) THEN
928 1306 : dr = gd - gdold
929 1306 : ddum = -gdold
930 : ELSE
931 134 : dr = (gd - gdold)*stp
932 134 : CALL dscal(n, stp, d, 1)
933 134 : ddum = -gdold*stp
934 : END IF
935 :
936 1440 : IF (dr <= epsmch*ddum) THEN
937 : ! skip the L-BFGS update.
938 4 : nskip = nskip + 1
939 4 : updatd = .FALSE.
940 4 : IF (iprint >= 1) WRITE (wunit, 1004) dr, ddum
941 : first = .FALSE.
942 : CYCLE
943 : END IF
944 :
945 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
946 : !
947 : ! Update the L-BFGS matrix.
948 : !
949 : !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
950 :
951 1436 : updatd = .TRUE.
952 1436 : iupdat = iupdat + 1
953 :
954 : ! Update matrices WS and WY and form the middle matrix in B.
955 :
956 : CALL matupd(n, m, ws, wy, sy, ss, d, r, itail, &
957 1436 : iupdat, col, head, theta, rr, dr, stp, dtd)
958 :
959 : ! Form the upper half of the pds T = theta*SS + L*D^(-1)*L';
960 : ! Store T in the upper triangular of the array wt;
961 : ! Cholesky factorize T to J*J' with
962 : ! J' stored in the upper triangular of wt.
963 :
964 1436 : CALL formt(m, wt, sy, ss, col, theta, info)
965 :
966 1436 : IF (info /= 0) THEN
967 : ! nonpositive definiteness in Cholesky factorization;
968 : ! refresh the lbfgs memory and restart the iteration.
969 0 : IF (iprint >= 1) WRITE (wunit, 1007)
970 0 : info = 0
971 0 : col = 0
972 0 : head = 1
973 0 : theta = one
974 0 : iupdat = 0
975 0 : updatd = .FALSE.
976 : END IF
977 :
978 : ! Now the inverse of the middle matrix in B is
979 :
980 : ! [ D^(1/2) O ] [ -D^(1/2) D^(-1/2)*L' ]
981 : ! [ -L*D^(-1/2) J ] [ 0 J' ]
982 :
983 : first = .FALSE.
984 : END DO
985 :
986 : 1001 FORMAT(//, ' L-BFGS| ITERATION ', i5)
987 : 1002 FORMAT &
988 : (/, ' L-BFGS| At iterate', i5, 4x, 'f= ', 1p, d12.5, 4x, '|proj g|= ', 1p, d12.5)
989 : 1003 FORMAT(2(1x, i4), 5x, '-', 5x, '-', 3x, '-', 5x, '-', 5x, '-', 8x, '-', 3x, &
990 : 1p, 2(1x, d10.3))
991 : 1004 FORMAT(' L-BFGS| ys=', 1p, e10.3, ' -gs=', 1p, e10.3, ' BFGS update SKIPPED')
992 : 1005 FORMAT(/, &
993 : ' L-BFGS| Singular triangular system detected;', /, &
994 : ' L-BFGS| refresh the lbfgs memory and restart the iteration.')
995 : 1006 FORMAT(/, &
996 : ' L-BFGS| Nonpositive definiteness in Cholesky factorization in formk;', /, &
997 : ' L-BFGS| refresh the lbfgs memory and restart the iteration.')
998 : 1007 FORMAT(/, &
999 : ' L-BFGS| Nonpositive definiteness in Cholesky factorization in formt;', /, &
1000 : ' L-BFGS| refresh the lbfgs memory and restart the iteration.')
1001 : 1008 FORMAT(/, &
1002 : ' L-BFGS| Bad direction in the line search;', /, &
1003 : ' L-BFGS| refresh the lbfgs memory and restart the iteration.')
1004 :
1005 : RETURN
1006 :
1007 : END SUBROUTINE mainlb
1008 :
1009 : ! **************************************************************************************************
1010 : !> \brief This subroutine initializes iwhere and projects the initial x to the feasible set if necessary.
1011 : !> \param n ...
1012 : !> \param lower_bound the lower bound on x.
1013 : !> \param upper_bound the upper bound on x.
1014 : !> \param nbd ...
1015 : !> \param x ...
1016 : !> \param iwhere iwhere(i)=-1 if x(i) has no bounds
1017 : !> 3 if l(i)=u(i)
1018 : !> 0 otherwise.
1019 : !> In cauchy, iwhere is given finer gradations.
1020 : !> \param iprint ...
1021 : !> \param x_projected ...
1022 : !> \param constrained ...
1023 : !> \param boxed ...
1024 : !> \param iwunit User-specified write unit, if not set then WRITE statements
1025 : !> write to default_output_unit by default
1026 : !> \author NEOS, November 1994. (Latest revision June 1996.)
1027 : !> Optimization Technology Center.
1028 : !> Argonne National Laboratory and Northwestern University.
1029 : !> Written by
1030 : !> Ciyou Zhu
1031 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1032 : ! **************************************************************************************************
1033 45 : SUBROUTINE active(n, lower_bound, upper_bound, nbd, x, iwhere, iprint, &
1034 : x_projected, constrained, boxed, iwunit)
1035 :
1036 : INTEGER, INTENT(in) :: n
1037 : REAL(KIND=dp), INTENT(in) :: lower_bound(n), upper_bound(n)
1038 : INTEGER :: nbd(n)
1039 : REAL(KIND=dp) :: x(n)
1040 : INTEGER, INTENT(out) :: iwhere(n)
1041 : INTEGER :: iprint
1042 : LOGICAL :: x_projected, constrained, boxed
1043 : INTEGER, OPTIONAL :: iwunit
1044 :
1045 : REAL(KIND=dp), PARAMETER :: zero = 0.0_dp
1046 :
1047 : INTEGER :: i, nbdd, wunit
1048 :
1049 45 : wunit = default_output_unit
1050 45 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
1051 :
1052 : ! ************
1053 : ! Initialize nbdd, x_projected, constrained and boxed.
1054 :
1055 45 : nbdd = 0
1056 45 : x_projected = .FALSE.
1057 45 : constrained = .FALSE.
1058 45 : boxed = .TRUE.
1059 :
1060 : ! Project the initial x to the easible set if necessary.
1061 :
1062 28632 : DO i = 1, n
1063 28632 : IF (nbd(i) > 0) THEN
1064 9018 : IF (nbd(i) <= 2 .AND. x(i) <= lower_bound(i)) THEN
1065 0 : IF (x(i) < lower_bound(i)) THEN
1066 0 : x_projected = .TRUE.
1067 0 : x(i) = lower_bound(i)
1068 : END IF
1069 0 : nbdd = nbdd + 1
1070 9018 : ELSE IF (nbd(i) >= 2 .AND. x(i) >= upper_bound(i)) THEN
1071 0 : IF (x(i) > upper_bound(i)) THEN
1072 0 : x_projected = .TRUE.
1073 0 : x(i) = upper_bound(i)
1074 : END IF
1075 0 : nbdd = nbdd + 1
1076 : END IF
1077 : END IF
1078 : END DO
1079 :
1080 : ! Initialize iwhere and assign values to constrained and boxed.
1081 :
1082 28632 : DO i = 1, n
1083 28587 : IF (nbd(i) /= 2) boxed = .FALSE.
1084 28632 : IF (nbd(i) == 0) THEN
1085 : ! this variable is always free
1086 19569 : iwhere(i) = -1
1087 :
1088 : ! otherwise set x(i)=mid(x(i), u(i), l(i)).
1089 : ELSE
1090 9018 : constrained = .TRUE.
1091 9018 : IF (nbd(i) == 2 .AND. upper_bound(i) - lower_bound(i) <= zero) THEN
1092 : ! this variable is always fixed
1093 0 : iwhere(i) = 3
1094 : ELSE
1095 9018 : iwhere(i) = 0
1096 : END IF
1097 : END IF
1098 : END DO
1099 :
1100 45 : IF (iprint >= 0) THEN
1101 45 : IF (x_projected) WRITE (wunit, 2001)
1102 45 : IF (.NOT. constrained) WRITE (wunit, 3001)
1103 : END IF
1104 :
1105 45 : IF (iprint > 0) WRITE (wunit, 1001) nbdd
1106 :
1107 : 1001 FORMAT(/, ' L-BFGS| At X0 ', i9, ' variables are exactly at the bounds')
1108 : 2001 FORMAT(' L-BFGS| The initial X is infeasible. Restart with its projection.')
1109 : 3001 FORMAT(' L-BFGS| This problem is unconstrained.')
1110 :
1111 45 : RETURN
1112 :
1113 : END SUBROUTINE active
1114 :
1115 : ! **************************************************************************************************
1116 : !> \brief This subroutine computes the product of the 2m x 2m middle matrix
1117 : !> in the compact L-BFGS formula of B and a 2m vector v;
1118 : !> it returns the product in p.
1119 : !> \param m m is the maximum number of variable metric corrections
1120 : !> used to define the limited memory matrix.
1121 : !> \param sy sy specifies the matrix S'Y.
1122 : !> \param wt wt specifies the upper triangular matrix J' which is
1123 : !> the Cholesky factor of (thetaS'S+LD^(-1)L').
1124 : !> \param col col specifies the number of s-vectors (or y-vectors)
1125 : !> stored in the compact L-BFGS formula.
1126 : !> \param v v specifies vector v.
1127 : !> \param p p is the product Mv.
1128 : !> \param info info = 0 for normal return,
1129 : !> = nonzero for abnormal return when the system to be solved by dtrsl is singular.
1130 : !> \author NEOS, November 1994. (Latest revision June 1996.)
1131 : !> Optimization Technology Center.
1132 : !> Argonne National Laboratory and Northwestern University.
1133 : !> Written by
1134 : !> Ciyou Zhu
1135 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1136 : ! **************************************************************************************************
1137 34 : SUBROUTINE bmv(m, sy, wt, col, v, p, info)
1138 :
1139 : INTEGER :: m
1140 : REAL(KIND=dp) :: sy(m, m), wt(m, m)
1141 : INTEGER :: col
1142 : REAL(KIND=dp), INTENT(in) :: v(2*col)
1143 : REAL(KIND=dp), INTENT(out) :: p(2*col)
1144 : INTEGER, INTENT(out) :: info
1145 :
1146 : INTEGER :: i, i2, k
1147 : REAL(KIND=dp) :: sum
1148 :
1149 34 : IF (col == 0) RETURN
1150 :
1151 : ! PART I: solve [ D^(1/2) O ] [ p1 ] = [ v1 ]
1152 : ! [ -L*D^(-1/2) J ] [ p2 ] [ v2 ].
1153 :
1154 : ! solve Jp2=v2+LD^(-1)v1.
1155 34 : p(col + 1) = v(col + 1)
1156 88 : DO i = 2, col
1157 54 : i2 = col + i
1158 54 : sum = 0.0_dp
1159 160 : DO k = 1, i - 1
1160 160 : sum = sum + sy(i, k)*v(k)/sy(k, k)
1161 : END DO
1162 88 : p(i2) = v(i2) + sum
1163 : END DO
1164 : ! Solve the triangular system
1165 34 : CALL dtrsl(wt, m, col, p(col + 1), 11, info)
1166 34 : IF (info /= 0) RETURN
1167 :
1168 : ! solve D^(1/2)p1=v1.
1169 122 : DO i = 1, col
1170 122 : p(i) = v(i)/SQRT(sy(i, i))
1171 : END DO
1172 :
1173 : ! PART II: solve [ -D^(1/2) D^(-1/2)*L' ] [ p1 ] = [ p1 ]
1174 : ! [ 0 J' ] [ p2 ] [ p2 ].
1175 :
1176 : ! solve J^Tp2=p2.
1177 34 : CALL dtrsl(wt, m, col, p(col + 1), 01, info)
1178 34 : IF (info /= 0) RETURN
1179 :
1180 : ! compute p1=-D^(-1/2)(p1-D^(-1/2)L'p2)
1181 : ! =-D^(-1/2)p1+D^(-1)L'p2.
1182 122 : DO i = 1, col
1183 122 : p(i) = -p(i)/SQRT(sy(i, i))
1184 : END DO
1185 122 : DO i = 1, col
1186 88 : sum = 0._dp
1187 194 : DO k = i + 1, col
1188 194 : sum = sum + sy(k, i)*p(col + k)/sy(i, i)
1189 : END DO
1190 122 : p(i) = p(i) + sum
1191 : END DO
1192 :
1193 : RETURN
1194 :
1195 : END SUBROUTINE bmv
1196 :
1197 : ! **************************************************************************************************
1198 : !> \brief For given x, l, u, g (with g_inf_norm > 0), and a limited memory
1199 : !> BFGS matrix B defined in terms of matrices WY, WS, WT, and
1200 : !> scalars head, col, and theta, this subroutine computes the
1201 : !> generalized Cauchy point (GCP), defined as the first local
1202 : !> minimizer of the quadratic
1203 : !>
1204 : !> Q(x + s) = g's + 1/2 s'Bs
1205 : !>
1206 : !> along the projected gradient direction P(x-tg,l,u).
1207 : !> The routine returns the GCP in xcp.
1208 : !> \param n n is the dimension of the problem.
1209 : !> \param x x is the starting point for the GCP computation.
1210 : !> \param lower_bound the lower bound on x.
1211 : !> \param upper_bound the upper bound on x.
1212 : !> \param nbd nbd represents the type of bounds imposed on the
1213 : !> variables, and must be specified as follows:
1214 : !> nbd(i)=0 if x(i) is unbounded,
1215 : !> 1 if x(i) has only a lower bound,
1216 : !> 2 if x(i) has both lower and upper bounds, and
1217 : !> 3 if x(i) has only an upper bound.
1218 : !> \param g g is the gradient of f(x). g must be a nonzero vector.
1219 : !> \param iorder iorder will be used to store the breakpoints in the piecewise
1220 : !> linear path and free variables encountered. On exit,
1221 : !> iorder(1),...,iorder(nleft) are indices of breakpoints
1222 : !> which have not been encountered;
1223 : !> iorder(nleft+1),...,iorder(nbreak) are indices of
1224 : !> encountered breakpoints; and
1225 : !> iorder(nfree),...,iorder(n) are indices of variables which
1226 : !> have no bound constraits along the search direction.
1227 : !> \param iwhere On entry iwhere indicates only the permanently fixed (iwhere=3)
1228 : !> or free (iwhere= -1) components of x.
1229 : !> On exit iwhere records the status of the current x variables.
1230 : !> iwhere(i)=-3 if x(i) is free and has bounds, but is not moved
1231 : !> 0 if x(i) is free and has bounds, and is moved
1232 : !> 1 if x(i) is fixed at l(i), and l(i) .ne. u(i)
1233 : !> 2 if x(i) is fixed at u(i), and u(i) .ne. l(i)
1234 : !> 3 if x(i) is always fixed, i.e., u(i)=x(i)=l(i)
1235 : !> -1 if x(i) is always free, i.e., it has no bounds.
1236 : !> \param t t will be used to store the break points.
1237 : !> \param d d is used to store the Cauchy direction P(x-tg)-x.
1238 : !> \param xcp is a double precision array of dimension n used to return the GCP on exit.
1239 : !> \param m m is the maximum number of variable metric corrections used to define the limited memory matrix.
1240 : !> \param wy ws, wy, sy, and wt are double precision arrays.
1241 : !> On entry they store information that defines the limited memory BFGS matrix:
1242 : !> wy(n,m) stores Y, a set of y-vectors;
1243 : !> \param ws ws(n,m) stores S, a set of s-vectors;
1244 : !> \param sy sy(m,m) stores S'Y;
1245 : !> \param wt wt(m,m) stores the Cholesky factorization of (theta*S'S+LD^(-1)L').
1246 : !> \param theta theta is the scaling factor specifying B_0 = theta I.
1247 : !> \param col col is the actual number of variable metric corrections stored so far.
1248 : !> \param head head is the location of the first s-vector (or y-vector in S (or Y)
1249 : !> \param p p will be used to store the vector p = W^(T)d.
1250 : !> \param c c will be used to store the vector c = W^(T)(xcp-x).
1251 : !> \param wbp wbp will be used to store the row of W corresponding to a breakpoint.
1252 : !> \param v v is a double precision working array.
1253 : !> \param nseg On exit nseg records the number of quadratic segments explored in searching for the GCP.
1254 : !> \param iprint iprint is an INTEGER variable that must be set by the user.
1255 : !> It controls the frequency and type of output generated:
1256 : !> iprint<0 no output is generated;
1257 : !> iprint=0 print only one line at the last iteration;
1258 : !> 0<iprint<99 print also f and |proj g| every iprint iterations;
1259 : !> iprint=99 print details of every iteration except n-vectors;
1260 : !> iprint=100 print also the changes of active set and final x;
1261 : !> iprint>100 print details of every iteration including x and g;
1262 : !> When iprint > 0, the file iterate.dat will be created to summarize the iteration.
1263 : !> \param g_inf_norm g_inf_norm is the norm of the projected gradient at x.
1264 : !> \param info On entry info is 0.
1265 : !> On exit info = 0 for normal return,
1266 : !> = nonzero for abnormal return when the the system
1267 : !> used in routine bmv is singular.
1268 : !> \param epsmch ...
1269 : !> \param iwunit User-specified write unit, if not set then WRITE statements
1270 : !> write to default_output_unit by default
1271 : !> \author NEOS, November 1994. (Latest revision June 1996.)
1272 : !> Optimization Technology Center.
1273 : !> Argonne National Laboratory and Northwestern University.
1274 : !> Written by
1275 : !> Ciyou Zhu
1276 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1277 : ! **************************************************************************************************
1278 61 : SUBROUTINE cauchy(n, x, lower_bound, upper_bound, nbd, g, iorder, iwhere, t, d, xcp, &
1279 61 : m, wy, ws, sy, wt, theta, col, head, p, c, wbp, &
1280 61 : v, nseg, iprint, g_inf_norm, info, epsmch, iwunit)
1281 : INTEGER, INTENT(in) :: n
1282 : REAL(KIND=dp), INTENT(in) :: x(n), lower_bound(n), upper_bound(n)
1283 : INTEGER, INTENT(in) :: nbd(n)
1284 : REAL(KIND=dp), INTENT(in) :: g(n)
1285 : INTEGER :: iorder(n)
1286 : INTEGER, INTENT(inout) :: iwhere(n)
1287 : REAL(KIND=dp) :: t(n), d(n), xcp(n)
1288 : INTEGER, INTENT(in) :: m
1289 : REAL(KIND=dp), INTENT(in) :: sy(m, m), wt(m, m), theta
1290 : INTEGER, INTENT(in) :: col
1291 : REAL(KIND=dp), INTENT(in) :: ws(n, col), wy(n, col)
1292 : INTEGER, INTENT(in) :: head
1293 : REAL(KIND=dp) :: p(2*m), c(2*m), wbp(2*m), v(2*m)
1294 : INTEGER :: nseg, iprint
1295 : REAL(KIND=dp), INTENT(in) :: g_inf_norm
1296 : INTEGER, INTENT(inout) :: info
1297 : REAL(KIND=dp) :: epsmch
1298 : INTEGER, OPTIONAL :: iwunit
1299 :
1300 : REAL(KIND=dp), PARAMETER :: one = 1.0_dp, zero = 0.0_dp
1301 :
1302 : INTEGER :: col2, i, ibkmin, ibp, iter, j, nbreak, &
1303 : nfree, nleft, pointr, wunit
1304 : LOGICAL :: bnded, xlower, xupper
1305 : REAL(KIND=dp) :: bkmin, ddot, dibp, dibp2, dt, dtm, f1, &
1306 : f2, f2_org, neggi, tj, tj0, tl, tsum, &
1307 : tu, wmc, wmp, wmw, zibp
1308 :
1309 61 : wunit = default_output_unit
1310 61 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
1311 :
1312 : ! References:
1313 : !
1314 : ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
1315 : ! memory algorithm for bound constrained optimization'',
1316 : ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
1317 : !
1318 : ! [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
1319 : ! Subroutines for Large Scale Bound Constrained Optimization''
1320 : ! Tech. Report, NAM-11, EECS Department, Northwestern University,
1321 : ! 1994.
1322 : !
1323 : ! (Postscript files of these papers are available via anonymous
1324 : ! ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
1325 : !
1326 : ! * * *
1327 : ! Check the status of the variables, reset iwhere(i) if necessary;
1328 : ! compute the Cauchy direction d and the breakpoints t; initialize
1329 : ! the derivative f1 and the vector p = W'd (for theta = 1).
1330 :
1331 61 : IF (g_inf_norm <= zero) THEN
1332 0 : IF (iprint >= 0) WRITE (wunit, 7010)
1333 0 : CALL dcopy(n, x, 1, xcp, 1)
1334 0 : RETURN
1335 : END IF
1336 61 : bnded = .TRUE.
1337 61 : nfree = n + 1
1338 61 : nbreak = 0
1339 61 : ibkmin = 0
1340 61 : bkmin = zero
1341 61 : col2 = 2*col
1342 61 : f1 = zero
1343 61 : IF (iprint >= 99) WRITE (wunit, 3010)
1344 :
1345 : ! We set p to zero and build it up as we determine d.
1346 :
1347 137 : DO i = 1, col2
1348 137 : p(i) = zero
1349 : END DO
1350 :
1351 : ! In the following loop we determine for each variable its bound
1352 : ! status and its breakpoint, and update p accordingly.
1353 : ! Smallest breakpoint is identified.
1354 :
1355 55738 : DO i = 1, n
1356 55677 : neggi = -g(i)
1357 55677 : IF (iwhere(i) /= 3 .AND. iwhere(i) /= -1) THEN
1358 : ! if x(i) is not a constant and has bounds,
1359 : ! compute the difference between x(i) and its bounds.
1360 36120 : IF (nbd(i) <= 2) tl = x(i) - lower_bound(i)
1361 36120 : IF (nbd(i) >= 2) tu = upper_bound(i) - x(i)
1362 :
1363 : ! If a variable is close enough to a bound
1364 : ! we treat it as at bound.
1365 36120 : xlower = nbd(i) <= 2 .AND. tl <= zero
1366 36120 : xupper = nbd(i) >= 2 .AND. tu <= zero
1367 :
1368 : ! reset iwhere(i).
1369 36120 : iwhere(i) = 0
1370 36120 : IF (xlower) THEN
1371 0 : IF (neggi <= zero) iwhere(i) = 1
1372 36120 : ELSE IF (xupper) THEN
1373 0 : IF (neggi >= zero) iwhere(i) = 2
1374 : ELSE
1375 36120 : IF (ABS(neggi) <= zero) iwhere(i) = -3
1376 : END IF
1377 : END IF
1378 55677 : pointr = head
1379 55738 : IF (iwhere(i) /= 0 .AND. iwhere(i) /= -1) THEN
1380 15 : d(i) = zero
1381 : ELSE
1382 55662 : d(i) = neggi
1383 55662 : f1 = f1 - neggi*neggi
1384 : ! calculate p := p - W'e_i* (g_i).
1385 114360 : DO j = 1, col
1386 58698 : p(j) = p(j) + wy(i, pointr)*neggi
1387 58698 : p(col + j) = p(col + j) + ws(i, pointr)*neggi
1388 114360 : pointr = MOD(pointr, m) + 1
1389 : END DO
1390 : IF (nbd(i) <= 2 .AND. nbd(i) /= 0 &
1391 55662 : & .AND. neggi < zero) THEN
1392 : ! x(i) + d(i) is bounded; compute t(i).
1393 18110 : nbreak = nbreak + 1
1394 18110 : iorder(nbreak) = i
1395 18110 : t(nbreak) = tl/(-neggi)
1396 18110 : IF (nbreak == 1 .OR. t(nbreak) < bkmin) THEN
1397 64 : bkmin = t(nbreak)
1398 64 : ibkmin = nbreak
1399 : END IF
1400 37552 : ELSE IF (nbd(i) >= 2 .AND. neggi > zero) THEN
1401 : ! x(i) + d(i) is bounded; compute t(i).
1402 17995 : nbreak = nbreak + 1
1403 17995 : iorder(nbreak) = i
1404 17995 : t(nbreak) = tu/neggi
1405 17995 : IF (nbreak == 1 .OR. t(nbreak) < bkmin) THEN
1406 49 : bkmin = t(nbreak)
1407 49 : ibkmin = nbreak
1408 : END IF
1409 : ELSE
1410 : ! x(i) + d(i) is not bounded.
1411 19557 : nfree = nfree - 1
1412 19557 : iorder(nfree) = i
1413 19557 : IF (ABS(neggi) > zero) bnded = .FALSE.
1414 : END IF
1415 : END IF
1416 : END DO
1417 :
1418 : ! The indices of the nonzero components of d are now stored
1419 : ! in iorder(1),...,iorder(nbreak) and iorder(nfree),...,iorder(n).
1420 : ! The smallest of the nbreak breakpoints is in t(ibkmin)=bkmin.
1421 :
1422 61 : IF (theta /= one) THEN
1423 : ! complete the initialization of p for theta not= one.
1424 13 : CALL dscal(col, theta, p(col + 1), 1)
1425 : END IF
1426 :
1427 : ! Initialize GCP xcp = x.
1428 :
1429 61 : CALL dcopy(n, x, 1, xcp, 1)
1430 :
1431 61 : IF (nbreak == 0 .AND. nfree == n + 1) THEN
1432 : ! is a zero vector, return with the initial xcp as GCP.
1433 0 : IF (iprint > 100) WRITE (wunit, 1010) (xcp(i), i=1, n)
1434 0 : RETURN
1435 : END IF
1436 :
1437 : ! Initialize c = W'(xcp - x) = 0.
1438 :
1439 137 : DO j = 1, col2
1440 137 : c(j) = zero
1441 : END DO
1442 :
1443 : ! Initialize derivative f2.
1444 :
1445 61 : f2 = -theta*f1
1446 61 : f2_org = f2
1447 61 : IF (col > 0) THEN
1448 13 : CALL bmv(m, sy, wt, col, p, v, info)
1449 13 : IF (info /= 0) RETURN
1450 13 : f2 = f2 - ddot(col2, v, 1, p, 1)
1451 : END IF
1452 61 : dtm = -f1/f2
1453 61 : tsum = zero
1454 61 : nseg = 1
1455 61 : IF (iprint >= 99) &
1456 0 : WRITE (wunit, 1011) nbreak
1457 :
1458 61 : nleft = nbreak
1459 61 : iter = 1
1460 :
1461 61 : tj = zero
1462 :
1463 : ! If there are no breakpoints, locate the GCP and return.
1464 :
1465 61 : IF (nleft == 0) THEN
1466 41 : IF (iprint >= 99) THEN
1467 0 : WRITE (wunit, 4012)
1468 0 : WRITE (wunit, 4010) nseg, f1, f2
1469 0 : WRITE (wunit, 6010) dtm
1470 : END IF
1471 41 : IF (dtm <= zero) dtm = zero
1472 41 : tsum = tsum + dtm
1473 :
1474 : ! Move free variables (i.e., the ones w/o breakpoints) and
1475 : ! the variables whose breakpoints haven't been reached.
1476 :
1477 41 : CALL daxpy(n, tsum, d, 1, xcp, 1)
1478 : END IF
1479 :
1480 71 : DO WHILE (nleft > 0)
1481 :
1482 : ! Find the next smallest breakpoint;
1483 : ! compute dt = t(nleft) - t(nleft + 1).
1484 :
1485 30 : tj0 = tj
1486 30 : IF (iter == 1) THEN
1487 : ! Since we already have the smallest breakpoint we need not do
1488 : ! heapsort yet. Often only one breakpoint is used and the
1489 : ! cost of heapsort is avoided.
1490 20 : tj = bkmin
1491 20 : ibp = iorder(ibkmin)
1492 : ELSE
1493 10 : IF (iter == 2) THEN
1494 : ! Replace the already used smallest breakpoint with the
1495 : ! breakpoint numbered nbreak > nlast, before heapsort call.
1496 5 : IF (ibkmin /= nbreak) THEN
1497 4 : t(ibkmin) = t(nbreak)
1498 4 : iorder(ibkmin) = iorder(nbreak)
1499 : END IF
1500 : ! Update heap structure of breakpoints
1501 : ! (if iter=2, initialize heap).
1502 : END IF
1503 10 : CALL hpsolb(nleft, t, iorder, iter - 2)
1504 10 : tj = t(nleft)
1505 10 : ibp = iorder(nleft)
1506 : END IF
1507 :
1508 30 : dt = tj - tj0
1509 :
1510 30 : IF (dt /= zero .AND. iprint >= 100) THEN
1511 0 : WRITE (wunit, 4011) nseg, f1, f2
1512 0 : WRITE (wunit, 5010) dt
1513 0 : WRITE (wunit, 6010) dtm
1514 : END IF
1515 :
1516 : ! If a minimizer is within this interval, locate the GCP and return.
1517 :
1518 30 : IF (dtm < dt) THEN
1519 20 : IF (iprint >= 99) THEN
1520 0 : WRITE (wunit, 4012)
1521 0 : WRITE (wunit, 4010) nseg, f1, f2
1522 0 : WRITE (wunit, 6010) dtm
1523 : END IF
1524 20 : IF (dtm <= zero) dtm = zero
1525 20 : tsum = tsum + dtm
1526 :
1527 : ! Move free variables (i.e., the ones w/o breakpoints) and
1528 : ! the variables whose breakpoints haven't been reached.
1529 :
1530 20 : CALL daxpy(n, tsum, d, 1, xcp, 1)
1531 20 : EXIT
1532 : END IF
1533 :
1534 : ! Otherwise fix one variable and
1535 : ! reset the corresponding component of d to zero.
1536 :
1537 10 : tsum = tsum + dt
1538 10 : nleft = nleft - 1
1539 10 : iter = iter + 1
1540 10 : dibp = d(ibp)
1541 10 : d(ibp) = zero
1542 10 : IF (dibp > zero) THEN
1543 2 : zibp = upper_bound(ibp) - x(ibp)
1544 2 : xcp(ibp) = upper_bound(ibp)
1545 2 : iwhere(ibp) = 2
1546 : ELSE
1547 8 : zibp = lower_bound(ibp) - x(ibp)
1548 8 : xcp(ibp) = lower_bound(ibp)
1549 8 : iwhere(ibp) = 1
1550 : END IF
1551 10 : IF (iprint >= 100) WRITE (wunit, 8010) ibp
1552 10 : IF (nleft == 0 .AND. nbreak == n) THEN
1553 : ! all n variables are fixed,
1554 : ! return with xcp as GCP.
1555 0 : dtm = dt
1556 0 : EXIT
1557 : END IF
1558 :
1559 : ! Update the derivative information.
1560 :
1561 10 : nseg = nseg + 1
1562 10 : dibp2 = dibp**2
1563 :
1564 : ! Update f1 and f2.
1565 :
1566 : ! temporarily set f1 and f2 for col=0.
1567 10 : f1 = f1 + dt*f2 + dibp2 - theta*dibp*zibp
1568 10 : f2 = f2 - theta*dibp2
1569 :
1570 10 : IF (col > 0) THEN
1571 : ! update c = c + dt*p.
1572 8 : CALL daxpy(col2, dt, p, 1, c, 1)
1573 :
1574 : ! choose wbp,
1575 : ! the row of W corresponding to the breakpoint encountered.
1576 8 : pointr = head
1577 20 : DO j = 1, col
1578 12 : wbp(j) = wy(ibp, pointr)
1579 12 : wbp(col + j) = theta*ws(ibp, pointr)
1580 20 : pointr = MOD(pointr, m) + 1
1581 : END DO
1582 :
1583 : ! compute (wbp)Mc, (wbp)Mp, and (wbp)M(wbp)'.
1584 8 : CALL bmv(m, sy, wt, col, wbp, v, info)
1585 8 : IF (info /= 0) RETURN
1586 8 : wmc = ddot(col2, c, 1, v, 1)
1587 8 : wmp = ddot(col2, p, 1, v, 1)
1588 8 : wmw = ddot(col2, wbp, 1, v, 1)
1589 :
1590 : ! update p = p - dibp*wbp.
1591 8 : CALL daxpy(col2, -dibp, wbp, 1, p, 1)
1592 :
1593 : ! complete updating f1 and f2 while col > 0.
1594 8 : f1 = f1 + dibp*wmc
1595 8 : f2 = f2 + 2.0_dp*dibp*wmp - dibp2*wmw
1596 : END IF
1597 :
1598 10 : f2 = MAX(epsmch*f2_org, f2)
1599 51 : IF (nleft > 0) THEN
1600 10 : dtm = -f1/f2
1601 : CYCLE
1602 : ! to repeat the loop for unsearched intervals.
1603 : ELSE
1604 0 : IF (bnded) THEN
1605 0 : f1 = zero
1606 0 : f2 = zero
1607 0 : dtm = zero
1608 : ELSE
1609 0 : dtm = -f1/f2
1610 : END IF
1611 0 : IF (iprint >= 99) THEN
1612 0 : WRITE (wunit, 4012)
1613 0 : WRITE (wunit, 4010) nseg, f1, f2
1614 0 : WRITE (wunit, 6010) dtm
1615 : END IF
1616 0 : IF (dtm <= zero) dtm = zero
1617 0 : tsum = tsum + dtm
1618 :
1619 : ! Move free variables (i.e., the ones w/o breakpoints) and
1620 : ! the variables whose breakpoints haven't been reached.
1621 :
1622 0 : CALL daxpy(n, tsum, d, 1, xcp, 1)
1623 0 : EXIT
1624 : END IF
1625 : END DO
1626 :
1627 : ! Update c = c + dtm*p = W'(x^c - x)
1628 : ! which will be used in computing r = Z'(B(x^c - x) + g).
1629 :
1630 61 : IF (col > 0) CALL daxpy(col2, dtm, p, 1, c, 1)
1631 61 : IF (iprint > 100) WRITE (wunit, 1010) (xcp(i), i=1, n)
1632 61 : IF (iprint >= 99) WRITE (wunit, 2010)
1633 :
1634 : 1010 FORMAT(' L-BFGS| Cauchy X = ', /, (4x, 1p, 6(1x, d11.4)))
1635 : 1011 FORMAT(/, ' L-BFGS| There are ', i12, ' breakpoints ')
1636 : 2010 FORMAT(/, ' L-BFGS| ---------------- exit CAUCHY-----------------')
1637 : 3010 FORMAT(/, ' L-BFGS| ---------------- enter CAUCHY ---------------')
1638 : 4010 FORMAT(' L-BFGS| Piece ', i3, ' --f1, f2 at start point ', 1p, 2(1x, d11.4))
1639 : 4011 FORMAT(/, ' L-BFGS| Piece ', i3, ' --f1, f2 at start point ', &
1640 : 1p, 2(1x, d11.4))
1641 : 4012 FORMAT(/, ' L-BFGS| GCP found in this segment')
1642 : 5010 FORMAT(' L-BFGS| Distance to the next break point = ', 1p, d11.4)
1643 : 6010 FORMAT(' L-BFGS| Distance to the stationary point = ', 1p, d11.4)
1644 : 7010 FORMAT(' L-BFGS| Subgnorm = 0. GCP = X.')
1645 : 8010 FORMAT(' L-BFGS| Variable ', i12, ' is fixed.')
1646 :
1647 : RETURN
1648 :
1649 : END SUBROUTINE cauchy
1650 :
1651 : ! **************************************************************************************************
1652 : !> \brief This subroutine computes r=-Z'B(xcp-xk)-Z'g by using
1653 : !> wa(2m+1)=W'(xcp-x) from subroutine cauchy.
1654 : !> \param n ...
1655 : !> \param m ...
1656 : !> \param x ...
1657 : !> \param g ...
1658 : !> \param ws ...
1659 : !> \param wy ...
1660 : !> \param sy ...
1661 : !> \param wt ...
1662 : !> \param z ...
1663 : !> \param r ...
1664 : !> \param wa ...
1665 : !> \param index ...
1666 : !> \param theta ...
1667 : !> \param col ...
1668 : !> \param head ...
1669 : !> \param nfree ...
1670 : !> \param constrained ...
1671 : !> \param info ...
1672 : !> \author NEOS, November 1994. (Latest revision June 1996.)
1673 : !> Optimization Technology Center.
1674 : !> Argonne National Laboratory and Northwestern University.
1675 : !> Written by
1676 : !> Ciyou Zhu
1677 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1678 : ! **************************************************************************************************
1679 1436 : SUBROUTINE cmprlb(n, m, x, g, ws, wy, sy, wt, z, r, wa, index, &
1680 : theta, col, head, nfree, constrained, info)
1681 :
1682 : INTEGER, INTENT(in) :: n, m
1683 : REAL(KIND=dp), INTENT(in) :: x(n), g(n), ws(n, m), wy(n, m), &
1684 : sy(m, m), wt(m, m), z(n)
1685 : REAL(KIND=dp), INTENT(out) :: r(n), wa(4*m)
1686 : INTEGER, INTENT(in) :: INDEX(n)
1687 : REAL(KIND=dp), INTENT(in) :: theta
1688 : INTEGER, INTENT(in) :: col, head, nfree
1689 : LOGICAL, INTENT(in) :: constrained
1690 : INTEGER :: info
1691 :
1692 : INTEGER :: i, j, k, pointr
1693 : REAL(KIND=dp) :: a1, a2
1694 :
1695 1436 : IF (.NOT. constrained .AND. col > 0) THEN
1696 810406 : DO i = 1, n
1697 810406 : r(i) = -g(i)
1698 : END DO
1699 : ELSE
1700 27083 : DO i = 1, nfree
1701 27070 : k = INDEX(i)
1702 27083 : r(i) = -theta*(z(k) - x(k)) - g(k)
1703 : END DO
1704 13 : CALL bmv(m, sy, wt, col, wa(2*m + 1), wa(1), info)
1705 13 : IF (info /= 0) THEN
1706 0 : info = -8
1707 0 : RETURN
1708 : END IF
1709 13 : pointr = head
1710 51 : DO j = 1, col
1711 38 : a1 = wa(j)
1712 38 : a2 = theta*wa(col + j)
1713 58754 : DO i = 1, nfree
1714 58716 : k = INDEX(i)
1715 58754 : r(i) = r(i) + wy(k, pointr)*a1 + ws(k, pointr)*a2
1716 : END DO
1717 51 : pointr = MOD(pointr, m) + 1
1718 : END DO
1719 : END IF
1720 :
1721 : RETURN
1722 :
1723 : END SUBROUTINE cmprlb
1724 :
1725 : ! **************************************************************************************************
1726 : !> \brief This subroutine checks the validity of the input data.
1727 : !> \param n ...
1728 : !> \param m ...
1729 : !> \param factr ...
1730 : !> \param lower_bound the lower bound on x.
1731 : !> \param upper_bound the upper bound on x.
1732 : !> \param nbd ...
1733 : !> \param task ...
1734 : !> \param info ...
1735 : !> \param k ...
1736 : !> \author NEOS, November 1994. (Latest revision June 1996.)
1737 : !> Optimization Technology Center.
1738 : !> Argonne National Laboratory and Northwestern University.
1739 : !> Written by
1740 : !> Ciyou Zhu
1741 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1742 : ! **************************************************************************************************
1743 45 : SUBROUTINE errclb(n, m, factr, lower_bound, upper_bound, nbd, task, info, k)
1744 :
1745 : INTEGER, INTENT(in) :: n, m
1746 : REAL(KIND=dp), INTENT(in) :: factr, lower_bound(n), upper_bound(n)
1747 : INTEGER :: nbd(n)
1748 : CHARACTER(LEN=60) :: task
1749 : INTEGER :: info, k
1750 :
1751 : REAL(KIND=dp), PARAMETER :: zero = 0.0_dp
1752 :
1753 : INTEGER :: i
1754 :
1755 : ! Check the input arguments for errors.
1756 :
1757 45 : IF (n <= 0) task = 'ERROR: N <= 0'
1758 45 : IF (m <= 0) task = 'ERROR: M <= 0'
1759 45 : IF (factr < zero) task = 'ERROR: FACTR < 0'
1760 :
1761 : ! Check the validity of the arrays nbd(i), u(i), and l(i).
1762 :
1763 28632 : DO i = 1, n
1764 28587 : IF (nbd(i) < 0 .OR. nbd(i) > 3) THEN
1765 : ! return
1766 0 : task = 'ERROR: INVALID NBD'
1767 0 : info = -6
1768 0 : k = i
1769 : END IF
1770 28632 : IF (nbd(i) == 2) THEN
1771 9018 : IF (lower_bound(i) > upper_bound(i)) THEN
1772 : ! return
1773 0 : task = 'ERROR: NO FEASIBLE SOLUTION'
1774 0 : info = -7
1775 0 : k = i
1776 : END IF
1777 : END IF
1778 : END DO
1779 :
1780 45 : RETURN
1781 :
1782 : END SUBROUTINE errclb
1783 :
1784 : ! **************************************************************************************************
1785 : !> \brief This subroutine forms the LEL^T factorization of the indefinite
1786 : !> matrix K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
1787 : !> [L_a -R_z theta*S'AA'S ]
1788 : !> where E = [-I 0]
1789 : !> [ 0 I]
1790 : !> The matrix K can be shown to be equal to the matrix M^[-1]N
1791 : !> occurring in section 5.1 of [1], as well as to the matrix
1792 : !> Mbar^[-1] Nbar in section 5.3.
1793 : !> \param n n is the dimension of the problem.
1794 : !> \param nsub nsub is the number of subspace variables in free set.
1795 : !> \param ind ind specifies the indices of subspace variables.
1796 : !> \param nenter nenter is the number of variables entering the free set.
1797 : !> \param ileave indx2(ileave),...,indx2(n) are the variables leaving the free set.
1798 : !> \param indx2 indx2(1),...,indx2(nenter) are the variables entering the free set,
1799 : !> while indx2(ileave),...,indx2(n) are the variables leaving the free set.
1800 : !> \param iupdat iupdat is the total number of BFGS updates made so far.
1801 : !> \param updatd 'updatd' is true if the L-BFGS matrix is updatd.
1802 : !> \param wn the upper triangle of wn stores the LEL^T factorization
1803 : !> of the 2*col x 2*col indefinite matrix
1804 : !> [-D -Y'ZZ'Y/theta L_a'-R_z' ]
1805 : !> [L_a -R_z theta*S'AA'S ]
1806 : !> \param wn1 On entry wn1 stores the lower triangular part of
1807 : !> [Y' ZZ'Y L_a'+R_z']
1808 : !> [L_a+R_z S'AA'S ]
1809 : !> in the previous iteration.
1810 : !> On exit wn1 stores the corresponding updated matrices.
1811 : !> The purpose of wn1 is just to store these inner products
1812 : !> so they can be easily updated and inserted into wn.
1813 : !> \param m m is the maximum number of variable metric corrections
1814 : !> used to define the limited memory matrix.
1815 : !> \param ws ws(n,m) stores S, a set of s-vectors;
1816 : !> \param wy wy(n,m) stores Y, a set of y-vectors;
1817 : !> \param sy sy(m,m) stores S'Y;
1818 : !> \param theta is the scaling factor specifying B_0 = theta I;
1819 : !> \param col is the number of variable metric corrections stored;
1820 : !> \param head is the location of the 1st s- (or y-) vector in S (or Y).
1821 : !> \param info info = 0 for normal return;
1822 : !> = -1 when the 1st Cholesky factorization failed;
1823 : !> = -2 when the 2st Cholesky factorization failed.
1824 : !> \author NEOS, November 1994. (Latest revision June 1996.)
1825 : !> Optimization Technology Center.
1826 : !> Argonne National Laboratory and Northwestern University.
1827 : !> Written by
1828 : !> Ciyou Zhu
1829 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1830 : ! **************************************************************************************************
1831 1436 : SUBROUTINE formk(n, nsub, ind, nenter, ileave, indx2, iupdat, &
1832 1436 : updatd, wn, wn1, m, ws, wy, sy, theta, col, &
1833 : head, info)
1834 :
1835 : INTEGER, INTENT(in) :: n, nsub, ind(n), nenter, ileave, &
1836 : indx2(n), iupdat
1837 : LOGICAL :: updatd
1838 : INTEGER, INTENT(in) :: m
1839 : REAL(KIND=dp) :: wn1(2*m, 2*m)
1840 : REAL(KIND=dp), INTENT(out) :: wn(2*m, 2*m)
1841 : REAL(KIND=dp), INTENT(in) :: ws(n, m), wy(n, m), sy(m, m), theta
1842 : INTEGER, INTENT(in) :: col, head
1843 : INTEGER, INTENT(out) :: info
1844 :
1845 : REAL(KIND=dp), PARAMETER :: zero = 0.0_dp
1846 :
1847 : INTEGER :: col2, dbegin, dend, i, ipntr, is, is1, &
1848 : iy, jpntr, js, js1, jy, k, k1, m2, &
1849 : pbegin, pend, upcl
1850 : REAL(KIND=dp) :: ddot, temp1, temp2, temp3, temp4
1851 :
1852 : ! References:
1853 : ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
1854 : ! memory algorithm for bound constrained optimization'',
1855 : ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
1856 : !
1857 : ! [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: a
1858 : ! limited memory FORTRAN code for solving bound constrained
1859 : ! optimization problems'', Tech. Report, NAM-11, EECS Department,
1860 : ! Northwestern University, 1994.
1861 : !
1862 : ! (Postscript files of these papers are available via anonymous
1863 : ! ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
1864 : !
1865 : ! * * *
1866 : ! Form the lower triangular part of
1867 : ! WN1 = [Y' ZZ'Y L_a'+R_z']
1868 : ! [L_a+R_z S'AA'S ]
1869 : ! where L_a is the strictly lower triangular part of S'AA'Y
1870 : ! R_z is the upper triangular part of S'ZZ'Y.
1871 :
1872 1436 : IF (updatd) THEN
1873 1436 : IF (iupdat > m) THEN
1874 : ! shift old part of WN1.
1875 6245 : DO jy = 1, m - 1
1876 4996 : js = m + jy
1877 4996 : CALL dcopy(m - jy, wn1(jy + 1, jy + 1), 1, wn1(jy, jy), 1)
1878 4996 : CALL dcopy(m - jy, wn1(js + 1, js + 1), 1, wn1(js, js), 1)
1879 6245 : CALL dcopy(m - 1, wn1(m + 2, jy + 1), 1, wn1(m + 1, jy), 1)
1880 : END DO
1881 : END IF
1882 :
1883 : ! put new rows in blocks (1,1), (2,1) and (2,2).
1884 1436 : pbegin = 1
1885 1436 : pend = nsub
1886 1436 : dbegin = nsub + 1
1887 1436 : dend = n
1888 1436 : iy = col
1889 1436 : is = m + col
1890 1436 : ipntr = head + col - 1
1891 1436 : IF (ipntr > m) ipntr = ipntr - m
1892 1436 : jpntr = head
1893 8656 : DO jy = 1, col
1894 7220 : js = m + jy
1895 7220 : temp1 = zero
1896 7220 : temp2 = zero
1897 7220 : temp3 = zero
1898 : ! compute element jy of row 'col' of Y'ZZ'Y
1899 3981683 : DO k = pbegin, pend
1900 3974463 : k1 = ind(k)
1901 3981683 : temp1 = temp1 + wy(k1, ipntr)*wy(k1, jpntr)
1902 : END DO
1903 : ! compute elements jy of row 'col' of L_a and S'AA'S
1904 7232 : DO k = dbegin, dend
1905 12 : k1 = ind(k)
1906 12 : temp2 = temp2 + ws(k1, ipntr)*ws(k1, jpntr)
1907 7232 : temp3 = temp3 + ws(k1, ipntr)*wy(k1, jpntr)
1908 : END DO
1909 7220 : wn1(iy, jy) = temp1
1910 7220 : wn1(is, js) = temp2
1911 7220 : wn1(is, jy) = temp3
1912 8656 : jpntr = MOD(jpntr, m) + 1
1913 : END DO
1914 :
1915 : ! put new column in block (2,1).
1916 1436 : jy = col
1917 1436 : jpntr = head + col - 1
1918 1436 : IF (jpntr > m) jpntr = jpntr - m
1919 : ipntr = head
1920 8656 : DO i = 1, col
1921 7220 : is = m + i
1922 7220 : temp3 = zero
1923 : ! compute element i of column 'col' of R_z
1924 3981683 : DO k = pbegin, pend
1925 3974463 : k1 = ind(k)
1926 3981683 : temp3 = temp3 + ws(k1, ipntr)*wy(k1, jpntr)
1927 : END DO
1928 7220 : ipntr = MOD(ipntr, m) + 1
1929 8656 : wn1(is, jy) = temp3
1930 : END DO
1931 1436 : upcl = col - 1
1932 : ELSE
1933 0 : upcl = col
1934 : END IF
1935 :
1936 : ! modify the old parts in blocks (1,1) and (2,2) due to changes
1937 : ! in the set of free variables.
1938 1436 : ipntr = head
1939 7220 : DO iy = 1, upcl
1940 5784 : is = m + iy
1941 5784 : jpntr = head
1942 22807 : DO jy = 1, iy
1943 17023 : js = m + jy
1944 17023 : temp1 = zero
1945 17023 : temp2 = zero
1946 17023 : temp3 = zero
1947 17023 : temp4 = zero
1948 17035 : DO k = 1, nenter
1949 12 : k1 = indx2(k)
1950 12 : temp1 = temp1 + wy(k1, ipntr)*wy(k1, jpntr)
1951 17035 : temp2 = temp2 + ws(k1, ipntr)*ws(k1, jpntr)
1952 : END DO
1953 17023 : DO k = ileave, n
1954 0 : k1 = indx2(k)
1955 0 : temp3 = temp3 + wy(k1, ipntr)*wy(k1, jpntr)
1956 17023 : temp4 = temp4 + ws(k1, ipntr)*ws(k1, jpntr)
1957 : END DO
1958 17023 : wn1(iy, jy) = wn1(iy, jy) + temp1 - temp3
1959 17023 : wn1(is, js) = wn1(is, js) - temp2 + temp4
1960 22807 : jpntr = MOD(jpntr, m) + 1
1961 : END DO
1962 7220 : ipntr = MOD(ipntr, m) + 1
1963 : END DO
1964 :
1965 : ! modify the old parts in block (2,1).
1966 1436 : ipntr = head
1967 7220 : DO is = m + 1, m + upcl
1968 : jpntr = head
1969 34046 : DO jy = 1, upcl
1970 28262 : temp1 = zero
1971 28262 : temp3 = zero
1972 28278 : DO k = 1, nenter
1973 16 : k1 = indx2(k)
1974 28278 : temp1 = temp1 + ws(k1, ipntr)*wy(k1, jpntr)
1975 : END DO
1976 28262 : DO k = ileave, n
1977 0 : k1 = indx2(k)
1978 28262 : temp3 = temp3 + ws(k1, ipntr)*wy(k1, jpntr)
1979 : END DO
1980 28262 : IF (is <= jy + m) THEN
1981 17023 : wn1(is, jy) = wn1(is, jy) + temp1 - temp3
1982 : ELSE
1983 11239 : wn1(is, jy) = wn1(is, jy) - temp1 + temp3
1984 : END IF
1985 34046 : jpntr = MOD(jpntr, m) + 1
1986 : END DO
1987 7220 : ipntr = MOD(ipntr, m) + 1
1988 : END DO
1989 :
1990 : ! Form the upper triangle of WN = [D+Y' ZZ'Y/theta -L_a'+R_z' ]
1991 : ! [-L_a +R_z S'AA'S*theta]
1992 :
1993 1436 : m2 = 2*m
1994 8656 : DO iy = 1, col
1995 7220 : is = col + iy
1996 7220 : is1 = m + iy
1997 31463 : DO jy = 1, iy
1998 24243 : js = col + jy
1999 24243 : js1 = m + jy
2000 24243 : wn(jy, iy) = wn1(iy, jy)/theta
2001 31463 : wn(js, is) = wn1(is1, js1)*theta
2002 : END DO
2003 24243 : DO jy = 1, iy - 1
2004 24243 : wn(jy, is) = -wn1(is1, jy)
2005 : END DO
2006 31463 : DO jy = iy, col
2007 31463 : wn(jy, is) = wn1(is1, jy)
2008 : END DO
2009 8656 : wn(iy, iy) = wn(iy, iy) + sy(iy, iy)
2010 : END DO
2011 :
2012 : ! Form the upper triangle of WN= [ LL' L^-1(-L_a'+R_z')]
2013 : ! [(-L_a +R_z)L'^-1 S'AA'S*theta ]
2014 :
2015 : ! first Cholesky factor (1,1) block of wn to get LL'
2016 : ! with L' stored in the upper triangle of wn.
2017 1436 : CALL dpofa(wn, m2, col, info)
2018 1436 : IF (info /= 0) THEN
2019 0 : info = -1
2020 0 : RETURN
2021 : END IF
2022 : ! then form L^-1(-L_a'+R_z') in the (1,2) block.
2023 1436 : col2 = 2*col
2024 8656 : DO js = col + 1, col2
2025 8656 : CALL dtrsl(wn, m2, col, wn(1, js), 11, info)
2026 : END DO
2027 :
2028 : ! Form S'AA'S*theta + (L^-1(-L_a'+R_z'))'L^-1(-L_a'+R_z') in the
2029 : ! upper triangle of (2,2) block of wn.
2030 :
2031 8656 : DO is = col + 1, col2
2032 32899 : DO js = is, col2
2033 31463 : wn(is, js) = wn(is, js) + ddot(col, wn(1, is), 1, wn(1, js), 1)
2034 : END DO
2035 : END DO
2036 :
2037 : ! Cholesky factorization of (2,2) block of wn.
2038 :
2039 1436 : CALL dpofa(wn(col + 1, col + 1), m2, col, info)
2040 1436 : IF (info /= 0) THEN
2041 0 : info = -2
2042 0 : RETURN
2043 : END IF
2044 :
2045 : RETURN
2046 :
2047 : END SUBROUTINE formk
2048 :
2049 : ! **************************************************************************************************
2050 : !> \brief This subroutine forms the upper half of the pos. def. and symm.
2051 : !> T = theta*SS + L*D^(-1)*L', stores T in the upper triangle
2052 : !> of the array wt, and performs the Cholesky factorization of T
2053 : !> to produce J*J', with J' stored in the upper triangle of wt.
2054 : !> \param m ...
2055 : !> \param wt ...
2056 : !> \param sy ...
2057 : !> \param ss ...
2058 : !> \param col ...
2059 : !> \param theta ...
2060 : !> \param info ...
2061 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2062 : !> Optimization Technology Center.
2063 : !> Argonne National Laboratory and Northwestern University.
2064 : !> Written by
2065 : !> Ciyou Zhu
2066 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2067 : ! **************************************************************************************************
2068 1436 : SUBROUTINE formt(m, wt, sy, ss, col, theta, info)
2069 :
2070 : INTEGER :: m
2071 : REAL(KIND=dp) :: wt(m, m), sy(m, m), ss(m, m)
2072 : INTEGER :: col
2073 : REAL(KIND=dp) :: theta
2074 : INTEGER :: info
2075 :
2076 : REAL(KIND=dp), PARAMETER :: zero = 0.0_dp
2077 :
2078 : INTEGER :: i, j, k, k1
2079 : REAL(KIND=dp) :: ddum
2080 :
2081 : ! Form the upper half of T = theta*SS + L*D^(-1)*L',
2082 : ! store T in the upper triangle of the array wt.
2083 :
2084 8656 : DO j = 1, col
2085 8656 : wt(1, j) = theta*ss(1, j)
2086 : END DO
2087 7220 : DO i = 2, col
2088 24243 : DO j = i, col
2089 17023 : k1 = MIN(i, j) - 1
2090 17023 : ddum = zero
2091 66619 : DO k = 1, k1
2092 66619 : ddum = ddum + sy(i, k)*sy(j, k)/sy(k, k)
2093 : END DO
2094 22807 : wt(i, j) = ddum + theta*ss(i, j)
2095 : END DO
2096 : END DO
2097 :
2098 : ! Cholesky factorize T to J*J' with
2099 : ! J' stored in the upper triangle of wt.
2100 :
2101 1436 : CALL dpofa(wt, m, col, info)
2102 1436 : IF (info /= 0) THEN
2103 0 : info = -3
2104 : END IF
2105 :
2106 1436 : RETURN
2107 :
2108 : END SUBROUTINE formt
2109 :
2110 : ! **************************************************************************************************
2111 : !> \brief This subroutine counts the entering and leaving variables when
2112 : !> iter > 0, and finds the index set of free and active variables
2113 : !> at the GCP.
2114 : !> \param n ...
2115 : !> \param nfree ...
2116 : !> \param index for i=1,...,nfree, index(i) are the indices of free variables
2117 : !> for i=nfree+1,...,n, index(i) are the indices of bound variables
2118 : !> On entry after the first iteration, index gives
2119 : !> the free variables at the previous iteration.
2120 : !> On exit it gives the free variables based on the determination
2121 : !> in cauchy using the array iwhere.
2122 : !> \param nenter ...
2123 : !> \param ileave ...
2124 : !> \param indx2 On exit with iter>0, indx2 indicates which variables
2125 : !> have changed status since the previous iteration.
2126 : !> For i= 1,...,nenter, indx2(i) have changed from bound to free.
2127 : !> For i= ileave+1,...,n, indx2(i) have changed from free to bound.
2128 : !> \param iwhere ...
2129 : !> \param wrk ...
2130 : !> \param updatd ...
2131 : !> \param constrained A variable indicating whether bounds are present
2132 : !> \param iprint ...
2133 : !> \param iter ...
2134 : !> \param iwunit User-specified write unit, if not set then WRITE statements
2135 : !> write to default_output_unit by default
2136 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2137 : !> Optimization Technology Center.
2138 : !> Argonne National Laboratory and Northwestern University.
2139 : !> Written by
2140 : !> Ciyou Zhu
2141 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2142 : ! **************************************************************************************************
2143 61 : SUBROUTINE freev(n, nfree, index, nenter, ileave, indx2, &
2144 61 : iwhere, wrk, updatd, constrained, iprint, iter, iwunit)
2145 :
2146 : INTEGER :: n, nfree
2147 : INTEGER, INTENT(inout) :: INDEX(n)
2148 : INTEGER :: nenter, ileave
2149 : INTEGER, INTENT(out) :: indx2(n)
2150 : INTEGER :: iwhere(n)
2151 : LOGICAL :: wrk, updatd, constrained
2152 : INTEGER :: iprint, iter
2153 : INTEGER, OPTIONAL :: iwunit
2154 :
2155 : INTEGER :: i, iact, k, wunit
2156 :
2157 61 : wunit = default_output_unit
2158 61 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
2159 :
2160 61 : nenter = 0
2161 61 : ileave = n + 1
2162 61 : IF (iter > 0 .AND. constrained) THEN
2163 : ! count the entering and leaving variables.
2164 27109 : DO i = 1, nfree
2165 27092 : k = INDEX(i)
2166 :
2167 27109 : IF (iwhere(k) > 0) THEN
2168 2 : ileave = ileave - 1
2169 2 : indx2(ileave) = k
2170 2 : IF (iprint >= 100) WRITE (wunit, 1030) k
2171 : END IF
2172 : END DO
2173 27 : DO i = 1 + nfree, n
2174 10 : k = INDEX(i)
2175 27 : IF (iwhere(k) <= 0) THEN
2176 4 : nenter = nenter + 1
2177 4 : indx2(nenter) = k
2178 4 : IF (iprint >= 100) WRITE (wunit, 2030) k
2179 : END IF
2180 : END DO
2181 17 : IF (iprint >= 99) WRITE (wunit, 3030) n + 1 - ileave, nenter
2182 : END IF
2183 61 : wrk = (ileave < n + 1) .OR. (nenter > 0) .OR. updatd
2184 :
2185 : ! Find the index set of free and active variables at the GCP.
2186 :
2187 61 : nfree = 0
2188 61 : iact = n + 1
2189 55738 : DO i = 1, n
2190 55738 : IF (iwhere(i) <= 0) THEN
2191 55667 : nfree = nfree + 1
2192 55667 : INDEX(nfree) = i
2193 : ELSE
2194 10 : iact = iact - 1
2195 10 : INDEX(iact) = i
2196 : END IF
2197 : END DO
2198 61 : IF (iprint >= 99) WRITE (wunit, 4030) nfree, iter + 1
2199 :
2200 : 1030 FORMAT(' L-BFGS| Variable ', i12, ' leaves the set of free variables')
2201 : 2030 FORMAT(' L-BFGS| Variable ', i12, ' enters the set of free variables')
2202 : 3030 FORMAT(' L-BFGS| ', i12, ' variables leave; ', i12, ' variables enter')
2203 : 4030 FORMAT(' L-BFGS| ', i12, ' variables are free at GCP ', i12)
2204 :
2205 61 : RETURN
2206 :
2207 : END SUBROUTINE freev
2208 :
2209 : ! **************************************************************************************************
2210 : !> \brief This subroutine sorts out the least element of t, and puts the
2211 : !> remaining elements of t in a heap.
2212 : !> \param n n is the dimension of the arrays t and iorder.
2213 : !> \param t On entry t stores the elements to be sorted,
2214 : !> On exit t(n) stores the least elements of t, and t(1) to t(n-1)
2215 : !> stores the remaining elements in the form of a heap.
2216 : !> \param iorder On entry iorder(i) is the index of t(i).
2217 : !> On exit iorder(i) is still the index of t(i), but iorder may be
2218 : !> permuted in accordance with t.
2219 : !> \param iheap iheap should be set as follows:
2220 : !> iheap .eq. 0 if t(1) to t(n) is not in the form of a heap,
2221 : !> iheap .ne. 0 if otherwise.
2222 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2223 : !> Optimization Technology Center.
2224 : !> Argonne National Laboratory and Northwestern University.
2225 : !> Written by
2226 : !> Ciyou Zhu
2227 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2228 : ! **************************************************************************************************
2229 10 : SUBROUTINE hpsolb(n, t, iorder, iheap)
2230 : INTEGER, INTENT(in) :: n
2231 : REAL(KIND=dp), INTENT(inout) :: t(n)
2232 : INTEGER, INTENT(inout) :: iorder(n)
2233 : INTEGER, INTENT(in) :: iheap
2234 :
2235 : INTEGER :: i, indxin, indxou, j, k
2236 : REAL(KIND=dp) :: ddum, out
2237 :
2238 : !
2239 : ! References:
2240 : ! Algorithm 232 of CACM (J. W. J. Williams): HEAPSORT.
2241 : !
2242 : ! * * *
2243 :
2244 10 : IF (iheap == 0) THEN
2245 :
2246 : ! Rearrange the elements t(1) to t(n) to form a heap.
2247 :
2248 13516 : DO k = 2, n
2249 13511 : ddum = t(k)
2250 13511 : indxin = iorder(k)
2251 :
2252 : ! Add ddum to the heap.
2253 13511 : i = k
2254 32488 : DO WHILE (i > 1)
2255 32458 : j = i/2
2256 32488 : IF (ddum < t(j)) THEN
2257 18977 : t(i) = t(j)
2258 18977 : iorder(i) = iorder(j)
2259 18977 : i = j
2260 : ELSE
2261 : EXIT
2262 : END IF
2263 : END DO
2264 13511 : t(i) = ddum
2265 13516 : iorder(i) = indxin
2266 : END DO
2267 : END IF
2268 :
2269 : ! Assign to 'out' the value of t(1), the least member of the heap,
2270 : ! and rearrange the remaining members to form a heap as
2271 : ! elements 1 to n-1 of t.
2272 :
2273 10 : IF (n > 1) THEN
2274 10 : i = 1
2275 10 : out = t(1)
2276 10 : indxou = iorder(1)
2277 10 : ddum = t(n)
2278 10 : indxin = iorder(n)
2279 :
2280 : ! Restore the heap
2281 10 : j = 2*i
2282 85 : DO WHILE (j <= n - 1)
2283 77 : IF (t(j + 1) < t(j)) j = j + 1
2284 77 : IF (t(j) < ddum) THEN
2285 75 : t(i) = t(j)
2286 75 : iorder(i) = iorder(j)
2287 75 : i = j
2288 : ELSE
2289 : EXIT
2290 : END IF
2291 77 : j = 2*i
2292 : END DO
2293 10 : t(i) = ddum
2294 10 : iorder(i) = indxin
2295 :
2296 : ! Put the least member in t(n).
2297 :
2298 10 : t(n) = out
2299 10 : iorder(n) = indxou
2300 : END IF
2301 :
2302 10 : RETURN
2303 :
2304 : END SUBROUTINE hpsolb
2305 :
2306 : ! **************************************************************************************************
2307 : !> \brief This subroutine calls subroutine dcsrch from the Minpack2 library
2308 : !> to perform the line search. Subroutine dscrch is safeguarded so
2309 : !> that all trial points lie within the feasible region.
2310 : !> \param n ...
2311 : !> \param lower_bound the lower bound on x.
2312 : !> \param upper_bound the upper bound on x.
2313 : !> \param nbd ...
2314 : !> \param x ...
2315 : !> \param f ...
2316 : !> \param fold ...
2317 : !> \param gd ...
2318 : !> \param gdold ...
2319 : !> \param g ...
2320 : !> \param d ...
2321 : !> \param r ...
2322 : !> \param t ...
2323 : !> \param z ...
2324 : !> \param stp ...
2325 : !> \param dnorm ...
2326 : !> \param dtd ...
2327 : !> \param xstep ...
2328 : !> \param step_max ...
2329 : !> \param iter ...
2330 : !> \param ifun ...
2331 : !> \param iback ...
2332 : !> \param nfgv ...
2333 : !> \param info ...
2334 : !> \param task ...
2335 : !> \param boxed ...
2336 : !> \param constrained ...
2337 : !> \param csave ...
2338 : !> \param isave ...
2339 : !> \param dsave ...
2340 : !> \param iwunit User-specified write unit, if not set then WRITE statements
2341 : !> write to default_output_unit by default
2342 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2343 : !> Optimization Technology Center.
2344 : !> Argonne National Laboratory and Northwestern University.
2345 : !> Written by
2346 : !> Ciyou Zhu
2347 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2348 : ! **************************************************************************************************
2349 3135 : SUBROUTINE lnsrlb(n, lower_bound, upper_bound, nbd, x, f, fold, gd, gdold, g, d, r, t, &
2350 3135 : z, stp, dnorm, dtd, xstep, step_max, iter, ifun, &
2351 : iback, nfgv, info, task, boxed, constrained, csave, &
2352 : isave, dsave, iwunit)
2353 :
2354 : INTEGER, INTENT(in) :: n
2355 : REAL(KIND=dp), INTENT(in) :: lower_bound(n), upper_bound(n)
2356 : INTEGER :: nbd(n)
2357 : REAL(KIND=dp) :: x(n), f, fold, gd, gdold, g(n), d(n), &
2358 : r(n), t(n), z(n), stp, dnorm, dtd, &
2359 : xstep, step_max
2360 : INTEGER :: iter, ifun, iback, nfgv, info
2361 : CHARACTER(LEN=60) :: task
2362 : LOGICAL :: boxed, constrained
2363 : CHARACTER(LEN=60) :: csave
2364 : INTEGER :: isave(2)
2365 : REAL(KIND=dp) :: dsave(13)
2366 : INTEGER, OPTIONAL :: iwunit
2367 :
2368 : REAL(KIND=dp), PARAMETER :: big = 1.0E10_dp, ftol = 1.0E-3_dp, &
2369 : gtol = 0.9_dp, one = 1.0_dp, &
2370 : xtol = 0.1_dp, zero = 0.0_dp
2371 :
2372 : INTEGER :: i, wunit
2373 : REAL(KIND=dp) :: a1, a2, ddot
2374 :
2375 3135 : wunit = default_output_unit
2376 3135 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
2377 :
2378 3135 : IF (.NOT. (task(1:5) == 'FG_LN')) THEN
2379 :
2380 1484 : dtd = ddot(n, d, 1, d, 1)
2381 1484 : dnorm = SQRT(dtd)
2382 :
2383 : ! Determine the maximum step length.
2384 :
2385 1484 : step_max = big
2386 1484 : IF (constrained) THEN
2387 20 : IF (iter == 0) THEN
2388 3 : step_max = one
2389 : ELSE
2390 27119 : DO i = 1, n
2391 27102 : a1 = d(i)
2392 27119 : IF (nbd(i) /= 0) THEN
2393 27102 : IF (a1 < zero .AND. nbd(i) <= 2) THEN
2394 8594 : a2 = lower_bound(i) - x(i)
2395 8594 : IF (a2 >= zero) THEN
2396 0 : step_max = zero
2397 8594 : ELSE IF (a1*step_max < a2) THEN
2398 13 : step_max = a2/a1
2399 : END IF
2400 18508 : ELSE IF (a1 > zero .AND. nbd(i) >= 2) THEN
2401 7872 : a2 = upper_bound(i) - x(i)
2402 7872 : IF (a2 <= zero) THEN
2403 0 : step_max = zero
2404 7872 : ELSE IF (a1*step_max > a2) THEN
2405 12 : step_max = a2/a1
2406 : END IF
2407 : END IF
2408 : END IF
2409 : END DO
2410 : END IF
2411 : END IF
2412 :
2413 1484 : IF (iter == 0 .AND. .NOT. boxed) THEN
2414 41 : stp = MIN(one/dnorm, step_max)
2415 : ELSE
2416 1443 : stp = one
2417 : END IF
2418 :
2419 1484 : CALL dcopy(n, x, 1, t, 1)
2420 1484 : CALL dcopy(n, g, 1, r, 1)
2421 1484 : fold = f
2422 1484 : ifun = 0
2423 1484 : iback = 0
2424 1484 : csave = 'START'
2425 : END IF
2426 3135 : gd = ddot(n, g, 1, d, 1)
2427 3135 : IF (ifun == 0) THEN
2428 1484 : gdold = gd
2429 1484 : IF (gd >= zero) THEN
2430 : ! the directional derivative >=0.
2431 : ! Line search is impossible.
2432 0 : WRITE (wunit, 1020) gd
2433 0 : info = -4
2434 0 : RETURN
2435 : END IF
2436 : END IF
2437 :
2438 3135 : CALL dcsrch(f, gd, stp, ftol, gtol, xtol, zero, step_max, csave, isave, dsave)
2439 :
2440 3135 : xstep = stp*dnorm
2441 3135 : IF (csave(1:4) /= 'CONV' .AND. csave(1:4) /= 'WARN') THEN
2442 1651 : task = 'FG_LNSRCH'
2443 1651 : ifun = ifun + 1
2444 1651 : nfgv = nfgv + 1
2445 1651 : iback = ifun - 1
2446 1651 : IF (stp == one) THEN
2447 1443 : CALL dcopy(n, z, 1, x, 1)
2448 : ELSE
2449 167926 : DO i = 1, n
2450 167926 : x(i) = stp*d(i) + t(i)
2451 : END DO
2452 : END IF
2453 : ELSE
2454 1484 : task = 'NEW_X'
2455 : END IF
2456 :
2457 : 1020 FORMAT(' L-BFGS| ascent direction in projection gd = ', d12.5)
2458 :
2459 : RETURN
2460 :
2461 : END SUBROUTINE lnsrlb
2462 :
2463 : ! **************************************************************************************************
2464 : !> \brief This subroutine updates matrices WS and WY, and forms the middle matrix in B.
2465 : !> \param n ...
2466 : !> \param m ...
2467 : !> \param ws ...
2468 : !> \param wy ...
2469 : !> \param sy ...
2470 : !> \param ss ...
2471 : !> \param d ...
2472 : !> \param r ...
2473 : !> \param itail ...
2474 : !> \param iupdat ...
2475 : !> \param col ...
2476 : !> \param head ...
2477 : !> \param theta ...
2478 : !> \param rr ...
2479 : !> \param dr ...
2480 : !> \param stp ...
2481 : !> \param dtd ...
2482 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2483 : !> Optimization Technology Center.
2484 : !> Argonne National Laboratory and Northwestern University.
2485 : !> Written by
2486 : !> Ciyou Zhu
2487 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2488 : ! **************************************************************************************************
2489 1436 : SUBROUTINE matupd(n, m, ws, wy, sy, ss, d, r, itail, &
2490 : iupdat, col, head, theta, rr, dr, stp, dtd)
2491 :
2492 : INTEGER :: n, m
2493 : REAL(KIND=dp) :: ws(n, m), wy(n, m), sy(m, m), ss(m, m), &
2494 : d(n), r(n)
2495 : INTEGER :: itail, iupdat, col, head
2496 : REAL(KIND=dp) :: theta, rr, dr, stp, dtd
2497 :
2498 : REAL(KIND=dp), PARAMETER :: one = 1.0_dp
2499 :
2500 : INTEGER :: j, pointr
2501 : REAL(KIND=dp) :: ddot
2502 :
2503 : ! ************
2504 : ! Set pointers for matrices WS and WY.
2505 :
2506 1436 : IF (iupdat <= m) THEN
2507 187 : col = iupdat
2508 187 : itail = MOD(head + iupdat - 2, m) + 1
2509 : ELSE
2510 1249 : itail = MOD(itail, m) + 1
2511 1249 : head = MOD(head, m) + 1
2512 : END IF
2513 :
2514 : ! Update matrices WS and WY.
2515 :
2516 1436 : CALL dcopy(n, d, 1, ws(1, itail), 1)
2517 1436 : CALL dcopy(n, r, 1, wy(1, itail), 1)
2518 :
2519 : ! Set theta=yy/ys.
2520 :
2521 1436 : theta = rr/dr
2522 :
2523 : ! Form the middle matrix in B.
2524 :
2525 : ! update the upper triangle of SS,
2526 : ! and the lower triangle of SY:
2527 1436 : IF (iupdat > m) THEN
2528 : ! move old information
2529 6245 : DO j = 1, col - 1
2530 4996 : CALL dcopy(j, ss(2, j + 1), 1, ss(1, j), 1)
2531 6245 : CALL dcopy(col - j, sy(j + 1, j + 1), 1, sy(j, j), 1)
2532 : END DO
2533 : END IF
2534 : ! add new information: the last row of SY
2535 : ! and the last column of SS:
2536 1436 : pointr = head
2537 7220 : DO j = 1, col - 1
2538 5784 : sy(col, j) = ddot(n, d, 1, wy(1, pointr), 1)
2539 5784 : ss(j, col) = ddot(n, ws(1, pointr), 1, d, 1)
2540 7220 : pointr = MOD(pointr, m) + 1
2541 : END DO
2542 1436 : IF (stp == one) THEN
2543 1305 : ss(col, col) = dtd
2544 : ELSE
2545 131 : ss(col, col) = stp*stp*dtd
2546 : END IF
2547 1436 : sy(col, col) = dr
2548 :
2549 1436 : RETURN
2550 :
2551 : END SUBROUTINE matupd
2552 :
2553 : ! **************************************************************************************************
2554 : !> \brief This subroutine prints the input data, initial point, upper and
2555 : !> lower bounds of each variable, machine precision, as well as
2556 : !> the headings of the output.
2557 : !>
2558 : !> \param n ...
2559 : !> \param m ...
2560 : !> \param lower_bound the lower bound on x.
2561 : !> \param upper_bound the upper bound on x.
2562 : !> \param x ...
2563 : !> \param iprint ...
2564 : !> \param itfile ...
2565 : !> \param epsmch ...
2566 : !> \param iwunit User-specified write unit, if not set then WRITE statements
2567 : !> write to default_output_unit by default
2568 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2569 : !> Optimization Technology Center.
2570 : !> Argonne National Laboratory and Northwestern University.
2571 : !> Written by
2572 : !> Ciyou Zhu
2573 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2574 : ! **************************************************************************************************
2575 45 : SUBROUTINE prn1lb(n, m, lower_bound, upper_bound, x, iprint, itfile, epsmch, iwunit)
2576 :
2577 : INTEGER, INTENT(in) :: n, m
2578 : REAL(KIND=dp), INTENT(in) :: lower_bound(n), upper_bound(n), x(n)
2579 : INTEGER :: iprint, itfile
2580 : REAL(KIND=dp) :: epsmch
2581 : INTEGER, OPTIONAL :: iwunit
2582 :
2583 : INTEGER :: i, wunit
2584 :
2585 45 : wunit = default_output_unit
2586 45 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
2587 :
2588 45 : IF (iprint >= 0) THEN
2589 45 : WRITE (wunit, 7001) epsmch
2590 45 : WRITE (wunit, 7002) n, m
2591 45 : IF (iprint >= 1) THEN
2592 45 : WRITE (itfile, 2001) epsmch
2593 45 : WRITE (itfile, 7003) n, m
2594 45 : WRITE (itfile, 9001)
2595 45 : IF (iprint > 100) THEN
2596 0 : WRITE (wunit, 1004) ' L-BFGS| L =', (lower_bound(i), i=1, n)
2597 0 : WRITE (wunit, 1004) ' L-BFGS| X0 =', (x(i), i=1, n)
2598 0 : WRITE (wunit, 1004) ' L-BFGS| U =', (upper_bound(i), i=1, n)
2599 : END IF
2600 : END IF
2601 : END IF
2602 :
2603 : 1004 FORMAT(/, a13, 1p, /, (4x, 1p, 6(1x, d11.4)))
2604 : 2001 FORMAT('RUNNING THE L-BFGS-B CODE', /, /, &
2605 : 'it = iteration number', /, &
2606 : 'nf = number of function evaluations', /, &
2607 : 'nseg = number of segments explored during the Cauchy search', /, &
2608 : 'nact = number of active bounds at the generalized Cauchy point' &
2609 : , /, &
2610 : 'sub = manner in which the subspace minimization terminated:' &
2611 : , /, ' con = converged, bnd = a bound was reached', /, &
2612 : 'itls = number of iterations performed in the line search', /, &
2613 : 'stepl = step length used', /, &
2614 : 'tstep = norm of the displacement (total step)', /, &
2615 : 'projg = norm of the projected gradient', /, &
2616 : 'f = function value', /, /, &
2617 : ' * * *', /, /, &
2618 : 'Machine precision =', 1p, d10.3)
2619 : 7001 FORMAT(/, ' L-BFGS| RUNNING THE L-BFGS-B CODE', /, &
2620 : ' L-BFGS| Machine precision =', 1p, d10.3)
2621 : 7002 FORMAT(/, ' L-BFGS| N = ', i12, ' M = ', i12)
2622 : 7003 FORMAT(' N = ', i12, ' M = ', i12)
2623 : 9001 FORMAT(/, 3x, 'it', 3x, 'nf', 2x, 'nseg', 2x, 'nact', 2x, 'sub', 2x, 'itls', &
2624 : 2x, 'stepl', 4x, 'tstep', 5x, 'projg', 8x, 'f')
2625 :
2626 45 : RETURN
2627 :
2628 : END SUBROUTINE prn1lb
2629 :
2630 : ! **************************************************************************************************
2631 : !> \brief This subroutine prints out new information after a successful line search.
2632 : !> \param n ...
2633 : !> \param x ...
2634 : !> \param f ...
2635 : !> \param g ...
2636 : !> \param iprint ...
2637 : !> \param itfile ...
2638 : !> \param iter ...
2639 : !> \param nfgv ...
2640 : !> \param nact ...
2641 : !> \param g_inf_norm ...
2642 : !> \param nseg ...
2643 : !> \param word ...
2644 : !> \param iword ...
2645 : !> \param iback ...
2646 : !> \param stp ...
2647 : !> \param xstep ...
2648 : !> \param iwunit User-specified write unit, if not set then WRITE statements
2649 : !> write to default_output_unit by default
2650 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2651 : !> Optimization Technology Center.
2652 : !> Argonne National Laboratory and Northwestern University.
2653 : !> Written by
2654 : !> Ciyou Zhu
2655 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2656 : ! **************************************************************************************************
2657 1484 : SUBROUTINE prn2lb(n, x, f, g, iprint, itfile, iter, nfgv, nact, &
2658 : g_inf_norm, nseg, word, iword, iback, stp, xstep, iwunit)
2659 :
2660 : INTEGER, INTENT(in) :: n
2661 : REAL(KIND=dp), INTENT(in) :: x(n), f, g(n)
2662 : INTEGER, INTENT(in) :: iprint, itfile, iter, nfgv, nact
2663 : REAL(KIND=dp), INTENT(in) :: g_inf_norm
2664 : INTEGER, INTENT(in) :: nseg
2665 : CHARACTER(LEN=3) :: word
2666 : INTEGER :: iword, iback
2667 : REAL(KIND=dp) :: stp, xstep
2668 : INTEGER, OPTIONAL :: iwunit
2669 :
2670 : INTEGER :: i, imod, wunit
2671 :
2672 1484 : wunit = default_output_unit
2673 1484 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
2674 :
2675 : ! 'word' records the status of subspace solutions.
2676 :
2677 1484 : IF (iword == 0) THEN
2678 : ! the subspace minimization converged.
2679 1436 : word = 'con'
2680 48 : ELSE IF (iword == 1) THEN
2681 : ! the subspace minimization stopped at a bound.
2682 0 : word = 'bnd'
2683 48 : ELSE IF (iword == 5) THEN
2684 : ! the truncated Newton step has been used.
2685 0 : word = 'TNT'
2686 : ELSE
2687 48 : word = '---'
2688 : END IF
2689 1484 : IF (iprint >= 99) THEN
2690 0 : WRITE (wunit, 2002) iback, xstep
2691 0 : WRITE (wunit, 2001) iter, f, g_inf_norm
2692 0 : IF (iprint > 100) THEN
2693 0 : WRITE (wunit, 1004) ' L-BFGS| X =', (x(i), i=1, n)
2694 0 : WRITE (wunit, 1004) ' L-BFGS| G =', (g(i), i=1, n)
2695 : END IF
2696 1484 : ELSE IF (iprint > 0) THEN
2697 1484 : imod = MOD(iter, iprint)
2698 1484 : IF (imod == 0) WRITE (wunit, 2001) iter, f, g_inf_norm
2699 : END IF
2700 1484 : IF (iprint >= 1) WRITE (itfile, 3001) &
2701 1484 : iter, nfgv, nseg, nact, word, iback, stp, xstep, g_inf_norm, f
2702 :
2703 : 1004 FORMAT(/, a12, 1p, /, (4x, 1p, 6(1x, d11.4)))
2704 : 2001 FORMAT &
2705 : (/, ' L-BFGS| At iterate', i5, 4x, 'f= ', 1p, d12.5, 4x, '|proj g|= ', 1p, d12.5)
2706 : 2002 FORMAT(/, ' L-BFGS| LINE SEARCH ', i12, ' times; norm of step = ', 1p, d24.15)
2707 : 3001 FORMAT(2(1x, i4), 2(1x, i5), 2x, a3, 1x, i4, 1p, 2(2x, d7.1), 1p, 2(1x, d10.3))
2708 :
2709 1484 : RETURN
2710 :
2711 : END SUBROUTINE prn2lb
2712 :
2713 : ! **************************************************************************************************
2714 : !> \brief This subroutine prints out information when either a built-in
2715 : !> convergence test is satisfied or when an error message is
2716 : !> generated.
2717 : !> \param n ...
2718 : !> \param x ...
2719 : !> \param f ...
2720 : !> \param task ...
2721 : !> \param iprint ...
2722 : !> \param info ...
2723 : !> \param itfile ...
2724 : !> \param iter ...
2725 : !> \param nfgv ...
2726 : !> \param nintol ...
2727 : !> \param nskip ...
2728 : !> \param nact ...
2729 : !> \param g_inf_norm ...
2730 : !> \param time ...
2731 : !> \param nseg ...
2732 : !> \param word ...
2733 : !> \param iback ...
2734 : !> \param stp ...
2735 : !> \param xstep ...
2736 : !> \param k ...
2737 : !> \param cachyt ...
2738 : !> \param sbtime ...
2739 : !> \param lnscht ...
2740 : !> \param iwunit User-specified write unit, if not set then WRITE statements
2741 : !> write to default_output_unit by default
2742 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2743 : !> Optimization Technology Center.
2744 : !> Argonne National Laboratory and Northwestern University.
2745 : !> Written by
2746 : !> Ciyou Zhu
2747 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2748 : ! **************************************************************************************************
2749 1 : SUBROUTINE prn3lb(n, x, f, task, iprint, info, itfile, &
2750 : iter, nfgv, nintol, nskip, nact, g_inf_norm, &
2751 : time, nseg, word, iback, stp, xstep, k, &
2752 : cachyt, sbtime, lnscht, iwunit)
2753 :
2754 : INTEGER, INTENT(in) :: n
2755 : REAL(KIND=dp), INTENT(in) :: x(n), f
2756 : CHARACTER(LEN=60), INTENT(in) :: task
2757 : INTEGER, INTENT(in) :: iprint, info, itfile, iter, nfgv, &
2758 : nintol, nskip, nact
2759 : REAL(KIND=dp), INTENT(in) :: g_inf_norm, time
2760 : INTEGER, INTENT(in) :: nseg
2761 : CHARACTER(LEN=3) :: word
2762 : INTEGER :: iback
2763 : REAL(KIND=dp) :: stp, xstep
2764 : INTEGER :: k
2765 : REAL(KIND=dp) :: cachyt, sbtime, lnscht
2766 : INTEGER, OPTIONAL :: iwunit
2767 :
2768 : INTEGER :: i, wunit
2769 :
2770 1 : wunit = default_output_unit
2771 1 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
2772 :
2773 1 : IF (iprint >= 0 .AND. .NOT. (task(1:5) == 'ERROR')) THEN
2774 1 : WRITE (wunit, 3003)
2775 1 : WRITE (wunit, 3004)
2776 1 : WRITE (wunit, 3005) n, iter, nfgv, nintol, nskip, nact, g_inf_norm, f
2777 1 : IF (iprint >= 100) THEN
2778 0 : WRITE (wunit, 1004) ' L-BFGS| X =', (x(i), i=1, n)
2779 : END IF
2780 1 : IF (iprint >= 1) WRITE (wunit, 3006) f
2781 : END IF
2782 1 : IF (iprint >= 0) THEN
2783 :
2784 1 : WRITE (wunit, 3001)
2785 1 : WRITE (wunit, 3009) task
2786 1 : IF (info /= 0) THEN
2787 0 : IF (info == -1) WRITE (wunit, 9011)
2788 0 : IF (info == -2) WRITE (wunit, 9012)
2789 0 : IF (info == -3) WRITE (wunit, 9013)
2790 0 : IF (info == -4) WRITE (wunit, 9014)
2791 0 : IF (info == -5) WRITE (wunit, 9015)
2792 0 : IF (info == -6) WRITE (wunit, 9016) k
2793 0 : IF (info == -7) WRITE (wunit, 9017) k, k
2794 0 : IF (info == -8) WRITE (wunit, 9018)
2795 0 : IF (info == -9) WRITE (wunit, 9019)
2796 : END IF
2797 1 : IF (iprint >= 1) WRITE (wunit, 3007) cachyt, sbtime, lnscht
2798 1 : WRITE (wunit, 3008) time
2799 1 : WRITE (wunit, 3001)
2800 :
2801 1 : IF (iprint >= 1) THEN
2802 1 : IF (info == -4 .OR. info == -9) THEN
2803 : WRITE (itfile, 3002) &
2804 0 : iter, nfgv, nseg, nact, word, iback, stp, xstep
2805 : END IF
2806 1 : WRITE (itfile, 4009) task
2807 1 : IF (info /= 0) THEN
2808 0 : IF (info == -1) WRITE (itfile, 9011)
2809 0 : IF (info == -2) WRITE (itfile, 9012)
2810 0 : IF (info == -3) WRITE (itfile, 9013)
2811 0 : IF (info == -4) WRITE (itfile, 9014)
2812 0 : IF (info == -5) WRITE (itfile, 9015)
2813 0 : IF (info == -8) WRITE (itfile, 9018)
2814 0 : IF (info == -9) WRITE (itfile, 9019)
2815 : END IF
2816 1 : WRITE (itfile, 3008) time
2817 : END IF
2818 : END IF
2819 :
2820 : 1004 FORMAT(/, a12, 1p, /, (4x, 1p, 6(1x, d11.4)))
2821 : 3001 FORMAT(/, ' L-BFGS| ---------------- Information ----------------')
2822 : 3002 FORMAT(2(1x, i4), 2(1x, i5), 2x, a3, 1x, i4, 1p, 2(2x, d7.1), 6x, '-', 10x, '-')
2823 : 3003 FORMAT(/, &
2824 : ' L-BFGS| * * *', /, /, &
2825 : ' L-BFGS| Tit = total number of iterations', /, &
2826 : ' L-BFGS| Tnf = total number of function evaluations', /, &
2827 : ' L-BFGS| Tnint = total number of segments explored during', &
2828 : ' L-BFGS| Cauchy searches', /, &
2829 : ' L-BFGS| Skip = number of BFGS updates skipped', /, &
2830 : ' L-BFGS| Nact = number of active bounds at final generalized', &
2831 : ' L-BFGS| Cauchy point', /, &
2832 : ' L-BFGS| Projg = norm of the final projected gradient', /, &
2833 : ' L-BFGS| F = final function value', /, /, &
2834 : ' L-BFGS| * * *')
2835 : 3004 FORMAT(/, ' L-BFGS| ', 3x, 'N', 4x, 'Tit', 5x, 'Tnf', 2x, 'Tnint', 2x, &
2836 : 'Skip', 2x, 'Nact', 5x, 'Projg', 8x, 'F')
2837 : 3005 FORMAT(' L-BFGS| ', i5, 2(1x, i6), (1x, i6), (2x, i4), (1x, i5), 1p, 2(2x, d10.3))
2838 : 3006 FORMAT(' L-BFGS| F =', d12.5)
2839 : 3007 FORMAT(/, &
2840 : ' L-BFGS| Cauchy time', 1p, e10.3, ' seconds.', / &
2841 : ' L-BFGS| Subspace minimization time', 1p, e10.3, ' seconds.', / &
2842 : ' L-BFGS| Line search time', 1p, e10.3, ' seconds.')
2843 : 3008 FORMAT(/, ' Total User time', 1p, e10.3, ' seconds.',/)
2844 : 3009 FORMAT(/, ' L-BFGS| ', a60)
2845 : 4009 FORMAT(/, a60)
2846 : 9011 FORMAT(/, &
2847 : ' Matrix in 1st Cholesky factorization in formk is not Pos. Def.')
2848 : 9012 FORMAT(/, &
2849 : ' Matrix in 2st Cholesky factorization in formk is not Pos. Def.')
2850 : 9013 FORMAT(/, &
2851 : ' Matrix in the Cholesky factorization in formt is not Pos. Def.')
2852 : 9014 FORMAT(/, &
2853 : ' Derivative >= 0, backtracking line search impossible.', /, &
2854 : ' Previous x, f and g restored.', /, &
2855 : ' Possible causes: 1 error in function or gradient evaluation;', /, &
2856 : ' 2 rounding errors dominate computation.')
2857 : 9015 FORMAT(/, &
2858 : ' Warning: more than 10 function and gradient', /, &
2859 : ' evaluations in the last line search. Termination', /, &
2860 : ' may possibly be caused by a bad search direction.')
2861 : 9016 FORMAT(' Input nbd(', i12, ') is invalid.')
2862 : 9017 FORMAT(' l(', i12, ') > u(', i12, '). No feasible solution.')
2863 : 9018 FORMAT(/, ' The triangular system is singular.')
2864 : 9019 FORMAT(/, &
2865 : ' Line search cannot locate an adequate point after 20 function', /, &
2866 : ' and gradient evaluations. Previous x, f and g restored.', /, &
2867 : ' Possible causes: 1 error in function or gradient evaluation;', /, &
2868 : ' 2 rounding error dominate computation.')
2869 :
2870 1 : RETURN
2871 :
2872 : END SUBROUTINE prn3lb
2873 :
2874 : ! **************************************************************************************************
2875 : !> \brief This subroutine computes the infinity norm of the projected gradient.
2876 : !> \param n ...
2877 : !> \param lower_bound the lower bound on x.
2878 : !> \param upper_bound the upper bound on x.
2879 : !> \param nbd ...
2880 : !> \param x ...
2881 : !> \param g ...
2882 : !> \param g_inf_norm ...
2883 : !> \author NEOS, November 1994. (Latest revision June 1996.)
2884 : !> Optimization Technology Center.
2885 : !> Argonne National Laboratory and Northwestern University.
2886 : !> Written by
2887 : !> Ciyou Zhu
2888 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2889 : ! **************************************************************************************************
2890 1528 : SUBROUTINE projgr(n, lower_bound, upper_bound, nbd, x, g, g_inf_norm)
2891 :
2892 : INTEGER, INTENT(in) :: n
2893 : REAL(KIND=dp), INTENT(in) :: lower_bound(n), upper_bound(n)
2894 : INTEGER, INTENT(in) :: nbd(n)
2895 : REAL(KIND=dp), INTENT(in) :: x(n), g(n)
2896 : REAL(KIND=dp) :: g_inf_norm
2897 :
2898 : REAL(KIND=dp), PARAMETER :: zero = 0.0_dp
2899 :
2900 : INTEGER :: i
2901 : REAL(KIND=dp) :: gi
2902 :
2903 1528 : g_inf_norm = zero
2904 894763 : DO i = 1, n
2905 893235 : gi = g(i)
2906 893235 : IF (nbd(i) /= 0) THEN
2907 45138 : IF (gi < zero) THEN
2908 22652 : IF (nbd(i) >= 2) gi = MAX((x(i) - upper_bound(i)), gi)
2909 : ELSE
2910 22486 : IF (nbd(i) <= 2) gi = MIN((x(i) - lower_bound(i)), gi)
2911 : END IF
2912 : END IF
2913 894763 : g_inf_norm = MAX(g_inf_norm, ABS(gi))
2914 : END DO
2915 :
2916 1528 : RETURN
2917 :
2918 : END SUBROUTINE projgr
2919 :
2920 : ! **************************************************************************************************
2921 : !> \brief This routine contains the major changes in the updated version.
2922 : !> The changes are described in the accompanying paper
2923 : !>
2924 : !> Jose Luis Morales, Jorge Nocedal
2925 : !> "Remark On Algorithm 788: L-BFGS-B: Fortran Subroutines for Large
2926 : !> Bound Constrained Optimization". Decemmber 27, 2010.
2927 : !>
2928 : !> J.L. Morales Departamento de Matematicas,
2929 : !> Instituto Tecnologico Autonomo de Mexico
2930 : !> Mexico D.F.
2931 : !>
2932 : !> J, Nocedal Department of Electrical Engineering and
2933 : !> Computer Science.
2934 : !> Northwestern University. Evanston, IL. USA
2935 : !>
2936 : !> January 17, 2011
2937 : !>
2938 : !> *****************************************************************
2939 : !>
2940 : !> Given xcp, l, u, r, an index set that specifies
2941 : !> the active set at xcp, and an l-BFGS matrix B
2942 : !> (in terms of WY, WS, SY, WT, head, col, and theta),
2943 : !> this subroutine computes an approximate solution
2944 : !> of the subspace problem
2945 : !>
2946 : !> (P) min Q(x) = r'(x-xcp) + 1/2 (x-xcp)' B (x-xcp)
2947 : !>
2948 : !> subject to l<=x<=u
2949 : !> x_i=xcp_i for all i in A(xcp)
2950 : !>
2951 : !> along the subspace unconstrained Newton direction
2952 : !>
2953 : !> d = -(Z'BZ)^(-1) r.
2954 : !>
2955 : !> The formula for the Newton direction, given the L-BFGS matrix
2956 : !> and the Sherman-Morrison formula, is
2957 : !>
2958 : !> d = (1/theta)r + (1/theta*2) Z'WK^(-1)W'Z r.
2959 : !>
2960 : !> where
2961 : !> K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
2962 : !> [L_a -R_z theta*S'AA'S ]
2963 : !>
2964 : !> Note that this procedure for computing d differs
2965 : !> from that described in [1]. One can show that the matrix K is
2966 : !> equal to the matrix M^[-1]N in that paper.
2967 : !> \param n n is the dimension of the problem.
2968 : !> \param m m is the maximum number of variable metric corrections
2969 : !> used to define the limited memory matrix.
2970 : !> \param nsub nsub is the number of free variables.
2971 : !> \param ind ind specifies the coordinate indices of free variables.
2972 : !> \param lower_bound the lower bound on x.
2973 : !> \param upper_bound the upper bound on x.
2974 : !> \param nbd nbd represents the type of bounds imposed on the
2975 : !> variables, and must be specified as follows:
2976 : !> nbd(i)=0 if x(i) is unbounded,
2977 : !> 1 if x(i) has only a lower bound,
2978 : !> 2 if x(i) has both lower and upper bounds, and
2979 : !> 3 if x(i) has only an upper bound.
2980 : !> \param x x is a double precision array of dimension n.
2981 : !> On entry x specifies the Cauchy point xcp.
2982 : !> On exit x(i) is the minimizer of Q over the subspace of free variables.
2983 : !> \param d On entry d is the reduced gradient of Q at xcp.
2984 : !> On exit d is the Newton direction of Q.
2985 : !> \param xp xp is a double precision array of dimension n.
2986 : !> used to safeguard the projected Newton direction
2987 : !> \param ws ws and wy are double precision arrays;
2988 : !> On entry they store the information defining the limited memory BFGS matrix:
2989 : !> ws(n,m) stores S, a set of s-vectors;
2990 : !> \param wy wy(n,m) stores Y, a set of y-vectors;
2991 : !> \param theta theta is the scaling factor specifying B_0 = theta I;
2992 : !> \param xx xx holds the current iterate
2993 : !> \param gg gg holds the gradient at the current iterate
2994 : !> \param col is the number of variable metric corrections stored;
2995 : !> \param head head is the location of the 1st s- (or y-) vector in S (or Y).
2996 : !> \param iword iword specifies the status of the subspace solution.
2997 : !> iword = 0 if the solution is in the box,
2998 : !> 1 if some bound is encountered.
2999 : !> \param wv wv is a working array
3000 : !> \param wn the upper triangle of wn stores the LEL^T factorization
3001 : !> of the indefinite matrix
3002 : !>
3003 : !> K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
3004 : !> [L_a -R_z theta*S'AA'S ]
3005 : !> where E = [-I 0]
3006 : !> [ 0 I]
3007 : !> \param iprint iprint is an INTEGER variable that must be set by the user.
3008 : !> It controls the frequency and type of output generated:
3009 : !> iprint<0 no output is generated;
3010 : !> iprint=0 print only one line at the last iteration;
3011 : !> 0<iprint<99 print also f and |proj g| every iprint iterations;
3012 : !> iprint=99 print details of every iteration except n-vectors;
3013 : !> iprint=100 print also the changes of active set and final x;
3014 : !> iprint>100 print details of every iteration including x and g;
3015 : !> When iprint > 0, the file iterate.dat will be created to summarize the iteration.
3016 : !> \param info info = 0 for normal return,
3017 : !> = nonzero for abnormal return when the matrix K is ill-conditioned.
3018 : !> \param iwunit User-specified write unit, if not set then WRITE statements
3019 : !> write to default_output_unit by default
3020 : !> \author NEOS, November 1994. (Latest revision June 1996.)
3021 : !> Optimization Technology Center.
3022 : !> Argonne National Laboratory and Northwestern University.
3023 : !> Written by
3024 : !> Ciyou Zhu
3025 : !> in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
3026 : ! **************************************************************************************************
3027 1436 : SUBROUTINE subsm(n, m, nsub, ind, lower_bound, upper_bound, nbd, x, d, xp, ws, wy, &
3028 1436 : theta, xx, gg, &
3029 1436 : col, head, iword, wv, wn, iprint, info, iwunit)
3030 : INTEGER, INTENT(in) :: n, m, nsub, ind(nsub)
3031 : REAL(KIND=dp), INTENT(in) :: lower_bound(n), upper_bound(n)
3032 : INTEGER, INTENT(in) :: nbd(n)
3033 : REAL(KIND=dp), INTENT(inout) :: x(n), d(n)
3034 : REAL(KIND=dp) :: xp(n)
3035 : REAL(KIND=dp), INTENT(in) :: ws(n, m), wy(n, m), theta, xx(n), gg(n)
3036 : INTEGER, INTENT(in) :: col, head
3037 : INTEGER, INTENT(out) :: iword
3038 : REAL(KIND=dp) :: wv(2*m)
3039 : REAL(KIND=dp), INTENT(in) :: wn(2*m, 2*m)
3040 : INTEGER :: iprint
3041 : INTEGER, INTENT(out) :: info
3042 : INTEGER, OPTIONAL :: iwunit
3043 :
3044 : REAL(KIND=dp), PARAMETER :: one = 1.0_dp, zero = 0.0_dp
3045 :
3046 : INTEGER :: col2, i, ibd, j, js, jy, k, m2, pointr, &
3047 : wunit
3048 : REAL(KIND=dp) :: alpha, dd_p, dk, temp1, temp2, xk
3049 :
3050 : ! References:
3051 : !
3052 : ! [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
3053 : ! memory algorithm for bound constrained optimization'',
3054 : ! SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
3055 : !
3056 : !
3057 : !
3058 : ! * * *
3059 : !
3060 :
3061 1436 : wunit = default_output_unit
3062 1436 : IF (PRESENT(iwunit) .AND. iwunit > 0) wunit = iwunit
3063 :
3064 1436 : IF (nsub <= 0) RETURN
3065 1436 : IF (iprint >= 99) WRITE (wunit, 4001)
3066 :
3067 : ! Compute wv = W'Zd.
3068 :
3069 1436 : pointr = head
3070 8656 : DO i = 1, col
3071 : temp1 = zero
3072 : temp2 = zero
3073 3981683 : DO j = 1, nsub
3074 3974463 : k = ind(j)
3075 3974463 : temp1 = temp1 + wy(k, pointr)*d(j)
3076 3981683 : temp2 = temp2 + ws(k, pointr)*d(j)
3077 : END DO
3078 7220 : wv(i) = temp1
3079 7220 : wv(col + i) = theta*temp2
3080 8656 : pointr = MOD(pointr, m) + 1
3081 : END DO
3082 :
3083 : ! Compute wv:=K^(-1)wv.
3084 :
3085 1436 : m2 = 2*m
3086 1436 : col2 = 2*col
3087 1436 : CALL dtrsl(wn, m2, col2, wv, 11, info)
3088 1436 : IF (info /= 0) RETURN
3089 8656 : DO i = 1, col
3090 8656 : wv(i) = -wv(i)
3091 : END DO
3092 1436 : CALL dtrsl(wn, m2, col2, wv, 01, info)
3093 1436 : IF (info /= 0) RETURN
3094 :
3095 : ! Compute d = (1/theta)d + (1/theta**2)Z'W wv.
3096 :
3097 : pointr = head
3098 8656 : DO jy = 1, col
3099 7220 : js = col + jy
3100 3981683 : DO i = 1, nsub
3101 3974463 : k = ind(i)
3102 : d(i) = d(i) + wy(k, pointr)*wv(jy)/theta &
3103 3981683 : & + ws(k, pointr)*wv(js)
3104 : END DO
3105 8656 : pointr = MOD(pointr, m) + 1
3106 : END DO
3107 :
3108 1436 : CALL dscal(nsub, one/theta, d, 1)
3109 : !
3110 : !-----------------------------------------------------------------
3111 : ! Let us try the projection, d is the Newton direction
3112 :
3113 1436 : iword = 0
3114 :
3115 1436 : CALL dcopy(n, x, 1, xp, 1)
3116 : !
3117 837489 : DO i = 1, nsub
3118 836053 : k = ind(i)
3119 836053 : dk = d(i)
3120 836053 : xk = x(k)
3121 837489 : IF (nbd(k) /= 0) THEN
3122 : !
3123 : ! lower bounds only
3124 27070 : IF (nbd(k) == 1) THEN
3125 0 : x(k) = MAX(lower_bound(k), xk + dk)
3126 0 : IF (x(k) == lower_bound(k)) iword = 1
3127 : ELSE
3128 : !
3129 : ! upper and lower bounds
3130 27070 : IF (nbd(k) == 2) THEN
3131 27070 : xk = MAX(lower_bound(k), xk + dk)
3132 27070 : x(k) = MIN(upper_bound(k), xk)
3133 27070 : IF (x(k) == lower_bound(k) .OR. x(k) == upper_bound(k)) iword = 1
3134 : ELSE
3135 : !
3136 : ! upper bounds only
3137 0 : IF (nbd(k) == 3) THEN
3138 0 : x(k) = MIN(upper_bound(k), xk + dk)
3139 0 : IF (x(k) == upper_bound(k)) iword = 1
3140 : END IF
3141 : END IF
3142 : END IF
3143 : !
3144 : ! free variables
3145 : ELSE
3146 808983 : x(k) = xk + dk
3147 : END IF
3148 : END DO
3149 : !
3150 1436 : IF (.NOT. (iword == 0)) THEN
3151 : !
3152 : ! check sign of the directional derivative
3153 : !
3154 : dd_p = zero
3155 0 : DO i = 1, n
3156 0 : dd_p = dd_p + (x(i) - xx(i))*gg(i)
3157 : END DO
3158 0 : IF (dd_p > zero) THEN
3159 0 : CALL dcopy(n, xp, 1, x, 1)
3160 0 : IF (iprint > 0) WRITE (wunit, 4002)
3161 0 : IF (iprint > 0) WRITE (wunit, 4003)
3162 0 : alpha = one
3163 0 : temp1 = alpha
3164 0 : ibd = 0
3165 0 : DO i = 1, nsub
3166 0 : k = ind(i)
3167 0 : dk = d(i)
3168 0 : IF (nbd(k) /= 0) THEN
3169 0 : IF (dk < zero .AND. nbd(k) <= 2) THEN
3170 0 : temp2 = lower_bound(k) - x(k)
3171 0 : IF (temp2 >= zero) THEN
3172 : temp1 = zero
3173 0 : ELSE IF (dk*alpha < temp2) THEN
3174 0 : temp1 = temp2/dk
3175 : END IF
3176 0 : ELSE IF (dk > zero .AND. nbd(k) >= 2) THEN
3177 0 : temp2 = upper_bound(k) - x(k)
3178 0 : IF (temp2 <= zero) THEN
3179 : temp1 = zero
3180 0 : ELSE IF (dk*alpha > temp2) THEN
3181 0 : temp1 = temp2/dk
3182 : END IF
3183 : END IF
3184 0 : IF (temp1 < alpha) THEN
3185 0 : alpha = temp1
3186 0 : ibd = i
3187 : END IF
3188 : END IF
3189 : END DO
3190 :
3191 0 : IF (alpha < one) THEN
3192 0 : dk = d(ibd)
3193 0 : k = ind(ibd)
3194 0 : IF (dk > zero) THEN
3195 0 : x(k) = upper_bound(k)
3196 0 : d(ibd) = zero
3197 0 : ELSE IF (dk < zero) THEN
3198 0 : x(k) = lower_bound(k)
3199 0 : d(ibd) = zero
3200 : END IF
3201 : END IF
3202 0 : DO i = 1, nsub
3203 0 : k = ind(i)
3204 0 : x(k) = x(k) + alpha*d(i)
3205 : END DO
3206 : END IF
3207 : END IF
3208 :
3209 1436 : IF (iprint >= 99) WRITE (wunit, 4004)
3210 :
3211 : 4001 FORMAT(/, ' L-BFGS| ---------------- enter SUBSM ----------------',/)
3212 : 4002 FORMAT(' L-BFGS| Positive dir derivative in projection ')
3213 : 4003 FORMAT(' L-BFGS| Using the backtracking step ')
3214 : 4004 FORMAT(/, ' L-BFGS| ---------------- exit SUBSM -----------------',/)
3215 :
3216 : RETURN
3217 :
3218 : END SUBROUTINE subsm
3219 :
3220 : ! **************************************************************************************************
3221 : !> \brief This subroutine finds a step that satisfies a sufficient
3222 : !> decrease condition and a curvature condition.
3223 : !>
3224 : !> Each call of the subroutine updates an interval with
3225 : !> endpoints stx and sty. The interval is initially chosen
3226 : !> so that it contains a minimizer of the modified function
3227 : !>
3228 : !> psi(stp) = f(stp) - f(0) - ftol*stp*f'(0).
3229 : !>
3230 : !> If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the
3231 : !> interval is chosen so that it contains a minimizer of f.
3232 : !>
3233 : !> The algorithm is designed to find a step that satisfies
3234 : !> the sufficient decrease condition
3235 : !>
3236 : !> f(stp) <= f(0) + ftol*stp*f'(0),
3237 : !>
3238 : !> and the curvature condition
3239 : !>
3240 : !> abs(f'(stp)) <= gtol*abs(f'(0)).
3241 : !>
3242 : !> If ftol is less than gtol and if, for example, the function
3243 : !> is bounded below, then there is always a step which satisfies
3244 : !> both conditions.
3245 : !>
3246 : !> If no step can be found that satisfies both conditions, then
3247 : !> the algorithm stops with a warning. In this case stp only
3248 : !> satisfies the sufficient decrease condition.
3249 : !>
3250 : !> A typical invocation of dcsrch has the following outline:
3251 : !>
3252 : !> task = 'START'
3253 : !> DO WHILE (.TRUE.)
3254 : !> call dcsrch( ... )
3255 : !> if (task .eq. 'FG') then
3256 : !> Evaluate the function and the gradient at stp
3257 : !> else
3258 : !> exit
3259 : !> end if
3260 : !> END DO
3261 : !> \param f On initial entry f is the value of the function at 0.
3262 : !> On subsequent entries f is the value of the
3263 : !> function at stp.
3264 : !> On exit f is the value of the function at stp.
3265 : !> \param g On initial entry g is the derivative of the function at 0.
3266 : !> On subsequent entries g is the derivative of the
3267 : !> function at stp.
3268 : !> On exit g is the derivative of the function at stp.
3269 : !> \param stp On entry stp is the current estimate of a satisfactory
3270 : !> step. On initial entry, a positive initial estimate
3271 : !> must be provided.
3272 : !> On exit stp is the current estimate of a satisfactory step
3273 : !> if task = 'FG'. If task = 'CONV' then stp satisfies
3274 : !> the sufficient decrease and curvature condition.
3275 : !> \param ftol ftol specifies a nonnegative tolerance for the
3276 : !> sufficient decrease condition.
3277 : !> \param gtol gtol specifies a nonnegative tolerance for the
3278 : !> curvature condition.
3279 : !> \param xtol xtol specifies a nonnegative relative tolerance
3280 : !> for an acceptable step. The subroutine exits with a
3281 : !> warning if the relative difference between sty and stx
3282 : !> is less than xtol.
3283 : !> \param stpmin stpmin is a nonnegative lower bound for the step.
3284 : !> \param stpmax stpmax is a nonnegative upper bound for the step.
3285 : !> \param task task is a character variable of length at least 60.
3286 : !> On initial entry task must be set to 'START'.
3287 : !> On exit task indicates the required action:
3288 : !>
3289 : !> If task(1:2) = 'FG' then evaluate the function and
3290 : !> derivative at stp and call dcsrch again.
3291 : !>
3292 : !> If task(1:4) = 'CONV' then the search is successful.
3293 : !>
3294 : !> If task(1:4) = 'WARN' then the subroutine is not able
3295 : !> to satisfy the convergence conditions. The exit value of
3296 : !> stp contains the best point found during the search.
3297 : !>
3298 : !> If task(1:5) = 'ERROR' then there is an error in the
3299 : !> input arguments.
3300 : !>
3301 : !> On exit with convergence, a warning or an error, the
3302 : !> variable task contains additional information.
3303 : !> \param isave is work array
3304 : !> \param dsave is a work array
3305 : ! **************************************************************************************************
3306 3135 : SUBROUTINE dcsrch(f, g, stp, ftol, gtol, xtol, stpmin, stpmax, &
3307 : task, isave, dsave)
3308 : REAL(KIND=dp) :: f, g
3309 : REAL(KIND=dp), INTENT(inout) :: stp
3310 : REAL(KIND=dp) :: ftol, gtol, xtol, stpmin, stpmax
3311 : CHARACTER(LEN=*) :: task
3312 : INTEGER :: isave(2)
3313 : REAL(KIND=dp) :: dsave(13)
3314 :
3315 : REAL(KIND=dp), PARAMETER :: p5 = 0.5_dp, p66 = 0.66_dp, &
3316 : xtrapl = 1.1_dp, xtrapu = 4.0_dp, &
3317 : zero = 0.0_dp
3318 :
3319 : INTEGER :: stage
3320 : LOGICAL :: brackt
3321 : REAL(KIND=dp) :: finit, fm, ftest, fx, fxm, fy, fym, &
3322 : ginit, gm, gtest, gx, gxm, gy, gym, &
3323 : stmax, stmin, stx, sty, width, width1
3324 :
3325 : !
3326 : ! NOTE: The user must no alter work arrays between calls.
3327 : !
3328 : !
3329 : ! MINPACK-1 Project. June 1983.
3330 : ! Argonne National Laboratory.
3331 : ! Jorge J. More' and David J. Thuente.
3332 : !
3333 : ! MINPACK-2 Project. October 1993.
3334 : ! Argonne National Laboratory and University of Minnesota.
3335 : ! Brett M. Averick, Richard G. Carter, and Jorge J. More'.
3336 : !
3337 : ! **********
3338 : ! Initialization block.
3339 :
3340 3135 : IF (task(1:5) == 'START') THEN
3341 :
3342 : ! Check the input arguments for errors.
3343 :
3344 1484 : IF (stp < stpmin) task = 'ERROR: STP < STPMIN'
3345 1484 : IF (stp > stpmax) task = 'ERROR: STP > STPMAX'
3346 1484 : IF (g >= zero) task = 'ERROR: INITIAL G >= ZERO'
3347 1484 : IF (ftol < zero) task = 'ERROR: FTOL < ZERO'
3348 1484 : IF (gtol < zero) task = 'ERROR: GTOL < ZERO'
3349 1484 : IF (xtol < zero) task = 'ERROR: XTOL < ZERO'
3350 1484 : IF (stpmin < zero) task = 'ERROR: STPMIN < ZERO'
3351 1484 : IF (stpmax < stpmin) task = 'ERROR: STPMAX < STPMIN'
3352 :
3353 : ! Exit if there are errors on input.
3354 :
3355 1484 : IF (task(1:5) == 'ERROR') RETURN
3356 :
3357 : ! Initialize local variables.
3358 :
3359 1484 : brackt = .FALSE.
3360 1484 : stage = 1
3361 1484 : finit = f
3362 1484 : ginit = g
3363 1484 : gtest = ftol*ginit
3364 1484 : width = stpmax - stpmin
3365 1484 : width1 = width/p5
3366 :
3367 : ! The variables stx, fx, gx contain the values of the step,
3368 : ! function, and derivative at the best step.
3369 : ! The variables sty, fy, gy contain the value of the step,
3370 : ! function, and derivative at sty.
3371 : ! The variables stp, f, g contain the values of the step,
3372 : ! function, and derivative at stp.
3373 :
3374 1484 : stx = zero
3375 1484 : fx = finit
3376 1484 : gx = ginit
3377 1484 : sty = zero
3378 1484 : fy = finit
3379 1484 : gy = ginit
3380 1484 : stmin = zero
3381 1484 : stmax = stp + xtrapu*stp
3382 1484 : task = 'FG'
3383 :
3384 : ELSE
3385 :
3386 : ! Restore local variables.
3387 :
3388 1651 : IF (isave(1) == 1) THEN
3389 154 : brackt = .TRUE.
3390 : ELSE
3391 1497 : brackt = .FALSE.
3392 : END IF
3393 1651 : stage = isave(2)
3394 1651 : ginit = dsave(1)
3395 1651 : gtest = dsave(2)
3396 1651 : gx = dsave(3)
3397 1651 : gy = dsave(4)
3398 1651 : finit = dsave(5)
3399 1651 : fx = dsave(6)
3400 1651 : fy = dsave(7)
3401 1651 : stx = dsave(8)
3402 1651 : sty = dsave(9)
3403 1651 : stmin = dsave(10)
3404 1651 : stmax = dsave(11)
3405 1651 : width = dsave(12)
3406 1651 : width1 = dsave(13)
3407 :
3408 : ! If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the
3409 : ! algorithm enters the second stage.
3410 :
3411 1651 : ftest = finit + stp*gtest
3412 1651 : IF (stage == 1 .AND. f <= ftest .AND. g >= zero) &
3413 329 : stage = 2
3414 :
3415 : ! Test for warnings.
3416 :
3417 1651 : IF (brackt .AND. (stp <= stmin .OR. stp >= stmax)) &
3418 3 : task = 'WARNING: ROUNDING ERRORS PREVENT PROGRESS'
3419 1651 : IF (brackt .AND. stmax - stmin <= xtol*stmax) &
3420 2 : task = 'WARNING: XTOL TEST SATISFIED'
3421 1651 : IF (stp == stpmax .AND. f <= ftest .AND. g <= gtest) &
3422 11 : task = 'WARNING: STP = STPMAX'
3423 1651 : IF (stp == stpmin .AND. (f > ftest .OR. g >= gtest)) &
3424 1 : task = 'WARNING: STP = STPMIN'
3425 :
3426 : ! Test for convergence.
3427 :
3428 1651 : IF (f <= ftest .AND. ABS(g) <= gtol*(-ginit)) &
3429 1476 : task = 'CONVERGENCE'
3430 :
3431 : ! Test for termination.
3432 :
3433 1651 : IF (.NOT. (task(1:4) == 'WARN' .OR. task(1:4) == 'CONV')) THEN
3434 :
3435 : ! A modified function is used to predict the step during the
3436 : ! first stage if a lower function value has been obtained but
3437 : ! the decrease is not sufficient.
3438 :
3439 167 : IF (stage == 1 .AND. f <= fx .AND. f > ftest) THEN
3440 :
3441 : ! Define the modified function and derivative values.
3442 :
3443 0 : fm = f - stp*gtest
3444 0 : fxm = fx - stx*gtest
3445 0 : fym = fy - sty*gtest
3446 0 : gm = g - gtest
3447 0 : gxm = gx - gtest
3448 0 : gym = gy - gtest
3449 :
3450 : ! Call dcstep to update stx, sty, and to compute the new step.
3451 :
3452 : CALL dcstep(stx, fxm, gxm, sty, fym, gym, stp, fm, gm, &
3453 0 : brackt, stmin, stmax)
3454 :
3455 : ! Reset the function and derivative values for f.
3456 :
3457 0 : fx = fxm + stx*gtest
3458 0 : fy = fym + sty*gtest
3459 0 : gx = gxm + gtest
3460 0 : gy = gym + gtest
3461 :
3462 : ELSE
3463 :
3464 : ! Call dcstep to update stx, sty, and to compute the new step.
3465 :
3466 : CALL dcstep(stx, fx, gx, sty, fy, gy, stp, f, g, &
3467 167 : brackt, stmin, stmax)
3468 :
3469 : END IF
3470 :
3471 : ! Decide if a bisection step is needed.
3472 :
3473 167 : IF (brackt) THEN
3474 154 : IF (ABS(sty - stx) >= p66*width1) stp = stx + p5*(sty - stx)
3475 154 : width1 = width
3476 154 : width = ABS(sty - stx)
3477 : END IF
3478 :
3479 : ! Set the minimum and maximum steps allowed for stp.
3480 :
3481 167 : IF (brackt) THEN
3482 154 : stmin = MIN(stx, sty)
3483 154 : stmax = MAX(stx, sty)
3484 : ELSE
3485 13 : stmin = stp + xtrapl*(stp - stx)
3486 13 : stmax = stp + xtrapu*(stp - stx)
3487 : END IF
3488 :
3489 : ! Force the step to be within the bounds stpmax and stpmin.
3490 :
3491 167 : stp = MAX(stp, stpmin)
3492 167 : stp = MIN(stp, stpmax)
3493 :
3494 : ! If further progress is not possible, let stp be the best
3495 : ! point obtained during the search.
3496 :
3497 : IF (brackt .AND. (stp <= stmin .OR. stp >= stmax) &
3498 167 : .OR. (brackt .AND. stmax - stmin <= xtol*stmax)) stp = stx
3499 :
3500 : ! Obtain another function and derivative.
3501 :
3502 167 : task = 'FG'
3503 :
3504 : END IF
3505 : END IF
3506 :
3507 : ! Save local variables.
3508 :
3509 3135 : IF (brackt) THEN
3510 273 : isave(1) = 1
3511 : ELSE
3512 2862 : isave(1) = 0
3513 : END IF
3514 3135 : isave(2) = stage
3515 3135 : dsave(1) = ginit
3516 3135 : dsave(2) = gtest
3517 3135 : dsave(3) = gx
3518 3135 : dsave(4) = gy
3519 3135 : dsave(5) = finit
3520 3135 : dsave(6) = fx
3521 3135 : dsave(7) = fy
3522 3135 : dsave(8) = stx
3523 3135 : dsave(9) = sty
3524 3135 : dsave(10) = stmin
3525 3135 : dsave(11) = stmax
3526 3135 : dsave(12) = width
3527 3135 : dsave(13) = width1
3528 :
3529 3135 : RETURN
3530 3135 : END SUBROUTINE dcsrch
3531 :
3532 : ! **************************************************************************************************
3533 : !> \brief This subroutine computes a safeguarded step for a search
3534 : !> procedure and updates an interval that contains a step that
3535 : !> satisfies a sufficient decrease and a curvature condition.
3536 : !>
3537 : !> The parameter stx contains the step with the least function
3538 : !> value. If brackt is set to .true. then a minimizer has
3539 : !> been bracketed in an interval with endpoints stx and sty.
3540 : !> The parameter stp contains the current step.
3541 : !> The subroutine assumes that if brackt is set to .true. then
3542 : !>
3543 : !> min(stx,sty) < stp < max(stx,sty),
3544 : !>
3545 : !> and that the derivative at stx is negative in the direction
3546 : !> of the step.
3547 : !> \param stx On entry stx is the best step obtained so far and is an
3548 : !> endpoint of the interval that contains the minimizer.
3549 : !> On exit stx is the updated best step.
3550 : !> \param fx fx is the function at stx.
3551 : !> \param dx On entry dx is the derivative of the function at
3552 : !> stx. The derivative must be negative in the direction of
3553 : !> the step, that is, dx and stp - stx must have opposite
3554 : !> signs.
3555 : !> On exit dx is the derivative of the function at stx.
3556 : !> \param sty On entry sty is the second endpoint of the interval that
3557 : !> contains the minimizer.
3558 : !> On exit sty is the updated endpoint of the interval that
3559 : !> contains the minimizer.
3560 : !> \param fy fy is the function at sty.
3561 : !> \param dy On entry dy is the derivative of the function at sty.
3562 : !> On exit dy is the derivative of the function at the exit sty.
3563 : !> \param stp On entry stp is the current step. If brackt is set to .true.
3564 : !> then on input stp must be between stx and sty.
3565 : !> On exit stp is a new trial step.
3566 : !> \param fp fp is the function at stp
3567 : !> \param dp_loc dp_loc is the the derivative of the function at stp.
3568 : !> \param brackt On entry brackt specifies if a minimizer has been bracketed.
3569 : !> Initially brackt must be set to .false.
3570 : !> On exit brackt specifies if a minimizer has been bracketed.
3571 : !> When a minimizer is bracketed brackt is set to .true.
3572 : !> \param stpmin stpmin is a lower bound for the step.
3573 : !> \param stpmax stpmax is an upper bound for the step.
3574 : ! **************************************************************************************************
3575 167 : SUBROUTINE dcstep(stx, fx, dx, sty, fy, dy, stp, fp, dp_loc, brackt, &
3576 : stpmin, stpmax)
3577 : REAL(KIND=dp), INTENT(inout) :: stx, fx, dx, sty, fy, dy, stp
3578 : REAL(KIND=dp), INTENT(in) :: fp, dp_loc
3579 : LOGICAL, INTENT(inout) :: brackt
3580 : REAL(KIND=dp), INTENT(in) :: stpmin, stpmax
3581 :
3582 : REAL(KIND=dp), PARAMETER :: p66 = 0.66_dp, three = 3.0_dp, &
3583 : two = 2.0_dp, zero = 0.0_dp
3584 :
3585 : REAL(KIND=dp) :: gamma, p, q, r, s, sgnd, stpc, stpf, &
3586 : stpq, theta
3587 :
3588 : !
3589 : ! MINPACK-1 Project. June 1983
3590 : ! Argonne National Laboratory.
3591 : ! Jorge J. More' and David J. Thuente.
3592 : !
3593 : ! MINPACK-2 Project. October 1993.
3594 : ! Argonne National Laboratory and University of Minnesota.
3595 : ! Brett M. Averick and Jorge J. More'.
3596 : !
3597 : ! **********
3598 :
3599 167 : sgnd = dp_loc*SIGN(1.0_dp, dx)
3600 :
3601 : ! First case: A higher function value. The minimum is bracketed.
3602 : ! If the cubic step is closer to stx than the quadratic step, the
3603 : ! cubic step is taken, otherwise the average of the cubic and
3604 : ! quadratic steps is taken.
3605 :
3606 167 : IF (fp > fx) THEN
3607 123 : theta = three*(fx - fp)/(stp - stx) + dx + dp_loc
3608 123 : s = MAX(ABS(theta), ABS(dx), ABS(dp_loc))
3609 123 : gamma = s*SQRT((theta/s)**2 - (dx/s)*(dp_loc/s))
3610 123 : IF (stp < stx) gamma = -gamma
3611 123 : p = (gamma - dx) + theta
3612 123 : q = ((gamma - dx) + gamma) + dp_loc
3613 123 : r = p/q
3614 123 : stpc = stx + r*(stp - stx)
3615 : stpq = stx + ((dx/((fx - fp)/(stp - stx) + dx))/two)* &
3616 123 : & (stp - stx)
3617 123 : IF (ABS(stpc - stx) < ABS(stpq - stx)) THEN
3618 : stpf = stpc
3619 : ELSE
3620 55 : stpf = stpc + (stpq - stpc)/two
3621 : END IF
3622 123 : brackt = .TRUE.
3623 :
3624 : ! Second case: A lower function value and derivatives of opposite
3625 : ! sign. The minimum is bracketed. If the cubic step is farther from
3626 : ! stp than the secant step, the cubic step is taken, otherwise the
3627 : ! secant step is taken.
3628 :
3629 44 : ELSE IF (sgnd < zero) THEN
3630 15 : theta = three*(fx - fp)/(stp - stx) + dx + dp_loc
3631 15 : s = MAX(ABS(theta), ABS(dx), ABS(dp_loc))
3632 15 : gamma = s*SQRT((theta/s)**2 - (dx/s)*(dp_loc/s))
3633 15 : IF (stp > stx) gamma = -gamma
3634 15 : p = (gamma - dp_loc) + theta
3635 15 : q = ((gamma - dp_loc) + gamma) + dx
3636 15 : r = p/q
3637 15 : stpc = stp + r*(stx - stp)
3638 15 : stpq = stp + (dp_loc/(dp_loc - dx))*(stx - stp)
3639 15 : IF (ABS(stpc - stp) > ABS(stpq - stp)) THEN
3640 : stpf = stpc
3641 : ELSE
3642 13 : stpf = stpq
3643 : END IF
3644 15 : brackt = .TRUE.
3645 :
3646 : ! Third case: A lower function value, derivatives of the same sign,
3647 : ! and the magnitude of the derivative decreases.
3648 :
3649 29 : ELSE IF (ABS(dp_loc) < ABS(dx)) THEN
3650 :
3651 : ! The cubic step is computed only if the cubic tends to infinity
3652 : ! in the direction of the step or if the minimum of the cubic
3653 : ! is beyond stp. Otherwise the cubic step is defined to be the
3654 : ! secant step.
3655 :
3656 8 : theta = three*(fx - fp)/(stp - stx) + dx + dp_loc
3657 8 : s = MAX(ABS(theta), ABS(dx), ABS(dp_loc))
3658 :
3659 : ! The case gamma = 0 only arises if the cubic does not tend
3660 : ! to infinity in the direction of the step.
3661 :
3662 8 : gamma = s*SQRT(MAX(zero, (theta/s)**2 - (dx/s)*(dp_loc/s)))
3663 8 : IF (stp > stx) gamma = -gamma
3664 8 : p = (gamma - dp_loc) + theta
3665 8 : q = (gamma + (dx - dp_loc)) + gamma
3666 8 : r = p/q
3667 8 : IF (r < zero .AND. gamma /= zero) THEN
3668 8 : stpc = stp + r*(stx - stp)
3669 0 : ELSE IF (stp > stx) THEN
3670 0 : stpc = stpmax
3671 : ELSE
3672 0 : stpc = stpmin
3673 : END IF
3674 8 : stpq = stp + (dp_loc/(dp_loc - dx))*(stx - stp)
3675 :
3676 8 : IF (brackt) THEN
3677 :
3678 : ! A minimizer has been bracketed. If the cubic step is
3679 : ! closer to stp than the secant step, the cubic step is
3680 : ! taken, otherwise the secant step is taken.
3681 :
3682 4 : IF (ABS(stpc - stp) < ABS(stpq - stp)) THEN
3683 : stpf = stpc
3684 : ELSE
3685 0 : stpf = stpq
3686 : END IF
3687 4 : IF (stp > stx) THEN
3688 4 : stpf = MIN(stp + p66*(sty - stp), stpf)
3689 : ELSE
3690 0 : stpf = MAX(stp + p66*(sty - stp), stpf)
3691 : END IF
3692 : ELSE
3693 :
3694 : ! A minimizer has not been bracketed. If the cubic step is
3695 : ! farther from stp than the secant step, the cubic step is
3696 : ! taken, otherwise the secant step is taken.
3697 :
3698 4 : IF (ABS(stpc - stp) > ABS(stpq - stp)) THEN
3699 : stpf = stpc
3700 : ELSE
3701 3 : stpf = stpq
3702 : END IF
3703 4 : stpf = MIN(stpmax, stpf)
3704 4 : stpf = MAX(stpmin, stpf)
3705 : END IF
3706 :
3707 : ! Fourth case: A lower function value, derivatives of the same sign,
3708 : ! and the magnitude of the derivative does not decrease. If the
3709 : ! minimum is not bracketed, the step is either stpmin or stpmax,
3710 : ! otherwise the cubic step is taken.
3711 :
3712 : ELSE
3713 21 : IF (brackt) THEN
3714 12 : theta = three*(fp - fy)/(sty - stp) + dy + dp_loc
3715 12 : s = MAX(ABS(theta), ABS(dy), ABS(dp_loc))
3716 12 : gamma = s*SQRT((theta/s)**2 - (dy/s)*(dp_loc/s))
3717 12 : IF (stp > sty) gamma = -gamma
3718 12 : p = (gamma - dp_loc) + theta
3719 12 : q = ((gamma - dp_loc) + gamma) + dy
3720 12 : r = p/q
3721 12 : stpc = stp + r*(sty - stp)
3722 12 : stpf = stpc
3723 9 : ELSE IF (stp > stx) THEN
3724 9 : stpf = stpmax
3725 : ELSE
3726 0 : stpf = stpmin
3727 : END IF
3728 : END IF
3729 :
3730 : ! Update the interval which contains a minimizer.
3731 :
3732 167 : IF (fp > fx) THEN
3733 123 : sty = stp
3734 123 : fy = fp
3735 123 : dy = dp_loc
3736 : ELSE
3737 44 : IF (sgnd < zero) THEN
3738 15 : sty = stx
3739 15 : fy = fx
3740 15 : dy = dx
3741 : END IF
3742 44 : stx = stp
3743 44 : fx = fp
3744 44 : dx = dp_loc
3745 : END IF
3746 :
3747 : ! Compute the new step.
3748 :
3749 167 : stp = stpf
3750 :
3751 167 : RETURN
3752 : END SUBROUTINE dcstep
3753 :
3754 : !MK LINPACK
3755 :
3756 : ! **************************************************************************************************
3757 : !> \brief factors a double precision symmetric positive definite
3758 : !> matrix.
3759 : !>
3760 : !> dpofa is usually called by dpoco, but it can be called
3761 : !> directly with a saving in time if rcond is not needed.
3762 : !> (time for dpoco) = (1 + 18/n)*(time for dpofa) .
3763 : !> \param a the symmetric matrix to be factored. only the
3764 : !> diagonal and upper triangle are used.
3765 : !> on return
3766 : !> an upper triangular matrix r so that a = trans(r)*r
3767 : !> where trans(r) is the transpose.
3768 : !> the strict lower triangle is unaltered.
3769 : !> if info .ne. 0 , the factorization is not complete.
3770 : !> \param lda the leading dimension of the array a .
3771 : !> \param n the order of the matrix a .
3772 : !> \param info = 0 for normal return.
3773 : !> = k signals an error condition. the leading minor
3774 : !> of order k is not positive definite.
3775 : ! **************************************************************************************************
3776 4308 : SUBROUTINE dpofa(a, lda, n, info)
3777 : INTEGER, INTENT(in) :: lda
3778 : REAL(KIND=dp) :: a(lda, *)
3779 : INTEGER, INTENT(in) :: n
3780 : INTEGER :: info
3781 :
3782 : INTEGER :: j, jm1, k
3783 : REAL(KIND=dp) :: ddot, s, t
3784 :
3785 : !
3786 : ! linpack. this version dated 08/14/78 .
3787 : ! cleve moler, university of new mexico, argonne national lab.
3788 : !
3789 : ! begin block with ...exits to 40
3790 : !
3791 : !
3792 :
3793 25968 : DO j = 1, n
3794 21660 : info = j
3795 21660 : s = 0.0_dp
3796 21660 : jm1 = j - 1
3797 21660 : IF (.NOT. (jm1 < 1)) THEN
3798 68421 : DO k = 1, jm1
3799 51069 : t = a(k, j) - ddot(k - 1, a(1, k), 1, a(1, j), 1)
3800 51069 : t = t/a(k, k)
3801 51069 : a(k, j) = t
3802 68421 : s = s + t*t
3803 : END DO
3804 : END IF
3805 21660 : s = a(j, j) - s
3806 : ! ......exit
3807 21660 : IF (s <= 0.0_dp) EXIT
3808 21660 : a(j, j) = SQRT(s)
3809 25968 : info = 0
3810 : END DO
3811 4308 : RETURN
3812 : END SUBROUTINE dpofa
3813 :
3814 : ! **************************************************************************************************
3815 : !> \brief dtrsl solves systems of the form
3816 : !>
3817 : !> t * x = b
3818 : !> or
3819 : !> trans(t) * x = b
3820 : !>
3821 : !> where t is a triangular matrix of order n. here trans(t)
3822 : !> denotes the transpose of the matrix t.
3823 : !> \param t t contains the matrix of the system. the zero
3824 : !> elements of the matrix are not referenced, and
3825 : !> the corresponding elements of the array can be
3826 : !> used to store other information.
3827 : !> \param ldt ldt is the leading dimension of the array t.
3828 : !> \param n n is the order of the system.
3829 : !> \param b contains the right hand side of the system.
3830 : !> on return
3831 : !> b contains the solution, if info .eq. 0.
3832 : !> otherwise b is unaltered.
3833 : !> \param job job specifies what kind of system is to be solved.
3834 : !> if job is
3835 : !> 00 solve t*x=b, t lower triangular,
3836 : !> 01 solve t*x=b, t upper triangular,
3837 : !> 10 solve trans(t)*x=b, t lower triangular,
3838 : !> 11 solve trans(t)*x=b, t upper triangular.
3839 : !> \param info on return
3840 : !> info contains zero if the system is nonsingular.
3841 : !> otherwise info contains the index of
3842 : !> the first zero diagonal element of t.
3843 : ! **************************************************************************************************
3844 10160 : SUBROUTINE dtrsl(t, ldt, n, b, job, info)
3845 : INTEGER, INTENT(in) :: ldt
3846 : REAL(KIND=dp), INTENT(in) :: t(ldt, *)
3847 : INTEGER, INTENT(in) :: n
3848 : REAL(KIND=dp), INTENT(inout) :: b(*)
3849 : INTEGER, INTENT(in) :: job
3850 : INTEGER, INTENT(out) :: info
3851 :
3852 : INTEGER :: CASE, j, jj
3853 : REAL(KIND=dp) :: ddot, temp
3854 :
3855 : ! linpack. this version dated 08/14/78 .
3856 : ! g. w. stewart, university of maryland, argonne national lab.
3857 : !
3858 : ! begin block permitting ...exits to 150
3859 : !
3860 : ! check for zero diagonal elements.
3861 : !
3862 :
3863 80482 : DO info = 1, n
3864 : ! ......exit
3865 80482 : IF (t(info, info) == 0.0_dp) RETURN
3866 : END DO
3867 10160 : info = 0
3868 : !
3869 : ! determine the task and go to it.
3870 : !
3871 10160 : CASE = 1
3872 10160 : IF (MOD(job, 10) /= 0) CASE = 2
3873 10160 : IF (MOD(job, 100)/10 /= 0) CASE = CASE + 2
3874 :
3875 0 : SELECT CASE (CASE)
3876 : CASE (1)
3877 : !
3878 : ! solve t*x=b for t lower triangular
3879 : !
3880 0 : b(1) = b(1)/t(1, 1)
3881 0 : IF (n > 1) THEN
3882 0 : DO j = 2, n
3883 0 : temp = -b(j - 1)
3884 0 : CALL daxpy(n - j + 1, temp, t(j, j - 1), 1, b(j), 1)
3885 0 : b(j) = b(j)/t(j, j)
3886 : END DO
3887 : END IF
3888 : CASE (2)
3889 : !
3890 : ! solve t*x=b for t upper triangular.
3891 : !
3892 1470 : b(n) = b(n)/t(n, n)
3893 1470 : IF (n > 1) THEN
3894 14518 : DO jj = 2, n
3895 13058 : j = n - jj + 1
3896 13058 : temp = -b(j + 1)
3897 13058 : CALL daxpy(j, temp, t(1, j + 1), 1, b(1), 1)
3898 14518 : b(j) = b(j)/t(j, j)
3899 : END DO
3900 : END IF
3901 : CASE (3)
3902 : !
3903 : ! solve trans(t)*x=b for t lower triangular.
3904 : !
3905 0 : b(n) = b(n)/t(n, n)
3906 0 : IF (n > 1) THEN
3907 0 : DO jj = 2, n
3908 0 : j = n - jj + 1
3909 0 : b(j) = b(j) - ddot(jj - 1, t(j + 1, j), 1, b(j + 1), 1)
3910 0 : b(j) = b(j)/t(j, j)
3911 : END DO
3912 : END IF
3913 : CASE (4)
3914 : !
3915 : ! solve trans(t)*x=b for t upper triangular.
3916 : !
3917 8690 : b(1) = b(1)/t(1, 1)
3918 8690 : IF (.NOT. (n < 2)) THEN
3919 55741 : DO j = 2, n
3920 47104 : b(j) = b(j) - ddot(j - 1, t(1, j), 1, b(1), 1)
3921 55741 : b(j) = b(j)/t(j, j)
3922 : END DO
3923 : END IF
3924 : CASE DEFAULT
3925 10160 : CPABORT("unexpected case")
3926 : END SELECT
3927 :
3928 : RETURN
3929 : END SUBROUTINE dtrsl
3930 :
3931 : !MK Timer
3932 :
3933 : ! **************************************************************************************************
3934 : !> \brief This routine computes cpu time in double precision; it makes use o
3935 : !> the intrinsic f90 cpu_time therefore a conversion type is
3936 : !> needed.
3937 : !> \param ttime ...
3938 : ! **************************************************************************************************
3939 6008 : SUBROUTINE timer(ttime)
3940 : REAL(KIND=dp) :: ttime
3941 :
3942 : !
3943 : ! REAL temp
3944 : !
3945 : ! J.L Morales Departamento de Matematicas,
3946 : ! Instituto Tecnologico Autonomo de Mexico
3947 : ! Mexico D.F.
3948 : !
3949 : ! J.L Nocedal Department of Electrical Engineering and
3950 : ! Computer Science.
3951 : ! Northwestern University. Evanston, IL. USA
3952 : !
3953 : ! January 21, 2011
3954 : !
3955 : !MK temp = sngl(ttime)
3956 : !MK CALL cpu_time(temp)
3957 : !MK ttime = REAL(temp, KIND=dp)
3958 :
3959 6008 : ttime = m_walltime()
3960 :
3961 6008 : END SUBROUTINE timer
3962 :
3963 : ! **************************************************************************************************
3964 : !> \brief Saves the lcoal variables, long term this should be replaces by a lbfgs type
3965 : !> \param lsave lsave is a working array
3966 : !> On exit with 'task' = NEW_X, the following information is available:
3967 : !> If lsave(1) = .true. then the initial X has been replaced by
3968 : !> its projection in the feasible set
3969 : !> If lsave(2) = .true. then the problem is constrained;
3970 : !> If lsave(3) = .true. then each variable has upper and lower bounds;
3971 : !> \param isave isave is a working array
3972 : !> On exit with 'task' = NEW_X, the following information is available:
3973 : !> isave(22) = the total number of intervals explored in the
3974 : !> search of Cauchy points;
3975 : !> isave(26) = the total number of skipped BFGS updates before the current iteration;
3976 : !> isave(30) = the number of current iteration;
3977 : !> isave(31) = the total number of BFGS updates prior the current iteration;
3978 : !> isave(33) = the number of intervals explored in the search of
3979 : !> Cauchy point in the current iteration;
3980 : !> isave(34) = the total number of function and gradient evaluations;
3981 : !> isave(36) = the number of function value or gradient
3982 : !> evaluations in the current iteration;
3983 : !> if isave(37) = 0 then the subspace argmin is within the box;
3984 : !> if isave(37) = 1 then the subspace argmin is beyond the box;
3985 : !> isave(38) = the number of free variables in the current iteration;
3986 : !> isave(39) = the number of active constraints in the current iteration;
3987 : !> n + 1 - isave(40) = the number of variables leaving the set of
3988 : !> active constraints in the current iteration;
3989 : !> isave(41) = the number of variables entering the set of active
3990 : !> constraints in the current iteration.
3991 : !> \param dsave dsave is a working array of dimension 29.
3992 : !> On exit with 'task' = NEW_X, the following information is available:
3993 : !> dsave(1) = current 'theta' in the BFGS matrix;
3994 : !> dsave(2) = f(x) in the previous iteration;
3995 : !> dsave(3) = factr*epsmch;
3996 : !> dsave(4) = 2-norm of the line search direction vector;
3997 : !> dsave(5) = the machine precision epsmch generated by the code;
3998 : !> dsave(7) = the accumulated time spent on searching for Cauchy points;
3999 : !> dsave(8) = the accumulated time spent on subspace minimization;
4000 : !> dsave(9) = the accumulated time spent on line search;
4001 : !> dsave(11) = the slope of the line search function at the current point of line search;
4002 : !> dsave(12) = the maximum relative step length imposed in line search;
4003 : !> dsave(13) = the infinity norm of the projected gradient;
4004 : !> dsave(14) = the relative step length in the line search;
4005 : !> dsave(15) = the slope of the line search function at the starting point of the line search;
4006 : !> dsave(16) = the square of the 2-norm of the line search direction vector.
4007 : !> \param x_projected ...
4008 : !> \param constrained ...
4009 : !> \param boxed ...
4010 : !> \param updatd ...
4011 : !> \param nintol ...
4012 : !> \param itfile ...
4013 : !> \param iback ...
4014 : !> \param nskip ...
4015 : !> \param head ...
4016 : !> \param col ...
4017 : !> \param itail ...
4018 : !> \param iter ...
4019 : !> \param iupdat ...
4020 : !> \param nseg ...
4021 : !> \param nfgv ...
4022 : !> \param info ...
4023 : !> \param ifun ...
4024 : !> \param iword ...
4025 : !> \param nfree ...
4026 : !> \param nact ...
4027 : !> \param ileave ...
4028 : !> \param nenter ...
4029 : !> \param theta ...
4030 : !> \param fold ...
4031 : !> \param tol ...
4032 : !> \param dnorm ...
4033 : !> \param epsmch ...
4034 : !> \param cpu1 ...
4035 : !> \param cachyt ...
4036 : !> \param sbtime ...
4037 : !> \param lnscht ...
4038 : !> \param time1 ...
4039 : !> \param gd ...
4040 : !> \param step_max ...
4041 : !> \param g_inf_norm ...
4042 : !> \param stp ...
4043 : !> \param gdold ...
4044 : !> \param dtd ...
4045 : !> \author Samuel Andermatt (01.15)
4046 : ! **************************************************************************************************
4047 :
4048 3181 : SUBROUTINE save_local(lsave,isave,dsave,x_projected,constrained,boxed,updatd,nintol,itfile,iback,nskip,head,col,itail,&
4049 : iter, iupdat, nseg, nfgv, info, ifun, iword, nfree, nact, ileave, nenter, theta, fold, tol, dnorm, epsmch, cpu1, &
4050 : cachyt, sbtime, lnscht, time1, gd, step_max, g_inf_norm, stp, gdold, dtd)
4051 : LOGICAL, INTENT(out) :: lsave(4)
4052 : INTEGER, INTENT(out) :: isave(23)
4053 : REAL(KIND=dp), INTENT(out) :: dsave(29)
4054 : LOGICAL, INTENT(in) :: x_projected, constrained, boxed, updatd
4055 : INTEGER, INTENT(in) :: nintol, itfile, iback, nskip, head, col, &
4056 : itail, iter, iupdat, nseg, nfgv, info, &
4057 : ifun, iword, nfree, nact, ileave, &
4058 : nenter
4059 : REAL(KIND=dp), INTENT(in) :: theta, fold, tol, dnorm, epsmch, cpu1, &
4060 : cachyt, sbtime, lnscht, time1, gd, &
4061 : step_max, g_inf_norm, stp, gdold, dtd
4062 :
4063 3181 : lsave(1) = x_projected
4064 3181 : lsave(2) = constrained
4065 3181 : lsave(3) = boxed
4066 3181 : lsave(4) = updatd
4067 :
4068 3181 : isave(1) = nintol
4069 3181 : isave(3) = itfile
4070 3181 : isave(4) = iback
4071 3181 : isave(5) = nskip
4072 3181 : isave(6) = head
4073 3181 : isave(7) = col
4074 3181 : isave(8) = itail
4075 3181 : isave(9) = iter
4076 3181 : isave(10) = iupdat
4077 3181 : isave(12) = nseg
4078 3181 : isave(13) = nfgv
4079 3181 : isave(14) = info
4080 3181 : isave(15) = ifun
4081 3181 : isave(16) = iword
4082 3181 : isave(17) = nfree
4083 3181 : isave(18) = nact
4084 3181 : isave(19) = ileave
4085 3181 : isave(20) = nenter
4086 :
4087 3181 : dsave(1) = theta
4088 3181 : dsave(2) = fold
4089 3181 : dsave(3) = tol
4090 3181 : dsave(4) = dnorm
4091 3181 : dsave(5) = epsmch
4092 3181 : dsave(6) = cpu1
4093 3181 : dsave(7) = cachyt
4094 3181 : dsave(8) = sbtime
4095 3181 : dsave(9) = lnscht
4096 3181 : dsave(10) = time1
4097 3181 : dsave(11) = gd
4098 3181 : dsave(12) = step_max
4099 3181 : dsave(13) = g_inf_norm
4100 3181 : dsave(14) = stp
4101 3181 : dsave(15) = gdold
4102 3181 : dsave(16) = dtd
4103 :
4104 3181 : END SUBROUTINE save_local
4105 :
4106 : END MODULE cp_lbfgs
|