poch1.f 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. *DECK POCH1
  2. FUNCTION POCH1 (A, X)
  3. C***BEGIN PROLOGUE POCH1
  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 SINGLE 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 generalization of Pochhammer's symbol for special
  14. C situations that require especially accurate values when X is small in
  15. C POCH1(A,X) = (POCH(A,X)-1)/X
  16. C = (GAMMA(A+X)/GAMMA(A) - 1.0)/X .
  17. C This specification is particularly suited for stably computing
  18. C expressions such as
  19. C (GAMMA(A+X)/GAMMA(A) - GAMMA(B+X)/GAMMA(B))/X
  20. C = POCH1(A,X) - POCH1(B,X)
  21. C Note that POCH1(A,0.0) = PSI(A)
  22. C
  23. C When ABS(X) is so small that substantial cancellation will occur if
  24. C the straightforward formula is used, we use an expansion due
  25. C to Fields and discussed by Y. L. Luke, The Special Functions and Their
  26. C Approximations, Vol. 1, Academic Press, 1969, page 34.
  27. C
  28. C The ratio POCH(A,X) = GAMMA(A+X)/GAMMA(A) is written by Luke as
  29. C (A+(X-1)/2)**X * polynomial in (A+(X-1)/2)**(-2) .
  30. C In order to maintain significance in POCH1, we write for positive A
  31. C (A+(X-1)/2)**X = EXP(X*LOG(A+(X-1)/2)) = EXP(Q)
  32. C = 1.0 + Q*EXPREL(Q) .
  33. C Likewise the polynomial is written
  34. C POLY = 1.0 + X*POLY1(A,X) .
  35. C Thus,
  36. C POCH1(A,X) = (POCH(A,X) - 1) / X
  37. C = EXPREL(Q)*(Q/X + Q*POLY1(A,X)) + POLY1(A,X)
  38. C
  39. C***REFERENCES (NONE)
  40. C***ROUTINES CALLED COT, EXPREL, POCH, PSI, R1MACH, XERMSG
  41. C***REVISION HISTORY (YYMMDD)
  42. C 770801 DATE WRITTEN
  43. C 890531 Changed all specific intrinsics to generic. (WRB)
  44. C 890531 REVISION DATE from Version 3.2
  45. C 891214 Prologue converted to Version 4.0 format. (BAB)
  46. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  47. C 900727 Added EXTERNAL statement. (WRB)
  48. C***END PROLOGUE POCH1
  49. DIMENSION BERN(9), GBERN(10)
  50. LOGICAL FIRST
  51. EXTERNAL COT
  52. SAVE BERN, PI, SQTBIG, ALNEPS, FIRST
  53. DATA BERN( 1) / .8333333333 3333333E-01 /
  54. DATA BERN( 2) / -.1388888888 8888889E-02 /
  55. DATA BERN( 3) / .3306878306 8783069E-04 /
  56. DATA BERN( 4) / -.8267195767 1957672E-06 /
  57. DATA BERN( 5) / .2087675698 7868099E-07 /
  58. DATA BERN( 6) / -.5284190138 6874932E-09 /
  59. DATA BERN( 7) / .1338253653 0684679E-10 /
  60. DATA BERN( 8) / -.3389680296 3225829E-12 /
  61. DATA BERN( 9) / .8586062056 2778446E-14 /
  62. DATA PI / 3.1415926535 8979324 E0 /
  63. DATA FIRST /.TRUE./
  64. C***FIRST EXECUTABLE STATEMENT POCH1
  65. IF (FIRST) THEN
  66. SQTBIG = 1.0/SQRT(24.0*R1MACH(1))
  67. ALNEPS = LOG(R1MACH(3))
  68. ENDIF
  69. FIRST = .FALSE.
  70. C
  71. IF (X.EQ.0.0) POCH1 = PSI(A)
  72. IF (X.EQ.0.0) RETURN
  73. C
  74. ABSX = ABS(X)
  75. ABSA = ABS(A)
  76. IF (ABSX.GT.0.1*ABSA) GO TO 70
  77. IF (ABSX*LOG(MAX(ABSA,2.0)).GT.0.1) GO TO 70
  78. C
  79. BP = A
  80. IF (A.LT.(-0.5)) BP = 1.0 - A - X
  81. INCR = 0
  82. IF (BP.LT.10.0) INCR = 11.0 - BP
  83. B = BP + INCR
  84. C
  85. VAR = B + 0.5*(X-1.0)
  86. ALNVAR = LOG(VAR)
  87. Q = X*ALNVAR
  88. C
  89. POLY1 = 0.0
  90. IF (VAR.GE.SQTBIG) GO TO 40
  91. VAR2 = (1.0/VAR)**2
  92. C
  93. RHO = 0.5*(X+1.0)
  94. GBERN(1) = 1.0
  95. GBERN(2) = -RHO/12.0
  96. TERM = VAR2
  97. POLY1 = GBERN(2)*TERM
  98. C
  99. NTERMS = -0.5*ALNEPS/ALNVAR + 1.0
  100. IF (NTERMS .GT. 9) CALL XERMSG ('SLATEC', 'POCH1',
  101. + 'NTERMS IS TOO BIG, MAYBE R1MACH(3) IS BAD', 1, 2)
  102. IF (NTERMS.LT.2) GO TO 40
  103. C
  104. DO 30 K=2,NTERMS
  105. GBK = 0.0
  106. DO 20 J=1,K
  107. NDX = K - J + 1
  108. GBK = GBK + BERN(NDX)*GBERN(J)
  109. 20 CONTINUE
  110. GBERN(K+1) = -RHO*GBK/K
  111. C
  112. TERM = TERM * (2*K-2.-X)*(2*K-1.-X)*VAR2
  113. POLY1 = POLY1 + GBERN(K+1)*TERM
  114. 30 CONTINUE
  115. C
  116. 40 POLY1 = (X-1.0)*POLY1
  117. POCH1 = EXPREL(Q)*(ALNVAR + Q*POLY1) + POLY1
  118. C
  119. IF (INCR.EQ.0) GO TO 60
  120. C
  121. C WE HAVE POCH1(B,X). BUT BP IS SMALL, SO WE USE BACKWARDS RECURSION
  122. C TO OBTAIN POCH1(BP,X).
  123. C
  124. DO 50 II=1,INCR
  125. I = INCR - II
  126. BINV = 1.0/(BP+I)
  127. POCH1 = (POCH1-BINV)/(1.0+X*BINV)
  128. 50 CONTINUE
  129. C
  130. 60 IF (BP.EQ.A) RETURN
  131. C
  132. C WE HAVE POCH1(BP,X), BUT A IS LT -0.5. WE THEREFORE USE A REFLECTION
  133. C FORMULA TO OBTAIN POCH1(A,X).
  134. C
  135. SINPXX = SIN(PI*X)/X
  136. SINPX2 = SIN(0.5*PI*X)
  137. TRIG = SINPXX*COT(PI*B) - 2.0*SINPX2*(SINPX2/X)
  138. C
  139. POCH1 = TRIG + (1.0 + X*TRIG) * POCH1
  140. RETURN
  141. C
  142. 70 POCH1 = (POCH(A,X) - 1.0) / X
  143. RETURN
  144. C
  145. END