pcg32_next_below Function

private function pcg32_next_below(gen, n, error) result(r)

Uniform integer in [0, n) from a PCG32 generator. Each attempt consumes two 32-bit outputs, so the stream stays word aligned no matter how many rejections occur.

Arguments

Type IntentOptional Attributes Name
type(pcg32_t), intent(inout) :: gen
integer(kind=default_int), intent(in) :: n
type(error_t), intent(inout), optional :: error

Return Value integer(kind=default_int)


Calls

proc~~pcg32_next_below~~CallsGraph proc~pcg32_next_below pcg32_next_below proc~error_set error_t%error_set proc~pcg32_next_below->proc~error_set proc~pcg32_next_u64 pcg32_t%pcg32_next_u64 proc~pcg32_next_below->proc~pcg32_next_u64 proc~rejection_mask rejection_mask proc~pcg32_next_below->proc~rejection_mask proc~pcg32_step pcg32_step proc~pcg32_next_u64->proc~pcg32_step 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 proc~u64_shr u64_shr proc~pcg32_step->proc~u64_shr

Called by

proc~~pcg32_next_below~~CalledByGraph proc~pcg32_next_below pcg32_next_below interface~next_below next_below interface~next_below->proc~pcg32_next_below

Variables

Type Visibility Attributes Name Initial
integer(kind=int64), private :: bound
integer(kind=int64), private :: candidate
integer(kind=int64), private :: mask

Source Code

   function pcg32_next_below(gen, n, error) result(r)
      !! Uniform integer in [0, n) from a PCG32 generator. Each attempt consumes
      !! two 32-bit outputs, so the stream stays word aligned no matter how many
      !! rejections occur.
      type(pcg32_t), intent(inout) :: gen
      integer(default_int), intent(in) :: n
      type(error_t), intent(inout), optional :: error
      integer(default_int) :: r

      integer(int64) :: bound, mask, candidate

      r = 0_default_int
      if (n <= 0_default_int) then
         if (present(error)) then
            call error%set(ERROR_VALIDATION, "pic_rng: next_below requires n > 0")
         end if
         return
      end if
      if (n == 1_default_int) return

      bound = int(n, int64)
      mask = rejection_mask(bound)
      do
         candidate = iand(gen%next_u64(), mask)
         if (candidate < bound) exit
      end do
      r = int(candidate, default_int)
   end function pcg32_next_below