lngamma Function

function lngamma(x) result(fn_val)

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(in) :: x

Return Value real(kind=dp)


Source Code

FUNCTION lngamma(x) RESULT(fn_val)
  ! Logarithm to base e of the gamma function.
  !
  ! Accurate to about 1.e-14.
  ! Programmer: Alan Miller
  ! Latest revision of Fortran 77 version - 28 February 1988
  REAL (dp), INTENT(IN) :: x
  REAL (dp)             :: fn_val
  !       Local variables
  REAL (dp) :: a1 = -4.166666666554424D-02, a2 = 2.430554511376954D-03,  &
       a3 = -7.685928044064347D-04, a4 = 5.660478426014386D-04,  &
       temp, arg, product, lnrt2pi = 9.189385332046727D-1,       &
       pi = 3.141592653589793D0
  LOGICAL   :: reflect
  !       lngamma is not defined if x = 0 or a negative integer.
  IF (x > 0.d0) GO TO 10
  IF (x /= INT(x)) GO TO 10
  fn_val = 0.d0
  RETURN
  !       If x < 0, use the reflection formula:
  !               gamma(x) * gamma(1-x) = pi * cosec(pi.x)
10 reflect = (x < 0.d0)
  IF (reflect) THEN
     arg = 1.d0 - x
  ELSE
     arg = x
  END IF
  !       Increase the argument, if necessary, to make it > 10.
  product = 1.d0
20 IF (arg <= 10.d0) THEN
     product = product * arg
     arg = arg + 1.d0
     GO TO 20
  END IF
  !  Use a polynomial approximation to Stirling's formula.
  !  N.B. The real Stirling's formula is used here, not the simpler, but less
  !       accurate formula given by De Moivre in a letter to Stirling, which
  !       is the one usually quoted.
  arg = arg - 0.5D0
  temp = 1.d0/arg**2
  fn_val = lnrt2pi + arg * (LOG(arg) - 1.d0 + &
       (((a4*temp + a3)*temp + a2)*temp + a1)*temp) - LOG(product)
  IF (reflect) THEN
     temp = SIN(pi * x)
     fn_val = LOG(pi/temp) - fn_val
  END IF
  RETURN
END FUNCTION lngamma