11#:include "common.fypp"
22#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
33module stdlib_stats_distribution_exponential
4+ use ieee_arithmetic, only: ieee_value, ieee_quiet_nan
45 use stdlib_kinds, only : sp, dp, xdp, qp, int32
5- use stdlib_error, only : error_stop
66 use stdlib_random, only : dist_rand
77 use stdlib_stats_distribution_uniform, only : uni=>rvs_uniform
88
@@ -71,7 +71,7 @@ module stdlib_stats_distribution_exponential
7171
7272contains
7373
74- subroutine zigset
74+ impure subroutine zigset
7575 ! Marsaglia & Tsang generator for random normals & random exponentials.
7676 ! Translated from C by Alan Miller (amiller@bigpond.net.au)
7777 !
@@ -90,7 +90,7 @@ contains
9090
9191 de = 7.697117470131487_dp
9292 te = de
93- !tables for random exponetials
93+ ! tables for random exponentials
9494 q = ve * exp(de)
9595 ke(0) = int((de / q) * M2, kind = int32)
9696 ke(1) = 0
@@ -112,7 +112,7 @@ contains
112112
113113
114114 #:for k1, t1 in REAL_KINDS_TYPES
115- function rvs_exp_0_${t1[0]}$${k1}$( ) result(res)
115+ impure function rvs_exp_0_${t1[0]}$${k1}$( ) result(res)
116116 !
117117 ! Standard exponential random variate (lambda=1)
118118 !
@@ -122,8 +122,8 @@ contains
122122
123123 if(.not. zig_exp_initialized ) call zigset
124124 iz = 0
125- jz = dist_rand(1_int32) !32bit random integer
126- iz = iand( jz, 255 ) !random integer in [0, 255]
125+ jz = dist_rand(1_int32) ! 32bit random integer
126+ iz = iand( jz, 255 ) ! random integer in [0, 255]
127127 if( abs( jz ) < ke(iz) ) then
128128 res = abs(jz) * we(iz)
129129 else
@@ -153,18 +153,19 @@ contains
153153
154154
155155 #:for k1, t1 in REAL_KINDS_TYPES
156- function rvs_exp_${t1[0]}$${k1}$(lambda) result(res)
156+ impure elemental function rvs_exp_${t1[0]}$${k1}$(lambda) result(res)
157157 !
158158 ! Exponential distributed random variate
159159 !
160160 ${t1}$, intent(in) :: lambda
161161 ${t1}$ :: res
162162
163-
164- if(lambda <= 0.0_${k1}$) call error_stop("Error(rvs_exp): Exponen" &
165- //"tial distribution lambda parameter must be greater than zero")
166- res = rvs_exp_0_${t1[0]}$${k1}$( )
167- res = res / lambda
163+ if (lambda <= 0._${k1}$) then
164+ res = ieee_value(1._${k1}$, ieee_quiet_nan)
165+ else
166+ res = rvs_exp_0_${t1[0]}$${k1}$( )
167+ res = res / lambda
168+ end if
168169 end function rvs_exp_${t1[0]}$${k1}$
169170
170171 #:endfor
@@ -173,7 +174,7 @@ contains
173174
174175
175176 #:for k1, t1 in CMPLX_KINDS_TYPES
176- function rvs_exp_${t1[0]}$${k1}$(lambda) result(res)
177+ impure elemental function rvs_exp_${t1[0]}$${k1}$(lambda) result(res)
177178 ${t1}$, intent(in) :: lambda
178179 ${t1}$ :: res
179180 real(${k1}$) :: tr, ti
@@ -189,15 +190,17 @@ contains
189190
190191
191192 #:for k1, t1 in REAL_KINDS_TYPES
192- function rvs_exp_array_${t1[0]}$${k1}$(lambda, array_size) result(res)
193+ impure function rvs_exp_array_${t1[0]}$${k1}$(lambda, array_size) result(res)
193194 ${t1}$, intent(in) :: lambda
194195 integer, intent(in) :: array_size
195196 ${t1}$ :: res(array_size), x, re
196197 ${t1}$, parameter :: r = 7.69711747013104972_${k1}$
197198 integer :: jz, iz, i
198199
199- if(lambda <= 0.0_${k1}$) call error_stop("Error(rvs_exp_array): Exp" &
200- //"onential distribution lambda parameter must be greater than zero")
200+ if (lambda <= 0._${k1}$) then
201+ res = ieee_value(1._${k1}$, ieee_quiet_nan)
202+ return
203+ end if
201204
202205 if(.not. zig_exp_initialized) call zigset
203206 do i = 1, array_size
@@ -235,7 +238,7 @@ contains
235238
236239
237240 #:for k1, t1 in CMPLX_KINDS_TYPES
238- function rvs_exp_array_${t1[0]}$${k1}$(lambda, array_size) result(res)
241+ impure function rvs_exp_array_${t1[0]}$${k1}$(lambda, array_size) result(res)
239242 ${t1}$, intent(in) :: lambda
240243 integer, intent(in) :: array_size
241244 ${t1}$ :: res(array_size)
@@ -255,18 +258,18 @@ contains
255258
256259
257260 #:for k1, t1 in REAL_KINDS_TYPES
258- impure elemental function pdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
261+ elemental function pdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
259262 !
260263 ! Exponential Distribution Probability Density Function
261264 !
262265 ${t1}$, intent(in) :: x, lambda
263266 real(${k1}$) :: res
264267
265- if( lambda <= 0.0_ ${k1}$) call error_stop("Error(pdf_exp): Expon" &
266- //"ential distribution lambda parameter must be greater than zero" )
267- if(x < 0.0_${k1}$) call error_stop("Error(pdf_exp): Exponential" &
268- //" distribution variate x must be non-negative")
269- res = exp(- x * lambda) * lambda
268+ if (( lambda <= 0._ ${k1}$) .or. (x < 0._${k1}$)) then
269+ res = ieee_value(1._${k1}$, ieee_quiet_nan )
270+ else
271+ res = exp(- x * lambda) * lambda
272+ end if
270273 end function pdf_exp_${t1[0]}$${k1}$
271274
272275 #:endfor
@@ -275,7 +278,7 @@ contains
275278
276279
277280 #:for k1, t1 in CMPLX_KINDS_TYPES
278- impure elemental function pdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
281+ elemental function pdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
279282 ${t1}$, intent(in) :: x, lambda
280283 real(${k1}$) :: res
281284
@@ -289,18 +292,18 @@ contains
289292
290293
291294 #:for k1, t1 in REAL_KINDS_TYPES
292- impure elemental function cdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
295+ elemental function cdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
293296 !
294297 ! Exponential Distribution Cumulative Distribution Function
295298 !
296299 ${t1}$, intent(in) :: x, lambda
297300 real(${k1}$) :: res
298301
299- if( lambda <= 0.0_ ${k1}$) call error_stop("Error(cdf_exp): Expon" &
300- //"ential distribution lambda parameter must be greater than zero" )
301- if(x < 0.0_${k1}$) call error_stop("Error(cdf_exp): Exponential" &
302- //" distribution variate x must be non-negative" )
303- res = 1.0_${k1}$ - exp(- x * lambda)
302+ if (( lambda <= 0._ ${k1}$) .or. (x < 0._${k1}$)) then
303+ res = ieee_value(1._${k1}$, ieee_quiet_nan )
304+ else
305+ res = 1.0_${k1}$ - exp(- x * lambda )
306+ end if
304307 end function cdf_exp_${t1[0]}$${k1}$
305308
306309 #:endfor
@@ -309,7 +312,7 @@ contains
309312
310313
311314 #:for k1, t1 in CMPLX_KINDS_TYPES
312- impure elemental function cdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
315+ elemental function cdf_exp_${t1[0]}$${k1}$(x, lambda) result(res)
313316 ${t1}$, intent(in) :: x, lambda
314317 real(${k1}$) :: res
315318
0 commit comments