dpoch1.f 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. *DECK DPOCH1
  2. DOUBLE PRECISION FUNCTION DPOCH1 (A, X)
  3. C***BEGIN PROLOGUE DPOCH1
  4. C***PURPOSE Calculate a generalization of Pochhammer's symbol starting
  5. C from first order.
  6. C***LIBRARY SLATEC (FNLIB)
  7. C***CATEGORY C1, C7A
  8. C***TYPE DOUBLE PRECISION (POCH1-S, DPOCH1-D)
  9. C***KEYWORDS FIRST ORDER, FNLIB, POCHHAMMER, SPECIAL FUNCTIONS
  10. C***AUTHOR Fullerton, W., (LANL)
  11. C***DESCRIPTION
  12. C
  13. C Evaluate a double precision generalization of Pochhammer's symbol
  14. C for double precision A and X for special situations that require
  15. C especially accurate values when X is small in
  16. C POCH1(A,X) = (POCH(A,X)-1)/X
  17. C = (GAMMA(A+X)/GAMMA(A) - 1.0)/X .
  18. C This specification is particularly suited for stably computing
  19. C expressions such as
  20. C (GAMMA(A+X)/GAMMA(A) - GAMMA(B+X)/GAMMA(B))/X
  21. C = POCH1(A,X) - POCH1(B,X)
  22. C Note that POCH1(A,0.0) = PSI(A)
  23. C
  24. C When ABS(X) is so small that substantial cancellation will occur if
  25. C the straightforward formula is used, we use an expansion due
  26. C to Fields and discussed by Y. L. Luke, The Special Functions and Their
  27. C Approximations, Vol. 1, Academic Press, 1969, page 34.
  28. C
  29. C The ratio POCH(A,X) = GAMMA(A+X)/GAMMA(A) is written by Luke as
  30. C (A+(X-1)/2)**X * polynomial in (A+(X-1)/2)**(-2) .
  31. C In order to maintain significance in POCH1, we write for positive a
  32. C (A+(X-1)/2)**X = EXP(X*LOG(A+(X-1)/2)) = EXP(Q)
  33. C = 1.0 + Q*EXPREL(Q) .
  34. C Likewise the polynomial is written
  35. C POLY = 1.0 + X*POLY1(A,X) .
  36. C Thus,
  37. C POCH1(A,X) = (POCH(A,X) - 1) / X
  38. C = EXPREL(Q)*(Q/X + Q*POLY1(A,X)) + POLY1(A,X)
  39. C
  40. C***REFERENCES (NONE)
  41. C***ROUTINES CALLED D1MACH, DCOT, DEXPRL, DPOCH, DPSI, XERMSG
  42. C***REVISION HISTORY (YYMMDD)
  43. C 770801 DATE WRITTEN
  44. C 890531 Changed all specific intrinsics to generic. (WRB)
  45. C 890911 Removed unnecessary intrinsics. (WRB)
  46. C 890911 REVISION DATE from Version 3.2
  47. C 891214 Prologue converted to Version 4.0 format. (BAB)
  48. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  49. C 900727 Added EXTERNAL statement. (WRB)
  50. C***END PROLOGUE DPOCH1
  51. DOUBLE PRECISION A, X, ABSA, ABSX, ALNEPS, ALNVAR, B, BERN(20),
  52. 1 BINV, BP, GBERN(21), GBK, PI, POLY1, Q, RHO, SINPXX, SINPX2,
  53. 2 SQTBIG, TERM, TRIG, VAR, VAR2, D1MACH, DPSI, DEXPRL, DCOT, DPOCH
  54. LOGICAL FIRST
  55. EXTERNAL DCOT
  56. SAVE BERN, PI, SQTBIG, ALNEPS, FIRST
  57. DATA BERN ( 1) / +.8333333333 3333333333 3333333333 333 D-1 /
  58. DATA BERN ( 2) / -.1388888888 8888888888 8888888888 888 D-2 /
  59. DATA BERN ( 3) / +.3306878306 8783068783 0687830687 830 D-4 /
  60. DATA BERN ( 4) / -.8267195767 1957671957 6719576719 576 D-6 /
  61. DATA BERN ( 5) / +.2087675698 7868098979 2100903212 014 D-7 /
  62. DATA BERN ( 6) / -.5284190138 6874931848 4768220217 955 D-9 /
  63. DATA BERN ( 7) / +.1338253653 0684678832 8269809751 291 D-10 /
  64. DATA BERN ( 8) / -.3389680296 3225828668 3019539124 944 D-12 /
  65. DATA BERN ( 9) / +.8586062056 2778445641 3590545042 562 D-14 /
  66. DATA BERN ( 10) / -.2174868698 5580618730 4151642386 591 D-15 /
  67. DATA BERN ( 11) / +.5509002828 3602295152 0265260890 225 D-17 /
  68. DATA BERN ( 12) / -.1395446468 5812523340 7076862640 635 D-18 /
  69. DATA BERN ( 13) / +.3534707039 6294674716 9322997780 379 D-20 /
  70. DATA BERN ( 14) / -.8953517427 0375468504 0261131811 274 D-22 /
  71. DATA BERN ( 15) / +.2267952452 3376830603 1095073886 816 D-23 /
  72. DATA BERN ( 16) / -.5744724395 2026452383 4847971943 400 D-24 /
  73. DATA BERN ( 17) / +.1455172475 6148649018 6626486727 132 D-26 /
  74. DATA BERN ( 18) / -.3685994940 6653101781 8178247990 866 D-28 /
  75. DATA BERN ( 19) / +.9336734257 0950446720 3255515278 562 D-30 /
  76. DATA BERN ( 20) / -.2365022415 7006299345 5963519636 983 D-31 /
  77. DATA PI / 3.1415926535 8979323846 2643383279 503 D0 /
  78. DATA FIRST /.TRUE./
  79. C***FIRST EXECUTABLE STATEMENT DPOCH1
  80. IF (FIRST) THEN
  81. SQTBIG = 1.0D0/SQRT(24.0D0*D1MACH(1))
  82. ALNEPS = LOG(D1MACH(3))
  83. ENDIF
  84. FIRST = .FALSE.
  85. C
  86. IF (X.EQ.0.0D0) DPOCH1 = DPSI(A)
  87. IF (X.EQ.0.0D0) RETURN
  88. C
  89. ABSX = ABS(X)
  90. ABSA = ABS(A)
  91. IF (ABSX.GT.0.1D0*ABSA) GO TO 70
  92. IF (ABSX*LOG(MAX(ABSA,2.0D0)).GT.0.1D0) GO TO 70
  93. C
  94. BP = A
  95. IF (A.LT.(-0.5D0)) BP = 1.0D0 - A - X
  96. INCR = 0
  97. IF (BP.LT.10.0D0) INCR = 11.0D0 - BP
  98. B = BP + INCR
  99. C
  100. VAR = B + 0.5D0*(X-1.0D0)
  101. ALNVAR = LOG(VAR)
  102. Q = X*ALNVAR
  103. C
  104. POLY1 = 0.0D0
  105. IF (VAR.GE.SQTBIG) GO TO 40
  106. VAR2 = (1.0D0/VAR)**2
  107. C
  108. RHO = 0.5D0*(X+1.0D0)
  109. GBERN(1) = 1.0D0
  110. GBERN(2) = -RHO/12.0D0
  111. TERM = VAR2
  112. POLY1 = GBERN(2)*TERM
  113. C
  114. NTERMS = -0.5D0*ALNEPS/ALNVAR + 1.0D0
  115. IF (NTERMS .GT. 20) CALL XERMSG ('SLATEC', 'DPOCH1',
  116. + 'NTERMS IS TOO BIG, MAYBE D1MACH(3) IS BAD', 1, 2)
  117. IF (NTERMS.LT.2) GO TO 40
  118. C
  119. DO 30 K=2,NTERMS
  120. GBK = 0.0D0
  121. DO 20 J=1,K
  122. NDX = K - J + 1
  123. GBK = GBK + BERN(NDX)*GBERN(J)
  124. 20 CONTINUE
  125. GBERN(K+1) = -RHO*GBK/K
  126. C
  127. TERM = TERM * (2*K-2-X)*(2*K-1-X)*VAR2
  128. POLY1 = POLY1 + GBERN(K+1)*TERM
  129. 30 CONTINUE
  130. C
  131. 40 POLY1 = (X-1.0D0)*POLY1
  132. DPOCH1 = DEXPRL(Q)*(ALNVAR+Q*POLY1) + POLY1
  133. C
  134. IF (INCR.EQ.0) GO TO 60
  135. C
  136. C WE HAVE DPOCH1(B,X), BUT BP IS SMALL, SO WE USE BACKWARDS RECURSION
  137. C TO OBTAIN DPOCH1(BP,X).
  138. C
  139. DO 50 II=1,INCR
  140. I = INCR - II
  141. BINV = 1.0D0/(BP+I)
  142. DPOCH1 = (DPOCH1 - BINV) / (1.0D0 + X*BINV)
  143. 50 CONTINUE
  144. C
  145. 60 IF (BP.EQ.A) RETURN
  146. C
  147. C WE HAVE DPOCH1(BP,X), BUT A IS LT -0.5. WE THEREFORE USE A REFLECTION
  148. C FORMULA TO OBTAIN DPOCH1(A,X).
  149. C
  150. SINPXX = SIN(PI*X)/X
  151. SINPX2 = SIN(0.5D0*PI*X)
  152. TRIG = SINPXX*DCOT(PI*B) - 2.0D0*SINPX2*(SINPX2/X)
  153. C
  154. DPOCH1 = TRIG + (1.0D0 + X*TRIG)*DPOCH1
  155. RETURN
  156. C
  157. 70 DPOCH1 = (DPOCH(A,X) - 1.0D0) / X
  158. RETURN
  159. C
  160. END