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 implementations of the procedures in module [pm_mathSqrt](@ref pm_mathSqrt).
19 : !>
20 : !> \finmain
21 : !>
22 : !> \author
23 : !> \FatemehBagheri, Sunday 11:23 PM, September 19, 2021, Dallas, TX
24 :
25 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26 :
27 : #if !getSqrt_ENABLED
28 : #error "Unrecognized interface."
29 : #endif
30 : #if Bin_ENABLED || Def_ENABLED
31 : integer(IKC) :: middle, upper
32 : integer(IKC) , parameter :: maxIntSqrt = floor(sqrt(real(huge(0_IKC), RKB)), IKC)
33 47 : CHECK_ASSERTION(__LINE__, 0_IKC <= posint, SK_"@getSqrt(): The condition `0 <= posint` must hold. posint = "//getStr(posint))
34 47 : upper = min(maxIntSqrt, posint) + 1_IKC ! Avoid possible overflow.
35 0 : intSqrt = 0_IKC
36 : do
37 480 : if (upper - intSqrt == 1_IKC) return
38 433 : middle = (intSqrt + upper) / 2_IKC
39 0 : if (middle * middle <= posint) then
40 0 : intSqrt = middle
41 : else
42 0 : upper = middle
43 : end if
44 : end do
45 : #elif Lin_ENABLED
46 : ! linear search, ascending, using addition.
47 : ! (intSqrt + 1)^2 = intSqrt^2 + 2L + 1 = intSqrt^2 + 1 + \sum _{i = 1}^intSqrt 2
48 : integer(IKC) :: a, d
49 : integer(IKC) , parameter :: huge_IKC = huge(0_IKC)
50 11 : CHECK_ASSERTION(__LINE__, 0_IKC <= posint, SK_"@getSqrt(): The condition `0 <= posint` must hold. posint = "//getStr(posint))
51 0 : intSqrt = 0_IKC
52 0 : a = 1_IKC
53 0 : d = 3_IKC
54 19 : do
55 30 : if (posint < a) return
56 19 : if (huge_IKC - a < d) return
57 19 : a = a + d ! (a + 1_IKC) ** 2_IKC
58 19 : d = d + 2_IKC
59 19 : intSqrt = intSqrt + 1_IKC
60 : end do
61 : #else
62 : !%%%%%%%%%%%%%%%%%%%%%%%%
63 : #error "Unrecognized interface."
64 : !%%%%%%%%%%%%%%%%%%%%%%%%
65 : #endif
|