4004
|
1 subroutine xgammainc (a, x, result) |
|
2 |
|
3 c -- jwe, based on DGAMIT. |
|
4 c |
|
5 c -- Do a better job than dgami for large values of x. |
|
6 |
|
7 double precision a, x, result |
|
8 intrinsic exp, log, sqrt, sign, aint |
4079
|
9 external dgami, dlngam, d9lgit, d9lgic, d9gmit |
|
10 |
|
11 C external dgamr |
|
12 C DOUBLE PRECISION DGAMR |
4004
|
13 |
|
14 DOUBLE PRECISION AEPS, AINTA, ALGAP1, ALNEPS, ALNG, ALX, |
4079
|
15 $ BOT, H, SGA, SGNGAM, SQEPS, T, D1MACH, D9GMIT, |
4004
|
16 $ D9LGIC, D9LGIT, DLNGAM, DGAMI |
|
17 |
|
18 LOGICAL FIRST |
|
19 |
|
20 SAVE ALNEPS, SQEPS, BOT, FIRST |
|
21 |
|
22 DATA FIRST /.TRUE./ |
|
23 |
|
24 if (x .eq. 0.0d0) then |
|
25 |
|
26 if (a .eq. 0.0d0) then |
|
27 result = 1.0d0 |
|
28 else |
|
29 result = 0.0d0 |
|
30 endif |
|
31 |
|
32 else |
|
33 |
|
34 IF (FIRST) THEN |
|
35 ALNEPS = -LOG (D1MACH(3)) |
|
36 SQEPS = SQRT(D1MACH(4)) |
|
37 BOT = LOG (D1MACH(1)) |
|
38 ENDIF |
|
39 FIRST = .FALSE. |
|
40 C |
|
41 IF (X .LT. 0.D0) CALL XERMSG ('SLATEC', 'XGMAINC', 'X IS NEGATIVE' |
|
42 + , 2, 2) |
|
43 C |
|
44 IF (X.NE.0.D0) ALX = LOG (X) |
|
45 SGA = 1.0D0 |
|
46 IF (A.NE.0.D0) SGA = SIGN (1.0D0, A) |
|
47 AINTA = AINT (A + 0.5D0*SGA) |
|
48 AEPS = A - AINTA |
|
49 C |
|
50 C IF (X.GT.0.D0) GO TO 20 |
|
51 C DGAMIT = 0.0D0 |
|
52 C IF (AINTA.GT.0.D0 .OR. AEPS.NE.0.D0) DGAMIT = DGAMR(A+1.0D0) |
|
53 C RETURN |
|
54 C |
|
55 20 IF (X.GT.1.D0) GO TO 30 |
|
56 IF (A.GE.(-0.5D0) .OR. AEPS.NE.0.D0) CALL DLGAMS (A+1.0D0, ALGAP1, |
|
57 1 SGNGAM) |
|
58 C DGAMIT = D9GMIT (A, X, ALGAP1, SGNGAM, ALX) |
|
59 result = exp (a*alx + log (D9GMIT (A, X, ALGAP1, SGNGAM, ALX))) |
|
60 RETURN |
|
61 C |
|
62 30 IF (A.LT.X) GO TO 40 |
|
63 T = D9LGIT (A, X, DLNGAM(A+1.0D0)) |
|
64 IF (T.LT.BOT) CALL XERCLR |
|
65 C DGAMIT = EXP (T) |
|
66 result = EXP (a*alx + T) |
|
67 RETURN |
|
68 C |
|
69 40 ALNG = D9LGIC (A, X, ALX) |
|
70 C |
|
71 C EVALUATE DGAMIT IN TERMS OF LOG (DGAMIC (A, X)) |
|
72 C |
|
73 H = 1.0D0 |
|
74 IF (AEPS.EQ.0.D0 .AND. AINTA.LE.0.D0) GO TO 50 |
|
75 C |
|
76 CALL DLGAMS (A+1.0D0, ALGAP1, SGNGAM) |
|
77 T = LOG (ABS(A)) + ALNG - ALGAP1 |
|
78 IF (T.GT.ALNEPS) GO TO 60 |
|
79 C |
|
80 IF (T.GT.(-ALNEPS)) H = 1.0D0 - SGA * SGNGAM * EXP(T) |
|
81 IF (ABS(H).GT.SQEPS) GO TO 50 |
|
82 C |
|
83 CALL XERCLR |
|
84 CALL XERMSG ('SLATEC', 'XGMAINC', 'RESULT LT HALF PRECISION', 1, |
|
85 + 1) |
|
86 C |
|
87 C 50 T = -A*ALX + LOG(ABS(H)) |
|
88 C IF (T.LT.BOT) CALL XERCLR |
|
89 C DGAMIT = SIGN (EXP(T), H) |
|
90 50 result = H |
|
91 RETURN |
|
92 C |
|
93 C 60 T = T - A*ALX |
|
94 60 IF (T.LT.BOT) CALL XERCLR |
|
95 result = -SGA * SGNGAM * EXP(T) |
|
96 RETURN |
|
97 |
|
98 endif |
|
99 return |
|
100 end |