0.6.2-dev0
FORCES
FORtran lib for Comp. Env. Sys.
Loading...
Searching...
No Matches
mo_nelmin.f90
Go to the documentation of this file.
1!> \file mo_nelmin.f90
2!> \brief \copybrief mo_nelmin
3!> \details \copydetails mo_nelmin
4
5!> \brief Nelder-Mead algorithm
6!> \details This module provides NELMIN, which minimizes a function using the Nelder-Mead algorithm
7!! with the Applied Statistics algorithms No. 047.
8!! Original FORTRAN77 version by R ONeill.
9!! FORTRAN90 version by John Burkardt.
10!> \author Matthias Cuntz
11!> \date 2012
12!> \copyright Copyright 2005-\today, the CHS Developers, Sabine Attinger: All rights reserved.
13!! FORCES is released under the LGPLv3+ license \license_note
15
16 USE mo_kind, ONLY: i4, sp, dp
17 USE mo_utils, ONLY: ne
18
19 IMPLICIT NONE
20
21 PUBLIC :: nelmin ! minimizes a function using the Nelder-Mead algorithm
22 PUBLIC :: nelminxy ! same as nelmin but pass x and y to function
23 PUBLIC :: nelminrange ! same as nelmin but with given range of parameter
24
25 ! ------------------------------------------------------------------
26 !> \brief Minimizes a user-specified function using the Nelder-Mead algorithm.
27 !> \details Simplex function minimisation procedure due to Nelder and Mead (1965),
28 !! as implemented by O'Neill(1971, Appl.Statist. 20, 338-45), with
29 !! subsequent comments by Chambers+Ertel(1974, 23, 250-1), Benyon(1976,
30 !! 25, 97) and Hill(1978, 27, 380-2)
31 !!
32 !! The function to be minimized is the first argument of nelmin and must be defined as
33 !! \code{.f90}
34 !! FUNCTION func(p)
35 !! USE mo_kind, ONLY: dp
36 !! IMPLICIT NONE
37 !! REAL(dp), DIMENSION(:), INTENT(IN) :: p
38 !! REAL(dp) :: func
39 !! END FUNCTION func
40 !! \endcode
41 !!
42 !! and for nelminxy
43 !! \code{.f90}
44 !! FUNCTION func(p,x,y)
45 !! USE mo_kind, ONLY: dp
46 !! IMPLICIT NONE
47 !! REAL(dp), DIMENSION(:), INTENT(IN) :: p
48 !! REAL(dp), DIMENSION(:), INTENT(IN) :: x
49 !! REAL(dp), DIMENSION(:), INTENT(IN) :: y
50 !! REAL(dp) :: func
51 !! END FUNCTION func
52 !! \endcode
53 !!
54 !! This routine does not include a termination test using the
55 !! fitting of a quadratic surface.
56 !!
57 !! \b Calling sequence
58 !! \code{.f90}
59 !! pmin = nelmin(func, pstart, funcmin, varmin, step, konvge, maxeval, &
60 !! neval, numrestart, ierror)
61 !! pmin = nelminxy(func, pstart, xx, yy, funcmin, varmin, step, konvge, maxeval, &
62 !! neval, numrestart, ierror)
63 !! pmin = nelmin(func, pstart, prange, funcmin, varmin, step, konvge, maxeval, &
64 !! neval, numrestart, ierror)
65 !! \endcode
66 !!
67 !! Original FORTRAN77 version by R ONeill.
68 !! FORTRAN90 version by John Burkardt.
69 !!
70 !! \b Example
71 !! \code{.f90}
72 !! pstart(1:n) = (/ -1.2_dp, 1.0_dp /)
73 !! step(1:n) = (/ 1.0_dp, 1.0_dp /)
74 !! pmin = nelmin(rosenbrock, pstart, step=step, ierror=ierror)
75 !! \endcode
76 !!
77 !! -> see also example in test directory
78 !!
79 !! \b Literature
80 !! 1. Simplex function minimisation procedure due to Nelder and Mead (1965),
81 !! as implemented by O'Neill(1971, Appl.Statist. 20, 338-45), with
82 !! subsequent comments by Chambers+Ertel(1974, 23, 250-1), Benyon(1976,
83 !! 25, 97) and Hill(1978, 27, 380-2)
84 !! 2. John Nelder, Roger Mead, A simplex method for function minimization,
85 !! Computer Journal, Volume 7, 1965, pages 308-313.
86 !! 3. R ONeill, Algorithm AS 47: Function Minimization Using a Simplex Procedure,
87 !! Applied Statistics, Volume 20, Number 3, 1971, pages 338-345.
88 !!
89 !> \param[in] "real(dp) :: func(p,xx,yy)" Function on which to search the minimum
90 !> \param[in] "real(dp) :: pstart(:)" Starting point for the iteration.
91 !> \param[in] "real(dp) :: xx" (ONLY nelminxy) First values to pass as function arguments
92 !> \param[in] "real(dp) :: yy" (ONLY nelminxy) Second values to pass as function arguments
93 !> \param[in] "real(dp) :: prange(:,2)" (ONLY nelminrange) Range of parameters (upper and lower bound).
94 !> \param[in] "real(dp), optional :: varmin" the terminating limit for the variance
95 !! of the function values. varmin>0 is required.
96 !> \param[in] "real(dp), optional :: step(:)" determines the size and shape of the initial simplex.
97 !! The relative magnitudes of its elements should reflect
98 !! the units of the variables. size(step)=size(start)
99 !> \param[in] "integer(i4), optional :: konvge" the convergence check is carried out every konvge iterations.
100 !! konvge>0 is required.
101 !> \param[in] "integer(i4), optional :: maxeval" the maximum number of function evaluations.
102 !! default: 1000
103 !> \param[out] "real(dp), optional :: funcmin" the minimum value of the function.
104 !> \param[out] "integer(i4), optional :: neval" the number of function evaluations used.
105 !> \param[out] "integer(i4), optional :: numrestart" the number of restarts.
106 !> \param[out] "integer(i4), optional :: ierror" error indicator.
107 !! 0: no errors detected.
108 !! 1: varmin or konvge have an illegal value.
109 !! 2: terminated because maxeval was exceeded without convergence.
110 !> \param[out] "real(dp), optional, allocatable :: history(:)" the history of best function values, history(neval)=funcmin
111 !> \return real(sp/dp) :: nelmin(size(start)) — coordinates of the point which is estimated to minimize the function.
112
113 !> \author Matthias Cuntz
114 !> \date Jul 2012
115 !! - i4, dp, intent
116 !! - function, optional
117 !! - nelminxy
118 !> \author Juliane Mai
119 !> \date Aug 2012
120 !! - nelminrange
121 !> \date Dec 2012
122 !! - history output
123 INTERFACE nelminrange
124 MODULE PROCEDURE nelminrange_dp, nelminrange_sp
125 END INTERFACE nelminrange
126
127 ! ------------------------------------------------------------------
128
129 PRIVATE
130
131 ! ------------------------------------------------------------------
132
133CONTAINS
134
135 !> \copydoc nelminrange
136 function nelmin(func, pstart, varmin, step, konvge, maxeval, &
137 funcmin, neval, numrestart, ierror, history)
138
139 implicit none
140
141 INTERFACE
142 FUNCTION func(pp)
143 USE mo_kind, ONLY: dp
144 IMPLICIT NONE
145 REAL(dp), DIMENSION(:), INTENT(IN) :: pp
146 REAL(dp) :: func
147 END FUNCTION func
148 END INTERFACE
149 real(dp), intent(IN) :: pstart(:)
150 real(dp), optional, intent(IN) :: varmin
151 real(dp), optional, intent(IN) :: step(:)
152 integer(i4), optional, intent(IN) :: konvge
153 integer(i4), optional, intent(IN) :: maxeval
154 real(dp), optional, intent(OUT) :: funcmin
155 integer(i4), optional, intent(OUT) :: neval
156 integer(i4), optional, intent(OUT) :: numrestart
157 integer(i4), optional, intent(OUT) :: ierror
158 real(dp), optional, intent(OUT), allocatable :: history(:) ! History of objective function values
159 real(dp) :: nelmin(size(pstart))
160
161 real(dp), parameter :: ccoeff = 0.5_dp
162 real(dp), parameter :: ecoeff = 2.0_dp
163 real(dp), parameter :: rcoeff = 1.0_dp
164 real(dp), parameter :: eps = 0.001_dp
165 real(dp) :: ipstart(size(pstart))
166 real(dp) :: ifuncmin
167 real(dp) :: ivarmin
168 real(dp) :: istep(size(pstart))
169 integer(i4) :: ikonvge
170 integer(i4) :: imaxeval
171 integer(i4) :: ineval
172 integer(i4) :: inumrestart
173 integer(i4) :: iierror
174 integer(i4) :: n, nn
175 integer(i4) :: i
176 integer(i4) :: ihi
177 integer(i4) :: ilo
178 integer(i4) :: j
179 integer(i4) :: jcount
180 integer(i4) :: l
181 real(dp) :: del
182 real(dp) :: p(size(pstart),size(pstart)+1)
183 real(dp) :: p2star(size(pstart))
184 real(dp) :: pbar(size(pstart))
185 real(dp) :: pstar(size(pstart))
186 real(dp) :: rq
187 real(dp) :: x
188 real(dp) :: y(size(pstart)+1)
189 real(dp) :: y2star
190 real(dp) :: ylo
191 real(dp) :: ystar
192 real(dp) :: z
193 real(dp) :: dn, dnn
194 real(dp) :: p0(size(pstart)), y0
195 real(dp), allocatable :: history_tmp(:)
196 !
197 ! Defaults
198 !
199 nelmin(:) = 0.
200 if (present(varmin)) then
201 if (varmin <= 0.0_dp) stop 'Error nelmin: varmin<0'
202 ivarmin = varmin
203 else
204 ivarmin = 1.0e-9_dp
205 endif
206 ! maximal number of function evaluations
207 if (present(maxeval)) then
208 if (maxeval <= 1) stop 'Error nelmin: maxeval<=1'
209 imaxeval = maxeval
210 else
211 imaxeval = 1000
212 endif
213 ! history output
214 if (present(history)) then
215 ! worst case length
216 allocate(history_tmp(imaxeval+3*size(ipstart)+1))
217 end if
218 if (present(konvge)) then
219 ikonvge = konvge
220 else
221 ikonvge = imaxeval / 10
222 endif
223 if (ikonvge < 1) stop 'Error nelmin: konvg<1'
224 !
225 if (present(step)) then
226 istep = step
227 else ! if not given, deviate initial by 1%
228 y0 = func(pstart)
229 do i=1, size(pstart)
230 p0 = pstart
231 if (ne(p0(i),0.0_dp)) then
232 p0(i) = 1.01_dp*p0(i)
233 else
234 p0(i) = 0.01_dp
235 endif
236 istep(i) = abs(func(p0) - y0)
237 enddo
238 endif
239 !
240 ! Check the input parameters.
241 !
242 !
243 ! Initialization.
244 !
245 ipstart = pstart
246 n = size(ipstart)
247 ineval = 0_i4
248 inumrestart = 0_i4
249 jcount = ikonvge
250 dn = real(n, dp)
251 nn = n + 1
252 dnn = real(nn, dp)
253 del = 1.0_dp
254 rq = ivarmin * dn
255 !
256 ! Initial or restarted loop.
257 !
258 do
259 p(1:n,nn) = ipstart(1:n)
260 y(nn) = func(ipstart)
261 ineval = ineval + 1
262 if (present(history)) history_tmp(ineval) = y(nn)
263 !
264 ! Define the initial simplex.
265 !
266 do j = 1, n
267 x = ipstart(j)
268 ipstart(j) = ipstart(j) + istep(j) * del
269 p(1:n,j) = ipstart(1:n)
270 y(j) = func(ipstart)
271 ineval = ineval + 1
272 ipstart(j) = x
273 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
274 end do
275 !
276 ! Find highest and lowest Y values. FUNCMIN = Y(IHI) indicates
277 ! the vertex of the simplex to be replaced.
278 !
279 ilo = minloc(y(1:n+1), 1)
280 ylo = y(ilo)
281 !
282 ! Inner loop.
283 !
284 do while ( ineval < imaxeval )
285 !
286 ! FUNCMIN is, of course, the HIGHEST value???
287 !
288 ihi = maxloc(y(1:n+1), 1)
289 ifuncmin = y(ihi)
290 !
291 ! Calculate PBAR, the centroid of the simplex vertices
292 ! excepting the vertex with Y value FUNCMIN.
293 !
294 do i = 1, n
295 pbar(i) = ( sum(p(i,1:n+1)) - p(i,ihi) ) / dn
296 end do
297 !
298 ! Reflection through the centroid.
299 !
300 pstar(1:n) = pbar(1:n) + rcoeff * ( pbar(1:n) - p(1:n,ihi) )
301 ystar = func(pstar)
302 ineval = ineval + 1
303 if (present(history)) history_tmp(ineval) = min( ystar, history_tmp(ineval-1) )
304 !
305 ! Successful reflection, so extension.
306 !
307 if ( ystar < ylo ) then
308
309 p2star(1:n) = pbar(1:n) + ecoeff * ( pstar(1:n) - pbar(1:n) )
310 y2star = func(p2star)
311 ineval = ineval + 1
312 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
313 !
314 ! Retain extension or contraction.
315 !
316 if ( ystar < y2star ) then
317 p(1:n,ihi) = pstar(1:n)
318 y(ihi) = ystar
319 else
320 p(1:n,ihi) = p2star(1:n)
321 y(ihi) = y2star
322 end if
323 !
324 ! No extension.
325 !
326 else
327 l = 0
328 do i = 1, nn
329 if ( ystar < y(i) ) l = l + 1
330 end do
331
332 if ( 1 < l ) then
333 p(1:n,ihi) = pstar(1:n)
334 y(ihi) = ystar
335 !
336 ! Contraction on the Y(IHI) side of the centroid.
337 !
338 else if ( l == 0 ) then
339 p2star(1:n) = pbar(1:n) + ccoeff * ( p(1:n,ihi) - pbar(1:n) )
340 y2star = func(p2star)
341 ineval = ineval + 1
342 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
343 !
344 ! Contract the whole simplex.
345 !
346 if ( y(ihi) < y2star ) then
347 do j = 1, n + 1
348 p(1:n,j) = ( p(1:n,j) + p(1:n,ilo) ) * 0.5_dp
349 nelmin(1:n) = p(1:n,j)
350 y(j) = func(nelmin)
351 ineval = ineval + 1
352 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
353 end do
354 ilo = minloc(y(1:n+1), 1)
355 ylo = y(ilo)
356
357 cycle
358 !
359 ! Retain contraction.
360 !
361 else
362 p(1:n,ihi) = p2star(1:n)
363 y(ihi) = y2star
364 end if
365 !
366 ! Contraction on the reflection side of the centroid.
367 !
368 else if ( l == 1 ) then
369
370 p2star(1:n) = pbar(1:n) + ccoeff * ( pstar(1:n) - pbar(1:n) )
371 y2star = func(p2star)
372 ineval = ineval + 1
373 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
374 !
375 ! Retain reflection?
376 !
377 if ( y2star <= ystar ) then
378 p(1:n,ihi) = p2star(1:n)
379 y(ihi) = y2star
380 else
381 p(1:n,ihi) = pstar(1:n)
382 y(ihi) = ystar
383 end if
384
385 end if
386
387 end if
388 !
389 ! Check if YLO improved.
390 !
391 if ( y(ihi) < ylo ) then
392 ylo = y(ihi)
393 ilo = ihi
394 end if
395
396 jcount = jcount - 1
397
398 if ( 0 < jcount ) cycle
399 !
400 ! Check to see if minimum reached.
401 !
402 if ( ineval <= imaxeval ) then
403 jcount = ikonvge
404 x = sum( y(1:n+1) ) / dnn
405 z = sum( ( y(1:n+1) - x )**2 )
406 if ( z <= rq ) exit
407 end if
408
409 end do
410 !
411 ! Factorial tests to check that FUNCMIN is a local minimum.
412 !
413 nelmin(1:n) = p(1:n,ilo)
414 ifuncmin = y(ilo)
415
416 if ( imaxeval < ineval ) then
417 iierror = 2
418 exit
419 end if
420
421 iierror = 0
422
423 do i = 1, n
424 del = istep(i) * eps
425 nelmin(i) = nelmin(i) + del
426 z = func(nelmin)
427 ineval = ineval + 1
428 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
429 if ( z < ifuncmin ) then
430 iierror = 2
431 exit
432 end if
433 nelmin(i) = nelmin(i) - del - del
434 z = func(nelmin)
435 ineval = ineval + 1
436 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
437 if ( z < ifuncmin ) then
438 iierror = 2
439 exit
440 end if
441 nelmin(i) = nelmin(i) + del
442 end do
443
444 if ( iierror == 0 ) exit
445 !
446 ! Restart the procedure.
447 !
448 ipstart(1:n) = nelmin(1:n)
449 del = eps
450 inumrestart = inumrestart + 1
451
452 end do
453
454 if (present(funcmin)) then
455 funcmin = ifuncmin
456 endif
457 if (present(neval)) then
458 neval = ineval
459 endif
460 if (present(numrestart)) then
461 numrestart = inumrestart
462 endif
463 if (present(ierror)) then
464 ierror = iierror
465 endif
466 if (present(history)) then
467 allocate(history(ineval))
468 history(:) = history_tmp(1:ineval)
469 end if
470
471 end function nelmin
472
473
474 !> \copydoc nelminrange
475 function nelminxy(func, pstart, xx, yy, varmin, step, konvge, maxeval, &
476 funcmin, neval, numrestart, ierror, history)
477
478 implicit none
479
480 INTERFACE
481 FUNCTION func(pp, xxx, yyy)
482 USE mo_kind, ONLY: dp
483 IMPLICIT NONE
484 REAL(dp), DIMENSION(:), INTENT(IN) :: pp
485 REAL(dp), DIMENSION(:), INTENT(IN) :: xxx
486 REAL(dp), DIMENSION(:), INTENT(IN) :: yyy
487 REAL(dp) :: func
488 END FUNCTION func
489 END INTERFACE
490 real(dp), intent(IN) :: pstart(:)
491 real(dp), intent(IN) :: xx(:)
492 real(dp), intent(IN) :: yy(:)
493 real(dp), optional, intent(OUT) :: funcmin
494 real(dp), optional, intent(IN) :: varmin
495 real(dp), optional, intent(IN) :: step(:)
496 integer(i4), optional, intent(IN) :: konvge
497 integer(i4), optional, intent(IN) :: maxeval
498 integer(i4), optional, intent(OUT) :: neval
499 integer(i4), optional, intent(OUT) :: numrestart
500 integer(i4), optional, intent(OUT) :: ierror
501 real(dp), optional, intent(OUT), allocatable :: history(:) ! History of objective function values
502 real(dp) :: nelminxy(size(pstart))
503
504 real(dp), parameter :: ccoeff = 0.5_dp
505 real(dp), parameter :: ecoeff = 2.0_dp
506 real(dp), parameter :: rcoeff = 1.0_dp
507 real(dp), parameter :: eps = 0.001_dp
508 real(dp) :: ipstart(size(pstart))
509 real(dp) :: ifuncmin
510 real(dp) :: ivarmin
511 real(dp) :: istep(size(pstart))
512 integer(i4) :: ikonvge
513 integer(i4) :: imaxeval
514 integer(i4) :: ineval
515 integer(i4) :: inumrestart
516 integer(i4) :: iierror
517 integer(i4) :: n, nn
518 integer(i4) :: i
519 integer(i4) :: ihi
520 integer(i4) :: ilo
521 integer(i4) :: j
522 integer(i4) :: jcount
523 integer(i4) :: l
524 real(dp) :: del
525 real(dp) :: p(size(pstart),size(pstart)+1)
526 real(dp) :: p2star(size(pstart))
527 real(dp) :: pbar(size(pstart))
528 real(dp) :: pstar(size(pstart))
529 real(dp) :: rq
530 real(dp) :: x
531 real(dp) :: y(size(pstart)+1)
532 real(dp) :: y2star
533 real(dp) :: ylo
534 real(dp) :: ystar
535 real(dp) :: z
536 real(dp) :: dn, dnn
537 real(dp) :: p0(size(pstart)), y0
538 real(dp), allocatable :: history_tmp(:)
539 !
540 ! Defaults
541 !
542 nelminxy(:) = 0.
543 if (present(varmin)) then
544 if (varmin <= 0.0_dp) stop 'Error nelminxy: varmin<0'
545 ivarmin = varmin
546 else
547 ivarmin = 1.0e-9_dp
548 endif
549 ! maximal number of function evaluations
550 if (present(maxeval)) then
551 if (maxeval <= 1) stop 'Error nelminxy: maxeval<=1'
552 imaxeval = maxeval
553 else
554 imaxeval = 1000
555 endif
556 ! history output
557 if (present(history)) then
558 ! worst case length
559 allocate(history_tmp(imaxeval+3*size(ipstart)+1))
560 end if
561 if (present(konvge)) then
562 ikonvge = konvge
563 else
564 ikonvge = imaxeval / 10
565 endif
566 if (ikonvge < 1) stop 'Error nelminxy: konvg<1'
567 if (size(xx) /= size(yy)) stop 'Error nelminxy: size(xx) /= size(yy)'
568 !
569 if (present(step)) then
570 istep = step
571 else ! if not given, deviate initial by 1%
572 y0 = func(pstart, xx, yy)
573 do i=1, size(pstart)
574 p0 = pstart
575 if (ne(p0(i),0.0_dp)) then
576 p0(i) = 1.01_dp*p0(i)
577 else
578 p0(i) = 0.01_dp
579 endif
580 istep(i) = abs(func(p0, xx, yy) - y0)
581 enddo
582 endif
583 !
584 ! Check the input parameters.
585 !
586 !
587 ! Initialization.
588 !
589 ipstart = pstart
590 n = size(ipstart)
591 ineval = 0_i4
592 inumrestart = 0_i4
593 jcount = ikonvge
594 dn = real(n, dp)
595 nn = n + 1
596 dnn = real(nn, dp)
597 del = 1.0_dp
598 rq = ivarmin * dn
599 !
600 ! Initial or restarted loop.
601 !
602 do
603 p(1:n,nn) = ipstart(1:n)
604 y(nn) = func(ipstart, xx, yy)
605 ineval = ineval + 1
606 if (present(history)) history_tmp(ineval) = y(nn)
607 !
608 ! Define the initial simplex.
609 !
610 do j = 1, n
611 x = ipstart(j)
612 ipstart(j) = ipstart(j) + istep(j) * del
613 p(1:n,j) = ipstart(1:n)
614 y(j) = func(ipstart, xx, yy)
615 ineval = ineval + 1
616 ipstart(j) = x
617 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
618 end do
619 !
620 ! Find highest and lowest Y values. FUNCMIN = Y(IHI) indicates
621 ! the vertex of the simplex to be replaced.
622 !
623 ilo = minloc(y(1:n+1), 1)
624 ylo = y(ilo)
625 !
626 ! Inner loop.
627 !
628 do while ( ineval < imaxeval )
629 !
630 ! FUNCMIN is, of course, the HIGHEST value???
631 !
632 ihi = maxloc(y(1:n+1), 1)
633 ifuncmin = y(ihi)
634 !
635 ! Calculate PBAR, the centroid of the simplex vertices
636 ! excepting the vertex with Y value FUNCMIN.
637 !
638 do i = 1, n
639 pbar(i) = ( sum(p(i,1:n+1)) - p(i,ihi) ) / dn
640 end do
641 !
642 ! Reflection through the centroid.
643 !
644 pstar(1:n) = pbar(1:n) + rcoeff * ( pbar(1:n) - p(1:n,ihi) )
645 ystar = func(pstar, xx, yy)
646 ineval = ineval + 1
647 if (present(history)) history_tmp(ineval) = min( ystar, history_tmp(ineval-1) )
648 !
649 ! Successful reflection, so extension.
650 !
651 if ( ystar < ylo ) then
652
653 p2star(1:n) = pbar(1:n) + ecoeff * ( pstar(1:n) - pbar(1:n) )
654 y2star = func(p2star, xx, yy)
655 ineval = ineval + 1
656 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
657 !
658 ! Retain extension or contraction.
659 !
660 if ( ystar < y2star ) then
661 p(1:n,ihi) = pstar(1:n)
662 y(ihi) = ystar
663 else
664 p(1:n,ihi) = p2star(1:n)
665 y(ihi) = y2star
666 end if
667 !
668 ! No extension.
669 !
670 else
671 l = 0
672 do i = 1, nn
673 if ( ystar < y(i) ) l = l + 1
674 end do
675
676 if ( 1 < l ) then
677 p(1:n,ihi) = pstar(1:n)
678 y(ihi) = ystar
679 !
680 ! Contraction on the Y(IHI) side of the centroid.
681 !
682 else if ( l == 0 ) then
683 p2star(1:n) = pbar(1:n) + ccoeff * ( p(1:n,ihi) - pbar(1:n) )
684 y2star = func(p2star, xx, yy)
685 ineval = ineval + 1
686 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
687 !
688 ! Contract the whole simplex.
689 !
690 if ( y(ihi) < y2star ) then
691 do j = 1, n + 1
692 p(1:n,j) = ( p(1:n,j) + p(1:n,ilo) ) * 0.5_dp
693 nelminxy(1:n) = p(1:n,j)
694 y(j) = func(nelminxy, xx, yy)
695 ineval = ineval + 1
696 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
697 end do
698 ilo = minloc(y(1:n+1), 1)
699 ylo = y(ilo)
700
701 cycle
702 !
703 ! Retain contraction.
704 !
705 else
706 p(1:n,ihi) = p2star(1:n)
707 y(ihi) = y2star
708 end if
709 !
710 ! Contraction on the reflection side of the centroid.
711 !
712 else if ( l == 1 ) then
713
714 p2star(1:n) = pbar(1:n) + ccoeff * ( pstar(1:n) - pbar(1:n) )
715 y2star = func(p2star, xx, yy)
716 ineval = ineval + 1
717 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
718 !
719 ! Retain reflection?
720 !
721 if ( y2star <= ystar ) then
722 p(1:n,ihi) = p2star(1:n)
723 y(ihi) = y2star
724 else
725 p(1:n,ihi) = pstar(1:n)
726 y(ihi) = ystar
727 end if
728
729 end if
730
731 end if
732 !
733 ! Check if YLO improved.
734 !
735 if ( y(ihi) < ylo ) then
736 ylo = y(ihi)
737 ilo = ihi
738 end if
739
740 jcount = jcount - 1
741
742 if ( 0 < jcount ) cycle
743 !
744 ! Check to see if minimum reached.
745 !
746 if ( ineval <= imaxeval ) then
747 jcount = ikonvge
748 x = sum( y(1:n+1) ) / dnn
749 z = sum( ( y(1:n+1) - x )**2 )
750 if ( z <= rq ) exit
751 end if
752
753 end do
754 !
755 ! Factorial tests to check that FUNCMIN is a local minimum.
756 !
757 nelminxy(1:n) = p(1:n,ilo)
758 ifuncmin = y(ilo)
759
760 if ( imaxeval < ineval ) then
761 iierror = 2
762 exit
763 end if
764
765 iierror = 0
766
767 do i = 1, n
768 del = istep(i) * eps
769 nelminxy(i) = nelminxy(i) + del
770 z = func(nelminxy, xx, yy)
771 ineval = ineval + 1
772 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
773 if ( z < ifuncmin ) then
774 iierror = 2
775 exit
776 end if
777 nelminxy(i) = nelminxy(i) - del - del
778 z = func(nelminxy, xx, yy)
779 ineval = ineval + 1
780 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
781 if ( z < ifuncmin ) then
782 iierror = 2
783 exit
784 end if
785 nelminxy(i) = nelminxy(i) + del
786 end do
787
788 if ( iierror == 0 ) exit
789 !
790 ! Restart the procedure.
791 !
792 ipstart(1:n) = nelminxy(1:n)
793 del = eps
794 inumrestart = inumrestart + 1
795
796 end do
797
798 if (present(funcmin)) then
799 funcmin = ifuncmin
800 endif
801 if (present(neval)) then
802 neval = ineval
803 endif
804 if (present(numrestart)) then
805 numrestart = inumrestart
806 endif
807 if (present(ierror)) then
808 ierror = iierror
809 endif
810 if (present(history)) then
811 allocate(history(ineval))
812 history(:) = history_tmp(1:ineval)
813 end if
814
815 end function nelminxy
816
817 function nelminrange_dp(func, pstart, prange, varmin, step, konvge, maxeval, &
818 funcmin, neval, numrestart, ierror, history)
819
820 implicit none
821
822 INTERFACE
823 FUNCTION func(pp)
824 USE mo_kind, ONLY: dp
825 IMPLICIT NONE
826 REAL(dp), DIMENSION(:), INTENT(IN) :: pp
827 REAL(dp) :: func
828 END FUNCTION func
829 END INTERFACE
830 real(dp), intent(IN) :: pstart(:)
831 real(dp), intent(IN) :: prange(:,:)
832 real(dp), optional, intent(IN) :: varmin
833 real(dp), optional, intent(IN) :: step(:)
834 integer(i4), optional, intent(IN) :: konvge
835 integer(i4), optional, intent(IN) :: maxeval
836 real(dp), optional, intent(OUT) :: funcmin
837 integer(i4), optional, intent(OUT) :: neval
838 integer(i4), optional, intent(OUT) :: numrestart
839 integer(i4), optional, intent(OUT) :: ierror
840 real(dp), optional, intent(OUT), allocatable :: history(:) ! History of objective function values
841 real(dp) :: nelminrange_dp(size(pstart))
842
843 real(dp), parameter :: ccoeff = 0.5_dp
844 real(dp), parameter :: ecoeff = 2.0_dp
845 real(dp), parameter :: rcoeff = 1.0_dp
846 real(dp), parameter :: eps = 0.001_dp
847 real(dp) :: ipstart(size(pstart))
848 real(dp) :: ifuncmin
849 real(dp) :: ivarmin
850 real(dp) :: istep(size(pstart))
851 integer(i4) :: ikonvge
852 integer(i4) :: imaxeval
853 integer(i4) :: ineval
854 integer(i4) :: inumrestart
855 integer(i4) :: iierror
856 integer(i4) :: n, nn
857 integer(i4) :: i
858 integer(i4) :: ihi
859 integer(i4) :: ilo
860 integer(i4) :: j
861 integer(i4) :: jcount
862 integer(i4) :: l
863 real(dp) :: del
864 real(dp) :: p(size(pstart),size(pstart)+1)
865 real(dp) :: p2star(size(pstart))
866 real(dp) :: pbar(size(pstart))
867 real(dp) :: pstar(size(pstart))
868 real(dp) :: rq
869 real(dp) :: x
870 real(dp) :: y(size(pstart)+1)
871 real(dp) :: y2star
872 real(dp) :: ylo
873 real(dp) :: ystar
874 real(dp) :: z
875 real(dp) :: dn, dnn
876 real(dp) :: p0(size(pstart)), y0
877 real(dp), allocatable :: history_tmp(:)
878 !
879 ! Defaults
880 !
881 nelminrange_dp(:) = 0.5_dp * ( prange(:,1) + prange(:,2) )
882
883 if (present(varmin)) then
884 if (varmin <= 0.0_dp) stop 'Error nelmin: varmin<0'
885 ivarmin = varmin
886 else
887 ivarmin = 1.0e-9_dp
888 endif
889 ! maximal number of function evaluations
890 if (present(maxeval)) then
891 if (maxeval <= 1) stop 'Error nelmin: maxeval<=1'
892 imaxeval = maxeval
893 else
894 imaxeval = 1000
895 endif
896 ! history output
897 if (present(history)) then
898 ! worst case length
899 allocate(history_tmp(imaxeval+3*size(ipstart)+1))
900 end if
901 if (present(konvge)) then
902 ikonvge = konvge
903 else
904 ikonvge = imaxeval / 10
905 endif
906 if (ikonvge < 1) stop 'Error nelmin: konvg<1'
907 !
908 if (present(step)) then
909 istep = step
910 else ! if not given, deviate initial by 1%
911 y0 = func(pstart)
912 do i=1, size(pstart)
913 p0 = pstart
914 if (ne(p0(i),0.0_dp)) then
915 ! bound to range
916 p0(i) = min( prange(i,2) , max( prange(i,1) , 1.01_dp*p0(i) ) )
917 else
918 ! bound to range
919 p0(i) = min( prange(i,2) , max( prange(i,1) , 0.01_dp ) )
920 endif
921 istep(i) = abs(func(p0) - y0)
922 enddo
923 endif
924 !
925 ! Check the input parameters.
926 !
927 if (size(prange,2) .ne. 2_i4) stop 'nelminrange_dp: range has to be array of size (:,2)'
928 if (size(prange,1) .ne. size(ipstart)) stop 'nelminrange_dp: range has to be given for each dimension'
929 if (.not. (all(prange(:,1) .le. pstart(:)) .and. all(prange(:,2) .ge. pstart(:)) )) then
930 stop 'nelminrange_dp: starting point is not in range'
931 end if
932 !
933 ! Initialization.
934 !
935 ipstart = pstart
936 n = size(ipstart)
937 ineval = 0_i4
938 inumrestart = 0_i4
939 jcount = ikonvge
940 dn = real(n, dp)
941 nn = n + 1
942 dnn = real(nn, dp)
943 del = 1.0_dp
944 rq = ivarmin * dn
945 !
946 ! Initial or restarted loop.
947 !
948 do
949 p(1:n,nn) = ipstart(1:n)
950 y(nn) = func(ipstart)
951 ineval = ineval + 1
952 if (present(history)) history_tmp(ineval) = y(nn)
953 !
954 ! Define the initial simplex.
955 !
956 do j = 1, n
957 x = ipstart(j)
958 ! bound to range
959 ipstart(j) = min( prange(j,2) , max( prange(j,1) , ipstart(j) + istep(j) * del ) )
960 p(1:n,j) = ipstart(1:n)
961 y(j) = func(ipstart)
962 ineval = ineval + 1
963 ipstart(j) = x
964 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
965 end do
966 !
967 ! Find highest and lowest Y values. FUNCMIN = Y(IHI) indicates
968 ! the vertex of the simplex to be replaced.
969 !
970 ilo = minloc(y(1:n+1), 1)
971 ylo = y(ilo)
972 !
973 ! Inner loop.
974 !
975 do while ( ineval < imaxeval )
976 !
977 ! FUNCMIN is, of course, the HIGHEST value???
978 !
979 ihi = maxloc(y(1:n+1), 1)
980 ifuncmin = y(ihi)
981 !
982 ! Calculate PBAR, the centroid of the simplex vertices
983 ! excepting the vertex with Y value FUNCMIN.
984 !
985 do i = 1, n
986 pbar(i) = ( sum(p(i,1:n+1)) - p(i,ihi) ) / dn
987 end do
988 !
989 ! Reflection through the centroid.
990 !
991 ! bound to range
992 pstar(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + rcoeff * ( pbar(1:n) - p(1:n,ihi) ) ) )
993 ystar = func(pstar)
994 ineval = ineval + 1
995 if (present(history)) history_tmp(ineval) = min( ystar, history_tmp(ineval-1) )
996 !
997 ! Successful reflection, so extension.
998 !
999 if ( ystar < ylo ) then
1000
1001 ! bound to range
1002 p2star(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + ecoeff * ( pstar(1:n) - pbar(1:n) ) ) )
1003 y2star = func(p2star)
1004 ineval = ineval + 1
1005 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
1006 !
1007 ! Retain extension or contraction.
1008 !
1009 if ( ystar < y2star ) then
1010 p(1:n,ihi) = pstar(1:n)
1011 y(ihi) = ystar
1012 else
1013 p(1:n,ihi) = p2star(1:n)
1014 y(ihi) = y2star
1015 end if
1016 !
1017 ! No extension.
1018 !
1019 else
1020 l = 0
1021 do i = 1, nn
1022 if ( ystar < y(i) ) l = l + 1
1023 end do
1024
1025 if ( 1 < l ) then
1026 p(1:n,ihi) = pstar(1:n)
1027 y(ihi) = ystar
1028 !
1029 ! Contraction on the Y(IHI) side of the centroid.
1030 !
1031 else if ( l == 0 ) then
1032 ! bound to range
1033 p2star(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + ccoeff * ( p(1:n,ihi) - pbar(1:n) ) ) )
1034 y2star = func(p2star)
1035 ineval = ineval + 1
1036 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
1037 !
1038 ! Contract the whole simplex.
1039 !
1040 if ( y(ihi) < y2star ) then
1041 do j = 1, n + 1
1042 ! bound to range
1043 p(1:n,j) = min( prange(1:n,2) , max( prange(1:n,1) , ( p(1:n,j) + p(1:n,ilo) ) * 0.5_dp ) )
1044 nelminrange_dp(1:n) = p(1:n,j)
1045 y(j) = func(nelminrange_dp)
1046 ineval = ineval + 1
1047 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
1048 end do
1049 ilo = minloc(y(1:n+1), 1)
1050 ylo = y(ilo)
1051
1052 cycle
1053 !
1054 ! Retain contraction.
1055 !
1056 else
1057 p(1:n,ihi) = p2star(1:n)
1058 y(ihi) = y2star
1059 end if
1060 !
1061 ! Contraction on the reflection side of the centroid.
1062 !
1063 else if ( l == 1 ) then
1064
1065 ! bound to range
1066 p2star(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + ccoeff * ( pstar(1:n) - pbar(1:n) ) ) )
1067 y2star = func(p2star)
1068 ineval = ineval + 1
1069 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
1070 !
1071 ! Retain reflection?
1072 !
1073 if ( y2star <= ystar ) then
1074 p(1:n,ihi) = p2star(1:n)
1075 y(ihi) = y2star
1076 else
1077 p(1:n,ihi) = pstar(1:n)
1078 y(ihi) = ystar
1079 end if
1080
1081 end if
1082
1083 end if
1084 !
1085 ! Check if YLO improved.
1086 !
1087 if ( y(ihi) < ylo ) then
1088 ylo = y(ihi)
1089 ilo = ihi
1090 end if
1091
1092 jcount = jcount - 1
1093
1094 if ( 0 < jcount ) cycle
1095 !
1096 ! Check to see if minimum reached.
1097 !
1098 if ( ineval <= imaxeval ) then
1099 jcount = ikonvge
1100 x = sum( y(1:n+1) ) / dnn
1101 z = sum( ( y(1:n+1) - x )**2 )
1102 if ( z <= rq ) exit
1103 end if
1104
1105 end do
1106 !
1107 ! Factorial tests to check that FUNCMIN is a local minimum.
1108 !
1109 ! bound to range
1110 nelminrange_dp(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , p(1:n,ilo) ) )
1111 ifuncmin = y(ilo)
1112
1113 if ( imaxeval < ineval ) then
1114 iierror = 2
1115 exit
1116 end if
1117
1118 iierror = 0
1119
1120 do i = 1, n
1121 del = istep(i) * eps
1122 ! bound to range: probably not necessary
1123 nelminrange_dp(i) = min( prange(i,2) , max( prange(i,1) , nelminrange_dp(i) + del ) )
1124 z = func(nelminrange_dp)
1125 ineval = ineval + 1
1126 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
1127 if ( z < ifuncmin ) then
1128 iierror = 2
1129 exit
1130 end if
1131 ! bound to range: probably not necessary
1132 nelminrange_dp(i) = min( prange(i,2) , max( prange(i,1) , nelminrange_dp(i) - del - del ) )
1133 z = func(nelminrange_dp)
1134 ineval = ineval + 1
1135 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
1136 if ( z < ifuncmin ) then
1137 iierror = 2
1138 exit
1139 end if
1140 ! bound to range: probably not necessary
1141 nelminrange_dp(i) = min( prange(i,2) , max( prange(i,1) , nelminrange_dp(i) + del ) )
1142 end do
1143
1144 if ( iierror == 0 ) exit
1145 !
1146 ! Restart the procedure.
1147 !
1148 ! bound to range: probably not necessary
1149 ipstart(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , nelminrange_dp(1:n) ) )
1150 del = eps
1151 inumrestart = inumrestart + 1
1152
1153 end do
1154
1155 if (present(funcmin)) then
1156 funcmin = ifuncmin
1157 endif
1158 if (present(neval)) then
1159 neval = ineval
1160 endif
1161 if (present(numrestart)) then
1162 numrestart = inumrestart
1163 endif
1164 if (present(ierror)) then
1165 ierror = iierror
1166 endif
1167 if (present(history)) then
1168 allocate(history(ineval))
1169 history(:) = history_tmp(1:ineval)
1170 end if
1171
1172 end function nelminrange_dp
1173
1174 function nelminrange_sp(func, pstart, prange, varmin, step, konvge, maxeval, &
1175 funcmin, neval, numrestart, ierror, history)
1176
1177 implicit none
1178
1179 INTERFACE
1180 FUNCTION func(pp)
1181 USE mo_kind, ONLY: sp
1182 IMPLICIT NONE
1183 REAL(sp), DIMENSION(:), INTENT(IN) :: pp
1184 REAL(sp) :: func
1185 END FUNCTION func
1186 END INTERFACE
1187 real(sp), intent(IN) :: pstart(:)
1188 real(sp), intent(IN) :: prange(:,:)
1189 real(sp), optional, intent(IN) :: varmin
1190 real(sp), optional, intent(IN) :: step(:)
1191 integer(i4), optional, intent(IN) :: konvge
1192 integer(i4), optional, intent(IN) :: maxeval
1193 real(sp), optional, intent(OUT) :: funcmin
1194 integer(i4), optional, intent(OUT) :: neval
1195 integer(i4), optional, intent(OUT) :: numrestart
1196 integer(i4), optional, intent(OUT) :: ierror
1197 real(sp), optional, intent(OUT), allocatable :: history(:) ! History of objective function values
1198 real(sp) :: nelminrange_sp(size(pstart))
1199
1200 real(sp), parameter :: ccoeff = 0.5_sp
1201 real(sp), parameter :: ecoeff = 2.0_sp
1202 real(sp), parameter :: rcoeff = 1.0_sp
1203 real(sp), parameter :: eps = 0.001_sp
1204 real(sp) :: ipstart(size(pstart))
1205 real(sp) :: ifuncmin
1206 real(sp) :: ivarmin
1207 real(sp) :: istep(size(pstart))
1208 integer(i4) :: ikonvge
1209 integer(i4) :: imaxeval
1210 integer(i4) :: ineval
1211 integer(i4) :: inumrestart
1212 integer(i4) :: iierror
1213 integer(i4) :: n, nn
1214 integer(i4) :: i
1215 integer(i4) :: ihi
1216 integer(i4) :: ilo
1217 integer(i4) :: j
1218 integer(i4) :: jcount
1219 integer(i4) :: l
1220 real(sp) :: del
1221 real(sp) :: p(size(pstart),size(pstart)+1)
1222 real(sp) :: p2star(size(pstart))
1223 real(sp) :: pbar(size(pstart))
1224 real(sp) :: pstar(size(pstart))
1225 real(sp) :: rq
1226 real(sp) :: x
1227 real(sp) :: y(size(pstart)+1)
1228 real(sp) :: y2star
1229 real(sp) :: ylo
1230 real(sp) :: ystar
1231 real(sp) :: z
1232 real(sp) :: dn, dnn
1233 real(sp) :: p0(size(pstart)), y0
1234 real(sp), allocatable :: history_tmp(:)
1235 !
1236 ! Defaults
1237 !
1238 nelminrange_sp(:) = 0.5_sp * ( prange(:,1) + prange(:,2) )
1239
1240 if (present(varmin)) then
1241 if (varmin <= 0.0_sp) stop 'Error nelmin: varmin<0'
1242 ivarmin = varmin
1243 else
1244 ivarmin = 1.0e-9_sp
1245 endif
1246 ! maximal number of function evaluations
1247 if (present(maxeval)) then
1248 if (maxeval <= 1) stop 'Error nelmin: maxeval<=1'
1249 imaxeval = maxeval
1250 else
1251 imaxeval = 1000
1252 endif
1253 ! history output
1254 if (present(history)) then
1255 ! worst case length
1256 allocate(history_tmp(imaxeval+3*size(ipstart)+1))
1257 end if
1258 if (present(konvge)) then
1259 ikonvge = konvge
1260 else
1261 ikonvge = imaxeval / 10
1262 endif
1263 if (ikonvge < 1) stop 'Error nelmin: konvg<1'
1264 !
1265 if (present(step)) then
1266 istep = step
1267 else ! if not given, deviate initial by 1%
1268 y0 = func(pstart)
1269 do i=1, size(pstart)
1270 p0 = pstart
1271 if (ne(p0(i),0.0_sp)) then
1272 ! bound to range
1273 p0(i) = min( prange(i,2) , max( prange(i,1) , 1.01_sp*p0(i) ) )
1274 else
1275 ! bound to range
1276 p0(i) = min( prange(i,2) , max( prange(i,1) , 0.01_sp ) )
1277 endif
1278 istep(i) = abs(func(p0) - y0)
1279 enddo
1280 endif
1281 !
1282 ! Check the input parameters.
1283 !
1284 if (size(prange,2) .ne. 2_i4) stop 'nelminrange_sp: range has to be array of size (:,2)'
1285 if (size(prange,1) .ne. size(ipstart)) stop 'nelminrange_sp: range has to be given for each dimension'
1286 if (.not. (all(prange(:,1) .le. pstart(:)) .and. all(prange(:,2) .ge. pstart(:)) )) then
1287 stop 'nelminrange_sp: starting point is not in range'
1288 end if
1289 !
1290 ! Initialization.
1291 !
1292 ipstart = pstart
1293 n = size(ipstart)
1294 ineval = 0_i4
1295 inumrestart = 0_i4
1296 jcount = ikonvge
1297 dn = real(n, sp)
1298 nn = n + 1
1299 dnn = real(nn, sp)
1300 del = 1.0_sp
1301 rq = ivarmin * dn
1302 !
1303 ! Initial or restarted loop.
1304 !
1305 do
1306 p(1:n,nn) = ipstart(1:n)
1307 y(nn) = func(ipstart)
1308 ineval = ineval + 1
1309 if (present(history)) history_tmp(ineval) = y(nn)
1310 !
1311 ! Define the initial simplex.
1312 !
1313 do j = 1, n
1314 x = ipstart(j)
1315 ! bound to range
1316 ipstart(j) = min( prange(j,2) , max( prange(j,1) , ipstart(j) + istep(j) * del ) )
1317 p(1:n,j) = ipstart(1:n)
1318 y(j) = func(ipstart)
1319 ineval = ineval + 1
1320 ipstart(j) = x
1321 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
1322 end do
1323 !
1324 ! Find highest and lowest Y values. FUNCMIN = Y(IHI) indicates
1325 ! the vertex of the simplex to be replaced.
1326 !
1327 ilo = minloc(y(1:n+1), 1)
1328 ylo = y(ilo)
1329 !
1330 ! Inner loop.
1331 !
1332 do while ( ineval < imaxeval )
1333 !
1334 ! FUNCMIN is, of course, the HIGHEST value???
1335 !
1336 ihi = maxloc(y(1:n+1), 1)
1337 ifuncmin = y(ihi)
1338 !
1339 ! Calculate PBAR, the centroid of the simplex vertices
1340 ! excepting the vertex with Y value FUNCMIN.
1341 !
1342 do i = 1, n
1343 pbar(i) = ( sum(p(i,1:n+1)) - p(i,ihi) ) / dn
1344 end do
1345 !
1346 ! Reflection through the centroid.
1347 !
1348 ! bound to range
1349 pstar(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + rcoeff * ( pbar(1:n) - p(1:n,ihi) ) ) )
1350 ystar = func(pstar)
1351 ineval = ineval + 1
1352 if (present(history)) history_tmp(ineval) = min( ystar, history_tmp(ineval-1) )
1353 !
1354 ! Successful reflection, so extension.
1355 !
1356 if ( ystar < ylo ) then
1357
1358 ! bound to range
1359 p2star(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + ecoeff * ( pstar(1:n) - pbar(1:n) ) ) )
1360 y2star = func(p2star)
1361 ineval = ineval + 1
1362 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
1363 !
1364 ! Retain extension or contraction.
1365 !
1366 if ( ystar < y2star ) then
1367 p(1:n,ihi) = pstar(1:n)
1368 y(ihi) = ystar
1369 else
1370 p(1:n,ihi) = p2star(1:n)
1371 y(ihi) = y2star
1372 end if
1373 !
1374 ! No extension.
1375 !
1376 else
1377 l = 0
1378 do i = 1, nn
1379 if ( ystar < y(i) ) l = l + 1
1380 end do
1381
1382 if ( 1 < l ) then
1383 p(1:n,ihi) = pstar(1:n)
1384 y(ihi) = ystar
1385 !
1386 ! Contraction on the Y(IHI) side of the centroid.
1387 !
1388 else if ( l == 0 ) then
1389 ! bound to range
1390 p2star(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + ccoeff * ( p(1:n,ihi) - pbar(1:n) ) ) )
1391 y2star = func(p2star)
1392 ineval = ineval + 1
1393 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
1394 !
1395 ! Contract the whole simplex.
1396 !
1397 if ( y(ihi) < y2star ) then
1398 do j = 1, n + 1
1399 ! bound to range
1400 p(1:n,j) = min( prange(1:n,2) , max( prange(1:n,1) , ( p(1:n,j) + p(1:n,ilo) ) * 0.5_sp ) )
1401 nelminrange_sp(1:n) = p(1:n,j)
1402 y(j) = func(nelminrange_sp)
1403 ineval = ineval + 1
1404 if (present(history)) history_tmp(ineval) = min( y(j), history_tmp(ineval-1) )
1405 end do
1406 ilo = minloc(y(1:n+1), 1)
1407 ylo = y(ilo)
1408
1409 cycle
1410 !
1411 ! Retain contraction.
1412 !
1413 else
1414 p(1:n,ihi) = p2star(1:n)
1415 y(ihi) = y2star
1416 end if
1417 !
1418 ! Contraction on the reflection side of the centroid.
1419 !
1420 else if ( l == 1 ) then
1421
1422 ! bound to range
1423 p2star(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , pbar(1:n) + ccoeff * ( pstar(1:n) - pbar(1:n) ) ) )
1424 y2star = func(p2star)
1425 ineval = ineval + 1
1426 if (present(history)) history_tmp(ineval) = min( y2star, history_tmp(ineval-1) )
1427 !
1428 ! Retain reflection?
1429 !
1430 if ( y2star <= ystar ) then
1431 p(1:n,ihi) = p2star(1:n)
1432 y(ihi) = y2star
1433 else
1434 p(1:n,ihi) = pstar(1:n)
1435 y(ihi) = ystar
1436 end if
1437
1438 end if
1439
1440 end if
1441 !
1442 ! Check if YLO improved.
1443 !
1444 if ( y(ihi) < ylo ) then
1445 ylo = y(ihi)
1446 ilo = ihi
1447 end if
1448
1449 jcount = jcount - 1
1450
1451 if ( 0 < jcount ) cycle
1452 !
1453 ! Check to see if minimum reached.
1454 !
1455 if ( ineval <= imaxeval ) then
1456 jcount = ikonvge
1457 x = sum( y(1:n+1) ) / dnn
1458 z = sum( ( y(1:n+1) - x )**2 )
1459 if ( z <= rq ) exit
1460 end if
1461
1462 end do
1463 !
1464 ! Factorial tests to check that FUNCMIN is a local minimum.
1465 !
1466 ! bound to range
1467 nelminrange_sp(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , p(1:n,ilo) ) )
1468 ifuncmin = y(ilo)
1469
1470 if ( imaxeval < ineval ) then
1471 iierror = 2
1472 exit
1473 end if
1474
1475 iierror = 0
1476
1477 do i = 1, n
1478 del = istep(i) * eps
1479 ! bound to range: probably not necessary
1480 nelminrange_sp(i) = min( prange(i,2) , max( prange(i,1) , nelminrange_sp(i) + del ) )
1481 z = func(nelminrange_sp)
1482 ineval = ineval + 1
1483 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
1484 if ( z < ifuncmin ) then
1485 iierror = 2
1486 exit
1487 end if
1488 ! bound to range: probably not necessary
1489 nelminrange_sp(i) = min( prange(i,2) , max( prange(i,1) , nelminrange_sp(i) - del - del ) )
1490 z = func(nelminrange_sp)
1491 ineval = ineval + 1
1492 if (present(history)) history_tmp(ineval) = min( z, history_tmp(ineval-1) )
1493 if ( z < ifuncmin ) then
1494 iierror = 2
1495 exit
1496 end if
1497 ! bound to range: probably not necessary
1498 nelminrange_sp(i) = min( prange(i,2) , max( prange(i,1) , nelminrange_sp(i) + del ) )
1499 end do
1500
1501 if ( iierror == 0 ) exit
1502 !
1503 ! Restart the procedure.
1504 !
1505 ! bound to range: probably not necessary
1506 ipstart(1:n) = min( prange(1:n,2) , max( prange(1:n,1) , nelminrange_sp(1:n) ) )
1507 del = eps
1508 inumrestart = inumrestart + 1
1509
1510 end do
1511
1512 if (present(funcmin)) then
1513 funcmin = ifuncmin
1514 endif
1515 if (present(neval)) then
1516 neval = ineval
1517 endif
1518 if (present(numrestart)) then
1519 numrestart = inumrestart
1520 endif
1521 if (present(ierror)) then
1522 ierror = iierror
1523 endif
1524 if (present(history)) then
1525 allocate(history(ineval))
1526 history(:) = history_tmp(1:ineval)
1527 end if
1528
1529 end function nelminrange_sp
1530
1531
1532 ! ------------------------------------------------------------------
1533
1534END MODULE mo_nelmin
Minimizes a user-specified function using the Nelder-Mead algorithm.
Comparison of real values for inequality.
Definition mo_utils.F90:289
Define number representations.
Definition mo_kind.F90:17
integer, parameter sp
Single Precision Real Kind.
Definition mo_kind.F90:44
integer, parameter i4
4 Byte Integer Kind
Definition mo_kind.F90:40
integer, parameter dp
Double Precision Real Kind.
Definition mo_kind.F90:46
Nelder-Mead algorithm.
Definition mo_nelmin.f90:14
real(dp) function, dimension(size(pstart)), public nelmin(func, pstart, varmin, step, konvge, maxeval, funcmin, neval, numrestart, ierror, history)
Minimizes a user-specified function using the Nelder-Mead algorithm.
real(dp) function, dimension(size(pstart)), public nelminxy(func, pstart, xx, yy, varmin, step, konvge, maxeval, funcmin, neval, numrestart, ierror, history)
Minimizes a user-specified function using the Nelder-Mead algorithm.
General utilities for the CHS library.
Definition mo_utils.F90:20