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