L-BFGS-B  3.0
Large-scale Bound-constrained Optimization
lnsrlb.f
Go to the documentation of this file.
1 c> \file lnsrlb.f
2 
3 c> \brief This subroutine calls subroutine dcsrch from the Minpack2 library
4 c> to perform the line search. Subroutine dscrch is safeguarded so
5 c> that all trial points lie within the feasible region.
6 c>
7 c> @param n number of parameters
8 c> @param l lower bounds of parameters
9 c> @param u upper bounds of parameters
10 c> @param nbd On entry nbd represents the type of bounds imposed on the
11 c> variables, and must be specified as follows:
12 c> nbd(i)=<ul><li>0 if x(i) is unbounded,</li>
13 c> <li>1 if x(i) has only a lower bound,</li>
14 c> <li>2 if x(i) has both lower and upper bounds, and</li>
15 c> <li>3 if x(i) has only an upper bound.</li></ul>
16 c> On exit nbd is unchanged.
17 c> @param x position
18 c> @param f function value at x
19 c> @param fold Function value at the start of this line search (i.e. the
20 c> accepted value from the previous iteration). Saved at entry
21 c> so the caller can restore x, g, f if the line search fails.
22 c> @param gd Directional derivative g'd at the current trial step. Computed
23 c> on every entry and passed to dcsrch as its `g` argument.
24 c> @param gdold Directional derivative at stp=0 (i.e. the initial g'd before
25 c> any line-search progress this iteration). Saved on the first
26 c> call and used by mainlb to test the curvature condition
27 c> after the line search returns.
28 c> @param g Gradient of f at x.
29 c> @param d Search direction (z - x_current). Length-n vector; the candidate
30 c> step is t + stp*d.
31 c> @param r Workspace: copy of g at the start of this line search. Used
32 c> alongside fold to restore the previous iterate on abnormal
33 c> line-search termination (mainlb does the restore from r and t).
34 c> @param t Workspace: copy of x at the start of this line search.
35 c> @param z Pre-projected candidate (cauchy/subsm output). When stp=1
36 c> exactly, lnsrlb sets x := z directly; otherwise it computes
37 c> x := t + stp*d.
38 c> @param stp Current trial step length. On the first entry of a line
39 c> search lnsrlb initialises stp; subsequent dcsrch calls
40 c> update it.
41 c> @param dnorm 2-norm of d (||d||).
42 c> @param dtd Squared 2-norm of d (d'd).
43 c> @param xstep On exit stp * ||d||, the actual length of the step in x-space.
44 c> @param stpmx Maximum allowed step. For unconstrained problems set to a
45 c> large constant (1e10); for bounded problems lnsrlb scans
46 c> the active bounds and tightens stpmx so x + stpmx*d stays
47 c> feasible.
48 c> @param iter Outer iteration number from mainlb.
49 c> @param ifun On exit number of f/g evaluations performed in this line
50 c> search; reset to 0 on each new line search.
51 c> @param iback On exit number of "backtracks" (ifun - 1). mainlb aborts
52 c> the line search if iback >= 20.
53 c> @param nfgv Cumulative count of f/g evaluations across all iterations;
54 c> incremented by 1 per evaluation requested.
55 c> @param info On exit 0 on success; -4 if the projected directional
56 c> derivative gd is non-negative on the first call (no descent
57 c> possible).
58 c> @param task Reverse-comm task. Initial entry: 'START'. While the line
59 c> search is running, lnsrlb returns 'FG_LNSRCH' (the user
60 c> evaluates f, g at the new x and re-enters with task starting
61 c> with 'FG_LN'). On line-search success lnsrlb returns 'NEW_X'.
62 c> @param boxed .true. if every variable has both lower and upper bounds.
63 c> When true, the initial trial step is unit (stp=1) regardless
64 c> of d's magnitude.
65 c> @param cnstnd .true. if the problem has at least one bound. Controls the
66 c> stpmx-from-bounds scan.
67 c> @param csave working array
68 c> @param isave working array
69 c> @param dsave working array
70  subroutine lnsrlb(n, l, u, nbd, x, f, fold, gd, gdold, g, d, r, t,
71  + z, stp, dnorm, dtd, xstep, stpmx, iter, ifun,
72  + iback, nfgv, info, task, boxed, cnstnd, csave,
73  + isave, dsave)
74 
75  character*60 task, csave
76  logical boxed, cnstnd
77  integer n, iter, ifun, iback, nfgv, info,
78  + nbd(n), isave(2)
79  double precision f, fold, gd, gdold, stp, dnorm, dtd, xstep,
80  + stpmx, x(n), l(n), u(n), g(n), d(n), r(n), t(n),
81  + z(n), dsave(13)
82 c
83 c * * *
84 c
85 c NEOS, November 1994. (Latest revision June 1996.)
86 c Optimization Technology Center.
87 c Argonne National Laboratory and Northwestern University.
88 c Written by
89 c Ciyou Zhu
90 c in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
91 c
92 c
93 c **********
94 
95  integer i
96  double precision ddot,a1,a2
97  double precision one,zero,big
98  parameter(one=1.0d0,zero=0.0d0,big=1.0d+10)
99 c Wolfe-condition tolerances passed to dcsrch:
100 c ftol -- sufficient-decrease constant (alpha in eq (2.5) of the
101 c algorithm tech report; 1.0d-3 here, vs 1.0d-4 stated in
102 c that report). The looser value 1.0d-3 matches the
103 c implementation that ships with Algorithm 778; neither
104 c the ACM paper (docs/code.pdf) nor the 2011 remark
105 c documents the change explicitly.
106 c gtol -- curvature constant (beta in eq (2.6) of the tech report,
107 c 0.9 -- matches the paper).
108 c xtol -- relative-step tolerance for dcsrch's bracketing safeguard.
109  double precision ftol,gtol,xtol
110  parameter (ftol=1.0d-3,gtol=0.9d0,xtol=0.1d0)
111 
112  if (task(1:5) .eq. 'FG_LN') goto 556
113 
114  dtd = ddot(n,d,1,d,1)
115  dnorm = sqrt(dtd)
116 
117 c Determine the maximum step length.
118 
119  stpmx = big
120  if (cnstnd) then
121  if (iter .eq. 0) then
122  stpmx = one
123  else
124  do 43 i = 1, n
125  a1 = d(i)
126  if (nbd(i) .ne. 0) then
127  if (a1 .lt. zero .and. nbd(i) .le. 2) then
128  a2 = l(i) - x(i)
129  if (a2 .ge. zero) then
130  stpmx = zero
131  else if (a1*stpmx .lt. a2) then
132  stpmx = a2/a1
133  endif
134  else if (a1 .gt. zero .and. nbd(i) .ge. 2) then
135  a2 = u(i) - x(i)
136  if (a2 .le. zero) then
137  stpmx = zero
138  else if (a1*stpmx .gt. a2) then
139  stpmx = a2/a1
140  endif
141  endif
142  endif
143  43 continue
144  endif
145  endif
146 
147  if (iter .eq. 0 .and. .not. boxed) then
148  stp = min(one/dnorm, stpmx)
149  else
150  stp = one
151  endif
152 
153  call dcopy(n,x,1,t,1)
154  call dcopy(n,g,1,r,1)
155  fold = f
156  ifun = 0
157  iback = 0
158  csave = 'START'
159  556 continue
160  gd = ddot(n,g,1,d,1)
161  if (ifun .eq. 0) then
162  gdold=gd
163  if (gd .ge. zero) then
164 c the directional derivative >=0.
165 c Line search is impossible.
166  write(6,*)' ascent direction in projection gd = ', gd
167  info = -4
168  return
169  endif
170  endif
171 
172  call dcsrch(f,gd,stp,ftol,gtol,xtol,zero,stpmx,csave,isave,dsave)
173 
174  xstep = stp*dnorm
175  if (csave(1:4) .ne. 'CONV' .and. csave(1:4) .ne. 'WARN') then
176  task = 'FG_LNSRCH'
177  ifun = ifun + 1
178  nfgv = nfgv + 1
179  iback = ifun - 1
180  if (stp .eq. one) then
181  call dcopy(n,z,1,x,1)
182  else
183  do 41 i = 1, n
184  x(i) = stp*d(i) + t(i)
185  41 continue
186  endif
187  else
188  task = 'NEW_X'
189  endif
190 
191  return
192 
193  end
subroutine dcsrch(f, g, stp, ftol, gtol, xtol, stpmin, stpmax, task, isave, dsave)
This subroutine finds a step that satisfies a sufficient decrease condition and a curvature condition...
Definition: dcsrch.f:96
subroutine lnsrlb(n, l, u, nbd, x, f, fold, gd, gdold, g, d, r, t, z, stp, dnorm, dtd, xstep, stpmx, iter, ifun, iback, nfgv, info, task, boxed, cnstnd, csave, isave, dsave)
This subroutine calls subroutine dcsrch from the Minpack2 library to perform the line search....
Definition: lnsrlb.f:74