dbesk.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /* dbesk.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 dbesk_(double const *x, double const *fnu, integer const *kode, integer const *n, double *y, integer *nz)
  12. {
  13. /* Initialized data */
  14. static integer nulim[2] = { 35,70 };
  15. /* System generated locals */
  16. integer i__1;
  17. /* Local variables. Some initialized to avoid -Wmaybe-uninitialized */
  18. integer i__, j, k;
  19. double s, t, w[2], s1, s2 = 0.;
  20. integer nb;
  21. double cn;
  22. integer nd;
  23. double fn;
  24. integer nn;
  25. double tm = 0.;
  26. integer mz;
  27. double zn, gln, fnn;
  28. integer nud;
  29. double dnu, gnu, etx, trx = 0., rtz, elim, xlim, flgik;
  30. /* ***BEGIN PROLOGUE DBESK */
  31. /* ***PURPOSE Implement forward recursion on the three term recursion */
  32. /* relation for a sequence of non-negative order Bessel */
  33. /* functions K/SUB(FNU+I-1)/(X), or scaled Bessel functions */
  34. /* EXP(X)*K/SUB(FNU+I-1)/(X), I=1,...,N for real, positive */
  35. /* X and non-negative orders FNU. */
  36. /* ***LIBRARY SLATEC */
  37. /* ***CATEGORY C10B3 */
  38. /* ***TYPE DOUBLE PRECISION (BESK-S, DBESK-D) */
  39. /* ***KEYWORDS K BESSEL FUNCTION, SPECIAL FUNCTIONS */
  40. /* ***AUTHOR Amos, D. E., (SNLA) */
  41. /* ***DESCRIPTION */
  42. /* Abstract **** a double precision routine **** */
  43. /* DBESK implements forward recursion on the three term */
  44. /* recursion relation for a sequence of non-negative order Bessel */
  45. /* functions K/sub(FNU+I-1)/(X), or scaled Bessel functions */
  46. /* EXP(X)*K/sub(FNU+I-1)/(X), I=1,..,N for real X .GT. 0.0D0 and */
  47. /* non-negative orders FNU. If FNU .LT. NULIM, orders FNU and */
  48. /* FNU+1 are obtained from DBSKNU to start the recursion. If */
  49. /* FNU .GE. NULIM, the uniform asymptotic expansion is used for */
  50. /* orders FNU and FNU+1 to start the recursion. NULIM is 35 or */
  51. /* 70 depending on whether N=1 or N .GE. 2. Under and overflow */
  52. /* tests are made on the leading term of the asymptotic expansion */
  53. /* before any extensive computation is done. */
  54. /* The maximum number of significant digits obtainable */
  55. /* is the smaller of 14 and the number of digits carried in */
  56. /* double precision arithmetic. */
  57. /* Description of Arguments */
  58. /* Input X,FNU are double precision */
  59. /* X - X .GT. 0.0D0 */
  60. /* FNU - order of the initial K function, FNU .GE. 0.0D0 */
  61. /* KODE - a parameter to indicate the scaling option */
  62. /* KODE=1 returns Y(I)= K/sub(FNU+I-1)/(X), */
  63. /* I=1,...,N */
  64. /* KODE=2 returns Y(I)=EXP(X)*K/sub(FNU+I-1)/(X), */
  65. /* I=1,...,N */
  66. /* N - number of members in the sequence, N .GE. 1 */
  67. /* Output Y is double precision */
  68. /* Y - a vector whose first N components contain values */
  69. /* for the sequence */
  70. /* Y(I)= k/sub(FNU+I-1)/(X), I=1,...,N or */
  71. /* Y(I)=EXP(X)*K/sub(FNU+I-1)/(X), I=1,...,N */
  72. /* depending on KODE */
  73. /* NZ - number of components of Y set to zero due to */
  74. /* underflow with KODE=1, */
  75. /* NZ=0 , normal return, computation completed */
  76. /* NZ .NE. 0, first NZ components of Y set to zero */
  77. /* due to underflow, Y(I)=0.0D0, I=1,...,NZ */
  78. /* Error Conditions */
  79. /* Improper input arguments - a fatal error */
  80. /* Overflow - a fatal error */
  81. /* Underflow with KODE=1 - a non-fatal error (NZ .NE. 0) */
  82. /* ***REFERENCES F. W. J. Olver, Tables of Bessel Functions of Moderate */
  83. /* or Large Orders, NPL Mathematical Tables 6, Her */
  84. /* Majesty's Stationery Office, London, 1962. */
  85. /* N. M. Temme, On the numerical evaluation of the modified */
  86. /* Bessel function of the third kind, Journal of */
  87. /* Computational Physics 19, (1975), pp. 324-337. */
  88. /* ***ROUTINES CALLED D1MACH, DASYIK, DBESK0, DBESK1, DBSK0E, DBSK1E, */
  89. /* DBSKNU, I1MACH, XERMSG */
  90. /* ***REVISION HISTORY (YYMMDD) */
  91. /* 790201 DATE WRITTEN */
  92. /* 890531 Changed all specific intrinsics to generic. (WRB) */
  93. /* 890911 Removed unnecessary intrinsics. (WRB) */
  94. /* 890911 REVISION DATE from Version 3.2 */
  95. /* 891214 Prologue converted to Version 4.0 format. (BAB) */
  96. /* 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) */
  97. /* 920501 Reformatted the REFERENCES section. (WRB) */
  98. /* ***END PROLOGUE DBESK */
  99. /* Parameter adjustments */
  100. --y;
  101. /* Function Body */
  102. /* ***FIRST EXECUTABLE STATEMENT DBESK */
  103. nn = -i1mach_(15);
  104. elim = (nn * d1mach_(5) - 3.) * 2.303;
  105. xlim = d1mach_(1) * 1e3;
  106. if (*kode < 1 || *kode > 2) {
  107. goto L280;
  108. }
  109. if (*fnu < 0.) {
  110. goto L290;
  111. }
  112. if (*x <= 0.) {
  113. goto L300;
  114. }
  115. if (*x < xlim) {
  116. goto L320;
  117. }
  118. if (*n < 1) {
  119. goto L310;
  120. }
  121. etx = (double) (*kode - 1);
  122. /* ND IS A DUMMY VARIABLE FOR N */
  123. /* GNU IS A DUMMY VARIABLE FOR FNU */
  124. /* NZ = NUMBER OF UNDERFLOWS ON KODE=1 */
  125. nd = *n;
  126. *nz = 0;
  127. nud = (integer) (*fnu);
  128. dnu = *fnu - nud;
  129. gnu = *fnu;
  130. nn = min(2,nd);
  131. fn = *fnu + *n - 1;
  132. fnn = fn;
  133. if (fn < 2.) {
  134. goto L150;
  135. }
  136. /* OVERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION) */
  137. /* FOR THE LAST ORDER, FNU+N-1.GE.NULIM */
  138. zn = *x / fn;
  139. if (zn == 0.) {
  140. goto L320;
  141. }
  142. rtz = sqrt(zn * zn + 1.);
  143. gln = log((rtz + 1.) / zn);
  144. t = rtz * (1. - etx) + etx / (zn + rtz);
  145. cn = -fn * (t - gln);
  146. if (cn > elim) {
  147. goto L320;
  148. }
  149. if (nud < nulim[nn - 1]) {
  150. goto L30;
  151. }
  152. if (nn == 1) {
  153. goto L20;
  154. }
  155. L10:
  156. /* UNDERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION) */
  157. /* FOR THE FIRST ORDER, FNU.GE.NULIM */
  158. fn = gnu;
  159. zn = *x / fn;
  160. rtz = sqrt(zn * zn + 1.);
  161. gln = log((rtz + 1.) / zn);
  162. t = rtz * (1. - etx) + etx / (zn + rtz);
  163. cn = -fn * (t - gln);
  164. L20:
  165. if (cn < -elim) {
  166. goto L230;
  167. }
  168. /* ASYMPTOTIC EXPANSION FOR ORDERS FNU AND FNU+1.GE.NULIM */
  169. flgik = -1.;
  170. dasyik_(x, &gnu, kode, &flgik, &rtz, &cn, &nn, &y[1]);
  171. if (nn == 1) {
  172. goto L240;
  173. }
  174. trx = 2. / *x;
  175. tm = (gnu + gnu + 2.) / *x;
  176. goto L130;
  177. L30:
  178. if (*kode == 2) {
  179. goto L40;
  180. }
  181. /* UNDERFLOW TEST (LEADING EXPONENTIAL OF ASYMPTOTIC EXPANSION IN X) */
  182. /* FOR ORDER DNU */
  183. if (*x > elim) {
  184. goto L230;
  185. }
  186. L40:
  187. if (dnu != 0.) {
  188. goto L80;
  189. }
  190. if (*kode == 2) {
  191. goto L50;
  192. }
  193. s1 = dbesk0_(x);
  194. goto L60;
  195. L50:
  196. s1 = dbsk0e_(x);
  197. L60:
  198. if (nud == 0 && nd == 1) {
  199. goto L120;
  200. }
  201. if (*kode == 2) {
  202. goto L70;
  203. }
  204. s2 = dbesk1_(x);
  205. goto L90;
  206. L70:
  207. s2 = dbsk1e_(x);
  208. goto L90;
  209. L80:
  210. nb = 2;
  211. if (nud == 0 && nd == 1) {
  212. nb = 1;
  213. }
  214. dbsknu_(x, &dnu, kode, &nb, w, nz);
  215. s1 = w[0];
  216. if (nb == 1) {
  217. goto L120;
  218. }
  219. s2 = w[1];
  220. L90:
  221. trx = 2. / *x;
  222. tm = (dnu + dnu + 2.) / *x;
  223. /* FORWARD RECUR FROM DNU TO FNU+1 TO GET Y(1) AND Y(2) */
  224. if (nd == 1) {
  225. --nud;
  226. }
  227. if (nud > 0) {
  228. goto L100;
  229. }
  230. if (nd > 1) {
  231. goto L120;
  232. }
  233. s1 = s2;
  234. goto L120;
  235. L100:
  236. i__1 = nud;
  237. for (i__ = 1; i__ <= i__1; ++i__) {
  238. s = s2;
  239. s2 = tm * s2 + s1;
  240. s1 = s;
  241. tm += trx;
  242. /* L110: */
  243. }
  244. if (nd == 1) {
  245. s1 = s2;
  246. }
  247. L120:
  248. y[1] = s1;
  249. if (nd == 1) {
  250. goto L240;
  251. }
  252. y[2] = s2;
  253. L130:
  254. if (nd == 2) {
  255. goto L240;
  256. }
  257. /* FORWARD RECUR FROM FNU+2 TO FNU+N-1 */
  258. i__1 = nd;
  259. for (i__ = 3; i__ <= i__1; ++i__) {
  260. y[i__] = tm * y[i__ - 1] + y[i__ - 2];
  261. tm += trx;
  262. /* L140: */
  263. }
  264. goto L240;
  265. L150:
  266. /* UNDERFLOW TEST FOR KODE=1 */
  267. if (*kode == 2) {
  268. goto L160;
  269. }
  270. if (*x > elim) {
  271. goto L230;
  272. }
  273. L160:
  274. /* OVERFLOW TEST */
  275. if (fn <= 1.) {
  276. goto L170;
  277. }
  278. if (-fn * (log(*x) - .693) > elim) {
  279. goto L320;
  280. }
  281. L170:
  282. if (dnu == 0.) {
  283. goto L180;
  284. }
  285. dbsknu_(x, fnu, kode, &nd, &y[1], &mz);
  286. goto L240;
  287. L180:
  288. j = nud;
  289. if (j == 1) {
  290. goto L210;
  291. }
  292. ++j;
  293. if (*kode == 2) {
  294. goto L190;
  295. }
  296. y[j] = dbesk0_(x);
  297. goto L200;
  298. L190:
  299. y[j] = dbsk0e_(x);
  300. L200:
  301. if (nd == 1) {
  302. goto L240;
  303. }
  304. ++j;
  305. L210:
  306. if (*kode == 2) {
  307. goto L220;
  308. }
  309. y[j] = dbesk1_(x);
  310. goto L240;
  311. L220:
  312. y[j] = dbsk1e_(x);
  313. goto L240;
  314. /* UPDATE PARAMETERS ON UNDERFLOW */
  315. L230:
  316. ++nud;
  317. --nd;
  318. if (nd == 0) {
  319. goto L240;
  320. }
  321. nn = min(2,nd);
  322. gnu += 1.;
  323. if (fnn < 2.) {
  324. goto L230;
  325. }
  326. if (nud < nulim[nn - 1]) {
  327. goto L230;
  328. }
  329. goto L10;
  330. L240:
  331. *nz = *n - nd;
  332. if (*nz == 0) {
  333. return 0;
  334. }
  335. if (nd == 0) {
  336. goto L260;
  337. }
  338. i__1 = nd;
  339. for (i__ = 1; i__ <= i__1; ++i__) {
  340. j = *n - i__ + 1;
  341. k = nd - i__ + 1;
  342. y[j] = y[k];
  343. /* L250: */
  344. }
  345. L260:
  346. i__1 = *nz;
  347. for (i__ = 1; i__ <= i__1; ++i__) {
  348. y[i__] = 0.;
  349. /* L270: */
  350. }
  351. return 0;
  352. L280:
  353. xermsg_("SLATEC", "DBESK", "SCALING OPTION, KODE, NOT 1 OR 2", &c__2, &
  354. c__1, (ftnlen)6, (ftnlen)5, (ftnlen)32);
  355. return 0;
  356. L290:
  357. xermsg_("SLATEC", "DBESK", "ORDER, FNU, LESS THAN ZERO", &c__2, &c__1, (
  358. ftnlen)6, (ftnlen)5, (ftnlen)26);
  359. return 0;
  360. L300:
  361. xermsg_("SLATEC", "DBESK", "X LESS THAN OR EQUAL TO ZERO", &c__2, &c__1, (
  362. ftnlen)6, (ftnlen)5, (ftnlen)28);
  363. return 0;
  364. L310:
  365. xermsg_("SLATEC", "DBESK", "N LESS THAN ONE", &c__2, &c__1, (ftnlen)6, (
  366. ftnlen)5, (ftnlen)15);
  367. return 0;
  368. L320:
  369. xermsg_("SLATEC", "DBESK", "OVERFLOW, FNU OR N TOO LARGE OR X TOO SMALL",
  370. &c__6, &c__1, (ftnlen)6, (ftnlen)5, (ftnlen)43);
  371. return 0;
  372. } /* dbesk_ */