random generation for nucleic acids
[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       write(iout,*) 'Warning calling chainbuild'
3299       call chainbuild
3300
3301 !el---------------------
3302 !      write (iout,'(/a)') &
3303 !        "Cartesian coordinates of the reference structure after SUMSL"
3304 !      write (iout,'(a,3(3x,a5),5x,3(3x,a5))') &
3305 !       "Residue","X(CA)","Y(CA)","Z(CA)","X(SC)","Y(SC)","Z(SC)"
3306 !      do i=1,nres
3307 !        write (iout,'(a3,1x,i3,3f8.3,5x,3f8.3)') &
3308 !          restyp(itype(i,1)),i,(c(j,i),j=1,3),&
3309 !          (c(j,i+nres),j=1,3)
3310 !      enddo
3311 !el----------------------------
3312 !     call etotal(energia) !sp
3313 !     etot=energia(0)
3314 !     call enerprint(energia) !sp
3315       nfun=iv(6)
3316
3317 !     write (*,*) 'Processor',MyID,' leaves MINIMIZE.'
3318
3319 !     ENDDO ! NOT_DONE
3320
3321       return
3322       end subroutine minimize
3323 !-----------------------------------------------------------------------------
3324 ! gradient_p.F
3325 !-----------------------------------------------------------------------------
3326       subroutine grad_restr(n,x,nf,g,uiparm,urparm,ufparm)
3327
3328       use energy, only: cartder,zerograd,etotal,sum_gradient
3329 !      implicit real*8 (a-h,o-z)
3330 !      include 'DIMENSIONS'
3331 !      include 'COMMON.CHAIN'
3332 !      include 'COMMON.DERIV'
3333 !      include 'COMMON.VAR'
3334 !      include 'COMMON.INTERACT'
3335 !      include 'COMMON.FFIELD'
3336 !      include 'COMMON.IOUNITS'
3337 !EL      external ufparm
3338       integer :: uiparm(1)
3339       real(kind=8) :: urparm(1)
3340       real(kind=8),dimension(6*nres) :: x,g !(maxvar) (maxvar=6*maxres)
3341       integer :: n,nf,ig,ind,i,j,ij,k,igall
3342       real(kind=8) :: f,gphii,gthetai,galphai,gomegai
3343       real(kind=8),external :: ufparm
3344
3345       icg=mod(nf,2)+1
3346       if (nf-nfl+1) 20,30,40
3347    20 call func_restr(n,x,nf,f,uiparm,urparm,ufparm)
3348 !     write (iout,*) 'grad 20'
3349       if (nf.eq.0) return
3350       goto 40
3351    30 continue
3352 #ifdef OSF
3353 !     Intercept NaNs in the coordinates
3354 !      write(iout,*) (var(i),i=1,nvar)
3355       x_sum=0.D0
3356       do i=1,n
3357         x_sum=x_sum+x(i)
3358       enddo
3359       if (x_sum.ne.x_sum) then
3360         write(iout,*)" *** grad_restr : Found NaN in coordinates"
3361         call flush(iout)
3362         print *," *** grad_restr : Found NaN in coordinates"
3363         return
3364       endif
3365 #endif
3366       call var_to_geom_restr(n,x)
3367       write(iout,*) 'Warning calling chainbuild'
3368       call chainbuild 
3369 !
3370 ! Evaluate the derivatives of virtual bond lengths and SC vectors in variables.
3371 !
3372    40 call cartder
3373 !
3374 ! Convert the Cartesian gradient into internal-coordinate gradient.
3375 !
3376
3377       ig=0
3378       ind=nres-2                                                                    
3379       do i=2,nres-2                
3380        IF (mask_phi(i+2).eq.1) THEN                                             
3381         gphii=0.0D0                                                             
3382         do j=i+1,nres-1                                                         
3383           ind=ind+1                                 
3384           do k=1,3                                                              
3385             gphii=gphii+dcdv(k+3,ind)*gradc(k,j,icg)                            
3386             gphii=gphii+dxdv(k+3,ind)*gradx(k,j,icg)                           
3387           enddo                                                                 
3388         enddo                                                                   
3389         ig=ig+1
3390         g(ig)=gphii
3391        ELSE
3392         ind=ind+nres-1-i
3393        ENDIF
3394       enddo                                        
3395
3396
3397       ind=0
3398       do i=1,nres-2
3399        IF (mask_theta(i+2).eq.1) THEN
3400         ig=ig+1
3401         gthetai=0.0D0
3402         do j=i+1,nres-1
3403           ind=ind+1
3404           do k=1,3
3405             gthetai=gthetai+dcdv(k,ind)*gradc(k,j,icg)
3406             gthetai=gthetai+dxdv(k,ind)*gradx(k,j,icg)
3407           enddo
3408         enddo
3409         g(ig)=gthetai
3410        ELSE
3411         ind=ind+nres-1-i
3412        ENDIF
3413       enddo
3414
3415       do i=2,nres-1
3416         if (itype(i,1).ne.10) then
3417          IF (mask_side(i).eq.1) THEN
3418           ig=ig+1
3419           galphai=0.0D0
3420           do k=1,3
3421             galphai=galphai+dxds(k,i)*gradx(k,i,icg)
3422           enddo
3423           g(ig)=galphai
3424          ENDIF
3425         endif
3426       enddo
3427
3428       
3429       do i=2,nres-1
3430         if (itype(i,1).ne.10) then
3431          IF (mask_side(i).eq.1) THEN
3432           ig=ig+1
3433           gomegai=0.0D0
3434           do k=1,3
3435             gomegai=gomegai+dxds(k+3,i)*gradx(k,i,icg)
3436           enddo
3437           g(ig)=gomegai
3438          ENDIF
3439         endif
3440       enddo
3441
3442 !
3443 ! Add the components corresponding to local energy terms.
3444 !
3445
3446       ig=0
3447       igall=0
3448       do i=4,nres
3449         igall=igall+1
3450         if (mask_phi(i).eq.1) then
3451           ig=ig+1
3452           g(ig)=g(ig)+gloc(igall,icg)
3453         endif
3454       enddo
3455
3456       do i=3,nres
3457         igall=igall+1
3458         if (mask_theta(i).eq.1) then
3459           ig=ig+1
3460           g(ig)=g(ig)+gloc(igall,icg)
3461         endif
3462       enddo
3463      
3464       do ij=1,2
3465       do i=2,nres-1
3466         if (itype(i,1).ne.10) then
3467           igall=igall+1
3468           if (mask_side(i).eq.1) then
3469             ig=ig+1
3470             g(ig)=g(ig)+gloc(igall,icg)
3471           endif
3472         endif
3473       enddo
3474       enddo
3475
3476 !d      do i=1,ig
3477 !d        write (iout,'(a2,i5,a3,f25.8)') 'i=',i,' g=',g(i)
3478 !d      enddo
3479       return
3480       end subroutine grad_restr
3481 !-----------------------------------------------------------------------------
3482       subroutine func_restr(n,x,nf,f,uiparm,urparm,ufparm) !from minimize_p.F
3483
3484       use comm_chu
3485       use energy, only: zerograd,etotal,sum_gradient
3486 !      implicit real*8 (a-h,o-z)
3487 !      include 'DIMENSIONS'
3488 !      include 'COMMON.DERIV'
3489 !      include 'COMMON.IOUNITS'
3490 !      include 'COMMON.GEO'
3491       integer :: n,nf
3492 !el      integer :: jjj
3493 !el      common /chuju/ jjj
3494       real(kind=8) :: energia(0:n_ene)
3495       real(kind=8) :: f
3496       real(kind=8),external :: ufparm                               
3497       integer :: uiparm(1)                                        
3498       real(kind=8) :: urparm(1)                                     
3499       real(kind=8),dimension(6*nres) :: x       !(maxvar) (maxvar=6*maxres)
3500 !     if (jjj.gt.0) then
3501 !       write (iout,'(10f8.3)') (rad2deg*x(i),i=1,n)
3502 !     endif
3503       nfl=nf
3504       icg=mod(nf,2)+1
3505       call var_to_geom_restr(n,x)
3506       call zerograd
3507       write(iout,*) 'Warning calling chainbuild'
3508       call chainbuild
3509 !d    write (iout,*) 'ETOTAL called from FUNC'
3510       call etotal(energia)
3511       call sum_gradient
3512       f=energia(0)
3513 !     if (jjj.gt.0) then
3514 !       write (iout,'(10f8.3)') (rad2deg*x(i),i=1,n)
3515 !       write (iout,*) 'f=',etot
3516 !       jjj=0
3517 !     endif
3518       return
3519       end subroutine func_restr
3520 !-----------------------------------------------------------------------------
3521 !      subroutine func(n,x,nf,f,uiparm,urparm,ufparm) in module energy
3522 !-----------------------------------------------------------------------------
3523       subroutine x2xx(x,xx,n)
3524
3525 !      implicit real*8 (a-h,o-z)
3526 !      include 'DIMENSIONS'
3527 !      include 'COMMON.VAR'
3528 !      include 'COMMON.CHAIN'
3529 !      include 'COMMON.INTERACT'
3530       integer :: n,i,ij,ig,igall
3531       real(kind=8),dimension(6*nres) :: xx,x    !(maxvar) (maxvar=6*maxres)
3532
3533 !el      allocate(varall(nvar)) allocated in alioc_ener_arrays
3534
3535       do i=1,nvar
3536         varall(i)=x(i)
3537       enddo
3538
3539       ig=0                                                                      
3540       igall=0                                                                   
3541       do i=4,nres                                                               
3542         igall=igall+1                                                           
3543         if (mask_phi(i).eq.1) then                                              
3544           ig=ig+1                                                               
3545           xx(ig)=x(igall)                       
3546         endif                                                                   
3547       enddo                                                                     
3548                                                                                 
3549       do i=3,nres                                                               
3550         igall=igall+1                                                           
3551         if (mask_theta(i).eq.1) then                                            
3552           ig=ig+1                                                               
3553           xx(ig)=x(igall)
3554         endif                                                                   
3555       enddo                                          
3556
3557       do ij=1,2                                                                 
3558       do i=2,nres-1                                                             
3559         if (itype(i,1).ne.10) then                                                
3560           igall=igall+1                                                         
3561           if (mask_side(i).eq.1) then                                           
3562             ig=ig+1                                                             
3563             xx(ig)=x(igall)
3564           endif                                                                 
3565         endif                                                                   
3566       enddo                                                                     
3567       enddo                              
3568  
3569       n=ig
3570
3571       return
3572       end subroutine x2xx
3573 !-----------------------------------------------------------------------------
3574 !el      subroutine xx2x(x,xx) in module math
3575 !-----------------------------------------------------------------------------
3576       subroutine minim_dc(etot,iretcode,nfun)
3577
3578       use MPI_data
3579       use energy, only: fdum,check_ecartint
3580 !      implicit real*8 (a-h,o-z)
3581 !      include 'DIMENSIONS'
3582 #ifdef MPI
3583       include 'mpif.h'
3584 #endif
3585       integer,parameter :: liv=60
3586 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3587 !      include 'COMMON.SETUP'
3588 !      include 'COMMON.IOUNITS'
3589 !      include 'COMMON.VAR'
3590 !      include 'COMMON.GEO'
3591 !      include 'COMMON.MINIM'
3592 !      include 'COMMON.CHAIN'
3593       integer :: iretcode,nfun,k,i,j,lv,idum(1)
3594       integer,dimension(liv) :: iv                                               
3595       real(kind=8) :: minval    !,v(1:77+(6*nres)*(6*nres+17)/2)        !(1:lv)
3596       real(kind=8),dimension(6*nres) :: x,d,xx  !(maxvar) (maxvar=6*maxres)
3597 !el      common /przechowalnia/ v
3598
3599       real(kind=8) :: energia(0:n_ene)
3600 !      external func_dc,grad_dc ,fdum
3601       logical :: not_done,change,reduce 
3602       real(kind=8) :: g(6*nres),f1,etot,rdum(1) !,fdum
3603
3604       lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3605
3606       if (.not. allocated(v)) allocate(v(1:lv))
3607
3608       call deflt(2,iv,liv,lv,v)                                         
3609 ! 12 means fresh start, dont call deflt                                 
3610       iv(1)=12                                                          
3611 ! max num of fun calls                                                  
3612       if (maxfun.eq.0) maxfun=500
3613       iv(17)=maxfun
3614 ! max num of iterations                                                 
3615       if (maxmin.eq.0) maxmin=1000
3616       iv(18)=maxmin
3617 ! controls output                                                       
3618       iv(19)=2                                                          
3619 ! selects output unit                                                   
3620       iv(21)=0
3621       if (print_min_ini+print_min_stat+print_min_res.gt.0) iv(21)=iout
3622 ! 1 means to print out result                                           
3623       iv(22)=print_min_res
3624 ! 1 means to print out summary stats                                    
3625       iv(23)=print_min_stat
3626 ! 1 means to print initial x and d                                      
3627       iv(24)=print_min_ini
3628 ! min val for v(radfac) default is 0.1                                  
3629       v(24)=0.1D0                                                       
3630 ! max val for v(radfac) default is 4.0                                  
3631       v(25)=2.0D0                                                       
3632 !     v(25)=4.0D0                                                       
3633 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
3634 ! the sumsl default is 0.1                                              
3635       v(26)=0.1D0
3636 ! false conv if (act fnctn decrease) .lt. v(34)                         
3637 ! the sumsl default is 100*machep                                       
3638       v(34)=v(34)/100.0D0                                               
3639 ! absolute convergence                                                  
3640       if (tolf.eq.0.0D0) tolf=1.0D-4
3641       v(31)=tolf
3642 ! relative convergence                                                  
3643       if (rtolf.eq.0.0D0) rtolf=1.0D-4
3644       v(32)=rtolf
3645 ! controls initial step size                                            
3646        v(35)=1.0D-1                                                    
3647 ! large vals of d correspond to small components of step                
3648       do i=1,6*nres
3649         d(i)=1.0D-1
3650       enddo
3651
3652       k=0
3653       do i=1,nres-1
3654         do j=1,3
3655           k=k+1
3656           x(k)=dc(j,i)
3657         enddo
3658       enddo
3659       do i=2,nres-1
3660         if (ialph(i,1).gt.0) then
3661         do j=1,3
3662           k=k+1
3663           x(k)=dc(j,i+nres)
3664         enddo
3665         endif
3666       enddo
3667 !      call check_ecartint
3668       call sumsl(k,d,x,func_dc,grad_dc,iv,liv,lv,v,idum,rdum,fdum)      
3669 !      call check_ecartint
3670       k=0
3671       do i=1,nres-1
3672         do j=1,3
3673           k=k+1
3674           dc(j,i)=x(k)
3675         enddo
3676       enddo
3677       do i=2,nres-1
3678         if (ialph(i,1).gt.0) then
3679         do j=1,3
3680           k=k+1
3681           dc(j,i+nres)=x(k)
3682         enddo
3683         endif
3684       enddo
3685       call chainbuild_cart
3686
3687 !d      call zerograd
3688 !d      nf=0
3689 !d      call func_dc(k,x,nf,f,idum,rdum,fdum)
3690 !d      call grad_dc(k,x,nf,g,idum,rdum,fdum)
3691 !d
3692 !d      do i=1,k
3693 !d       x(i)=x(i)+1.0D-5
3694 !d       call func_dc(k,x,nf,f1,idum,rdum,fdum)
3695 !d       x(i)=x(i)-1.0D-5
3696 !d       print '(i5,2f15.5)',i,g(i),(f1-f)/1.0D-5
3697 !d      enddo
3698 !el---------------------
3699 !      write (iout,'(/a)') &
3700 !        "Cartesian coordinates of the reference structure after SUMSL"
3701 !      write (iout,'(a,3(3x,a5),5x,3(3x,a5))') &
3702 !       "Residue","X(CA)","Y(CA)","Z(CA)","X(SC)","Y(SC)","Z(SC)"
3703 !      do i=1,nres
3704 !        write (iout,'(a3,1x,i3,3f8.3,5x,3f8.3)') &
3705 !          restyp(itype(i,1)),i,(c(j,i),j=1,3),&
3706 !          (c(j,i+nres),j=1,3)
3707 !      enddo
3708 !el----------------------------
3709       etot=v(10)                                                      
3710       iretcode=iv(1)
3711       nfun=iv(6)
3712       return
3713       end subroutine  minim_dc
3714 !-----------------------------------------------------------------------------
3715       subroutine func_dc(n,x,nf,f,uiparm,urparm,ufparm)
3716
3717       use MPI_data
3718       use energy, only: zerograd,etotal
3719 !      implicit real*8 (a-h,o-z)
3720 !      include 'DIMENSIONS'
3721 #ifdef MPI
3722       include 'mpif.h'
3723 #endif
3724 !      include 'COMMON.SETUP'
3725 !      include 'COMMON.DERIV'
3726 !      include 'COMMON.IOUNITS'
3727 !      include 'COMMON.GEO'
3728 !      include 'COMMON.CHAIN'
3729 !      include 'COMMON.VAR'
3730       integer :: n,nf,k,i,j
3731       real(kind=8) :: energia(0:n_ene)
3732       real(kind=8),external :: ufparm
3733       integer :: uiparm(1)                                                 
3734       real(kind=8) :: urparm(1)                                                    
3735       real(kind=8),dimension(6*nres) :: x       !(maxvar) (maxvar=6*maxres)
3736       real(kind=8) :: f
3737       nfl=nf
3738 !bad      icg=mod(nf,2)+1
3739       icg=1
3740
3741       k=0
3742       do i=1,nres-1
3743         do j=1,3
3744           k=k+1
3745           dc(j,i)=x(k)
3746         enddo
3747       enddo
3748       do i=2,nres-1
3749         if (ialph(i,1).gt.0) then
3750         do j=1,3
3751           k=k+1
3752           dc(j,i+nres)=x(k)
3753         enddo
3754         endif
3755       enddo
3756       call chainbuild_cart
3757
3758       call zerograd
3759       call etotal(energia)
3760       f=energia(0)
3761
3762 !d      print *,'func_dc ',nf,nfl,f
3763
3764       return
3765       end subroutine func_dc
3766 !-----------------------------------------------------------------------------
3767       subroutine grad_dc(n,x,nf,g,uiparm,urparm,ufparm)
3768
3769       use MPI_data
3770       use energy, only: cartgrad,zerograd,etotal
3771 !      use MD_data
3772 !      implicit real*8 (a-h,o-z)
3773 !      include 'DIMENSIONS'
3774 #ifdef MPI
3775       include 'mpif.h'
3776 #endif
3777 !      include 'COMMON.SETUP'
3778 !      include 'COMMON.CHAIN'
3779 !      include 'COMMON.DERIV'
3780 !      include 'COMMON.VAR'
3781 !      include 'COMMON.INTERACT'
3782 !      include 'COMMON.FFIELD'
3783 !      include 'COMMON.MD'
3784 !      include 'COMMON.IOUNITS'
3785       real(kind=8),external :: ufparm
3786       integer :: n,nf,i,j,k
3787       integer :: uiparm(1)
3788       real(kind=8) :: urparm(1)
3789       real(kind=8),dimension(6*nres) :: x,g     !(maxvar) (maxvar=6*maxres)
3790       real(kind=8) :: f
3791 !
3792 !elwrite(iout,*) "jestesmy w grad dc"
3793 !
3794 !bad      icg=mod(nf,2)+1
3795       icg=1
3796 !d      print *,'grad_dc ',nf,nfl,nf-nfl+1,icg
3797 !elwrite(iout,*) "jestesmy w grad dc nf-nfl+1", nf-nfl+1
3798       if (nf-nfl+1) 20,30,40
3799    20 call func_dc(n,x,nf,f,uiparm,urparm,ufparm)
3800 !d      print *,20
3801       if (nf.eq.0) return
3802       goto 40
3803    30 continue
3804 !d      print *,30
3805       k=0
3806       do i=1,nres-1
3807         do j=1,3
3808           k=k+1
3809           dc(j,i)=x(k)
3810         enddo
3811       enddo
3812       do i=2,nres-1
3813         if (ialph(i,1).gt.0) then
3814         do j=1,3
3815           k=k+1
3816           dc(j,i+nres)=x(k)
3817         enddo
3818         endif
3819       enddo
3820 !elwrite(iout,*) "jestesmy w grad dc"
3821       call chainbuild_cart
3822
3823 !
3824 ! Evaluate the derivatives of virtual bond lengths and SC vectors in variables.
3825 !
3826    40 call cartgrad
3827 !d      print *,40
3828 !elwrite(iout,*) "jestesmy w grad dc"
3829       k=0
3830       do i=1,nres-1
3831         do j=1,3
3832           k=k+1
3833           g(k)=gcart(j,i)
3834         enddo
3835       enddo
3836       do i=2,nres-1
3837         if (ialph(i,1).gt.0) then
3838         do j=1,3
3839           k=k+1
3840           g(k)=gxcart(j,i)
3841         enddo
3842         endif
3843       enddo       
3844 !elwrite(iout,*) "jestesmy w grad dc"
3845
3846       return
3847       end subroutine grad_dc
3848 !-----------------------------------------------------------------------------
3849 ! minim_mcmf.F
3850 !-----------------------------------------------------------------------------
3851 #ifdef MPI
3852       subroutine minim_mcmf
3853
3854       use MPI_data
3855       use csa_data
3856       use energy, only: func,gradient,fdum
3857 !      implicit real*8 (a-h,o-z)
3858 !      include 'DIMENSIONS'
3859       include 'mpif.h'
3860       integer,parameter :: liv=60
3861 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3862 !      include 'COMMON.VAR'
3863 !      include 'COMMON.IOUNITS'
3864 !      include 'COMMON.MINIM'
3865 !      real(kind=8) :: fdum
3866 !      external func,gradient,fdum
3867 !el      real(kind=4) :: ran1,ran2,ran3
3868 !      include 'COMMON.SETUP'
3869 !      include 'COMMON.GEO'
3870 !      include 'COMMON.CHAIN'
3871 !      include 'COMMON.FFIELD'
3872       real(kind=8),dimension(6*nres) :: var     !(maxvar) (maxvar=6*maxres)
3873       real(kind=8),dimension(mxch*(mxch+1)/2+1) :: erg
3874       real(kind=8),dimension(6*nres) :: d,garbage       !(maxvar) (maxvar=6*maxres)
3875 !el      real(kind=8) :: v(1:77+(6*nres)*(6*nres+17)/2+1)                    
3876       integer,dimension(6) :: indx
3877       integer,dimension(liv) :: iv                                               
3878       integer :: lv,idum(1),nf  !
3879       real(kind=8) :: rdum(1)
3880       real(kind=8) :: przes(3),obrot(3,3),eee
3881       logical :: non_conv
3882
3883       integer,dimension(MPI_STATUS_SIZE) :: muster
3884
3885       integer :: ichuj,i,ierr
3886       real(kind=8) :: rad,ene0
3887       data rad /1.745329252d-2/
3888 !el      common /przechowalnia/ v
3889
3890       lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
3891       if (.not. allocated(v)) allocate(v(1:lv))
3892
3893       ichuj=0
3894    10 continue
3895       ichuj = ichuj + 1
3896       call mpi_recv(indx,6,mpi_integer,king,idint,CG_COMM,&
3897                     muster,ierr)
3898       if (indx(1).eq.0) return
3899 !      print *, 'worker ',me,' received order ',n,ichuj
3900       call mpi_recv(var,nvar,mpi_double_precision,&
3901                     king,idreal,CG_COMM,muster,ierr)
3902       call mpi_recv(ene0,1,mpi_double_precision,&
3903                     king,idreal,CG_COMM,muster,ierr)
3904 !      print *, 'worker ',me,' var read '
3905
3906
3907       call deflt(2,iv,liv,lv,v)                                         
3908 ! 12 means fresh start, dont call deflt                                 
3909       iv(1)=12                                                          
3910 ! max num of fun calls                                                  
3911       if (maxfun.eq.0) maxfun=500
3912       iv(17)=maxfun
3913 ! max num of iterations                                                 
3914       if (maxmin.eq.0) maxmin=1000
3915       iv(18)=maxmin
3916 ! controls output                                                       
3917       iv(19)=2                                                          
3918 ! selects output unit                                                   
3919 !      iv(21)=iout                                                       
3920       iv(21)=0
3921 ! 1 means to print out result                                           
3922       iv(22)=0                                                          
3923 ! 1 means to print out summary stats                                    
3924       iv(23)=0                                                          
3925 ! 1 means to print initial x and d                                      
3926       iv(24)=0                                                          
3927 ! min val for v(radfac) default is 0.1                                  
3928       v(24)=0.1D0                                                       
3929 ! max val for v(radfac) default is 4.0                                  
3930       v(25)=2.0D0                                                       
3931 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
3932 ! the sumsl default is 0.1                                              
3933       v(26)=0.1D0
3934 ! false conv if (act fnctn decrease) .lt. v(34)                         
3935 ! the sumsl default is 100*machep                                       
3936       v(34)=v(34)/100.0D0                                               
3937 ! absolute convergence                                                  
3938       if (tolf.eq.0.0D0) tolf=1.0D-4
3939       v(31)=tolf
3940 ! relative convergence                                                  
3941       if (rtolf.eq.0.0D0) rtolf=1.0D-4
3942       v(32)=rtolf
3943 ! controls initial step size                                            
3944        v(35)=1.0D-1                                                    
3945 ! large vals of d correspond to small components of step                
3946       do i=1,nphi
3947         d(i)=1.0D-1
3948       enddo
3949       do i=nphi+1,nvar
3950         d(i)=1.0D-1
3951       enddo
3952 !  minimize energy
3953
3954       call func(nvar,var,nf,eee,idum,rdum,fdum)
3955       if(eee.gt.1.0d18) then
3956 !       print *,'MINIM_JLEE: ',me,' CHUJ NASTAPIL'
3957 !       print *,' energy before SUMSL =',eee
3958 !       print *,' aborting local minimization'
3959        iv(1)=-1
3960        v(10)=eee
3961        nf=1
3962        go to 201
3963       endif
3964
3965       call sumsl(nvar,d,var,func,gradient,iv,liv,lv,v,idum,rdum,fdum)
3966 !  find which conformation was returned from sumsl
3967         nf=iv(7)+1
3968   201  continue
3969 ! total # of ftn evaluations (for iwf=0, it includes all minimizations).
3970         indx(4)=nf
3971         indx(5)=iv(1)
3972         eee=v(10)
3973
3974         call mpi_send(indx,6,mpi_integer,king,idint,CG_COMM,&
3975                        ierr)
3976 !       print '(a5,i3,15f10.5)', 'ENEX0',indx(1),v(10)
3977         call mpi_send(var,nvar,mpi_double_precision,&
3978                      king,idreal,CG_COMM,ierr)
3979         call mpi_send(eee,1,mpi_double_precision,king,idreal,&
3980                        CG_COMM,ierr)
3981         call mpi_send(ene0,1,mpi_double_precision,king,idreal,&
3982                        CG_COMM,ierr)
3983         go to 10
3984       return
3985       end subroutine minim_mcmf
3986 #endif
3987 !-----------------------------------------------------------------------------
3988 ! rmdd.f
3989 !-----------------------------------------------------------------------------
3990 !     algorithm 611, collected algorithms from acm.
3991 !     algorithm appeared in acm-trans. math. software, vol.9, no. 4,
3992 !     dec., 1983, p. 503-524.
3993       integer function imdcon(k)
3994 !
3995       integer :: k
3996 !
3997 !  ***  return integer machine-dependent constants  ***
3998 !
3999 !     ***  k = 1 means return standard output unit number.   ***
4000 !     ***  k = 2 means return alternate output unit number.  ***
4001 !     ***  k = 3 means return  input unit number.            ***
4002 !          (note -- k = 2, 3 are used only by test programs.)
4003 !
4004 !  +++  port version follows...
4005 !     external i1mach
4006 !     integer i1mach
4007 !     integer mdperm(3)
4008 !     data mdperm(1)/2/, mdperm(2)/4/, mdperm(3)/1/
4009 !     imdcon = i1mach(mdperm(k))
4010 !  +++  end of port version  +++
4011 !
4012 !  +++  non-port version follows...
4013       integer :: mdcon(3)
4014       data mdcon(1)/6/, mdcon(2)/8/, mdcon(3)/5/
4015       imdcon = mdcon(k)
4016 !  +++  end of non-port version  +++
4017 !
4018  999  return
4019 !  ***  last card of imdcon follows  ***
4020       end function imdcon
4021 !-----------------------------------------------------------------------------
4022       real(kind=8) function rmdcon(k)
4023 !
4024 !  ***  return machine dependent constants used by nl2sol  ***
4025 !
4026 ! +++  comments below contain data statements for various machines.  +++
4027 ! +++  to convert to another machine, place a c in column 1 of the   +++
4028 ! +++  data statement line(s) that correspond to the current machine +++
4029 ! +++  and remove the c from column 1 of the data statement line(s)  +++
4030 ! +++  that correspond to the new machine.                           +++
4031 !
4032       integer :: k
4033 !
4034 !  ***  the constant returned depends on k...
4035 !
4036 !  ***        k = 1... smallest pos. eta such that -eta exists.
4037 !  ***        k = 2... square root of eta.
4038 !  ***        k = 3... unit roundoff = smallest pos. no. machep such
4039 !  ***                 that 1 + machep .gt. 1 .and. 1 - machep .lt. 1.
4040 !  ***        k = 4... square root of machep.
4041 !  ***        k = 5... square root of big (see k = 6).
4042 !  ***        k = 6... largest machine no. big such that -big exists.
4043 !
4044       real(kind=8) :: big, eta, machep
4045       integer :: bigi(4), etai(4), machei(4)
4046 !/+
4047 !el      real(kind=8) :: dsqrt
4048 !/
4049       equivalence (big,bigi(1)), (eta,etai(1)), (machep,machei(1))
4050 !
4051 !  +++  ibm 360, ibm 370, or xerox  +++
4052 !
4053 !     data big/z7fffffffffffffff/, eta/z0010000000000000/,
4054 !    1     machep/z3410000000000000/
4055 !
4056 !  +++  data general  +++
4057 !
4058 !     data big/0.7237005577d+76/, eta/0.5397605347d-78/,
4059 !    1     machep/2.22044605d-16/
4060 !
4061 !  +++  dec 11  +++
4062 !
4063 !     data big/1.7d+38/, eta/2.938735878d-39/, machep/2.775557562d-17/
4064 !
4065 !  +++  hp3000  +++
4066 !
4067 !     data big/1.157920892d+77/, eta/8.636168556d-78/,
4068 !    1     machep/5.551115124d-17/
4069 !
4070 !  +++  honeywell  +++
4071 !
4072 !     data big/1.69d+38/, eta/5.9d-39/, machep/2.1680435d-19/
4073 !
4074 !  +++  dec10  +++
4075 !
4076 !     data big/"377777100000000000000000/,
4077 !    1     eta/"002400400000000000000000/,
4078 !    2     machep/"104400000000000000000000/
4079 !
4080 !  +++  burroughs  +++
4081 !
4082 !     data big/o0777777777777777,o7777777777777777/,
4083 !    1     eta/o1771000000000000,o7770000000000000/,
4084 !    2     machep/o1451000000000000,o0000000000000000/
4085 !
4086 !  +++  control data  +++
4087 !
4088 !     data big/37767777777777777777b,37167777777777777777b/,
4089 !    1     eta/00014000000000000000b,00000000000000000000b/,
4090 !    2     machep/15614000000000000000b,15010000000000000000b/
4091 !
4092 !  +++  prime  +++
4093 !
4094 !     data big/1.0d+9786/, eta/1.0d-9860/, machep/1.4210855d-14/
4095 !
4096 !  +++  univac  +++
4097 !
4098 !     data big/8.988d+307/, eta/1.2d-308/, machep/1.734723476d-18/
4099 !
4100 !  +++  vax  +++
4101 !
4102       data big/1.7d+38/, eta/2.939d-39/, machep/1.3877788d-17/
4103 !
4104 !  +++  cray 1  +++
4105 !
4106 !     data bigi(1)/577767777777777777777b/,
4107 !    1     bigi(2)/000007777777777777776b/,
4108 !    2     etai(1)/200004000000000000000b/,
4109 !    3     etai(2)/000000000000000000000b/,
4110 !    4     machei(1)/377224000000000000000b/,
4111 !    5     machei(2)/000000000000000000000b/
4112 !
4113 !  +++  port library -- requires more than just a data statement... +++
4114 !
4115 !     external d1mach
4116 !     double precision d1mach, zero
4117 !     data big/0.d+0/, eta/0.d+0/, machep/0.d+0/, zero/0.d+0/
4118 !     if (big .gt. zero) go to 1
4119 !        big = d1mach(2)
4120 !        eta = d1mach(1)
4121 !        machep = d1mach(4)
4122 !1    continue
4123 !
4124 !  +++ end of port +++
4125 !
4126 !-------------------------------  body  --------------------------------
4127 !
4128       go to (10, 20, 30, 40, 50, 60), k
4129 !
4130  10   rmdcon = eta
4131       go to 999
4132 !
4133  20   rmdcon = dsqrt(256.d+0*eta)/16.d+0
4134       go to 999
4135 !
4136  30   rmdcon = machep
4137       go to 999
4138 !
4139  40   rmdcon = dsqrt(machep)
4140       go to 999
4141 !
4142  50   rmdcon = dsqrt(big/256.d+0)*16.d+0
4143       go to 999
4144 !
4145  60   rmdcon = big
4146 !
4147  999  return
4148 !  ***  last card of rmdcon follows  ***
4149       end function rmdcon
4150 !-----------------------------------------------------------------------------
4151 ! sc_move.F
4152 !-----------------------------------------------------------------------------
4153       subroutine sc_move(n_start,n_end,n_maxtry,e_drop,n_fun,etot)
4154
4155       use control
4156       use random, only: iran_num
4157       use energy, only: esc
4158 !     Perform a quick search over side-chain arrangments (over
4159 !     residues n_start to n_end) for a given (frozen) CA trace
4160 !     Only side-chains are minimized (at most n_maxtry times each),
4161 !     not CA positions
4162 !     Stops if energy drops by e_drop, otherwise tries all residues
4163 !     in the given range
4164 !     If there is an energy drop, full minimization may be useful
4165 !     n_start, n_end CAN be modified by this routine, but only if
4166 !     out of bounds (n_start <= 1, n_end >= nres, n_start < n_end)
4167 !     NOTE: this move should never increase the energy
4168 !rc      implicit none
4169
4170 !     Includes
4171 !      implicit real*8 (a-h,o-z)
4172 !      include 'DIMENSIONS'
4173       include 'mpif.h'
4174 !      include 'COMMON.GEO'
4175 !      include 'COMMON.VAR'
4176 !      include 'COMMON.HEADER'
4177 !      include 'COMMON.IOUNITS'
4178 !      include 'COMMON.CHAIN'
4179 !      include 'COMMON.FFIELD'
4180
4181 !     External functions
4182 !el      integer iran_num
4183 !el      external iran_num
4184
4185 !     Input arguments
4186       integer :: n_start,n_end,n_maxtry
4187       real(kind=8) :: e_drop
4188
4189 !     Output arguments
4190       integer :: n_fun
4191       real(kind=8) :: etot
4192
4193 !     Local variables
4194 !      real(kind=8) :: energy(0:n_ene)
4195       real(kind=8) :: cur_alph(2:nres-1),cur_omeg(2:nres-1)
4196       real(kind=8) :: orig_e,cur_e
4197       integer :: n,n_steps,n_first,n_cur,n_tot  !,i
4198       real(kind=8) :: orig_w(0:n_ene)
4199       real(kind=8) :: wtime
4200
4201 !elwrite(iout,*) "in sc_move etot= ", etot
4202 !     Set non side-chain weights to zero (minimization is faster)
4203 !     NOTE: e(2) does not actually depend on the side-chain, only CA
4204       orig_w(2)=wscp
4205       orig_w(3)=welec
4206       orig_w(4)=wcorr
4207       orig_w(5)=wcorr5
4208       orig_w(6)=wcorr6
4209       orig_w(7)=wel_loc
4210       orig_w(8)=wturn3
4211       orig_w(9)=wturn4
4212       orig_w(10)=wturn6
4213       orig_w(11)=wang
4214       orig_w(13)=wtor
4215       orig_w(14)=wtor_d
4216       orig_w(15)=wvdwpp
4217
4218       wscp=0.D0
4219       welec=0.D0
4220       wcorr=0.D0
4221       wcorr5=0.D0
4222       wcorr6=0.D0
4223       wel_loc=0.D0
4224       wturn3=0.D0
4225       wturn4=0.D0
4226       wturn6=0.D0
4227       wang=0.D0
4228       wtor=0.D0
4229       wtor_d=0.D0
4230       wvdwpp=0.D0
4231
4232 !     Make sure n_start, n_end are within proper range
4233       if (n_start.lt.2) n_start=2
4234       if (n_end.gt.nres-1) n_end=nres-1
4235 !rc      if (n_start.lt.n_end) then
4236       if (n_start.gt.n_end) then
4237         n_start=2
4238         n_end=nres-1
4239       endif
4240
4241 !     Save the initial values of energy and coordinates
4242 !d      call chainbuild
4243 !d      call etotal(energy)
4244 !d      write (iout,*) 'start sc ene',energy(0)
4245 !d      call enerprint(energy(0))
4246 !rc      etot=energy(0)
4247        n_fun=0
4248 !rc      orig_e=etot
4249 !rc      cur_e=orig_e
4250 !rc      do i=2,nres-1
4251 !rc        cur_alph(i)=alph(i)
4252 !rc        cur_omeg(i)=omeg(i)
4253 !rc      enddo
4254
4255 !t      wtime=MPI_WTIME()
4256 !     Try (one by one) all specified residues, starting from a
4257 !     random position in sequence
4258 !     Stop early if the energy has decreased by at least e_drop
4259       n_tot=n_end-n_start+1
4260       n_first=iran_num(0,n_tot-1)
4261       n_steps=0
4262       n=0
4263 !rc      do while (n.lt.n_tot .and. orig_e-etot.lt.e_drop)
4264       do while (n.lt.n_tot)
4265         n_cur=n_start+mod(n_first+n,n_tot)
4266         call single_sc_move(n_cur,n_maxtry,e_drop,&
4267              n_steps,n_fun,etot)
4268 !elwrite(iout,*) "after msingle sc_move etot= ", etot
4269 !     If a lower energy was found, update the current structure...
4270 !rc        if (etot.lt.cur_e) then
4271 !rc          cur_e=etot
4272 !rc          do i=2,nres-1
4273 !rc            cur_alph(i)=alph(i)
4274 !rc            cur_omeg(i)=omeg(i)
4275 !rc          enddo
4276 !rc        else
4277 !     ...else revert to the previous one
4278 !rc          etot=cur_e
4279 !rc          do i=2,nres-1
4280 !rc            alph(i)=cur_alph(i)
4281 !rc            omeg(i)=cur_omeg(i)
4282 !rc          enddo
4283 !rc        endif
4284         n=n+1
4285 !d
4286 !d      call chainbuild
4287 !d      call etotal(energy)
4288 !d      print *,'running',n,energy(0)
4289       enddo
4290
4291 !d      call chainbuild
4292 !d      call etotal(energy)
4293 !d      write (iout,*) 'end   sc ene',energy(0)
4294
4295 !     Put the original weights back to calculate the full energy
4296       wscp=orig_w(2)
4297       welec=orig_w(3)
4298       wcorr=orig_w(4)
4299       wcorr5=orig_w(5)
4300       wcorr6=orig_w(6)
4301       wel_loc=orig_w(7)
4302       wturn3=orig_w(8)
4303       wturn4=orig_w(9)
4304       wturn6=orig_w(10)
4305       wang=orig_w(11)
4306       wtor=orig_w(13)
4307       wtor_d=orig_w(14)
4308       wvdwpp=orig_w(15)
4309
4310 !rc      n_fun=n_fun+1
4311 !t      write (iout,*) 'sc_local time= ',MPI_WTIME()-wtime
4312       return
4313       end subroutine sc_move
4314 !-----------------------------------------------------------------------------
4315       subroutine single_sc_move(res_pick,n_maxtry,e_drop,n_steps,n_fun,e_sc)
4316
4317 !     Perturb one side-chain (res_pick) and minimize the
4318 !     neighbouring region, keeping all CA's and non-neighbouring
4319 !     side-chains fixed
4320 !     Try until e_drop energy improvement is achieved, or n_maxtry
4321 !     attempts have been made
4322 !     At the start, e_sc should contain the side-chain-only energy(0)
4323 !     nsteps and nfun for this move are ADDED to n_steps and n_fun
4324 !rc      implicit none
4325       use energy, only: esc
4326       use geometry, only:dist
4327 !     Includes
4328 !      implicit real*8 (a-h,o-z)
4329 !      include 'DIMENSIONS'
4330 !      include 'COMMON.VAR'
4331 !      include 'COMMON.INTERACT'
4332 !      include 'COMMON.CHAIN'
4333 !      include 'COMMON.MINIM'
4334 !      include 'COMMON.FFIELD'
4335 !      include 'COMMON.IOUNITS'
4336
4337 !     External functions
4338 !el      double precision dist
4339 !el      external dist
4340
4341 !     Input arguments
4342       integer :: res_pick,n_maxtry
4343       real(kind=8) :: e_drop
4344
4345 !     Input/Output arguments
4346       integer :: n_steps,n_fun
4347       real(kind=8) :: e_sc
4348
4349 !     Local variables
4350       logical :: fail
4351       integer :: i,j
4352       integer :: nres_moved
4353       integer :: iretcode,loc_nfun,orig_maxfun,n_try
4354       real(kind=8) :: sc_dist,sc_dist_cutoff
4355 !      real(kind=8) :: energy_(0:n_ene)
4356       real(kind=8) :: evdw,escloc,orig_e,cur_e
4357       real(kind=8) :: cur_alph(2:nres-1),cur_omeg(2:nres-1)
4358       real(kind=8) :: var(6*nres)       !(maxvar) (maxvar=6*maxres)
4359
4360       real(kind=8) :: orig_theta(1:nres),orig_phi(1:nres),&
4361            orig_alph(1:nres),orig_omeg(1:nres)
4362
4363 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4364 !     Define what is meant by "neighbouring side-chain"
4365       sc_dist_cutoff=5.0D0
4366
4367 !     Don't do glycine or ends
4368       i=itype(res_pick,1)
4369       if (i.eq.10 .or. i.eq.ntyp1 .or. molnum(res_pick).eq.5) return
4370
4371 !     Freeze everything (later will relax only selected side-chains)
4372       mask_r=.true.
4373       do i=1,nres
4374         mask_phi(i)=0
4375         mask_theta(i)=0
4376         mask_side(i)=0
4377       enddo
4378
4379 !     Find the neighbours of the side-chain to move
4380 !     and save initial variables
4381 !rc      orig_e=e_sc
4382 !rc      cur_e=orig_e
4383       nres_moved=0
4384       do i=2,nres-1
4385 !     Don't do glycine (itype(j,1)==10)
4386         if ((itype(i,1).ne.10).and.(itype(i,1).ne.ntyp1) &
4387         .and.(molnum(i).ne.5)) then
4388           sc_dist=dist(nres+i,nres+res_pick)
4389         else
4390           sc_dist=sc_dist_cutoff
4391         endif
4392         if (sc_dist.lt.sc_dist_cutoff) then
4393           nres_moved=nres_moved+1
4394           mask_side(i)=1
4395           cur_alph(i)=alph(i)
4396           cur_omeg(i)=omeg(i)
4397         endif
4398       enddo
4399       write(iout,*) 'Warning calling chainbuild'
4400       call chainbuild
4401       call egb1(evdw)
4402       call esc(escloc)
4403 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4404 !elwrite(iout,*) "in sinle wsc=",wsc,"evdw",evdw,"wscloc",wscloc,"escloc",escloc
4405       e_sc=wsc*evdw+wscloc*escloc
4406 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4407 !d      call etotal(energy)
4408 !d      print *,'new       ',(energy(k),k=0,n_ene)
4409       orig_e=e_sc
4410       cur_e=orig_e
4411
4412       n_try=0
4413       do while (n_try.lt.n_maxtry .and. orig_e-cur_e.lt.e_drop)
4414 !     Move the selected residue (don't worry if it fails)
4415         call gen_side(iabs(itype(res_pick,molnum(res_pick))),theta(res_pick+1),&
4416              alph(res_pick),omeg(res_pick),fail,molnum(res_pick))
4417
4418 !     Minimize the side-chains starting from the new arrangement
4419         call geom_to_var(nvar,var)
4420         orig_maxfun=maxfun
4421         maxfun=7
4422
4423 !rc        do i=1,nres
4424 !rc          orig_theta(i)=theta(i)
4425 !rc          orig_phi(i)=phi(i)
4426 !rc          orig_alph(i)=alph(i)
4427 !rc          orig_omeg(i)=omeg(i)
4428 !rc        enddo
4429
4430 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4431         call minimize_sc1(e_sc,var,iretcode,loc_nfun)
4432         
4433 !elwrite(iout,*) "in sinle etot/ e_sc",e_sc
4434 !v        write(*,'(2i3,2f12.5,2i3)') 
4435 !v     &       res_pick,nres_moved,orig_e,e_sc-cur_e,
4436 !v     &       iretcode,loc_nfun
4437
4438 !$$$        if (iretcode.eq.8) then
4439 !$$$          write(iout,*)'Coordinates just after code 8'
4440 !$$$          call chainbuild
4441 !$$$          call all_varout
4442 !$$$          call flush(iout)
4443 !$$$          do i=1,nres
4444 !$$$            theta(i)=orig_theta(i)
4445 !$$$            phi(i)=orig_phi(i)
4446 !$$$            alph(i)=orig_alph(i)
4447 !$$$            omeg(i)=orig_omeg(i)
4448 !$$$          enddo
4449 !$$$          write(iout,*)'Coordinates just before code 8'
4450 !$$$          call chainbuild
4451 !$$$          call all_varout
4452 !$$$          call flush(iout)
4453 !$$$        endif
4454
4455         n_fun=n_fun+loc_nfun
4456         maxfun=orig_maxfun
4457         call var_to_geom(nvar,var)
4458
4459 !     If a lower energy was found, update the current structure...
4460         if (e_sc.lt.cur_e) then
4461 !v              call chainbuild
4462 !v              call etotal(energy)
4463 !d              call egb1(evdw)
4464 !d              call esc(escloc)
4465 !d              e_sc1=wsc*evdw+wscloc*escloc
4466 !d              print *,'     new',e_sc1,energy(0)
4467 !v              print *,'new       ',energy(0)
4468 !d              call enerprint(energy(0))
4469           cur_e=e_sc
4470           do i=2,nres-1
4471             if (mask_side(i).eq.1) then
4472               cur_alph(i)=alph(i)
4473               cur_omeg(i)=omeg(i)
4474             endif
4475           enddo
4476         else
4477 !     ...else revert to the previous one
4478           e_sc=cur_e
4479           do i=2,nres-1
4480             if (mask_side(i).eq.1) then
4481               alph(i)=cur_alph(i)
4482               omeg(i)=cur_omeg(i)
4483             endif
4484           enddo
4485         endif
4486         n_try=n_try+1
4487
4488       enddo
4489       n_steps=n_steps+n_try
4490
4491 !     Reset the minimization mask_r to false
4492       mask_r=.false.
4493
4494       return
4495       end subroutine single_sc_move
4496 !-----------------------------------------------------------------------------
4497       subroutine sc_minimize(etot,iretcode,nfun)
4498
4499 !     Minimizes side-chains only, leaving backbone frozen
4500 !rc      implicit none
4501       use energy, only: etotal
4502 !     Includes
4503 !      implicit real*8 (a-h,o-z)
4504 !      include 'DIMENSIONS'
4505 !      include 'COMMON.VAR'
4506 !      include 'COMMON.CHAIN'
4507 !      include 'COMMON.FFIELD'
4508
4509 !     Output arguments
4510       real(kind=8) :: etot
4511       integer :: iretcode,nfun
4512
4513 !     Local variables
4514       integer :: i
4515       real(kind=8) :: orig_w(0:n_ene),energy_(0:n_ene)
4516       real(kind=8) :: var(6*nres)       !(maxvar)(maxvar=6*maxres)
4517
4518
4519 !     Set non side-chain weights to zero (minimization is faster)
4520 !     NOTE: e(2) does not actually depend on the side-chain, only CA
4521       orig_w(2)=wscp
4522       orig_w(3)=welec
4523       orig_w(4)=wcorr
4524       orig_w(5)=wcorr5
4525       orig_w(6)=wcorr6
4526       orig_w(7)=wel_loc
4527       orig_w(8)=wturn3
4528       orig_w(9)=wturn4
4529       orig_w(10)=wturn6
4530       orig_w(11)=wang
4531       orig_w(13)=wtor
4532       orig_w(14)=wtor_d
4533
4534       wscp=0.D0
4535       welec=0.D0
4536       wcorr=0.D0
4537       wcorr5=0.D0
4538       wcorr6=0.D0
4539       wel_loc=0.D0
4540       wturn3=0.D0
4541       wturn4=0.D0
4542       wturn6=0.D0
4543       wang=0.D0
4544       wtor=0.D0
4545       wtor_d=0.D0
4546
4547 !     Prepare to freeze backbone
4548       do i=1,nres
4549         mask_phi(i)=0
4550         mask_theta(i)=0
4551         mask_side(i)=1
4552       enddo
4553
4554 !     Minimize the side-chains
4555       mask_r=.true.
4556       call geom_to_var(nvar,var)
4557       call minimize(etot,var,iretcode,nfun)
4558       call var_to_geom(nvar,var)
4559       mask_r=.false.
4560
4561 !     Put the original weights back and calculate the full energy
4562       wscp=orig_w(2)
4563       welec=orig_w(3)
4564       wcorr=orig_w(4)
4565       wcorr5=orig_w(5)
4566       wcorr6=orig_w(6)
4567       wel_loc=orig_w(7)
4568       wturn3=orig_w(8)
4569       wturn4=orig_w(9)
4570       wturn6=orig_w(10)
4571       wang=orig_w(11)
4572       wtor=orig_w(13)
4573       wtor_d=orig_w(14)
4574       write(iout,*) 'Warning calling chainbuild'
4575       call chainbuild
4576       call etotal(energy_)
4577       etot=energy_(0)
4578
4579       return
4580       end subroutine sc_minimize
4581 !-----------------------------------------------------------------------------
4582       subroutine minimize_sc1(etot,x,iretcode,nfun)
4583
4584       use energy, only: func,gradient,fdum,etotal,enerprint
4585       use comm_srutu
4586 !      implicit real*8 (a-h,o-z)
4587 !      include 'DIMENSIONS'
4588       integer,parameter :: liv=60
4589       integer :: iretcode,nfun
4590 !      integer :: lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
4591 !      include 'COMMON.IOUNITS'
4592 !      include 'COMMON.VAR'
4593 !      include 'COMMON.GEO'
4594 !      include 'COMMON.MINIM'
4595 !el      integer :: icall
4596 !el      common /srutu/ icall
4597       integer,dimension(liv) :: iv                                               
4598       real(kind=8) :: minval    !,v(1:77+(6*nres)*(6*nres+17)/2)        !(1:lv)
4599       real(kind=8),dimension(6*nres) :: x,d,xx  !(maxvar) (maxvar=6*maxres)
4600       real(kind=8) :: energia(0:n_ene)
4601 !el      real(kind=8) :: fdum
4602 !      external gradient,fdum   !func,
4603 !      external func_restr1,grad_restr1
4604       logical :: not_done,change,reduce 
4605 !el      common /przechowalnia/ v
4606
4607       integer :: nvar_restr,lv,i,j
4608       integer :: idum(1)
4609       real(kind=8) :: rdum(1),etot      !,fdum
4610
4611       lv=(77+(6*nres)*(6*nres+17)/2) !(77+maxvar*(maxvar+17)/2)) (maxvar=6*maxres)
4612       if (.not. allocated(v)) allocate(v(1:lv))
4613
4614       call deflt(2,iv,liv,lv,v)                                         
4615 ! 12 means fresh start, dont call deflt                                 
4616       iv(1)=12                                                          
4617 ! max num of fun calls                                                  
4618       if (maxfun.eq.0) maxfun=500
4619       iv(17)=maxfun
4620 ! max num of iterations                                                 
4621       if (maxmin.eq.0) maxmin=1000
4622       iv(18)=maxmin
4623 ! controls output                                                       
4624       iv(19)=2                                                          
4625 ! selects output unit                                                   
4626 !     iv(21)=iout                                                       
4627       iv(21)=0
4628 ! 1 means to print out result                                           
4629       iv(22)=0                                                          
4630 ! 1 means to print out summary stats                                    
4631       iv(23)=0                                                          
4632 ! 1 means to print initial x and d                                      
4633       iv(24)=0                                                          
4634 ! min val for v(radfac) default is 0.1                                  
4635       v(24)=0.1D0                                                       
4636 ! max val for v(radfac) default is 4.0                                  
4637       v(25)=2.0D0                                                       
4638 !     v(25)=4.0D0                                                       
4639 ! check false conv if (act fnctn decrease) .lt. v(26)*(exp decrease)    
4640 ! the sumsl default is 0.1                                              
4641       v(26)=0.1D0
4642 ! false conv if (act fnctn decrease) .lt. v(34)                         
4643 ! the sumsl default is 100*machep                                       
4644       v(34)=v(34)/100.0D0                                               
4645 ! absolute convergence                                                  
4646       if (tolf.eq.0.0D0) tolf=1.0D-4
4647       v(31)=tolf
4648 ! relative convergence                                                  
4649       if (rtolf.eq.0.0D0) rtolf=1.0D-4
4650       v(32)=rtolf
4651 ! controls initial step size                                            
4652        v(35)=1.0D-1                                                    
4653 ! large vals of d correspond to small components of step                
4654       do i=1,nphi
4655         d(i)=1.0D-1
4656       enddo
4657       do i=nphi+1,nvar
4658         d(i)=1.0D-1
4659       enddo
4660 !elmask_r=.false.
4661       IF (mask_r) THEN
4662        call x2xx(x,xx,nvar_restr)
4663        call sumsl(nvar_restr,d,xx,func_restr1,grad_restr1,&
4664                           iv,liv,lv,v,idum,rdum,fdum)      
4665        call xx2x(x,xx)
4666       ELSE
4667        call sumsl(nvar,d,x,func,gradient,iv,liv,lv,v,idum,rdum,fdum)      
4668       ENDIF
4669 !el---------------------
4670 !      write (iout,'(/a)') &
4671 !        "Cartesian coordinates of the reference structure after SUMSL"
4672 !      write (iout,'(a,3(3x,a5),5x,3(3x,a5))') &
4673 !       "Residue","X(CA)","Y(CA)","Z(CA)","X(SC)","Y(SC)","Z(SC)"
4674 !      do i=1,nres
4675 !        write (iout,'(a3,1x,i3,3f8.3,5x,3f8.3)') &
4676 !          restyp(itype(i,1)),i,(c(j,i),j=1,3),&
4677 !          (c(j,i+nres),j=1,3)
4678 !      enddo
4679 !      call etotal(energia)
4680 !      call enerprint(energia)
4681 !el----------------------------
4682       etot=v(10)                                                      
4683       iretcode=iv(1)
4684       nfun=iv(6)
4685
4686       return
4687       end subroutine minimize_sc1
4688 !-----------------------------------------------------------------------------
4689       subroutine func_restr1(n,x,nf,f,uiparm,urparm,ufparm)
4690
4691       use comm_chu
4692       use energy, only: zerograd,esc,sc_grad
4693 !      implicit real*8 (a-h,o-z)
4694 !      include 'DIMENSIONS'
4695 !      include 'COMMON.DERIV'
4696 !      include 'COMMON.IOUNITS'
4697 !      include 'COMMON.GEO'
4698 !      include 'COMMON.FFIELD'
4699 !      include 'COMMON.INTERACT'
4700 !      include 'COMMON.TIME1'
4701       integer :: n,nf,i,j
4702 !el      common /chuju/ jjj
4703       real(kind=8) :: energia(0:n_ene),evdw,escloc
4704       real(kind=8) :: e1,e2,f
4705       real(kind=8),external :: ufparm                                                   
4706       integer :: uiparm(1)                                                 
4707       real(kind=8) :: urparm(1)                                                    
4708       real(kind=8),dimension(6*nres) :: x       !(maxvar) (maxvar=6*maxres)
4709       nfl=nf
4710       icg=mod(nf,2)+1
4711
4712 #ifdef OSF
4713 !     Intercept NaNs in the coordinates, before calling etotal
4714       x_sum=0.D0
4715       do i=1,n
4716         x_sum=x_sum+x(i)
4717       enddo
4718       FOUND_NAN=.false.
4719       if (x_sum.ne.x_sum) then
4720         write(iout,*)"   *** func_restr1 : Found NaN in coordinates"
4721         f=1.0D+73
4722         FOUND_NAN=.true.
4723         return
4724       endif
4725 #endif
4726
4727       call var_to_geom_restr(n,x)
4728       call zerograd
4729       write(iout,*) 'Warning calling chainbuild'
4730       call chainbuild
4731 !d    write (iout,*) 'ETOTAL called from FUNC'
4732       call egb1(evdw)
4733       call esc(escloc)
4734       f=wsc*evdw+wscloc*escloc
4735 !d      call etotal(energia(0))
4736 !d      f=wsc*energia(1)+wscloc*energia(12)
4737 !d      print *,f,evdw,escloc,energia(0)
4738 !
4739 ! Sum up the components of the Cartesian gradient.
4740 !
4741       do i=1,nct
4742         do j=1,3
4743           gradx(j,i,icg)=wsc*gvdwx(j,i)
4744         enddo
4745       enddo
4746
4747       return
4748       end subroutine func_restr1
4749 !-----------------------------------------------------------------------------
4750       subroutine grad_restr1(n,x,nf,g,uiparm,urparm,ufparm)
4751
4752       use energy, only: cartder,zerograd,esc,sc_grad
4753 !      implicit real*8 (a-h,o-z)
4754 !      include 'DIMENSIONS'
4755 !      include 'COMMON.CHAIN'
4756 !      include 'COMMON.DERIV'
4757 !      include 'COMMON.VAR'
4758 !      include 'COMMON.INTERACT'
4759 !      include 'COMMON.FFIELD'
4760 !      include 'COMMON.IOUNITS'
4761 !el      external ufparm
4762       integer :: i,j,k,ind,n,nf,uiparm(1)
4763       real(kind=8) :: f,urparm(1)
4764       real(kind=8),dimension(6*nres) :: x,g     !(maxvar) (maxvar=6*maxres)
4765       integer :: ig,igall,ij
4766       real(kind=8) :: gphii,gthetai,galphai,gomegai
4767       real(kind=8),external :: ufparm
4768
4769       icg=mod(nf,2)+1
4770       if (nf-nfl+1) 20,30,40
4771    20 call func_restr1(n,x,nf,f,uiparm,urparm,ufparm)
4772 !     write (iout,*) 'grad 20'
4773       if (nf.eq.0) return
4774       goto 40
4775    30 call var_to_geom_restr(n,x)
4776       write(iout,*) 'Warning calling chainbuild'
4777       call chainbuild 
4778 !
4779 ! Evaluate the derivatives of virtual bond lengths and SC vectors in variables.
4780 !
4781    40 call cartder
4782 !
4783 ! Convert the Cartesian gradient into internal-coordinate gradient.
4784 !
4785
4786       ig=0
4787       ind=nres-2                                                                    
4788       do i=2,nres-2                
4789        IF (mask_phi(i+2).eq.1) THEN                                             
4790         gphii=0.0D0                                                             
4791         do j=i+1,nres-1                                                         
4792           ind=ind+1                                 
4793           do k=1,3                                                              
4794             gphii=gphii+dcdv(k+3,ind)*gradc(k,j,icg)                            
4795             gphii=gphii+dxdv(k+3,ind)*gradx(k,j,icg)                           
4796           enddo                                                                 
4797         enddo                                                                   
4798         ig=ig+1
4799         g(ig)=gphii
4800        ELSE
4801         ind=ind+nres-1-i
4802        ENDIF
4803       enddo                                        
4804
4805
4806       ind=0
4807       do i=1,nres-2
4808        IF (mask_theta(i+2).eq.1) THEN
4809         ig=ig+1
4810         gthetai=0.0D0
4811         do j=i+1,nres-1
4812           ind=ind+1
4813           do k=1,3
4814             gthetai=gthetai+dcdv(k,ind)*gradc(k,j,icg)
4815             gthetai=gthetai+dxdv(k,ind)*gradx(k,j,icg)
4816           enddo
4817         enddo
4818         g(ig)=gthetai
4819        ELSE
4820         ind=ind+nres-1-i
4821        ENDIF
4822       enddo
4823
4824       do i=2,nres-1
4825         if (itype(i,1).ne.10) then
4826          IF (mask_side(i).eq.1) THEN
4827           ig=ig+1
4828           galphai=0.0D0
4829           do k=1,3
4830             galphai=galphai+dxds(k,i)*gradx(k,i,icg)
4831           enddo
4832           g(ig)=galphai
4833          ENDIF
4834         endif
4835       enddo
4836
4837       
4838       do i=2,nres-1
4839         if (itype(i,1).ne.10) then
4840          IF (mask_side(i).eq.1) THEN
4841           ig=ig+1
4842           gomegai=0.0D0
4843           do k=1,3
4844             gomegai=gomegai+dxds(k+3,i)*gradx(k,i,icg)
4845           enddo
4846           g(ig)=gomegai
4847          ENDIF
4848         endif
4849       enddo
4850
4851 !
4852 ! Add the components corresponding to local energy terms.
4853 !
4854
4855       ig=0
4856       igall=0
4857       do i=4,nres
4858         igall=igall+1
4859         if (mask_phi(i).eq.1) then
4860           ig=ig+1
4861           g(ig)=g(ig)+gloc(igall,icg)
4862         endif
4863       enddo
4864
4865       do i=3,nres
4866         igall=igall+1
4867         if (mask_theta(i).eq.1) then
4868           ig=ig+1
4869           g(ig)=g(ig)+gloc(igall,icg)
4870         endif
4871       enddo
4872      
4873       do ij=1,2
4874       do i=2,nres-1
4875         if (itype(i,1).ne.10) then
4876           igall=igall+1
4877           if (mask_side(i).eq.1) then
4878             ig=ig+1
4879             g(ig)=g(ig)+gloc(igall,icg)
4880           endif
4881         endif
4882       enddo
4883       enddo
4884
4885 !d      do i=1,ig
4886 !d        write (iout,'(a2,i5,a3,f25.8)') 'i=',i,' g=',g(i)
4887 !d      enddo
4888       return
4889       end subroutine  grad_restr1
4890 !-----------------------------------------------------------------------------
4891       subroutine egb1(evdw)
4892 !
4893 ! This subroutine calculates the interaction energy of nonbonded side chains
4894 ! assuming the Gay-Berne potential of interaction.
4895 !
4896       use calc_data
4897       use energy, only: sc_grad
4898 !      use control, only:stopx
4899 !      implicit real*8 (a-h,o-z)
4900 !      include 'DIMENSIONS'
4901 !      include 'COMMON.GEO'
4902 !      include 'COMMON.VAR'
4903 !      include 'COMMON.LOCAL'
4904 !      include 'COMMON.CHAIN'
4905 !      include 'COMMON.DERIV'
4906 !      include 'COMMON.NAMES'
4907 !      include 'COMMON.INTERACT'
4908 !      include 'COMMON.IOUNITS'
4909 !      include 'COMMON.CALC'
4910 !      include 'COMMON.CONTROL'
4911       logical :: lprn
4912       real(kind=8) :: evdw
4913 !el local variables
4914       integer :: iint,ind,itypi,itypi1,itypj
4915       real(kind=8) :: xi,yi,zi,rrij,sig,sig0ij,rij_shift,fac,e1,e2,&
4916                   sigm,epsi
4917 !elwrite(iout,*) "check evdw"
4918 !     print *,'Entering EGB nnt=',nnt,' nct=',nct,' expon=',expon
4919       evdw=0.0D0
4920       lprn=.false.
4921 !     if (icall.eq.0) lprn=.true.
4922       ind=0
4923       do i=iatsc_s,iatsc_e
4924
4925         itypi=iabs(itype(i,1))
4926         itypi1=iabs(itype(i+1,1))
4927         xi=c(1,nres+i)
4928         yi=c(2,nres+i)
4929         zi=c(3,nres+i)
4930         dxi=dc_norm(1,nres+i)
4931         dyi=dc_norm(2,nres+i)
4932         dzi=dc_norm(3,nres+i)
4933         dsci_inv=dsc_inv(itypi)
4934 !elwrite(iout,*) itypi,itypi1,xi,yi,zi,dxi,dyi,dzi,dsci_inv
4935 !
4936 ! Calculate SC interaction energy.
4937 !
4938         do iint=1,nint_gr(i)
4939           do j=istart(i,iint),iend(i,iint)
4940           IF (mask_side(j).eq.1.or.mask_side(i).eq.1) THEN
4941             ind=ind+1
4942             itypj=iabs(itype(j,1))
4943             dscj_inv=dsc_inv(itypj)
4944             sig0ij=sigma(itypi,itypj)
4945             chi1=chi(itypi,itypj)
4946             chi2=chi(itypj,itypi)
4947             chi12=chi1*chi2
4948             chip1=chip(itypi)
4949             chip2=chip(itypj)
4950             chip12=chip1*chip2
4951             alf1=alp(itypi)
4952             alf2=alp(itypj)
4953             alf12=0.5D0*(alf1+alf2)
4954 ! For diagnostics only!!!
4955 !           chi1=0.0D0
4956 !           chi2=0.0D0
4957 !           chi12=0.0D0
4958 !           chip1=0.0D0
4959 !           chip2=0.0D0
4960 !           chip12=0.0D0
4961 !           alf1=0.0D0
4962 !           alf2=0.0D0
4963 !           alf12=0.0D0
4964             xj=c(1,nres+j)-xi
4965             yj=c(2,nres+j)-yi
4966             zj=c(3,nres+j)-zi
4967             dxj=dc_norm(1,nres+j)
4968             dyj=dc_norm(2,nres+j)
4969             dzj=dc_norm(3,nres+j)
4970             rrij=1.0D0/(xj*xj+yj*yj+zj*zj)
4971             rij=dsqrt(rrij)
4972 ! Calculate angle-dependent terms of energy and contributions to their
4973 ! derivatives.
4974             call sc_angular
4975             sigsq=1.0D0/sigsq
4976             sig=sig0ij*dsqrt(sigsq)
4977             rij_shift=1.0D0/rij-sig+sig0ij
4978 ! I hate to put IF's in the loops, but here don't have another choice!!!!
4979             if (rij_shift.le.0.0D0) then
4980               evdw=1.0D20
4981 !d              write (iout,'(2(a3,i3,2x),17(0pf7.3))') &
4982 !d              restyp(itypi),i,restyp(itypj),j, &
4983 !d              rij_shift,1.0D0/rij,sig,sig0ij,sigsq,1-dsqrt(sigsq)
4984               return
4985             endif
4986             sigder=-sig*sigsq
4987 !---------------------------------------------------------------
4988             rij_shift=1.0D0/rij_shift 
4989             fac=rij_shift**expon
4990             e1=fac*fac*aa_aq(itypi,itypj)
4991             e2=fac*bb_aq(itypi,itypj)
4992             evdwij=eps1*eps2rt*eps3rt*(e1+e2)
4993             eps2der=evdwij*eps3rt
4994             eps3der=evdwij*eps2rt
4995             evdwij=evdwij*eps2rt*eps3rt
4996             evdw=evdw+evdwij
4997 !            if (wliptran.gt.0.0) print *,"WARNING eps_aq used!"
4998             if (lprn) then
4999             sigm=dabs(aa_aq(itypi,itypj)/bb_aq(itypi,itypj))**(1.0D0/6.0D0)
5000             epsi=bb_aq(itypi,itypj)**2/aa_aq(itypi,itypj)
5001 !d            write (iout,'(2(a3,i3,2x),17(0pf7.3))') &
5002 !d              restyp(itypi),i,restyp(itypj),j, &
5003 !d              epsi,sigm,chi1,chi2,chip1,chip2, &
5004 !d              eps1,eps2rt**2,eps3rt**2,sig,sig0ij, &
5005 !d              om1,om2,om12,1.0D0/rij,1.0D0/rij_shift, &
5006 !d              evdwij
5007             endif
5008
5009             if (energy_dec) write (iout,'(a6,2i5,0pf7.3)') &
5010                               'evdw',i,j,evdwij
5011
5012 ! Calculate gradient components.
5013             e1=e1*eps1*eps2rt**2*eps3rt**2
5014             fac=-expon*(e1+evdwij)*rij_shift
5015             sigder=fac*sigder
5016             fac=rij*fac
5017 ! Calculate the radial part of the gradient
5018             gg(1)=xj*fac
5019             gg(2)=yj*fac
5020             gg(3)=zj*fac
5021 ! Calculate angular part of the gradient.
5022
5023 !elwrite(iout,*) evdw
5024             call sc_grad
5025 !elwrite(iout,*) "evdw=",evdw,j,iint,i
5026           ENDIF
5027 !elwrite(iout,*) evdw
5028           enddo      ! j
5029 !elwrite(iout,*) evdw
5030         enddo        ! iint
5031 !elwrite(iout,*) evdw
5032       enddo          ! i
5033 !elwrite(iout,*) evdw,i
5034       end subroutine egb1
5035 !-----------------------------------------------------------------------------
5036 ! sumsld.f
5037 !-----------------------------------------------------------------------------
5038       subroutine sumsl(n,d,x,calcf,calcg,iv,liv,lv,v,uiparm,urparm,ufparm)
5039 !
5040 !  ***  minimize general unconstrained objective function using   ***
5041 !  ***  analytic gradient and hessian approx. from secant update  ***
5042 !
5043 !      use control
5044       integer :: n, liv, lv
5045       integer :: iv(liv), uiparm(1)
5046       real(kind=8) :: d(n), x(n), v(lv), urparm(1)
5047       real(kind=8),external :: ufparm !funtion name as an argument
5048
5049 !     dimension v(71 + n*(n+15)/2), uiparm(*), urparm(*)
5050       external :: calcf, calcg !subroutine name as an argument
5051 !
5052 !  ***  purpose  ***
5053 !
5054 !        this routine interacts with subroutine  sumit  in an attempt
5055 !     to find an n-vector  x*  that minimizes the (unconstrained)
5056 !     objective function computed by  calcf.  (often the  x*  found is
5057 !     a local minimizer rather than a global one.)
5058 !
5059 !--------------------------  parameter usage  --------------------------
5060 !
5061 ! n........ (input) the number of variables on which  f  depends, i.e.,
5062 !                  the number of components in  x.
5063 ! d........ (input/output) a scale vector such that  d(i)*x(i),
5064 !                  i = 1,2,...,n,  are all in comparable units.
5065 !                  d can strongly affect the behavior of sumsl.
5066 !                  finding the best choice of d is generally a trial-
5067 !                  and-error process.  choosing d so that d(i)*x(i)
5068 !                  has about the same value for all i often works well.
5069 !                  the defaults provided by subroutine deflt (see i
5070 !                  below) require the caller to supply d.
5071 ! x........ (input/output) before (initially) calling sumsl, the call-
5072 !                  er should set  x  to an initial guess at  x*.  when
5073 !                  sumsl returns,  x  contains the best point so far
5074 !                  found, i.e., the one that gives the least value so
5075 !                  far seen for  f(x).
5076 ! calcf.... (input) a subroutine that, given x, computes f(x).  calcf
5077 !                  must be declared external in the calling program.
5078 !                  it is invoked by
5079 !                       call calcf(n, x, nf, f, uiparm, urparm, ufparm)
5080 !                  when calcf is called, nf is the invocation
5081 !                  count for calcf.  nf is included for possible use
5082 !                  with calcg.  if x is out of bounds (e.g., if it
5083 !                  would cause overflow in computing f(x)), then calcf
5084 !                  should set nf to 0.  this will cause a shorter step
5085 !                  to be attempted.  (if x is in bounds, then calcf
5086 !                  should not change nf.)  the other parameters are as
5087 !                  described above and below.  calcf should not change
5088 !                  n, p, or x.
5089 ! calcg.... (input) a subroutine that, given x, computes g(x), the gra-
5090 !                  dient of f at x.  calcg must be declared external in
5091 !                  the calling program.  it is invoked by
5092 !                       call calcg(n, x, nf, g, uiparm, urparm, ufaprm)
5093 !                  when calcg is called, nf is the invocation
5094 !                  count for calcf at the time f(x) was evaluated.  the
5095 !                  x passed to calcg is usually the one passed to calcf
5096 !                  on either its most recent invocation or the one
5097 !                  prior to it.  if calcf saves intermediate results
5098 !                  for use by calcg, then it is possible to tell from
5099 !                  nf whether they are valid for the current x (or
5100 !                  which copy is valid if two copies are kept).  if g
5101 !                  cannot be computed at x, then calcg should set nf to
5102 !                  0.  in this case, sumsl will return with iv(1) = 65.
5103 !                  (if g can be computed at x, then calcg should not
5104 !                  changed nf.)  the other parameters to calcg are as
5105 !                  described above and below.  calcg should not change
5106 !                  n or x.
5107 ! iv....... (input/output) an integer value array of length liv (see
5108 !                  below) that helps control the sumsl algorithm and
5109 !                  that is used to store various intermediate quanti-
5110 !                  ties.  of particular interest are the initialization/
5111 !                  return code iv(1) and the entries in iv that control
5112 !                  printing and limit the number of iterations and func-
5113 !                  tion evaluations.  see the section on iv input
5114 !                  values below.
5115 ! liv...... (input) length of iv array.  must be at least 60.  if li
5116 !                  is too small, then sumsl returns with iv(1) = 15.
5117 !                  when sumsl returns, the smallest allowed value of
5118 !                  liv is stored in iv(lastiv) -- see the section on
5119 !                  iv output values below.  (this is intended for use
5120 !                  with extensions of sumsl that handle constraints.)
5121 ! lv....... (input) length of v array.  must be at least 71+n*(n+15)/2.
5122 !                  (at least 77+n*(n+17)/2 for smsno, at least
5123 !                  78+n*(n+12) for humsl).  if lv is too small, then
5124 !                  sumsl returns with iv(1) = 16.  when sumsl returns,
5125 !                  the smallest allowed value of lv is stored in
5126 !                  iv(lastv) -- see the section on iv output values
5127 !                  below.
5128 ! v........ (input/output) a floating-point value array of length l
5129 !                  (see below) that helps control the sumsl algorithm
5130 !                  and that is used to store various intermediate
5131 !                  quantities.  of particular interest are the entries
5132 !                  in v that limit the length of the first step
5133 !                  attempted (lmax0) and specify convergence tolerances
5134 !                  (afctol, lmaxs, rfctol, sctol, xctol, xftol).
5135 ! uiparm... (input) user integer parameter array passed without change
5136 !                  to calcf and calcg.
5137 ! urparm... (input) user floating-point parameter array passed without
5138 !                  change to calcf and calcg.
5139 ! ufparm... (input) user external subroutine or function passed without
5140 !                  change to calcf and calcg.
5141 !
5142 !  ***  iv input values (from subroutine deflt)  ***
5143 !
5144 ! iv(1)...  on input, iv(1) should have a value between 0 and 14......
5145 !             0 and 12 mean this is a fresh start.  0 means that
5146 !                  deflt(2, iv, liv, lv, v)
5147 !             is to be called to provide all default values to iv and
5148 !             v.  12 (the value that deflt assigns to iv(1)) means the
5149 !             caller has already called deflt and has possibly changed
5150 !             some iv and/or v entries to non-default values.
5151 !             13 means deflt has been called and that sumsl (and
5152 !             sumit) should only do their storage allocation.  that is,
5153 !             they should set the output components of iv that tell
5154 !             where various subarrays arrays of v begin, such as iv(g)
5155 !             (and, for humsl and humit only, iv(dtol)), and return.
5156 !             14 means that a storage has been allocated (by a call
5157 !             with iv(1) = 13) and that the algorithm should be
5158 !             started.  when called with iv(1) = 13, sumsl returns
5159 !             iv(1) = 14 unless liv or lv is too small (or n is not
5160 !             positive).  default = 12.
5161 ! iv(inith).... iv(25) tells whether the hessian approximation h should
5162 !             be initialized.  1 (the default) means sumit should
5163 !             initialize h to the diagonal matrix whose i-th diagonal
5164 !             element is d(i)**2.  0 means the caller has supplied a
5165 !             cholesky factor  l  of the initial hessian approximation
5166 !             h = l*(l**t)  in v, starting at v(iv(lmat)) = v(iv(42))
5167 !             (and stored compactly by rows).  note that iv(lmat) may
5168 !             be initialized by calling sumsl with iv(1) = 13 (see
5169 !             the iv(1) discussion above).  default = 1.
5170 ! iv(mxfcal)... iv(17) gives the maximum number of function evaluations
5171 !             (calls on calcf) allowed.  if this number does not suf-
5172 !             fice, then sumsl returns with iv(1) = 9.  default = 200.
5173 ! iv(mxiter)... iv(18) gives the maximum number of iterations allowed.
5174 !             it also indirectly limits the number of gradient evalua-
5175 !             tions (calls on calcg) to iv(mxiter) + 1.  if iv(mxiter)
5176 !             iterations do not suffice, then sumsl returns with
5177 !             iv(1) = 10.  default = 150.
5178 ! iv(outlev)... iv(19) controls the number and length of iteration sum-
5179 !             mary lines printed (by itsum).  iv(outlev) = 0 means do
5180 !             not print any summary lines.  otherwise, print a summary
5181 !             line after each abs(iv(outlev)) iterations.  if iv(outlev)
5182 !             is positive, then summary lines of length 78 (plus carri-
5183 !             age control) are printed, including the following...  the
5184 !             iteration and function evaluation counts, f = the current
5185 !             function value, relative difference in function values
5186 !             achieved by the latest step (i.e., reldf = (f0-v(f))/f01,
5187 !             where f01 is the maximum of abs(v(f)) and abs(v(f0)) and
5188 !             v(f0) is the function value from the previous itera-
5189 !             tion), the relative function reduction predicted for the
5190 !             step just taken (i.e., preldf = v(preduc) / f01, where
5191 !             v(preduc) is described below), the scaled relative change
5192 !             in x (see v(reldx) below), the step parameter for the
5193 !             step just taken (stppar = 0 means a full newton step,
5194 !             between 0 and 1 means a relaxed newton step, between 1
5195 !             and 2 means a double dogleg step, greater than 2 means
5196 !             a scaled down cauchy step -- see subroutine dbldog), the
5197 !             2-norm of the scale vector d times the step just taken
5198 !             (see v(dstnrm) below), and npreldf, i.e.,
5199 !             v(nreduc)/f01, where v(nreduc) is described below -- if
5200 !             npreldf is positive, then it is the relative function
5201 !             reduction predicted for a newton step (one with
5202 !             stppar = 0).  if npreldf is negative, then it is the
5203 !             negative of the relative function reduction predicted
5204 !             for a step computed with step bound v(lmaxs) for use in
5205 !             testing for singular convergence.
5206 !                  if iv(outlev) is negative, then lines of length 50
5207 !             are printed, including only the first 6 items listed
5208 !             above (through reldx).
5209 !             default = 1.
5210 ! iv(parprt)... iv(20) = 1 means print any nondefault v values on a
5211 !             fresh start or any changed v values on a restart.
5212 !             iv(parprt) = 0 means skip this printing.  default = 1.
5213 ! iv(prunit)... iv(21) is the output unit number on which all printing
5214 !             is done.  iv(prunit) = 0 means suppress all printing.
5215 !             default = standard output unit (unit 6 on most systems).
5216 ! iv(solprt)... iv(22) = 1 means print out the value of x returned (as
5217 !             well as the gradient and the scale vector d).
5218 !             iv(solprt) = 0 means skip this printing.  default = 1.
5219 ! iv(statpr)... iv(23) = 1 means print summary statistics upon return-
5220 !             ing.  these consist of the function value, the scaled
5221 !             relative change in x caused by the most recent step (see
5222 !             v(reldx) below), the number of function and gradient
5223 !             evaluations (calls on calcf and calcg), and the relative
5224 !             function reductions predicted for the last step taken and
5225 !             for a newton step (or perhaps a step bounded by v(lmaxs)
5226 !             -- see the descriptions of preldf and npreldf under
5227 !             iv(outlev) above).
5228 !             iv(statpr) = 0 means skip this printing.
5229 !             iv(statpr) = -1 means skip this printing as well as that
5230 !             of the one-line termination reason message.  default = 1.
5231 ! iv(x0prt).... iv(24) = 1 means print the initial x and scale vector d
5232 !             (on a fresh start only).  iv(x0prt) = 0 means skip this
5233 !             printing.  default = 1.
5234 !
5235 !  ***  (selected) iv output values  ***
5236 !
5237 ! iv(1)........ on output, iv(1) is a return code....
5238 !             3 = x-convergence.  the scaled relative difference (see
5239 !                  v(reldx)) between the current parameter vector x and
5240 !                  a locally optimal parameter vector is very likely at
5241 !                  most v(xctol).
5242 !             4 = relative function convergence.  the relative differ-
5243 !                  ence between the current function value and its lo-
5244 !                  cally optimal value is very likely at most v(rfctol).
5245 !             5 = both x- and relative function convergence (i.e., the
5246 !                  conditions for iv(1) = 3 and iv(1) = 4 both hold).
5247 !             6 = absolute function convergence.  the current function
5248 !                  value is at most v(afctol) in absolute value.
5249 !             7 = singular convergence.  the hessian near the current
5250 !                  iterate appears to be singular or nearly so, and a
5251 !                  step of length at most v(lmaxs) is unlikely to yield
5252 !                  a relative function decrease of more than v(sctol).
5253 !             8 = false convergence.  the iterates appear to be converg-
5254 !                  ing to a noncritical point.  this may mean that the
5255 !                  convergence tolerances (v(afctol), v(rfctol),
5256 !                  v(xctol)) are too small for the accuracy to which
5257 !                  the function and gradient are being computed, that
5258 !                  there is an error in computing the gradient, or that
5259 !                  the function or gradient is discontinuous near x.
5260 !             9 = function evaluation limit reached without other con-
5261 !                  vergence (see iv(mxfcal)).
5262 !            10 = iteration limit reached without other convergence
5263 !                  (see iv(mxiter)).
5264 !            11 = stopx returned .true. (external interrupt).  see the
5265 !                  usage notes below.
5266 !            14 = storage has been allocated (after a call with
5267 !                  iv(1) = 13).
5268 !            17 = restart attempted with n changed.
5269 !            18 = d has a negative component and iv(dtype) .le. 0.
5270 !            19...43 = v(iv(1)) is out of range.
5271 !            63 = f(x) cannot be computed at the initial x.
5272 !            64 = bad parameters passed to assess (which should not
5273 !                  occur).
5274 !            65 = the gradient could not be computed at x (see calcg
5275 !                  above).
5276 !            67 = bad first parameter to deflt.
5277 !            80 = iv(1) was out of range.
5278 !            81 = n is not positive.
5279 ! iv(g)........ iv(28) is the starting subscript in v of the current
5280 !             gradient vector (the one corresponding to x).
5281 ! iv(lastiv)... iv(44) is the least acceptable value of liv.  (it is
5282 !             only set if liv is at least 44.)
5283 ! iv(lastv).... iv(45) is the least acceptable value of lv.  (it is
5284 !             only set if liv is large enough, at least iv(lastiv).)
5285 ! iv(nfcall)... iv(6) is the number of calls so far made on calcf (i.e.,
5286 !             function evaluations).
5287 ! iv(ngcall)... iv(30) is the number of gradient evaluations (calls on
5288 !             calcg).
5289 ! iv(niter).... iv(31) is the number of iterations performed.
5290 !
5291 !  ***  (selected) v input values (from subroutine deflt)  ***
5292 !
5293 ! v(bias)..... v(43) is the bias parameter used in subroutine dbldog --
5294 !             see that subroutine for details.  default = 0.8.
5295 ! v(afctol)... v(31) is the absolute function convergence tolerance.
5296 !             if sumsl finds a point where the function value is less
5297 !             than v(afctol) in absolute value, and if sumsl does not
5298 !             return with iv(1) = 3, 4, or 5, then it returns with
5299 !             iv(1) = 6.  this test can be turned off by setting
5300 !             v(afctol) to zero.  default = max(10**-20, machep**2),
5301 !             where machep is the unit roundoff.
5302 ! v(dinit).... v(38), if nonnegative, is the value to which the scale
5303 !             vector d is initialized.  default = -1.
5304 ! v(lmax0).... v(35) gives the maximum 2-norm allowed for d times the
5305 !             very first step that sumsl attempts.  this parameter can
5306 !             markedly affect the performance of sumsl.
5307 ! v(lmaxs).... v(36) is used in testing for singular convergence -- if
5308 !             the function reduction predicted for a step of length
5309 !             bounded by v(lmaxs) is at most v(sctol) * abs(f0), where
5310 !             f0  is the function value at the start of the current
5311 !             iteration, and if sumsl does not return with iv(1) = 3,
5312 !             4, 5, or 6, then it returns with iv(1) = 7.  default = 1.
5313 ! v(rfctol)... v(32) is the relative function convergence tolerance.
5314 !             if the current model predicts a maximum possible function
5315 !             reduction (see v(nreduc)) of at most v(rfctol)*abs(f0)
5316 !             at the start of the current iteration, where  f0  is the
5317 !             then current function value, and if the last step attempt-
5318 !             ed achieved no more than twice the predicted function
5319 !             decrease, then sumsl returns with iv(1) = 4 (or 5).
5320 !             default = max(10**-10, machep**(2/3)), where machep is
5321 !             the unit roundoff.
5322 ! v(sctol).... v(37) is the singular convergence tolerance -- see the
5323 !             description of v(lmaxs) above.
5324 ! v(tuner1)... v(26) helps decide when to check for false convergence.
5325 !             this is done if the actual function decrease from the
5326 !             current step is no more than v(tuner1) times its predict-
5327 !             ed value.  default = 0.1.
5328 ! v(xctol).... v(33) is the x-convergence tolerance.  if a newton step
5329 !             (see v(nreduc)) is tried that has v(reldx) .le. v(xctol)
5330 !             and if this step yields at most twice the predicted func-
5331 !             tion decrease, then sumsl returns with iv(1) = 3 (or 5).
5332 !             (see the description of v(reldx) below.)
5333 !             default = machep**0.5, where machep is the unit roundoff.
5334 ! v(xftol).... v(34) is the false convergence tolerance.  if a step is
5335 !             tried that gives no more than v(tuner1) times the predict-
5336 !             ed function decrease and that has v(reldx) .le. v(xftol),
5337 !             and if sumsl does not return with iv(1) = 3, 4, 5, 6, or
5338 !             7, then it returns with iv(1) = 8.  (see the description
5339 !             of v(reldx) below.)  default = 100*machep, where
5340 !             machep is the unit roundoff.
5341 ! v(*)........ deflt supplies to v a number of tuning constants, with
5342 !             which it should ordinarily be unnecessary to tinker.  see
5343 !             section 17 of version 2.2 of the nl2sol usage summary
5344 !             (i.e., the appendix to ref. 1) for details on v(i),
5345 !             i = decfac, incfac, phmnfc, phmxfc, rdfcmn, rdfcmx,
5346 !             tuner2, tuner3, tuner4, tuner5.
5347 !
5348 !  ***  (selected) v output values  ***
5349 !
5350 ! v(dgnorm)... v(1) is the 2-norm of (diag(d)**-1)*g, where g is the
5351 !             most recently computed gradient.
5352 ! v(dstnrm)... v(2) is the 2-norm of diag(d)*step, where step is the
5353 !             current step.
5354 ! v(f)........ v(10) is the current function value.
5355 ! v(f0)....... v(13) is the function value at the start of the current
5356 !             iteration.
5357 ! v(nreduc)... v(6), if positive, is the maximum function reduction
5358 !             possible according to the current model, i.e., the func-
5359 !             tion reduction predicted for a newton step (i.e.,
5360 !             step = -h**-1 * g,  where  g  is the current gradient and
5361 !             h is the current hessian approximation).
5362 !                  if v(nreduc) is negative, then it is the negative of
5363 !             the function reduction predicted for a step computed with
5364 !             a step bound of v(lmaxs) for use in testing for singular
5365 !             convergence.
5366 ! v(preduc)... v(7) is the function reduction predicted (by the current
5367 !             quadratic model) for the current step.  this (divided by
5368 !             v(f0)) is used in testing for relative function
5369 !             convergence.
5370 ! v(reldx).... v(17) is the scaled relative change in x caused by the
5371 !             current step, computed as
5372 !                  max(abs(d(i)*(x(i)-x0(i)), 1 .le. i .le. p) /
5373 !                     max(d(i)*(abs(x(i))+abs(x0(i))), 1 .le. i .le. p),
5374 !             where x = x0 + step.
5375 !
5376 !-------------------------------  notes  -------------------------------
5377 !
5378 !  ***  algorithm notes  ***
5379 !
5380 !        this routine uses a hessian approximation computed from the
5381 !     bfgs update (see ref 3).  only a cholesky factor of the hessian
5382 !     approximation is stored, and this is updated using ideas from
5383 !     ref. 4.  steps are computed by the double dogleg scheme described
5384 !     in ref. 2.  the steps are assessed as in ref. 1.
5385 !
5386 !  ***  usage notes  ***
5387 !
5388 !        after a return with iv(1) .le. 11, it is possible to restart,
5389 !     i.e., to change some of the iv and v input values described above
5390 !     and continue the algorithm from the point where it was interrupt-
5391 !     ed.  iv(1) should not be changed, nor should any entries of i
5392 !     and v other than the input values (those supplied by deflt).
5393 !        those who do not wish to write a calcg which computes the
5394 !     gradient analytically should call smsno rather than sumsl.
5395 !     smsno uses finite differences to compute an approximate gradient.
5396 !        those who would prefer to provide f and g (the function and
5397 !     gradient) by reverse communication rather than by writing subrou-
5398 !     tines calcf and calcg may call on sumit directly.  see the com-
5399 !     ments at the beginning of sumit.
5400 !        those who use sumsl interactively may wish to supply their
5401 !     own stopx function, which should return .true. if the break key
5402 !     has been pressed since stopx was last invoked.  this makes it
5403 !     possible to externally interrupt sumsl (which will return with
5404 !     iv(1) = 11 if stopx returns .true.).
5405 !        storage for g is allocated at the end of v.  thus the caller
5406 !     may make v longer than specified above and may allow calcg to use
5407 !     elements of g beyond the first n as scratch storage.
5408 !
5409 !  ***  portability notes  ***
5410 !
5411 !        the sumsl distribution tape contains both single- and double-
5412 !     precision versions of the sumsl source code, so it should be un-
5413 !     necessary to change precisions.
5414 !        only the functions imdcon and rmdcon contain machine-dependent
5415 !     constants.  to change from one machine to another, it should
5416 !     suffice to change the (few) relevant lines in these functions.
5417 !        intrinsic functions are explicitly declared.  on certain com-
5418 !     puters (e.g. univac), it may be necessary to comment out these
5419 !     declarations.  so that this may be done automatically by a simple
5420 !     program, such declarations are preceded by a comment having c/+
5421 !     in columns 1-3 and blanks in columns 4-72 and are followed by
5422 !     a comment having c/ in columns 1 and 2 and blanks in columns 3-72.
5423 !        the sumsl source code is expressed in 1966 ansi standard
5424 !     fortran.  it may be converted to fortran 77 by commenting out all
5425 !     lines that fall between a line having c/6 in columns 1-3 and a
5426 !     line having c/7 in columns 1-3 and by removing (i.e., replacing
5427 !     by a blank) the c in column 1 of the lines that follow the c/7
5428 !     line and precede a line having c/ in columns 1-2 and blanks in
5429 !     columns 3-72.  these changes convert some data statements into
5430 !     parameter statements, convert some variables from real to
5431 !     character*4, and make the data statements that initialize these
5432 !     variables use character strings delimited by primes instead
5433 !     of hollerith constants.  (such variables and data statements
5434 !     appear only in modules itsum and parck.  parameter statements
5435 !     appear nearly everywhere.)  these changes also add save state-
5436 !     ments for variables given machine-dependent constants by rmdcon.
5437 !
5438 !  ***  references  ***
5439 !
5440 ! 1.  dennis, j.e., gay, d.m., and welsch, r.e. (1981), algorithm 573 --
5441 !             an adaptive nonlinear least-squares algorithm, acm trans.
5442 !             math. software 7, pp. 369-383.
5443 !
5444 ! 2.  dennis, j.e., and mei, h.h.w. (1979), two new unconstrained opti-
5445 !             mization algorithms which use function and gradient
5446 !             values, j. optim. theory applic. 28, pp. 453-482.
5447 !
5448 ! 3.  dennis, j.e., and more, j.j. (1977), quasi-newton methods, motiva-
5449 !             tion and theory, siam rev. 19, pp. 46-89.
5450 !
5451 ! 4.  goldfarb, d. (1976), factorized variable metric methods for uncon-
5452 !             strained optimization, math. comput. 30, pp. 796-811.
5453 !
5454 !  ***  general  ***
5455 !
5456 !     coded by david m. gay (winter 1980).  revised summer 1982.
5457 !     this subroutine was written in connection with research
5458 !     supported in part by the national science foundation under
5459 !     grants mcs-7600324, dcr75-10143, 76-14311dss, mcs76-11989,
5460 !     and mcs-7906671.
5461 !.
5462 !
5463 !----------------------------  declarations  ---------------------------
5464 !
5465 !el      external deflt, sumit
5466 !
5467 ! deflt... supplies default iv and v input components.
5468 ! sumit... reverse-communication routine that carries out sumsl algo-
5469 !             rithm.
5470 !
5471       integer :: g1, iv1, nf
5472       real(kind=8) :: f
5473 !
5474 !  ***  subscripts for iv   ***
5475 !
5476 !el      integer nextv, nfcall, nfgcal, g, toobig, vneed
5477 !
5478 !/6
5479 !     data nextv/47/, nfcall/6/, nfgcal/7/, g/28/, toobig/2/, vneed/4/
5480 !/7
5481       integer,parameter :: nextv=47, nfcall=6, nfgcal=7, g=28,&
5482                            toobig=2, vneed=4
5483 !/
5484 !
5485 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
5486 !
5487 !elwrite(iout,*) "in sumsl"
5488       if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
5489       iv1 = iv(1)
5490       if (iv1 .eq. 12 .or. iv1 .eq. 13) iv(vneed) = iv(vneed) + n
5491       if (iv1 .eq. 14) go to 10
5492       if (iv1 .gt. 2 .and. iv1 .lt. 12) go to 10
5493       g1 = 1
5494       if (iv1 .eq. 12) iv(1) = 13
5495       go to 20
5496 !
5497  10   g1 = iv(g)
5498 !elwrite(iout,*) "in sumsl go to 10"
5499
5500 !
5501 !elwrite(iout,*) "in sumsl"
5502  20   call sumit(d, f, v(g1), iv, liv, lv, n, v, x)
5503 !elwrite(iout,*) "in sumsl, go to 20"
5504   
5505 !elwrite(iout,*) "in sumsl, go to 20, po sumit"
5506 !elwrite(iout,*) "in sumsl iv()", iv(1)-2
5507       if (iv(1) - 2) 30, 40, 50
5508 !
5509  30   nf = iv(nfcall)
5510 !elwrite(iout,*) "in sumsl iv",iv(nfcall)
5511       call calcf(n, x, nf, f, uiparm, urparm, ufparm)
5512 !elwrite(iout,*) "in sumsl"
5513       if (nf .le. 0) iv(toobig) = 1
5514       go to 20
5515 !
5516 !elwrite(iout,*) "in sumsl"
5517  40   call calcg(n, x, iv(nfgcal), v(g1), uiparm, urparm, ufparm)
5518 !elwrite(iout,*) "in sumsl"
5519       go to 20
5520 !
5521  50   if (iv(1) .ne. 14) go to 999
5522 !
5523 !  ***  storage allocation
5524 !
5525       iv(g) = iv(nextv)
5526       iv(nextv) = iv(g) + n
5527       if (iv1 .ne. 13) go to 10
5528 !elwrite(iout,*) "in sumsl"
5529 !
5530  999  return
5531 !  ***  last card of sumsl follows  ***
5532       end subroutine sumsl
5533 !-----------------------------------------------------------------------------
5534       subroutine sumit(d,fx,g,iv,liv,lv,n,v,x)
5535       
5536       use control, only:stopx
5537 !
5538 !  ***  carry out sumsl (unconstrained minimization) iterations, using
5539 !  ***  double-dogleg/bfgs steps.
5540 !
5541 !  ***  parameter declarations  ***
5542 !
5543       integer :: liv, lv, n
5544       integer :: iv(liv)
5545       real(kind=8) :: d(n), fx, g(n), v(lv), x(n)
5546 !
5547 !--------------------------  parameter usage  --------------------------
5548 !
5549 ! d.... scale vector.
5550 ! fx... function value.
5551 ! g.... gradient vector.
5552 ! iv... integer value array.
5553 ! liv.. length of iv (at least 60).
5554 ! lv... length of v (at least 71 + n*(n+13)/2).
5555 ! n.... number of variables (components in x and g).
5556 ! v.... floating-point value array.
5557 ! x.... vector of parameters to be optimized.
5558 !
5559 !  ***  discussion  ***
5560 !
5561 !        parameters iv, n, v, and x are the same as the corresponding
5562 !     ones to sumsl (which see), except that v can be shorter (since
5563 !     the part of v that sumsl uses for storing g is not needed).
5564 !     moreover, compared with sumsl, iv(1) may have the two additional
5565 !     output values 1 and 2, which are explained below, as is the use
5566 !     of iv(toobig) and iv(nfgcal).  the value iv(g), which is an
5567 !     output value from sumsl (and smsno), is not referenced by
5568 !     sumit or the subroutines it calls.
5569 !        fx and g need not have been initialized when sumit is called
5570 !     with iv(1) = 12, 13, or 14.
5571 !
5572 ! iv(1) = 1 means the caller should set fx to f(x), the function value
5573 !             at x, and call sumit again, having changed none of the
5574 !             other parameters.  an exception occurs if f(x) cannot be
5575 !             (e.g. if overflow would occur), which may happen because
5576 !             of an oversized step.  in this case the caller should set
5577 !             iv(toobig) = iv(2) to 1, which will cause sumit to ig-
5578 !             nore fx and try a smaller step.  the parameter nf that
5579 !             sumsl passes to calcf (for possible use by calcg) is a
5580 !             copy of iv(nfcall) = iv(6).
5581 ! iv(1) = 2 means the caller should set g to g(x), the gradient vector
5582 !             of f at x, and call sumit again, having changed none of
5583 !             the other parameters except possibly the scale vector d
5584 !             when iv(dtype) = 0.  the parameter nf that sumsl passes
5585 !             to calcg is iv(nfgcal) = iv(7).  if g(x) cannot be
5586 !             evaluated, then the caller may set iv(nfgcal) to 0, in
5587 !             which case sumit will return with iv(1) = 65.
5588 !.
5589 !  ***  general  ***
5590 !
5591 !     coded by david m. gay (december 1979).  revised sept. 1982.
5592 !     this subroutine was written in connection with research supported
5593 !     in part by the national science foundation under grants
5594 !     mcs-7600324 and mcs-7906671.
5595 !
5596 !        (see sumsl for references.)
5597 !
5598 !+++++++++++++++++++++++++++  declarations  ++++++++++++++++++++++++++++
5599 !
5600 !  ***  local variables  ***
5601 !
5602       integer :: dg1, dummy, g01, i, k, l, lstgst, nwtst1, step1,&
5603               temp1, w, x01, z
5604       real(kind=8) :: t
5605 !el      logical :: lstopx
5606 !
5607 !     ***  constants  ***
5608 !
5609 !el      real(kind=8) :: half, negone, one, onep2, zero
5610 !
5611 !  ***  no intrinsic functions  ***
5612 !
5613 !  ***  external functions and subroutines  ***
5614 !
5615 !el      external assst, dbdog, deflt, dotprd, itsum, litvmu, livmul,
5616 !el     1         ltvmul, lupdat, lvmul, parck, reldst, stopx, vaxpy,
5617 !el     2         vcopy, vscopy, vvmulp, v2norm, wzbfgs
5618 !el      logical stopx
5619 !el      real(kind=8) :: dotprd, reldst, v2norm
5620 !
5621 ! assst.... assesses candidate step.
5622 ! dbdog.... computes double-dogleg (candidate) step.
5623 ! deflt.... supplies default iv and v input components.
5624 ! dotprd... returns inner product of two vectors.
5625 ! itsum.... prints iteration summary and info on initial and final x.
5626 ! litvmu... multiplies inverse transpose of lower triangle times vector.
5627 ! livmul... multiplies inverse of lower triangle times vector.
5628 ! ltvmul... multiplies transpose of lower triangle times vector.
5629 ! lupdt.... updates cholesky factor of hessian approximation.
5630 ! lvmul.... multiplies lower triangle times vector.
5631 ! parck.... checks validity of input iv and v values.
5632 ! reldst... computes v(reldx) = relative step size.
5633 ! stopx.... returns .true. if the break key has been pressed.
5634 ! vaxpy.... computes scalar times one vector plus another.
5635 ! vcopy.... copies one vector to another.
5636 ! vscopy... sets all elements of a vector to a scalar.
5637 ! vvmulp... multiplies vector by vector raised to power (componentwise).
5638 ! v2norm... returns the 2-norm of a vector.
5639 ! wzbfgs... computes w and z for lupdat corresponding to bfgs update.
5640 !
5641 !  ***  subscripts for iv and v  ***
5642 !
5643 !el      integer afctol
5644 !el      integer cnvcod, dg, dgnorm, dinit, dstnrm, dst0, f, f0, fdif,
5645 !el     1        gthg, gtstep, g0, incfac, inith, irc, kagqt, lmat, lmax0,
5646 !el     2        lmaxs, mode, model, mxfcal, mxiter, nextv, nfcall, nfgcal,
5647 !el     3        ngcall, niter, nreduc, nwtstp, preduc, radfac, radinc,
5648 !el     4        radius, rad0, reldx, restor, step, stglim, stlstg, toobig,
5649 !el     5        tuner4, tuner5, vneed, xirc, x0
5650 !
5651 !  ***  iv subscript values  ***
5652 !
5653 !/6
5654 !     data cnvcod/55/, dg/37/, g0/48/, inith/25/, irc/29/, kagqt/33/,
5655 !    1     mode/35/, model/5/, mxfcal/17/, mxiter/18/, nfcall/6/,
5656 !    2     nfgcal/7/, ngcall/30/, niter/31/, nwtstp/34/, radinc/8/,
5657 !    3     restor/9/, step/40/, stglim/11/, stlstg/41/, toobig/2/,
5658 !    4     vneed/4/, xirc/13/, x0/43/
5659 !/7
5660       integer,parameter :: cnvcod=55, dg=37, g0=48, inith=25, irc=29, kagqt=33,&
5661                  mode=35, model=5, mxfcal=17, mxiter=18, nfcall=6,&
5662                  nfgcal=7, ngcall=30, niter=31, nwtstp=34, radinc=8,&
5663                  restor=9, step=40, stglim=11, stlstg=41, toobig=2,&
5664                  vneed=4, xirc=13, x0=43
5665 !/
5666 !
5667 !  ***  v subscript values  ***
5668 !
5669 !/6
5670 !     data afctol/31/
5671 !     data dgnorm/1/, dinit/38/, dstnrm/2/, dst0/3/, f/10/, f0/13/,
5672 !    1     fdif/11/, gthg/44/, gtstep/4/, incfac/23/, lmat/42/,
5673 !    2     lmax0/35/, lmaxs/36/, nextv/47/, nreduc/6/, preduc/7/,
5674 !    3     radfac/16/, radius/8/, rad0/9/, reldx/17/, tuner4/29/,
5675 !    4     tuner5/30/
5676 !/7
5677       integer,parameter :: afctol=31
5678       integer,parameter :: dgnorm=1, dinit=38, dstnrm=2, dst0=3, f=10, f0=13,&
5679                  fdif=11, gthg=44, gtstep=4, incfac=23, lmat=42,&
5680                  lmax0=35, lmaxs=36, nextv=47, nreduc=6, preduc=7,&
5681                  radfac=16, radius=8, rad0=9, reldx=17, tuner4=29,&
5682                  tuner5=30
5683 !/
5684 !
5685 !/6
5686 !     data half/0.5d+0/, negone/-1.d+0/, one/1.d+0/, onep2/1.2d+0/,
5687 !    1     zero/0.d+0/
5688 !/7
5689       real(kind=8),parameter :: half=0.5d+0, negone=-1.d+0, one=1.d+0,&
5690                  onep2=1.2d+0,zero=0.d+0
5691 !/
5692 !
5693 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
5694 !
5695 ! Following SAVE statement inserted.
5696       save l
5697       i = iv(1)
5698       if (i .eq. 1) go to 50
5699       if (i .eq. 2) go to 60
5700 !
5701 !  ***  check validity of iv and v input values  ***
5702 !
5703       if (iv(1) .eq. 0) call deflt(2, iv, liv, lv, v)
5704       if (iv(1) .eq. 12 .or. iv(1) .eq. 13) &
5705            iv(vneed) = iv(vneed) + n*(n+13)/2
5706       call parck(2, d, iv, liv, lv, n, v)
5707       i = iv(1) - 2
5708       if (i .gt. 12) go to 999
5709       go to (180, 180, 180, 180, 180, 180, 120, 90, 120, 10, 10, 20), i
5710 !
5711 !  ***  storage allocation  ***
5712 !
5713 10    l = iv(lmat)
5714       iv(x0) = l + n*(n+1)/2
5715       iv(step) = iv(x0) + n
5716       iv(stlstg) = iv(step) + n
5717       iv(g0) = iv(stlstg) + n
5718       iv(nwtstp) = iv(g0) + n
5719       iv(dg) = iv(nwtstp) + n
5720       iv(nextv) = iv(dg) + n
5721       if (iv(1) .ne. 13) go to 20
5722          iv(1) = 14
5723          go to 999
5724 !
5725 !  ***  initialization  ***
5726 !
5727  20   iv(niter) = 0
5728       iv(nfcall) = 1
5729       iv(ngcall) = 1
5730       iv(nfgcal) = 1
5731       iv(mode) = -1
5732       iv(model) = 1
5733       iv(stglim) = 1
5734       iv(toobig) = 0
5735       iv(cnvcod) = 0
5736       iv(radinc) = 0
5737       v(rad0) = zero
5738       if (v(dinit) .ge. zero) call vscopy(n, d, v(dinit))
5739       if (iv(inith) .ne. 1) go to 40
5740 !
5741 !     ***  set the initial hessian approximation to diag(d)**-2  ***
5742 !
5743          l = iv(lmat)
5744          call vscopy(n*(n+1)/2, v(l), zero)
5745          k = l - 1
5746          do 30 i = 1, n
5747               k = k + i
5748               t = d(i)
5749               if (t .le. zero) t = one
5750               v(k) = t
5751  30           continue
5752 !
5753 !  ***  compute initial function value  ***
5754 !
5755  40   iv(1) = 1
5756       go to 999
5757 !
5758  50   v(f) = fx
5759       if (iv(mode) .ge. 0) go to 180
5760       iv(1) = 2
5761       if (iv(toobig) .eq. 0) go to 999
5762          iv(1) = 63
5763          go to 300
5764 !
5765 !  ***  make sure gradient could be computed  ***
5766 !
5767  60   if (iv(nfgcal) .ne. 0) go to 70
5768          iv(1) = 65
5769          go to 300
5770 !
5771  70   dg1 = iv(dg)
5772       call vvmulp(n, v(dg1), g, d, -1)
5773       v(dgnorm) = v2norm(n, v(dg1))
5774 !
5775 !  ***  test norm of gradient  ***
5776 !
5777       if (v(dgnorm) .gt. v(afctol)) go to 75
5778       iv(irc) = 10
5779       iv(cnvcod) = iv(irc) - 4
5780 !
5781  75   if (iv(cnvcod) .ne. 0) go to 290
5782       if (iv(mode) .eq. 0) go to 250
5783 !
5784 !  ***  allow first step to have scaled 2-norm at most v(lmax0)  ***
5785 !
5786       v(radius) = v(lmax0)
5787 !
5788       iv(mode) = 0
5789 !
5790 !
5791 !-----------------------------  main loop  -----------------------------
5792 !
5793 !
5794 !  ***  print iteration summary, check iteration limit  ***
5795 !
5796  80   call itsum(d, g, iv, liv, lv, n, v, x)
5797  90   k = iv(niter)
5798       if (k .lt. iv(mxiter)) go to 100
5799          iv(1) = 10
5800          go to 300
5801 !
5802 !  ***  update radius  ***
5803 !
5804  100  iv(niter) = k + 1
5805       if(k.gt.0)v(radius) = v(radfac) * v(dstnrm)
5806 !
5807 !  ***  initialize for start of next iteration  ***
5808 !
5809       g01 = iv(g0)
5810       x01 = iv(x0)
5811       v(f0) = v(f)
5812       iv(irc) = 4
5813       iv(kagqt) = -1
5814 !
5815 !     ***  copy x to x0, g to g0  ***
5816 !
5817       call vcopy(n, v(x01), x)
5818       call vcopy(n, v(g01), g)
5819 !
5820 !  ***  check stopx and function evaluation limit  ***
5821 !
5822 ! AL 4/30/95
5823       dummy=iv(nfcall)
5824 !el      lstopx = stopx(dummy)
5825 !elwrite(iout,*) "lstopx",lstopx,dummy
5826  110  if (.not. stopx(dummy)) go to 130
5827          iv(1) = 11
5828 !         write (iout,*) "iv(1)=11 !!!!"
5829          go to 140
5830 !
5831 !     ***  come here when restarting after func. eval. limit or stopx.
5832 !
5833  120  if (v(f) .ge. v(f0)) go to 130
5834          v(radfac) = one
5835          k = iv(niter)
5836          go to 100
5837 !
5838  130  if (iv(nfcall) .lt. iv(mxfcal)) go to 150
5839          iv(1) = 9
5840  140     if (v(f) .ge. v(f0)) go to 300
5841 !
5842 !        ***  in case of stopx or function evaluation limit with
5843 !        ***  improved v(f), evaluate the gradient at x.
5844 !
5845               iv(cnvcod) = iv(1)
5846               go to 240
5847 !
5848 !. . . . . . . . . . . . .  compute candidate step  . . . . . . . . . .
5849 !
5850  150  step1 = iv(step)
5851       dg1 = iv(dg)
5852       nwtst1 = iv(nwtstp)
5853       if (iv(kagqt) .ge. 0) go to 160
5854          l = iv(lmat)
5855          call livmul(n, v(nwtst1), v(l), g)
5856          v(nreduc) = half * dotprd(n, v(nwtst1), v(nwtst1))
5857          call litvmu(n, v(nwtst1), v(l), v(nwtst1))
5858          call vvmulp(n, v(step1), v(nwtst1), d, 1)
5859          v(dst0) = v2norm(n, v(step1))
5860          call vvmulp(n, v(dg1), v(dg1), d, -1)
5861          call ltvmul(n, v(step1), v(l), v(dg1))
5862          v(gthg) = v2norm(n, v(step1))
5863          iv(kagqt) = 0
5864  160  call dbdog(v(dg1), lv, n, v(nwtst1), v(step1), v)
5865       if (iv(irc) .eq. 6) go to 180
5866 !
5867 !  ***  check whether evaluating f(x0 + step) looks worthwhile  ***
5868 !
5869       if (v(dstnrm) .le. zero) go to 180
5870       if (iv(irc) .ne. 5) go to 170
5871       if (v(radfac) .le. one) go to 170
5872       if (v(preduc) .le. onep2 * v(fdif)) go to 180
5873 !
5874 !  ***  compute f(x0 + step)  ***
5875 !
5876  170  x01 = iv(x0)
5877       step1 = iv(step)
5878       call vaxpy(n, x, one, v(step1), v(x01))
5879       iv(nfcall) = iv(nfcall) + 1
5880       iv(1) = 1
5881       iv(toobig) = 0
5882       go to 999
5883 !
5884 !. . . . . . . . . . . . .  assess candidate step  . . . . . . . . . . .
5885 !
5886  180  x01 = iv(x0)
5887       v(reldx) = reldst(n, d, x, v(x01))
5888       call assst(iv, liv, lv, v)
5889       step1 = iv(step)
5890       lstgst = iv(stlstg)
5891       if (iv(restor) .eq. 1) call vcopy(n, x, v(x01))
5892       if (iv(restor) .eq. 2) call vcopy(n, v(lstgst), v(step1))
5893       if (iv(restor) .ne. 3) go to 190
5894          call vcopy(n, v(step1), v(lstgst))
5895          call vaxpy(n, x, one, v(step1), v(x01))
5896          v(reldx) = reldst(n, d, x, v(x01))
5897 !
5898  190  k = iv(irc)
5899       go to (200,230,230,230,200,210,220,220,220,220,220,220,280,250), k
5900 !
5901 !     ***  recompute step with changed radius  ***
5902 !
5903  200     v(radius) = v(radfac) * v(dstnrm)
5904          go to 110
5905 !
5906 !  ***  compute step of length v(lmaxs) for singular convergence test.
5907 !
5908  210  v(radius) = v(lmaxs)
5909       go to 150
5910 !
5911 !  ***  convergence or false convergence  ***
5912 !
5913  220  iv(cnvcod) = k - 4
5914       if (v(f) .ge. v(f0)) go to 290
5915          if (iv(xirc) .eq. 14) go to 290
5916               iv(xirc) = 14
5917 !
5918 !. . . . . . . . . . . .  process acceptable step  . . . . . . . . . . .
5919 !
5920  230  if (iv(irc) .ne. 3) go to 240
5921          step1 = iv(step)
5922          temp1 = iv(stlstg)
5923 !
5924 !     ***  set  temp1 = hessian * step  for use in gradient tests  ***
5925 !
5926          l = iv(lmat)
5927          call ltvmul(n, v(temp1), v(l), v(step1))
5928          call lvmul(n, v(temp1), v(l), v(temp1))
5929 !
5930 !  ***  compute gradient  ***
5931 !
5932  240  iv(ngcall) = iv(ngcall) + 1
5933       iv(1) = 2
5934       go to 999
5935 !
5936 !  ***  initializations -- g0 = g - g0, etc.  ***
5937 !
5938  250  g01 = iv(g0)
5939       call vaxpy(n, v(g01), negone, v(g01), g)
5940       step1 = iv(step)
5941       temp1 = iv(stlstg)
5942       if (iv(irc) .ne. 3) go to 270
5943 !
5944 !  ***  set v(radfac) by gradient tests  ***
5945 !
5946 !     ***  set  temp1 = diag(d)**-1 * (hessian*step + (g(x0)-g(x)))  ***
5947 !
5948          call vaxpy(n, v(temp1), negone, v(g01), v(temp1))
5949          call vvmulp(n, v(temp1), v(temp1), d, -1)
5950 !
5951 !        ***  do gradient tests  ***
5952 !
5953          if (v2norm(n, v(temp1)) .le. v(dgnorm) * v(tuner4)) &
5954                         go to 260
5955               if (dotprd(n, g, v(step1)) &
5956                         .ge. v(gtstep) * v(tuner5))  go to 270
5957  260               v(radfac) = v(incfac)
5958 !
5959 !  ***  update h, loop  ***
5960 !
5961  270  w = iv(nwtstp)
5962       z = iv(x0)
5963       l = iv(lmat)
5964       call wzbfgs(v(l), n, v(step1), v(w), v(g01), v(z))
5965 !
5966 !     ** use the n-vectors starting at v(step1) and v(g01) for scratch..
5967       call lupdat(v(temp1), v(step1), v(l), v(g01), v(l), n, v(w), v(z))
5968       iv(1) = 2
5969       go to 80
5970 !
5971 !. . . . . . . . . . . . . .  misc. details  . . . . . . . . . . . . . .
5972 !
5973 !  ***  bad parameters to assess  ***
5974 !
5975  280  iv(1) = 64
5976       go to 300
5977 !
5978 !  ***  print summary of final iteration and other requested items  ***
5979 !
5980  290  iv(1) = iv(cnvcod)
5981       iv(cnvcod) = 0
5982  300  call itsum(d, g, iv, liv, lv, n, v, x)
5983 !
5984  999  return
5985 !
5986 !  ***  last line of sumit follows  ***
5987       end subroutine sumit
5988 !-----------------------------------------------------------------------------
5989       subroutine dbdog(dig,lv,n,nwtstp,step,v)
5990 !
5991 !  ***  compute double dogleg step  ***
5992 !
5993 !  ***  parameter declarations  ***
5994 !
5995       integer :: lv, n
5996       real(kind=8) :: dig(n), nwtstp(n), step(n), v(lv)
5997 !
5998 !  ***  purpose  ***
5999 !
6000 !        this subroutine computes a candidate step (for use in an uncon-
6001 !     strained minimization code) by the double dogleg algorithm of
6002 !     dennis and mei (ref. 1), which is a variation on powell*s dogleg
6003 !     scheme (ref. 2, p. 95).
6004 !
6005 !--------------------------  parameter usage  --------------------------
6006 !
6007 !    dig (input) diag(d)**-2 * g -- see algorithm notes.
6008 !      g (input) the current gradient vector.
6009 !     lv (input) length of v.
6010 !      n (input) number of components in  dig, g, nwtstp,  and  step.
6011 ! nwtstp (input) negative newton step -- see algorithm notes.
6012 !   step (output) the computed step.
6013 !      v (i/o) values array, the following components of which are
6014 !             used here...
6015 ! v(bias)   (input) bias for relaxed newton step, which is v(bias) of
6016 !             the way from the full newton to the fully relaxed newton
6017 !             step.  recommended value = 0.8 .
6018 ! v(dgnorm) (input) 2-norm of diag(d)**-1 * g -- see algorithm notes.
6019 ! v(dstnrm) (output) 2-norm of diag(d) * step, which is v(radius)
6020 !             unless v(stppar) = 0 -- see algorithm notes.
6021 ! v(dst0) (input) 2-norm of diag(d) * nwtstp -- see algorithm notes.
6022 ! v(grdfac) (output) the coefficient of  dig  in the step returned --
6023 !             step(i) = v(grdfac)*dig(i) + v(nwtfac)*nwtstp(i).
6024 ! v(gthg)   (input) square-root of (dig**t) * (hessian) * dig -- see
6025 !             algorithm notes.
6026 ! v(gtstep) (output) inner product between g and step.
6027 ! v(nreduc) (output) function reduction predicted for the full newton
6028 !             step.
6029 ! v(nwtfac) (output) the coefficient of  nwtstp  in the step returned --
6030 !             see v(grdfac) above.
6031 ! v(preduc) (output) function reduction predicted for the step returned.
6032 ! v(radius) (input) the trust region radius.  d times the step returned
6033 !             has 2-norm v(radius) unless v(stppar) = 0.
6034 ! v(stppar) (output) code telling how step was computed... 0 means a
6035 !             full newton step.  between 0 and 1 means v(stppar) of the
6036 !             way from the newton to the relaxed newton step.  between
6037 !             1 and 2 means a true double dogleg step, v(stppar) - 1 of
6038 !             the way from the relaxed newton to the cauchy step.
6039 !             greater than 2 means 1 / (v(stppar) - 1) times the cauchy
6040 !             step.
6041 !
6042 !-------------------------------  notes  -------------------------------
6043 !
6044 !  ***  algorithm notes  ***
6045 !
6046 !        let  g  and  h  be the current gradient and hessian approxima-
6047 !     tion respectively and let d be the current scale vector.  this
6048 !     routine assumes dig = diag(d)**-2 * g  and  nwtstp = h**-1 * g.
6049 !     the step computed is the same one would get by replacing g and h
6050 !     by  diag(d)**-1 * g  and  diag(d)**-1 * h * diag(d)**-1,
6051 !     computing step, and translating step back to the original
6052 !     variables, i.e., premultiplying it by diag(d)**-1.
6053 !
6054 !  ***  references  ***
6055 !
6056 ! 1.  dennis, j.e., and mei, h.h.w. (1979), two new unconstrained opti-
6057 !             mization algorithms which use function and gradient
6058 !             values, j. optim. theory applic. 28, pp. 453-482.
6059 ! 2. powell, m.j.d. (1970), a hybrid method for non-linear equations,
6060 !             in numerical methods for non-linear equations, edited by
6061 !             p. rabinowitz, gordon and breach, london.
6062 !
6063 !  ***  general  ***
6064 !
6065 !     coded by david m. gay.
6066 !     this subroutine was written in connection with research supported
6067 !     by the national science foundation under grants mcs-7600324 and
6068 !     mcs-7906671.
6069 !
6070 !------------------------  external quantities  ------------------------
6071 !
6072 !  ***  functions and subroutines called  ***
6073 !
6074 !el      external dotprd, v2norm
6075 !el      real(kind=8) :: dotprd, v2norm
6076 !
6077 ! dotprd... returns inner product of two vectors.
6078 ! v2norm... returns 2-norm of a vector.
6079 !
6080 !  ***  intrinsic functions  ***
6081 !/+
6082 !el      real(kind=8) :: dsqrt
6083 !/
6084 !--------------------------  local variables  --------------------------
6085 !
6086       integer :: i
6087       real(kind=8) :: cfact, cnorm, ctrnwt, ghinvg, femnsq, gnorm,&
6088                        nwtnrm, relax, rlambd, t, t1, t2
6089 !el      real(kind=8) :: half, one, two, zero
6090 !
6091 !  ***  v subscripts  ***
6092 !
6093 !el      integer bias, dgnorm, dstnrm, dst0, grdfac, gthg, gtstep,
6094 !el     1        nreduc, nwtfac, preduc, radius, stppar
6095 !
6096 !  ***  data initializations  ***
6097 !
6098 !/6
6099 !     data half/0.5d+0/, one/1.d+0/, two/2.d+0/, zero/0.d+0/
6100 !/7
6101       real(kind=8),parameter :: half=0.5d+0, one=1.d+0, two=2.d+0, zero=0.d+0
6102 !/
6103 !
6104 !/6
6105 !     data bias/43/, dgnorm/1/, dstnrm/2/, dst0/3/, grdfac/45/,
6106 !    1     gthg/44/, gtstep/4/, nreduc/6/, nwtfac/46/, preduc/7/,
6107 !    2     radius/8/, stppar/5/
6108 !/7
6109       integer,parameter :: bias=43, dgnorm=1, dstnrm=2, dst0=3, grdfac=45,&
6110                  gthg=44, gtstep=4, nreduc=6, nwtfac=46, preduc=7,&
6111                  radius=8, stppar=5
6112 !/
6113 !
6114 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
6115 !
6116       nwtnrm = v(dst0)
6117       rlambd = one
6118       if (nwtnrm .gt. zero) rlambd = v(radius) / nwtnrm
6119       gnorm = v(dgnorm)
6120       ghinvg = two * v(nreduc)
6121       v(grdfac) = zero
6122       v(nwtfac) = zero
6123       if (rlambd .lt. one) go to 30
6124 !
6125 !        ***  the newton step is inside the trust region  ***
6126 !
6127          v(stppar) = zero
6128          v(dstnrm) = nwtnrm
6129          v(gtstep) = -ghinvg
6130          v(preduc) = v(nreduc)
6131          v(nwtfac) = -one
6132          do 20 i = 1, n
6133  20           step(i) = -nwtstp(i)
6134          go to 999
6135 !
6136  30   v(dstnrm) = v(radius)
6137       cfact = (gnorm / v(gthg))**2
6138 !     ***  cauchy step = -cfact * g.
6139       cnorm = gnorm * cfact
6140       relax = one - v(bias) * (one - gnorm*cnorm/ghinvg)
6141       if (rlambd .lt. relax) go to 50
6142 !
6143 !        ***  step is between relaxed newton and full newton steps  ***
6144 !
6145          v(stppar)  =  one  -  (rlambd - relax) / (one - relax)
6146          t = -rlambd
6147          v(gtstep) = t * ghinvg
6148          v(preduc) = rlambd * (one - half*rlambd) * ghinvg
6149          v(nwtfac) = t
6150          do 40 i = 1, n
6151  40           step(i) = t * nwtstp(i)
6152          go to 999
6153 !
6154  50   if (cnorm .lt. v(radius)) go to 70
6155 !
6156 !        ***  the cauchy step lies outside the trust region --
6157 !        ***  step = scaled cauchy step  ***
6158 !
6159          t = -v(radius) / gnorm
6160          v(grdfac) = t
6161          v(stppar) = one  +  cnorm / v(radius)
6162          v(gtstep) = -v(radius) * gnorm
6163       v(preduc) = v(radius)*(gnorm - half*v(radius)*(v(gthg)/gnorm)**2)
6164          do 60 i = 1, n
6165  60           step(i) = t * dig(i)
6166          go to 999
6167 !
6168 !     ***  compute dogleg step between cauchy and relaxed newton  ***
6169 !     ***  femur = relaxed newton step minus cauchy step  ***
6170 !
6171  70   ctrnwt = cfact * relax * ghinvg / gnorm
6172 !     *** ctrnwt = inner prod. of cauchy and relaxed newton steps,
6173 !     *** scaled by gnorm**-1.
6174       t1 = ctrnwt - gnorm*cfact**2
6175 !     ***  t1 = inner prod. of femur and cauchy step, scaled by
6176 !     ***  gnorm**-1.
6177       t2 = v(radius)*(v(radius)/gnorm) - gnorm*cfact**2
6178       t = relax * nwtnrm
6179       femnsq = (t/gnorm)*t - ctrnwt - t1
6180 !     ***  femnsq = square of 2-norm of femur, scaled by gnorm**-1.
6181       t = t2 / (t1 + dsqrt(t1**2 + femnsq*t2))
6182 !     ***  dogleg step  =  cauchy step  +  t * femur.
6183       t1 = (t - one) * cfact
6184       v(grdfac) = t1
6185       t2 = -t * relax
6186       v(nwtfac) = t2
6187       v(stppar) = two - t
6188       v(gtstep) = t1*gnorm**2 + t2*ghinvg
6189       v(preduc) = -t1*gnorm * ((t2 + one)*gnorm) &
6190                        - t2 * (one + half*t2)*ghinvg &
6191                         - half * (v(gthg)*t1)**2
6192       do 80 i = 1, n
6193  80      step(i) = t1*dig(i) + t2*nwtstp(i)
6194 !
6195  999  return
6196 !  ***  last line of dbdog follows  ***
6197       end subroutine dbdog
6198 !-----------------------------------------------------------------------------
6199       subroutine ltvmul(n,x,l,y)
6200 !
6201 !  ***  compute  x = (l**t)*y, where  l  is an  n x n  lower
6202 !  ***  triangular matrix stored compactly by rows.  x and y may
6203 !  ***  occupy the same storage.  ***
6204 !
6205       integer :: n
6206 !al   real(kind=8) :: x(n), l(1), y(n)
6207       real(kind=8) :: x(n), l(n*(n+1)/2), y(n)
6208 !     dimension l(n*(n+1)/2)
6209       integer :: i, ij, i0, j
6210       real(kind=8) :: yi        !el, zero
6211 !/6
6212 !     data zero/0.d+0/
6213 !/7
6214       real(kind=8),parameter :: zero=0.d+0
6215 !/
6216 !
6217       i0 = 0
6218       do 20 i = 1, n
6219          yi = y(i)
6220          x(i) = zero
6221          do 10 j = 1, i
6222               ij = i0 + j
6223               x(j) = x(j) + yi*l(ij)
6224  10           continue
6225          i0 = i0 + i
6226  20      continue
6227  999  return
6228 !  ***  last card of ltvmul follows  ***
6229       end subroutine ltvmul
6230 !-----------------------------------------------------------------------------
6231       subroutine lupdat(beta,gamma,l,lambda,lplus,n,w,z)
6232 !
6233 !  ***  compute lplus = secant update of l  ***
6234 !
6235 !  ***  parameter declarations  ***
6236 !
6237       integer :: n
6238 !al   double precision beta(n), gamma(n), l(1), lambda(n), lplus(1),
6239       real(kind=8) :: beta(n), gamma(n), l(n*(n+1)/2), lambda(n), &
6240          lplus(n*(n+1)/2),w(n), z(n)
6241 !     dimension l(n*(n+1)/2), lplus(n*(n+1)/2)
6242 !
6243 !--------------------------  parameter usage  --------------------------
6244 !
6245 !   beta = scratch vector.
6246 !  gamma = scratch vector.
6247 !      l (input) lower triangular matrix, stored rowwise.
6248 ! lambda = scratch vector.
6249 !  lplus (output) lower triangular matrix, stored rowwise, which may
6250 !             occupy the same storage as  l.
6251 !      n (input) length of vector parameters and order of matrices.
6252 !      w (input, destroyed on output) right singular vector of rank 1
6253 !             correction to  l.
6254 !      z (input, destroyed on output) left singular vector of rank 1
6255 !             correction to  l.
6256 !
6257 !-------------------------------  notes  -------------------------------
6258 !
6259 !  ***  application and usage restrictions  ***
6260 !
6261 !        this routine updates the cholesky factor  l  of a symmetric
6262 !     positive definite matrix to which a secant update is being
6263 !     applied -- it computes a cholesky factor  lplus  of
6264 !     l * (i + z*w**t) * (i + w*z**t) * l**t.  it is assumed that  w
6265 !     and  z  have been chosen so that the updated matrix is strictly
6266 !     positive definite.
6267 !
6268 !  ***  algorithm notes  ***
6269 !
6270 !        this code uses recurrence 3 of ref. 1 (with d(j) = 1 for all j)
6271 !     to compute  lplus  of the form  l * (i + z*w**t) * q,  where  q
6272 !     is an orthogonal matrix that makes the result lower triangular.
6273 !        lplus may have some negative diagonal elements.
6274 !
6275 !  ***  references  ***
6276 !
6277 ! 1.  goldfarb, d. (1976), factorized variable metric methods for uncon-
6278 !             strained optimization, math. comput. 30, pp. 796-811.
6279 !
6280 !  ***  general  ***
6281 !
6282 !     coded by david m. gay (fall 1979).
6283 !     this subroutine was written in connection with research supported
6284 !     by the national science foundation under grants mcs-7600324 and
6285 !     mcs-7906671.
6286 !
6287 !------------------------  external quantities  ------------------------
6288 !
6289 !  ***  intrinsic functions  ***
6290 !/+
6291 !el      real(kind=8) :: dsqrt
6292 !/
6293 !--------------------------  local variables  --------------------------
6294 !
6295       integer :: i, ij, j, jj, jp1, k, nm1, np1
6296       real(kind=8) :: a, b, bj, eta, gj, lj, lij, ljj, nu, s, theta,&
6297                        wj, zj
6298 !el      real(kind=8) :: one, zero
6299 !
6300 !  ***  data initializations  ***
6301 !
6302 !/6
6303 !     data one/1.d+0/, zero/0.d+0/
6304 !/7
6305       real(kind=8),parameter :: one=1.d+0, zero=0.d+0
6306 !/
6307 !
6308 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
6309 !
6310       nu = one
6311       eta = zero
6312       if (n .le. 1) go to 30
6313       nm1 = n - 1
6314 !
6315 !  ***  temporarily store s(j) = sum over k = j+1 to n of w(k)**2 in
6316 !  ***  lambda(j).
6317 !
6318       s = zero
6319       do 10 i = 1, nm1
6320          j = n - i
6321          s = s + w(j+1)**2
6322          lambda(j) = s
6323  10      continue
6324 !
6325 !  ***  compute lambda, gamma, and beta by goldfarb*s recurrence 3.
6326 !
6327       do 20 j = 1, nm1
6328          wj = w(j)
6329          a = nu*z(j) - eta*wj
6330          theta = one + a*wj
6331          s = a*lambda(j)
6332          lj = dsqrt(theta**2 + a*s)
6333          if (theta .gt. zero) lj = -lj
6334          lambda(j) = lj
6335          b = theta*wj + s
6336          gamma(j) = b * nu / lj
6337          beta(j) = (a - b*eta) / lj
6338          nu = -nu / lj
6339          eta = -(eta + (a**2)/(theta - lj)) / lj
6340  20      continue
6341  30   lambda(n) = one + (nu*z(n) - eta*w(n))*w(n)
6342 !
6343 !  ***  update l, gradually overwriting  w  and  z  with  l*w  and  l*z.
6344 !
6345       np1 = n + 1
6346       jj = n * (n + 1) / 2
6347       do 60 k = 1, n
6348          j = np1 - k
6349          lj = lambda(j)
6350          ljj = l(jj)
6351          lplus(jj) = lj * ljj
6352          wj = w(j)
6353          w(j) = ljj * wj
6354          zj = z(j)
6355          z(j) = ljj * zj
6356          if (k .eq. 1) go to 50
6357          bj = beta(j)
6358          gj = gamma(j)
6359          ij = jj + j
6360          jp1 = j + 1
6361          do 40 i = jp1, n
6362               lij = l(ij)
6363               lplus(ij) = lj*lij + bj*w(i) + gj*z(i)
6364               w(i) = w(i) + lij*wj
6365               z(i) = z(i) + lij*zj
6366               ij = ij + i
6367  40           continue
6368  50      jj = jj - j
6369  60      continue
6370 !
6371  999  return
6372 !  ***  last card of lupdat follows  ***
6373       end subroutine lupdat
6374 !-----------------------------------------------------------------------------
6375       subroutine lvmul(n,x,l,y)
6376 !
6377 !  ***  compute  x = l*y, where  l  is an  n x n  lower triangular
6378 !  ***  matrix stored compactly by rows.  x and y may occupy the same
6379 !  ***  storage.  ***
6380 !
6381       integer :: n
6382 !al   double precision x(n), l(1), y(n)
6383       real(kind=8) :: x(n), l(n*(n+1)/2), y(n)
6384 !     dimension l(n*(n+1)/2)
6385       integer :: i, ii, ij, i0, j, np1
6386       real(kind=8) :: t !el, zero
6387 !/6
6388 !     data zero/0.d+0/
6389 !/7
6390       real(kind=8),parameter :: zero=0.d+0
6391 !/
6392 !
6393       np1 = n + 1
6394       i0 = n*(n+1)/2
6395       do 20 ii = 1, n
6396          i = np1 - ii
6397          i0 = i0 - i
6398          t = zero
6399          do 10 j = 1, i
6400               ij = i0 + j
6401               t = t + l(ij)*y(j)
6402  10           continue
6403          x(i) = t
6404  20      continue
6405  999  return
6406 !  ***  last card of lvmul follows  ***
6407       end subroutine lvmul
6408 !-----------------------------------------------------------------------------
6409       subroutine vvmulp(n,x,y,z,k)
6410 !
6411 ! ***  set x(i) = y(i) * z(i)**k, 1 .le. i .le. n (for k = 1 or -1)  ***
6412 !
6413       integer :: n, k
6414       real(kind=8) :: x(n), y(n), z(n)
6415       integer :: i
6416 !
6417       if (k .ge. 0) go to 20
6418       do 10 i = 1, n
6419  10      x(i) = y(i) / z(i)
6420       go to 999
6421 !
6422  20   do 30 i = 1, n
6423  30      x(i) = y(i) * z(i)
6424  999  return
6425 !  ***  last card of vvmulp follows  ***
6426       end subroutine vvmulp
6427 !-----------------------------------------------------------------------------
6428       subroutine wzbfgs(l,n,s,w,y,z)
6429 !
6430 !  ***  compute  y  and  z  for  lupdat  corresponding to bfgs update.
6431 !
6432       integer :: n
6433 !al   double precision l(1), s(n), w(n), y(n), z(n)
6434       real(kind=8) :: l(n*(n+1)/2), s(n), w(n), y(n), z(n)
6435 !     dimension l(n*(n+1)/2)
6436 !
6437 !--------------------------  parameter usage  --------------------------
6438 !
6439 ! l (i/o) cholesky factor of hessian, a lower triang. matrix stored
6440 !             compactly by rows.
6441 ! n (input) order of  l  and length of  s,  w,  y,  z.
6442 ! s (input) the step just taken.
6443 ! w (output) right singular vector of rank 1 correction to l.
6444 ! y (input) change in gradients corresponding to s.
6445 ! z (output) left singular vector of rank 1 correction to l.
6446 !
6447 !-------------------------------  notes  -------------------------------
6448 !
6449 !  ***  algorithm notes  ***
6450 !
6451 !        when  s  is computed in certain ways, e.g. by  gqtstp  or
6452 !     dbldog,  it is possible to save n**2/2 operations since  (l**t)*s
6453 !     or  l*(l**t)*s is then known.
6454 !        if the bfgs update to l*(l**t) would reduce its determinant to
6455 !     less than eps times its old value, then this routine in effect
6456 !     replaces  y  by  theta*y + (1 - theta)*l*(l**t)*s,  where  theta
6457 !     (between 0 and 1) is chosen to make the reduction factor = eps.
6458 !
6459 !  ***  general  ***
6460 !
6461 !     coded by david m. gay (fall 1979).
6462 !     this subroutine was written in connection with research supported
6463 !     by the national science foundation under grants mcs-7600324 and
6464 !     mcs-7906671.
6465 !
6466 !------------------------  external quantities  ------------------------
6467 !
6468 !  ***  functions and subroutines called  ***
6469 !
6470 !el      external dotprd, livmul, ltvmul
6471 !el      real(kind=8) :: dotprd
6472 ! dotprd returns inner product of two vectors.
6473 ! livmul multiplies l**-1 times a vector.
6474 ! ltvmul multiplies l**t times a vector.
6475 !
6476 !  ***  intrinsic functions  ***
6477 !/+
6478 !el      real(kind=8) :: dsqrt
6479 !/
6480 !--------------------------  local variables  --------------------------
6481 !
6482       integer :: i
6483       real(kind=8) :: cs, cy, epsrt, shs, ys, theta     !el, eps, one
6484 !
6485 !  ***  data initializations  ***
6486 !
6487 !/6
6488 !     data eps/0.1d+0/, one/1.d+0/
6489 !/7
6490       real(kind=8),parameter :: eps=0.1d+0, one=1.d+0
6491 !/
6492 !
6493 !+++++++++++++++++++++++++++++++  body  ++++++++++++++++++++++++++++++++
6494 !
6495       call ltvmul(n, w, l, s)
6496       shs = dotprd(n, w, w)
6497       ys = dotprd(n, y, s)
6498       if (ys .ge. eps*shs) go to 10
6499          theta = (one - eps) * shs / (shs - ys)
6500          epsrt = dsqrt(eps)
6501          cy = theta / (shs * epsrt)
6502          cs = (one + (theta-one)/epsrt) / shs
6503          go to 20
6504  10   cy = one / (dsqrt(ys) * dsqrt(shs))
6505       cs = one / shs
6506  20   call livmul(n, z, l, y)
6507       do 30 i = 1, n
6508  30      z(i) = cy * z(i)  -  cs * w(i)
6509 !
6510  999  return
6511 !  ***  last card of wzbfgs follows  ***
6512       end subroutine wzbfgs
6513 !-----------------------------------------------------------------------------
6514 !-----------------------------------------------------------------------------
6515       end module minimm