rename
[unres4.git] / source / unres / minim.F90
1       module minimm
2 !-----------------------------------------------------------------------------
3       use io_units
4       use names
5       use math
6 !      use MPI_data
7       use geometry_data
8       use energy_data
9       use control_data
10       use minim_data
11       use geometry
12 !      use csa_data
13 !      use energy
14       implicit none
15 !-----------------------------------------------------------------------------
16 !
17 !
18 !-----------------------------------------------------------------------------
19       contains
20 !-----------------------------------------------------------------------------
21 ! cored.f
22 !-----------------------------------------------------------------------------
23       subroutine assst(iv, liv, lv, v)
24 !
25 !  ***  assess candidate step (***sol version 2.3)  ***
26 !
27       integer :: liv, l,lv
28       integer :: iv(liv)
29       real(kind=8) :: v(lv)
30 !
31 !  ***  purpose  ***
32 !
33 !        this subroutine is called by an unconstrained minimization
34 !     routine to assess the next candidate step.  it may recommend one
35 !     of several courses of action, such as accepting the step, recom-
36 !     puting it using the same or a new quadratic model, or halting due
37 !     to convergence or false convergence.  see the return code listing
38 !     below.
39 !
40 !--------------------------  parameter usage  --------------------------
41 !
42 !  iv (i/o) integer parameter and scratch vector -- see description
43 !             below of iv values referenced.
44 ! liv (in)  length of iv array.
45 !  lv (in)  length of v array.
46 !   v (i/o) real parameter and scratch vector -- see description
47 !             below of v values referenced.
48 !
49 !  ***  iv values referenced  ***
50 !
51 !    iv(irc) (i/o) on input for the first step tried in a new iteration,
52 !             iv(irc) should be set to 3 or 4 (the value to which it is
53 !             set when step is definitely to be accepted).  on input
54 !             after step has been recomputed, iv(irc) should be
55 !             unchanged since the previous return of assst.
56 !                on output, iv(irc) is a return code having one of the
57 !             following values...
58 !                  1 = switch models or try smaller step.
59 !                  2 = switch models or accept step.
60 !                  3 = accept step and determine v(radfac) by gradient
61 !                       tests.
62 !                  4 = accept step, v(radfac) has been determined.
63 !                  5 = recompute step (using the same model).
64 !                  6 = recompute step with radius = v(lmaxs) but do not
65 !                       evaulate the objective function.
66 !                  7 = x-convergence (see v(xctol)).
67 !                  8 = relative function convergence (see v(rfctol)).
68 !                  9 = both x- and relative function convergence.
69 !                 10 = absolute function convergence (see v(afctol)).
70 !                 11 = singular convergence (see v(lmaxs)).
71 !                 12 = false convergence (see v(xftol)).
72 !                 13 = iv(irc) was out of range on input.
73 !             return code i has precdence over i+1 for i = 9, 10, 11.
74 ! iv(mlstgd) (i/o) saved value of iv(model).
75 !  iv(model) (i/o) on input, iv(model) should be an integer identifying
76 !             the current quadratic model of the objective function.
77 !             if a previous step yielded a better function reduction,
78 !             then iv(model) will be set to iv(mlstgd) on output.
79 ! iv(nfcall) (in)  invocation count for the objective function.
80 ! iv(nfgcal) (i/o) value of iv(nfcall) at step that gave the biggest
81 !             function reduction this iteration.  iv(nfgcal) remains
82 !             unchanged until a function reduction is obtained.
83 ! iv(radinc) (i/o) the number of radius increases (or minus the number
84 !             of decreases) so far this iteration.
85 ! iv(restor) (out) set to 1 if v(f) has been restored and x should be
86 !             restored to its initial value, to 2 if x should be saved,
87 !             to 3 if x should be restored from the saved value, and to
88 !             0 otherwise.
89 !  iv(stage) (i/o) count of the number of models tried so far in the
90 !             current iteration.
91 ! iv(stglim) (in)  maximum number of models to consider.
92 ! iv(switch) (out) set to 0 unless a new model is being tried and it
93 !             gives a smaller function value than the previous model,
94 !             in which case assst sets iv(switch) = 1.
95 ! iv(toobig) (in)  is nonzero if step was too big (e.g. if it caused
96 !             overflow).
97 !   iv(xirc) (i/o) value that iv(irc) would have in the absence of
98 !             convergence, false convergence, and oversized steps.
99 !
100 !  ***  v values referenced  ***
101 !
102 ! v(afctol) (in)  absolute function convergence tolerance.  if the
103 !             absolute value of the current function value v(f) is less
104 !             than v(afctol), then assst returns with iv(irc) = 10.
105 ! v(decfac) (in)  factor by which to decrease radius when iv(toobig) is
106 !             nonzero.
107 ! v(dstnrm) (in)  the 2-norm of d*step.
108 ! v(dstsav) (i/o) value of v(dstnrm) on saved step.
109 !   v(dst0) (in)  the 2-norm of d times the newton step (when defined,
110 !             i.e., for v(nreduc) .ge. 0).
111 !      v(f) (i/o) on both input and output, v(f) is the objective func-
112 !             tion value at x.  if x is restored to a previous value,
113 !             then v(f) is restored to the corresponding value.
114 !   v(fdif) (out) the function reduction v(f0) - v(f) (for the output
115 !             value of v(f) if an earlier step gave a bigger function
116 !             decrease, and for the input value of v(f) otherwise).
117 ! v(flstgd) (i/o) saved value of v(f).
118 !     v(f0) (in)  objective function value at start of iteration.
119 ! v(gtslst) (i/o) value of v(gtstep) on saved step.
120 ! v(gtstep) (in)  inner product between step and gradient.
121 ! v(incfac) (in)  minimum factor by which to increase radius.
122 !  v(lmaxs) (in)  maximum reasonable step size (and initial step bound).
123 !             if the actual function decrease is no more than twice
124 !             what was predicted, if a return with iv(irc) = 7, 8, 9,
125 !             or 10 does not occur, if v(dstnrm) .gt. v(lmaxs), and if
126 !             v(preduc) .le. v(sctol) * abs(v(f0)), then assst re-
127 !             turns with iv(irc) = 11.  if so doing appears worthwhile,
128 !             then assst repeats this test with v(preduc) computed for
129 !             a step of length v(lmaxs) (by a return with iv(irc) = 6).
130 ! v(nreduc) (i/o)  function reduction predicted by quadratic model for
131 !             newton step.  if assst is called with iv(irc) = 6, i.e.,
132 !             if v(preduc) has been computed with radius = v(lmaxs) for
133 !             use in the singular convervence test, then v(nreduc) is
134 !             set to -v(preduc) before the latter is restored.
135 ! v(plstgd) (i/o) value of v(preduc) on saved step.
136 ! v(preduc) (i/o) function reduction predicted by quadratic model for
137 !             current step.
138 ! v(radfac) (out) factor to be used in determining the new radius,
139 !             which should be v(radfac)*dst, where  dst  is either the
140 !             output value of v(dstnrm) or the 2-norm of
141 !             diag(newd)*step  for the output value of step and the
142 !             updated version, newd, of the scale vector d.  for
143 !             iv(irc) = 3, v(radfac) = 1.0 is returned.
144 ! v(rdfcmn) (in)  minimum value for v(radfac) in terms of the input
145 !             value of v(dstnrm) -- suggested value = 0.1.
146 ! v(rdfcmx) (in)  maximum value for v(radfac) -- suggested value = 4.0.
147 !  v(reldx) (in) scaled relative change in x caused by step, computed
148 !             (e.g.) by function  reldst  as
149 !                 max (d(i)*abs(x(i)-x0(i)), 1 .le. i .le. p) /
150 !                    max (d(i)*(abs(x(i))+abs(x0(i))), 1 .le. i .le. p).
151 ! v(rfctol) (in)  relative function convergence tolerance.  if the
152 !             actual function reduction is at most twice what was pre-
153 !             dicted and  v(nreduc) .le. v(rfctol)*abs(v(f0)),  then
154 !             assst returns with iv(irc) = 8 or 9.
155 ! v(stppar) (in)  marquardt parameter -- 0 means full newton step.
156 ! v(tuner1) (in)  tuning constant used to decide if the function
157 !             reduction was much less than expected.  suggested
158 !             value = 0.1.
159 ! v(tuner2) (in)  tuning constant used to decide if the function
160 !             reduction was large enough to accept step.  suggested
161 !             value = 10**-4.
162 ! v(tuner3) (in)  tuning constant used to decide if the radius
163 !             should be increased.  suggested value = 0.75.
164 !  v(xctol) (in)  x-convergence criterion.  if step is a newton step
165 !             (v(stppar) = 0) having v(reldx) .le. v(xctol) and giving
166 !             at most twice the predicted function decrease, then
167 !             assst returns iv(irc) = 7 or 9.
168 !  v(xftol) (in)  false convergence tolerance.  if step gave no or only
169 !             a small function decrease and v(reldx) .le. v(xftol),
170 !             then assst returns with iv(irc) = 12.
171 !
172 !-------------------------------  notes  -------------------------------
173 !
174 !  ***  application and usage restrictions  ***
175 !
176 !        this routine is called as part of the nl2sol (nonlinear
177 !     least-squares) package.  it may be used in any unconstrained
178 !     minimization solver that uses dogleg, goldfeld-quandt-trotter,
179 !     or levenberg-marquardt steps.
180 !
181 !  ***  algorithm notes  ***
182 !
183 !        see (1) for further discussion of the assessing and model
184 !     switching strategies.  while nl2sol considers only two models,
185 !     assst is designed to handle any number of models.
186 !
187 !  ***  usage notes  ***
188 !
189 !        on the first call of an iteration, only the i/o variables
190 !     step, x, iv(irc), iv(model), v(f), v(dstnrm), v(gtstep), and
191 !     v(preduc) need have been initialized.  between calls, no i/o
192 !     values execpt step, x, iv(model), v(f) and the stopping toler-
193 !     ances should be changed.
194 !        after a return for convergence or false convergence, one can
195 !     change the stopping tolerances and call assst again, in which
196 !     case the stopping tests will be repeated.
197 !
198 !  ***  references  ***
199 !
200 !     (1) dennis, j.e., jr., gay, d.m., and welsch, r.e. (1981),
201 !        an adaptive nonlinear least-squares algorithm,
202 !        acm trans. math. software, vol. 7, no. 3.
203 !
204 !     (2) powell, m.j.d. (1970)  a fortran subroutine for solving
205 !        systems of nonlinear algebraic equations, in numerical
206 !        methods for nonlinear algebraic equations, edited by
207 !        p. rabinowitz, gordon and breach, london.
208 !
209 !  ***  history  ***
210 !
211 !        john dennis designed much of this routine, starting with
212 !     ideas in (2). roy welsch suggested the model switching strategy.
213 !        david gay and stephen peters cast this subroutine into a more
214 !     portable form (winter 1977), and david gay cast it into its
215 !     present form (fall 1978).
216 !
217 !  ***  general  ***
218 !
219 !     this subroutine was written in connection with research
220 !     supported by the national science foundation under grants
221 !     mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989, and
222 !     mcs-7906671.
223 !
224 !------------------------  external quantities  ------------------------
225 !
226 !  ***  no external functions and subroutines  ***
227 !
228 !  ***  intrinsic functions  ***
229 !/+
230 !el      real(kind=8) :: dabs, dmax1
231 !/
232 !  ***  no common blocks  ***
233 !
234 !--------------------------  local variables  --------------------------
235 !
236       logical :: goodx
237       integer :: i, nfc
238       real(kind=8) :: emax, emaxs, gts, rfac1, xmax
239 !el      real(kind=8) :: half, one, onep2, two, zero
240 !
241 !  ***  subscripts for iv and v  ***
242 !
243 !el      integer :: afctol, decfac, dstnrm, dstsav, dst0, f, fdif, flstgd, f0,&
244 !el              gtslst, gtstep, incfac, irc, lmaxs, mlstgd, model, nfcall,&
245 !el              nfgcal, nreduc, plstgd, preduc, radfac, radinc, rdfcmn,&
246 !el              rdfcmx, reldx, restor, rfctol, sctol, stage, stglim,&
247 !el              stppar, switch, toobig, tuner1, tuner2, tuner3, xctol,&
248 !el              xftol, xirc
249 !
250 !
251 !  ***  data initializations  ***
252 !
253 !/6
254 !     data half/0.5d+0/, one/1.d+0/, onep2/1.2d+0/, two/2.d+0/,
255 !    1     zero/0.d+0/
256 !/7
257       real(kind=8),parameter :: half=0.5d+0, one=1.d+0, onep2=1.2d+0, two=2.d+0,&
258                  zero=0.d+0
259 !/
260 !
261 !/6
262 !     data irc/29/, mlstgd/32/, model/5/, nfcall/6/, nfgcal/7/,
263 !    1     radinc/8/, restor/9/, stage/10/, stglim/11/, switch/12/,
264 !    2     toobig/2/, xirc/13/
265 !/7
266       integer,parameter :: irc=29, mlstgd=32, model=5, nfcall=6, nfgcal=7,&
267                  radinc=8, restor=9, stage=10, stglim=11, switch=12,&
268                  toobig=2, xirc=13
269 !/
270 !/6
271 !     data afctol/31/, decfac/22/, dstnrm/2/, dst0/3/, dstsav/18/,
272 !    1     f/10/, fdif/11/, flstgd/12/, f0/13/, gtslst/14/, gtstep/4/,
273 !    2     incfac/23/, lmaxs/36/, nreduc/6/, plstgd/15/, preduc/7/,
274 !    3     radfac/16/, rdfcmn/24/, rdfcmx/25/, reldx/17/, rfctol/32/,
275 !    4     sctol/37/, stppar/5/, tuner1/26/, tuner2/27/, tuner3/28/,
276 !    5     xctol/33/, xftol/34/
277 !/7
278       integer,parameter :: afctol=31, decfac=22, dstnrm=2, dst0=3, dstsav=18,&
279                  f=10, fdif=11, flstgd=12, f0=13, gtslst=14, gtstep=4,&
280                  incfac=23, lmaxs=36, nreduc=6, plstgd=15, preduc=7,&
281                  radfac=16, rdfcmn=24, rdfcmx=25, reldx=17, rfctol=32,&
282                  sctol=37, stppar=5, tuner1=26, tuner2=27, tuner3=28,&
283                  xctol=33, xftol=34
284 !/
285 !
286 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
287 !
288       nfc = iv(nfcall)
289       iv(switch) = 0
290       iv(restor) = 0
291       rfac1 = one
292       goodx = .true.
293       i = iv(irc)
294       if (i .ge. 1 .and. i .le. 12) &
295                    go to (20,30,10,10,40,280,220,220,220,220,220,170), i
296          iv(irc) = 13
297          go to 999
298 !
299 !  ***  initialize for new iteration  ***
300 !
301  10   iv(stage) = 1
302       iv(radinc) = 0
303       v(flstgd) = v(f0)
304       if (iv(toobig) .eq. 0) go to 110
305          iv(stage) = -1
306          iv(xirc) = i
307          go to 60
308 !
309 !  ***  step was recomputed with new model or smaller radius  ***
310 !  ***  first decide which  ***
311 !
312  20   if (iv(model) .ne. iv(mlstgd)) go to 30
313 !        ***  old model retained, smaller radius tried  ***
314 !        ***  do not consider any more new models this iteration  ***
315          iv(stage) = iv(stglim)
316          iv(radinc) = -1
317          go to 110
318 !
319 !  ***  a new model is being tried.  decide whether to keep it.  ***
320 !
321  30   iv(stage) = iv(stage) + 1
322 !
323 !     ***  now we add the possibiltiy that step was recomputed with  ***
324 !     ***  the same model, perhaps because of an oversized step.     ***
325 !
326  40   if (iv(stage) .gt. 0) go to 50
327 !
328 !        ***  step was recomputed because it was too big.  ***
329 !
330          if (iv(toobig) .ne. 0) go to 60
331 !
332 !        ***  restore iv(stage) and pick up where we left off.  ***
333 !
334          iv(stage) = -iv(stage)
335          i = iv(xirc)
336          go to (20, 30, 110, 110, 70), i
337 !
338  50   if (iv(toobig) .eq. 0) go to 70
339 !
340 !  ***  handle oversize step  ***
341 !
342       if (iv(radinc) .gt. 0) go to 80
343          iv(stage) = -iv(stage)
344          iv(xirc) = iv(irc)
345 !
346  60      v(radfac) = v(decfac)
347          iv(radinc) = iv(radinc) - 1
348          iv(irc) = 5
349          iv(restor) = 1
350          go to 999
351 !
352  70   if (v(f) .lt. v(flstgd)) go to 110
353 !
354 !     *** the new step is a loser.  restore old model.  ***
355 !
356       if (iv(model) .eq. iv(mlstgd)) go to 80
357          iv(model) = iv(mlstgd)
358          iv(switch) = 1
359 !
360 !     ***  restore step, etc. only if a previous step decreased v(f).
361 !
362  80   if (v(flstgd) .ge. v(f0)) go to 110
363          iv(restor) = 1
364          v(f) = v(flstgd)
365          v(preduc) = v(plstgd)
366          v(gtstep) = v(gtslst)
367          if (iv(switch) .eq. 0) rfac1 = v(dstnrm) / v(dstsav)
368          v(dstnrm) = v(dstsav)
369          nfc = iv(nfgcal)
370          goodx = .false.
371 !
372  110  v(fdif) = v(f0) - v(f)
373       if (v(fdif) .gt. v(tuner2) * v(preduc)) go to 140
374       if(iv(radinc).gt.0) go to 140
375 !
376 !        ***  no (or only a trivial) function decrease
377 !        ***  -- so try new model or smaller radius
378 !
379          if (v(f) .lt. v(f0)) go to 120
380               iv(mlstgd) = iv(model)
381               v(flstgd) = v(f)
382               v(f) = v(f0)
383               iv(restor) = 1
384               go to 130
385  120     iv(nfgcal) = nfc
386  130     iv(irc) = 1
387          if (iv(stage) .lt. iv(stglim)) go to 160
388               iv(irc) = 5
389               iv(radinc) = iv(radinc) - 1
390               go to 160
391 !
392 !  ***  nontrivial function decrease achieved  ***
393 !
394  140  iv(nfgcal) = nfc
395       rfac1 = one
396       v(dstsav) = v(dstnrm)
397       if (v(fdif) .gt. v(preduc)*v(tuner1)) go to 190
398 !
399 !  ***  decrease was much less than predicted -- either change models
400 !  ***  or accept step with decreased radius.
401 !
402       if (iv(stage) .ge. iv(stglim)) go to 150
403 !        ***  consider switching models  ***
404          iv(irc) = 2
405          go to 160
406 !
407 !     ***  accept step with decreased radius  ***
408 !
409  150  iv(irc) = 4
410 !
411 !  ***  set v(radfac) to fletcher*s decrease factor  ***
412 !
413  160  iv(xirc) = iv(irc)
414       emax = v(gtstep) + v(fdif)
415       v(radfac) = half * rfac1
416       if (emax .lt. v(gtstep)) v(radfac) = rfac1 * dmax1(v(rdfcmn),&
417                                                  half * v(gtstep)/emax)
418 !
419 !  ***  do false convergence test  ***
420 !
421  170  if (v(reldx) .le. v(xftol)) go to 180
422          iv(irc) = iv(xirc)
423          if (v(f) .lt. v(f0)) go to 200
424               go to 230
425 !
426  180  iv(irc) = 12
427       go to 240
428 !
429 !  ***  handle good function decrease  ***
430 !
431  190  if (v(fdif) .lt. (-v(tuner3) * v(gtstep))) go to 210
432 !
433 !     ***  increasing radius looks worthwhile.  see if we just
434 !     ***  recomputed step with a decreased radius or restored step
435 !     ***  after recomputing it with a larger radius.
436 !
437       if (iv(radinc) .lt. 0) go to 210
438       if (iv(restor) .eq. 1) go to 210
439 !
440 !        ***  we did not.  try a longer step unless this was a newton
441 !        ***  step.
442
443          v(radfac) = v(rdfcmx)
444          gts = v(gtstep)
445          if (v(fdif) .lt. (half/v(radfac) - one) * gts) &
446                   v(radfac) = dmax1(v(incfac), half*gts/(gts + v(fdif)))
447          iv(irc) = 4
448          if (v(stppar) .eq. zero) go to 230
449          if (v(dst0) .ge. zero .and. (v(dst0) .lt. two*v(dstnrm) &
450                    .or. v(nreduc) .lt. onep2*v(fdif)))  go to 230
451 !             ***  step was not a newton step.  recompute it with
452 !             ***  a larger radius.
453               iv(irc) = 5
454               iv(radinc) = iv(radinc) + 1
455 !
456 !  ***  save values corresponding to good step  ***
457 !
458  200  v(flstgd) = v(f)
459       iv(mlstgd) = iv(model)
460       if (iv(restor) .ne. 1) iv(restor) = 2
461       v(dstsav) = v(dstnrm)
462       iv(nfgcal) = nfc
463       v(plstgd) = v(preduc)
464       v(gtslst) = v(gtstep)
465       go to 230
466 !
467 !  ***  accept step with radius unchanged  ***
468 !
469  210  v(radfac) = one
470       iv(irc) = 3
471       go to 230
472 !
473 !  ***  come here for a restart after convergence  ***
474 !
475  220  iv(irc) = iv(xirc)
476       if (v(dstsav) .ge. zero) go to 240
477          iv(irc) = 12
478          go to 240
479 !
480 !  ***  perform convergence tests  ***
481 !
482  230  iv(xirc) = iv(irc)
483  240  if (iv(restor) .eq. 1 .and. v(flstgd) .lt. v(f0)) iv(restor) = 3
484       if (half * v(fdif) .gt. v(preduc)) go to 999
485       emax = v(rfctol) * dabs(v(f0))
486       emaxs = v(sctol) * dabs(v(f0))
487       if (v(dstnrm) .gt. v(lmaxs) .and. v(preduc) .le. emaxs) &
488                              iv(irc) = 11
489       if (v(dst0) .lt. zero) go to 250
490       i = 0
491       if ((v(nreduc) .gt. zero .and. v(nreduc) .le. emax) .or. &
492           (v(nreduc) .eq. zero .and. v(preduc) .eq. zero))  i = 2
493       if (v(stppar) .eq. zero .and. v(reldx) .le. v(xctol) &
494                               .and. goodx)                  i = i + 1
495       if (i .gt. 0) iv(irc) = i + 6
496 !
497 !  ***  consider recomputing step of length v(lmaxs) for singular
498 !  ***  convergence test.
499 !
500  250  if (iv(irc) .gt. 5 .and. iv(irc) .ne. 12) go to 999
501       if (v(dstnrm) .gt. v(lmaxs)) go to 260
502          if (v(preduc) .ge. emaxs) go to 999
503               if (v(dst0) .le. zero) go to 270
504                    if (half * v(dst0) .le. v(lmaxs)) go to 999
505                         go to 270
506  260  if (half * v(dstnrm) .le. v(lmaxs)) go to 999
507       xmax = v(lmaxs) / v(dstnrm)
508       if (xmax * (two - xmax) * v(preduc) .ge. emaxs) go to 999
509  270  if (v(nreduc) .lt. zero) go to 290
510 !
511 !  ***  recompute v(preduc) for use in singular convergence test  ***
512 !
513       v(gtslst) = v(gtstep)
514       v(dstsav) = v(dstnrm)
515       if (iv(irc) .eq. 12) v(dstsav) = -v(dstsav)
516       v(plstgd) = v(preduc)
517       i = iv(restor)
518       iv(restor) = 2
519       if (i .eq. 3) iv(restor) = 0
520       iv(irc) = 6
521       go to 999
522 !
523 !  ***  perform singular convergence test with recomputed v(preduc)  ***
524 !
525  280  v(gtstep) = v(gtslst)
526       v(dstnrm) = dabs(v(dstsav))
527       iv(irc) = iv(xirc)
528       if (v(dstsav) .le. zero) iv(irc) = 12
529       v(nreduc) = -v(preduc)
530       v(preduc) = v(plstgd)
531       iv(restor) = 3
532  290  if (-v(nreduc) .le. v(sctol) * dabs(v(f0))) iv(irc) = 11
533 !
534  999  return
535 !
536 !  ***  last card of assst follows  ***
537       end subroutine assst
538 !-----------------------------------------------------------------------------
539       subroutine deflt(alg, iv, liv, lv, v)
540 !
541 !  ***  supply ***sol (version 2.3) default values to iv and v  ***
542 !
543 !  ***  alg = 1 means regression constants.
544 !  ***  alg = 2 means general unconstrained optimization constants.
545 !
546       integer :: liv, l,lv
547       integer :: alg, iv(liv)
548       real(kind=8) :: v(lv)
549 !
550 !el      external imdcon, vdflt
551 !el      integer imdcon
552 ! imdcon... returns machine-dependent integer constants.
553 ! vdflt.... provides default values to v.
554 !
555       integer :: miv, m
556       integer :: miniv(2), minv(2)
557 !
558 !  ***  subscripts for iv  ***
559 !
560 !el      integer algsav, covprt, covreq, dtype, hc, ierr, inith, inits,
561 !el     1        ipivot, ivneed, lastiv, lastv, lmat, mxfcal, mxiter,
562 !el     2        nfcov, ngcov, nvdflt, outlev, parprt, parsav, perm,
563 !el     3        prunit, qrtyp, rdreq, rmat, solprt, statpr, vneed,
564 !el     4        vsave, x0prt
565 !
566 !  ***  iv subscript values  ***
567 !
568 !/6
569 !     data algsav/51/, covprt/14/, covreq/15/, dtype/16/, hc/71/,
570 !    1     ierr/75/, inith/25/, inits/25/, ipivot/76/, ivneed/3/,
571 !    2     lastiv/44/, lastv/45/, lmat/42/, mxfcal/17/, mxiter/18/,
572 !    3     nfcov/52/, ngcov/53/, nvdflt/50/, outlev/19/, parprt/20/,
573 !    4     parsav/49/, perm/58/, prunit/21/, qrtyp/80/, rdreq/57/,
574 !    5     rmat/78/, solprt/22/, statpr/23/, vneed/4/, vsave/60/,
575 !    6     x0prt/24/
576 !/7
577       integer,parameter :: algsav=51, covprt=14, covreq=15, dtype=16, hc=71,&
578                  ierr=75, inith=25, inits=25, ipivot=76, ivneed=3,&
579                  lastiv=44, lastv=45, lmat=42, mxfcal=17, mxiter=18,&
580                  nfcov=52, ngcov=53, nvdflt=50, outlev=19, parprt=20,&
581                  parsav=49, perm=58, prunit=21, qrtyp=80, rdreq=57,&
582                  rmat=78, solprt=22, statpr=23, vneed=4, vsave=60,&
583                  x0prt=24
584 !/
585       data miniv(1)/80/, miniv(2)/59/, minv(1)/98/, minv(2)/71/
586 !el local variables
587       integer :: mv
588 !
589 !-------------------------------  body  --------------------------------
590 !
591       if (alg .lt. 1 .or. alg .gt. 2) go to 40
592       miv = miniv(alg)
593       if (liv .lt. miv) go to 20
594       mv = minv(alg)
595       if (lv .lt. mv) go to 30
596       call vdflt(alg, lv, v)
597       iv(1) = 12
598       iv(algsav) = alg
599       iv(ivneed) = 0
600       iv(lastiv) = miv
601       iv(lastv) = mv
602       iv(lmat) = mv + 1
603       iv(mxfcal) = 200
604       iv(mxiter) = 150
605       iv(outlev) = 1
606       iv(parprt) = 1
607       iv(perm) = miv + 1
608       iv(prunit) = imdcon(1)
609       iv(solprt) = 1
610       iv(statpr) = 1
611       iv(vneed) = 0
612       iv(x0prt) = 1
613 !
614       if (alg .ge. 2) go to 10
615 !
616 !  ***  regression  values
617 !
618       iv(covprt) = 3
619       iv(covreq) = 1
620       iv(dtype) = 1
621       iv(hc) = 0
622       iv(ierr) = 0
623       iv(inits) = 0
624       iv(ipivot) = 0
625       iv(nvdflt) = 32
626       iv(parsav) = 67
627       iv(qrtyp) = 1
628       iv(rdreq) = 3
629       iv(rmat) = 0
630       iv(vsave) = 58
631       go to 999
632 !
633 !  ***  general optimization values
634 !
635  10   iv(dtype) = 0
636       iv(inith) = 1
637       iv(nfcov) = 0
638       iv(ngcov) = 0
639       iv(nvdflt) = 25
640       iv(parsav) = 47
641       go to 999
642 !
643  20   iv(1) = 15
644       go to 999
645 !
646  30   iv(1) = 16
647       go to 999
648 !
649  40   iv(1) = 67
650 !
651  999  return
652 !  ***  last card of deflt follows  ***
653       end subroutine deflt
654 !-----------------------------------------------------------------------------
655       real(kind=8) function dotprd(p,x,y)
656 !
657 !  ***  return the inner product of the p-vectors x and y.  ***
658 !
659       integer :: p
660       real(kind=8) :: x(p), y(p)
661 !
662       integer :: i
663 !el      real(kind=8) :: one, zero
664       real(kind=8) :: sqteta, t
665 !/+
666 !el      real(kind=8) :: dmax1, dabs
667 !/
668 !el      external rmdcon
669 !el      real(kind=8) :: rmdcon
670 !
671 !  ***  rmdcon(2) returns a machine-dependent constant, sqteta, which
672 !  ***  is slightly larger than the smallest positive number that
673 !  ***  can be squared without underflowing.
674 !
675 !/6
676 !     data one/1.d+0/, sqteta/0.d+0/, zero/0.d+0/
677 !/7
678       real(kind=8),parameter :: one=1.d+0, zero=0.d+0
679       data sqteta/0.d+0/
680 !/
681 !
682       dotprd = zero
683       if (p .le. 0) go to 999
684 !rc      if (sqteta .eq. zero) sqteta = rmdcon(2)
685       do 20 i = 1, p
686 !rc         t = dmax1(dabs(x(i)), dabs(y(i)))
687 !rc         if (t .gt. one) go to 10
688 !rc         if (t .lt. sqteta) go to 20
689 !rc         t = (x(i)/sqteta)*y(i)
690 !rc         if (dabs(t) .lt. sqteta) go to 20
691  10      dotprd = dotprd + x(i)*y(i)
692  20   continue
693 !
694  999  return
695 !  ***  last card of dotprd follows  ***
696       end function dotprd
697 !-----------------------------------------------------------------------------
698       subroutine itsum(d, g, iv, liv, lv, p, v, x)
699 !
700 !  ***  print iteration summary for ***sol (version 2.3)  ***
701 !
702 !  ***  parameter declarations  ***
703 !
704       integer :: liv, lv, p
705       integer :: iv(liv)
706       real(kind=8) :: d(p), g(p), v(lv), x(p)
707 !
708 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
709 !
710 !  ***  local variables  ***
711 !
712       integer :: alg, i, iv1, m, nf, ng, ol, pu
713 !/6
714 !     real model1(6), model2(6)
715 !/7
716       character(len=4) :: model1(6), model2(6)
717 !/
718       real(kind=8) :: nreldf, oldf, preldf, reldf       !el, zero
719 !
720 !  ***  intrinsic functions  ***
721 !/+
722 !el      integer :: iabs
723 !el      real(kind=8) :: dabs, dmax1
724 !/
725 !  ***  no external functions or subroutines  ***
726 !
727 !  ***  subscripts for iv and v  ***
728 !
729 !el      integer algsav, dstnrm, f, fdif, f0, needhd, nfcall, nfcov, ngcov,
730 !el     1        ngcall, niter, nreduc, outlev, preduc, prntit, prunit,
731 !el     2        reldx, solprt, statpr, stppar, sused, x0prt
732 !
733 !  ***  iv subscript values  ***
734 !
735 !/6
736 !     data algsav/51/, needhd/36/, nfcall/6/, nfcov/52/, ngcall/30/,
737 !    1     ngcov/53/, niter/31/, outlev/19/, prntit/39/, prunit/21/,
738 !    2     solprt/22/, statpr/23/, sused/64/, x0prt/24/
739 !/7
740       integer,parameter :: algsav=51, needhd=36, nfcall=6, nfcov=52, ngcall=30,&
741                  ngcov=53, niter=31, outlev=19, prntit=39, prunit=21,&
742                  solprt=22, statpr=23, sused=64, x0prt=24
743 !/
744 !
745 !  ***  v subscript values  ***
746 !
747 !/6
748 !     data dstnrm/2/, f/10/, f0/13/, fdif/11/, nreduc/6/, preduc/7/,
749 !    1     reldx/17/, stppar/5/
750 !/7
751       integer,parameter :: dstnrm=2, f=10, f0=13, fdif=11, nreduc=6, preduc=7,&
752                  reldx=17, stppar=5
753 !/
754 !
755 !/6
756 !     data zero/0.d+0/
757 !/7
758       real(kind=8),parameter :: zero=0.d+0
759 !/
760 !/6
761 !     data model1(1)/4h    /, model1(2)/4h    /, model1(3)/4h    /,
762 !    1     model1(4)/4h    /, model1(5)/4h  g /, model1(6)/4h  s /,
763 !    2     model2(1)/4h g  /, model2(2)/4h s  /, model2(3)/4hg-s /,
764 !    3     model2(4)/4hs-g /, model2(5)/4h-s-g/, model2(6)/4h-g-s/
765 !/7
766       data model1/'    ','    ','    ','    ','  g ','  s '/,&
767            model2/' g  ',' s  ','g-s ','s-g ','-s-g','-g-s'/
768 !/
769 !
770 !-------------------------------  body  --------------------------------
771 !
772       pu = iv(prunit)
773       if (pu .eq. 0) go to 999
774       iv1 = iv(1)
775       if (iv1 .gt. 62) iv1 = iv1 - 51
776       ol = iv(outlev)
777       alg = iv(algsav)
778       if (iv1 .lt. 2 .or. iv1 .gt. 15) go to 370
779       if (iv1 .ge. 12) go to 120
780       if (iv1 .eq. 2 .and. iv(niter) .eq. 0) go to 390
781       if (ol .eq. 0) go to 120
782       if (iv1 .ge. 10 .and. iv(prntit) .eq. 0) go to 120
783       if (iv1 .gt. 2) go to 10
784          iv(prntit) = iv(prntit) + 1
785          if (iv(prntit) .lt. iabs(ol)) go to 999
786  10   nf = iv(nfcall) - iabs(iv(nfcov))
787       iv(prntit) = 0
788       reldf = zero
789       preldf = zero
790       oldf = dmax1(dabs(v(f0)), dabs(v(f)))
791       if (oldf .le. zero) go to 20
792          reldf = v(fdif) / oldf
793          preldf = v(preduc) / oldf
794  20   if (ol .gt. 0) go to 60
795 !
796 !        ***  print short summary line  ***
797 !
798          if (iv(needhd) .eq. 1 .and. alg .eq. 1) write(pu,30)
799  30   format(/10h   it   nf,6x,1hf,7x,5hreldf,3x,6hpreldf,3x,5hreldx,&
800              2x,13hmodel  stppar)
801          if (iv(needhd) .eq. 1 .and. alg .eq. 2) write(pu,40)
802  40   format(/11h    it   nf,7x,1hf,8x,5hreldf,4x,6hpreldf,4x,5hreldx,&
803              3x,6hstppar)
804          iv(needhd) = 0
805          if (alg .eq. 2) go to 50
806          m = iv(sused)
807          write(pu,100) iv(niter), nf, v(f), reldf, preldf, v(reldx),&
808                        model1(m), model2(m), v(stppar)
809          go to 120
810 !
811  50      write(pu,110) iv(niter), nf, v(f), reldf, preldf, v(reldx),&
812                        v(stppar)
813          go to 120
814 !
815 !     ***  print long summary line  ***
816 !
817  60   if (iv(needhd) .eq. 1 .and. alg .eq. 1) write(pu,70)
818  70   format(/11h    it   nf,6x,1hf,7x,5hreldf,3x,6hpreldf,3x,5hreldx,&
819              2x,13hmodel  stppar,2x,6hd*step,2x,7hnpreldf)
820       if (iv(needhd) .eq. 1 .and. alg .eq. 2) write(pu,80)
821  80   format(/11h    it   nf,7x,1hf,8x,5hreldf,4x,6hpreldf,4x,5hreldx,&
822              3x,6hstppar,3x,6hd*step,3x,7hnpreldf)
823       iv(needhd) = 0
824       nreldf = zero
825       if (oldf .gt. zero) nreldf = v(nreduc) / oldf
826       if (alg .eq. 2) go to 90
827       m = iv(sused)
828       write(pu,100) iv(niter), nf, v(f), reldf, preldf, v(reldx),&
829                    model1(m), model2(m), v(stppar), v(dstnrm), nreldf
830       go to 120
831 !
832  90   write(pu,110) iv(niter), nf, v(f), reldf, preldf,&
833                    v(reldx), v(stppar), v(dstnrm), nreldf
834  100  format(i6,i5,d10.3,2d9.2,d8.1,a3,a4,2d8.1,d9.2)
835  110  format(i6,i5,d11.3,2d10.2,3d9.1,d10.2)
836 !
837  120  if (iv(statpr) .lt. 0) go to 430
838       go to (999, 999, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310,&
839              330, 350, 520), iv1
840 !
841  130  write(pu,140)
842  140  format(/26h ***** x-convergence *****)
843       go to 430
844 !
845  150  write(pu,160)
846  160  format(/42h ***** relative function convergence *****)
847       go to 430
848 !
849  170  write(pu,180)
850  180  format(/49h ***** x- and relative function convergence *****)
851       go to 430
852 !
853  190  write(pu,200)
854  200  format(/42h ***** absolute function convergence *****)
855       go to 430
856 !
857  210  write(pu,220)
858  220  format(/33h ***** singular convergence *****)
859       go to 430
860 !
861  230  write(pu,240)
862  240  format(/30h ***** false convergence *****)
863       go to 430
864 !
865  250  write(pu,260)
866  260  format(/38h ***** function evaluation limit *****)
867       go to 430
868 !
869  270  write(pu,280)
870  280  format(/28h ***** iteration limit *****)
871       go to 430
872 !
873  290  write(pu,300)
874  300  format(/18h ***** stopx *****)
875       go to 430
876 !
877  310  write(pu,320)
878  320  format(/44h ***** initial f(x) cannot be computed *****)
879 !
880       go to 390
881 !
882  330  write(pu,340)
883  340  format(/37h ***** bad parameters to assess *****)
884       go to 999
885 !
886  350  write(pu,360)
887  360  format(/43h ***** gradient could not be computed *****)
888       if (iv(niter) .gt. 0) go to 480
889       go to 390
890 !
891  370  write(pu,380) iv(1)
892  380  format(/14h ***** iv(1) =,i5,6h *****)
893       go to 999
894 !
895 !  ***  initial call on itsum  ***
896 !
897  390  if (iv(x0prt) .ne. 0) write(pu,400) (i, x(i), d(i), i = 1, p)
898  400  format(/23h     i     initial x(i),8x,4hd(i)//(1x,i5,d17.6,d14.3))
899 !     *** the following are to avoid undefined variables when the
900 !     *** function evaluation limit is 1...
901       v(dstnrm) = zero
902       v(fdif) = zero
903       v(nreduc) = zero
904       v(preduc) = zero
905       v(reldx)  = zero
906       if (iv1 .ge. 12) go to 999
907       iv(needhd) = 0
908       iv(prntit) = 0
909       if (ol .eq. 0) go to 999
910       if (ol .lt. 0 .and. alg .eq. 1) write(pu,30)
911       if (ol .lt. 0 .and. alg .eq. 2) write(pu,40)
912       if (ol .gt. 0 .and. alg .eq. 1) write(pu,70)
913       if (ol .gt. 0 .and. alg .eq. 2) write(pu,80)
914       if (alg .eq. 1) write(pu,410) v(f)
915       if (alg .eq. 2) write(pu,420) v(f)
916  410  format(/11h     0    1,d10.3)
917 !365  format(/11h     0    1,e11.3)
918  420  format(/11h     0    1,d11.3)
919       go to 999
920 !
921 !  ***  print various information requested on solution  ***
922 !
923  430  iv(needhd) = 1
924       if (iv(statpr) .eq. 0) go to 480
925          oldf = dmax1(dabs(v(f0)), dabs(v(f)))
926          preldf = zero
927          nreldf = zero
928          if (oldf .le. zero) go to 440
929               preldf = v(preduc) / oldf
930               nreldf = v(nreduc) / oldf
931  440     nf = iv(nfcall) - iv(nfcov)
932          ng = iv(ngcall) - iv(ngcov)
933          write(pu,450) v(f), v(reldx), nf, ng, preldf, nreldf
934  450  format(/9h function,d17.6,8h   reldx,d17.3/12h func. evals,&
935          i8,9x,11hgrad. evals,i8/7h preldf,d16.3,6x,7hnpreldf,d15.3)
936 !
937          if (iv(nfcov) .gt. 0) write(pu,460) iv(nfcov)
938  460     format(/1x,i4,50h extra func. evals for covariance and diagnostics.)
939          if (iv(ngcov) .gt. 0) write(pu,470) iv(ngcov)
940  470     format(1x,i4,50h extra grad. evals for covariance and diagnostics.)
941 !
942  480  if (iv(solprt) .eq. 0) go to 999
943          iv(needhd) = 1
944          write(pu,490)
945  490  format(/22h     i      final x(i),8x,4hd(i),10x,4hg(i)/)
946          do 500 i = 1, p
947               write(pu,510) i, x(i), d(i), g(i)
948  500          continue
949  510     format(1x,i5,d16.6,2d14.3)
950       go to 999
951 !
952  520  write(pu,530)
953  530  format(/24h inconsistent dimensions)
954  999  return
955 !  ***  last card of itsum follows  ***
956       end subroutine itsum
957 !-----------------------------------------------------------------------------
958       subroutine litvmu(n, x, l, y)
959 !
960 !  ***  solve  (l**t)*x = y,  where  l  is an  n x n  lower triangular
961 !  ***  matrix stored compactly by rows.  x and y may occupy the same
962 !  ***  storage.  ***
963 !
964       integer :: n
965 !al   real(kind=8) :: x(n), l(1), y(n)
966       real(kind=8) :: x(n), l(n*(n+1)/2), y(n)
967       integer :: i, ii, ij, im1, i0, j, np1
968       real(kind=8) :: xi        !el, zero
969 !/6
970 !     data zero/0.d+0/
971 !/7
972       real(kind=8),parameter :: zero=0.d+0
973 !/
974 !
975       do 10 i = 1, n
976  10      x(i) = y(i)
977       np1 = n + 1
978       i0 = n*(n+1)/2
979       do 30 ii = 1, n
980          i = np1 - ii
981          xi = x(i)/l(i0)
982          x(i) = xi
983          if (i .le. 1) go to 999
984          i0 = i0 - i
985          if (xi .eq. zero) go to 30
986          im1 = i - 1
987          do 20 j = 1, im1
988               ij = i0 + j
989               x(j) = x(j) - xi*l(ij)
990  20           continue
991  30      continue
992  999  return
993 !  ***  last card of litvmu follows  ***
994       end subroutine litvmu
995 !-----------------------------------------------------------------------------
996       subroutine livmul(n, x, l, y)
997 !
998 !  ***  solve  l*x = y, where  l  is an  n x n  lower triangular
999 !  ***  matrix stored compactly by rows.  x and y may occupy the same
1000 !  ***  storage.  ***
1001 !
1002       integer :: n
1003 !al   real(kind=8) :: x(n), l(1), y(n)
1004       real(kind=8) :: x(n), l(n*(n+1)/2), y(n)
1005 !el      external dotprd
1006 !el      real(kind=8) :: dotprd
1007       integer :: i, j, k
1008       real(kind=8) :: t !el, zero
1009 !/6
1010 !     data zero/0.d+0/
1011 !/7
1012       real(kind=8),parameter :: zero=0.d+0
1013 !/
1014 !
1015       do 10 k = 1, n
1016          if (y(k) .ne. zero) go to 20
1017          x(k) = zero
1018  10      continue
1019       go to 999
1020  20   j = k*(k+1)/2
1021       x(k) = y(k) / l(j)
1022       if (k .ge. n) go to 999
1023       k = k + 1
1024       do 30 i = k, n
1025          t = dotprd(i-1, l(j+1), x)
1026          j = j + i
1027          x(i) = (y(i) - t)/l(j)
1028  30      continue
1029  999  return
1030 !  ***  last card of livmul follows  ***
1031       end subroutine livmul
1032 !-----------------------------------------------------------------------------
1033       subroutine parck(alg, d, iv, liv, lv, n, v)
1034 !
1035 !  ***  check ***sol (version 2.3) parameters, print changed values  ***
1036 !
1037 !  ***  alg = 1 for regression, alg = 2 for general unconstrained opt.
1038 !
1039       integer :: alg, liv, lv, n
1040       integer :: iv(liv)
1041       real(kind=8) :: d(n), v(lv)
1042 !
1043 !el      external rmdcon, vcopy, vdflt
1044 !el      real(kind=8) :: rmdcon
1045 ! rmdcon -- returns machine-dependent constants.
1046 ! vcopy  -- copies one vector to another.
1047 ! vdflt  -- supplies default parameter values to v alone.
1048 !/+
1049 !el      integer :: max0
1050 !/
1051 !
1052 !  ***  local variables  ***
1053 !
1054       integer :: i, ii, iv1, j, k, l, m, miv1, miv2, ndfalt, parsv1, pu
1055       integer :: ijmp, jlim(2), miniv(2), ndflt(2)
1056 !/6
1057 !     integer varnm(2), sh(2)
1058 !     real cngd(3), dflt(3), vn(2,34), which(3)
1059 !/7
1060       character(len=1) :: varnm(2), sh(2)
1061       character(len=4) :: cngd(3), dflt(3), vn(2,34), which(3)
1062 !/
1063       real(kind=8) :: big, machep, tiny, vk, vm(34), vx(34), zero
1064 !
1065 !  ***  iv and v subscripts  ***
1066 !
1067 !el      integer algsav, dinit, dtype, dtype0, epslon, inits, ivneed,
1068 !el     1        lastiv, lastv, lmat, nextiv, nextv, nvdflt, oldn,
1069 !el     2        parprt, parsav, perm, prunit, vneed
1070 !
1071 !
1072 !/6
1073 !     data algsav/51/, dinit/38/, dtype/16/, dtype0/54/, epslon/19/,
1074 !    1     inits/25/, ivneed/3/, lastiv/44/, lastv/45/, lmat/42/,
1075 !    2     nextiv/46/, nextv/47/, nvdflt/50/, oldn/38/, parprt/20/,
1076 !    3     parsav/49/, perm/58/, prunit/21/, vneed/4/
1077 !/7
1078       integer,parameter :: algsav=51, dinit=38, dtype=16, dtype0=54, epslon=19,&
1079                  inits=25, ivneed=3, lastiv=44, lastv=45, lmat=42,&
1080                  nextiv=46, nextv=47, nvdflt=50, oldn=38, parprt=20,&
1081                  parsav=49, perm=58, prunit=21, vneed=4
1082       save big, machep, tiny
1083 !/
1084 !
1085       data big/0.d+0/, machep/-1.d+0/, tiny/1.d+0/, zero/0.d+0/
1086 !/6
1087 !     data vn(1,1),vn(2,1)/4hepsl,4hon../
1088 !     data vn(1,2),vn(2,2)/4hphmn,4hfc../
1089 !     data vn(1,3),vn(2,3)/4hphmx,4hfc../
1090 !     data vn(1,4),vn(2,4)/4hdecf,4hac../
1091 !     data vn(1,5),vn(2,5)/4hincf,4hac../
1092 !     data vn(1,6),vn(2,6)/4hrdfc,4hmn../
1093 !     data vn(1,7),vn(2,7)/4hrdfc,4hmx../
1094 !     data vn(1,8),vn(2,8)/4htune,4hr1../
1095 !     data vn(1,9),vn(2,9)/4htune,4hr2../
1096 !     data vn(1,10),vn(2,10)/4htune,4hr3../
1097 !     data vn(1,11),vn(2,11)/4htune,4hr4../
1098 !     data vn(1,12),vn(2,12)/4htune,4hr5../
1099 !     data vn(1,13),vn(2,13)/4hafct,4hol../
1100 !     data vn(1,14),vn(2,14)/4hrfct,4hol../
1101 !     data vn(1,15),vn(2,15)/4hxcto,4hl.../
1102 !     data vn(1,16),vn(2,16)/4hxfto,4hl.../
1103 !     data vn(1,17),vn(2,17)/4hlmax,4h0.../
1104 !     data vn(1,18),vn(2,18)/4hlmax,4hs.../
1105 !     data vn(1,19),vn(2,19)/4hscto,4hl.../
1106 !     data vn(1,20),vn(2,20)/4hdini,4ht.../
1107 !     data vn(1,21),vn(2,21)/4hdtin,4hit../
1108 !     data vn(1,22),vn(2,22)/4hd0in,4hit../
1109 !     data vn(1,23),vn(2,23)/4hdfac,4h..../
1110 !     data vn(1,24),vn(2,24)/4hdltf,4hdc../
1111 !     data vn(1,25),vn(2,25)/4hdltf,4hdj../
1112 !     data vn(1,26),vn(2,26)/4hdelt,4ha0../
1113 !     data vn(1,27),vn(2,27)/4hfuzz,4h..../
1114 !     data vn(1,28),vn(2,28)/4hrlim,4hit../
1115 !     data vn(1,29),vn(2,29)/4hcosm,4hin../
1116 !     data vn(1,30),vn(2,30)/4hhube,4hrc../
1117 !     data vn(1,31),vn(2,31)/4hrspt,4hol../
1118 !     data vn(1,32),vn(2,32)/4hsigm,4hin../
1119 !     data vn(1,33),vn(2,33)/4heta0,4h..../
1120 !     data vn(1,34),vn(2,34)/4hbias,4h..../
1121 !/7
1122       data vn(1,1),vn(2,1)/'epsl','on..'/
1123       data vn(1,2),vn(2,2)/'phmn','fc..'/
1124       data vn(1,3),vn(2,3)/'phmx','fc..'/
1125       data vn(1,4),vn(2,4)/'decf','ac..'/
1126       data vn(1,5),vn(2,5)/'incf','ac..'/
1127       data vn(1,6),vn(2,6)/'rdfc','mn..'/
1128       data vn(1,7),vn(2,7)/'rdfc','mx..'/
1129       data vn(1,8),vn(2,8)/'tune','r1..'/
1130       data vn(1,9),vn(2,9)/'tune','r2..'/
1131       data vn(1,10),vn(2,10)/'tune','r3..'/
1132       data vn(1,11),vn(2,11)/'tune','r4..'/
1133       data vn(1,12),vn(2,12)/'tune','r5..'/
1134       data vn(1,13),vn(2,13)/'afct','ol..'/
1135       data vn(1,14),vn(2,14)/'rfct','ol..'/
1136       data vn(1,15),vn(2,15)/'xcto','l...'/
1137       data vn(1,16),vn(2,16)/'xfto','l...'/
1138       data vn(1,17),vn(2,17)/'lmax','0...'/
1139       data vn(1,18),vn(2,18)/'lmax','s...'/
1140       data vn(1,19),vn(2,19)/'scto','l...'/
1141       data vn(1,20),vn(2,20)/'dini','t...'/
1142       data vn(1,21),vn(2,21)/'dtin','it..'/
1143       data vn(1,22),vn(2,22)/'d0in','it..'/
1144       data vn(1,23),vn(2,23)/'dfac','....'/
1145       data vn(1,24),vn(2,24)/'dltf','dc..'/
1146       data vn(1,25),vn(2,25)/'dltf','dj..'/
1147       data vn(1,26),vn(2,26)/'delt','a0..'/
1148       data vn(1,27),vn(2,27)/'fuzz','....'/
1149       data vn(1,28),vn(2,28)/'rlim','it..'/
1150       data vn(1,29),vn(2,29)/'cosm','in..'/
1151       data vn(1,30),vn(2,30)/'hube','rc..'/
1152       data vn(1,31),vn(2,31)/'rspt','ol..'/
1153       data vn(1,32),vn(2,32)/'sigm','in..'/
1154       data vn(1,33),vn(2,33)/'eta0','....'/
1155       data vn(1,34),vn(2,34)/'bias','....'/
1156 !/
1157 !
1158       data vm(1)/1.0d-3/, vm(2)/-0.99d+0/, vm(3)/1.0d-3/, vm(4)/1.0d-2/,&
1159            vm(5)/1.2d+0/, vm(6)/1.d-2/, vm(7)/1.2d+0/, vm(8)/0.d+0/,&
1160            vm(9)/0.d+0/, vm(10)/1.d-3/, vm(11)/-1.d+0/, vm(13)/0.d+0/,&
1161            vm(15)/0.d+0/, vm(16)/0.d+0/, vm(19)/0.d+0/, vm(20)/-10.d+0/,&
1162            vm(21)/0.d+0/, vm(22)/0.d+0/, vm(23)/0.d+0/, vm(27)/1.01d+0/,&
1163            vm(28)/1.d+10/, vm(30)/0.d+0/, vm(31)/0.d+0/, vm(32)/0.d+0/,&
1164            vm(34)/0.d+0/
1165       data vx(1)/0.9d+0/, vx(2)/-1.d-3/, vx(3)/1.d+1/, vx(4)/0.8d+0/,&
1166            vx(5)/1.d+2/, vx(6)/0.8d+0/, vx(7)/1.d+2/, vx(8)/0.5d+0/,&
1167            vx(9)/0.5d+0/, vx(10)/1.d+0/, vx(11)/1.d+0/, vx(14)/0.1d+0/,&
1168            vx(15)/1.d+0/, vx(16)/1.d+0/, vx(19)/1.d+0/, vx(23)/1.d+0/,&
1169            vx(24)/1.d+0/, vx(25)/1.d+0/, vx(26)/1.d+0/, vx(27)/1.d+10/,&
1170            vx(29)/1.d+0/, vx(31)/1.d+0/, vx(32)/1.d+0/, vx(33)/1.d+0/,&
1171            vx(34)/1.d+0/
1172 !
1173 !/6
1174 !     data varnm(1)/1hp/, varnm(2)/1hn/, sh(1)/1hs/, sh(2)/1hh/
1175 !     data cngd(1),cngd(2),cngd(3)/4h---c,4hhang,4hed v/,
1176 !    1     dflt(1),dflt(2),dflt(3)/4hnond,4hefau,4hlt v/
1177 !/7
1178       data varnm(1)/'p'/, varnm(2)/'n'/, sh(1)/'s'/, sh(2)/'h'/
1179       data cngd(1),cngd(2),cngd(3)/'---c','hang','ed v'/,&
1180            dflt(1),dflt(2),dflt(3)/'nond','efau','lt v'/
1181 !/
1182       data ijmp/33/, jlim(1)/0/, jlim(2)/24/, ndflt(1)/32/, ndflt(2)/25/
1183       data miniv(1)/80/, miniv(2)/59/
1184 !
1185 !...............................  body  ................................
1186 !
1187       pu = 0
1188       if (prunit .le. liv) pu = iv(prunit)
1189       if (alg .lt. 1 .or. alg .gt. 2) go to 340
1190       if (iv(1) .eq. 0) call deflt(alg, iv, liv, lv, v)
1191       iv1 = iv(1)
1192       if (iv1 .ne. 13 .and. iv1 .ne. 12) go to 10
1193       miv1 = miniv(alg)
1194       if (perm .le. liv) miv1 = max0(miv1, iv(perm) - 1)
1195       if (ivneed .le. liv) miv2 = miv1 + max0(iv(ivneed), 0)
1196       if (lastiv .le. liv) iv(lastiv) = miv2
1197       if (liv .lt. miv1) go to 300
1198       iv(ivneed) = 0
1199       iv(lastv) = max0(iv(vneed), 0) + iv(lmat) - 1
1200       iv(vneed) = 0
1201       if (liv .lt. miv2) go to 300
1202       if (lv .lt. iv(lastv)) go to 320
1203  10   if (alg .eq. iv(algsav)) go to 30
1204          if (pu .ne. 0) write(pu,20) alg, iv(algsav)
1205  20      format(/39h the first parameter to deflt should be,i3,&
1206                 12h rather than,i3)
1207          iv(1) = 82
1208          go to 999
1209  30   if (iv1 .lt. 12 .or. iv1 .gt. 14) go to 60
1210          if (n .ge. 1) go to 50
1211               iv(1) = 81
1212               if (pu .eq. 0) go to 999
1213               write(pu,40) varnm(alg), n
1214  40           format(/8h /// bad,a1,2h =,i5)
1215               go to 999
1216  50      if (iv1 .ne. 14) iv(nextiv) = iv(perm)
1217          if (iv1 .ne. 14) iv(nextv) = iv(lmat)
1218          if (iv1 .eq. 13) go to 999
1219          k = iv(parsav) - epslon
1220          call vdflt(alg, lv-k, v(k+1))
1221          iv(dtype0) = 2 - alg
1222          iv(oldn) = n
1223          which(1) = dflt(1)
1224          which(2) = dflt(2)
1225          which(3) = dflt(3)
1226          go to 110
1227  60   if (n .eq. iv(oldn)) go to 80
1228          iv(1) = 17
1229          if (pu .eq. 0) go to 999
1230          write(pu,70) varnm(alg), iv(oldn), n
1231  70      format(/5h /// ,1a1,14h changed from ,i5,4h to ,i5)
1232          go to 999
1233 !
1234  80   if (iv1 .le. 11 .and. iv1 .ge. 1) go to 100
1235          iv(1) = 80
1236          if (pu .ne. 0) write(pu,90) iv1
1237  90      format(/13h ///  iv(1) =,i5,28h should be between 0 and 14.)
1238          go to 999
1239 !
1240  100  which(1) = cngd(1)
1241       which(2) = cngd(2)
1242       which(3) = cngd(3)
1243 !
1244  110  if (iv1 .eq. 14) iv1 = 12
1245       if (big .gt. tiny) go to 120
1246          tiny = rmdcon(1)
1247          machep = rmdcon(3)
1248          big = rmdcon(6)
1249          vm(12) = machep
1250          vx(12) = big
1251          vx(13) = big
1252          vm(14) = machep
1253          vm(17) = tiny
1254          vx(17) = big
1255          vm(18) = tiny
1256          vx(18) = big
1257          vx(20) = big
1258          vx(21) = big
1259          vx(22) = big
1260          vm(24) = machep
1261          vm(25) = machep
1262          vm(26) = machep
1263          vx(28) = rmdcon(5)
1264          vm(29) = machep
1265          vx(30) = big
1266          vm(33) = machep
1267  120  m = 0
1268       i = 1
1269       j = jlim(alg)
1270       k = epslon
1271       ndfalt = ndflt(alg)
1272       do 150 l = 1, ndfalt
1273          vk = v(k)
1274          if (vk .ge. vm(i) .and. vk .le. vx(i)) go to 140
1275               m = k
1276               if (pu .ne. 0) write(pu,130) vn(1,i), vn(2,i), k, vk,&
1277                                           vm(i), vx(i)
1278  130          format(/6h ///  ,2a4,5h.. v(,i2,3h) =,d11.3,7h should,&
1279                      11h be between,d11.3,4h and,d11.3)
1280  140     k = k + 1
1281          i = i + 1
1282          if (i .eq. j) i = ijmp
1283  150     continue
1284 !
1285       if (iv(nvdflt) .eq. ndfalt) go to 170
1286          iv(1) = 51
1287          if (pu .eq. 0) go to 999
1288          write(pu,160) iv(nvdflt), ndfalt
1289  160     format(/13h iv(nvdflt) =,i5,13h rather than ,i5)
1290          go to 999
1291  170  if ((iv(dtype) .gt. 0 .or. v(dinit) .gt. zero) .and. iv1 .eq. 12) &
1292                         go to 200
1293       do 190 i = 1, n
1294          if (d(i) .gt. zero) go to 190
1295               m = 18
1296               if (pu .ne. 0) write(pu,180) i, d(i)
1297  180     format(/8h ///  d(,i3,3h) =,d11.3,19h should be positive)
1298  190     continue
1299  200  if (m .eq. 0) go to 210
1300          iv(1) = m
1301          go to 999
1302 !
1303  210  if (pu .eq. 0 .or. iv(parprt) .eq. 0) go to 999
1304       if (iv1 .ne. 12 .or. iv(inits) .eq. alg-1) go to 230
1305          m = 1
1306          write(pu,220) sh(alg), iv(inits)
1307  220     format(/22h nondefault values..../5h init,a1,14h..... iv(25) =,&
1308                 i3)
1309  230  if (iv(dtype) .eq. iv(dtype0)) go to 250
1310          if (m .eq. 0) write(pu,260) which
1311          m = 1
1312          write(pu,240) iv(dtype)
1313  240     format(20h dtype..... iv(16) =,i3)
1314  250  i = 1
1315       j = jlim(alg)
1316       k = epslon
1317       l = iv(parsav)
1318       ndfalt = ndflt(alg)
1319       do 290 ii = 1, ndfalt
1320          if (v(k) .eq. v(l)) go to 280
1321               if (m .eq. 0) write(pu,260) which
1322  260          format(/1h ,3a4,9halues..../)
1323               m = 1
1324               write(pu,270) vn(1,i), vn(2,i), k, v(k)
1325  270          format(1x,2a4,5h.. v(,i2,3h) =,d15.7)
1326  280     k = k + 1
1327          l = l + 1
1328          i = i + 1
1329          if (i .eq. j) i = ijmp
1330  290     continue
1331 !
1332       iv(dtype0) = iv(dtype)
1333       parsv1 = iv(parsav)
1334       call vcopy(iv(nvdflt), v(parsv1), v(epslon))
1335       go to 999
1336 !
1337  300  iv(1) = 15
1338       if (pu .eq. 0) go to 999
1339       write(pu,310) liv, miv2
1340  310  format(/10h /// liv =,i5,17h must be at least,i5)
1341       if (liv .lt. miv1) go to 999
1342       if (lv .lt. iv(lastv)) go to 320
1343       go to 999
1344 !
1345  320  iv(1) = 16
1346       if (pu .eq. 0) go to 999
1347       write(pu,330) lv, iv(lastv)
1348  330  format(/9h /// lv =,i5,17h must be at least,i5)
1349       go to 999
1350 !
1351  340  iv(1) = 67
1352       if (pu .eq. 0) go to 999
1353       write(pu,350) alg
1354  350  format(/10h /// alg =,i5,15h must be 1 or 2)
1355 !
1356  999  return
1357 !  ***  last card of parck follows  ***
1358       end subroutine parck
1359 !-----------------------------------------------------------------------------
1360       real(kind=8) function reldst(p, d, x, x0)
1361 !
1362 !  ***  compute and return relative difference between x and x0  ***
1363 !  ***  nl2sol version 2.2  ***
1364 !
1365       integer :: p
1366       real(kind=8) :: d(p), x(p), x0(p)
1367 !/+
1368 !el      real(kind=8) :: dabs
1369 !/
1370       integer :: i
1371       real(kind=8) :: emax, t, xmax     !el, zero
1372 !/6
1373 !     data zero/0.d+0/
1374 !/7
1375       real(kind=8),parameter :: zero=0.d+0
1376 !/
1377 !
1378       emax = zero
1379       xmax = zero
1380       do 10 i = 1, p
1381          t = dabs(d(i) * (x(i) - x0(i)))
1382          if (emax .lt. t) emax = t
1383          t = d(i) * (dabs(x(i)) + dabs(x0(i)))
1384          if (xmax .lt. t) xmax = t
1385  10      continue
1386       reldst = zero
1387       if (xmax .gt. zero) reldst = emax / xmax
1388  999  return
1389 !  ***  last card of reldst follows  ***
1390       end function reldst
1391 !-----------------------------------------------------------------------------
1392       subroutine vaxpy(p, w, a, x, y)
1393 !
1394 !  ***  set w = a*x + y  --  w, x, y = p-vectors, a = scalar  ***
1395 !
1396       integer :: p
1397       real(kind=8) :: a, w(p), x(p), y(p)
1398 !
1399       integer :: i
1400 !
1401       do 10 i = 1, p
1402  10      w(i) = a*x(i) + y(i)
1403       return
1404       end subroutine vaxpy
1405 !-----------------------------------------------------------------------------
1406       subroutine vcopy(p, y, x)
1407 !
1408 !  ***  set y = x, where x and y are p-vectors  ***
1409 !
1410       integer :: p
1411       real(kind=8) :: x(p), y(p)
1412 !
1413       integer :: i
1414 !
1415       do 10 i = 1, p
1416  10      y(i) = x(i)
1417       return
1418       end subroutine vcopy
1419 !-----------------------------------------------------------------------------
1420       subroutine vdflt(alg, lv, v)
1421 !
1422 !  ***  supply ***sol (version 2.3) default values to v  ***
1423 !
1424 !  ***  alg = 1 means regression constants.
1425 !  ***  alg = 2 means general unconstrained optimization constants.
1426 !
1427       integer :: alg, l,lv
1428       real(kind=8) :: v(lv)
1429 !/+
1430 !el      real(kind=8) :: dmax1
1431 !/
1432 !el      external rmdcon
1433 !el      real(kind=8) :: rmdcon
1434 ! rmdcon... returns machine-dependent constants
1435 !
1436       real(kind=8) :: machep, mepcrt, sqteps    !el one, three
1437 !
1438 !  ***  subscripts for v  ***
1439 !
1440 !el      integer afctol, bias, cosmin, decfac, delta0, dfac, dinit, dltfdc,
1441 !el     1        dltfdj, dtinit, d0init, epslon, eta0, fuzz, huberc,
1442 !el     2        incfac, lmax0, lmaxs, phmnfc, phmxfc, rdfcmn, rdfcmx,
1443 !el     3        rfctol, rlimit, rsptol, sctol, sigmin, tuner1, tuner2,
1444 !el     4        tuner3, tuner4, tuner5, xctol, xftol
1445 !
1446 !/6
1447 !     data one/1.d+0/, three/3.d+0/
1448 !/7
1449       real(kind=8),parameter :: one=1.d+0, three=3.d+0
1450 !/
1451 !
1452 !  ***  v subscript values  ***
1453 !
1454 !/6
1455 !     data afctol/31/, bias/43/, cosmin/47/, decfac/22/, delta0/44/,
1456 !    1     dfac/41/, dinit/38/, dltfdc/42/, dltfdj/43/, dtinit/39/,
1457 !    2     d0init/40/, epslon/19/, eta0/42/, fuzz/45/, huberc/48/,
1458 !    3     incfac/23/, lmax0/35/, lmaxs/36/, phmnfc/20/, phmxfc/21/,
1459 !    4     rdfcmn/24/, rdfcmx/25/, rfctol/32/, rlimit/46/, rsptol/49/,
1460 !    5     sctol/37/, sigmin/50/, tuner1/26/, tuner2/27/, tuner3/28/,
1461 !    6     tuner4/29/, tuner5/30/, xctol/33/, xftol/34/
1462 !/7
1463       integer,parameter :: afctol=31, bias=43, cosmin=47, decfac=22, delta0=44,&
1464                  dfac=41, dinit=38, dltfdc=42, dltfdj=43, dtinit=39,&
1465                  d0init=40, epslon=19, eta0=42, fuzz=45, huberc=48,&
1466                  incfac=23, lmax0=35, lmaxs=36, phmnfc=20, phmxfc=21,&
1467                  rdfcmn=24, rdfcmx=25, rfctol=32, rlimit=46, rsptol=49,&
1468                  sctol=37, sigmin=50, tuner1=26, tuner2=27, tuner3=28,&
1469                  tuner4=29, tuner5=30, xctol=33, xftol=34
1470 !/
1471 !
1472 !-------------------------------  body  --------------------------------
1473 !
1474       machep = rmdcon(3)
1475       v(afctol) = 1.d-20
1476       if (machep .gt. 1.d-10) v(afctol) = machep**2
1477       v(decfac) = 0.5d+0
1478       sqteps = rmdcon(4)
1479       v(dfac) = 0.6d+0
1480       v(delta0) = sqteps
1481       v(dtinit) = 1.d-6
1482       mepcrt = machep ** (one/three)
1483       v(d0init) = 1.d+0
1484       v(epslon) = 0.1d+0
1485       v(incfac) = 2.d+0
1486       v(lmax0) = 1.d+0
1487       v(lmaxs) = 1.d+0
1488       v(phmnfc) = -0.1d+0
1489       v(phmxfc) = 0.1d+0
1490       v(rdfcmn) = 0.1d+0
1491       v(rdfcmx) = 4.d+0
1492       v(rfctol) = dmax1(1.d-10, mepcrt**2)
1493       v(sctol) = v(rfctol)
1494       v(tuner1) = 0.1d+0
1495       v(tuner2) = 1.d-4
1496       v(tuner3) = 0.75d+0
1497       v(tuner4) = 0.5d+0
1498       v(tuner5) = 0.75d+0
1499       v(xctol) = sqteps
1500       v(xftol) = 1.d+2 * machep
1501 !
1502       if (alg .ge. 2) go to 10
1503 !
1504 !  ***  regression  values
1505 !
1506       v(cosmin) = dmax1(1.d-6, 1.d+2 * machep)
1507       v(dinit) = 0.d+0
1508       v(dltfdc) = mepcrt
1509       v(dltfdj) = sqteps
1510       v(fuzz) = 1.5d+0
1511       v(huberc) = 0.7d+0
1512       v(rlimit) = rmdcon(5)
1513       v(rsptol) = 1.d-3
1514       v(sigmin) = 1.d-4
1515       go to 999
1516 !
1517 !  ***  general optimization values
1518 !
1519  10   v(bias) = 0.8d+0
1520       v(dinit) = -1.0d+0
1521       v(eta0) = 1.0d+3 * machep
1522 !
1523  999  return
1524 !  ***  last card of vdflt follows  ***
1525       end subroutine vdflt
1526 !-----------------------------------------------------------------------------
1527       subroutine vscopy(p, y, s)
1528 !
1529 !  ***  set p-vector y to scalar s  ***
1530 !
1531       integer :: p
1532       real(kind=8) :: s, y(p)
1533 !
1534       integer :: i
1535 !
1536       do 10 i = 1, p
1537  10      y(i) = s
1538       return
1539       end subroutine vscopy
1540 !-----------------------------------------------------------------------------
1541       real(kind=8) function v2norm(p, x)
1542 !
1543 !  ***  return the 2-norm of the p-vector x, taking  ***
1544 !  ***  care to avoid the most likely underflows.    ***
1545 !
1546       integer :: p
1547       real(kind=8) :: x(p)
1548 !
1549       integer :: i, j
1550       real(kind=8) :: r, scale, sqteta, t, xi   !el, one, zero
1551 !/+
1552 !el      real(kind=8) :: dabs, dsqrt
1553 !/
1554 !el      external rmdcon
1555 !el      real(kind=8) :: rmdcon
1556 !
1557 !/6
1558 !     data one/1.d+0/, zero/0.d+0/
1559 !/7
1560       real(kind=8),parameter :: one=1.d+0, zero=0.d+0
1561       save sqteta
1562 !/
1563       data sqteta/0.d+0/
1564 !
1565       if (p .gt. 0) go to 10
1566          v2norm = zero
1567          go to 999
1568  10   do 20 i = 1, p
1569          if (x(i) .ne. zero) go to 30
1570  20      continue
1571       v2norm = zero
1572       go to 999
1573 !
1574  30   scale = dabs(x(i))
1575       if (i .lt. p) go to 40
1576          v2norm = scale
1577          go to 999
1578  40   t = one
1579       if (sqteta .eq. zero) sqteta = rmdcon(2)
1580 !
1581 !     ***  sqteta is (slightly larger than) the square root of the
1582 !     ***  smallest positive floating point number on the machine.
1583 !     ***  the tests involving sqteta are done to prevent underflows.
1584 !
1585       j = i + 1
1586       do 60 i = j, p
1587          xi = dabs(x(i))
1588          if (xi .gt. scale) go to 50
1589               r = xi / scale
1590               if (r .gt. sqteta) t = t + r*r
1591               go to 60
1592  50           r = scale / xi
1593               if (r .le. sqteta) r = zero
1594               t = one  +  t * r*r
1595               scale = xi
1596  60      continue
1597 !
1598       v2norm = scale * dsqrt(t)
1599  999  return
1600 !  ***  last card of v2norm follows  ***
1601       end function v2norm
1602 !-----------------------------------------------------------------------------
1603       subroutine humsl(n,d,x,calcf,calcgh,iv,liv,lv,v,uiparm,urparm,ufparm)
1604 !
1605 !  ***  minimize general unconstrained objective function using   ***
1606 !  ***  (analytic) gradient and hessian provided by the caller.   ***
1607 !
1608       integer :: liv, lv, n
1609       integer :: iv(liv), uiparm(1)
1610       real(kind=8) :: d(n), x(n), v(lv), urparm(1)
1611       real(kind=8),external :: ufparm
1612 !     dimension v(78 + n*(n+12)), uiparm(*), urparm(*)
1613       external :: calcf, calcgh
1614 !
1615 !------------------------------  discussion  ---------------------------
1616 !
1617 !        this routine is like sumsl, except that the subroutine para-
1618 !     meter calcg of sumsl (which computes the gradient of the objec-
1619 !     tive function) is replaced by the subroutine parameter calcgh,
1620 !     which computes both the gradient and (lower triangle of the)
1621 !     hessian of the objective function.  the calling sequence is...
1622 !             call calcgh(n, x, nf, g, h, uiparm, urparm, ufparm)
1623 !     parameters n, x, nf, g, uiparm, urparm, and ufparm are the same
1624 !     as for sumsl, while h is an array of length n*(n+1)/2 in which
1625 !     calcgh must store the lower triangle of the hessian at x.  start-
1626 !     ing at h(1), calcgh must store the hessian entries in the order
1627 !     (1,1), (2,1), (2,2), (3,1), (3,2), (3,3), ...
1628 !        the value printed (by itsum) in the column labelled stppar
1629 !     is the levenberg-marquardt used in computing the current step.
1630 !     zero means a full newton step.  if the special case described in
1631 !     ref. 1 is detected, then stppar is negated.  the value printed
1632 !     in the column labelled npreldf is zero if the current hessian
1633 !     is not positive definite.
1634 !        it sometimes proves worthwhile to let d be determined from the
1635 !     diagonal of the hessian matrix by setting iv(dtype) = 1 and
1636 !     v(dinit) = 0.  the following iv and v components are relevant...
1637 !
1638 ! iv(dtol)..... iv(59) gives the starting subscript in v of the dtol
1639 !             array used when d is updated.  (iv(dtol) can be
1640 !             initialized by calling humsl with iv(1) = 13.)
1641 ! iv(dtype).... iv(16) tells how the scale vector d should be chosen.
1642 !             iv(dtype) .le. 0 means that d should not be updated, and
1643 !             iv(dtype) .ge. 1 means that d should be updated as
1644 !             described below with v(dfac).  default = 0.
1645 ! v(dfac)..... v(41) and the dtol and d0 arrays (see v(dtinit) and
1646 !             v(d0init)) are used in updating the scale vector d when
1647 !             iv(dtype) .gt. 0.  (d is initialized according to
1648 !             v(dinit), described in sumsl.)  let
1649 !                  d1(i) = max(sqrt(abs(h(i,i))), v(dfac)*d(i)),
1650 !             where h(i,i) is the i-th diagonal element of the current
1651 !             hessian.  if iv(dtype) = 1, then d(i) is set to d1(i)
1652 !             unless d1(i) .lt. dtol(i), in which case d(i) is set to
1653 !                  max(d0(i), dtol(i)).
1654 !             if iv(dtype) .ge. 2, then d is updated during the first
1655 !             iteration as for iv(dtype) = 1 (after any initialization
1656 !             due to v(dinit)) and is left unchanged thereafter.
1657 !             default = 0.6.
1658 ! v(dtinit)... v(39), if positive, is the value to which all components
1659 !             of the dtol array (see v(dfac)) are initialized.  if
1660 !             v(dtinit) = 0, then it is assumed that the caller has
1661 !             stored dtol in v starting at v(iv(dtol)).
1662 !             default = 10**-6.
1663 ! v(d0init)... v(40), if positive, is the value to which all components
1664 !             of the d0 vector (see v(dfac)) are initialized.  if
1665 !             v(dfac) = 0, then it is assumed that the caller has
1666 !             stored d0 in v starting at v(iv(dtol)+n).  default = 1.0.
1667 !
1668 !  ***  reference  ***
1669 !
1670 ! 1. gay, d.m. (1981), computing optimal locally constrained steps,
1671 !         siam j. sci. statist. comput. 2, pp. 186-197.
1672 !.
1673 !  ***  general  ***
1674 !
1675 !     coded by david m. gay (winter 1980).  revised sept. 1982.
1676 !     this subroutine was written in connection with research supported
1677 !     in part by the national science foundation under grants
1678 !     mcs-7600324 and mcs-7906671.
1679 !
1680 !----------------------------  declarations  ---------------------------
1681 !
1682 !el      external deflt, humit
1683 !
1684 ! deflt... provides default input values for iv and v.
1685 ! humit... reverse-communication routine that does humsl algorithm.
1686 !
1687       integer :: g1, h1, iv1, lh, nf
1688       real(kind=8) :: f
1689 !
1690 !  ***  subscripts for iv   ***
1691 !
1692 !el      integer g, h, nextv, nfcall, nfgcal, toobig, vneed
1693 !
1694 !/6
1695 !     data nextv/47/, nfcall/6/, nfgcal/7/, g/28/, h/56/, toobig/2/,
1696 !    1     vneed/4/
1697 !/7
1698       integer,parameter :: nextv=47, nfcall=6, nfgcal=7, g=28, h=56,&
1699                            toobig=2,vneed=4
1700 !/
1701 !
1702 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
1703 !
1704       lh = n * (n + 1) / 2
1705       if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
1706       if (iv(1) .eq. 12 .or. iv(1) .eq. 13) &
1707            iv(vneed) = iv(vneed) + n*(n+3)/2
1708       iv1 = iv(1)
1709       if (iv1 .eq. 14) go to 10
1710       if (iv1 .gt. 2 .and. iv1 .lt. 12) go to 10
1711       g1 = 1
1712       h1 = 1
1713       if (iv1 .eq. 12) iv(1) = 13
1714       go to 20
1715 !
1716  10   g1 = iv(g)
1717       h1 = iv(h)
1718 !
1719  20   call humit(d, f, v(g1), v(h1), iv, lh, liv, lv, n, v, x)
1720       if (iv(1) - 2) 30, 40, 50
1721 !
1722  30   nf = iv(nfcall)
1723       call calcf(n, x, nf, f, uiparm, urparm, ufparm)
1724       if (nf .le. 0) iv(toobig) = 1
1725       go to 20
1726 !
1727  40   call calcgh(n, x, iv(nfgcal), v(g1), v(h1), uiparm, urparm,&
1728                   ufparm)
1729       go to 20
1730 !
1731  50   if (iv(1) .ne. 14) go to 999
1732 !
1733 !  ***  storage allocation
1734 !
1735       iv(g) = iv(nextv)
1736       iv(h) = iv(g) + n
1737       iv(nextv) = iv(h) + n*(n+1)/2
1738       if (iv1 .ne. 13) go to 10
1739 !
1740  999  return
1741 !  ***  last card of humsl follows  ***
1742       end subroutine humsl
1743 !-----------------------------------------------------------------------------
1744       subroutine humit(d, fx, g, h, iv, lh, liv, lv, n, v, x)
1745 !
1746 !  ***  carry out humsl (unconstrained minimization) iterations, using
1747 !  ***  hessian matrix provided by the caller.
1748 !
1749 !el      use control
1750       use control, only:stopx
1751
1752 !  ***  parameter declarations  ***
1753 !
1754       integer :: lh, liv, lv, n
1755       integer :: iv(liv)
1756       real(kind=8) :: d(n), fx, g(n), h(lh), v(lv), x(n)
1757 !
1758 !--------------------------  parameter usage  --------------------------
1759 !
1760 ! d.... scale vector.
1761 ! fx... function value.
1762 ! g.... gradient vector.
1763 ! h.... lower triangle of the hessian, stored rowwise.
1764 ! iv... integer value array.
1765 ! lh... length of h = p*(p+1)/2.
1766 ! liv.. length of iv (at least 60).
1767 ! lv... length of v (at least 78 + n*(n+21)/2).
1768 ! n.... number of variables (components in x and g).
1769 ! v.... floating-point value array.
1770 ! x.... parameter vector.
1771 !
1772 !  ***  discussion  ***
1773 !
1774 !        parameters iv, n, v, and x are the same as the corresponding
1775 !     ones to humsl (which see), except that v can be shorter (since
1776 !     the part of v that humsl uses for storing g and h is not needed).
1777 !     moreover, compared with humsl, iv(1) may have the two additional
1778 !     output values 1 and 2, which are explained below, as is the use
1779 !     of iv(toobig) and iv(nfgcal).  the value iv(g), which is an
1780 !     output value from humsl, is not referenced by humit or the
1781 !     subroutines it calls.
1782 !
1783 ! iv(1) = 1 means the caller should set fx to f(x), the function value
1784 !             at x, and call humit again, having changed none of the
1785 !             other parameters.  an exception occurs if f(x) cannot be
1786 !             computed (e.g. if overflow would occur), which may happen
1787 !             because of an oversized step.  in this case the caller
1788 !             should set iv(toobig) = iv(2) to 1, which will cause
1789 !             humit to ignore fx and try a smaller step.  the para-
1790 !             meter nf that humsl passes to calcf (for possible use by
1791 !             calcgh) is a copy of iv(nfcall) = iv(6).
1792 ! iv(1) = 2 means the caller should set g to g(x), the gradient of f at
1793 !             x, and h to the lower triangle of h(x), the hessian of f
1794 !             at x, and call humit again, having changed none of the
1795 !             other parameters except perhaps the scale vector d.
1796 !                  the parameter nf that humsl passes to calcg is
1797 !             iv(nfgcal) = iv(7).  if g(x) and h(x) cannot be evaluated,
1798 !             then the caller may set iv(nfgcal) to 0, in which case
1799 !             humit will return with iv(1) = 65.
1800 !                  note -- humit overwrites h with the lower triangle
1801 !             of  diag(d)**-1 * h(x) * diag(d)**-1.
1802 !.
1803 !  ***  general  ***
1804 !
1805 !     coded by david m. gay (winter 1980).  revised sept. 1982.
1806 !     this subroutine was written in connection with research supported
1807 !     in part by the national science foundation under grants
1808 !     mcs-7600324 and mcs-7906671.
1809 !
1810 !        (see sumsl and humsl for references.)
1811 !
1812 !+++++++++++++++++++++++++++  declarations  ++++++++++++++++++++++++++++
1813 !
1814 !  ***  local variables  ***
1815 !
1816       integer :: dg1, dummy, i, j, k, l, lstgst, nn1o2, step1,&
1817               temp1, w1, x01
1818       real(kind=8) :: t
1819 !
1820 !     ***  constants  ***
1821 !
1822 !el      real(kind=8) :: one, onep2, zero
1823 !
1824 !  ***  no intrinsic functions  ***
1825 !
1826 !  ***  external functions and subroutines  ***
1827 !
1828 !el      external assst, deflt, dotprd, dupdu, gqtst, itsum, parck,
1829 !el     1         reldst, slvmul, stopx, vaxpy, vcopy, vscopy, v2norm
1830 !el      logical stopx
1831 !el      real(kind=8) :: dotprd, reldst, v2norm
1832 !
1833 ! assst.... assesses candidate step.
1834 ! deflt.... provides default iv and v input values.
1835 ! dotprd... returns inner product of two vectors.
1836 ! dupdu.... updates scale vector d.
1837 ! gqtst.... computes optimally locally constrained step.
1838 ! itsum.... prints iteration summary and info on initial and final x.
1839 ! parck.... checks validity of input iv and v values.
1840 ! reldst... computes v(reldx) = relative step size.
1841 ! slvmul... multiplies symmetric matrix times vector, given the lower
1842 !             triangle of the matrix.
1843 ! stopx.... returns .true. if the break key has been pressed.
1844 ! vaxpy.... computes scalar times one vector plus another.
1845 ! vcopy.... copies one vector to another.
1846 ! vscopy... sets all elements of a vector to a scalar.
1847 ! v2norm... returns the 2-norm of a vector.
1848 !
1849 !  ***  subscripts for iv and v  ***
1850 !
1851 !el      integer cnvcod, dg, dgnorm, dinit, dstnrm, dtinit, dtol,
1852 !el     1        dtype, d0init, f, f0, fdif, gtstep, incfac, irc, kagqt,
1853 !el     2        lmat, lmax0, lmaxs, mode, model, mxfcal, mxiter, nextv,
1854 !el     3        nfcall, nfgcal, ngcall, niter, preduc, radfac, radinc,
1855 !el     4        radius, rad0, reldx, restor, step, stglim, stlstg, stppar,
1856 !el     5        toobig, tuner4, tuner5, vneed, w, xirc, x0
1857 !
1858 !  ***  iv subscript values  ***
1859 !
1860 !/6
1861 !     data cnvcod/55/, dg/37/, dtol/59/, dtype/16/, irc/29/, kagqt/33/,
1862 !    1     lmat/42/, mode/35/, model/5/, mxfcal/17/, mxiter/18/,
1863 !    2     nextv/47/, nfcall/6/, nfgcal/7/, ngcall/30/, niter/31/,
1864 !    3     radinc/8/, restor/9/, step/40/, stglim/11/, stlstg/41/,
1865 !    4     toobig/2/, vneed/4/, w/34/, xirc/13/, x0/43/
1866 !/7
1867       integer,parameter :: cnvcod=55, dg=37, dtol=59, dtype=16, irc=29, kagqt=33,&
1868                  lmat=42, mode=35, model=5, mxfcal=17, mxiter=18,&
1869                  nextv=47, nfcall=6, nfgcal=7, ngcall=30, niter=31,&
1870                  radinc=8, restor=9, step=40, stglim=11, stlstg=41,&
1871                  toobig=2, vneed=4, w=34, xirc=13, x0=43
1872 !/
1873 !
1874 !  ***  v subscript values  ***
1875 !
1876 !/6
1877 !     data dgnorm/1/, dinit/38/, dstnrm/2/, dtinit/39/, d0init/40/,
1878 !    1     f/10/, f0/13/, fdif/11/, gtstep/4/, incfac/23/, lmax0/35/,
1879 !    2     lmaxs/36/, preduc/7/, radfac/16/, radius/8/, rad0/9/,
1880 !    3     reldx/17/, stppar/5/, tuner4/29/, tuner5/30/
1881 !/7
1882       integer,parameter :: dgnorm=1, dinit=38, dstnrm=2, dtinit=39, d0init=40,&
1883                  f=10, f0=13, fdif=11, gtstep=4, incfac=23, lmax0=35,&
1884                  lmaxs=36, preduc=7, radfac=16, radius=8, rad0=9,&
1885                  reldx=17, stppar=5, tuner4=29, tuner5=30
1886 !/
1887 !
1888 !/6
1889 !     data one/1.d+0/, onep2/1.2d+0/, zero/0.d+0/
1890 !/7
1891       real(kind=8),parameter :: one=1.d+0, onep2=1.2d+0, zero=0.d+0
1892 !/
1893 !
1894 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
1895 !
1896       i = iv(1)
1897       if (i .eq. 1) go to 30
1898       if (i .eq. 2) go to 40
1899 !
1900 !  ***  check validity of iv and v input values  ***
1901 !
1902       if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
1903       if (iv(1) .eq. 12 .or. iv(1) .eq. 13) &
1904            iv(vneed) = iv(vneed) + n*(n+21)/2 + 7
1905       call parck(2, d, iv, liv, lv, n, v)
1906       i = iv(1) - 2
1907       if (i .gt. 12) go to 999
1908       nn1o2 = n * (n + 1) / 2
1909       if (lh .ge. nn1o2) go to (210,210,210,210,210,210,160,120,160,&
1910                                 10,10,20), i
1911          iv(1) = 66
1912          go to 350
1913 !
1914 !  ***  storage allocation  ***
1915 !
1916  10   iv(dtol) = iv(lmat) + nn1o2
1917       iv(x0) = iv(dtol) + 2*n
1918       iv(step) = iv(x0) + n
1919       iv(stlstg) = iv(step) + n
1920       iv(dg) = iv(stlstg) + n
1921       iv(w) = iv(dg) + n
1922       iv(nextv) = iv(w) + 4*n + 7
1923       if (iv(1) .ne. 13) go to 20
1924          iv(1) = 14
1925          go to 999
1926 !
1927 !  ***  initialization  ***
1928 !
1929  20   iv(niter) = 0
1930       iv(nfcall) = 1
1931       iv(ngcall) = 1
1932       iv(nfgcal) = 1
1933       iv(mode) = -1
1934       iv(model) = 1
1935       iv(stglim) = 1
1936       iv(toobig) = 0
1937       iv(cnvcod) = 0
1938       iv(radinc) = 0
1939       v(rad0) = zero
1940       v(stppar) = zero
1941       if (v(dinit) .ge. zero) call vscopy(n, d, v(dinit))
1942       k = iv(dtol)
1943       if (v(dtinit) .gt. zero) call vscopy(n, v(k), v(dtinit))
1944       k = k + n
1945       if (v(d0init) .gt. zero) call vscopy(n, v(k), v(d0init))
1946       iv(1) = 1
1947       go to 999
1948 !
1949  30   v(f) = fx
1950       if (iv(mode) .ge. 0) go to 210
1951       iv(1) = 2
1952       if (iv(toobig) .eq. 0) go to 999
1953          iv(1) = 63
1954          go to 350
1955 !
1956 !  ***  make sure gradient could be computed  ***
1957 !
1958  40   if (iv(nfgcal) .ne. 0) go to 50
1959          iv(1) = 65
1960          go to 350
1961 !
1962 !  ***  update the scale vector d  ***
1963 !
1964  50   dg1 = iv(dg)
1965       if (iv(dtype) .le. 0) go to 70
1966       k = dg1
1967       j = 0
1968       do 60 i = 1, n
1969          j = j + i
1970          v(k) = h(j)
1971          k = k + 1
1972  60      continue
1973       call dupdu(d, v(dg1), iv, liv, lv, n, v)
1974 !
1975 !  ***  compute scaled gradient and its norm  ***
1976 !
1977  70   dg1 = iv(dg)
1978       k = dg1
1979       do 80 i = 1, n
1980          v(k) = g(i) / d(i)
1981          k = k + 1
1982  80      continue
1983       v(dgnorm) = v2norm(n, v(dg1))
1984 !
1985 !  ***  compute scaled hessian  ***
1986 !
1987       k = 1
1988       do 100 i = 1, n
1989          t = one / d(i)
1990          do 90 j = 1, i
1991               h(k) = t * h(k) / d(j)
1992               k = k + 1
1993  90           continue
1994  100     continue
1995 !
1996       if (iv(cnvcod) .ne. 0) go to 340
1997       if (iv(mode) .eq. 0) go to 300
1998 !
1999 !  ***  allow first step to have scaled 2-norm at most v(lmax0)  ***
2000 !
2001       v(radius) = v(lmax0)
2002 !
2003       iv(mode) = 0
2004 !
2005 !
2006 !-----------------------------  main loop  -----------------------------
2007 !
2008 !
2009 !  ***  print iteration summary, check iteration limit  ***
2010 !
2011  110  call itsum(d, g, iv, liv, lv, n, v, x)
2012  120  k = iv(niter)
2013       if (k .lt. iv(mxiter)) go to 130
2014          iv(1) = 10
2015          go to 350
2016 !
2017  130  iv(niter) = k + 1
2018 !
2019 !  ***  initialize for start of next iteration  ***
2020 !
2021       dg1 = iv(dg)
2022       x01 = iv(x0)
2023       v(f0) = v(f)
2024       iv(irc) = 4
2025       iv(kagqt) = -1
2026 !
2027 !     ***  copy x to x0  ***
2028 !
2029       call vcopy(n, v(x01), x)
2030 !
2031 !  ***  update radius  ***
2032 !
2033       if (k .eq. 0) go to 150
2034       step1 = iv(step)
2035       k = step1
2036       do 140 i = 1, n
2037          v(k) = d(i) * v(k)
2038          k = k + 1
2039  140     continue
2040       v(radius) = v(radfac) * v2norm(n, v(step1))
2041 !
2042 !  ***  check stopx and function evaluation limit  ***
2043 !
2044 ! AL 4/30/95
2045       dummy=iv(nfcall)
2046  150  if (.not. stopx(dummy)) go to 170
2047          iv(1) = 11
2048          go to 180
2049 !
2050 !     ***  come here when restarting after func. eval. limit or stopx.
2051 !
2052  160  if (v(f) .ge. v(f0)) go to 170
2053          v(radfac) = one
2054          k = iv(niter)
2055          go to 130
2056 !
2057  170  if (iv(nfcall) .lt. iv(mxfcal)) go to 190
2058          iv(1) = 9
2059  180     if (v(f) .ge. v(f0)) go to 350
2060 !
2061 !        ***  in case of stopx or function evaluation limit with
2062 !        ***  improved v(f), evaluate the gradient at x.
2063 !
2064               iv(cnvcod) = iv(1)
2065               go to 290
2066 !
2067 !. . . . . . . . . . . . .  compute candidate step  . . . . . . . . . .
2068 !
2069  190  step1 = iv(step)
2070       dg1 = iv(dg)
2071       l = iv(lmat)
2072       w1 = iv(w)
2073       call gqtst(d, v(dg1), h, iv(kagqt), v(l), n, v(step1), v, v(w1))
2074       if (iv(irc) .eq. 6) go to 210
2075 !
2076 !  ***  check whether evaluating f(x0 + step) looks worthwhile  ***
2077 !
2078       if (v(dstnrm) .le. zero) go to 210
2079       if (iv(irc) .ne. 5) go to 200
2080       if (v(radfac) .le. one) go to 200
2081       if (v(preduc) .le. onep2 * v(fdif)) go to 210
2082 !
2083 !  ***  compute f(x0 + step)  ***
2084 !
2085  200  x01 = iv(x0)
2086       step1 = iv(step)
2087       call vaxpy(n, x, one, v(step1), v(x01))
2088       iv(nfcall) = iv(nfcall) + 1
2089       iv(1) = 1
2090       iv(toobig) = 0
2091       go to 999
2092 !
2093 !. . . . . . . . . . . . .  assess candidate step  . . . . . . . . . . .
2094 !
2095  210  x01 = iv(x0)
2096       v(reldx) = reldst(n, d, x, v(x01))
2097       call assst(iv, liv, lv, v)
2098       step1 = iv(step)
2099       lstgst = iv(stlstg)
2100       if (iv(restor) .eq. 1) call vcopy(n, x, v(x01))
2101       if (iv(restor) .eq. 2) call vcopy(n, v(lstgst), v(step1))
2102       if (iv(restor) .ne. 3) go to 220
2103          call vcopy(n, v(step1), v(lstgst))
2104          call vaxpy(n, x, one, v(step1), v(x01))
2105          v(reldx) = reldst(n, d, x, v(x01))
2106 !
2107  220  k = iv(irc)
2108       go to (230,260,260,260,230,240,250,250,250,250,250,250,330,300), k
2109 !
2110 !     ***  recompute step with new radius  ***
2111 !
2112  230     v(radius) = v(radfac) * v(dstnrm)
2113          go to 150
2114 !
2115 !  ***  compute step of length v(lmaxs) for singular convergence test.
2116 !
2117  240  v(radius) = v(lmaxs)
2118       go to 190
2119 !
2120 !  ***  convergence or false convergence  ***
2121 !
2122  250  iv(cnvcod) = k - 4
2123       if (v(f) .ge. v(f0)) go to 340
2124          if (iv(xirc) .eq. 14) go to 340
2125               iv(xirc) = 14
2126 !
2127 !. . . . . . . . . . . .  process acceptable step  . . . . . . . . . . .
2128 !
2129  260  if (iv(irc) .ne. 3) go to 290
2130          temp1 = lstgst
2131 !
2132 !     ***  prepare for gradient tests  ***
2133 !     ***  set  temp1 = hessian * step + g(x0)
2134 !     ***             = diag(d) * (h * step + g(x0))
2135 !
2136 !        use x0 vector as temporary.
2137          k = x01
2138          do 270 i = 1, n
2139               v(k) = d(i) * v(step1)
2140               k = k + 1
2141               step1 = step1 + 1
2142  270          continue
2143          call slvmul(n, v(temp1), h, v(x01))
2144          do 280 i = 1, n
2145               v(temp1) = d(i) * v(temp1) + g(i)
2146               temp1 = temp1 + 1
2147  280          continue
2148 !
2149 !  ***  compute gradient and hessian  ***
2150 !
2151  290  iv(ngcall) = iv(ngcall) + 1
2152       iv(1) = 2
2153       go to 999
2154 !
2155  300  iv(1) = 2
2156       if (iv(irc) .ne. 3) go to 110
2157 !
2158 !  ***  set v(radfac) by gradient tests  ***
2159 !
2160       temp1 = iv(stlstg)
2161       step1 = iv(step)
2162 !
2163 !     ***  set  temp1 = diag(d)**-1 * (hessian*step + (g(x0)-g(x)))  ***
2164 !
2165       k = temp1
2166       do 310 i = 1, n
2167          v(k) = (v(k) - g(i)) / d(i)
2168          k = k + 1
2169  310     continue
2170 !
2171 !     ***  do gradient tests  ***
2172 !
2173       if (v2norm(n, v(temp1)) .le. v(dgnorm) * v(tuner4)) go to 320
2174            if (dotprd(n, g, v(step1)) &
2175                      .ge. v(gtstep) * v(tuner5))  go to 110
2176  320            v(radfac) = v(incfac)
2177                 go to 110
2178 !
2179 !. . . . . . . . . . . . . .  misc. details  . . . . . . . . . . . . . .
2180 !
2181 !  ***  bad parameters to assess  ***
2182 !
2183  330  iv(1) = 64
2184       go to 350
2185 !
2186 !  ***  print summary of final iteration and other requested items  ***
2187 !
2188  340  iv(1) = iv(cnvcod)
2189       iv(cnvcod) = 0
2190  350  call itsum(d, g, iv, liv, lv, n, v, x)
2191 !
2192  999  return
2193 !
2194 !  ***  last card of humit follows  ***
2195       end subroutine humit
2196 !-----------------------------------------------------------------------------
2197       subroutine dupdu(d, hdiag, iv, liv, lv, n, v)
2198 !
2199 !  ***  update scale vector d for humsl  ***
2200 !
2201 !  ***  parameter declarations  ***
2202 !
2203       integer :: liv, lv, n
2204       integer :: iv(liv)
2205       real(kind=8) :: d(n), hdiag(n), v(lv)
2206 !
2207 !  ***  local variables  ***
2208 !
2209       integer :: dtoli, d0i, i
2210       real(kind=8) :: t, vdfac
2211 !
2212 !  ***  intrinsic functions  ***
2213 !/+
2214 !el      real(kind=8) :: dabs, dmax1, dsqrt
2215 !/
2216 !  ***  subscripts for iv and v  ***
2217 !
2218 !el      integer :: dfac, dtol, dtype, niter
2219 !/6
2220 !     data dfac/41/, dtol/59/, dtype/16/, niter/31/
2221 !/7
2222       integer,parameter :: dfac=41, dtol=59, dtype=16, niter=31
2223 !/
2224 !
2225 !-------------------------------  body  --------------------------------
2226 !
2227       i = iv(dtype)
2228       if (i .eq. 1) go to 10
2229          if (iv(niter) .gt. 0) go to 999
2230 !
2231  10   dtoli = iv(dtol)
2232       d0i = dtoli + n
2233       vdfac = v(dfac)
2234       do 20 i = 1, n
2235          t = dmax1(dsqrt(dabs(hdiag(i))), vdfac*d(i))
2236          if (t .lt. v(dtoli)) t = dmax1(v(dtoli), v(d0i))
2237          d(i) = t
2238          dtoli = dtoli + 1
2239          d0i = d0i + 1
2240  20      continue
2241 !
2242  999  return
2243 !  ***  last card of dupdu follows  ***
2244       end subroutine dupdu
2245 !-----------------------------------------------------------------------------
2246       subroutine gqtst(d, dig, dihdi, ka, l, p, step, v, w)
2247 !
2248 !  *** compute goldfeld-quandt-trotter step by more-hebden technique ***
2249 !  ***  (nl2sol version 2.2), modified a la more and sorensen  ***
2250 !
2251 !  ***  parameter declarations  ***
2252 !
2253       integer :: ka, p
2254 !al   real(kind=8) :: d(p), dig(p), dihdi(1), l(1), v(21), step(p),
2255 !al  1                 w(1)
2256       real(kind=8) :: d(p), dig(p), dihdi(p*(p+1)/2), l(p*(p+1)/2),&
2257           v(21), step(p),w(4*p+7)
2258 !     dimension dihdi(p*(p+1)/2), l(p*(p+1)/2), w(4*p+7)
2259 !
2260 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2261 !
2262 !  ***  purpose  ***
2263 !
2264 !        given the (compactly stored) lower triangle of a scaled
2265 !     hessian (approximation) and a nonzero scaled gradient vector,
2266 !     this subroutine computes a goldfeld-quandt-trotter step of
2267 !     approximate length v(radius) by the more-hebden technique.  in
2268 !     other words, step is computed to (approximately) minimize
2269 !     psi(step) = (g**t)*step + 0.5*(step**t)*h*step  such that the
2270 !     2-norm of d*step is at most (approximately) v(radius), where
2271 !     g  is the gradient,  h  is the hessian, and  d  is a diagonal
2272 !     scale matrix whose diagonal is stored in the parameter d.
2273 !     (gqtst assumes  dig = d**-1 * g  and  dihdi = d**-1 * h * d**-1.)
2274 !
2275 !  ***  parameter description  ***
2276 !
2277 !     d (in)  = the scale vector, i.e. the diagonal of the scale
2278 !              matrix  d  mentioned above under purpose.
2279 !   dig (in)  = the scaled gradient vector, d**-1 * g.  if g = 0, then
2280 !              step = 0  and  v(stppar) = 0  are returned.
2281 ! dihdi (in)  = lower triangle of the scaled hessian (approximation),
2282 !              i.e., d**-1 * h * d**-1, stored compactly by rows., i.e.,
2283 !              in the order (1,1), (2,1), (2,2), (3,1), (3,2), etc.
2284 !    ka (i/o) = the number of hebden iterations (so far) taken to deter-
2285 !              mine step.  ka .lt. 0 on input means this is the first
2286 !              attempt to determine step (for the present dig and dihdi)
2287 !              -- ka is initialized to 0 in this case.  output with
2288 !              ka = 0  (or v(stppar) = 0)  means  step = -(h**-1)*g.
2289 !     l (i/o) = workspace of length p*(p+1)/2 for cholesky factors.
2290 !     p (in)  = number of parameters -- the hessian is a  p x p  matrix.
2291 !  step (i/o) = the step computed.
2292 !     v (i/o) contains various constants and variables described below.
2293 !     w (i/o) = workspace of length 4*p + 6.
2294 !
2295 !  ***  entries in v  ***
2296 !
2297 ! v(dgnorm) (i/o) = 2-norm of (d**-1)*g.
2298 ! v(dstnrm) (output) = 2-norm of d*step.
2299 ! v(dst0)   (i/o) = 2-norm of d*(h**-1)*g (for pos. def. h only), or
2300 !             overestimate of smallest eigenvalue of (d**-1)*h*(d**-1).
2301 ! v(epslon) (in)  = max. rel. error allowed for psi(step).  for the
2302 !             step returned, psi(step) will exceed its optimal value
2303 !             by less than -v(epslon)*psi(step).  suggested value = 0.1.
2304 ! v(gtstep) (out) = inner product between g and step.
2305 ! v(nreduc) (out) = psi(-(h**-1)*g) = psi(newton step)  (for pos. def.
2306 !             h only -- v(nreduc) is set to zero otherwise).
2307 ! v(phmnfc) (in)  = tol. (together with v(phmxfc)) for accepting step
2308 !             (more*s sigma).  the error v(dstnrm) - v(radius) must lie
2309 !             between v(phmnfc)*v(radius) and v(phmxfc)*v(radius).
2310 ! v(phmxfc) (in)  (see v(phmnfc).)
2311 !             suggested values -- v(phmnfc) = -0.25, v(phmxfc) = 0.5.
2312 ! v(preduc) (out) = psi(step) = predicted obj. func. reduction for step.
2313 ! v(radius) (in)  = radius of current (scaled) trust region.
2314 ! v(rad0)   (i/o) = value of v(radius) from previous call.
2315 ! v(stppar) (i/o) is normally the marquardt parameter, i.e. the alpha
2316 !             described below under algorithm notes.  if h + alpha*d**2
2317 !             (see algorithm notes) is (nearly) singular, however,
2318 !             then v(stppar) = -alpha.
2319 !
2320 !  ***  usage notes  ***
2321 !
2322 !     if it is desired to recompute step using a different value of
2323 !     v(radius), then this routine may be restarted by calling it
2324 !     with all parameters unchanged except v(radius).  (this explains
2325 !     why step and w are listed as i/o).  on an initial call (one with
2326 !     ka .lt. 0), step and w need not be initialized and only compo-
2327 !     nents v(epslon), v(stppar), v(phmnfc), v(phmxfc), v(radius), and
2328 !     v(rad0) of v must be initialized.
2329 !
2330 !  ***  algorithm notes  ***
2331 !
2332 !        the desired g-q-t step (ref. 2, 3, 4, 6) satisfies
2333 !     (h + alpha*d**2)*step = -g  for some nonnegative alpha such that
2334 !     h + alpha*d**2 is positive semidefinite.  alpha and step are
2335 !     computed by a scheme analogous to the one described in ref. 5.
2336 !     estimates of the smallest and largest eigenvalues of the hessian
2337 !     are obtained from the gerschgorin circle theorem enhanced by a
2338 !     simple form of the scaling described in ref. 7.  cases in which
2339 !     h + alpha*d**2 is nearly (or exactly) singular are handled by
2340 !     the technique discussed in ref. 2.  in these cases, a step of
2341 !     (exact) length v(radius) is returned for which psi(step) exceeds
2342 !     its optimal value by less than -v(epslon)*psi(step).  the test
2343 !     suggested in ref. 6 for detecting the special case is performed
2344 !     once two matrix factorizations have been done -- doing so sooner
2345 !     seems to degrade the performance of optimization routines that
2346 !     call this routine.
2347 !
2348 !  ***  functions and subroutines called  ***
2349 !
2350 ! dotprd - returns inner product of two vectors.
2351 ! litvmu - applies inverse-transpose of compact lower triang. matrix.
2352 ! livmul - applies inverse of compact lower triang. matrix.
2353 ! lsqrt  - finds cholesky factor (of compactly stored lower triang.).
2354 ! lsvmin - returns approx. to min. sing. value of lower triang. matrix.
2355 ! rmdcon - returns machine-dependent constants.
2356 ! v2norm - returns 2-norm of a vector.
2357 !
2358 !  ***  references  ***
2359 !
2360 ! 1.  dennis, j.e., gay, d.m., and welsch, r.e. (1981), an adaptive
2361 !             nonlinear least-squares algorithm, acm trans. math.
2362 !             software, vol. 7, no. 3.
2363 ! 2.  gay, d.m. (1981), computing optimal locally constrained steps,
2364 !             siam j. sci. statist. computing, vol. 2, no. 2, pp.
2365 !             186-197.
2366 ! 3.  goldfeld, s.m., quandt, r.e., and trotter, h.f. (1966),
2367 !             maximization by quadratic hill-climbing, econometrica 34,
2368 !             pp. 541-551.
2369 ! 4.  hebden, m.d. (1973), an algorithm for minimization using exact
2370 !             second derivatives, report t.p. 515, theoretical physics
2371 !             div., a.e.r.e. harwell, oxon., england.
2372 ! 5.  more, j.j. (1978), the levenberg-marquardt algorithm, implemen-
2373 !             tation and theory, pp.105-116 of springer lecture notes
2374 !             in mathematics no. 630, edited by g.a. watson, springer-
2375 !             verlag, berlin and new york.
2376 ! 6.  more, j.j., and sorensen, d.c. (1981), computing a trust region
2377 !             step, technical report anl-81-83, argonne national lab.
2378 ! 7.  varga, r.s. (1965), minimal gerschgorin sets, pacific j. math. 15,
2379 !             pp. 719-729.
2380 !
2381 !  ***  general  ***
2382 !
2383 !     coded by david m. gay.
2384 !     this subroutine was written in connection with research
2385 !     supported by the national science foundation under grants
2386 !     mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989, and
2387 !     mcs-7906671.
2388 !
2389 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2390 !
2391 !  ***  local variables  ***
2392 !
2393       logical :: restrt
2394       integer :: dggdmx, diag, diag0, dstsav, emax, emin, i, im1, inc, irc,&
2395               j, k, kalim, kamin, k1, lk0, phipin, q, q0, uk0, x
2396       real(kind=8) :: alphak, aki, akk, delta, dst, eps, gtsta, lk,&
2397                        oldphi, phi, phimax, phimin, psifac, rad, radsq,&
2398                        root, si, sk, sw, t, twopsi, t1, t2, uk, wi
2399 !
2400 !     ***  constants  ***
2401       real(kind=8) :: big, dgxfac       !el, epsfac, four, half, kappa, negone,
2402 !el     1                 one, p001, six, three, two, zero
2403 !
2404 !  ***  intrinsic functions  ***
2405 !/+
2406 !el      real(kind=8) :: dabs, dmax1, dmin1, dsqrt
2407 !/
2408 !  ***  external functions and subroutines  ***
2409 !
2410 !el      external dotprd, litvmu, livmul, lsqrt, lsvmin, rmdcon, v2norm
2411 !el      real(kind=8) :: dotprd, lsvmin, rmdcon, v2norm
2412 !
2413 !  ***  subscripts for v  ***
2414 !
2415 !el      integer dgnorm, dstnrm, dst0, epslon, gtstep, stppar, nreduc,
2416 !el     1        phmnfc, phmxfc, preduc, radius, rad0
2417 !/6
2418 !     data dgnorm/1/, dstnrm/2/, dst0/3/, epslon/19/, gtstep/4/,
2419 !    1     nreduc/6/, phmnfc/20/, phmxfc/21/, preduc/7/, radius/8/,
2420 !    2     rad0/9/, stppar/5/
2421 !/7
2422       integer,parameter :: dgnorm=1, dstnrm=2, dst0=3, epslon=19, gtstep=4,&
2423                  nreduc=6, phmnfc=20, phmxfc=21, preduc=7, radius=8,&
2424                  rad0=9, stppar=5
2425 !/
2426 !
2427 !/6
2428 !     data epsfac/50.0d+0/, four/4.0d+0/, half/0.5d+0/,
2429 !    1     kappa/2.0d+0/, negone/-1.0d+0/, one/1.0d+0/, p001/1.0d-3/,
2430 !    2     six/6.0d+0/, three/3.0d+0/, two/2.0d+0/, zero/0.0d+0/
2431 !/7
2432      real(kind=8), parameter :: epsfac=50.0d+0, four=4.0d+0, half=0.5d+0,&
2433            kappa=2.0d+0, negone=-1.0d+0, one=1.0d+0, p001=1.0d-3,&
2434            six=6.0d+0, three=3.0d+0, two=2.0d+0, zero=0.0d+0
2435       save dgxfac
2436 !/
2437       data big/0.d+0/, dgxfac/0.d+0/
2438 !
2439 !  ***  body  ***
2440 !
2441 !     ***  store largest abs. entry in (d**-1)*h*(d**-1) at w(dggdmx).
2442       dggdmx = p + 1
2443 !     ***  store gerschgorin over- and underestimates of the largest
2444 !     ***  and smallest eigenvalues of (d**-1)*h*(d**-1) at w(emax)
2445 !     ***  and w(emin) respectively.
2446       emax = dggdmx + 1
2447       emin = emax + 1
2448 !     ***  for use in recomputing step, the final values of lk, uk, dst,
2449 !     ***  and the inverse derivative of more*s phi at 0 (for pos. def.
2450 !     ***  h) are stored in w(lk0), w(uk0), w(dstsav), and w(phipin)
2451 !     ***  respectively.
2452       lk0 = emin + 1
2453       phipin = lk0 + 1
2454       uk0 = phipin + 1
2455       dstsav = uk0 + 1
2456 !     ***  store diag of (d**-1)*h*(d**-1) in w(diag),...,w(diag0+p).
2457       diag0 = dstsav
2458       diag = diag0 + 1
2459 !     ***  store -d*step in w(q),...,w(q0+p).
2460       q0 = diag0 + p
2461       q = q0 + 1
2462 !     ***  allocate storage for scratch vector x  ***
2463       x = q + p
2464       rad = v(radius)
2465       radsq = rad**2
2466 !     ***  phitol = max. error allowed in dst = v(dstnrm) = 2-norm of
2467 !     ***  d*step.
2468       phimax = v(phmxfc) * rad
2469       phimin = v(phmnfc) * rad
2470       psifac = two * v(epslon) / (three * (four * (v(phmnfc) + one) * &
2471                              (kappa + one)  +  kappa  +  two) * rad**2)
2472 !     ***  oldphi is used to detect limits of numerical accuracy.  if
2473 !     ***  we recompute step and it does not change, then we accept it.
2474       oldphi = zero
2475       eps = v(epslon)
2476       irc = 0
2477       restrt = .false.
2478       kalim = ka + 50
2479 !
2480 !  ***  start or restart, depending on ka  ***
2481 !
2482       if (ka .ge. 0) go to 290
2483 !
2484 !  ***  fresh start  ***
2485 !
2486       k = 0
2487       uk = negone
2488       ka = 0
2489       kalim = 50
2490       v(dgnorm) = v2norm(p, dig)
2491       v(nreduc) = zero
2492       v(dst0) = zero
2493       kamin = 3
2494       if (v(dgnorm) .eq. zero) kamin = 0
2495 !
2496 !     ***  store diag(dihdi) in w(diag0+1),...,w(diag0+p)  ***
2497 !
2498       j = 0
2499       do 10 i = 1, p
2500          j = j + i
2501          k1 = diag0 + i
2502          w(k1) = dihdi(j)
2503  10      continue
2504 !
2505 !     ***  determine w(dggdmx), the largest element of dihdi  ***
2506 !
2507       t1 = zero
2508       j = p * (p + 1) / 2
2509       do 20 i = 1, j
2510          t = dabs(dihdi(i))
2511          if (t1 .lt. t) t1 = t
2512  20      continue
2513       w(dggdmx) = t1
2514 !
2515 !  ***  try alpha = 0  ***
2516 !
2517  30   call lsqrt(1, p, l, dihdi, irc)
2518       if (irc .eq. 0) go to 50
2519 !        ***  indef. h -- underestimate smallest eigenvalue, use this
2520 !        ***  estimate to initialize lower bound lk on alpha.
2521          j = irc*(irc+1)/2
2522          t = l(j)
2523          l(j) = one
2524          do 40 i = 1, irc
2525  40           w(i) = zero
2526          w(irc) = one
2527          call litvmu(irc, w, l, w)
2528          t1 = v2norm(irc, w)
2529          lk = -t / t1 / t1
2530          v(dst0) = -lk
2531          if (restrt) go to 210
2532          go to 70
2533 !
2534 !     ***  positive definite h -- compute unmodified newton step.  ***
2535  50   lk = zero
2536       t = lsvmin(p, l, w(q), w(q))
2537       if (t .ge. one) go to 60
2538          if (big .le. zero) big = rmdcon(6)
2539          if (v(dgnorm) .ge. t*t*big) go to 70
2540  60   call livmul(p, w(q), l, dig)
2541       gtsta = dotprd(p, w(q), w(q))
2542       v(nreduc) = half * gtsta
2543       call litvmu(p, w(q), l, w(q))
2544       dst = v2norm(p, w(q))
2545       v(dst0) = dst
2546       phi = dst - rad
2547       if (phi .le. phimax) go to 260
2548       if (restrt) go to 210
2549 !
2550 !  ***  prepare to compute gerschgorin estimates of largest (and
2551 !  ***  smallest) eigenvalues.  ***
2552 !
2553  70   k = 0
2554       do 100 i = 1, p
2555          wi = zero
2556          if (i .eq. 1) go to 90
2557          im1 = i - 1
2558          do 80 j = 1, im1
2559               k = k + 1
2560               t = dabs(dihdi(k))
2561               wi = wi + t
2562               w(j) = w(j) + t
2563  80           continue
2564  90      w(i) = wi
2565          k = k + 1
2566  100     continue
2567 !
2568 !  ***  (under-)estimate smallest eigenvalue of (d**-1)*h*(d**-1)  ***
2569 !
2570       k = 1
2571       t1 = w(diag) - w(1)
2572       if (p .le. 1) go to 120
2573       do 110 i = 2, p
2574          j = diag0 + i
2575          t = w(j) - w(i)
2576          if (t .ge. t1) go to 110
2577               t1 = t
2578               k = i
2579  110     continue
2580 !
2581  120  sk = w(k)
2582       j = diag0 + k
2583       akk = w(j)
2584       k1 = k*(k-1)/2 + 1
2585       inc = 1
2586       t = zero
2587       do 150 i = 1, p
2588          if (i .eq. k) go to 130
2589          aki = dabs(dihdi(k1))
2590          si = w(i)
2591          j = diag0 + i
2592          t1 = half * (akk - w(j) + si - aki)
2593          t1 = t1 + dsqrt(t1*t1 + sk*aki)
2594          if (t .lt. t1) t = t1
2595          if (i .lt. k) go to 140
2596  130     inc = i
2597  140     k1 = k1 + inc
2598  150     continue
2599 !
2600       w(emin) = akk - t
2601       uk = v(dgnorm)/rad - w(emin)
2602       if (v(dgnorm) .eq. zero) uk = uk + p001 + p001*uk
2603       if (uk .le. zero) uk = p001
2604 !
2605 !  ***  compute gerschgorin (over-)estimate of largest eigenvalue  ***
2606 !
2607       k = 1
2608       t1 = w(diag) + w(1)
2609       if (p .le. 1) go to 170
2610       do 160 i = 2, p
2611          j = diag0 + i
2612          t = w(j) + w(i)
2613          if (t .le. t1) go to 160
2614               t1 = t
2615               k = i
2616  160     continue
2617 !
2618  170  sk = w(k)
2619       j = diag0 + k
2620       akk = w(j)
2621       k1 = k*(k-1)/2 + 1
2622       inc = 1
2623       t = zero
2624       do 200 i = 1, p
2625          if (i .eq. k) go to 180
2626          aki = dabs(dihdi(k1))
2627          si = w(i)
2628          j = diag0 + i
2629          t1 = half * (w(j) + si - aki - akk)
2630          t1 = t1 + dsqrt(t1*t1 + sk*aki)
2631          if (t .lt. t1) t = t1
2632          if (i .lt. k) go to 190
2633  180     inc = i
2634  190     k1 = k1 + inc
2635  200     continue
2636 !
2637       w(emax) = akk + t
2638       lk = dmax1(lk, v(dgnorm)/rad - w(emax))
2639 !
2640 !     ***  alphak = current value of alpha (see alg. notes above).  we
2641 !     ***  use more*s scheme for initializing it.
2642       alphak = dabs(v(stppar)) * v(rad0)/rad
2643 !
2644       if (irc .ne. 0) go to 210
2645 !
2646 !  ***  compute l0 for positive definite h  ***
2647 !
2648       call livmul(p, w, l, w(q))
2649       t = v2norm(p, w)
2650       w(phipin) = dst / t / t
2651       lk = dmax1(lk, phi*w(phipin))
2652 !
2653 !  ***  safeguard alphak and add alphak*i to (d**-1)*h*(d**-1)  ***
2654 !
2655  210  ka = ka + 1
2656       if (-v(dst0) .ge. alphak .or. alphak .lt. lk .or. alphak .ge. uk) &
2657                             alphak = uk * dmax1(p001, dsqrt(lk/uk))
2658       if (alphak .le. zero) alphak = half * uk
2659       if (alphak .le. zero) alphak = uk
2660       k = 0
2661       do 220 i = 1, p
2662          k = k + i
2663          j = diag0 + i
2664          dihdi(k) = w(j) + alphak
2665  220     continue
2666 !
2667 !  ***  try computing cholesky decomposition  ***
2668 !
2669       call lsqrt(1, p, l, dihdi, irc)
2670       if (irc .eq. 0) go to 240
2671 !
2672 !  ***  (d**-1)*h*(d**-1) + alphak*i  is indefinite -- overestimate
2673 !  ***  smallest eigenvalue for use in updating lk  ***
2674 !
2675       j = (irc*(irc+1))/2
2676       t = l(j)
2677       l(j) = one
2678       do 230 i = 1, irc
2679  230     w(i) = zero
2680       w(irc) = one
2681       call litvmu(irc, w, l, w)
2682       t1 = v2norm(irc, w)
2683       lk = alphak - t/t1/t1
2684       v(dst0) = -lk
2685       go to 210
2686 !
2687 !  ***  alphak makes (d**-1)*h*(d**-1) positive definite.
2688 !  ***  compute q = -d*step, check for convergence.  ***
2689 !
2690  240  call livmul(p, w(q), l, dig)
2691       gtsta = dotprd(p, w(q), w(q))
2692       call litvmu(p, w(q), l, w(q))
2693       dst = v2norm(p, w(q))
2694       phi = dst - rad
2695       if (phi .le. phimax .and. phi .ge. phimin) go to 270
2696       if (phi .eq. oldphi) go to 270
2697       oldphi = phi
2698       if (phi .lt. zero) go to 330
2699 !
2700 !  ***  unacceptable alphak -- update lk, uk, alphak  ***
2701 !
2702  250  if (ka .ge. kalim) go to 270
2703 !     ***  the following dmin1 is necessary because of restarts  ***
2704       if (phi .lt. zero) uk = dmin1(uk, alphak)
2705 !     *** kamin = 0 only iff the gradient vanishes  ***
2706       if (kamin .eq. 0) go to 210
2707       call livmul(p, w, l, w(q))
2708       t1 = v2norm(p, w)
2709       alphak = alphak  +  (phi/t1) * (dst/t1) * (dst/rad)
2710       lk = dmax1(lk, alphak)
2711       go to 210
2712 !
2713 !  ***  acceptable step on first try  ***
2714 !
2715  260  alphak = zero
2716 !
2717 !  ***  successful step in general.  compute step = -(d**-1)*q  ***
2718 !
2719  270  do 280 i = 1, p
2720          j = q0 + i
2721          step(i) = -w(j)/d(i)
2722  280     continue
2723       v(gtstep) = -gtsta
2724       v(preduc) = half * (dabs(alphak)*dst*dst + gtsta)
2725       go to 410
2726 !
2727 !
2728 !  ***  restart with new radius  ***
2729 !
2730  290  if (v(dst0) .le. zero .or. v(dst0) - rad .gt. phimax) go to 310
2731 !
2732 !     ***  prepare to return newton step  ***
2733 !
2734          restrt = .true.
2735          ka = ka + 1
2736          k = 0
2737          do 300 i = 1, p
2738               k = k + i
2739               j = diag0 + i
2740               dihdi(k) = w(j)
2741  300          continue
2742          uk = negone
2743          go to 30
2744 !
2745  310  kamin = ka + 3
2746       if (v(dgnorm) .eq. zero) kamin = 0
2747       if (ka .eq. 0) go to 50
2748 !
2749       dst = w(dstsav)
2750       alphak = dabs(v(stppar))
2751       phi = dst - rad
2752       t = v(dgnorm)/rad
2753       uk = t - w(emin)
2754       if (v(dgnorm) .eq. zero) uk = uk + p001 + p001*uk
2755       if (uk .le. zero) uk = p001
2756       if (rad .gt. v(rad0)) go to 320
2757 !
2758 !        ***  smaller radius  ***
2759          lk = zero
2760          if (alphak .gt. zero) lk = w(lk0)
2761          lk = dmax1(lk, t - w(emax))
2762          if (v(dst0) .gt. zero) lk = dmax1(lk, (v(dst0)-rad)*w(phipin))
2763          go to 250
2764 !
2765 !     ***  bigger radius  ***
2766  320  if (alphak .gt. zero) uk = dmin1(uk, w(uk0))
2767       lk = dmax1(zero, -v(dst0), t - w(emax))
2768       if (v(dst0) .gt. zero) lk = dmax1(lk, (v(dst0)-rad)*w(phipin))
2769       go to 250
2770 !
2771 !  ***  decide whether to check for special case... in practice (from
2772 !  ***  the standpoint of the calling optimization code) it seems best
2773 !  ***  not to check until a few iterations have failed -- hence the
2774 !  ***  test on kamin below.
2775 !
2776  330  delta = alphak + dmin1(zero, v(dst0))
2777       twopsi = alphak*dst*dst + gtsta
2778       if (ka .ge. kamin) go to 340
2779 !     *** if the test in ref. 2 is satisfied, fall through to handle
2780 !     *** the special case (as soon as the more-sorensen test detects
2781 !     *** it).
2782       if (delta .ge. psifac*twopsi) go to 370
2783 !
2784 !  ***  check for the special case of  h + alpha*d**2  (nearly)
2785 !  ***  singular.  use one step of inverse power method with start
2786 !  ***  from lsvmin to obtain approximate eigenvector corresponding
2787 !  ***  to smallest eigenvalue of (d**-1)*h*(d**-1).  lsvmin returns
2788 !  ***  x and w with  l*w = x.
2789 !
2790  340  t = lsvmin(p, l, w(x), w)
2791 !
2792 !     ***  normalize w  ***
2793       do 350 i = 1, p
2794  350     w(i) = t*w(i)
2795 !     ***  complete current inv. power iter. -- replace w by (l**-t)*w.
2796       call litvmu(p, w, l, w)
2797       t2 = one/v2norm(p, w)
2798       do 360 i = 1, p
2799  360     w(i) = t2*w(i)
2800       t = t2 * t
2801 !
2802 !  ***  now w is the desired approximate (unit) eigenvector and
2803 !  ***  t*x = ((d**-1)*h*(d**-1) + alphak*i)*w.
2804 !
2805       sw = dotprd(p, w(q), w)
2806       t1 = (rad + dst) * (rad - dst)
2807       root = dsqrt(sw*sw + t1)
2808       if (sw .lt. zero) root = -root
2809       si = t1 / (sw + root)
2810 !
2811 !  ***  the actual test for the special case...
2812 !
2813       if ((t2*si)**2 .le. eps*(dst**2 + alphak*radsq)) go to 380
2814 !
2815 !  ***  update upper bound on smallest eigenvalue (when not positive)
2816 !  ***  (as recommended by more and sorensen) and continue...
2817 !
2818       if (v(dst0) .le. zero) v(dst0) = dmin1(v(dst0), t2**2 - alphak)
2819       lk = dmax1(lk, -v(dst0))
2820 !
2821 !  ***  check whether we can hope to detect the special case in
2822 !  ***  the available arithmetic.  accept step as it is if not.
2823 !
2824 !     ***  if not yet available, obtain machine dependent value dgxfac.
2825  370  if (dgxfac .eq. zero) dgxfac = epsfac * rmdcon(3)
2826 !
2827       if (delta .gt. dgxfac*w(dggdmx)) go to 250
2828          go to 270
2829 !
2830 !  ***  special case detected... negate alphak to indicate special case
2831 !
2832  380  alphak = -alphak
2833       v(preduc) = half * twopsi
2834 !
2835 !  ***  accept current step if adding si*w would lead to a
2836 !  ***  further relative reduction in psi of less than v(epslon)/3.
2837 !
2838       t1 = zero
2839       t = si*(alphak*sw - half*si*(alphak + t*dotprd(p,w(x),w)))
2840       if (t .lt. eps*twopsi/six) go to 390
2841          v(preduc) = v(preduc) + t
2842          dst = rad
2843          t1 = -si
2844  390  do 400 i = 1, p
2845          j = q0 + i
2846          w(j) = t1*w(i) - w(j)
2847          step(i) = w(j) / d(i)
2848  400     continue
2849       v(gtstep) = dotprd(p, dig, w(q))
2850 !
2851 !  ***  save values for use in a possible restart  ***
2852 !
2853  410  v(dstnrm) = dst
2854       v(stppar) = alphak
2855       w(lk0) = lk
2856       w(uk0) = uk
2857       v(rad0) = rad
2858       w(dstsav) = dst
2859 !
2860 !     ***  restore diagonal of dihdi  ***
2861 !
2862       j = 0
2863       do 420 i = 1, p
2864          j = j + i
2865          k = diag0 + i
2866          dihdi(j) = w(k)
2867  420     continue
2868 !
2869  999  return
2870 !
2871 !  ***  last card of gqtst follows  ***
2872       end subroutine gqtst
2873 !-----------------------------------------------------------------------------
2874       subroutine lsqrt(n1, n, l, a, irc)
2875 !
2876 !  ***  compute rows n1 through n of the cholesky factor  l  of
2877 !  ***  a = l*(l**t),  where  l  and the lower triangle of  a  are both
2878 !  ***  stored compactly by rows (and may occupy the same storage).
2879 !  ***  irc = 0 means all went well.  irc = j means the leading
2880 !  ***  principal  j x j  submatrix of  a  is not positive definite --
2881 !  ***  and  l(j*(j+1)/2)  contains the (nonpos.) reduced j-th diagonal.
2882 !
2883 !  ***  parameters  ***
2884 !
2885       integer :: n1, n, irc
2886 !al   real(kind=8) :: l(1), a(1)
2887       real(kind=8) :: l(n*(n+1)/2), a(n*(n+1)/2)
2888 !     dimension l(n*(n+1)/2), a(n*(n+1)/2)
2889 !
2890 !  ***  local variables  ***
2891 !
2892       integer :: i, ij, ik, im1, i0, j, jk, jm1, j0, k
2893       real(kind=8) :: t, td     !el, zero
2894 !
2895 !  ***  intrinsic functions  ***
2896 !/+
2897 !el      real(kind=8) :: dsqrt
2898 !/
2899 !/6
2900 !     data zero/0.d+0/
2901 !/7
2902       real(kind=8),parameter :: zero=0.d+0
2903 !/
2904 !
2905 !  ***  body  ***
2906 !
2907       i0 = n1 * (n1 - 1) / 2
2908       do 50 i = n1, n
2909          td = zero
2910          if (i .eq. 1) go to 40
2911          j0 = 0
2912          im1 = i - 1
2913          do 30 j = 1, im1
2914               t = zero
2915               if (j .eq. 1) go to 20
2916               jm1 = j - 1
2917               do 10 k = 1, jm1
2918                    ik = i0 + k
2919                    jk = j0 + k
2920                    t = t + l(ik)*l(jk)
2921  10                continue
2922  20           ij = i0 + j
2923               j0 = j0 + j
2924               t = (a(ij) - t) / l(j0)
2925               l(ij) = t
2926               td = td + t*t
2927  30           continue
2928  40      i0 = i0 + i
2929          t = a(i0) - td
2930          if (t .le. zero) go to 60
2931          l(i0) = dsqrt(t)
2932  50      continue
2933 !
2934       irc = 0
2935       go to 999
2936 !
2937  60   l(i0) = t
2938       irc = i
2939 !
2940  999  return
2941 !
2942 !  ***  last card of lsqrt  ***
2943       end subroutine lsqrt
2944 !-----------------------------------------------------------------------------
2945       real(kind=8) function lsvmin(p, l, x, y)
2946 !
2947 !  ***  estimate smallest sing. value of packed lower triang. matrix l
2948 !
2949 !  ***  parameter declarations  ***
2950 !
2951       integer :: p
2952 !al   real(kind=8) :: l(1), x(p), y(p)
2953       real(kind=8) :: l(p*(p+1)/2), x(p), y(p)
2954 !     dimension l(p*(p+1)/2)
2955 !
2956 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2957 !
2958 !  ***  purpose  ***
2959 !
2960 !     this function returns a good over-estimate of the smallest
2961 !     singular value of the packed lower triangular matrix l.
2962 !
2963 !  ***  parameter description  ***
2964 !
2965 !  p (in)  = the order of l.  l is a  p x p  lower triangular matrix.
2966 !  l (in)  = array holding the elements of  l  in row order, i.e.
2967 !             l(1,1), l(2,1), l(2,2), l(3,1), l(3,2), l(3,3), etc.
2968 !  x (out) if lsvmin returns a positive value, then x is a normalized
2969 !             approximate left singular vector corresponding to the
2970 !             smallest singular value.  this approximation may be very
2971 !             crude.  if lsvmin returns zero, then some components of x
2972 !             are zero and the rest retain their input values.
2973 !  y (out) if lsvmin returns a positive value, then y = (l**-1)*x is an
2974 !             unnormalized approximate right singular vector correspond-
2975 !             ing to the smallest singular value.  this approximation
2976 !             may be crude.  if lsvmin returns zero, then y retains its
2977 !             input value.  the caller may pass the same vector for x
2978 !             and y (nonstandard fortran usage), in which case y over-
2979 !             writes x (for nonzero lsvmin returns).
2980 !
2981 !  ***  algorithm notes  ***
2982 !
2983 !     the algorithm is based on (1), with the additional provision that
2984 !     lsvmin = 0 is returned if the smallest diagonal element of l
2985 !     (in magnitude) is not more than the unit roundoff times the
2986 !     largest.  the algorithm uses a random number generator proposed
2987 !     in (4), which passes the spectral test with flying colors -- see
2988 !     (2) and (3).
2989 !
2990 !  ***  subroutines and functions called  ***
2991 !
2992 !        v2norm - function, returns the 2-norm of a vector.
2993 !
2994 !  ***  references  ***
2995 !
2996 !     (1) cline, a., moler, c., stewart, g., and wilkinson, j.h.(1977),
2997 !         an estimate for the condition number of a matrix, report
2998 !         tm-310, applied math. div., argonne national laboratory.
2999 !
3000 !     (2) hoaglin, d.c. (1976), theoretical properties of congruential
3001 !         random-number generators --  an empirical view,
3002 !         memorandum ns-340, dept. of statistics, harvard univ.
3003 !
3004 !     (3) knuth, d.e. (1969), the art of computer programming, vol. 2
3005 !         (seminumerical algorithms), addison-wesley, reading, mass.
3006 !
3007 !     (4) smith, c.s. (1971), multiplicative pseudo-random number
3008 !         generators with prime modulus, j. assoc. comput. mach. 18,
3009 !         pp. 586-593.
3010 !
3011 !  ***  history  ***
3012 !
3013 !     designed and coded by david m. gay (winter 1977/summer 1978).
3014 !
3015 !  ***  general  ***
3016 !
3017 !     this subroutine was written in connection with research
3018 !     supported by the national science foundation under grants
3019 !     mcs-7600324, dcr75-10143, 76-14311dss, and mcs76-11989.
3020 !
3021 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3022 !
3023 !  ***  local variables  ***
3024 !
3025       integer :: i, ii, ix, j, ji, jj, jjj, jm1, j0, pm1
3026       real(kind=8) :: b, sminus, splus, t, xminus, xplus
3027 !
3028 !  ***  constants  ***
3029 !
3030 !el      real(kind=8) :: half, one, r9973, zero
3031 !
3032 !  ***  intrinsic functions  ***
3033 !/+
3034 !el      integer mod
3035 !el      real float
3036 !el      real(kind=8) :: dabs
3037 !/
3038 !  ***  external functions and subroutines  ***
3039 !
3040 !el      external dotprd, v2norm, vaxpy
3041 !el      real(kind=8) :: dotprd, v2norm
3042 !
3043 !/6
3044 !     data half/0.5d+0/, one/1.d+0/, r9973/9973.d+0/, zero/0.d+0/
3045 !/7
3046       real(kind=8),parameter :: half=0.5d+0, one=1.d+0, r9973=9973.d+0, zero=0.d+0
3047 !/
3048 !
3049 !  ***  body  ***
3050 !
3051       ix = 2
3052       pm1 = p - 1
3053 !
3054 !  ***  first check whether to return lsvmin = 0 and initialize x  ***
3055 !
3056       ii = 0
3057       j0 = p*pm1/2
3058       jj = j0 + p
3059       if (l(jj) .eq. zero) go to 110
3060       ix = mod(3432*ix, 9973)
3061       b = half*(one + float(ix)/r9973)
3062       xplus = b / l(jj)
3063       x(p) = xplus
3064       if (p .le. 1) go to 60
3065       do 10 i = 1, pm1
3066          ii = ii + i
3067          if (l(ii) .eq. zero) go to 110
3068          ji = j0 + i
3069          x(i) = xplus * l(ji)
3070  10      continue
3071 !
3072 !  ***  solve (l**t)*x = b, where the components of b have randomly
3073 !  ***  chosen magnitudes in (.5,1) with signs chosen to make x large.
3074 !
3075 !     do j = p-1 to 1 by -1...
3076       do 50 jjj = 1, pm1
3077          j = p - jjj
3078 !       ***  determine x(j) in this iteration. note for i = 1,2,...,j
3079 !       ***  that x(i) holds the current partial sum for row i.
3080          ix = mod(3432*ix, 9973)
3081          b = half*(one + float(ix)/r9973)
3082          xplus = (b - x(j))
3083          xminus = (-b - x(j))
3084          splus = dabs(xplus)
3085          sminus = dabs(xminus)
3086          jm1 = j - 1
3087          j0 = j*jm1/2
3088          jj = j0 + j
3089          xplus = xplus/l(jj)
3090          xminus = xminus/l(jj)
3091          if (jm1 .eq. 0) go to 30
3092          do 20 i = 1, jm1
3093               ji = j0 + i
3094               splus = splus + dabs(x(i) + l(ji)*xplus)
3095               sminus = sminus + dabs(x(i) + l(ji)*xminus)
3096  20           continue
3097  30      if (sminus .gt. splus) xplus = xminus
3098          x(j) = xplus
3099 !       ***  update partial sums  ***
3100          if (jm1 .gt. 0) call vaxpy(jm1, x, xplus, l(j0+1), x)
3101  50      continue
3102 !
3103 !  ***  normalize x  ***
3104 !
3105  60   t = one/v2norm(p, x)
3106       do 70 i = 1, p
3107  70      x(i) = t*x(i)
3108 !
3109 !  ***  solve l*y = x and return lsvmin = 1/twonorm(y)  ***
3110 !
3111       do 100 j = 1, p
3112          jm1 = j - 1
3113          j0 = j*jm1/2
3114          jj = j0 + j
3115          t = zero
3116          if (jm1 .gt. 0) t = dotprd(jm1, l(j0+1), y)
3117          y(j) = (x(j) - t) / l(jj)
3118  100     continue
3119 !
3120       lsvmin = one/v2norm(p, y)
3121       go to 999
3122 !
3123  110  lsvmin = zero
3124  999  return
3125 !  ***  last card of lsvmin follows  ***
3126       end function lsvmin
3127 !-----------------------------------------------------------------------------
3128       subroutine slvmul(p, y, s, x)
3129 !
3130 !  ***  set  y = s * x,  s = p x p symmetric matrix.  ***
3131 !  ***  lower triangle of  s  stored rowwise.         ***
3132 !
3133 !  ***  parameter declarations  ***
3134 !
3135       integer :: p
3136 !al   real(kind=8) :: s(1), x(p), y(p)
3137       real(kind=8) :: s(p*(p+1)/2), x(p), y(p)
3138 !     dimension s(p*(p+1)/2)
3139 !
3140 !  ***  local variables  ***
3141 !
3142       integer :: i, im1, j, k
3143       real(kind=8) :: xi
3144 !
3145 !  ***  no intrinsic functions  ***
3146 !
3147 !  ***  external function  ***
3148 !
3149 !el      external dotprd
3150 !el      real(kind=8) :: dotprd
3151 !
3152 !-----------------------------------------------------------------------
3153 !
3154       j = 1
3155       do 10 i = 1, p
3156          y(i) = dotprd(i, s(j), x)
3157          j = j + i
3158  10      continue
3159 !
3160       if (p .le. 1) go to 999
3161       j = 1
3162       do 40 i = 2, p
3163          xi = x(i)
3164          im1 = i - 1
3165          j = j + 1
3166          do 30 k = 1, im1
3167               y(k) = y(k) + s(j)*xi
3168               j = j + 1
3169  30           continue
3170  40      continue
3171 !
3172  999  return
3173 !  ***  last card of slvmul follows  ***
3174       end subroutine slvmul
3175 !-----------------------------------------------------------------------------
3176 ! minimize_p.F
3177 !-----------------------------------------------------------------------------
3178       subroutine minimize(etot,x,iretcode,nfun)
3179
3180       use energy, only: func,gradient,fdum!,etotal,enerprint
3181       use comm_srutu
3182 !      implicit real*8 (a-h,o-z)
3183 !      include 'DIMENSIONS'
3184       integer,parameter :: liv=60
3185 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2)        !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3186 !********************************************************************
3187 ! OPTIMIZE sets up SUMSL or DFP and provides a simple interface for *
3188 ! the calling subprogram.                                           *     
3189 ! when d(i)=1.0, then v(35) is the length of the initial step,      *     
3190 ! calculated in the usual pythagorean way.                          *     
3191 ! absolute convergence occurs when the function is within v(31) of  *     
3192 ! zero. unless you know the minimum value in advance, abs convg     *     
3193 ! is probably not useful.                                           *     
3194 ! relative convergence is when the model predicts that the function *   
3195 ! will decrease by less than v(32)*abs(fun).                        *   
3196 !********************************************************************
3197 !      include 'COMMON.IOUNITS'
3198 !      include 'COMMON.VAR'
3199 !      include 'COMMON.GEO'
3200 !      include 'COMMON.MINIM'
3201       integer :: i
3202 !el      common /srutu/ icall
3203       integer,dimension(liv) :: iv                                               
3204       real(kind=8) :: minval    !,v(1:77+(6*nres)*(6*nres+17)/2)        !(1:lv)
3205 !el      real(kind=8),dimension(6*nres) :: x,d,xx       !(maxvar) (maxvar=6*maxres)
3206       real(kind=8),dimension(6*nres) :: x,d,xx  !(maxvar) (maxvar=6*maxres)
3207       real(kind=8) :: energia(0:n_ene)
3208 !      external func,gradient,fdum
3209 !      external func_restr,grad_restr
3210       logical :: not_done,change,reduce 
3211 !el      common /przechowalnia/ v
3212 !el local variables
3213       integer :: iretcode,nfun,lv,nvar_restr,idum(1),j
3214       real(kind=8) :: etot,rdum(1)      !,fdum
3215
3216       lv=(77+(6*nres)*(6*nres+17)/2)    !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3217
3218       if (.not.allocated(v)) allocate(v(1:lv))
3219
3220       icall = 1
3221
3222       NOT_DONE=.TRUE.
3223
3224 !     DO WHILE (NOT_DONE)
3225
3226       call deflt(2,iv,liv,lv,v)                                         
3227 ! 12 means fresh start, dont call deflt                                 
3228       iv(1)=12                                                          
3229 ! max num of fun calls                                                  
3230       if (maxfun.eq.0) maxfun=500
3231       iv(17)=maxfun
3232 ! max num of iterations                                                 
3233       if (maxmin.eq.0) maxmin=1000
3234       iv(18)=maxmin
3235 ! controls output                                                       
3236       iv(19)=2                                                          
3237 ! selects output unit                                                   
3238       iv(21)=0
3239       if (print_min_ini+print_min_stat+print_min_res.gt.0) iv(21)=iout
3240 ! 1 means to print out result                                           
3241       iv(22)=print_min_res
3242 ! 1 means to print out summary stats                                    
3243       iv(23)=print_min_stat
3244 ! 1 means to print initial x and d                                      
3245       iv(24)=print_min_ini
3246 ! min val for v(radfac) default is 0.1                                  
3247       v(24)=0.1D0                                                       
3248 ! max val for v(radfac) default is 4.0                                  
3249       v(25)=2.0D0                                                       
3250 !     v(25)=4.0D0                                                       
3251 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
3252 ! the sumsl default is 0.1                                              
3253       v(26)=0.1D0
3254 ! false conv if (act fnctn decrease) .lt. v(34)                         
3255 ! the sumsl default is 100*machep                                       
3256       v(34)=v(34)/100.0D0                                               
3257 ! absolute convergence                                                  
3258       if (tolf.eq.0.0D0) tolf=1.0D-4
3259       v(31)=tolf
3260 ! relative convergence                                                  
3261       if (rtolf.eq.0.0D0) rtolf=1.0D-4
3262       v(32)=rtolf
3263 ! controls initial step size                                            
3264        v(35)=1.0D-1                                                    
3265 ! large vals of d correspond to small components of step                
3266       do i=1,nphi
3267         d(i)=1.0D-1
3268       enddo
3269       do i=nphi+1,nvar
3270         d(i)=1.0D-1
3271       enddo
3272 !d    print *,'Calling SUMSL'
3273 !     call var_to_geom(nvar,x)
3274 !     call chainbuild
3275 !     call etotal(energia(0))
3276 !     etot = energia(0)
3277 !elmask_r=.true.
3278       IF (mask_r) THEN
3279        call x2xx(x,xx,nvar_restr)
3280        call sumsl(nvar_restr,d,xx,func_restr,grad_restr,&
3281                           iv,liv,lv,v,idum,rdum,fdum)      
3282        call xx2x(x,xx)
3283       ELSE
3284        call sumsl(nvar,d,x,func,gradient,iv,liv,lv,v,idum,rdum,fdum)      
3285       ENDIF
3286       etot=v(10)                                                      
3287       iretcode=iv(1)
3288 !d    print *,'Exit SUMSL; return code:',iretcode,' energy:',etot
3289 !d    write (iout,'(/a,i4/)') 'SUMSL return code:',iv(1)
3290 !     call intout
3291 !     change=reduce(x)
3292       call var_to_geom(nvar,x)
3293 !     if (change) then
3294 !       write (iout,'(a)') 'Reduction worked, minimizing again...'
3295 !     else
3296 !       not_done=.false.
3297 !     endif
3298       call chainbuild
3299
3300 !el---------------------
3301 !      write (iout,'(/a)') &
3302 !        "Cartesian coordinates of the reference structure after SUMSL"
3303 !      write (iout,'(a,3(3x,a5),5x,3(3x,a5))') &
3304 !       "Residue","X(CA)","Y(CA)","Z(CA)","X(SC)","Y(SC)","Z(SC)"
3305 !      do i=1,nres
3306 !        write (iout,'(a3,1x,i3,3f8.3,5x,3f8.3)') &
3307 !          restyp(itype(i)),i,(c(j,i),j=1,3),&
3308 !          (c(j,i+nres),j=1,3)
3309 !      enddo
3310 !el----------------------------
3311 !     call etotal(energia) !sp
3312 !     etot=energia(0)
3313 !     call enerprint(energia) !sp
3314       nfun=iv(6)
3315
3316 !     write (*,*) 'Processor',MyID,' leaves MINIMIZE.'
3317
3318 !     ENDDO ! NOT_DONE
3319
3320       return
3321       end subroutine minimize
3322 !-----------------------------------------------------------------------------
3323 ! gradient_p.F
3324 !-----------------------------------------------------------------------------
3325       subroutine grad_restr(n,x,nf,g,uiparm,urparm,ufparm)
3326
3327       use energy, only: cartder,zerograd,etotal,sum_gradient
3328 !      implicit real*8 (a-h,o-z)
3329 !      include 'DIMENSIONS'
3330 !      include 'COMMON.CHAIN'
3331 !      include 'COMMON.DERIV'
3332 !      include 'COMMON.VAR'
3333 !      include 'COMMON.INTERACT'
3334 !      include 'COMMON.FFIELD'
3335 !      include 'COMMON.IOUNITS'
3336 !EL      external ufparm
3337       integer :: uiparm(1)
3338       real(kind=8) :: urparm(1)
3339       real(kind=8),dimension(6*nres) :: x,g !(maxvar) (maxvar=6*maxres)
3340       integer :: n,nf,ig,ind,i,j,ij,k,igall
3341       real(kind=8) :: f,gphii,gthetai,galphai,gomegai
3342       real(kind=8),external :: ufparm
3343
3344       icg=mod(nf,2)+1
3345       if (nf-nfl+1) 20,30,40
3346    20 call func_restr(n,x,nf,f,uiparm,urparm,ufparm)
3347 !     write (iout,*) 'grad 20'
3348       if (nf.eq.0) return
3349       goto 40
3350    30 continue
3351 #ifdef OSF
3352 !     Intercept NaNs in the coordinates
3353 !      write(iout,*) (var(i),i=1,nvar)
3354       x_sum=0.D0
3355       do i=1,n
3356         x_sum=x_sum+x(i)
3357       enddo
3358       if (x_sum.ne.x_sum) then
3359         write(iout,*)" *** grad_restr : Found NaN in coordinates"
3360         call flush(iout)
3361         print *," *** grad_restr : Found NaN in coordinates"
3362         return
3363       endif
3364 #endif
3365       call var_to_geom_restr(n,x)
3366       call chainbuild 
3367 !
3368 ! Evaluate the derivatives of virtual bond lengths and SC vectors in variables.
3369 !
3370    40 call cartder
3371 !
3372 ! Convert the Cartesian gradient into internal-coordinate gradient.
3373 !
3374
3375       ig=0
3376       ind=nres-2                                                                    
3377       do i=2,nres-2                
3378        IF (mask_phi(i+2).eq.1) THEN                                             
3379         gphii=0.0D0                                                             
3380         do j=i+1,nres-1                                                         
3381           ind=ind+1                                 
3382           do k=1,3                                                              
3383             gphii=gphii+dcdv(k+3,ind)*gradc(k,j,icg)                            
3384             gphii=gphii+dxdv(k+3,ind)*gradx(k,j,icg)                           
3385           enddo                                                                 
3386         enddo                                                                   
3387         ig=ig+1
3388         g(ig)=gphii
3389        ELSE
3390         ind=ind+nres-1-i
3391        ENDIF
3392       enddo                                        
3393
3394
3395       ind=0
3396       do i=1,nres-2
3397        IF (mask_theta(i+2).eq.1) THEN
3398         ig=ig+1
3399         gthetai=0.0D0
3400         do j=i+1,nres-1
3401           ind=ind+1
3402           do k=1,3
3403             gthetai=gthetai+dcdv(k,ind)*gradc(k,j,icg)
3404             gthetai=gthetai+dxdv(k,ind)*gradx(k,j,icg)
3405           enddo
3406         enddo
3407         g(ig)=gthetai
3408        ELSE
3409         ind=ind+nres-1-i
3410        ENDIF
3411       enddo
3412
3413       do i=2,nres-1
3414         if (itype(i).ne.10) then
3415          IF (mask_side(i).eq.1) THEN
3416           ig=ig+1
3417           galphai=0.0D0
3418           do k=1,3
3419             galphai=galphai+dxds(k,i)*gradx(k,i,icg)
3420           enddo
3421           g(ig)=galphai
3422          ENDIF
3423         endif
3424       enddo
3425
3426       
3427       do i=2,nres-1
3428         if (itype(i).ne.10) then
3429          IF (mask_side(i).eq.1) THEN
3430           ig=ig+1
3431           gomegai=0.0D0
3432           do k=1,3
3433             gomegai=gomegai+dxds(k+3,i)*gradx(k,i,icg)
3434           enddo
3435           g(ig)=gomegai
3436          ENDIF
3437         endif
3438       enddo
3439
3440 !
3441 ! Add the components corresponding to local energy terms.
3442 !
3443
3444       ig=0
3445       igall=0
3446       do i=4,nres
3447         igall=igall+1
3448         if (mask_phi(i).eq.1) then
3449           ig=ig+1
3450           g(ig)=g(ig)+gloc(igall,icg)
3451         endif
3452       enddo
3453
3454       do i=3,nres
3455         igall=igall+1
3456         if (mask_theta(i).eq.1) then
3457           ig=ig+1
3458           g(ig)=g(ig)+gloc(igall,icg)
3459         endif
3460       enddo
3461      
3462       do ij=1,2
3463       do i=2,nres-1
3464         if (itype(i).ne.10) then
3465           igall=igall+1
3466           if (mask_side(i).eq.1) then
3467             ig=ig+1
3468             g(ig)=g(ig)+gloc(igall,icg)
3469           endif
3470         endif
3471       enddo
3472       enddo
3473
3474 !d      do i=1,ig
3475 !d        write (iout,'(a2,i5,a3,f25.8)') 'i=',i,' g=',g(i)
3476 !d      enddo
3477       return
3478       end subroutine grad_restr
3479 !-----------------------------------------------------------------------------
3480       subroutine func_restr(n,x,nf,f,uiparm,urparm,ufparm) !from minimize_p.F
3481
3482       use comm_chu
3483       use energy, only: zerograd,etotal,sum_gradient
3484 !      implicit real*8 (a-h,o-z)
3485 !      include 'DIMENSIONS'
3486 !      include 'COMMON.DERIV'
3487 !      include 'COMMON.IOUNITS'
3488 !      include 'COMMON.GEO'
3489       integer :: n,nf
3490 !el      integer :: jjj
3491 !el      common /chuju/ jjj
3492       real(kind=8) :: energia(0:n_ene)
3493       real(kind=8) :: f
3494       real(kind=8),external :: ufparm                               
3495       integer :: uiparm(1)                                        
3496       real(kind=8) :: urparm(1)                                     
3497       real(kind=8),dimension(6*nres) :: x       !(maxvar) (maxvar=6*maxres)
3498 !     if (jjj.gt.0) then
3499 !       write (iout,'(10f8.3)') (rad2deg*x(i),i=1,n)
3500 !     endif
3501       nfl=nf
3502       icg=mod(nf,2)+1
3503       call var_to_geom_restr(n,x)
3504       call zerograd
3505       call chainbuild
3506 !d    write (iout,*) 'ETOTAL called from FUNC'
3507       call etotal(energia)
3508       call sum_gradient
3509       f=energia(0)
3510 !     if (jjj.gt.0) then
3511 !       write (iout,'(10f8.3)') (rad2deg*x(i),i=1,n)
3512 !       write (iout,*) 'f=',etot
3513 !       jjj=0
3514 !     endif
3515       return
3516       end subroutine func_restr
3517 !-----------------------------------------------------------------------------
3518 !      subroutine func(n,x,nf,f,uiparm,urparm,ufparm) in module energy
3519 !-----------------------------------------------------------------------------
3520       subroutine x2xx(x,xx,n)
3521
3522 !      implicit real*8 (a-h,o-z)
3523 !      include 'DIMENSIONS'
3524 !      include 'COMMON.VAR'
3525 !      include 'COMMON.CHAIN'
3526 !      include 'COMMON.INTERACT'
3527       integer :: n,i,ij,ig,igall
3528       real(kind=8),dimension(6*nres) :: xx,x    !(maxvar) (maxvar=6*maxres)
3529
3530 !el      allocate(varall(nvar)) allocated in alioc_ener_arrays
3531
3532       do i=1,nvar
3533         varall(i)=x(i)
3534       enddo
3535
3536       ig=0                                                                      
3537       igall=0                                                                   
3538       do i=4,nres                                                               
3539         igall=igall+1                                                           
3540         if (mask_phi(i).eq.1) then                                              
3541           ig=ig+1                                                               
3542           xx(ig)=x(igall)                       
3543         endif                                                                   
3544       enddo                                                                     
3545                                                                                 
3546       do i=3,nres                                                               
3547         igall=igall+1                                                           
3548         if (mask_theta(i).eq.1) then                                            
3549           ig=ig+1                                                               
3550           xx(ig)=x(igall)
3551         endif                                                                   
3552       enddo                                          
3553
3554       do ij=1,2                                                                 
3555       do i=2,nres-1                                                             
3556         if (itype(i).ne.10) then                                                
3557           igall=igall+1                                                         
3558           if (mask_side(i).eq.1) then                                           
3559             ig=ig+1                                                             
3560             xx(ig)=x(igall)
3561           endif                                                                 
3562         endif                                                                   
3563       enddo                                                                     
3564       enddo                              
3565  
3566       n=ig
3567
3568       return
3569       end subroutine x2xx
3570 !-----------------------------------------------------------------------------
3571 !el      subroutine xx2x(x,xx) in module math
3572 !-----------------------------------------------------------------------------
3573       subroutine minim_dc(etot,iretcode,nfun)
3574
3575       use MPI_data
3576       use energy, only: fdum,check_ecartint
3577 !      implicit real*8 (a-h,o-z)
3578 !      include 'DIMENSIONS'
3579 #ifdef MPI
3580       include 'mpif.h'
3581 #endif
3582       integer,parameter :: liv=60
3583 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3584 !      include 'COMMON.SETUP'
3585 !      include 'COMMON.IOUNITS'
3586 !      include 'COMMON.VAR'
3587 !      include 'COMMON.GEO'
3588 !      include 'COMMON.MINIM'
3589 !      include 'COMMON.CHAIN'
3590       integer :: iretcode,nfun,k,i,j,lv,idum(1)
3591       integer,dimension(liv) :: iv                                               
3592       real(kind=8) :: minval    !,v(1:77+(6*nres)*(6*nres+17)/2)        !(1:lv)
3593       real(kind=8),dimension(6*nres) :: x,d,xx  !(maxvar) (maxvar=6*maxres)
3594 !el      common /przechowalnia/ v
3595
3596       real(kind=8) :: energia(0:n_ene)
3597 !      external func_dc,grad_dc ,fdum
3598       logical :: not_done,change,reduce 
3599       real(kind=8) :: g(6*nres),f1,etot,rdum(1) !,fdum
3600
3601       lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3602
3603       if (.not. allocated(v)) allocate(v(1:lv))
3604
3605       call deflt(2,iv,liv,lv,v)                                         
3606 ! 12 means fresh start, dont call deflt                                 
3607       iv(1)=12                                                          
3608 ! max num of fun calls                                                  
3609       if (maxfun.eq.0) maxfun=500
3610       iv(17)=maxfun
3611 ! max num of iterations                                                 
3612       if (maxmin.eq.0) maxmin=1000
3613       iv(18)=maxmin
3614 ! controls output                                                       
3615       iv(19)=2                                                          
3616 ! selects output unit                                                   
3617       iv(21)=0
3618       if (print_min_ini+print_min_stat+print_min_res.gt.0) iv(21)=iout
3619 ! 1 means to print out result                                           
3620       iv(22)=print_min_res
3621 ! 1 means to print out summary stats                                    
3622       iv(23)=print_min_stat
3623 ! 1 means to print initial x and d                                      
3624       iv(24)=print_min_ini
3625 ! min val for v(radfac) default is 0.1                                  
3626       v(24)=0.1D0                                                       
3627 ! max val for v(radfac) default is 4.0                                  
3628       v(25)=2.0D0                                                       
3629 !     v(25)=4.0D0                                                       
3630 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
3631 ! the sumsl default is 0.1                                              
3632       v(26)=0.1D0
3633 ! false conv if (act fnctn decrease) .lt. v(34)                         
3634 ! the sumsl default is 100*machep                                       
3635       v(34)=v(34)/100.0D0                                               
3636 ! absolute convergence                                                  
3637       if (tolf.eq.0.0D0) tolf=1.0D-4
3638       v(31)=tolf
3639 ! relative convergence                                                  
3640       if (rtolf.eq.0.0D0) rtolf=1.0D-4
3641       v(32)=rtolf
3642 ! controls initial step size                                            
3643        v(35)=1.0D-1                                                    
3644 ! large vals of d correspond to small components of step                
3645       do i=1,6*nres
3646         d(i)=1.0D-1
3647       enddo
3648
3649       k=0
3650       do i=1,nres-1
3651         do j=1,3
3652           k=k+1
3653           x(k)=dc(j,i)
3654         enddo
3655       enddo
3656       do i=2,nres-1
3657         if (ialph(i,1).gt.0) then
3658         do j=1,3
3659           k=k+1
3660           x(k)=dc(j,i+nres)
3661         enddo
3662         endif
3663       enddo
3664       call check_ecartint
3665       call sumsl(k,d,x,func_dc,grad_dc,iv,liv,lv,v,idum,rdum,fdum)      
3666       call check_ecartint
3667       k=0
3668       do i=1,nres-1
3669         do j=1,3
3670           k=k+1
3671           dc(j,i)=x(k)
3672         enddo
3673       enddo
3674       do i=2,nres-1
3675         if (ialph(i,1).gt.0) then
3676         do j=1,3
3677           k=k+1
3678           dc(j,i+nres)=x(k)
3679         enddo
3680         endif
3681       enddo
3682       call chainbuild_cart
3683
3684 !d      call zerograd
3685 !d      nf=0
3686 !d      call func_dc(k,x,nf,f,idum,rdum,fdum)
3687 !d      call grad_dc(k,x,nf,g,idum,rdum,fdum)
3688 !d
3689 !d      do i=1,k
3690 !d       x(i)=x(i)+1.0D-5
3691 !d       call func_dc(k,x,nf,f1,idum,rdum,fdum)
3692 !d       x(i)=x(i)-1.0D-5
3693 !d       print '(i5,2f15.5)',i,g(i),(f1-f)/1.0D-5
3694 !d      enddo
3695 !el---------------------
3696 !      write (iout,'(/a)') &
3697 !        "Cartesian coordinates of the reference structure after SUMSL"
3698 !      write (iout,'(a,3(3x,a5),5x,3(3x,a5))') &
3699 !       "Residue","X(CA)","Y(CA)","Z(CA)","X(SC)","Y(SC)","Z(SC)"
3700 !      do i=1,nres
3701 !        write (iout,'(a3,1x,i3,3f8.3,5x,3f8.3)') &
3702 !          restyp(itype(i)),i,(c(j,i),j=1,3),&
3703 !          (c(j,i+nres),j=1,3)
3704 !      enddo
3705 !el----------------------------
3706       etot=v(10)                                                      
3707       iretcode=iv(1)
3708       nfun=iv(6)
3709       return
3710       end subroutine  minim_dc
3711 !-----------------------------------------------------------------------------
3712       subroutine func_dc(n,x,nf,f,uiparm,urparm,ufparm)
3713
3714       use MPI_data
3715       use energy, only: zerograd,etotal
3716 !      implicit real*8 (a-h,o-z)
3717 !      include 'DIMENSIONS'
3718 #ifdef MPI
3719       include 'mpif.h'
3720 #endif
3721 !      include 'COMMON.SETUP'
3722 !      include 'COMMON.DERIV'
3723 !      include 'COMMON.IOUNITS'
3724 !      include 'COMMON.GEO'
3725 !      include 'COMMON.CHAIN'
3726 !      include 'COMMON.VAR'
3727       integer :: n,nf,k,i,j
3728       real(kind=8) :: energia(0:n_ene)
3729       real(kind=8),external :: ufparm
3730       integer :: uiparm(1)                                                 
3731       real(kind=8) :: urparm(1)                                                    
3732       real(kind=8),dimension(6*nres) :: x       !(maxvar) (maxvar=6*maxres)
3733       real(kind=8) :: f
3734       nfl=nf
3735 !bad      icg=mod(nf,2)+1
3736       icg=1
3737
3738       k=0
3739       do i=1,nres-1
3740         do j=1,3
3741           k=k+1
3742           dc(j,i)=x(k)
3743         enddo
3744       enddo
3745       do i=2,nres-1
3746         if (ialph(i,1).gt.0) then
3747         do j=1,3
3748           k=k+1
3749           dc(j,i+nres)=x(k)
3750         enddo
3751         endif
3752       enddo
3753       call chainbuild_cart
3754
3755       call zerograd
3756       call etotal(energia)
3757       f=energia(0)
3758
3759 !d      print *,'func_dc ',nf,nfl,f
3760
3761       return
3762       end subroutine func_dc
3763 !-----------------------------------------------------------------------------
3764       subroutine grad_dc(n,x,nf,g,uiparm,urparm,ufparm)
3765
3766       use MPI_data
3767       use energy, only: cartgrad,zerograd,etotal
3768 !      use MD_data
3769 !      implicit real*8 (a-h,o-z)
3770 !      include 'DIMENSIONS'
3771 #ifdef MPI
3772       include 'mpif.h'
3773 #endif
3774 !      include 'COMMON.SETUP'
3775 !      include 'COMMON.CHAIN'
3776 !      include 'COMMON.DERIV'
3777 !      include 'COMMON.VAR'
3778 !      include 'COMMON.INTERACT'
3779 !      include 'COMMON.FFIELD'
3780 !      include 'COMMON.MD'
3781 !      include 'COMMON.IOUNITS'
3782       real(kind=8),external :: ufparm
3783       integer :: n,nf,i,j,k
3784       integer :: uiparm(1)
3785       real(kind=8) :: urparm(1)
3786       real(kind=8),dimension(6*nres) :: x,g     !(maxvar) (maxvar=6*maxres)
3787       real(kind=8) :: f
3788 !
3789 !elwrite(iout,*) "jestesmy w grad dc"
3790 !
3791 !bad      icg=mod(nf,2)+1
3792       icg=1
3793 !d      print *,'grad_dc ',nf,nfl,nf-nfl+1,icg
3794 !elwrite(iout,*) "jestesmy w grad dc nf-nfl+1", nf-nfl+1
3795       if (nf-nfl+1) 20,30,40
3796    20 call func_dc(n,x,nf,f,uiparm,urparm,ufparm)
3797 !d      print *,20
3798       if (nf.eq.0) return
3799       goto 40
3800    30 continue
3801 !d      print *,30
3802       k=0
3803       do i=1,nres-1
3804         do j=1,3
3805           k=k+1
3806           dc(j,i)=x(k)
3807         enddo
3808       enddo
3809       do i=2,nres-1
3810         if (ialph(i,1).gt.0) then
3811         do j=1,3
3812           k=k+1
3813           dc(j,i+nres)=x(k)
3814         enddo
3815         endif
3816       enddo
3817 !elwrite(iout,*) "jestesmy w grad dc"
3818       call chainbuild_cart
3819
3820 !
3821 ! Evaluate the derivatives of virtual bond lengths and SC vectors in variables.
3822 !
3823    40 call cartgrad
3824 !d      print *,40
3825 !elwrite(iout,*) "jestesmy w grad dc"
3826       k=0
3827       do i=1,nres-1
3828         do j=1,3
3829           k=k+1
3830           g(k)=gcart(j,i)
3831         enddo
3832       enddo
3833       do i=2,nres-1
3834         if (ialph(i,1).gt.0) then
3835         do j=1,3
3836           k=k+1
3837           g(k)=gxcart(j,i)
3838         enddo
3839         endif
3840       enddo       
3841 !elwrite(iout,*) "jestesmy w grad dc"
3842
3843       return
3844       end subroutine grad_dc
3845 !-----------------------------------------------------------------------------
3846 ! minim_mcmf.F
3847 !-----------------------------------------------------------------------------
3848 #ifdef MPI
3849       subroutine minim_mcmf
3850
3851       use MPI_data
3852       use csa_data
3853       use energy, only: func,gradient,fdum
3854 !      implicit real*8 (a-h,o-z)
3855 !      include 'DIMENSIONS'
3856       include 'mpif.h'
3857       integer,parameter :: liv=60
3858 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3859 !      include 'COMMON.VAR'
3860 !      include 'COMMON.IOUNITS'
3861 !      include 'COMMON.MINIM'
3862 !      real(kind=8) :: fdum
3863 !      external func,gradient,fdum
3864 !el      real(kind=4) :: ran1,ran2,ran3
3865 !      include 'COMMON.SETUP'
3866 !      include 'COMMON.GEO'
3867 !      include 'COMMON.CHAIN'
3868 !      include 'COMMON.FFIELD'
3869       real(kind=8),dimension(6*nres) :: var     !(maxvar) (maxvar=6*maxres)
3870       real(kind=8),dimension(mxch*(mxch+1)/2+1) :: erg
3871       real(kind=8),dimension(6*nres) :: d,garbage       !(maxvar) (maxvar=6*maxres)
3872 !el      real(kind=8) :: v(1:77+(6*nres)*(6*nres+17)/2+1)                    
3873       integer,dimension(6) :: indx
3874       integer,dimension(liv) :: iv                                               
3875       integer :: lv,idum(1),nf  !
3876       real(kind=8) :: rdum(1)
3877       real(kind=8) :: przes(3),obrot(3,3),eee
3878       logical :: non_conv
3879
3880       integer,dimension(MPI_STATUS_SIZE) :: muster
3881
3882       integer :: ichuj,i,ierr
3883       real(kind=8) :: rad,ene0
3884       data rad /1.745329252d-2/
3885 !el      common /przechowalnia/ v
3886
3887       lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3888       if (.not. allocated(v)) allocate(v(1:lv))
3889
3890       ichuj=0
3891    10 continue
3892       ichuj = ichuj + 1
3893       call mpi_recv(indx,6,mpi_integer,king,idint,CG_COMM,&
3894                     muster,ierr)
3895       if (indx(1).eq.0) return
3896 !      print *, 'worker ',me,' received order ',n,ichuj
3897       call mpi_recv(var,nvar,mpi_double_precision,&
3898                     king,idreal,CG_COMM,muster,ierr)
3899       call mpi_recv(ene0,1,mpi_double_precision,&
3900                     king,idreal,CG_COMM,muster,ierr)
3901 !      print *, 'worker ',me,' var read '
3902
3903
3904       call deflt(2,iv,liv,lv,v)                                         
3905 ! 12 means fresh start, dont call deflt                                 
3906       iv(1)=12                                                          
3907 ! max num of fun calls                                                  
3908       if (maxfun.eq.0) maxfun=500
3909       iv(17)=maxfun
3910 ! max num of iterations                                                 
3911       if (maxmin.eq.0) maxmin=1000
3912       iv(18)=maxmin
3913 ! controls output                                                       
3914       iv(19)=2                                                          
3915 ! selects output unit                                                   
3916 !      iv(21)=iout                                                       
3917       iv(21)=0
3918 ! 1 means to print out result                                           
3919       iv(22)=0                                                          
3920 ! 1 means to print out summary stats                                    
3921       iv(23)=0                                                          
3922 ! 1 means to print initial x and d                                      
3923       iv(24)=0                                                          
3924 ! min val for v(radfac) default is 0.1                                  
3925       v(24)=0.1D0                                                       
3926 ! max val for v(radfac) default is 4.0                                  
3927       v(25)=2.0D0                                                       
3928 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
3929 ! the sumsl default is 0.1                                              
3930       v(26)=0.1D0
3931 ! false conv if (act fnctn decrease) .lt. v(34)                         
3932 ! the sumsl default is 100*machep                                       
3933       v(34)=v(34)/100.0D0                                               
3934 ! absolute convergence                                                  
3935       if (tolf.eq.0.0D0) tolf=1.0D-4
3936       v(31)=tolf
3937 ! relative convergence                                                  
3938       if (rtolf.eq.0.0D0) rtolf=1.0D-4
3939       v(32)=rtolf
3940 ! controls initial step size                                            
3941        v(35)=1.0D-1                                                    
3942 ! large vals of d correspond to small components of step                
3943       do i=1,nphi
3944         d(i)=1.0D-1
3945       enddo
3946       do i=nphi+1,nvar
3947         d(i)=1.0D-1
3948       enddo
3949 !  minimize energy
3950
3951       call func(nvar,var,nf,eee,idum,rdum,fdum)
3952       if(eee.gt.1.0d18) then
3953 !       print *,'MINIM_JLEE: ',me,' CHUJ NASTAPIL'
3954 !       print *,' energy before SUMSL =',eee
3955 !       print *,' aborting local minimization'
3956        iv(1)=-1
3957        v(10)=eee
3958        nf=1
3959        go to 201
3960       endif
3961
3962       call sumsl(nvar,d,var,func,gradient,iv,liv,lv,v,idum,rdum,fdum)
3963 !  find which conformation was returned from sumsl
3964         nf=iv(7)+1
3965   201  continue
3966 ! total # of ftn evaluations (for iwf=0, it includes all minimizations).
3967         indx(4)=nf
3968         indx(5)=iv(1)
3969         eee=v(10)
3970
3971         call mpi_send(indx,6,mpi_integer,king,idint,CG_COMM,&
3972                        ierr)
3973 !       print '(a5,i3,15f10.5)', 'ENEX0',indx(1),v(10)
3974         call mpi_send(var,nvar,mpi_double_precision,&
3975                      king,idreal,CG_COMM,ierr)
3976         call mpi_send(eee,1,mpi_double_precision,king,idreal,&
3977                        CG_COMM,ierr)
3978         call mpi_send(ene0,1,mpi_double_precision,king,idreal,&
3979                        CG_COMM,ierr)
3980         go to 10
3981       return
3982       end subroutine minim_mcmf
3983 #endif
3984 !-----------------------------------------------------------------------------
3985 ! rmdd.f
3986 !-----------------------------------------------------------------------------
3987 !     algorithm 611, collected algorithms from acm.
3988 !     algorithm appeared in acm-trans. math. software, vol.9, no. 4,
3989 !     dec., 1983, p. 503-524.
3990       integer function imdcon(k)
3991 !
3992       integer :: k
3993 !
3994 !  ***  return integer machine-dependent constants  ***
3995 !
3996 !     ***  k = 1 means return standard output unit number.   ***
3997 !     ***  k = 2 means return alternate output unit number.  ***
3998 !     ***  k = 3 means return  input unit number.            ***
3999 !          (note -- k = 2, 3 are used only by test programs.)
4000 !
4001 !  +++  port version follows...
4002 !     external i1mach
4003 !     integer i1mach
4004 !     integer mdperm(3)
4005 !     data mdperm(1)/2/, mdperm(2)/4/, mdperm(3)/1/
4006 !     imdcon = i1mach(mdperm(k))
4007 !  +++  end of port version  +++
4008 !
4009 !  +++  non-port version follows...
4010       integer :: mdcon(3)
4011       data mdcon(1)/6/, mdcon(2)/8/, mdcon(3)/5/
4012       imdcon = mdcon(k)
4013 !  +++  end of non-port version  +++
4014 !
4015  999  return
4016 !  ***  last card of imdcon follows  ***
4017       end function imdcon
4018 !-----------------------------------------------------------------------------
4019       real(kind=8) function rmdcon(k)
4020 !
4021 !  ***  return machine dependent constants used by nl2sol  ***
4022 !
4023 ! +++  comments below contain data statements for various machines.  +++
4024 ! +++  to convert to another machine, place a c in column 1 of the   +++
4025 ! +++  data statement line(s) that correspond to the current machine +++
4026 ! +++  and remove the c from column 1 of the data statement line(s)  +++
4027 ! +++  that correspond to the new machine.                           +++
4028 !
4029       integer :: k
4030 !
4031 !  ***  the constant returned depends on k...
4032 !
4033 !  ***        k = 1... smallest pos. eta such that -eta exists.
4034 !  ***        k = 2... square root of eta.
4035 !  ***        k = 3... unit roundoff = smallest pos. no. machep such
4036 !  ***                 that 1 + machep .gt. 1 .and. 1 - machep .lt. 1.
4037 !  ***        k = 4... square root of machep.
4038 !  ***        k = 5... square root of big (see k = 6).
4039 !  ***        k = 6... largest machine no. big such that -big exists.
4040 !
4041       real(kind=8) :: big, eta, machep
4042       integer :: bigi(4), etai(4), machei(4)
4043 !/+
4044 !el      real(kind=8) :: dsqrt
4045 !/
4046       equivalence (big,bigi(1)), (eta,etai(1)), (machep,machei(1))
4047 !
4048 !  +++  ibm 360, ibm 370, or xerox  +++
4049 !
4050 !     data big/z7fffffffffffffff/, eta/z0010000000000000/,
4051 !    1     machep/z3410000000000000/
4052 !
4053 !  +++  data general  +++
4054 !
4055 !     data big/0.7237005577d+76/, eta/0.5397605347d-78/,
4056 !    1     machep/2.22044605d-16/
4057 !
4058 !  +++  dec 11  +++
4059 !
4060 !     data big/1.7d+38/, eta/2.938735878d-39/, machep/2.775557562d-17/
4061 !
4062 !  +++  hp3000  +++
4063 !
4064 !     data big/1.157920892d+77/, eta/8.636168556d-78/,
4065 !    1     machep/5.551115124d-17/
4066 !
4067 !  +++  honeywell  +++
4068 !
4069 !     data big/1.69d+38/, eta/5.9d-39/, machep/2.1680435d-19/
4070 !
4071 !  +++  dec10  +++
4072 !
4073 !     data big/"377777100000000000000000/,
4074 !    1     eta/"002400400000000000000000/,
4075 !    2     machep/"104400000000000000000000/
4076 !
4077 !  +++  burroughs  +++
4078 !
4079 !     data big/o0777777777777777,o7777777777777777/,
4080 !    1     eta/o1771000000000000,o7770000000000000/,
4081 !    2     machep/o1451000000000000,o0000000000000000/
4082 !
4083 !  +++  control data  +++
4084 !
4085 !     data big/37767777777777777777b,37167777777777777777b/,
4086 !    1     eta/00014000000000000000b,00000000000000000000b/,
4087 !    2     machep/15614000000000000000b,15010000000000000000b/
4088 !
4089 !  +++  prime  +++
4090 !
4091 !     data big/1.0d+9786/, eta/1.0d-9860/, machep/1.4210855d-14/
4092 !
4093 !  +++  univac  +++
4094 !
4095 !     data big/8.988d+307/, eta/1.2d-308/, machep/1.734723476d-18/
4096 !
4097 !  +++  vax  +++
4098 !
4099       data big/1.7d+38/, eta/2.939d-39/, machep/1.3877788d-17/
4100 !
4101 !  +++  cray 1  +++
4102 !
4103 !     data bigi(1)/577767777777777777777b/,
4104 !    1     bigi(2)/000007777777777777776b/,
4105 !    2     etai(1)/200004000000000000000b/,
4106 !    3     etai(2)/000000000000000000000b/,
4107 !    4     machei(1)/377224000000000000000b/,
4108 !    5     machei(2)/000000000000000000000b/
4109 !
4110 !  +++  port library -- requires more than just a data statement... +++
4111 !
4112 !     external d1mach
4113 !     double precision d1mach, zero
4114 !     data big/0.d+0/, eta/0.d+0/, machep/0.d+0/, zero/0.d+0/
4115 !     if (big .gt. zero) go to 1
4116 !        big = d1mach(2)
4117 !        eta = d1mach(1)
4118 !        machep = d1mach(4)
4119 !1    continue
4120 !
4121 !  +++ end of port +++
4122 !
4123 !-------------------------------  body  --------------------------------
4124 !
4125       go to (10, 20, 30, 40, 50, 60), k
4126 !
4127  10   rmdcon = eta
4128       go to 999
4129 !
4130  20   rmdcon = dsqrt(256.d+0*eta)/16.d+0
4131       go to 999
4132 !
4133  30   rmdcon = machep
4134       go to 999
4135 !
4136  40   rmdcon = dsqrt(machep)
4137       go to 999
4138 !
4139  50   rmdcon = dsqrt(big/256.d+0)*16.d+0
4140       go to 999
4141 !
4142  60   rmdcon = big
4143 !
4144  999  return
4145 !  ***  last card of rmdcon follows  ***
4146       end function rmdcon
4147 !-----------------------------------------------------------------------------
4148 ! sc_move.F
4149 !-----------------------------------------------------------------------------
4150       subroutine sc_move(n_start,n_end,n_maxtry,e_drop,n_fun,etot)
4151
4152       use control
4153       use random, only: iran_num
4154       use energy, only: esc
4155 !     Perform a quick search over side-chain arrangments (over
4156 !     residues n_start to n_end) for a given (frozen) CA trace
4157 !     Only side-chains are minimized (at most n_maxtry times each),
4158 !     not CA positions
4159 !     Stops if energy drops by e_drop, otherwise tries all residues
4160 !     in the given range
4161 !     If there is an energy drop, full minimization may be useful
4162 !     n_start, n_end CAN be modified by this routine, but only if
4163 !     out of bounds (n_start <= 1, n_end >= nres, n_start < n_end)
4164 !     NOTE: this move should never increase the energy
4165 !rc      implicit none
4166
4167 !     Includes
4168 !      implicit real*8 (a-h,o-z)
4169 !      include 'DIMENSIONS'
4170       include 'mpif.h'
4171 !      include 'COMMON.GEO'
4172 !      include 'COMMON.VAR'
4173 !      include 'COMMON.HEADER'
4174 !      include 'COMMON.IOUNITS'
4175 !      include 'COMMON.CHAIN'
4176 !      include 'COMMON.FFIELD'
4177
4178 !     External functions
4179 !el      integer iran_num
4180 !el      external iran_num
4181
4182 !     Input arguments
4183       integer :: n_start,n_end,n_maxtry
4184       real(kind=8) :: e_drop
4185
4186 !     Output arguments
4187       integer :: n_fun
4188       real(kind=8) :: etot
4189
4190 !     Local variables
4191 !      real(kind=8) :: energy(0:n_ene)
4192       real(kind=8) :: cur_alph(2:nres-1),cur_omeg(2:nres-1)
4193       real(kind=8) :: orig_e,cur_e
4194       integer :: n,n_steps,n_first,n_cur,n_tot  !,i
4195       real(kind=8) :: orig_w(0:n_ene)
4196       real(kind=8) :: wtime
4197
4198 !elwrite(iout,*) "in sc_move etot= ", etot
4199 !     Set non side-chain weights to zero (minimization is faster)
4200 !     NOTE: e(2) does not actually depend on the side-chain, only CA
4201       orig_w(2)=wscp
4202       orig_w(3)=welec
4203       orig_w(4)=wcorr
4204       orig_w(5)=wcorr5
4205       orig_w(6)=wcorr6
4206       orig_w(7)=wel_loc
4207       orig_w(8)=wturn3
4208       orig_w(9)=wturn4
4209       orig_w(10)=wturn6
4210       orig_w(11)=wang
4211       orig_w(13)=wtor
4212       orig_w(14)=wtor_d
4213       orig_w(15)=wvdwpp
4214
4215       wscp=0.D0
4216       welec=0.D0
4217       wcorr=0.D0
4218       wcorr5=0.D0
4219       wcorr6=0.D0
4220       wel_loc=0.D0
4221       wturn3=0.D0
4222       wturn4=0.D0
4223       wturn6=0.D0
4224       wang=0.D0
4225       wtor=0.D0
4226       wtor_d=0.D0
4227       wvdwpp=0.D0
4228
4229 !     Make sure n_start, n_end are within proper range
4230       if (n_start.lt.2) n_start=2
4231       if (n_end.gt.nres-1) n_end=nres-1
4232 !rc      if (n_start.lt.n_end) then
4233       if (n_start.gt.n_end) then
4234         n_start=2
4235         n_end=nres-1
4236       endif
4237
4238 !     Save the initial values of energy and coordinates
4239 !d      call chainbuild
4240 !d      call etotal(energy)
4241 !d      write (iout,*) 'start sc ene',energy(0)
4242 !d      call enerprint(energy(0))
4243 !rc      etot=energy(0)
4244        n_fun=0
4245 !rc      orig_e=etot
4246 !rc      cur_e=orig_e
4247 !rc      do i=2,nres-1
4248 !rc        cur_alph(i)=alph(i)
4249 !rc        cur_omeg(i)=omeg(i)
4250 !rc      enddo
4251
4252 !t      wtime=MPI_WTIME()
4253 !     Try (one by one) all specified residues, starting from a
4254 !     random position in sequence
4255 !     Stop early if the energy has decreased by at least e_drop
4256       n_tot=n_end-n_start+1
4257       n_first=iran_num(0,n_tot-1)
4258       n_steps=0
4259       n=0
4260 !rc      do while (n.lt.n_tot .and. orig_e-etot.lt.e_drop)
4261       do while (n.lt.n_tot)
4262         n_cur=n_start+mod(n_first+n,n_tot)
4263         call single_sc_move(n_cur,n_maxtry,e_drop,&
4264              n_steps,n_fun,etot)
4265 !elwrite(iout,*) "after msingle sc_move etot= ", etot
4266 !     If a lower energy was found, update the current structure...
4267 !rc        if (etot.lt.cur_e) then
4268 !rc          cur_e=etot
4269 !rc          do i=2,nres-1
4270 !rc            cur_alph(i)=alph(i)
4271 !rc            cur_omeg(i)=omeg(i)
4272 !rc          enddo
4273 !rc        else
4274 !     ...else revert to the previous one
4275 !rc          etot=cur_e
4276 !rc          do i=2,nres-1
4277 !rc            alph(i)=cur_alph(i)
4278 !rc            omeg(i)=cur_omeg(i)
4279 !rc          enddo
4280 !rc        endif
4281         n=n+1
4282 !d
4283 !d      call chainbuild
4284 !d      call etotal(energy)
4285 !d      print *,'running',n,energy(0)
4286       enddo
4287
4288 !d      call chainbuild
4289 !d      call etotal(energy)
4290 !d      write (iout,*) 'end   sc ene',energy(0)
4291
4292 !     Put the original weights back to calculate the full energy
4293       wscp=orig_w(2)
4294       welec=orig_w(3)
4295       wcorr=orig_w(4)
4296       wcorr5=orig_w(5)
4297       wcorr6=orig_w(6)
4298       wel_loc=orig_w(7)
4299       wturn3=orig_w(8)
4300       wturn4=orig_w(9)
4301       wturn6=orig_w(10)
4302       wang=orig_w(11)
4303       wtor=orig_w(13)
4304       wtor_d=orig_w(14)
4305       wvdwpp=orig_w(15)
4306
4307 !rc      n_fun=n_fun+1
4308 !t      write (iout,*) 'sc_local time= ',MPI_WTIME()-wtime
4309       return
4310       end subroutine sc_move
4311 !-----------------------------------------------------------------------------
4312       subroutine single_sc_move(res_pick,n_maxtry,e_drop,n_steps,n_fun,e_sc)
4313
4314 !     Perturb one side-chain (res_pick) and minimize the
4315 !     neighbouring region, keeping all CA's and non-neighbouring
4316 !     side-chains fixed
4317 !     Try until e_drop energy improvement is achieved, or n_maxtry
4318 !     attempts have been made
4319 !     At the start, e_sc should contain the side-chain-only energy(0)
4320 !     nsteps and nfun for this move are ADDED to n_steps and n_fun
4321 !rc      implicit none
4322       use energy, only: esc
4323       use geometry, only:dist
4324 !     Includes
4325 !      implicit real*8 (a-h,o-z)
4326 !      include 'DIMENSIONS'
4327 !      include 'COMMON.VAR'
4328 !      include 'COMMON.INTERACT'
4329 !      include 'COMMON.CHAIN'
4330 !      include 'COMMON.MINIM'
4331 !      include 'COMMON.FFIELD'
4332 !      include 'COMMON.IOUNITS'
4333
4334 !     External functions
4335 !el      double precision dist
4336 !el      external dist
4337
4338 !     Input arguments
4339       integer :: res_pick,n_maxtry
4340       real(kind=8) :: e_drop
4341
4342 !     Input/Output arguments
4343       integer :: n_steps,n_fun
4344       real(kind=8) :: e_sc
4345
4346 !     Local variables
4347       logical :: fail
4348       integer :: i,j
4349       integer :: nres_moved
4350       integer :: iretcode,loc_nfun,orig_maxfun,n_try
4351       real(kind=8) :: sc_dist,sc_dist_cutoff
4352 !      real(kind=8) :: energy_(0:n_ene)
4353       real(kind=8) :: evdw,escloc,orig_e,cur_e
4354       real(kind=8) :: cur_alph(2:nres-1),cur_omeg(2:nres-1)
4355       real(kind=8) :: var(6*nres)       !(maxvar) (maxvar=6*maxres)
4356
4357       real(kind=8) :: orig_theta(1:nres),orig_phi(1:nres),&
4358            orig_alph(1:nres),orig_omeg(1:nres)
4359
4360 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4361 !     Define what is meant by "neighbouring side-chain"
4362       sc_dist_cutoff=5.0D0
4363
4364 !     Don't do glycine or ends
4365       i=itype(res_pick)
4366       if (i.eq.10 .or. i.eq.ntyp1) return
4367
4368 !     Freeze everything (later will relax only selected side-chains)
4369       mask_r=.true.
4370       do i=1,nres
4371         mask_phi(i)=0
4372         mask_theta(i)=0
4373         mask_side(i)=0
4374       enddo
4375
4376 !     Find the neighbours of the side-chain to move
4377 !     and save initial variables
4378 !rc      orig_e=e_sc
4379 !rc      cur_e=orig_e
4380       nres_moved=0
4381       do i=2,nres-1
4382 !     Don't do glycine (itype(j)==10)
4383         if (itype(i).ne.10) then
4384           sc_dist=dist(nres+i,nres+res_pick)
4385         else
4386           sc_dist=sc_dist_cutoff
4387         endif
4388         if (sc_dist.lt.sc_dist_cutoff) then
4389           nres_moved=nres_moved+1
4390           mask_side(i)=1
4391           cur_alph(i)=alph(i)
4392           cur_omeg(i)=omeg(i)
4393         endif
4394       enddo
4395
4396       call chainbuild
4397       call egb1(evdw)
4398       call esc(escloc)
4399 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4400 !elwrite(iout,*) "in sinle wsc=",wsc,"evdw",evdw,"wscloc",wscloc,"escloc",escloc
4401       e_sc=wsc*evdw+wscloc*escloc
4402 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4403 !d      call etotal(energy)
4404 !d      print *,'new       ',(energy(k),k=0,n_ene)
4405       orig_e=e_sc
4406       cur_e=orig_e
4407
4408       n_try=0
4409       do while (n_try.lt.n_maxtry .and. orig_e-cur_e.lt.e_drop)
4410 !     Move the selected residue (don't worry if it fails)
4411         call gen_side(iabs(itype(res_pick)),theta(res_pick+1),&
4412              alph(res_pick),omeg(res_pick),fail)
4413
4414 !     Minimize the side-chains starting from the new arrangement
4415         call geom_to_var(nvar,var)
4416         orig_maxfun=maxfun
4417         maxfun=7
4418
4419 !rc        do i=1,nres
4420 !rc          orig_theta(i)=theta(i)
4421 !rc          orig_phi(i)=phi(i)
4422 !rc          orig_alph(i)=alph(i)
4423 !rc          orig_omeg(i)=omeg(i)
4424 !rc        enddo
4425
4426 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4427         call minimize_sc1(e_sc,var,iretcode,loc_nfun)
4428         
4429 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4430 !v        write(*,'(2i3,2f12.5,2i3)') 
4431 !v     &       res_pick,nres_moved,orig_e,e_sc-cur_e,
4432 !v     &       iretcode,loc_nfun
4433
4434 !$$$        if (iretcode.eq.8) then
4435 !$$$          write(iout,*)'Coordinates just after code 8'
4436 !$$$          call chainbuild
4437 !$$$          call all_varout
4438 !$$$          call flush(iout)
4439 !$$$          do i=1,nres
4440 !$$$            theta(i)=orig_theta(i)
4441 !$$$            phi(i)=orig_phi(i)
4442 !$$$            alph(i)=orig_alph(i)
4443 !$$$            omeg(i)=orig_omeg(i)
4444 !$$$          enddo
4445 !$$$          write(iout,*)'Coordinates just before code 8'
4446 !$$$          call chainbuild
4447 !$$$          call all_varout
4448 !$$$          call flush(iout)
4449 !$$$        endif
4450
4451         n_fun=n_fun+loc_nfun
4452         maxfun=orig_maxfun
4453         call var_to_geom(nvar,var)
4454
4455 !     If a lower energy was found, update the current structure...
4456         if (e_sc.lt.cur_e) then
4457 !v              call chainbuild
4458 !v              call etotal(energy)
4459 !d              call egb1(evdw)
4460 !d              call esc(escloc)
4461 !d              e_sc1=wsc*evdw+wscloc*escloc
4462 !d              print *,'     new',e_sc1,energy(0)
4463 !v              print *,'new       ',energy(0)
4464 !d              call enerprint(energy(0))
4465           cur_e=e_sc
4466           do i=2,nres-1
4467             if (mask_side(i).eq.1) then
4468               cur_alph(i)=alph(i)
4469               cur_omeg(i)=omeg(i)
4470             endif
4471           enddo
4472         else
4473 !     ...else revert to the previous one
4474           e_sc=cur_e
4475           do i=2,nres-1
4476             if (mask_side(i).eq.1) then
4477               alph(i)=cur_alph(i)
4478               omeg(i)=cur_omeg(i)
4479             endif
4480           enddo
4481         endif
4482         n_try=n_try+1
4483
4484       enddo
4485       n_steps=n_steps+n_try
4486
4487 !     Reset the minimization mask_r to false
4488       mask_r=.false.
4489
4490       return
4491       end subroutine single_sc_move
4492 !-----------------------------------------------------------------------------
4493       subroutine sc_minimize(etot,iretcode,nfun)
4494
4495 !     Minimizes side-chains only, leaving backbone frozen
4496 !rc      implicit none
4497       use energy, only: etotal
4498 !     Includes
4499 !      implicit real*8 (a-h,o-z)
4500 !      include 'DIMENSIONS'
4501 !      include 'COMMON.VAR'
4502 !      include 'COMMON.CHAIN'
4503 !      include 'COMMON.FFIELD'
4504
4505 !     Output arguments
4506       real(kind=8) :: etot
4507       integer :: iretcode,nfun
4508
4509 !     Local variables
4510       integer :: i
4511       real(kind=8) :: orig_w(0:n_ene),energy_(0:n_ene)
4512       real(kind=8) :: var(6*nres)       !(maxvar)(maxvar=6*maxres)
4513
4514
4515 !     Set non side-chain weights to zero (minimization is faster)
4516 !     NOTE: e(2) does not actually depend on the side-chain, only CA
4517       orig_w(2)=wscp
4518       orig_w(3)=welec
4519       orig_w(4)=wcorr
4520       orig_w(5)=wcorr5
4521       orig_w(6)=wcorr6
4522       orig_w(7)=wel_loc
4523       orig_w(8)=wturn3
4524       orig_w(9)=wturn4
4525       orig_w(10)=wturn6
4526       orig_w(11)=wang
4527       orig_w(13)=wtor
4528       orig_w(14)=wtor_d
4529
4530       wscp=0.D0
4531       welec=0.D0
4532       wcorr=0.D0
4533       wcorr5=0.D0
4534       wcorr6=0.D0
4535       wel_loc=0.D0
4536       wturn3=0.D0
4537       wturn4=0.D0
4538       wturn6=0.D0
4539       wang=0.D0
4540       wtor=0.D0
4541       wtor_d=0.D0
4542
4543 !     Prepare to freeze backbone
4544       do i=1,nres
4545         mask_phi(i)=0
4546         mask_theta(i)=0
4547         mask_side(i)=1
4548       enddo
4549
4550 !     Minimize the side-chains
4551       mask_r=.true.
4552       call geom_to_var(nvar,var)
4553       call minimize(etot,var,iretcode,nfun)
4554       call var_to_geom(nvar,var)
4555       mask_r=.false.
4556
4557 !     Put the original weights back and calculate the full energy
4558       wscp=orig_w(2)
4559       welec=orig_w(3)
4560       wcorr=orig_w(4)
4561       wcorr5=orig_w(5)
4562       wcorr6=orig_w(6)
4563       wel_loc=orig_w(7)
4564       wturn3=orig_w(8)
4565       wturn4=orig_w(9)
4566       wturn6=orig_w(10)
4567       wang=orig_w(11)
4568       wtor=orig_w(13)
4569       wtor_d=orig_w(14)
4570
4571       call chainbuild
4572       call etotal(energy_)
4573       etot=energy_(0)
4574
4575       return
4576       end subroutine sc_minimize
4577 !-----------------------------------------------------------------------------
4578       subroutine minimize_sc1(etot,x,iretcode,nfun)
4579
4580       use energy, only: func,gradient,fdum,etotal,enerprint
4581       use comm_srutu
4582 !      implicit real*8 (a-h,o-z)
4583 !      include 'DIMENSIONS'
4584       integer,parameter :: liv=60
4585       integer :: iretcode,nfun
4586 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
4587 !      include 'COMMON.IOUNITS'
4588 !      include 'COMMON.VAR'
4589 !      include 'COMMON.GEO'
4590 !      include 'COMMON.MINIM'
4591 !el      integer :: icall
4592 !el      common /srutu/ icall
4593       integer,dimension(liv) :: iv                                               
4594       real(kind=8) :: minval    !,v(1:77+(6*nres)*(6*nres+17)/2)        !(1:lv)
4595       real(kind=8),dimension(6*nres) :: x,d,xx  !(maxvar) (maxvar=6*maxres)
4596       real(kind=8) :: energia(0:n_ene)
4597 !el      real(kind=8) :: fdum
4598 !      external gradient,fdum   !func,
4599 !      external func_restr1,grad_restr1
4600       logical :: not_done,change,reduce 
4601 !el      common /przechowalnia/ v
4602
4603       integer :: nvar_restr,lv,i,j
4604       integer :: idum(1)
4605       real(kind=8) :: rdum(1),etot      !,fdum
4606
4607       lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
4608       if (.not. allocated(v)) allocate(v(1:lv))
4609
4610       call deflt(2,iv,liv,lv,v)                                         
4611 ! 12 means fresh start, dont call deflt                                 
4612       iv(1)=12                                                          
4613 ! max num of fun calls                                                  
4614       if (maxfun.eq.0) maxfun=500
4615       iv(17)=maxfun
4616 ! max num of iterations                                                 
4617       if (maxmin.eq.0) maxmin=1000
4618       iv(18)=maxmin
4619 ! controls output                                                       
4620       iv(19)=2                                                          
4621 ! selects output unit                                                   
4622 !     iv(21)=iout                                                       
4623       iv(21)=0
4624 ! 1 means to print out result                                           
4625       iv(22)=0                                                          
4626 ! 1 means to print out summary stats                                    
4627       iv(23)=0                                                          
4628 ! 1 means to print initial x and d                                      
4629       iv(24)=0                                                          
4630 ! min val for v(radfac) default is 0.1                                  
4631       v(24)=0.1D0                                                       
4632 ! max val for v(radfac) default is 4.0                                  
4633       v(25)=2.0D0                                                       
4634 !     v(25)=4.0D0                                                       
4635 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
4636 ! the sumsl default is 0.1                                              
4637       v(26)=0.1D0
4638 ! false conv if (act fnctn decrease) .lt. v(34)                         
4639 ! the sumsl default is 100*machep                                       
4640       v(34)=v(34)/100.0D0                                               
4641 ! absolute convergence                                                  
4642       if (tolf.eq.0.0D0) tolf=1.0D-4
4643       v(31)=tolf
4644 ! relative convergence                                                  
4645       if (rtolf.eq.0.0D0) rtolf=1.0D-4
4646       v(32)=rtolf
4647 ! controls initial step size                                            
4648        v(35)=1.0D-1                                                    
4649 ! large vals of d correspond to small components of step                
4650       do i=1,nphi
4651         d(i)=1.0D-1
4652       enddo
4653       do i=nphi+1,nvar
4654         d(i)=1.0D-1
4655       enddo
4656 !elmask_r=.false.
4657       IF (mask_r) THEN
4658        call x2xx(x,xx,nvar_restr)
4659        call sumsl(nvar_restr,d,xx,func_restr1,grad_restr1,&
4660                           iv,liv,lv,v,idum,rdum,fdum)      
4661        call xx2x(x,xx)
4662       ELSE
4663        call sumsl(nvar,d,x,func,gradient,iv,liv,lv,v,idum,rdum,fdum)      
4664       ENDIF
4665 !el---------------------
4666 !      write (iout,'(/a)') &
4667 !        "Cartesian coordinates of the reference structure after SUMSL"
4668 !      write (iout,'(a,3(3x,a5),5x,3(3x,a5))') &
4669 !       "Residue","X(CA)","Y(CA)","Z(CA)","X(SC)","Y(SC)","Z(SC)"
4670 !      do i=1,nres
4671 !        write (iout,'(a3,1x,i3,3f8.3,5x,3f8.3)') &
4672 !          restyp(itype(i)),i,(c(j,i),j=1,3),&
4673 !          (c(j,i+nres),j=1,3)
4674 !      enddo
4675 !      call etotal(energia)
4676 !      call enerprint(energia)
4677 !el----------------------------
4678       etot=v(10)                                                      
4679       iretcode=iv(1)
4680       nfun=iv(6)
4681
4682       return
4683       end subroutine minimize_sc1
4684 !-----------------------------------------------------------------------------
4685       subroutine func_restr1(n,x,nf,f,uiparm,urparm,ufparm)
4686
4687       use comm_chu
4688       use energy, only: zerograd,esc,sc_grad
4689 !      implicit real*8 (a-h,o-z)
4690 !      include 'DIMENSIONS'
4691 !      include 'COMMON.DERIV'
4692 !      include 'COMMON.IOUNITS'
4693 !      include 'COMMON.GEO'
4694 !      include 'COMMON.FFIELD'
4695 !      include 'COMMON.INTERACT'
4696 !      include 'COMMON.TIME1'
4697       integer :: n,nf,i,j
4698 !el      common /chuju/ jjj
4699       real(kind=8) :: energia(0:n_ene),evdw,escloc
4700       real(kind=8) :: e1,e2,f
4701       real(kind=8),external :: ufparm                                                   
4702       integer :: uiparm(1)                                                 
4703       real(kind=8) :: urparm(1)                                                    
4704       real(kind=8),dimension(6*nres) :: x       !(maxvar) (maxvar=6*maxres)
4705       nfl=nf
4706       icg=mod(nf,2)+1
4707
4708 #ifdef OSF
4709 !     Intercept NaNs in the coordinates, before calling etotal
4710       x_sum=0.D0
4711       do i=1,n
4712         x_sum=x_sum+x(i)
4713       enddo
4714       FOUND_NAN=.false.
4715       if (x_sum.ne.x_sum) then
4716         write(iout,*)"   *** func_restr1 : Found NaN in coordinates"
4717         f=1.0D+73
4718         FOUND_NAN=.true.
4719         return
4720       endif
4721 #endif
4722
4723       call var_to_geom_restr(n,x)
4724       call zerograd
4725       call chainbuild
4726 !d    write (iout,*) 'ETOTAL called from FUNC'
4727       call egb1(evdw)
4728       call esc(escloc)
4729       f=wsc*evdw+wscloc*escloc
4730 !d      call etotal(energia(0))
4731 !d      f=wsc*energia(1)+wscloc*energia(12)
4732 !d      print *,f,evdw,escloc,energia(0)
4733 !
4734 ! Sum up the components of the Cartesian gradient.
4735 !
4736       do i=1,nct
4737         do j=1,3
4738           gradx(j,i,icg)=wsc*gvdwx(j,i)
4739         enddo
4740       enddo
4741
4742       return
4743       end subroutine func_restr1
4744 !-----------------------------------------------------------------------------
4745       subroutine grad_restr1(n,x,nf,g,uiparm,urparm,ufparm)
4746
4747       use energy, only: cartder,zerograd,esc,sc_grad
4748 !      implicit real*8 (a-h,o-z)
4749 !      include 'DIMENSIONS'
4750 !      include 'COMMON.CHAIN'
4751 !      include 'COMMON.DERIV'
4752 !      include 'COMMON.VAR'
4753 !      include 'COMMON.INTERACT'
4754 !      include 'COMMON.FFIELD'
4755 !      include 'COMMON.IOUNITS'
4756 !el      external ufparm
4757       integer :: i,j,k,ind,n,nf,uiparm(1)
4758       real(kind=8) :: f,urparm(1)
4759       real(kind=8),dimension(6*nres) :: x,g     !(maxvar) (maxvar=6*maxres)
4760       integer :: ig,igall,ij
4761       real(kind=8) :: gphii,gthetai,galphai,gomegai
4762       real(kind=8),external :: ufparm
4763
4764       icg=mod(nf,2)+1
4765       if (nf-nfl+1) 20,30,40
4766    20 call func_restr1(n,x,nf,f,uiparm,urparm,ufparm)
4767 !     write (iout,*) 'grad 20'
4768       if (nf.eq.0) return
4769       goto 40
4770    30 call var_to_geom_restr(n,x)
4771       call chainbuild 
4772 !
4773 ! Evaluate the derivatives of virtual bond lengths and SC vectors in variables.
4774 !
4775    40 call cartder
4776 !
4777 ! Convert the Cartesian gradient into internal-coordinate gradient.
4778 !
4779
4780       ig=0
4781       ind=nres-2                                                                    
4782       do i=2,nres-2                
4783        IF (mask_phi(i+2).eq.1) THEN                                             
4784         gphii=0.0D0                                                             
4785         do j=i+1,nres-1                                                         
4786           ind=ind+1                                 
4787           do k=1,3                                                              
4788             gphii=gphii+dcdv(k+3,ind)*gradc(k,j,icg)                            
4789             gphii=gphii+dxdv(k+3,ind)*gradx(k,j,icg)                           
4790           enddo                                                                 
4791         enddo                                                                   
4792         ig=ig+1
4793         g(ig)=gphii
4794        ELSE
4795         ind=ind+nres-1-i
4796        ENDIF
4797       enddo                                        
4798
4799
4800       ind=0
4801       do i=1,nres-2
4802        IF (mask_theta(i+2).eq.1) THEN
4803         ig=ig+1
4804         gthetai=0.0D0
4805         do j=i+1,nres-1
4806           ind=ind+1
4807           do k=1,3
4808             gthetai=gthetai+dcdv(k,ind)*gradc(k,j,icg)
4809             gthetai=gthetai+dxdv(k,ind)*gradx(k,j,icg)
4810           enddo
4811         enddo
4812         g(ig)=gthetai
4813        ELSE
4814         ind=ind+nres-1-i
4815        ENDIF
4816       enddo
4817
4818       do i=2,nres-1
4819         if (itype(i).ne.10) then
4820          IF (mask_side(i).eq.1) THEN
4821           ig=ig+1
4822           galphai=0.0D0
4823           do k=1,3
4824             galphai=galphai+dxds(k,i)*gradx(k,i,icg)
4825           enddo
4826           g(ig)=galphai
4827          ENDIF
4828         endif
4829       enddo
4830
4831       
4832       do i=2,nres-1
4833         if (itype(i).ne.10) then
4834          IF (mask_side(i).eq.1) THEN
4835           ig=ig+1
4836           gomegai=0.0D0
4837           do k=1,3
4838             gomegai=gomegai+dxds(k+3,i)*gradx(k,i,icg)
4839           enddo
4840           g(ig)=gomegai
4841          ENDIF
4842         endif
4843       enddo
4844
4845 !
4846 ! Add the components corresponding to local energy terms.
4847 !
4848
4849       ig=0
4850       igall=0
4851       do i=4,nres
4852         igall=igall+1
4853         if (mask_phi(i).eq.1) then
4854           ig=ig+1
4855           g(ig)=g(ig)+gloc(igall,icg)
4856         endif
4857       enddo
4858
4859       do i=3,nres
4860         igall=igall+1
4861         if (mask_theta(i).eq.1) then
4862           ig=ig+1
4863           g(ig)=g(ig)+gloc(igall,icg)
4864         endif
4865       enddo
4866      
4867       do ij=1,2
4868       do i=2,nres-1
4869         if (itype(i).ne.10) then
4870           igall=igall+1
4871           if (mask_side(i).eq.1) then
4872             ig=ig+1
4873             g(ig)=g(ig)+gloc(igall,icg)
4874           endif
4875         endif
4876       enddo
4877       enddo
4878
4879 !d      do i=1,ig
4880 !d        write (iout,'(a2,i5,a3,f25.8)') 'i=',i,' g=',g(i)
4881 !d      enddo
4882       return
4883       end subroutine  grad_restr1
4884 !-----------------------------------------------------------------------------
4885       subroutine egb1(evdw)
4886 !
4887 ! This subroutine calculates the interaction energy of nonbonded side chains
4888 ! assuming the Gay-Berne potential of interaction.
4889 !
4890       use calc_data
4891       use energy, only: sc_grad
4892 !      use control, only:stopx
4893 !      implicit real*8 (a-h,o-z)
4894 !      include 'DIMENSIONS'
4895 !      include 'COMMON.GEO'
4896 !      include 'COMMON.VAR'
4897 !      include 'COMMON.LOCAL'
4898 !      include 'COMMON.CHAIN'
4899 !      include 'COMMON.DERIV'
4900 !      include 'COMMON.NAMES'
4901 !      include 'COMMON.INTERACT'
4902 !      include 'COMMON.IOUNITS'
4903 !      include 'COMMON.CALC'
4904 !      include 'COMMON.CONTROL'
4905       logical :: lprn
4906       real(kind=8) :: evdw
4907 !el local variables
4908       integer :: iint,ind,itypi,itypi1,itypj
4909       real(kind=8) :: xi,yi,zi,rrij,sig,sig0ij,rij_shift,fac,e1,e2,&
4910                   sigm,epsi
4911 !elwrite(iout,*) "check evdw"
4912 !     print *,'Entering EGB nnt=',nnt,' nct=',nct,' expon=',expon
4913       evdw=0.0D0
4914       lprn=.false.
4915 !     if (icall.eq.0) lprn=.true.
4916       ind=0
4917       do i=iatsc_s,iatsc_e
4918
4919         itypi=iabs(itype(i))
4920         itypi1=iabs(itype(i+1))
4921         xi=c(1,nres+i)
4922         yi=c(2,nres+i)
4923         zi=c(3,nres+i)
4924         dxi=dc_norm(1,nres+i)
4925         dyi=dc_norm(2,nres+i)
4926         dzi=dc_norm(3,nres+i)
4927         dsci_inv=dsc_inv(itypi)
4928 !elwrite(iout,*) itypi,itypi1,xi,yi,zi,dxi,dyi,dzi,dsci_inv
4929 !
4930 ! Calculate SC interaction energy.
4931 !
4932         do iint=1,nint_gr(i)
4933           do j=istart(i,iint),iend(i,iint)
4934           IF (mask_side(j).eq.1.or.mask_side(i).eq.1) THEN
4935             ind=ind+1
4936             itypj=iabs(itype(j))
4937             dscj_inv=dsc_inv(itypj)
4938             sig0ij=sigma(itypi,itypj)
4939             chi1=chi(itypi,itypj)
4940             chi2=chi(itypj,itypi)
4941             chi12=chi1*chi2
4942             chip1=chip(itypi)
4943             chip2=chip(itypj)
4944             chip12=chip1*chip2
4945             alf1=alp(itypi)
4946             alf2=alp(itypj)
4947             alf12=0.5D0*(alf1+alf2)
4948 ! For diagnostics only!!!
4949 !           chi1=0.0D0
4950 !           chi2=0.0D0
4951 !           chi12=0.0D0
4952 !           chip1=0.0D0
4953 !           chip2=0.0D0
4954 !           chip12=0.0D0
4955 !           alf1=0.0D0
4956 !           alf2=0.0D0
4957 !           alf12=0.0D0
4958             xj=c(1,nres+j)-xi
4959             yj=c(2,nres+j)-yi
4960             zj=c(3,nres+j)-zi
4961             dxj=dc_norm(1,nres+j)
4962             dyj=dc_norm(2,nres+j)
4963             dzj=dc_norm(3,nres+j)
4964             rrij=1.0D0/(xj*xj+yj*yj+zj*zj)
4965             rij=dsqrt(rrij)
4966 ! Calculate angle-dependent terms of energy and contributions to their
4967 ! derivatives.
4968             call sc_angular
4969             sigsq=1.0D0/sigsq
4970             sig=sig0ij*dsqrt(sigsq)
4971             rij_shift=1.0D0/rij-sig+sig0ij
4972 ! I hate to put IF's in the loops, but here don't have another choice!!!!
4973             if (rij_shift.le.0.0D0) then
4974               evdw=1.0D20
4975 !d              write (iout,'(2(a3,i3,2x),17(0pf7.3))') &
4976 !d              restyp(itypi),i,restyp(itypj),j, &
4977 !d              rij_shift,1.0D0/rij,sig,sig0ij,sigsq,1-dsqrt(sigsq)
4978               return
4979             endif
4980             sigder=-sig*sigsq
4981 !---------------------------------------------------------------
4982             rij_shift=1.0D0/rij_shift 
4983             fac=rij_shift**expon
4984             e1=fac*fac*aa(itypi,itypj)
4985             e2=fac*bb(itypi,itypj)
4986             evdwij=eps1*eps2rt*eps3rt*(e1+e2)
4987             eps2der=evdwij*eps3rt
4988             eps3der=evdwij*eps2rt
4989             evdwij=evdwij*eps2rt*eps3rt
4990             evdw=evdw+evdwij
4991             if (lprn) then
4992             sigm=dabs(aa(itypi,itypj)/bb(itypi,itypj))**(1.0D0/6.0D0)
4993             epsi=bb(itypi,itypj)**2/aa(itypi,itypj)
4994 !d            write (iout,'(2(a3,i3,2x),17(0pf7.3))') &
4995 !d              restyp(itypi),i,restyp(itypj),j, &
4996 !d              epsi,sigm,chi1,chi2,chip1,chip2, &
4997 !d              eps1,eps2rt**2,eps3rt**2,sig,sig0ij, &
4998 !d              om1,om2,om12,1.0D0/rij,1.0D0/rij_shift, &
4999 !d              evdwij
5000             endif
5001
5002             if (energy_dec) write (iout,'(a6,2i5,0pf7.3)') &
5003                               'evdw',i,j,evdwij
5004
5005 ! Calculate gradient components.
5006             e1=e1*eps1*eps2rt**2*eps3rt**2
5007             fac=-expon*(e1+evdwij)*rij_shift
5008             sigder=fac*sigder
5009             fac=rij*fac
5010 ! Calculate the radial part of the gradient
5011             gg(1)=xj*fac
5012             gg(2)=yj*fac
5013             gg(3)=zj*fac
5014 ! Calculate angular part of the gradient.
5015
5016 !elwrite(iout,*) evdw
5017             call sc_grad
5018 !elwrite(iout,*) "evdw=",evdw,j,iint,i
5019           ENDIF
5020 !elwrite(iout,*) evdw
5021           enddo      ! j
5022 !elwrite(iout,*) evdw
5023         enddo        ! iint
5024 !elwrite(iout,*) evdw
5025       enddo          ! i
5026 !elwrite(iout,*) evdw,i
5027       end subroutine egb1
5028 !-----------------------------------------------------------------------------
5029 ! sumsld.f
5030 !-----------------------------------------------------------------------------
5031       subroutine sumsl(n,d,x,calcf,calcg,iv,liv,lv,v,uiparm,urparm,ufparm)
5032 !
5033 !  ***  minimize general unconstrained objective function using   ***
5034 !  ***  analytic gradient and hessian approx. from secant update  ***
5035 !
5036 !      use control
5037       integer :: n, liv, lv
5038       integer :: iv(liv), uiparm(1)
5039       real(kind=8) :: d(n), x(n), v(lv), urparm(1)
5040       real(kind=8),external :: ufparm !funtion name as an argument
5041
5042 !     dimension v(71 + n*(n+15)/2), uiparm(*), urparm(*)
5043       external :: calcf, calcg !subroutine name as an argument
5044 !
5045 !  ***  purpose  ***
5046 !
5047 !        this routine interacts with subroutine  sumit  in an attempt
5048 !     to find an n-vector  x*  that minimizes the (unconstrained)
5049 !     objective function computed by  calcf.  (often the  x*  found is
5050 !     a local minimizer rather than a global one.)
5051 !
5052 !--------------------------  parameter usage  --------------------------
5053 !
5054 ! n........ (input) the number of variables on which  f  depends, i.e.,
5055 !                  the number of components in  x.
5056 ! d........ (input/output) a scale vector such that  d(i)*x(i),
5057 !                  i = 1,2,...,n,  are all in comparable units.
5058 !                  d can strongly affect the behavior of sumsl.
5059 !                  finding the best choice of d is generally a trial-
5060 !                  and-error process.  choosing d so that d(i)*x(i)
5061 !                  has about the same value for all i often works well.
5062 !                  the defaults provided by subroutine deflt (see i
5063 !                  below) require the caller to supply d.
5064 ! x........ (input/output) before (initially) calling sumsl, the call-
5065 !                  er should set  x  to an initial guess at  x*.  when
5066 !                  sumsl returns,  x  contains the best point so far
5067 !                  found, i.e., the one that gives the least value so
5068 !                  far seen for  f(x).
5069 ! calcf.... (input) a subroutine that, given x, computes f(x).  calcf
5070 !                  must be declared external in the calling program.
5071 !                  it is invoked by
5072 !                       call calcf(n, x, nf, f, uiparm, urparm, ufparm)
5073 !                  when calcf is called, nf is the invocation
5074 !                  count for calcf.  nf is included for possible use
5075 !                  with calcg.  if x is out of bounds (e.g., if it
5076 !                  would cause overflow in computing f(x)), then calcf
5077 !                  should set nf to 0.  this will cause a shorter step
5078 !                  to be attempted.  (if x is in bounds, then calcf
5079 !                  should not change nf.)  the other parameters are as
5080 !                  described above and below.  calcf should not change
5081 !                  n, p, or x.
5082 ! calcg.... (input) a subroutine that, given x, computes g(x), the gra-
5083 !                  dient of f at x.  calcg must be declared external in
5084 !                  the calling program.  it is invoked by
5085 !                       call calcg(n, x, nf, g, uiparm, urparm, ufaprm)
5086 !                  when calcg is called, nf is the invocation
5087 !                  count for calcf at the time f(x) was evaluated.  the
5088 !                  x passed to calcg is usually the one passed to calcf
5089 !                  on either its most recent invocation or the one
5090 !                  prior to it.  if calcf saves intermediate results
5091 !                  for use by calcg, then it is possible to tell from
5092 !                  nf whether they are valid for the current x (or
5093 !                  which copy is valid if two copies are kept).  if g
5094 !                  cannot be computed at x, then calcg should set nf to
5095 !                  0.  in this case, sumsl will return with iv(1) = 65.
5096 !                  (if g can be computed at x, then calcg should not
5097 !                  changed nf.)  the other parameters to calcg are as
5098 !                  described above and below.  calcg should not change
5099 !                  n or x.
5100 ! iv....... (input/output) an integer value array of length liv (see
5101 !                  below) that helps control the sumsl algorithm and
5102 !                  that is used to store various intermediate quanti-
5103 !                  ties.  of particular interest are the initialization/
5104 !                  return code iv(1) and the entries in iv that control
5105 !                  printing and limit the number of iterations and func-
5106 !                  tion evaluations.  see the section on iv input
5107 !                  values below.
5108 ! liv...... (input) length of iv array.  must be at least 60.  if li
5109 !                  is too small, then sumsl returns with iv(1) = 15.
5110 !                  when sumsl returns, the smallest allowed value of
5111 !                  liv is stored in iv(lastiv) -- see the section on
5112 !                  iv output values below.  (this is intended for use
5113 !                  with extensions of sumsl that handle constraints.)
5114 ! lv....... (input) length of v array.  must be at least 71+n*(n+15)/2.
5115 !                  (at least 77+n*(n+17)/2 for smsno, at least
5116 !                  78+n*(n+12) for humsl).  if lv is too small, then
5117 !                  sumsl returns with iv(1) = 16.  when sumsl returns,
5118 !                  the smallest allowed value of lv is stored in
5119 !                  iv(lastv) -- see the section on iv output values
5120 !                  below.
5121 ! v........ (input/output) a floating-point value array of length l
5122 !                  (see below) that helps control the sumsl algorithm
5123 !                  and that is used to store various intermediate
5124 !                  quantities.  of particular interest are the entries
5125 !                  in v that limit the length of the first step
5126 !                  attempted (lmax0) and specify convergence tolerances
5127 !                  (afctol, lmaxs, rfctol, sctol, xctol, xftol).
5128 ! uiparm... (input) user integer parameter array passed without change
5129 !                  to calcf and calcg.
5130 ! urparm... (input) user floating-point parameter array passed without
5131 !                  change to calcf and calcg.
5132 ! ufparm... (input) user external subroutine or function passed without
5133 !                  change to calcf and calcg.
5134 !
5135 !  ***  iv input values (from subroutine deflt)  ***
5136 !
5137 ! iv(1)...  on input, iv(1) should have a value between 0 and 14......
5138 !             0 and 12 mean this is a fresh start.  0 means that
5139 !                  deflt(2, iv, liv, lv, v)
5140 !             is to be called to provide all default values to iv and
5141 !             v.  12 (the value that deflt assigns to iv(1)) means the
5142 !             caller has already called deflt and has possibly changed
5143 !             some iv and/or v entries to non-default values.
5144 !             13 means deflt has been called and that sumsl (and
5145 !             sumit) should only do their storage allocation.  that is,
5146 !             they should set the output components of iv that tell
5147 !             where various subarrays arrays of v begin, such as iv(g)
5148 !             (and, for humsl and humit only, iv(dtol)), and return.
5149 !             14 means that a storage has been allocated (by a call
5150 !             with iv(1) = 13) and that the algorithm should be
5151 !             started.  when called with iv(1) = 13, sumsl returns
5152 !             iv(1) = 14 unless liv or lv is too small (or n is not
5153 !             positive).  default = 12.
5154 ! iv(inith).... iv(25) tells whether the hessian approximation h should
5155 !             be initialized.  1 (the default) means sumit should
5156 !             initialize h to the diagonal matrix whose i-th diagonal
5157 !             element is d(i)**2.  0 means the caller has supplied a
5158 !             cholesky factor  l  of the initial hessian approximation
5159 !             h = l*(l**t)  in v, starting at v(iv(lmat)) = v(iv(42))
5160 !             (and stored compactly by rows).  note that iv(lmat) may
5161 !             be initialized by calling sumsl with iv(1) = 13 (see
5162 !             the iv(1) discussion above).  default = 1.
5163 ! iv(mxfcal)... iv(17) gives the maximum number of function evaluations
5164 !             (calls on calcf) allowed.  if this number does not suf-
5165 !             fice, then sumsl returns with iv(1) = 9.  default = 200.
5166 ! iv(mxiter)... iv(18) gives the maximum number of iterations allowed.
5167 !             it also indirectly limits the number of gradient evalua-
5168 !             tions (calls on calcg) to iv(mxiter) + 1.  if iv(mxiter)
5169 !             iterations do not suffice, then sumsl returns with
5170 !             iv(1) = 10.  default = 150.
5171 ! iv(outlev)... iv(19) controls the number and length of iteration sum-
5172 !             mary lines printed (by itsum).  iv(outlev) = 0 means do
5173 !             not print any summary lines.  otherwise, print a summary
5174 !             line after each abs(iv(outlev)) iterations.  if iv(outlev)
5175 !             is positive, then summary lines of length 78 (plus carri-
5176 !             age control) are printed, including the following...  the
5177 !             iteration and function evaluation counts, f = the current
5178 !             function value, relative difference in function values
5179 !             achieved by the latest step (i.e., reldf = (f0-v(f))/f01,
5180 !             where f01 is the maximum of abs(v(f)) and abs(v(f0)) and
5181 !             v(f0) is the function value from the previous itera-
5182 !             tion), the relative function reduction predicted for the
5183 !             step just taken (i.e., preldf = v(preduc) / f01, where
5184 !             v(preduc) is described below), the scaled relative change
5185 !             in x (see v(reldx) below), the step parameter for the
5186 !             step just taken (stppar = 0 means a full newton step,
5187 !             between 0 and 1 means a relaxed newton step, between 1
5188 !             and 2 means a double dogleg step, greater than 2 means
5189 !             a scaled down cauchy step -- see subroutine dbldog), the
5190 !             2-norm of the scale vector d times the step just taken
5191 !             (see v(dstnrm) below), and npreldf, i.e.,
5192 !             v(nreduc)/f01, where v(nreduc) is described below -- if
5193 !             npreldf is positive, then it is the relative function
5194 !             reduction predicted for a newton step (one with
5195 !             stppar = 0).  if npreldf is negative, then it is the
5196 !             negative of the relative function reduction predicted
5197 !             for a step computed with step bound v(lmaxs) for use in
5198 !             testing for singular convergence.
5199 !                  if iv(outlev) is negative, then lines of length 50
5200 !             are printed, including only the first 6 items listed
5201 !             above (through reldx).
5202 !             default = 1.
5203 ! iv(parprt)... iv(20) = 1 means print any nondefault v values on a
5204 !             fresh start or any changed v values on a restart.
5205 !             iv(parprt) = 0 means skip this printing.  default = 1.
5206 ! iv(prunit)... iv(21) is the output unit number on which all printing
5207 !             is done.  iv(prunit) = 0 means suppress all printing.
5208 !             default = standard output unit (unit 6 on most systems).
5209 ! iv(solprt)... iv(22) = 1 means print out the value of x returned (as
5210 !             well as the gradient and the scale vector d).
5211 !             iv(solprt) = 0 means skip this printing.  default = 1.
5212 ! iv(statpr)... iv(23) = 1 means print summary statistics upon return-
5213 !             ing.  these consist of the function value, the scaled
5214 !             relative change in x caused by the most recent step (see
5215 !             v(reldx) below), the number of function and gradient
5216 !             evaluations (calls on calcf and calcg), and the relative
5217 !             function reductions predicted for the last step taken and
5218 !             for a newton step (or perhaps a step bounded by v(lmaxs)
5219 !             -- see the descriptions of preldf and npreldf under
5220 !             iv(outlev) above).
5221 !             iv(statpr) = 0 means skip this printing.
5222 !             iv(statpr) = -1 means skip this printing as well as that
5223 !             of the one-line termination reason message.  default = 1.
5224 ! iv(x0prt).... iv(24) = 1 means print the initial x and scale vector d
5225 !             (on a fresh start only).  iv(x0prt) = 0 means skip this
5226 !             printing.  default = 1.
5227 !
5228 !  ***  (selected) iv output values  ***
5229 !
5230 ! iv(1)........ on output, iv(1) is a return code....
5231 !             3 = x-convergence.  the scaled relative difference (see
5232 !                  v(reldx)) between the current parameter vector x and
5233 !                  a locally optimal parameter vector is very likely at
5234 !                  most v(xctol).
5235 !             4 = relative function convergence.  the relative differ-
5236 !                  ence between the current function value and its lo-
5237 !                  cally optimal value is very likely at most v(rfctol).
5238 !             5 = both x- and relative function convergence (i.e., the
5239 !                  conditions for iv(1) = 3 and iv(1) = 4 both hold).
5240 !             6 = absolute function convergence.  the current function
5241 !                  value is at most v(afctol) in absolute value.
5242 !             7 = singular convergence.  the hessian near the current
5243 !                  iterate appears to be singular or nearly so, and a
5244 !                  step of length at most v(lmaxs) is unlikely to yield
5245 !                  a relative function decrease of more than v(sctol).
5246 !             8 = false convergence.  the iterates appear to be converg-
5247 !                  ing to a noncritical point.  this may mean that the
5248 !                  convergence tolerances (v(afctol), v(rfctol),
5249 !                  v(xctol)) are too small for the accuracy to which
5250 !                  the function and gradient are being computed, that
5251 !                  there is an error in computing the gradient, or that
5252 !                  the function or gradient is discontinuous near x.
5253 !             9 = function evaluation limit reached without other con-
5254 !                  vergence (see iv(mxfcal)).
5255 !            10 = iteration limit reached without other convergence
5256 !                  (see iv(mxiter)).
5257 !            11 = stopx returned .true. (external interrupt).  see the
5258 !                  usage notes below.
5259 !            14 = storage has been allocated (after a call with
5260 !                  iv(1) = 13).
5261 !            17 = restart attempted with n changed.
5262 !            18 = d has a negative component and iv(dtype) .le. 0.
5263 !            19...43 = v(iv(1)) is out of range.
5264 !            63 = f(x) cannot be computed at the initial x.
5265 !            64 = bad parameters passed to assess (which should not
5266 !                  occur).
5267 !            65 = the gradient could not be computed at x (see calcg
5268 !                  above).
5269 !            67 = bad first parameter to deflt.
5270 !            80 = iv(1) was out of range.
5271 !            81 = n is not positive.
5272 ! iv(g)........ iv(28) is the starting subscript in v of the current
5273 !             gradient vector (the one corresponding to x).
5274 ! iv(lastiv)... iv(44) is the least acceptable value of liv.  (it is
5275 !             only set if liv is at least 44.)
5276 ! iv(lastv).... iv(45) is the least acceptable value of lv.  (it is
5277 !             only set if liv is large enough, at least iv(lastiv).)
5278 ! iv(nfcall)... iv(6) is the number of calls so far made on calcf (i.e.,
5279 !             function evaluations).
5280 ! iv(ngcall)... iv(30) is the number of gradient evaluations (calls on
5281 !             calcg).
5282 ! iv(niter).... iv(31) is the number of iterations performed.
5283 !
5284 !  ***  (selected) v input values (from subroutine deflt)  ***
5285 !
5286 ! v(bias)..... v(43) is the bias parameter used in subroutine dbldog --
5287 !             see that subroutine for details.  default = 0.8.
5288 ! v(afctol)... v(31) is the absolute function convergence tolerance.
5289 !             if sumsl finds a point where the function value is less
5290 !             than v(afctol) in absolute value, and if sumsl does not
5291 !             return with iv(1) = 3, 4, or 5, then it returns with
5292 !             iv(1) = 6.  this test can be turned off by setting
5293 !             v(afctol) to zero.  default = max(10**-20, machep**2),
5294 !             where machep is the unit roundoff.
5295 ! v(dinit).... v(38), if nonnegative, is the value to which the scale
5296 !             vector d is initialized.  default = -1.
5297 ! v(lmax0).... v(35) gives the maximum 2-norm allowed for d times the
5298 !             very first step that sumsl attempts.  this parameter can
5299 !             markedly affect the performance of sumsl.
5300 ! v(lmaxs).... v(36) is used in testing for singular convergence -- if
5301 !             the function reduction predicted for a step of length
5302 !             bounded by v(lmaxs) is at most v(sctol) * abs(f0), where
5303 !             f0  is the function value at the start of the current
5304 !             iteration, and if sumsl does not return with iv(1) = 3,
5305 !             4, 5, or 6, then it returns with iv(1) = 7.  default = 1.
5306 ! v(rfctol)... v(32) is the relative function convergence tolerance.
5307 !             if the current model predicts a maximum possible function
5308 !             reduction (see v(nreduc)) of at most v(rfctol)*abs(f0)
5309 !             at the start of the current iteration, where  f0  is the
5310 !             then current function value, and if the last step attempt-
5311 !             ed achieved no more than twice the predicted function
5312 !             decrease, then sumsl returns with iv(1) = 4 (or 5).
5313 !             default = max(10**-10, machep**(2/3)), where machep is
5314 !             the unit roundoff.
5315 ! v(sctol).... v(37) is the singular convergence tolerance -- see the
5316 !             description of v(lmaxs) above.
5317 ! v(tuner1)... v(26) helps decide when to check for false convergence.
5318 !             this is done if the actual function decrease from the
5319 !             current step is no more than v(tuner1) times its predict-
5320 !             ed value.  default = 0.1.
5321 ! v(xctol).... v(33) is the x-convergence tolerance.  if a newton step
5322 !             (see v(nreduc)) is tried that has v(reldx) .le. v(xctol)
5323 !             and if this step yields at most twice the predicted func-
5324 !             tion decrease, then sumsl returns with iv(1) = 3 (or 5).
5325 !             (see the description of v(reldx) below.)
5326 !             default = machep**0.5, where machep is the unit roundoff.
5327 ! v(xftol).... v(34) is the false convergence tolerance.  if a step is
5328 !             tried that gives no more than v(tuner1) times the predict-
5329 !             ed function decrease and that has v(reldx) .le. v(xftol),
5330 !             and if sumsl does not return with iv(1) = 3, 4, 5, 6, or
5331 !             7, then it returns with iv(1) = 8.  (see the description
5332 !             of v(reldx) below.)  default = 100*machep, where
5333 !             machep is the unit roundoff.
5334 ! v(*)........ deflt supplies to v a number of tuning constants, with
5335 !             which it should ordinarily be unnecessary to tinker.  see
5336 !             section 17 of version 2.2 of the nl2sol usage summary
5337 !             (i.e., the appendix to ref. 1) for details on v(i),
5338 !             i = decfac, incfac, phmnfc, phmxfc, rdfcmn, rdfcmx,
5339 !             tuner2, tuner3, tuner4, tuner5.
5340 !
5341 !  ***  (selected) v output values  ***
5342 !
5343 ! v(dgnorm)... v(1) is the 2-norm of (diag(d)**-1)*g, where g is the
5344 !             most recently computed gradient.
5345 ! v(dstnrm)... v(2) is the 2-norm of diag(d)*step, where step is the
5346 !             current step.
5347 ! v(f)........ v(10) is the current function value.
5348 ! v(f0)....... v(13) is the function value at the start of the current
5349 !             iteration.
5350 ! v(nreduc)... v(6), if positive, is the maximum function reduction
5351 !             possible according to the current model, i.e., the func-
5352 !             tion reduction predicted for a newton step (i.e.,
5353 !             step = -h**-1 * g,  where  g  is the current gradient and
5354 !             h is the current hessian approximation).
5355 !                  if v(nreduc) is negative, then it is the negative of
5356 !             the function reduction predicted for a step computed with
5357 !             a step bound of v(lmaxs) for use in testing for singular
5358 !             convergence.
5359 ! v(preduc)... v(7) is the function reduction predicted (by the current
5360 !             quadratic model) for the current step.  this (divided by
5361 !             v(f0)) is used in testing for relative function
5362 !             convergence.
5363 ! v(reldx).... v(17) is the scaled relative change in x caused by the
5364 !             current step, computed as
5365 !                  max(abs(d(i)*(x(i)-x0(i)), 1 .le. i .le. p) /
5366 !                     max(d(i)*(abs(x(i))+abs(x0(i))), 1 .le. i .le. p),
5367 !             where x = x0 + step.
5368 !
5369 !-------------------------------  notes  -------------------------------
5370 !
5371 !  ***  algorithm notes  ***
5372 !
5373 !        this routine uses a hessian approximation computed from the
5374 !     bfgs update (see ref 3).  only a cholesky factor of the hessian
5375 !     approximation is stored, and this is updated using ideas from
5376 !     ref. 4.  steps are computed by the double dogleg scheme described
5377 !     in ref. 2.  the steps are assessed as in ref. 1.
5378 !
5379 !  ***  usage notes  ***
5380 !
5381 !        after a return with iv(1) .le. 11, it is possible to restart,
5382 !     i.e., to change some of the iv and v input values described above
5383 !     and continue the algorithm from the point where it was interrupt-
5384 !     ed.  iv(1) should not be changed, nor should any entries of i
5385 !     and v other than the input values (those supplied by deflt).
5386 !        those who do not wish to write a calcg which computes the
5387 !     gradient analytically should call smsno rather than sumsl.
5388 !     smsno uses finite differences to compute an approximate gradient.
5389 !        those who would prefer to provide f and g (the function and
5390 !     gradient) by reverse communication rather than by writing subrou-
5391 !     tines calcf and calcg may call on sumit directly.  see the com-
5392 !     ments at the beginning of sumit.
5393 !        those who use sumsl interactively may wish to supply their
5394 !     own stopx function, which should return .true. if the break key
5395 !     has been pressed since stopx was last invoked.  this makes it
5396 !     possible to externally interrupt sumsl (which will return with
5397 !     iv(1) = 11 if stopx returns .true.).
5398 !        storage for g is allocated at the end of v.  thus the caller
5399 !     may make v longer than specified above and may allow calcg to use
5400 !     elements of g beyond the first n as scratch storage.
5401 !
5402 !  ***  portability notes  ***
5403 !
5404 !        the sumsl distribution tape contains both single- and double-
5405 !     precision versions of the sumsl source code, so it should be un-
5406 !     necessary to change precisions.
5407 !        only the functions imdcon and rmdcon contain machine-dependent
5408 !     constants.  to change from one machine to another, it should
5409 !     suffice to change the (few) relevant lines in these functions.
5410 !        intrinsic functions are explicitly declared.  on certain com-
5411 !     puters (e.g. univac), it may be necessary to comment out these
5412 !     declarations.  so that this may be done automatically by a simple
5413 !     program, such declarations are preceded by a comment having c/+
5414 !     in columns 1-3 and blanks in columns 4-72 and are followed by
5415 !     a comment having c/ in columns 1 and 2 and blanks in columns 3-72.
5416 !        the sumsl source code is expressed in 1966 ansi standard
5417 !     fortran.  it may be converted to fortran 77 by commenting out all
5418 !     lines that fall between a line having c/6 in columns 1-3 and a
5419 !     line having c/7 in columns 1-3 and by removing (i.e., replacing
5420 !     by a blank) the c in column 1 of the lines that follow the c/7
5421 !     line and precede a line having c/ in columns 1-2 and blanks in
5422 !     columns 3-72.  these changes convert some data statements into
5423 !     parameter statements, convert some variables from real to
5424 !     character*4, and make the data statements that initialize these
5425 !     variables use character strings delimited by primes instead
5426 !     of hollerith constants.  (such variables and data statements
5427 !     appear only in modules itsum and parck.  parameter statements
5428 !     appear nearly everywhere.)  these changes also add save state-
5429 !     ments for variables given machine-dependent constants by rmdcon.
5430 !
5431 !  ***  references  ***
5432 !
5433 ! 1.  dennis, j.e., gay, d.m., and welsch, r.e. (1981), algorithm 573 --
5434 !             an adaptive nonlinear least-squares algorithm, acm trans.
5435 !             math. software 7, pp. 369-383.
5436 !
5437 ! 2.  dennis, j.e., and mei, h.h.w. (1979), two new unconstrained opti-
5438 !             mization algorithms which use function and gradient
5439 !             values, j. optim. theory applic. 28, pp. 453-482.
5440 !
5441 ! 3.  dennis, j.e., and more, j.j. (1977), quasi-newton methods, motiva-
5442 !             tion and theory, siam rev. 19, pp. 46-89.
5443 !
5444 ! 4.  goldfarb, d. (1976), factorized variable metric methods for uncon-
5445 !             strained optimization, math. comput. 30, pp. 796-811.
5446 !
5447 !  ***  general  ***
5448 !
5449 !     coded by david m. gay (winter 1980).  revised summer 1982.
5450 !     this subroutine was written in connection with research
5451 !     supported in part by the national science foundation under
5452 !     grants mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989,
5453 !     and mcs-7906671.
5454 !.
5455 !
5456 !----------------------------  declarations  ---------------------------
5457 !
5458 !el      external deflt, sumit
5459 !
5460 ! deflt... supplies default iv and v input components.
5461 ! sumit... reverse-communication routine that carries out sumsl algo-
5462 !             rithm.
5463 !
5464       integer :: g1, iv1, nf
5465       real(kind=8) :: f
5466 !
5467 !  ***  subscripts for iv   ***
5468 !
5469 !el      integer nextv, nfcall, nfgcal, g, toobig, vneed
5470 !
5471 !/6
5472 !     data nextv/47/, nfcall/6/, nfgcal/7/, g/28/, toobig/2/, vneed/4/
5473 !/7
5474       integer,parameter :: nextv=47, nfcall=6, nfgcal=7, g=28,&
5475                            toobig=2, vneed=4
5476 !/
5477 !
5478 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
5479 !
5480 !elwrite(iout,*) "in sumsl"
5481       if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
5482       iv1 = iv(1)
5483       if (iv1 .eq. 12 .or. iv1 .eq. 13) iv(vneed) = iv(vneed) + n
5484       if (iv1 .eq. 14) go to 10
5485       if (iv1 .gt. 2 .and. iv1 .lt. 12) go to 10
5486       g1 = 1
5487       if (iv1 .eq. 12) iv(1) = 13
5488       go to 20
5489 !
5490  10   g1 = iv(g)
5491 !elwrite(iout,*) "in sumsl go to 10"
5492
5493 !
5494 !elwrite(iout,*) "in sumsl"
5495  20   call sumit(d, f, v(g1), iv, liv, lv, n, v, x)
5496 !elwrite(iout,*) "in sumsl, go to 20"
5497   
5498 !elwrite(iout,*) "in sumsl, go to 20, po sumit"
5499 !elwrite(iout,*) "in sumsl iv()", iv(1)-2
5500       if (iv(1) - 2) 30, 40, 50
5501 !
5502  30   nf = iv(nfcall)
5503 !elwrite(iout,*) "in sumsl iv",iv(nfcall)
5504       call calcf(n, x, nf, f, uiparm, urparm, ufparm)
5505 !elwrite(iout,*) "in sumsl"
5506       if (nf .le. 0) iv(toobig) = 1
5507       go to 20
5508 !
5509 !elwrite(iout,*) "in sumsl"
5510  40   call calcg(n, x, iv(nfgcal), v(g1), uiparm, urparm, ufparm)
5511 !elwrite(iout,*) "in sumsl"
5512       go to 20
5513 !
5514  50   if (iv(1) .ne. 14) go to 999
5515 !
5516 !  ***  storage allocation
5517 !
5518       iv(g) = iv(nextv)
5519       iv(nextv) = iv(g) + n
5520       if (iv1 .ne. 13) go to 10
5521 !elwrite(iout,*) "in sumsl"
5522 !
5523  999  return
5524 !  ***  last card of sumsl follows  ***
5525       end subroutine sumsl
5526 !-----------------------------------------------------------------------------
5527       subroutine sumit(d,fx,g,iv,liv,lv,n,v,x)
5528       
5529       use control, only:stopx
5530 !
5531 !  ***  carry out sumsl (unconstrained minimization) iterations, using
5532 !  ***  double-dogleg/bfgs steps.
5533 !
5534 !  ***  parameter declarations  ***
5535 !
5536       integer :: liv, lv, n
5537       integer :: iv(liv)
5538       real(kind=8) :: d(n), fx, g(n), v(lv), x(n)
5539 !
5540 !--------------------------  parameter usage  --------------------------
5541 !
5542 ! d.... scale vector.
5543 ! fx... function value.
5544 ! g.... gradient vector.
5545 ! iv... integer value array.
5546 ! liv.. length of iv (at least 60).
5547 ! lv... length of v (at least 71 + n*(n+13)/2).
5548 ! n.... number of variables (components in x and g).
5549 ! v.... floating-point value array.
5550 ! x.... vector of parameters to be optimized.
5551 !
5552 !  ***  discussion  ***
5553 !
5554 !        parameters iv, n, v, and x are the same as the corresponding
5555 !     ones to sumsl (which see), except that v can be shorter (since
5556 !     the part of v that sumsl uses for storing g is not needed).
5557 !     moreover, compared with sumsl, iv(1) may have the two additional
5558 !     output values 1 and 2, which are explained below, as is the use
5559 !     of iv(toobig) and iv(nfgcal).  the value iv(g), which is an
5560 !     output value from sumsl (and smsno), is not referenced by
5561 !     sumit or the subroutines it calls.
5562 !        fx and g need not have been initialized when sumit is called
5563 !     with iv(1) = 12, 13, or 14.
5564 !
5565 ! iv(1) = 1 means the caller should set fx to f(x), the function value
5566 !             at x, and call sumit again, having changed none of the
5567 !             other parameters.  an exception occurs if f(x) cannot be
5568 !             (e.g. if overflow would occur), which may happen because
5569 !             of an oversized step.  in this case the caller should set
5570 !             iv(toobig) = iv(2) to 1, which will cause sumit to ig-
5571 !             nore fx and try a smaller step.  the parameter nf that
5572 !             sumsl passes to calcf (for possible use by calcg) is a
5573 !             copy of iv(nfcall) = iv(6).
5574 ! iv(1) = 2 means the caller should set g to g(x), the gradient vector
5575 !             of f at x, and call sumit again, having changed none of
5576 !             the other parameters except possibly the scale vector d
5577 !             when iv(dtype) = 0.  the parameter nf that sumsl passes
5578 !             to calcg is iv(nfgcal) = iv(7).  if g(x) cannot be
5579 !             evaluated, then the caller may set iv(nfgcal) to 0, in
5580 !             which case sumit will return with iv(1) = 65.
5581 !.
5582 !  ***  general  ***
5583 !
5584 !     coded by david m. gay (december 1979).  revised sept. 1982.
5585 !     this subroutine was written in connection with research supported
5586 !     in part by the national science foundation under grants
5587 !     mcs-7600324 and mcs-7906671.
5588 !
5589 !        (see sumsl for references.)
5590 !
5591 !+++++++++++++++++++++++++++  declarations  ++++++++++++++++++++++++++++
5592 !
5593 !  ***  local variables  ***
5594 !
5595       integer :: dg1, dummy, g01, i, k, l, lstgst, nwtst1, step1,&
5596               temp1, w, x01, z
5597       real(kind=8) :: t
5598 !el      logical :: lstopx
5599 !
5600 !     ***  constants  ***
5601 !
5602 !el      real(kind=8) :: half, negone, one, onep2, zero
5603 !
5604 !  ***  no intrinsic functions  ***
5605 !
5606 !  ***  external functions and subroutines  ***
5607 !
5608 !el      external assst, dbdog, deflt, dotprd, itsum, litvmu, livmul,
5609 !el     1         ltvmul, lupdat, lvmul, parck, reldst, stopx, vaxpy,
5610 !el     2         vcopy, vscopy, vvmulp, v2norm, wzbfgs
5611 !el      logical stopx
5612 !el      real(kind=8) :: dotprd, reldst, v2norm
5613 !
5614 ! assst.... assesses candidate step.
5615 ! dbdog.... computes double-dogleg (candidate) step.
5616 ! deflt.... supplies default iv and v input components.
5617 ! dotprd... returns inner product of two vectors.
5618 ! itsum.... prints iteration summary and info on initial and final x.
5619 ! litvmu... multiplies inverse transpose of lower triangle times vector.
5620 ! livmul... multiplies inverse of lower triangle times vector.
5621 ! ltvmul... multiplies transpose of lower triangle times vector.
5622 ! lupdt.... updates cholesky factor of hessian approximation.
5623 ! lvmul.... multiplies lower triangle times vector.
5624 ! parck.... checks validity of input iv and v values.
5625 ! reldst... computes v(reldx) = relative step size.
5626 ! stopx.... returns .true. if the break key has been pressed.
5627 ! vaxpy.... computes scalar times one vector plus another.
5628 ! vcopy.... copies one vector to another.
5629 ! vscopy... sets all elements of a vector to a scalar.
5630 ! vvmulp... multiplies vector by vector raised to power (componentwise).
5631 ! v2norm... returns the 2-norm of a vector.
5632 ! wzbfgs... computes w and z for lupdat corresponding to bfgs update.
5633 !
5634 !  ***  subscripts for iv and v  ***
5635 !
5636 !el      integer afctol
5637 !el      integer cnvcod, dg, dgnorm, dinit, dstnrm, dst0, f, f0, fdif,
5638 !el     1        gthg, gtstep, g0, incfac, inith, irc, kagqt, lmat, lmax0,
5639 !el     2        lmaxs, mode, model, mxfcal, mxiter, nextv, nfcall, nfgcal,
5640 !el     3        ngcall, niter, nreduc, nwtstp, preduc, radfac, radinc,
5641 !el     4        radius, rad0, reldx, restor, step, stglim, stlstg, toobig,
5642 !el     5        tuner4, tuner5, vneed, xirc, x0
5643 !
5644 !  ***  iv subscript values  ***
5645 !
5646 !/6
5647 !     data cnvcod/55/, dg/37/, g0/48/, inith/25/, irc/29/, kagqt/33/,
5648 !    1     mode/35/, model/5/, mxfcal/17/, mxiter/18/, nfcall/6/,
5649 !    2     nfgcal/7/, ngcall/30/, niter/31/, nwtstp/34/, radinc/8/,
5650 !    3     restor/9/, step/40/, stglim/11/, stlstg/41/, toobig/2/,
5651 !    4     vneed/4/, xirc/13/, x0/43/
5652 !/7
5653       integer,parameter :: cnvcod=55, dg=37, g0=48, inith=25, irc=29, kagqt=33,&
5654                  mode=35, model=5, mxfcal=17, mxiter=18, nfcall=6,&
5655                  nfgcal=7, ngcall=30, niter=31, nwtstp=34, radinc=8,&
5656                  restor=9, step=40, stglim=11, stlstg=41, toobig=2,&
5657                  vneed=4, xirc=13, x0=43
5658 !/
5659 !
5660 !  ***  v subscript values  ***
5661 !
5662 !/6
5663 !     data afctol/31/
5664 !     data dgnorm/1/, dinit/38/, dstnrm/2/, dst0/3/, f/10/, f0/13/,
5665 !    1     fdif/11/, gthg/44/, gtstep/4/, incfac/23/, lmat/42/,
5666 !    2     lmax0/35/, lmaxs/36/, nextv/47/, nreduc/6/, preduc/7/,
5667 !    3     radfac/16/, radius/8/, rad0/9/, reldx/17/, tuner4/29/,
5668 !    4     tuner5/30/
5669 !/7
5670       integer,parameter :: afctol=31
5671       integer,parameter :: dgnorm=1, dinit=38, dstnrm=2, dst0=3, f=10, f0=13,&
5672                  fdif=11, gthg=44, gtstep=4, incfac=23, lmat=42,&
5673                  lmax0=35, lmaxs=36, nextv=47, nreduc=6, preduc=7,&
5674                  radfac=16, radius=8, rad0=9, reldx=17, tuner4=29,&
5675                  tuner5=30
5676 !/
5677 !
5678 !/6
5679 !     data half/0.5d+0/, negone/-1.d+0/, one/1.d+0/, onep2/1.2d+0/,
5680 !    1     zero/0.d+0/
5681 !/7
5682       real(kind=8),parameter :: half=0.5d+0, negone=-1.d+0, one=1.d+0,&
5683                  onep2=1.2d+0,zero=0.d+0
5684 !/
5685 !
5686 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
5687 !
5688 ! Following SAVE statement inserted.
5689       save l
5690       i = iv(1)
5691       if (i .eq. 1) go to 50
5692       if (i .eq. 2) go to 60
5693 !
5694 !  ***  check validity of iv and v input values  ***
5695 !
5696       if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
5697       if (iv(1) .eq. 12 .or. iv(1) .eq. 13) &
5698            iv(vneed) = iv(vneed) + n*(n+13)/2
5699       call parck(2, d, iv, liv, lv, n, v)
5700       i = iv(1) - 2
5701       if (i .gt. 12) go to 999
5702       go to (180, 180, 180, 180, 180, 180, 120, 90, 120, 10, 10, 20), i
5703 !
5704 !  ***  storage allocation  ***
5705 !
5706 10    l = iv(lmat)
5707       iv(x0) = l + n*(n+1)/2
5708       iv(step) = iv(x0) + n
5709       iv(stlstg) = iv(step) + n
5710       iv(g0) = iv(stlstg) + n
5711       iv(nwtstp) = iv(g0) + n
5712       iv(dg) = iv(nwtstp) + n
5713       iv(nextv) = iv(dg) + n
5714       if (iv(1) .ne. 13) go to 20
5715          iv(1) = 14
5716          go to 999
5717 !
5718 !  ***  initialization  ***
5719 !
5720  20   iv(niter) = 0
5721       iv(nfcall) = 1
5722       iv(ngcall) = 1
5723       iv(nfgcal) = 1
5724       iv(mode) = -1
5725       iv(model) = 1
5726       iv(stglim) = 1
5727       iv(toobig) = 0
5728       iv(cnvcod) = 0
5729       iv(radinc) = 0
5730       v(rad0) = zero
5731       if (v(dinit) .ge. zero) call vscopy(n, d, v(dinit))
5732       if (iv(inith) .ne. 1) go to 40
5733 !
5734 !     ***  set the initial hessian approximation to diag(d)**-2  ***
5735 !
5736          l = iv(lmat)
5737          call vscopy(n*(n+1)/2, v(l), zero)
5738          k = l - 1
5739          do 30 i = 1, n
5740               k = k + i
5741               t = d(i)
5742               if (t .le. zero) t = one
5743               v(k) = t
5744  30           continue
5745 !
5746 !  ***  compute initial function value  ***
5747 !
5748  40   iv(1) = 1
5749       go to 999
5750 !
5751  50   v(f) = fx
5752       if (iv(mode) .ge. 0) go to 180
5753       iv(1) = 2
5754       if (iv(toobig) .eq. 0) go to 999
5755          iv(1) = 63
5756          go to 300
5757 !
5758 !  ***  make sure gradient could be computed  ***
5759 !
5760  60   if (iv(nfgcal) .ne. 0) go to 70
5761          iv(1) = 65
5762          go to 300
5763 !
5764  70   dg1 = iv(dg)
5765       call vvmulp(n, v(dg1), g, d, -1)
5766       v(dgnorm) = v2norm(n, v(dg1))
5767 !
5768 !  ***  test norm of gradient  ***
5769 !
5770       if (v(dgnorm) .gt. v(afctol)) go to 75
5771       iv(irc) = 10
5772       iv(cnvcod) = iv(irc) - 4
5773 !
5774  75   if (iv(cnvcod) .ne. 0) go to 290
5775       if (iv(mode) .eq. 0) go to 250
5776 !
5777 !  ***  allow first step to have scaled 2-norm at most v(lmax0)  ***
5778 !
5779       v(radius) = v(lmax0)
5780 !
5781       iv(mode) = 0
5782 !
5783 !
5784 !-----------------------------  main loop  -----------------------------
5785 !
5786 !
5787 !  ***  print iteration summary, check iteration limit  ***
5788 !
5789  80   call itsum(d, g, iv, liv, lv, n, v, x)
5790  90   k = iv(niter)
5791       if (k .lt. iv(mxiter)) go to 100
5792          iv(1) = 10
5793          go to 300
5794 !
5795 !  ***  update radius  ***
5796 !
5797  100  iv(niter) = k + 1
5798       if(k.gt.0)v(radius) = v(radfac) * v(dstnrm)
5799 !
5800 !  ***  initialize for start of next iteration  ***
5801 !
5802       g01 = iv(g0)
5803       x01 = iv(x0)
5804       v(f0) = v(f)
5805       iv(irc) = 4
5806       iv(kagqt) = -1
5807 !
5808 !     ***  copy x to x0, g to g0  ***
5809 !
5810       call vcopy(n, v(x01), x)
5811       call vcopy(n, v(g01), g)
5812 !
5813 !  ***  check stopx and function evaluation limit  ***
5814 !
5815 ! AL 4/30/95
5816       dummy=iv(nfcall)
5817 !el      lstopx = stopx(dummy)
5818 !elwrite(iout,*) "lstopx",lstopx,dummy
5819  110  if (.not. stopx(dummy)) go to 130
5820          iv(1) = 11
5821 !         write (iout,*) "iv(1)=11 !!!!"
5822          go to 140
5823 !
5824 !     ***  come here when restarting after func. eval. limit or stopx.
5825 !
5826  120  if (v(f) .ge. v(f0)) go to 130
5827          v(radfac) = one
5828          k = iv(niter)
5829          go to 100
5830 !
5831  130  if (iv(nfcall) .lt. iv(mxfcal)) go to 150
5832          iv(1) = 9
5833  140     if (v(f) .ge. v(f0)) go to 300
5834 !
5835 !        ***  in case of stopx or function evaluation limit with
5836 !        ***  improved v(f), evaluate the gradient at x.
5837 !
5838               iv(cnvcod) = iv(1)
5839               go to 240
5840 !
5841 !. . . . . . . . . . . . .  compute candidate step  . . . . . . . . . .
5842 !
5843  150  step1 = iv(step)
5844       dg1 = iv(dg)
5845       nwtst1 = iv(nwtstp)
5846       if (iv(kagqt) .ge. 0) go to 160
5847          l = iv(lmat)
5848          call livmul(n, v(nwtst1), v(l), g)
5849          v(nreduc) = half * dotprd(n, v(nwtst1), v(nwtst1))
5850          call litvmu(n, v(nwtst1), v(l), v(nwtst1))
5851          call vvmulp(n, v(step1), v(nwtst1), d, 1)
5852          v(dst0) = v2norm(n, v(step1))
5853          call vvmulp(n, v(dg1), v(dg1), d, -1)
5854          call ltvmul(n, v(step1), v(l), v(dg1))
5855          v(gthg) = v2norm(n, v(step1))
5856          iv(kagqt) = 0
5857  160  call dbdog(v(dg1), lv, n, v(nwtst1), v(step1), v)
5858       if (iv(irc) .eq. 6) go to 180
5859 !
5860 !  ***  check whether evaluating f(x0 + step) looks worthwhile  ***
5861 !
5862       if (v(dstnrm) .le. zero) go to 180
5863       if (iv(irc) .ne. 5) go to 170
5864       if (v(radfac) .le. one) go to 170
5865       if (v(preduc) .le. onep2 * v(fdif)) go to 180
5866 !
5867 !  ***  compute f(x0 + step)  ***
5868 !
5869  170  x01 = iv(x0)
5870       step1 = iv(step)
5871       call vaxpy(n, x, one, v(step1), v(x01))
5872       iv(nfcall) = iv(nfcall) + 1
5873       iv(1) = 1
5874       iv(toobig) = 0
5875       go to 999
5876 !
5877 !. . . . . . . . . . . . .  assess candidate step  . . . . . . . . . . .
5878 !
5879  180  x01 = iv(x0)
5880       v(reldx) = reldst(n, d, x, v(x01))
5881       call assst(iv, liv, lv, v)
5882       step1 = iv(step)
5883       lstgst = iv(stlstg)
5884       if (iv(restor) .eq. 1) call vcopy(n, x, v(x01))
5885       if (iv(restor) .eq. 2) call vcopy(n, v(lstgst), v(step1))
5886       if (iv(restor) .ne. 3) go to 190
5887          call vcopy(n, v(step1), v(lstgst))
5888          call vaxpy(n, x, one, v(step1), v(x01))
5889          v(reldx) = reldst(n, d, x, v(x01))
5890 !
5891  190  k = iv(irc)
5892       go to (200,230,230,230,200,210,220,220,220,220,220,220,280,250), k
5893 !
5894 !     ***  recompute step with changed radius  ***
5895 !
5896  200     v(radius) = v(radfac) * v(dstnrm)
5897          go to 110
5898 !
5899 !  ***  compute step of length v(lmaxs) for singular convergence test.
5900 !
5901  210  v(radius) = v(lmaxs)
5902       go to 150
5903 !
5904 !  ***  convergence or false convergence  ***
5905 !
5906  220  iv(cnvcod) = k - 4
5907       if (v(f) .ge. v(f0)) go to 290
5908          if (iv(xirc) .eq. 14) go to 290
5909               iv(xirc) = 14
5910 !
5911 !. . . . . . . . . . . .  process acceptable step  . . . . . . . . . . .
5912 !
5913  230  if (iv(irc) .ne. 3) go to 240
5914          step1 = iv(step)
5915          temp1 = iv(stlstg)
5916 !
5917 !     ***  set  temp1 = hessian * step  for use in gradient tests  ***
5918 !
5919          l = iv(lmat)
5920          call ltvmul(n, v(temp1), v(l), v(step1))
5921          call lvmul(n, v(temp1), v(l), v(temp1))
5922 !
5923 !  ***  compute gradient  ***
5924 !
5925  240  iv(ngcall) = iv(ngcall) + 1
5926       iv(1) = 2
5927       go to 999
5928 !
5929 !  ***  initializations -- g0 = g - g0, etc.  ***
5930 !
5931  250  g01 = iv(g0)
5932       call vaxpy(n, v(g01), negone, v(g01), g)
5933       step1 = iv(step)
5934       temp1 = iv(stlstg)
5935       if (iv(irc) .ne. 3) go to 270
5936 !
5937 !  ***  set v(radfac) by gradient tests  ***
5938 !
5939 !     ***  set  temp1 = diag(d)**-1 * (hessian*step + (g(x0)-g(x)))  ***
5940 !
5941          call vaxpy(n, v(temp1), negone, v(g01), v(temp1))
5942          call vvmulp(n, v(temp1), v(temp1), d, -1)
5943 !
5944 !        ***  do gradient tests  ***
5945 !
5946          if (v2norm(n, v(temp1)) .le. v(dgnorm) * v(tuner4)) &
5947                         go to 260
5948               if (dotprd(n, g, v(step1)) &
5949                         .ge. v(gtstep) * v(tuner5))  go to 270
5950  260               v(radfac) = v(incfac)
5951 !
5952 !  ***  update h, loop  ***
5953 !
5954  270  w = iv(nwtstp)
5955       z = iv(x0)
5956       l = iv(lmat)
5957       call wzbfgs(v(l), n, v(step1), v(w), v(g01), v(z))
5958 !
5959 !     ** use the n-vectors starting at v(step1) and v(g01) for scratch..
5960       call lupdat(v(temp1), v(step1), v(l), v(g01), v(l), n, v(w), v(z))
5961       iv(1) = 2
5962       go to 80
5963 !
5964 !. . . . . . . . . . . . . .  misc. details  . . . . . . . . . . . . . .
5965 !
5966 !  ***  bad parameters to assess  ***
5967 !
5968  280  iv(1) = 64
5969       go to 300
5970 !
5971 !  ***  print summary of final iteration and other requested items  ***
5972 !
5973  290  iv(1) = iv(cnvcod)
5974       iv(cnvcod) = 0
5975  300  call itsum(d, g, iv, liv, lv, n, v, x)
5976 !
5977  999  return
5978 !
5979 !  ***  last line of sumit follows  ***
5980       end subroutine sumit
5981 !-----------------------------------------------------------------------------
5982       subroutine dbdog(dig,lv,n,nwtstp,step,v)
5983 !
5984 !  ***  compute double dogleg step  ***
5985 !
5986 !  ***  parameter declarations  ***
5987 !
5988       integer :: lv, n
5989       real(kind=8) :: dig(n), nwtstp(n), step(n), v(lv)
5990 !
5991 !  ***  purpose  ***
5992 !
5993 !        this subroutine computes a candidate step (for use in an uncon-
5994 !     strained minimization code) by the double dogleg algorithm of
5995 !     dennis and mei (ref. 1), which is a variation on powell*s dogleg
5996 !     scheme (ref. 2, p. 95).
5997 !
5998 !--------------------------  parameter usage  --------------------------
5999 !
6000 !    dig (input) diag(d)**-2 * g -- see algorithm notes.
6001 !      g (input) the current gradient vector.
6002 !     lv (input) length of v.
6003 !      n (input) number of components in  dig, g, nwtstp,  and  step.
6004 ! nwtstp (input) negative newton step -- see algorithm notes.
6005 !   step (output) the computed step.
6006 !      v (i/o) values array, the following components of which are
6007 !             used here...
6008 ! v(bias)   (input) bias for relaxed newton step, which is v(bias) of
6009 !             the way from the full newton to the fully relaxed newton
6010 !             step.  recommended value = 0.8 .
6011 ! v(dgnorm) (input) 2-norm of diag(d)**-1 * g -- see algorithm notes.
6012 ! v(dstnrm) (output) 2-norm of diag(d) * step, which is v(radius)
6013 !             unless v(stppar) = 0 -- see algorithm notes.
6014 ! v(dst0) (input) 2-norm of diag(d) * nwtstp -- see algorithm notes.
6015 ! v(grdfac) (output) the coefficient of  dig  in the step returned --
6016 !             step(i) = v(grdfac)*dig(i) + v(nwtfac)*nwtstp(i).
6017 ! v(gthg)   (input) square-root of (dig**t) * (hessian) * dig -- see
6018 !             algorithm notes.
6019 ! v(gtstep) (output) inner product between g and step.
6020 ! v(nreduc) (output) function reduction predicted for the full newton
6021 !             step.
6022 ! v(nwtfac) (output) the coefficient of  nwtstp  in the step returned --
6023 !             see v(grdfac) above.
6024 ! v(preduc) (output) function reduction predicted for the step returned.
6025 ! v(radius) (input) the trust region radius.  d times the step returned
6026 !             has 2-norm v(radius) unless v(stppar) = 0.
6027 ! v(stppar) (output) code telling how step was computed... 0 means a
6028 !             full newton step.  between 0 and 1 means v(stppar) of the
6029 !             way from the newton to the relaxed newton step.  between
6030 !             1 and 2 means a true double dogleg step, v(stppar) - 1 of
6031 !             the way from the relaxed newton to the cauchy step.
6032 !             greater than 2 means 1 / (v(stppar) - 1) times the cauchy
6033 !             step.
6034 !
6035 !-------------------------------  notes  -------------------------------
6036 !
6037 !  ***  algorithm notes  ***
6038 !
6039 !        let  g  and  h  be the current gradient and hessian approxima-
6040 !     tion respectively and let d be the current scale vector.  this
6041 !     routine assumes dig = diag(d)**-2 * g  and  nwtstp = h**-1 * g.
6042 !     the step computed is the same one would get by replacing g and h
6043 !     by  diag(d)**-1 * g  and  diag(d)**-1 * h * diag(d)**-1,
6044 !     computing step, and translating step back to the original
6045 !     variables, i.e., premultiplying it by diag(d)**-1.
6046 !
6047 !  ***  references  ***
6048 !
6049 ! 1.  dennis, j.e., and mei, h.h.w. (1979), two new unconstrained opti-
6050 !             mization algorithms which use function and gradient
6051 !             values, j. optim. theory applic. 28, pp. 453-482.
6052 ! 2. powell, m.j.d. (1970), a hybrid method for non-linear equations,
6053 !             in numerical methods for non-linear equations, edited by
6054 !             p. rabinowitz, gordon and breach, london.
6055 !
6056 !  ***  general  ***
6057 !
6058 !     coded by david m. gay.
6059 !     this subroutine was written in connection with research supported
6060 !     by the national science foundation under grants mcs-7600324 and
6061 !     mcs-7906671.
6062 !
6063 !------------------------  external quantities  ------------------------
6064 !
6065 !  ***  functions and subroutines called  ***
6066 !
6067 !el      external dotprd, v2norm
6068 !el      real(kind=8) :: dotprd, v2norm
6069 !
6070 ! dotprd... returns inner product of two vectors.
6071 ! v2norm... returns 2-norm of a vector.
6072 !
6073 !  ***  intrinsic functions  ***
6074 !/+
6075 !el      real(kind=8) :: dsqrt
6076 !/
6077 !--------------------------  local variables  --------------------------
6078 !
6079       integer :: i
6080       real(kind=8) :: cfact, cnorm, ctrnwt, ghinvg, femnsq, gnorm,&
6081                        nwtnrm, relax, rlambd, t, t1, t2
6082 !el      real(kind=8) :: half, one, two, zero
6083 !
6084 !  ***  v subscripts  ***
6085 !
6086 !el      integer bias, dgnorm, dstnrm, dst0, grdfac, gthg, gtstep,
6087 !el     1        nreduc, nwtfac, preduc, radius, stppar
6088 !
6089 !  ***  data initializations  ***
6090 !
6091 !/6
6092 !     data half/0.5d+0/, one/1.d+0/, two/2.d+0/, zero/0.d+0/
6093 !/7
6094       real(kind=8),parameter :: half=0.5d+0, one=1.d+0, two=2.d+0, zero=0.d+0
6095 !/
6096 !
6097 !/6
6098 !     data bias/43/, dgnorm/1/, dstnrm/2/, dst0/3/, grdfac/45/,
6099 !    1     gthg/44/, gtstep/4/, nreduc/6/, nwtfac/46/, preduc/7/,
6100 !    2     radius/8/, stppar/5/
6101 !/7
6102       integer,parameter :: bias=43, dgnorm=1, dstnrm=2, dst0=3, grdfac=45,&
6103                  gthg=44, gtstep=4, nreduc=6, nwtfac=46, preduc=7,&
6104                  radius=8, stppar=5
6105 !/
6106 !
6107 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
6108 !
6109       nwtnrm = v(dst0)
6110       rlambd = one
6111       if (nwtnrm .gt. zero) rlambd = v(radius) / nwtnrm
6112       gnorm = v(dgnorm)
6113       ghinvg = two * v(nreduc)
6114       v(grdfac) = zero
6115       v(nwtfac) = zero
6116       if (rlambd .lt. one) go to 30
6117 !
6118 !        ***  the newton step is inside the trust region  ***
6119 !
6120          v(stppar) = zero
6121          v(dstnrm) = nwtnrm
6122          v(gtstep) = -ghinvg
6123          v(preduc) = v(nreduc)
6124          v(nwtfac) = -one
6125          do 20 i = 1, n
6126  20           step(i) = -nwtstp(i)
6127          go to 999
6128 !
6129  30   v(dstnrm) = v(radius)
6130       cfact = (gnorm / v(gthg))**2
6131 !     ***  cauchy step = -cfact * g.
6132       cnorm = gnorm * cfact
6133       relax = one - v(bias) * (one - gnorm*cnorm/ghinvg)
6134       if (rlambd .lt. relax) go to 50
6135 !
6136 !        ***  step is between relaxed newton and full newton steps  ***
6137 !
6138          v(stppar)  =  one  -  (rlambd - relax) / (one - relax)
6139          t = -rlambd
6140          v(gtstep) = t * ghinvg
6141          v(preduc) = rlambd * (one - half*rlambd) * ghinvg
6142          v(nwtfac) = t
6143          do 40 i = 1, n
6144  40           step(i) = t * nwtstp(i)
6145          go to 999
6146 !
6147  50   if (cnorm .lt. v(radius)) go to 70
6148 !
6149 !        ***  the cauchy step lies outside the trust region --
6150 !        ***  step = scaled cauchy step  ***
6151 !
6152          t = -v(radius) / gnorm
6153          v(grdfac) = t
6154          v(stppar) = one  +  cnorm / v(radius)
6155          v(gtstep) = -v(radius) * gnorm
6156       v(preduc) = v(radius)*(gnorm - half*v(radius)*(v(gthg)/gnorm)**2)
6157          do 60 i = 1, n
6158  60           step(i) = t * dig(i)
6159          go to 999
6160 !
6161 !     ***  compute dogleg step between cauchy and relaxed newton  ***
6162 !     ***  femur = relaxed newton step minus cauchy step  ***
6163 !
6164  70   ctrnwt = cfact * relax * ghinvg / gnorm
6165 !     *** ctrnwt = inner prod. of cauchy and relaxed newton steps,
6166 !     *** scaled by gnorm**-1.
6167       t1 = ctrnwt - gnorm*cfact**2
6168 !     ***  t1 = inner prod. of femur and cauchy step, scaled by
6169 !     ***  gnorm**-1.
6170       t2 = v(radius)*(v(radius)/gnorm) - gnorm*cfact**2
6171       t = relax * nwtnrm
6172       femnsq = (t/gnorm)*t - ctrnwt - t1
6173 !     ***  femnsq = square of 2-norm of femur, scaled by gnorm**-1.
6174       t = t2 / (t1 + dsqrt(t1**2 + femnsq*t2))
6175 !     ***  dogleg step  =  cauchy step  +  t * femur.
6176       t1 = (t - one) * cfact
6177       v(grdfac) = t1
6178       t2 = -t * relax
6179       v(nwtfac) = t2
6180       v(stppar) = two - t
6181       v(gtstep) = t1*gnorm**2 + t2*ghinvg
6182       v(preduc) = -t1*gnorm * ((t2 + one)*gnorm) &
6183                        - t2 * (one + half*t2)*ghinvg &
6184                         - half * (v(gthg)*t1)**2
6185       do 80 i = 1, n
6186  80      step(i) = t1*dig(i) + t2*nwtstp(i)
6187 !
6188  999  return
6189 !  ***  last line of dbdog follows  ***
6190       end subroutine dbdog
6191 !-----------------------------------------------------------------------------
6192       subroutine ltvmul(n,x,l,y)
6193 !
6194 !  ***  compute  x = (l**t)*y, where  l  is an  n x n  lower
6195 !  ***  triangular matrix stored compactly by rows.  x and y may
6196 !  ***  occupy the same storage.  ***
6197 !
6198       integer :: n
6199 !al   real(kind=8) :: x(n), l(1), y(n)
6200       real(kind=8) :: x(n), l(n*(n+1)/2), y(n)
6201 !     dimension l(n*(n+1)/2)
6202       integer :: i, ij, i0, j
6203       real(kind=8) :: yi        !el, zero
6204 !/6
6205 !     data zero/0.d+0/
6206 !/7
6207       real(kind=8),parameter :: zero=0.d+0
6208 !/
6209 !
6210       i0 = 0
6211       do 20 i = 1, n
6212          yi = y(i)
6213          x(i) = zero
6214          do 10 j = 1, i
6215               ij = i0 + j
6216               x(j) = x(j) + yi*l(ij)
6217  10           continue
6218          i0 = i0 + i
6219  20      continue
6220  999  return
6221 !  ***  last card of ltvmul follows  ***
6222       end subroutine ltvmul
6223 !-----------------------------------------------------------------------------
6224       subroutine lupdat(beta,gamma,l,lambda,lplus,n,w,z)
6225 !
6226 !  ***  compute lplus = secant update of l  ***
6227 !
6228 !  ***  parameter declarations  ***
6229 !
6230       integer :: n
6231 !al   double precision beta(n), gamma(n), l(1), lambda(n), lplus(1),
6232       real(kind=8) :: beta(n), gamma(n), l(n*(n+1)/2), lambda(n), &
6233          lplus(n*(n+1)/2),w(n), z(n)
6234 !     dimension l(n*(n+1)/2), lplus(n*(n+1)/2)
6235 !
6236 !--------------------------  parameter usage  --------------------------
6237 !
6238 !   beta = scratch vector.
6239 !  gamma = scratch vector.
6240 !      l (input) lower triangular matrix, stored rowwise.
6241 ! lambda = scratch vector.
6242 !  lplus (output) lower triangular matrix, stored rowwise, which may
6243 !             occupy the same storage as  l.
6244 !      n (input) length of vector parameters and order of matrices.
6245 !      w (input, destroyed on output) right singular vector of rank 1
6246 !             correction to  l.
6247 !      z (input, destroyed on output) left singular vector of rank 1
6248 !             correction to  l.
6249 !
6250 !-------------------------------  notes  -------------------------------
6251 !
6252 !  ***  application and usage restrictions  ***
6253 !
6254 !        this routine updates the cholesky factor  l  of a symmetric
6255 !     positive definite matrix to which a secant update is being
6256 !     applied -- it computes a cholesky factor  lplus  of
6257 !     l * (i + z*w**t) * (i + w*z**t) * l**t.  it is assumed that  w
6258 !     and  z  have been chosen so that the updated matrix is strictly
6259 !     positive definite.
6260 !
6261 !  ***  algorithm notes  ***
6262 !
6263 !        this code uses recurrence 3 of ref. 1 (with d(j) = 1 for all j)
6264 !     to compute  lplus  of the form  l * (i + z*w**t) * q,  where  q
6265 !     is an orthogonal matrix that makes the result lower triangular.
6266 !        lplus may have some negative diagonal elements.
6267 !
6268 !  ***  references  ***
6269 !
6270 ! 1.  goldfarb, d. (1976), factorized variable metric methods for uncon-
6271 !             strained optimization, math. comput. 30, pp. 796-811.
6272 !
6273 !  ***  general  ***
6274 !
6275 !     coded by david m. gay (fall 1979).
6276 !     this subroutine was written in connection with research supported
6277 !     by the national science foundation under grants mcs-7600324 and
6278 !     mcs-7906671.
6279 !
6280 !------------------------  external quantities  ------------------------
6281 !
6282 !  ***  intrinsic functions  ***
6283 !/+
6284 !el      real(kind=8) :: dsqrt
6285 !/
6286 !--------------------------  local variables  --------------------------
6287 !
6288       integer :: i, ij, j, jj, jp1, k, nm1, np1
6289       real(kind=8) :: a, b, bj, eta, gj, lj, lij, ljj, nu, s, theta,&
6290                        wj, zj
6291 !el      real(kind=8) :: one, zero
6292 !
6293 !  ***  data initializations  ***
6294 !
6295 !/6
6296 !     data one/1.d+0/, zero/0.d+0/
6297 !/7
6298       real(kind=8),parameter :: one=1.d+0, zero=0.d+0
6299 !/
6300 !
6301 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
6302 !
6303       nu = one
6304       eta = zero
6305       if (n .le. 1) go to 30
6306       nm1 = n - 1
6307 !
6308 !  ***  temporarily store s(j) = sum over k = j+1 to n of w(k)**2 in
6309 !  ***  lambda(j).
6310 !
6311       s = zero
6312       do 10 i = 1, nm1
6313          j = n - i
6314          s = s + w(j+1)**2
6315          lambda(j) = s
6316  10      continue
6317 !
6318 !  ***  compute lambda, gamma, and beta by goldfarb*s recurrence 3.
6319 !
6320       do 20 j = 1, nm1
6321          wj = w(j)
6322          a = nu*z(j) - eta*wj
6323          theta = one + a*wj
6324          s = a*lambda(j)
6325          lj = dsqrt(theta**2 + a*s)
6326          if (theta .gt. zero) lj = -lj
6327          lambda(j) = lj
6328          b = theta*wj + s
6329          gamma(j) = b * nu / lj
6330          beta(j) = (a - b*eta) / lj
6331          nu = -nu / lj
6332          eta = -(eta + (a**2)/(theta - lj)) / lj
6333  20      continue
6334  30   lambda(n) = one + (nu*z(n) - eta*w(n))*w(n)
6335 !
6336 !  ***  update l, gradually overwriting  w  and  z  with  l*w  and  l*z.
6337 !
6338       np1 = n + 1
6339       jj = n * (n + 1) / 2
6340       do 60 k = 1, n
6341          j = np1 - k
6342          lj = lambda(j)
6343          ljj = l(jj)
6344          lplus(jj) = lj * ljj
6345          wj = w(j)
6346          w(j) = ljj * wj
6347          zj = z(j)
6348          z(j) = ljj * zj
6349          if (k .eq. 1) go to 50
6350          bj = beta(j)
6351          gj = gamma(j)
6352          ij = jj + j
6353          jp1 = j + 1
6354          do 40 i = jp1, n
6355               lij = l(ij)
6356               lplus(ij) = lj*lij + bj*w(i) + gj*z(i)
6357               w(i) = w(i) + lij*wj
6358               z(i) = z(i) + lij*zj
6359               ij = ij + i
6360  40           continue
6361  50      jj = jj - j
6362  60      continue
6363 !
6364  999  return
6365 !  ***  last card of lupdat follows  ***
6366       end subroutine lupdat
6367 !-----------------------------------------------------------------------------
6368       subroutine lvmul(n,x,l,y)
6369 !
6370 !  ***  compute  x = l*y, where  l  is an  n x n  lower triangular
6371 !  ***  matrix stored compactly by rows.  x and y may occupy the same
6372 !  ***  storage.  ***
6373 !
6374       integer :: n
6375 !al   double precision x(n), l(1), y(n)
6376       real(kind=8) :: x(n), l(n*(n+1)/2), y(n)
6377 !     dimension l(n*(n+1)/2)
6378       integer :: i, ii, ij, i0, j, np1
6379       real(kind=8) :: t !el, zero
6380 !/6
6381 !     data zero/0.d+0/
6382 !/7
6383       real(kind=8),parameter :: zero=0.d+0
6384 !/
6385 !
6386       np1 = n + 1
6387       i0 = n*(n+1)/2
6388       do 20 ii = 1, n
6389          i = np1 - ii
6390          i0 = i0 - i
6391          t = zero
6392          do 10 j = 1, i
6393               ij = i0 + j
6394               t = t + l(ij)*y(j)
6395  10           continue
6396          x(i) = t
6397  20      continue
6398  999  return
6399 !  ***  last card of lvmul follows  ***
6400       end subroutine lvmul
6401 !-----------------------------------------------------------------------------
6402       subroutine vvmulp(n,x,y,z,k)
6403 !
6404 ! ***  set x(i) = y(i) * z(i)**k, 1 .le. i .le. n (for k = 1 or -1)  ***
6405 !
6406       integer :: n, k
6407       real(kind=8) :: x(n), y(n), z(n)
6408       integer :: i
6409 !
6410       if (k .ge. 0) go to 20
6411       do 10 i = 1, n
6412  10      x(i) = y(i) / z(i)
6413       go to 999
6414 !
6415  20   do 30 i = 1, n
6416  30      x(i) = y(i) * z(i)
6417  999  return
6418 !  ***  last card of vvmulp follows  ***
6419       end subroutine vvmulp
6420 !-----------------------------------------------------------------------------
6421       subroutine wzbfgs(l,n,s,w,y,z)
6422 !
6423 !  ***  compute  y  and  z  for  lupdat  corresponding to bfgs update.
6424 !
6425       integer :: n
6426 !al   double precision l(1), s(n), w(n), y(n), z(n)
6427       real(kind=8) :: l(n*(n+1)/2), s(n), w(n), y(n), z(n)
6428 !     dimension l(n*(n+1)/2)
6429 !
6430 !--------------------------  parameter usage  --------------------------
6431 !
6432 ! l (i/o) cholesky factor of hessian, a lower triang. matrix stored
6433 !             compactly by rows.
6434 ! n (input) order of  l  and length of  s,  w,  y,  z.
6435 ! s (input) the step just taken.
6436 ! w (output) right singular vector of rank 1 correction to l.
6437 ! y (input) change in gradients corresponding to s.
6438 ! z (output) left singular vector of rank 1 correction to l.
6439 !
6440 !-------------------------------  notes  -------------------------------
6441 !
6442 !  ***  algorithm notes  ***
6443 !
6444 !        when  s  is computed in certain ways, e.g. by  gqtstp  or
6445 !     dbldog,  it is possible to save n**2/2 operations since  (l**t)*s
6446 !     or  l*(l**t)*s is then known.
6447 !        if the bfgs update to l*(l**t) would reduce its determinant to
6448 !     less than eps times its old value, then this routine in effect
6449 !     replaces  y  by  theta*y + (1 - theta)*l*(l**t)*s,  where  theta
6450 !     (between 0 and 1) is chosen to make the reduction factor = eps.
6451 !
6452 !  ***  general  ***
6453 !
6454 !     coded by david m. gay (fall 1979).
6455 !     this subroutine was written in connection with research supported
6456 !     by the national science foundation under grants mcs-7600324 and
6457 !     mcs-7906671.
6458 !
6459 !------------------------  external quantities  ------------------------
6460 !
6461 !  ***  functions and subroutines called  ***
6462 !
6463 !el      external dotprd, livmul, ltvmul
6464 !el      real(kind=8) :: dotprd
6465 ! dotprd returns inner product of two vectors.
6466 ! livmul multiplies l**-1 times a vector.
6467 ! ltvmul multiplies l**t times a vector.
6468 !
6469 !  ***  intrinsic functions  ***
6470 !/+
6471 !el      real(kind=8) :: dsqrt
6472 !/
6473 !--------------------------  local variables  --------------------------
6474 !
6475       integer :: i
6476       real(kind=8) :: cs, cy, epsrt, shs, ys, theta     !el, eps, one
6477 !
6478 !  ***  data initializations  ***
6479 !
6480 !/6
6481 !     data eps/0.1d+0/, one/1.d+0/
6482 !/7
6483       real(kind=8),parameter :: eps=0.1d+0, one=1.d+0
6484 !/
6485 !
6486 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
6487 !
6488       call ltvmul(n, w, l, s)
6489       shs = dotprd(n, w, w)
6490       ys = dotprd(n, y, s)
6491       if (ys .ge. eps*shs) go to 10
6492          theta = (one - eps) * shs / (shs - ys)
6493          epsrt = dsqrt(eps)
6494          cy = theta / (shs * epsrt)
6495          cs = (one + (theta-one)/epsrt) / shs
6496          go to 20
6497  10   cy = one / (dsqrt(ys) * dsqrt(shs))
6498       cs = one / shs
6499  20   call livmul(n, z, l, y)
6500       do 30 i = 1, n
6501  30      z(i) = cy * z(i)  -  cs * w(i)
6502 !
6503  999  return
6504 !  ***  last card of wzbfgs follows  ***
6505       end subroutine wzbfgs
6506 !-----------------------------------------------------------------------------
6507 !-----------------------------------------------------------------------------
6508       end module minimm