https://www.cdslab.org/paramonte/fortran/2
Current view: top level - main - pm_ziggurat@routines.inc.F90 (source / functions) Hit Total Coverage
Test: ParaMonte 2.0.0 :: Serial Fortran - Code Coverage Report Lines: 28 28 100.0 %
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 procedure implementation of [pm_ziggurat](@ref pm_ziggurat).
      19             : !>
      20             : !>  \finmain
      21             : !>
      22             : !>  \author
      23             : !>  \AmirShahmoradi, April 25, 2015, 2:21 PM, National Institute for Fusion Studies, The University of Texas at Austin
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             :         !%%%%%%%%%%%%%
      28             : #if     getZig_ENABLED
      29             :         !%%%%%%%%%%%%%
      30             : 
      31             :         real(RKC)   :: ub, area
      32             :         real(RKC)   , parameter :: SQRT_HUGE = sqrt(huge(0._RKC))
      33             :         real(RKC)   , parameter :: lb = 10 * epsilon(0._RKC)
      34           3 :         CHECK_ASSERTION(__LINE__, 1_IK < nlay, SK_"@getZig(): The condition `1 <= nlay` must hold. shape(nlay) = "//getStr(nlay))
      35           3 :         zig(1, nlay) = 0._RKC ! The highest rectangle point (origin).
      36           3 :         zig(2, nlay) = getFunc(zig(1, nlay)) ! maxFunc (corresponding to the highest rectangle point)
      37             :         ! Define the upper bound of the search limit.
      38           3 :         ub = lb
      39           9 :         CHECK_ASSERTION(__LINE__, 0 <= getZ(lb), SK_"@getZig(): Internal library error occurred. The condition `0 <= getZ(lb)` must hold. lb, getZ(lb) = "//getStr([lb, getZ(lb)]))
      40             :         do
      41         272 :             ub = 2._RKC * ub
      42         272 :             if (0._RKC <= getZ(ub)) cycle ! \todo should we compare the sign change from zlb to zub here instead?
      43           9 :             CHECK_ASSERTION(__LINE__, ub < SQRT_HUGE, SK_"@getZig(): The specified `getFunc()` does not appear to be monotonically decreasing. The condition `ub < SQRT_HUGE` must hold. ub, SQRT_HUGE = "//getStr([ub, SQRT_HUGE]))
      44         269 :             exit
      45             :         end do
      46           3 :         zig(1, 1) = getRoot(getZ, lb, ub, abstol = abstol) ! r: first/lowest/largest rectangle-corner point.
      47           3 :         zig(1, 0) = area / zig(2, 1)
      48           3 :         zig(2, 0) = 0._RKC
      49             : 
      50             :     contains
      51             : 
      52             :         ! This function returns the difference between the first computed area (from the lowest layer) and the last computed area from the highest layer.
      53         343 :         impure function getZ(r) result(z)
      54             :             real(RKC)   , intent(in)    :: r
      55             :             real(RKC)                   :: z
      56             :             real(RKC)                   :: func
      57             :             integer(IK)                 :: ilay
      58         343 :             zig(1, 1) = r
      59         343 :             zig(2, 1) = getFunc(r)
      60         343 :             area = getZigArea(r) ! v: partition area. Store it in the first (always zero) element to save space.
      61        7516 :             do ilay = 2, nlay - 1
      62        7408 :                 func = zig(2, ilay - 1) + area / zig(1, ilay - 1)
      63        7408 :                 if (zig(2, nlay) < func) then
      64         235 :                     z = SQRT_HUGE
      65         235 :                     abserr = z
      66         235 :                     return
      67             :                 end if
      68        7173 :                 zig(1, ilay) = getFuncInv(func)
      69        7281 :                 zig(2, ilay) = getFunc(zig(1, ilay))
      70             :             end do
      71         108 :             ilay = nlay - 1_IK
      72         108 :             z = area - zig(1, ilay) * (zig(2, nlay) - zig(2, ilay))
      73         108 :             abserr = abs(z)
      74         108 :         end function
      75             : 
      76             : !        !%%%%%%%%%%%%%%%%%%
      77             : !#elif   getZig_ENABLED && 0
      78             : !        !%%%%%%%%%%%%%%%%%%
      79             : !
      80             : !        real(RKC)   :: ub, area
      81             : !        real(RKC)   , parameter :: SQRT_HUGE = sqrt(huge(0._RKC))
      82             : !        real(RKC)   , parameter :: lb = 10 * epsilon(0._RKC)
      83             : !        integer(IK) :: nlayTwice
      84             : !        nlayTwice = 2 * nlay
      85             : !        CHECK_ASSERTION(__LINE__, 1_IK < nlay, SK_"@getZig(): The condition `1 <= nlay` must hold. shape(nlay) = "//getStr(nlay))
      86             : !        zig(nlay) = 0._RKC ! The highest rectangle point (origin).
      87             : !        zig(nlayTwice) = getFunc(zig(nlay)) ! maxFunc (corresponding to the highest rectangle point)
      88             : !        ! Define the upper bound of the search limit.
      89             : !        ub = lb
      90             : !        if (getZ(lb) < 0._RKC) error stop "@getZig(): Internal error occurred. Please report to the ParaMonte library developers."
      91             : !        do
      92             : !            ub = 2._RKC * ub
      93             : !            if (getZ(ub) < 0._RKC) exit
      94             : !        end do
      95             : !        zig(1) = getRoot(getZ, lb, ub) ! r: first/lowest/largest rectangle-corner point.
      96             : !        zig(0) = area / zig(1 + nlay)
      97             : !        !zig(nlayTwice + 1) = getRoot(getZ, lb, ub) ! r: first/lowest/largest rectangle-corner point.
      98             : !        !zig(2 : nlay) = zig(2 : nlay) / zig(1 : nlay - 1)
      99             : !        !zig(1) = zig(1) * zig(1 + nlay) / area ! x1 / x0 = x1 / (area / f(r)) = x1 * f(r) / area.
     100             : !        !!zig(1 : nlay) = zig(1 : nlay) * 2._RKC**31
     101             : !
     102             : !    contains
     103             : !
     104             : !        impure function getZ(r) result(z)
     105             : !            real(RKC)   , intent(in)    :: r
     106             : !            real(RKC)                   :: z
     107             : !            real(RKC)                   :: func
     108             : !            integer(IK)                 :: ilay
     109             : !            zig(1) = r
     110             : !            zig(1 + nlay) = getFunc(r)
     111             : !            area = getZigArea(r) ! v: partition area. Store it in the first (always zero) element to save space.
     112             : !            do ilay = 2_IK, nlay - 1_IK
     113             : !                func = area / zig(ilay - 1) + zig(ilay - 1 + nlay)
     114             : !                if (zig(nlayTwice) < func) then
     115             : !                    z = SQRT_HUGE
     116             : !                    abserr = z
     117             : !                    return
     118             : !                end if
     119             : !                zig(ilay) = getFuncInv(func)
     120             : !                zig(ilay + nlay) = getFunc(zig(ilay))
     121             : !            end do
     122             : !            ilay = nlay - 1_IK
     123             : !            z = area + zig(ilay) * (zig(ilay + nlay) - 1._RKC)
     124             : !            abserr = z
     125             : !        end function
     126             : !
     127             : !        !%%%%%%%%%%%%%%%%
     128             : !#elif   getZigCRD_ENABLED
     129             : !        !%%%%%%%%%%%%%%%%
     130             : !
     131             : !        integer(IK) :: lenZig ! ilay, nlay,
     132             : !        lenZig = size(zig, 1, IK)
     133             : !        CHECK_ASSERTION(__LINE__, mod(lenZig, 2_IK) == 1_IK, SK_"@getZigCRD(): The condition `mod(size(zig), 2) == 1` must hold. shape(size(zig)) = "//getStr(lenZig))
     134             : !        crd(1,:) = zig(1 : lenZig / 2)
     135             : !        crd(2,:) = zig(1 + lenZig / 2 : lenZig - 1)
     136             : !        !nlay = lenZig / 2_IK
     137             : !        !crd(1, 1) = zig(lenZig)
     138             : !        !crd(2, 1) = zig(nlay + 1)
     139             : !        !do ilay = 2_IK, nlay
     140             : !        !    crd(1, ilay) = crd(1, ilay - 1) * zig(ilay) ! * 0.5_RKC**31
     141             : !        !    crd(2, ilay) = zig(nlay + ilay)
     142             : !        !end do
     143             : 
     144             : #else
     145             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     146             : #error  "Unlayognized interface."
     147             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     148             : #endif

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