poch.f 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. *DECK POCH
  2. FUNCTION POCH (A, X)
  3. C***BEGIN PROLOGUE POCH
  4. C***PURPOSE Evaluate a generalization of Pochhammer's symbol.
  5. C***LIBRARY SLATEC (FNLIB)
  6. C***CATEGORY C1, C7A
  7. C***TYPE SINGLE PRECISION (POCH-S, DPOCH-D)
  8. C***KEYWORDS FNLIB, POCHHAMMER, SPECIAL FUNCTIONS
  9. C***AUTHOR Fullerton, W., (LANL)
  10. C***DESCRIPTION
  11. C
  12. C Evaluate a generalization of Pochhammer's symbol
  13. C (A)-sub-X = GAMMA(A+X)/GAMMA(A). For X a non-negative integer,
  14. C POCH(A,X) is just Pochhammer's symbol. A and X are single precision.
  15. C This is a preliminary version. Error handling when POCH(A,X) is
  16. C less than half precision is probably incorrect. Grossly incorrect
  17. C arguments are not handled properly.
  18. C
  19. C***REFERENCES (NONE)
  20. C***ROUTINES CALLED ALGAMS, ALNREL, FAC, GAMMA, GAMR, R9LGMC, XERMSG
  21. C***REVISION HISTORY (YYMMDD)
  22. C 770701 DATE WRITTEN
  23. C 890531 Changed all specific intrinsics to generic. (WRB)
  24. C 890531 REVISION DATE from Version 3.2
  25. C 891214 Prologue converted to Version 4.0 format. (BAB)
  26. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  27. C 900727 Added EXTERNAL statement. (WRB)
  28. C***END PROLOGUE POCH
  29. EXTERNAL GAMMA
  30. SAVE PI
  31. DATA PI / 3.1415926535 89793238 E0 /
  32. C***FIRST EXECUTABLE STATEMENT POCH
  33. AX = A + X
  34. IF (AX.GT.0.0) GO TO 30
  35. IF (AINT(AX).NE.AX) GO TO 30
  36. C
  37. IF (A .GT. 0.0 .OR. AINT(A) .NE. A) CALL XERMSG ('SLATEC', 'POCH',
  38. + 'A+X IS NON-POSITIVE INTEGER BUT A IS NOT', 2, 2)
  39. C
  40. C WE KNOW HERE THAT BOTH A+X AND A ARE NON-POSITIVE INTEGERS.
  41. C
  42. POCH = 1.0
  43. IF (X.EQ.0.0) RETURN
  44. C
  45. N = X
  46. IF (MIN(A+X,A).LT.(-20.0)) GO TO 20
  47. C
  48. POCH = (-1.0)**N * FAC(-INT(A))/FAC(-INT(A)-N)
  49. RETURN
  50. C
  51. 20 POCH = (-1.0)**N * EXP ((A-0.5)*ALNREL(X/(A-1.0))
  52. 1 + X*LOG(-A+1.0-X) - X + R9LGMC(-A+1.) - R9LGMC(-A-X+1.) )
  53. RETURN
  54. C
  55. C HERE WE KNOW A+X IS NOT ZERO OR A NEGATIVE INTEGER.
  56. C
  57. 30 POCH = 0.0
  58. IF (A.LE.0.0 .AND. AINT(A).EQ.A) RETURN
  59. C
  60. N = ABS(X)
  61. IF (REAL(N).NE.X .OR. N.GT.20) GO TO 50
  62. C
  63. C X IS A SMALL NON-POSITIVE INTEGER, PRESUMMABLY A COMMON CASE.
  64. C
  65. POCH = 1.0
  66. IF (N.EQ.0) RETURN
  67. DO 40 I=1,N
  68. POCH = POCH * (A+I-1)
  69. 40 CONTINUE
  70. RETURN
  71. C
  72. 50 ABSAX = ABS(A+X)
  73. ABSA = ABS(A)
  74. IF (MAX(ABSAX,ABSA).GT.20.0) GO TO 60
  75. POCH = GAMMA(A+X)*GAMR(A)
  76. RETURN
  77. C
  78. 60 IF (ABS(X).GT.0.5*ABSA) GO TO 70
  79. C
  80. C HERE ABS(X) IS SMALL AND BOTH ABS(A+X) AND ABS(A) ARE LARGE. THUS,
  81. C A+X AND A MUST HAVE THE SAME SIGN. FOR NEGATIVE A, WE USE
  82. C GAMMA(A+X)/GAMMA(A) = GAMMA(-A+1)/GAMMA(-A-X+1) *
  83. C SIN(PI*A)/SIN(PI*(A+X))
  84. C
  85. B = A
  86. IF (B.LT.0.0) B = -A - X + 1.0
  87. POCH = EXP ((B-0.5)*ALNREL(X/B) + X*LOG(B+X) - X +
  88. 1 R9LGMC(B+X) - R9LGMC(B) )
  89. IF (A.LT.0.0 .AND. POCH.NE.0.0) POCH = POCH/(COS(PI*X) +
  90. 1 COT(PI*A)*SIN(PI*X))
  91. RETURN
  92. C
  93. 70 CALL ALGAMS (A+X, ALNGAX, SGNGAX)
  94. CALL ALGAMS (A, ALNGA, SGNGA)
  95. POCH = SGNGAX * SGNGA * EXP(ALNGAX-ALNGA)
  96. C
  97. RETURN
  98. END