https://www.cdslab.org/paramonte/fortran/2
Current view: top level - main - pm_distMultiNorm@routines.inc.F90 (source / functions) Hit Total Coverage
Test: ParaMonte 2.0.0 :: Serial Fortran - Code Coverage Report Lines: 30 33 90.9 %
Date: 2024-04-08 03:18:57 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       2             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       3             : !!!!                                                                                                                            !!!!
       4             : !!!!    ParaMonte: Parallel Monte Carlo and Machine Learning Library.                                                           !!!!
       5             : !!!!                                                                                                                            !!!!
       6             : !!!!    Copyright (C) 2012-present, The Computational Data Science Lab                                                          !!!!
       7             : !!!!                                                                                                                            !!!!
       8             : !!!!    This file is part of the ParaMonte library.                                                                             !!!!
       9             : !!!!                                                                                                                            !!!!
      10             : !!!!    LICENSE                                                                                                                 !!!!
      11             : !!!!                                                                                                                            !!!!
      12             : !!!!       https://github.com/cdslaborg/paramonte/blob/main/LICENSE.md                                                          !!!!
      13             : !!!!                                                                                                                            !!!!
      14             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      15             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      16             : 
      17             : !>  \brief
      18             : !>  This include file contains procedure implementation of [pm_distMultiNorm](@ref pm_distMultiNorm).
      19             : !>
      20             : !>  \finmain
      21             : !>
      22             : !>  \author
      23             : !>  \AmirShahmoradi, Oct 16, 2009, 11:14 AM, Michigan
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             :         ! Set the uniform RNG
      28             : #if     RNGD_ENABLED
      29             : #define RNG
      30             : #elif   RNGF_ENABLED || RNGX_ENABLED
      31             : #define RNG rng,
      32             : #elif   getMNR_ENABLED || setMNR_ENABLED
      33             : #error  "Unrecognized interface."
      34             : #endif
      35             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
      36             : #if     getMultiNormLogPDFNF_ENABLED
      37             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
      38             : 
      39             :         real(RKC), parameter :: LOG_INVERSE_SQRT_TWO_PI = -0.5_RKC * log(2 * acos(-1._RKC))
      40             : #if     I_ENABLED
      41             :         integer(IK) :: ndim
      42             :         real(RKC) :: logSqrtDetInvCov
      43      250003 :         logSqrtDetInvCov = getMatDetSqrtLog(invCov, uppDia)
      44      250003 :         ndim = size(invCov, 1, IK)
      45             : #elif   IF_ENABLED
      46             :         integer(IK) :: ndim
      47           2 :         real(RKC)   :: logSqrtDetInvCov, chol(size(invCov, 1, IK), size(invCov, 1, IK))
      48           1 :         CHECK_ASSERTION(__LINE__, size(invCov, 1, IK) == size(invCov, 2, IK), SK_"@getMultiNormLogPDFNF(): The condition `size(invCov, 1) == size(invCov, 2)` must hold. shape(invCov) = "//getStr(shape(invCov, IK)))
      49           1 :         call setMatDetSqrtLog(invCov, uppDia, logSqrtDetInvCov, info, chol, nothing)
      50             :         ndim = size(invCov, 1, IK)
      51           1 :         if (info /= 0_IK) return
      52             : #elif   ND_ENABLED
      53      613108 :         CHECK_ASSERTION(__LINE__, 0_IK < ndim, SK_"@getMultiNormLogPDFNF(): The input `ndim` must be positive. ndim = "//getStr(ndim))
      54             : #else
      55             : #error  "Unrecognized interface."
      56             : #endif
      57           1 :         logPDFNF = ndim * LOG_INVERSE_SQRT_TWO_PI + logSqrtDetInvCov
      58             : 
      59             :         !%%%%%%%%%%%%%%%%%%%%%%%%%
      60             : #elif   getMultiNormLogPDF_ENABLED
      61             :         !%%%%%%%%%%%%%%%%%%%%%%%%%
      62             : 
      63             :         ! Set the normalization factor for different interfaces.
      64             : #if     DDD_ENABLED || MDD_ENABLED
      65             : #define LOGNORMFAC getMultiNormLogPDFNF(size(X,1,IK), 0._RKC)
      66             : #elif   DID_ENABLED || MID_ENABLED
      67             : #define LOGNORMFAC getMultiNormLogPDFNF(invCov)
      68             : #elif   DDN_ENABLED || MDN_ENABLED || DIN_ENABLED || MIN_ENABLED
      69             : #define LOGNORMFAC logPDFNF
      70             : #else
      71             : #error  "Unrecognized interface."
      72             : #endif
      73             :         ! Set the Mahalanobis distance.
      74             : #if     DDD_ENABLED || DDN_ENABLED
      75             : #define MAHAL_SQ sum(X**2)
      76             : #elif   DID_ENABLED || DIN_ENABLED
      77             : #define MAHAL_SQ getMahalSq(X, invCov)
      78           0 :         CHECK_ASSERTION(__LINE__, all(shape(invCov, IK) == size(X, 1, IK)), SK_"@getMultiNormLogPDF(): The condition `all(shape(invCov) == size(X))` must hold. shape(invCov), size(X) = "//getStr([shape(invCov, IK), size(X, 1, IK)]))
      79             : #elif   MID_ENABLED || MIN_ENABLED
      80             : #define MAHAL_SQ getMahalSq(X, invCov, mean)
      81     2000016 :         CHECK_ASSERTION(__LINE__, all(shape(invCov, IK) == size(X, 1, IK)), SK_"@getMultiNormLogPDF(): The condition `all(shape(invCov) == size(X))` must hold. shape(invCov), size(X) = "//getStr([shape(invCov, IK), size(X, 1, IK)]))
      82      750006 :         CHECK_ASSERTION(__LINE__, size(mean, 1, IK) == size(X, 1, IK), SK_"@getMultiNormLogPDF(): The condition `size(mean) == size(X)` must hold. size(mean), size(X) = "//getStr([size(mean, 1, IK), size(X, 1, IK)]))
      83             : #elif   MDD_ENABLED || MDN_ENABLED
      84             : #define MAHAL_SQ sum((X - mean)**2)
      85     1839312 :         CHECK_ASSERTION(__LINE__, size(mean, 1, IK) == size(X, 1, IK), SK_"@getMultiNormLogPDF(): The condition `size(mean) == size(X)` must hold. size(mean), size(X) = "//getStr([size(mean, 1, IK), size(X, 1, IK)]))
      86             : #else
      87             : #error  "Unrecognized interface."
      88             : #endif
      89     3315524 :         logPDF = LOGNORMFAC - 0.5_RKC * MAHAL_SQ
      90             : 
      91             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      92             : #elif   D1_ENABLED && (getMNR_ENABLED || setMNR_ENABLED)
      93             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      94             : 
      95             :         integer(IK) :: ndim
      96     1121986 :         ndim = size(rand, kind = IK)
      97             : #if     AM_ENABLED
      98     3305952 :         CHECK_ASSERTION(__LINE__, size(rand, 1, IK) == size(mean, 1, IK), SK_"@setMultiNormRand(): The condition `size(rand) == size(mean)` must hold. size(rand), size(mean) = "//getStr([size(rand, 1, IK), size(mean, 1, IK)]))
      99             : #elif   !DM_ENABLED
     100             : #error  "Unrecognized interface."
     101             : #endif
     102             :         ! Generate random MVN.
     103             : #if     DC_ENABLED && DM_ENABLED
     104        5001 :         call setNormRand(RNG rand)
     105             : #elif   DC_ENABLED && AM_ENABLED
     106       10002 :         call setNormRand(RNG rand)
     107       30006 :         rand = rand + mean
     108             : #elif   AC_ENABLED && (AM_ENABLED || DM_ENABLED)
     109     8895872 :         CHECK_ASSERTION(__LINE__, all(size(rand, 1, IK) == shape(chol, IK)), SK_"@setMultiNormRand(): The condition `all(size(rand) == shape(chol))` must hold. size(rand), shape(chol) = "//getStr([size(rand, 1, IK), shape(chol, IK)]))
     110             :         ! Define the indexing rules.
     111             : #if     XLD_ENABLED
     112             : #define GET_INDEX(I,J)I,J
     113             : #elif   UXD_ENABLED
     114             : #define GET_INDEX(I,J)J,I
     115             : #elif   D1_ENABLED && setMUR_ENABLED
     116             : #error  "Unrecognized interface."
     117             : #endif
     118             :         ! Define the default mean.
     119             : #if     DM_ENABLED
     120             : #define XPLUS(X)
     121             : #elif   AM_ENABLED
     122             : #define XPLUS(X)X +
     123             : #else
     124             : #error  "Unrecognized interface."
     125             : #endif
     126             :         block
     127             :             integer(IK) :: idim
     128             :             real(RKC) :: normrnd
     129             :             ! Separate the first to allow the possibility of adding an optional `mean`.
     130     1111984 :             call setNormRand(RNG normrnd)
     131     4876224 :             rand(1 : ndim) = XPLUS(mean) chol(GET_INDEX(1 : ndim, 1)) * normrnd
     132     3764240 :             do idim = 2_IK, ndim
     133       20004 :                 call setNormRand(RNG normrnd)
     134     8835765 :                 rand(idim : ndim) = rand(idim : ndim) + chol(GET_INDEX(idim : ndim, idim)) * normrnd
     135             :             end do
     136             :         end block
     137             : #undef  GET_INDEX
     138             : #undef  XPLUS
     139             : #endif
     140             : 
     141             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     142             : #elif   D2_ENABLED && getMNR_ENABLED
     143             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     144             : 
     145             : #if     AM_ENABLED && DC_ENABLED
     146           1 :         call setMultiNormRand(RNG rand, mean)
     147             : #elif   DM_ENABLED && AC_ENABLED
     148           2 :         call setMultiNormRand(RNG rand, chol, subset)
     149             : #elif   AM_ENABLED && AC_ENABLED
     150           0 :         call setMultiNormRand(RNG rand, mean, chol, subset)
     151             : #else
     152             : #error  "Unrecognized interface."
     153             : #endif
     154             : 
     155             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     156             : #elif   D2_ENABLED && setMNR_ENABLED
     157             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     158             : 
     159             :         integer(IK) :: ipnt, ndim
     160           7 :         ndim = size(rand, 1, IK)
     161       35007 :         do ipnt = 1_IK, size(rand, 2, IK)
     162             : #if         DM_ENABLED && DC_ENABLED
     163        5001 :             call setMultiNormRand(RNG rand(1:ndim, ipnt))
     164             : #elif       AM_ENABLED && DC_ENABLED
     165       10002 :             call setMultiNormRand(RNG rand(1:ndim, ipnt), mean)
     166             : #elif       DM_ENABLED && AC_ENABLED
     167       20004 :             call setMultiNormRand(RNG rand(1:ndim, ipnt), chol, subset)
     168             : #elif       AM_ENABLED && AC_ENABLED
     169           0 :             call setMultiNormRand(RNG rand(1:ndim, ipnt), mean, chol, subset)
     170             : #else
     171             : #error  "Unrecognized interface."
     172             : #endif
     173             :         end do
     174             : 
     175             : #else
     176             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     177             : #error  "Unrecognized interface."
     178             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     179             : #endif
     180             : #undef  LOGNORMFAC
     181             : #undef  MAHAL_SQ
     182             : #undef  RNG

ParaMonte: Parallel Monte Carlo and Machine Learning Library 
The Computational Data Science Lab
© Copyright 2012 - 2024