1 subroutine assst(iv, liv, lv, v)
3 c *** assess candidate step (***sol version 2.3) ***
11 c this subroutine is called by an unconstrained minimization
12 c routine to assess the next candidate step. it may recommend one
13 c of several courses of action, such as accepting the step, recom-
14 c puting it using the same or a new quadratic model, or halting due
15 c to convergence or false convergence. see the return code listing
18 c-------------------------- parameter usage --------------------------
20 c iv (i/o) integer parameter and scratch vector -- see description
21 c below of iv values referenced.
22 c liv (in) length of iv array.
23 c lv (in) length of v array.
24 c v (i/o) real parameter and scratch vector -- see description
25 c below of v values referenced.
27 c *** iv values referenced ***
29 c iv(irc) (i/o) on input for the first step tried in a new iteration,
30 c iv(irc) should be set to 3 or 4 (the value to which it is
31 c set when step is definitely to be accepted). on input
32 c after step has been recomputed, iv(irc) should be
33 c unchanged since the previous return of assst.
34 c on output, iv(irc) is a return code having one of the
36 c 1 = switch models or try smaller step.
37 c 2 = switch models or accept step.
38 c 3 = accept step and determine v(radfac) by gradient
40 c 4 = accept step, v(radfac) has been determined.
41 c 5 = recompute step (using the same model).
42 c 6 = recompute step with radius = v(lmaxs) but do not
43 c evaulate the objective function.
44 c 7 = x-convergence (see v(xctol)).
45 c 8 = relative function convergence (see v(rfctol)).
46 c 9 = both x- and relative function convergence.
47 c 10 = absolute function convergence (see v(afctol)).
48 c 11 = singular convergence (see v(lmaxs)).
49 c 12 = false convergence (see v(xftol)).
50 c 13 = iv(irc) was out of range on input.
51 c return code i has precdence over i+1 for i = 9, 10, 11.
52 c iv(mlstgd) (i/o) saved value of iv(model).
53 c iv(model) (i/o) on input, iv(model) should be an integer identifying
54 c the current quadratic model of the objective function.
55 c if a previous step yielded a better function reduction,
56 c then iv(model) will be set to iv(mlstgd) on output.
57 c iv(nfcall) (in) invocation count for the objective function.
58 c iv(nfgcal) (i/o) value of iv(nfcall) at step that gave the biggest
59 c function reduction this iteration. iv(nfgcal) remains
60 c unchanged until a function reduction is obtained.
61 c iv(radinc) (i/o) the number of radius increases (or minus the number
62 c of decreases) so far this iteration.
63 c iv(restor) (out) set to 1 if v(f) has been restored and x should be
64 c restored to its initial value, to 2 if x should be saved,
65 c to 3 if x should be restored from the saved value, and to
67 c iv(stage) (i/o) count of the number of models tried so far in the
69 c iv(stglim) (in) maximum number of models to consider.
70 c iv(switch) (out) set to 0 unless a new model is being tried and it
71 c gives a smaller function value than the previous model,
72 c in which case assst sets iv(switch) = 1.
73 c iv(toobig) (in) is nonzero if step was too big (e.g. if it caused
75 c iv(xirc) (i/o) value that iv(irc) would have in the absence of
76 c convergence, false convergence, and oversized steps.
78 c *** v values referenced ***
80 c v(afctol) (in) absolute function convergence tolerance. if the
81 c absolute value of the current function value v(f) is less
82 c than v(afctol), then assst returns with iv(irc) = 10.
83 c v(decfac) (in) factor by which to decrease radius when iv(toobig) is
85 c v(dstnrm) (in) the 2-norm of d*step.
86 c v(dstsav) (i/o) value of v(dstnrm) on saved step.
87 c v(dst0) (in) the 2-norm of d times the newton step (when defined,
88 c i.e., for v(nreduc) .ge. 0).
89 c v(f) (i/o) on both input and output, v(f) is the objective func-
90 c tion value at x. if x is restored to a previous value,
91 c then v(f) is restored to the corresponding value.
92 c v(fdif) (out) the function reduction v(f0) - v(f) (for the output
93 c value of v(f) if an earlier step gave a bigger function
94 c decrease, and for the input value of v(f) otherwise).
95 c v(flstgd) (i/o) saved value of v(f).
96 c v(f0) (in) objective function value at start of iteration.
97 c v(gtslst) (i/o) value of v(gtstep) on saved step.
98 c v(gtstep) (in) inner product between step and gradient.
99 c v(incfac) (in) minimum factor by which to increase radius.
100 c v(lmaxs) (in) maximum reasonable step size (and initial step bound).
101 c if the actual function decrease is no more than twice
102 c what was predicted, if a return with iv(irc) = 7, 8, 9,
103 c or 10 does not occur, if v(dstnrm) .gt. v(lmaxs), and if
104 c v(preduc) .le. v(sctol) * abs(v(f0)), then assst re-
105 c turns with iv(irc) = 11. if so doing appears worthwhile,
106 c then assst repeats this test with v(preduc) computed for
107 c a step of length v(lmaxs) (by a return with iv(irc) = 6).
108 c v(nreduc) (i/o) function reduction predicted by quadratic model for
109 c newton step. if assst is called with iv(irc) = 6, i.e.,
110 c if v(preduc) has been computed with radius = v(lmaxs) for
111 c use in the singular convervence test, then v(nreduc) is
112 c set to -v(preduc) before the latter is restored.
113 c v(plstgd) (i/o) value of v(preduc) on saved step.
114 c v(preduc) (i/o) function reduction predicted by quadratic model for
116 c v(radfac) (out) factor to be used in determining the new radius,
117 c which should be v(radfac)*dst, where dst is either the
118 c output value of v(dstnrm) or the 2-norm of
119 c diag(newd)*step for the output value of step and the
120 c updated version, newd, of the scale vector d. for
121 c iv(irc) = 3, v(radfac) = 1.0 is returned.
122 c v(rdfcmn) (in) minimum value for v(radfac) in terms of the input
123 c value of v(dstnrm) -- suggested value = 0.1.
124 c v(rdfcmx) (in) maximum value for v(radfac) -- suggested value = 4.0.
125 c v(reldx) (in) scaled relative change in x caused by step, computed
126 c (e.g.) by function reldst as
127 c max (d(i)*abs(x(i)-x0(i)), 1 .le. i .le. p) /
128 c max (d(i)*(abs(x(i))+abs(x0(i))), 1 .le. i .le. p).
129 c v(rfctol) (in) relative function convergence tolerance. if the
130 c actual function reduction is at most twice what was pre-
131 c dicted and v(nreduc) .le. v(rfctol)*abs(v(f0)), then
132 c assst returns with iv(irc) = 8 or 9.
133 c v(stppar) (in) marquardt parameter -- 0 means full newton step.
134 c v(tuner1) (in) tuning constant used to decide if the function
135 c reduction was much less than expected. suggested
137 c v(tuner2) (in) tuning constant used to decide if the function
138 c reduction was large enough to accept step. suggested
140 c v(tuner3) (in) tuning constant used to decide if the radius
141 c should be increased. suggested value = 0.75.
142 c v(xctol) (in) x-convergence criterion. if step is a newton step
143 c (v(stppar) = 0) having v(reldx) .le. v(xctol) and giving
144 c at most twice the predicted function decrease, then
145 c assst returns iv(irc) = 7 or 9.
146 c v(xftol) (in) false convergence tolerance. if step gave no or only
147 c a small function decrease and v(reldx) .le. v(xftol),
148 c then assst returns with iv(irc) = 12.
150 c------------------------------- notes -------------------------------
152 c *** application and usage restrictions ***
154 c this routine is called as part of the nl2sol (nonlinear
155 c least-squares) package. it may be used in any unconstrained
156 c minimization solver that uses dogleg, goldfeld-quandt-trotter,
157 c or levenberg-marquardt steps.
159 c *** algorithm notes ***
161 c see (1) for further discussion of the assessing and model
162 c switching strategies. while nl2sol considers only two models,
163 c assst is designed to handle any number of models.
165 c *** usage notes ***
167 c on the first call of an iteration, only the i/o variables
168 c step, x, iv(irc), iv(model), v(f), v(dstnrm), v(gtstep), and
169 c v(preduc) need have been initialized. between calls, no i/o
170 c values execpt step, x, iv(model), v(f) and the stopping toler-
171 c ances should be changed.
172 c after a return for convergence or false convergence, one can
173 c change the stopping tolerances and call assst again, in which
174 c case the stopping tests will be repeated.
178 c (1) dennis, j.e., jr., gay, d.m., and welsch, r.e. (1981),
179 c an adaptive nonlinear least-squares algorithm,
180 c acm trans. math. software, vol. 7, no. 3.
182 c (2) powell, m.j.d. (1970) a fortran subroutine for solving
183 c systems of nonlinear algebraic equations, in numerical
184 c methods for nonlinear algebraic equations, edited by
185 c p. rabinowitz, gordon and breach, london.
189 c john dennis designed much of this routine, starting with
190 c ideas in (2). roy welsch suggested the model switching strategy.
191 c david gay and stephen peters cast this subroutine into a more
192 c portable form (winter 1977), and david gay cast it into its
193 c present form (fall 1978).
197 c this subroutine was written in connection with research
198 c supported by the national science foundation under grants
199 c mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989, and
202 c------------------------ external quantities ------------------------
204 c *** no external functions and subroutines ***
206 c *** intrinsic functions ***
208 double precision dabs, dmax1
210 c *** no common blocks ***
212 c-------------------------- local variables --------------------------
216 double precision emax, emaxs, gts, rfac1, xmax
217 double precision half, one, onep2, two, zero
219 c *** subscripts for iv and v ***
221 integer afctol, decfac, dstnrm, dstsav, dst0, f, fdif, flstgd, f0,
222 1 gtslst, gtstep, incfac, irc, lmaxs, mlstgd, model, nfcall,
223 2 nfgcal, nreduc, plstgd, preduc, radfac, radinc, rdfcmn,
224 3 rdfcmx, reldx, restor, rfctol, sctol, stage, stglim,
225 4 stppar, switch, toobig, tuner1, tuner2, tuner3, xctol,
228 c *** data initializations ***
231 c data half/0.5d+0/, one/1.d+0/, onep2/1.2d+0/, two/2.d+0/,
234 parameter (half=0.5d+0, one=1.d+0, onep2=1.2d+0, two=2.d+0,
239 c data irc/29/, mlstgd/32/, model/5/, nfcall/6/, nfgcal/7/,
240 c 1 radinc/8/, restor/9/, stage/10/, stglim/11/, switch/12/,
241 c 2 toobig/2/, xirc/13/
243 parameter (irc=29, mlstgd=32, model=5, nfcall=6, nfgcal=7,
244 1 radinc=8, restor=9, stage=10, stglim=11, switch=12,
248 c data afctol/31/, decfac/22/, dstnrm/2/, dst0/3/, dstsav/18/,
249 c 1 f/10/, fdif/11/, flstgd/12/, f0/13/, gtslst/14/, gtstep/4/,
250 c 2 incfac/23/, lmaxs/36/, nreduc/6/, plstgd/15/, preduc/7/,
251 c 3 radfac/16/, rdfcmn/24/, rdfcmx/25/, reldx/17/, rfctol/32/,
252 c 4 sctol/37/, stppar/5/, tuner1/26/, tuner2/27/, tuner3/28/,
253 c 5 xctol/33/, xftol/34/
255 parameter (afctol=31, decfac=22, dstnrm=2, dst0=3, dstsav=18,
256 1 f=10, fdif=11, flstgd=12, f0=13, gtslst=14, gtstep=4,
257 2 incfac=23, lmaxs=36, nreduc=6, plstgd=15, preduc=7,
258 3 radfac=16, rdfcmn=24, rdfcmx=25, reldx=17, rfctol=32,
259 4 sctol=37, stppar=5, tuner1=26, tuner2=27, tuner3=28,
260 5 xctol=33, xftol=34)
263 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
271 if (i .ge. 1 .and. i .le. 12)
272 1 go to (20,30,10,10,40,280,220,220,220,220,220,170), i
276 c *** initialize for new iteration ***
281 if (iv(toobig) .eq. 0) go to 110
286 c *** step was recomputed with new model or smaller radius ***
287 c *** first decide which ***
289 20 if (iv(model) .ne. iv(mlstgd)) go to 30
290 c *** old model retained, smaller radius tried ***
291 c *** do not consider any more new models this iteration ***
292 iv(stage) = iv(stglim)
296 c *** a new model is being tried. decide whether to keep it. ***
298 30 iv(stage) = iv(stage) + 1
300 c *** now we add the possibiltiy that step was recomputed with ***
301 c *** the same model, perhaps because of an oversized step. ***
303 40 if (iv(stage) .gt. 0) go to 50
305 c *** step was recomputed because it was too big. ***
307 if (iv(toobig) .ne. 0) go to 60
309 c *** restore iv(stage) and pick up where we left off. ***
311 iv(stage) = -iv(stage)
313 go to (20, 30, 110, 110, 70), i
315 50 if (iv(toobig) .eq. 0) go to 70
317 c *** handle oversize step ***
319 if (iv(radinc) .gt. 0) go to 80
320 iv(stage) = -iv(stage)
323 60 v(radfac) = v(decfac)
324 iv(radinc) = iv(radinc) - 1
329 70 if (v(f) .lt. v(flstgd)) go to 110
331 c *** the new step is a loser. restore old model. ***
333 if (iv(model) .eq. iv(mlstgd)) go to 80
334 iv(model) = iv(mlstgd)
337 c *** restore step, etc. only if a previous step decreased v(f).
339 80 if (v(flstgd) .ge. v(f0)) go to 110
342 v(preduc) = v(plstgd)
343 v(gtstep) = v(gtslst)
344 if (iv(switch) .eq. 0) rfac1 = v(dstnrm) / v(dstsav)
345 v(dstnrm) = v(dstsav)
349 110 v(fdif) = v(f0) - v(f)
350 if (v(fdif) .gt. v(tuner2) * v(preduc)) go to 140
351 if(iv(radinc).gt.0) go to 140
353 c *** no (or only a trivial) function decrease
354 c *** -- so try new model or smaller radius
356 if (v(f) .lt. v(f0)) go to 120
357 iv(mlstgd) = iv(model)
364 if (iv(stage) .lt. iv(stglim)) go to 160
366 iv(radinc) = iv(radinc) - 1
369 c *** nontrivial function decrease achieved ***
373 v(dstsav) = v(dstnrm)
374 if (v(fdif) .gt. v(preduc)*v(tuner1)) go to 190
376 c *** decrease was much less than predicted -- either change models
377 c *** or accept step with decreased radius.
379 if (iv(stage) .ge. iv(stglim)) go to 150
380 c *** consider switching models ***
384 c *** accept step with decreased radius ***
388 c *** set v(radfac) to fletcher*s decrease factor ***
390 160 iv(xirc) = iv(irc)
391 emax = v(gtstep) + v(fdif)
392 v(radfac) = half * rfac1
393 if (emax .lt. v(gtstep)) v(radfac) = rfac1 * dmax1(v(rdfcmn),
394 1 half * v(gtstep)/emax)
396 c *** do false convergence test ***
398 170 if (v(reldx) .le. v(xftol)) go to 180
400 if (v(f) .lt. v(f0)) go to 200
406 c *** handle good function decrease ***
408 190 if (v(fdif) .lt. (-v(tuner3) * v(gtstep))) go to 210
410 c *** increasing radius looks worthwhile. see if we just
411 c *** recomputed step with a decreased radius or restored step
412 c *** after recomputing it with a larger radius.
414 if (iv(radinc) .lt. 0) go to 210
415 if (iv(restor) .eq. 1) go to 210
417 c *** we did not. try a longer step unless this was a newton
420 v(radfac) = v(rdfcmx)
422 if (v(fdif) .lt. (half/v(radfac) - one) * gts)
423 1 v(radfac) = dmax1(v(incfac), half*gts/(gts + v(fdif)))
425 if (v(stppar) .eq. zero) go to 230
426 if (v(dst0) .ge. zero .and. (v(dst0) .lt. two*v(dstnrm)
427 1 .or. v(nreduc) .lt. onep2*v(fdif))) go to 230
428 c *** step was not a newton step. recompute it with
429 c *** a larger radius.
431 iv(radinc) = iv(radinc) + 1
433 c *** save values corresponding to good step ***
436 iv(mlstgd) = iv(model)
437 if (iv(restor) .ne. 1) iv(restor) = 2
438 v(dstsav) = v(dstnrm)
440 v(plstgd) = v(preduc)
441 v(gtslst) = v(gtstep)
444 c *** accept step with radius unchanged ***
450 c *** come here for a restart after convergence ***
452 220 iv(irc) = iv(xirc)
453 if (v(dstsav) .ge. zero) go to 240
457 c *** perform convergence tests ***
459 230 iv(xirc) = iv(irc)
460 240 if (iv(restor) .eq. 1 .and. v(flstgd) .lt. v(f0)) iv(restor) = 3
461 if (half * v(fdif) .gt. v(preduc)) go to 999
462 emax = v(rfctol) * dabs(v(f0))
463 emaxs = v(sctol) * dabs(v(f0))
464 if (v(dstnrm) .gt. v(lmaxs) .and. v(preduc) .le. emaxs)
466 if (v(dst0) .lt. zero) go to 250
468 if ((v(nreduc) .gt. zero .and. v(nreduc) .le. emax) .or.
469 1 (v(nreduc) .eq. zero. and. v(preduc) .eq. zero)) i = 2
470 if (v(stppar) .eq. zero .and. v(reldx) .le. v(xctol)
471 1 .and. goodx) i = i + 1
472 if (i .gt. 0) iv(irc) = i + 6
474 c *** consider recomputing step of length v(lmaxs) for singular
475 c *** convergence test.
477 250 if (iv(irc) .gt. 5 .and. iv(irc) .ne. 12) go to 999
478 if (v(dstnrm) .gt. v(lmaxs)) go to 260
479 if (v(preduc) .ge. emaxs) go to 999
480 if (v(dst0) .le. zero) go to 270
481 if (half * v(dst0) .le. v(lmaxs)) go to 999
483 260 if (half * v(dstnrm) .le. v(lmaxs)) go to 999
484 xmax = v(lmaxs) / v(dstnrm)
485 if (xmax * (two - xmax) * v(preduc) .ge. emaxs) go to 999
486 270 if (v(nreduc) .lt. zero) go to 290
488 c *** recompute v(preduc) for use in singular convergence test ***
490 v(gtslst) = v(gtstep)
491 v(dstsav) = v(dstnrm)
492 if (iv(irc) .eq. 12) v(dstsav) = -v(dstsav)
493 v(plstgd) = v(preduc)
496 if (i .eq. 3) iv(restor) = 0
500 c *** perform singular convergence test with recomputed v(preduc) ***
502 280 v(gtstep) = v(gtslst)
503 v(dstnrm) = dabs(v(dstsav))
505 if (v(dstsav) .le. zero) iv(irc) = 12
506 v(nreduc) = -v(preduc)
507 v(preduc) = v(plstgd)
509 290 if (-v(nreduc) .le. v(sctol) * dabs(v(f0))) iv(irc) = 11
513 c *** last card of assst follows ***
515 subroutine deflt(alg, iv, liv, lv, v)
517 c *** supply ***sol (version 2.3) default values to iv and v ***
519 c *** alg = 1 means regression constants.
520 c *** alg = 2 means general unconstrained optimization constants.
524 double precision v(lv)
526 external imdcon, vdflt
528 c imdcon... returns machine-dependent integer constants.
529 c vdflt.... provides default values to v.
532 integer miniv(2), minv(2)
534 c *** subscripts for iv ***
536 integer algsav, covprt, covreq, dtype, hc, ierr, inith, inits,
537 1 ipivot, ivneed, lastiv, lastv, lmat, mxfcal, mxiter,
538 2 nfcov, ngcov, nvdflt, outlev, parprt, parsav, perm,
539 3 prunit, qrtyp, rdreq, rmat, solprt, statpr, vneed,
542 c *** iv subscript values ***
545 c data algsav/51/, covprt/14/, covreq/15/, dtype/16/, hc/71/,
546 c 1 ierr/75/, inith/25/, inits/25/, ipivot/76/, ivneed/3/,
547 c 2 lastiv/44/, lastv/45/, lmat/42/, mxfcal/17/, mxiter/18/,
548 c 3 nfcov/52/, ngcov/53/, nvdflt/50/, outlev/19/, parprt/20/,
549 c 4 parsav/49/, perm/58/, prunit/21/, qrtyp/80/, rdreq/57/,
550 c 5 rmat/78/, solprt/22/, statpr/23/, vneed/4/, vsave/60/,
553 parameter (algsav=51, covprt=14, covreq=15, dtype=16, hc=71,
554 1 ierr=75, inith=25, inits=25, ipivot=76, ivneed=3,
555 2 lastiv=44, lastv=45, lmat=42, mxfcal=17, mxiter=18,
556 3 nfcov=52, ngcov=53, nvdflt=50, outlev=19, parprt=20,
557 4 parsav=49, perm=58, prunit=21, qrtyp=80, rdreq=57,
558 5 rmat=78, solprt=22, statpr=23, vneed=4, vsave=60,
561 data miniv(1)/80/, miniv(2)/59/, minv(1)/98/, minv(2)/71/
563 c------------------------------- body --------------------------------
565 if (alg .lt. 1 .or. alg .gt. 2) go to 40
567 if (liv .lt. miv) go to 20
569 if (lv .lt. mv) go to 30
570 call vdflt(alg, lv, v)
582 iv(prunit) = imdcon(1)
588 if (alg .ge. 2) go to 10
590 c *** regression values
607 c *** general optimization values
626 c *** last card of deflt follows ***
628 double precision function dotprd(p, x, y)
630 c *** return the inner product of the p-vectors x and y. ***
633 double precision x(p), y(p)
636 double precision one, sqteta, t, zero
638 double precision dmax1, dabs
641 double precision rmdcon
643 c *** rmdcon(2) returns a machine-dependent constant, sqteta, which
644 c *** is slightly larger than the smallest positive number that
645 c *** can be squared without underflowing.
648 c data one/1.d+0/, sqteta/0.d+0/, zero/0.d+0/
650 parameter (one=1.d+0, zero=0.d+0)
655 if (p .le. 0) go to 999
656 crc if (sqteta .eq. zero) sqteta = rmdcon(2)
658 crc t = dmax1(dabs(x(i)), dabs(y(i)))
659 crc if (t .gt. one) go to 10
660 crc if (t .lt. sqteta) go to 20
661 crc t = (x(i)/sqteta)*y(i)
662 crc if (dabs(t) .lt. sqteta) go to 20
663 10 dotprd = dotprd + x(i)*y(i)
667 c *** last card of dotprd follows ***
669 subroutine itsum(d, g, iv, liv, lv, p, v, x)
671 c *** print iteration summary for ***sol (version 2.3) ***
673 c *** parameter declarations ***
677 double precision d(p), g(p), v(lv), x(p)
679 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
681 c *** local variables ***
683 integer alg, i, iv1, m, nf, ng, ol, pu
685 c real model1(6), model2(6)
687 character*4 model1(6), model2(6)
689 double precision nreldf, oldf, preldf, reldf, zero
691 c *** intrinsic functions ***
694 double precision dabs, dmax1
696 c *** no external functions or subroutines ***
698 c *** subscripts for iv and v ***
700 integer algsav, dstnrm, f, fdif, f0, needhd, nfcall, nfcov, ngcov,
701 1 ngcall, niter, nreduc, outlev, preduc, prntit, prunit,
702 2 reldx, solprt, statpr, stppar, sused, x0prt
704 c *** iv subscript values ***
707 c data algsav/51/, needhd/36/, nfcall/6/, nfcov/52/, ngcall/30/,
708 c 1 ngcov/53/, niter/31/, outlev/19/, prntit/39/, prunit/21/,
709 c 2 solprt/22/, statpr/23/, sused/64/, x0prt/24/
711 parameter (algsav=51, needhd=36, nfcall=6, nfcov=52, ngcall=30,
712 1 ngcov=53, niter=31, outlev=19, prntit=39, prunit=21,
713 2 solprt=22, statpr=23, sused=64, x0prt=24)
716 c *** v subscript values ***
719 c data dstnrm/2/, f/10/, f0/13/, fdif/11/, nreduc/6/, preduc/7/,
720 c 1 reldx/17/, stppar/5/
722 parameter (dstnrm=2, f=10, f0=13, fdif=11, nreduc=6, preduc=7,
723 1 reldx=17, stppar=5)
729 parameter (zero=0.d+0)
732 c data model1(1)/4h /, model1(2)/4h /, model1(3)/4h /,
733 c 1 model1(4)/4h /, model1(5)/4h g /, model1(6)/4h s /,
734 c 2 model2(1)/4h g /, model2(2)/4h s /, model2(3)/4hg-s /,
735 c 3 model2(4)/4hs-g /, model2(5)/4h-s-g/, model2(6)/4h-g-s/
737 data model1/' ',' ',' ',' ',' g ',' s '/,
738 1 model2/' g ',' s ','g-s ','s-g ','-s-g','-g-s'/
741 c------------------------------- body --------------------------------
744 if (pu .eq. 0) go to 999
746 if (iv1 .gt. 62) iv1 = iv1 - 51
749 if (iv1 .lt. 2 .or. iv1 .gt. 15) go to 370
750 if (iv1 .ge. 12) go to 120
751 if (iv1 .eq. 2 .and. iv(niter) .eq. 0) go to 390
752 if (ol .eq. 0) go to 120
753 if (iv1 .ge. 10 .and. iv(prntit) .eq. 0) go to 120
754 if (iv1 .gt. 2) go to 10
755 iv(prntit) = iv(prntit) + 1
756 if (iv(prntit) .lt. iabs(ol)) go to 999
757 10 nf = iv(nfcall) - iabs(iv(nfcov))
761 oldf = dmax1(dabs(v(f0)), dabs(v(f)))
762 if (oldf .le. zero) go to 20
763 reldf = v(fdif) / oldf
764 preldf = v(preduc) / oldf
765 20 if (ol .gt. 0) go to 60
767 c *** print short summary line ***
769 if (iv(needhd) .eq. 1 .and. alg .eq. 1) write(pu,30)
770 30 format(/10h it nf,6x,1hf,7x,5hreldf,3x,6hpreldf,3x,5hreldx,
771 1 2x,13hmodel stppar)
772 if (iv(needhd) .eq. 1 .and. alg .eq. 2) write(pu,40)
773 40 format(/11h it nf,7x,1hf,8x,5hreldf,4x,6hpreldf,4x,5hreldx,
776 if (alg .eq. 2) go to 50
778 write(pu,100) iv(niter), nf, v(f), reldf, preldf, v(reldx),
779 1 model1(m), model2(m), v(stppar)
782 50 write(pu,110) iv(niter), nf, v(f), reldf, preldf, v(reldx),
786 c *** print long summary line ***
788 60 if (iv(needhd) .eq. 1 .and. alg .eq. 1) write(pu,70)
789 70 format(/11h it nf,6x,1hf,7x,5hreldf,3x,6hpreldf,3x,5hreldx,
790 1 2x,13hmodel stppar,2x,6hd*step,2x,7hnpreldf)
791 if (iv(needhd) .eq. 1 .and. alg .eq. 2) write(pu,80)
792 80 format(/11h it nf,7x,1hf,8x,5hreldf,4x,6hpreldf,4x,5hreldx,
793 1 3x,6hstppar,3x,6hd*step,3x,7hnpreldf)
796 if (oldf .gt. zero) nreldf = v(nreduc) / oldf
797 if (alg .eq. 2) go to 90
799 write(pu,100) iv(niter), nf, v(f), reldf, preldf, v(reldx),
800 1 model1(m), model2(m), v(stppar), v(dstnrm), nreldf
803 90 write(pu,110) iv(niter), nf, v(f), reldf, preldf,
804 1 v(reldx), v(stppar), v(dstnrm), nreldf
805 100 format(i6,i5,d10.3,2d9.2,d8.1,a3,a4,2d8.1,d9.2)
806 110 format(i6,i5,d11.3,2d10.2,3d9.1,d10.2)
808 120 if (iv(statpr) .lt. 0) go to 430
809 go to (999, 999, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310,
810 1 330, 350, 520), iv1
813 140 format(/26h ***** x-convergence *****)
817 160 format(/42h ***** relative function convergence *****)
821 180 format(/49h ***** x- and relative function convergence *****)
825 200 format(/42h ***** absolute function convergence *****)
829 220 format(/33h ***** singular convergence *****)
833 240 format(/30h ***** false convergence *****)
837 260 format(/38h ***** function evaluation limit *****)
841 280 format(/28h ***** iteration limit *****)
845 300 format(/18h ***** stopx *****)
849 320 format(/44h ***** initial f(x) cannot be computed *****)
854 340 format(/37h ***** bad parameters to assess *****)
858 360 format(/43h ***** gradient could not be computed *****)
859 if (iv(niter) .gt. 0) go to 480
862 370 write(pu,380) iv(1)
863 380 format(/14h ***** iv(1) =,i5,6h *****)
866 c *** initial call on itsum ***
868 390 if (iv(x0prt) .ne. 0) write(pu,400) (i, x(i), d(i), i = 1, p)
869 400 format(/23h i initial x(i),8x,4hd(i)//(1x,i5,d17.6,d14.3))
870 c *** the following are to avoid undefined variables when the
871 c *** function evaluation limit is 1...
877 if (iv1 .ge. 12) go to 999
880 if (ol .eq. 0) go to 999
881 if (ol .lt. 0 .and. alg .eq. 1) write(pu,30)
882 if (ol .lt. 0 .and. alg .eq. 2) write(pu,40)
883 if (ol .gt. 0 .and. alg .eq. 1) write(pu,70)
884 if (ol .gt. 0 .and. alg .eq. 2) write(pu,80)
885 if (alg .eq. 1) write(pu,410) v(f)
886 if (alg .eq. 2) write(pu,420) v(f)
887 410 format(/11h 0 1,d10.3)
888 c365 format(/11h 0 1,e11.3)
889 420 format(/11h 0 1,d11.3)
892 c *** print various information requested on solution ***
895 if (iv(statpr) .eq. 0) go to 480
896 oldf = dmax1(dabs(v(f0)), dabs(v(f)))
899 if (oldf .le. zero) go to 440
900 preldf = v(preduc) / oldf
901 nreldf = v(nreduc) / oldf
902 440 nf = iv(nfcall) - iv(nfcov)
903 ng = iv(ngcall) - iv(ngcov)
904 write(pu,450) v(f), v(reldx), nf, ng, preldf, nreldf
905 450 format(/9h function,d17.6,8h reldx,d17.3/12h func. evals,
906 1 i8,9x,11hgrad. evals,i8/7h preldf,d16.3,6x,7hnpreldf,d15.3)
908 if (iv(nfcov) .gt. 0) write(pu,460) iv(nfcov)
909 460 format(/1x,i4,50h extra func. evals for covariance and diagnost
911 if (iv(ngcov) .gt. 0) write(pu,470) iv(ngcov)
912 470 format(1x,i4,50h extra grad. evals for covariance and diagnosti
915 480 if (iv(solprt) .eq. 0) go to 999
918 490 format(/22h i final x(i),8x,4hd(i),10x,4hg(i)/)
920 write(pu,510) i, x(i), d(i), g(i)
922 510 format(1x,i5,d16.6,2d14.3)
926 530 format(/24h inconsistent dimensions)
928 c *** last card of itsum follows ***
930 subroutine litvmu(n, x, l, y)
932 c *** solve (l**t)*x = y, where l is an n x n lower triangular
933 c *** matrix stored compactly by rows. x and y may occupy the same
937 cal double precision x(n), l(1), y(n)
938 double precision x(n), l(n*(n+1)/2), y(n)
939 integer i, ii, ij, im1, i0, j, np1
940 double precision xi, zero
944 parameter (zero=0.d+0)
955 if (i .le. 1) go to 999
957 if (xi .eq. zero) go to 30
961 x(j) = x(j) - xi*l(ij)
965 c *** last card of litvmu follows ***
967 subroutine livmul(n, x, l, y)
969 c *** solve l*x = y, where l is an n x n lower triangular
970 c *** matrix stored compactly by rows. x and y may occupy the same
974 cal double precision x(n), l(1), y(n)
975 double precision x(n), l(n*(n+1)/2), y(n)
977 double precision dotprd
979 double precision t, zero
983 parameter (zero=0.d+0)
987 if (y(k) .ne. zero) go to 20
993 if (k .ge. n) go to 999
996 t = dotprd(i-1, l(j+1), x)
998 x(i) = (y(i) - t)/l(j)
1001 c *** last card of livmul follows ***
1003 subroutine parck(alg, d, iv, liv, lv, n, v)
1005 c *** check ***sol (version 2.3) parameters, print changed values ***
1007 c *** alg = 1 for regression, alg = 2 for general unconstrained opt.
1009 integer alg, liv, lv, n
1011 double precision d(n), v(lv)
1013 external rmdcon, vcopy, vdflt
1014 double precision rmdcon
1015 c rmdcon -- returns machine-dependent constants.
1016 c vcopy -- copies one vector to another.
1017 c vdflt -- supplies default parameter values to v alone.
1022 c *** local variables ***
1024 integer i, ii, iv1, j, k, l, m, miv1, miv2, ndfalt, parsv1, pu
1025 integer ijmp, jlim(2), miniv(2), ndflt(2)
1027 c integer varnm(2), sh(2)
1028 c real cngd(3), dflt(3), vn(2,34), which(3)
1030 character*1 varnm(2), sh(2)
1031 character*4 cngd(3), dflt(3), vn(2,34), which(3)
1033 double precision big, machep, tiny, vk, vm(34), vx(34), zero
1035 c *** iv and v subscripts ***
1037 integer algsav, dinit, dtype, dtype0, epslon, inits, ivneed,
1038 1 lastiv, lastv, lmat, nextiv, nextv, nvdflt, oldn,
1039 2 parprt, parsav, perm, prunit, vneed
1043 c data algsav/51/, dinit/38/, dtype/16/, dtype0/54/, epslon/19/,
1044 c 1 inits/25/, ivneed/3/, lastiv/44/, lastv/45/, lmat/42/,
1045 c 2 nextiv/46/, nextv/47/, nvdflt/50/, oldn/38/, parprt/20/,
1046 c 3 parsav/49/, perm/58/, prunit/21/, vneed/4/
1048 parameter (algsav=51, dinit=38, dtype=16, dtype0=54, epslon=19,
1049 1 inits=25, ivneed=3, lastiv=44, lastv=45, lmat=42,
1050 2 nextiv=46, nextv=47, nvdflt=50, oldn=38, parprt=20,
1051 3 parsav=49, perm=58, prunit=21, vneed=4)
1052 save big, machep, tiny
1055 data big/0.d+0/, machep/-1.d+0/, tiny/1.d+0/, zero/0.d+0/
1057 c data vn(1,1),vn(2,1)/4hepsl,4hon../
1058 c data vn(1,2),vn(2,2)/4hphmn,4hfc../
1059 c data vn(1,3),vn(2,3)/4hphmx,4hfc../
1060 c data vn(1,4),vn(2,4)/4hdecf,4hac../
1061 c data vn(1,5),vn(2,5)/4hincf,4hac../
1062 c data vn(1,6),vn(2,6)/4hrdfc,4hmn../
1063 c data vn(1,7),vn(2,7)/4hrdfc,4hmx../
1064 c data vn(1,8),vn(2,8)/4htune,4hr1../
1065 c data vn(1,9),vn(2,9)/4htune,4hr2../
1066 c data vn(1,10),vn(2,10)/4htune,4hr3../
1067 c data vn(1,11),vn(2,11)/4htune,4hr4../
1068 c data vn(1,12),vn(2,12)/4htune,4hr5../
1069 c data vn(1,13),vn(2,13)/4hafct,4hol../
1070 c data vn(1,14),vn(2,14)/4hrfct,4hol../
1071 c data vn(1,15),vn(2,15)/4hxcto,4hl.../
1072 c data vn(1,16),vn(2,16)/4hxfto,4hl.../
1073 c data vn(1,17),vn(2,17)/4hlmax,4h0.../
1074 c data vn(1,18),vn(2,18)/4hlmax,4hs.../
1075 c data vn(1,19),vn(2,19)/4hscto,4hl.../
1076 c data vn(1,20),vn(2,20)/4hdini,4ht.../
1077 c data vn(1,21),vn(2,21)/4hdtin,4hit../
1078 c data vn(1,22),vn(2,22)/4hd0in,4hit../
1079 c data vn(1,23),vn(2,23)/4hdfac,4h..../
1080 c data vn(1,24),vn(2,24)/4hdltf,4hdc../
1081 c data vn(1,25),vn(2,25)/4hdltf,4hdj../
1082 c data vn(1,26),vn(2,26)/4hdelt,4ha0../
1083 c data vn(1,27),vn(2,27)/4hfuzz,4h..../
1084 c data vn(1,28),vn(2,28)/4hrlim,4hit../
1085 c data vn(1,29),vn(2,29)/4hcosm,4hin../
1086 c data vn(1,30),vn(2,30)/4hhube,4hrc../
1087 c data vn(1,31),vn(2,31)/4hrspt,4hol../
1088 c data vn(1,32),vn(2,32)/4hsigm,4hin../
1089 c data vn(1,33),vn(2,33)/4heta0,4h..../
1090 c data vn(1,34),vn(2,34)/4hbias,4h..../
1092 data vn(1,1),vn(2,1)/'epsl','on..'/
1093 data vn(1,2),vn(2,2)/'phmn','fc..'/
1094 data vn(1,3),vn(2,3)/'phmx','fc..'/
1095 data vn(1,4),vn(2,4)/'decf','ac..'/
1096 data vn(1,5),vn(2,5)/'incf','ac..'/
1097 data vn(1,6),vn(2,6)/'rdfc','mn..'/
1098 data vn(1,7),vn(2,7)/'rdfc','mx..'/
1099 data vn(1,8),vn(2,8)/'tune','r1..'/
1100 data vn(1,9),vn(2,9)/'tune','r2..'/
1101 data vn(1,10),vn(2,10)/'tune','r3..'/
1102 data vn(1,11),vn(2,11)/'tune','r4..'/
1103 data vn(1,12),vn(2,12)/'tune','r5..'/
1104 data vn(1,13),vn(2,13)/'afct','ol..'/
1105 data vn(1,14),vn(2,14)/'rfct','ol..'/
1106 data vn(1,15),vn(2,15)/'xcto','l...'/
1107 data vn(1,16),vn(2,16)/'xfto','l...'/
1108 data vn(1,17),vn(2,17)/'lmax','0...'/
1109 data vn(1,18),vn(2,18)/'lmax','s...'/
1110 data vn(1,19),vn(2,19)/'scto','l...'/
1111 data vn(1,20),vn(2,20)/'dini','t...'/
1112 data vn(1,21),vn(2,21)/'dtin','it..'/
1113 data vn(1,22),vn(2,22)/'d0in','it..'/
1114 data vn(1,23),vn(2,23)/'dfac','....'/
1115 data vn(1,24),vn(2,24)/'dltf','dc..'/
1116 data vn(1,25),vn(2,25)/'dltf','dj..'/
1117 data vn(1,26),vn(2,26)/'delt','a0..'/
1118 data vn(1,27),vn(2,27)/'fuzz','....'/
1119 data vn(1,28),vn(2,28)/'rlim','it..'/
1120 data vn(1,29),vn(2,29)/'cosm','in..'/
1121 data vn(1,30),vn(2,30)/'hube','rc..'/
1122 data vn(1,31),vn(2,31)/'rspt','ol..'/
1123 data vn(1,32),vn(2,32)/'sigm','in..'/
1124 data vn(1,33),vn(2,33)/'eta0','....'/
1125 data vn(1,34),vn(2,34)/'bias','....'/
1128 data vm(1)/1.0d-3/, vm(2)/-0.99d+0/, vm(3)/1.0d-3/, vm(4)/1.0d-2/,
1129 1 vm(5)/1.2d+0/, vm(6)/1.d-2/, vm(7)/1.2d+0/, vm(8)/0.d+0/,
1130 2 vm(9)/0.d+0/, vm(10)/1.d-3/, vm(11)/-1.d+0/, vm(13)/0.d+0/,
1131 3 vm(15)/0.d+0/, vm(16)/0.d+0/, vm(19)/0.d+0/, vm(20)/-10.d+0/,
1132 4 vm(21)/0.d+0/, vm(22)/0.d+0/, vm(23)/0.d+0/, vm(27)/1.01d+0/,
1133 5 vm(28)/1.d+10/, vm(30)/0.d+0/, vm(31)/0.d+0/, vm(32)/0.d+0/,
1135 data vx(1)/0.9d+0/, vx(2)/-1.d-3/, vx(3)/1.d+1/, vx(4)/0.8d+0/,
1136 1 vx(5)/1.d+2/, vx(6)/0.8d+0/, vx(7)/1.d+2/, vx(8)/0.5d+0/,
1137 2 vx(9)/0.5d+0/, vx(10)/1.d+0/, vx(11)/1.d+0/, vx(14)/0.1d+0/,
1138 3 vx(15)/1.d+0/, vx(16)/1.d+0/, vx(19)/1.d+0/, vx(23)/1.d+0/,
1139 4 vx(24)/1.d+0/, vx(25)/1.d+0/, vx(26)/1.d+0/, vx(27)/1.d+10/,
1140 5 vx(29)/1.d+0/, vx(31)/1.d+0/, vx(32)/1.d+0/, vx(33)/1.d+0/,
1144 c data varnm(1)/1hp/, varnm(2)/1hn/, sh(1)/1hs/, sh(2)/1hh/
1145 c data cngd(1),cngd(2),cngd(3)/4h---c,4hhang,4hed v/,
1146 c 1 dflt(1),dflt(2),dflt(3)/4hnond,4hefau,4hlt v/
1148 data varnm(1)/'p'/, varnm(2)/'n'/, sh(1)/'s'/, sh(2)/'h'/
1149 data cngd(1),cngd(2),cngd(3)/'---c','hang','ed v'/,
1150 1 dflt(1),dflt(2),dflt(3)/'nond','efau','lt v'/
1152 data ijmp/33/, jlim(1)/0/, jlim(2)/24/, ndflt(1)/32/, ndflt(2)/25/
1153 data miniv(1)/80/, miniv(2)/59/
1155 c............................... body ................................
1158 if (prunit .le. liv) pu = iv(prunit)
1159 if (alg .lt. 1 .or. alg .gt. 2) go to 340
1160 if (iv(1) .eq. 0) call deflt(alg, iv, liv, lv, v)
1162 if (iv1 .ne. 13 .and. iv1 .ne. 12) go to 10
1164 if (perm .le. liv) miv1 = max0(miv1, iv(perm) - 1)
1165 if (ivneed .le. liv) miv2 = miv1 + max0(iv(ivneed), 0)
1166 if (lastiv .le. liv) iv(lastiv) = miv2
1167 if (liv .lt. miv1) go to 300
1169 iv(lastv) = max0(iv(vneed), 0) + iv(lmat) - 1
1171 if (liv .lt. miv2) go to 300
1172 if (lv .lt. iv(lastv)) go to 320
1173 10 if (alg .eq. iv(algsav)) go to 30
1174 if (pu .ne. 0) write(pu,20) alg, iv(algsav)
1175 20 format(/39h the first parameter to deflt should be,i3,
1176 1 12h rather than,i3)
1179 30 if (iv1 .lt. 12 .or. iv1 .gt. 14) go to 60
1180 if (n .ge. 1) go to 50
1182 if (pu .eq. 0) go to 999
1183 write(pu,40) varnm(alg), n
1184 40 format(/8h /// bad,a1,2h =,i5)
1186 50 if (iv1 .ne. 14) iv(nextiv) = iv(perm)
1187 if (iv1 .ne. 14) iv(nextv) = iv(lmat)
1188 if (iv1 .eq. 13) go to 999
1189 k = iv(parsav) - epslon
1190 call vdflt(alg, lv-k, v(k+1))
1191 iv(dtype0) = 2 - alg
1197 60 if (n .eq. iv(oldn)) go to 80
1199 if (pu .eq. 0) go to 999
1200 write(pu,70) varnm(alg), iv(oldn), n
1201 70 format(/5h /// ,1a1,14h changed from ,i5,4h to ,i5)
1204 80 if (iv1 .le. 11 .and. iv1 .ge. 1) go to 100
1206 if (pu .ne. 0) write(pu,90) iv1
1207 90 format(/13h /// iv(1) =,i5,28h should be between 0 and 14.)
1210 100 which(1) = cngd(1)
1214 110 if (iv1 .eq. 14) iv1 = 12
1215 if (big .gt. tiny) go to 120
1242 do 150 l = 1, ndfalt
1244 if (vk .ge. vm(i) .and. vk .le. vx(i)) go to 140
1246 if (pu .ne. 0) write(pu,130) vn(1,i), vn(2,i), k, vk,
1248 130 format(/6h /// ,2a4,5h.. v(,i2,3h) =,d11.3,7h should,
1249 1 11h be between,d11.3,4h and,d11.3)
1252 if (i .eq. j) i = ijmp
1255 if (iv(nvdflt) .eq. ndfalt) go to 170
1257 if (pu .eq. 0) go to 999
1258 write(pu,160) iv(nvdflt), ndfalt
1259 160 format(/13h iv(nvdflt) =,i5,13h rather than ,i5)
1261 170 if ((iv(dtype) .gt. 0 .or. v(dinit) .gt. zero) .and. iv1 .eq. 12)
1264 if (d(i) .gt. zero) go to 190
1266 if (pu .ne. 0) write(pu,180) i, d(i)
1267 180 format(/8h /// d(,i3,3h) =,d11.3,19h should be positive)
1269 200 if (m .eq. 0) go to 210
1273 210 if (pu .eq. 0 .or. iv(parprt) .eq. 0) go to 999
1274 if (iv1 .ne. 12 .or. iv(inits) .eq. alg-1) go to 230
1276 write(pu,220) sh(alg), iv(inits)
1277 220 format(/22h nondefault values..../5h init,a1,14h..... iv(25) =,
1279 230 if (iv(dtype) .eq. iv(dtype0)) go to 250
1280 if (m .eq. 0) write(pu,260) which
1282 write(pu,240) iv(dtype)
1283 240 format(20h dtype..... iv(16) =,i3)
1289 do 290 ii = 1, ndfalt
1290 if (v(k) .eq. v(l)) go to 280
1291 if (m .eq. 0) write(pu,260) which
1292 260 format(/1h ,3a4,9halues..../)
1294 write(pu,270) vn(1,i), vn(2,i), k, v(k)
1295 270 format(1x,2a4,5h.. v(,i2,3h) =,d15.7)
1299 if (i .eq. j) i = ijmp
1302 iv(dtype0) = iv(dtype)
1304 call vcopy(iv(nvdflt), v(parsv1), v(epslon))
1308 if (pu .eq. 0) go to 999
1309 write(pu,310) liv, miv2
1310 310 format(/10h /// liv =,i5,17h must be at least,i5)
1311 if (liv .lt. miv1) go to 999
1312 if (lv .lt. iv(lastv)) go to 320
1316 if (pu .eq. 0) go to 999
1317 write(pu,330) lv, iv(lastv)
1318 330 format(/9h /// lv =,i5,17h must be at least,i5)
1322 if (pu .eq. 0) go to 999
1324 350 format(/10h /// alg =,i5,15h must be 1 or 2)
1327 c *** last card of parck follows ***
1329 double precision function reldst(p, d, x, x0)
1331 c *** compute and return relative difference between x and x0 ***
1332 c *** nl2sol version 2.2 ***
1335 double precision d(p), x(p), x0(p)
1337 double precision dabs
1340 double precision emax, t, xmax, zero
1344 parameter (zero=0.d+0)
1350 t = dabs(d(i) * (x(i) - x0(i)))
1351 if (emax .lt. t) emax = t
1352 t = d(i) * (dabs(x(i)) + dabs(x0(i)))
1353 if (xmax .lt. t) xmax = t
1356 if (xmax .gt. zero) reldst = emax / xmax
1358 c *** last card of reldst follows ***
1360 c logical function stopx(idummy)
1361 c *****parameters...
1364 c ..................................................................
1367 c this function may serve as the stopx (asynchronous interruption)
1368 c function for the nl2sol (nonlinear least-squares) package at
1369 c those installations which do not wish to implement a
1372 c *****algorithm notes...
1373 c at installations where the nl2sol system is used
1374 c interactively, this dummy stopx should be replaced by a
1375 c function that returns .true. if and only if the interrupt
1376 c (break) key has been pressed since the last call on stopx.
1378 c ..................................................................
1383 subroutine vaxpy(p, w, a, x, y)
1385 c *** set w = a*x + y -- w, x, y = p-vectors, a = scalar ***
1388 double precision a, w(p), x(p), y(p)
1393 10 w(i) = a*x(i) + y(i)
1396 subroutine vcopy(p, y, x)
1398 c *** set y = x, where x and y are p-vectors ***
1401 double precision x(p), y(p)
1409 subroutine vdflt(alg, lv, v)
1411 c *** supply ***sol (version 2.3) default values to v ***
1413 c *** alg = 1 means regression constants.
1414 c *** alg = 2 means general unconstrained optimization constants.
1417 double precision v(lv)
1419 double precision dmax1
1422 double precision rmdcon
1423 c rmdcon... returns machine-dependent constants
1425 double precision machep, mepcrt, one, sqteps, three
1427 c *** subscripts for v ***
1429 integer afctol, bias, cosmin, decfac, delta0, dfac, dinit, dltfdc,
1430 1 dltfdj, dtinit, d0init, epslon, eta0, fuzz, huberc,
1431 2 incfac, lmax0, lmaxs, phmnfc, phmxfc, rdfcmn, rdfcmx,
1432 3 rfctol, rlimit, rsptol, sctol, sigmin, tuner1, tuner2,
1433 4 tuner3, tuner4, tuner5, xctol, xftol
1436 c data one/1.d+0/, three/3.d+0/
1438 parameter (one=1.d+0, three=3.d+0)
1441 c *** v subscript values ***
1444 c data afctol/31/, bias/43/, cosmin/47/, decfac/22/, delta0/44/,
1445 c 1 dfac/41/, dinit/38/, dltfdc/42/, dltfdj/43/, dtinit/39/,
1446 c 2 d0init/40/, epslon/19/, eta0/42/, fuzz/45/, huberc/48/,
1447 c 3 incfac/23/, lmax0/35/, lmaxs/36/, phmnfc/20/, phmxfc/21/,
1448 c 4 rdfcmn/24/, rdfcmx/25/, rfctol/32/, rlimit/46/, rsptol/49/,
1449 c 5 sctol/37/, sigmin/50/, tuner1/26/, tuner2/27/, tuner3/28/,
1450 c 6 tuner4/29/, tuner5/30/, xctol/33/, xftol/34/
1452 parameter (afctol=31, bias=43, cosmin=47, decfac=22, delta0=44,
1453 1 dfac=41, dinit=38, dltfdc=42, dltfdj=43, dtinit=39,
1454 2 d0init=40, epslon=19, eta0=42, fuzz=45, huberc=48,
1455 3 incfac=23, lmax0=35, lmaxs=36, phmnfc=20, phmxfc=21,
1456 4 rdfcmn=24, rdfcmx=25, rfctol=32, rlimit=46, rsptol=49,
1457 5 sctol=37, sigmin=50, tuner1=26, tuner2=27, tuner3=28,
1458 6 tuner4=29, tuner5=30, xctol=33, xftol=34)
1461 c------------------------------- body --------------------------------
1465 if (machep .gt. 1.d-10) v(afctol) = machep**2
1471 mepcrt = machep ** (one/three)
1481 v(rfctol) = dmax1(1.d-10, mepcrt**2)
1482 v(sctol) = v(rfctol)
1489 v(xftol) = 1.d+2 * machep
1491 if (alg .ge. 2) go to 10
1493 c *** regression values
1495 v(cosmin) = dmax1(1.d-6, 1.d+2 * machep)
1501 v(rlimit) = rmdcon(5)
1506 c *** general optimization values
1510 v(eta0) = 1.0d+3 * machep
1513 c *** last card of vdflt follows ***
1515 subroutine vscopy(p, y, s)
1517 c *** set p-vector y to scalar s ***
1520 double precision s, y(p)
1528 double precision function v2norm(p, x)
1530 c *** return the 2-norm of the p-vector x, taking ***
1531 c *** care to avoid the most likely underflows. ***
1534 double precision x(p)
1537 double precision one, r, scale, sqteta, t, xi, zero
1539 double precision dabs, dsqrt
1542 double precision rmdcon
1545 c data one/1.d+0/, zero/0.d+0/
1547 parameter (one=1.d+0, zero=0.d+0)
1552 if (p .gt. 0) go to 10
1556 if (x(i) .ne. zero) go to 30
1561 30 scale = dabs(x(i))
1562 if (i .lt. p) go to 40
1566 if (sqteta .eq. zero) sqteta = rmdcon(2)
1568 c *** sqteta is (slightly larger than) the square root of the
1569 c *** smallest positive floating point number on the machine.
1570 c *** the tests involving sqteta are done to prevent underflows.
1575 if (xi .gt. scale) go to 50
1577 if (r .gt. sqteta) t = t + r*r
1580 if (r .le. sqteta) r = zero
1585 v2norm = scale * dsqrt(t)
1587 c *** last card of v2norm follows ***
1589 subroutine humsl(n, d, x, calcf, calcgh, iv, liv, lv, v,
1590 1 uiparm, urparm, ufparm)
1592 c *** minimize general unconstrained objective function using ***
1593 c *** (analytic) gradient and hessian provided by the caller. ***
1596 integer iv(liv), uiparm(1)
1597 double precision d(n), x(n), v(lv), urparm(1)
1598 c dimension v(78 + n*(n+12)), uiparm(*), urparm(*)
1599 external calcf, calcgh, ufparm
1601 c------------------------------ discussion ---------------------------
1603 c this routine is like sumsl, except that the subroutine para-
1604 c meter calcg of sumsl (which computes the gradient of the objec-
1605 c tive function) is replaced by the subroutine parameter calcgh,
1606 c which computes both the gradient and (lower triangle of the)
1607 c hessian of the objective function. the calling sequence is...
1608 c call calcgh(n, x, nf, g, h, uiparm, urparm, ufparm)
1609 c parameters n, x, nf, g, uiparm, urparm, and ufparm are the same
1610 c as for sumsl, while h is an array of length n*(n+1)/2 in which
1611 c calcgh must store the lower triangle of the hessian at x. start-
1612 c ing at h(1), calcgh must store the hessian entries in the order
1613 c (1,1), (2,1), (2,2), (3,1), (3,2), (3,3), ...
1614 c the value printed (by itsum) in the column labelled stppar
1615 c is the levenberg-marquardt used in computing the current step.
1616 c zero means a full newton step. if the special case described in
1617 c ref. 1 is detected, then stppar is negated. the value printed
1618 c in the column labelled npreldf is zero if the current hessian
1619 c is not positive definite.
1620 c it sometimes proves worthwhile to let d be determined from the
1621 c diagonal of the hessian matrix by setting iv(dtype) = 1 and
1622 c v(dinit) = 0. the following iv and v components are relevant...
1624 c iv(dtol)..... iv(59) gives the starting subscript in v of the dtol
1625 c array used when d is updated. (iv(dtol) can be
1626 c initialized by calling humsl with iv(1) = 13.)
1627 c iv(dtype).... iv(16) tells how the scale vector d should be chosen.
1628 c iv(dtype) .le. 0 means that d should not be updated, and
1629 c iv(dtype) .ge. 1 means that d should be updated as
1630 c described below with v(dfac). default = 0.
1631 c v(dfac)..... v(41) and the dtol and d0 arrays (see v(dtinit) and
1632 c v(d0init)) are used in updating the scale vector d when
1633 c iv(dtype) .gt. 0. (d is initialized according to
1634 c v(dinit), described in sumsl.) let
1635 c d1(i) = max(sqrt(abs(h(i,i))), v(dfac)*d(i)),
1636 c where h(i,i) is the i-th diagonal element of the current
1637 c hessian. if iv(dtype) = 1, then d(i) is set to d1(i)
1638 c unless d1(i) .lt. dtol(i), in which case d(i) is set to
1639 c max(d0(i), dtol(i)).
1640 c if iv(dtype) .ge. 2, then d is updated during the first
1641 c iteration as for iv(dtype) = 1 (after any initialization
1642 c due to v(dinit)) and is left unchanged thereafter.
1644 c v(dtinit)... v(39), if positive, is the value to which all components
1645 c of the dtol array (see v(dfac)) are initialized. if
1646 c v(dtinit) = 0, then it is assumed that the caller has
1647 c stored dtol in v starting at v(iv(dtol)).
1649 c v(d0init)... v(40), if positive, is the value to which all components
1650 c of the d0 vector (see v(dfac)) are initialized. if
1651 c v(dfac) = 0, then it is assumed that the caller has
1652 c stored d0 in v starting at v(iv(dtol)+n). default = 1.0.
1656 c 1. gay, d.m. (1981), computing optimal locally constrained steps,
1657 c siam j. sci. statist. comput. 2, pp. 186-197.
1661 c coded by david m. gay (winter 1980). revised sept. 1982.
1662 c this subroutine was written in connection with research supported
1663 c in part by the national science foundation under grants
1664 c mcs-7600324 and mcs-7906671.
1666 c---------------------------- declarations ---------------------------
1668 external deflt, humit
1670 c deflt... provides default input values for iv and v.
1671 c humit... reverse-communication routine that does humsl algorithm.
1673 integer g1, h1, iv1, lh, nf
1676 c *** subscripts for iv ***
1678 integer g, h, nextv, nfcall, nfgcal, toobig, vneed
1681 c data nextv/47/, nfcall/6/, nfgcal/7/, g/28/, h/56/, toobig/2/,
1684 parameter (nextv=47, nfcall=6, nfgcal=7, g=28, h=56, toobig=2,
1688 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
1690 lh = n * (n + 1) / 2
1691 if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
1692 if (iv(1) .eq. 12 .or. iv(1) .eq. 13)
1693 1 iv(vneed) = iv(vneed) + n*(n+3)/2
1695 if (iv1 .eq. 14) go to 10
1696 if (iv1 .gt. 2 .and. iv1 .lt. 12) go to 10
1699 if (iv1 .eq. 12) iv(1) = 13
1705 20 call humit(d, f, v(g1), v(h1), iv, lh, liv, lv, n, v, x)
1706 if (iv(1) - 2) 30, 40, 50
1709 call calcf(n, x, nf, f, uiparm, urparm, ufparm)
1710 if (nf .le. 0) iv(toobig) = 1
1713 40 call calcgh(n, x, iv(nfgcal), v(g1), v(h1), uiparm, urparm,
1717 50 if (iv(1) .ne. 14) go to 999
1719 c *** storage allocation
1723 iv(nextv) = iv(h) + n*(n+1)/2
1724 if (iv1 .ne. 13) go to 10
1727 c *** last card of humsl follows ***
1729 subroutine humit(d, fx, g, h, iv, lh, liv, lv, n, v, x)
1731 c *** carry out humsl (unconstrained minimization) iterations, using
1732 c *** hessian matrix provided by the caller.
1734 c *** parameter declarations ***
1736 integer lh, liv, lv, n
1738 double precision d(n), fx, g(n), h(lh), v(lv), x(n)
1740 c-------------------------- parameter usage --------------------------
1742 c d.... scale vector.
1743 c fx... function value.
1744 c g.... gradient vector.
1745 c h.... lower triangle of the hessian, stored rowwise.
1746 c iv... integer value array.
1747 c lh... length of h = p*(p+1)/2.
1748 c liv.. length of iv (at least 60).
1749 c lv... length of v (at least 78 + n*(n+21)/2).
1750 c n.... number of variables (components in x and g).
1751 c v.... floating-point value array.
1752 c x.... parameter vector.
1754 c *** discussion ***
1756 c parameters iv, n, v, and x are the same as the corresponding
1757 c ones to humsl (which see), except that v can be shorter (since
1758 c the part of v that humsl uses for storing g and h is not needed).
1759 c moreover, compared with humsl, iv(1) may have the two additional
1760 c output values 1 and 2, which are explained below, as is the use
1761 c of iv(toobig) and iv(nfgcal). the value iv(g), which is an
1762 c output value from humsl, is not referenced by humit or the
1763 c subroutines it calls.
1765 c iv(1) = 1 means the caller should set fx to f(x), the function value
1766 c at x, and call humit again, having changed none of the
1767 c other parameters. an exception occurs if f(x) cannot be
1768 c computed (e.g. if overflow would occur), which may happen
1769 c because of an oversized step. in this case the caller
1770 c should set iv(toobig) = iv(2) to 1, which will cause
1771 c humit to ignore fx and try a smaller step. the para-
1772 c meter nf that humsl passes to calcf (for possible use by
1773 c calcgh) is a copy of iv(nfcall) = iv(6).
1774 c iv(1) = 2 means the caller should set g to g(x), the gradient of f at
1775 c x, and h to the lower triangle of h(x), the hessian of f
1776 c at x, and call humit again, having changed none of the
1777 c other parameters except perhaps the scale vector d.
1778 c the parameter nf that humsl passes to calcg is
1779 c iv(nfgcal) = iv(7). if g(x) and h(x) cannot be evaluated,
1780 c then the caller may set iv(nfgcal) to 0, in which case
1781 c humit will return with iv(1) = 65.
1782 c note -- humit overwrites h with the lower triangle
1783 c of diag(d)**-1 * h(x) * diag(d)**-1.
1787 c coded by david m. gay (winter 1980). revised sept. 1982.
1788 c this subroutine was written in connection with research supported
1789 c in part by the national science foundation under grants
1790 c mcs-7600324 and mcs-7906671.
1792 c (see sumsl and humsl for references.)
1794 c+++++++++++++++++++++++++++ declarations ++++++++++++++++++++++++++++
1796 c *** local variables ***
1798 integer dg1, dummy, i, j, k, l, lstgst, nn1o2, step1,
1804 double precision one, onep2, zero
1806 c *** no intrinsic functions ***
1808 c *** external functions and subroutines ***
1810 external assst, deflt, dotprd, dupdu, gqtst, itsum, parck,
1811 1 reldst, slvmul, stopx, vaxpy, vcopy, vscopy, v2norm
1813 double precision dotprd, reldst, v2norm
1815 c assst.... assesses candidate step.
1816 c deflt.... provides default iv and v input values.
1817 c dotprd... returns inner product of two vectors.
1818 c dupdu.... updates scale vector d.
1819 c gqtst.... computes optimally locally constrained step.
1820 c itsum.... prints iteration summary and info on initial and final x.
1821 c parck.... checks validity of input iv and v values.
1822 c reldst... computes v(reldx) = relative step size.
1823 c slvmul... multiplies symmetric matrix times vector, given the lower
1824 c triangle of the matrix.
1825 c stopx.... returns .true. if the break key has been pressed.
1826 c vaxpy.... computes scalar times one vector plus another.
1827 c vcopy.... copies one vector to another.
1828 c vscopy... sets all elements of a vector to a scalar.
1829 c v2norm... returns the 2-norm of a vector.
1831 c *** subscripts for iv and v ***
1833 integer cnvcod, dg, dgnorm, dinit, dstnrm, dtinit, dtol,
1834 1 dtype, d0init, f, f0, fdif, gtstep, incfac, irc, kagqt,
1835 2 lmat, lmax0, lmaxs, mode, model, mxfcal, mxiter, nextv,
1836 3 nfcall, nfgcal, ngcall, niter, preduc, radfac, radinc,
1837 4 radius, rad0, reldx, restor, step, stglim, stlstg, stppar,
1838 5 toobig, tuner4, tuner5, vneed, w, xirc, x0
1840 c *** iv subscript values ***
1843 c data cnvcod/55/, dg/37/, dtol/59/, dtype/16/, irc/29/, kagqt/33/,
1844 c 1 lmat/42/, mode/35/, model/5/, mxfcal/17/, mxiter/18/,
1845 c 2 nextv/47/, nfcall/6/, nfgcal/7/, ngcall/30/, niter/31/,
1846 c 3 radinc/8/, restor/9/, step/40/, stglim/11/, stlstg/41/,
1847 c 4 toobig/2/, vneed/4/, w/34/, xirc/13/, x0/43/
1849 parameter (cnvcod=55, dg=37, dtol=59, dtype=16, irc=29, kagqt=33,
1850 1 lmat=42, mode=35, model=5, mxfcal=17, mxiter=18,
1851 2 nextv=47, nfcall=6, nfgcal=7, ngcall=30, niter=31,
1852 3 radinc=8, restor=9, step=40, stglim=11, stlstg=41,
1853 4 toobig=2, vneed=4, w=34, xirc=13, x0=43)
1856 c *** v subscript values ***
1859 c data dgnorm/1/, dinit/38/, dstnrm/2/, dtinit/39/, d0init/40/,
1860 c 1 f/10/, f0/13/, fdif/11/, gtstep/4/, incfac/23/, lmax0/35/,
1861 c 2 lmaxs/36/, preduc/7/, radfac/16/, radius/8/, rad0/9/,
1862 c 3 reldx/17/, stppar/5/, tuner4/29/, tuner5/30/
1864 parameter (dgnorm=1, dinit=38, dstnrm=2, dtinit=39, d0init=40,
1865 1 f=10, f0=13, fdif=11, gtstep=4, incfac=23, lmax0=35,
1866 2 lmaxs=36, preduc=7, radfac=16, radius=8, rad0=9,
1867 3 reldx=17, stppar=5, tuner4=29, tuner5=30)
1871 c data one/1.d+0/, onep2/1.2d+0/, zero/0.d+0/
1873 parameter (one=1.d+0, onep2=1.2d+0, zero=0.d+0)
1876 c+++++++++++++++++++++++++++++++ body ++++++++++++++++++++++++++++++++
1879 if (i .eq. 1) go to 30
1880 if (i .eq. 2) go to 40
1882 c *** check validity of iv and v input values ***
1884 if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
1885 if (iv(1) .eq. 12 .or. iv(1) .eq. 13)
1886 1 iv(vneed) = iv(vneed) + n*(n+21)/2 + 7
1887 call parck(2, d, iv, liv, lv, n, v)
1889 if (i .gt. 12) go to 999
1890 nn1o2 = n * (n + 1) / 2
1891 if (lh .ge. nn1o2) go to (210,210,210,210,210,210,160,120,160,
1896 c *** storage allocation ***
1898 10 iv(dtol) = iv(lmat) + nn1o2
1899 iv(x0) = iv(dtol) + 2*n
1900 iv(step) = iv(x0) + n
1901 iv(stlstg) = iv(step) + n
1902 iv(dg) = iv(stlstg) + n
1904 iv(nextv) = iv(w) + 4*n + 7
1905 if (iv(1) .ne. 13) go to 20
1909 c *** initialization ***
1923 if (v(dinit) .ge. zero) call vscopy(n, d, v(dinit))
1925 if (v(dtinit) .gt. zero) call vscopy(n, v(k), v(dtinit))
1927 if (v(d0init) .gt. zero) call vscopy(n, v(k), v(d0init))
1932 if (iv(mode) .ge. 0) go to 210
1934 if (iv(toobig) .eq. 0) go to 999
1938 c *** make sure gradient could be computed ***
1940 40 if (iv(nfgcal) .ne. 0) go to 50
1944 c *** update the scale vector d ***
1947 if (iv(dtype) .le. 0) go to 70
1955 call dupdu(d, v(dg1), iv, liv, lv, n, v)
1957 c *** compute scaled gradient and its norm ***
1965 v(dgnorm) = v2norm(n, v(dg1))
1967 c *** compute scaled hessian ***
1973 h(k) = t * h(k) / d(j)
1978 if (iv(cnvcod) .ne. 0) go to 340
1979 if (iv(mode) .eq. 0) go to 300
1981 c *** allow first step to have scaled 2-norm at most v(lmax0) ***
1983 v(radius) = v(lmax0)
1988 c----------------------------- main loop -----------------------------
1991 c *** print iteration summary, check iteration limit ***
1993 110 call itsum(d, g, iv, liv, lv, n, v, x)
1995 if (k .lt. iv(mxiter)) go to 130
1999 130 iv(niter) = k + 1
2001 c *** initialize for start of next iteration ***
2009 c *** copy x to x0 ***
2011 call vcopy(n, v(x01), x)
2013 c *** update radius ***
2015 if (k .eq. 0) go to 150
2022 v(radius) = v(radfac) * v2norm(n, v(step1))
2024 c *** check stopx and function evaluation limit ***
2028 150 if (.not. stopx(dummy)) go to 170
2032 c *** come here when restarting after func. eval. limit or stopx.
2034 160 if (v(f) .ge. v(f0)) go to 170
2039 170 if (iv(nfcall) .lt. iv(mxfcal)) go to 190
2041 180 if (v(f) .ge. v(f0)) go to 350
2043 c *** in case of stopx or function evaluation limit with
2044 c *** improved v(f), evaluate the gradient at x.
2049 c. . . . . . . . . . . . . compute candidate step . . . . . . . . . .
2051 190 step1 = iv(step)
2055 call gqtst(d, v(dg1), h, iv(kagqt), v(l), n, v(step1), v, v(w1))
2056 if (iv(irc) .eq. 6) go to 210
2058 c *** check whether evaluating f(x0 + step) looks worthwhile ***
2060 if (v(dstnrm) .le. zero) go to 210
2061 if (iv(irc) .ne. 5) go to 200
2062 if (v(radfac) .le. one) go to 200
2063 if (v(preduc) .le. onep2 * v(fdif)) go to 210
2065 c *** compute f(x0 + step) ***
2069 call vaxpy(n, x, one, v(step1), v(x01))
2070 iv(nfcall) = iv(nfcall) + 1
2075 c. . . . . . . . . . . . . assess candidate step . . . . . . . . . . .
2078 v(reldx) = reldst(n, d, x, v(x01))
2079 call assst(iv, liv, lv, v)
2082 if (iv(restor) .eq. 1) call vcopy(n, x, v(x01))
2083 if (iv(restor) .eq. 2) call vcopy(n, v(lstgst), v(step1))
2084 if (iv(restor) .ne. 3) go to 220
2085 call vcopy(n, v(step1), v(lstgst))
2086 call vaxpy(n, x, one, v(step1), v(x01))
2087 v(reldx) = reldst(n, d, x, v(x01))
2090 go to (230,260,260,260,230,240,250,250,250,250,250,250,330,300), k
2092 c *** recompute step with new radius ***
2094 230 v(radius) = v(radfac) * v(dstnrm)
2097 c *** compute step of length v(lmaxs) for singular convergence test.
2099 240 v(radius) = v(lmaxs)
2102 c *** convergence or false convergence ***
2104 250 iv(cnvcod) = k - 4
2105 if (v(f) .ge. v(f0)) go to 340
2106 if (iv(xirc) .eq. 14) go to 340
2109 c. . . . . . . . . . . . process acceptable step . . . . . . . . . . .
2111 260 if (iv(irc) .ne. 3) go to 290
2114 c *** prepare for gradient tests ***
2115 c *** set temp1 = hessian * step + g(x0)
2116 c *** = diag(d) * (h * step + g(x0))
2118 c use x0 vector as temporary.
2121 v(k) = d(i) * v(step1)
2125 call slvmul(n, v(temp1), h, v(x01))
2127 v(temp1) = d(i) * v(temp1) + g(i)
2131 c *** compute gradient and hessian ***
2133 290 iv(ngcall) = iv(ngcall) + 1
2138 if (iv(irc) .ne. 3) go to 110
2140 c *** set v(radfac) by gradient tests ***
2145 c *** set temp1 = diag(d)**-1 * (hessian*step + (g(x0)-g(x))) ***
2149 v(k) = (v(k) - g(i)) / d(i)
2153 c *** do gradient tests ***
2155 if (v2norm(n, v(temp1)) .le. v(dgnorm) * v(tuner4)) go to 320
2156 if (dotprd(n, g, v(step1))
2157 1 .ge. v(gtstep) * v(tuner5)) go to 110
2158 320 v(radfac) = v(incfac)
2161 c. . . . . . . . . . . . . . misc. details . . . . . . . . . . . . . .
2163 c *** bad parameters to assess ***
2168 c *** print summary of final iteration and other requested items ***
2170 340 iv(1) = iv(cnvcod)
2172 350 call itsum(d, g, iv, liv, lv, n, v, x)
2176 c *** last card of humit follows ***
2178 subroutine dupdu(d, hdiag, iv, liv, lv, n, v)
2180 c *** update scale vector d for humsl ***
2182 c *** parameter declarations ***
2186 double precision d(n), hdiag(n), v(lv)
2188 c *** local variables ***
2190 integer dtoli, d0i, i
2191 double precision t, vdfac
2193 c *** intrinsic functions ***
2195 double precision dabs, dmax1, dsqrt
2197 c *** subscripts for iv and v ***
2199 integer dfac, dtol, dtype, niter
2201 c data dfac/41/, dtol/59/, dtype/16/, niter/31/
2203 parameter (dfac=41, dtol=59, dtype=16, niter=31)
2206 c------------------------------- body --------------------------------
2209 if (i .eq. 1) go to 10
2210 if (iv(niter) .gt. 0) go to 999
2216 t = dmax1(dsqrt(dabs(hdiag(i))), vdfac*d(i))
2217 if (t .lt. v(dtoli)) t = dmax1(v(dtoli), v(d0i))
2224 c *** last card of dupdu follows ***
2226 subroutine gqtst(d, dig, dihdi, ka, l, p, step, v, w)
2228 c *** compute goldfeld-quandt-trotter step by more-hebden technique ***
2229 c *** (nl2sol version 2.2), modified a la more and sorensen ***
2231 c *** parameter declarations ***
2234 cal double precision d(p), dig(p), dihdi(1), l(1), v(21), step(p),
2236 double precision d(p), dig(p), dihdi(p*(p+1)/2), l(p*(p+1)/2),
2237 1 v(21), step(p),w(4*p+7)
2238 c dimension dihdi(p*(p+1)/2), l(p*(p+1)/2), w(4*p+7)
2240 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2244 c given the (compactly stored) lower triangle of a scaled
2245 c hessian (approximation) and a nonzero scaled gradient vector,
2246 c this subroutine computes a goldfeld-quandt-trotter step of
2247 c approximate length v(radius) by the more-hebden technique. in
2248 c other words, step is computed to (approximately) minimize
2249 c psi(step) = (g**t)*step + 0.5*(step**t)*h*step such that the
2250 c 2-norm of d*step is at most (approximately) v(radius), where
2251 c g is the gradient, h is the hessian, and d is a diagonal
2252 c scale matrix whose diagonal is stored in the parameter d.
2253 c (gqtst assumes dig = d**-1 * g and dihdi = d**-1 * h * d**-1.)
2255 c *** parameter description ***
2257 c d (in) = the scale vector, i.e. the diagonal of the scale
2258 c matrix d mentioned above under purpose.
2259 c dig (in) = the scaled gradient vector, d**-1 * g. if g = 0, then
2260 c step = 0 and v(stppar) = 0 are returned.
2261 c dihdi (in) = lower triangle of the scaled hessian (approximation),
2262 c i.e., d**-1 * h * d**-1, stored compactly by rows., i.e.,
2263 c in the order (1,1), (2,1), (2,2), (3,1), (3,2), etc.
2264 c ka (i/o) = the number of hebden iterations (so far) taken to deter-
2265 c mine step. ka .lt. 0 on input means this is the first
2266 c attempt to determine step (for the present dig and dihdi)
2267 c -- ka is initialized to 0 in this case. output with
2268 c ka = 0 (or v(stppar) = 0) means step = -(h**-1)*g.
2269 c l (i/o) = workspace of length p*(p+1)/2 for cholesky factors.
2270 c p (in) = number of parameters -- the hessian is a p x p matrix.
2271 c step (i/o) = the step computed.
2272 c v (i/o) contains various constants and variables described below.
2273 c w (i/o) = workspace of length 4*p + 6.
2275 c *** entries in v ***
2277 c v(dgnorm) (i/o) = 2-norm of (d**-1)*g.
2278 c v(dstnrm) (output) = 2-norm of d*step.
2279 c v(dst0) (i/o) = 2-norm of d*(h**-1)*g (for pos. def. h only), or
2280 c overestimate of smallest eigenvalue of (d**-1)*h*(d**-1).
2281 c v(epslon) (in) = max. rel. error allowed for psi(step). for the
2282 c step returned, psi(step) will exceed its optimal value
2283 c by less than -v(epslon)*psi(step). suggested value = 0.1.
2284 c v(gtstep) (out) = inner product between g and step.
2285 c v(nreduc) (out) = psi(-(h**-1)*g) = psi(newton step) (for pos. def.
2286 c h only -- v(nreduc) is set to zero otherwise).
2287 c v(phmnfc) (in) = tol. (together with v(phmxfc)) for accepting step
2288 c (more*s sigma). the error v(dstnrm) - v(radius) must lie
2289 c between v(phmnfc)*v(radius) and v(phmxfc)*v(radius).
2290 c v(phmxfc) (in) (see v(phmnfc).)
2291 c suggested values -- v(phmnfc) = -0.25, v(phmxfc) = 0.5.
2292 c v(preduc) (out) = psi(step) = predicted obj. func. reduction for step.
2293 c v(radius) (in) = radius of current (scaled) trust region.
2294 c v(rad0) (i/o) = value of v(radius) from previous call.
2295 c v(stppar) (i/o) is normally the marquardt parameter, i.e. the alpha
2296 c described below under algorithm notes. if h + alpha*d**2
2297 c (see algorithm notes) is (nearly) singular, however,
2298 c then v(stppar) = -alpha.
2300 c *** usage notes ***
2302 c if it is desired to recompute step using a different value of
2303 c v(radius), then this routine may be restarted by calling it
2304 c with all parameters unchanged except v(radius). (this explains
2305 c why step and w are listed as i/o). on an initial call (one with
2306 c ka .lt. 0), step and w need not be initialized and only compo-
2307 c nents v(epslon), v(stppar), v(phmnfc), v(phmxfc), v(radius), and
2308 c v(rad0) of v must be initialized.
2310 c *** algorithm notes ***
2312 c the desired g-q-t step (ref. 2, 3, 4, 6) satisfies
2313 c (h + alpha*d**2)*step = -g for some nonnegative alpha such that
2314 c h + alpha*d**2 is positive semidefinite. alpha and step are
2315 c computed by a scheme analogous to the one described in ref. 5.
2316 c estimates of the smallest and largest eigenvalues of the hessian
2317 c are obtained from the gerschgorin circle theorem enhanced by a
2318 c simple form of the scaling described in ref. 7. cases in which
2319 c h + alpha*d**2 is nearly (or exactly) singular are handled by
2320 c the technique discussed in ref. 2. in these cases, a step of
2321 c (exact) length v(radius) is returned for which psi(step) exceeds
2322 c its optimal value by less than -v(epslon)*psi(step). the test
2323 c suggested in ref. 6 for detecting the special case is performed
2324 c once two matrix factorizations have been done -- doing so sooner
2325 c seems to degrade the performance of optimization routines that
2326 c call this routine.
2328 c *** functions and subroutines called ***
2330 c dotprd - returns inner product of two vectors.
2331 c litvmu - applies inverse-transpose of compact lower triang. matrix.
2332 c livmul - applies inverse of compact lower triang. matrix.
2333 c lsqrt - finds cholesky factor (of compactly stored lower triang.).
2334 c lsvmin - returns approx. to min. sing. value of lower triang. matrix.
2335 c rmdcon - returns machine-dependent constants.
2336 c v2norm - returns 2-norm of a vector.
2338 c *** references ***
2340 c 1. dennis, j.e., gay, d.m., and welsch, r.e. (1981), an adaptive
2341 c nonlinear least-squares algorithm, acm trans. math.
2342 c software, vol. 7, no. 3.
2343 c 2. gay, d.m. (1981), computing optimal locally constrained steps,
2344 c siam j. sci. statist. computing, vol. 2, no. 2, pp.
2346 c 3. goldfeld, s.m., quandt, r.e., and trotter, h.f. (1966),
2347 c maximization by quadratic hill-climbing, econometrica 34,
2349 c 4. hebden, m.d. (1973), an algorithm for minimization using exact
2350 c second derivatives, report t.p. 515, theoretical physics
2351 c div., a.e.r.e. harwell, oxon., england.
2352 c 5. more, j.j. (1978), the levenberg-marquardt algorithm, implemen-
2353 c tation and theory, pp.105-116 of springer lecture notes
2354 c in mathematics no. 630, edited by g.a. watson, springer-
2355 c verlag, berlin and new york.
2356 c 6. more, j.j., and sorensen, d.c. (1981), computing a trust region
2357 c step, technical report anl-81-83, argonne national lab.
2358 c 7. varga, r.s. (1965), minimal gerschgorin sets, pacific j. math. 15,
2363 c coded by david m. gay.
2364 c this subroutine was written in connection with research
2365 c supported by the national science foundation under grants
2366 c mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989, and
2369 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2371 c *** local variables ***
2374 integer dggdmx, diag, diag0, dstsav, emax, emin, i, im1, inc, irc,
2375 1 j, k, kalim, kamin, k1, lk0, phipin, q, q0, uk0, x
2376 double precision alphak, aki, akk, delta, dst, eps, gtsta, lk,
2377 1 oldphi, phi, phimax, phimin, psifac, rad, radsq,
2378 2 root, si, sk, sw, t, twopsi, t1, t2, uk, wi
2381 double precision big, dgxfac, epsfac, four, half, kappa, negone,
2382 1 one, p001, six, three, two, zero
2384 c *** intrinsic functions ***
2386 double precision dabs, dmax1, dmin1, dsqrt
2388 c *** external functions and subroutines ***
2390 external dotprd, litvmu, livmul, lsqrt, lsvmin, rmdcon, v2norm
2391 double precision dotprd, lsvmin, rmdcon, v2norm
2393 c *** subscripts for v ***
2395 integer dgnorm, dstnrm, dst0, epslon, gtstep, stppar, nreduc,
2396 1 phmnfc, phmxfc, preduc, radius, rad0
2398 c data dgnorm/1/, dstnrm/2/, dst0/3/, epslon/19/, gtstep/4/,
2399 c 1 nreduc/6/, phmnfc/20/, phmxfc/21/, preduc/7/, radius/8/,
2400 c 2 rad0/9/, stppar/5/
2402 parameter (dgnorm=1, dstnrm=2, dst0=3, epslon=19, gtstep=4,
2403 1 nreduc=6, phmnfc=20, phmxfc=21, preduc=7, radius=8,
2408 c data epsfac/50.0d+0/, four/4.0d+0/, half/0.5d+0/,
2409 c 1 kappa/2.0d+0/, negone/-1.0d+0/, one/1.0d+0/, p001/1.0d-3/,
2410 c 2 six/6.0d+0/, three/3.0d+0/, two/2.0d+0/, zero/0.0d+0/
2412 parameter (epsfac=50.0d+0, four=4.0d+0, half=0.5d+0,
2413 1 kappa=2.0d+0, negone=-1.0d+0, one=1.0d+0, p001=1.0d-3,
2414 2 six=6.0d+0, three=3.0d+0, two=2.0d+0, zero=0.0d+0)
2417 data big/0.d+0/, dgxfac/0.d+0/
2421 c *** store largest abs. entry in (d**-1)*h*(d**-1) at w(dggdmx).
2423 c *** store gerschgorin over- and underestimates of the largest
2424 c *** and smallest eigenvalues of (d**-1)*h*(d**-1) at w(emax)
2425 c *** and w(emin) respectively.
2428 c *** for use in recomputing step, the final values of lk, uk, dst,
2429 c *** and the inverse derivative of more*s phi at 0 (for pos. def.
2430 c *** h) are stored in w(lk0), w(uk0), w(dstsav), and w(phipin)
2436 c *** store diag of (d**-1)*h*(d**-1) in w(diag),...,w(diag0+p).
2439 c *** store -d*step in w(q),...,w(q0+p).
2442 c *** allocate storage for scratch vector x ***
2446 c *** phitol = max. error allowed in dst = v(dstnrm) = 2-norm of
2448 phimax = v(phmxfc) * rad
2449 phimin = v(phmnfc) * rad
2450 psifac = two * v(epslon) / (three * (four * (v(phmnfc) + one) *
2451 1 (kappa + one) + kappa + two) * rad**2)
2452 c *** oldphi is used to detect limits of numerical accuracy. if
2453 c *** we recompute step and it does not change, then we accept it.
2460 c *** start or restart, depending on ka ***
2462 if (ka .ge. 0) go to 290
2464 c *** fresh start ***
2470 v(dgnorm) = v2norm(p, dig)
2474 if (v(dgnorm) .eq. zero) kamin = 0
2476 c *** store diag(dihdi) in w(diag0+1),...,w(diag0+p) ***
2485 c *** determine w(dggdmx), the largest element of dihdi ***
2491 if (t1 .lt. t) t1 = t
2495 c *** try alpha = 0 ***
2497 30 call lsqrt(1, p, l, dihdi, irc)
2498 if (irc .eq. 0) go to 50
2499 c *** indef. h -- underestimate smallest eigenvalue, use this
2500 c *** estimate to initialize lower bound lk on alpha.
2507 call litvmu(irc, w, l, w)
2511 if (restrt) go to 210
2514 c *** positive definite h -- compute unmodified newton step. ***
2516 t = lsvmin(p, l, w(q), w(q))
2517 if (t .ge. one) go to 60
2518 if (big .le. zero) big = rmdcon(6)
2519 if (v(dgnorm) .ge. t*t*big) go to 70
2520 60 call livmul(p, w(q), l, dig)
2521 gtsta = dotprd(p, w(q), w(q))
2522 v(nreduc) = half * gtsta
2523 call litvmu(p, w(q), l, w(q))
2524 dst = v2norm(p, w(q))
2527 if (phi .le. phimax) go to 260
2528 if (restrt) go to 210
2530 c *** prepare to compute gerschgorin estimates of largest (and
2531 c *** smallest) eigenvalues. ***
2536 if (i .eq. 1) go to 90
2548 c *** (under-)estimate smallest eigenvalue of (d**-1)*h*(d**-1) ***
2552 if (p .le. 1) go to 120
2556 if (t .ge. t1) go to 110
2568 if (i .eq. k) go to 130
2569 aki = dabs(dihdi(k1))
2572 t1 = half * (akk - w(j) + si - aki)
2573 t1 = t1 + dsqrt(t1*t1 + sk*aki)
2574 if (t .lt. t1) t = t1
2575 if (i .lt. k) go to 140
2581 uk = v(dgnorm)/rad - w(emin)
2582 if (v(dgnorm) .eq. zero) uk = uk + p001 + p001*uk
2583 if (uk .le. zero) uk = p001
2585 c *** compute gerschgorin (over-)estimate of largest eigenvalue ***
2589 if (p .le. 1) go to 170
2593 if (t .le. t1) go to 160
2605 if (i .eq. k) go to 180
2606 aki = dabs(dihdi(k1))
2609 t1 = half * (w(j) + si - aki - akk)
2610 t1 = t1 + dsqrt(t1*t1 + sk*aki)
2611 if (t .lt. t1) t = t1
2612 if (i .lt. k) go to 190
2618 lk = dmax1(lk, v(dgnorm)/rad - w(emax))
2620 c *** alphak = current value of alpha (see alg. notes above). we
2621 c *** use more*s scheme for initializing it.
2622 alphak = dabs(v(stppar)) * v(rad0)/rad
2624 if (irc .ne. 0) go to 210
2626 c *** compute l0 for positive definite h ***
2628 call livmul(p, w, l, w(q))
2630 w(phipin) = dst / t / t
2631 lk = dmax1(lk, phi*w(phipin))
2633 c *** safeguard alphak and add alphak*i to (d**-1)*h*(d**-1) ***
2636 if (-v(dst0) .ge. alphak .or. alphak .lt. lk .or. alphak .ge. uk)
2637 1 alphak = uk * dmax1(p001, dsqrt(lk/uk))
2638 if (alphak .le. zero) alphak = half * uk
2639 if (alphak .le. zero) alphak = uk
2644 dihdi(k) = w(j) + alphak
2647 c *** try computing cholesky decomposition ***
2649 call lsqrt(1, p, l, dihdi, irc)
2650 if (irc .eq. 0) go to 240
2652 c *** (d**-1)*h*(d**-1) + alphak*i is indefinite -- overestimate
2653 c *** smallest eigenvalue for use in updating lk ***
2661 call litvmu(irc, w, l, w)
2663 lk = alphak - t/t1/t1
2667 c *** alphak makes (d**-1)*h*(d**-1) positive definite.
2668 c *** compute q = -d*step, check for convergence. ***
2670 240 call livmul(p, w(q), l, dig)
2671 gtsta = dotprd(p, w(q), w(q))
2672 call litvmu(p, w(q), l, w(q))
2673 dst = v2norm(p, w(q))
2675 if (phi .le. phimax .and. phi .ge. phimin) go to 270
2676 if (phi .eq. oldphi) go to 270
2678 if (phi .lt. zero) go to 330
2680 c *** unacceptable alphak -- update lk, uk, alphak ***
2682 250 if (ka .ge. kalim) go to 270
2683 c *** the following dmin1 is necessary because of restarts ***
2684 if (phi .lt. zero) uk = dmin1(uk, alphak)
2685 c *** kamin = 0 only iff the gradient vanishes ***
2686 if (kamin .eq. 0) go to 210
2687 call livmul(p, w, l, w(q))
2689 alphak = alphak + (phi/t1) * (dst/t1) * (dst/rad)
2690 lk = dmax1(lk, alphak)
2693 c *** acceptable step on first try ***
2697 c *** successful step in general. compute step = -(d**-1)*q ***
2701 step(i) = -w(j)/d(i)
2704 v(preduc) = half * (dabs(alphak)*dst*dst + gtsta)
2708 c *** restart with new radius ***
2710 290 if (v(dst0) .le. zero .or. v(dst0) - rad .gt. phimax) go to 310
2712 c *** prepare to return newton step ***
2726 if (v(dgnorm) .eq. zero) kamin = 0
2727 if (ka .eq. 0) go to 50
2730 alphak = dabs(v(stppar))
2734 if (v(dgnorm) .eq. zero) uk = uk + p001 + p001*uk
2735 if (uk .le. zero) uk = p001
2736 if (rad .gt. v(rad0)) go to 320
2738 c *** smaller radius ***
2740 if (alphak .gt. zero) lk = w(lk0)
2741 lk = dmax1(lk, t - w(emax))
2742 if (v(dst0) .gt. zero) lk = dmax1(lk, (v(dst0)-rad)*w(phipin))
2745 c *** bigger radius ***
2746 320 if (alphak .gt. zero) uk = dmin1(uk, w(uk0))
2747 lk = dmax1(zero, -v(dst0), t - w(emax))
2748 if (v(dst0) .gt. zero) lk = dmax1(lk, (v(dst0)-rad)*w(phipin))
2751 c *** decide whether to check for special case... in practice (from
2752 c *** the standpoint of the calling optimization code) it seems best
2753 c *** not to check until a few iterations have failed -- hence the
2754 c *** test on kamin below.
2756 330 delta = alphak + dmin1(zero, v(dst0))
2757 twopsi = alphak*dst*dst + gtsta
2758 if (ka .ge. kamin) go to 340
2759 c *** if the test in ref. 2 is satisfied, fall through to handle
2760 c *** the special case (as soon as the more-sorensen test detects
2762 if (delta .ge. psifac*twopsi) go to 370
2764 c *** check for the special case of h + alpha*d**2 (nearly)
2765 c *** singular. use one step of inverse power method with start
2766 c *** from lsvmin to obtain approximate eigenvector corresponding
2767 c *** to smallest eigenvalue of (d**-1)*h*(d**-1). lsvmin returns
2768 c *** x and w with l*w = x.
2770 340 t = lsvmin(p, l, w(x), w)
2772 c *** normalize w ***
2775 c *** complete current inv. power iter. -- replace w by (l**-t)*w.
2776 call litvmu(p, w, l, w)
2777 t2 = one/v2norm(p, w)
2782 c *** now w is the desired approximate (unit) eigenvector and
2783 c *** t*x = ((d**-1)*h*(d**-1) + alphak*i)*w.
2785 sw = dotprd(p, w(q), w)
2786 t1 = (rad + dst) * (rad - dst)
2787 root = dsqrt(sw*sw + t1)
2788 if (sw .lt. zero) root = -root
2789 si = t1 / (sw + root)
2791 c *** the actual test for the special case...
2793 if ((t2*si)**2 .le. eps*(dst**2 + alphak*radsq)) go to 380
2795 c *** update upper bound on smallest eigenvalue (when not positive)
2796 c *** (as recommended by more and sorensen) and continue...
2798 if (v(dst0) .le. zero) v(dst0) = dmin1(v(dst0), t2**2 - alphak)
2799 lk = dmax1(lk, -v(dst0))
2801 c *** check whether we can hope to detect the special case in
2802 c *** the available arithmetic. accept step as it is if not.
2804 c *** if not yet available, obtain machine dependent value dgxfac.
2805 370 if (dgxfac .eq. zero) dgxfac = epsfac * rmdcon(3)
2807 if (delta .gt. dgxfac*w(dggdmx)) go to 250
2810 c *** special case detected... negate alphak to indicate special case
2812 380 alphak = -alphak
2813 v(preduc) = half * twopsi
2815 c *** accept current step if adding si*w would lead to a
2816 c *** further relative reduction in psi of less than v(epslon)/3.
2819 t = si*(alphak*sw - half*si*(alphak + t*dotprd(p,w(x),w)))
2820 if (t .lt. eps*twopsi/six) go to 390
2821 v(preduc) = v(preduc) + t
2826 w(j) = t1*w(i) - w(j)
2827 step(i) = w(j) / d(i)
2829 v(gtstep) = dotprd(p, dig, w(q))
2831 c *** save values for use in a possible restart ***
2840 c *** restore diagonal of dihdi ***
2851 c *** last card of gqtst follows ***
2853 subroutine lsqrt(n1, n, l, a, irc)
2855 c *** compute rows n1 through n of the cholesky factor l of
2856 c *** a = l*(l**t), where l and the lower triangle of a are both
2857 c *** stored compactly by rows (and may occupy the same storage).
2858 c *** irc = 0 means all went well. irc = j means the leading
2859 c *** principal j x j submatrix of a is not positive definite --
2860 c *** and l(j*(j+1)/2) contains the (nonpos.) reduced j-th diagonal.
2862 c *** parameters ***
2865 cal double precision l(1), a(1)
2866 double precision l(n*(n+1)/2), a(n*(n+1)/2)
2867 c dimension l(n*(n+1)/2), a(n*(n+1)/2)
2869 c *** local variables ***
2871 integer i, ij, ik, im1, i0, j, jk, jm1, j0, k
2872 double precision t, td, zero
2874 c *** intrinsic functions ***
2876 double precision dsqrt
2881 parameter (zero=0.d+0)
2886 i0 = n1 * (n1 - 1) / 2
2889 if (i .eq. 1) go to 40
2894 if (j .eq. 1) go to 20
2903 t = (a(ij) - t) / l(j0)
2909 if (t .le. zero) go to 60
2921 c *** last card of lsqrt ***
2923 double precision function lsvmin(p, l, x, y)
2925 c *** estimate smallest sing. value of packed lower triang. matrix l
2927 c *** parameter declarations ***
2930 cal double precision l(1), x(p), y(p)
2931 double precision l(p*(p+1)/2), x(p), y(p)
2932 c dimension l(p*(p+1)/2)
2934 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2938 c this function returns a good over-estimate of the smallest
2939 c singular value of the packed lower triangular matrix l.
2941 c *** parameter description ***
2943 c p (in) = the order of l. l is a p x p lower triangular matrix.
2944 c l (in) = array holding the elements of l in row order, i.e.
2945 c l(1,1), l(2,1), l(2,2), l(3,1), l(3,2), l(3,3), etc.
2946 c x (out) if lsvmin returns a positive value, then x is a normalized
2947 c approximate left singular vector corresponding to the
2948 c smallest singular value. this approximation may be very
2949 c crude. if lsvmin returns zero, then some components of x
2950 c are zero and the rest retain their input values.
2951 c y (out) if lsvmin returns a positive value, then y = (l**-1)*x is an
2952 c unnormalized approximate right singular vector correspond-
2953 c ing to the smallest singular value. this approximation
2954 c may be crude. if lsvmin returns zero, then y retains its
2955 c input value. the caller may pass the same vector for x
2956 c and y (nonstandard fortran usage), in which case y over-
2957 c writes x (for nonzero lsvmin returns).
2959 c *** algorithm notes ***
2961 c the algorithm is based on (1), with the additional provision that
2962 c lsvmin = 0 is returned if the smallest diagonal element of l
2963 c (in magnitude) is not more than the unit roundoff times the
2964 c largest. the algorithm uses a random number generator proposed
2965 c in (4), which passes the spectral test with flying colors -- see
2968 c *** subroutines and functions called ***
2970 c v2norm - function, returns the 2-norm of a vector.
2972 c *** references ***
2974 c (1) cline, a., moler, c., stewart, g., and wilkinson, j.h.(1977),
2975 c an estimate for the condition number of a matrix, report
2976 c tm-310, applied math. div., argonne national laboratory.
2978 c (2) hoaglin, d.c. (1976), theoretical properties of congruential
2979 c random-number generators -- an empirical view,
2980 c memorandum ns-340, dept. of statistics, harvard univ.
2982 c (3) knuth, d.e. (1969), the art of computer programming, vol. 2
2983 c (seminumerical algorithms), addison-wesley, reading, mass.
2985 c (4) smith, c.s. (1971), multiplicative pseudo-random number
2986 c generators with prime modulus, j. assoc. comput. mach. 18,
2991 c designed and coded by david m. gay (winter 1977/summer 1978).
2995 c this subroutine was written in connection with research
2996 c supported by the national science foundation under grants
2997 c mcs-7600324, dcr75-10143, 76-14311dss, and mcs76-11989.
2999 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3001 c *** local variables ***
3003 integer i, ii, ix, j, ji, jj, jjj, jm1, j0, pm1
3004 double precision b, sminus, splus, t, xminus, xplus
3008 double precision half, one, r9973, zero
3010 c *** intrinsic functions ***
3014 double precision dabs
3016 c *** external functions and subroutines ***
3018 external dotprd, v2norm, vaxpy
3019 double precision dotprd, v2norm
3022 c data half/0.5d+0/, one/1.d+0/, r9973/9973.d+0/, zero/0.d+0/
3024 parameter (half=0.5d+0, one=1.d+0, r9973=9973.d+0, zero=0.d+0)
3032 c *** first check whether to return lsvmin = 0 and initialize x ***
3037 if (l(jj) .eq. zero) go to 110
3038 ix = mod(3432*ix, 9973)
3039 b = half*(one + float(ix)/r9973)
3042 if (p .le. 1) go to 60
3045 if (l(ii) .eq. zero) go to 110
3047 x(i) = xplus * l(ji)
3050 c *** solve (l**t)*x = b, where the components of b have randomly
3051 c *** chosen magnitudes in (.5,1) with signs chosen to make x large.
3053 c do j = p-1 to 1 by -1...
3056 c *** determine x(j) in this iteration. note for i = 1,2,...,j
3057 c *** that x(i) holds the current partial sum for row i.
3058 ix = mod(3432*ix, 9973)
3059 b = half*(one + float(ix)/r9973)
3061 xminus = (-b - x(j))
3063 sminus = dabs(xminus)
3068 xminus = xminus/l(jj)
3069 if (jm1 .eq. 0) go to 30
3072 splus = splus + dabs(x(i) + l(ji)*xplus)
3073 sminus = sminus + dabs(x(i) + l(ji)*xminus)
3075 30 if (sminus .gt. splus) xplus = xminus
3077 c *** update partial sums ***
3078 if (jm1 .gt. 0) call vaxpy(jm1, x, xplus, l(j0+1), x)
3081 c *** normalize x ***
3083 60 t = one/v2norm(p, x)
3087 c *** solve l*y = x and return lsvmin = 1/twonorm(y) ***
3094 if (jm1 .gt. 0) t = dotprd(jm1, l(j0+1), y)
3095 y(j) = (x(j) - t) / l(jj)
3098 lsvmin = one/v2norm(p, y)
3103 c *** last card of lsvmin follows ***
3105 subroutine slvmul(p, y, s, x)
3107 c *** set y = s * x, s = p x p symmetric matrix. ***
3108 c *** lower triangle of s stored rowwise. ***
3110 c *** parameter declarations ***
3113 cal double precision s(1), x(p), y(p)
3114 double precision s(p*(p+1)/2), x(p), y(p)
3115 c dimension s(p*(p+1)/2)
3117 c *** local variables ***
3119 integer i, im1, j, k
3122 c *** no intrinsic functions ***
3124 c *** external function ***
3127 double precision dotprd
3129 c-----------------------------------------------------------------------
3133 y(i) = dotprd(i, s(j), x)
3137 if (p .le. 1) go to 999
3144 y(k) = y(k) + s(j)*xi
3150 c *** last card of slvmul follows ***