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