https://www.cdslab.org/paramonte/fortran/2
Current view: top level - main - pm_sampleCCF@routines.inc.F90 (source / functions) Hit Total Coverage
Test: ParaMonte 2.0.0 :: Serial Fortran - Code Coverage Report Lines: 118 122 96.7 %
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 file contains the implementation details of the 2D routines under the generic interface [pm_sampleCCF](@ref pm_sampleCCF).
      19             : !>
      20             : !>  \finmain
      21             : !>
      22             : !>  \author
      23             : !>  \FatemehBagheri, Saturday 4:40 PM, August 21, 2021, Dallas, TX
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             :         ! Set the type and kind and the conjugation rule.
      28             : #if     CK_ENABLED
      29             : #define GET_ABSQ(X)(real(X)**2 + aimag(X)**2)
      30             : #define TYPE_OF_SEQ complex(TKC)
      31             : #define GET_RE(X)X%re
      32             : #elif   RK_ENABLED
      33             : #define TYPE_OF_SEQ real(TKC)
      34             : #define GET_ABSQ(X)X**2
      35             : #define GET_RE(X)X
      36             : #else
      37             : #error  "Unrecognized interface."
      38             : #endif
      39             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
      40             : #if     getACF_ENABLED && D1_ENABLED
      41             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
      42             : 
      43             :         real(TKC) :: normfac
      44             :         TYPE_OF_SEQ :: meanf
      45       16016 :         class(*), allocatable :: norm_def
      46             :         TYPE_OF_SEQ, parameter :: ZERO = 0._TKC
      47             :         TYPE_OF_SEQ, allocatable :: ff(:), coef(:)
      48             :         integer(IK), allocatable :: factor(:)
      49             :         logical(LK) :: unscaled, inf
      50             :         integer(IK) :: lagmax
      51             :         integer(IK) :: lagmin
      52             :         integer(IK) :: lenacf
      53             : 
      54        9608 :         lagmax = size(f, 1, IK) - 1_IK
      55        9608 :         lagmin = 1_IK - size(f, 1, IK)
      56        9608 :         if (present(lag)) then
      57        6402 :             if (size(lag, 1, IK) == 0_IK) then
      58        3200 :                 allocate(acf(0))
      59             :                 return
      60             :             end if
      61        3202 :             CHECK_ASSERTION(__LINE__, isAscending(lag), SK_"@setACF(): The condition `isAscending(lag)` must hold. lag = "//getStr(lag))
      62        3202 :             lagmax = max(lagmax, lag(size(lag, 1, IK)))
      63        3202 :             lagmin = min(lagmin, lag(1))
      64             :         end if
      65        6408 :         lenacf = lagmax - lagmin + 1_IK
      66             : 
      67             :         ! Allocate and pad the arrays.
      68             : 
      69        6408 :         allocate(ff(lenacf), coef(lenacf), acf(lenacf))
      70             : 
      71             :         ! Shift the padded arrays if needed.
      72             : 
      73        6408 :         if (present(norm)) then
      74        4804 :             unscaled = logical(same_type_as(norm, zscore_type()) .or. same_type_as(norm, stdscale_type()), LK)
      75        4804 :             norm_def = norm
      76             :         else
      77             :             unscaled = .true._LK
      78        1604 :             norm_def = zscore_type() ! Intel cannot digest `same_type_as(norm_def, zscore_type())` if norm_def is set to constant.
      79             :         end if
      80             : 
      81        6408 :         if (same_type_as(norm_def, meanshift_type()) .or. same_type_as(norm_def, zscore_type())) then
      82        4804 :             meanf = getMean(f)
      83      105966 :             ff(1 : size(f, 1, IK)) = f - meanf
      84        1604 :         elseif (same_type_as(norm_def, stdscale_type()) .or. same_type_as(norm_def, nothing_type())) then
      85       72258 :             ff(1 : size(f, 1, IK)) = f
      86             :         else
      87             :             error stop MODULE_NAME//SK_"@getACF(): Unrecognized `norm`." ! LCOV_EXCL_LINE
      88             :         end if
      89      267684 :         ff(size(f, 1, IK) + 1 : lenacf) = ZERO
      90             : 
      91             :         ! Compute the ACF.
      92             : 
      93       25080 :         factor = getFactorFFT(ff, coef)
      94        6408 :         call setACF(factor, coef, ff, acf, inf)
      95             : 
      96             :         ! Normalize and shift.
      97             : 
      98        6408 :         normfac = 1._TKC / lenacf ! default scale.
      99        6408 :         if (inf) then
     100        2468 :             if (unscaled) normfac = 1._TKC / GET_RE(ff(1))
     101        2468 :             if (present(lag)) then
     102      106108 :                 acf = cshift(ff * normfac, lagmin)
     103             :             else
     104       23210 :                 acf = ff(1 : 1 + lagmax) * normfac
     105             :             end if
     106             :         else
     107        3940 :             if (unscaled) normfac = 1._TKC / GET_RE(acf(1))
     108        3940 :             if (present(lag)) then
     109      124588 :                 acf = cshift(acf * normfac, lagmin)
     110             :             else
     111      170776 :                 acf = acf(1 : 1 + lagmax) * normfac
     112             :             end if
     113             :         end if
     114      490096 :         if (present(lag)) acf = acf(lag - lagmin + 1)
     115        6408 :         deallocate(ff, coef) ! essential for gfortran on heap.
     116             : 
     117             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     118             : #elif   setACF_ENABLED && FP_ENABLED && D1_ENABLED
     119             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     120             : 
     121             :         integer(IK) :: isam, nsam
     122        6577 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) >= 2_IK, SK_"@setACF(): The condition `1 < size(f)` must hold. size(f) = "//getStr(size(f, 1, IK)))
     123       19731 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) == size(coef, 1, IK), SK_"@setACF(): The condition `size(f) == size(coef)` must hold. size(f), size(coef) = "//getStr([size(f, 1, IK), size(coef, 1, IK)]))
     124       19731 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) == size(work, 1, IK), SK_"@setACF(): The condition `size(f) == size(work)` must hold. size(f), size(work) = "//getStr([size(f, 1, IK), size(work, 1, IK)]))
     125        6577 :         call setFFTF(factor, coef, f, work, inf)
     126             :         nsam = size(f, 1, IK)
     127             : #if     CK_ENABLED
     128        3286 :         if (inf) then
     129             :             ! fft of `f` is in `work`.
     130             :             do concurrent(isam = 1 : nsam)
     131      108492 :                 f(isam)%re = work(isam)%re**2 + work(isam)%im**2
     132      110536 :                 f(isam)%im = 0._TKC
     133             :             end do
     134             :         else
     135             :             ! fft of `f` is in `f`.
     136             :             do concurrent(isam = 1 : nsam)
     137       73822 :                 f(isam)%re = f(isam)%re**2 + f(isam)%im**2
     138       75064 :                 f(isam)%im = 0._TKC
     139             :             end do
     140             :         end if
     141             : #elif   RK_ENABLED
     142        3291 :         if (mod(nsam, 2_IK) == 0_IK) nsam = nsam - 1_IK
     143        3291 :         if (inf) then
     144             :             ! fft of `f` is in `work`.
     145        2024 :             f(1) = work(1)**2
     146             :             do concurrent(isam = 2 : nsam : 2)
     147       90876 :                 f(isam) = work(isam)**2 + work(isam + 1)**2
     148       92900 :                 f(isam + 1) = 0._TKC
     149             :             end do
     150        2024 :             if (nsam < size(f, 1, IK)) f(nsam + 1) = work(nsam + 1)**2
     151             :         else
     152             :             ! fft of `f` is in `f`.
     153        1267 :             f(1) = f(1)**2
     154             :             do concurrent(isam = 2 : nsam : 2)
     155       36092 :                 f(isam) = f(isam)**2 + f(isam + 1)**2
     156       37359 :                 f(isam + 1) = 0._TKC
     157             :             end do
     158        1267 :             if (nsam < size(f, 1, IK)) f(nsam + 1) = f(nsam + 1)**2
     159             :         end if
     160             : #else
     161             : #error  "Unrecognized interface."
     162             : #endif
     163             :         ! result is now in `f`.
     164        6577 :         call setFFTR(factor, coef, f, work, inf)
     165        6577 :         inf = .not. inf
     166             : #undef  SET_CCF
     167             : 
     168             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     169             : #elif   getCCF_ENABLED && FG_ENABLED
     170             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%
     171             : 
     172             :         TYPE_OF_SEQ :: meanf, meang
     173             :         TYPE_OF_SEQ, parameter :: ZERO = 0._TKC
     174             :         TYPE_OF_SEQ, allocatable :: ff(:), gg(:), coef(:)
     175             :         real(TKC) :: normfac, sumsqf, sumsqg
     176             :         integer(IK), allocatable :: factor(:)
     177       32812 :         class(*), allocatable :: norm_def
     178             :         integer(IK) :: lagmax
     179             :         integer(IK) :: lagmin
     180             :         integer(IK) :: lenccf
     181             :         integer(IK) :: iell
     182             :         logical(LK) :: inf
     183             : 
     184       18406 :         lagmax = size(g, 1, IK) - 1_IK
     185       18406 :         lagmin = 1_IK - size(f, 1, IK)
     186       18406 :         if (present(lag)) then
     187       14404 :             if (size(lag, 1, IK) == 0_IK) then
     188        4000 :                 allocate(ccf(0))
     189             :                 return
     190             :             end if
     191       10404 :             CHECK_ASSERTION(__LINE__, isAscending(lag), SK_"@setCCF(): The condition `isAscending(lag)` must hold. lag = "//getStr(lag))
     192       10404 :             lagmax = max(lagmax, lag(size(lag, 1, IK)))
     193       10404 :             lagmin = min(lagmin, lag(1))
     194             :         end if
     195       14406 :         lenccf = lagmax - lagmin + 1_IK
     196             : 
     197             :         ! Allocate and pad the arrays.
     198             : 
     199       14406 :         allocate(ff(lenccf), gg(lenccf), coef(lenccf), ccf(lenccf))
     200             : 
     201             :         ! Shift the padded arrays if needed.
     202             : 
     203       14406 :         if (present(norm)) then
     204       11201 :             norm_def = norm
     205             :         else
     206        3205 :             norm_def = zscore_type()
     207             :         end if
     208             : 
     209       14406 :         normfac = 1._TKC / lenccf
     210       14406 :         if (same_type_as(norm_def, meanshift_type()) .or. same_type_as(norm_def, zscore_type())) then
     211        9605 :             meanf = getMean(f)
     212        9605 :             meang = getMean(g)
     213      212724 :             ff(1 : size(f, 1, IK)) = f - meanf
     214      211086 :             gg(1 : size(g, 1, IK)) = g - meang
     215             :         else
     216      106452 :             ff(1 : size(f, 1, IK)) = f
     217      105360 :             gg(1 : size(g, 1, IK)) = g
     218             :         end if
     219      518868 :         ff(size(f, 1, IK) + 1 : lenccf) = ZERO
     220      521598 :         gg(size(g, 1, IK) + 1 : lenccf) = ZERO
     221             : 
     222       14406 :         if (same_type_as(norm_def, stdscale_type()) .or. same_type_as(norm_def, zscore_type())) then
     223        4800 :             sumsqf = 0._TKC
     224      212766 :             do iell = 1, size(f, 1, IK)
     225      212766 :                 sumsqf = sumsqf + GET_ABSQ(ff(iell))
     226             :             end do
     227        4800 :             sumsqg = 0._TKC
     228      211128 :             do iell = 1, size(g, 1, IK)
     229      211128 :                 sumsqg = sumsqg + GET_ABSQ(gg(iell))
     230             :             end do
     231        9606 :             normfac = normfac / sqrt(sumsqf * sumsqg)
     232        4800 :         elseif (.not. (same_type_as(norm_def, meanshift_type()) .or. same_type_as(norm_def, nothing_type()))) then
     233             :             error stop MODULE_NAME//SK_"@getCCF(): Unrecognized `norm`." ! LCOV_EXCL_LINE
     234             :         end if
     235             : 
     236       58630 :         factor = getFactorFFT(ff, coef)
     237       14406 :         call setCCF(factor, coef, ff, gg, ccf, inf)
     238             : 
     239       14406 :         if (inf) then
     240      360712 :             ccf = cshift(ff * normfac, lagmin)
     241             :         else
     242      462926 :             ccf = cshift(gg * normfac, lagmin)
     243             :         end if
     244     1307538 :         if (present(lag)) ccf = ccf(lag - lagmin + 1)
     245       14406 :         deallocate(ff, gg, coef) ! essential for gfortran on heap.
     246             : 
     247             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     248             : #elif   setCCF_ENABLED && FP_ENABLED && FG_ENABLED
     249             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     250             : 
     251             :         integer(IK) :: isam, nsam
     252       22744 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) >= 2_IK, SK_"@setCCF(): The condition `1 < size(f)` must hold. size(f) = "//getStr(size(f, 1, IK)))
     253       68232 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) == size(g, 1, IK), SK_"@setCCF(): The condition `size(f) == size(g)` must hold. size(f), size(g) = "//getStr([size(f, 1, IK), size(g, 1, IK)]))
     254       68232 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) == size(coef, 1, IK), SK_"@setCCF(): The condition `size(f) == size(coef)` must hold. size(f), size(coef) = "//getStr([size(f, 1, IK), size(coef, 1, IK)]))
     255       68232 :         CHECK_ASSERTION(__LINE__, size(f, 1, IK) == size(work, 1, IK), SK_"@setCCF(): The condition `size(f) == size(work)` must hold. size(f), size(work) = "//getStr([size(f, 1, IK), size(work, 1, IK)]))
     256       22744 :         call setFFTF(factor, coef, f, work, inf)
     257             :         nsam = size(f, 1, IK)
     258             : #if     CK_ENABLED
     259             : #define SET_CCF(RES,TS1,TS2)\
     260             : do concurrent(isam = 1 : nsam); \
     261             : RES(isam) = TS1(isam) * conjg(TS2(isam)); \
     262             : end do;
     263       11370 :         if (inf) then
     264             :             ! fft of `f` is in `work`.
     265        6458 :             call setFFTF(factor, coef, g, f, inf)
     266        6458 :             if (inf) then
     267             :                 ! fft of `g` is in `f`.
     268      357102 :                 SET_CCF(f,work,f)
     269             :             else
     270             :                 ! fft of `g` is in `g`.
     271           0 :                 SET_CCF(f,work,g)
     272             :             end if
     273             :         else
     274             :             ! fft of `f` is in `f`.
     275        4912 :             call setFFTF(factor, coef, g, work, inf)
     276        4912 :             if (inf) then
     277             :                 ! fft of `g` is in `work`.
     278           0 :                 SET_CCF(f,f,work)
     279             :             else
     280             :                 ! fft of `g` is in `g`.
     281      287298 :                 SET_CCF(f,f,g)
     282             :             end if
     283             :         end if
     284             : #elif   RK_ENABLED
     285             : #define SET_CCF(RES,TS1,TS2)\
     286             : RES(1) = TS2(1) * TS1(1); \
     287             : do concurrent(isam = 2 : nsam : 2); \
     288             : t1 = TS1(isam) * TS2(isam) + TS1(isam + 1) * TS2(isam + 1); \
     289             : t2 = TS1(isam + 1) * TS2(isam) - TS1(isam) * TS2(isam + 1); \
     290             : RES(isam + 1) = t2; \
     291             : RES(isam) = t1; \
     292             : end do; \
     293             : if (nsam < size(f, 1, IK)) f(nsam + 1) = TS2(nsam + 1) * TS1(nsam + 1);
     294             :         block
     295             :             TYPE_OF_SEQ :: t1, t2
     296       11374 :             if (mod(nsam, 2_IK) == 0_IK) nsam = nsam - 1_IK
     297       11374 :             if (inf) then
     298             :                 ! fft of `f` is in `work`.
     299        6334 :                 call setFFTF(factor, coef, g, f, inf)
     300        6334 :                 if (inf) then
     301             :                     ! fft of `g` is in `f`.
     302      179858 :                     SET_CCF(f,work,f)
     303             :                 else
     304             :                     ! fft of `g` is in `g`.
     305           0 :                     SET_CCF(f,work,g)
     306             :                 end if
     307             :             else
     308             :                 ! fft of `f` is in `f`.
     309        5040 :                 call setFFTF(factor, coef, g, work, inf)
     310        5040 :                 if (inf) then
     311             :                     ! fft of `g` is in `work`.
     312           0 :                     SET_CCF(f,f,work)
     313             :                 else
     314             :                     ! fft of `g` is in `g`.
     315      143774 :                     SET_CCF(f,f,g)
     316             :                 end if
     317             :             end if
     318             :         end block
     319             : #else
     320             : #error  "Unrecognized interface."
     321             : #endif
     322             :         ! result is now in `f`.
     323       22744 :         call setFFTR(factor, coef, f, g, inf)
     324       22744 :         inf = .not. inf
     325             :         !if (inwork) work = g
     326             :         !call setFFTR(factor, coef, work, f, inwork)
     327             :         !normfac = 1._TKC / real(size(work, 1, IK), TKC)
     328             :         !if (inwork) then
     329             :         !    do concurrent(isam = 1 : size(work, 1, IK))
     330             :         !        work(isam) = f(isam) * normfac
     331             :         !    end do
     332             :         !else
     333             :         !    do concurrent(isam = 1 : size(work, 1, IK))
     334             :         !        work(isam) = work(isam) * normfac
     335             :         !    end do
     336             :         !end if
     337             : #undef  SET_CCF
     338             : 
     339             : #else
     340             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     341             : #error  "Unrecognized interface."
     342             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     343             : #endif
     344             : #undef  TYPE_OF_SEQ
     345             : #undef  GET_ABSQ
     346             : #undef  GET_RE

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