The ParaMonte Documentation Website
Current view: top level - kernel - ParaDXXX_mod@Setup_smod.inc.f90 (source / functions) Hit Total Coverage
Test: ParaMonte 1.5.1 :: MPI Parallel Kernel - Code Coverage Report Lines: 592 604 98.0 %
Date: 2021-01-08 13:07:16 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       2             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       3             : !!!!
       4             : !!!!   MIT License
       5             : !!!!
       6             : !!!!   ParaMonte: plain powerful parallel Monte Carlo library.
       7             : !!!!
       8             : !!!!   Copyright (C) 2012-present, The Computational Data Science Lab
       9             : !!!!
      10             : !!!!   This file is part of the ParaMonte library.
      11             : !!!!
      12             : !!!!   Permission is hereby granted, free of charge, to any person obtaining a
      13             : !!!!   copy of this software and associated documentation files (the "Software"),
      14             : !!!!   to deal in the Software without restriction, including without limitation
      15             : !!!!   the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             : !!!!   and/or sell copies of the Software, and to permit persons to whom the
      17             : !!!!   Software is furnished to do so, subject to the following conditions:
      18             : !!!!
      19             : !!!!   The above copyright notice and this permission notice shall be
      20             : !!!!   included in all copies or substantial portions of the Software.
      21             : !!!!
      22             : !!!!   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      23             : !!!!   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      24             : !!!!   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      25             : !!!!   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
      26             : !!!!   DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
      27             : !!!!   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
      28             : !!!!   OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      29             : !!!!
      30             : !!!!   ACKNOWLEDGMENT
      31             : !!!!
      32             : !!!!   ParaMonte is an honor-ware and its currency is acknowledgment and citations.
      33             : !!!!   As per the ParaMonte library license agreement terms, if you use any parts of
      34             : !!!!   this library for any purposes, kindly acknowledge the use of ParaMonte in your
      35             : !!!!   work (education/research/industry/development/...) by citing the ParaMonte
      36             : !!!!   library as described on this page:
      37             : !!!!
      38             : !!!!       https://github.com/cdslaborg/paramonte/blob/main/ACKNOWLEDGMENT.md
      39             : !!!!
      40             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      41             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      42             : 
      43             : !> \brief
      44             : !> This file implements the body of the `Setup_smod` submodules of the `ParaDRAM_mod` and `ParaDISE_mod` modules.
      45             : !>
      46             : !> \remark
      47             : !> This module requires preprocessing, prior to compilation.
      48             : !>
      49             : !> \author Amir Shahmoradi
      50             : 
      51             : #if defined PARADRAM
      52             : 
      53             : #define ParaDXXX ParaDRAM
      54             : #define ParaDXXX_type ParaDRAM_type
      55             : #define ParaDXXXProposalAbstract_mod ParaDRAMProposalAbstract_mod
      56             : 
      57             : #elif defined PARADISE
      58             : 
      59             : #define ParaDXXX ParaDISE
      60             : #define ParaDXXX_type ParaDISE_type
      61             : #define ParaDXXXProposalAbstract_mod ParaDISEProposalAbstract_mod
      62             : 
      63             : #else
      64             : #error "Unrecognized sampler in ParaDXXX_mod@Setup_mod.inc.f90"
      65             : #endif
      66             : 
      67             : !submodule (ParaDRAM_mod) Setup_smod
      68             : 
      69             :     !use Constants_mod, only: IK, RK ! gfortran 9.3 compile crashes with this line
      70             :     implicit none
      71             : 
      72             :     character(*), parameter :: SUBMODULE_NAME = MODULE_NAME // "@Setup_smod"
      73             : 
      74             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      75             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      76             : 
      77             : contains
      78             : 
      79             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      80             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      81             : 
      82             :     !> \brief
      83             :     !> This procedure is a method of [ParaDRAM_type](@ref paradram_type) and [ParaDISE_type](@ref paradise_type) classes.
      84             :     !> Setup the sampler and run the simulation.
      85             :     !>
      86             :     !> \remark
      87             :     !> There are only two mandatory pieces of information that must be provided when calling this subroutine.
      88             :     !> The rest of the parameters can be also set from within an external input file, whose path can be given
      89             :     !> as an input argument `inputFile` to this subroutine.
      90             :     !>
      91             :     !> @param[in]   ndim        :   The number of dimensions of the domain of the objective function to be sampled.
      92             :     !> @param[in]   getLogFunc  :   The first point.
      93             :     !> @param[in]   inputFile   :   The path to the external input file (**optional**).
      94             :     !>
      95             :     !> \remark
      96             :     !> For detailed descriptions of the rest of the input parameters of this subroutine,
      97             :     !> see: https://www.cdslab.org/paramonte/notes/usage/paradram/specifications/
      98             :     !>
      99             :     !> \remark
     100             :     !> This procedure requires preprocessing.
     101        1047 :     module subroutine runSampler( self                                  &
     102             :                                 , ndim                                  &
     103             :                                 , getLogFunc                            &
     104             :                                 , inputFile                             &
     105             :                                 ! ParaMonte variables
     106             :                                 , sampleSize                            &
     107             :                                 , randomSeed                            &
     108             :                                 , description                           &
     109             :                                 , outputFileName                        &
     110             :                                 , outputDelimiter                       &
     111             :                                 , chainFileFormat                       &
     112         126 :                                 , variableNameList                      &
     113             :                                 , restartFileFormat                     &
     114             :                                 , outputColumnWidth                     &
     115             :                                 , overwriteRequested                    &
     116             :                                 , outputRealPrecision                   &
     117             :                                 , silentModeRequested                   &
     118          78 :                                 , domainLowerLimitVec                   &
     119          78 :                                 , domainUpperLimitVec                   &
     120             :                                 , parallelizationModel                  &
     121             :                                 , progressReportPeriod                  &
     122             :                                 , targetAcceptanceRate                  &
     123             :                                 , mpiFinalizeRequested                  &
     124             :                                 , maxNumDomainCheckToWarn               &
     125             :                                 , maxNumDomainCheckToStop               &
     126             :                                 ! ParaMCMC variables
     127             :                                 , chainSize                             &
     128          12 :                                 , startPointVec                         &
     129             :                                 , sampleRefinementCount                 &
     130             :                                 , sampleRefinementMethod                &
     131             :                                 , randomStartPointRequested             &
     132          24 :                                 , randomStartPointDomainLowerLimitVec   &
     133          24 :                                 , randomStartPointDomainUpperLimitVec   &
     134             :                                 ! ParaDRAM variables
     135             :                                 , scaleFactor                           &
     136             :                                 , proposalModel                         &
     137          18 :                                 , proposalStartStdVec                   &
     138          18 :                                 , proposalStartCorMat                   &
     139          12 :                                 , proposalStartCovMat                   &
     140             :                                 , adaptiveUpdateCount                   &
     141             :                                 , adaptiveUpdatePeriod                  &
     142             :                                 , greedyAdaptationCount                 &
     143             :                                 , delayedRejectionCount                 &
     144             :                                 , burninAdaptationMeasure               &
     145        1047 :                                 , delayedRejectionScaleFactorVec        &
     146             :                                 ) !  result(self)
     147             : #if INTEL_COMPILER_ENABLED && defined DLL_ENABLED && (OS_IS_WINDOWS || defined OS_IS_DARWIN)
     148             :         !!DEC$ ATTRIBUTES DLLEXPORT :: ParaDXXX_type
     149             :         !DEC$ ATTRIBUTES DLLEXPORT :: runSampler
     150             : #endif
     151             :         use, intrinsic :: iso_fortran_env, only: output_unit, stat_stopped_image
     152             : #if defined PARADRAM
     153             :         use ParaDRAMProposalUniform_mod, only: ProposalUniform_type => Proposal_type
     154             :         use ParaDRAMProposalNormal_mod, only: ProposalNormal_type => Proposal_type
     155             : #elif defined PARADISE
     156             :         use ParaDISEProposalUniform_mod, only: ProposalUniform_type => Proposal_type
     157             :         use ParaDISEProposalNormal_mod, only: ProposalNormal_type => Proposal_type
     158             : #endif
     159             :         use ParaMonteLogFunc_mod, only: getLogFunc_proc
     160             :         use Decoration_mod, only: GENERIC_OUTPUT_FORMAT
     161             :         use Decoration_mod, only: GENERIC_TABBED_FORMAT
     162             :         use Decoration_mod, only: getGenericFormat
     163             :         use Decoration_mod, only: INDENT
     164             :         use Statistics_mod, only: getCorMatUpperFromCovMatUpper
     165             :         use Statistics_mod, only: getWeiSamCovUppMeanTrans
     166             :         use Statistics_mod, only: getQuantile
     167             :         use Statistics_mod, only: getMean
     168             :         use ParaMonte_mod, only: QPROB
     169             :         use Constants_mod, only: IK, RK, NLC, PMSM, UNDEFINED, POSINF_RK
     170             :         use DateTime_mod, only: getNiceDateTime
     171             :         use String_mod, only: num2str
     172             :         use Matrix_mod, only: getEye
     173             : 
     174             :         implicit none
     175             : 
     176             :         ! self
     177             :         class(ParaDXXX_type), intent(inout) :: self
     178             : 
     179             :         ! mandatory variables
     180             :         integer(IK) , intent(in)            :: ndim
     181             :         procedure(getLogFunc_proc)          :: getLogFunc
     182             : 
     183             :         character(*), intent(in), optional  :: inputFile
     184             : 
     185             :         ! ParaMonte variables
     186             :         integer(IK) , intent(in), optional  :: sampleSize
     187             :         integer(IK) , intent(in), optional  :: randomSeed
     188             :         character(*), intent(in), optional  :: description
     189             :         character(*), intent(in), optional  :: outputFileName
     190             :         character(*), intent(in), optional  :: outputDelimiter
     191             :         character(*), intent(in), optional  :: chainFileFormat
     192             :         character(*), intent(in), optional  :: variableNameList(ndim)
     193             :         character(*), intent(in), optional  :: restartFileFormat
     194             :         integer(IK) , intent(in), optional  :: outputColumnWidth
     195             :         logical     , intent(in), optional  :: overwriteRequested
     196             :         integer(IK) , intent(in), optional  :: outputRealPrecision
     197             :         real(RK)    , intent(in), optional  :: domainLowerLimitVec(ndim)
     198             :         real(RK)    , intent(in), optional  :: domainUpperLimitVec(ndim)
     199             :         logical     , intent(in), optional  :: silentModeRequested
     200             :         character(*), intent(in), optional  :: parallelizationModel
     201             :         integer(IK) , intent(in), optional  :: progressReportPeriod
     202             :         real(RK)    , intent(in), optional  :: targetAcceptanceRate(2)
     203             :         logical     , intent(in), optional  :: mpiFinalizeRequested
     204             :         integer(IK) , intent(in), optional  :: maxNumDomainCheckToWarn
     205             :         integer(IK) , intent(in), optional  :: maxNumDomainCheckToStop
     206             : 
     207             :         ! ParaMCMC variables
     208             :         integer(IK) , intent(in), optional  :: chainSize
     209             :         real(RK)    , intent(in), optional  :: startPointVec(ndim)
     210             :         integer(IK) , intent(in), optional  :: sampleRefinementCount
     211             :         character(*), intent(in), optional  :: sampleRefinementMethod
     212             :         logical     , intent(in), optional  :: randomStartPointRequested
     213             :         real(RK)    , intent(in), optional  :: randomStartPointDomainLowerLimitVec(ndim)
     214             :         real(RK)    , intent(in), optional  :: randomStartPointDomainUpperLimitVec(ndim)
     215             : 
     216             :         ! ParaDRAM variables
     217             :         character(*), intent(in), optional  :: scaleFactor
     218             :         character(*), intent(in), optional  :: proposalModel
     219             :         real(RK)    , intent(in), optional  :: proposalStartStdVec(ndim)
     220             :         real(RK)    , intent(in), optional  :: proposalStartCorMat(ndim,ndim)
     221             :         real(RK)    , intent(in), optional  :: proposalStartCovMat(ndim,ndim)
     222             :         integer(IK) , intent(in), optional  :: adaptiveUpdateCount
     223             :         integer(IK) , intent(in), optional  :: adaptiveUpdatePeriod
     224             :         integer(IK) , intent(in), optional  :: greedyAdaptationCount
     225             :         integer(IK) , intent(in), optional  :: delayedRejectionCount
     226             :         real(RK)    , intent(in), optional  :: burninAdaptationMeasure
     227             :         real(RK)    , intent(in), optional  :: delayedRejectionScaleFactorVec(:)
     228             : 
     229             :         character(*), parameter             :: PROCEDURE_NAME = SUBMODULE_NAME // "@runSampler()"
     230             : 
     231             :        !type(ProposalSymmetric_type), target:: ProposalSymmetric
     232             :         integer(IK)                         :: i, iq, effectiveSampleSize
     233        1047 :         character(:), allocatable           :: msg, formatStr, formatStrInt, formatStrReal, formatAllReal
     234             :         real(RK)    , allocatable           :: ContiguousChain(:,:) ! used to avoid temporary array creation and the compiler warning message in debug mode
     235        1047 :         real(RK)                            :: mcmcSamplingEfficiency
     236             : 
     237             : 
     238             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     239             :         ! Initialize SpecBase variables, then check existence of inputFile and open it and return the unit file, if it exists
     240             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     241             : 
     242             :         call self%setupParaMonte( nd = ndim             &
     243             :                                 , name = PMSM%ParaDXXX  &
     244             :                                 , inputFile = inputFile &
     245        1047 :                                 )
     246             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     247        1047 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     248             : #endif
     249        1047 :         if (self%Err%occurred) then
     250             :             ! LCOV_EXCL_START
     251             :             self%Err%msg = PROCEDURE_NAME // self%Err%msg
     252             :             call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
     253             :             return
     254             :             ! LCOV_EXCL_STOP
     255             :         end if
     256             : 
     257             : 
     258             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     259             :         ! Initialize ParaMCMC variables
     260             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     261             : 
     262        1047 :         call self%setupParaMCMC()
     263             : 
     264             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     265             :         ! Initialize ParaDXXX variables
     266             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     267             : 
     268        1047 :         self%SpecDRAM = SpecDRAM_type( self%nd%val, self%name ) ! , self%SpecMCMC%ChainSize%def )
     269             : 
     270             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     271             :         ! read variables from input file if it exists
     272             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     273             : 
     274        1047 :         call self%getSpecFromInputFile(ndim)
     275             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     276        1047 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     277             : #endif
     278        1047 :         if (self%Err%occurred) then
     279             :             ! LCOV_EXCL_START
     280             :             self%Err%msg = PROCEDURE_NAME // self%Err%msg
     281             :             call self%abort( Err = self%Err, prefix = self%brand, newline = "\n", outputUnit = self%LogFile%unit )
     282             :             return
     283             :             ! LCOV_EXCL_STOP
     284             :         end if
     285             : 
     286             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     287             :         ! read variables from argument list if needed
     288             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     289             : 
     290        1047 :         call self%setWarnAboutProcArgHasPriority()
     291        1047 :         if (self%procArgNeeded) then
     292             :             call self%SpecBase%setFromInputArgs ( Err                                   = self%Err                              & ! LCOV_EXCL_LINE
     293             :                                                 , sampleSize                            = sampleSize                            & ! LCOV_EXCL_LINE
     294             :                                                 , randomSeed                            = randomSeed                            & ! LCOV_EXCL_LINE
     295             :                                                 , description                           = description                           & ! LCOV_EXCL_LINE
     296             :                                                 , outputFileName                        = outputFileName                        & ! LCOV_EXCL_LINE
     297             :                                                 , outputDelimiter                       = outputDelimiter                       & ! LCOV_EXCL_LINE
     298             :                                                 , chainFileFormat                       = chainFileFormat                       & ! LCOV_EXCL_LINE
     299             :                                                 , variableNameList                      = variableNameList                      & ! LCOV_EXCL_LINE
     300             :                                                 , restartFileFormat                     = restartFileFormat                     & ! LCOV_EXCL_LINE
     301             :                                                 , outputColumnWidth                     = outputColumnWidth                     & ! LCOV_EXCL_LINE
     302             :                                                 , overwriteRequested                    = overwriteRequested                    & ! LCOV_EXCL_LINE
     303             :                                                 , outputRealPrecision                   = outputRealPrecision                   & ! LCOV_EXCL_LINE
     304             :                                                 , silentModeRequested                   = silentModeRequested                   & ! LCOV_EXCL_LINE
     305             :                                                 , domainLowerLimitVec                   = domainLowerLimitVec                   & ! LCOV_EXCL_LINE
     306             :                                                 , domainUpperLimitVec                   = domainUpperLimitVec                   & ! LCOV_EXCL_LINE
     307             :                                                 , parallelizationModel                  = parallelizationModel                  & ! LCOV_EXCL_LINE
     308             :                                                 , progressReportPeriod                  = progressReportPeriod                  & ! LCOV_EXCL_LINE
     309             :                                                 , targetAcceptanceRate                  = targetAcceptanceRate                  & ! LCOV_EXCL_LINE
     310             :                                                 , mpiFinalizeRequested                  = mpiFinalizeRequested                  & ! LCOV_EXCL_LINE
     311             :                                                 , maxNumDomainCheckToWarn               = maxNumDomainCheckToWarn               & ! LCOV_EXCL_LINE
     312             :                                                 , maxNumDomainCheckToStop               = maxNumDomainCheckToStop               & ! LCOV_EXCL_LINE
     313        1041 :                                                 )
     314             :             call self%SpecMCMC%setFromInputArgs ( chainSize                             = chainSize                             & ! LCOV_EXCL_LINE
     315             :                                                 , scaleFactor                           = scaleFactor                           & ! LCOV_EXCL_LINE
     316             :                                                 , startPointVec                         = startPointVec                         & ! LCOV_EXCL_LINE
     317             :                                                 , proposalModel                         = proposalModel                         & ! LCOV_EXCL_LINE
     318             :                                                 , proposalStartStdVec                   = proposalStartStdVec                   & ! LCOV_EXCL_LINE
     319             :                                                 , proposalStartCorMat                   = proposalStartCorMat                   & ! LCOV_EXCL_LINE
     320             :                                                 , proposalStartCovMat                   = proposalStartCovMat                   & ! LCOV_EXCL_LINE
     321             :                                                 , sampleRefinementCount                 = sampleRefinementCount                 & ! LCOV_EXCL_LINE
     322             :                                                 , sampleRefinementMethod                = sampleRefinementMethod                & ! LCOV_EXCL_LINE
     323             :                                                 , randomStartPointRequested             = randomStartPointRequested             & ! LCOV_EXCL_LINE
     324             :                                                 , randomStartPointDomainLowerLimitVec   = randomStartPointDomainLowerLimitVec   & ! LCOV_EXCL_LINE
     325             :                                                 , randomStartPointDomainUpperLimitVec   = randomStartPointDomainUpperLimitVec   & ! LCOV_EXCL_LINE
     326        1041 :                                                 )
     327             :             call self%SpecDRAM%setFromInputArgs ( adaptiveUpdateCount                   = adaptiveUpdateCount                   & ! LCOV_EXCL_LINE
     328             :                                                 , adaptiveUpdatePeriod                  = adaptiveUpdatePeriod                  & ! LCOV_EXCL_LINE
     329             :                                                 , greedyAdaptationCount                 = greedyAdaptationCount                 & ! LCOV_EXCL_LINE
     330             :                                                 , delayedRejectionCount                 = delayedRejectionCount                 & ! LCOV_EXCL_LINE
     331             :                                                 , burninAdaptationMeasure               = burninAdaptationMeasure               & ! LCOV_EXCL_LINE
     332             :                                                 , delayedRejectionScaleFactorVec        = delayedRejectionScaleFactorVec        & ! LCOV_EXCL_LINE
     333        1041 :                                                 )
     334             :         end if
     335             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     336        1047 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     337             : #endif
     338        1047 :         if (self%Err%occurred) then
     339             :             ! LCOV_EXCL_START
     340             :             self%Err%msg = PROCEDURE_NAME // self%Err%msg
     341             :             call self%abort( Err = self%Err, prefix = self%brand, newline = "\n", outputUnit = self%LogFile%unit )
     342             :             return
     343             :             ! LCOV_EXCL_STOP
     344             :         end if
     345             : 
     346             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     347             :         ! Now depending on the requested parallelism type, determine the process leader/rooter type and open output files
     348             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     349             : 
     350        1047 :         self%Image%isLeader = self%Image%isFirst .or. self%SpecBase%ParallelizationModel%isMultiChain
     351        1047 :         self%Image%isRooter = .not. self%Image%isLeader
     352             : 
     353             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     354             :         ! setup log file and open output files
     355             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     356             : 
     357        1047 :         call self%setupOutputFiles()
     358             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     359        1047 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     360             : #endif
     361        1047 :         if (self%Err%occurred) then
     362             :             ! LCOV_EXCL_START
     363             :             self%Err%msg = PROCEDURE_NAME // self%Err%msg
     364             :             call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
     365             :             return
     366             :             ! LCOV_EXCL_STOP
     367             :         end if
     368             : 
     369             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     370             :         ! report variable values to the log file
     371             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     372             : 
     373        1035 :         if (self%isFreshRun) then
     374         969 :             call self%SpecBase%reportValues(prefix=self%brand,outputUnit=self%LogFile%unit,isLeaderImage=self%Image%isLeader)
     375         969 :             call self%SpecMCMC%reportValues(prefix=self%brand,outputUnit=self%LogFile%unit,isLeaderImage=self%Image%isLeader,methodName=self%name,splashModeRequested=self%SpecBase%SilentModeRequested%isFalse)
     376         969 :             call self%SpecDRAM%reportValues(prefix=self%brand,outputUnit=self%LogFile%unit,isLeaderImage=self%Image%isLeader,splashModeRequested=self%SpecBase%SilentModeRequested%isFalse)
     377             :         end if
     378             : 
     379             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     380             :         ! perform variable value sanity checks
     381             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     382             : 
     383        1035 :         self%Err%msg = ""
     384        1035 :         self%Err%occurred = .false.
     385             : 
     386        1035 :         call self%SpecBase%checkForSanity(Err = self%Err, methodName = self%name)
     387        1035 :         call self%SpecMCMC%checkForSanity(SpecBase = self%SpecBase, methodName = self%name, Err = self%Err, nd = ndim)
     388        1035 :         call self%SpecDRAM%checkForSanity(Err = self%Err, methodName = self%name, nd = ndim)
     389             : 
     390             :         !if (self%Image%isLeader) then
     391             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     392        1035 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     393             : #endif
     394        1035 :         if (self%Err%occurred) then
     395         348 :             self%Err%msg = PROCEDURE_NAME // self%Err%msg
     396         348 :             call self%abort( Err = self%Err, prefix = self%brand, newline = "\n", outputUnit = self%LogFile%unit )
     397         348 :             return
     398             :         end if
     399             :         !end if
     400             : 
     401             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     402             :         ! setup output files
     403             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     404             : 
     405             :         ! setup chain file
     406             : 
     407             :         block
     408             :             use ParaMonteChainFileContents_mod, only: ChainFileContents_type
     409        1101 :             self%Chain = ChainFileContents_type( ndim = ndim, variableNameList = self%SpecBase%VariableNameList%Val )
     410             :         end block
     411             : 
     412         687 :         if (self%isFreshRun) then
     413         627 :             if (self%Image%isLeader) then
     414             :                 call self%Chain%writeHeader ( ndim              = ndim &
     415             :                                             , chainFileUnit     = self%ChainFile%unit &
     416             :                                             , isBinary          = self%SpecBase%ChainFileFormat%isBinary &
     417             :                                             , chainFileFormat   = self%ChainFile%format &
     418         237 :                                             )
     419         237 :                 flush(self%ChainFile%unit)
     420             :             end if
     421             :         else
     422          60 :             call self%Chain%getLenHeader(ndim=ndim,isBinary=self%SpecBase%ChainFileFormat%isBinary,chainFileFormat=self%ChainFile%format)
     423             :         end if
     424             : 
     425             :         ! setup progress file
     426             : 
     427         687 :         if (self%Image%isLeader) then
     428         269 :             if (.not.self%isFreshRun) then
     429          32 :                 read(self%TimeFile%unit, *, iostat = self%Err%stat) ! read the header line of the time file, only by leader images
     430             :             end if
     431         269 :             if (self%isFreshRun .or. is_iostat_end(self%Err%stat)) then
     432         237 :                     write( self%TimeFile%unit, self%TimeFile%format ) "NumFuncCallTotal" &
     433         237 :                                                                     , "NumFuncCallAccepted" &
     434         237 :                                                                     , "MeanAcceptanceRateSinceStart" &
     435         237 :                                                                     , "MeanAcceptanceRateSinceLastReport" &
     436         237 :                                                                     , "TimeElapsedSinceLastReportInSeconds" &
     437         237 :                                                                     , "TimeElapsedSinceStartInSeconds" &
     438         474 :                                                                     , "TimeRemainedToFinishInSeconds"
     439         237 :                     flush(self%TimeFile%unit)
     440             :             end if
     441             :         end if
     442             : 
     443             :         ! The format setup of setupOutputFiles() uses the generic g0 edit descriptor. Here the format is revised to be more specific.
     444             :         ! g0 edit descriptor format is slightly more arbitrary and compiler-dependent.
     445             : 
     446         687 :         if (self%SpecBase%OutputColumnWidth%val>0) then
     447             :             self%TimeFile%format  = "("     // &
     448             :                                     "2I"    // self%SpecBase%OutputColumnWidth%str // ",'" // self%SpecBase%OutputDelimiter%val // &
     449             :                                     "',5(E" // self%SpecBase%OutputColumnWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3" // &
     450           6 :                                     ",:,'"  // self%SpecBase%OutputDelimiter%val // "'))"
     451             :             self%ChainFile%format = "("     // &
     452             :                                     "2(I"   // self%SpecBase%OutputColumnWidth%str // &
     453             :                                     ",'"    // self%SpecBase%OutputDelimiter%val // "')," // &
     454             :                                     "2(E"   // self%SpecBase%OutputColumnWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3" // &
     455             :                                     ",'"    // self%SpecBase%OutputDelimiter%val // "')," // &
     456             :                                     "2(I"   // self%SpecBase%OutputColumnWidth%str // &
     457             :                                     ",'"    // self%SpecBase%OutputDelimiter%val // "')" // &
     458             :                                     ","     // num2str(3_IK+self%nd%val) // &
     459             :                                     "(E"    // self%SpecBase%OutputColumnWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3" // &
     460             :                                     ",:,'"  // self%SpecBase%OutputDelimiter%val // "')" // &
     461           6 :                                     ")"
     462             :         end if
     463             : 
     464             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     465             :         ! setup the proposal distribution
     466             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     467             : 
     468         687 :         if (allocated(self%Proposal)) deallocate(self%Proposal)
     469             :         if (self%SpecMCMC%ProposalModel%isNormal) then ! LCOV_EXCL_LINE
     470             :             allocate( self%Proposal, source = ProposalNormal_type   ( ndim          = ndim & ! LCOV_EXCL_LINE
     471             :                                                                     , SpecBase      = self%SpecBase & ! LCOV_EXCL_LINE
     472             :                                                                     , SpecMCMC      = self%SpecMCMC & ! LCOV_EXCL_LINE
     473             :                                                                     , SpecDRAM      = self%SpecDRAM & ! LCOV_EXCL_LINE
     474             :                                                                     , Image         = self%Image & ! LCOV_EXCL_LINE
     475             :                                                                     , name          = self%name & ! LCOV_EXCL_LINE
     476             :                                                                     , brand         = self%brand & ! LCOV_EXCL_LINE
     477             :                                                                     , LogFile       = self%LogFile & ! LCOV_EXCL_LINE
     478             :                                                                     , RestartFile   = self%RestartFile & ! LCOV_EXCL_LINE
     479             :                                                                     , isFreshRun    = self%isFreshRun & ! LCOV_EXCL_LINE
     480         567 :                                                                     ) )
     481             :         elseif (self%SpecMCMC%ProposalModel%isUniform) then ! LCOV_EXCL_LINE
     482             :             allocate( self%Proposal, source = ProposalUniform_type  ( ndim          = ndim & ! LCOV_EXCL_LINE
     483             :                                                                     , SpecBase      = self%SpecBase & ! LCOV_EXCL_LINE
     484             :                                                                     , SpecMCMC      = self%SpecMCMC & ! LCOV_EXCL_LINE
     485             :                                                                     , SpecDRAM      = self%SpecDRAM & ! LCOV_EXCL_LINE
     486             :                                                                     , Image         = self%Image & ! LCOV_EXCL_LINE
     487             :                                                                     , name          = self%name & ! LCOV_EXCL_LINE
     488             :                                                                     , brand         = self%brand & ! LCOV_EXCL_LINE
     489             :                                                                     , LogFile       = self%LogFile & ! LCOV_EXCL_LINE
     490             :                                                                     , RestartFile   = self%RestartFile & ! LCOV_EXCL_LINE
     491             :                                                                     , isFreshRun    = self%isFreshRun & ! LCOV_EXCL_LINE
     492         120 :                                                                     ) )
     493             :         else
     494             :             ! LCOV_EXCL_START
     495             :             self%Err%occurred = .true.
     496             :             self%Err%msg = PROCEDURE_NAME // ": Internal error occurred. Unsupported proposal distribution for " // self%name // "."
     497             :             call self%abort( Err = self%Err, prefix = self%brand, newline = "\n", outputUnit = self%LogFile%unit )
     498             :             error stop
     499             :             return
     500             :             ! LCOV_EXCL_STOP
     501             :         end if
     502             : 
     503             : #if (defined MATLAB_ENABLED || defined PYTHON_ENABLED || defined R_ENABLED) && !defined CAF_ENABLED && !defined MPI_ENABLED
     504             :             block
     505             : #if defined PARADRAM
     506             :                 use ParaDXXXProposalAbstract_mod, only: ProposalErr
     507             : #elif defined PARADISE
     508             :                 use ParaDXXXProposalAbstract_mod, only: ProposalErr
     509             : #endif
     510             : 
     511             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     512             :                 block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     513             : #endif
     514             :                 if (ProposalErr%occurred) then
     515             :                     self%Err%occurred = .true.
     516             :                     self%Err%msg = PROCEDURE_NAME // ProposalErr%msg
     517             :                     call self%abort( Err = self%Err, prefix = self%brand, newline = "\n", outputUnit = self%LogFile%unit )
     518             :                     return
     519             :                 end if
     520             :             end block
     521             : #endif
     522             : 
     523             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     524             :         ! run ParaDXXX kernel
     525             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     526             : 
     527         687 :         if (self%isFreshRun .and. self%Image%isLeader) then
     528             :             call self%Decor%writeDecoratedText  ( text = "\nStarting the " // self%name // " sampling - " // getNiceDateTime() // "\n" &
     529             :                                                 , marginTop = 1_IK  &
     530             :                                                 , marginBot = 1_IK  &
     531             :                                                 , newline = "\n"    &
     532         237 :                                                 , outputUnit = self%LogFile%unit )
     533             :         end if
     534             : 
     535         687 :         call self%runKernel( getLogFunc = getLogFunc )
     536             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
     537         687 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
     538             : #endif
     539             :         ! relevant only for MATLAB / Python
     540         687 :         if (self%Err%occurred) then
     541           6 :             self%Err%msg = PROCEDURE_NAME // self%Err%msg
     542           6 :             call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
     543           6 :             return
     544             :         end if
     545             : 
     546         681 :         if (self%isFreshRun .and. self%Image%isLeader) then
     547             :             call self%Decor%writeDecoratedText  ( text = "\nExiting the " // self%name // " sampling - " // getNiceDateTime() // "\n" &
     548             :                                                 , marginTop = 1_IK  &
     549             :                                                 , marginBot = 1_IK  &
     550             :                                                 , newline = "\n"    &
     551         263 :                                                 , outputUnit = self%LogFile%unit )
     552             :         end if
     553             : 
     554             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     555             :         ! start ParaDXXX post-processing
     556             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     557             : 
     558             :         ! WARNING: For any error that happens within the leader if block below, the control must be passed to after the block
     559             :         ! WARNING: This is essential for error handling during testing in parallel mode.
     560             : 
     561         681 :         blockLeaderPostProcessing: if (self%Image%isLeader) then
     562             : 
     563         263 :             formatStrInt  = "('" // INDENT // "',1A" // self%LogFile%maxColWidth%str // ",*(I" // self%LogFile%maxColWidth%str // "))"
     564         263 :             formatStrReal = "('" // INDENT // "',1A" // self%LogFile%maxColWidth%str // ",*(E" // self%LogFile%maxColWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3))"
     565             : 
     566             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     567             : 
     568         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     569         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.numFuncCall.accepted"
     570         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     571         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%NumFunCall%accepted
     572         263 :             msg = "This is the total number of accepted function calls (unique samples)."
     573         263 :             call self%reportDesc(msg)
     574             : 
     575             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     576             : 
     577         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     578         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.numFuncCall.acceptedRejected"
     579         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     580         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%NumFunCall%acceptedRejected
     581         263 :             msg = "This is the total number of accepted or rejected function calls."
     582         263 :             call self%reportDesc(msg)
     583             : 
     584             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     585             : 
     586         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     587         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.numFuncCall.acceptedRejectedDelayed"
     588         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     589         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%NumFunCall%acceptedRejectedDelayed
     590         263 :             msg = "This is the total number of accepted or rejected or delayed-rejection (if any requested) function calls."
     591         263 :             call self%reportDesc(msg)
     592             : 
     593             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     594             : 
     595         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     596         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.numFuncCall.acceptedRejectedDelayedUnused"
     597         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     598         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%NumFunCall%acceptedRejectedDelayedUnused
     599         263 :             msg = "This is the total number of accepted or rejected or unused function calls (by all processes, including delayed rejections, if any requested)."
     600         263 :             call self%reportDesc(msg)
     601             : 
     602             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     603             : 
     604         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     605         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.efficiency.meanAcceptanceRate"
     606         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     607         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Chain%MeanAccRate(self%Stats%NumFunCall%accepted)
     608         263 :             msg = "This is the average MCMC acceptance rate."
     609         263 :             call self%reportDesc(msg)
     610             : 
     611             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     612             : 
     613         263 :             mcmcSamplingEfficiency = real(self%Stats%NumFunCall%accepted,kind=RK) / real(self%Stats%NumFunCall%acceptedRejected,kind=RK)
     614             : 
     615         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     616         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.efficiency.acceptedOverAcceptedRejected"
     617         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     618         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) mcmcSamplingEfficiency
     619             :             msg =   "This is the MCMC sampling efficiency given the accepted and rejected function calls, that is, &
     620         263 :                     &the number of accepted function calls divided by the number of (accepted + rejected) function calls."
     621         263 :             call self%reportDesc(msg)
     622             : 
     623             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     624             : 
     625         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     626         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.efficiency.acceptedOverAcceptedRejectedDelayed"
     627         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     628         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) real(self%Stats%NumFunCall%accepted,kind=RK) / real(self%Stats%NumFunCall%acceptedRejectedDelayed,kind=RK)
     629             :             msg =   "This is the MCMC sampling efficiency given the accepted, rejected, and delayed-rejection (if any requested) function calls, that is, &
     630         263 :                     &the number of accepted function calls divided by the number of (accepted + rejected + delayed-rejection) function calls."
     631         263 :             call self%reportDesc(msg)
     632             : 
     633             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     634             : 
     635         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     636         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.efficiency.acceptedOverAcceptedRejectedDelayedUnused"
     637         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     638         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) real(self%Stats%NumFunCall%accepted,kind=RK) / real(self%Stats%NumFunCall%acceptedRejectedDelayedUnused,kind=RK)
     639             :             msg =   "This is the MCMC sampling efficiency given the accepted, rejected, delayed-rejection (if any requested), and unused function calls, that is, &
     640         263 :                     &the number of accepted function calls divided by the number of (accepted + rejected + delayed-rejection + unused) function calls."
     641         263 :             call self%reportDesc(msg)
     642             : 
     643             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     644             : 
     645         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     646         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.total"
     647         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     648         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Timer%Time%total
     649         263 :             msg = "This is the total runtime in seconds."
     650         263 :             call self%reportDesc(msg)
     651             : 
     652             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     653             : 
     654         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     655         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.perFuncCallAccepted"
     656         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     657         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Timer%Time%total / real(self%Stats%NumFunCall%accepted,kind=RK)
     658         263 :             msg = "This is the average effective time cost of each accepted function call, in seconds."
     659         263 :             call self%reportDesc(msg)
     660             : 
     661             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     662             : 
     663         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     664         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.perFuncCallAcceptedRejected"
     665         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     666         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Timer%Time%total / real(self%Stats%NumFunCall%acceptedRejected,kind=RK)
     667         263 :             msg = "This is the average effective time cost of each accepted or rejected function call, in seconds."
     668         263 :             call self%reportDesc(msg)
     669             : 
     670             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     671             : 
     672         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     673         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.perFuncCallAcceptedRejectedDelayed"
     674         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     675         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Timer%Time%total / real(self%Stats%NumFunCall%acceptedRejectedDelayed,kind=RK)
     676         263 :             msg = "This is the average effective time cost of each accepted or rejected function call (including delayed-rejections, if any requested), in seconds."
     677         263 :             call self%reportDesc(msg)
     678             : 
     679             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     680             : 
     681         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     682         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.perFuncCallAcceptedRejectedDelayedUnused"
     683         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     684         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Timer%Time%total / real(self%Stats%NumFunCall%acceptedRejectedDelayedUnused,kind=RK)
     685         263 :             msg = "This is the average effective time cost of each accepted or rejected or unused function call (including delayed-rejections, if any requested), in seconds."
     686         263 :             call self%reportDesc(msg)
     687             : 
     688             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     689             : 
     690         263 :             if (self%Image%count==1_IK) then
     691             :                 msg = UNDEFINED ! LCOV_EXCL_LINE
     692             :             else ! LCOV_EXCL_LINE
     693             :                 msg = num2str( self%Stats%avgCommTimePerFunCall ) ! LCOV_EXCL_LINE
     694             :             end if
     695             : 
     696         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     697         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.perInterProcessCommunication"
     698         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     699         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) msg
     700         263 :             msg = "This is the average time cost of inter-process communications per used (accepted or rejected or delayed-rejection) function call, in seconds."
     701         263 :             call self%reportDesc(msg)
     702             : 
     703             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     704             : 
     705         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     706         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.time.perFuncCall"
     707         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     708         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%avgTimePerFunCalInSec
     709         263 :             msg = "This is the average pure time cost of each function call, in seconds."
     710         263 :             call self%reportDesc(msg)
     711             : 
     712             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     713             : 
     714         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     715         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.current.numProcess"
     716         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     717         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Image%count
     718             : #if defined CAF_ENABLED || defined MPI_ENABLED
     719         263 :             if (self%Image%count==1_IK) then
     720             :                 msg =   self%name // " " // &
     721             :                         "is being used in parallel mode but with only one processor. This is computationally inefficient. &
     722           0 :                         &Consider using the serial version of the code or provide more processes at runtime if it is beneficial."
     723             :                 call self%note  ( prefix     = self%brand   &
     724             :                                 , outputUnit = output_unit  &
     725             :                                 , newline    = NLC          &
     726             :                                 , marginTop  = 3_IK         &
     727             :                                 , marginBot  = 0_IK         &
     728           0 :                                 , msg        = msg          )
     729             :             end if
     730             : #endif
     731         263 :             msg = "This is the number of processes (images) used in this simulation."
     732         263 :             call self%reportDesc(msg)
     733             : 
     734             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     735             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% begin speedup compute %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     736             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     737             : 
     738             :             blockSpeedup: block
     739             : 
     740             :                 use Parallelism_mod, only: ForkJoin_type
     741             :                 integer(IK)                 :: imageCount
     742         263 :                 character(:), allocatable   :: formatIn, formatScaling
     743             :                 logical                     :: isForkJoinParallelism
     744         263 :                 type(ForkJoin_type)         :: ForkJoin
     745         263 :                 character(:), allocatable   :: undefinedInfinity
     746             : 
     747         263 :                 if (self%SpecBase%ParallelizationModel%isMultiChain) then
     748          54 :                     undefinedInfinity = "+INFINITY"
     749             :                 else
     750         209 :                     undefinedInfinity = UNDEFINED
     751             :                 end if
     752             : 
     753         263 :                 isForkJoinParallelism = self%Image%count > 1_IK .and. self%SpecBase%ParallelizationModel%isSinglChain
     754             : 
     755         263 :                 formatScaling = "('" // INDENT // "',10(E" // self%LogFile%maxColWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3))" ! ,:,','
     756             : 
     757             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     758             :                 ! compute the effective MCMC efficiency from the processor contributions and the current strong scaling
     759             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     760             : 
     761         263 :                 imageCount = 1_IK
     762         263 :                 if (isForkJoinParallelism) imageCount = self%Image%count
     763             :                 ForkJoin = ForkJoin_type( processCount = imageCount & ! LCOV_EXCL_LINE
     764             :                                         , lenProcessID = self%Stats%NumFunCall%accepted & ! LCOV_EXCL_LINE
     765             :                                         , ProcessID = self%Chain%ProcessID & ! LCOV_EXCL_LINE
     766             :                                         , successProb = mcmcSamplingEfficiency & ! LCOV_EXCL_LINE
     767             :                                         , seqSecTime = epsilon(1._RK) &  ! LCOV_EXCL_LINE ! time cost of the sequential section of the code, which is negligible here
     768             :                                         , parSecTime = self%Stats%avgTimePerFunCalInSec & ! LCOV_EXCL_LINE
     769             :                                         , comSecTime = self%Stats%avgCommTimePerFunCall & ! LCOV_EXCL_LINE
     770         263 :                                         )
     771         263 :                 if (ForkJoin%Err%occurred) then
     772             :                     ! LCOV_EXCL_START
     773             :                     self%Err = ForkJoin%Err
     774             :                     self%Err%msg = PROCEDURE_NAME // self%Err%msg
     775             :                     call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
     776             :                     exit blockLeaderPostProcessing
     777             :                     return
     778             :                     ! LCOV_EXCL_STOP
     779             :                 end if
     780             : 
     781             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     782             : 
     783         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     784         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.processContribution"
     785         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     786         263 :                 block
     787             :                     integer, parameter :: NCOL = 40
     788         263 :                     character(:), allocatable :: formatInteger
     789         263 :                     formatInteger = "('"//INDENT//"',"//num2str(NCOL)//"(I0,:,' '))"
     790        1052 :                     do imageCount = 1, ForkJoin%Contribution%count, NCOL
     791         526 :                         write(self%LogFile%unit,formatInteger) ForkJoin%Contribution%Frequency( imageCount : min( imageCount+NCOL-1, ForkJoin%Contribution%count ) )
     792             :                     end do
     793             :                 end block
     794             :                 msg =   "These are contributions of individual processes to the construction of the MCMC chain. &
     795             :                         &Essentially, they represent the total number of accepted states by the corresponding processor, &
     796             :                         &starting from the first processor to the last. This information is mostly informative in parallel &
     797         263 :                         &Fork-Join (singleChain) simulations."
     798         263 :                 call self%reportDesc(msg)
     799             : 
     800             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     801             : 
     802         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     803         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.processContribution.geometricFit.successProbNormFac"
     804         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     805         263 :                 if (isForkJoinParallelism) then
     806         209 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) ForkJoin%SuccessProb%PowellMinimum%xmin(1), exp(ForkJoin%SuccessProb%PowellMinimum%xmin(2))
     807             :                 else
     808          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) UNDEFINED
     809             :                 end if
     810             :                 msg =   "These are the parameters of the Geometric fit to the distribution of the processor contributions &
     811             :                         &to the construction of the MCMC chain (the processor contributions are reported in the first column &
     812             :                         &of the output chain file. The fit has the following form: "//NLC//NLC// &
     813             :                         "    ProcessConstribution(i) = successProbNormFac(1) * successProbNormFac(2) * (1-successProbNormFac(1))^(i-1)"//NLC// &
     814             :                         "                            / (1 - (1 - successProbNormFac(1))^numProcess)"//NLC//NLC// &
     815             :                         "where i is the ID of the processor (starting from index 1), numProcess is the total number of processes &
     816             :                         &used in the simulation, and successProbNormFac(1) is equivalent to an effective MCMC sampling efficiency &
     817             :                         &computed from contributions of individual processes to the MCMC chain and successProbNormFac(2) is a &
     818         263 :                         &normalization constant."
     819         263 :                 call self%reportDesc(msg)
     820             : 
     821             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     822             : 
     823         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     824         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.current.speedup"
     825         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     826         263 :                 write(self%LogFile%unit,GENERIC_TABBED_FORMAT) ForkJoin%Speedup%current
     827         263 :                 msg = "This is the estimated maximum speedup gained via "//self%SpecBase%ParallelizationModel%val//" parallelization model compared to serial mode."
     828         263 :                 call self%reportDesc(msg)
     829             : 
     830             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     831             : 
     832         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     833         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.optimal.current.numProcess"
     834         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     835         263 :                 if (isForkJoinParallelism) then
     836         209 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) ForkJoin%Speedup%Maximum%nproc
     837             :                 else
     838          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) undefinedInfinity
     839             :                 end if
     840         263 :                 msg = "This is the predicted optimal number of physical computing processes for "//self%SpecBase%ParallelizationModel%val//" parallelization model, given the current MCMC sampling efficiency."
     841         263 :                 call self%reportDesc(msg)
     842             : 
     843             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     844             : 
     845         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     846         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.optimal.current.speedup"
     847         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     848         263 :                 if (isForkJoinParallelism) then
     849         209 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) ForkJoin%Speedup%Maximum%value
     850         209 :                     msg = ""
     851         209 :                     if (ForkJoin%Speedup%current<1._RK) then
     852         209 :                         formatIn = "(g0.6)"
     853             :                         msg =   "The time cost of calling the user-provided objective function must be at least " // &
     854             :                                 num2str(1._RK/ForkJoin%Speedup%current,formatIn) // " times more (that is, ~" // &
     855             :                                 num2str(10**6*self%Stats%avgTimePerFunCalInSec/ForkJoin%Speedup%current,formatIn) // &
     856             :                                 " microseconds) to see any performance benefits from " // &
     857         209 :                                 self%SpecBase%ParallelizationModel%val // " parallelization model for this simulation. "
     858         209 :                         if (ForkJoin%Speedup%Maximum%nproc==1_IK) then
     859             :                             msg = msg// "Consider simulating in the serial mode in the future (if used within &
     860         208 :                                         &the same computing environment and with the same configuration as used here)."
     861             :                         else
     862             :                             msg = msg// "Consider simulating on " // num2str(ForkJoin%Speedup%Maximum%nproc) // " processors in the future &
     863           1 :                                         &(if used within the same computing environment and with the same configuration as used here)."
     864             :                         end if
     865             :                         call self%note  ( prefix   = self%brand     &
     866             :                                         , outputUnit = output_unit  &
     867             :                                         , newline    = NLC          &
     868             :                                         , marginTop  = 3_IK         &
     869             :                                         , marginBot  = 0_IK         &
     870         209 :                                         , msg        = msg          )
     871         209 :                         msg = NLC // msg
     872             :                     end if
     873             :                 else
     874          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) undefinedInfinity
     875             :                 end if
     876         263 :                 msg = "This is the predicted optimal maximum speedup gained via "//self%SpecBase%ParallelizationModel%val//" parallelization model, given the current MCMC sampling efficiency." // msg
     877         263 :                 call self%reportDesc(msg)
     878             : 
     879             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     880             : 
     881         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     882         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.optimal.current.scaling.strong.speedup"
     883         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     884         263 :                 if (isForkJoinParallelism) then
     885         418 :                     do imageCount = 1, ForkJoin%Speedup%count, 10
     886         418 :                         write(self%LogFile%unit,formatScaling) ForkJoin%Speedup%Scaling(imageCount:min(imageCount+9_IK,ForkJoin%Speedup%count))
     887             :                     end do
     888             :                 else
     889          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) UNDEFINED
     890             :                 end if
     891             :                 msg =   "This is the predicted strong-scaling speedup behavior of the "//self%SpecBase%ParallelizationModel%val//" parallelization model, &
     892         263 :                         &given the current MCMC sampling efficiency, for increasing numbers of processes, starting from a single process."
     893         263 :                 call self%reportDesc(msg)
     894             : 
     895             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     896             :                 ! compute the absolute optimal parallelism efficiency under any MCMC sampling efficiency
     897             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     898             : 
     899         263 :                 if (isForkJoinParallelism) then
     900             :                     ForkJoin = ForkJoin_type( processCount = self%Image%count & ! LCOV_EXCL_LINE
     901             :                                             , lenProcessID = self%Stats%NumFunCall%accepted & ! LCOV_EXCL_LINE
     902             :                                             , ProcessID = self%Chain%ProcessID & ! LCOV_EXCL_LINE
     903             :                                             , successProb = 0._RK & ! LCOV_EXCL_LINE
     904             :                                             , seqSecTime = epsilon(1._RK) &  ! LCOV_EXCL_LINE ! time cost of the sequential section of the code, which is negligible here
     905             :                                             , parSecTime = self%Stats%avgTimePerFunCalInSec & ! LCOV_EXCL_LINE
     906             :                                             , comSecTime = self%Stats%avgCommTimePerFunCall & ! LCOV_EXCL_LINE
     907         209 :                                             )
     908         209 :                     if (ForkJoin%Err%occurred) then
     909             :                         ! LCOV_EXCL_START
     910             :                         self%Err = ForkJoin%Err
     911             :                         self%Err%msg = PROCEDURE_NAME // self%Err%msg
     912             :                         call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
     913             :                         exit blockLeaderPostProcessing
     914             :                         return
     915             :                         ! LCOV_EXCL_STOP
     916             :                     end if
     917             :                 end if ! otherwise, use the previously-generated ForkJoin
     918             : 
     919             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     920             : 
     921         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     922         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.optimal.absolute.numProcess"
     923             :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) ! LCOV_EXCL_LINE
     924         263 :                 if (isForkJoinParallelism) then
     925         209 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) ForkJoin%Speedup%Maximum%nproc
     926             :                 else
     927          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) undefinedInfinity
     928             :                 end if
     929         263 :                 msg = "This is the predicted absolute optimal number of physical computing processes for "//self%SpecBase%ParallelizationModel%val//" parallelization model, under any MCMC sampling efficiency."
     930         263 :                 call self%reportDesc(msg)
     931             : 
     932             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     933             : 
     934         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     935         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.optimal.absolute.speedup"
     936             :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) ! LCOV_EXCL_LINE
     937         263 :                 if (isForkJoinParallelism) then
     938         209 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) ForkJoin%Speedup%Maximum%value
     939             :                 else
     940          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) undefinedInfinity
     941             :                 end if
     942             :                 msg =   "This is the predicted absolute optimal maximum speedup gained via "//self%SpecBase%ParallelizationModel%val//" parallelization model, under any MCMC sampling efficiency. &
     943             :                         &This simulation will likely NOT benefit from any additional computing processors beyond the predicted absolute optimal number, " // num2str(ForkJoin%Speedup%Maximum%nproc) // ", &
     944             :                         &in the above. This is true for any value of MCMC sampling efficiency. Keep in mind that the predicted absolute optimal number of processors is just an estimate &
     945             :                         &whose accuracy depends on many runtime factors, including the topology of the communication network being used, the number of processors per node, &
     946         263 :                         &and the number of tasks to each processor or node."
     947         263 :                 call self%reportDesc(msg)
     948             : 
     949             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     950             : 
     951         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     952         263 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.parallelism.optimal.absolute.scaling.strong.speedup"
     953             :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) ! LCOV_EXCL_LINE
     954         263 :                 if (isForkJoinParallelism) then
     955         418 :                     do imageCount = 1, ForkJoin%Speedup%count, 10
     956         418 :                         write(self%LogFile%unit,formatScaling) ForkJoin%Speedup%Scaling(imageCount:min(imageCount+9_IK,ForkJoin%Speedup%count))
     957             :                     end do
     958             :                 else
     959          54 :                     write(self%LogFile%unit,GENERIC_TABBED_FORMAT) UNDEFINED
     960             :                 end if
     961             :                 msg =   "This is the predicted absolute strong-scaling speedup behavior of the "//self%SpecBase%ParallelizationModel%val//" parallelization model, &
     962         263 :                         &under any MCMC sampling efficiency, for increasing numbers of processes, starting from a single process."
     963         526 :                 call self%reportDesc(msg)
     964             : 
     965             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     966             : 
     967             :             end block blockSpeedup
     968             : 
     969             : 
     970             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     971             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end speedup compute %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     972             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     973             : 
     974             : 
     975         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     976         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.compact.burnin.location.likelihoodBased"
     977         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     978         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%BurninLoc%compact
     979         263 :             msg = "This is the burnin location in the compact chain, based on the occurrence likelihood."
     980         263 :             call self%reportDesc(msg)
     981             : 
     982             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     983             : 
     984         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     985         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.compact.burnin.location.adaptationBased"
     986         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     987         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%AdaptationBurninLoc%compact
     988         263 :             msg = "This is the burnin location in the compact chain, based on the value of burninAdaptationMeasure simulation specification."
     989         263 :             call self%reportDesc(msg)
     990             : 
     991             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     992             : 
     993         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     994         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.burnin.location.likelihoodBased"
     995         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
     996         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%BurninLoc%verbose
     997         263 :             msg = "This is the burnin location in the verbose (Markov) chain, based on the occurrence likelihood."
     998         263 :             call self%reportDesc(msg)
     999             : 
    1000             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1001             : 
    1002         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1003         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.burnin.location.adaptationBased"
    1004         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1005         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%AdaptationBurninLoc%verbose
    1006         263 :             msg = "This is the burnin location in the verbose (Markov) chain, based on the value of burninAdaptationMeasure simulation specification."
    1007         263 :             call self%reportDesc(msg)
    1008             : 
    1009             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1010             : 
    1011             :             ! reset BurninLoc to the maximum value
    1012             : 
    1013         263 :             if (self%Stats%AdaptationBurninLoc%compact>self%Stats%BurninLoc%compact) then
    1014           1 :                 self%Stats%BurninLoc%compact = self%Stats%AdaptationBurninLoc%compact
    1015           1 :                 self%Stats%BurninLoc%verbose = self%Stats%AdaptationBurninLoc%verbose
    1016             :             end if
    1017             : 
    1018             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1019             : 
    1020         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1021         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.logFunc.max"
    1022         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1023         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%LogFuncMode%val
    1024         263 :             msg = "This is the maximum logFunc value (the maximum of the user-specified objective function)."
    1025         263 :             call self%reportDesc(msg)
    1026             : 
    1027             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1028             : 
    1029         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1030         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.compact.logFunc.max.location"
    1031         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1032         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%LogFuncMode%Loc%compact
    1033         263 :             msg = "This is the location of the first occurrence of the maximum logFunc in the compact chain."
    1034         263 :             call self%reportDesc(msg)
    1035             : 
    1036             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1037             : 
    1038         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1039         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.logFunc.max.location"
    1040         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1041         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%LogFuncMode%Loc%verbose
    1042         263 :             msg = "This is the location of the first occurrence of the maximum logFunc in the verbose (Markov) chain."
    1043         263 :             call self%reportDesc(msg)
    1044             : 
    1045             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1046             : 
    1047         263 :             formatAllReal = "('" // INDENT // "',*(E" // self%LogFile%maxColWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3))"
    1048             : 
    1049         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1050         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.logFunc.max.state"
    1051         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1052         683 :             write(self%LogFile%unit,self%LogFile%format) (trim(adjustl(self%SpecBase%VariableNameList%Val(i))), i=1, ndim)
    1053         263 :             write(self%LogFile%unit,formatAllReal) self%Stats%LogFuncMode%Crd
    1054         263 :             msg = "This is the coordinates, within the domain of the user-specified objective function, where the maximum logFunc occurs."
    1055         263 :             call self%reportDesc(msg)
    1056             : 
    1057             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1058             :             ! Compute the statistical properties of the MCMC chain
    1059             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1060             : 
    1061         263 :             if (self%Image%isFirst) then
    1062             :                 call self%note  ( prefix        = self%brand    &
    1063             :                                 , outputUnit    = output_unit   &
    1064             :                                 , newline       = NLC           &
    1065             :                                 , marginTop     = 3_IK          &
    1066         227 :                                 , msg           = "Computing the statistical properties of the Markov chain..." )
    1067             :             end if
    1068             : 
    1069             :             call self%Decor%writeDecoratedText  ( text = "\nThe statistical properties of the Markov chain\n" &
    1070             :                                                 , marginTop = 1_IK  &
    1071             :                                                 , marginBot = 1_IK  &
    1072             :                                                 , newline = "\n"    &
    1073         263 :                                                 , outputUnit = self%LogFile%unit )
    1074             : 
    1075       94279 :             self%Stats%Chain%count = sum(self%Chain%Weight(self%Stats%BurninLoc%compact:self%Chain%count%compact))
    1076             : 
    1077             :             ! compute the covariance and correlation upper-triangle matrices
    1078             : 
    1079         263 :             if (allocated(self%Stats%Chain%Mean)) deallocate(self%Stats%Chain%Mean); allocate(self%Stats%Chain%Mean(ndim))
    1080         263 :             if (allocated(self%Stats%Chain%CovMat)) deallocate(self%Stats%Chain%CovMat); allocate(self%Stats%Chain%CovMat(ndim,ndim))
    1081             :             call getWeiSamCovUppMeanTrans   ( np = self%Chain%count%compact - self%Stats%BurninLoc%compact + 1_IK & ! LCOV_EXCL_LINE
    1082             :                                             , sumWeight = self%Stats%Chain%count & ! LCOV_EXCL_LINE
    1083             :                                             , nd = ndim & ! LCOV_EXCL_LINE
    1084             :                                             , Point = self%Chain%State(1:ndim,self%Stats%BurninLoc%compact:self%Chain%count%compact) & ! LCOV_EXCL_LINE
    1085             :                                             , Weight = self%Chain%Weight(self%Stats%BurninLoc%compact:self%Chain%count%compact) & ! LCOV_EXCL_LINE
    1086             :                                             , CovMatUpper = self%Stats%Chain%CovMat & ! LCOV_EXCL_LINE
    1087             :                                             , Mean = self%Stats%Chain%Mean & ! LCOV_EXCL_LINE
    1088         263 :                                             )
    1089             : 
    1090        1431 :             self%Stats%Chain%CorMat = getCorMatUpperFromCovMatUpper(nd=ndim,CovMatUpper=self%Stats%Chain%CovMat)
    1091             : 
    1092             :             ! transpose the covariance and correlation matrices
    1093             : 
    1094         683 :             do i = 1, ndim
    1095         420 :                 self%Stats%Chain%CorMat(i,i) = 1._RK
    1096         577 :                 self%Stats%Chain%CorMat(i+1:ndim,i) = self%Stats%Chain%CorMat(i,i+1:ndim)
    1097         840 :                 self%Stats%Chain%CovMat(i+1:ndim,i) = self%Stats%Chain%CovMat(i,i+1:ndim)
    1098             :             end do
    1099             : 
    1100             :             ! compute the quantiles
    1101             : 
    1102         263 :             if (allocated(self%Stats%Chain%Quantile)) deallocate(self%Stats%Chain%Quantile)
    1103         263 :             allocate(self%Stats%Chain%Quantile(QPROB%count,ndim))
    1104      158322 :             ContiguousChain = transpose(self%Chain%State(1:ndim,self%Stats%BurninLoc%compact:self%Chain%count%compact)) ! avoid temporary array creation and the warning message in debug mode
    1105         683 :             do i = 1, ndim
    1106        2520 :                     self%Stats%Chain%Quantile(1:QPROB%count,i) = getQuantile( np = self%Chain%count%compact - self%Stats%BurninLoc%compact + 1_IK &
    1107             :                                                                             , nq = QPROB%count & ! LCOV_EXCL_LINE
    1108             :                                                                             , SortedQuantileProbability = QPROB%Value & ! LCOV_EXCL_LINE
    1109             :                                                                             , Point = ContiguousChain(:,i) & ! LCOV_EXCL_LINE
    1110        1680 :                                                                             , Weight = self%Chain%Weight(self%Stats%BurninLoc%compact:self%Chain%count%compact) &
    1111             :                                                                             , sumWeight = self%Stats%Chain%count & ! LCOV_EXCL_LINE
    1112        4463 :                                                                             )
    1113             :             end do
    1114             : 
    1115             :             ! report the MCMC chain statistics
    1116             : 
    1117             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1118             : 
    1119         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1120         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.length.burninExcluded"
    1121         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1122         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%Chain%count
    1123         263 :             msg = "This is the length of the verbose (Markov) Chain excluding burnin."
    1124         263 :             call self%reportDesc(msg)
    1125             : 
    1126             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1127             : 
    1128         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1129         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.avgStd"
    1130         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1131         263 :             write(self%LogFile%unit,self%LogFile%format) "variableName", "Mean", "Standard Deviation"
    1132         683 :             do i = 1, ndim
    1133         683 :                 write(self%LogFile%unit,formatStrReal) trim(adjustl(self%SpecBase%VariableNameList%Val(i))), self%Stats%Chain%Mean(i), sqrt(self%Stats%Chain%CovMat(i,i))
    1134             :             end do
    1135         263 :             msg = "This is the mean and standard deviation of the verbose (Markov) chain variables."
    1136         263 :             call self%reportDesc(msg)
    1137             : 
    1138             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1139             : 
    1140         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1141         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.covmat"
    1142         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1143         683 :             write(self%LogFile%unit,self%LogFile%format) "", (trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1144         683 :             do i = 1, ndim
    1145         683 :                 write(self%LogFile%unit,formatStrReal) trim(adjustl(self%SpecBase%VariableNameList%Val(i))), self%Stats%Chain%CovMat(1:ndim,i)
    1146             :             end do
    1147         263 :             msg = "This is the covariance matrix of the verbose (Markov) chain."
    1148         263 :             call self%reportDesc(msg)
    1149             : 
    1150             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1151             : 
    1152         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1153         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.cormat"
    1154         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1155         683 :             write(self%LogFile%unit,self%LogFile%format) "", (trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1156         683 :             do i = 1, ndim
    1157         683 :                 write(self%LogFile%unit,formatStrReal) trim(adjustl(self%SpecBase%VariableNameList%Val(i))), self%Stats%Chain%CorMat(1:ndim,i)
    1158             :             end do
    1159         263 :             msg = "This is the correlation matrix of the verbose (Markov) chain."
    1160         263 :             call self%reportDesc(msg)
    1161             : 
    1162             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1163             : 
    1164         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1165         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.verbose.quantile"
    1166         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1167         683 :             write(self%LogFile%unit,self%LogFile%format) "Quantile", (trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1168        2630 :             do iq = 1, QPROB%count
    1169        6410 :                 write(self%LogFile%unit,formatStrReal) trim(adjustl(QPROB%Name(iq))), (self%Stats%Chain%Quantile(iq,i),i=1,ndim)
    1170             :             end do
    1171         263 :             msg = "This is the quantiles table of the variables of the verbose (Markov) chain."
    1172         263 :             call self%reportDesc(msg)
    1173             : 
    1174             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1175             :             ! Generate the i.i.d. sample statistics and output file (if requested)
    1176             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1177             : 
    1178             :             ! report refined sample statistics, and generate output refined sample if requested.
    1179             : 
    1180         263 :             if (self%Image%isFirst) then
    1181             :                 call self%note  ( prefix        = self%brand    &
    1182             :                                 , outputUnit    = output_unit   &
    1183             :                                 , newline       = NLC           &
    1184         227 :                                 , msg           = "Computing the final decorrelated sample size..." )
    1185             :             end if
    1186             : 
    1187             :             call self%RefinedChain%get  ( CFC                       = self%Chain                                  &
    1188             :                                         , Err                       = self%Err                                    &
    1189             :                                         , burninLoc                 = self%Stats%BurninLoc%compact                &
    1190             :                                         , sampleRefinementCount     = self%SpecMCMC%SampleRefinementCount%val     &
    1191             :                                         , sampleRefinementMethod    = self%SpecMCMC%SampleRefinementMethod%val    &
    1192         263 :                                         )
    1193             : 
    1194         263 :             if (self%Err%occurred) then
    1195             :                 ! LCOV_EXCL_START
    1196             :                 self%Err%msg = PROCEDURE_NAME // self%Err%msg
    1197             :                 call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1198             :                 exit blockLeaderPostProcessing
    1199             :                 return
    1200             :                 ! LCOV_EXCL_STOP
    1201             :             end if
    1202             : 
    1203             :             ! compute the maximum integrated autocorrelation times for each variable
    1204             : 
    1205             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1206             : 
    1207         263 :             formatStr = "('" // INDENT // "',2I" // self%LogFile%maxColWidth%str // ",*(E" // self%LogFile%maxColWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3))"
    1208             : 
    1209         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1210         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.iac"
    1211         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1212         683 :             write(self%LogFile%unit,self%LogFile%format) "RefinementStage","SampleSize","IAC_SampleLogFunc",("IAC_"//trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1213         957 :             do i = 0, self%RefinedChain%numRefinement
    1214         957 :                 write(self%LogFile%unit,formatStr) i, self%RefinedChain%Count(i)%Verbose, self%RefinedChain%IAC(0:ndim,i)
    1215             :             end do
    1216         263 :             msg = "This is the table of the Integrated Autocorrelation (IAC) of individual variables in the verbose (Markov) chain, at increasing stages of chain refinements."
    1217         263 :             if (self%RefinedChain%numRefinement==0_IK) then
    1218             :                 msg = msg // NLC // "The user-specified sampleRefinementCount ("// num2str(self%SpecMCMC%SampleRefinementCount%val) // ") &
    1219             :                                     &is too small to ensure an accurate computation of the decorrelated i.i.d. effective sample size. &
    1220          10 :                                     &No refinement of the Markov chain was performed."
    1221             :             end if
    1222         263 :             call self%reportDesc(msg)
    1223             : 
    1224             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1225             : 
    1226             :             ! report the final Effective Sample Size (ESS) based on IAC
    1227             : 
    1228             :             !blockEffectiveSampleSize: associate( effectiveSampleSize => sum(self%RefinedChain%Weight(1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact)) )
    1229         263 :             effectiveSampleSize = self%RefinedChain%Count(self%RefinedChain%numRefinement)%verbose
    1230             : 
    1231             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1232             : 
    1233         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1234         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.ess"
    1235         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1236         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) effectiveSampleSize
    1237         263 :             msg = "This is the estimated Effective (decorrelated) Sample Size (ESS) of the final refined chain."
    1238         263 :             call self%reportDesc(msg)
    1239             : 
    1240             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1241             : 
    1242         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1243         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.efficiency.essOverAccepted"
    1244         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1245         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) real(effectiveSampleSize,kind=RK) / real(self%Stats%NumFunCall%accepted,kind=RK)
    1246             :             msg =   "This is the effective MCMC sampling efficiency given the accepted function calls, that is, &
    1247         263 :                     &the final refined effective sample size (ESS) divided by the number of accepted function calls."
    1248         263 :             call self%reportDesc(msg)
    1249             : 
    1250             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1251             : 
    1252         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1253         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.efficiency.essOverAcceptedRejected"
    1254         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1255         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) real(effectiveSampleSize,kind=RK) / real(self%Stats%NumFunCall%acceptedRejected,kind=RK)
    1256             :             msg =   "This is the effective MCMC sampling efficiency given the accepted and rejected function calls, that is, &
    1257         263 :                     &the final refined effective sample size (ESS) divided by the number of (accepted + rejected) function calls."
    1258         263 :             call self%reportDesc(msg)
    1259             : 
    1260             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1261             : 
    1262         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1263         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.efficiency.essOverAcceptedRejectedDelayed"
    1264         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1265         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) real(effectiveSampleSize,kind=RK) / real(self%Stats%NumFunCall%acceptedRejectedDelayed,kind=RK)
    1266             :             msg =   "This is the effective MCMC sampling efficiency given the accepted, rejected, and delayed-rejection (if any requested) function calls, that is, &
    1267         263 :                     &the final refined effective sample size (ESS) divided by the number of (accepted + rejected + delayed-rejection) function calls."
    1268         263 :             call self%reportDesc(msg)
    1269             : 
    1270             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1271             : 
    1272         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1273         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.efficiency.essOverAcceptedRejectedDelayedUnused"
    1274         263 :             write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1275         263 :             write(self%LogFile%unit,GENERIC_TABBED_FORMAT) real(effectiveSampleSize,kind=RK) / real(self%Stats%NumFunCall%acceptedRejectedDelayedUnused,kind=RK)
    1276             :             msg =   "This is the effective MCMC sampling efficiency given the accepted, rejected, delayed-rejection (if any requested), and unused function calls, that is, &
    1277         263 :                     &the final refined effective sample size (ESS) divided by the number of (accepted + rejected + delayed-rejection + unused) function calls."
    1278         263 :             call self%reportDesc(msg)
    1279             : 
    1280             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1281             : 
    1282             :             !end associate blockEffectiveSampleSize
    1283             : 
    1284             :             ! generate output refined sample if requested
    1285             : 
    1286         263 :             blockSampleFileGeneration: if (self%SpecBase%SampleSize%val==0_IK) then
    1287             : 
    1288             :                 call self%note  ( prefix        = self%brand        & ! LCOV_EXCL_LINE
    1289             :                                 , outputUnit    = self%LogFile%unit & ! LCOV_EXCL_LINE
    1290             :                                 , newline       = NLC               & ! LCOV_EXCL_LINE
    1291           2 :                                 , msg           = "Skipping the generation of the decorrelated sample and output file, as requested by the user..." )
    1292             : 
    1293             :             else blockSampleFileGeneration
    1294             : 
    1295             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1296             :                 ! sample file generation report
    1297             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1298             : 
    1299             :                 ! report to the report-file(s)
    1300             : 
    1301             :                 call self%note  ( prefix        = self%brand        & ! LCOV_EXCL_LINE
    1302             :                                 , outputUnit    = self%LogFile%unit & ! LCOV_EXCL_LINE
    1303             :                                 , newline       = NLC               & ! LCOV_EXCL_LINE
    1304         261 :                                 , msg           = "Generating the output " // self%SampleFile%suffix // " file:"//NLC // self%SampleFile%Path%original )
    1305             : 
    1306             : 
    1307         261 :                 if (self%Image%isFirst) then
    1308             : 
    1309             :                     ! print the message for the generating the output sample file on the first image
    1310             : 
    1311             :                     call self%note  ( prefix     = self%brand       & ! LCOV_EXCL_LINE
    1312             :                                     , outputUnit = output_unit      & ! LCOV_EXCL_LINE
    1313             :                                     , newline    = NLC              & ! LCOV_EXCL_LINE
    1314             :                                     , marginBot  = 0_IK             & ! LCOV_EXCL_LINE
    1315         225 :                                     , msg        = "Generating the output " // self%SampleFile%suffix // " file:" )
    1316             : 
    1317             :                     call self%note  ( prefix     = self%brand       &
    1318             :                                     , outputUnit = output_unit      &
    1319             :                                     , newline    = NLC              &
    1320             :                                     , marginTop  = 0_IK             &
    1321             :                                     , marginBot  = 0_IK             &
    1322         225 :                                     , msg = self%SampleFile%Path%original )
    1323             : 
    1324             :                     ! print the message for the generating the output sample file on the rest of the images in order
    1325             : 
    1326             : #if defined CAF_ENABLED || defined MPI_ENABLED
    1327         225 :                     if (self%SpecBase%ParallelizationModel%isMultiChain) then
    1328             :                         block
    1329             :                             use String_mod, only: replaceStr, num2str
    1330             :                             integer(IK) :: imageID
    1331          54 :                             do imageID = 2, self%Image%count
    1332             :                                 call self%note  ( prefix = self%brand       &
    1333             :                                                 , outputUnit = output_unit  &
    1334             :                                                 , newline = NLC             &
    1335             :                                                 , marginTop = 0_IK          &
    1336             :                                                 , marginBot = 0_IK          &
    1337          54 :                                                 , msg = replaceStr( string = self%SampleFile%Path%original, search = "process_1", substitute = "process_"//num2str(imageID) ) )
    1338             :                             end do
    1339             :                         end block
    1340             :                     end if
    1341             : #endif
    1342         225 :                     call self%Decor%write(output_unit,0,1)
    1343             : 
    1344             :                 end if
    1345             : 
    1346             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1347             :                 ! begin sample file generation
    1348             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1349             : 
    1350         261 :                 if (self%SpecBase%SampleSize%val/=-1_IK) then
    1351             : 
    1352          85 :                     if (self%SpecBase%SampleSize%val<0_IK) then
    1353          26 :                         self%SpecBase%SampleSize%abs = abs(self%SpecBase%SampleSize%abs) * self%RefinedChain%Count(self%RefinedChain%numRefinement)%verbose
    1354             :                     end if
    1355             : 
    1356             :                     ! regenerate the refined sample, this time with the user-specified sample size.
    1357             : 
    1358             :                     call self%RefinedChain%get  ( CFC                       = self%Chain &
    1359             :                                                 , Err                       = self%Err &
    1360             :                                                 , burninLoc                 = self%Stats%BurninLoc%compact &
    1361             :                                                 , refinedChainSize          = self%SpecBase%SampleSize%abs &
    1362             :                                                 , sampleRefinementCount     = self%SpecMCMC%SampleRefinementCount%val     &
    1363             :                                                 , sampleRefinementMethod    = self%SpecMCMC%SampleRefinementMethod%val    &
    1364          85 :                                                 )
    1365          85 :                     if (self%Err%occurred) then
    1366             :                         ! LCOV_EXCL_START
    1367             :                         self%Err%msg = PROCEDURE_NAME // self%Err%msg
    1368             :                         call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1369             :                         exit blockLeaderPostProcessing
    1370             :                         return
    1371             :                         ! LCOV_EXCL_STOP
    1372             :                     end if
    1373             : 
    1374             :                 end if
    1375             : 
    1376             :                 ! open the output sample file
    1377             : 
    1378         261 :                 self%SampleFile%unit = 3000001 + self%Image%id  ! for some unknown reason, if newunit is used, GFortran opens the file as an internal file
    1379             :                 open( unit      = self%SampleFile%unit            &
    1380             :                     , file      = self%SampleFile%Path%original   &
    1381             :                     , status    = self%SampleFile%status          &
    1382             :                     , iostat    = self%SampleFile%Err%stat        &
    1383             : #if defined INTEL_COMPILER_ENABLED && defined OS_IS_WINDOWS
    1384             :                     , SHARED &
    1385             : #endif
    1386         261 :                     , position  = self%SampleFile%Position%value  )
    1387         261 :                 self%Err = self%SampleFile%getOpenErr(self%SampleFile%Err%stat)
    1388         261 :                 if (self%Err%occurred) then
    1389             :                     ! LCOV_EXCL_START
    1390             :                     self%Err%msg = PROCEDURE_NAME//": Error occurred while opening the "//self%name//" "//self%SampleFile%suffix//" file='"//self%SampleFile%Path%original//"'. "
    1391             :                     call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1392             :                     exit blockLeaderPostProcessing
    1393             :                     return
    1394             :                     ! LCOV_EXCL_STOP
    1395             :                 end if
    1396             : 
    1397             :                 ! determine the sample file's contents' format
    1398             : 
    1399         261 :                 if (self%SpecBase%OutputColumnWidth%val>0) then
    1400           2 :                     formatStr = "(*(E"//self%SpecBase%OutputColumnWidth%str//"."//self%SpecBase%OutputRealPrecision%str//"E3,:,'"//self%SpecBase%OutputDelimiter%val//"'))"
    1401             :                 else
    1402         259 :                     formatStr = self%SampleFile%format
    1403             :                 end if
    1404             : 
    1405             :                 ! write to the output sample file
    1406             : 
    1407         261 :                 call self%RefinedChain%write(self%SampleFile%unit,self%SampleFile%format,formatStr)
    1408         261 :                 close(self%SampleFile%unit)
    1409             : 
    1410             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1411             :                 ! Compute the statistical properties of the refined sample
    1412             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1413             : 
    1414         261 :                 if (self%Image%isFirst) then
    1415             :                     call self%note  ( prefix        = self%brand        &
    1416             :                                     , outputUnit    = output_unit       &
    1417             :                                     , newline       = NLC               &
    1418             :                                     , marginTop     = 2_IK              &
    1419         225 :                                     , msg           = "Computing the statistical properties of the final refined sample..." )
    1420             :                 end if
    1421             : 
    1422             :                 call self%Decor%writeDecoratedText  ( text = "\nThe statistical properties of the final refined sample \n" &
    1423             :                                                     , marginTop = 1_IK  &
    1424             :                                                     , marginBot = 1_IK  &
    1425             :                                                     , newline = "\n"    &
    1426         261 :                                                     , outputUnit = self%LogFile%unit )
    1427             : 
    1428         261 :                 self%Stats%Sample%count = self%RefinedChain%Count(self%RefinedChain%numRefinement)%verbose
    1429             : 
    1430             :                 ! compute the covariance and correlation upper-triangle matrices
    1431             : 
    1432         261 :                 if (allocated(self%Stats%Sample%Mean)) deallocate(self%Stats%Sample%Mean); allocate(self%Stats%Sample%Mean(ndim))
    1433         261 :                 if (allocated(self%Stats%Sample%CovMat)) deallocate(self%Stats%Sample%CovMat); allocate(self%Stats%Sample%CovMat(ndim,ndim))
    1434         261 :                 if (self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact > ndim + 1_IK) then
    1435      123336 :                     ContiguousChain = self%RefinedChain%LogFuncState(1:ndim,1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact)
    1436         508 :                     call getWeiSamCovUppMeanTrans   ( np = self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact &
    1437         508 :                                                     , sumWeight = self%RefinedChain%Count(self%RefinedChain%numRefinement)%verbose &
    1438             :                                                     , nd = ndim & ! LCOV_EXCL_LINE
    1439             :                                                     , Point = ContiguousChain & ! LCOV_EXCL_LINE
    1440             :                                                     , Weight = self%RefinedChain%Weight(1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact) & ! LCOV_EXCL_LINE
    1441             :                                                     , CovMatUpper = self%Stats%Sample%CovMat & ! LCOV_EXCL_LINE
    1442             :                                                     , Mean = self%Stats%Sample%Mean & ! LCOV_EXCL_LINE
    1443         254 :                                                     )
    1444        1376 :                     self%Stats%Sample%CorMat = getCorMatUpperFromCovMatUpper(nd=ndim,CovMatUpper=self%Stats%Sample%CovMat)
    1445             : 
    1446             :                 else
    1447             :                     if (allocated(self%Stats%Sample%CovMat)) deallocate(self%Stats%Sample%CovMat) ! LCOV_EXCL_LINE
    1448          49 :                     allocate(self%Stats%Sample%CovMat(ndim,ndim), source = POSINF_RK)
    1449          49 :                     self%Stats%Sample%CorMat = getEye(ndim,ndim)
    1450             :                     self%Stats%Sample%Mean   = getMean  ( nd = ndim &
    1451          14 :                                                         , np = self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact &
    1452             :                                                         , Point = self%RefinedChain%LogFuncState(1:ndim,1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact) & ! LCOV_EXCL_LINE
    1453          42 :                                                         , Weight = self%RefinedChain%Weight(1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact) &
    1454          34 :                                                         )
    1455             :                 end if
    1456             : 
    1457             :                 ! transpose the covariance and correlation matrices
    1458             : 
    1459         679 :                 do i = 1, ndim
    1460         418 :                     self%Stats%Sample%CorMat(i,i) = 1._RK
    1461         575 :                     self%Stats%Sample%CorMat(i+1:ndim,i) = self%Stats%Sample%CorMat(i,i+1:ndim)
    1462         836 :                     self%Stats%Sample%CovMat(i+1:ndim,i) = self%Stats%Sample%CovMat(i,i+1:ndim)
    1463             :                 end do
    1464             : 
    1465             :                 ! compute the quantiles
    1466             : 
    1467       78756 :                 ContiguousChain = transpose(self%RefinedChain%LogFuncState(1:ndim,1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact)) ! avoid temporary array creation and the warning message in debug mode
    1468         261 :                 if (allocated(self%Stats%Sample%Quantile)) deallocate(self%Stats%Sample%Quantile)
    1469         261 :                 allocate(self%Stats%Sample%Quantile(QPROB%count,ndim))
    1470         679 :                 do i = 1, ndim
    1471        3344 :                     self%Stats%Sample%Quantile(1:QPROB%count,i) = getQuantile   ( np = self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact &
    1472             :                                                                                 , nq = QPROB%count & ! LCOV_EXCL_LINE
    1473             :                                                                                 , SortedQuantileProbability = QPROB%Value & ! LCOV_EXCL_LINE
    1474             :                                                                                 , Point = ContiguousChain(:,i) & ! LCOV_EXCL_LINE
    1475             :                                                                                 , Weight = self%RefinedChain%Weight(1:self%RefinedChain%Count(self%RefinedChain%numRefinement)%compact) & ! LCOV_EXCL_LINE
    1476         836 :                                                                                 , sumWeight = self%RefinedChain%Count(self%RefinedChain%numRefinement)%verbose &
    1477        4441 :                                                                                 )
    1478             :                 end do
    1479             : 
    1480             :                 ! report the refined chain statistics
    1481             : 
    1482             :                 !formatStr = "(1A" // self%LogFile%maxColWidth%str // ",*(E" // self%LogFile%maxColWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "))"
    1483             : 
    1484             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1485             : 
    1486         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1487         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.length"
    1488         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1489         261 :                 write(self%LogFile%unit,GENERIC_TABBED_FORMAT) self%Stats%Sample%count
    1490         261 :                 msg = "This is the final output refined sample size. "
    1491         261 :                 if (self%SpecBase%SampleSize%val/=-1_IK) then
    1492          85 :                     if (abs(self%SpecBase%SampleSize%abs)<effectiveSampleSize) then
    1493             :                         msg = msg // "The user-requested sample size ("// num2str(self%SpecBase%SampleSize%abs) // ") is smaller &
    1494             :                             &than the potentially-optimal i.i.d. sample size (" // num2str(effectiveSampleSize) // "). The output sample &
    1495             :                             &contains i.i.d. samples, however, the sample-size could have been larger if it had been set to the optimal size. &
    1496          15 :                             &To get the optimal size in the future runs, set sampleSize = -1, or drop it from the input list."
    1497          70 :                     elseif (abs(self%SpecBase%SampleSize%abs)>effectiveSampleSize) then
    1498             :                         msg = msg // "The user-requested sample size ("// num2str(self%SpecBase%SampleSize%abs) // ") is larger than &
    1499             :                             &the potentially-optimal i.i.d. sample size (" // num2str(effectiveSampleSize) // "). The resulting sample &
    1500             :                             &likely contains duplicates and is not independently and identically distributed (i.i.d.).\nTo get the optimal &
    1501          70 :                             &size in the future runs, set sampleSize = -1, or drop it from the input list."
    1502             :                     else ! LCOV_EXCL_LINE
    1503             :                         msg = msg // "How lucky that could be! The user-requested sample size (" // num2str(self%SpecBase%SampleSize%abs) // & ! LCOV_EXCL_LINE
    1504             :                              ") is equal to the potentially-optimal i.i.d. sample size determined by the "//self%name//" sampler." ! LCOV_EXCL_LINE
    1505             :                     end if
    1506             :                 end if
    1507         261 :                 call self%reportDesc(msg)
    1508             : 
    1509             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1510             : 
    1511         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1512         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.avgStd"
    1513         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1514         261 :                 write(self%LogFile%unit,self%LogFile%format) "variableName", "Mean", "Standard Deviation"
    1515         679 :                 do i = 1, ndim
    1516         679 :                     write(self%LogFile%unit,formatStrReal) trim(adjustl(self%SpecBase%VariableNameList%Val(i))), self%Stats%Sample%Mean(i), sqrt(self%Stats%Sample%CovMat(i,i))
    1517             :                 end do
    1518         261 :                 msg = "This is the Mean and standard deviation table of the final output refined sample."
    1519         261 :                 call self%reportDesc(msg)
    1520             : 
    1521             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1522             : 
    1523         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1524         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.covmat"
    1525         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1526         679 :                 write(self%LogFile%unit,self%LogFile%format) "", (trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1527         679 :                 do i = 1, ndim
    1528         679 :                     write(self%LogFile%unit,formatStrReal) trim(adjustl(self%SpecBase%VariableNameList%Val(i))), self%Stats%Sample%CovMat(1:ndim,i)
    1529             :                 end do
    1530         261 :                 msg = "This is the covariance matrix of the final output refined sample."
    1531         261 :                 call self%reportDesc(msg)
    1532             : 
    1533             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1534             : 
    1535         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1536         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.cormat"
    1537         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1538         679 :                 write(self%LogFile%unit,self%LogFile%format) "", (trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1539         679 :                 do i = 1, ndim
    1540         679 :                     write(self%LogFile%unit,formatStrReal) trim(adjustl(self%SpecBase%VariableNameList%Val(i))), self%Stats%Sample%CorMat(1:ndim,i)
    1541             :                 end do
    1542         261 :                 msg = "This is the correlation matrix of the final output refined sample."
    1543         261 :                 call self%reportDesc(msg)
    1544             : 
    1545             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1546             : 
    1547         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1548         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.quantile"
    1549         261 :                 write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1550         679 :                 write(self%LogFile%unit,self%LogFile%format) "Quantile", (trim(adjustl(self%SpecBase%VariableNameList%Val(i))),i=1,ndim)
    1551        2610 :                 do iq = 1, QPROB%count
    1552        6372 :                     write(self%LogFile%unit,formatStrReal) trim(adjustl(QPROB%Name(iq))), (self%Stats%Sample%Quantile(iq,i),i=1,ndim)
    1553             :                 end do
    1554         261 :                 msg = "This is the quantiles table of the variables of the final output refined sample."
    1555         261 :                 call self%reportDesc(msg)
    1556             : 
    1557             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1558             :                 ! Begin inter-chain convergence test in multiChain parallelization mode
    1559             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1560             : 
    1561             : #if defined CAF_ENABLED || defined MPI_ENABLED
    1562             : 
    1563         261 :                 blockInterChainConvergence: if (self%SpecBase%ParallelizationModel%isMultiChain .and. self%Image%count>1_IK) then
    1564             : 
    1565             :                     call self%note  ( prefix            = self%brand        &
    1566             :                                     , outputUnit        = self%LogFile%unit &
    1567             :                                     , newline           = NLC               &
    1568             :                                     , marginTop         = 1_IK              &
    1569             :                                     , marginBot         = 1_IK              &
    1570          54 :                                     , msg               = "Computing the inter-chain convergence probabilities..." )
    1571          54 :                     if (self%Image%isFirst) then ! print the message on stdout
    1572             :                         call self%note  ( prefix        = self%brand        &
    1573             :                                         , outputUnit    = output_unit       &
    1574             :                                         , newline       = NLC               &
    1575             :                                         , marginTop     = 1_IK              &
    1576             :                                         , marginBot     = 1_IK              &
    1577          18 :                                         , msg           = "Computing the inter-chain convergence probabilities..." )
    1578             :                     end if
    1579             : 
    1580          54 :                     call self%Image%sync()
    1581             : 
    1582             :                     ! read the sample files generated by other images
    1583             : 
    1584             :                     multiChainConvergenceTest: block
    1585             : 
    1586             :                         use Sort_mod, only: sortAscending
    1587             :                         use String_mod, only: replaceStr
    1588             :                         use Statistics_mod, only: doSortedKS2
    1589             :                         use ParaMCMCRefinedChain_mod, only: readRefinedChain, RefinedChain_type
    1590          54 :                         type(RefinedChain_type)     :: RefinedChainThisImage, RefinedChainThatImage
    1591             :                         integer(IK)                 :: imageID,indexMinProbKS,imageMinProbKS
    1592          54 :                         real(RK)                    :: statKS, minProbKS
    1593             :                         real(RK)    , allocatable   :: ProbKS(:)
    1594          54 :                         character(:), allocatable   :: inputSamplePath
    1595             : 
    1596          54 :                         minProbKS = huge(minProbKS)
    1597             :                         if (allocated(ProbKS)) deallocate(ProbKS) ! LCOV_EXCL_LINE
    1598          54 :                         allocate(ProbKS(0:ndim))
    1599             : 
    1600             :                         ! read the refined chain on the current image
    1601             : 
    1602          54 :                         RefinedChainThisImage = readRefinedChain( sampleFilePath=self%SampleFile%Path%original, delimiter=self%SpecBase%OutputDelimiter%val, ndim=ndim, tenabled = .true. )
    1603          54 :                         if (RefinedChainThisImage%Err%occurred) then
    1604             :                             ! LCOV_EXCL_START
    1605             :                             self%Err%occurred = .true.
    1606             :                             self%Err%msg = PROCEDURE_NAME//RefinedChainThisImage%Err%msg
    1607             :                             call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1608             :                             exit blockLeaderPostProcessing
    1609             :                             return
    1610             :                             ! LCOV_EXCL_STOP
    1611             :                         end if
    1612             : 
    1613             :                         ! sort the refined chain on the current image
    1614             : 
    1615         210 :                         do i = 0, ndim
    1616           0 :                             call sortAscending  ( np = RefinedChainThisImage%Count(RefinedChainThisImage%numRefinement)%verbose &
    1617           0 :                                                 , Point = RefinedChainThisImage%LogFuncState(1:RefinedChainThisImage%Count(RefinedChainThisImage%numRefinement)%verbose,i) &
    1618             :                                                 , Err = self%Err &
    1619         156 :                                                 )
    1620         210 :                             if (self%Err%occurred) then
    1621             :                                 ! LCOV_EXCL_START
    1622             :                                 self%Err%msg = PROCEDURE_NAME//self%Err%msg
    1623             :                                 call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1624             :                                 exit blockLeaderPostProcessing
    1625             :                                 return
    1626             :                                 ! LCOV_EXCL_STOP
    1627             :                             end if
    1628             :                         end do
    1629             : 
    1630             :                         ! compute and report the KS convergence probabilities for all images
    1631             : 
    1632          54 :                         formatStr = "(1I" // self%LogFile%maxColWidth%str // ",*(E" // self%LogFile%maxColWidth%str // "." // self%SpecBase%OutputRealPrecision%str // "E3))"
    1633             : 
    1634             :                         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1635             : 
    1636          54 :                         write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1637          54 :                         write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.kstest.prob"
    1638          54 :                         write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1639         210 :                         write(self%LogFile%unit,self%LogFile%format) "ProcessID",("probKS("//trim(adjustl(self%RefinedChain%ColHeader(i)%record))//")",i=0,ndim)
    1640             : 
    1641         216 :                         do imageID = 1, self%Image%count
    1642             : 
    1643         216 :                             if (imageID/=self%Image%id) then
    1644             : 
    1645             :                                 ! read the refined chain on the other image
    1646             : 
    1647           0 :                                 inputSamplePath = replaceStr( string = self%SampleFile%Path%original &
    1648             :                                                             , search = "process_"//num2str(self%Image%id) &
    1649         108 :                                                             , substitute = "process_"//num2str(imageID) )
    1650             : 
    1651         318 :                                 RefinedChainThatImage = readRefinedChain( sampleFilePath=inputSamplePath, delimiter=self%SpecBase%OutputDelimiter%val, ndim=ndim, tenabled = .true. )
    1652         108 :                                 if (RefinedChainThatImage%Err%occurred) then
    1653             :                                     ! LCOV_EXCL_START
    1654             :                                     self%Err%occurred = .true.
    1655             :                                     self%Err%msg = PROCEDURE_NAME//RefinedChainThatImage%Err%msg
    1656             :                                     call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1657             :                                     exit blockLeaderPostProcessing
    1658             :                                     return
    1659             :                                     ! LCOV_EXCL_STOP
    1660             :                                 end if
    1661             : 
    1662         420 :                                 do i = 0, ndim
    1663             : 
    1664             :                                     ! sort the refined chain on the other image
    1665             : 
    1666           0 :                                     call sortAscending  ( np = RefinedChainThatImage%Count(RefinedChainThatImage%numRefinement)%verbose &
    1667           0 :                                                         , Point = RefinedChainThatImage%LogFuncState(1:RefinedChainThatImage%Count(RefinedChainThatImage%numRefinement)%verbose,i) &
    1668             :                                                         , Err = self%Err &
    1669         312 :                                                         )
    1670         312 :                                     if (self%Err%occurred) then
    1671             :                                         ! LCOV_EXCL_START
    1672             :                                         self%Err%msg = PROCEDURE_NAME//self%Err%msg
    1673             :                                         call self%abort( Err = self%Err, prefix = self%brand, newline = NLC, outputUnit = self%LogFile%unit )
    1674             :                                         exit blockLeaderPostProcessing
    1675             :                                         return
    1676             :                                         ! LCOV_EXCL_STOP
    1677             :                                     end if
    1678             : 
    1679             :                                     ! compute the inter-chain KS probability table
    1680             : 
    1681           0 :                                     call doSortedKS2( np1 = RefinedChainThisImage%Count(RefinedChainThisImage%numRefinement)%verbose &
    1682           0 :                                                     , np2 = RefinedChainThatImage%Count(RefinedChainThatImage%numRefinement)%verbose &
    1683           0 :                                                     , SortedPoint1 = RefinedChainThisImage%LogFuncState(1:RefinedChainThisImage%Count(RefinedChainThisImage%numRefinement)%verbose,i) &
    1684           0 :                                                     , SortedPoint2 = RefinedChainThatImage%LogFuncState(1:RefinedChainThatImage%Count(RefinedChainThatImage%numRefinement)%verbose,i) &
    1685             :                                                     , statKS = statKS &
    1686           0 :                                                     , probKS = ProbKS(i) &
    1687         312 :                                                     )
    1688             : 
    1689             :                                     ! determine the minimum KS
    1690             : 
    1691         420 :                                     if (ProbKS(i)<minProbKS) then
    1692         128 :                                         minProbKS = ProbKS(i)
    1693         128 :                                         indexMinProbKS = i
    1694         128 :                                         imageMinProbKS = imageID
    1695             :                                     end if
    1696             : 
    1697             :                                 end do
    1698             : 
    1699             :                                 ! write the inter-chain KS probability table row
    1700             : 
    1701         420 :                                 write(self%LogFile%unit, formatStr) imageID, (ProbKS(i), i = 0, ndim)
    1702             : 
    1703             :                             end if
    1704             : 
    1705             :                         end do
    1706             :                         msg =   "This is the table pairwise inter-chain Kolmogorov-Smirnov (KS) convergence (similarity) probabilities. &
    1707          54 :                                 &Higher KS probabilities are better, indicating less evidence for a lack of convergence."
    1708          54 :                         call self%reportDesc(msg)
    1709             : 
    1710             :                         ! write the smallest KS probabilities
    1711             : 
    1712             :                         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1713             : 
    1714          54 :                         write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1715          54 :                         write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT) "stats.chain.refined.kstest.prob.min"
    1716          54 :                         write(self%LogFile%unit,GENERIC_OUTPUT_FORMAT)
    1717          54 :                         write(self%LogFile%unit,GENERIC_TABBED_FORMAT) minProbKS
    1718         108 :                         msg =   "This is the smallest KS-test probability for the inter-chain sampling convergence, which has happened between "//self%RefinedChain%ColHeader(indexMinProbKS)%record// &
    1719          54 :                                 " on the chains generated by processes "//num2str(self%Image%id)//" and "//num2str(imageMinProbKS)//"."
    1720          54 :                         call self%reportDesc(msg)
    1721             : 
    1722             :                         ! report the smallest KS probabilities on stdout
    1723             : 
    1724          54 :                         if (self%Image%isFirst) call self%note  ( prefix     = self%brand       &
    1725             :                                                                 , outputUnit = output_unit      &
    1726             :                                                                 , newline    = NLC              &
    1727             :                                                                 , marginTop  = 2_IK             &
    1728             :                                                                 , marginBot  = 0_IK             &
    1729          18 :                                                                 , msg        = "The smallest KS probabilities for the inter-chain sampling convergence:" )
    1730             : 
    1731         690 :                         do imageID = 1, self%Image%count
    1732         162 :                             if (imageID==self%Image%id) then
    1733             :                                 call self%note  ( prefix     = self%brand       &
    1734             :                                                 , outputUnit = output_unit      &
    1735             :                                                 , newline    = NLC              &
    1736             :                                                 , marginTop  = 0_IK             &
    1737             :                                                 , marginBot  = 0_IK             &
    1738         108 :                                                 , msg        = num2str(minProbKS)//" for "//self%RefinedChain%ColHeader(indexMinProbKS)%record//&
    1739             :                                                                " on the chains generated by processes "//num2str(self%Image%id)//&
    1740          54 :                                                                " and "//num2str(imageMinProbKS)//"." )
    1741             :                             end if
    1742             : #if defined CAF_ENABLED || MPI_ENABLED
    1743         162 :                             call execute_command_line(" ", cmdstat = self%Err%stat)
    1744         162 :                             flush(output_unit)
    1745         216 :                             call self%Image%sync()
    1746             : #endif
    1747             :                         end do
    1748             : 
    1749             :                     end block multiChainConvergenceTest
    1750             : 
    1751             :                 end if blockInterChainConvergence
    1752             : #endif
    1753             : 
    1754             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1755             :                 ! End inter-chain convergence test in multiChain parallelization mode
    1756             :                 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1757             : 
    1758             :             end if blockSampleFileGeneration
    1759             : 
    1760             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1761             :             ! End of generating the i.i.d. sample statistics and output file (if requested)
    1762             :             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1763             : 
    1764         263 :             call self%Decor%write(self%LogFile%unit,1,1)
    1765             : 
    1766             :             ! Mission accomplished.
    1767             : 
    1768         263 :             call self%note( prefix = self%brand, outputUnit = self%LogFile%unit, newline = "\n", msg = "Mission Accomplished." )
    1769         263 :             if (output_unit/=self%LogFile%unit .and. self%Image%isFirst) then
    1770         227 :                 call self%Decor%write(output_unit,1,1)
    1771         227 :                 call self%note( prefix = self%brand, outputUnit = output_unit, newline = "\n", msg = "Mission Accomplished." )
    1772         227 :                 call self%Decor%write(output_unit,1,1)
    1773             :             end if
    1774             : 
    1775         263 :             close(self%TimeFile%unit)
    1776         263 :             close(self%LogFile%unit)
    1777             : 
    1778             :         end if blockLeaderPostProcessing
    1779             : 
    1780             : #if (defined MPI_ENABLED || defined CAF_ENABLED) && (defined CODECOV_ENABLED || defined SAMPLER_TEST_ENABLED)
    1781         681 :         block; use Err_mod, only: bcastErr; call bcastErr(self%Err); end block
    1782             : #endif
    1783             :         if (self%Err%occurred) return ! LCOV_EXCL_LINE
    1784             : 
    1785             :         !nullify(self%Proposal)
    1786             : #if defined CAF_ENABLED || defined MPI_ENABLED
    1787         681 :             if (self%SpecBase%MpiFinalizeRequested%val) call self%Image%finalize()
    1788             : #endif
    1789             : 
    1790        2460 :     end subroutine runSampler
    1791             : 
    1792             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1793             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1794             : 
    1795             : !end submodule Setup_smod
    1796             : 
    1797             : #undef ParaDXXXProposalAbstract_mod
    1798             : #undef ParaDXXX_type
    1799             : #undef ParaDXXX

ParaMonte: Plain Powerful Parallel Monte Carlo Library 
The Computational Data Science Lab
© Copyright 2012 - 2021