1
1
#:include "common.fypp"
2
2
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
3
3
module stdlib_stats_distribution_exponential
4
+ use ieee_arithmetic, only: ieee_value, ieee_quiet_nan
4
5
use stdlib_kinds, only : sp, dp, xdp, qp, int32
5
- use stdlib_error, only : error_stop
6
6
use stdlib_random, only : dist_rand
7
7
use stdlib_stats_distribution_uniform, only : uni=>rvs_uniform
8
8
@@ -71,7 +71,7 @@ module stdlib_stats_distribution_exponential
71
71
72
72
contains
73
73
74
- subroutine zigset
74
+ impure subroutine zigset
75
75
! Marsaglia & Tsang generator for random normals & random exponentials.
76
76
! Translated from C by Alan Miller (amiller@bigpond.net.au)
77
77
!
@@ -90,7 +90,7 @@ contains
90
90
91
91
de = 7.697117470131487_dp
92
92
te = de
93
- !tables for random exponetials
93
+ ! tables for random exponentials
94
94
q = ve * exp(de)
95
95
ke(0) = int((de / q) * M2, kind = int32)
96
96
ke(1) = 0
@@ -112,7 +112,7 @@ contains
112
112
113
113
114
114
#: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)
116
116
!
117
117
! Standard exponential random variate (lambda=1)
118
118
!
@@ -122,8 +122,8 @@ contains
122
122
123
123
if(.not. zig_exp_initialized ) call zigset
124
124
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]
127
127
if( abs( jz ) < ke(iz) ) then
128
128
res = abs(jz) * we(iz)
129
129
else
@@ -153,18 +153,19 @@ contains
153
153
154
154
155
155
#: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)
157
157
!
158
158
! Exponential distributed random variate
159
159
!
160
160
${t1}$, intent(in) :: lambda
161
161
${t1}$ :: res
162
162
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
168
169
end function rvs_exp_${t1[0]}$${k1}$
169
170
170
171
#:endfor
@@ -173,7 +174,7 @@ contains
173
174
174
175
175
176
#: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)
177
178
${t1}$, intent(in) :: lambda
178
179
${t1}$ :: res
179
180
real(${k1}$) :: tr, ti
@@ -189,15 +190,17 @@ contains
189
190
190
191
191
192
#: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)
193
194
${t1}$, intent(in) :: lambda
194
195
integer, intent(in) :: array_size
195
196
${t1}$ :: res(array_size), x, re
196
197
${t1}$, parameter :: r = 7.69711747013104972_${k1}$
197
198
integer :: jz, iz, i
198
199
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
201
204
202
205
if(.not. zig_exp_initialized) call zigset
203
206
do i = 1, array_size
@@ -235,7 +238,7 @@ contains
235
238
236
239
237
240
#: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)
239
242
${t1}$, intent(in) :: lambda
240
243
integer, intent(in) :: array_size
241
244
${t1}$ :: res(array_size)
@@ -255,18 +258,18 @@ contains
255
258
256
259
257
260
#: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)
259
262
!
260
263
! Exponential Distribution Probability Density Function
261
264
!
262
265
${t1}$, intent(in) :: x, lambda
263
266
real(${k1}$) :: res
264
267
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
270
273
end function pdf_exp_${t1[0]}$${k1}$
271
274
272
275
#:endfor
@@ -275,7 +278,7 @@ contains
275
278
276
279
277
280
#: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)
279
282
${t1}$, intent(in) :: x, lambda
280
283
real(${k1}$) :: res
281
284
@@ -289,18 +292,18 @@ contains
289
292
290
293
291
294
#: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)
293
296
!
294
297
! Exponential Distribution Cumulative Distribution Function
295
298
!
296
299
${t1}$, intent(in) :: x, lambda
297
300
real(${k1}$) :: res
298
301
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
304
307
end function cdf_exp_${t1[0]}$${k1}$
305
308
306
309
#:endfor
@@ -309,7 +312,7 @@ contains
309
312
310
313
311
314
#: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)
313
316
${t1}$, intent(in) :: x, lambda
314
317
real(${k1}$) :: res
315
318
0 commit comments