Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=dp), | intent(in) | :: | x |
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