besk.f 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. *DECK BESK
  2. SUBROUTINE BESK (X, FNU, KODE, N, Y, NZ)
  3. C***BEGIN PROLOGUE BESK
  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.
  9. C***LIBRARY SLATEC
  10. C***CATEGORY C10B3
  11. C***TYPE SINGLE PRECISION (BESK-S, DBESK-D)
  12. C***KEYWORDS K BESSEL FUNCTION, SPECIAL FUNCTIONS
  13. C***AUTHOR Amos, D. E., (SNLA)
  14. C***DESCRIPTION
  15. C
  16. C Abstract
  17. C BESK 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.0E0 and
  21. C non-negative orders FNU. If FNU .LT. NULIM, orders FNU and
  22. C FNU+1 are obtained from BESKNU 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.
  28. C
  29. C Description of Arguments
  30. C
  31. C Input
  32. C X - X .GT. 0.0E0
  33. C FNU - order of the initial K function, FNU .GE. 0.0E0
  34. C KODE - a parameter to indicate the scaling option
  35. C KODE=1 returns Y(I)= K/sub(FNU+I-1)/(X),
  36. C I=1,...,N
  37. C KODE=2 returns Y(I)=EXP(X)*K/sub(FNU+I-1)/(X),
  38. C I=1,...,N
  39. C N - number of members in the sequence, N .GE. 1
  40. C
  41. C Output
  42. C y - a vector whose first n components contain values
  43. C for the sequence
  44. C Y(I)= K/sub(FNU+I-1)/(X), I=1,...,N or
  45. C Y(I)=EXP(X)*K/sub(FNU+I-1)/(X), I=1,...,N
  46. C depending on KODE
  47. C NZ - number of components of Y set to zero due to
  48. C underflow with KODE=1,
  49. C NZ=0 , normal return, computation completed
  50. C NZ .NE. 0, first NZ components of Y set to zero
  51. C due to underflow, Y(I)=0.0E0, I=1,...,NZ
  52. C
  53. C Error Conditions
  54. C Improper input arguments - a fatal error
  55. C Overflow - a fatal error
  56. C Underflow with KODE=1 - a non-fatal error (NZ .NE. 0)
  57. C
  58. C***REFERENCES F. W. J. Olver, Tables of Bessel Functions of Moderate
  59. C or Large Orders, NPL Mathematical Tables 6, Her
  60. C Majesty's Stationery Office, London, 1962.
  61. C N. M. Temme, On the numerical evaluation of the modified
  62. C Bessel function of the third kind, Journal of
  63. C Computational Physics 19, (1975), pp. 324-337.
  64. C***ROUTINES CALLED ASYIK, BESK0, BESK0E, BESK1, BESK1E, BESKNU,
  65. C I1MACH, R1MACH, XERMSG
  66. C***REVISION HISTORY (YYMMDD)
  67. C 790201 DATE WRITTEN
  68. C 890531 Changed all specific intrinsics to generic. (WRB)
  69. C 890531 REVISION DATE from Version 3.2
  70. C 891214 Prologue converted to Version 4.0 format. (BAB)
  71. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  72. C 900326 Removed duplicate information from DESCRIPTION section.
  73. C (WRB)
  74. C 920501 Reformatted the REFERENCES section. (WRB)
  75. C***END PROLOGUE BESK
  76. C
  77. INTEGER I, J, K, KODE, MZ, N, NB, ND, NN, NUD, NULIM, NZ
  78. INTEGER I1MACH
  79. REAL CN, DNU, ELIM, ETX, FLGIK,FN, FNN, FNU,GLN,GNU,RTZ,S,S1,S2,
  80. 1 T, TM, TRX, W, X, XLIM, Y, ZN
  81. REAL BESK0, BESK1, BESK1E, BESK0E, R1MACH
  82. DIMENSION W(2), NULIM(2), Y(*)
  83. SAVE NULIM
  84. DATA NULIM(1),NULIM(2) / 35 , 70 /
  85. C***FIRST EXECUTABLE STATEMENT BESK
  86. NN = -I1MACH(12)
  87. ELIM = 2.303E0*(NN*R1MACH(5)-3.0E0)
  88. XLIM = R1MACH(1)*1.0E+3
  89. IF (KODE.LT.1 .OR. KODE.GT.2) GO TO 280
  90. IF (FNU.LT.0.0E0) GO TO 290
  91. IF (X.LE.0.0E0) GO TO 300
  92. IF (X.LT.XLIM) GO TO 320
  93. IF (N.LT.1) GO TO 310
  94. ETX = KODE - 1
  95. C
  96. C ND IS A DUMMY VARIABLE FOR N
  97. C GNU IS A DUMMY VARIABLE FOR FNU
  98. C NZ = NUMBER OF UNDERFLOWS ON KODE=1
  99. C
  100. ND = N
  101. NZ = 0
  102. NUD = INT(FNU)
  103. DNU = FNU - NUD
  104. GNU = FNU
  105. NN = MIN(2,ND)
  106. FN = FNU + N - 1
  107. FNN = FN
  108. IF (FN.LT.2.0E0) GO TO 150
  109. C
  110. C OVERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION)
  111. C FOR THE LAST ORDER, FNU+N-1.GE.NULIM
  112. C
  113. ZN = X/FN
  114. IF (ZN.EQ.0.0E0) GO TO 320
  115. RTZ = SQRT(1.0E0+ZN*ZN)
  116. GLN = LOG((1.0E0+RTZ)/ZN)
  117. T = RTZ*(1.0E0-ETX) + ETX/(ZN+RTZ)
  118. CN = -FN*(T-GLN)
  119. IF (CN.GT.ELIM) GO TO 320
  120. IF (NUD.LT.NULIM(NN)) GO TO 30
  121. IF (NN.EQ.1) GO TO 20
  122. 10 CONTINUE
  123. C
  124. C UNDERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION)
  125. C FOR THE FIRST ORDER, FNU.GE.NULIM
  126. C
  127. FN = GNU
  128. ZN = X/FN
  129. RTZ = SQRT(1.0E0+ZN*ZN)
  130. GLN = LOG((1.0E0+RTZ)/ZN)
  131. T = RTZ*(1.0E0-ETX) + ETX/(ZN+RTZ)
  132. CN = -FN*(T-GLN)
  133. 20 CONTINUE
  134. IF (CN.LT.-ELIM) GO TO 230
  135. C
  136. C ASYMPTOTIC EXPANSION FOR ORDERS FNU AND FNU+1.GE.NULIM
  137. C
  138. FLGIK = -1.0E0
  139. CALL ASYIK(X,GNU,KODE,FLGIK,RTZ,CN,NN,Y)
  140. IF (NN.EQ.1) GO TO 240
  141. TRX = 2.0E0/X
  142. TM = (GNU+GNU+2.0E0)/X
  143. GO TO 130
  144. C
  145. 30 CONTINUE
  146. IF (KODE.EQ.2) GO TO 40
  147. C
  148. C UNDERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION IN X)
  149. C FOR ORDER DNU
  150. C
  151. IF (X.GT.ELIM) GO TO 230
  152. 40 CONTINUE
  153. IF (DNU.NE.0.0E0) GO TO 80
  154. IF (KODE.EQ.2) GO TO 50
  155. S1 = BESK0(X)
  156. GO TO 60
  157. 50 S1 = BESK0E(X)
  158. 60 CONTINUE
  159. IF (NUD.EQ.0 .AND. ND.EQ.1) GO TO 120
  160. IF (KODE.EQ.2) GO TO 70
  161. S2 = BESK1(X)
  162. GO TO 90
  163. 70 S2 = BESK1E(X)
  164. GO TO 90
  165. 80 CONTINUE
  166. NB = 2
  167. IF (NUD.EQ.0 .AND. ND.EQ.1) NB = 1
  168. CALL BESKNU(X, DNU, KODE, NB, W, NZ)
  169. S1 = W(1)
  170. IF (NB.EQ.1) GO TO 120
  171. S2 = W(2)
  172. 90 CONTINUE
  173. TRX = 2.0E0/X
  174. TM = (DNU+DNU+2.0E0)/X
  175. C FORWARD RECUR FROM DNU TO FNU+1 TO GET Y(1) AND Y(2)
  176. IF (ND.EQ.1) NUD = NUD - 1
  177. IF (NUD.GT.0) GO TO 100
  178. IF (ND.GT.1) GO TO 120
  179. S1 = S2
  180. GO TO 120
  181. 100 CONTINUE
  182. DO 110 I=1,NUD
  183. S = S2
  184. S2 = TM*S2 + S1
  185. S1 = S
  186. TM = TM + TRX
  187. 110 CONTINUE
  188. IF (ND.EQ.1) S1 = S2
  189. 120 CONTINUE
  190. Y(1) = S1
  191. IF (ND.EQ.1) GO TO 240
  192. Y(2) = S2
  193. 130 CONTINUE
  194. IF (ND.EQ.2) GO TO 240
  195. C FORWARD RECUR FROM FNU+2 TO FNU+N-1
  196. DO 140 I=3,ND
  197. Y(I) = TM*Y(I-1) + Y(I-2)
  198. TM = TM + TRX
  199. 140 CONTINUE
  200. GO TO 240
  201. C
  202. 150 CONTINUE
  203. C UNDERFLOW TEST FOR KODE=1
  204. IF (KODE.EQ.2) GO TO 160
  205. IF (X.GT.ELIM) GO TO 230
  206. 160 CONTINUE
  207. C OVERFLOW TEST
  208. IF (FN.LE.1.0E0) GO TO 170
  209. IF (-FN*(LOG(X)-0.693E0).GT.ELIM) GO TO 320
  210. 170 CONTINUE
  211. IF (DNU.EQ.0.0E0) GO TO 180
  212. CALL BESKNU(X, FNU, KODE, ND, Y, MZ)
  213. GO TO 240
  214. 180 CONTINUE
  215. J = NUD
  216. IF (J.EQ.1) GO TO 210
  217. J = J + 1
  218. IF (KODE.EQ.2) GO TO 190
  219. Y(J) = BESK0(X)
  220. GO TO 200
  221. 190 Y(J) = BESK0E(X)
  222. 200 IF (ND.EQ.1) GO TO 240
  223. J = J + 1
  224. 210 IF (KODE.EQ.2) GO TO 220
  225. Y(J) = BESK1(X)
  226. GO TO 240
  227. 220 Y(J) = BESK1E(X)
  228. GO TO 240
  229. C
  230. C UPDATE PARAMETERS ON UNDERFLOW
  231. C
  232. 230 CONTINUE
  233. NUD = NUD + 1
  234. ND = ND - 1
  235. IF (ND.EQ.0) GO TO 240
  236. NN = MIN(2,ND)
  237. GNU = GNU + 1.0E0
  238. IF (FNN.LT.2.0E0) GO TO 230
  239. IF (NUD.LT.NULIM(NN)) GO TO 230
  240. GO TO 10
  241. 240 CONTINUE
  242. NZ = N - ND
  243. IF (NZ.EQ.0) RETURN
  244. IF (ND.EQ.0) GO TO 260
  245. DO 250 I=1,ND
  246. J = N - I + 1
  247. K = ND - I + 1
  248. Y(J) = Y(K)
  249. 250 CONTINUE
  250. 260 CONTINUE
  251. DO 270 I=1,NZ
  252. Y(I) = 0.0E0
  253. 270 CONTINUE
  254. RETURN
  255. C
  256. C
  257. C
  258. 280 CONTINUE
  259. CALL XERMSG ('SLATEC', 'BESK', 'SCALING OPTION, KODE, NOT 1 OR 2'
  260. + , 2, 1)
  261. RETURN
  262. 290 CONTINUE
  263. CALL XERMSG ('SLATEC', 'BESK', 'ORDER, FNU, LESS THAN ZERO', 2,
  264. + 1)
  265. RETURN
  266. 300 CONTINUE
  267. CALL XERMSG ('SLATEC', 'BESK', 'X LESS THAN OR EQUAL TO ZERO', 2,
  268. + 1)
  269. RETURN
  270. 310 CONTINUE
  271. CALL XERMSG ('SLATEC', 'BESK', 'N LESS THAN ONE', 2, 1)
  272. RETURN
  273. 320 CONTINUE
  274. CALL XERMSG ('SLATEC', 'BESK',
  275. + 'OVERFLOW, FNU OR N TOO LARGE OR X TOO SMALL', 6, 1)
  276. RETURN
  277. END