randoms_mod.f90 Source File


Source Code

module randoms
  !---------------------------------------------------------------------------------------------------------------------
  !! This module provides Gaussian sampling utility routines for use in unit testing.
  !---------------------------------------------------------------------------------------------------------------------
  use, intrinsic :: iso_fortran_env, only: r128=>real128, r64=>real64, r32=>real32
  implicit none (type, external)
  private

  ! Public API list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public :: random_gauss

  ! Definitions and Interfaces ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  interface gauss                                                                          ! Submodule gaussian_sampling
    !-------------------------------------------------------------------------------------------------------------------
    !! Samples random numbers from the standard Normal (Gaussian) Distribution with the given mean and sigma.
    !! Uses the Acceptance-complement ratio from W. Hoermann and G. Derflinger.
    !! This is one of the fastest existing methods for generating normal random variables.
    !!
    !! REFERENCE: - W. Hoermann and G. Derflinger (1990):
    !!              The ACR Method for generating normal random variables,
    !!              OR Spektrum 12 (1990), 181-185.
    !!
    !! Implementation taken from <https://root.cern.ch/doc/master/TRandom_8cxx_source.html#l00274>
    !! UNURAN (c) 2000  W. Hoermann & J. Leydold, Institut f. Statistik, WU Wien
    !---------------------------------------------------------------------------------------------------------------
    impure real(r128) module function gauss_r128(mu, sig) result(gauss_res)
      real(r128), intent(in) :: mu, sig
    end function gauss_r128
    impure real(r64) module function gauss_r64(mu, sig) result(gauss_res)
      real(r64), intent(in) :: mu, sig
    end function gauss_r64
    impure real(r32) module function gauss_r32(mu, sig) result(gauss_res)
      real(r32), intent(in) :: mu, sig
    end function gauss_r32
  end interface

  interface random_gauss                                                                   ! Submodule gaussian_sampling
    !-------------------------------------------------------------------------------------------------------------------
    !! Applies `gauss` to whole arrays and scalars.
    !-------------------------------------------------------------------------------------------------------------------
    impure elemental module subroutine random_gauss_r128(x, mu, sig)
      real(r128), intent(inout) :: x
      real(r128), intent(in)    :: mu, sig
    end subroutine random_gauss_r128
    impure elemental module subroutine random_gauss_r64(x, mu, sig)
      real(r64), intent(inout) :: x
      real(r64), intent(in)    :: mu, sig
    end subroutine random_gauss_r64
    impure elemental module subroutine random_gauss_r32(x, mu, sig)
      real(r32), intent(inout) :: x
      real(r32), intent(in)    :: mu, sig
    end subroutine random_gauss_r32
  end interface
end module randoms