ParaMonte Fortran 2.0.0
Parallel Monte Carlo and Machine Learning Library
See the latest version documentation.
pm_mathLog1p.F90
Go to the documentation of this file.
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
38
39!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40
42
43 use pm_kind, only: SK, IK, LK
45
46 implicit none
47
48 character(*, SK), parameter :: MODULE_NAME = "@pm_mathLog1p"
49
50!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51
61 ! INTERNAL NOTE: Based on the benchmark results,
62 ! there does not appear to exist any performance benefits in having a control optional argument.
63 ! As such, it is removed from the interface.
64 ! \param control : The input scalar object that can be,
65 ! <ol>
66 ! <li> the constant [selection](@ref pm_control::selection) or equivalently,
67 ! an object of type [selection_type](@ref pm_control::selection_type).<br>
68 ! Specifying this option enables the runtime checks for underflow occurrence via branching and dynamic dispatch.<br>
69 ! Enabling this option can aid runtime efficiency when the `x` ratio is expected to cause underflow.<br>
70 ! In such cases, the logarithm can be avoided if `control =` [selection](@ref pm_control::selection), leading
71 ! to better runtime efficiency since logarithm is highly expensive (on the order of ~200 CPU cycles).<br>
72 ! See [the relevant benchmark here](#benchmark-getLog1p).<br>
73 ! </ol>
74 ! The presence of this argument is merely for compile-time resolution of the procedures of this generic interface.<br>
75 ! (**optional**. If missing, a sequence control flow will be assumed without dynamic dispatch.)
113 ! \benchmarks
114 !
115 ! \benchmark{getLog1p, The effects of `control` on runtime efficiency}
116 ! The following program compares the runtime performance of [getLog1p](@ref pm_mathLog1p::getLog1p)
117 ! algorithm with and without checking for underflows.
118 ! \include{lineno} benchmark/pm_mathLog1p/getLog1p/main.F90
119 ! \compilefb{getLog1p}
120 ! \postprocb{getLog1p}
121 ! \include{lineno} benchmark/pm_mathLog1p/getLog1p/main.py
122 ! \visb{getLog1p}
123 ! \image html benchmark/pm_mathLog1p/getLog1p/benchmark.getLog1p.runtime.png width=1000
124 ! \image html benchmark/pm_mathLog1p/getLog1p/benchmark.getLog1p.runtime.ratio.png width=1000
125 ! \moralb{getLog1p}
126 ! -# If the input value `x` is known to be frequently `< tiny(x)` or `> epsilon(x)` then it is generally beneficial
127 ! to call the interface with `control` argument set to [selection](@ref pm_control::selection).<br>
136 interface getLog1p
137
138 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141
142 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143
144#if CK5_ENABLED
145 PURE elemental module function getLog1pSeq_CK5(x) result(log1p)
146#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
147 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_CK5
148#endif
149 use pm_kind, only: CKG => CK5
150 complex(CKG) , intent(in) :: x
151 complex(CKG) :: log1p
152 end function
153#endif
154
155#if CK4_ENABLED
156 PURE elemental module function getLog1pSeq_CK4(x) result(log1p)
157#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
158 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_CK4
159#endif
160 use pm_kind, only: CKG => CK4
161 complex(CKG), intent(in) :: x
162 complex(CKG) :: log1p
163 end function
164#endif
165
166#if CK3_ENABLED
167 PURE elemental module function getLog1pSeq_CK3(x) result(log1p)
168#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
169 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_CK3
170#endif
171 use pm_kind, only: CKG => CK3
172 complex(CKG), intent(in) :: x
173 complex(CKG) :: log1p
174 end function
175#endif
176
177#if CK2_ENABLED
178 PURE elemental module function getLog1pSeq_CK2(x) result(log1p)
179#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
180 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_CK2
181#endif
182 use pm_kind, only: CKG => CK2
183 complex(CKG), intent(in) :: x
184 complex(CKG) :: log1p
185 end function
186#endif
187
188#if CK1_ENABLED
189 PURE elemental module function getLog1pSeq_CK1(x) result(log1p)
190#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
191 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_CK1
192#endif
193 use pm_kind, only: CKG => CK1
194 complex(CKG), intent(in) :: x
195 complex(CKG) :: log1p
196 end function
197#endif
198
199 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200
201#if RK5_ENABLED
202 PURE elemental module function getLog1pSeq_RK5(x) result(log1p)
203#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
204 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_RK5
205#endif
206 use pm_kind, only: RKG => RK5
207 real(RKG) , intent(in) :: x
208 real(RKG) :: log1p
209 end function
210#endif
211
212#if RK4_ENABLED
213 PURE elemental module function getLog1pSeq_RK4(x) result(log1p)
214#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
215 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_RK4
216#endif
217 use pm_kind, only: RKG => RK4
218 real(RKG) , intent(in) :: x
219 real(RKG) :: log1p
220 end function
221#endif
222
223#if RK3_ENABLED
224 PURE elemental module function getLog1pSeq_RK3(x) result(log1p)
225#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
226 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_RK3
227#endif
228 use pm_kind, only: RKG => RK3
229 real(RKG) , intent(in) :: x
230 real(RKG) :: log1p
231 end function
232#endif
233
234#if RK2_ENABLED
235 PURE elemental module function getLog1pSeq_RK2(x) result(log1p)
236#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
237 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_RK2
238#endif
239 use pm_kind, only: RKG => RK2
240 real(RKG) , intent(in) :: x
241 real(RKG) :: log1p
242 end function
243#endif
244
245#if RK1_ENABLED
246 PURE elemental module function getLog1pSeq_RK1(x) result(log1p)
247#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
248 !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSeq_RK1
249#endif
250 use pm_kind, only: RKG => RK1
251 real(RKG) , intent(in) :: x
252 real(RKG) :: log1p
253 end function
254#endif
255
256! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257!
258! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261!
262! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
263!
264!#if CK5_ENABLED
265! PURE elemental module function getLog1pSel_CK5(x, control) result(log1p)
266!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
267! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_CK5
268!#endif
269! use pm_kind, only: CKG => CK5
270! type(selection_type), intent(in) :: control
271! complex(CKG) , intent(in) :: x
272! complex(CKG) :: log1p
273! end function
274!#endif
275!
276!#if CK4_ENABLED
277! PURE elemental module function getLog1pSel_CK4(x, control) result(log1p)
278!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
279! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_CK4
280!#endif
281! use pm_kind, only: CKG => CK4
282! type(selection_type), intent(in) :: control
283! complex(CKG) , intent(in) :: x
284! complex(CKG) :: log1p
285! end function
286!#endif
287!
288!#if CK3_ENABLED
289! PURE elemental module function getLog1pSel_CK3(x, control) result(log1p)
290!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
291! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_CK3
292!#endif
293! use pm_kind, only: CKG => CK3
294! type(selection_type), intent(in) :: control
295! complex(CKG) , intent(in) :: x
296! complex(CKG) :: log1p
297! end function
298!#endif
299!
300!#if CK2_ENABLED
301! PURE elemental module function getLog1pSel_CK2(x, control) result(log1p)
302!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
303! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_CK2
304!#endif
305! use pm_kind, only: CKG => CK2
306! type(selection_type), intent(in) :: control
307! complex(CKG) , intent(in) :: x
308! complex(CKG) :: log1p
309! end function
310!#endif
311!
312!#if CK1_ENABLED
313! PURE elemental module function getLog1pSel_CK1(x, control) result(log1p)
314!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
315! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_CK1
316!#endif
317! use pm_kind, only: CKG => CK1
318! type(selection_type), intent(in) :: control
319! complex(CKG) , intent(in) :: x
320! complex(CKG) :: log1p
321! end function
322!#endif
323!
324! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325!
326!#if RK5_ENABLED
327! PURE elemental module function getLog1pSel_RK5(x, control) result(log1p)
328!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
329! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_RK5
330!#endif
331! use pm_kind, only: RKG => RK5
332! type(selection_type), intent(in) :: control
333! real(RKG) , intent(in) :: x
334! real(RKG) :: log1p
335! end function
336!#endif
337!
338!#if RK4_ENABLED
339! PURE elemental module function getLog1pSel_RK4(x, control) result(log1p)
340!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
341! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_RK4
342!#endif
343! use pm_kind, only: RKG => RK4
344! type(selection_type), intent(in) :: control
345! real(RKG) , intent(in) :: x
346! real(RKG) :: log1p
347! end function
348!#endif
349!
350!#if RK3_ENABLED
351! PURE elemental module function getLog1pSel_RK3(x, control) result(log1p)
352!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
353! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_RK3
354!#endif
355! use pm_kind, only: RKG => RK3
356! type(selection_type), intent(in) :: control
357! real(RKG) , intent(in) :: x
358! real(RKG) :: log1p
359! end function
360!#endif
361!
362!#if RK2_ENABLED
363! PURE elemental module function getLog1pSel_RK2(x, control) result(log1p)
364!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
365! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_RK2
366!#endif
367! use pm_kind, only: RKG => RK2
368! type(selection_type), intent(in) :: control
369! real(RKG) , intent(in) :: x
370! real(RKG) :: log1p
371! end function
372!#endif
373!
374!#if RK1_ENABLED
375! PURE elemental module function getLog1pSel_RK1(x, control) result(log1p)
376!#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
377! !DEC$ ATTRIBUTES DLLEXPORT :: getLog1pSel_RK1
378!#endif
379! use pm_kind, only: RKG => RK1
380! type(selection_type), intent(in) :: control
381! real(RKG) , intent(in) :: x
382! real(RKG) :: log1p
383! end function
384!#endif
385
386 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387
388 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391
392 end interface
393
394!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395
396end module pm_mathLog1p ! LCOV_EXCL_LINE
Generate and return the expression log(1 + x) robustly (without numerical underflow).
This module contains abstract and concrete derived types that are required for compile-time resolutio...
Definition: pm_control.F90:45
character(*, SK), parameter MODULE_NAME
Definition: pm_control.F90:51
type(selection_type), parameter selection
This is a scalar parameter object of type selection_type that is exclusively used to request selectio...
Definition: pm_control.F90:320
This module defines the relevant Fortran kind type-parameters frequently used in the ParaMonte librar...
Definition: pm_kind.F90:268
integer, parameter RK5
Definition: pm_kind.F90:478
integer, parameter RK4
Definition: pm_kind.F90:489
integer, parameter RK2
Definition: pm_kind.F90:511
integer, parameter CK1
Definition: pm_kind.F90:464
integer, parameter RK3
Definition: pm_kind.F90:500
integer, parameter LK
The default logical kind in the ParaMonte library: kind(.true.) in Fortran, kind(....
Definition: pm_kind.F90:541
integer, parameter CK5
Definition: pm_kind.F90:420
integer, parameter CK4
Definition: pm_kind.F90:431
integer, parameter CK2
Definition: pm_kind.F90:453
integer, parameter CK3
Definition: pm_kind.F90:442
integer, parameter IK
The default integer kind in the ParaMonte library: int32 in Fortran, c_int32_t in C-Fortran Interoper...
Definition: pm_kind.F90:540
integer, parameter SK
The default character kind in the ParaMonte library: kind("a") in Fortran, c_char in C-Fortran Intero...
Definition: pm_kind.F90:539
integer, parameter RK1
Definition: pm_kind.F90:522
This module contains procedures and generic interfaces for computing log(1 + x) more precisely for ti...
This is a concrete derived type whose instances are exclusively used to request selection control flo...
Definition: pm_control.F90:295