Millepede-II  V04-00-00_preview
 All Classes Files Functions Variables Enumerator Pages
linesrch.f90
Go to the documentation of this file.
1 
2 ! Code converted using TO_F90 by Alan Miller
3 ! Date: 2012-03-16 Time: 11:06:29
4 
31 
33 MODULE linesrch
34  IMPLICIT NONE
35 
36  INTEGER, PARAMETER :: msfd=20
37  INTEGER :: nsfd !< number of function calls
38  INTEGER :: idgl !< index of smallest negative slope
39  INTEGER :: idgr !< index of smallest positive slope
40  INTEGER :: idgm !< index of minimal slope
41  INTEGER :: minf=1 !< min. number of function calls
42  INTEGER :: maxf=5 !< max. number of function calls
43  INTEGER :: lsinfo !< (status) information
44  DOUBLE PRECISION, DIMENSION(4,msfd) :: sfd !< abscissa; function value; slope; predicted zero
45  DOUBLE PRECISION :: stmx=0.9 !< maximum slope ratio
46  DOUBLE PRECISION :: gtol !< slope ratio
47 
48 END MODULE linesrch
49 
67 
68 SUBROUTINE ptline(n,x,f,g,s,step, info) ! - 2 arguments
69  USE linesrch
70 
71  IMPLICIT NONE
72  INTEGER, INTENT(IN) :: n
73  DOUBLE PRECISION, INTENT(IN OUT) :: x(n)
74  DOUBLE PRECISION, INTENT(IN OUT) :: f
75  DOUBLE PRECISION, INTENT(IN OUT) :: g(n)
76  DOUBLE PRECISION, INTENT(IN OUT) :: s(n)
77  DOUBLE PRECISION, INTENT(OUT) :: step
78  INTEGER, INTENT(OUT) :: info
79 
80  INTEGER:: i1
81  INTEGER :: i2
82  INTEGER :: i ! internal
83  INTEGER :: im ! internal
84  DOUBLE PRECISION :: alpha ! internal
85  DOUBLE PRECISION :: dginit ! internal
86  DOUBLE PRECISION :: dg ! internal
87  DOUBLE PRECISION :: fsaved ! internal
88  DOUBLE PRECISION :: tot ! internal
89  DOUBLE PRECISION :: fp1 ! internal
90  DOUBLE PRECISION :: fp2 ! internal
91  SAVE
92 
93  ! initialization ---------------------------------------------------
94 
95  info=0 ! reset INFO flag
96  dg=0.0d0
97  DO i=1,n !
98  dg=dg-g(i)*s(i) ! DG = scalar product: grad x search
99  END do!
100 
101  IF(nsfd == 0) THEN ! initial call
102  dginit=dg ! DG = initial directional gradient
103  IF(dginit >= 0.0d0) go to 100 ! error: step not decreasing
104  step=1.0d0 ! initial step factor is one
105  alpha=step ! get initial step factor
106  tot=0.0d0 ! reset total step
107  idgl=1 ! index of smallest negative slope
108  idgr=0 ! index of smallest positive slope
109  fsaved=f ! initial Function value
110  nsfd=1 ! starting point of iteration
111  sfd(1,1)=0.0 ! abscissa
112  sfd(2,1)=0.0 ! reference function value
113  sfd(3,1)=dginit ! slope
114  sfd(4,1)=0.0 ! predicted zero
115  im=1 ! optimum
116  ELSE ! subsequent call
117  nsfd=nsfd+1
118  sfd(1,nsfd)=tot ! abscissa
119  sfd(2,nsfd)=f-fsaved ! function value difference to reference
120  sfd(3,nsfd)=dg ! slope
121  sfd(4,nsfd)=0.0 ! predicted zero (see below)
122  IF(dg < sfd(3,im)) THEN
123  im=nsfd
124  END IF
125 
126  ! define interval indices IDGL and IDGR
127  IF(dg <= 0.0d0) THEN
128  IF(dg >= sfd(3,idgl)) idgl=nsfd
129  END IF
130  IF(dg >= 0.0d0) THEN ! limit to the right
131  IF(idgr == 0) idgr=nsfd
132  IF(dg <= sfd(3,idgr)) idgr=nsfd
133  END IF
134 
135  IF(idgr == 0) THEN
136  i1=nsfd-1
137  i2=nsfd
138  ELSE
139  i1=idgl
140  i2=idgr
141  END IF
142  fp1=sfd(3,i1)
143  fp2=sfd(3,i2) ! interpolation
144  sfd(4,nsfd)=(sfd(1,i1)*fp2-sfd(1,i2)*fp1)/(fp2-fp1)
145 
146  ! convergence tests
147  IF(nsfd >= minf.AND.abs(dg) <= abs(dginit)*gtol) THEN
148  ! normal convergence return with INFO=1 ----------------------
149  alpha=tot+alpha ! total ALPHA is returned
150  step =alpha
151  idgm=idgl
152  IF(idgr /= 0) THEN
153  IF(sfd(3,idgr)+sfd(3,idgl) < 0.0d0) idgm=idgr
154  END IF
155  go to 101
156  END IF
157  IF(nsfd >= maxf) go to 102 ! max number of function calls
158  alpha=min(sfd(4,nsfd),stmx)-tot ! new step from previous
159  IF(abs(alpha) < 1.0d-3.AND.sfd(4,nsfd) > stmx) go to 103
160  IF(abs(alpha) < 1.0d-3) go to 104
161  END IF
162 
163  ! prepare next function call ---------------------------------------
164 
165  DO i=1,n
166  x(i)=x(i)+alpha*s(i) ! step by ALPHA -> new X
167  END DO
168  tot=tot+alpha !
169  step=tot
170  info=-1 ! recalculate function and gradient
171  lsinfo=info
172  return
173 
174  ! error exits ------------------------------------------------------
175 104 info=info+1 ! 4: step small
176 103 info=info+1 ! 3: maximum reached
177 102 info=info+1 ! 2: too many function calls
178 101 info=info+1 ! 1: normal convergence
179  lsinfo=info
180  im=1
181  DO i=1,nsfd
182  IF(abs(sfd(3,i)) < abs(sfd(3,im))) im=i
183  END DO
184  alpha=sfd(1,im)-sfd(1,nsfd)
185  IF(im == nsfd) return ! already at minimum
186  DO i=1,n
187  x(i)=x(i)+alpha*s(i) ! step by ALPHA to slope minimum
188  END DO
189  f=sfd(2,im)+fsaved ! F at minimum
190  step=sfd(1,im) ! total step at convergence
191  IF(im /= 1) return ! improvement
192  info=5 ! no improvement
193 100 step=0.0d0 ! 0: initial slope not negative
194  lsinfo=info
195  return
196 END SUBROUTINE ptline
197 
210 
211 SUBROUTINE ptldef(gtole,stmax,minfe,maxfe)
212  USE linesrch
213 
214  IMPLICIT NONE
215  INTEGER, INTENT(IN) :: minfe
216  INTEGER, INTENT(IN) :: maxfe
217  REAL, INTENT(IN) :: gtole
218  REAL, INTENT(IN) :: stmax
219 
220  gtol=max(1.0e-4,min(gtole,0.9e0)) ! slope ratio
221  IF(gtole == 0.0) gtol=0.9d0 ! default slope ratio
222  stmx=stmax ! maximum total step
223  IF(stmx == 0.0d0) stmx=10.0d0 ! default limit
224  minf=max(1,min(minfe,msfd-2)) ! minimum number of evaluations
225  maxf=max(2,min(maxfe,msfd-1)) ! maximum number of evaluations
226  IF(maxfe == 0) maxf=5 ! default max number of values
227  nsfd=0 ! reset
228 END SUBROUTINE ptldef
229 
236 
237 SUBROUTINE ptlopt(nf,m,slopes,steps)
238  USE linesrch
239  IMPLICIT NONE
240 
241  INTEGER, INTENT(OUT) :: nf
242  INTEGER, INTENT(OUT) :: m
243  REAL, DIMENSION(3), INTENT(OUT) :: slopes
244  REAL, DIMENSION(3), INTENT(OUT) :: steps
245  INTEGER :: i
246 
247  ! ...
248  nf=nsfd
249  IF(nsfd == 0) THEN ! no values
250  m=0
251  DO i=1,3
252  slopes(i)=0.0
253  steps(i) =0.0
254  END DO
255  ELSE ! values exist
256  m=1
257  DO i=1,nsfd
258  IF(abs(sfd(3,i)) < abs(sfd(3,m))) m=i
259  END DO
260  slopes(1)=REAL(sfd(3,1))
261  slopes(2)=REAL(sfd(3,nsfd))
262  slopes(3)=REAL(sfd(3,m))
263  steps(1) =REAL(sfd(1,1))
264  steps(2) =REAL(sfd(1,nsfd))
265  steps(3) =REAL(sfd(1,m))
266  END IF
267 END SUBROUTINE ptlopt
268 
272 
273 SUBROUTINE ptlprt(lunp)
274  USE linesrch
275 
276  IMPLICIT NONE
277  INTEGER :: i
278  INTEGER :: j
279  INTEGER :: im
280  INTEGER :: lun
281  INTEGER, INTENT(IN) :: lunp
282  REAL :: ratio
283  CHARACTER (LEN=2) :: tlr
284  ! ...
285  lun=lunp
286  IF(lun == 0) lun=6
287  IF(nsfd <= 0) return
288  WRITE(lun,*) ' '
289  WRITE(lun,*) 'PTLINE: line-search method based on slopes', &
290  ' with sufficient slope-decrease'
291  WRITE(lun,*) 'PTLDEF: slope ratio limit=',gtol
292  WRITE(lun,*) 'PTLDEF: maximum step =',stmx
293  WRITE(lun,*) 'PTLDEF:',minf,' <= nr of calls <=',maxf
294  WRITE(lun,101)
295  im=1
296  DO i=1,nsfd
297  IF(abs(sfd(3,i)) < abs(sfd(3,im))) im=i
298  END DO
299  DO i=1,nsfd
300  tlr=' '
301  IF(i == im) tlr='**'
302  IF(i == idgl) tlr(1:1)='L'
303  IF(i == idgr) tlr(2:2)='R'
304  IF(i == 1) THEN
305  WRITE(lun,102) i-1, sfd(1,i),tlr,(sfd(j,i),j=2,4)
306  ELSE
307  ratio=REAL(abs(sfd(3,i)/sfd(3,1)))
308  WRITE(lun,103) i-1, sfd(1,i),tlr,(sfd(j,i),j=2,4),ratio
309  END IF
310 
311  END DO
312  IF(lsinfo == 0) WRITE(lun,*) &
313  'PTLINE: INFO=0 input error (e.g. gradient not negative)'
314  IF(lsinfo == 1) WRITE(lun,*) 'PTLINE: INFO=1 convergence reached'
315  IF(lsinfo == 2) WRITE(lun,*) 'PTLINE: INFO=2 too many function calls'
316  IF(lsinfo == 3) WRITE(lun,*) 'PTLINE: INFO=3 maximum step reached'
317  IF(lsinfo == 4) WRITE(lun,*) 'PTLINE: INFO=4 step too small (< 0.001)'
318  WRITE(lun,*) ' '
319 
320 101 format(' i x F(x) F''(X)', &
321  ' minimum F''(X)')
322 102 format(i3,f12.6,1x,a2,g15.6,g14.6,f12.6,' ratio')
323 103 format(i3,f12.6,1x,a2,g15.6,g14.6,f12.6,f10.3)
324 
325 END SUBROUTINE ptlprt
326