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

          Line data    Source code
       1             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       2             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       3             : !!!!                                                                                                                            !!!!
       4             : !!!!    ParaMonte: Parallel Monte Carlo and Machine Learning Library.                                                           !!!!
       5             : !!!!                                                                                                                            !!!!
       6             : !!!!    Copyright (C) 2012-present, The Computational Data Science Lab                                                          !!!!
       7             : !!!!                                                                                                                            !!!!
       8             : !!!!    This file is part of the ParaMonte library.                                                                             !!!!
       9             : !!!!                                                                                                                            !!!!
      10             : !!!!    LICENSE                                                                                                                 !!!!
      11             : !!!!                                                                                                                            !!!!
      12             : !!!!       https://github.com/cdslaborg/paramonte/blob/main/LICENSE.md                                                          !!!!
      13             : !!!!                                                                                                                            !!!!
      14             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      15             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      16             : 
      17             : !>  \brief
      18             : !>  This include file contains procedure implementation of the generic interfaces of [pm_quadRomb](@ref pm_quadRomb).
      19             : !>
      20             : !>  \finmain
      21             : !>
      22             : !>  \author
      23             : !>  \AmirShahmoradi, Apr 21, 2017, 1:54 AM, Institute for Computational Engineering and Sciences (ICES), The University of Texas at Austin
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             :         !%%%%%%%%%%%%%%%%%%
      28             : #if     getQuadRomb_ENABLED
      29             :         !%%%%%%%%%%%%%%%%%%
      30             : 
      31             : #if     Clos_ENABLED
      32             :         real(RKC)   , parameter     :: FACTOR = 0.5_RKC
      33             :         real(RKC)   , parameter     :: SHRINKAGE = 0.25_RKC
      34             :         integer(IK) , parameter     :: POINT_INCREMENT_BASE = 2_IK
      35             : #elif   Open_ENABLED || PWRL_ENABLED || NEXP_ENABLED || PEXP_ENABLED || LBIS_ENABLED || UBIS_ENABLED
      36             :         real(RKC)   , parameter     :: FACTOR = 1._RKC / 3._RKC
      37             :         real(RKC)   , parameter     :: SHRINKAGE = 1._RKC / 9._RKC
      38             :         integer(IK) , parameter     :: POINT_INCREMENT_BASE = 3_IK
      39             :         real(RKC)                   :: resolutionDouble
      40             : #if     !Open_ENABLED
      41             :         real(RKC)                   :: lbTrans, ubTrans
      42             : #endif
      43             : #if     LBIS_ENABLED || UBIS_ENABLED
      44             :         real(RKC)                   :: inverseOneMinusExp, exp2InverseOneMinusExp ! 1 / (1 - exponent), exponent / (1 - exponent)
      45             : #endif
      46             : #else
      47             : #error  "Unrecognized interface."
      48             : #endif
      49             :         integer(IK) , parameter     :: NSTEP = ceiling(log(epsilon(0._RKC)) / log(SHRINKAGE)) ! 31_IK: Beyond this integer, the newer QuadRombAbscissa values become identical, which automatically fail `setInterp()`.
      50             :         integer(IK)                 :: refinementStage, km
      51             :         real(RKC)                   :: QuadRombAbscissa(NSTEP + 1), QuadRombProxy(NSTEP + 1)
      52             :         real(RKC)                   :: integrationRange, nevalNewInverse, resolution, sumFunc, x
      53             :         integer(IK)                 :: nevalNew, ieval
      54             : #if     EM_ENABLED
      55             :         real(RKC)                   :: relerr
      56             : #endif
      57             : #if     NP_ENABLED && Clos_ENABLED
      58           3 :         neval = 2_IK
      59             : #elif   NP_ENABLED
      60          18 :         neval = 1_IK
      61             : #endif
      62             :         ! Set the final normalization of the integral, only necessary when there is singularity at a limit.
      63             : #if     LBIS_ENABLED || UBIS_ENABLED
      64             : #define NORMALIZE_QUAD_ROMB quadRomb = quadRomb * inverseOneMinusExp;
      65             : #else
      66             : #define NORMALIZE_QUAD_ROMB
      67             : #endif
      68             :         ! Set the transformed limits
      69             : #if     Clos_ENABLED || Open_ENABLED
      70             : #define GET_FUNC(x)getFunc(x)
      71             : #define lbTrans lb
      72             : #define ubTrans ub
      73             : #elif   PWRL_ENABLED
      74             : #define GET_FUNC(x)getFunc(1._RKC / x) / x**2
      75           3 :         lbTrans = 1._RKC / ub
      76           3 :         ubTrans = 1._RKC / lb
      77             : #elif   NEXP_ENABLED
      78             : #define GET_FUNC(x)getFunc(-log(x)) / x
      79           6 :         lbTrans = exp(-ub)
      80           6 :         ubTrans = exp(-lb)
      81             : #elif   PEXP_ENABLED
      82             : #define GET_FUNC(x)getFunc(+log(x)) / x
      83           6 :         lbTrans = exp(lb)
      84           6 :         ubTrans = exp(ub)
      85             : #elif   LBIS_ENABLED || UBIS_ENABLED
      86             :         lbTrans = 0._RKC
      87          16 :         ubTrans = (ub - lb)**(1._RKC + real(Interval%exponent, RKC))
      88          16 :         inverseOneMinusExp = 1._RKC / (1._RKC + real(Interval%exponent, RKC))
      89          16 :         exp2InverseOneMinusExp = -real(Interval%exponent, RKC) * inverseOneMinusExp
      90          16 :         CHECK_ASSERTION(__LINE__, -1._RKC < Interval%exponent .and. Interval%exponent <= 0._RKC, \
      91             :         SK_"The conditions `-1. < Interval%exponent .and. Interval%exponent <= 0.` must hold: Interval%exponent = "//getStr(Interval%exponent))
      92             : #if     LBIS_ENABLED
      93             : #define GET_FUNC(x)x**exp2InverseOneMinusExp * getFunc(lb + x**inverseOneMinusExp)
      94             : #elif   UBIS_ENABLED
      95             : #define GET_FUNC(x)x**exp2InverseOneMinusExp * getFunc(ub - x**inverseOneMinusExp)
      96             : #endif
      97             : #endif
      98          21 :         integrationRange = ubTrans - lbTrans
      99          37 :         CHECK_ASSERTION(__LINE__, integrationRange >= 0._RKC, SK_"The input lower and upper integration bounds [lb, ub] must satisfy `lb < ub`.")
     100          37 :         CHECK_ASSERTION(__LINE__, nref > 0_IK, SK_"The input refinement count in the Romberg method must satisfy `nref > 0`. nref = "//getStr(nref))
     101         111 :         CHECK_ASSERTION(__LINE__, nref <= NSTEP, SK_"The input refinement count in the Romberg method must satisfy `nref > 0`. nref, NSTEP = "//getStr([nref, NSTEP]))
     102          37 :         km = nref - 1_IK
     103             :         refinementStage = 1_IK
     104          37 :         QuadRombAbscissa(refinementStage) = 1._RKC
     105             : #if     Clos_ENABLED
     106           3 :         QuadRombProxy(refinementStage) = 0.5_RKC * integrationRange * (GET_FUNC(lbTrans) + GET_FUNC(ubTrans))
     107             : #else
     108          34 :         QuadRombProxy(refinementStage) = integrationRange * GET_FUNC((0.5_RKC * (lbTrans + ubTrans))) ! \warning extra parentheses are important
     109             : #endif
     110             :         ! Define the evaluation instruction.
     111             : #define EVAL_QUAD_ROMB \
     112             : if (refinementStage >= nref) then; \
     113             : call setExtrap(monopol, QuadRombAbscissa(refinementStage - km : refinementStage), QuadRombProxy(refinementStage - km : refinementStage), 0._RKC, quadRomb, relerr); \
     114             : relerr = abs(relerr); \
     115             : if (relerr <= tol * abs(quadRomb)) then; \
     116             : NORMALIZE_QUAD_ROMB \
     117             : return; \
     118             : end if; \
     119             : end if; \
     120             : QuadRombProxy(refinementStage + 1_IK) = QuadRombProxy(refinementStage); \
     121             : QuadRombAbscissa(refinementStage + 1_IK) = SHRINKAGE * QuadRombAbscissa(refinementStage);
     122             :         ! Compute the integral.
     123          37 :         EVAL_QUAD_ROMB
     124         200 :         do refinementStage = 2_IK, NSTEP
     125           3 :             nevalNew = POINT_INCREMENT_BASE**(refinementStage - 2_IK)
     126         200 :             nevalNewInverse = 1._RKC / real(nevalNew, RKC)
     127             : #if         Clos_ENABLED
     128           9 :             resolution = integrationRange * nevalNewInverse
     129             : #else
     130         191 :             resolution = integrationRange * nevalNewInverse * FACTOR
     131         191 :             resolutionDouble = resolution + resolution
     132             : #endif
     133         200 :             x = lbTrans + 0.5_RKC * resolution
     134             :             sumFunc = 0._RKC
     135      120462 :             do ieval = 1_IK, nevalNew
     136      120262 :                 sumFunc = sumFunc + GET_FUNC(x)
     137             : #if             !Clos_ENABLED
     138      120241 :                 x = x + resolutionDouble
     139      120241 :                 sumFunc = sumFunc + GET_FUNC(x)
     140             : #endif
     141      120462 :                 x = x + resolution
     142             :             end do
     143         200 :             QuadRombProxy(refinementStage) = FACTOR * (QuadRombProxy(refinementStage) + integrationRange * sumFunc * nevalNewInverse)
     144             : #if         NP_ENABLED && Clos_ENABLED
     145           9 :             neval = neval + nevalNew
     146             : #elif       NP_ENABLED
     147          87 :             neval = neval + nevalNew * 2
     148             : #endif
     149         200 :             EVAL_QUAD_ROMB
     150             :         end do
     151             : #if     EM_ENABLED
     152           0 :         error stop __FILE__//"@getQuadRomb(): The Romberg integration failed to converge."
     153             : #elif   EP_ENABLED
     154           0 :         relerr = -huge(relerr)
     155             : #else
     156             : #error  "Unrecognized interface."
     157             : #endif
     158             : 
     159             : #else
     160             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     161             : #error  "Unrecognized interface."
     162             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     163             : #endif
     164             : #undef  NORMALIZE_QUAD_ROMB
     165             : #undef  GET_FUNC
     166             : #undef  lbTrans
     167             : #undef  ubTrans

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