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 procedure implementations of [pm_quadTest](@ref pm_quadTest).
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 : submodule (pm_quadTest) routines ! LCOV_EXCL_LINE
28 :
29 : #if CHECK_ENABLED
30 : use pm_err, only: getFine
31 : use pm_val2str, only: getStr
32 : use pm_err, only: setAsserted
33 : #define CHECK_ASSERTION(LINE,ASSERTION,MSG) \
34 : call setAsserted(ASSERTION,getFine(__FILE__,LINE)//MODULE_NAME//MSG);
35 : #else
36 : #define CHECK_ASSERTION(LINE,ASSERTION,MSG) continue;
37 : #endif
38 :
39 : use pm_val2str, only: getStr
40 : use pm_except, only: getInfNeg
41 : use pm_except, only: getInfPos
42 : use pm_quadPack, only: GK15, GK21
43 : use pm_quadPack, only: GK31, GK41
44 : use pm_quadPack, only: GK51, GK61
45 : use pm_quadPack, only: getQuadErr
46 : use pm_quadPack, only: isFailedQuad
47 : use pm_quadPack, only: weps, pinf, ninf
48 : use pm_quadPack, only: setNodeWeightGK
49 : use pm_arrayResize, only: setResized
50 : use pm_strASCII, only: getStrUpper
51 : use pm_io, only: display_type
52 : use pm_option, only: getOption
53 :
54 : implicit none
55 :
56 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 :
58 : contains
59 :
60 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61 :
62 : #define test_isFailedQuad_ENABLED 1
63 : ! \bug gfortran cannot recognize the procedure arguments without duplicating the full interface in the submodule.
64 24 : module subroutine test_isFailedQuad_RKH(disp, integrand, abstol, reltol)
65 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
66 : !DEC$ ATTRIBUTES DLLEXPORT :: test_isFailedQuad_RKH
67 : #endif
68 : use pm_kind, only: RKC => RKH
69 : use pm_io, only: display_type
70 : type(display_type) , intent(inout) :: disp
71 : class(integrand_type) , intent(in) :: integrand
72 : real(RKC) , intent(in), optional :: abstol, reltol
73 : #include "pm_quadTest@routines.inc.F90"
74 : end subroutine
75 : #undef test_isFailedQuad_ENABLED
76 :
77 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 :
79 : #define test_getQuadErr_ENABLED 1
80 : ! \bug gfortran cannot recognize the procedure arguments without duplicating the full interface in the submodule.
81 21 : module subroutine test_getQuadErr_RKH(disp, integrand, atol, rtol, nintmax)
82 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
83 : !DEC$ ATTRIBUTES DLLEXPORT :: test_getQuadErr_RKH
84 : #endif
85 : use pm_kind, only: RKC => RKH
86 : use pm_io, only: display_type
87 : type(display_type) , intent(inout) :: disp
88 : class(integrand_type) , intent(in) :: integrand
89 : real(RKC) , intent(in), optional :: atol, rtol
90 : integer(IK) , intent(in), optional :: nintmax
91 : #include "pm_quadTest@routines.inc.F90"
92 : end subroutine
93 : #undef test_getQuadErr_ENABLED
94 :
95 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 :
97 2 : module procedure constructInt1
98 : use pm_except, only: getInfNeg, getInfPos
99 : use pm_option, only: getOption
100 : use pm_kind, only: RKC => RKH
101 2 : self%lb = getOption(getInfNeg(0._RKC), lb)
102 2 : self%ub = getOption(getInfPos(0._RKC), ub)
103 : self%integral = (atan(self%ub/2._RKC) * 2._RKC - atan(self%ub)) / 3._RKC & ! LCOV_EXCL_LINE
104 2 : - (atan(self%lb/2._RKC) * 2._RKC - atan(self%lb)) / 3._RKC
105 2 : self%desc = "Int1_type: an algebraic integrand of the form f(x) = x**2 / (x**2 + 1) / (x**2 + 4) for x in (lb, ub)"
106 2 : end procedure
107 :
108 5972 : module procedure getInt1
109 : use pm_kind, only: RKC => RKH
110 23888 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, SK_"@getInt1(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
111 5972 : func = x**2 / (x**2 + 1._RKC) / (x**2 + 4._RKC)
112 5972 : end procedure
113 :
114 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115 :
116 2 : module procedure constructInt2
117 : use pm_kind, only: RKC => RKH
118 : use pm_option, only: getOption
119 : use pm_except, only: getInfNeg, getInfPos
120 2 : self%a = getOption(1._RKC, a)
121 2 : self%b = getOption(1._RKC, b)
122 2 : self%ub = self%a / self%b
123 2 : self%lb = 0._RKC
124 2 : self%integral = 2._RKC * (sqrt(self%a - self%b * self%lb) - sqrt(self%a - self%b * self%ub)) / self%b
125 2 : self%desc = "Int2_type: an algebraic integrand of the form f(x) = 1 / sqrt(a - b * x) for x in (0, a / b) with a > 0 and b > 0 with a singularity at the upper bound of integration"
126 2 : CHECK_ASSERTION(__LINE__, self%a > 0._RKC, SK_"@constructInt2(): The condition `self%a > 0._RKC` must hold. self%lb, self%a = "//getStr(self%a))
127 2 : CHECK_ASSERTION(__LINE__, self%b > 0._RKC, SK_"@constructInt2(): The condition `self%b > 0._RKC` must hold. self%lb, self%a = "//getStr(self%b))
128 2 : end procedure
129 :
130 67496 : module procedure getInt2
131 : use pm_kind, only: RKC => RKH
132 269984 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
133 : SK_"@getInt2(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
134 67496 : func = 1._RKC / sqrt(self%a - self%b * x)
135 67496 : end procedure
136 :
137 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 :
139 2 : module procedure constructInt3
140 : use pm_kind, only: RKC => RKH
141 : use pm_option, only: getOption
142 : use pm_except, only: getInfNeg, getInfPos
143 2 : self%lb = 0._RKC
144 2 : self%ub = getOption(+1._RKC, ub)
145 2 : CHECK_ASSERTION(__LINE__, 0._RKC <= self%ub, SK_"@constructInt3(): The condition `0._RKC <= self%ub` must hold. self%ub = "//getStr(self%ub))
146 2 : self%integral = 2._RKC * sqrt(self%ub) * (log(self%ub) - 2._RKC)
147 2 : self%desc = "Int3_type: an algebraic integrand of the form f(x) = log(x) / sqrt(x) for x in (0, ub) with a singularity at the lower limit of integration"
148 2 : end procedure
149 :
150 113070 : module procedure getInt3
151 : use pm_kind, only: RKC => RKH
152 452280 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
153 : SK_"@getInt3(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
154 113070 : func = log(x) / sqrt(x)
155 113070 : end procedure
156 :
157 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 :
159 2 : module procedure constructInt4
160 : use pm_kind, only: RKC => RKH
161 : use pm_option, only: getOption
162 : use pm_except, only: getInfNeg, getInfPos
163 2 : self%lb = 0._RKC
164 2 : self%ub = 1._RKC
165 2 : self%integral = -0.189275187882093321180367135892330338053417661540147291526012234_RKC
166 2 : self%desc = "Int4_type: an algebraic integrand of the form f(x) = log(x) / (1. + log(x)**2)**2 for x in (0, 1) with a singularity at the lower limit"
167 2 : end procedure
168 :
169 48854 : module procedure getInt4
170 : use pm_kind, only: RKC => RKH
171 195416 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
172 : SK_"@getInt4(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
173 48854 : func = log(x) / (1._RKC + log(x)**2)**2
174 48854 : end procedure
175 :
176 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 :
178 4 : module procedure constructInt5
179 : use pm_kind, only: RKC => RKH
180 : use pm_option, only: getOption
181 : use pm_except, only: getInfNeg, getInfPos
182 : real(RKC), parameter :: breakList(*) = [-sqrt(2._RKC), -1._RKC, 1._RKC, sqrt(2._RKC)]
183 : integer(IK) :: i
184 4 : self%lb = getOption(0._RKC, lb)
185 4 : self%ub = getOption(3._RKC, ub)
186 4 : self%break = [real(RKC) ::]
187 20 : do i = 1, size(breakList)
188 98 : if (self%lb <= breakList(i) .and. breakList(i) <= self%ub) self%break = [self%break, breakList(i)]
189 : end do
190 4 : self%integral = getIntegral(self%ub) - getIntegral(self%lb)
191 16 : self%desc = "Int5_type: an algebraic integrand of the form f(x) = x**3 log(abs((x**2 - 1) * (x**2 - 2))) for x in ("//getTTZ(getStr([self%lb, self%ub]))//SK_") with 4 possible singularities: [-sqrt(2.), -1., 1., sqrt(2.)]"
192 : contains
193 8 : pure function getIntegral(x) result(integral)
194 : real(RKC), intent(in) :: x
195 : real(RKC) :: integral
196 8 : integral = 4._RKC * real(log(cmplx(x**2 - 2._RKC, 0._RKC, RKC)), RKC) + real(log(cmplx(x**2 - 1._RKC, 0._RKC, RKC)), RKC)
197 8 : integral = 0.25_RKC * (x**4 * log(abs((x**2 - 1._RKC) * (x**2 - 2._RKC))) - integral - 3._RKC * x**2 - x**4)
198 8 : end function
199 : end procedure
200 :
201 690622 : module procedure getInt5
202 : use pm_kind, only: RKC => RKH
203 2762488 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
204 : SK_"@getInt5(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
205 8175500 : CHECK_ASSERTION(__LINE__, all(10 * abs(x - nearest(x, x)) < abs(x - self%break)), \
206 : SK_"@getInt5(): The condition `all(10 * abs(x - nearest(x, x)) < abs(x - self%break))` must hold. 10 * abs(x - nearest(x, x)), abs(x - self%break) = "//getStr([real(RKC) :: 10 * abs(x - nearest(x, x)), abs(x - self%break)]))
207 690622 : func = x**3 * log(abs((x**2 - 1._RKC) * (x**2 - 2._RKC)))
208 690622 : end procedure
209 :
210 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211 :
212 2 : module procedure constructInt6
213 : use pm_kind, only: RKC => RKH
214 : use pm_option, only: getOption
215 : use pm_except, only: getInfNeg, getInfPos
216 2 : self%lb = 0._RKC
217 2 : self%ub = getInfPos(0._RKC)
218 2 : self%integral = -acos(-1._RKC) * log(10._RKC) / 20._RKC
219 2 : self%desc = "Int6_type: an algebraic integrand of the form f(x) = log(x) / (1 + 100 * x**2) for x in (0, +Inf) with a singularity at the lower limit"
220 2 : end procedure
221 :
222 110250 : module procedure getInt6
223 : use pm_kind, only: RKC => RKH
224 441000 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, SK_"@getInt6(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
225 110250 : func = log(x) / (1._RKC + 100._RKC * x**2)
226 110250 : end procedure
227 :
228 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 :
230 2 : module procedure constructInt7
231 : use pm_kind, only: RKC => RKH
232 : use pm_option, only: getOption
233 : use pm_except, only: getInfNeg, getInfPos
234 2 : self%lb = 1._RKC / 3._RKC
235 2 : self%ub = getInfPos(0._RKC)
236 6 : self%break = [1._RKC / sqrt(2._RKC), 1._RKC]
237 2 : self%integral = 52.7407483834714449977291997202299809_RKC
238 2 : self%desc = "Int7_type: an algebraic integrand of the form f(x) = -log(abs((1 - x**2) * (1 - 2 * x**2)) / x**4) / x**5 for x in (1./3., +Inf) with two singularities at [1 / sqrt(2), 1]"
239 2 : end procedure
240 :
241 227512 : module procedure getInt7
242 : use pm_kind, only: RKC => RKH
243 910048 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
244 : SK_"@getInt7(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
245 1820096 : CHECK_ASSERTION(__LINE__, all(10 * abs(x - nearest(x, x)) < abs(x - self%break)), \
246 : SK_"@getInt7(): The condition `all(10 * abs(x - nearest(x, x)) < abs(x - self%break))` must hold. 10 * abs(x - nearest(x, x)), abs(x - self%break) = "//getStr([real(RKC) :: 10 * abs(x - nearest(x, x)), abs(x - self%break)]))
247 227512 : func = log(abs((1._RKC - x**2) * (1._RKC - 2 * x**2)) / x**4) / x**5
248 227512 : end procedure
249 :
250 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 :
252 2 : module procedure constructInt8
253 : use pm_kind, only: RKC => RKH
254 : use pm_option, only: getOption
255 : use pm_except, only: getInfNeg, getInfPos
256 2 : self%lb = getInfNeg(0._RKC)
257 2 : self%ub = -1._RKC / 3._RKC
258 6 : self%break = [-1._RKC, -1._RKC / sqrt(2._RKC)]
259 2 : self%integral = 52.7407483834714449977291997202299809_RKC
260 2 : self%desc = "Int8_type: an algebraic integrand of the form f(x) = log(abs((1 - x**2) * (1 - 2 * x**2)) / x**4) / x**5 for x in (-Inf, -1./3.) with two singularities at [-1, -1 / sqrt(2)]"
261 2 : end procedure
262 :
263 227512 : module procedure getInt8
264 : use pm_kind, only: RKC => RKH
265 910048 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, SK_"@getInt8(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
266 1820096 : CHECK_ASSERTION(__LINE__, all(10 * abs(x - nearest(x, x)) < abs(x - self%break)), \
267 : SK_"@getInt8(): The condition `all(10 * abs(x - nearest(x, x)) < abs(x - self%break))` must hold. 10 * abs(x - nearest(x, x)), abs(x - self%break) = "//getStr([real(RKC) :: 10 * abs(x - nearest(x, x)), abs(x - self%break)]))
268 227512 : func = -log(abs((1._RKC - x**2) * (1._RKC - 2 * x**2)) / x**4) / x**5
269 227512 : end procedure
270 :
271 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272 :
273 2 : module procedure constructInt9
274 : use pm_kind, only: RKC => RKH
275 : use pm_option, only: getOption
276 : use pm_except, only: getInfNeg, getInfPos
277 2 : self%lb = getInfNeg(0._RKC)
278 2 : self%ub = getInfPos(0._RKC)
279 12 : self%break = [-10._RKC, -9._RKC, 1._RKC / 3._RKC, 1._RKC / sqrt(2._RKC), 1._RKC]
280 2 : self%integral = 53.7407483834714449977291997202299809_RKC
281 2 : self%desc = "Int9_type: an algebraic piecewise integrand of the form f(x) = log(abs((1 - x**2) * (1 - 2 * x**2)) / x**4) / x**5 for x in (1./3., +Inf) and 1 / (acos(-1) * sqrt(-(x+10) * (x+9))) for x in (-10, 9), otherwise 0, with two singularities at [-10, -9, 1/3., 1 / sqrt(2), 1]"
282 2 : end procedure
283 :
284 1049200 : module procedure getInt9
285 : use pm_kind, only: RKC => RKH
286 : !check_assertion(__LINE__, all(10 * abs(x - nearest(x, x)) < abs(x - self%break)), \
287 : !SK_"@getInt9(): The condition `all(abs(x - nearest(x, x)) < abs(x - self%break))` must hold. abs(x - nearest(x, x)), abs(x - self%break) = "//getStr([real(RKC) :: abs(x - nearest(x, x)), abs(x - self%break)]))
288 6295136 : if (all(abs(x - nearest(x, x)) < 10 * abs(x - self%break))) then
289 1049168 : func = 0._RKC
290 1049168 : if (x > 1._RKC / 3._RKC) func = log(abs((1._RKC - x**2) * (1._RKC - 2 * x**2)) / x**4) / x**5
291 1049168 : if (-10._RKC < x .and. x < -9._RKC) func = 1._RKC / (acos(-1._RKC) * sqrt(-(x + 10._RKC) * (x + 9._RKC)))
292 : else
293 32 : func = 1.e9_RKC
294 : end if
295 1049200 : end procedure
296 :
297 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 :
299 1 : module procedure constructIntGamUpp
300 : use pm_kind, only: RKC => RKH
301 : use pm_option, only: getOption
302 : use pm_except, only: getInfNeg, getInfPos, setNAN, isInfPos
303 : use pm_mathGamma, only: getGammaIncUpp
304 : real(RKC) :: lbint, ubint
305 1 : if (present(lb)) then
306 0 : CHECK_ASSERTION(__LINE__, 0 < lb, SK_"@getIntGamUpp(): The condition `0 < lb` must hold. lb = "//getStr(lb))
307 0 : self%lb = lb
308 : else
309 1 : self%lb = 1._RKC
310 : end if
311 1 : if (present(ub)) then
312 0 : CHECK_ASSERTION(__LINE__, 0 < ub, SK_"@getIntGamUpp(): The condition `0 < lb` must hold. lb = "//getStr(lb))
313 0 : self%ub = ub
314 : else
315 1 : self%ub = getInfPos(0._RKC)
316 : end if
317 3 : CHECK_ASSERTION(__LINE__, self%lb < self%ub, SK_"@getIntGamUpp(): The condition `lb < ub` must hold. lb, ub = "//getStr([self%lb, self%ub]))
318 1 : if (present(alpha)) then
319 0 : self%alpha = alpha
320 : else
321 1 : self%alpha = 1._RKC
322 : end if
323 1 : if (present(beta)) then
324 0 : CHECK_ASSERTION(__LINE__, 0 < beta, SK_"@getIntGamUpp(): The condition `0 < beta` must hold. beta = "//getStr(beta))
325 0 : self%beta = beta
326 : else
327 1 : self%beta = 1._RKC
328 : end if
329 1 : if (self%alpha > -1) then
330 1 : lbint = gamma(self%alpha + 1) * getGammaIncUpp(self%beta * self%lb, kappa = self%alpha + 1)
331 1 : lbint = lbint * exp(self%beta * self%lb) / (self%lb**self%alpha * self%beta**(self%alpha + 1))
332 1 : if (isInfPos(self%ub)) then
333 1 : ubint = 0._RKC
334 : else
335 0 : ubint = gamma(self%alpha + 1) * getGammaIncUpp(self%beta * self%ub, kappa = self%alpha + 1)
336 0 : ubint = ubint * exp(self%beta * self%ub) / (self%ub**self%alpha * self%beta**(self%alpha + 1))
337 : end if
338 1 : self%integral = lbint + ubint
339 : else
340 0 : call setNAN(self%integral)
341 : end if
342 1 : self%desc = "IntGamUpp_type: an algebraic integrand of the form f(x; lb, alpha, beta) = (x / lb)**alpha * exp(-beta * (x - lb)) for x in (lb, +Inf), lb > 0."
343 1 : end procedure
344 :
345 966 : module procedure getIntGamUpp
346 : use pm_kind, only: RKC => RKH
347 3864 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, SK_"@getIntGamUpp(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
348 966 : func = (x / self%lb)**self%alpha * exp(-self%beta * (x - self%lb))
349 966 : end procedure
350 :
351 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352 :
353 2 : module procedure constructIntSinCos
354 : use pm_kind, only: RKC => RKH
355 : use pm_option, only: getOption
356 : use pm_except, only: getInfNeg, getInfPos
357 2 : self%lb = getOption(-1_IK, lf) * acos(-1._RKC)
358 2 : self%ub = getOption(+1_IK, uf) * acos(-1._RKC)
359 2 : self%a = getOption(1._RKC, a)
360 2 : self%b = getOption(1._RKC, b)
361 2 : self%integral = (self%ub - self%lb) * bessel_j0(self%a)
362 2 : self%desc = "IntSinCos_type(): a highly oscillatory integrand of the form f(x) = cos(a * sin(b * x)) for x in (lb, ub)"
363 2 : end procedure
364 :
365 459032 : module procedure getIntSinCos
366 : use pm_kind, only: RKC => RKH
367 1836128 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
368 : SK_"@getIntSinCos(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
369 459032 : func = cos(self%a * sin(self%b * x))
370 459032 : end procedure
371 :
372 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373 :
374 4 : module procedure constructIntNormPDF
375 : use pm_kind, only: RKC => RKH
376 : use pm_option, only: getOption
377 : use pm_distNorm, only: getNormCDF
378 : use pm_except, only: getInfNeg, getInfPos
379 4 : self%lb = getOption(getInfNeg(0._RKC), lb)
380 4 : self%ub = getOption(getInfPos(0._RKC), ub)
381 4 : self%mu = getOption(+0._RKC, mu)
382 4 : self%sigma = getOption(1._RKC, sigma)
383 4 : self%invSigma = 1._RKC / self%sigma
384 4 : self%logInvSigma = log(self%invSigma)
385 4 : self%integral = getNormCDF(self%ub, self%mu, self%sigma) - getNormCDF(self%lb, self%mu, self%sigma)
386 4 : self%desc = "IntNormPDF_type: f(x) = exp(-0.5 * (log(x) - mu)**2 / sigma**2) / (sigma * sqrt(2 * acos(-1.))) for x in (lb, ub)"
387 4 : end procedure
388 :
389 15904 : module procedure getIntNormPDF
390 : use pm_kind, only: RKC => RKH
391 : use pm_distNorm, only: setNormLogPDF
392 63616 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
393 : SK_"@getIntNormPDF(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
394 15904 : call setNormLogPDF(func, x, self%mu, self%invSigma, self%logInvSigma)
395 15904 : func = exp(func)
396 15904 : end procedure
397 :
398 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399 :
400 4 : module procedure constructIntLogNormPDF
401 : use pm_kind, only: RKC => RKH
402 : use pm_option, only: getOption
403 : use pm_distLogNorm, only: getLogNormCDF
404 : use pm_except, only: getInfNeg, getInfPos
405 4 : self%lb = getOption(0._RKC, lb)
406 4 : self%ub = getOption(getInfPos(0._RKC), ub)
407 12 : CHECK_ASSERTION(__LINE__, 0._RKC <= self%lb .and. self%lb <= self%ub, \
408 : SK_"@constructIntLogNormPDF(): The condition `0._RKC <= self%lb .and. slef%lb <= self%ub` must hold. self%lb, self%ub = "//getStr([self%lb, self%ub]))
409 4 : self%mu = getOption(+0._RKC, mu)
410 4 : self%sigma = getOption(1._RKC, sigma)
411 4 : self%invSigma = 1._RKC / self%sigma
412 4 : self%logInvSigma = log(self%invSigma)
413 4 : self%integral = getLogNormCDF(self%ub, self%mu, self%sigma) - getLogNormCDF(self%lb, self%mu, self%sigma)
414 4 : self%desc = "IntLogNormPDF_type: f(x) = exp(-0.5 * (log(x) - mu)**2 / sigma**2) / (x * sigma * sqrt(2 * acos(-1.))) for x in (0 <= lb, ub)"
415 4 : end procedure
416 :
417 38908 : module procedure getIntLogNormPDF
418 : use pm_kind, only: RKC => RKH
419 : use pm_distLogNorm, only: setLogNormLogPDF
420 155632 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
421 : SK_"@getIntLogNormPDF(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
422 38908 : call setLogNormLogPDF(func, log(x), self%mu, self%invSigma, self%logInvSigma)
423 38908 : func = exp(func)
424 38908 : end procedure
425 :
426 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 :
428 2 : module procedure constructIntGenExpGammaPDF
429 : use pm_kind, only: RKC => RKH
430 : use pm_option, only: getOption
431 : use pm_except, only: getInfNeg, getInfPos
432 : !use pm_distGenExpGamma, only: getGenExpGammaCDF
433 : use pm_distGenExpGamma, only: getGenExpGammaLogPDFNF
434 2 : self%lb = getOption(getInfNeg(0._RKC), lb)
435 2 : self%ub = getOption(getInfPos(0._RKC), ub)
436 2 : self%kappa = getOption(1._RKC, kappa)
437 2 : self%invOmega = getOption(1._RKC, invOmega)
438 2 : self%logSigma = getOption(0._RKC, logSigma)
439 4 : self%logPDFNF = getGenExpGammaLogPDFNF(self%kappa, self%invOmega)
440 2 : CHECK_ASSERTION(__LINE__, 0._RKC < self%kappa, SK_"@constructIntGenExpGammaPDF(): The condition `0._RKC < kappa` must hold. kappa = "//getStr(self%kappa))
441 2 : CHECK_ASSERTION(__LINE__, 0._RKC < self%invOmega, SK_"@constructIntGenExpGammaPDF(): The condition `0._RKC < invOmega` must hold. invOmega = "//getStr(self%invOmega))
442 2 : self%integral = 1._RKC !getGenExpGammaCDF(exp(self%ub), self%mu, self%sigma) - getGenExpGammaCDF(self%lb, self%mu, self%sigma)
443 2 : self%desc = SK_"IntGenExpGammaPDF_type: f(x) = GenExpGamma(x; kappa = "//getTTZ(getStr(self%kappa))//SK_", omega = "//getTTZ(getStr(1._RKC/self%invOmega))//SK_", logSigma = "//getTTZ(getStr(self%logSigma))//SK_") for x in ("//getTTZ(getStr(self%lb))//SK_", "//getTTZ(getStr(self%ub))//SK_")"
444 2 : end procedure
445 :
446 6216 : module procedure getIntGenExpGammaPDF
447 : use pm_kind, only: RKC => RKH
448 : use pm_distGenExpGamma, only: setGenExpGammaLogPDF
449 24864 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, SK_"@getIntGenExpGammaPDF(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
450 6216 : call setGenExpGammaLogPDF(func, x, self%logPDFNF, self%kappa, self%invOmega, self%logSigma)
451 6216 : func = exp(func)
452 6216 : end procedure
453 :
454 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
455 :
456 2 : module procedure constructIntPentaGammaInf
457 : use pm_kind, only: RKC => RKH
458 : use pm_option, only: getOption
459 : use pm_except, only: getInfNeg, getInfPos
460 2 : self%lb = getInfNeg(0._RKC)
461 2 : self%ub = getInfPos(0._RKC)
462 12 : self%break = [-9._RKC, -5._RKC, 2._RKC, 5._RKC, 7._RKC]
463 2 : self%integral = 5._RKC
464 2 : self%desc = "IntPentaGammaInf_type: f(x) = sum of five Gamma PDFs with five break points in the integration range x in (-Inf, +Inf)"
465 2 : end procedure
466 :
467 856904 : module procedure getIntPentaGammaInf
468 : use pm_distGamma, only: getGammaLogPDF
469 : use pm_kind, only: RKC => RKH
470 : !check_assertion(__LINE__, all(10 * abs(x - nearest(x, x)) < abs(x - self%break)), \
471 : !SK_"@getIntPentaGammaInf(): The condition `all(10 * abs(x - nearest(x, x)) < abs(x - self%break))` must hold. 10 * abs(x - nearest(x, x)), abs(x - self%break) = "//getStr([real(RKC) :: 10 * abs(x - nearest(x, x)), abs(x - self%break)]))
472 5139536 : if (all(abs(x - nearest(x, x)) < 10 * abs(x - self%break))) then
473 856264 : func = 0._RKC
474 856264 : if (x > -9._RKC) func = func + exp(getGammaLogPDF(x + 9._RKC, 0.7_RKC, 1._RKC))
475 856264 : if (x > -5._RKC) func = func + exp(getGammaLogPDF(x + 5._RKC, 0.7_RKC, 1._RKC))
476 856264 : if (x > +5._RKC) func = func + exp(getGammaLogPDF(x - 5._RKC, 0.7_RKC, 1._RKC))
477 856264 : if (x < +2._RKC) func = func + exp(getGammaLogPDF(2._RKC - x, 0.7_RKC, 1._RKC))
478 856264 : if (x < +7._RKC) func = func + exp(getGammaLogPDF(7._RKC - x, 0.7_RKC, 1._RKC))
479 : else
480 640 : func = 1.e9_RKC
481 : end if
482 856904 : end procedure
483 :
484 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 :
486 2 : module procedure constructIntDoncker1
487 : use pm_kind, only: RKC => RKH
488 : use pm_except, only: getInfNeg, getInfPos
489 : use pm_option, only: getOption
490 2 : self%lb = getOption(0._RKC, lb)
491 2 : self%ub = getOption(getInfPos(0._RKC), ub)
492 2 : CHECK_ASSERTION(__LINE__, 0._RKC <= self%lb, SK_"@constructIntDoncker1(): The condition `0._RKC <= self%lb` must hold. self%ub = "//getStr(self%ub))
493 6 : CHECK_ASSERTION(__LINE__, self%lb < self%ub, SK_"@constructIntDoncker1(): The condition `self%lb <= self%ub` must hold. self%ub = "//getStr([self%lb, self%ub]))
494 2 : self%integral = 2._RKC * (atan(sqrt(self%ub)) - atan(sqrt(self%lb)))
495 2 : self%desc = "IntDoncker1_type: f(x) = 1 / (1 + x) / sqrt(x) for x in (0 <= lb, ub) with a square-root singularity at 0"
496 2 : end procedure
497 :
498 144358 : module procedure getIntDoncker1
499 : use pm_kind, only: RKC => RKH
500 577432 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
501 : SK_"@getIntDoncker1(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
502 144358 : func = 1._RKC / (1._RKC + x) / sqrt(x)
503 144358 : end procedure
504 :
505 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 :
507 4 : module procedure constructIntDoncker2
508 : use pm_kind, only: RKC => RKH
509 : use pm_option, only: getOption
510 : use pm_except, only: getInfNeg, getInfPos
511 4 : self%lb = getOption(getInfNeg(0._RKC), lb)
512 4 : self%ub = getOption(0._RKC, ub)
513 4 : CHECK_ASSERTION(__LINE__, self%ub <= 0._RKC, SK_"@constructIntDoncker2(): The condition `0._RKC <= self%ub` must hold. self%ub = "//getStr(self%ub))
514 12 : CHECK_ASSERTION(__LINE__, self%lb < self%ub, SK_"@constructIntDoncker2(): The condition `self%lb <= self%ub` must hold. self%ub = "//getStr([self%lb, self%ub]))
515 4 : self%integral = sqrt(acos(-1._RKC)) * (erf(sqrt(-self%lb)) - erf(sqrt(-self%ub)))
516 4 : self%desc = "IntDoncker2_type: f(x) = exp(x) / sqrt(-x) for x in (lb, ub <= 0) with a square-root singularity at 0"
517 4 : end procedure
518 :
519 84750 : module procedure getIntDoncker2
520 : use pm_kind, only: RKC => RKH
521 339000 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, SK_"@getIntDoncker2(): The condition `self%lb <= x .and. x <= self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
522 84750 : func = exp(x) / sqrt(-x)
523 84750 : end procedure
524 :
525 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526 :
527 2 : module procedure constructIntCauchy1
528 : use pm_kind, only: RKC => RKH
529 2 : self%lb = getOption(-2._RKC, lb)
530 2 : self%ub = getOption(+3._RKC, ub)
531 2 : self%wcauchy = wcauchy_type(getOption(+1._RKC, cs))
532 8 : CHECK_ASSERTION(__LINE__, self%lb < self%wcauchy%cs .and. self%wcauchy%cs < self%ub, SK_"@constructIntCauchy1(): The condition `self%lb < self%wcauchy%cs .and. self%wcauchy%cs < self%ub` must hold. self%lb, self%wcauchy%cs, self%ub = "//getStr([self%lb, self%wcauchy%cs, self%ub]))
533 2 : self%integral = log(self%ub - self%wcauchy%cs) - log(self%wcauchy%cs - self%lb)
534 2 : self%desc = "IntCauchy1_type: an integrand of the form w(x) * f(x) with Cauchy weight w(x) 1 / (x - cs) and f(x) = 1 ~,~ x \in (lb < cs, cs < ub)"
535 2 : end procedure
536 :
537 74346 : module procedure getIntCauchy1
538 : use pm_kind, only: RKC => RKH
539 297384 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
540 : SK_"@getIntCauchy1(): The condition `self%lb < x .and. x < self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
541 223038 : CHECK_ASSERTION(__LINE__, abs(x - nearest(x, x)) < abs(x - self%wcauchy%cs), \
542 : SK_"@getIntCauchy1(): The condition `abs(x - nearest(x, x)) < abs(x - self%wcauchy%cs)` must hold. 10 * abs(x - nearest(x, x)), abs(x - self%wcauchy%cs) = "//getStr([abs(x - nearest(x, x)), abs(x - self%wcauchy%cs)]))
543 74346 : func = 1._RKC
544 74346 : end procedure
545 :
546 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
547 :
548 2 : module procedure constructIntCauchy2
549 : use pm_kind, only: RKC => RKH
550 : use pm_val2str, only: getStr
551 : use pm_swap, only: setSwapped
552 : use pm_mathMinMax, only: setMinMax
553 2 : self%lb = getOption(-3._RKC, lb)
554 2 : self%ub = getOption(+2._RKC, ub)
555 2 : self%pole(1) = getOption(-2._RKC, cs1)
556 2 : self%pole(2) = getOption(+3._RKC, cs2)
557 2 : call setMinMax(self%pole)
558 14 : CHECK_ASSERTION(__LINE__, .not. (self%lb < self%pole(1) .and. self%pole(1) < self%ub .and. self%lb < self%pole(2) .and. self%pole(2) < self%ub), \
559 : SK_"@getIntCauchy2(): The two specified Cauchy poles of the integrand must not simultaneously appear with the integration range. lb, cs1, cs2, ub = "//\
560 : getStr([self%lb, self%pole, self%ub]))
561 2 : self%wcauchy = wcauchy_type(self%pole(1))
562 2 : self%csnot = self%pole(2)
563 2 : if (self%lb < self%csnot .and. self%csnot < self%ub) call setSwapped(self%wcauchy%cs, self%csnot)
564 2 : self%integral = getIntegralIndef(self%ub) - getIntegralIndef(self%lb)
565 : self%desc = SK_"IntCauchy2_type: an integrand of the form w(x) * f(x) = 1 / (x "//merge(SK_"+ ", SK_"- ", self%pole(1) < 0._RKC)//getTTZ(getStr(abs(self%pole(1))))// & ! LCOV_EXCL_LINE
566 : SK_") / (x "//merge(SK_"+ ", SK_"- ", self%pole(2) < 0._RKC)//getTTZ(getStr(abs(self%pole(2))))// & ! LCOV_EXCL_LINE
567 6 : SK_") for x in ("//getTTZ(getStr(self%lb))//SK_", "//getTTZ(getStr(self%ub))//SK_")"
568 : contains
569 4 : PURE function getIntegralIndef(x) result(integralIndef)
570 : real(RKC), intent(in) :: x
571 : real(RKC) :: integralIndef
572 : !integralIndef = real((log(cmplx(x - self%pole(1), 0._RKC, RKC)) - log(cmplx(x - self%pole(2), 0._RKC, RKC))), RKC) / (self%pole(1) - self%pole(2))
573 4 : integralIndef = real((log(cmplx(1._RKC + (self%pole(2) - self%pole(1)) / (x - self%pole(2)), 0._RKC, RKC))), RKC) / (self%pole(1) - self%pole(2))
574 4 : end function
575 : end procedure
576 :
577 79802 : module procedure getIntCauchy2
578 : use pm_kind, only: RKC => RKH
579 319208 : CHECK_ASSERTION(__LINE__, self%lb <= x .and. x <= self%ub, \
580 : SK_"@getIntCauchy2(): The condition `self%lb < x .and. x < self%ub` must hold. self%lb, x, self%ub = "//getStr([self%lb, x, self%ub]))
581 : !check_assertion(__LINE__, all(abs(x - nearest(x, x)) < abs(x - self%pole)), \
582 : !SK_"@getIntCauchy2(): The condition `all(10 * abs(x - nearest(x, x)) < abs(x - self%pole))` must hold. abs(x - nearest(x, x)), abs(x - self%pole)) = "//getStr([real(RKC) :: abs(x - nearest(x, x)), abs(x - self%pole)]))
583 239342 : if (all(abs(x - nearest(x, x)) < abs(x - self%pole))) then
584 79770 : func = 1._RKC / (x - self%csnot)
585 : else
586 32 : func = 1.e9_RKC
587 : end if
588 79802 : end procedure
589 :
590 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 :
592 : #undef CHECK_ASSERTION
593 :
594 : end submodule routines
|