19 real(kind_real),
parameter ::
rho = 0.5_kind_real
20 real(kind_real),
parameter ::
tol = 1.0e-6_kind_real
28 real(kind_real),
allocatable :: x(:)
29 real(kind_real),
allocatable :: guess(:)
30 real(kind_real),
allocatable :: binf(:)
31 real(kind_real),
allocatable :: bsup(:)
32 real(kind_real),
allocatable :: obs(:)
33 character(len=1024) :: cost_function
34 real(kind_real) :: f_guess
35 real(kind_real) :: f_min
36 character(len=1024) :: algo
46 integer,
allocatable :: l0rl0_to_l0(:,:)
47 real(kind_real),
allocatable :: disth(:)
48 real(kind_real),
allocatable :: distv(:,:)
52 real(kind_real),
allocatable :: dx(:,:)
53 real(kind_real),
allocatable :: dy(:,:)
54 real(kind_real),
allocatable :: dz(:,:)
55 logical,
allocatable :: dmask(:,:)
82 class(minim_type),
intent(inout) :: minim
83 type(mpl_type),
intent(in) :: mpl
84 logical,
intent(in) :: lprt
87 real(kind_real) :: guess(minim%nx)
90 if (minim%nx<=0)
call mpl%abort(
'nx should be positive to minimize')
91 if (minim%ny<=0)
call mpl%abort(
'nx should be positive to minimize')
95 call minim%vt_inv(mpl,guess)
98 call minim%cost(mpl,guess,minim%f_guess)
100 select case (trim(minim%algo))
103 call minim%hooke(mpl,guess)
107 call minim%cost(mpl,minim%x,minim%f_min)
110 if (minim%f_min<minim%f_guess)
then 111 call minim%vt_dir(minim%x)
113 write(mpl%info,
'(a13,a,f6.1,a,e9.2,a,e9.2,a)')
'',
'Minimizer '//trim(minim%algo)//
', cost function decrease:', &
114 & abs(minim%f_min-minim%f_guess)/minim%f_guess*100.0,
'% (',minim%f_guess,
' to ',minim%f_min,
')' 118 minim%x = minim%guess
119 if (lprt)
call mpl%warning(
'Minimizer '//trim(minim%algo)//
' failed')
133 class(minim_type),
intent(in) :: minim
134 type(mpl_type),
intent(in) :: mpl
135 real(kind_real),
intent(in) :: x(minim%nx)
136 real(kind_real),
intent(out) :: f
138 select case (minim%cost_function)
140 call minim%cost_fit_diag(mpl,x,f)
141 case (
'fit_diag_dble')
142 call minim%cost_fit_diag_dble(mpl,x,f)
144 call minim%cost_fit_lct(mpl,x,f)
158 class(minim_type),
intent(in) :: minim
159 type(mpl_type),
intent(in) :: mpl
160 real(kind_real),
intent(in) :: x(minim%nx)
161 real(kind_real),
intent(out) :: f
164 integer :: offset,il0
165 real(kind_real) :: fo,fh,fv,norm,fit_rh_avg,fit_rv_avg
166 real(kind_real) :: fit_rh(minim%nl0),fit_rv(minim%nl0)
167 real(kind_real) :: fit(minim%nc3,minim%nl0r,minim%nl0)
168 real(kind_real) :: xtmp(minim%nx),fit_pack(minim%ny)
172 if (minim%lhomh)
then 175 offset = offset+minim%nl0
177 if (minim%lhomv)
then 180 offset = offset+minim%nl0
185 call minim%vt_dir(xtmp)
189 if (minim%lhomh)
then 190 fit_rh = xtmp(offset+1)
193 fit_rh = xtmp(offset+1:offset+minim%nl0)
194 offset = offset+minim%nl0
196 if (minim%lhomv)
then 197 fit_rv = xtmp(offset+1)
200 fit_rv = xtmp(offset+1:offset+minim%nl0)
201 offset = offset+minim%nl0
205 call fit_diag(mpl,minim%nc3,minim%nl0r,minim%nl0,minim%l0rl0_to_l0,minim%disth,minim%distv,fit_rh,fit_rv,fit)
208 fit_pack = pack(fit,mask=.true.)
211 fo = sum((fit_pack-minim%obs)**2,mask=
isnotmsr(minim%obs).and.
isnotmsr(fit_pack))
213 if (norm>0.0) fo = fo/norm
219 fit_rh_avg = 0.5*(fit_rh(il0-1)+fit_rh(il0+1))
221 if (norm>0.0) fh = fh+(fit_rh(il0)-fit_rh_avg)**2/norm
222 fit_rv_avg = 0.5*(fit_rv(il0-1)+fit_rv(il0+1))
224 if (norm>0.0) fv = fv+(fit_rv(il0)-fit_rv_avg)**2/norm
241 class(minim_type),
intent(in) :: minim
242 type(mpl_type),
intent(in) :: mpl
243 real(kind_real),
intent(in) :: x(minim%nx)
244 real(kind_real),
intent(out) :: f
247 integer :: offset,il0
248 real(kind_real) :: fo,fh,fv,fr,fc,norm,fit_rh_avg,fit_rv_avg,fit_rv_rfac_avg,fit_rv_coef_avg
249 real(kind_real) :: fit_rh(minim%nl0),fit_rv(minim%nl0),fit_rv_rfac(minim%nl0),fit_rv_coef(minim%nl0)
250 real(kind_real) :: fit(minim%nc3,minim%nl0r,minim%nl0)
251 real(kind_real) :: xtmp(minim%nx),fit_pack(minim%ny)
255 call minim%vt_dir(xtmp)
259 if (minim%lhomh)
then 260 fit_rh = xtmp(offset+1)
263 fit_rh = xtmp(offset+1:offset+minim%nl0)
264 offset = offset+minim%nl0
266 if (minim%lhomv)
then 267 fit_rv = xtmp(offset+1)
269 fit_rv_rfac = xtmp(offset+1)
271 fit_rv_coef = xtmp(offset+1)
274 fit_rv = xtmp(offset+1:offset+minim%nl0)
275 offset = offset+minim%nl0
276 fit_rv_rfac = xtmp(offset+1:offset+minim%nl0)
277 offset = offset+minim%nl0
278 fit_rv_coef = xtmp(offset+1:offset+minim%nl0)
279 offset = offset+minim%nl0
283 call fit_diag_dble(mpl,minim%nc3,minim%nl0r,minim%nl0,minim%l0rl0_to_l0,minim%disth,minim%distv,fit_rh,fit_rv, &
284 & fit_rv_rfac,fit_rv_coef,fit)
287 fit_pack = pack(fit,mask=.true.)
290 fo = sum((fit_pack-minim%obs)**2,mask=
isnotmsr(minim%obs).and.
isnotmsr(fit_pack))
292 if (norm>0.0) fo = fo/norm
300 fit_rh_avg = 0.5*(fit_rh(il0-1)+fit_rh(il0+1))
302 if (norm>0.0) fh = fh+(fit_rh(il0)-fit_rh_avg)**2/norm
303 fit_rv_avg = 0.5*(fit_rv(il0-1)+fit_rv(il0+1))
305 if (norm>0.0) fv = fv+(fit_rv(il0)-fit_rv_avg)**2/norm
306 fit_rv_rfac_avg = 0.5*(fit_rv_rfac(il0-1)+fit_rv_rfac(il0+1))
307 norm = fit_rv_rfac_avg**2
308 if (norm>0.0) fr = fr+(fit_rv_rfac(il0)-fit_rv_rfac_avg)**2/norm
309 fit_rv_coef_avg = 0.5*(fit_rv_coef(il0-1)+fit_rv_coef(il0+1))
310 norm = fit_rv_coef_avg**2
311 if (norm>0.0) fc = fc+(fit_rv_coef(il0)-fit_rv_coef_avg)**2/norm
328 class(minim_type),
intent(in) :: minim
329 type(mpl_type),
intent(in) :: mpl
330 real(kind_real),
intent(in) :: x(minim%nx)
331 real(kind_real),
intent(out) :: f
334 integer :: iscales,icomp
335 real(kind_real) :: norm
336 real(kind_real) :: fit(minim%nc3,minim%nl0),D(4,minim%nscales)
337 real(kind_real) :: xtmp(minim%nx),fit_pack(minim%ny),coef(minim%nscales)
341 call minim%vt_dir(xtmp)
344 do iscales=1,minim%nscales
346 d(icomp,iscales) = xtmp((iscales-1)*4+icomp)
349 if (minim%nscales>1)
then 350 coef(1:minim%nscales-1) = xtmp(minim%nscales*4+1:minim%nscales*4+minim%nscales-1)
351 coef(minim%nscales) = 1.0-sum(coef(1:minim%nscales-1))
355 call fit_lct(mpl,minim%nc3,minim%nl0,minim%dx,minim%dy,minim%dz,minim%dmask,minim%nscales, &
356 & xtmp(1:minim%nscales*4),coef,fit)
359 fit_pack = pack(fit,mask=.true.)
362 f = sum((fit_pack-minim%obs)**2,mask=
isnotmsr(minim%obs).and.
isnotmsr(fit_pack))
364 if (norm>0.0) f = f/norm
378 class(minim_type),
intent(inout) :: minim
379 type(mpl_type),
intent(in) :: mpl
380 real(kind_real),
intent(in) :: guess(minim%nx)
383 integer :: funevals,i,iters,keep
384 real(kind_real) :: fbefore,newf,steplength,tmp
385 real(kind_real) :: delta(minim%nx),newx(minim%nx)
391 if (
sup(abs(guess(i)),
rth))
then 392 delta(i) =
rho*abs(guess(i))
400 call minim%cost(mpl,newx,fbefore)
401 funevals = funevals + 1
411 call minim%best_nearby(mpl,delta,newx,fbefore,funevals,newf)
416 do while (
inf(newf,fbefore).and.(keep==1))
419 if (
sup(newx(i),minim%x(i)))
then 420 delta(i) = abs(delta(i))
422 delta(i) = -abs(delta(i))
428 newx(i) = newx(i)+newx(i)-tmp
433 call minim%best_nearby(mpl,delta,newx,fbefore,funevals,newf)
436 if (
inf(fbefore,newf))
exit 444 if (
inf(0.5*abs(delta(i)),abs(newx(i)-minim%x(i))))
then 452 steplength = steplength*
rho 469 class(minim_type),
intent(inout) :: minim
470 type(mpl_type),
intent(in) :: mpl
471 real(kind_real),
intent(inout) :: delta(minim%nx)
472 real(kind_real),
intent(inout) :: point(minim%nx)
473 real(kind_real),
intent(in) :: prevbest
474 integer,
intent(inout) :: funevals
475 real(kind_real),
intent(out) :: minf
479 real(kind_real) :: ftmp
480 real(kind_real) :: z(minim%nx)
487 z(i) = point(i)+delta(i)
488 call minim%cost(mpl,z,ftmp)
489 funevals = funevals+1
490 if (
inf(ftmp,minf))
then 494 z(i) = point(i)+delta(i)
495 call minim%cost(mpl,z,ftmp)
496 funevals = funevals+1
497 if (
inf(ftmp,minf))
then 519 class(minim_type),
intent(in) :: minim
520 real(kind_real),
intent(inout) :: x(minim%nx)
523 x = minim%binf+0.5*(1.0+tanh(x))*(minim%bsup-minim%binf)
536 class(minim_type),
intent(in) :: minim
537 type(mpl_type),
intent(in) :: mpl
538 real(kind_real),
intent(inout) :: x(minim%nx)
544 if (any((x<minim%binf).or.(x>minim%bsup)))
call mpl%abort(
'variable out of bounds in vt_inv')
546 if (
sup(minim%bsup(ix),minim%binf(ix)))
then 547 x(ix) = atanh(2.0*(x(ix)-minim%binf(ix))/(minim%bsup(ix)-minim%binf(ix))-1.0)
subroutine minim_vt_dir(minim, x)
subroutine minim_cost(minim, mpl, x, f)
subroutine minim_cost_fit_diag_dble(minim, mpl, x, f)
subroutine minim_best_nearby(minim, mpl, delta, point, prevbest, funevals, minf)
real(kind_real), parameter rho
real(kind_real), parameter tol
subroutine minim_hooke(minim, mpl, guess)
subroutine minim_compute(minim, mpl, lprt)
subroutine minim_cost_fit_diag(minim, mpl, x, f)
subroutine minim_vt_inv(minim, mpl, x)
subroutine minim_cost_fit_lct(minim, mpl, x, f)
integer, parameter, public kind_real
integer, parameter itermax