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