source: mincjg.f@ e40e335

Last change on this file since e40e335 was e40e335, checked in by baerbaer <baerbaer@…>, 16 years ago

Initial import to BerliOS corresponding to 3.0.4

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

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