/[MITgcm]/MITgcm_contrib/mlosch/optim_m1qn3/m1qn3_offline.F
ViewVC logotype

Annotation of /MITgcm_contrib/mlosch/optim_m1qn3/m1qn3_offline.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.5 - (hide annotations) (download)
Wed May 2 20:16:26 2012 UTC (11 years, 11 months ago) by mlosch
Branch: MAIN
Changes since 1.4: +2 -3 lines
more variables to store (indica,indicd,t_increased)

1 mlosch 1.5 C $Header: /u/gcmpack/MITgcm_contrib/mlosch/optim_m1qn3/m1qn3_offline.F,v 1.4 2012/05/02 10:10:57 mlosch Exp $
2 mlosch 1.3 C $Name: $
3 mlosch 1.2 C
4     C The original m1qn3 has been modified to work "offline", i.e.
5     C the simulator and the driver of m1qn3_offline are separate
6 mlosch 1.3 C programs that are called alternatingly from a (shell-)script.
7     C This requires that the "state" of m1qn3 is saved before
8 mlosch 1.2 C this program terminates. Communication with the routine
9     C writing and restoring the state of m1qn3 is achieved via
10     C 3 new common-blocks that are contained in 3 header files.
11     C
12     C Apr27, 2012, Martin.Losch@awi.de
13     C
14 mlosch 1.1 subroutine m1qn3_offline
15     & (simul,prosca,ctonb,ctcab,n,x,f,g,dxmin,df1,
16     & epsg,normtype,impres,io,imode,omode,niter,nsim,
17     & iz,dz,ndz,reverse,indic,izs,rzs,dzs)
18     c
19     c-----------------------------------------------------------------------
20     c
21     c M1QN3, Version 3.3, October 2009
22     c
23     c M1qn3 has two running modes: the SID (Scalar Initial Scaling) mode
24     c and the DIS (Diagonal Initial Scaling) mode. Both do not require
25     c the same amount of storage, the same subroutines, ...
26     c In the description below, items that differ in the DIS mode with
27     c respect to the SIS mode are given in brakets.
28     c
29     c Use the following subroutines:
30     c M1QN3A
31     c DDD, DDDS
32     c NLIS0 + DCUBE (Dec 88)
33     c MUPDTS, DYSTBL.
34     c
35     c The following routines are proposed to the user in case the
36     c Euclidean scalar product is used:
37     c DUCLID, DTONBE, DTCABE.
38     c
39     c La sous-routine M1QN3 est une interface entre le programme
40     c appelant et la sous-routine M1QN3A, le minimiseur proprement dit.
41     c
42     c Le module PROSCA est sense realiser le produit scalaire de deux
43     c vecteurs de Rn; le module DTONB est sense realiser le changement
44     c de coordonnees correspondant au changement de bases: base
45     c euclidienne -> base orthonormale (pour le produit scalaire
46     c PROSCA); le module CTBAB fait la transformation inverse: base
47     c orthonormale -> base euclidienne.
48     c
49     c Iz is an integer working zone for M1QN3A, its dimension is 5.
50     c It is formed of 5 scalars that are set by the optimizer:
51     c - the dimension of the problem,
52     c - an identifier of the scaling mode,
53     c - the number of updates,
54     c - two pointers.
55     c
56     c Dz est la zone de travail pour M1QN3A, de dimension ndz.
57     c Elle est subdivisee en
58     c 3 [ou 4] vecteurs de dimension n: d,gg,[diag,]aux
59     c m scalaires: alpha
60     c m vecteurs de dimension n: ybar
61     c m vecteurs de dimension n: sbar
62     c
63     c m est alors le plus grand entier tel que
64     c m*(2*n+1)+3*n .le. ndz [m*(2*n+1)+4*n .le. ndz)]
65     c soit m := (ndz-3*n) / (2*n+1) [m := (ndz-4*n) / (2*n+1)].
66     c Il faut avoir m >= 1, donc ndz >= 5n+1 [ndz >= 6n+1].
67     c
68     c A chaque iteration la metrique est formee a partir d un multiple
69     c de l'identite [d'une matrice diagonale] D qui est mise a jour m
70     c fois par la formule de BFGS en utilisant les m couples {y,s} les
71     c plus recents.
72     c
73     c-----------------------------------------------------------------------
74     c
75     c Authors: Jean Charles Gilbert, Claude Lemarechal, INRIA.
76     c
77     c Copyright 2008, 2009, INRIA.
78     c
79     c M1QN3 is distributed under the terms of the GNU General Public
80     c License.
81     c
82     c-----------------------------------------------------------------------
83     c
84     c This program is free software: you can redistribute it and/or
85     c modify it under the terms of the GNU General Public License as
86     c published by the Free Software Foundation, either version 3 of
87     c the License, or (at your option) any later version.
88     c
89     c This program is distributed in the hope that it will be useful,
90     c but WITHOUT ANY WARRANTY; without even the implied warranty of
91     c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
92     c General Public License for more details.
93     c
94     c You should have received a copy of the GNU General Public License
95     c along with this program. If not, see
96     c <http://www.gnu.org/licenses/>.
97     c
98     c-----------------------------------------------------------------------
99     c
100     implicit none
101     c
102     c arguments
103     c
104     character*3 normtype
105     integer n,impres,io,imode(3),omode,niter,nsim,iz(5),ndz,indic,
106     & reverse,izs(*)
107     real rzs(*)
108     double precision x(n),f,g(n),dxmin,df1,epsg,dz(ndz),dzs(*)
109     external simul,prosca,ctonb,ctcab
110     c
111     c --- local variables
112     c
113     c The variable 'reentry' is used to know where to jump when entering
114     c the subroutine in reverse commnunication (it is better than using
115     c 'reverse', which is known outside m1qn3 and could be changed by
116     c the user):
117     c = 0: no jump, start at the begining of the subroutine
118     c = 1: jump inside m1qn3a, where the simulator was called with
119     c indic=1
120     c = 2: jump inside m1qn3a/mlis3, where the simulator was called with
121     c indic=4
122     c The variable 'reentry' is set to 0 by the compiler and when m1qn3
123     c has completed its job (see below); since the value is saved, it
124     c has always the value 0 when entering the solver for the first
125     c time when solving a new problem, even if it is in the same
126     c program.
127     c
128     logical sscale
129     integer ntravu,m,mmemo
130     double precision gnorm,ps
131     #include "m1qn3_common.h"
132     CML logical inmemo,sscale
133     CML integer ntravu,id,igg,idiag,iaux,ialpha,iybar,isbar,m,mmemo,
134     CML & reentry
135     CML double precision gnorm,ps
136     CML save inmemo,sscale,ntravu,id,igg,idiag,iaux,ialpha,iybar,isbar,m,
137     CML & mmemo,reentry,gnorm,ps
138     c
139     c data
140     c
141     CML this needs to be done outside of m1qn3_offline
142     CML data reentry /0/
143     c
144     c --- function
145     c
146     double precision ddot,dnrmi
147     c
148     c --- stop if reverse < 0 (m1qn3 should not be called with reverse < 0)
149     c
150     if (reverse.lt.0) then
151     write (io,'(/a,a,i0,a/)')
152     & " >>> m1qn3 should not be called with a negative reverse",
153     & " (=", reverse, ")"
154     stop
155     endif
156     c
157     c --- possible jumps
158     c 9999: go directly in m1qn3a
159     c
160     if (reentry.gt.0) goto 9999
161     c
162     c---- license notice
163     c
164     if (impres.ge.5) then
165     write (io,934)
166     endif
167     934 format (1x,79("-")
168     & /1x,"M1QN3 Copyright (C) 2008, J. Ch. Gilbert, Cl. ",
169     & "Lemarechal."
170     & /1x,79("-")
171     & /1x,"This program comes with ABSOLUTELY NO WARRANTY. This is",
172     & " free software, and you"
173     & /1x,"are welcome to redistribute it under certain ",
174     & "conditions. See the file COPYING "
175     & /1x,"in the root directory of the M1QN3 distribution for ",
176     & "details."
177     & /1x,79("-"))
178     c
179     c---- impressions initiales et controle des arguments
180     c
181     if (impres.ge.1) then
182     write (io,900) n,dxmin,df1,epsg,normtype,niter,nsim,impres
183     if (reverse.gt.0) then
184     write (io,'(5x,a)') "reverse communication"
185     else
186     write (io,'(5x,a)') "direct communication"
187     endif
188     endif
189     900 format (/" M1QN3 (Version 3.3, October 2009): entry point"/
190     & 5x,"dimension of the problem (n):",i14/
191     & 5x,"absolute precision on x (dxmin):",9x,1pd9.2/
192     & 5x,"expected decrease for f (df1):",11x,1pd9.2/
193     & 5x,"relative precision on g (epsg):",10x,1pd9.2,
194     & " (",a3,"-norm)"/
195     & 5x,"maximal number of iterations (niter):",i6/
196     & 5x,"maximal number of simulations (nsim):",i6/
197     & 5x,"printing level (impres):",15x,i4)
198     c
199     c---- check the arguments
200     c
201     if (n.le.0) then
202     omode=2
203     if (reverse.gt.0) reverse = -1
204     if (impres.ge.1) write (io,'(/a)')
205     & " >>> m1qn3: n should be > 0"
206     return
207     endif
208     if (niter.le.0) then
209     omode=2
210     if (reverse.gt.0) reverse = -1
211     if (impres.ge.1) write (io,'(/a)')
212     & " >>> m1qn3: niter should be > 0"
213     return
214     endif
215     if (nsim.le.0) then
216     omode=2
217     if (reverse.gt.0) reverse = -1
218     if (impres.ge.1) write (io,'(/a)')
219     & " >>> m1qn3: nsim should be > 0"
220     return
221     endif
222     if (dxmin.le.0.d0) then
223     omode=2
224     if (reverse.gt.0) reverse = -1
225     if (impres.ge.1) write (io,'(/a)')
226     & " >>> m1qn3: dxmin should be > 0.d0"
227     return
228     endif
229     c if (epsg.le.0.d0 .or. epsg.gt.1.d0) then
230     if (epsg.le.0.d0) then
231     omode=2
232     if (reverse.gt.0) reverse = -1
233     if (impres.ge.1) write (io,'(/a)')
234     & " >>> m1qn3: epsg should be > 0.d0"
235     return
236     endif
237     if (epsg.ge.1.d0) then
238     omode=1
239     niter=0
240     nsim=0
241     epsg=1.d0
242     if (reverse.gt.0) reverse = -1
243     if (impres.ge.1) write (io,'(/a)')
244     & " >>> m1qn3: epsg is >= 1.d0, no need to make progress"
245     goto 1000
246     endif
247     if ((normtype.ne.'two') .and.
248     & (normtype.ne.'sup') .and.
249     & (normtype.ne.'dfn')) then
250     omode=2
251     if (reverse.gt.0) reverse = -1
252     write (io,'(/a,a,a/)') " >>> m1qn3: unknown norm type '",
253     & normtype, "'"
254     return
255     endif
256     if (impres.lt.0) then
257     omode=2
258     if (reverse.gt.0) reverse = -1
259     write (io,'(/a,i0/)')
260     & " >>> m1qn3: impres should be >= 0 and has the value ",
261     & impres
262     return
263     endif
264     c
265     c---- what method
266     c
267     if (imode(1).eq.0) then
268     if (impres.ge.1) write (io,920)
269     920 format (/" m1qn3: Diagonal Initial Scaling mode")
270     sscale=.false.
271     else
272     if (impres.ge.1) write (io,921)
273     921 format (/" m1qn3: Scalar Initial Scaling mode")
274     sscale=.true.
275     endif
276     c
277     if ((ndz.lt.5*n+1).or.((.not.sscale).and.(ndz.lt.6*n+1))) then
278     omode=2
279     if (reverse.gt.0) reverse = -1
280     if (impres.ge.1) write (io,922)
281     922 format (/" >>> m1qn3: not enough memory allocated")
282     return
283     endif
284     c
285     c---- Compute m
286     c
287     call mupdts (sscale,inmemo,n,m,ndz)
288     c
289     c --- Check the value of m (if (y,s) pairs in core, m will be >= 1)
290     c
291     if (m.lt.1) then
292     omode=2
293     if (reverse.gt.0) reverse = -1
294     if (impres.ge.1) write (io,930)
295     930 format (/" >>> m1qn3: m is set too small in mupdts")
296     return
297     endif
298     c
299     c --- mmemo = number of (y,s) pairs in core memory
300     c
301     mmemo=1
302     if (inmemo) mmemo=m
303     c
304     ntravu=2*(2+mmemo)*n+m
305     if (sscale) ntravu=ntravu-n
306     if (impres.ge.1) write (io,931) ndz,ntravu,m
307     931 format (/5x,"allocated memory (ndz) :",i9/
308     & 5x,"used memory : ",i9/
309     & 5x,"number of updates : ",i9)
310     if (ndz.lt.ntravu) then
311     omode=2
312     if (reverse.gt.0) reverse = -1
313     if (impres.ge.1) write (io,922)
314     return
315     endif
316     c
317     if (impres.ge.1) then
318     if (inmemo) then
319     write (io,932)
320     else
321     write (io,933)
322     endif
323     endif
324     932 format (5x,"(y,s) pairs are stored in core memory")
325     933 format (5x,"(y,s) pairs are stored by the user")
326     c
327     c---- cold start or warm restart ?
328     c check iz: iz(1)=n, iz(2)=(0 if DIS, 1 if SIS),
329     c iz(3)=m, iz(4)=jmin, iz(5)=jmax
330     c
331     if (imode(2).eq.0) then
332     if (impres.ge.1) write (io,940)
333     else
334     if (iz(1).ne.n .or. iz(2).ne.imode(1) .or. iz(3).ne.m .or.
335     & iz(4).lt.1 .or. iz(5).lt.0 .or. iz(4).gt.iz(3) .or.
336     & iz(5).gt.iz(3))
337     & then
338     omode=2
339     if (reverse.gt.0) reverse = -1
340     if (impres.ge.1) then
341     write (io,941)
342     if (iz(1).ne.n) write (io,942)
343     if (iz(2).ne.imode(1)) write (io,943)
344     if (iz(3).ne.m) write (io,944)
345     if (iz(4).lt.1 .or. iz(5).lt.0 .or. iz(4).gt.iz(3)
346     & .or. iz(5).gt.iz(3)) write (io,945)
347     endif
348     return
349     endif
350     if (impres.ge.1) write (io,946)
351     endif
352     940 format (/" m1qn3: cold start"/1x)
353     941 format (/" >>> m1qn3: inconsistent warm restart ")
354     942 format (" >>> m1qn3: (the number of variables has changed)")
355     943 format (" >>> m1qn3: (the scaling mode has changed)")
356     944 format (" >>> m1qn3: (the number of updates has changed)")
357     945 format (" >>> m1qn3: (wrong pointers)")
358     946 format (/" m1qn3: warm restart"/1x)
359     iz(1)=n
360     iz(2)=0
361     if (sscale) iz(2)=1
362     iz(3)=m
363     c
364     c---- split the working zone dz
365     c
366     idiag=1
367     iybar=idiag+n
368     if (sscale) iybar=1
369     isbar=iybar+n*mmemo
370     id=isbar+n*mmemo
371     igg=id+n
372     iaux=igg+n
373     ialpha=iaux+n
374     c
375     c---- call the optimization code
376     c
377     9999 continue
378     call m1qn3a (simul,prosca,ctonb,ctcab,n,x,f,g,dxmin,df1,epsg,
379     & normtype,impres,io,imode,omode,niter,nsim,inmemo,
380     & iz(3),iz(4),iz(5),dz(id),dz(igg),dz(idiag),dz(iaux),
381     & dz(ialpha),dz(iybar),dz(isbar),reverse,reentry,indic,
382     & izs,rzs,dzs)
383     if (reentry.gt.0) return
384     c
385     c---- impressions finales
386     c
387     1000 continue
388     if (impres.ge.1) write (io,960) omode,niter,nsim,epsg
389     960 format (/1x,79("-")/
390     & /" m1qn3: output mode is ",i2
391     & /5x,"number of iterations: ",i14
392     & /5x,"number of simulations: ",i13
393     & /5x,"realized relative precision on g: ",1pd9.2)
394     if (normtype.eq.'two') then
395     gnorm = sqrt(ddot(n,g,1,g,1))
396     elseif (normtype.eq.'sup') then
397     gnorm = dnrmi(n,g)
398     elseif (normtype.eq.'dfn') then
399     call prosca (n,g,g,ps,izs,rzs,dzs)
400     gnorm=dsqrt(ps)
401     endif
402    
403     if (impres.ge.1) write (io,961) f,normtype,gnorm
404     961 format (5x,"f = ",1pd15.8
405     & /5x,a3,"-norm of g = ",1pd15.8)
406    
407     return
408     end
409     c
410     c--------0---------0---------0---------0---------0---------0---------0--
411     c
412     subroutine m1qn3a (simul,prosca,ctonb,ctcab,n,x,f,g,dxmin,df1,
413     & epsg,normtype,impres,io,imode,omode,niter,nsim,
414     & inmemo,m,jmin,jmax,d,gg,diag,aux,alpha,ybar,
415     & sbar,reverse,reentry,indic,izs,rzs,dzs)
416     c----
417     c
418     c Code d optimisation proprement dit.
419     c
420     c----
421     c
422     implicit none
423     c
424     c arguments
425     c
426     logical inmemo
427     character*3 normtype
428     integer n,impres,io,imode(3),omode,niter,nsim,m,jmin,jmax,indic,
429     & reverse,reentry,izs(*)
430     real rzs(*)
431     double precision x(n),f,g(n),dxmin,df1,epsg,d(n),gg(n),diag(n),
432     & aux(n),alpha(m),ybar(n,1),sbar(n,1),dzs(*)
433     external simul,prosca,ctonb,ctcab
434     c
435     c variables locales
436     c
437     logical skip_update
438     integer i,moderl
439     #include "m1qn3a_common.h"
440     CML logical sscale,cold,warm,skip_update
441     CML integer i,itmax,moderl,isim,jcour
442     CML double precision d1,t,tmin,tmax,gnorm,gnorms,eps1,ff,preco,precos,
443     CML & ys,den,dk,dk1,ps,ps2,hp0
444     CML save sscale,cold,warm,i,itmax,moderl,isim,jcour,d1,t,tmin,tmax,
445     CML & gnorm,gnorms,eps1,ff,preco,precos,ys,den,dk,dk1,ps,ps2,hp0
446     c
447     c parametres
448     c
449     double precision rm1,rm2
450     parameter (rm1=0.0001d+0,rm2=0.99d+0)
451     double precision pi
452     parameter (pi=3.1415927d+0)
453     double precision rmin
454     c
455     c function
456     c
457     double precision ddot,dnrmi
458     c
459     c --- possible jumps
460     c 9998: call of the simulator in m1qn3a with indic = 1
461     c 9999: call of the simulator in mlis3 with indic = 4
462     c
463     if (reentry.eq.1) goto 9998
464     if (reentry.eq.2) goto 9999
465     c
466     c---- initialisation
467     c
468     rmin=1.d-20
469     c
470     sscale=.true.
471     if (imode(1).eq.0) sscale=.false.
472     c
473     warm=.false.
474     if (imode(2).eq.1) warm=.true.
475     cold=.not.warm
476     c
477     skip_update = .false.
478     c
479     itmax=niter
480     niter=0
481     isim=1
482     eps1=1.d+0
483     c
484     call prosca (n,g,g,ps,izs,rzs,dzs)
485     gnorm = dsqrt(ps)
486     if (normtype.eq.'two') then
487     gnorms = sqrt(ddot(n,g,1,g,1))
488     elseif (normtype.eq.'sup') then
489     gnorms = dnrmi(n,g)
490     elseif (normtype.eq.'dfn') then
491     gnorms = gnorm
492     endif
493     if (impres.ge.1) write (io,900) f,normtype,gnorms
494     900 format (5x,"f = ",1pd15.8
495     & /5x,a3,"-norm of g = ",1pd15.8)
496     if (gnorms.lt.rmin) then
497     omode=2
498     if (impres.ge.1) write (io,901)
499     goto 1000
500     endif
501     901 format (/" >>> m1qn3a: initial gradient is too small")
502     c
503     c --- initialisation pour dd
504     c
505     if (cold) then
506     jmin=1
507     jmax=0
508     endif
509     jcour=1
510     if (inmemo) jcour=jmax
511     c
512     c --- mise a l'echelle de la premiere direction de descente
513     c
514     if (cold) then
515     c
516     c --- use Fletcher's scaling and initialize diag to 1.
517     c
518     precos=2.d+0*df1/gnorm**2
519     do 10 i=1,n
520     d(i)=-g(i)*precos
521     diag(i)=1.d+0
522     10 continue
523     if (impres.ge.5) write(io,902) precos
524     902 format (/" m1qn3a: descent direction -g: precon = ",d10.3)
525     else
526     c
527     c --- use the matrix stored in [diag and] the (y,s) pairs
528     c
529     if (sscale) then
530     call prosca (n,ybar(1,jcour),ybar(1,jcour),ps,izs,rzs,dzs)
531     precos=1.d+0/ps
532     endif
533     do 11 i=1,n
534     d(i)=-g(i)
535     11 continue
536     if (inmemo) then
537     call dd (prosca,ctonb,ctcab,n,sscale,m,d,aux,jmin,jmax,
538     & precos,diag,alpha,ybar,sbar,izs,rzs,dzs)
539     else
540     call dds (prosca,ctonb,ctcab,n,sscale,m,d,aux,jmin,jmax,
541     & precos,diag,alpha,ybar,sbar,izs,rzs,dzs)
542     endif
543     endif
544     c
545     if (impres.eq.3) write(io,903)
546     if (impres.eq.4) write(io,903)
547     903 format (/1x,79("-"))
548     904 format (1x)
549     c
550     c --- initialisation pour mlis3
551     c
552     tmax=1.d+20
553     call prosca (n,d,g,hp0,izs,rzs,dzs)
554     if (hp0.ge.0.d+0) then
555     omode=7
556     if (impres.ge.1) write (io,905) niter,hp0
557     goto 1000
558     endif
559     905 format (/" >>> m1qn3 (iteration ",i2,"): "
560     & /5x," the search direction d is not a ",
561     & "descent direction: (g,d) = ",d12.5)
562     c
563     c --- compute the angle (-g,d)
564     c
565     if (warm.and.impres.ge.5) then
566     call prosca (n,g,g,ps,izs,rzs,dzs)
567     ps=dsqrt(ps)
568     call prosca (n,d,d,ps2,izs,rzs,dzs)
569     ps2=dsqrt(ps2)
570     ps=hp0/ps/ps2
571     ps=dmin1(-ps,1.d+0)
572     ps=dacos(ps)
573     d1=ps*180.d+0/pi
574     write (io,906) sngl(d1)
575     endif
576     906 format (/" m1qn3: descent direction d: ",
577     & "angle(-g,d) = ",f5.1," degrees")
578     c
579     c---- Debut de l iteration. on cherche x(k+1) de la forme x(k) + t*d,
580     c avec t > 0. On connait d.
581     c
582     c Debut de la boucle: etiquette 100,
583     c Sortie de la boucle: goto 1000.
584     c
585     100 niter=niter+1
586     if (impres.ge.5) write(io,903)
587     if (impres.ge.4) write(io,904)
588     if (impres.ge.4) write (io,910) niter,isim,f,hp0
589     910 format (" m1qn3: iter ",i0,", simul ",i0,
590     & ", f=",1pd15.8,", h'(0)=",d12.5)
591     c
592     c --- free simulation if desired
593     c
594     if (imode(3).gt.0) then
595     if (mod(niter-1,imode(3)).eq.0) then
596     indic=1
597     if (reverse.gt.0) then
598     reentry = 1
599     return
600     else
601     call simul(indic,n,x,f,g,izs,rzs,dzs)
602     endif
603     endif
604     endif
605     9998 continue
606     c
607     c --- recherche lineaire et nouveau point x(k+1)
608     c
609     do 101 i=1,n
610     gg(i)=g(i)
611     101 continue
612     ff=f
613     if (impres.ge.5) write (io,911)
614     911 format (/" m1qn3: line search")
615     c
616     c --- calcul de tmin
617     c
618     tmin=0.d+0
619     do 200 i=1,n
620     tmin=dmax1(tmin,dabs(d(i)))
621     200 continue
622     tmin=dxmin/tmin
623     t=1.d+0
624     d1=hp0
625     c
626     9999 continue
627     call mlis3 (n,simul,prosca,x,f,d1,t,tmin,tmax,d,g,rm2,rm1,impres,
628     & io,moderl,isim,nsim,aux,reverse,reentry,indic,izs,rzs,
629     & dzs)
630     if (reentry.gt.0) return
631     c
632     c --- mlis3 renvoie les nouvelles valeurs de x, f et g
633     c
634     if (moderl.ne.0) then
635     if (moderl.lt.0) then
636     c
637     c --- calcul impossible
638     c t, g: ou les calculs sont impossibles
639     c x, f: ceux du t_gauche (donc f <= ff)
640     c
641     omode=moderl
642     goto 1000
643     elseif (moderl.eq.1) then
644     c
645     c --- descente bloquee sur tmax
646     c
647     skip_update = .true.
648     c omode=3
649     c if (impres.ge.1) write(io,912) niter
650     c 912 format (/" >>> m1qn3 (iteration ",i0,
651     c & "): line search blocked on tmax: "/
652     c & " >>> possible reasons: bad scaling,",
653     c & " unbounded problem")
654     elseif (moderl.eq.4) then
655     c
656     c --- nsim atteint
657     c x, f: ceux du t_gauche (donc f <= ff)
658     c
659     omode=5
660     goto 1000
661     elseif (moderl.eq.5) then
662     c
663     c --- arret demande par l utilisateur (indic = 0)
664     c x, f: ceux en sortie du simulateur
665     c
666     omode=0
667     goto 1000
668     elseif (moderl.eq.6) then
669     c
670     c --- arret sur dxmin ou appel incoherent
671     c x, f: ceux du t_gauche (donc f <= ff)
672     c
673     omode=6
674     goto 1000
675     endif
676     else
677     skip_update = .false.
678     endif
679     c
680     c NOTE: stopping tests are now done after having updated the matrix, so
681     c that update information can be stored in case of a later warm restart
682     c
683     c --- mise a jour de la matrice
684     c
685     if (skip_update) then
686     if (impres.ge.5) write(io,'(/a)')
687     & " m1qn3: matrix update is skipped"
688     elseif (m.gt.0) then
689     c
690     c --- mise a jour des pointeurs
691     c
692     jmax=jmax+1
693     if (jmax.gt.m) jmax=jmax-m
694     if ((cold.and.niter.gt.m).or.(warm.and.jmin.eq.jmax)) then
695     jmin=jmin+1
696     if (jmin.gt.m) jmin=jmin-m
697     endif
698     if (inmemo) jcour=jmax
699     c
700     c --- y, s et (y,s)
701     c
702     do 400 i=1,n
703     sbar(i,jcour)=t*d(i)
704     ybar(i,jcour)=g(i)-gg(i)
705     400 continue
706     if (impres.ge.5) then
707     call prosca (n,sbar(1,jcour),sbar(1,jcour),ps,izs,rzs,dzs)
708     dk1=dsqrt(ps)
709     if (niter.gt.1) write (io,930) dk1/dk
710     930 format (/" m1qn3: convergence rate, s(k)/s(k-1) = ",
711     & 1pd12.5)
712     dk=dk1
713     endif
714     call prosca (n,ybar(1,jcour),sbar(1,jcour),ys,izs,rzs,dzs)
715     if (ys.le.0.d+0) then
716     omode=7
717     if (impres.ge.1) write (io,931) niter,ys
718     931 format (/" >>> m1qn3 (iteration ",i2,
719     & "): the scalar product (y,s) = ",d12.5
720     & /27x,"is not positive")
721     goto 1000
722     endif
723     c
724     c --- ybar et sbar
725     c
726     d1=dsqrt(1.d+0/ys)
727     do 410 i=1,n
728     sbar(i,jcour)=d1*sbar(i,jcour)
729     ybar(i,jcour)=d1*ybar(i,jcour)
730     410 continue
731     if (.not.inmemo) call ystbl (.true.,ybar,sbar,n,jmax)
732     c
733     c --- compute the scalar or diagonal preconditioner
734     c
735     if (impres.ge.5) write(io,932)
736     932 format (/" m1qn3: matrix update:")
737     c
738     c --- Here is the Oren-Spedicato factor, for scalar scaling
739     c
740     if (sscale) then
741     call prosca (n,ybar(1,jcour),ybar(1,jcour),ps,izs,rzs,dzs)
742     precos=1.d+0/ps
743     c
744     if (impres.ge.5) write (io,933) precos
745     933 format (5x,"Oren-Spedicato factor = ",d10.3)
746     c
747     c --- Scale the diagonal to Rayleigh s ellipsoid.
748     c Initially (niter.eq.1) and for a cold start, this is
749     c equivalent to an Oren-Spedicato scaling of the
750     c identity matrix.
751     c
752     else
753     call ctonb (n,ybar(1,jcour),aux,izs,rzs,dzs)
754     ps=0.d0
755     do 420 i=1,n
756     ps=ps+diag(i)*aux(i)*aux(i)
757     420 continue
758     d1=1.d0/ps
759     if (impres.ge.5) then
760     write (io,934) d1
761     934 format(5x,"fitting the ellipsoid: factor = ",1pd10.3)
762     endif
763     do 421 i=1,n
764     diag(i)=diag(i)*d1
765     421 continue
766     c
767     c --- update the diagonal
768     c (gg is used as an auxiliary vector)
769     c
770     call ctonb (n,sbar(1,jcour),gg,izs,rzs,dzs)
771     ps=0.d0
772     do 430 i=1,n
773     ps=ps+gg(i)*gg(i)/diag(i)
774     430 continue
775     den=ps
776     do 431 i=1,n
777     diag(i)=1.d0/
778     & (1.d0/diag(i)+aux(i)**2-(gg(i)/diag(i))**2/den)
779     if (diag(i).le.0.d0) then
780     if (impres.ge.5) write (io,935) i,diag(i),rmin
781     diag(i)=rmin
782     endif
783     431 continue
784     935 format (/" >>> m1qn3-WARNING: diagonal element ",i8,
785     & " is negative (",d10.3,"), reset to ",d10.3)
786     c
787     if (impres.ge.5) then
788     ps=0.d0
789     do 440 i=1,n
790     ps=ps+diag(i)
791     440 continue
792     ps=ps/n
793     preco=ps
794     c
795     ps2=0.d0
796     do 441 i=1,n
797     ps2=ps2+(diag(i)-ps)**2
798     441 continue
799     ps2=dsqrt(ps2/n)
800     write (io,936) preco,ps2
801     936 format (5x,"updated diagonal: average value = ",
802     & 1pd10.3,", sqrt(variance) = ",d10.3)
803     endif
804     endif
805     endif
806     c
807     c --- printings
808     c
809     c
810     c --- tests d arret
811     c
812     call prosca(n,g,g,ps,izs,rzs,dzs)
813     if (normtype.eq.'two') then
814     gnorm = sqrt(ddot(n,g,1,g,1))
815     elseif (normtype.eq.'sup') then
816     gnorm = dnrmi(n,g)
817     elseif (normtype.eq.'dfn') then
818     gnorm = dsqrt(ps)
819     endif
820     eps1 = gnorm/gnorms
821     c
822     if (impres.eq.3) then
823     if (mod(niter-1,50).eq.0) write(io,'(/a,a)')
824     & " iter simul stepsize f |g|",
825     & " |g|/|g0|"
826     write(io,
827     & '(1x,i5,2x,i5,2x,1pd8.2,2x,d21.14,2x,d11.5,2x,d10.4)')
828     & niter, isim, t, f, gnorm, eps1
829     endif
830     if (impres.ge.5) write (io,940) eps1
831     940 format (/" m1qn3: stopping criterion on g: ",1pd12.5)
832     if (eps1.lt.epsg) then
833     omode=1
834     goto 1000
835     endif
836     if (niter.eq.itmax) then
837     omode=4
838     if (impres.ge.1) write (io,941) niter
839     941 format (/" >>> m1qn3 (iteration ",i0,
840     & "): maximal number of iterations")
841     goto 1000
842     endif
843     if (isim.gt.nsim) then
844     omode=5
845     if (impres.ge.1) write (io,942) niter,isim
846     942 format (/" >>> m1qn3 (iteration ",i3,"): ",i6,
847     & " simulations (maximal number reached)")
848     goto 1000
849     endif
850     c
851     c --- calcul de la nouvelle direction de descente d = - H.g
852     c
853     if (m.eq.0) then
854     preco=2.d0*(ff-f)/ps
855     do 500 i=1,n
856     d(i)=-g(i)*preco
857     500 continue
858     else
859     do 510 i=1,n
860     d(i)=-g(i)
861     510 continue
862     if (inmemo) then
863     call dd (prosca,ctonb,ctcab,n,sscale,m,d,aux,jmin,jmax,
864     & precos,diag,alpha,ybar,sbar,izs,rzs,dzs)
865     else
866     call dds (prosca,ctonb,ctcab,n,sscale,m,d,aux,jmin,jmax,
867     & precos,diag,alpha,ybar,sbar,izs,rzs,dzs)
868     endif
869     endif
870     c
871     c --- test: la direction d est-elle de descente ?
872     c hp0 sera utilise par mlis3
873     c
874     call prosca (n,d,g,hp0,izs,rzs,dzs)
875     if (hp0.ge.0.d+0) then
876     omode=7
877     if (impres.ge.1) write (io,905) niter,hp0
878     goto 1000
879     endif
880     if (impres.ge.5) then
881     call prosca (n,g,g,ps,izs,rzs,dzs)
882     ps=dsqrt(ps)
883     call prosca (n,d,d,ps2,izs,rzs,dzs)
884     ps2=dsqrt(ps2)
885     ps=hp0/ps/ps2
886     ps=dmin1(-ps,1.d+0)
887     ps=dacos(ps)
888     d1=ps
889     d1=d1*180.d0/pi
890     write (io,906) sngl(d1)
891     endif
892     c
893     c---- on poursuit les iterations
894     c
895     goto 100
896     c
897     c --- n1qn3 has finished for ever
898     c
899     1000 continue
900     if (reverse.ne.0) reverse = -1
901     reentry = 0
902     nsim=isim
903     epsg=eps1
904     return
905     end
906     c
907     c--------0---------0---------0---------0---------0---------0---------0--
908     c
909     subroutine dd (prosca,ctonb,ctcab,n,sscale,nm,depl,aux,jmin,jmax,
910     & precos,diag,alpha,ybar,sbar,izs,rzs,dzs)
911     c----
912     c
913     c calcule le produit H.g ou
914     c . H est une matrice construite par la formule de bfgs inverse
915     c a nm memoires a partir de la matrice diagonale diag
916     c dans un espace hilbertien dont le produit scalaire
917     c est donne par prosca
918     c (cf. J. Nocedal, Math. of Comp. 35/151 (1980) 773-782)
919     c . g est un vecteur de dimension n (en general le gradient)
920     c
921     c la matrice diag apparait donc comme un preconditionneur diagonal
922     c
923     c depl = g (en entree), = H g (en sortie)
924     c
925     c la matrice H est memorisee par les vecteurs des tableaux
926     c ybar, sbar et les pointeurs jmin, jmax
927     c
928     c alpha(nm) est une zone de travail
929     c
930     c izs(*),rzs(*),dzs(*) sont des zones de travail pour prosca
931     c
932     c----
933     c
934     implicit none
935     c
936     c arguments
937     c
938     logical sscale
939     integer n,nm,jmin,jmax,izs(*)
940     real rzs(*)
941     double precision depl(n),precos,diag(n),alpha(nm),ybar(n,1),
942     & sbar(n,1),aux(n),dzs(*)
943     external prosca,ctonb,ctcab
944     c
945     c variables locales
946     c
947     integer jfin,i,j,jp
948     double precision r,ps
949     c
950     jfin=jmax
951     if (jfin.lt.jmin) jfin=jmax+nm
952     c
953     c phase de descente
954     c
955     do 100 j=jfin,jmin,-1
956     jp=j
957     if (jp.gt.nm) jp=jp-nm
958     call prosca (n,depl,sbar(1,jp),ps,izs,rzs,dzs)
959     r=ps
960     alpha(jp)=r
961     do 20 i=1,n
962     depl(i)=depl(i)-r*ybar(i,jp)
963     20 continue
964     100 continue
965     c
966     c preconditionnement
967     c
968     if (sscale) then
969     do 150 i=1,n
970     depl(i)=depl(i)*precos
971     150 continue
972     else
973     call ctonb (n,depl,aux,izs,rzs,dzs)
974     do 151 i=1,n
975     aux(i)=aux(i)*diag(i)
976     151 continue
977     call ctcab (n,aux,depl,izs,rzs,dzs)
978     endif
979     c
980     c remontee
981     c
982     do 200 j=jmin,jfin
983     jp=j
984     if (jp.gt.nm) jp=jp-nm
985     call prosca (n,depl,ybar(1,jp),ps,izs,rzs,dzs)
986     r=alpha(jp)-ps
987     do 120 i=1,n
988     depl(i)=depl(i)+r*sbar(i,jp)
989     120 continue
990     200 continue
991     return
992     end
993     c
994     c--------0---------0---------0---------0---------0---------0---------0--
995     c
996     subroutine dds (prosca,ctonb,ctcab,n,sscale,nm,depl,aux,jmin,
997     & jmax,precos,diag,alpha,ybar,sbar,izs,rzs,dzs)
998     c----
999     c
1000     c This subroutine has the same role as dd (computation of the
1001     c product H.g). It supposes however that the (y,s) pairs are not
1002     c stored in core memory, but on a devise chosen by the user.
1003     c The access to this devise is performed via the subroutine ystbl.
1004     c
1005     c----
1006     c
1007     implicit none
1008     c
1009     c arguments
1010     c
1011     logical sscale
1012     integer n,nm,jmin,jmax,izs(*)
1013     real rzs(*)
1014     double precision depl(n),precos,diag(n),alpha(nm),ybar(n),sbar(n),
1015     & aux(n),dzs(*)
1016     external prosca,ctonb,ctcab
1017     c
1018     c variables locales
1019     c
1020     integer jfin,i,j,jp
1021     double precision r,ps
1022     c
1023     jfin=jmax
1024     if (jfin.lt.jmin) jfin=jmax+nm
1025     c
1026     c phase de descente
1027     c
1028     do 100 j=jfin,jmin,-1
1029     jp=j
1030     if (jp.gt.nm) jp=jp-nm
1031     call ystbl (.false.,ybar,sbar,n,jp)
1032     call prosca (n,depl,sbar,ps,izs,rzs,dzs)
1033     r=ps
1034     alpha(jp)=r
1035     do 20 i=1,n
1036     depl(i)=depl(i)-r*ybar(i)
1037     20 continue
1038     100 continue
1039     c
1040     c preconditionnement
1041     c
1042     if (sscale) then
1043     do 150 i=1,n
1044     depl(i)=depl(i)*precos
1045     150 continue
1046     else
1047     call ctonb (n,depl,aux,izs,rzs,dzs)
1048     do 151 i=1,n
1049     aux(i)=aux(i)*diag(i)
1050     151 continue
1051     call ctcab (n,aux,depl,izs,rzs,dzs)
1052     endif
1053     c
1054     c remontee
1055     c
1056     do 200 j=jmin,jfin
1057     jp=j
1058     if (jp.gt.nm) jp=jp-nm
1059     call ystbl (.false.,ybar,sbar,n,jp)
1060     call prosca (n,depl,ybar(1),ps,izs,rzs,dzs)
1061     r=alpha(jp)-ps
1062     do 120 i=1,n
1063     depl(i)=depl(i)+r*sbar(i)
1064     120 continue
1065     200 continue
1066     return
1067     end
1068     c
1069     c--------0---------0---------0---------0---------0---------0---------0--
1070     c
1071     subroutine mlis3 (n,simul,prosca,x,f,fpn,t,tmin,tmax,d,g,
1072     1 amd,amf,imp,io,logic,nap,napmax,xn,
1073     1 reverse,reentry,indic,izs,rzs,dzs)
1074     c
1075     c ----
1076     c
1077     c mlis3 + minuscules + commentaires
1078     c + version amelioree (XII 88): interpolation cubique systematique
1079     c et anti-overflows
1080     c + declaration variables (II/89, JCG).
1081     c + barr is also progressively decreased (12/93, CL & JChG).
1082     c barmul is set to 5.
1083     c
1084     c ----------------------------------------------------------------
1085     c
1086     c en sortie logic =
1087     c
1088     c 0 descente serieuse
1089     c 1 descente bloquee sur tmax
1090     c 4 nap > napmax
1091     c 5 arret demande par le simulateur
1092     c 6 fonction et gradient pas d accord
1093     c < 0 contrainte implicite active
1094     c
1095     c indic on entry (in reverse communication)
1096     c
1097     c < 0: the simulator cannot compute f and g
1098     c = 0: the simulator wants to stop
1099     c > 0: the simulator has done its work
1100     c
1101     c indic on return (in reverse communication)
1102     c
1103     c = 4: the simulator is asked to compute f and g
1104     c
1105     c reverse
1106     c
1107     c = 0: direct communication
1108     c = 1: reverse communication
1109     c
1110     c reentry on entry
1111     c
1112     c = 2: reverse communication, return from a simulation, skip to
1113     c the place where the simulator was called (9999)
1114     c
1115     c reentry return
1116     c
1117     c = 0: reverse communication, the linesearch has finished its job
1118     c = 2: reverse communication, a simulation is required
1119     c
1120     c ----
1121     c
1122     implicit none
1123     c
1124     c --- arguments
1125     c
1126     integer n,imp,io,logic,nap,napmax,indic,reverse,reentry,izs(*)
1127     real rzs(*)
1128     double precision x(n),f,fpn,t,tmin,tmax,d(n),g(n),amd,amf,xn(n),
1129     & dzs(*)
1130     external simul,prosca
1131     c
1132     c --- variables locales
1133     c
1134     #include "mlis3_common.h"
1135 mlosch 1.5 integer i
1136 mlosch 1.2 double precision taa,ps
1137 mlosch 1.1 CML save t_increased,i,indica,indicd,tesf,tesd,tg,fg,fpg,td,ta,fa,
1138     CML & fpa,d2,fn,fp,ffn,fd,fpd,z,test,barmin,barmul,barmax,barr,
1139     CML & gauche,droite,taa,ps
1140     c
1141     1000 format (/4x," mlis3 ",4x,"fpn=",1pd10.3," d2=",d9.2,
1142     1 " tmin=",d9.2," tmax=",d9.2)
1143     1001 format (/4x," mlis3",3x,"stop on tmin",5x,
1144     1 "stepsizes",11x,"functions",8x,"derivatives")
1145     1002 format (4x," mlis3",37x,1pd10.3,2d11.3)
1146     1003 format (4x," mlis3",1pd14.3,2d11.3)
1147     1004 format (4x," mlis3",37x,1pd10.3," indic=",i3)
1148     1005 format (4x," mlis3",14x,1pd18.8,2x,d21.14,2x,d11.4)
1149     1006 format (4x," mlis3",14x,1pd18.8," indic=",i3)
1150     1007 format (/4x," mlis3",10x,"tmin forced to tmax")
1151     1008 format (/4x," mlis3",10x,"inconsistent call")
1152     c
1153     c --- possible jump
1154     c
1155     if (reentry.eq.2) goto 9999
1156     c
1157     if (n.gt.0 .and. fpn.lt.0.d0 .and. t.gt.0.d0
1158     1 .and. tmax.gt.0.d0 .and. amf.gt.0.d0
1159     1 .and. amd.gt.amf .and. amd.lt.1.d0) go to 5
1160     logic=6
1161     go to 999
1162     5 tesf=amf*fpn
1163     tesd=amd*fpn
1164     barmin=0.01d0
1165     barmul=5.d0
1166     barmax=0.3d0
1167     barr=barmin
1168     td=0.d0
1169     tg=0.d0
1170     fn=f
1171     fg=fn
1172     fpg=fpn
1173     ta=0.d0
1174     fa=fn
1175     fpa=fpn
1176     call prosca (n,d,d,ps,izs,rzs,dzs)
1177     d2=ps
1178     c
1179     c elimination d un t initial ridiculement petit
1180     c
1181     c<
1182     c if (t.gt.tmin) go to 20
1183     c t=tmin
1184     c if (t.le.tmax) go to 20
1185     c if (imp.gt.0) write (io,1007)
1186     c tmin=tmax
1187     c 20 if (fn+t*fpn.lt.fn+0.9d0*t*fpn) go to 30
1188     c t=2.d0*t
1189     c go to 20
1190     c changed into
1191     if (t.lt.tmin) then
1192     t=tmin
1193     if (imp.ge.4) write (io,'(a)')
1194     & ' mlis3: initial step-size increased to tmin'
1195     if (t.gt.tmax) then
1196     if (imp.gt.0) write (io,1007)
1197     tmin=tmax
1198     endif
1199     endif
1200     t_increased = .false.
1201     do while (fn+t*fpn.ge.fn+0.9d0*t*fpn)
1202     t_increased = .true.
1203     t = 2.d0*t
1204     enddo
1205     if (t_increased .and. (imp.ge.4)) write (io,'(a,1pd10.3)')
1206     & ' mlis3: initial step-size increased to ',t
1207     c>
1208     30 indica=1
1209     logic=0
1210     if (t.gt.tmax) then
1211     t=tmax
1212     logic=1
1213     endif
1214     if (imp.ge.4) write (io,1000) fpn,d2,tmin,tmax
1215     c
1216     c --- nouveau x
1217     c initialize xn to the current iterate
1218     c use x as the trial iterate
1219     c
1220     do i=1,n
1221     xn(i)=x(i)
1222     x(i)=xn(i)+t*d(i)
1223     enddo
1224     c
1225     c --- boucle
1226     c
1227     100 nap=nap+1
1228     if(nap.gt.napmax) then
1229     logic=4
1230     fn=fg
1231     do i=1,n
1232     xn(i)=xn(i)+tg*d(i)
1233     enddo
1234     go to 999
1235     endif
1236     c
1237     c --- appel simulateur
1238     c
1239     indic=4
1240     if (reverse.gt.0) then
1241     reentry = 2
1242     return
1243     else
1244     call simul(indic,n,x,f,g,izs,rzs,dzs)
1245     endif
1246     9999 continue
1247     if (indic.eq.0) then
1248     c
1249     c --- arret demande par l utilisateur
1250     c
1251     logic=5
1252     fn=f
1253     do 170 i=1,n
1254     xn(i)=x(i)
1255     170 continue
1256     go to 999
1257     endif
1258     if(indic.lt.0) then
1259     c
1260     c --- les calculs n ont pas pu etre effectues par le simulateur
1261     c
1262     td=t
1263     indicd=indic
1264     logic=0
1265     if (imp.ge.4) write (io,1004) t,indic
1266     t=tg+0.1d0*(td-tg)
1267     go to 905
1268     endif
1269     c
1270     c --- les tests elementaires sont faits, on y va
1271     c
1272     call prosca (n,d,g,ps,izs,rzs,dzs)
1273     fp=ps
1274     c
1275     c --- premier test de Wolfe
1276     c
1277     ffn=f-fn
1278     if(ffn.gt.t*tesf) then
1279     td=t
1280     fd=f
1281     fpd=fp
1282     indicd=indic
1283     logic=0
1284     if(imp.ge.4) write (io,1002) t,ffn,fp
1285     go to 500
1286     endif
1287     c
1288     c --- test 1 ok, donc deuxieme test de Wolfe
1289     c
1290     if(imp.ge.4) write (io,1003) t,ffn,fp
1291     if(fp.gt.tesd) then
1292     logic=0
1293     go to 320
1294     endif
1295     if (logic.eq.0) go to 350
1296     c
1297     c --- test 2 ok, donc pas serieux, on sort
1298     c
1299     320 fn=f
1300     do 330 i=1,n
1301     xn(i)=x(i)
1302     330 continue
1303     go to 999
1304     c
1305     c
1306     c
1307     350 tg=t
1308     fg=f
1309     fpg=fp
1310     if(td.ne.0.d0) go to 500
1311     c
1312     c extrapolation
1313     c
1314     taa=t
1315     gauche=(1.d0+barmin)*t
1316     droite=10.d0*t
1317     call ecube (t,f,fp,ta,fa,fpa,gauche,droite)
1318     ta=taa
1319     if(t.lt.tmax) go to 900
1320     logic=1
1321     t=tmax
1322     go to 900
1323     c
1324     c interpolation
1325     c
1326     500 if(indica.le.0) then
1327     ta=t
1328     t=0.9d0*tg+0.1d0*td
1329     go to 900
1330     endif
1331     test=barr*(td-tg)
1332     gauche=tg+test
1333     droite=td-test
1334     taa=t
1335     call ecube (t,f,fp,ta,fa,fpa,gauche,droite)
1336     ta=taa
1337     if (t.gt.gauche .and. t.lt.droite) then
1338     barr=dmax1(barmin,barr/barmul)
1339     c barr=barmin
1340     else
1341     barr=dmin1(barmul*barr,barmax)
1342     endif
1343     c
1344     c --- fin de boucle
1345     c - t peut etre bloque sur tmax
1346     c (venant de l extrapolation avec logic=1)
1347     c
1348     900 fa=f
1349     fpa=fp
1350     905 indica=indic
1351     c
1352     c --- faut-il continuer ?
1353     c
1354     if (td.eq.0.d0) go to 950
1355     if (td-tg.lt.tmin) go to 920
1356     c
1357     c --- limite de precision machine (arret de secours) ?
1358     c
1359     do 910 i=1,n
1360     z=xn(i)+t*d(i)
1361     if (z.ne.xn(i).and.z.ne.x(i)) go to 950
1362     910 continue
1363     if (imp.gt.3) write (io,'(5x,a)') "mlis3 no change in x"
1364     c
1365     c --- arret sur dxmin ou de secours
1366     c
1367     920 logic=6
1368     c
1369     c si indicd<0, derniers calculs non faits par simul
1370     c
1371     if (indicd.lt.0) logic=indicd
1372     c
1373     c si tg=0, xn = xn_depart,
1374     c sinon on prend xn=x_gauche qui fait decroitre f
1375     c
1376     if (tg.eq.0.d0) go to 940
1377     fn=fg
1378     do 930 i=1,n
1379     930 xn(i)=xn(i)+tg*d(i)
1380     940 if (imp.le.3) go to 999
1381     write (io,1001)
1382     write (io,1005) tg,fg,fpg
1383     if (logic.eq.6) write (io,1005) td,fd,fpd
1384     if (logic.eq.7) write (io,1006) td,indicd
1385     go to 999
1386     c
1387     c recopiage de x et boucle
1388     c
1389     950 do 960 i=1,n
1390     960 x(i)=xn(i)+t*d(i)
1391     go to 100
1392     c --- linesearch finished, no skip at next entry in mlis3
1393     999 if (reverse.ne.0) reentry = 0
1394     return
1395     end
1396     c
1397     c
1398     c--------0---------0---------0---------0---------0---------0---------0--
1399     c
1400     subroutine ecube (t,f,fp,ta,fa,fpa,tlower,tupper)
1401     c
1402     implicit none
1403     c
1404     c --- arguments
1405     c
1406     double precision sign,den,anum,t,f,fp,ta,fa,fpa,tlower,tupper
1407     c
1408     c --- variables locales
1409     c
1410     double precision z1,b,discri
1411     c
1412     c Using f and fp at t and ta, computes new t by cubic formula
1413     c safeguarded inside [tlower,tupper].
1414     c
1415     z1=fp+fpa-3.d0*(fa-f)/(ta-t)
1416     b=z1+fp
1417     c
1418     c first compute the discriminant (without overflow)
1419     c
1420     if (dabs(z1).le.1.d0) then
1421     discri=z1*z1-fp*fpa
1422     else
1423     discri=fp/z1
1424     discri=discri*fpa
1425     discri=z1-discri
1426     if (z1.ge.0.d0 .and. discri.ge.0.d0) then
1427     discri=dsqrt(z1)*dsqrt(discri)
1428     go to 120
1429     endif
1430     if (z1.le.0.d0 .and. discri.le.0.d0) then
1431     discri=dsqrt(-z1)*dsqrt(-discri)
1432     go to 120
1433     endif
1434     discri=-1.d0
1435     endif
1436     if (discri.lt.0.d0) then
1437     if (fp.lt.0.d0) t=tupper
1438     if (fp.ge.0.d0) t=tlower
1439     go to 900
1440     endif
1441     c
1442     c discriminant nonnegative, compute solution (without overflow)
1443     c
1444     discri=dsqrt(discri)
1445     120 if (t-ta.lt.0.d0) discri=-discri
1446     sign=(t-ta)/dabs(t-ta)
1447     if (b*sign.gt.0.d+0) then
1448     t=t+fp*(ta-t)/(b+discri)
1449     else
1450     den=z1+b+fpa
1451     anum=b-discri
1452     if (dabs((t-ta)*anum).lt.(tupper-tlower)*dabs(den)) then
1453     t=t+anum*(ta-t)/den
1454     else
1455     t=tupper
1456     endif
1457     endif
1458     900 t=dmax1(t,tlower)
1459     t=dmin1(t,tupper)
1460     return
1461     end
1462     c
1463     c--------0---------0---------0---------0---------0---------0---------0--
1464     c
1465     subroutine mupdts (sscale,inmemo,n,m,nrz)
1466     c
1467     implicit none
1468     c
1469     c arguments
1470     c
1471     logical sscale,inmemo
1472     integer n,m,nrz
1473     c----
1474     c
1475     c On entry:
1476     c sscale: .true. if scalar initial scaling,
1477     c .false. if diagonal initial scaling
1478     c n: number of variables
1479     c
1480     c This routine has to return:
1481     c m: the number of updates to form the approximate Hessien H,
1482     c inmemo: .true., if the vectors y and s used to form H are stored
1483     c in core memory,
1484     c .false. otherwise (storage of y and s on disk, for
1485     c instance).
1486     c When inmemo=.false., the routine "ystbl", which stores and
1487     c restores (y,s) pairs, has to be rewritten.
1488     c
1489     c----
1490     c
1491     if (sscale) then
1492     m=(nrz-3*n)/(2*n+1)
1493     else
1494     m=(nrz-4*n)/(2*n+1)
1495     endif
1496     inmemo=.true.
1497     return
1498     end
1499     c
1500     c--------0---------0---------0---------0---------0---------0---------0--
1501     c
1502     subroutine ystbl (store,ybar,sbar,n,j)
1503     c----
1504     c
1505     c This subroutine should store (if store = .true.) or restore
1506     c (if store = .false.) a pair (ybar,sbar) at or from position
1507     c j in memory. Be sure to have 1 <= j <= m, where m in the number
1508     c of updates specified by subroutine mupdts.
1509     c
1510     c The subroutine is used only when the (y,s) pairs are not
1511     c stored in core memory in the arrays ybar(.,.) and sbar(.,.).
1512     c In this case, the subroutine has to be written by the user.
1513     c
1514     c----
1515     c
1516     implicit none
1517     c
1518     c arguments
1519     c
1520     logical store
1521     integer n,j
1522     double precision ybar(n),sbar(n)
1523     c
1524     return
1525     end
1526     c
1527     c--------0---------0---------0---------0---------0---------0---------0--
1528     c
1529     subroutine ctonbe (n,u,v,izs,rzs,dzs)
1530     c
1531     implicit none
1532     integer n,izs(*)
1533     real rzs(*)
1534     double precision u(1),v(1),dzs(*)
1535     c
1536     integer i
1537     c
1538     do i=1,n
1539     v(i)=u(i)
1540     enddo
1541     return
1542     end
1543     c
1544     c--------0---------0---------0---------0---------0---------0---------0--
1545     c
1546     subroutine ctcabe (n,u,v,izs,rzs,dzs)
1547     c
1548     implicit none
1549     integer n,izs(*)
1550     real rzs(*)
1551     double precision u(1),v(1),dzs(*)
1552     c
1553     integer i
1554     c
1555     do i=1,n
1556     v(i)=u(i)
1557     enddo
1558     return
1559     end
1560     c
1561     c--------0---------0---------0---------0---------0---------0---------0--
1562     c
1563     subroutine euclid (n,x,y,ps,izs,rzs,dzs)
1564     c
1565     implicit none
1566     integer n,izs(*)
1567     real rzs(*)
1568     double precision x(n),y(n),ps,dzs(*)
1569     c
1570     integer i
1571     c
1572     ps=0.d0
1573     do i=1,n
1574     ps=ps+x(i)*y(i)
1575     enddo
1576     return
1577     end
1578     c
1579     c--------0---------0---------0---------0---------0---------0---------0--
1580     c
1581     subroutine simul_rc (indic,n,x,f,g,izs,rzs,dzs)
1582     c
1583     implicit none
1584     integer indic,n,izs(*)
1585     real rzs(*)
1586     double precision x(n),f,g(n),dzs(*)
1587     c
1588     return
1589     end
1590     c
1591     c--------0---------0---------0---------0---------0---------0---------0--
1592     c
1593     double precision function dnrmi (n,v)
1594     c
1595     integer n
1596     double precision v(n)
1597     c
1598     c----
1599     c
1600     c Commputes the infinty-norm of the vector v(n)
1601     c
1602     c----
1603     c
1604     c --- local variables
1605     c
1606     integer i
1607     double precision norm
1608     c
1609     c --- compute
1610     c
1611     norm = 0.d0
1612     if (n.gt.0) then
1613     do i=1,n
1614     norm = max(norm,abs(v(i)))
1615     enddo
1616     endif
1617     dnrmi = norm
1618     c
1619     return
1620     end

  ViewVC Help
Powered by ViewVC 1.1.22