123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- *DECK CPSI
- COMPLEX FUNCTION CPSI (ZIN)
- C***BEGIN PROLOGUE CPSI
- C***PURPOSE Compute the Psi (or Digamma) function.
- C***LIBRARY SLATEC (FNLIB)
- C***CATEGORY C7C
- C***TYPE COMPLEX (PSI-S, DPSI-D, CPSI-C)
- C***KEYWORDS DIGAMMA FUNCTION, FNLIB, PSI FUNCTION, SPECIAL FUNCTIONS
- C***AUTHOR Fullerton, W., (LANL)
- C***DESCRIPTION
- C
- C PSI(X) calculates the psi (or digamma) function of X. PSI(X)
- C is the logarithmic derivative of the gamma function of X.
- C
- C***REFERENCES (NONE)
- C***ROUTINES CALLED CCOT, R1MACH, XERMSG
- C***REVISION HISTORY (YYMMDD)
- C 780501 DATE WRITTEN
- C 890531 Changed all specific intrinsics to generic. (WRB)
- C 890531 REVISION DATE from Version 3.2
- C 891214 Prologue converted to Version 4.0 format. (BAB)
- C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
- C 900727 Added EXTERNAL statement. (WRB)
- C***END PROLOGUE CPSI
- COMPLEX ZIN, Z, Z2INV, CORR, CCOT
- DIMENSION BERN(13)
- LOGICAL FIRST
- EXTERNAL CCOT
- SAVE BERN, PI, NTERM, BOUND, DXREL, RMIN, RBIG, FIRST
- DATA BERN( 1) / .8333333333 3333333 E-1 /
- DATA BERN( 2) / -.8333333333 3333333 E-2 /
- DATA BERN( 3) / .3968253968 2539683 E-2 /
- DATA BERN( 4) / -.4166666666 6666667 E-2 /
- DATA BERN( 5) / .7575757575 7575758 E-2 /
- DATA BERN( 6) / -.2109279609 2796093 E-1 /
- DATA BERN( 7) / .8333333333 3333333 E-1 /
- DATA BERN( 8) / -.4432598039 2156863 E0 /
- DATA BERN( 9) / .3053954330 2701197 E1 /
- DATA BERN(10) / -.2645621212 1212121 E2 /
- DATA BERN(11) / .2814601449 2753623 E3 /
- DATA BERN(12) / -.3454885393 7728938 E4 /
- DATA BERN(13) / .5482758333 3333333 E5 /
- DATA PI / 3.141592653 589793 E0 /
- DATA FIRST /.TRUE./
- C***FIRST EXECUTABLE STATEMENT CPSI
- IF (FIRST) THEN
- NTERM = -0.30*LOG(R1MACH(3))
- C MAYBE BOUND = N*(0.1*EPS)**(-1/(2*N-1)) / (PI*EXP(1))
- BOUND = 0.1171*NTERM*(0.1*R1MACH(3))**(-1.0/(2*NTERM-1))
- DXREL = SQRT(R1MACH(4))
- RMIN = EXP (MAX (LOG(R1MACH(1)), -LOG(R1MACH(2))) + 0.011 )
- RBIG = 1.0/R1MACH(3)
- ENDIF
- FIRST = .FALSE.
- C
- Z = ZIN
- X = REAL(Z)
- Y = AIMAG(Z)
- IF (Y.LT.0.0) Z = CONJG(Z)
- C
- CORR = (0.0, 0.0)
- CABSZ = ABS(Z)
- IF (X.GE.0.0 .AND. CABSZ.GT.BOUND) GO TO 50
- IF (X.LT.0.0 .AND. ABS(Y).GT.BOUND) GO TO 50
- C
- IF (CABSZ.LT.BOUND) GO TO 20
- C
- C USE THE REFLECTION FORMULA FOR REAL(Z) NEGATIVE, ABS(Z) LARGE, AND
- C ABS(AIMAG(Y)) SMALL.
- C
- CORR = -PI*CCOT(PI*Z)
- Z = 1.0 - Z
- GO TO 50
- C
- C USE THE RECURSION RELATION FOR ABS(Z) SMALL.
- C
- 20 IF (CABSZ .LT. RMIN) CALL XERMSG ('SLATEC', 'CPSI',
- + 'CPSI CALLED WITH Z SO NEAR 0 THAT CPSI OVERFLOWS', 2, 2)
- C
- IF (X.GE.(-0.5) .OR. ABS(Y).GT.DXREL) GO TO 30
- IF (ABS((Z-AINT(X-0.5))/X) .LT. DXREL) CALL XERMSG ('SLATEC',
- + 'CPSI',
- + 'ANSWER LT HALF PRECISION BECAUSE Z TOO NEAR NEGATIVE INTEGER',
- + 1, 1)
- IF (Y .EQ. 0.0 .AND. X .EQ. AINT(X)) CALL XERMSG ('SLATEC',
- + 'CPSI', 'Z IS A NEGATIVE INTEGER', 3, 2)
- C
- 30 N = SQRT(BOUND**2-Y**2) - X + 1.0
- DO 40 I=1,N
- CORR = CORR - 1.0/Z
- Z = Z + 1.0
- 40 CONTINUE
- C
- C NOW EVALUATE THE ASYMPTOTIC SERIES FOR SUITABLY LARGE Z.
- C
- 50 IF (CABSZ.GT.RBIG) CPSI = LOG(Z) + CORR
- IF (CABSZ.GT.RBIG) GO TO 70
- C
- CPSI = (0.0, 0.0)
- Z2INV = 1.0/Z**2
- DO 60 I=1,NTERM
- NDX = NTERM + 1 - I
- CPSI = BERN(NDX) + Z2INV*CPSI
- 60 CONTINUE
- CPSI = LOG(Z) - 0.5/Z - CPSI*Z2INV + CORR
- C
- 70 IF (Y.LT.0.0) CPSI = CONJG(CPSI)
- C
- RETURN
- END
|