2
SUBROUTINE DBESK (X, FNU, KODE, N, Y, NZ)
3
C***BEGIN PROLOGUE DBESK
4
C***PURPOSE Implement forward recursion on the three term recursion
5
C relation for a sequence of non-negative order Bessel
6
C functions K/SUB(FNU+I-1)/(X), or scaled Bessel functions
7
C EXP(X)*K/SUB(FNU+I-1)/(X), I=1,...,N for real, positive
8
C X and non-negative orders FNU.
11
C***TYPE DOUBLE PRECISION (BESK-S, DBESK-D)
12
C***KEYWORDS K BESSEL FUNCTION, SPECIAL FUNCTIONS
13
C***AUTHOR Amos, D. E., (SNLA)
16
C Abstract **** a double precision routine ****
17
C DBESK implements forward recursion on the three term
18
C recursion relation for a sequence of non-negative order Bessel
19
C functions K/sub(FNU+I-1)/(X), or scaled Bessel functions
20
C EXP(X)*K/sub(FNU+I-1)/(X), I=1,..,N for real X .GT. 0.0D0 and
21
C non-negative orders FNU. If FNU .LT. NULIM, orders FNU and
22
C FNU+1 are obtained from DBSKNU to start the recursion. If
23
C FNU .GE. NULIM, the uniform asymptotic expansion is used for
24
C orders FNU and FNU+1 to start the recursion. NULIM is 35 or
25
C 70 depending on whether N=1 or N .GE. 2. Under and overflow
26
C tests are made on the leading term of the asymptotic expansion
27
C before any extensive computation is done.
29
C The maximum number of significant digits obtainable
30
C is the smaller of 14 and the number of digits carried in
31
C double precision arithmetic.
33
C Description of Arguments
35
C Input X,FNU are double precision
37
C FNU - order of the initial K function, FNU .GE. 0.0D0
38
C KODE - a parameter to indicate the scaling option
39
C KODE=1 returns Y(I)= K/sub(FNU+I-1)/(X),
41
C KODE=2 returns Y(I)=EXP(X)*K/sub(FNU+I-1)/(X),
43
C N - number of members in the sequence, N .GE. 1
45
C Output Y is double precision
46
C Y - a vector whose first N components contain values
48
C Y(I)= k/sub(FNU+I-1)/(X), I=1,...,N or
49
C Y(I)=EXP(X)*K/sub(FNU+I-1)/(X), I=1,...,N
51
C NZ - number of components of Y set to zero due to
52
C underflow with KODE=1,
53
C NZ=0 , normal return, computation completed
54
C NZ .NE. 0, first NZ components of Y set to zero
55
C due to underflow, Y(I)=0.0D0, I=1,...,NZ
58
C Improper input arguments - a fatal error
59
C Overflow - a fatal error
60
C Underflow with KODE=1 - a non-fatal error (NZ .NE. 0)
62
C***REFERENCES F. W. J. Olver, Tables of Bessel Functions of Moderate
63
C or Large Orders, NPL Mathematical Tables 6, Her
64
C Majesty's Stationery Office, London, 1962.
65
C N. M. Temme, On the numerical evaluation of the modified
66
C Bessel function of the third kind, Journal of
67
C Computational Physics 19, (1975), pp. 324-337.
68
C***ROUTINES CALLED D1MACH, DASYIK, DBESK0, DBESK1, DBSK0E, DBSK1E,
69
C DBSKNU, I1MACH, XERMSG
70
C***REVISION HISTORY (YYMMDD)
72
C 890531 Changed all specific intrinsics to generic. (WRB)
73
C 890911 Removed unnecessary intrinsics. (WRB)
74
C 890911 REVISION DATE from Version 3.2
75
C 891214 Prologue converted to Version 4.0 format. (BAB)
76
C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
77
C 920501 Reformatted the REFERENCES section. (WRB)
78
C***END PROLOGUE DBESK
80
INTEGER I, J, K, KODE, MZ, N, NB, ND, NN, NUD, NULIM, NZ
82
DOUBLE PRECISION CN,DNU,ELIM,ETX,FLGIK,FN,FNN,FNU,GLN,GNU,RTZ,
83
1 S, S1, S2, T, TM, TRX, W, X, XLIM, Y, ZN
84
DOUBLE PRECISION DBESK0, DBESK1, DBSK1E, DBSK0E, D1MACH
85
DIMENSION W(2), NULIM(2), Y(*)
87
DATA NULIM(1),NULIM(2) / 35 , 70 /
88
C***FIRST EXECUTABLE STATEMENT DBESK
90
ELIM = 2.303D0*(NN*D1MACH(5)-3.0D0)
91
XLIM = D1MACH(1)*1.0D+3
92
IF (KODE.LT.1 .OR. KODE.GT.2) GO TO 280
93
IF (FNU.LT.0.0D0) GO TO 290
94
IF (X.LE.0.0D0) GO TO 300
95
IF (X.LT.XLIM) GO TO 320
99
C ND IS A DUMMY VARIABLE FOR N
100
C GNU IS A DUMMY VARIABLE FOR FNU
101
C NZ = NUMBER OF UNDERFLOWS ON KODE=1
111
IF (FN.LT.2.0D0) GO TO 150
113
C OVERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION)
114
C FOR THE LAST ORDER, FNU+N-1.GE.NULIM
117
IF (ZN.EQ.0.0D0) GO TO 320
118
RTZ = SQRT(1.0D0+ZN*ZN)
119
GLN = LOG((1.0D0+RTZ)/ZN)
120
T = RTZ*(1.0D0-ETX) + ETX/(ZN+RTZ)
122
IF (CN.GT.ELIM) GO TO 320
123
IF (NUD.LT.NULIM(NN)) GO TO 30
124
IF (NN.EQ.1) GO TO 20
127
C UNDERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION)
128
C FOR THE FIRST ORDER, FNU.GE.NULIM
132
RTZ = SQRT(1.0D0+ZN*ZN)
133
GLN = LOG((1.0D0+RTZ)/ZN)
134
T = RTZ*(1.0D0-ETX) + ETX/(ZN+RTZ)
137
IF (CN.LT.-ELIM) GO TO 230
139
C ASYMPTOTIC EXPANSION FOR ORDERS FNU AND FNU+1.GE.NULIM
142
CALL DASYIK(X,GNU,KODE,FLGIK,RTZ,CN,NN,Y)
143
IF (NN.EQ.1) GO TO 240
145
TM = (GNU+GNU+2.0D0)/X
149
IF (KODE.EQ.2) GO TO 40
151
C UNDERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION IN X)
154
IF (X.GT.ELIM) GO TO 230
156
IF (DNU.NE.0.0D0) GO TO 80
157
IF (KODE.EQ.2) GO TO 50
162
IF (NUD.EQ.0 .AND. ND.EQ.1) GO TO 120
163
IF (KODE.EQ.2) GO TO 70
170
IF (NUD.EQ.0 .AND. ND.EQ.1) NB = 1
171
CALL DBSKNU(X, DNU, KODE, NB, W, NZ)
173
IF (NB.EQ.1) GO TO 120
177
TM = (DNU+DNU+2.0D0)/X
178
C FORWARD RECUR FROM DNU TO FNU+1 TO GET Y(1) AND Y(2)
179
IF (ND.EQ.1) NUD = NUD - 1
180
IF (NUD.GT.0) GO TO 100
181
IF (ND.GT.1) GO TO 120
194
IF (ND.EQ.1) GO TO 240
197
IF (ND.EQ.2) GO TO 240
198
C FORWARD RECUR FROM FNU+2 TO FNU+N-1
200
Y(I) = TM*Y(I-1) + Y(I-2)
206
C UNDERFLOW TEST FOR KODE=1
207
IF (KODE.EQ.2) GO TO 160
208
IF (X.GT.ELIM) GO TO 230
211
IF (FN.LE.1.0D0) GO TO 170
212
IF (-FN*(LOG(X)-0.693D0).GT.ELIM) GO TO 320
214
IF (DNU.EQ.0.0D0) GO TO 180
215
CALL DBSKNU(X, FNU, KODE, ND, Y, MZ)
219
IF (J.EQ.1) GO TO 210
221
IF (KODE.EQ.2) GO TO 190
225
200 IF (ND.EQ.1) GO TO 240
227
210 IF (KODE.EQ.2) GO TO 220
233
C UPDATE PARAMETERS ON UNDERFLOW
238
IF (ND.EQ.0) GO TO 240
241
IF (FNN.LT.2.0D0) GO TO 230
242
IF (NUD.LT.NULIM(NN)) GO TO 230
247
IF (ND.EQ.0) GO TO 260
262
CALL XERMSG ('SLATEC', 'DBESK',
263
+ 'SCALING OPTION, KODE, NOT 1 OR 2', 2, 1)
266
CALL XERMSG ('SLATEC', 'DBESK', 'ORDER, FNU, LESS THAN ZERO', 2,
270
CALL XERMSG ('SLATEC', 'DBESK', 'X LESS THAN OR EQUAL TO ZERO',
274
CALL XERMSG ('SLATEC', 'DBESK', 'N LESS THAN ONE', 2, 1)
277
CALL XERMSG ('SLATEC', 'DBESK',
278
+ 'OVERFLOW, FNU OR N TOO LARGE OR X TOO SMALL', 6, 1)