pcg32_next_exponential_int Function

private function pcg32_next_exponential_int(gen, mean, err) result(r)

Exponential integer with the given mean, from a pcg32_t generator.

Arguments

Type IntentOptional Attributes Name
type(pcg32_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 [0, EXPONENTIAL_MAX_MEAN].

type(error_t), intent(inout), optional :: err

Set to ERROR_VALIDATION when mean is out of range.

Return Value integer(kind=int64)


Calls

proc~~pcg32_next_exponential_int~~CallsGraph proc~pcg32_next_exponential_int pcg32_next_exponential_int proc~error_set error_t%error_set proc~pcg32_next_exponential_int->proc~error_set proc~pcg32_next_u64 pcg32_t%pcg32_next_u64 proc~pcg32_next_exponential_int->proc~pcg32_next_u64 proc~scale_by_mean scale_by_mean proc~pcg32_next_exponential_int->proc~scale_by_mean proc~u64_shr u64_shr proc~pcg32_next_exponential_int->proc~u64_shr proc~pcg32_step pcg32_step proc~pcg32_next_u64->proc~pcg32_step proc~scale_by_mean->proc~u64_shr proc~pcg32_step->proc~u64_shr proc~rotate_right32 rotate_right32 proc~pcg32_step->proc~rotate_right32 proc~u64_add u64_add proc~pcg32_step->proc~u64_add proc~u64_mul u64_mul proc~pcg32_step->proc~u64_mul

Called by

proc~~pcg32_next_exponential_int~~CalledByGraph proc~pcg32_next_exponential_int pcg32_next_exponential_int interface~next_exponential_int next_exponential_int interface~next_exponential_int->proc~pcg32_next_exponential_int proc~pcg32_next_poisson_int pcg32_next_poisson_int proc~pcg32_next_poisson_int->proc~pcg32_next_exponential_int interface~next_poisson_int next_poisson_int interface~next_poisson_int->proc~pcg32_next_poisson_int

Variables

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

Source Code

   function pcg32_next_exponential_int(gen, mean, err) result(r)
      !! Exponential integer with the given mean, from a pcg32_t generator.
      type(pcg32_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 pcg32_next_exponential_int