2
SUBROUTINE DBSKNU (X, FNU, KODE, N, Y, NZ)
3
C***BEGIN PROLOGUE DBSKNU
5
C***PURPOSE Subsidiary to DBESK
7
C***TYPE DOUBLE PRECISION (BESKNU-S, DBSKNU-D)
8
C***AUTHOR Amos, D. E., (SNLA)
11
C Abstract **** A DOUBLE PRECISION routine ****
12
C DBSKNU computes N member sequences of K Bessel functions
13
C K/SUB(FNU+I-1)/(X), I=1,N for non-negative orders FNU and
14
C positive X. Equations of the references are implemented on
15
C small orders DNU for K/SUB(DNU)/(X) and K/SUB(DNU+1)/(X).
16
C Forward recursion with the three term recursion relation
17
C generates higher orders FNU+I-1, I=1,...,N. The parameter
18
C KODE permits K/SUB(FNU+I-1)/(X) values or scaled values
19
C EXP(X)*K/SUB(FNU+I-1)/(X), I=1,N to be returned.
21
C To start the recursion FNU is normalized to the interval
22
C -0.5.LE.DNU.LT.0.5. A special form of the power series is
23
C implemented on 0.LT.X.LE.X1 while the Miller algorithm for the
24
C K Bessel function in terms of the confluent hypergeometric
25
C function U(FNU+0.5,2*FNU+1,X) is implemented on X1.LT.X.LE.X2.
26
C For X.GT.X2, the asymptotic expansion for large X is used.
27
C When FNU is a half odd integer, a special formula for
28
C DNU=-0.5 and DNU+1.0=0.5 is used to start the recursion.
30
C The maximum number of significant digits obtainable
31
C is the smaller of 14 and the number of digits carried in
32
C DOUBLE PRECISION arithmetic.
34
C DBSKNU assumes that a significant digit SINH function is
37
C Description of Arguments
39
C INPUT X,FNU are DOUBLE PRECISION
41
C FNU - Order of initial K function, FNU.GE.0.0D0
42
C N - Number of members of the sequence, N.GE.1
43
C KODE - A parameter to indicate the scaling option
45
C Y(I)= K/SUB(FNU+I-1)/(X)
48
C Y(I)=EXP(X)*K/SUB(FNU+I-1)/(X)
51
C OUTPUT Y is DOUBLE PRECISION
52
C Y - A vector whose first N components contain values
54
C Y(I)= K/SUB(FNU+I-1)/(X), I=1,...,N or
55
C Y(I)=EXP(X)*K/SUB(FNU+I-1)/(X), I=1,...,N
57
C NZ - Number of components set to zero due to
59
C NZ= 0 , normal return
60
C NZ.NE.0 , first NZ components of Y set to zero
61
C due to underflow, Y(I)=0.0D0,I=1,...,NZ
64
C Improper input arguments - a fatal error
65
C Overflow - a fatal error
66
C Underflow with KODE=1 - a non-fatal error (NZ.NE.0)
69
C***REFERENCES N. M. Temme, On the numerical evaluation of the modified
70
C Bessel function of the third kind, Journal of
71
C Computational Physics 19, (1975), pp. 324-337.
72
C***ROUTINES CALLED D1MACH, DGAMMA, I1MACH, XERMSG
73
C***REVISION HISTORY (YYMMDD)
75
C 890531 Changed all specific intrinsics to generic. (WRB)
76
C 890911 Removed unnecessary intrinsics. (WRB)
77
C 891214 Prologue converted to Version 4.0 format. (BAB)
78
C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
79
C 900326 Removed duplicate information from DESCRIPTION section.
81
C 900328 Added TYPE section. (WRB)
82
C 900727 Added EXTERNAL statement. (WRB)
83
C 910408 Updated the AUTHOR and REFERENCES sections. (WRB)
84
C 920501 Reformatted the REFERENCES section. (WRB)
85
C***END PROLOGUE DBSKNU
87
INTEGER I, IFLAG, INU, J, K, KK, KODE, KODED, N, NN, NZ
89
DOUBLE PRECISION A,AK,A1,A2,B,BK,CC,CK,COEF,CX,DK,DNU,DNU2,ELIM,
90
1 ETEST, EX, F, FC, FHS, FK, FKS, FLRX, FMU, FNU, G1, G2, P, PI,
91
2 PT, P1, P2, Q, RTHPI, RX, S, SMU, SQK, ST, S1, S2, TM, TOL, T1,
93
DIMENSION A(160), B(160), Y(*), CC(8)
94
DOUBLE PRECISION DGAMMA, D1MACH
96
SAVE X1, X2, PI, RTHPI, CC
97
DATA X1, X2 / 2.0D0, 17.0D0 /
98
DATA PI,RTHPI / 3.14159265358979D+00, 1.25331413731550D+00/
99
DATA CC(1), CC(2), CC(3), CC(4), CC(5), CC(6), CC(7), CC(8)
100
1 / 5.77215664901533D-01,-4.20026350340952D-02,
101
2-4.21977345555443D-02, 7.21894324666300D-03,-2.15241674114900D-04,
102
3-2.01348547807000D-05, 1.13302723200000D-06, 6.11609500000000D-09/
103
C***FIRST EXECUTABLE STATEMENT DBSKNU
105
ELIM = 2.303D0*(KK*D1MACH(5)-3.0D0)
107
TOL = MAX(AK,1.0D-15)
108
IF (X.LE.0.0D0) GO TO 350
109
IF (FNU.LT.0.0D0) GO TO 360
110
IF (KODE.LT.1 .OR. KODE.GT.2) GO TO 370
111
IF (N.LT.1) GO TO 380
118
IF (ABS(DNU).EQ.0.5D0) GO TO 120
120
IF (ABS(DNU).LT.TOL) GO TO 10
123
IF (X.GT.X1) GO TO 120
129
T1 = 1.0D0/DGAMMA(A1)
130
T2 = 1.0D0/DGAMMA(A2)
131
IF (ABS(DNU).GT.0.1D0) GO TO 40
132
C SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU)
139
IF (ABS(TM).LT.TOL) GO TO 30
144
G1 = (T1-T2)/(DNU+DNU)
151
IF (DNU.EQ.0.0D0) GO TO 60
154
IF (FMU.NE.0.0D0) SMU = SINH(FMU)/FMU
156
F = FC*(G1*COSH(FMU)+G2*FLRX*SMU)
165
IF (INU.GT.0 .OR. N.GT.1) GO TO 90
166
IF (X.LT.TOL) GO TO 80
169
F = (AK*F+P+Q)/(BK-DNU2)
175
BK = BK + AK + AK + 1.0D0
177
S = ABS(T1)/(1.0D0+ABS(S1))
178
IF (S.GT.TOL) GO TO 70
181
IF (KODED.EQ.1) RETURN
185
IF (X.LT.TOL) GO TO 110
188
F = (AK*F+P+Q)/(BK-DNU2)
196
BK = BK + AK + AK + 1.0D0
198
S = ABS(T1)/(1.0D0+ABS(S1)) + ABS(T2)/(1.0D0+ABS(S2))
199
IF (S.GT.TOL) GO TO 100
202
IF (KODED.EQ.1) GO TO 170
209
IF (KODED.EQ.2) GO TO 130
210
IF (X.GT.ELIM) GO TO 330
213
IF (ABS(DNU).EQ.0.5D0) GO TO 340
214
IF (X.GT.X2) GO TO 280
216
C MILLER ALGORITHM FOR X1.LT.X.LE.X2
218
ETEST = COS(PI*DNU)/(PI*X*TOL)
229
AK = (FHS-DNU2)/(FKS+FK)
237
FKS = FKS + FK + FK + 1.0D0
239
IF (ETEST.GT.FK*P1) GO TO 140
246
P2 = (B(KK)*P2-P1)/A(KK)
252
IF (INU.GT.0 .OR. N.GT.1) GO TO 160
255
S2 = S1*(X+DNU+0.5D0-P1/P2)/X
257
C FORWARD RECURSION ON THE THREE TERM RECURSION RELATION
260
CK = (DNU+DNU+2.0D0)/X
261
IF (N.EQ.1) INU = INU - 1
262
IF (INU.GT.0) GO TO 180
263
IF (N.GT.1) GO TO 200
275
IF (IFLAG.EQ.1) GO TO 220
281
Y(I) = CK*Y(I-1) + Y(I-2)
290
IF (S.LT.-ELIM) GO TO 230
298
IF (S.LT.-ELIM) GO TO 240
304
IF (NZ.LT.2) GO TO 260
314
IF (S.LT.-ELIM) GO TO 250
325
Y(KK) = EXP(-X+LOG(S2))
329
Y(I) = CK*Y(I-1) + Y(I-2)
334
C ASYMPTOTIC EXPANSION FOR LARGE X, X.GT.X2
336
C IFLAG=0 MEANS NO UNDERFLOW OCCURRED
337
C IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH
338
C KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD
342
IF (INU.EQ.0 .AND. N.EQ.1) NN = 1
345
IF (ABS(DNU2).LT.TOL) GO TO 290
363
IF (ABS(CK).LT.TOL) GO TO 310
366
FMU = FMU + 8.0D0*DNU + 4.0D0
368
IF (NN.GT.1) GO TO 170
376
C FNU=HALF ODD INTEGER CASE
384
350 CALL XERMSG ('SLATEC', 'DBSKNU', 'X NOT GREATER THAN ZERO', 2, 1)
386
360 CALL XERMSG ('SLATEC', 'DBSKNU', 'FNU NOT ZERO OR POSITIVE', 2,
389
370 CALL XERMSG ('SLATEC', 'DBSKNU', 'KODE NOT 1 OR 2', 2, 1)
391
380 CALL XERMSG ('SLATEC', 'DBSKNU', 'N NOT GREATER THAN 0', 2, 1)