https://www.cdslab.org/paramonte/fortran/2
Current view: top level - test - test_pm_sampleCor@routines.inc.F90 (source / functions) Hit Total Coverage
Test: ParaMonte 2.0.0 :: Serial Fortran - Code Coverage Report Lines: 522 526 99.2 %
Date: 2024-04-08 03:18:57 Functions: 132 132 100.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 file contains procedure implementations of tests of [pm_sampleCor](@ref pm_sampleCor).
      19             : !>
      20             : !>  \fintest
      21             : !>
      22             : !>  \author
      23             : !>  \FatemehBagheri, Wednesday 5:03 PM, August 11, 2021, Dallas, TX
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             :         ! Define the comparison precision and tolerance.
      28             : #if     CK_ENABLED && (getCor_ENABLED || setCor_ENABLED)
      29             :         real(TKC), parameter :: rtol = epsilon(1._TKC) * 100
      30             :         complex(TKC), parameter :: ctol = (rtol, rtol)
      31             : #define GET_CONJG(X)conjg(X)
      32             : #elif   RK_ENABLED && (getCor_ENABLED || setCor_ENABLED)
      33             :         real(TKC), parameter :: rtol = epsilon(1._TKC) * 100
      34             :         real(TKC), parameter :: ctol = rtol
      35             : #define GET_CONJG(X)X
      36             : #elif   getCor_ENABLED || setCor_ENABLED
      37             : #error  "Unrecognized interface."
      38             : #else
      39             :         real(RK), parameter :: rtol = epsilon(1._RK) * 100
      40             : #endif
      41             :         ! Define the sample type.
      42             : #if     SK_ENABLED && D0_ENABLED
      43             : #define GET_SHAPE len
      44             : #define TYPE_OF_SAMPLE character(:,TKC)
      45             :         character(1,TKC), parameter :: lb = TKC_"a", ub = TKC_"z"
      46             : #else
      47             : #define GET_SHAPE shape
      48             : #if     SK_ENABLED
      49             : #define TYPE_OF_SAMPLE character(2,TKC)
      50             :         TYPE_OF_SAMPLE, parameter :: lb = TKC_"aa", ub = TKC_"zz"
      51             : #elif   IK_ENABLED
      52             : #define TYPE_OF_SAMPLE integer(TKC)
      53             :         TYPE_OF_SAMPLE, parameter :: lb = -9_TKC, ub = +9_TKC
      54             : #elif   CK_ENABLED
      55             : #define TYPE_OF_SAMPLE complex(TKC)
      56             :         TYPE_OF_SAMPLE, parameter :: lb = (2._TKC, -3._TKC), ub = (3._TKC, -2._TKC), ZERO = (0._TKC, 0._TKC), ONE = (1._TKC, 0._TKC), ONES = (1._TKC, 1._TKC), TWOS = ONES + ONES
      57             : #elif   RK_ENABLED
      58             : #define TYPE_OF_SAMPLE real(TKC)
      59             :         TYPE_OF_SAMPLE, parameter :: lb = 2._TKC, ub = 3._TKC, ZERO = 0._TKC, ONE = 1._TKC, ONES = 1._TKC, TWOS = ONES + ONES
      60             : #elif   PSSK_ENABLED
      61             : #define TYPE_OF_SAMPLE type(css_pdt(TKC))
      62             :         character(1,TKC), parameter :: lb = TKC_"a", ub = TKC_"z"
      63             : #elif   BSSK_ENABLED
      64             : #define TYPE_OF_SAMPLE type(css_type)
      65             :         character(1,TKC), parameter :: lb = TKC_"a", ub = TKC_"z"
      66             : #elif   !setCordance_ENABLED
      67             : #error  "Unrecognized interface."
      68             : #endif
      69             : #endif
      70             :         !%%%%%%%%%%%%%
      71             : #if     getCor_ENABLED
      72             :         !%%%%%%%%%%%%%
      73             : 
      74             :         real(TKC) :: rweisum
      75             :         integer(IK) :: iweisum
      76             :         real(TKC), allocatable :: rweight(:)
      77             :         integer(IK), allocatable :: iweight(:)
      78             :         integer(IK) :: itry, nsam, ndim, dim
      79             :         TYPE_OF_SAMPLE, allocatable :: sample(:,:), mean(:)
      80             :         TYPE_OF_SAMPLE, allocatable :: cor(:,:), cov(:,:), covupp(:,:), covlow(:,:), cor_ref(:,:), cdiff(:,:)
      81             :         real(TKC), allocatable :: std(:), stdinv(:)
      82           7 :         assertion = .true._LK
      83             : 
      84         408 :         do itry = 1, 50
      85             : 
      86             :             ! Test CFC: The strategy is to construct a cot mat, convert to cov mat using `setCov`, and recover the original cor mat using `setCor`.
      87             : 
      88             :             block
      89             : 
      90         400 :                 ndim = getUnifRand(1_IK, 5_IK)
      91        6210 :                 cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
      92         400 :                 call setMatCopy(cor_ref, rdpack, cor_ref, rdpack, upp, transHerm)
      93         400 :                 call setMatInit(cor_ref, dia, ONE)
      94        1969 :                 std = getUnifRand(1._TKC, 2._TKC, ndim)
      95        1969 :                 stdinv = 1._TKC / std
      96       11620 :                 cov = getCov(cor_ref, uppDia, std)
      97        6862 :                 covupp = cov; call setMatInit(covupp, low, ZERO)
      98        6862 :                 covlow = cov; call setMatInit(covlow, upp, ZERO)
      99             : 
     100       11620 :                 cor = getCor(covupp, uppDia)
     101         400 :                 call reportCFC(__LINE__)
     102             : 
     103       11620 :                 cor = getCor(covlow, lowDia)
     104         400 :                 call reportCFC(__LINE__)
     105             : 
     106         400 :                 call setMatInit(covupp, dia, ZERO)
     107         400 :                 call setMatInit(covlow, dia, ZERO)
     108             : 
     109       11620 :                 cor = getCor(covupp, upp, stdinv)
     110         400 :                 call reportCFC(__LINE__, stdinv)
     111             : 
     112       11620 :                 cor = getCor(covlow, low, stdinv)
     113         400 :                 call reportCFC(__LINE__, stdinv)
     114             : 
     115             :             end block
     116             : 
     117             :             ! Test Prs: The strategy is to construct a sample, compute its correlation and compare it against the reference computed here.
     118             : 
     119         400 :             nsam = getUnifRand(2_IK, 7_IK)
     120             : 
     121             :             ! test sample interface.
     122             : 
     123             :             block
     124             : 
     125             :                 type(uppDia_type), parameter :: subsetr = uppDia_type()
     126         400 :                 dim = getChoice([1, 2])
     127         400 :                 ndim = getUnifRand(1_IK, 5_IK)
     128         400 :                 if (dim == 2) then
     129        4217 :                     sample = getUnifRand(ONES, TWOS, ndim, nsam)
     130             :                 else
     131        3611 :                     sample = getUnifRand(ONES, TWOS, nsam, ndim)
     132             :                 end if
     133        2625 :                 rweight = getUnifRand(1._TKC, 9._TKC, nsam)
     134        2625 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
     135        2225 :                 iweisum = sum(iweight)
     136        2225 :                 rweisum = sum(rweight)
     137             : 
     138        6244 :                 cor_ref = getFilled(ZERO, ndim, ndim)
     139        6244 :                 cor = getFilled(ZERO, ndim, ndim)
     140             : 
     141             :                 ! integer weighted
     142             : 
     143        1972 :                 mean = getMean(sample, dim, iweight)
     144             : 
     145        6244 :                 cor = getCor(sample, dim, iweight)
     146         400 :                 call setCor(cor_ref, subsetr, mean, sample, dim, iweight, iweisum)
     147         400 :                 call setMatCopy(cor_ref, rdpack, cor_ref, rdpack, subsetr, transHerm)
     148         400 :                 call report(__LINE__, SK_"integer-weighted")
     149             : 
     150             :                 ! real weighted
     151             : 
     152        1972 :                 mean = getMean(sample, dim, rweight)
     153             : 
     154        6244 :                 cor = getCor(sample, dim, rweight)
     155         400 :                 call setCor(cor_ref, subsetr, mean, sample, dim, rweight, rweisum)
     156         400 :                 call setMatCopy(cor_ref, rdpack, cor_ref, rdpack, subsetr, transHerm)
     157         400 :                 call report(__LINE__, SK_"real-weighted")
     158             : 
     159             :                 ! unweighted
     160             : 
     161        1972 :                 mean = getMean(sample, dim)
     162             : 
     163        6244 :                 cor = getCor(sample, dim)
     164         400 :                 call setCor(cor_ref, subsetr, mean, sample, dim)
     165         400 :                 call setMatCopy(cor_ref, rdpack, cor_ref, rdpack, subsetr, transHerm)
     166         400 :                 call report(__LINE__, SK_"unweighted")
     167             : 
     168             :             end block
     169             : 
     170             :             ! test sample XY interface.
     171             : 
     172           8 :             block
     173             : 
     174         400 :                 dim = 1
     175         400 :                 ndim = 2
     176        5250 :                 sample = getUnifRand(ONES, TWOS, nsam, ndim)
     177        2625 :                 rweight = getUnifRand(1._TKC, 9._TKC, nsam)
     178        2625 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
     179        2225 :                 iweisum = sum(iweight)
     180        2225 :                 rweisum = sum(rweight)
     181             : 
     182        3200 :                 cor_ref = getFilled(ZERO, ndim, ndim)
     183        3200 :                 cor = getFilled(ZERO, ndim, ndim)
     184             : 
     185             :                 ! integer weighted
     186             : 
     187        1600 :                 mean = getMean(sample, dim, iweight)
     188             : 
     189         400 :                 cor(1,2) = getCor(sample(:,1), sample(:,2), iweight)
     190         400 :                 call setCor(cor_ref(1,2), mean, sample(:,1), sample(:,2), iweight, iweisum)
     191         400 :                 call report(__LINE__, SK_"integer-weighted")
     192             : 
     193             :                 ! real weighted
     194             : 
     195        1600 :                 mean = getMean(sample, dim, rweight)
     196             : 
     197         400 :                 cor(1,2) = getCor(sample(:,1), sample(:,2), rweight)
     198         400 :                 call setCor(cor_ref(1,2), mean, sample(:,1), sample(:,2), rweight, rweisum)
     199         400 :                 call report(__LINE__, SK_"real-weighted")
     200             : 
     201             :                 ! unweighted
     202             : 
     203        1600 :                 mean = getMean(sample, dim)
     204             : 
     205         400 :                 cor(1,2) = getCor(sample(:,1), sample(:,2))
     206         400 :                 call setCor(cor_ref(1,2), mean, sample(:,1), sample(:,2))
     207         400 :                 call report(__LINE__, SK_"unweighted")
     208             : 
     209             :             end block
     210             : 
     211             :         end do
     212             : 
     213             :     contains
     214             : 
     215        1600 :         subroutine reportCFC(line, stdinv)
     216             :             real(TKC), intent(in), optional :: stdinv(:)
     217             :             integer, intent(in) :: line
     218       36176 :             cdiff = abs(cor - cor_ref)
     219       23240 :             assertion = assertion .and. all(cdiff < ctol)
     220        1600 :             if (test%traceable .and. .not. assertion) then
     221             :                 ! LCOV_EXCL_START
     222             :                 call test%disp%skip()
     223             :                 call test%disp%show("ndim")
     224             :                 call test%disp%show( ndim )
     225             :                 call test%disp%show("present(stdinv)")
     226             :                 call test%disp%show( present(stdinv) )
     227             :                 if (present(stdinv)) then
     228             :                     call test%disp%show("stdinv")
     229             :                     call test%disp%show( stdinv )
     230             :                 end if
     231             :                 call test%disp%show("cov")
     232             :                 call test%disp%show( cov )
     233             :                 call test%disp%show("cor")
     234             :                 call test%disp%show( cor )
     235             :                 call test%disp%show("cor_ref")
     236             :                 call test%disp%show( cor_ref )
     237             :                 call test%disp%show("cdiff")
     238             :                 call test%disp%show( cdiff )
     239             :                 call test%disp%skip()
     240             :                 ! LCOV_EXCL_STOP
     241             :             end if
     242        1600 :             call test%assert(assertion, SK_"The `cor` must be correctly computed from the specified `cor` and `stdinv`.", int(line, IK))
     243        1600 :         end subroutine
     244             : 
     245        2400 :         subroutine report(line, this)
     246             :             integer, intent(in) :: line
     247             :             character(*, SK), intent(in) :: this
     248       39648 :             cdiff = abs(cor - cor_ref)
     249       25932 :             assertion = assertion .and. all(cdiff < ctol)
     250        2400 :             if (test%traceable .and. .not. assertion) then
     251             :                 ! LCOV_EXCL_START
     252             :                 call test%disp%skip()
     253             :                 call test%disp%show("[ndim, nsam, dim, shape(sample, IK)]")
     254             :                 call test%disp%show( [ndim, nsam, dim, shape(sample, IK)] )
     255             :                 call test%disp%show("sample")
     256             :                 call test%disp%show( sample )
     257             :                 call test%disp%show("iweight")
     258             :                 call test%disp%show( iweight )
     259             :                 call test%disp%show("rweight")
     260             :                 call test%disp%show( rweight )
     261             :                 call test%disp%show("cor_ref")
     262             :                 call test%disp%show( cor_ref )
     263             :                 call test%disp%show("cor")
     264             :                 call test%disp%show( cor )
     265             :                 call test%disp%show("cdiff")
     266             :                 call test%disp%show( cdiff )
     267             :                 call test%disp%skip()
     268             :                 ! LCOV_EXCL_STOP
     269             :             end if
     270        2400 :             call test%assert(assertion, SK_"The `cor` must be computed correctly for "//this//SK_" sample.", int(line, IK))
     271        2400 :         end subroutine
     272             : 
     273             :         !%%%%%%%%%%%%%
     274             : #elif   setCor_ENABLED
     275             :         !%%%%%%%%%%%%%
     276             : 
     277             :         real(TKC) :: rweisum
     278             :         integer(IK) :: iweisum
     279             :         real(TKC), allocatable :: rweight(:)
     280             :         integer(IK), allocatable :: iweight(:)
     281             :         integer(IK) :: itry, nsam, ndim, dim
     282             :         TYPE_OF_SAMPLE, allocatable :: sample(:,:), mean(:)
     283             :         TYPE_OF_SAMPLE, allocatable :: cor(:,:), cov(:,:), cor_ref(:,:), cdiff(:,:)
     284             :         real(TKC), allocatable :: std(:), stdinv(:)
     285           8 :         assertion = .true._LK
     286             : 
     287         408 :         do itry = 1, 50
     288             : 
     289             :             ! Test CFC: The strategy is to construct a cot mat, convert to cov mat using `setCov`, and recover the original cor mat using `setCor`.
     290             : 
     291             :             block
     292             : 
     293             :                 block
     294             : 
     295             :                     type(low_type) :: subsetr
     296             :                     type(low_type) :: subsetv
     297         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     298        6600 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     299         400 :                     call setMatInit(cor_ref, getSubComp(subsetr), ZERO, ZERO)
     300        2032 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     301        2032 :                     stdinv = 1._TKC / std
     302        6600 :                     cov = getFilled(ZERO, ndim, ndim)
     303         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     304             : 
     305        6600 :                     cor = getFilled(ZERO, ndim, ndim)
     306         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     307         400 :                     call reportCFC(__LINE__)
     308             : 
     309         400 :                     call setMatInit(cov, dia, ZERO)
     310        6600 :                     cor = getFilled(ZERO, ndim, ndim)
     311         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     312         400 :                     call reportCFC(__LINE__, stdinv)
     313             : 
     314             :                 end block
     315             : 
     316             :                 block
     317             : 
     318             :                     type(low_type) :: subsetr
     319             :                     type(upp_type) :: subsetv
     320         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     321        6458 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     322         400 :                     call setMatInit(cor_ref, getSubComp(subsetr), ZERO, ZERO)
     323        2011 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     324        2011 :                     stdinv = 1._TKC / std
     325        6458 :                     cov = getFilled(ZERO, ndim, ndim)
     326         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     327             : 
     328        6458 :                     cor = getFilled(ZERO, ndim, ndim)
     329         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     330         400 :                     call reportCFC(__LINE__)
     331             : 
     332         400 :                     call setMatInit(cov, dia, ZERO)
     333        6458 :                     cor = getFilled(ZERO, ndim, ndim)
     334         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     335         400 :                     call reportCFC(__LINE__, stdinv)
     336             : 
     337             :                 end block
     338             : 
     339             :                 block
     340             : 
     341             :                     type(upp_type) :: subsetr
     342             :                     type(low_type) :: subsetv
     343         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     344        6350 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     345         400 :                     call setMatInit(cor_ref, getSubComp(subsetr), ZERO, ZERO)
     346        1992 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     347        1992 :                     stdinv = 1._TKC / std
     348        6350 :                     cov = getFilled(ZERO, ndim, ndim)
     349         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     350             : 
     351        6350 :                     cor = getFilled(ZERO, ndim, ndim)
     352         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     353         400 :                     call reportCFC(__LINE__)
     354             : 
     355         400 :                     call setMatInit(cov, dia, ZERO)
     356        6350 :                     cor = getFilled(ZERO, ndim, ndim)
     357         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     358         400 :                     call reportCFC(__LINE__, stdinv)
     359             : 
     360             :                 end block
     361             : 
     362             :                 block
     363             : 
     364             :                     type(upp_type) :: subsetr
     365             :                     type(upp_type) :: subsetv
     366         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     367        6476 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     368         400 :                     call setMatInit(cor_ref, getSubComp(subsetr), ZERO, ZERO)
     369        2013 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     370        2013 :                     stdinv = 1._TKC / std
     371        6476 :                     cov = getFilled(ZERO, ndim, ndim)
     372         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     373             : 
     374        6476 :                     cor = getFilled(ZERO, ndim, ndim)
     375         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     376         400 :                     call reportCFC(__LINE__)
     377             : 
     378         400 :                     call setMatInit(cov, dia, ZERO)
     379        6476 :                     cor = getFilled(ZERO, ndim, ndim)
     380         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     381         400 :                     call reportCFC(__LINE__, stdinv)
     382             : 
     383             :                 end block
     384             : 
     385             :                 block
     386             : 
     387             :                     type(lowDia_type) :: subsetr
     388             :                     type(low_type) :: subsetv
     389         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     390        6104 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     391         400 :                     call setMatInit(cor_ref, getSubSymm(subsetr), ZERO, ONE)
     392        1955 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     393        1955 :                     stdinv = 1._TKC / std
     394        6104 :                     cov = getFilled(ZERO, ndim, ndim)
     395         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     396             : 
     397        6104 :                     cor = getFilled(ZERO, ndim, ndim)
     398         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     399         400 :                     call reportCFC(__LINE__)
     400             : 
     401         400 :                     call setMatInit(cov, dia, ZERO)
     402        6104 :                     cor = getFilled(ZERO, ndim, ndim)
     403         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     404         400 :                     call reportCFC(__LINE__, stdinv)
     405             : 
     406             :                 end block
     407             : 
     408             :                 block
     409             : 
     410             :                     type(lowDia_type) :: subsetr
     411             :                     type(upp_type) :: subsetv
     412         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     413        6028 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     414         400 :                     call setMatInit(cor_ref, getSubSymm(subsetr), ZERO, ONE)
     415        1948 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     416        1948 :                     stdinv = 1._TKC / std
     417        6028 :                     cov = getFilled(ZERO, ndim, ndim)
     418         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     419             : 
     420        6028 :                     cor = getFilled(ZERO, ndim, ndim)
     421         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     422         400 :                     call reportCFC(__LINE__)
     423             : 
     424         400 :                     call setMatInit(cov, dia, ZERO)
     425        6028 :                     cor = getFilled(ZERO, ndim, ndim)
     426         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     427         400 :                     call reportCFC(__LINE__, stdinv)
     428             : 
     429             :                 end block
     430             : 
     431             :                 block
     432             : 
     433             :                     type(uppDia_type) :: subsetr
     434             :                     type(low_type) :: subsetv
     435         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     436        6546 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     437         400 :                     call setMatInit(cor_ref, getSubSymm(subsetr), ZERO, ONE)
     438        2014 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     439        2014 :                     stdinv = 1._TKC / std
     440        6546 :                     cov = getFilled(ZERO, ndim, ndim)
     441         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     442             : 
     443        6546 :                     cor = getFilled(ZERO, ndim, ndim)
     444         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     445         400 :                     call reportCFC(__LINE__)
     446             : 
     447         400 :                     call setMatInit(cov, dia, ZERO)
     448        6546 :                     cor = getFilled(ZERO, ndim, ndim)
     449         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     450         400 :                     call reportCFC(__LINE__, stdinv)
     451             : 
     452             :                 end block
     453             : 
     454             :                 block
     455             : 
     456             :                     type(uppDia_type) :: subsetr
     457             :                     type(upp_type) :: subsetv
     458         400 :                     ndim = getUnifRand(1_IK, 5_IK)
     459        6422 :                     cor_ref = getUnifRand(-ONES, ONES, ndim, ndim)
     460         400 :                     call setMatInit(cor_ref, getSubSymm(subsetr), ZERO, ONE)
     461        2002 :                     std = getUnifRand(1._TKC, 2._TKC, ndim)
     462        2002 :                     stdinv = 1._TKC / std
     463        6422 :                     cov = getFilled(ZERO, ndim, ndim)
     464         400 :                     call setCov(cov, getSubUnion(subsetv, dia), cor_ref, getSubUnion(subsetr, dia), std)
     465             : 
     466        6422 :                     cor = getFilled(ZERO, ndim, ndim)
     467         400 :                     call setCor(cor, subsetr, cov, getSubUnion(subsetv, dia))
     468         400 :                     call reportCFC(__LINE__)
     469             : 
     470         400 :                     call setMatInit(cov, dia, ZERO)
     471        6422 :                     cor = getFilled(ZERO, ndim, ndim)
     472         400 :                     call setCor(cor, subsetr, cov, subsetv, stdinv)
     473         400 :                     call reportCFC(__LINE__, stdinv)
     474             : 
     475             :                 end block
     476             :             end block
     477             : 
     478             :             ! Test Prs: The strategy is to construct a sample, compute its correlation and compare it against the reference computed here.
     479             : 
     480         400 :             nsam = getUnifRand(2_IK, 7_IK)
     481             : 
     482             :             ! test sample lowDia interface.
     483             : 
     484             :             block
     485             : 
     486             :                 type(lowDia_type), parameter :: subsetr = lowDia_type()
     487         400 :                 dim = getChoice([1, 2])
     488         400 :                 ndim = getUnifRand(1_IK, 5_IK)
     489         400 :                 if (dim == 2) then
     490        3975 :                     sample = getUnifRand(ONES, TWOS, ndim, nsam)
     491             :                 else
     492        3641 :                     sample = getUnifRand(ONES, TWOS, nsam, ndim)
     493             :                 end if
     494        2582 :                 rweight = getUnifRand(1._TKC, 9._TKC, nsam)
     495        2582 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
     496        2182 :                 iweisum = sum(iweight)
     497        2182 :                 rweisum = sum(rweight)
     498             : 
     499             :                 ! integer weighted
     500             : 
     501        1995 :                 mean = getMean(sample, dim, iweight)
     502        8142 :                 cor_ref = getCorRef(mean, sample, dim, real(iweight, TKC))
     503             : 
     504        6360 :                 cor = getFilled(ZERO, ndim, ndim)
     505         400 :                 call setCor(cor, subsetr, mean, sample, dim, iweight, iweisum)
     506         400 :                 call report(__LINE__, subsetr, SK_"integer-weighted")
     507             : 
     508        6360 :                 cor = getFilled(ZERO, ndim, ndim)
     509        1595 :                 call setCor(cor, subsetr, getShifted(sample, dim, -mean), dim, iweight, iweisum)
     510         400 :                 call report(__LINE__, subsetr, SK_"integer-weighted shifted")
     511             : 
     512             :                 ! real weighted
     513             : 
     514        1995 :                 mean = getMean(sample, dim, rweight)
     515        6360 :                 cor_ref = getCorRef(mean, sample, dim, rweight)
     516             : 
     517        6360 :                 cor = getFilled(ZERO, ndim, ndim)
     518         400 :                 call setCor(cor, subsetr, mean, sample, dim, rweight, rweisum)
     519         400 :                 call report(__LINE__, subsetr, SK_"real-weighted")
     520             : 
     521        6360 :                 cor = getFilled(ZERO, ndim, ndim)
     522        1595 :                 call setCor(cor, subsetr, getShifted(sample, dim, -mean), dim, rweight, rweisum)
     523         400 :                 call report(__LINE__, subsetr, SK_"real-weighted shifted")
     524             : 
     525             :                 ! unweighted
     526             : 
     527        1995 :                 mean = getMean(sample, dim)
     528        6360 :                 cor_ref = getCorRef(mean, sample, dim)
     529             : 
     530        6360 :                 cor = getFilled(ZERO, ndim, ndim)
     531         400 :                 call setCor(cor, subsetr, mean, sample, dim)
     532         400 :                 call report(__LINE__, subsetr, SK_"unweighted")
     533             : 
     534        6360 :                 cor = getFilled(ZERO, ndim, ndim)
     535        1595 :                 call setCor(cor, subsetr, getShifted(sample, dim, -mean), dim)
     536         400 :                 call report(__LINE__, subsetr, SK_"unweighted shifted")
     537             : 
     538             :             end block
     539             : 
     540             :             ! test sample uppDia interface.
     541             : 
     542             :             block
     543             : 
     544             :                 type(uppDia_type), parameter :: subsetr = uppDia_type()
     545         400 :                 dim = getChoice([1, 2])
     546         400 :                 ndim = getUnifRand(1_IK, 5_IK)
     547         400 :                 if (dim == 2) then
     548        3946 :                     sample = getUnifRand(ONES, TWOS, ndim, nsam)
     549             :                 else
     550        3859 :                     sample = getUnifRand(ONES, TWOS, nsam, ndim)
     551             :                 end if
     552        2582 :                 rweight = getUnifRand(1._TKC, 9._TKC, nsam)
     553        2582 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
     554        2182 :                 iweisum = sum(iweight)
     555        2182 :                 rweisum = sum(rweight)
     556             : 
     557             :                 ! integer weighted
     558             : 
     559        2022 :                 mean = getMean(sample, dim, iweight)
     560        8310 :                 cor_ref = getCorRef(mean, sample, dim, real(iweight, TKC))
     561             : 
     562        6528 :                 cor = getFilled(ZERO, ndim, ndim)
     563         400 :                 call setCor(cor, subsetr, mean, sample, dim, iweight, iweisum)
     564         400 :                 call report(__LINE__, subsetr, SK_"integer-weighted")
     565             : 
     566        6528 :                 cor = getFilled(ZERO, ndim, ndim)
     567        1622 :                 call setCor(cor, subsetr, getShifted(sample, dim, -mean), dim, iweight, iweisum)
     568         400 :                 call report(__LINE__, subsetr, SK_"integer-weighted shifted")
     569             : 
     570             :                 ! real weighted
     571             : 
     572        2022 :                 mean = getMean(sample, dim, rweight)
     573        6528 :                 cor_ref = getCorRef(mean, sample, dim, rweight)
     574             : 
     575        6528 :                 cor = getFilled(ZERO, ndim, ndim)
     576         400 :                 call setCor(cor, subsetr, mean, sample, dim, rweight, rweisum)
     577         400 :                 call report(__LINE__, subsetr, SK_"real-weighted")
     578             : 
     579        6528 :                 cor = getFilled(ZERO, ndim, ndim)
     580        1622 :                 call setCor(cor, subsetr, getShifted(sample, dim, -mean), dim, rweight, rweisum)
     581         400 :                 call report(__LINE__, subsetr, SK_"real-weighted shifted")
     582             : 
     583             :                 ! unweighted
     584             : 
     585        2022 :                 mean = getMean(sample, dim)
     586        6528 :                 cor_ref = getCorRef(mean, sample, dim)
     587             : 
     588        6528 :                 cor = getFilled(ZERO, ndim, ndim)
     589         400 :                 call setCor(cor, subsetr, mean, sample, dim)
     590         400 :                 call report(__LINE__, subsetr, SK_"unweighted")
     591             : 
     592        6528 :                 cor = getFilled(ZERO, ndim, ndim)
     593        1622 :                 call setCor(cor, subsetr, getShifted(sample, dim, -mean), dim)
     594         400 :                 call report(__LINE__, subsetr, SK_"unweighted shifted")
     595             : 
     596             :             end block
     597             : 
     598             :             ! test sample XY interface.
     599             : 
     600           8 :             block
     601             : 
     602             :                 type(lowDia_type), parameter :: subsetr = lowDia_type()
     603         400 :                 dim = 1_IK
     604         400 :                 ndim = 2_IK
     605        1600 :                 mean = getFilled(ZERO, ndim)
     606        3200 :                 cor_ref = getFilled(ZERO, ndim, ndim)
     607        5164 :                 sample = getUnifRand(ONES, TWOS, nsam, ndim)
     608        2582 :                 rweight = getUnifRand(1._TKC, 9._TKC, nsam)
     609        2582 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
     610        2182 :                 iweisum = sum(iweight)
     611        2182 :                 rweisum = sum(rweight)
     612             : 
     613             :                 ! integer weighted
     614             : 
     615        1600 :                 mean = getMean(sample, dim, iweight)
     616        4982 :                 cor_ref = getCorRef(mean, sample, dim, real(iweight, TKC))
     617             : 
     618        6400 :                 cor = getMatInit([ndim, ndim], uppLowDia, ZERO, ZERO, ONE)
     619         400 :                 call setCor(cor(1,2), mean, sample(:,1), sample(:,2), iweight, iweisum)
     620         400 :                 call report(__LINE__, uppLowDia, SK_"integer-weighted")
     621             : 
     622        6400 :                 cor = getMatInit([ndim, ndim], uppLowDia, ZERO, ZERO, ONE)
     623        3964 :                 call setCor(cor(1,2), sample(:,1) - mean(1), sample(:,2) - mean(2), iweight, iweisum)
     624         400 :                 call report(__LINE__, uppLowDia, SK_"integer-weighted")
     625             : 
     626             :                 ! real weighted
     627             : 
     628        1600 :                 mean = getMean(sample, dim, rweight)
     629        3200 :                 cor_ref = getCorRef(mean, sample, dim, rweight)
     630             : 
     631        6400 :                 cor = getMatInit([ndim, ndim], uppLowDia, ZERO, ZERO, ONE)
     632         400 :                 call setCor(cor(1,2), mean, sample(:,1), sample(:,2), rweight, rweisum)
     633         400 :                 call report(__LINE__, uppLowDia, SK_"real-weighted")
     634             : 
     635        6400 :                 cor = getMatInit([ndim, ndim], uppLowDia, ZERO, ZERO, ONE)
     636        3964 :                 call setCor(cor(1,2), sample(:,1) - mean(1), sample(:,2) - mean(2), rweight, rweisum)
     637         400 :                 call report(__LINE__, uppLowDia, SK_"real-weighted")
     638             : 
     639             :                 ! unweighted
     640             : 
     641        1600 :                 mean = getMean(sample, dim)
     642        3200 :                 cor_ref = getCorRef(mean, sample, dim)
     643             : 
     644        6400 :                 cor = getMatInit([ndim, ndim], uppLowDia, ZERO, ZERO, ONE)
     645         400 :                 call setCor(cor(1,2), mean, sample(:,1), sample(:,2))
     646         400 :                 call report(__LINE__, uppLowDia, SK_"unweighted")
     647             : 
     648        6400 :                 cor = getMatInit([ndim, ndim], uppLowDia, ZERO, ZERO, ONE)
     649        3964 :                 call setCor(cor(1,2), sample(:,1) - mean(1), sample(:,2) - mean(2))
     650         400 :                 call report(__LINE__, uppLowDia, SK_"unweighted")
     651             : 
     652             :             end block
     653             : 
     654             :         end do
     655             : 
     656             :     contains
     657             : 
     658        6400 :         subroutine reportCFC(line, stdinv)
     659             :             real(TKC), intent(in), optional :: stdinv(:)
     660             :             integer, intent(in) :: line
     661      147656 :             cdiff = abs(cor - cor_ref)
     662       95568 :             assertion = assertion .and. all(cdiff < ctol)
     663        6400 :             if (test%traceable .and. .not. assertion) then
     664             :                 ! LCOV_EXCL_START
     665             :                 call test%disp%skip()
     666             :                 call test%disp%show("ndim")
     667             :                 call test%disp%show( ndim )
     668             :                 call test%disp%show("present(stdinv)")
     669             :                 call test%disp%show( present(stdinv) )
     670             :                 if (present(stdinv)) then
     671             :                     call test%disp%show("stdinv")
     672             :                     call test%disp%show( stdinv )
     673             :                 end if
     674             :                 call test%disp%show("cov")
     675             :                 call test%disp%show( cov )
     676             :                 call test%disp%show("cor")
     677             :                 call test%disp%show( cor )
     678             :                 call test%disp%show("cor_ref")
     679             :                 call test%disp%show( cor_ref )
     680             :                 call test%disp%show("cdiff")
     681             :                 call test%disp%show( cdiff )
     682             :                 call test%disp%skip()
     683             :                 ! LCOV_EXCL_STOP
     684             :             end if
     685        6400 :             call test%assert(assertion, SK_"The `cor` must be correctly computed from the specified `cor` and `stdinv`.", int(line, IK))
     686        6400 :         end subroutine
     687             : 
     688        3600 :         PURE function getCorRef(mean, sample, dim, weight) result(cor)
     689             :             ! returns the full correlation matrix of the sample.
     690             :             integer(IK), intent(in) :: dim
     691             :             real(TKC), intent(in), optional :: weight(:)
     692             :             TYPE_OF_SAMPLE, intent(in), contiguous :: sample(:,:), mean(:)
     693             :             TYPE_OF_SAMPLE :: cor(size(sample, 3 - dim, IK), size(sample, 3 - dim, IK))
     694        7200 :             TYPE_OF_SAMPLE :: sampleShifted(size(sample, 1, IK), size(sample, 2, IK))
     695             :             integer(IK) :: idim, jdim, ndim
     696        7200 :             real(TKC) :: stdinv(size(sample, 3 - dim, IK))
     697        3600 :             ndim = size(sample, 3 - dim, IK)
     698       13251 :             sampleShifted = getShifted(sample, dim, -mean)
     699        3600 :             if (present(weight)) then
     700       23784 :                 call setCov(cor, uppDia, sampleShifted, dim, weight, sum(weight))
     701             :             else
     702        1200 :                 call setCov(cor, uppDia, sampleShifted, dim)
     703             :             end if
     704       13251 :             do jdim = 1, ndim
     705        9651 :                 stdinv(jdim) = 1._TKC / sqrt(real(cor(jdim, jdim), TKC))
     706        9651 :                 cor(jdim, jdim) = 1._TKC
     707       24132 :                 do idim = jdim - 1, 1, -1
     708       10881 :                     cor(idim, jdim) = cor(idim, jdim) * stdinv(idim) * stdinv(jdim)
     709       20532 :                     cor(jdim, idim) = GET_CONJG(cor(idim, jdim))
     710             :                 end do
     711             :             end do
     712        3600 :         end function
     713             : 
     714        7200 :         subroutine report(line, subsetr, this)
     715             :             integer, intent(in) :: line
     716             :             class(*), intent(in) :: subsetr
     717             :             character(*, SK), intent(in) :: this
     718        7200 :             if (same_type_as(subsetr, uppDia)) then
     719        2400 :                 call setMatCopy(cor, rdpack, cor, rdpack, uppDia, transHerm)
     720        4800 :             elseif (same_type_as(subsetr, lowDia)) then
     721        2400 :                 call setMatCopy(cor, rdpack, cor, rdpack, lowDia, transHerm)
     722        2400 :             elseif (same_type_as(subsetr, uppLowDia)) then
     723        2400 :                 cor(2,1) = GET_CONJG(cor(1,2))
     724             :             else
     725           0 :                 error stop "Unrecognized subset."
     726             :             end if
     727      138120 :             cdiff = abs(cor - cor_ref)
     728       89328 :             assertion = assertion .and. all(cdiff < ctol)
     729        7200 :             if (test%traceable .and. .not. assertion) then
     730             :                 ! LCOV_EXCL_START
     731             :                 call test%disp%skip()
     732             :                 call test%disp%show("[ndim, nsam, dim, shape(sample, IK)]")
     733             :                 call test%disp%show( [ndim, nsam, dim, shape(sample, IK)] )
     734             :                 call test%disp%show("sample")
     735             :                 call test%disp%show( sample )
     736             :                 call test%disp%show("iweight")
     737             :                 call test%disp%show( iweight )
     738             :                 call test%disp%show("rweight")
     739             :                 call test%disp%show( rweight )
     740             :                 call test%disp%show("cor_ref")
     741             :                 call test%disp%show( cor_ref )
     742             :                 call test%disp%show("cor")
     743             :                 call test%disp%show( cor )
     744             :                 call test%disp%show("cdiff")
     745             :                 call test%disp%show( cdiff )
     746             :                 call test%disp%skip()
     747             :                 ! LCOV_EXCL_STOP
     748             :             end if
     749        7200 :             call test%assert(assertion, SK_"The `cor` must be computed correctly for "//this//SK_" sample.", int(line, IK))
     750        7200 :         end subroutine
     751             : 
     752             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     753             : #elif   getRho_ENABLED && (XY_ENABLED || D0_ENABLED)
     754             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     755             : 
     756             :         integer(IK) :: itry, nsam
     757             :         real(RK), allocatable :: rweight(:)
     758             :         integer(IK), allocatable :: iweight(:)
     759             :         real(RK), allocatable :: frankx(:), franky(:)
     760             : #if     D0_ENABLED
     761           1 :         TYPE_OF_SAMPLE, allocatable :: x, y
     762             : #elif   XY_ENABLED
     763           1 :         TYPE_OF_SAMPLE, allocatable :: x(:), y(:)
     764             : #else
     765             : #error  "Unrecognized interface."
     766             : #endif
     767             :         real(RK) :: rho, rho_ref, rdiff
     768          12 :         assertion = .true._LK
     769         666 :         do itry = 1, 50
     770             : 
     771         600 :             nsam = getUnifRand(20_IK, 30_IK)
     772             : #if         D0_ENABLED && SK_ENABLED
     773        2552 :             x = getUnifRand(repeat(lb, nsam), repeat(ub, nsam))
     774        2552 :             y = getUnifRand(repeat(lb, nsam), repeat(ub, nsam))
     775             : #elif       XY_ENABLED && (BSSK_ENABLED || PSSK_ENABLED)
     776        2498 :             if (allocated(x)) deallocate(x); allocate(x(nsam))
     777        2498 :             if (allocated(y)) deallocate(y); allocate(y(nsam))
     778             :             block
     779             :                 integer(IK) :: isam
     780        1287 :                 do isam = 1, nsam
     781        1237 :                     x(isam)%val = getUnifRand(lb, ub)
     782        1287 :                     y(isam)%val = getUnifRand(lb, ub)
     783             :                 end do
     784             :             end block
     785             : #elif       XY_ENABLED
     786       13504 :             x = getUnifRand(lb, ub, nsam)
     787       13504 :             y = getUnifRand(lb, ub, nsam)
     788             : #else
     789             : #error      "Unrecognized interface."
     790             : #endif
     791       16192 :             iweight = getUnifRand(1_IK, 9_IK, nsam)
     792       16192 :             rweight = getUnifRand(1._RK, 9._RK, nsam)
     793             : 
     794             :             ! integer weighted
     795             : 
     796       15592 :             rho_ref = getRhoCoef(real(iweight, RK))
     797             : 
     798         600 :             rho = getRho(x, y, iweight)
     799         600 :             call report(__LINE__, SK_"integer-weighted")
     800             : 
     801             :             ! real weighted
     802             : 
     803         600 :             rho_ref = getRhoCoef(rweight)
     804             : 
     805         600 :             rho = getRho(x, y, rweight)
     806         600 :             call report(__LINE__, SK_"real-weighted")
     807             : 
     808             :             ! unweighted
     809             : 
     810         600 :             rho_ref = getRhoCoef()
     811             : 
     812         600 :             rho = getRho(x, y)
     813         612 :             call report(__LINE__, SK_"unweighted")
     814             : 
     815             :         end do
     816             : 
     817             :     contains
     818             : 
     819        1800 :         function getRhoCoef(weight) result(rho)
     820             :             ! returns the full correlation matrix of the sample.
     821             :             real(RK), intent(in), optional :: weight(:)
     822             :             real(RK) :: rho
     823       48576 :             frankx = getRankFractional(x)
     824       48576 :             franky = getRankFractional(y)
     825        1800 :             if (present(weight)) then
     826       31184 :                 rho = getCor(frankx, franky, weight)
     827             :             else
     828         600 :                 rho = getCor(frankx, franky)
     829             :             end if
     830        1800 :         end function
     831             : 
     832        1800 :         subroutine report(line, this)
     833             :             integer, intent(in) :: line
     834             :             character(*, SK), intent(in) :: this
     835        1800 :             rdiff = abs(rho - rho_ref)
     836        1800 :             assertion = assertion .and. rdiff < rtol
     837        1800 :             if (test%traceable .and. .not. assertion) then
     838             :                 ! LCOV_EXCL_START
     839             :                 call test%disp%skip()
     840             :                 call test%disp%show("nsam")
     841             :                 call test%disp%show( nsam )
     842             :                 call test%disp%show("x")
     843             :                 call test%disp%show( x , deliml = SK_"""" )
     844             :                 call test%disp%show("y" )
     845             :                 call test%disp%show( y , deliml = SK_"""" )
     846             :                 call test%disp%show("iweight")
     847             :                 call test%disp%show( iweight )
     848             :                 call test%disp%show("rweight")
     849             :                 call test%disp%show( rweight )
     850             :                 call test%disp%show("rho_ref")
     851             :                 call test%disp%show( rho_ref )
     852             :                 call test%disp%show("rho")
     853             :                 call test%disp%show( rho )
     854             :                 call test%disp%show("rdiff")
     855             :                 call test%disp%show( rdiff )
     856             :                 call test%disp%skip()
     857             :                 ! LCOV_EXCL_STOP
     858             :             end if
     859        1800 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
     860        1800 :         end subroutine
     861             : 
     862             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     863             : #elif   getRho_ENABLED && D2_ENABLED
     864             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     865             : 
     866             :         real(RK), allocatable :: rweight(:)
     867             :         integer(IK), allocatable :: iweight(:)
     868             :         integer(IK) :: itry, nsam
     869             :         real(RK), allocatable :: rho(:,:), rho_ref(:,:), rdiff(:,:)
     870           1 :         TYPE_OF_SAMPLE, allocatable :: sample(:,:)
     871             :         integer(IK) :: ndim, dim
     872          11 :         assertion = .true._LK
     873             : 
     874         584 :         do itry = 1, 50
     875             : 
     876             :             ! Test Rho: The strategy is to construct a sample, compute its correlation and compare it against the reference computed here.
     877             : 
     878         550 :             nsam = getUnifRand(20_IK, 30_IK)
     879             : 
     880             :             ! test sample lowDia interface.
     881             : 
     882          11 :             block
     883             : 
     884         550 :                 dim = getChoice([1, 2])
     885         550 :                 ndim = getUnifRand(1_IK, 5_IK)
     886         550 :                 if (dim == 2) then
     887             : #if                 PSSK_ENABLED
     888             :                     sample = css_pdt(getUnifRand(lb, ub, ndim, nsam))
     889             : #elif               BSSK_ENABLED
     890        8035 :                     sample = css_type(getUnifRand(lb, ub, ndim, nsam))
     891             : #else
     892       25930 :                     sample = getUnifRand(lb, ub, ndim, nsam)
     893             : #endif
     894             :                 else
     895             : #if                 PSSK_ENABLED
     896             :                     sample = css_pdt(getUnifRand(lb, ub, nsam, ndim))
     897             : #elif               BSSK_ENABLED
     898        7769 :                     sample = css_type(getUnifRand(lb, ub, nsam, ndim))
     899             : #else
     900       21573 :                     sample = getUnifRand(lb, ub, nsam, ndim)
     901             : #endif
     902             :                 end if
     903       14945 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
     904       14945 :                 rweight = getUnifRand(1., 9., nsam)
     905             : 
     906             :                 ! integer weighted
     907             : 
     908       23075 :                 rho_ref = getRhoRef(real(iweight, RK))
     909        9230 :                 rho = getRho(sample, dim, iweight)
     910         550 :                 call report(__LINE__, SK_"integer-weighted")
     911             : 
     912             :                 ! real weighted
     913             : 
     914        9230 :                 rho_ref = getRhoRef(rweight)
     915        9230 :                 rho = getRho(sample, dim, rweight)
     916         550 :                 call report(__LINE__, SK_"real-weighted")
     917             : 
     918             :                 ! unweighted
     919             : 
     920        9230 :                 rho_ref = getRhoRef()
     921        9230 :                 rho = getRho(sample, dim)
     922         550 :                 call report(__LINE__, SK_"unweighted")
     923             : 
     924             :             end block
     925             : 
     926             :         end do
     927             : 
     928             :     contains
     929             : 
     930        1650 :         function getRhoRef(weight) result(rho)
     931             :             ! returns the full correlation matrix of the sample.
     932             :             real(RK), intent(in), optional :: weight(:)
     933             :             real(RK) :: rho(size(sample, 3 - dim, IK), size(sample, 3 - dim, IK))
     934        1650 :             real(RK) :: frank(size(sample, 1, IK), size(sample, 2, IK))
     935             :             integer(IK) :: idim, ndim, nsam
     936             :             ndim = size(sample, 3 - dim, IK)
     937             :             nsam = size(sample, dim, IK)
     938        1650 :             if (dim == 2_IK) then
     939        3327 :                 do idim = 1, ndim
     940      129507 :                     frank(idim, :) = getRankFractional(sample(idim, :))
     941             :                 end do
     942             :             else
     943        3462 :                 do idim = 1, ndim
     944        3462 :                     frank(:, idim) = getRankFractional(sample(:, idim))
     945             :                 end do
     946             :             end if
     947        1650 :             if (present(weight)) then
     948       28790 :                 rho = getCor(frank, dim, weight)
     949             :             else
     950         550 :                 rho = getCor(frank, dim)
     951             :             end if
     952        1650 :         end function
     953             : 
     954        1650 :         subroutine report(line, this)
     955             :             integer, intent(in) :: line
     956             :             character(*, SK), intent(in) :: this
     957       27690 :             rdiff = abs(rho - rho_ref)
     958       26040 :             assertion = assertion .and. all(rdiff < rtol)
     959        1650 :             if (test%traceable .and. .not. assertion) then
     960             :                 ! LCOV_EXCL_START
     961             :                 call test%disp%skip()
     962             :                 call test%disp%show("[ndim, nsam, dim, GET_SHAPE(sample, IK)]")
     963             :                 call test%disp%show( [ndim, nsam, dim, GET_SHAPE(sample, IK)] )
     964             :                 call test%disp%show("sample")
     965             :                 call test%disp%show( sample )
     966             :                 call test%disp%show("iweight")
     967             :                 call test%disp%show( iweight )
     968             :                 call test%disp%show("rweight")
     969             :                 call test%disp%show( rweight )
     970             :                 call test%disp%show("rho_ref")
     971             :                 call test%disp%show( rho_ref )
     972             :                 call test%disp%show("rho")
     973             :                 call test%disp%show( rho )
     974             :                 call test%disp%show("rdiff")
     975             :                 call test%disp%show( rdiff )
     976             :                 call test%disp%skip()
     977             :                 ! LCOV_EXCL_STOP
     978             :             end if
     979        1650 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
     980        1650 :         end subroutine
     981             : 
     982             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     983             : #elif   setRho_ENABLED && (XY_ENABLED || D0_ENABLED)
     984             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     985             : 
     986             :         integer(IK) :: itry, nsam
     987             :         real(RK), allocatable :: rweight(:)
     988             :         integer(IK), allocatable :: iweight(:)
     989             :         real(RK), allocatable :: frankx(:), franky(:), frankx_ref(:), franky_ref(:)
     990             : #if     D0_ENABLED
     991           1 :         TYPE_OF_SAMPLE, allocatable :: x, y
     992             : #elif   XY_ENABLED
     993           1 :         TYPE_OF_SAMPLE, allocatable :: x(:), y(:)
     994             : #else
     995             : #error  "Unrecognized interface."
     996             : #endif
     997             :         real(RK) :: rho, rho_ref, rdiff
     998          12 :         assertion = .true._LK
     999         668 :         do itry = 1, 50
    1000             : 
    1001         600 :             nsam = getUnifRand(20_IK, 30_IK)
    1002             : #if         D0_ENABLED && SK_ENABLED
    1003        2536 :             x = getUnifRand(repeat(lb, nsam), repeat(ub, nsam))
    1004        2536 :             y = getUnifRand(repeat(lb, nsam), repeat(ub, nsam))
    1005             : #elif       XY_ENABLED && (BSSK_ENABLED || PSSK_ENABLED)
    1006        2481 :             if (allocated(x)) deallocate(x); allocate(x(nsam))
    1007        2481 :             if (allocated(y)) deallocate(y); allocate(y(nsam))
    1008             :             block
    1009             :                 integer(IK) :: isam
    1010        1279 :                 do isam = 1, nsam
    1011        1229 :                     x(isam)%val = getUnifRand(lb, ub)
    1012        1279 :                     y(isam)%val = getUnifRand(lb, ub)
    1013             :                 end do
    1014             :             end block
    1015             : #elif       XY_ENABLED
    1016       13469 :             x = getUnifRand(lb, ub, nsam)
    1017       13469 :             y = getUnifRand(lb, ub, nsam)
    1018             : #else
    1019             : #error      "Unrecognized interface."
    1020             : #endif
    1021       16141 :             frankx = getFilled(0._RK, nsam)
    1022       16141 :             franky = getFilled(0._RK, nsam)
    1023       16141 :             iweight = getUnifRand(1_IK, 9_IK, nsam)
    1024       16141 :             rweight = getUnifRand(1._RK, 9._RK, nsam)
    1025             : 
    1026             :             ! integer weighted
    1027             : 
    1028       15541 :             rho_ref = getRhoCoef(real(iweight, RK))
    1029             : 
    1030             :             call setRho(rho, frankx, franky, x, y, iweight)
    1031         600 :             call report(__LINE__, SK_"integer-weighted")
    1032             : 
    1033             :             ! real weighted
    1034             : 
    1035         600 :             rho_ref = getRhoCoef(rweight)
    1036             : 
    1037             :             call setRho(rho, frankx, franky, x, y, rweight)
    1038         600 :             call report(__LINE__, SK_"real-weighted")
    1039             : 
    1040             :             ! unweighted
    1041             : 
    1042         600 :             rho_ref = getRhoCoef()
    1043             : 
    1044             :             call setRho(rho, frankx, franky, x, y)
    1045        1812 :             call report(__LINE__, SK_"unweighted")
    1046             : 
    1047             :         end do
    1048             : 
    1049             :     contains
    1050             : 
    1051        1800 :         function getRhoCoef(weight) result(rho)
    1052             :             ! returns the full correlation matrix of the sample.
    1053             :             real(RK), intent(in), optional :: weight(:)
    1054             :             real(RK) :: rho
    1055       48423 :             frankx_ref = getRankFractional(x)
    1056       48423 :             franky_ref = getRankFractional(y)
    1057        1800 :             if (present(weight)) then
    1058       31082 :                 rho = getCor(frankx_ref, franky_ref, weight)
    1059             :             else
    1060         600 :                 rho = getCor(frankx_ref, franky_ref)
    1061             :             end if
    1062        1800 :         end function
    1063             : 
    1064        1800 :         subroutine report(line, this)
    1065             :             integer, intent(in) :: line
    1066             :             character(*, SK), intent(in) :: this
    1067        1800 :             rdiff = abs(rho - rho_ref)
    1068        1800 :             assertion = assertion .and. rdiff < rtol
    1069       46623 :             assertion = assertion .and. all(abs(frankx - frankx_ref) < rtol)
    1070       46623 :             assertion = assertion .and. all(abs(franky - franky_ref) < rtol)
    1071        1800 :             if (test%traceable .and. .not. assertion) then
    1072             :                 ! LCOV_EXCL_START
    1073             :                 call test%disp%skip()
    1074             :                 call test%disp%show("nsam")
    1075             :                 call test%disp%show( nsam )
    1076             :                 call test%disp%show("x")
    1077             :                 call test%disp%show( x , deliml = SK_"""" )
    1078             :                 call test%disp%show("y" )
    1079             :                 call test%disp%show( y , deliml = SK_"""" )
    1080             :                 call test%disp%show("iweight")
    1081             :                 call test%disp%show( iweight )
    1082             :                 call test%disp%show("rweight")
    1083             :                 call test%disp%show( rweight )
    1084             :                 call test%disp%show("frankx")
    1085             :                 call test%disp%show( frankx )
    1086             :                 call test%disp%show("frankx_ref")
    1087             :                 call test%disp%show( frankx_ref )
    1088             :                 call test%disp%show("franky")
    1089             :                 call test%disp%show( franky )
    1090             :                 call test%disp%show("franky_ref")
    1091             :                 call test%disp%show( franky_ref )
    1092             :                 call test%disp%show("rho_ref")
    1093             :                 call test%disp%show( rho_ref )
    1094             :                 call test%disp%show("rho")
    1095             :                 call test%disp%show( rho )
    1096             :                 call test%disp%show("rdiff")
    1097             :                 call test%disp%show( rdiff )
    1098             :                 call test%disp%skip()
    1099             :                 ! LCOV_EXCL_STOP
    1100             :             end if
    1101             :             ! Three tests, so three calls.
    1102        1800 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
    1103        1800 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
    1104        1800 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
    1105        1800 :         end subroutine
    1106             : 
    1107             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1108             : #elif   setRho_ENABLED && D2_ENABLED
    1109             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1110             : 
    1111             :         real(RK), allocatable :: rweight(:)
    1112             :         integer(IK), allocatable :: iweight(:)
    1113             :         integer(IK) :: itry, nsam
    1114             :         real(RK), allocatable :: frank(:,:), frank_ref(:,:), rho(:,:), rho_ref(:,:), rdiff(:,:)
    1115           1 :         TYPE_OF_SAMPLE, allocatable :: sample(:,:)
    1116             :         integer(IK) :: ndim, dim
    1117          11 :         assertion = .true._LK
    1118             : 
    1119         592 :         do itry = 1, 50
    1120             : 
    1121             :             ! Test Rho: The strategy is to construct a sample, compute its correlation and compare it against the reference computed here.
    1122             : 
    1123         550 :             nsam = getUnifRand(20_IK, 30_IK)
    1124             : 
    1125             :             ! test sample lowDia interface.
    1126             : 
    1127             :             block
    1128             : 
    1129             :                 type(lowDia_type), parameter :: subsetr = lowDia_type()
    1130         550 :                 dim = getChoice([1, 2])
    1131         550 :                 ndim = getUnifRand(1_IK, 5_IK)
    1132         550 :                 if (dim == 2) then
    1133             : #if                 PSSK_ENABLED
    1134             :                     sample = css_pdt(getUnifRand(lb, ub, ndim, nsam))
    1135             : #elif               BSSK_ENABLED
    1136        7993 :                     sample = css_type(getUnifRand(lb, ub, ndim, nsam))
    1137             : #else
    1138       25868 :                     sample = getUnifRand(lb, ub, ndim, nsam)
    1139             : #endif
    1140             :                 else
    1141             : #if                 PSSK_ENABLED
    1142             :                     sample = css_pdt(getUnifRand(lb, ub, nsam, ndim))
    1143             : #elif               BSSK_ENABLED
    1144        6074 :                     sample = css_type(getUnifRand(lb, ub, nsam, ndim))
    1145             : #else
    1146       19391 :                     sample = getUnifRand(lb, ub, nsam, ndim)
    1147             : #endif
    1148             :                 end if
    1149       49252 :                 frank = getFilled(0._RK, size(sample, 1, IK), size(sample, 2, IK))
    1150       50336 :                 frank_ref = frank
    1151       14779 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
    1152       14779 :                 rweight = getUnifRand(1., 9., nsam)
    1153             : 
    1154             :                 ! integer weighted
    1155             : 
    1156       22389 :                 rho_ref = getRhoRef(real(iweight, RK))
    1157             : 
    1158        8710 :                 rho = getFilled(0._RK, ndim, ndim)
    1159         550 :                 call setRho(rho, subsetr, frank, sample, dim, iweight)
    1160         550 :                 call report(__LINE__, subsetr, SK_"integer-weighted")
    1161             : 
    1162             :                 ! real weighted
    1163             : 
    1164        8710 :                 rho_ref = getRhoRef(rweight)
    1165             : 
    1166        8710 :                 rho = getFilled(0._RK, ndim, ndim)
    1167         550 :                 call setRho(rho, subsetr, frank, sample, dim, rweight)
    1168         550 :                 call report(__LINE__, subsetr, SK_"real-weighted")
    1169             : 
    1170             :                 ! unweighted
    1171             : 
    1172        8710 :                 rho_ref = getRhoRef()
    1173             : 
    1174        8710 :                 rho = getFilled(0._RK, ndim, ndim)
    1175         550 :                 call setRho(rho, subsetr, frank, sample, dim)
    1176         550 :                 call report(__LINE__, subsetr, SK_"unweighted")
    1177             : 
    1178             :             end block
    1179             : 
    1180             :             ! test sample uppDia interface.
    1181             : 
    1182          11 :             block
    1183             : 
    1184             :                 type(uppDia_type), parameter :: subsetr = uppDia_type()
    1185         550 :                 dim = getChoice([1, 2])
    1186         550 :                 ndim = getUnifRand(1_IK, 5_IK)
    1187         550 :                 if (dim == 2) then
    1188             : #if                 PSSK_ENABLED
    1189             :                     sample = css_pdt(getUnifRand(lb, ub, ndim, nsam))
    1190             : #elif               BSSK_ENABLED
    1191        7174 :                     sample = css_type(getUnifRand(lb, ub, ndim, nsam))
    1192             : #else
    1193       25801 :                     sample = getUnifRand(lb, ub, ndim, nsam)
    1194             : #endif
    1195             :                 else
    1196             : #if                 PSSK_ENABLED
    1197             :                     sample = css_pdt(getUnifRand(lb, ub, nsam, ndim))
    1198             : #elif               BSSK_ENABLED
    1199        6085 :                     sample = css_type(getUnifRand(lb, ub, nsam, ndim))
    1200             : #else
    1201       20168 :                     sample = getUnifRand(lb, ub, nsam, ndim)
    1202             : #endif
    1203             :                 end if
    1204       49926 :                 frank = getFilled(0._RK, size(sample, 1, IK), size(sample, 2, IK))
    1205       50940 :                 frank_ref = frank
    1206       14779 :                 iweight = getUnifRand(1_IK, 9_IK, nsam)
    1207       14779 :                 rweight = getUnifRand(1., 9., nsam)
    1208             : 
    1209             :                 ! integer weighted
    1210             : 
    1211       22569 :                 rho_ref = getRhoRef(real(iweight, RK))
    1212             : 
    1213        8890 :                 rho = getFilled(0._RK, ndim, ndim)
    1214         550 :                 call setRho(rho, subsetr, frank, sample, dim, iweight)
    1215         550 :                 call report(__LINE__, subsetr, SK_"integer-weighted")
    1216             : 
    1217             :                 ! real weighted
    1218             : 
    1219        8890 :                 rho_ref = getRhoRef(rweight)
    1220             : 
    1221        8890 :                 rho = getFilled(0._RK, ndim, ndim)
    1222         550 :                 call setRho(rho, subsetr, frank, sample, dim, rweight)
    1223         550 :                 call report(__LINE__, subsetr, SK_"real-weighted")
    1224             : 
    1225             :                 ! unweighted
    1226             : 
    1227        8890 :                 rho_ref = getRhoRef()
    1228             : 
    1229        8890 :                 rho = getFilled(0._RK, ndim, ndim)
    1230         550 :                 call setRho(rho, subsetr, frank, sample, dim)
    1231         550 :                 call report(__LINE__, subsetr, SK_"unweighted")
    1232             : 
    1233             :             end block
    1234             : 
    1235             :         end do
    1236             : 
    1237             :     contains
    1238             : 
    1239        3300 :         function getRhoRef(weight) result(rho)
    1240             :             ! returns the full correlation matrix of the sample.
    1241             :             real(RK), intent(in), optional :: weight(:)
    1242             :             real(RK) :: rho(size(sample, 3 - dim, IK), size(sample, 3 - dim, IK))
    1243             :             integer(IK) :: idim, ndim, nsam
    1244             :             ndim = size(sample, 3 - dim, IK)
    1245             :             nsam = size(sample, dim, IK)
    1246        3300 :             if (dim == 2_IK) then
    1247        6660 :                 do idim = 1, ndim
    1248      254634 :                     frank_ref(idim, :) = getRankFractional(sample(idim, :))
    1249             :                 end do
    1250             :             else
    1251        6486 :                 do idim = 1, ndim
    1252      127290 :                     frank_ref(:, idim) = getRankFractional(sample(:, idim))
    1253             :                 end do
    1254             :             end if
    1255        3300 :             if (present(weight)) then
    1256       56916 :                 rho = getCor(frank_ref, dim, weight)
    1257             :             else
    1258        1100 :                 rho = getCor(frank_ref, dim)
    1259             :             end if
    1260        3300 :         end function
    1261             : 
    1262        3300 :         subroutine report(line, subsetr, this)
    1263             :             integer, intent(in) :: line
    1264             :             class(*), intent(in) :: subsetr
    1265             :             character(*, SK), intent(in) :: this
    1266        3300 :             if (same_type_as(subsetr, uppDia)) then
    1267        1650 :                 call setMatCopy(rho, rdpack, rho, rdpack, uppDia, transHerm)
    1268        1650 :             elseif (same_type_as(subsetr, lowDia)) then
    1269        1650 :                 call setMatCopy(rho, rdpack, rho, rdpack, lowDia, transHerm)
    1270           0 :             elseif (same_type_as(subsetr, uppLowDia)) then
    1271           0 :                 rho(2,1) = rho(1,2)
    1272             :             else
    1273           0 :                 error stop "Unrecognized subset."
    1274             :             end if
    1275       52800 :             rdiff = abs(rho - rho_ref)
    1276       49500 :             assertion = assertion .and. all(rdiff < rtol)
    1277      294234 :             assertion = assertion .and. all(abs(frank - frank_ref) < rtol)
    1278        3300 :             if (test%traceable .and. .not. assertion) then
    1279             :                 ! LCOV_EXCL_START
    1280             :                 call test%disp%skip()
    1281             :                 call test%disp%show("[ndim, nsam, dim, GET_SHAPE(sample, IK)]")
    1282             :                 call test%disp%show( [ndim, nsam, dim, GET_SHAPE(sample, IK)] )
    1283             :                 call test%disp%show("sample")
    1284             :                 call test%disp%show( sample )
    1285             :                 call test%disp%show("iweight")
    1286             :                 call test%disp%show( iweight )
    1287             :                 call test%disp%show("rweight")
    1288             :                 call test%disp%show( rweight )
    1289             :                 call test%disp%show("frank_ref")
    1290             :                 call test%disp%show( frank_ref )
    1291             :                 call test%disp%show("frank")
    1292             :                 call test%disp%show( frank )
    1293             :                 call test%disp%show("rho_ref")
    1294             :                 call test%disp%show( rho_ref )
    1295             :                 call test%disp%show("rho")
    1296             :                 call test%disp%show( rho )
    1297             :                 call test%disp%show("rdiff")
    1298             :                 call test%disp%show( rdiff )
    1299             :                 call test%disp%skip()
    1300             :                 ! LCOV_EXCL_STOP
    1301             :             end if
    1302             :             ! two tests, two reports.
    1303        3300 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
    1304        3300 :             call test%assert(assertion, SK_"The `rho` and fractional ranks must be computed correctly for "//this//SK_" sample.", int(line, IK))
    1305        3300 :         end subroutine
    1306             : 
    1307             :         !%%%%%%%%%%%%%%%%%%
    1308             : #elif   setCordance_ENABLED
    1309             :         !%%%%%%%%%%%%%%%%%%
    1310             : 
    1311             :         assertion = .true.
    1312             : 
    1313             : #else
    1314             :         !%%%%%%%%%%%%%%%%%%%%%%%%
    1315             : #error  "Unrecognized interface."
    1316             :         !%%%%%%%%%%%%%%%%%%%%%%%%
    1317             : #endif
    1318             : #undef  TYPE_OF_SAMPLE
    1319             : #undef  GET_CONJG
    1320             : #undef  GET_SHAPE

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