[e40e335] | 1 | c **************************************************************
|
---|
| 2 | c
|
---|
| 3 | c This file contains the subroutines: mincjg
|
---|
| 4 | c
|
---|
| 5 | c Copyright 2003-2005 Frank Eisenmenger, U.H.E. Hansmann,
|
---|
| 6 | c Shura Hayryan, Chin-Ku
|
---|
| 7 | c Copyright 2007 Frank Eisenmenger, U.H.E. Hansmann,
|
---|
| 8 | c Jan H. Meinke, Sandipan Mohanty
|
---|
| 9 | c
|
---|
| 10 | c ********************************************************************
|
---|
| 11 | subroutine mincjg(n,mxn,x,f,g,acur,d,xa,ga,dt,yt,gt,maxfun,nfun)
|
---|
| 12 |
|
---|
| 13 | c ....................................................................
|
---|
| 14 | c
|
---|
| 15 | c Conjugate Gradient Minimizer
|
---|
| 16 | c
|
---|
| 17 | c INPUT: X,F,G - variables, value of FUNC, gradient at START/
|
---|
| 18 | c ACUR - convergence is assumed if ACUR > SUM ( G(I)**2 )
|
---|
| 19 | c MAXFUN - maximum overall number of function calls
|
---|
| 20 | c
|
---|
| 21 | c OUTPUT: X,F,G - variables, value of FUNC, gradient at MINIMUM
|
---|
| 22 | c NFUN - overall number of function calls used
|
---|
| 23 | c
|
---|
| 24 | c ARRAYS: D,XA,GA,YT,DT,GT - dimension N
|
---|
| 25 | c
|
---|
| 26 | c CALLS: MOVE - calculate function & its gradients for current X
|
---|
| 27 | c
|
---|
| 28 | c PARAMETERS: AMF - rough estimate of first reduction in F, used
|
---|
| 29 | c to guess initial step of 1st line search
|
---|
| 30 | c MXFCON - see 'ier=4'
|
---|
| 31 | c MAXLIN -
|
---|
| 32 | c
|
---|
| 33 | c DIAGNOSTICS (ier)
|
---|
| 34 | c
|
---|
| 35 | c = 0: minimization completed successfully
|
---|
| 36 | c = 1: number of steps reached MAXFUN
|
---|
| 37 | c = 2: line search was abandoned
|
---|
| 38 | c = 3: search direction is uphill
|
---|
| 39 | c = 4: two consecutive line searches failed to reduce F
|
---|
| 40 | c ....................................................................
|
---|
| 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 |
|
---|