source: mincjg.f@ 32289cd

Last change on this file since 32289cd was 32289cd, checked in by baerbaer <baerbaer@…>, 14 years ago

Explicitly declare variables.

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/smmp/trunk@33 26dc1dd8-5c4e-0410-9ffe-d298b4865968

  • Property mode set to 100644
File size: 6.5 KB
Line 
1! **************************************************************
2!
3! This file contains the subroutines: mincjg
4!
5! Copyright 2003-2005 Frank Eisenmenger, U.H.E. Hansmann,
6! Shura Hayryan, Chin-Ku
7! Copyright 2007 Frank Eisenmenger, U.H.E. Hansmann,
8! Jan H. Meinke, Sandipan Mohanty
9!
10! ********************************************************************
11 subroutine mincjg(n,mxn,x,f,g,acur,d,xa,ga,dt,yt,gt,maxfun,nfun)
12
13! ....................................................................
14!
15! Conjugate Gradient Minimizer
16!
17! INPUT: X,F,G - variables, value of FUNC, gradient at START/
18! ACUR - convergence is assumed if ACUR > SUM ( G(I)**2 )
19! MAXFUN - maximum overall number of function calls
20!
21! OUTPUT: X,F,G - variables, value of FUNC, gradient at MINIMUM
22! NFUN - overall number of function calls used
23!
24! ARRAYS: D,XA,GA,YT,DT,GT - dimension N
25!
26! CALLS: MOVE - calculate function & its gradients for current X
27!
28! PARAMETERS: AMF - rough estimate of first reduction in F, used
29! to guess initial step of 1st line search
30! MXFCON - see 'ier=4'
31! MAXLIN -
32!
33! DIAGNOSTICS (ier)
34!
35! = 0: minimization completed successfully
36! = 1: number of steps reached MAXFUN
37! = 2: line search was abandoned
38! = 3: search direction is uphill
39! = 4: two consecutive line searches failed to reduce F
40! ....................................................................
41
42 double precision amf, tol, eps, gsqrd, fmin, f, t, g, ga, d, xa, x
43 double precision gsq2, gnew, dfpr, stmin, fuit, gdit, gt, gdmi
44 double precision sbound, stepch, step, wo, sum, fch, acur, ddspln
45 double precision gspln, beta, gama, yt, dt, gamden, di
46
47 integer mxfcon, maxlin, mxn, ier, iter, iterfm, iterrs, nfun
48 integer nfopt, i, n, nfbeg, iretry, maxfun
49
50 parameter (AMF = 10.d0,
51 & MXFCON = 2,
52 & MAXLIN = 5,
53 & TOL = 1.d-7, ! controls 'stepch'
54 & EPS = .7d0)
55
56 dimension x(mxn),g(mxn),
57 & d(mxn),xa(mxn),ga(mxn),dt(mxn),yt(mxn),gt(mxn)
58
59
60 ier = 0
61 iter = 0
62 iterfm = 0
63 iterrs = 0
64 nfun = 0
65 nfopt = nfun
66
67 gsqrd = 0.d0
68 fmin = f
69
70 do i=1,n
71 t = g(i)
72 ga(i) = t
73 d(i) = -t
74 gsqrd = gsqrd + t**2
75 xa(i) = x(i)
76 enddo
77
78 gsq2 = .2d0 * gsqrd
79 gnew = -gsqrd
80 dfpr = AMF
81 stmin = AMF / gsqrd
82
83 1 iter = iter + 1
84
85 fuit = f
86 gdit = 0.d0
87
88 do i=1,n
89 t = g(i)
90 gt(i) = t
91 gdit = gdit + d(i) * t
92 enddo
93
94 if ( gdit .ge. 0.d0 ) then
95 write(*,*) ' mincjg> search direction is uphill'
96 ier = 3
97 goto 6
98 endif
99
100 gdmi = gdit
101 sbound = -1.d0
102 nfbeg = nfun
103 iretry = -1
104
105 stepch = min( stmin, abs ( (dfpr/gdit) ) )
106 stmin = 0.d0
107
108 2 step = stmin + stepch
109 wo = 0.d0
110
111 do i=1,n
112 t = stepch * d(i)
113 wo = max( wo, abs( t ) )
114 x(i) = xa(i) + t
115 enddo
116
117 if ( wo .gt. TOL ) then
118
119 nfun = nfun + 1
120 call move(nfun,n,f,x,g)
121
122 gnew = 0.d0
123 sum = 0.d0
124
125 do i=1,n
126 t = g(i)
127 gnew = gnew + d(i) * t
128 sum = sum + t**2
129 enddo
130
131 fch = f - fmin
132
133 if ( fch .le. 0.d0 ) then
134
135 if ( fch .lt. 0.d0 .or. (gnew/gdmi) .ge. -1.d0 ) then
136
137 fmin = f
138 gsqrd = sum
139 gsq2 = .2d0 * gsqrd
140 nfopt = nfun
141
142 do i=1,n
143 xa(i) = x(i)
144 ga(i) = g(i)
145 enddo
146
147 endif
148
149 if ( sum .le. ACUR ) return ! normal end
150
151 endif
152
153 if ( nfun .eq. MAXFUN ) then
154 ier = 1
155 return
156 endif
157
158 else ! stepch is effectively zero
159
160 if ( nfun .gt. (nfbeg + 1) .or.
161 & abs(gdmi/gdit) .gt. EPS ) then
162
163 ier=2
164 write(*,*) ' mincjg> too small step in search direction'
165 endif
166
167 goto 6
168
169 endif
170
171 wo = (fch + fch) / stepch - gnew - gdmi
172 ddspln = (gnew - gdmi) / stepch
173
174 if ( nfun .le. nfopt ) then
175
176 if ( gdmi * gnew .le. 0.d0 ) sbound = stmin
177
178 stmin = step
179 gdmi = gnew
180 stepch = -stepch
181
182 else
183
184 sbound = step
185
186 endif
187
188 if ( fch .ne. 0.d0 ) ddspln = ddspln + (wo + wo) / stepch
189
190 if ( gdmi .eq. 0.d0 ) goto 6
191
192 if ( nfun .le. (nfbeg + 1) ) goto 4
193
194 if ( abs(gdmi/gdit) .le. EPS ) goto 6
195
196 3 if ( nfun .ge. (nfopt + MAXLIN) ) then
197
198 ier = 2
199 goto 6
200
201 endif
202
203 4 if ( sbound .lt. -.5d0 ) then
204 stepch = 9.d0 * stmin
205 else
206 stepch = .5d0 * ( sbound - stmin )
207 endif
208
209 gspln = gdmi + stepch * ddspln
210
211 if ( (gdmi * gspln) .lt. 0.d0 ) stepch = stepch * gdmi /
212 & (gdmi - gspln)
213
214 goto 2
215
216 5 sum = 0.d0
217 do i=1,n
218 sum = sum + g(i) * gt(i)
219 enddo
220
221 beta = (gsqrd - sum) / (gdmi - gdit)
222
223 if ( abs(beta * gdmi) .gt. gsq2) then
224 iretry = iretry + 1
225 if (iretry .le. 0) goto 3
226 endif
227
228 if ( f .lt. fuit ) iterfm = iter
229
230 if ( iter .ge. (iterfm + MXFCON) ) then
231 ier = 4
232 write(*,*) ' mincjg> line search failed to reduce function'
233 return
234 endif
235
236 dfpr = stmin * gdit
237
238 if ( iretry .gt. 0 ) then
239
240 do i=1,n
241 d(i) = -g(i)
242 enddo
243
244 iterrs = 0
245
246 else
247
248 if (iterrs .ne. 0 .and. (iter - iterrs) .lt. (n-1) .and.
249 & abs(sum) .lt. gsq2 ) then
250
251 gama = 0.d0
252 sum = 0.d0
253
254 do i=1,n
255 t = g(i)
256 gama = gama + t * yt(i)
257 sum = sum + t * dt(i)
258 enddo
259
260 gama = gama / gamden
261
262 if ( abs( (beta * gdmi + gama * sum) ) .lt. gsq2) then
263
264 do i=1,n
265 d(i) = -g(i) + beta * d(i) + gama * dt(i)
266 enddo
267
268 goto 1
269
270 endif
271
272 endif
273
274 gamden = gdmi - gdit
275
276 do i=1,n
277 t = g(i)
278 di = d(i)
279 dt(i) = di
280 yt(i) = t - gt(i)
281 d(i) = -t + beta * di
282 enddo
283
284 iterrs = iter
285
286 endif
287
288 goto 1
289
290 6 if ( nfun .ne. nfopt ) then
291
292 f = fmin
293
294 do i=1,n
295 x(i) = xa(i)
296 g(i) = ga(i)
297 enddo
298
299 endif
300
301 if ( ier .eq. 0 ) goto 5
302
303 nfun = nfun + 1
304 call move(nfun,n,f,x,g)
305
306 write(*,*) ' mincjg> ier = ',ier
307
308 return
309 end
310
Note: See TracBrowser for help on using the repository browser.