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

          Line data    Source code
       1             :  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       2             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       3             : !!!!                                                                                                                            !!!!
       4             : !!!!    ParaMonte: Parallel Monte Carlo and Machine Learning Library.                                                           !!!!
       5             : !!!!                                                                                                                            !!!!
       6             : !!!!    Copyright (C) 2012-present, The Computational Data Science Lab                                                          !!!!
       7             : !!!!                                                                                                                            !!!!
       8             : !!!!    This file is part of the ParaMonte library.                                                                             !!!!
       9             : !!!!                                                                                                                            !!!!
      10             : !!!!    LICENSE                                                                                                                 !!!!
      11             : !!!!                                                                                                                            !!!!
      12             : !!!!       https://github.com/cdslaborg/paramonte/blob/main/LICENSE.md                                                          !!!!
      13             : !!!!                                                                                                                            !!!!
      14             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      15             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      16             : 
      17             : !>  \brief
      18             : !>  This include file contains the implementations of procedures of [pm_distBand](@ref pm_distBand).
      19             : !>
      20             : !>  \finmain
      21             : !>
      22             : !>  \author
      23             : !>  \AmirShahmoradi, Oct 16, 2009, 11:14 AM, Michigan
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             : #define CHECK_ALPHA_NEQ_TWO \
      28             : CHECK_ASSERTION(__LINE__, alpha /= -2._RKC, SK_": The condition `alpha /= -2.` must hold. alpha = "//getStr(alpha))
      29             : #define CHECK_ALPHA_GEQ_BETA \
      30             : CHECK_ASSERTION(__LINE__, beta < alpha, SK_": The condition `beta < alpha` must hold. beta, alpha = "//getStr([beta, alpha]))
      31             : #define CHECK_EBREAK_GEQ_ZERO \
      32             : CHECK_ASSERTION(__LINE__, 0._RKC < ebreak, SK_": The condition `0. < ebreak` must hold. ebreak = "//getStr(ebreak))
      33             : 
      34             :         !%%%%%%%%%%%%%%%%%%%
      35             : #if     getBandEpeak_ENABLED
      36             :         !%%%%%%%%%%%%%%%%%%%
      37             : 
      38           6 :         CHECK_ALPHA_NEQ_TWO
      39          18 :         CHECK_ALPHA_GEQ_BETA
      40           6 :         CHECK_EBREAK_GEQ_ZERO
      41           6 :         epeak = ebreak * (alpha + 2._RKC) / (alpha - beta)
      42             : 
      43             :         !%%%%%%%%%%%%%%%%%%%%
      44             : #elif   getBandEbreak_ENABLED
      45             :         !%%%%%%%%%%%%%%%%%%%%
      46             : 
      47       12317 :         CHECK_ALPHA_NEQ_TWO
      48       36951 :         CHECK_ALPHA_GEQ_BETA
      49       12317 :         CHECK_ASSERTION(__LINE__, 0._RKC < epeak, SK_"@getBandEbreak(): The condition `0. < epeak` must hold. epeak = "//getStr(epeak))
      50       12317 :         ebreak = epeak * (alpha - beta) / (alpha + 2._RKC)
      51             : 
      52             :         !%%%%%%%%%%%%%%%%%%
      53             : #elif   getBandZeta_ENABLED
      54             :         !%%%%%%%%%%%%%%%%%%
      55             : 
      56       31239 :         CHECK_EBREAK_GEQ_ZERO
      57       31239 :         zeta = ebreak**(alpha - beta) * exp(beta - alpha)
      58             :         !logZeta = (alpha - beta) * (ebreak - 1._RKC)
      59             : 
      60             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      61             : #elif   getBandUDF_ENABLED && Any_ENABLED
      62             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      63             : 
      64        3998 :         CHECK_ALPHA_NEQ_TWO
      65       11994 :         CHECK_ALPHA_GEQ_BETA
      66        3998 :         CHECK_EBREAK_GEQ_ZERO
      67        3998 :         CHECK_ASSERTION(__LINE__, 0._RKC < energy, SK_"@getBandUDF(): The condition `0. < energy` must hold. energy = "//getStr(energy))
      68        3998 :         if (energy < ebreak) then
      69         848 :             if (present(invEfold)) then
      70           7 :                 CHECK_ASSERTION(__LINE__, abs(invEfold - (alpha - beta) / ebreak) < 10 * epsilon(energy), \
      71             :                 SK_"@getBandUDF(): The condition `abs(invEfold - (alpha - beta) / ebreak) < 10 * epsilon(energy)` must hold. alpha, beta, ebreak, invEfold, (alpha - beta) / ebreak, epsilon(energy) = "//\
      72             :                 getStr([alpha, beta, ebreak, invEfold, (alpha - beta) / ebreak, epsilon(energy)]))
      73           1 :                 udf = energy**alpha * exp(-energy * invEfold)
      74             :             else
      75         847 :                 udf = energy**alpha * exp((beta - alpha) * (energy / ebreak))
      76             :             end if
      77        3150 :         elseif (present(zeta)) then
      78           0 :             CHECK_ASSERTION(__LINE__, abs(zeta - getBandZeta(alpha, beta, ebreak)) < 10 * epsilon(energy), \
      79             :             SK_"@getBandUDF(): The condition `abs(zeta - getBandZeta(alpha, beta, ebreak)) < 10 * epsilon(energy)` must hold. alpha, beta, ebreak, zeta, getBandZeta(alpha, beta, ebreak), epsilon(energy) = "//\
      80             :             getStr([alpha, beta, ebreak, zeta, getBandZeta(alpha, beta, ebreak), epsilon(energy)]))
      81           0 :             udf = zeta * energy**beta
      82             :         else
      83        3150 :             udf = getBandZeta(alpha, beta, ebreak) * energy**beta
      84             :         end if
      85             : 
      86             :         !%%%%%%%%%%%%%%%%%%
      87             : #elif   setBandUCDF_ENABLED
      88             :         !%%%%%%%%%%%%%%%%%%
      89             : 
      90             :         real(RKC) :: mb, tmp, invEfold
      91             : 
      92       33239 :         CHECK_ALPHA_NEQ_TWO
      93       99717 :         CHECK_ALPHA_GEQ_BETA
      94       33239 :         CHECK_EBREAK_GEQ_ZERO
      95             : 
      96       33239 :         info = 0_IK
      97       33239 :         ucdf = 0._RKC
      98       33239 :         if (lb < ub) then ! integrate the spectrum
      99       33235 :             CHECK_ASSERTION(__LINE__, 0._RKC < lb, SK_"@setBandUCDF(): The condition `0. < lb` must hold. lb = "//getStr(lb))
     100       33235 :             if (lb < ebreak) then
     101             :                 ! First compute the contribution from the lower component via either Gamma CDF or brute-force integration.
     102       28563 :                 mb = min(ub, ebreak)
     103       28563 :                 invEfold = (alpha - beta) / ebreak
     104       28563 :                 if (-1._RKC < alpha) then
     105             :                     ! use Gamma CDF.
     106             :                     block
     107             :                         real(RKC) :: kappa, dumm
     108       23098 :                         kappa = alpha + 1._RKC
     109       23098 :                         dumm = log_gamma(kappa)
     110       23098 :                         call setGammaCDF(ucdf, lb, dumm, kappa, invEfold, info)
     111             :                         if (info < 0_IK) return ! LCOV_EXCL_LINE
     112       23098 :                         call setGammaCDF(tmp, mb, dumm, kappa, invEfold, info)
     113             :                         if (info < 0_IK) return ! LCOV_EXCL_LINE
     114       23098 :                         ucdf = (tmp - ucdf) * gamma(kappa) / invEfold**kappa
     115             :                     end block
     116             :                 else
     117             :                     block
     118             :                         integer(IK) :: neval, nint, sindex(1000)
     119             :                         real(RKC) :: abstol, reltol, abserr, sinfo(4, 1000)
     120        5465 :                         abstol = 0._RKC
     121        5465 :                         reltol = epsilon(0._RKC)**(2./3.)
     122        5465 :                         info = getQuadErr(getBandLowUDF, lb, mb, abstol, reltol, GK21, weps, ucdf, abserr, sinfo, sindex, neval, nint)
     123             :                         if (info /= 0_IK) info = -info ! LCOV_EXCL_LINE
     124             :                         if (info < 0_IK) return ! LCOV_EXCL_LINE
     125             :                     end block
     126             :                 end if
     127       28563 :                 if (mb == ub) return
     128             :             else
     129        4672 :                 mb = lb
     130             :             end if
     131             :             ! Add the remaining part of the ucdf from the high-energy component.
     132       28083 :             tmp = beta + 1._RKC
     133       28083 :             if (tmp /= 0._RKC) then
     134       23871 :                 ucdf = ucdf + getBandZeta(alpha, beta, ebreak) * (ub**tmp - mb**tmp) / tmp
     135             :             else
     136        4212 :                 ucdf = ucdf + getBandZeta(alpha, beta, ebreak) * log(ub / mb)
     137             :             end if
     138             :         end if
     139             : 
     140             :     contains
     141             : 
     142     1401351 :         PURE function getBandLowUDF(energy) result(udf)
     143             :             implicit none
     144             :             real(RKC), intent(in)    :: energy
     145             :             real(RKC)                :: udf
     146     5605404 :             CHECK_ASSERTION(__LINE__, lb <= energy .and. energy <= ub, SK_"@setBandUCDF(): The condition `lb <= energy .and. energy <= ub` must hold. lb, energy, ub = "//getStr([lb, energy, ub]))
     147     1401351 :             udf = energy**alpha * exp(-invEfold * energy)
     148             :             !print *, udf, invEfold, energy
     149     1401351 :         end function
     150             : 
     151             :         !%%%%%%%%%%%%%%%%%%
     152             : #elif   setBandMean_ENABLED
     153             :         !%%%%%%%%%%%%%%%%%%
     154             : 
     155             : #if     Def_ENABLED
     156             : #define LBNEW lb
     157             : #define UBNEW ub
     158             : #elif   !New_ENABLED
     159             : #error  "Unrecognized interface."
     160             : #endif
     161             :         real(RKC) :: denom
     162           1 :         call setBandUCDF(denom, lb, ub, alpha, beta, ebreak, info)
     163             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     164           1 :         call setBandUCDF(mean, LBNEW, UBNEW, alpha + 1._RKC, beta + 1._RKC, ebreak, info)
     165             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     166           1 :         mean = mean / denom
     167             : #undef  LBNEW
     168             : #undef  UBNEW
     169             : 
     170             :         !%%%%%%%%%%%%%%%%%%%%
     171             : #elif   setBandPhoton_ENABLED
     172             :         !%%%%%%%%%%%%%%%%%%%%
     173             : 
     174             : #if     FromPhoton_ENABLED && NewB_ENABLED
     175             :         real(RKC) :: denom, numer
     176           0 :         CHECK_ASSERTION(__LINE__, lb <= ub, SK_"@setBandPhoton(): The condition `lb <= ub` must hold. lb, ub = "//getStr([lb, ub]))
     177           0 :         CHECK_ASSERTION(__LINE__, lbnew <= ubnew, SK_"@setBandPhoton(): The condition `lbnew <= ubnew` must hold. lbnew, ubnew = "//getStr([lbnew, ubnew]))
     178           0 :         CHECK_ASSERTION(__LINE__, 0._RKC < photon, SK_"@setBandPhoton(): The condition `0. < photon` must hold. photon = "//getStr(photon))
     179           0 :         call setBandUCDF(denom, lb, ub, alpha, beta, ebreak, info)
     180             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     181           0 :         call setBandUCDF(numer, lbnew, ubnew, alpha, beta, ebreak, info)
     182             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     183           0 :         photon = numer * (photon / denom)
     184             : #elif   FromEnergy_ENABLED
     185             : #if     OldB_ENABLED
     186             : #define LBNEW lb
     187             : #define UBNEW ub
     188             : #elif   !NewB_ENABLED
     189             : #error  "Unrecognized interface."
     190             : #endif
     191             :         real(RKC) :: denom, numer
     192        5001 :         CHECK_ASSERTION(__LINE__, 0._RKC < energy, SK_"@setBandPhoton(): The condition `0. < energy` must hold. energy = "//getStr(energy))
     193        5001 :         call setBandUCDF(denom, lb, ub, alpha + 1._RKC, beta + 1._RKC, ebreak, info)
     194             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     195        5001 :         call setBandUCDF(numer, LBNEW, UBNEW, alpha, beta, ebreak, info)
     196             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     197        5001 :         photon = numer * (energy / denom)
     198             : #undef  LBNEW
     199             : #undef  UBNEW
     200             : #else
     201             : #error  "Unrecognized interface."
     202             : #endif
     203             : 
     204             :         !%%%%%%%%%%%%%%%%%%%%
     205             : #elif   setBandEnergy_ENABLED
     206             :         !%%%%%%%%%%%%%%%%%%%%
     207             : 
     208             : #if     FromEnergy_ENABLED && NewB_ENABLED
     209             :         real(RKC) :: denom, numer
     210        6924 :         CHECK_ASSERTION(__LINE__, lb <= ub, SK_"@setBandPhoton(): The condition `lb <= ub` must hold. lb, ub = "//getStr([lb, ub]))
     211        6924 :         CHECK_ASSERTION(__LINE__, lbnew <= ubnew, SK_"@setBandPhoton(): The condition `lbnew <= ubnew` must hold. lbnew, ubnew = "//getStr([lbnew, ubnew]))
     212        2308 :         CHECK_ASSERTION(__LINE__, 0._RKC < energy, SK_"@setBandPhoton(): The condition `0. < energy` must hold. energy = "//getStr(energy))
     213        2308 :         call setBandUCDF(denom, lb, ub, alpha + 1._RKC, beta + 1._RKC, ebreak, info)
     214             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     215        2308 :         call setBandUCDF(numer, lbnew, ubnew, alpha + 1._RKC, beta + 1._RKC, ebreak, info)
     216             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     217        2308 :         energy = numer * (energy / denom)
     218             : #elif   FromPhoton_ENABLED
     219             : #if     OldB_ENABLED
     220             : #define LBNEW lb
     221             : #define UBNEW ub
     222             : #elif   !NewB_ENABLED
     223             : #error  "Unrecognized interface."
     224             : #endif
     225             :         real(RKC) :: denom, numer
     226        7309 :         CHECK_ASSERTION(__LINE__, 0._RKC < photon, SK_"@setBandPhoton(): The condition `0. < photon` must hold. photon = "//getStr(photon))
     227        7309 :         call setBandUCDF(denom, lb, ub, alpha, beta, ebreak, info)
     228             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     229        7309 :         call setBandUCDF(numer, LBNEW, UBNEW, alpha + 1._RKC, beta + 1._RKC, ebreak, info)
     230             :         if (info < 0_IK) return ! LCOV_EXCL_LINE
     231        7309 :         energy = numer * (photon / denom)
     232             : #undef  LBNEW
     233             : #undef  UBNEW
     234             : #else
     235             : #error  "Unrecognized interface."
     236             : #endif
     237             : 
     238             : #else
     239             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     240             : #error  "Unrecognized interface."
     241             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     242             : #endif
     243             : #undef  CHECK_EBREAK_GEQ_ZERO
     244             : #undef  CHECK_ALPHA_GEQ_BETA
     245             : #undef  CHECK_ALPHA_NEQ_TWO

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