282 MODULE PROCEDURE generate_neighborhood_weight_dp
290 prange, prange_func, & ! optional IN: exactly one of both
291 temp, Dt, nITERmax, Len, nST, eps, acc, & ! optional IN
292 seeds, printflag, maskpara, weight, & ! optional IN
293 changeParaMode, reflectionFlag, & ! optional IN
294 pertubFlexFlag, maxit, undef_funcval, & ! optional IN
295 tmp_file, & ! optional IN
296 funcbest, history & ! optional OUT
306 SUBROUTINE prange_func(paraset, iPar, rangePar)
309 real(
dp),
dimension(:),
INTENT(IN) :: paraset
310 integer(i4),
INTENT(IN) :: ipar
311 real(
dp),
dimension(2),
INTENT(OUT) :: rangepar
312 END SUBROUTINE prange_func
314 optional :: prange_func
316 real(dp),
dimension(:),
intent(in) :: para
318 real(dp),
optional,
dimension(size(para, 1), 2),
intent(in) :: prange
319 real(dp),
optional,
intent(in) :: temp
320 real(dp),
optional,
intent(in) :: dt
321 integer(i4),
optional,
intent(in) :: nitermax
322 integer(i4),
optional,
intent(in) :: len
324 integer(i4),
optional,
intent(in) :: nst
325 real(dp),
optional,
intent(in) :: eps
326 real(dp),
optional,
intent(in) :: acc
328 INTEGER(I8),
optional,
intent(in) :: seeds(3)
329 logical,
optional,
intent(in) :: printflag
331 logical,
optional,
dimension(size(para, 1)),
intent(in) :: maskpara
334 real(dp),
optional,
dimension(size(para, 1)),
intent(in) :: weight
337 integer(i4),
optional,
intent(in) :: changeparamode
340 logical,
optional,
intent(in) :: reflectionflag
343 logical,
optional,
intent(in) :: pertubflexflag
346 logical,
optional,
intent(in) :: maxit
349 real(dp),
optional,
intent(in) :: undef_funcval
352 CHARACTER(LEN = *),
optional,
intent(in) :: tmp_file
353 real(dp),
optional,
intent(out) :: funcbest
355 real(dp),
optional,
dimension(:, :),
allocatable,
intent(out) :: history
358 real(dp),
dimension(size(para, 1)) :: parabest
361 integer(i4) :: ipar, par
362 real(dp),
dimension(2) :: iparrange
365 integer(i4) :: nitermax_in
366 integer(i4) :: len_in
367 integer(i4) :: nst_in
370 INTEGER(I8) :: seeds_in(3)
371 logical :: printflag_in
372 logical :: coststatus
374 logical,
dimension(size(para, 1)) :: maskpara_in
375 integer(i4),
dimension(:),
allocatable :: truepara
376 real(dp),
dimension(size(para, 1)) :: weight_in
377 real(dp),
dimension(size(para, 1)) :: weightuni
378 real(dp),
dimension(size(para, 1)) :: weightgrad
379 integer(i4) :: changeparamode_inin
380 logical :: reflectionflag_inin
382 logical :: pertubflexflag_inin
386 real(dp),
dimension(:, :),
allocatable :: history_out
387 real(dp),
dimension(:, :),
allocatable :: history_out_tmp
397 type (paramlim),
dimension (size(para, 1)),
target :: gamma
400 real(dp) :: rn1, rn2, rn3
401 integer(I8),
dimension(n_save_state) :: save_state_1
402 integer(I8),
dimension(n_save_state) :: save_state_2
403 integer(I8),
dimension(n_save_state) :: save_state_3
405 logical,
dimension(size(para, 1)) :: neighborhood
406 real(dp) :: pertubationr
409 integer(i4) :: idummy, i
411 real(dp) :: ac_ratio, pa
412 integer(i4),
dimension(:, :),
allocatable :: ipos_ineg_history
413 real(dp) :: fo, fn, df, fbest
414 real(dp) :: rho, finc, fbb, dr
416 real(dp),
parameter :: small = -700._dp
417 integer(i4) :: j, iter, kk
418 integer(i4) :: ipos, ineg
419 integer(i4) :: iconl, iconr, iconf
420 integer(i4) :: itotalcounter
421 integer(i4) :: itotalcounterr
430 if (
present(prange) .eqv.
present(prange_func))
then
431 stop
'anneal: Either range or prange_func has to be given'
434 if (
present(dt))
then
435 if ((dt .lt. 0.7_dp) .or. (dt .gt. 0.999_dp))
then
436 stop
'Input argument DT must lie between 0.7 and 0.999'
444 if (
present(nitermax))
then
445 if (nitermax .lt. 1_i4)
then
446 stop
'Input argument nITERmax must be greater 0'
448 nitermax_in = nitermax
451 nitermax_in = 1000_i4
454 if (
present(len))
then
455 if (len .lt. max(20_i4 * n, 250_i4))
then
456 print*,
'WARNING: Input argument LEN should be greater than Max(250,20*N), N=number of parameters'
462 len_in = max(20_i4 * n, 250_i4)
465 idummy = nitermax_in / len_in + 1_i4
466 allocate(history_out(idummy, 2))
468 if (
present(nst))
then
469 if (nst .lt. 0_i4)
then
470 stop
'Input argument nST must be greater than 0'
478 allocate(ipos_ineg_history(nst_in, 2))
479 ipos_ineg_history = 0_i4
481 if (
present(eps))
then
482 if (
le(eps, 0.0_dp))
then
483 stop
'Input argument eps must be greater than 0'
491 if (
present(acc))
then
492 if (
le(acc, 0.0_dp) .or.
ge(acc, 1.0_dp))
then
493 stop
'Input argument acc must lie between 0.0 and 1.0'
501 if (
present(seeds))
then
508 if (
present(printflag))
then
509 printflag_in = printflag
511 printflag_in = .false.
514 if (
present(maskpara))
then
515 if (count(maskpara) .eq. 0_i4)
then
516 stop
'Input argument maskpara: At least one element has to be true'
518 maskpara_in = maskpara
524 if (
present(maxit))
then
536 if (
present(temp))
then
537 if ((temp .lt. 0.0_dp))
then
538 stop
'Input argument temp must be greater then zero'
543 if (
present(prange_func))
then
544 if (
present(undef_funcval))
then
545 t_in =
gettemperature(eval, cost, para, 0.95_dp, prange_func = prange_func, &
546 maskpara = maskpara_in, samplesize = 2_i4 * len_in, &
547 seeds = seeds_in(1 : 2), printflag = printflag_in, &
548 maxit = ldummy, undef_funcval = undef_funcval)
550 t_in =
gettemperature(eval, cost, para, 0.95_dp, prange_func = prange_func, &
551 maskpara = maskpara_in, samplesize = 2_i4 * len_in, &
552 seeds = seeds_in(1 : 2), printflag = printflag_in, &
556 if (
present(undef_funcval))
then
557 t_in =
gettemperature(eval, cost, para, 0.95_dp, prange = prange, &
558 maskpara = maskpara_in, samplesize = 2_i4 * len_in, &
559 seeds = seeds_in(1 : 2), printflag = printflag_in, &
560 maxit = ldummy, undef_funcval = undef_funcval)
562 t_in =
gettemperature(eval, cost, para, 0.95_dp, prange = prange, &
563 maskpara = maskpara_in, samplesize = 2_i4 * len_in, &
564 seeds = seeds_in(1 : 2), printflag = printflag_in, &
570 if (
present(changeparamode))
then
571 changeparamode_inin = changeparamode
573 changeparamode_inin = 1_i4
576 if (
present(reflectionflag))
then
577 reflectionflag_inin = reflectionflag
579 reflectionflag_inin = .false.
582 if (
present(pertubflexflag))
then
583 pertubflexflag_inin = pertubflexflag
585 pertubflexflag_inin = .true.
589 if(
present(tmp_file))
then
590 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', status =
'unknown')
591 write(999, *)
'# settings :: general'
592 write(999, *)
'# nIterations iseed'
593 write(999, *) nitermax_in, seeds_in
594 write(999, *)
'# settings :: anneal specific'
595 write(999, *)
'# sa_tmp'
597 write(999, *)
'# iter bestf (bestx(j),j=1,nopt)'
603 allocate (truepara(count(maskpara_in)))
606 if (maskpara_in(i))
then
607 idummy = idummy + 1_i4
612 if (printflag_in)
then
613 print*,
'Following parameters will be optimized: ', truepara
618 if (
present(weight))
then
619 where (maskpara_in(:))
620 weight_in(:) = weight(:)
621 weightuni(:) = 1.0_dp
624 where (maskpara_in(:))
625 weight_in(:) = 1.0_dp
626 weightuni(:) = 1.0_dp
630 weight_in = weight_in / sum(weight_in)
631 weightuni = weightuni / sum(weightuni)
634 weight_in(i) = weight_in(i) + weight_in(i - 1)
635 weightuni(i) = weightuni(i) + weightuni(i - 1)
638 call xor4096 (seeds_in(1), rn1, save_state = save_state_1)
639 call xor4096 (seeds_in(2), rn2, save_state = save_state_2)
640 call xor4096g(seeds_in(3), rn3, save_state = save_state_3)
644 gamma(:)%dmult = 1.0_dp
645 gamma(:)%new = para(:)
646 gamma(:)%old = para(:)
647 gamma(:)%best = para(:)
653 fo = cost(gamma(:)%old, eval) * maxit_in
654 if (abs(fo) .lt. tiny(0.0_dp)) fo = 0.0000001_dp * maxit_in
656 file_write :
if (
present(tmp_file))
then
657 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', position =
'append', recl = (n + 2) * 30)
658 if (.not. ldummy)
then
659 write(999, *)
'0', fo, gamma(:)%old
661 write(999, *)
'0', -fo, gamma(:)%old
671 itotalcounterr = 0_i4
679 normphi = fo * maxit_in
681 fbest = 1.0_dp * maxit_in
683 if (printflag_in)
then
684 print
'(A15,E15.7,A4,E15.7,A4)',
' start NSe = ', fbest * maxit_in,
' ( ', fbest * normphi * maxit_in,
' ) '
685 print
'(I8, 2I5, 4E15.7)', 1_i4, 0_i4, 0_i4, 1._dp, t_in, fo * normphi * maxit_in, fbest * normphi * maxit_in
692 looptest :
do while (istop)
700 looplen :
do while (j .le. len_in)
702 itotalcounterr = itotalcounterr + 1_i4
703 itotalcounter = itotalcounter + 1_i4
707 dr = (1.0_dp - real(itotalcounterr, dp) / real(nitermax_in, dp))**2.0_dp
708 if (.not. (
ge(dr, 0.05_dp)) .and. &
709 (itotalcounterr <= int(real(nitermax_in, dp) / 3._dp * 4_dp, i4)))
then
713 if (pertubflexflag_inin)
then
714 pertubationr = max(dr / 5.0_dp, 0.05_dp)
716 pertubationr = 0.2_dp
723 weightgrad(:) = weightuni(:) + (ac_ratio) * (weight_in(:) - weightuni(:))
725 select case(changeparamode_inin)
728 call xor4096(seeds_in(2), rn2, save_state = save_state_2)
731 do while (weightgrad(ipar) .lt. rn2)
734 if (
present(prange_func))
then
735 call prange_func(gamma(:)%old, ipar, iparrange)
737 iparrange(1) = prange(ipar, 1)
738 iparrange(2) = prange(ipar, 2)
740 gamma(ipar)%min = iparrange(1)
741 gamma(ipar)%max = iparrange(2)
742 if (reflectionflag_inin)
then
743 call xor4096g(seeds_in(3), rn3, save_state = save_state_3)
744 gamma(ipar)%new = pargen_dds_dp(gamma(ipar)%old, pertubationr, &
745 gamma(ipar)%min, gamma(ipar)%max, rn3)
747 call xor4096(seeds_in(2), rn2, save_state = save_state_2)
748 gamma(ipar)%new = pargen_anneal_dp(gamma(ipar)%old, dr, &
749 gamma(ipar)%min, gamma(ipar)%max, rn2)
752 do par = 1,
size(truepara)
754 if (
present(prange_func))
then
755 call prange_func(gamma(:)%old, ipar, iparrange)
757 iparrange(1) = prange(ipar, 1)
758 iparrange(2) = prange(ipar, 2)
760 gamma(ipar)%min = iparrange(1)
761 gamma(ipar)%max = iparrange(2)
762 if (reflectionflag_inin)
then
763 call xor4096g(seeds_in(3), rn3, save_state = save_state_3)
764 gamma(ipar)%new = pargen_dds_dp(gamma(ipar)%old, pertubationr, &
765 gamma(ipar)%min, gamma(ipar)%max, rn3)
767 call xor4096(seeds_in(2), rn2, save_state = save_state_2)
768 gamma(ipar)%new = pargen_anneal_dp(gamma(ipar)%old, dr, &
769 gamma(ipar)%min, gamma(ipar)%max, rn2)
774 call generate_neighborhood_weight_dp(truepara, weightgrad, save_state_1, &
775 itotalcounter, nitermax_in, neighborhood)
779 if (neighborhood(ipar))
then
781 if (
present(prange_func))
then
782 call prange_func(gamma(:)%old, ipar, iparrange)
784 iparrange(1) = prange(ipar, 1)
785 iparrange(2) = prange(ipar, 2)
787 gamma(ipar)%min = iparrange(1)
788 gamma(ipar)%max = iparrange(2)
790 if (reflectionflag_inin)
then
792 call xor4096g(seeds_in(3), rn3, save_state = save_state_3)
793 gamma(ipar)%new = pargen_dds_dp(gamma(ipar)%old, pertubationr, &
794 gamma(ipar)%min, gamma(ipar)%max, rn3)
797 call xor4096(seeds_in(2), rn2, save_state = save_state_2)
798 gamma(ipar)%new = pargen_anneal_dp(gamma(ipar)%old, dr, &
799 gamma(ipar)%min, gamma(ipar)%max, rn2)
806 fn = cost(gamma(:)%new, eval) * maxit_in
808 if (
present(undef_funcval))
then
809 if (abs(fn * maxit_in - undef_funcval) .lt. tiny(1.0_dp))
then
814 feasible :
if (coststatus)
then
821 if (df < 0.0_dp)
then
826 gamma(:)%old = gamma(:)%new
831 gamma(:)%best = gamma(:)%new
834 if (df > eps_in)
then
836 if (rho < small)
then
842 call xor4096(seeds_in(1), rn1, save_state = save_state_1)
849 gamma(:)%old = gamma(:)%new
856 itotalcounterr = itotalcounterr - 1_i4
857 itotalcounter = itotalcounter - 1_i4
862 ac_ratio = (real(ipos, dp) + real(ineg, dp)) / real(len_in, dp)
863 if (modulo(itotalcounter, len_in * nst_in) / len_in .gt. 0_i4)
then
864 idummy = modulo(itotalcounter, len_in * nst_in) / len_in
868 ipos_ineg_history(idummy, :) = (/ ipos, ineg /)
871 history_out(itotalcounter / len_in, 1) = real(itotalcounter, dp)
872 history_out(itotalcounter / len_in, 2) = maxit_in * fbest * normphi
874 file_write2 :
if (
present(tmp_file))
then
875 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', position =
'append', recl = (n + 2) * 30)
876 write(999, *) itotalcounter, maxit_in * fbest * normphi, gamma(:)%best
880 if (printflag_in)
then
881 print
'(I8, 2I5, E15.7, 3E15.7)', itotalcounter, ipos, ineg, ac_ratio, t_in, &
882 fo * normphi * maxit_in, fbest * normphi * maxit_in
886 if (fbb .gt. tiny(1.0_dp))
then
887 finc = (fbb - fbest) / fbb
891 if (finc < 0.00000001_dp)
then
897 if ((ac_ratio < 0.15_dp) .and. (iconf > 5_i4) .and. (iconr <= -3_i4))
then
899 if (printflag_in)
then
900 print *,
'Re-heating: ', iconr
905 itotalcounterr = 0_i4
907 gamma(:)%old = gamma(:)%best
910 if (ac_ratio < 0.4_dp)
then
919 if (finc < eps_in)
then
924 if ((iconl > nst_in) .and. (ac_ratio < acc_in) .and. (iconr > 2_i4) .and. &
925 (sum(ipos_ineg_history(:, :)) .lt. 1_i4))
then
929 if ((itotalcounter > nitermax_in) .and. &
930 (sum(ipos_ineg_history(:, :)) .ge. 1_i4))
then
933 allocate(history_out_tmp(
size(history_out, 1),
size(history_out, 2)))
934 history_out_tmp = history_out
935 deallocate(history_out)
937 nitermax_in = max(nitermax_in + len_in, int(real(nitermax_in, dp) * 1.10_dp, i4))
938 if (printflag_in)
then
939 print *,
'nITERmax changed to =', nitermax_in
943 idummy = nitermax_in / len_in + 1_i4
944 allocate(history_out(idummy, 2))
946 do j = 1,
size(history_out_tmp, 1)
947 history_out(j, :) = history_out_tmp(j, :)
950 deallocate(history_out_tmp)
954 if (itotalcounter > nitermax_in)
then
961 parabest = gamma(:)%best
962 costbest = cost(parabest, eval) * maxit_in
963 if (
present (funcbest))
then
964 funcbest = costbest * maxit_in
966 fo = costbest / normphi
968 if (printflag_in)
then
970 print
'(A15,E15.7)',
' end cost = ', maxit_in * fbest * normphi
971 print *,
'end parameter: '
973 print
'(A10,I3,A3, E15.7)',
' para #', kk,
' = ', gamma(kk)%best
976 print *,
'Final check: ', (fo - fbest)
979 if (
present(history))
then
980 allocate(history(
size(history_out, 1) - 1,
size(history_out, 2)))
981 history(:, :) = history_out(1 :
size(history_out, 1) - 1, :)
985 deallocate(history_out)
992 prange, prange_func, &
993 samplesize, maskpara, seeds, printflag, &
994 weight, maxit, undef_funcval &
1001 real(
dp),
dimension(:),
intent(in) :: paraset
1002 real(
dp),
intent(in) :: acc_goal
1003 real(
dp),
optional,
dimension(size(paraset, 1), 2),
intent(in) :: prange
1004 integer(i4),
optional,
intent(in) :: samplesize
1006 logical,
optional,
dimension(size(paraset, 1)),
intent(in) :: maskpara
1009 integer(i8),
optional,
dimension(2),
intent(in) :: seeds
1010 logical,
optional,
intent(in) :: printflag
1012 real(
dp),
OPTIONAL,
dimension(size(paraset, 1)),
INTENT(IN) :: weight
1015 logical,
OPTIONAL,
INTENT(IN) :: maxit
1018 real(
dp),
OPTIONAL,
INTENT(IN) :: undef_funcval
1023 SUBROUTINE prange_func(paraset, iPar, rangePar)
1026 real(
dp),
dimension(:),
INTENT(IN) :: paraset
1027 integer(i4),
INTENT(IN) :: ipar
1028 real(
dp),
dimension(2),
INTENT(OUT) :: rangepar
1029 END SUBROUTINE prange_func
1031 OPTIONAL :: prange_func
1036 integer(i4) :: samplesize_in
1037 integer(i4) :: idummy, i, j
1039 real(dp),
dimension(2) :: iparrange
1041 real(dp) :: fo, fn, dr
1044 logical :: coststatus
1045 logical,
dimension(size(paraset, 1)) :: maskpara_in
1046 integer(i4),
dimension(:),
ALLOCATABLE :: truepara
1047 logical :: printflag_in
1048 real(dp),
dimension(size(paraset, 1)) :: weight_in
1049 real(dp) :: maxit_in
1061 type (paramlim),
dimension (size(paraset, 1)),
target :: gamma
1064 INTEGER(I8) :: seeds_in(2)
1065 real(dp) :: rn1, rn2
1066 integer(I8),
dimension(n_save_state) :: save_state_1
1067 integer(I8),
dimension(n_save_state) :: save_state_2
1070 real(dp) :: acc_estim
1073 real(dp),
dimension(:, :),
allocatable :: energy
1076 n =
size(paraset, 1)
1079 if (
present(prange) .eqv.
present(prange_func))
then
1080 stop
'anneal: Either range or prange_func has to be given'
1083 if (
present(samplesize))
then
1084 if (samplesize .lt. max(20_i4 * n, 250_i4))
then
1086 print*,
'WARNING (GetTemperature): '
1087 print*,
'Input argument samplesize should be greater than Max(250,20*N), N=number of parameters'
1088 samplesize_in = samplesize
1090 samplesize_in = samplesize
1093 samplesize_in = max(20_i4 * n, 250_i4)
1096 if (
present(maskpara))
then
1097 if (count(maskpara) .eq. 0_i4)
then
1098 stop
'Input argument maskpara: At least one element has to be true'
1100 maskpara_in = maskpara
1103 maskpara_in = .true.
1106 if (
present(seeds))
then
1111 print*,
'temp: seeds(1)=', seeds_in(1)
1114 if (
present(printflag))
then
1115 printflag_in = printflag
1117 printflag_in = .false.
1120 if (
present(maxit))
then
1130 allocate(energy(samplesize_in, 2))
1132 allocate (truepara(count(maskpara_in)))
1135 if (maskpara_in(i))
then
1136 idummy = idummy + 1_i4
1137 truepara(idummy) = i
1142 if (
present(weight))
then
1143 where (maskpara_in(:))
1144 weight_in(:) = weight(:)
1147 where (maskpara_in(:))
1148 weight_in(:) = 1.0_dp
1152 weight_in = weight_in / sum(weight_in)
1155 weight_in(i) = weight_in(i) + weight_in(i - 1)
1161 call xor4096(seeds_in(1), rn1, save_state = save_state_1)
1162 call xor4096(seeds_in(2), rn2, save_state = save_state_2)
1166 gamma(:)%dmult = 1.0_dp
1167 gamma(:)%new = paraset(:)
1168 gamma(:)%old = paraset(:)
1169 gamma(:)%best = paraset(:)
1170 normphi = -9999.9_dp
1172 fo = cost(paraset, eval) * maxit_in
1173 if (abs(fo) .lt. tiny(0.0_dp)) fo = 0.0000001_dp * maxit_in
1175 fo = fo / normphi * maxit_in
1178 loopsamplesize :
do while (j .le. samplesize_in)
1184 call xor4096(seeds_in(1), rn1, save_state = save_state_1)
1186 do while (weight_in(ipar) .lt. rn1)
1191 if (
present(prange_func))
then
1192 call prange_func(gamma(:)%old, ipar, iparrange)
1194 iparrange(1) = prange(ipar, 1)
1195 iparrange(2) = prange(ipar, 2)
1197 gamma(ipar)%min = iparrange(1)
1198 gamma(ipar)%max = iparrange(2)
1199 call xor4096(seeds_in(2), rn2, save_state = save_state_2)
1200 gamma(ipar)%new = pargen_anneal_dp(gamma(ipar)%old, gamma(ipar)%dMult * dr, &
1201 gamma(ipar)%min, gamma(ipar)%max, rn2)
1204 fn = cost(gamma(:)%new, eval) * maxit_in
1206 if (
present(undef_funcval))
then
1207 if (abs(fn * maxit_in - undef_funcval) .lt. tiny(1.0_dp))
then
1208 coststatus = .false.
1212 feasible :
if (coststatus)
then
1222 end do loopsamplesize
1228 acc_estim = sum(exp(-(energy(:, 2) / t))) / sum(exp(-(energy(:, 1) / t)))
1229 if (printflag_in)
then
1230 print*,
"acc_estimate = ", acc_estim,
" ( T = ", t,
" )"
1232 Do While ((acc_estim .lt. 1.0_dp) .and. (abs(acc_estim - acc_goal) .gt. 0.0001_dp))
1233 t = t * (log(acc_estim) / log(acc_goal))**(0.5_dp)
1234 if (all(t .gt. energy(:, 1) / 709._dp) .and. all(t .gt. energy(:, 2) / 709._dp))
then
1235 acc_estim = sum(exp(-(energy(:, 2) / t))) / sum(exp(-(energy(:, 1) / t)))
1236 if (printflag_in)
then
1237 print*,
"acc_estimate = ", acc_estim,
" ( T = ", t,
" )"
1240 t = t / (log(acc_estim) / log(acc_goal))**(0.5_dp)
1252 real(dp) function pargen_anneal_dp(old, dmax, omin, omax, rn)
1256 real(
dp),
intent(IN) :: old, dmax, omin, omax
1257 real(
dp),
intent(IN) :: rn
1260 real(
dp) :: oi, ox, delta, dmaxscal
1261 integer(i4) :: idigit, iszero
1269 dmaxscal = dmax * abs(omax - omin)
1272 pargen_anneal_dp = (oi + ox) / 2.0_dp
1274 if ((old - dmaxscal) > oi) oi = old - dmaxscal
1275 if ((old + dmaxscal) < ox) ox = old + dmaxscal
1276 delta = (oi + rn * (ox - oi)) - old
1277 if (delta > dmaxscal) delta = dmaxscal
1278 if (delta <-dmaxscal) delta = -dmaxscal
1279 pargen_anneal_dp = old + dchange_dp(delta, idigit, iszero)
1285 if (pargen_anneal_dp < omin)
then
1286 pargen_anneal_dp = omin
1287 elseif(pargen_anneal_dp > omax)
then
1288 pargen_anneal_dp = omax
1290 end function pargen_anneal_dp
1292 real(
dp) function pargen_dds_dp(old, perturb, omin, omax, rn)
1300 real(
dp),
intent(IN) :: old, perturb, omin, omax
1301 real(
dp),
intent(IN) :: rn
1304 pargen_dds_dp = old + perturb * (omax - omin) * rn
1307 if (pargen_dds_dp .lt. omin)
then
1308 pargen_dds_dp = omin + (omin - pargen_dds_dp)
1309 if (pargen_dds_dp .gt. omax) pargen_dds_dp = omin
1312 if (pargen_dds_dp .gt. omax)
then
1313 pargen_dds_dp = omax - (pargen_dds_dp - omax)
1314 if (pargen_dds_dp .lt. omin) pargen_dds_dp = omax
1317 end function pargen_dds_dp
1319 real(
dp) function dchange_dp(delta, idigit, iszero)
1323 integer(i4),
intent(IN) :: idigit, iszero
1324 real(
dp),
intent(IN) :: delta
1327 integer(i4) :: ioszt
1328 integer(I8) :: idelta
1331 idelta = int(delta * real(ioszt,
dp),
i8)
1332 if(iszero == 1_i4)
then
1333 if(idelta == 0_i8)
then
1334 if(delta < 0_i4)
then
1341 dchange_dp = real(idelta,
dp) / real(ioszt,
dp)
1342 end function dchange_dp
1344 subroutine generate_neighborhood_weight_dp(truepara, cum_weight, save_state_xor, iTotalCounter, &
1345 nITERmax, neighborhood)
1350 integer(i4),
dimension(:),
intent(in) :: truepara
1351 real(
dp),
dimension(:),
intent(in) :: cum_weight
1352 integer(i8),
dimension(n_save_state),
intent(inout) :: save_state_xor
1353 integer(i4),
intent(in) :: itotalcounter
1354 integer(i4),
intent(in) :: nitermax
1355 logical,
dimension(size(cum_weight)),
intent(out) :: neighborhood
1358 integer(i4) :: ipar, npar
1359 integer(i4) :: isize, size_neighbor
1362 real(
dp) :: weight, norm
1363 real(
dp),
dimension(size(cum_weight)) :: local_cum_weight
1365 prob = 1.0_dp - log(real(itotalcounter,
dp)) / log(real(nitermax,
dp))
1366 neighborhood = .false.
1368 npar =
size(cum_weight)
1369 local_cum_weight = cum_weight
1372 size_neighbor = 0_i4
1373 do ipar = 1,
size(truepara)
1374 call xor4096(0_i8, rn, save_state = save_state_xor)
1376 size_neighbor = size_neighbor + 1_i4
1380 size_neighbor = max(1_i4, size_neighbor)
1383 do isize = 1, size_neighbor
1385 call xor4096(0_i8, rn, save_state = save_state_xor)
1389 do while (local_cum_weight(ipar) .lt. rn)
1394 neighborhood(ipar) = .true.
1398 if (ipar .gt. 1_i4)
then
1399 weight = local_cum_weight(ipar) - local_cum_weight(ipar - 1)
1401 weight = local_cum_weight(1)
1404 local_cum_weight(ipar : npar) = local_cum_weight(ipar : npar) - weight
1406 if (count(neighborhood) .lt.
size(truepara))
then
1407 norm = 1.0_dp / local_cum_weight(npar)
1411 local_cum_weight(:) = local_cum_weight(:) * norm
1415 end subroutine generate_neighborhood_weight_dp
Optimize cost function with simulated annealing.
Find initial temperature for simulated annealing.
Interface for evaluation routine.
Interface for objective function.
Comparison of real values: a >= b.
Comparison of real values: a <= b.
Generate seed for xor4096.
Uniform XOR4096-based RNG.
Gaussian XOR4096-based RNG.
Anneal optimization of cost function.
real(dp) function gettemperature_dp(eval, cost, paraset, acc_goal, prange, prange_func, samplesize, maskpara, seeds, printflag, weight, maxit, undef_funcval)
real(dp) function, dimension(size(para, 1)) anneal_dp(eval, cost, para, prange, prange_func, temp, dt, nitermax, len, nst, eps, acc, seeds, printflag, maskpara, weight, changeparamode, reflectionflag, pertubflexflag, maxit, undef_funcval, tmp_file, funcbest, history)
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.
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.