212 function sce(eval, functn, pini, prange, & ! IN
213 mymaxn, mymaxit, mykstop, mypcento, mypeps, myseed, & ! Optional IN
214 myngs, mynpg, mynps, mynspl, mymings, myiniflg, myprint, & ! Optional IN
215 mymask, myalpha, mybeta, & ! Optional IN
216 tmp_file, popul_file, & ! Optional IN
217 popul_file_append, & ! Optional IN
218 parallel, restart, restart_file, & ! OPTIONAL IN
222 bestf, neval, history & ! Optional OUT
230 use iso_fortran_env,
only : output_unit, error_unit
241 real(
dp),
dimension(:),
intent(in) :: pini
242 real(
dp),
dimension(:, :),
intent(in) :: prange
245 integer(i8),
optional,
intent(in) :: mymaxn
247 logical,
optional,
intent(in) :: mymaxit
249 integer(i4),
optional,
intent(in) :: mykstop
252 real(
dp),
optional,
intent(in) :: mypcento
255 real(
dp),
optional,
intent(in) :: mypeps
258 integer(i8),
optional,
intent(in) :: myseed
260 integer(i4),
optional,
intent(in) :: myngs
262 integer(i4),
optional,
intent(in) :: mynpg
264 integer(i4),
optional,
intent(in) :: mynps
266 integer(i4),
optional,
intent(in) :: mynspl
269 integer(i4),
optional,
intent(in) :: mymings
273 integer(i4),
optional,
intent(in) :: myiniflg
276 integer(i4),
optional,
intent(in) :: myprint
280 logical,
optional,
intent(in),
dimension(size(pini, 1)) :: mymask
282 real(
dp),
optional,
intent(in) :: myalpha
284 real(
dp),
optional,
intent(in) :: mybeta
286 character(len = *),
optional,
intent(in) :: tmp_file
290 character(len = *),
optional,
intent(in) :: popul_file
294 logical,
optional,
intent(in) :: popul_file_append
295 logical,
optional,
intent(in) :: parallel
299 logical,
optional,
intent(in) :: restart
300 character(len = *),
optional,
intent(in) :: restart_file
302 type(mpi_comm),
optional,
intent(in) :: comm
304 real(
dp),
optional,
intent(out) :: bestf
305 integer(i8),
optional,
intent(out) :: neval
306 real(
dp),
optional,
dimension(:),
allocatable,
intent(out) :: history
307 real(
dp),
dimension(size(pini, 1)) :: bestx
310 real(
dp),
dimension(size(pini, 1)) :: bl
311 real(
dp),
dimension(1000) :: dummy_bl
312 real(
dp),
dimension(size(pini, 1)) :: bu
313 real(
dp),
dimension(1000) :: dummy_bu
327 integer(i4) :: iniflg
328 integer(i4) :: iprint
330 logical,
dimension(size(pini, 1)) :: maskpara
332 logical,
dimension(1000) :: dummy_maskpara
336 character(len = 1024) :: istmp_file
337 logical :: ipopul_file
338 character(len = 1024) :: ispopul_file
340 real(
dp),
dimension(:),
allocatable :: history_tmp
341 real(
dp),
dimension(:),
allocatable :: ihistory_tmp
342 real(
dp) :: bestf_tmp
345 character(len = 1024) :: isrestart_file
352 real(
dp),
dimension(:, :),
allocatable :: x
353 real(
dp),
dimension(:),
allocatable :: xf
354 real(
dp),
dimension(size(pini, 1)) :: xx
355 real(
dp),
dimension(1000) :: dummy_xx
356 real(
dp),
dimension(:, :),
allocatable :: cx
357 real(
dp),
dimension(:),
allocatable :: cf
358 real(
dp),
dimension(:, :),
allocatable :: s
359 real(
dp),
dimension(:),
allocatable :: sf
360 real(
dp),
dimension(:),
allocatable :: worstx
362 real(
dp),
dimension(:),
allocatable :: xnstd
364 integer(i4),
dimension(:),
allocatable :: lcs
365 real(
dp),
dimension(:),
allocatable :: bound
366 real(
dp),
dimension(:),
allocatable :: unit
369 real(
dp),
dimension(:),
allocatable :: criter
371 integer(i4) :: ipcnvg
385 integer(i8) :: icall_merk, iicall
387 integer(i4) :: k1, k2
390 character(4),
dimension(:),
allocatable :: xname
391 character(512) :: format_str1
392 character(512) :: format_str2
395 integer(i8),
dimension(:),
allocatable :: iseed
396 integer(i8),
dimension(:, :),
allocatable :: save_state_unif
397 integer(i8),
dimension(:, :),
allocatable :: save_state_gauss
398 real(
dp),
dimension(:),
allocatable :: rand_tmp
399 integer(i4) :: ithread, n_threads
400 integer(i8),
dimension(n_save_state) :: itmp
401 real(
dp),
dimension(:, :),
allocatable :: xtmp
402 real(
dp),
dimension(:),
allocatable :: ftmp
404 logical :: ipopul_file_append
406 real(
dp),
dimension(:),
allocatable :: htmp
408 integer(i4) :: ierror
409 logical :: do_obj_loop
410 integer(i4) :: iproc, nproc
413 namelist /restartnml1/ &
414 bestx, dummy_bl, dummy_bu, maxn, maxit, kstop, pcento, peps, ngs, npg, nps, nspl, &
415 mings, iniflg, iprint, idot, dummy_maskpara, alpha, beta, bestf_tmp, &
416 parall, nopt, nn, npt, fpini, dummy_xx, worstf, gnrng, &
417 ngs1, ngs2, nloop, npt1, icall, &
418 n_threads, ipopul_file_append, itmp_file, istmp_file, &
419 ipopul_file, ispopul_file
420 namelist /restartnml2/ &
421 history_tmp, x, xf, worstx, xnstd, &
422 bound, unit, criter, xname, iseed, save_state_unif, &
425 if (
present(restart))
then
431 if (
present(restart_file))
then
432 isrestart_file = restart_file
434 isrestart_file =
'mo_sce.restart'
437 if (.not. irestart)
then
441 if (
present(parallel))
then
443 write(*, *)
'WARNING: sce: openMP parallelization with MPI enabled is no implemented yet'
447 if (
present(parallel))
then
468 allocate(rand_tmp(n_threads))
469 allocate(iseed(n_threads))
473 if (
present(mymask))
then
474 if (.not. any(mymask)) stop
'mo_sce: all parameters are masked --> none will be optimized'
481 nopt = count(maskpara, dim = 1)
486 if (
size(prange, dim = 1) .ne.
size(pini, 1))
then
487 stop
'mo_sce: prange has not matching rows'
489 if (
size(prange, dim = 2) .ne. 2)
then
490 stop
'mo_sce: two colums expected for prange'
495 if(((bu(ii) - bl(ii)) .lt. tiny(1.0_dp)) .and. maskpara(ii))
then
496 write(error_unit, *)
'para #', ii,
' :: range = ( ', bl(ii),
' , ', bu(ii),
' )'
497 stop
'mo_sce: inconsistent or too small parameter range'
503 if (
present(mymaxn))
then
504 if (mymaxn .lt. 2_i4) stop
'mo_sce: maxn has to be at least 2'
509 if (
present(mymaxit))
then
514 if (
present(mykstop))
then
515 if (mykstop .lt. 1_i4) stop
'mo_sce: kstop has to be at least 1'
520 if (
present(mypcento))
then
521 if (mypcento .lt. 0_dp) stop
'mo_sce: pcento should be positive'
526 if (
present(mypeps))
then
527 if (mypeps .lt. 0_dp) stop
'mo_sce: peps should be positive'
532 if (
present(myseed))
then
533 if (myseed .lt. 1_i8) stop
'mo_sce: seed should be non-negative'
534 forall(ii = 1 : n_threads) iseed(ii) = myseed + (ii - 1) * 1000_i8
538 if (
present(myngs))
then
539 if (myngs .lt. 1_i4) stop
'mo_sce: ngs has to be at least 1'
544 if (
present(mynpg))
then
545 if (mynpg .lt. 3_i4) stop
'mo_sce: npg has to be at least 3'
550 if (
present(mynps))
then
551 if (mynps .lt. 2_i4) stop
'mo_sce: nps has to be at least 2'
556 if (
present(mynspl))
then
557 if (mynspl .lt. 3_i4) stop
'mo_sce: nspl has to be at least 3'
562 if (
present(mymings))
then
563 if (mymings .lt. 1_i4) stop
'mo_sce: mings has to be at least 1'
568 if (
present(myiniflg))
then
569 if ((myiniflg .ne. 1_i4) .and. (myiniflg .ne. 0_i4)) stop
'mo_sce: iniflg has to be 0 or 1'
575 if (
present(myprint))
then
576 if ((myprint .lt. 0_i4) .or. (myprint .gt. 4_i4)) stop
'mo_sce: iprint has to be between 0 and 4'
577 if (myprint > 2_i4)
then
587 if (
present(myalpha))
then
592 if (
present(mybeta))
then
598 if (
present(popul_file_append))
then
599 ipopul_file_append = popul_file_append
601 ipopul_file_append = .false.
604 if (
present(tmp_file))
then
606 istmp_file = tmp_file
607 open(999, file = trim(adjustl(istmp_file)), action =
'write', status =
'unknown')
608 write(999, *)
'# settings :: general'
609 write(999, *)
'# nIterations seed'
610 write(999, *) maxn, iseed
611 write(999, *)
'# settings :: sce specific'
612 write(999, *)
'# sce_ngs sce_npg sce_nps'
613 write(999, *) ngs, npg, nps
614 write(999, *)
'# nloop icall ngs1 bestf worstf gnrng (bestx(j),j=1,nn)'
621 if (
present(popul_file))
then
623 ispopul_file = popul_file
625 ipopul_file = .false.
629 if (ipopul_file .and. (.not. ipopul_file_append))
then
630 open(999, file = trim(adjustl(ispopul_file)), action =
'write', status =
'unknown')
631 write(999, *)
'# xf(i) (x(i,j),j=1,nn)'
636 allocate(x(ngs * npg, nn))
637 allocate(xf(ngs * npg))
642 allocate(criter(kstop + 1))
644 allocate(history_tmp(maxn + 3 * ngs * nspl))
645 allocate(xtmp(npg, nn))
648 large = -0.5_dp * huge(1.0_dp)
650 large = 0.5_dp * huge(1.0_dp)
652 history_tmp(:) = large
669 if (iprint .lt. 2)
then
670 write(output_unit, *)
'=================================================='
671 write(output_unit, *)
'ENTER THE SHUFFLED COMPLEX EVOLUTION GLOBAL SEARCH'
672 write(output_unit, *)
'=================================================='
676 if (iprint .lt. 2)
then
677 write (*, *)
' Seeds used : ', iseed
680 call xor4096(iseed, rand_tmp, save_state = save_state_unif)
682 iseed = iseed + 1000_i8
683 call xor4096g(iseed, rand_tmp, save_state = save_state_gauss)
688 bound(ii) = bu(ii) - bl(ii)
696 if (idot)
write(output_unit,
'(A1)')
'.'
698 call mpi_comm_size(comm, nproc, ierror)
699 do iproc = 1, nproc-1
701 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
704 if (.not. maxit)
then
705 fpini = functn(pini, eval)
706 history_tmp(1) = fpini
708 fpini = -functn(pini, eval)
709 history_tmp(1) = -fpini
715 if (iprint .lt. 2)
then
716 write(output_unit, *)
''
717 write(output_unit, *)
''
718 write(output_unit, *)
'*** PRINT THE INITIAL POINT AND ITS CRITERION VALUE ***'
719 call write_best_final()
722 open(999, file = trim(adjustl(istmp_file)), action =
'write', position =
'append', recl = (nn + 6) * 30)
723 if (.not. maxit)
then
724 write(999, *) 0, 1, ngs1, fpini, fpini, 1.0_dp, pini
726 write(999, *) 0, 1, ngs1, -fpini, -fpini, 1.0_dp, pini
733 if (iniflg .eq. 1)
then
741 itmp = save_state_unif(1, :)
742 call getpnt(1, bl(1 : nn), bu(1 : nn), unit(1 : nn), pini(1 : nn), maskpara, itmp, xx)
743 save_state_unif(1, :) = itmp
747 if (idot)
write(output_unit,
'(A1)')
'.'
749 call mpi_comm_size(comm, nproc, ierror)
750 do iproc = 1, nproc-1
752 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
755 if (.not. maxit)
then
756 xf(1) = functn(xx, eval)
758 xf(1) = -functn(xx, eval)
778 itmp = save_state_unif(ithread, :)
779 call getpnt(1, bl(1 : nn), bu(1 : nn), unit(1 : nn), pini(1 : nn), maskpara, itmp, xx)
780 save_state_unif(ithread, :) = itmp
784 if (idot)
write(output_unit,
'(A1)')
'.'
786 call mpi_comm_size(comm, nproc, ierror)
787 do iproc = 1, nproc-1
789 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
792 if (.not. maxit)
then
793 xf(ii) = functn(xx, eval)
794 history_tmp(ii) = xf(ii)
796 xf(ii) = -functn(xx, eval)
797 history_tmp(ii) = -xf(ii)
813 call getpnt(1, bl(1 : nn), bu(1 : nn), unit(1 : nn), pini(1 : nn), maskpara, save_state_unif(ithread, :), xx)
817 if (idot)
write(output_unit,
'(A1)')
'.'
819 call mpi_comm_size(comm, nproc, ierror)
820 do iproc = 1, nproc-1
822 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
825 if (.not. maxit)
then
826 xf(ii) = functn(xx, eval)
828 history_tmp(icall) = xf(ii)
830 xf(ii) = -functn(xx, eval)
832 history_tmp(icall) = -xf(ii)
835 if (icall .ge. maxn)
then
837 if (iprint .lt. 2)
then
839 call write_termination_case(1)
840 call write_best_final()
848 icall = int(npt1,
i8)
852 large = minval(xf(1 : npt1))
853 large = merge(0.9_dp * large, 1.1_dp * large, large>0._dp)
855 large = maxval(xf(1 : npt1))
856 large = merge(1.1_dp * large, 0.9_dp * large, large>0._dp)
858 xf(1 : npt1) = merge(xf(1 : npt1), large,
is_finite(xf(1 : npt1)))
861 nonan =
size(pack(history_tmp(1 : npt1), mask =
is_finite(history_tmp(1 : npt1))))
862 if (nonan /= npt1)
then
863 allocate(htmp(nonan))
864 htmp(1 : nonan) = pack(history_tmp(1 : npt1), mask =
is_finite(history_tmp(1 : npt1)))
865 call sort(htmp(1 : nonan))
866 history_tmp(1 : nonan) = htmp(1 : nonan)
867 history_tmp(nonan + 1 : npt1) =
special_value(1.0_dp,
'IEEE_QUIET_NAN')
870 call sort(history_tmp(1 : npt1))
872 call sort_matrix(x(1 : npt1, 1 : nn), xf(1 : npt1))
877 worstx(ii) = x(npt1, ii)
883 call parstt(x(1 : npt1, 1 : nn), bound, peps, maskpara, xnstd, gnrng, ipcnvg)
887 call write_best_intermediate(.true.)
891 if (ipopul_file)
then
892 call write_population(.true.)
896 print :
if (iprint .lt. 2)
then
898 call write_best_intermediate(.false.)
901 if (iprint .eq. 1)
then
902 call write_population(.false.)
907 if (icall .ge. maxn)
then
908 if (iprint .lt. 2)
then
910 call write_termination_case(1)
911 call write_best_final()
918 call mpi_comm_size(comm, nproc, ierror)
919 do iproc = 1, nproc-1
920 do_obj_loop = .false.
921 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
928 if (ipcnvg .eq. 1)
then
929 if (iprint .lt. 2)
then
931 call write_termination_case(3)
932 call write_best_final()
939 call mpi_comm_size(comm, nproc, ierror)
940 do iproc = 1, nproc-1
941 do_obj_loop = .false.
942 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
949 dummy_maskpara = .false.
950 dummy_maskpara(1 :
size(pini, 1)) = maskpara
951 dummy_bl = -9999.0_dp
952 dummy_bl(1 :
size(pini, 1)) = bl
953 dummy_bu = -9999.0_dp
954 dummy_bu(1 :
size(pini, 1)) = bu
955 dummy_xx = -9999.0_dp
956 dummy_xx(1 :
size(pini, 1)) = xx
959 open(999, file = isrestart_file, status =
'unknown', action =
'write', delim =
'quote')
960 write(999, restartnml1)
961 write(999, restartnml2)
967 open(999, file = isrestart_file, status =
'old', action =
'read', delim =
'quote')
968 read(999, nml = restartnml1)
972 maskpara = dummy_maskpara(1 :
size(pini, 1))
973 bl = dummy_bl(1 :
size(pini, 1))
974 bu = dummy_bu(1 :
size(pini, 1))
975 xx = dummy_xx(1 :
size(pini, 1))
978 allocate(rand_tmp(n_threads))
979 allocate(iseed(n_threads))
982 allocate(x(ngs * npg, nn))
983 allocate(xf(ngs * npg))
988 allocate(criter(kstop + 1))
990 allocate(history_tmp(maxn + 3 * ngs * nspl))
991 allocate(xtmp(npg, nn))
997 mainloop :
do while (icall .lt. maxn)
999 open(999, file = isrestart_file, status =
'old', action =
'read', delim =
'quote')
1000 read(999, nml = restartnml1)
1001 read(999, nml = restartnml2)
1005 maskpara = dummy_maskpara(1 :
size(pini, 1))
1006 bl = dummy_bl(1 :
size(pini, 1))
1007 bu = dummy_bu(1 :
size(pini, 1))
1008 xx = dummy_xx(1 :
size(pini, 1))
1012 if (iprint .lt. 2)
then
1013 write(output_unit, *)
''
1014 write(output_unit,
'(A28,I4)')
' *** Evolution Loop Number ', nloop
1030 allocate(cx(npg, nn))
1033 allocate(s(nps, nn))
1035 allocate(ihistory_tmp(maxn + 3 * ngs * nspl))
1037 comploop_omp :
do igs = 1, ngs1
1042 k2 = (k1 - 1) * ngs1 + igs
1044 cx(k1, jj) = x(k2, jj)
1051 subcomploop_omp :
do loop = 1, nspl
1058 if (nps .eq. npg)
then
1063 call xor4096(iseed(ithread), rand, save_state = save_state_unif(ithread, :))
1064 lcs(1) = 1 + int(real(npg,
dp) + 0.5_dp &
1065 - sqrt((real(npg,
dp) + .5_dp)**2 - real(npg,
dp) * real(npg + 1,
dp) * rand))
1068 do while (.not. lpos_ok)
1070 call xor4096(iseed(ithread), rand, save_state = save_state_unif(ithread, :))
1071 lpos = 1 + int(real(npg,
dp) + 0.5_dp &
1072 - sqrt((real(npg,
dp) + .5_dp)**2 - real(npg,
dp) * real(npg + 1,
dp) * rand))
1075 if (lpos .eq. lcs(k1)) lpos_ok = (lpos_ok .and. .false.)
1082 call sort(lcs(1 : nps))
1088 s(kk, jj) = cx(lcs(kk), jj)
1090 sf(kk) = cf(lcs(kk))
1095 large = minval(cf(1 : npg))
1096 large = merge(0.9_dp * large, 1.1_dp * large, large>0._dp)
1098 large = maxval(cf(1 : npg))
1099 large = merge(1.1_dp * large, 0.9_dp * large, large>0._dp)
1105 ihistory_tmp = history_tmp
1107 call cce(s(1 : nps, 1 : nn), sf(1 : nps), bl(1 : nn), bu(1 : nn), maskpara, xnstd(1 : nn), &
1108 iicall, maxn, maxit, save_state_gauss(ithread, :), functn, eval, alpha, beta, ihistory_tmp, idot, comm)
1110 call cce(s(1 : nps, 1 : nn), sf(1 : nps), bl(1 : nn), bu(1 : nn), maskpara, xnstd(1 : nn), &
1111 iicall, maxn, maxit, save_state_gauss(ithread, :), functn, eval, alpha, beta, ihistory_tmp, idot)
1113 history_tmp(icall + 1 : icall + (iicall - icall_merk)) = ihistory_tmp(icall_merk + 1 : iicall)
1114 icall = icall + (iicall - icall_merk)
1120 cx(lcs(kk), jj) = s(kk, jj)
1122 cf(lcs(kk)) = sf(kk)
1126 cf(1 : npg) = merge(cf(1 : npg), large,
is_finite(cf(1 : npg)))
1127 call sort_matrix(cx(1 : npg, 1 : nn), cf(1 : npg))
1132 end do subcomploop_omp
1136 k2 = (k1 - 1) * ngs1 + igs
1138 x(k2, jj) = cx(k1, jj)
1152 deallocate(ihistory_tmp)
1161 allocate(cx(npg, nn))
1164 allocate(s(nps, nn))
1169 comploop :
do igs = 1, ngs1
1173 k2 = (k1 - 1) * ngs1 + igs
1175 cx(k1, jj) = x(k2, jj)
1182 subcomploop :
do loop = 1, nspl
1189 if (nps .eq. npg)
then
1194 call xor4096(iseed(ithread), rand, save_state = save_state_unif(ithread, :))
1195 lcs(1) = 1 + int(real(npg,
dp) + 0.5_dp &
1196 - sqrt((real(npg,
dp) + .5_dp)**2 - real(npg,
dp) * real(npg + 1,
dp) * rand))
1199 do while (.not. lpos_ok)
1201 call xor4096(iseed(ithread), rand, save_state = save_state_unif(ithread, :))
1202 lpos = 1 + int(real(npg,
dp) + 0.5_dp &
1203 - sqrt((real(npg,
dp) + .5_dp)**2 - real(npg,
dp) * real(npg + 1,
dp) * rand))
1206 if (lpos .eq. lcs(k1)) lpos_ok = (lpos_ok .and. .false.)
1213 call sort(lcs(1 : nps))
1219 s(kk, jj) = cx(lcs(kk), jj)
1221 sf(kk) = cf(lcs(kk))
1226 large = minval(cf(1 : npg))
1227 large = merge(0.9_dp * large, 1.1_dp * large, large>0._dp)
1229 large = maxval(cf(1 : npg))
1230 large = merge(1.1_dp * large, 0.9_dp * large, large>0._dp)
1235 call cce(s(1 : nps, 1 : nn), sf(1 : nps), bl(1 : nn), bu(1 : nn), maskpara, xnstd(1 : nn), &
1236 icall, maxn, maxit, save_state_gauss(ithread, :), functn, eval, alpha, beta, history_tmp, idot, comm)
1238 call cce(s(1 : nps, 1 : nn), sf(1 : nps), bl(1 : nn), bu(1 : nn), maskpara, xnstd(1 : nn), &
1239 icall, maxn, maxit, save_state_gauss(ithread, :), functn, eval, alpha, beta, history_tmp, idot)
1246 cx(lcs(kk), jj) = s(kk, jj)
1248 cf(lcs(kk)) = sf(kk)
1252 cf(1 : npg) = merge(cf(1 : npg), large,
is_finite(cf(1 : npg)))
1253 call sort_matrix(cx(1 : npg, 1 : nn), cf(1 : npg))
1256 if (icall .ge. maxn)
then
1257 if (iprint .lt. 2)
then
1259 call write_termination_case(1)
1260 call write_best_final()
1269 k2 = (k1 - 1) * ngs1 + igs
1271 x(k2, jj) = cx(k1, jj)
1275 if (icall .ge. maxn)
then
1276 if (iprint .lt. 2)
then
1278 call write_termination_case(1)
1279 call write_best_final()
1296 call sort_matrix(x(1 : npt1, 1 : nn), xf(1 : npt1))
1300 bestx(jj) = x(1, jj)
1301 worstx(jj) = x(npt1, jj)
1307 call parstt(x(1 : npt1, 1 : nn), bound, peps, maskpara, xnstd, gnrng, ipcnvg)
1311 call write_best_intermediate(.true.)
1315 if (ipopul_file)
then
1316 call write_population(.true.)
1320 if (iprint .lt. 2)
then
1321 call write_best_intermediate(.false.)
1323 if (iprint .eq. 1)
then
1324 call write_population(.false.)
1331 if (icall .ge. maxn)
then
1332 if (iprint .lt. 2)
then
1334 call write_termination_case(1)
1335 call write_best_final()
1342 call mpi_comm_size(comm, nproc, ierror)
1343 do iproc = 1, nproc-1
1344 do_obj_loop = .false.
1345 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
1352 criter(kstop + 1) = bestf_tmp
1353 if (nloop .gt. kstop)
then
1354 denomi = 0.5_dp * abs(criter((kstop + 1) - kstop) + criter(kstop + 1))
1355 denomi = max(denomi, 1.0e-15_dp)
1356 timeou = abs(criter((kstop + 1) - kstop) - criter(kstop + 1)) / denomi
1357 if (timeou .lt. pcento)
then
1358 if (iprint .lt. 2)
then
1360 call write_termination_case(2)
1361 call write_best_final()
1368 call mpi_comm_size(comm, nproc, ierror)
1369 do iproc = 1, nproc-1
1370 do_obj_loop = .false.
1371 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
1377 criter(1 : kstop) = criter(2 : kstop + 1)
1380 if (ipcnvg .eq. 1)
then
1381 if (iprint .lt. 2)
then
1383 call write_termination_case(3)
1384 call write_best_final()
1391 call mpi_comm_size(comm, nproc, ierror)
1392 do iproc = 1, nproc-1
1393 do_obj_loop = .false.
1394 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
1403 if (ngs1 .gt. mings)
then
1407 call comp(ngs2, npg, x(1 : ngs2 * npg, 1 : nn), xf(1 : ngs2 * npg), xtmp(1 : ngs2 * npg, 1 : nn), ftmp(1 : ngs2 * npg))
1411 dummy_maskpara = .false.
1412 dummy_maskpara(1 :
size(pini, 1)) = maskpara
1413 dummy_bl = -9999.0_dp
1414 dummy_bl(1 :
size(pini, 1)) = bl
1415 dummy_bu = -9999.0_dp
1416 dummy_bu(1 :
size(pini, 1)) = bu
1417 dummy_xx = -9999.0_dp
1418 dummy_xx(1 :
size(pini, 1)) = xx
1421 open(999, file = isrestart_file, status =
'unknown', action =
'write', delim =
'quote')
1422 write(999, restartnml1)
1423 write(999, restartnml2)
1433 call mpi_comm_size(comm, nproc, ierror)
1434 do iproc = 1, nproc-1
1435 do_obj_loop = .false.
1436 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
1441 subroutine write_best_intermediate(to_file)
1445 logical,
intent(in) :: to_file
1449 open(999, file = trim(adjustl(istmp_file)), action =
'write', position =
'append', recl = (nn + 6) * 30)
1450 if (.not. maxit)
then
1451 write(999, *) nloop, icall, ngs1, bestf_tmp, worstf, gnrng, (bestx(ll), ll = 1, nn)
1453 write(999, *) nloop, icall, ngs1, -bestf_tmp, -worstf, gnrng, (bestx(ll), ll = 1, nn)
1457 write(format_str1,
'(A13,I3,A8)')
'( A49, ', nn,
'(6X,A4))'
1458 write(format_str2,
'(A26,I3,A8)')
'(I5,1X,I5,3X,I5,3(E22.14), ', nn,
'(G10.3))'
1459 if (nloop == 0)
then
1460 write(output_unit, *)
''
1461 write(output_unit,
'(A44)')
' *** PRINT THE RESULTS OF THE SCE SEARCH ***'
1462 write(output_unit, *)
''
1463 write(output_unit, format_str1)
' LOOP TRIALS COMPLXS BEST F WORST F PAR RNG ', (xname(ll), ll = 1, nn)
1465 if (.not. maxit)
then
1466 write(output_unit, format_str2) nloop, icall, ngs1, bestf_tmp, worstf, gnrng, (bestx(ll), ll = 1, nn)
1468 write(output_unit, format_str2) nloop, icall, ngs1, -bestf_tmp, -worstf, gnrng, (bestx(ll), ll = 1, nn)
1472 end subroutine write_best_intermediate
1474 subroutine write_best_final()
1480 write(format_str1,
'(A13,I3,A8)')
'( A10, ', nn,
'(6X,A4))'
1481 write(format_str2,
'(A14,I3,A8)')
'(E22.14, ', nn,
'(G10.3))'
1483 write(output_unit, format_str1)
'CRITERION ', (xname(ll), ll = 1, nn)
1484 if (.not. maxit)
then
1485 write(output_unit, format_str2) bestf_tmp, (bestx(ll), ll = 1, nn)
1487 write(output_unit, format_str2) -bestf_tmp, (bestx(ll), ll = 1, nn)
1490 end subroutine write_best_final
1492 subroutine write_population(to_file)
1494 logical,
intent(in) :: to_file
1496 integer(i4) :: ll, mm
1499 write(format_str2,
'(A13,I3,A9)')
'(I4, E22.14, ', nn,
'(E22.14))'
1500 open(unit = 999, file = trim(adjustl(ispopul_file)), action =
'write', position =
'append', recl = (nn + 2) * 30)
1501 if (.not. maxit)
then
1503 write(999, *) nloop, xf(mm), (x(mm, ll), ll = 1, nn)
1507 write(999, *) nloop, -xf(mm), (x(mm, ll), ll = 1, nn)
1512 write(format_str2,
'(A12,I3,A8)')
'(I4, E22.14, ', nn,
'(G10.3))'
1513 write(output_unit, *)
''
1514 write(output_unit,
'(A22,I3)')
' POPULATION AT LOOP ', nloop
1515 write(output_unit,
'(A27)')
'---------------------------'
1516 if (.not. maxit)
then
1518 write(output_unit, format_str2) nloop, xf(mm), (x(mm, ll), ll = 1, nn)
1522 write(output_unit, format_str2) nloop, -xf(mm), (x(mm, ll), ll = 1, nn)
1527 end subroutine write_population
1529 subroutine write_termination_case(case)
1531 integer(i4),
intent(in) :: case
1535 write(output_unit, *)
''
1536 write(output_unit,
'(A46,A39,I7,A46,I4,A12,I4,A19,I4,A4)') &
1537 '*** OPTIMIZATION SEARCH TERMINATED BECAUSE THE', &
1538 ' LIMIT ON THE MAXIMUM NUMBER OF TRIALS ', maxn, &
1539 ' EXCEEDED. SEARCH WAS STOPPED AT SUB-COMPLEX ', &
1540 loop,
' OF COMPLEX ', igs,
' IN SHUFFLING LOOP ', nloop,
' ***'
1543 write(output_unit, *)
''
1544 write(output_unit,
'(A72,F8.4,A12,I3,A20)')
'*** OPTIMIZATION TERMINATED BECAUSE THE CRITERION VALUE HAS NOT CHANGED ', &
1545 pcento * 100._dp,
' PERCENT IN ', kstop,
' SHUFFLING LOOPS ***'
1548 write(output_unit, *)
''
1549 write(output_unit,
'(A50,A20,F8.4,A34)')
'*** OPTIMIZATION TERMINATED BECAUSE THE POPULATION', &
1550 ' HAS CONVERGED INTO ', gnrng * 100._dp,
' PERCENT OF THE FEASIBLE SPACE ***'
1553 write(error_unit, *)
'This termination case is not implemented!'
1557 write(output_unit, *)
''
1558 write(output_unit,
'(A66)')
'*** PRINT THE FINAL PARAMETER ESTIMATE AND ITS CRITERION VALUE ***'
1560 end subroutine write_termination_case
1562 subroutine set_optional()
1566 if (
present(neval)) neval = icall
1567 if (
present(bestf) .and. .not. maxit) bestf = bestf_tmp
1568 if (
present(bestf) .and. maxit) bestf = -bestf_tmp
1569 if (
present(history))
then
1570 allocate(history(icall))
1571 history(:) = history_tmp(1 : icall)
1574 end subroutine set_optional
1579 subroutine parstt(x, bound, peps, mask, xnstd, gnrng, ipcnvg)
1587 real(
dp),
dimension(:, :),
intent(in) :: x
1588 real(
dp),
dimension(:),
intent(in) :: bound
1589 real(
dp),
intent(in) :: peps
1591 logical,
dimension(:),
intent(in) :: mask
1592 real(
dp),
dimension(size(bound, 1)),
intent(out) :: xnstd
1593 real(
dp),
intent(out) :: gnrng
1594 integer(i4),
intent(out) :: ipcnvg
1600 integer(i4) :: ii, kk
1605 real(
dp),
dimension(size(bound, 1)) :: xmin
1606 real(
dp),
dimension(size(bound, 1)) :: xmax
1607 real(
dp),
dimension(size(bound, 1)) :: xmean
1608 real(
dp),
parameter :: delta = tiny(1.0_dp)
1617 xmax(kk) = -huge(1.0_dp)
1618 xmin(kk) = huge(1.0_dp)
1622 xmax(kk) = dmax1(x(ii, kk), xmax(kk))
1623 xmin(kk) = dmin1(x(ii, kk), xmin(kk))
1624 xsum1 = xsum1 + x(ii, kk)
1625 xsum2 = xsum2 + x(ii, kk) * x(ii, kk)
1627 xmean(kk) = xsum1 / real(npt1,
dp)
1628 xnstd(kk) = (xsum2 / real(npt1,
dp) - xmean(kk) * xmean(kk))
1629 if (xnstd(kk) .le. delta)
then
1632 xnstd(kk) = sqrt(xnstd(kk))
1633 xnstd(kk) = xnstd(kk) / bound(kk)
1634 gsum = gsum + log(delta + (xmax(kk) - xmin(kk)) / bound(kk))
1637 gnrng = exp(gsum / real(nn,
dp))
1641 if (gnrng .le. peps)
then
1645 end subroutine parstt
1647 subroutine comp(ngs2, npg, a, af, b, bf)
1661 integer(i4),
intent(in) :: ngs2
1662 integer(i4),
intent(in) :: npg
1663 real(
dp),
dimension(:, :),
intent(inout) :: a
1664 real(
dp),
dimension(:),
intent(inout) :: af
1665 real(
dp),
dimension(size(a, 1), size(a, 2)),
intent(out) :: b
1666 real(
dp),
dimension(size(af)),
intent(out) :: bf
1675 integer(i4) :: k1, k2
1677 n =
size(a, dim = 2)
1685 k1 = (ipg - 1) * ngs2 + igs
1686 k2 = (ipg - 1) * ngs1 + igs
1703 subroutine sort_matrix(rb, ra)
1710 real(
dp),
dimension(:),
intent(inout) :: ra
1711 real(
dp),
dimension(:, :),
intent(inout) :: rb
1717 integer(i4),
dimension(size(rb, 1)) :: iwk
1730 rb(1 : n, i) = rb(iwk, i)
1733 end subroutine sort_matrix
1735 subroutine chkcst(x, bl, bu, mask, ibound)
1751 real(
dp),
dimension(:),
intent(in) :: x
1752 real(
dp),
dimension(:),
intent(in) :: bl
1753 real(
dp),
dimension(:),
intent(in) :: bu
1754 logical,
dimension(:),
intent(in) :: mask
1755 integer(i4),
intent(out) :: ibound
1766 if ((x(ii) .lt. bl(ii)) .or. (x(ii) .gt. bu(ii)))
then
1774 end subroutine chkcst
1776 subroutine getpnt(idist, bl, bu, std, xi, mask, save_state, x)
1787 integer(i4),
intent(in) :: idist
1790 real(
dp),
dimension(:),
intent(in) :: bl
1791 real(
dp),
dimension(:),
intent(in) :: bu
1792 real(
dp),
dimension(:),
intent(in) :: std
1793 real(
dp),
dimension(:),
intent(in) :: xi
1794 logical,
dimension(:),
intent(in) :: mask
1795 integer(i8),
dimension(n_save_state),
intent(inout) :: save_state
1797 real(
dp),
dimension(size(xi, 1)),
intent(out) :: x
1802 integer(i4) :: ibound
1809 do while (ibound .eq. 1)
1810 if (idist .eq. 1)
then
1811 call xor4096(0_i8, rand, save_state = save_state)
1812 x(jj) = bl(jj) + std(jj) * rand * (bu(jj) - bl(jj))
1814 if (idist .eq. 2)
then
1815 call xor4096g(0_i8, rand, save_state = save_state)
1816 x(jj) = xi(jj) + std(jj) * rand * (bu(jj) - bl(jj))
1821 call chkcst((/x(jj)/), (/bl(jj)/), (/bu(jj)/), (/mask(jj)/), ibound)
1828 end subroutine getpnt
1830 subroutine cce(s, sf, bl, bu, maskpara, xnstd, icall, maxn, maxit, save_state_gauss, functn, eval, &
1831 alpha, beta, history, idot &
1844 use iso_fortran_env,
only : output_unit
1853 real(
dp),
dimension(:, :),
intent(inout) :: s
1854 real(
dp),
dimension(:),
intent(inout) :: sf
1856 real(
dp),
dimension(:),
intent(in) :: bl
1857 real(
dp),
dimension(:),
intent(in) :: bu
1858 logical,
dimension(:),
intent(in) :: maskpara
1859 real(
dp),
dimension(:),
intent(in) :: xnstd
1861 integer(i8),
intent(inout) :: icall
1862 integer(i8),
intent(in) :: maxn
1863 logical,
intent(in) :: maxit
1864 integer(i8),
dimension(n_save_state),
intent(inout) :: save_state_gauss
1867 real(
dp),
intent(in) :: alpha
1868 real(
dp),
intent(in) :: beta
1869 real(
dp),
dimension(maxn),
intent(inout) :: history
1870 logical,
intent(in) :: idot
1872 type(mpi_comm),
optional,
intent(in) :: comm
1881 integer(i4) :: ibound
1884 real(
dp),
dimension(size(s, 2)) :: sw
1885 real(
dp),
dimension(size(s, 2)) :: sb
1886 real(
dp),
dimension(size(s, 2)) :: ce
1887 real(
dp),
dimension(size(s, 2)) :: snew
1891 integer(i4) :: ierror
1892 logical :: do_obj_loop
1893 integer(i4) :: iproc, nproc
1912 ce(j) = ce(j) + s(i, j)
1914 ce(j) = ce(j) / real(n - 1,
dp)
1922 if (maskpara(j))
then
1923 snew(j) = ce(j) + alpha * (ce(j) - sw(j))
1930 call chkcst(snew(1 : nn), bl(1 : nn), bu(1 : nn), maskpara(1 : nn), ibound)
1936 if (ibound .eq. 1)
then
1937 call getpnt(2, bl(1 : nn), bu(1 : nn), xnstd(1 : nn), sb(1 : nn), maskpara(1 : nn), save_state_gauss, snew)
1941 if (idot)
write(output_unit,
'(A1)')
'.'
1943 call mpi_comm_size(comm, nproc, ierror)
1944 do iproc = 1, nproc-1
1945 do_obj_loop = .true.
1946 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
1949 if (.not. maxit)
then
1950 fnew = functn(snew, eval)
1951 icall = icall + 1_i8
1952 history(icall) = min(history(icall - 1), fnew)
1954 fnew = -functn(snew, eval)
1955 icall = icall + 1_i8
1956 history(icall) = max(history(icall - 1), -fnew)
1960 if (icall .ge. maxn)
return
1964 if ((fnew .gt. fw) .or. (.not.
is_finite(fnew)))
then
1966 if (maskpara(j))
then
1967 snew(j) = ce(j) - beta * (ce(j) - sw(j))
1974 if (idot)
write(output_unit,
'(A1)')
'.'
1976 call mpi_comm_size(comm, nproc, ierror)
1977 do iproc = 1, nproc-1
1978 do_obj_loop = .true.
1979 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
1982 if (.not. maxit)
then
1983 fnew = functn(snew, eval)
1984 icall = icall + 1_i8
1985 history(icall) = min(history(icall - 1), fnew)
1987 fnew = -functn(snew, eval)
1988 icall = icall + 1_i8
1989 history(icall) = max(history(icall - 1), -fnew)
1993 if (icall .ge. maxn)
return
1997 if ((fnew .gt. fw) .or. (.not.
is_finite(fnew)))
then
2002 call getpnt(2, bl(1 : nn), bu(1 : nn), xnstd(1 : nn), sb(1 : nn), maskpara(1 : nn), save_state_gauss, snew)
2005 if (idot)
write(output_unit,
'(A1)')
'.'
2007 call mpi_comm_size(comm, nproc, ierror)
2008 do iproc = 1, nproc-1
2009 do_obj_loop = .true.
2010 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
2013 if (.not. maxit)
then
2014 fnew = functn(snew, eval)
2015 icall = icall + 1_i8
2016 history(icall) = min(history(icall - 1), fnew)
2018 fnew = -functn(snew, eval)
2019 icall = icall + 1_i8
2020 history(icall) = max(history(icall - 1), -fnew)
2024 if (icall .ge. maxn)
return
Interface for evaluation routine.
Interface for objective function.
Gives the indeces that would sort an array in ascending order.
Sorts the input array in ascending order.
Generate seed for xor4096.
Uniform XOR4096-based RNG.
Gaussian XOR4096-based RNG.
Define number representations.
integer, parameter i4
4 Byte Integer Kind
integer, parameter i8
8 Byte Integer Kind
integer, parameter dp
Double Precision Real Kind.
Utility functions, such as interface definitions, for optimization routines.
Sort and ranking routines.
Shuffled Complex Evolution optimization algorithm.
real(dp) function, dimension(size(pini, 1)), public sce(eval, functn, pini, prange, mymaxn, mymaxit, mykstop, mypcento, mypeps, myseed, myngs, mynpg, mynps, mynspl, mymings, myiniflg, myprint, mymask, myalpha, mybeta, tmp_file, popul_file, popul_file_append, parallel, restart, restart_file, bestf, neval, history)
Shuffled Complex Evolution (SCE) algorithm for global optimization.
character(len(whitespaces)) function, public compress(whitespaces, n)
Remove white spaces.
General utilities for the CHS library.
XOR4096-based random number generator.
integer(i4), parameter, public n_save_state
Dimension of vector saving the state of a stream.