20#ifdef FORCES_WITH_NETCDF
204 MODULE PROCEDURE mcmc_dp
420 MODULE PROCEDURE mcmc_stddev_dp
433 SUBROUTINE mcmc_dp(eval, likelihood, para, rangePar, & ! obligatory IN
434 mcmc_paras, burnin_paras, & ! obligatory OUT
435 seed_in, printflag_in, maskpara_in, & ! optional IN
436 restart, restart_file, & ! optional IN: if mcmc is restarted and file which contains restart variables
437 tmp_file, & ! optional IN: filename for temporal output of
439 loglike_in, & ! optional IN: true if loglikelihood is given
440 ParaSelectMode_in, & ! optional IN: (=1) half, (=2) one, (=3) all
448 procedure(eval_interface),
INTENT(IN),
POINTER :: eval
449 procedure(objective_interface),
intent(in),
pointer :: likelihood
451 REAL(DP),
DIMENSION(:, :),
INTENT(IN) :: rangePar
452 REAL(DP),
DIMENSION(:),
INTENT(IN) :: para
453 INTEGER(I8),
OPTIONAL,
INTENT(IN) :: seed_in
455 LOGICAL,
OPTIONAL,
INTENT(IN) :: printflag_in
457 LOGICAL,
OPTIONAL,
DIMENSION(size(para, 1)), &
458 INTENT(IN) :: maskpara_in
461 logical,
OPTIONAL,
INTENT(in) :: restart
463 character(len = *),
OPTIONAL,
INTENT(in) :: restart_file
465 LOGICAL,
OPTIONAL,
INTENT(IN) :: loglike_in
467 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: ParaSelectMode_in
471 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: iter_burnin_in
473 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: iter_mcmc_in
475 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: chains_in
477 REAL(DP),
OPTIONAL,
DIMENSION(size(para, 1)), &
478 INTENT(IN) :: stepsize_in
480 CHARACTER(len = *),
OPTIONAL,
INTENT(IN) :: tmp_file
484 REAL(DP),
DIMENSION(:, :),
ALLOCATABLE,
INTENT(OUT) :: mcmc_paras
487 REAL(DP),
DIMENSION(:, :),
ALLOCATABLE,
INTENT(OUT) :: burnin_paras
494 LOGICAL,
DIMENSION(size(para, 1)) :: maskpara
495 LOGICAL,
DIMENSION(1000) :: dummy_maskpara
496 INTEGER(I4),
DIMENSION(:),
ALLOCATABLE :: truepara
498 LOGICAL :: skip_burnin
500 character(len = 1024) :: istmp_file
502 character(len = 1024) :: isrestart_file
505 INTEGER(I8),
dimension(:, :),
allocatable :: seeds
506 REAL(DP) :: RN1, RN2, RN3
507 integer(I8),
dimension(:, :),
allocatable :: save_state_1
508 integer(I8),
dimension(:, :),
allocatable :: save_state_2
509 integer(I8),
dimension(:, :),
allocatable :: save_state_3
513 REAL(DP),
DIMENSION(:, :, :),
ALLOCATABLE :: tmp
514 integer(I4) :: idummy
515 logical :: oddsSwitch1, oddsSwitch2
516 character(100) :: str
517 character(200) :: outputfile
518 integer(i4) :: slash_pos
519 integer(i4) :: len_filename
520 character(200) :: filename
521 character(200) :: path
524 REAL(DP),
DIMENSION(:, :, :),
ALLOCATABLE :: mcmc_paras_3d
527 integer(I4),
dimension(:),
allocatable :: Ipos, Ineg
529 INTEGER(I4) :: ParaSelectMode
530 INTEGER(I4) :: iter_burnin
531 INTEGER(I4) :: iter_mcmc
532 INTEGER(I4) :: chains
536 LOGICAL,
DIMENSION(size(para, 1)) :: ChangePara
538 REAL(DP),
DIMENSION(size(para, 1)) :: stepsize
539 REAL(DP),
DIMENSION(1000) :: dummy_stepsize
540 REAL(DP),
DIMENSION(size(para, 1)) :: paraold
541 REAL(DP),
DIMENSION(size(para, 1)) :: paranew
542 REAL(DP),
DIMENSION(size(para, 1)) :: parabest
543 REAL(DP),
DIMENSION(1000) :: dummy_parabest
544 REAL(DP),
DIMENSION(size(para, 1)) :: initial_paraset_mcmc
545 REAL(DP),
DIMENSION(1000) :: dummy_initial_paraset_mcmc
546 REAL(DP) :: likeliold
547 REAL(DP) :: likelinew
548 REAL(DP) :: likelibest
549 INTEGER(I4) :: markov
550 REAL(DP),
DIMENSION(:, :),
ALLOCATABLE :: burnin_paras_part
551 REAL(DP) :: oddsRatio
552 REAL(DP),
dimension(:),
allocatable :: accRatio
553 REAL(DP) :: accratio_stddev
554 REAL(DP),
DIMENSION(:),
ALLOCATABLE :: history_accratio
555 INTEGER(I4) :: accratio_n
558 real(dp),
allocatable,
dimension(:) :: sqrtR
559 real(dp),
allocatable,
dimension(:) :: vDotJ
560 real(dp),
allocatable,
dimension(:) :: s2
564 integer(i4) :: n_start, n_end, iPar
568 integer(i4) :: n_threads
570 namelist /restartnml1/ &
571 n, printflag, dummy_maskpara, loglike, skip_burnin, &
572 istop, paraselectmode, iter_burnin, &
573 iter_mcmc, chains, accmult, rejmult, trial, dummy_stepsize, &
574 dummy_parabest, likelibest, dummy_initial_paraset_mcmc, &
576 accratio_n, vdotdot, b, w, converged, &
578 itmp_file, istmp_file
580 namelist /restartnml2/ &
581 truepara, seeds, save_state_1, save_state_2, save_state_3, &
582 ipos, ineg, mcmc_paras_3d, &
588 if (
present(restart))
then
594 if (
present(restart_file))
then
595 isrestart_file = restart_file
597 isrestart_file =
'mo_mcmc.restart'
600 if (.not. irestart)
then
602 if (
present(tmp_file))
then
604 istmp_file = tmp_file
610 if (
present(loglike_in))
then
616 if (
present(maskpara_in))
then
617 if (count(maskpara_in) .eq. 0_i4)
then
618 stop
'Input argument maskpara: At least one element has to be true'
620 maskpara = maskpara_in
626 allocate (truepara(count(maskpara)))
628 do i = 1,
size(para, 1)
629 if (maskpara(i))
then
630 idummy = idummy + 1_i4
635 n =
size(truepara, 1)
637 if (
present(paraselectmode_in))
then
638 paraselectmode = paraselectmode_in
641 paraselectmode = 2_i4
645 if (
present(iter_burnin_in))
then
646 if (iter_burnin_in .le. 0_i4)
then
647 stop
'Input argument iter_burn_in must be greater than 0!'
649 iter_burnin = iter_burnin_in
652 iter_burnin = max(250_i4, 1000_i4 * n)
657 if (
present(iter_mcmc_in))
then
658 if (iter_mcmc_in .le. 0_i4)
then
659 stop
'Input argument iter_mcmc must be greater than 0!'
661 iter_mcmc = iter_mcmc_in
664 iter_mcmc = 1000_i4 * n
667 if (
present(chains_in))
then
668 if (chains_in .lt. 2_i4)
then
669 stop
'Input argument chains must be at least 2!'
676 if (
present(stepsize_in))
then
677 stepsize = stepsize_in
680 skip_burnin = .false.
683 if (
present(printflag_in))
then
684 printflag = printflag_in
699 write(*, *)
'Following parameters will be sampled with MCMC: ', truepara
702 allocate(seeds(chains, 3))
706 allocate(ipos(chains), ineg(chains), accratio(chains))
707 allocate(vdotj(chains), s2(chains))
708 allocate(sqrtr(
size(para)))
712 accratio = -9999.0_dp
717 if (
present(seed_in))
then
718 seeds(1, :) = (/ seed_in, seed_in + 1000_i8, seed_in + 2000_i8 /)
724 seeds(chain, :) = seeds(chain - 1_i4, :) + 3000_i8
728 call xor4096(seeds(chain, 1), rn1, save_state = save_state_1(chain, :))
729 call xor4096(seeds(chain, 2), rn2, save_state = save_state_2(chain, :))
730 call xor4096g(seeds(chain, 3), rn3, save_state = save_state_3(chain, :))
737 likelibest = likelihood(parabest, eval)
743 if (.not. skip_burnin)
then
747 write(*, *)
'--------------------------------------------------'
748 write(*, *)
'Starting Burn-In (iter_burnin = ', iter_burnin,
')'
749 write(*, *)
'--------------------------------------------------'
756 allocate(burnin_paras_part(iter_burnin,
size(para)))
758 if (
allocated(burnin_paras))
deallocate(burnin_paras)
759 if (
allocated(history_accratio))
deallocate(history_accratio)
770 write(*, *)
'Start Burn-In with: '
771 write(*, *)
' parabest = ', parabest
772 write(*, *)
' likelihood = ', likelibest
779 convergedburnin :
do while (.not. istop)
784 likeliold = likelibest
789 markovchain :
do markov = 1, iter_burnin
795 call generatenewparameterset_dp(paraselectmode, paraold, truepara, rangepar, stepsize, &
796 save_state_2(1, :), &
797 save_state_3(1, :), &
801 likelinew = likelihood(paranew, eval)
803 oddsswitch1 = .false.
805 oddsratio = likelinew - likeliold
806 if (oddsratio .gt. 0.0_dp) oddsswitch1 = .true.
808 oddsratio = likelinew / likeliold
809 if (oddsratio .gt. 1.0_dp) oddsswitch1 = .true.
813 If (oddsswitch1)
then
816 ipos(1) = ipos(1) + 1_i4
818 likeliold = likelinew
820 stepsize = stepsize * accmult
822 if (likelinew .gt. likelibest)
then
824 likeliold = likelinew
825 likelibest = likelinew
828 write(*, *)
'best para changed: ', paranew
829 write(*, *)
'likelihood new: ', likelinew
832 burnin_paras_part(ipos(1) + ineg(1), :) = paranew(:)
836 call xor4096(seeds(1, 1), rn1, save_state = save_state_1(1, :))
837 oddsswitch2 = .false.
839 if (oddsratio .lt. -700.0_dp) oddsratio = -700.0_dp
840 if (rn1 .lt. exp(oddsratio)) oddsswitch2 = .true.
842 if (rn1 .lt. oddsratio) oddsswitch2 = .true.
845 If (oddsswitch2)
then
848 ineg(1) = ineg(1) + 1_i4
850 likeliold = likelinew
852 stepsize = stepsize * accmult
854 burnin_paras_part(ipos(1) + ineg(1), :) = paranew(:)
860 stepsize = stepsize * rejmult
869 accratio(1) = real(ipos(1) + ineg(1), dp) / real(iter_burnin, dp)
871 write(str,
'(A,I03,A)')
'(A7,I4,A15,F5.3,A17,',
size(para, 1),
'(E9.2,1X),A1)'
872 write(*, str)
'trial #', trial,
' acc_ratio = ', accratio(1),
' (stepsize = ', stepsize,
')'
875 if (ipos(1) + ineg(1) .gt. 0_i4)
then
876 call append(burnin_paras, burnin_paras_part(1 : ipos(1) + ineg(1), :))
880 if (accratio(1) .lt. 0.234_dp) accmult = accmult * 0.99_dp
881 if (accratio(1) .gt. 0.441_dp) accmult = accmult * 1.01_dp
884 if (accratio(1) .lt. 0.234_dp .or. accratio(1) .gt. 0.441_dp)
then
885 if(
allocated(history_accratio))
deallocate(history_accratio)
887 call append(history_accratio, accratio(1))
891 if (
allocated(history_accratio))
then
892 accratio_n =
size(history_accratio, 1)
893 if (accratio_n .ge. 10_i4)
then
894 idummy = accratio_n - 9_i4
895 accratio_stddev =
stddev(history_accratio(idummy : accratio_n))
898 if ((accratio_stddev .lt. sqrt(1._dp / 12._dp * 0.05_dp**2)))
then
902 write(*, *)
'STOP BURN-IN with accaptence ratio of ', history_accratio(accratio_n)
903 write(*, *)
'final stepsize: ', stepsize
904 write(*, *)
'best parameter set found: ', parabest
905 write(*, *)
'with likelihood: ', likelibest
914 end do convergedburnin
926 allocate(mcmc_paras_3d(iter_mcmc,
size(para), chains))
927 mcmc_paras_3d = -9999.0_dp
936 initial_paraset_mcmc = parabest
945 dummy_maskpara = .false.
946 dummy_maskpara(1 :
size(para, 1)) = maskpara
947 dummy_stepsize = -9999.0_dp
948 dummy_stepsize(1 :
size(para, 1)) = stepsize
949 dummy_parabest = -9999.0_dp
950 dummy_parabest(1 :
size(para, 1)) = parabest
951 dummy_initial_paraset_mcmc = -9999.0_dp
952 dummy_initial_paraset_mcmc(1 :
size(para, 1)) = initial_paraset_mcmc
955 open(999, file = isrestart_file, status =
'unknown', action =
'write', delim =
'QUOTE')
956 write(999, restartnml1)
957 write(999, restartnml2)
963 open(999, file = isrestart_file, status =
'old', action =
'read', delim =
'QUOTE')
964 read(999, nml = restartnml1)
968 maskpara = dummy_maskpara(1 :
size(para, 1))
969 stepsize = dummy_stepsize(1 :
size(para, 1))
970 parabest = dummy_parabest(1 :
size(para, 1))
971 initial_paraset_mcmc = dummy_initial_paraset_mcmc(1 :
size(para, 1))
974 allocate(truepara(count(maskpara)))
975 allocate(seeds(chains, 3))
979 allocate(ipos(chains), ineg(chains), accratio(chains))
980 allocate(vdotj(chains), s2(chains))
981 allocate(sqrtr(
size(para)))
982 if (.not. converged)
then
983 if (
present(iter_mcmc_in))
then
984 allocate(mcmc_paras_3d(iter_mcmc - iter_mcmc_in,
size(para), chains))
986 allocate(mcmc_paras_3d(iter_mcmc - 1000_i4 * n,
size(para), chains))
989 allocate(mcmc_paras_3d(iter_mcmc,
size(para), chains))
1000 write(*, *)
'--------------------------------------------------'
1001 write(*, *)
'Starting MCMC (chains = ', chains,
', iter_mcmc = ', iter_mcmc,
')'
1002 write(*, *)
'--------------------------------------------------'
1006 convergedmcmc :
do while (.not. converged)
1008 open(999, file = isrestart_file, status =
'unknown', action =
'read', delim =
'QUOTE')
1009 read(999, restartnml1)
1010 read(999, restartnml2)
1014 maskpara = dummy_maskpara(1 :
size(para, 1))
1015 stepsize = dummy_stepsize(1 :
size(para, 1))
1016 parabest = dummy_parabest(1 :
size(para, 1))
1017 initial_paraset_mcmc = dummy_initial_paraset_mcmc(1 :
size(para, 1))
1022 idummy = minval(ipos + ineg)
1023 if ((iter_mcmc - idummy) > 0)
then
1024 allocate(tmp(idummy,
size(para), chains))
1025 tmp(:, :, :) = mcmc_paras_3d(1 : idummy, :, :)
1026 deallocate(mcmc_paras_3d)
1027 allocate(mcmc_paras_3d(iter_mcmc,
size(para), chains))
1028 mcmc_paras_3d(1 : idummy, :, :) = tmp(:, :, :)
1035 parallelchain :
do chain = 1, chains
1037 if (ipos(chain) + ineg(chain) .eq. 0_i4)
then
1038 paraold = initial_paraset_mcmc
1040 paraold = mcmc_paras_3d(ipos(chain) + ineg(chain), :, chain)
1042 likeliold = likelihood(paraold, eval)
1044 markovchainmcmc :
do
1047 changepara = .false.
1050 call generatenewparameterset_dp(paraselectmode, paraold, truepara, rangepar, stepsize, &
1051 save_state_2(chain, :), &
1052 save_state_3(chain, :), &
1053 paranew, changepara)
1056 likelinew = likelihood(paranew, eval)
1057 oddsswitch1 = .false.
1059 oddsratio = likelinew - likeliold
1060 if (oddsratio .gt. 0.0_dp) oddsswitch1 = .true.
1062 oddsratio = likelinew / likeliold
1063 if (oddsratio .gt. 1.0_dp) oddsswitch1 = .true.
1067 If (oddsswitch1)
then
1070 ipos(chain) = ipos(chain) + 1_i4
1072 likeliold = likelinew
1073 mcmc_paras_3d(ipos(chain) + ineg(chain), :, chain) = paranew(:)
1076 if ((ipos(chain) + ineg(chain) .gt. 0_i4) .and. &
1077 (mod(ipos(chain) + ineg(chain), 10000_i4)) .eq. 0)
then
1078 write(*, *)
'Chain ', chain,
': Done ', ipos(chain) + ineg(chain),
' samples ...'
1099 call xor4096(seeds(chain, 1), rn1, save_state = save_state_1(chain, :))
1100 oddsswitch2 = .false.
1102 if (rn1 .lt. exp(oddsratio)) oddsswitch2 = .true.
1104 if (rn1 .lt. oddsratio) oddsswitch2 = .true.
1107 If (oddsswitch2)
then
1110 ineg(chain) = ineg(chain) + 1_i4
1112 likeliold = likelinew
1113 mcmc_paras_3d(ipos(chain) + ineg(chain), :, chain) = paranew(:)
1116 if ((ipos(chain) + ineg(chain) .gt. 0_i4) .and. &
1117 (mod(ipos(chain) + ineg(chain), 10000_i4)) .eq. 0)
then
1118 write(*, *)
'Chain ', chain,
': Done ', ipos(chain) + ineg(chain),
' samples ...'
1127 if ((ipos(chain) + ineg(chain) .gt. 0_i4) .and. &
1128 (mod(ipos(chain) + ineg(chain), iter_mcmc) .eq. 0_i4))
exit
1130 end do markovchainmcmc
1132 end do parallelchain
1136#ifdef FORCES_WITH_NETCDF
1140 slash_pos = index(istmp_file,
'/', .true.)
1141 len_filename = len_trim(istmp_file)
1142 path = istmp_file(1 : slash_pos)
1143 filename = istmp_file(slash_pos + 1 : len_filename)
1145 do chain = 1, chains
1147 write(outputfile, *) trim(adjustl(path)), trim(adjustl(str)),
'_', trim(adjustl(filename))
1148 if (
present(iter_mcmc_in))
then
1149 allocate(tmp(iter_mcmc_in,
size(para, 1), 1))
1150 tmp(:, :, 1) = mcmc_paras_3d(iter_mcmc - iter_mcmc_in + 1_i4 : iter_mcmc, :, chain)
1151 if (iter_mcmc .ne. iter_mcmc_in)
then
1160 allocate(tmp(1000_i4 * n,
size(para, 1), 1))
1161 tmp(:, :, 1) = mcmc_paras_3d(iter_mcmc - (1000_i4 * n) + 1_i4 : iter_mcmc, :, chain)
1162 if (iter_mcmc .ne. 1000_i4 * n)
then
1175 call error_message(
"MCMC: FORCES was compiled without NetCDF support but you set 'tmp_file'")
1186 write(*, *)
'Checking for convergence ....'
1189 n_end = minval(ipos + ineg)
1190 n_start = n_end / 2_i4 + 1_i4
1192 do ipar = 1,
size(truepara)
1195 do chain = 1, chains
1196 vdotj(chain) = 1.0_dp / real(n_end - n_start + 1_i4, dp) * &
1197 sum(mcmc_paras_3d(n_start : n_end, truepara(ipar), chain))
1199 vdotdot = 1.0_dp / real(chains, dp) * sum(vdotj)
1200 b = real(n_end - n_start + 1_i4, dp) / real(chains - 1_i4, dp) * &
1201 sum((vdotj - vdotdot) * (vdotj - vdotdot))
1204 do chain = 1, chains
1205 s2(chain) = 1.0_dp / real(n_end - n_start, dp) * &
1206 sum((mcmc_paras_3d(n_start : n_end, truepara(ipar), chain) - vdotj(chain))**2)
1208 w = 1.0_dp / real(chains, dp) * sum(s2)
1211 if ((w .lt. tiny(1.0_dp)) .and. (b .lt. tiny(1.0_dp)))
then
1213 sqrtr(truepara(ipar)) = sqrt(real(n_end - n_start, dp) / real(n_end - n_start + 1_i4, dp))
1215 sqrtr(truepara(ipar)) = real(n_end - n_start, dp) / real(n_end - n_start + 1_i4, dp) * w + &
1216 1.0_dp / real(n_end - n_start + 1_i4, dp) * b
1217 sqrtr(truepara(ipar)) = sqrt(sqrtr(truepara(ipar)) / w)
1221 do i = 1,
size(para)
1222 if (sqrtr(i) .gt. 1.1_dp)
then
1223 write(*, *)
' sqrtR para #', i,
' : ', sqrtr(i),
' <-- FAILED'
1225 write(*, *)
' sqrtR para #', i,
' : ', sqrtr(i)
1229 if (all(sqrtr .lt. 1.1_dp))
then
1232 write(*, *)
' --> converged (all less than 1.1)'
1237 if (
present(iter_mcmc_in))
then
1238 iter_mcmc = iter_mcmc + iter_mcmc_in
1240 iter_mcmc = iter_mcmc + 1000_i4 * n
1244 write(*, *)
' --> not converged (not all less than 1.1)'
1245 write(*, *)
' increasing iterations to ', iter_mcmc
1251 dummy_maskpara = .false.
1252 dummy_maskpara(1 :
size(para, 1)) = maskpara
1253 dummy_stepsize = -9999.0_dp
1254 dummy_stepsize(1 :
size(para, 1)) = stepsize
1255 dummy_parabest = -9999.0_dp
1256 dummy_parabest(1 :
size(para, 1)) = parabest
1257 dummy_initial_paraset_mcmc = -9999.0_dp
1258 dummy_initial_paraset_mcmc(1 :
size(para, 1)) = initial_paraset_mcmc
1261 open(999, file = isrestart_file, status =
'unknown', action =
'write', delim =
'QUOTE')
1262 write(999, restartnml1)
1263 write(999, restartnml2)
1266 end do convergedmcmc
1269 open(999, file = isrestart_file, status =
'unknown', action =
'read', delim =
'QUOTE')
1270 read(999, restartnml1)
1271 read(999, restartnml2)
1275 maskpara = dummy_maskpara(1 :
size(para, 1))
1276 stepsize = dummy_stepsize(1 :
size(para, 1))
1277 parabest = dummy_parabest(1 :
size(para, 1))
1278 initial_paraset_mcmc = dummy_initial_paraset_mcmc(1 :
size(para, 1))
1281 allocate(mcmc_paras(
size(mcmc_paras_3d, 1) *
size(mcmc_paras_3d, 3),
size(mcmc_paras_3d, 2)))
1282 do chain = 1, chains
1283 mcmc_paras((chain - 1_i4) *
size(mcmc_paras_3d, 1) + 1_i4 : chain *
size(mcmc_paras_3d, 1), :) = mcmc_paras_3d(:, :, chain)
1287 END SUBROUTINE mcmc_dp
1289 SUBROUTINE mcmc_stddev_dp(eval, likelihood, para, rangePar, & ! obligatory IN
1290 mcmc_paras, burnin_paras, & ! obligatory OUT
1291 seed_in, printflag_in, maskpara_in, & ! optional IN
1292 tmp_file, & ! optional IN : filename for temporal output of
1294 loglike_in, & ! optional IN : true if loglikelihood is given
1295 ParaSelectMode_in, & ! optional IN : (=1) half, (=2) one, (=3) all
1303 procedure(eval_interface),
INTENT(IN),
POINTER :: eval
1304 procedure(objective_interface),
intent(in),
pointer :: likelihood
1306 REAL(DP),
DIMENSION(:, :),
INTENT(IN) :: rangePar
1307 REAL(DP),
DIMENSION(:),
INTENT(IN) :: para
1308 INTEGER(I8),
OPTIONAL,
INTENT(IN) :: seed_in
1310 LOGICAL,
OPTIONAL,
INTENT(IN) :: printflag_in
1312 LOGICAL,
OPTIONAL,
DIMENSION(size(para, 1)), &
1313 INTENT(IN) :: maskpara_in
1316 LOGICAL,
OPTIONAL,
INTENT(IN) :: loglike_in
1318 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: ParaSelectMode_in
1322 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: iter_burnin_in
1324 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: iter_mcmc_in
1326 INTEGER(I4),
OPTIONAL,
INTENT(IN) :: chains_in
1328 REAL(DP),
OPTIONAL,
DIMENSION(size(para, 1)), &
1329 INTENT(IN) :: stepsize_in
1331 CHARACTER(len = *),
OPTIONAL,
INTENT(IN) :: tmp_file
1335 REAL(DP),
DIMENSION(:, :),
ALLOCATABLE,
INTENT(OUT) :: mcmc_paras
1338 REAL(DP),
DIMENSION(:, :),
ALLOCATABLE,
INTENT(OUT) :: burnin_paras
1344 LOGICAL :: printflag
1345 LOGICAL,
DIMENSION(size(para, 1)) :: maskpara
1346 INTEGER(I4),
DIMENSION(:),
ALLOCATABLE :: truepara
1350 INTEGER(I8),
dimension(:, :),
allocatable :: seeds
1351 REAL(DP) :: RN1, RN2, RN3
1352 integer(I8),
dimension(:, :),
allocatable :: save_state_1
1353 integer(I8),
dimension(:, :),
allocatable :: save_state_2
1354 integer(I8),
dimension(:, :),
allocatable :: save_state_3
1358 REAL(DP),
DIMENSION(:, :, :),
ALLOCATABLE :: tmp
1359 integer(I4) :: idummy
1360 logical :: oddsSwitch1, oddsSwitch2
1361 character(100) :: str
1362 character(200) :: outputfile
1363 integer(i4) :: slash_pos
1364 integer(i4) :: len_filename
1365 character(200) :: filename
1366 character(200) :: path
1369 REAL(DP),
DIMENSION(:, :, :),
ALLOCATABLE :: mcmc_paras_3d
1372 integer(I4),
dimension(:),
allocatable :: Ipos, Ineg
1374 INTEGER(I4) :: ParaSelectMode
1375 INTEGER(I4) :: iter_burnin
1376 INTEGER(I4) :: iter_mcmc
1377 INTEGER(I4) :: chains
1378 INTEGER(I4) :: chain
1381 LOGICAL,
DIMENSION(size(para, 1)) :: ChangePara
1382 INTEGER(I4) :: trial
1383 REAL(DP),
DIMENSION(size(para, 1)) :: stepsize
1384 REAL(DP),
DIMENSION(size(para, 1)) :: paraold
1385 REAL(DP),
DIMENSION(size(para, 1)) :: paranew
1386 REAL(DP),
DIMENSION(size(para, 1)) :: parabest
1387 REAL(DP),
DIMENSION(size(para, 1)) :: initial_paraset_mcmc
1388 REAL(DP) :: stddev_data
1389 LOGICAL :: parabestChanged
1390 REAL(DP) :: likeliold
1391 REAL(DP) :: likelinew
1392 REAL(DP) :: likelibest
1393 REAL(DP) :: stddev_new
1394 REAL(DP) :: likeli_new
1395 INTEGER(I4) :: markov
1396 REAL(DP),
DIMENSION(:, :),
ALLOCATABLE :: burnin_paras_part
1397 REAL(DP) :: oddsRatio
1398 REAL(DP),
dimension(:),
allocatable :: accRatio
1399 REAL(DP) :: accratio_stddev
1400 REAL(DP),
DIMENSION(:),
ALLOCATABLE :: history_accratio
1401 INTEGER(I4) :: accratio_n
1405 real(dp),
allocatable,
dimension(:) :: sqrtR
1406 real(dp),
allocatable,
dimension(:) :: vDotJ
1407 real(dp),
allocatable,
dimension(:) :: s2
1411 integer(i4) :: n_start, n_end, iPar
1412 LOGICAL :: converged
1419 if (
present(loglike_in))
then
1420 loglike = loglike_in
1425 if (
present(maskpara_in))
then
1426 if (count(maskpara_in) .eq. 0_i4)
then
1427 stop
'Input argument maskpara: At least one element has to be true'
1429 maskpara = maskpara_in
1435 allocate (truepara(count(maskpara)))
1437 do i = 1,
size(para, 1)
1438 if (maskpara(i))
then
1439 idummy = idummy + 1_i4
1440 truepara(idummy) = i
1444 n =
size(truepara, 1)
1446 if (
present(paraselectmode_in))
then
1447 paraselectmode = paraselectmode_in
1450 paraselectmode = 2_i4
1454 if (
present(iter_burnin_in))
then
1455 if (iter_burnin_in .le. 0_i4)
then
1456 stop
'Input argument iter_burn_in must be greater than 0!'
1458 iter_burnin = iter_burnin_in
1461 iter_burnin = max(250_i4, 1000_i4 * n)
1466 if (
present(iter_mcmc_in))
then
1467 if (iter_mcmc_in .le. 0_i4)
then
1468 stop
'Input argument iter_mcmc must be greater than 0!'
1470 iter_mcmc = iter_mcmc_in
1473 iter_mcmc = 1000_i4 * n
1476 if (
present(chains_in))
then
1477 if (chains_in .lt. 2_i4)
then
1478 stop
'Input argument chains must be at least 2!'
1485 if (
present(stepsize_in))
then
1486 stepsize = stepsize_in
1489 if (
present(printflag_in))
then
1490 printflag = printflag_in
1504 write(*, *)
'Following parameters will be sampled with MCMC: ', truepara
1507 allocate(seeds(chains, 3))
1511 allocate(ipos(chains), ineg(chains), accratio(chains))
1512 allocate(vdotj(chains), s2(chains))
1513 allocate(sqrtr(
size(para)))
1515 if (
present(seed_in))
then
1516 seeds(1, :) = (/ seed_in, seed_in + 1000_i8, seed_in + 2000_i8 /)
1521 do chain = 2, chains
1522 seeds(chain, :) = seeds(chain - 1_i4, :) + 3000_i8
1525 do chain = 1, chains
1526 call xor4096(seeds(chain, 1), rn1, save_state = save_state_1(chain, :))
1527 call xor4096(seeds(chain, 2), rn2, save_state = save_state_2(chain, :))
1528 call xor4096g(seeds(chain, 3), rn3, save_state = save_state_3(chain, :))
1536 likelibest = likelihood(parabest, eval, 1.0_dp, stddev_new, likeli_new)
1537 likelibest = likeli_new
1538 stddev_data = stddev_new
1544 if (.not.
present(stepsize_in))
then
1547 write(*, *)
'--------------------------------------------------'
1548 write(*, *)
'Starting Burn-In (iter_burnin = ', iter_burnin,
')'
1549 write(*, *)
'--------------------------------------------------'
1556 allocate(burnin_paras_part(iter_burnin,
size(para)))
1558 parabestchanged = .true.
1563 betterparafound :
do while (parabestchanged)
1565 if (
allocated(burnin_paras))
deallocate(burnin_paras)
1566 if (
allocated(history_accratio))
deallocate(history_accratio)
1568 parabestchanged = .false.
1581 write(*, *)
'Restart Burn-In with new approximation of std.dev. of data: '
1582 write(*, *)
' parabest = ', parabest
1583 write(*, *)
' stddev = ', stddev_data
1584 write(*, *)
' likelihood = ', likelibest
1585 write(*, *)
' ssq = ', -2.0_dp * stddev_data**2 * likelibest
1593 convergedburnin :
do while ((.not. istop) .and. (.not. parabestchanged))
1598 likeliold = likelibest
1603 markovchain :
do markov = 1, iter_burnin
1606 changepara = .false.
1609 call generatenewparameterset_dp(paraselectmode, paraold, truepara, rangepar, stepsize, &
1610 save_state_2(1, :), &
1611 save_state_3(1, :), &
1612 paranew, changepara)
1615 likelinew = likelihood(paranew, eval, stddev_data, stddev_new, likeli_new)
1617 oddsswitch1 = .false.
1619 oddsratio = likelinew - likeliold
1620 if (oddsratio .gt. 0.0_dp) oddsswitch1 = .true.
1622 oddsratio = likelinew / likeliold
1623 if (oddsratio .gt. 1.0_dp) oddsswitch1 = .true.
1628 If (oddsswitch1)
then
1631 ipos(1) = ipos(1) + 1_i4
1633 likeliold = likelinew
1635 stepsize = stepsize * accmult
1637 if (likelinew .gt. likelibest)
then
1639 likeliold = likeli_new
1641 likelibest = likeli_new
1642 stddev_data = stddev_new
1644 parabestchanged = .true.
1646 write(*, *)
'best para changed: ', paranew
1647 write(*, *)
'likelihood new: ', likelinew
1650 burnin_paras_part(ipos(1) + ineg(1), :) = paranew(:)
1655 call xor4096(seeds(1, 1), rn1, save_state = save_state_1(1, :))
1656 oddsswitch2 = .false.
1658 if (oddsratio .lt. -700.0_dp) oddsratio = -700.0_dp
1659 if (rn1 .lt. exp(oddsratio)) oddsswitch2 = .true.
1661 if (rn1 .lt. oddsratio) oddsswitch2 = .true.
1664 If (oddsswitch2)
then
1667 ineg(1) = ineg(1) + 1_i4
1669 likeliold = likelinew
1672 stepsize = stepsize * accmult
1674 burnin_paras_part(ipos(1) + ineg(1), :) = paranew(:)
1681 stepsize = stepsize * rejmult
1693 accratio(1) = real(ipos(1) + ineg(1), dp) / real(iter_burnin, dp)
1695 write(str,
'(A,I03,A)')
'(A7,I4,A15,F5.3,A17,',
size(para, 1),
'(E9.2,1X),A1)'
1696 write(*, str)
'trial #', trial,
' acc_ratio = ', accratio(1),
' (stepsize = ', stepsize,
')'
1699 if (ipos(1) + ineg(1) .gt. 0_i4)
then
1700 call append(burnin_paras, burnin_paras_part(1 : ipos(1) + ineg(1), :))
1704 if (accratio(1) .lt. 0.234_dp) accmult = accmult * 0.99_dp
1705 if (accratio(1) .gt. 0.441_dp) accmult = accmult * 1.01_dp
1708 if (accratio(1) .lt. 0.234_dp .or. accratio(1) .gt. 0.441_dp)
then
1709 if(
allocated(history_accratio))
deallocate(history_accratio)
1711 call append(history_accratio, accratio(1))
1715 if (
allocated(history_accratio))
then
1716 accratio_n =
size(history_accratio, 1)
1717 if (accratio_n .ge. 10_i4)
then
1718 idummy = accratio_n - 9_i4
1719 accratio_stddev =
stddev(history_accratio(idummy : accratio_n))
1722 if ((accratio_stddev .lt. sqrt(1._dp / 12._dp * 0.05_dp**2)))
then
1726 write(*, *)
'STOP BURN-IN with accaptence ratio of ', history_accratio(accratio_n)
1727 write(*, *)
'final stepsize: ', stepsize
1728 if (parabestchanged)
then
1729 write(*, *)
'better parameter set was found: ', parabest
1730 write(*, *)
'with likelihood: ', likelibest
1738 trial = trial + 1_i4
1740 end do convergedburnin
1742 end do betterparafound
1753 initial_paraset_mcmc = parabest
1757 write(*, *)
'--------------------------------------------------'
1758 write(*, *)
'Starting MCMC (chains = ', chains,
', iter_mcmc = ', iter_mcmc,
')'
1759 write(*, *)
'--------------------------------------------------'
1768 convergedmcmc :
do while (.not. converged)
1770 if (.not.
allocated(mcmc_paras_3d))
then
1773 allocate(mcmc_paras_3d(iter_mcmc,
size(para), chains))
1776 idummy = minval(ipos + ineg)
1779 allocate(tmp(idummy,
size(para), chains))
1780 tmp(:, :, :) = mcmc_paras_3d(1 : idummy, :, :)
1781 deallocate(mcmc_paras_3d)
1782 allocate(mcmc_paras_3d(iter_mcmc,
size(para), chains))
1783 mcmc_paras_3d(1 : idummy, :, :) = tmp(:, :, :)
1790 parallelchain :
do chain = 1, chains
1792 if (ipos(chain) + ineg(chain) .eq. 0_i4)
then
1793 paraold = initial_paraset_mcmc
1795 paraold = mcmc_paras_3d(ipos(chain) + ineg(chain), :, chain)
1797 likeliold = likelihood(paraold, eval, stddev_data)
1799 markovchainmcmc :
do
1802 changepara = .false.
1805 call generatenewparameterset_dp(paraselectmode, paraold, truepara, rangepar, stepsize, &
1806 save_state_2(chain, :), &
1807 save_state_3(chain, :), &
1808 paranew, changepara)
1811 likelinew = likelihood(paranew, eval, stddev_data)
1812 oddsswitch1 = .false.
1814 oddsratio = likelinew - likeliold
1815 if (oddsratio .gt. 0.0_dp) oddsswitch1 = .true.
1817 oddsratio = likelinew / likeliold
1818 if (oddsratio .gt. 1.0_dp) oddsswitch1 = .true.
1822 If (oddsswitch1)
then
1825 ipos(chain) = ipos(chain) + 1_i4
1827 likeliold = likelinew
1828 mcmc_paras_3d(ipos(chain) + ineg(chain), :, chain) = paranew(:)
1831 if ((ipos(chain) + ineg(chain) .gt. 0_i4) .and. &
1832 (mod(ipos(chain) + ineg(chain), 10000_i4)) .eq. 0)
then
1833 write(*, *)
'Chain ', chain,
': Done ', ipos(chain) + ineg(chain),
' samples ...'
1837 if (likelinew .gt. likelibest)
then
1839 likelibest = likelinew
1842 write(*, *)
'best para changed: ', paranew
1843 write(*, *)
'likelihood new: ', likelinew
1850 call xor4096(seeds(chain, 1), rn1, save_state = save_state_1(chain, :))
1851 oddsswitch2 = .false.
1853 if (rn1 .lt. exp(oddsratio)) oddsswitch2 = .true.
1855 if (rn1 .lt. oddsratio) oddsswitch2 = .true.
1858 If (oddsswitch2)
then
1861 ineg(chain) = ineg(chain) + 1_i4
1863 likeliold = likelinew
1864 mcmc_paras_3d(ipos(chain) + ineg(chain), :, chain) = paranew(:)
1867 if ((ipos(chain) + ineg(chain) .gt. 0_i4) .and. &
1868 (mod(ipos(chain) + ineg(chain), 10000_i4)) .eq. 0)
then
1869 write(*, *)
'Chain ', chain,
': Done ', ipos(chain) + ineg(chain),
' samples ...'
1878 if ((ipos(chain) + ineg(chain) .gt. 0_i4) .and. &
1879 (mod(ipos(chain) + ineg(chain), iter_mcmc) .eq. 0_i4))
exit
1881 end do markovchainmcmc
1883 end do parallelchain
1887#ifdef FORCES_WITH_NETCDF
1889 if (
present(tmp_file))
then
1891 slash_pos = index(tmp_file,
'/', .true.)
1892 len_filename = len_trim(tmp_file)
1893 path = tmp_file(1 : slash_pos)
1894 filename = tmp_file(slash_pos + 1 : len_filename)
1896 do chain = 1, chains
1898 write(outputfile, *) trim(adjustl(path)), trim(adjustl(str)),
'_', trim(adjustl(filename))
1899 if (
present(iter_mcmc_in))
then
1900 allocate(tmp(iter_mcmc_in,
size(para, 1), 1))
1901 tmp(:, :, 1) = mcmc_paras_3d(iter_mcmc - iter_mcmc_in + 1_i4 : iter_mcmc, :, chain)
1902 if (iter_mcmc .ne. iter_mcmc_in)
then
1911 allocate(tmp(1000_i4 * n,
size(para, 1), 1))
1912 tmp(:, :, 1) = mcmc_paras_3d(iter_mcmc - (1000_i4 * n) + 1_i4 : iter_mcmc, :, chain)
1913 if (iter_mcmc .ne. 1000_i4 * n)
then
1925 if (
present(tmp_file)) &
1926 call error_message(
"MCMC: FORCES was compiled without NetCDF support but you set 'tmp_file'")
1937 write(*, *)
'Checking for convergence ....'
1940 n_end = minval(ipos + ineg)
1941 n_start = n_end / 2_i4 + 1_i4
1943 do ipar = 1,
size(truepara)
1946 do chain = 1, chains
1947 vdotj(chain) = 1.0_dp / real(n_end - n_start + 1_i4, dp) * &
1948 sum(mcmc_paras_3d(n_start : n_end, truepara(ipar), chain))
1950 vdotdot = 1.0_dp / real(chains, dp) * sum(vdotj)
1951 b = real(n_end - n_start + 1_i4, dp) / real(chains - 1_i4, dp) * &
1952 sum((vdotj - vdotdot) * (vdotj - vdotdot))
1955 do chain = 1, chains
1956 s2(chain) = 1.0_dp / real(n_end - n_start, dp) * &
1957 sum((mcmc_paras_3d(n_start : n_end, truepara(ipar), chain) - vdotj(chain))**2)
1959 w = 1.0_dp / real(chains, dp) * sum(s2)
1962 if ((w .lt. tiny(1.0_dp)) .and. (b .lt. tiny(1.0_dp)))
then
1964 sqrtr(truepara(ipar)) = sqrt(real(n_end - n_start, dp) / real(n_end - n_start + 1_i4, dp))
1966 sqrtr(truepara(ipar)) = real(n_end - n_start, dp) / real(n_end - n_start + 1_i4, dp) * w + &
1967 1.0_dp / real(n_end - n_start + 1_i4, dp) * b
1968 sqrtr(truepara(ipar)) = sqrt(sqrtr(truepara(ipar)) / w)
1972 do i = 1,
size(para)
1973 if (sqrtr(i) .gt. 1.1_dp)
then
1974 write(*, *)
' sqrtR para #', i,
' : ', sqrtr(i),
' <-- FAILED'
1976 write(*, *)
' sqrtR para #', i,
' : ', sqrtr(i)
1980 if (all(sqrtr .lt. 1.1_dp))
then
1983 write(*, *)
' --> converged (all less than 1.1)'
1988 if (
present(iter_mcmc_in))
then
1989 iter_mcmc = iter_mcmc + iter_mcmc_in
1991 iter_mcmc = iter_mcmc + 1000_i4 * n
1995 write(*, *)
' --> not converged (not all less than 1.1)'
1996 write(*, *)
' increasing iterations to ', iter_mcmc
2001 end do convergedmcmc
2004 allocate(mcmc_paras(
size(mcmc_paras_3d, 1) *
size(mcmc_paras_3d, 3),
size(mcmc_paras_3d, 2)))
2005 do chain = 1, chains
2006 mcmc_paras((chain - 1_i4) *
size(mcmc_paras_3d, 1) + 1_i4 : chain *
size(mcmc_paras_3d, 1), :) = mcmc_paras_3d(:, :, chain)
2010 END SUBROUTINE mcmc_stddev_dp
2017 real(DP) function parGen_dp(old, dMax, oMin, oMax, RN, inbound)
2021 REAL(DP),
intent(IN) :: old, dMax, oMin, oMax
2022 REAL(DP),
intent(IN) :: RN
2023 LOGICAL,
OPTIONAL,
INTENT(OUT) :: inbound
2029 pargen_dp = old + (rn * 2.0_dp * dmax - dmax)
2031 if (pargen_dp < omin)
then
2034 elseif(pargen_dp > omax)
then
2039 if (
present(inbound)) inbound = inbound2
2041 end function pargen_dp
2047 real(DP) function parGenNorm_dp(old, dMax, oMin, oMax, RN, inbound)
2051 REAL(DP),
intent(IN) :: old, dMax, oMin, oMax
2052 REAL(DP),
intent(IN) :: RN
2053 LOGICAL,
OPTIONAL,
INTENT(OUT) :: inbound
2056 REAL(DP) :: RN_scale
2057 REAL(DP) :: old_scaled
2063 old_scaled = (old - omin) / (omax - omin)
2068 rn_scale = (rn * dmax)
2071 pargennorm_dp = old_scaled + rn_scale
2081 if (
present(inbound)) inbound = inbound2
2084 pargennorm_dp = pargennorm_dp * (omax - omin) + omin
2086 end function pargennorm_dp
2088 recursive subroutine generatenewparameterset_dp(ParaSelectMode, paraold, truepara, rangePar, stepsize, &
2089 save_state_2, save_state_3, paranew, ChangePara)
2091 integer(i4),
intent(in) :: ParaSelectMode
2092 real(dp),
dimension(:),
intent(in) :: paraold
2093 integer(i4),
dimension(:),
intent(in) :: truepara
2094 real(dp),
dimension(:, :),
intent(in) :: rangePar
2095 real(dp),
dimension(:),
intent(in) :: stepsize
2096 integer(I8),
dimension(n_save_state),
intent(inout) :: save_state_2
2097 integer(I8),
dimension(n_save_state),
intent(inout) :: save_state_3
2098 real(dp),
dimension(size(paraold)),
intent(out) :: paranew
2099 logical,
dimension(size(paraold)),
intent(out) :: ChangePara
2102 REAL(DP) :: RN2, RN3
2104 integer(i4) :: i, iPar
2107 changepara = .false.
2109 select case(paraselectmode)
2111 do i = 1,
size(truepara)
2112 call xor4096(0_i8, rn2, save_state = save_state_2)
2113 if (rn2 > 0.5_dp)
then
2116 call xor4096(0_i8, rn3, save_state = save_state_3)
2117 paranew(ipar) = pargennorm_dp(paraold(ipar), stepsize(ipar), rangepar(ipar, 1), rangepar(ipar, 2), rn3, inbound)
2118 changepara(ipar) = .true.
2122 if (count(changepara) .eq. 0_i4)
then
2123 call xor4096(0_i8, rn2, save_state = save_state_2)
2124 ipar = truepara(int((rn2 * real(
size(truepara), dp)) + 1.0_dp, i4))
2126 call xor4096(0_i8, rn3, save_state = save_state_3)
2127 paranew(ipar) = pargennorm_dp(paraold(ipar), stepsize(ipar), rangepar(ipar, 1), rangepar(ipar, 2), rn3, inbound)
2128 changepara(ipar) = .true.
2132 call xor4096(0_i8, rn2, save_state = save_state_2)
2133 ipar = truepara(int((rn2 * real(
size(truepara), dp)) + 1.0_dp, i4))
2135 call xor4096g(0_i8, rn3, save_state = save_state_3)
2136 paranew(ipar) = pargennorm_dp(paraold(ipar), stepsize(ipar), rangepar(ipar, 1), rangepar(ipar, 2), rn3, inbound)
2139 changepara(ipar) = .true.
2142 do i = 1,
size(truepara)
2145 do while(.not. inbound)
2146 call xor4096g(0_i8, rn2, save_state = save_state_3)
2147 paranew(ipar) = pargennorm_dp(paraold(ipar), stepsize(ipar), rangepar(ipar, 1), rangepar(ipar, 2), rn3, inbound)
2149 changepara(ipar) = .true.
2154 end subroutine generatenewparameterset_dp
Append (rows) scalars, vectors, and matrixes onto existing array.
This module is Monte Carlo Markov Chain sampling of a posterior parameter distribution (measurement e...
This module is Monte Carlo Markov Chain sampling of a posterior parameter distribution (measurement e...
Standard deviation of a vector.
Variable simple write in netcdf.
Interface for evaluation routine.
Interface for objective function.
Generate seed for xor4096.
Uniform XOR4096-based RNG.
Gaussian XOR4096-based RNG.
Append values on existing arrays.
Define number representations.
integer, parameter i4
4 Byte Integer Kind
integer, parameter i8
8 Byte Integer Kind
integer, parameter dp
Double Precision Real Kind.
Monte Carlo Markov Chain sampling.
Write out concatenated strings.
subroutine, public error_message(t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15, t16, uni, advance, show, raise, reset_format)
Write out an error message to stderr and call stop 1.
Utility functions, such as interface definitions, for optimization routines.
XOR4096-based random number generator.
integer(i4), parameter, public n_save_state
Dimension of vector saving the state of a stream.