dbesy.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* dbesy.f -- translated by f2c (version 20100827).
  2. This file no longer depends on f2c.
  3. */
  4. #include "slatec-internal.hpp"
  5. /* Table of constant values */
  6. static integer const c__15 = 15;
  7. static integer const c__5 = 5;
  8. static integer const c__1 = 1;
  9. static integer const c__2 = 2;
  10. static integer const c__6 = 6;
  11. int dbesy_(double const *x, double const *fnu, integer const *n, double *y)
  12. {
  13. /* Initialized data */
  14. static integer nulim[2] = { 70,100 };
  15. /* System generated locals */
  16. integer i__1;
  17. /* Local variables. Some initialized to avoid -Wmaybe-uninitialized */
  18. integer i__, j;
  19. double s, w[2], s1, s2 = 0.;
  20. integer nb;
  21. double cn;
  22. integer nd;
  23. double fn;
  24. integer nn;
  25. double tm = 0., wk[7], w2n, ran;
  26. integer nud;
  27. double dnu, azn, trx = 0., xxn, elim;
  28. integer iflw;
  29. double xlim, flgjy;
  30. /* ***BEGIN PROLOGUE DBESY */
  31. /* ***PURPOSE Implement forward recursion on the three term recursion */
  32. /* relation for a sequence of non-negative order Bessel */
  33. /* functions Y/SUB(FNU+I-1)/(X), I=1,...,N for real, positive */
  34. /* X and non-negative orders FNU. */
  35. /* ***LIBRARY SLATEC */
  36. /* ***CATEGORY C10A3 */
  37. /* ***TYPE DOUBLE PRECISION (BESY-S, DBESY-D) */
  38. /* ***KEYWORDS SPECIAL FUNCTIONS, Y BESSEL FUNCTION */
  39. /* ***AUTHOR Amos, D. E., (SNLA) */
  40. /* ***DESCRIPTION */
  41. /* Abstract **** a double precision routine **** */
  42. /* DBESY implements forward recursion on the three term */
  43. /* recursion relation for a sequence of non-negative order Bessel */
  44. /* functions Y/sub(FNU+I-1)/(X), I=1,N for real X .GT. 0.0D0 and */
  45. /* non-negative orders FNU. If FNU .LT. NULIM, orders FNU and */
  46. /* FNU+1 are obtained from DBSYNU which computes by a power */
  47. /* series for X .LE. 2, the K Bessel function of an imaginary */
  48. /* argument for 2 .LT. X .LE. 20 and the asymptotic expansion for */
  49. /* X .GT. 20. */
  50. /* If FNU .GE. NULIM, the uniform asymptotic expansion is coded */
  51. /* in DASYJY for orders FNU and FNU+1 to start the recursion. */
  52. /* NULIM is 70 or 100 depending on whether N=1 or N .GE. 2. An */
  53. /* overflow test is made on the leading term of the asymptotic */
  54. /* expansion before any extensive computation is done. */
  55. /* The maximum number of significant digits obtainable */
  56. /* is the smaller of 14 and the number of digits carried in */
  57. /* double precision arithmetic. */
  58. /* Description of Arguments */
  59. /* Input */
  60. /* X - X .GT. 0.0D0 */
  61. /* FNU - order of the initial Y function, FNU .GE. 0.0D0 */
  62. /* N - number of members in the sequence, N .GE. 1 */
  63. /* Output */
  64. /* Y - a vector whose first N components contain values */
  65. /* for the sequence Y(I)=Y/sub(FNU+I-1)/(X), I=1,N. */
  66. /* Error Conditions */
  67. /* Improper input arguments - a fatal error */
  68. /* Overflow - a fatal error */
  69. /* ***REFERENCES F. W. J. Olver, Tables of Bessel Functions of Moderate */
  70. /* or Large Orders, NPL Mathematical Tables 6, Her */
  71. /* Majesty's Stationery Office, London, 1962. */
  72. /* N. M. Temme, On the numerical evaluation of the modified */
  73. /* Bessel function of the third kind, Journal of */
  74. /* Computational Physics 19, (1975), pp. 324-337. */
  75. /* N. M. Temme, On the numerical evaluation of the ordinary */
  76. /* Bessel function of the second kind, Journal of */
  77. /* Computational Physics 21, (1976), pp. 343-350. */
  78. /* ***ROUTINES CALLED D1MACH, DASYJY, DBESY0, DBESY1, DBSYNU, DYAIRY, */
  79. /* I1MACH, XERMSG */
  80. /* ***REVISION HISTORY (YYMMDD) */
  81. /* 800501 DATE WRITTEN */
  82. /* 890531 Changed all specific intrinsics to generic. (WRB) */
  83. /* 890911 Removed unnecessary intrinsics. (WRB) */
  84. /* 890911 REVISION DATE from Version 3.2 */
  85. /* 891214 Prologue converted to Version 4.0 format. (BAB) */
  86. /* 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) */
  87. /* 920501 Reformatted the REFERENCES section. (WRB) */
  88. /* ***END PROLOGUE DBESY */
  89. /* Parameter adjustments */
  90. --y;
  91. /* Function Body */
  92. /* ***FIRST EXECUTABLE STATEMENT DBESY */
  93. nn = -i1mach_(15);
  94. elim = (nn * d1mach_(5) - 3.) * 2.303;
  95. xlim = d1mach_(1) * 1e3;
  96. if (*fnu < 0.) {
  97. goto L140;
  98. }
  99. if (*x <= 0.) {
  100. goto L150;
  101. }
  102. if (*x < xlim) {
  103. goto L170;
  104. }
  105. if (*n < 1) {
  106. goto L160;
  107. }
  108. /* ND IS A DUMMY VARIABLE FOR N */
  109. nd = *n;
  110. nud = (integer) (*fnu);
  111. dnu = *fnu - nud;
  112. nn = min(2,nd);
  113. fn = *fnu + *n - 1;
  114. if (fn < 2.) {
  115. goto L100;
  116. }
  117. /* OVERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION) */
  118. /* FOR THE LAST ORDER, FNU+N-1.GE.NULIM */
  119. xxn = *x / fn;
  120. w2n = 1. - xxn * xxn;
  121. if (w2n <= 0.) {
  122. goto L10;
  123. }
  124. ran = sqrt(w2n);
  125. azn = log((ran + 1.) / xxn) - ran;
  126. cn = fn * azn;
  127. if (cn > elim) {
  128. goto L170;
  129. }
  130. L10:
  131. if (nud < nulim[nn - 1]) {
  132. goto L20;
  133. }
  134. /* ASYMPTOTIC EXPANSION FOR ORDERS FNU AND FNU+1.GE.NULIM */
  135. flgjy = -1.;
  136. dasyjy_(dyairy_, x, fnu, &flgjy, &nn, &y[1], wk, &iflw);
  137. if (iflw != 0) {
  138. goto L170;
  139. }
  140. if (nn == 1) {
  141. return 0;
  142. }
  143. trx = 2. / *x;
  144. tm = (*fnu + *fnu + 2.) / *x;
  145. goto L80;
  146. L20:
  147. if (dnu != 0.) {
  148. goto L30;
  149. }
  150. s1 = dbesy0_(x);
  151. if (nud == 0 && nd == 1) {
  152. goto L70;
  153. }
  154. s2 = dbesy1_(x);
  155. goto L40;
  156. L30:
  157. nb = 2;
  158. if (nud == 0 && nd == 1) {
  159. nb = 1;
  160. }
  161. dbsynu_(x, &dnu, &nb, w);
  162. s1 = w[0];
  163. if (nb == 1) {
  164. goto L70;
  165. }
  166. s2 = w[1];
  167. L40:
  168. trx = 2. / *x;
  169. tm = (dnu + dnu + 2.) / *x;
  170. /* FORWARD RECUR FROM DNU TO FNU+1 TO GET Y(1) AND Y(2) */
  171. if (nd == 1) {
  172. --nud;
  173. }
  174. if (nud > 0) {
  175. goto L50;
  176. }
  177. if (nd > 1) {
  178. goto L70;
  179. }
  180. s1 = s2;
  181. goto L70;
  182. L50:
  183. i__1 = nud;
  184. for (i__ = 1; i__ <= i__1; ++i__) {
  185. s = s2;
  186. s2 = tm * s2 - s1;
  187. s1 = s;
  188. tm += trx;
  189. /* L60: */
  190. }
  191. if (nd == 1) {
  192. s1 = s2;
  193. }
  194. L70:
  195. y[1] = s1;
  196. if (nd == 1) {
  197. return 0;
  198. }
  199. y[2] = s2;
  200. L80:
  201. if (nd == 2) {
  202. return 0;
  203. }
  204. /* FORWARD RECUR FROM FNU+2 TO FNU+N-1 */
  205. i__1 = nd;
  206. for (i__ = 3; i__ <= i__1; ++i__) {
  207. y[i__] = tm * y[i__ - 1] - y[i__ - 2];
  208. tm += trx;
  209. /* L90: */
  210. }
  211. return 0;
  212. L100:
  213. /* OVERFLOW TEST */
  214. if (fn <= 1.) {
  215. goto L110;
  216. }
  217. if (-fn * (log(*x) - .693) > elim) {
  218. goto L170;
  219. }
  220. L110:
  221. if (dnu == 0.) {
  222. goto L120;
  223. }
  224. dbsynu_(x, fnu, &nd, &y[1]);
  225. return 0;
  226. L120:
  227. j = nud;
  228. if (j == 1) {
  229. goto L130;
  230. }
  231. ++j;
  232. y[j] = dbesy0_(x);
  233. if (nd == 1) {
  234. return 0;
  235. }
  236. ++j;
  237. L130:
  238. y[j] = dbesy1_(x);
  239. if (nd == 1) {
  240. return 0;
  241. }
  242. trx = 2. / *x;
  243. tm = trx;
  244. goto L80;
  245. L140:
  246. xermsg_("SLATEC", "DBESY", "ORDER, FNU, LESS THAN ZERO", &c__2, &c__1, (
  247. ftnlen)6, (ftnlen)5, (ftnlen)26);
  248. return 0;
  249. L150:
  250. xermsg_("SLATEC", "DBESY", "X LESS THAN OR EQUAL TO ZERO", &c__2, &c__1, (
  251. ftnlen)6, (ftnlen)5, (ftnlen)28);
  252. return 0;
  253. L160:
  254. xermsg_("SLATEC", "DBESY", "N LESS THAN ONE", &c__2, &c__1, (ftnlen)6, (
  255. ftnlen)5, (ftnlen)15);
  256. return 0;
  257. L170:
  258. xermsg_("SLATEC", "DBESY", "OVERFLOW, FNU OR N TOO LARGE OR X TOO SMALL",
  259. &c__6, &c__1, (ftnlen)6, (ftnlen)5, (ftnlen)43);
  260. return 0;
  261. } /* dbesy_ */