Exponential integer with the given mean, from a splitmix64_t generator.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(splitmix64_t), | intent(inout) | :: | gen |
Generator, advanced by one draw, or more in the tail. |
||
| integer(kind=int64), | intent(in) | :: | mean |
Mean of the distribution, in |
||
| type(error_t), | intent(inout), | optional | :: | err |
Set to |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=default_int), | private | :: | cell | ||||
| integer(kind=default_int), | private | :: | frac | ||||
| integer(kind=int64), | private | :: | gap | ||||
| integer(kind=default_int), | private | :: | turns | ||||
| integer(kind=int64), | private | :: | word | ||||
| integer(kind=int64), | private | :: | x_q32 |
function splitmix64_next_exponential_int(gen, mean, err) result(r) !! Exponential integer with the given mean, from a splitmix64_t generator. type(splitmix64_t), intent(inout) :: gen !! Generator, advanced by one draw, or more in the tail. integer(int64), intent(in) :: mean !! Mean of the distribution, in `[0, EXPONENTIAL_MAX_MEAN]`. type(error_t), intent(inout), optional :: err !! Set to `ERROR_VALIDATION` when `mean` is out of range. integer(int64) :: r integer(int64) :: word, x_q32, gap integer(default_int) :: cell, frac, turns r = 0_int64 if (mean < 0_int64 .or. mean > EXPONENTIAL_MAX_MEAN) then if (present(err)) then call err%set(ERROR_VALIDATION, & "pic_random_dist: next_exponential_int mean out of range") end if return end if if (mean == 0_int64) return x_q32 = 0_int64 turns = 0_default_int do word = gen%next_u64() cell = int(ibits(word, 0_default_int, EXP_CELL_BITS), default_int) if (cell < EXP_TOP_CELL .or. turns >= EXP_MAX_TAIL) then if (cell >= EXP_TOP_CELL) cell = EXP_TOP_CELL - 1_default_int frac = int(ibits(word, 33_default_int, FRAC_BITS), default_int) gap = EXP_TABLE(cell + 1_default_int) - EXP_TABLE(cell) x_q32 = x_q32 + EXP_TABLE(cell) + u64_shr(gap*int(frac, int64), FRAC_BITS) exit end if x_q32 = x_q32 + EXP_LN_CELLS turns = turns + 1_default_int end do r = scale_by_mean(x_q32, mean) end function splitmix64_next_exponential_int