! !======================================================================= ! MODULE DIGAMMA_FUNCTION ! ! This module provides different subroutine/functions ! to compute the Digamma function, namely: ! ! ! ! 3) SUBROUTINE PSI(X,PS) <-- x real ! ! USE ACCURACY_REAL ! CONTAINS ! !======================================================================= ! SUBROUTINE PSI(X,PS) ! !*********************************************************************72 ! ! PSI computes the Psi function. ! ! Licensing: ! ! This routine is copyrighted by Shanjie Zhang and Jianming Jin. However, ! they give permission to incorporate this routine into a user program ! provided that the copyright is acknowledged. ! ! Modified: ! ! 22 July 2012 ! ! Author: ! ! Shanjie Zhang, Jianming Jin ! ! Reference: ! ! Shanjie Zhang, Jianming Jin, ! Computation of Special Functions, ! Wiley, 1996, ! ISBN: 0-471-11963-6, ! LC: QA351.C45. ! ! ============================================ ! ! Purpose: Compute Psi function ! ! Input : X --- Argument of psi(x) ! ! Output: PS --- psi(x) ! ! ============================================ ! ! ! Last modified (DS) : 1 Sep 2020 ! ! USE REAL_NUMBERS, ONLY : ZERO,ONE,TWO,TEN, & HALF,INF USE PI_ETC, ONLY : PI ! IMPLICIT NONE ! INTEGER :: K,N ! REAL (WP), INTENT(IN) :: X ! REAL (WP), INTENT(OUT) :: PS ! REAL (WP) :: A1,A2,A3,A4,A5,A6,A7,A8 REAL (WP) :: S,X2,XA ! REAL (WP), PARAMETER :: EL = 0.5772156649015329E+00_WP ! XA = DABS(X) ! S = ZERO ! ! IF(X == INT(X) .AND. X <= ZERO) THEN ! ! PS = INF ! RETURN ! ! ELSE IF(XA == INT(XA)) THEN ! ! N = INT(XA) ! DO K = 1, N - 1 ! S = S + ONE / K ! END DO ! PS = - EL + S ! ! ELSE IF(XA + HALF == INT(XA + HALF)) THEN ! ! N = INT(XA - HALF) ! DO K = 1, N ! S = S + ONE / (TWO * K - ONE) ! END DO PS = - EL + TWO * S - 1.386294361119891E+00_WP ! ! ELSE ! ! IF(XA < TEN) THEN ! N = 10 - INT(XA) ! DO K = 0, N - 1 ! S = S + ONE / (XA + K) ! END DO ! XA = XA + N ! END IF ! ! X2 = ONE / (XA * XA) ! A1 = -0.8333333333333E-01_WP ! A2 = 0.83333333333333333E-02_WP ! A3 = -0.39682539682539683E-02_WP ! A4 = 0.41666666666666667E-02_WP ! A5 = -0.75757575757575758E-02_WP ! A6 = 0.21092796092796093E-01_WP ! A7 = -0.83333333333333333E-01_WP ! A8 = 0.4432598039215686E+00_WP ! ! PS = DLOG(XA) - HALF / XA + X2 * ((((((( & ! A8 * X2 & ! + A7) * X2 & ! + A6) * X2 & ! + A5) * X2 & ! + A4) * X2 & ! + A3) * X2 & ! + A2) * X2 & ! + A1) ! PS = PS - S ! ! END IF ! ! IF(X < ZERO) THEN ! PS = PS - PI * DCOS(PI * X) / DSIN(PI * X) - ONE / X ! END IF ! ! RETURN ! ! END SUBROUTINE PSI ! END MODULE DIGAMMA_FUNCTION