1 subroutine sumsl(n, d, x, calcf, calcg, iv, liv, lv, v,
2 1 uiparm, urparm, ufparm)
4 c *** minimize general unconstrained objective function using ***
5 c *** analytic gradient and hessian approx. from secant update ***
8 integer iv(liv), uiparm(1)
9 double precision d(n), x(n), v(lv), urparm(1)
10 c dimension v(71 + n*(n+15)/2), uiparm(*), urparm(*)
11 external calcf, calcg, ufparm
15 c this routine interacts with subroutine sumit in an attempt
16 c to find an n-vector x* that minimizes the (unconstrained)
17 c objective function computed by calcf. (often the x* found is
18 c a local minimizer rather than a global one.)
20 c-------------------------- parameter usage --------------------------
22 c n........ (input) the number of variables on which f depends, i.e.,
23 c the number of components in x.
24 c d........ (input/output) a scale vector such that d(i)*x(i),
25 c i = 1,2,...,n, are all in comparable units.
26 c d can strongly affect the behavior of sumsl.
27 c finding the best choice of d is generally a trial-
28 c and-error process. choosing d so that d(i)*x(i)
29 c has about the same value for all i often works well.
30 c the defaults provided by subroutine deflt (see i
31 c below) require the caller to supply d.
32 c x........ (input/output) before (initially) calling sumsl, the call-
33 c er should set x to an initial guess at x*. when
34 c sumsl returns, x contains the best point so far
35 c found, i.e., the one that gives the least value so
37 c calcf.... (input) a subroutine that, given x, computes f(x). calcf
38 c must be declared external in the calling program.
40 c call calcf(n, x, nf, f, uiparm, urparm, ufparm)
41 c when calcf is called, nf is the invocation
42 c count for calcf. nf is included for possible use
43 c with calcg. if x is out of bounds (e.g., if it
44 c would cause overflow in computing f(x)), then calcf
45 c should set nf to 0. this will cause a shorter step
46 c to be attempted. (if x is in bounds, then calcf
47 c should not change nf.) the other parameters are as
48 c described above and below. calcf should not change
50 c calcg.... (input) a subroutine that, given x, computes g(x), the gra-
51 c dient of f at x. calcg must be declared external in
52 c the calling program. it is invoked by
53 c call calcg(n, x, nf, g, uiparm, urparm, ufaprm)
54 c when calcg is called, nf is the invocation
55 c count for calcf at the time f(x) was evaluated. the
56 c x passed to calcg is usually the one passed to calcf
57 c on either its most recent invocation or the one
58 c prior to it. if calcf saves intermediate results
59 c for use by calcg, then it is possible to tell from
60 c nf whether they are valid for the current x (or
61 c which copy is valid if two copies are kept). if g
62 c cannot be computed at x, then calcg should set nf to
63 c 0. in this case, sumsl will return with iv(1) = 65.
64 c (if g can be computed at x, then calcg should not
65 c changed nf.) the other parameters to calcg are as
66 c described above and below. calcg should not change
68 c iv....... (input/output) an integer value array of length liv (see
69 c below) that helps control the sumsl algorithm and
70 c that is used to store various intermediate quanti-
71 c ties. of particular interest are the initialization/
72 c return code iv(1) and the entries in iv that control
73 c printing and limit the number of iterations and func-
74 c tion evaluations. see the section on iv input
76 c liv...... (input) length of iv array. must be at least 60. if li
77 c is too small, then sumsl returns with iv(1) = 15.
78 c when sumsl returns, the smallest allowed value of
79 c liv is stored in iv(lastiv) -- see the section on
80 c iv output values below. (this is intended for use
81 c with extensions of sumsl that handle constraints.)
82 c lv....... (input) length of v array. must be at least 71+n*(n+15)/2.
83 c (at least 77+n*(n+17)/2 for smsno, at least
84 c 78+n*(n+12) for humsl). if lv is too small, then
85 c sumsl returns with iv(1) = 16. when sumsl returns,
86 c the smallest allowed value of lv is stored in
87 c iv(lastv) -- see the section on iv output values
89 c v........ (input/output) a floating-point value array of length l
90 c (see below) that helps control the sumsl algorithm
91 c and that is used to store various intermediate
92 c quantities. of particular interest are the entries
93 c in v that limit the length of the first step
94 c attempted (lmax0) and specify convergence tolerances
95 c (afctol, lmaxs, rfctol, sctol, xctol, xftol).
96 c uiparm... (input) user integer parameter array passed without change
98 c urparm... (input) user floating-point parameter array passed without
99 c change to calcf and calcg.
100 c ufparm... (input) user external subroutine or function passed without
101 c change to calcf and calcg.
103 c *** iv input values (from subroutine deflt) ***
105 c iv(1)... on input, iv(1) should have a value between 0 and 14......
106 c 0 and 12 mean this is a fresh start. 0 means that
107 c deflt(2, iv, liv, lv, v)
108 c is to be called to provide all default values to iv and
109 c v. 12 (the value that deflt assigns to iv(1)) means the
110 c caller has already called deflt and has possibly changed
111 c some iv and/or v entries to non-default values.
112 c 13 means deflt has been called and that sumsl (and
113 c sumit) should only do their storage allocation. that is,
114 c they should set the output components of iv that tell
115 c where various subarrays arrays of v begin, such as iv(g)
116 c (and, for humsl and humit only, iv(dtol)), and return.
117 c 14 means that a storage has been allocated (by a call
118 c with iv(1) = 13) and that the algorithm should be
119 c started. when called with iv(1) = 13, sumsl returns
120 c iv(1) = 14 unless liv or lv is too small (or n is not
121 c positive). default = 12.
122 c iv(inith).... iv(25) tells whether the hessian approximation h should
123 c be initialized. 1 (the default) means sumit should
124 c initialize h to the diagonal matrix whose i-th diagonal
125 c element is d(i)**2. 0 means the caller has supplied a
126 c cholesky factor l of the initial hessian approximation
127 c h = l*(l**t) in v, starting at v(iv(lmat)) = v(iv(42))
128 c (and stored compactly by rows). note that iv(lmat) may
129 c be initialized by calling sumsl with iv(1) = 13 (see
130 c the iv(1) discussion above). default = 1.
131 c iv(mxfcal)... iv(17) gives the maximum number of function evaluations
132 c (calls on calcf) allowed. if this number does not suf-
133 c fice, then sumsl returns with iv(1) = 9. default = 200.
134 c iv(mxiter)... iv(18) gives the maximum number of iterations allowed.
135 c it also indirectly limits the number of gradient evalua-
136 c tions (calls on calcg) to iv(mxiter) + 1. if iv(mxiter)
137 c iterations do not suffice, then sumsl returns with
138 c iv(1) = 10. default = 150.
139 c iv(outlev)... iv(19) controls the number and length of iteration sum-
140 c mary lines printed (by itsum). iv(outlev) = 0 means do
141 c not print any summary lines. otherwise, print a summary
142 c line after each abs(iv(outlev)) iterations. if iv(outlev)
143 c is positive, then summary lines of length 78 (plus carri-
144 c age control) are printed, including the following... the
145 c iteration and function evaluation counts, f = the current
146 c function value, relative difference in function values
147 c achieved by the latest step (i.e., reldf = (f0-v(f))/f01,
148 c where f01 is the maximum of abs(v(f)) and abs(v(f0)) and
149 c v(f0) is the function value from the previous itera-
150 c tion), the relative function reduction predicted for the
151 c step just taken (i.e., preldf = v(preduc) / f01, where
152 c v(preduc) is described below), the scaled relative change
153 c in x (see v(reldx) below), the step parameter for the
154 c step just taken (stppar = 0 means a full newton step,
155 c between 0 and 1 means a relaxed newton step, between 1
156 c and 2 means a double dogleg step, greater than 2 means
157 c a scaled down cauchy step -- see subroutine dbldog), the
158 c 2-norm of the scale vector d times the step just taken
159 c (see v(dstnrm) below), and npreldf, i.e.,
160 c v(nreduc)/f01, where v(nreduc) is described below -- if
161 c npreldf is positive, then it is the relative function
162 c reduction predicted for a newton step (one with
163 c stppar = 0). if npreldf is negative, then it is the
164 c negative of the relative function reduction predicted
165 c for a step computed with step bound v(lmaxs) for use in
166 c testing for singular convergence.
167 c if iv(outlev) is negative, then lines of length 50
168 c are printed, including only the first 6 items listed
169 c above (through reldx).
171 c iv(parprt)... iv(20) = 1 means print any nondefault v values on a
172 c fresh start or any changed v values on a restart.
173 c iv(parprt) = 0 means skip this printing. default = 1.
174 c iv(prunit)... iv(21) is the output unit number on which all printing
175 c is done. iv(prunit) = 0 means suppress all printing.
176 c default = standard output unit (unit 6 on most systems).
177 c iv(solprt)... iv(22) = 1 means print out the value of x returned (as
178 c well as the gradient and the scale vector d).
179 c iv(solprt) = 0 means skip this printing. default = 1.
180 c iv(statpr)... iv(23) = 1 means print summary statistics upon return-
181 c ing. these consist of the function value, the scaled
182 c relative change in x caused by the most recent step (see
183 c v(reldx) below), the number of function and gradient
184 c evaluations (calls on calcf and calcg), and the relative
185 c function reductions predicted for the last step taken and
186 c for a newton step (or perhaps a step bounded by v(lmaxs)
187 c -- see the descriptions of preldf and npreldf under
189 c iv(statpr) = 0 means skip this printing.
190 c iv(statpr) = -1 means skip this printing as well as that
191 c of the one-line termination reason message. default = 1.
192 c iv(x0prt).... iv(24) = 1 means print the initial x and scale vector d
193 c (on a fresh start only). iv(x0prt) = 0 means skip this
194 c printing. default = 1.
196 c *** (selected) iv output values ***
198 c iv(1)........ on output, iv(1) is a return code....
199 c 3 = x-convergence. the scaled relative difference (see
200 c v(reldx)) between the current parameter vector x and
201 c a locally optimal parameter vector is very likely at
203 c 4 = relative function convergence. the relative differ-
204 c ence between the current function value and its lo-
205 c cally optimal value is very likely at most v(rfctol).
206 c 5 = both x- and relative function convergence (i.e., the
207 c conditions for iv(1) = 3 and iv(1) = 4 both hold).
208 c 6 = absolute function convergence. the current function
209 c value is at most v(afctol) in absolute value.
210 c 7 = singular convergence. the hessian near the current
211 c iterate appears to be singular or nearly so, and a
212 c step of length at most v(lmaxs) is unlikely to yield
213 c a relative function decrease of more than v(sctol).
214 c 8 = false convergence. the iterates appear to be converg-
215 c ing to a noncritical point. this may mean that the
216 c convergence tolerances (v(afctol), v(rfctol),
217 c v(xctol)) are too small for the accuracy to which
218 c the function and gradient are being computed, that
219 c there is an error in computing the gradient, or that
220 c the function or gradient is discontinuous near x.
221 c 9 = function evaluation limit reached without other con-
222 c vergence (see iv(mxfcal)).
223 c 10 = iteration limit reached without other convergence
225 c 11 = stopx returned .true. (external interrupt). see the
227 c 14 = storage has been allocated (after a call with
229 c 17 = restart attempted with n changed.
230 c 18 = d has a negative component and iv(dtype) .le. 0.
231 c 19...43 = v(iv(1)) is out of range.
232 c 63 = f(x) cannot be computed at the initial x.
233 c 64 = bad parameters passed to assess (which should not
235 c 65 = the gradient could not be computed at x (see calcg
237 c 67 = bad first parameter to deflt.
238 c 80 = iv(1) was out of range.
239 c 81 = n is not positive.
240 c iv(g)........ iv(28) is the starting subscript in v of the current
241 c gradient vector (the one corresponding to x).
242 c iv(lastiv)... iv(44) is the least acceptable value of liv. (it is
243 c only set if liv is at least 44.)
244 c iv(lastv).... iv(45) is the least acceptable value of lv. (it is
245 c only set if liv is large enough, at least iv(lastiv).)
246 c iv(nfcall)... iv(6) is the number of calls so far made on calcf (i.e.,
247 c function evaluations).
248 c iv(ngcall)... iv(30) is the number of gradient evaluations (calls on
250 c iv(niter).... iv(31) is the number of iterations performed.
252 c *** (selected) v input values (from subroutine deflt) ***
254 c v(bias)..... v(43) is the bias parameter used in subroutine dbldog --
255 c see that subroutine for details. default = 0.8.
256 c v(afctol)... v(31) is the absolute function convergence tolerance.
257 c if sumsl finds a point where the function value is less
258 c than v(afctol) in absolute value, and if sumsl does not
259 c return with iv(1) = 3, 4, or 5, then it returns with
260 c iv(1) = 6. this test can be turned off by setting
261 c v(afctol) to zero. default = max(10**-20, machep**2),
262 c where machep is the unit roundoff.
263 c v(dinit).... v(38), if nonnegative, is the value to which the scale
264 c vector d is initialized. default = -1.
265 c v(lmax0).... v(35) gives the maximum 2-norm allowed for d times the
266 c very first step that sumsl attempts. this parameter can
267 c markedly affect the performance of sumsl.
268 c v(lmaxs).... v(36) is used in testing for singular convergence -- if
269 c the function reduction predicted for a step of length
270 c bounded by v(lmaxs) is at most v(sctol) * abs(f0), where
271 c f0 is the function value at the start of the current
272 c iteration, and if sumsl does not return with iv(1) = 3,
273 c 4, 5, or 6, then it returns with iv(1) = 7. default = 1.
274 c v(rfctol)... v(32) is the relative function convergence tolerance.
275 c if the current model predicts a maximum possible function
276 c reduction (see v(nreduc)) of at most v(rfctol)*abs(f0)
277 c at the start of the current iteration, where f0 is the
278 c then current function value, and if the last step attempt-
279 c ed achieved no more than twice the predicted function
280 c decrease, then sumsl returns with iv(1) = 4 (or 5).
281 c default = max(10**-10, machep**(2/3)), where machep is
283 c v(sctol).... v(37) is the singular convergence tolerance -- see the
284 c description of v(lmaxs) above.
285 c v(tuner1)... v(26) helps decide when to check for false convergence.
286 c this is done if the actual function decrease from the
287 c current step is no more than v(tuner1) times its predict-
288 c ed value. default = 0.1.
289 c v(xctol).... v(33) is the x-convergence tolerance. if a newton step
290 c (see v(nreduc)) is tried that has v(reldx) .le. v(xctol)
291 c and if this step yields at most twice the predicted func-
292 c tion decrease, then sumsl returns with iv(1) = 3 (or 5).
293 c (see the description of v(reldx) below.)
294 c default = machep**0.5, where machep is the unit roundoff.
295 c v(xftol).... v(34) is the false convergence tolerance. if a step is
296 c tried that gives no more than v(tuner1) times the predict-
297 c ed function decrease and that has v(reldx) .le. v(xftol),
298 c and if sumsl does not return with iv(1) = 3, 4, 5, 6, or
299 c 7, then it returns with iv(1) = 8. (see the description
300 c of v(reldx) below.) default = 100*machep, where
301 c machep is the unit roundoff.
302 c v(*)........ deflt supplies to v a number of tuning constants, with
303 c which it should ordinarily be unnecessary to tinker. see
304 c section 17 of version 2.2 of the nl2sol usage summary
305 c (i.e., the appendix to ref. 1) for details on v(i),
306 c i = decfac, incfac, phmnfc, phmxfc, rdfcmn, rdfcmx,
307 c tuner2, tuner3, tuner4, tuner5.
309 c *** (selected) v output values ***
311 c v(dgnorm)... v(1) is the 2-norm of (diag(d)**-1)*g, where g is the
312 c most recently computed gradient.
313 c v(dstnrm)... v(2) is the 2-norm of diag(d)*step, where step is the
315 c v(f)........ v(10) is the current function value.
316 c v(f0)....... v(13) is the function value at the start of the current
318 c v(nreduc)... v(6), if positive, is the maximum function reduction
319 c possible according to the current model, i.e., the func-
320 c tion reduction predicted for a newton step (i.e.,
321 c step = -h**-1 * g, where g is the current gradient and
322 c h is the current hessian approximation).
323 c if v(nreduc) is negative, then it is the negative of
324 c the function reduction predicted for a step computed with
325 c a step bound of v(lmaxs) for use in testing for singular
327 c v(preduc)... v(7) is the function reduction predicted (by the current
328 c quadratic model) for the current step. this (divided by
329 c v(f0)) is used in testing for relative function
331 c v(reldx).... v(17) is the scaled relative change in x caused by the
332 c current step, computed as
333 c max(abs(d(i)*(x(i)-x0(i)), 1 .le. i .le. p) /
334 c max(d(i)*(abs(x(i))+abs(x0(i))), 1 .le. i .le. p),
335 c where x = x0 + step.
337 c------------------------------- notes -------------------------------
339 c *** algorithm notes ***
341 c this routine uses a hessian approximation computed from the
342 c bfgs update (see ref 3). only a cholesky factor of the hessian
343 c approximation is stored, and this is updated using ideas from
344 c ref. 4. steps are computed by the double dogleg scheme described
345 c in ref. 2. the steps are assessed as in ref. 1.
347 c *** usage notes ***
349 c after a return with iv(1) .le. 11, it is possible to restart,
350 c i.e., to change some of the iv and v input values described above
351 c and continue the algorithm from the point where it was interrupt-
352 c ed. iv(1) should not be changed, nor should any entries of i
353 c and v other than the input values (those supplied by deflt).
354 c those who do not wish to write a calcg which computes the
355 c gradient analytically should call smsno rather than sumsl.
356 c smsno uses finite differences to compute an approximate gradient.
357 c those who would prefer to provide f and g (the function and
358 c gradient) by reverse communication rather than by writing subrou-
359 c tines calcf and calcg may call on sumit directly. see the com-
360 c ments at the beginning of sumit.
361 c those who use sumsl interactively may wish to supply their
362 c own stopx function, which should return .true. if the break key
363 c has been pressed since stopx was last invoked. this makes it
364 c possible to externally interrupt sumsl (which will return with
365 c iv(1) = 11 if stopx returns .true.).
366 c storage for g is allocated at the end of v. thus the caller
367 c may make v longer than specified above and may allow calcg to use
368 c elements of g beyond the first n as scratch storage.
370 c *** portability notes ***
372 c the sumsl distribution tape contains both single- and double-
373 c precision versions of the sumsl source code, so it should be un-
374 c necessary to change precisions.
375 c only the functions imdcon and rmdcon contain machine-dependent
376 c constants. to change from one machine to another, it should
377 c suffice to change the (few) relevant lines in these functions.
378 c intrinsic functions are explicitly declared. on certain com-
379 c puters (e.g. univac), it may be necessary to comment out these
380 c declarations. so that this may be done automatically by a simple
381 c program, such declarations are preceded by a comment having c/+
382 c in columns 1-3 and blanks in columns 4-72 and are followed by
383 c a comment having c/ in columns 1 and 2 and blanks in columns 3-72.
384 c the sumsl source code is expressed in 1966 ansi standard
385 c fortran. it may be converted to fortran 77 by commenting out all
386 c lines that fall between a line having c/6 in columns 1-3 and a
387 c line having c/7 in columns 1-3 and by removing (i.e., replacing
388 c by a blank) the c in column 1 of the lines that follow the c/7
389 c line and precede a line having c/ in columns 1-2 and blanks in
390 c columns 3-72. these changes convert some data statements into
391 c parameter statements, convert some variables from real to
392 c character*4, and make the data statements that initialize these
393 c variables use character strings delimited by primes instead
394 c of hollerith constants. (such variables and data statements
395 c appear only in modules itsum and parck. parameter statements
396 c appear nearly everywhere.) these changes also add save state-
397 c ments for variables given machine-dependent constants by rmdcon.
401 c 1. dennis, j.e., gay, d.m., and welsch, r.e. (1981), algorithm 573 --
402 c an adaptive nonlinear least-squares algorithm, acm trans.
403 c math. software 7, pp. 369-383.
405 c 2. dennis, j.e., and mei, h.h.w. (1979), two new unconstrained opti-
406 c mization algorithms which use function and gradient
407 c values, j. optim. theory applic. 28, pp. 453-482.
409 c 3. dennis, j.e., and more, j.j. (1977), quasi-newton methods, motiva-
410 c tion and theory, siam rev. 19, pp. 46-89.
412 c 4. goldfarb, d. (1976), factorized variable metric methods for uncon-
413 c strained optimization, math. comput. 30, pp. 796-811.
417 c coded by david m. gay (winter 1980). revised summer 1982.
418 c this subroutine was written in connection with research
419 c supported in part by the national science foundation under
420 c grants mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989,
424 c---------------------------- declarations ---------------------------
426 external deflt, sumit
428 c deflt... supplies default iv and v input components.
429 c sumit... reverse-communication routine that carries out sumsl algo-
435 c *** subscripts for iv ***
437 integer nextv, nfcall, nfgcal, g, toobig, vneed
440 c data nextv/47/, nfcall/6/, nfgcal/7/, g/28/, toobig/2/, vneed/4/
442 parameter (nextv=47, nfcall=6, nfgcal=7, g=28, toobig=2, vneed=4)
445 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
447 if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
449 if (iv1 .eq. 12 .or. iv1 .eq. 13) iv(vneed) = iv(vneed) + n
450 if (iv1 .eq. 14) go to 10
451 if (iv1 .gt. 2 .and. iv1 .lt. 12) go to 10
453 if (iv1 .eq. 12) iv(1) = 13
458 20 call sumit(d, f, v(g1), iv, liv, lv, n, v, x)
459 if (iv(1) - 2) 30, 40, 50
462 call calcf(n, x, nf, f, uiparm, urparm, ufparm)
463 if (nf .le. 0) iv(toobig) = 1
466 40 call calcg(n, x, iv(nfgcal), v(g1), uiparm, urparm, ufparm)
469 50 if (iv(1) .ne. 14) go to 999
471 c *** storage allocation
474 iv(nextv) = iv(g) + n
475 if (iv1 .ne. 13) go to 10
478 c *** last card of sumsl follows ***
480 subroutine sumit(d, fx, g, iv, liv, lv, n, v, x)
482 c *** carry out sumsl (unconstrained minimization) iterations, using
483 c *** double-dogleg/bfgs steps.
485 c *** parameter declarations ***
489 double precision d(n), fx, g(n), v(lv), x(n)
491 c-------------------------- parameter usage --------------------------
493 c d.... scale vector.
494 c fx... function value.
495 c g.... gradient vector.
496 c iv... integer value array.
497 c liv.. length of iv (at least 60).
498 c lv... length of v (at least 71 + n*(n+13)/2).
499 c n.... number of variables (components in x and g).
500 c v.... floating-point value array.
501 c x.... vector of parameters to be optimized.
505 c parameters iv, n, v, and x are the same as the corresponding
506 c ones to sumsl (which see), except that v can be shorter (since
507 c the part of v that sumsl uses for storing g is not needed).
508 c moreover, compared with sumsl, iv(1) may have the two additional
509 c output values 1 and 2, which are explained below, as is the use
510 c of iv(toobig) and iv(nfgcal). the value iv(g), which is an
511 c output value from sumsl (and smsno), is not referenced by
512 c sumit or the subroutines it calls.
513 c fx and g need not have been initialized when sumit is called
514 c with iv(1) = 12, 13, or 14.
516 c iv(1) = 1 means the caller should set fx to f(x), the function value
517 c at x, and call sumit again, having changed none of the
518 c other parameters. an exception occurs if f(x) cannot be
519 c (e.g. if overflow would occur), which may happen because
520 c of an oversized step. in this case the caller should set
521 c iv(toobig) = iv(2) to 1, which will cause sumit to ig-
522 c nore fx and try a smaller step. the parameter nf that
523 c sumsl passes to calcf (for possible use by calcg) is a
524 c copy of iv(nfcall) = iv(6).
525 c iv(1) = 2 means the caller should set g to g(x), the gradient vector
526 c of f at x, and call sumit again, having changed none of
527 c the other parameters except possibly the scale vector d
528 c when iv(dtype) = 0. the parameter nf that sumsl passes
529 c to calcg is iv(nfgcal) = iv(7). if g(x) cannot be
530 c evaluated, then the caller may set iv(nfgcal) to 0, in
531 c which case sumit will return with iv(1) = 65.
535 c coded by david m. gay (december 1979). revised sept. 1982.
536 c this subroutine was written in connection with research supported
537 c in part by the national science foundation under grants
538 c mcs-7600324 and mcs-7906671.
540 c (see sumsl for references.)
542 c+++++++++++++++++++++++++++ declarations ++++++++++++++++++++++++++++
544 c *** local variables ***
546 integer dg1, dummy, g01, i, k, l, lstgst, nwtst1, step1,
552 double precision half, negone, one, onep2, zero
554 c *** no intrinsic functions ***
556 c *** external functions and subroutines ***
558 external assst, dbdog, deflt, dotprd, itsum, litvmu, livmul,
559 1 ltvmul, lupdat, lvmul, parck, reldst, stopx, vaxpy,
560 2 vcopy, vscopy, vvmulp, v2norm, wzbfgs
562 double precision dotprd, reldst, v2norm
564 c assst.... assesses candidate step.
565 c dbdog.... computes double-dogleg (candidate) step.
566 c deflt.... supplies default iv and v input components.
567 c dotprd... returns inner product of two vectors.
568 c itsum.... prints iteration summary and info on initial and final x.
569 c litvmu... multiplies inverse transpose of lower triangle times vector.
570 c livmul... multiplies inverse of lower triangle times vector.
571 c ltvmul... multiplies transpose of lower triangle times vector.
572 c lupdt.... updates cholesky factor of hessian approximation.
573 c lvmul.... multiplies lower triangle times vector.
574 c parck.... checks validity of input iv and v values.
575 c reldst... computes v(reldx) = relative step size.
576 c stopx.... returns .true. if the break key has been pressed.
577 c vaxpy.... computes scalar times one vector plus another.
578 c vcopy.... copies one vector to another.
579 c vscopy... sets all elements of a vector to a scalar.
580 c vvmulp... multiplies vector by vector raised to power (componentwise).
581 c v2norm... returns the 2-norm of a vector.
582 c wzbfgs... computes w and z for lupdat corresponding to bfgs update.
584 c *** subscripts for iv and v ***
587 integer cnvcod, dg, dgnorm, dinit, dstnrm, dst0, f, f0, fdif,
588 1 gthg, gtstep, g0, incfac, inith, irc, kagqt, lmat, lmax0,
589 2 lmaxs, mode, model, mxfcal, mxiter, nextv, nfcall, nfgcal,
590 3 ngcall, niter, nreduc, nwtstp, preduc, radfac, radinc,
591 4 radius, rad0, reldx, restor, step, stglim, stlstg, toobig,
592 5 tuner4, tuner5, vneed, xirc, x0
594 c *** iv subscript values ***
597 c data cnvcod/55/, dg/37/, g0/48/, inith/25/, irc/29/, kagqt/33/,
598 c 1 mode/35/, model/5/, mxfcal/17/, mxiter/18/, nfcall/6/,
599 c 2 nfgcal/7/, ngcall/30/, niter/31/, nwtstp/34/, radinc/8/,
600 c 3 restor/9/, step/40/, stglim/11/, stlstg/41/, toobig/2/,
601 c 4 vneed/4/, xirc/13/, x0/43/
603 parameter (cnvcod=55, dg=37, g0=48, inith=25, irc=29, kagqt=33,
604 1 mode=35, model=5, mxfcal=17, mxiter=18, nfcall=6,
605 2 nfgcal=7, ngcall=30, niter=31, nwtstp=34, radinc=8,
606 3 restor=9, step=40, stglim=11, stlstg=41, toobig=2,
607 4 vneed=4, xirc=13, x0=43)
610 c *** v subscript values ***
614 c data dgnorm/1/, dinit/38/, dstnrm/2/, dst0/3/, f/10/, f0/13/,
615 c 1 fdif/11/, gthg/44/, gtstep/4/, incfac/23/, lmat/42/,
616 c 2 lmax0/35/, lmaxs/36/, nextv/47/, nreduc/6/, preduc/7/,
617 c 3 radfac/16/, radius/8/, rad0/9/, reldx/17/, tuner4/29/,
620 parameter (afctol=31)
621 parameter (dgnorm=1, dinit=38, dstnrm=2, dst0=3, f=10, f0=13,
622 1 fdif=11, gthg=44, gtstep=4, incfac=23, lmat=42,
623 2 lmax0=35, lmaxs=36, nextv=47, nreduc=6, preduc=7,
624 3 radfac=16, radius=8, rad0=9, reldx=17, tuner4=29,
629 c data half/0.5d+0/, negone/-1.d+0/, one/1.d+0/, onep2/1.2d+0/,
632 parameter (half=0.5d+0, negone=-1.d+0, one=1.d+0, onep2=1.2d+0,
636 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
638 C Following SAVE statement inserted.
641 if (i .eq. 1) go to 50
642 if (i .eq. 2) go to 60
644 c *** check validity of iv and v input values ***
646 if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
647 if (iv(1) .eq. 12 .or. iv(1) .eq. 13)
648 1 iv(vneed) = iv(vneed) + n*(n+13)/2
649 call parck(2, d, iv, liv, lv, n, v)
651 if (i .gt. 12) go to 999
652 go to (180, 180, 180, 180, 180, 180, 120, 90, 120, 10, 10, 20), i
654 c *** storage allocation ***
657 iv(x0) = l + n*(n+1)/2
658 iv(step) = iv(x0) + n
659 iv(stlstg) = iv(step) + n
660 iv(g0) = iv(stlstg) + n
661 iv(nwtstp) = iv(g0) + n
662 iv(dg) = iv(nwtstp) + n
663 iv(nextv) = iv(dg) + n
664 if (iv(1) .ne. 13) go to 20
668 c *** initialization ***
681 if (v(dinit) .ge. zero) call vscopy(n, d, v(dinit))
682 if (iv(inith) .ne. 1) go to 40
684 c *** set the initial hessian approximation to diag(d)**-2 ***
687 call vscopy(n*(n+1)/2, v(l), zero)
692 if (t .le. zero) t = one
696 c *** compute initial function value ***
702 if (iv(mode) .ge. 0) go to 180
704 if (iv(toobig) .eq. 0) go to 999
708 c *** make sure gradient could be computed ***
710 60 if (iv(nfgcal) .ne. 0) go to 70
715 call vvmulp(n, v(dg1), g, d, -1)
716 v(dgnorm) = v2norm(n, v(dg1))
718 c *** test norm of gradient ***
720 if (v(dgnorm) .gt. v(afctol)) go to 75
722 iv(cnvcod) = iv(irc) - 4
724 75 if (iv(cnvcod) .ne. 0) go to 290
725 if (iv(mode) .eq. 0) go to 250
727 c *** allow first step to have scaled 2-norm at most v(lmax0) ***
734 c----------------------------- main loop -----------------------------
737 c *** print iteration summary, check iteration limit ***
739 80 call itsum(d, g, iv, liv, lv, n, v, x)
741 if (k .lt. iv(mxiter)) go to 100
745 c *** update radius ***
747 100 iv(niter) = k + 1
748 if(k.gt.0)v(radius) = v(radfac) * v(dstnrm)
750 c *** initialize for start of next iteration ***
758 c *** copy x to x0, g to g0 ***
760 call vcopy(n, v(x01), x)
761 call vcopy(n, v(g01), g)
763 c *** check stopx and function evaluation limit ***
767 110 if (.not. stopx(dummy)) go to 130
771 c *** come here when restarting after func. eval. limit or stopx.
773 120 if (v(f) .ge. v(f0)) go to 130
778 130 if (iv(nfcall) .lt. iv(mxfcal)) go to 150
780 140 if (v(f) .ge. v(f0)) go to 300
782 c *** in case of stopx or function evaluation limit with
783 c *** improved v(f), evaluate the gradient at x.
788 c. . . . . . . . . . . . . compute candidate step . . . . . . . . . .
793 if (iv(kagqt) .ge. 0) go to 160
795 call livmul(n, v(nwtst1), v(l), g)
796 v(nreduc) = half * dotprd(n, v(nwtst1), v(nwtst1))
797 call litvmu(n, v(nwtst1), v(l), v(nwtst1))
798 call vvmulp(n, v(step1), v(nwtst1), d, 1)
799 v(dst0) = v2norm(n, v(step1))
800 call vvmulp(n, v(dg1), v(dg1), d, -1)
801 call ltvmul(n, v(step1), v(l), v(dg1))
802 v(gthg) = v2norm(n, v(step1))
804 160 call dbdog(v(dg1), lv, n, v(nwtst1), v(step1), v)
805 if (iv(irc) .eq. 6) go to 180
807 c *** check whether evaluating f(x0 + step) looks worthwhile ***
809 if (v(dstnrm) .le. zero) go to 180
810 if (iv(irc) .ne. 5) go to 170
811 if (v(radfac) .le. one) go to 170
812 if (v(preduc) .le. onep2 * v(fdif)) go to 180
814 c *** compute f(x0 + step) ***
818 call vaxpy(n, x, one, v(step1), v(x01))
819 iv(nfcall) = iv(nfcall) + 1
824 c. . . . . . . . . . . . . assess candidate step . . . . . . . . . . .
827 v(reldx) = reldst(n, d, x, v(x01))
828 call assst(iv, liv, lv, v)
831 if (iv(restor) .eq. 1) call vcopy(n, x, v(x01))
832 if (iv(restor) .eq. 2) call vcopy(n, v(lstgst), v(step1))
833 if (iv(restor) .ne. 3) go to 190
834 call vcopy(n, v(step1), v(lstgst))
835 call vaxpy(n, x, one, v(step1), v(x01))
836 v(reldx) = reldst(n, d, x, v(x01))
839 go to (200,230,230,230,200,210,220,220,220,220,220,220,280,250), k
841 c *** recompute step with changed radius ***
843 200 v(radius) = v(radfac) * v(dstnrm)
846 c *** compute step of length v(lmaxs) for singular convergence test.
848 210 v(radius) = v(lmaxs)
851 c *** convergence or false convergence ***
853 220 iv(cnvcod) = k - 4
854 if (v(f) .ge. v(f0)) go to 290
855 if (iv(xirc) .eq. 14) go to 290
858 c. . . . . . . . . . . . process acceptable step . . . . . . . . . . .
860 230 if (iv(irc) .ne. 3) go to 240
864 c *** set temp1 = hessian * step for use in gradient tests ***
867 call ltvmul(n, v(temp1), v(l), v(step1))
868 call lvmul(n, v(temp1), v(l), v(temp1))
870 c *** compute gradient ***
872 240 iv(ngcall) = iv(ngcall) + 1
876 c *** initializations -- g0 = g - g0, etc. ***
879 call vaxpy(n, v(g01), negone, v(g01), g)
882 if (iv(irc) .ne. 3) go to 270
884 c *** set v(radfac) by gradient tests ***
886 c *** set temp1 = diag(d)**-1 * (hessian*step + (g(x0)-g(x))) ***
888 call vaxpy(n, v(temp1), negone, v(g01), v(temp1))
889 call vvmulp(n, v(temp1), v(temp1), d, -1)
891 c *** do gradient tests ***
893 if (v2norm(n, v(temp1)) .le. v(dgnorm) * v(tuner4))
895 if (dotprd(n, g, v(step1))
896 1 .ge. v(gtstep) * v(tuner5)) go to 270
897 260 v(radfac) = v(incfac)
899 c *** update h, loop ***
904 call wzbfgs(v(l), n, v(step1), v(w), v(g01), v(z))
906 c ** use the n-vectors starting at v(step1) and v(g01) for scratch..
907 call lupdat(v(temp1), v(step1), v(l), v(g01), v(l), n, v(w), v(z))
911 c. . . . . . . . . . . . . . misc. details . . . . . . . . . . . . . .
913 c *** bad parameters to assess ***
918 c *** print summary of final iteration and other requested items ***
920 290 iv(1) = iv(cnvcod)
922 300 call itsum(d, g, iv, liv, lv, n, v, x)
926 c *** last line of sumit follows ***
928 subroutine dbdog(dig, lv, n, nwtstp, step, v)
930 c *** compute double dogleg step ***
932 c *** parameter declarations ***
935 double precision dig(n), nwtstp(n), step(n), v(lv)
939 c this subroutine computes a candidate step (for use in an uncon-
940 c strained minimization code) by the double dogleg algorithm of
941 c dennis and mei (ref. 1), which is a variation on powell*s dogleg
942 c scheme (ref. 2, p. 95).
944 c-------------------------- parameter usage --------------------------
946 c dig (input) diag(d)**-2 * g -- see algorithm notes.
947 c g (input) the current gradient vector.
948 c lv (input) length of v.
949 c n (input) number of components in dig, g, nwtstp, and step.
950 c nwtstp (input) negative newton step -- see algorithm notes.
951 c step (output) the computed step.
952 c v (i/o) values array, the following components of which are
954 c v(bias) (input) bias for relaxed newton step, which is v(bias) of
955 c the way from the full newton to the fully relaxed newton
956 c step. recommended value = 0.8 .
957 c v(dgnorm) (input) 2-norm of diag(d)**-1 * g -- see algorithm notes.
958 c v(dstnrm) (output) 2-norm of diag(d) * step, which is v(radius)
959 c unless v(stppar) = 0 -- see algorithm notes.
960 c v(dst0) (input) 2-norm of diag(d) * nwtstp -- see algorithm notes.
961 c v(grdfac) (output) the coefficient of dig in the step returned --
962 c step(i) = v(grdfac)*dig(i) + v(nwtfac)*nwtstp(i).
963 c v(gthg) (input) square-root of (dig**t) * (hessian) * dig -- see
965 c v(gtstep) (output) inner product between g and step.
966 c v(nreduc) (output) function reduction predicted for the full newton
968 c v(nwtfac) (output) the coefficient of nwtstp in the step returned --
969 c see v(grdfac) above.
970 c v(preduc) (output) function reduction predicted for the step returned.
971 c v(radius) (input) the trust region radius. d times the step returned
972 c has 2-norm v(radius) unless v(stppar) = 0.
973 c v(stppar) (output) code telling how step was computed... 0 means a
974 c full newton step. between 0 and 1 means v(stppar) of the
975 c way from the newton to the relaxed newton step. between
976 c 1 and 2 means a true double dogleg step, v(stppar) - 1 of
977 c the way from the relaxed newton to the cauchy step.
978 c greater than 2 means 1 / (v(stppar) - 1) times the cauchy
981 c------------------------------- notes -------------------------------
983 c *** algorithm notes ***
985 c let g and h be the current gradient and hessian approxima-
986 c tion respectively and let d be the current scale vector. this
987 c routine assumes dig = diag(d)**-2 * g and nwtstp = h**-1 * g.
988 c the step computed is the same one would get by replacing g and h
989 c by diag(d)**-1 * g and diag(d)**-1 * h * diag(d)**-1,
990 c computing step, and translating step back to the original
991 c variables, i.e., premultiplying it by diag(d)**-1.
995 c 1. dennis, j.e., and mei, h.h.w. (1979), two new unconstrained opti-
996 c mization algorithms which use function and gradient
997 c values, j. optim. theory applic. 28, pp. 453-482.
998 c 2. powell, m.j.d. (1970), a hybrid method for non-linear equations,
999 c in numerical methods for non-linear equations, edited by
1000 c p. rabinowitz, gordon and breach, london.
1004 c coded by david m. gay.
1005 c this subroutine was written in connection with research supported
1006 c by the national science foundation under grants mcs-7600324 and
1009 c------------------------ external quantities ------------------------
1011 c *** functions and subroutines called ***
1013 external dotprd, v2norm
1014 double precision dotprd, v2norm
1016 c dotprd... returns inner product of two vectors.
1017 c v2norm... returns 2-norm of a vector.
1019 c *** intrinsic functions ***
1021 double precision dsqrt
1023 c-------------------------- local variables --------------------------
1026 double precision cfact, cnorm, ctrnwt, ghinvg, femnsq, gnorm,
1027 1 nwtnrm, relax, rlambd, t, t1, t2
1028 double precision half, one, two, zero
1030 c *** v subscripts ***
1032 integer bias, dgnorm, dstnrm, dst0, grdfac, gthg, gtstep,
1033 1 nreduc, nwtfac, preduc, radius, stppar
1035 c *** data initializations ***
1038 c data half/0.5d+0/, one/1.d+0/, two/2.d+0/, zero/0.d+0/
1040 parameter (half=0.5d+0, one=1.d+0, two=2.d+0, zero=0.d+0)
1044 c data bias/43/, dgnorm/1/, dstnrm/2/, dst0/3/, grdfac/45/,
1045 c 1 gthg/44/, gtstep/4/, nreduc/6/, nwtfac/46/, preduc/7/,
1046 c 2 radius/8/, stppar/5/
1048 parameter (bias=43, dgnorm=1, dstnrm=2, dst0=3, grdfac=45,
1049 1 gthg=44, gtstep=4, nreduc=6, nwtfac=46, preduc=7,
1050 2 radius=8, stppar=5)
1053 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
1057 if (nwtnrm .gt. zero) rlambd = v(radius) / nwtnrm
1059 ghinvg = two * v(nreduc)
1062 if (rlambd .lt. one) go to 30
1064 c *** the newton step is inside the trust region ***
1069 v(preduc) = v(nreduc)
1072 20 step(i) = -nwtstp(i)
1075 30 v(dstnrm) = v(radius)
1076 cfact = (gnorm / v(gthg))**2
1077 c *** cauchy step = -cfact * g.
1078 cnorm = gnorm * cfact
1079 relax = one - v(bias) * (one - gnorm*cnorm/ghinvg)
1080 if (rlambd .lt. relax) go to 50
1082 c *** step is between relaxed newton and full newton steps ***
1084 v(stppar) = one - (rlambd - relax) / (one - relax)
1086 v(gtstep) = t * ghinvg
1087 v(preduc) = rlambd * (one - half*rlambd) * ghinvg
1090 40 step(i) = t * nwtstp(i)
1093 50 if (cnorm .lt. v(radius)) go to 70
1095 c *** the cauchy step lies outside the trust region --
1096 c *** step = scaled cauchy step ***
1098 t = -v(radius) / gnorm
1100 v(stppar) = one + cnorm / v(radius)
1101 v(gtstep) = -v(radius) * gnorm
1102 v(preduc) = v(radius)*(gnorm - half*v(radius)*(v(gthg)/gnorm)**2)
1104 60 step(i) = t * dig(i)
1107 c *** compute dogleg step between cauchy and relaxed newton ***
1108 c *** femur = relaxed newton step minus cauchy step ***
1110 70 ctrnwt = cfact * relax * ghinvg / gnorm
1111 c *** ctrnwt = inner prod. of cauchy and relaxed newton steps,
1112 c *** scaled by gnorm**-1.
1113 t1 = ctrnwt - gnorm*cfact**2
1114 c *** t1 = inner prod. of femur and cauchy step, scaled by
1116 t2 = v(radius)*(v(radius)/gnorm) - gnorm*cfact**2
1118 femnsq = (t/gnorm)*t - ctrnwt - t1
1119 c *** femnsq = square of 2-norm of femur, scaled by gnorm**-1.
1120 t = t2 / (t1 + dsqrt(t1**2 + femnsq*t2))
1121 c *** dogleg step = cauchy step + t * femur.
1122 t1 = (t - one) * cfact
1127 v(gtstep) = t1*gnorm**2 + t2*ghinvg
1128 v(preduc) = -t1*gnorm * ((t2 + one)*gnorm)
1129 1 - t2 * (one + half*t2)*ghinvg
1130 2 - half * (v(gthg)*t1)**2
1132 80 step(i) = t1*dig(i) + t2*nwtstp(i)
1135 c *** last line of dbdog follows ***
1137 subroutine ltvmul(n, x, l, y)
1139 c *** compute x = (l**t)*y, where l is an n x n lower
1140 c *** triangular matrix stored compactly by rows. x and y may
1141 c *** occupy the same storage. ***
1144 cal double precision x(n), l(1), y(n)
1145 double precision x(n), l(n*(n+1)/2), y(n)
1146 c dimension l(n*(n+1)/2)
1147 integer i, ij, i0, j
1148 double precision yi, zero
1152 parameter (zero=0.d+0)
1161 x(j) = x(j) + yi*l(ij)
1166 c *** last card of ltvmul follows ***
1168 subroutine lupdat(beta, gamma, l, lambda, lplus, n, w, z)
1170 c *** compute lplus = secant update of l ***
1172 c *** parameter declarations ***
1175 cal double precision beta(n), gamma(n), l(1), lambda(n), lplus(1),
1176 double precision beta(n), gamma(n), l(n*(n+1)/2), lambda(n),
1177 1 lplus(n*(n+1)/2),w(n), z(n)
1178 c dimension l(n*(n+1)/2), lplus(n*(n+1)/2)
1180 c-------------------------- parameter usage --------------------------
1182 c beta = scratch vector.
1183 c gamma = scratch vector.
1184 c l (input) lower triangular matrix, stored rowwise.
1185 c lambda = scratch vector.
1186 c lplus (output) lower triangular matrix, stored rowwise, which may
1187 c occupy the same storage as l.
1188 c n (input) length of vector parameters and order of matrices.
1189 c w (input, destroyed on output) right singular vector of rank 1
1191 c z (input, destroyed on output) left singular vector of rank 1
1194 c------------------------------- notes -------------------------------
1196 c *** application and usage restrictions ***
1198 c this routine updates the cholesky factor l of a symmetric
1199 c positive definite matrix to which a secant update is being
1200 c applied -- it computes a cholesky factor lplus of
1201 c l * (i + z*w**t) * (i + w*z**t) * l**t. it is assumed that w
1202 c and z have been chosen so that the updated matrix is strictly
1203 c positive definite.
1205 c *** algorithm notes ***
1207 c this code uses recurrence 3 of ref. 1 (with d(j) = 1 for all j)
1208 c to compute lplus of the form l * (i + z*w**t) * q, where q
1209 c is an orthogonal matrix that makes the result lower triangular.
1210 c lplus may have some negative diagonal elements.
1212 c *** references ***
1214 c 1. goldfarb, d. (1976), factorized variable metric methods for uncon-
1215 c strained optimization, math. comput. 30, pp. 796-811.
1219 c coded by david m. gay (fall 1979).
1220 c this subroutine was written in connection with research supported
1221 c by the national science foundation under grants mcs-7600324 and
1224 c------------------------ external quantities ------------------------
1226 c *** intrinsic functions ***
1228 double precision dsqrt
1230 c-------------------------- local variables --------------------------
1232 integer i, ij, j, jj, jp1, k, nm1, np1
1233 double precision a, b, bj, eta, gj, lj, lij, ljj, nu, s, theta,
1235 double precision one, zero
1237 c *** data initializations ***
1240 c data one/1.d+0/, zero/0.d+0/
1242 parameter (one=1.d+0, zero=0.d+0)
1245 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
1249 if (n .le. 1) go to 30
1252 c *** temporarily store s(j) = sum over k = j+1 to n of w(k)**2 in
1262 c *** compute lambda, gamma, and beta by goldfarb*s recurrence 3.
1266 a = nu*z(j) - eta*wj
1269 lj = dsqrt(theta**2 + a*s)
1270 if (theta .gt. zero) lj = -lj
1273 gamma(j) = b * nu / lj
1274 beta(j) = (a - b*eta) / lj
1276 eta = -(eta + (a**2)/(theta - lj)) / lj
1278 30 lambda(n) = one + (nu*z(n) - eta*w(n))*w(n)
1280 c *** update l, gradually overwriting w and z with l*w and l*z.
1283 jj = n * (n + 1) / 2
1288 lplus(jj) = lj * ljj
1293 if (k .eq. 1) go to 50
1300 lplus(ij) = lj*lij + bj*w(i) + gj*z(i)
1301 w(i) = w(i) + lij*wj
1302 z(i) = z(i) + lij*zj
1309 c *** last card of lupdat follows ***
1311 subroutine lvmul(n, x, l, y)
1313 c *** compute x = l*y, where l is an n x n lower triangular
1314 c *** matrix stored compactly by rows. x and y may occupy the same
1318 cal double precision x(n), l(1), y(n)
1319 double precision x(n), l(n*(n+1)/2), y(n)
1320 c dimension l(n*(n+1)/2)
1321 integer i, ii, ij, i0, j, np1
1322 double precision t, zero
1326 parameter (zero=0.d+0)
1342 c *** last card of lvmul follows ***
1344 subroutine vvmulp(n, x, y, z, k)
1346 c *** set x(i) = y(i) * z(i)**k, 1 .le. i .le. n (for k = 1 or -1) ***
1349 double precision x(n), y(n), z(n)
1352 if (k .ge. 0) go to 20
1354 10 x(i) = y(i) / z(i)
1358 30 x(i) = y(i) * z(i)
1360 c *** last card of vvmulp follows ***
1362 subroutine wzbfgs (l, n, s, w, y, z)
1364 c *** compute y and z for lupdat corresponding to bfgs update.
1367 cal double precision l(1), s(n), w(n), y(n), z(n)
1368 double precision l(n*(n+1)/2), s(n), w(n), y(n), z(n)
1369 c dimension l(n*(n+1)/2)
1371 c-------------------------- parameter usage --------------------------
1373 c l (i/o) cholesky factor of hessian, a lower triang. matrix stored
1374 c compactly by rows.
1375 c n (input) order of l and length of s, w, y, z.
1376 c s (input) the step just taken.
1377 c w (output) right singular vector of rank 1 correction to l.
1378 c y (input) change in gradients corresponding to s.
1379 c z (output) left singular vector of rank 1 correction to l.
1381 c------------------------------- notes -------------------------------
1383 c *** algorithm notes ***
1385 c when s is computed in certain ways, e.g. by gqtstp or
1386 c dbldog, it is possible to save n**2/2 operations since (l**t)*s
1387 c or l*(l**t)*s is then known.
1388 c if the bfgs update to l*(l**t) would reduce its determinant to
1389 c less than eps times its old value, then this routine in effect
1390 c replaces y by theta*y + (1 - theta)*l*(l**t)*s, where theta
1391 c (between 0 and 1) is chosen to make the reduction factor = eps.
1395 c coded by david m. gay (fall 1979).
1396 c this subroutine was written in connection with research supported
1397 c by the national science foundation under grants mcs-7600324 and
1400 c------------------------ external quantities ------------------------
1402 c *** functions and subroutines called ***
1404 external dotprd, livmul, ltvmul
1405 double precision dotprd
1406 c dotprd returns inner product of two vectors.
1407 c livmul multiplies l**-1 times a vector.
1408 c ltvmul multiplies l**t times a vector.
1410 c *** intrinsic functions ***
1412 double precision dsqrt
1414 c-------------------------- local variables --------------------------
1417 double precision cs, cy, eps, epsrt, one, shs, ys, theta
1419 c *** data initializations ***
1422 c data eps/0.1d+0/, one/1.d+0/
1424 parameter (eps=0.1d+0, one=1.d+0)
1427 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
1429 call ltvmul(n, w, l, s)
1430 shs = dotprd(n, w, w)
1431 ys = dotprd(n, y, s)
1432 if (ys .ge. eps*shs) go to 10
1433 theta = (one - eps) * shs / (shs - ys)
1435 cy = theta / (shs * epsrt)
1436 cs = (one + (theta-one)/epsrt) / shs
1438 10 cy = one / (dsqrt(ys) * dsqrt(shs))
1440 20 call livmul(n, z, l, y)
1442 30 z(i) = cy * z(i) - cs * w(i)
1445 c *** last card of wzbfgs follows ***