dbesi.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /* dbesi.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__3 = 3;
  7. static integer const c__15 = 15;
  8. static integer const c__5 = 5;
  9. static integer const c__14 = 14;
  10. static integer const c__2 = 2;
  11. static integer const c__1 = 1;
  12. static integer const c__6 = 6;
  13. int dbesi_(double const *x, double const *alpha, integer const *kode, integer const *n, double *y, integer *nz)
  14. {
  15. /* Initialized data */
  16. static double const rttpi = .398942280401433;
  17. static integer inlim = 80;
  18. /* System generated locals */
  19. integer i__1;
  20. double d__1;
  21. /* Local variables. Some initialized to avoid -Wmaybe-uninitialized */
  22. integer i__, k;
  23. double s, t, z__;
  24. integer i1;
  25. double s1, s2, t2, ak, ap, ra, fn, ta;
  26. integer kk, in, km = 0;
  27. double tb;
  28. integer is, nn;
  29. double dx;
  30. integer kt, ns = 0;
  31. double tm, sx, xo2, ain, akm, arg, dfn, fnf, fni, gln, ans, dtm, tfn,
  32. fnu, tol, etx, trx, fnp1, xo2l, sxo2, earg;
  33. integer ialp;
  34. double elim, atol, temp[3], flgik, tolln;
  35. /* ***BEGIN PROLOGUE DBESI */
  36. /* ***PURPOSE Compute an N member sequence of I Bessel functions */
  37. /* I/SUB(ALPHA+K-1)/(X), K=1,...,N or scaled Bessel functions */
  38. /* EXP(-X)*I/SUB(ALPHA+K-1)/(X), K=1,...,N for nonnegative */
  39. /* ALPHA and X. */
  40. /* ***LIBRARY SLATEC */
  41. /* ***CATEGORY C10B3 */
  42. /* ***TYPE DOUBLE PRECISION (BESI-S, DBESI-D) */
  43. /* ***KEYWORDS I BESSEL FUNCTION, SPECIAL FUNCTIONS */
  44. /* ***AUTHOR Amos, D. E., (SNLA) */
  45. /* Daniel, S. L., (SNLA) */
  46. /* ***DESCRIPTION */
  47. /* Abstract **** a double precision routine **** */
  48. /* DBESI computes an N member sequence of I Bessel functions */
  49. /* I/sub(ALPHA+K-1)/(X), K=1,...,N or scaled Bessel functions */
  50. /* EXP(-X)*I/sub(ALPHA+K-1)/(X), K=1,...,N for nonnegative ALPHA */
  51. /* and X. A combination of the power series, the asymptotic */
  52. /* expansion for X to infinity, and the uniform asymptotic */
  53. /* expansion for NU to infinity are applied over subdivisions of */
  54. /* the (NU,X) plane. For values not covered by one of these */
  55. /* formulae, the order is incremented by an integer so that one */
  56. /* of these formulae apply. Backward recursion is used to reduce */
  57. /* orders by integer values. The asymptotic expansion for X to */
  58. /* infinity is used only when the entire sequence (specifically */
  59. /* the last member) lies within the region covered by the */
  60. /* expansion. Leading terms of these expansions are used to test */
  61. /* for over or underflow where appropriate. If a sequence is */
  62. /* requested and the last member would underflow, the result is */
  63. /* set to zero and the next lower order tried, etc., until a */
  64. /* member comes on scale or all are set to zero. An overflow */
  65. /* cannot occur with scaling. */
  66. /* The maximum number of significant digits obtainable */
  67. /* is the smaller of 14 and the number of digits carried in */
  68. /* double precision arithmetic. */
  69. /* Description of Arguments */
  70. /* Input X,ALPHA are double precision */
  71. /* X - X .GE. 0.0D0 */
  72. /* ALPHA - order of first member of the sequence, */
  73. /* ALPHA .GE. 0.0D0 */
  74. /* KODE - a parameter to indicate the scaling option */
  75. /* KODE=1 returns */
  76. /* Y(K)= I/sub(ALPHA+K-1)/(X), */
  77. /* K=1,...,N */
  78. /* KODE=2 returns */
  79. /* Y(K)=EXP(-X)*I/sub(ALPHA+K-1)/(X), */
  80. /* K=1,...,N */
  81. /* N - number of members in the sequence, N .GE. 1 */
  82. /* Output Y is double precision */
  83. /* Y - a vector whose first N components contain */
  84. /* values for I/sub(ALPHA+K-1)/(X) or scaled */
  85. /* values for EXP(-X)*I/sub(ALPHA+K-1)/(X), */
  86. /* K=1,...,N depending on KODE */
  87. /* NZ - number of components of Y set to zero due to */
  88. /* underflow, */
  89. /* NZ=0 , normal return, computation completed */
  90. /* NZ .NE. 0, last NZ components of Y set to zero, */
  91. /* Y(K)=0.0D0, K=N-NZ+1,...,N. */
  92. /* Error Conditions */
  93. /* Improper input arguments - a fatal error */
  94. /* Overflow with KODE=1 - a fatal error */
  95. /* Underflow - a non-fatal error(NZ .NE. 0) */
  96. /* ***REFERENCES D. E. Amos, S. L. Daniel and M. K. Weston, CDC 6600 */
  97. /* subroutines IBESS and JBESS for Bessel functions */
  98. /* I(NU,X) and J(NU,X), X .GE. 0, NU .GE. 0, ACM */
  99. /* Transactions on Mathematical Software 3, (1977), */
  100. /* pp. 76-92. */
  101. /* F. W. J. Olver, Tables of Bessel Functions of Moderate */
  102. /* or Large Orders, NPL Mathematical Tables 6, Her */
  103. /* Majesty's Stationery Office, London, 1962. */
  104. /* ***ROUTINES CALLED D1MACH, DASYIK, DLNGAM, I1MACH, XERMSG */
  105. /* ***REVISION HISTORY (YYMMDD) */
  106. /* 750101 DATE WRITTEN */
  107. /* 890531 Changed all specific intrinsics to generic. (WRB) */
  108. /* 890911 Removed unnecessary intrinsics. (WRB) */
  109. /* 890911 REVISION DATE from Version 3.2 */
  110. /* 891214 Prologue converted to Version 4.0 format. (BAB) */
  111. /* 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) */
  112. /* 900326 Removed duplicate information from DESCRIPTION section. */
  113. /* (WRB) */
  114. /* 920501 Reformatted the REFERENCES section. (WRB) */
  115. /* ***END PROLOGUE DBESI */
  116. /* Parameter adjustments */
  117. --y;
  118. /* Function Body */
  119. /* ***FIRST EXECUTABLE STATEMENT DBESI */
  120. *nz = 0;
  121. kt = 1;
  122. /* I1MACH(15) REPLACES I1MACH(12) IN A DOUBLE PRECISION CODE */
  123. /* I1MACH(14) REPLACES I1MACH(11) IN A DOUBLE PRECISION CODE */
  124. ra = d1mach_(3);
  125. tol = max(ra,1e-15);
  126. i1 = -i1mach_(15);
  127. gln = d1mach_(5);
  128. elim = (i1 * gln - 3.) * 2.303;
  129. /* TOLLN = -LN(TOL) */
  130. i1 = i1mach_(14) + 1;
  131. tolln = gln * 2.303 * i1;
  132. tolln = min(tolln,34.5388);
  133. if ((i__1 = *n - 1) < 0) {
  134. goto L590;
  135. } else if (i__1 == 0) {
  136. goto L10;
  137. } else {
  138. goto L20;
  139. }
  140. L10:
  141. kt = 2;
  142. L20:
  143. nn = *n;
  144. if (*kode < 1 || *kode > 2) {
  145. goto L570;
  146. }
  147. if (*x < 0.) {
  148. goto L600;
  149. } else if (*x == 0) {
  150. goto L30;
  151. } else {
  152. goto L80;
  153. }
  154. L30:
  155. if (*alpha < 0.) {
  156. goto L580;
  157. } else if (*alpha == 0) {
  158. goto L40;
  159. } else {
  160. goto L50;
  161. }
  162. L40:
  163. y[1] = 1.;
  164. if (*n == 1) {
  165. return 0;
  166. }
  167. i1 = 2;
  168. goto L60;
  169. L50:
  170. i1 = 1;
  171. L60:
  172. i__1 = *n;
  173. for (i__ = i1; i__ <= i__1; ++i__) {
  174. y[i__] = 0.;
  175. /* L70: */
  176. }
  177. return 0;
  178. L80:
  179. if (*alpha < 0.) {
  180. goto L580;
  181. }
  182. ialp = (integer) (*alpha);
  183. fni = (double) (ialp + *n - 1);
  184. fnf = *alpha - ialp;
  185. dfn = fni + fnf;
  186. fnu = dfn;
  187. in = 0;
  188. xo2 = *x * .5;
  189. sxo2 = xo2 * xo2;
  190. etx = (double) (*kode - 1);
  191. sx = etx * *x;
  192. /* DECISION TREE FOR REGION WHERE SERIES, ASYMPTOTIC EXPANSION FOR X */
  193. /* TO INFINITY AND ASYMPTOTIC EXPANSION FOR NU TO INFINITY ARE */
  194. /* APPLIED. */
  195. if (sxo2 <= fnu + 1.) {
  196. goto L90;
  197. }
  198. if (*x <= 12.) {
  199. goto L110;
  200. }
  201. fn = fnu * .55 * fnu;
  202. fn = max(17.,fn);
  203. if (*x >= fn) {
  204. goto L430;
  205. }
  206. /* Computing MAX */
  207. d__1 = 36. - fnu;
  208. ans = max(d__1,0.);
  209. ns = (integer) ans;
  210. fni += ns;
  211. dfn = fni + fnf;
  212. fn = dfn;
  213. is = kt;
  214. km = *n - 1 + ns;
  215. if (km > 0) {
  216. is = 3;
  217. }
  218. goto L120;
  219. L90:
  220. fn = fnu;
  221. fnp1 = fn + 1.;
  222. xo2l = log(xo2);
  223. is = kt;
  224. if (*x <= .5) {
  225. goto L230;
  226. }
  227. ns = 0;
  228. L100:
  229. fni += ns;
  230. dfn = fni + fnf;
  231. fn = dfn;
  232. fnp1 = fn + 1.;
  233. is = kt;
  234. if (*n - 1 + ns > 0) {
  235. is = 3;
  236. }
  237. goto L230;
  238. L110:
  239. xo2l = log(xo2);
  240. ns = (integer) (sxo2 - fnu);
  241. goto L100;
  242. L120:
  243. /* OVERFLOW TEST ON UNIFORM ASYMPTOTIC EXPANSION */
  244. if (*kode == 2) {
  245. goto L130;
  246. }
  247. if (*alpha < 1.) {
  248. goto L150;
  249. }
  250. z__ = *x / *alpha;
  251. ra = sqrt(z__ * z__ + 1.);
  252. gln = log((ra + 1.) / z__);
  253. t = ra * (1. - etx) + etx / (z__ + ra);
  254. arg = *alpha * (t - gln);
  255. if (arg > elim) {
  256. goto L610;
  257. }
  258. if (km == 0) {
  259. goto L140;
  260. }
  261. L130:
  262. /* UNDERFLOW TEST ON UNIFORM ASYMPTOTIC EXPANSION */
  263. z__ = *x / fn;
  264. ra = sqrt(z__ * z__ + 1.);
  265. gln = log((ra + 1.) / z__);
  266. t = ra * (1. - etx) + etx / (z__ + ra);
  267. arg = fn * (t - gln);
  268. L140:
  269. if (arg < -elim) {
  270. goto L280;
  271. }
  272. goto L190;
  273. L150:
  274. if (*x > elim) {
  275. goto L610;
  276. }
  277. goto L130;
  278. /* UNIFORM ASYMPTOTIC EXPANSION FOR NU TO INFINITY */
  279. L160:
  280. if (km != 0) {
  281. goto L170;
  282. }
  283. y[1] = temp[2];
  284. return 0;
  285. L170:
  286. temp[0] = temp[2];
  287. in = ns;
  288. kt = 1;
  289. i1 = 0;
  290. L180:
  291. is = 2;
  292. fni += -1.;
  293. dfn = fni + fnf;
  294. fn = dfn;
  295. if (i1 == 2) {
  296. goto L350;
  297. }
  298. z__ = *x / fn;
  299. ra = sqrt(z__ * z__ + 1.);
  300. gln = log((ra + 1.) / z__);
  301. t = ra * (1. - etx) + etx / (z__ + ra);
  302. arg = fn * (t - gln);
  303. L190:
  304. i1 = (i__1 = 3 - is, abs(i__1));
  305. i1 = max(i1,1);
  306. flgik = 1.;
  307. dasyik_(x, &fn, kode, &flgik, &ra, &arg, &i1, &temp[is - 1]);
  308. switch (is) {
  309. case 1: goto L180;
  310. case 2: goto L350;
  311. case 3: goto L510;
  312. }
  313. /* SERIES FOR (X/2)**2.LE.NU+1 */
  314. L230:
  315. gln = dlngam_(&fnp1);
  316. arg = fn * xo2l - gln - sx;
  317. if (arg < -elim) {
  318. goto L300;
  319. }
  320. earg = exp(arg);
  321. L240:
  322. s = 1.;
  323. if (*x < tol) {
  324. goto L260;
  325. }
  326. ak = 3.;
  327. t2 = 1.;
  328. t = 1.;
  329. s1 = fn;
  330. for (k = 1; k <= 17; ++k) {
  331. s2 = t2 + s1;
  332. t = t * sxo2 / s2;
  333. s += t;
  334. if (abs(t) < tol) {
  335. goto L260;
  336. }
  337. t2 += ak;
  338. ak += 2.;
  339. s1 += fn;
  340. /* L250: */
  341. }
  342. L260:
  343. temp[is - 1] = s * earg;
  344. switch (is) {
  345. case 1: goto L270;
  346. case 2: goto L350;
  347. case 3: goto L500;
  348. }
  349. L270:
  350. earg = earg * fn / xo2;
  351. fni += -1.;
  352. dfn = fni + fnf;
  353. fn = dfn;
  354. is = 2;
  355. goto L240;
  356. /* SET UNDERFLOW VALUE AND UPDATE PARAMETERS */
  357. L280:
  358. y[nn] = 0.;
  359. --nn;
  360. fni += -1.;
  361. dfn = fni + fnf;
  362. fn = dfn;
  363. if ((i__1 = nn - 1) < 0) {
  364. goto L340;
  365. } else if (i__1 == 0) {
  366. goto L290;
  367. } else {
  368. goto L130;
  369. }
  370. L290:
  371. kt = 2;
  372. is = 2;
  373. goto L130;
  374. L300:
  375. y[nn] = 0.;
  376. --nn;
  377. fnp1 = fn;
  378. fni += -1.;
  379. dfn = fni + fnf;
  380. fn = dfn;
  381. if ((i__1 = nn - 1) < 0) {
  382. goto L340;
  383. } else if (i__1 == 0) {
  384. goto L310;
  385. } else {
  386. goto L320;
  387. }
  388. L310:
  389. kt = 2;
  390. is = 2;
  391. L320:
  392. if (sxo2 <= fnp1) {
  393. goto L330;
  394. }
  395. goto L130;
  396. L330:
  397. arg = arg - xo2l + log(fnp1);
  398. if (arg < -elim) {
  399. goto L300;
  400. }
  401. goto L230;
  402. L340:
  403. *nz = *n - nn;
  404. return 0;
  405. /* BACKWARD RECURSION SECTION */
  406. L350:
  407. *nz = *n - nn;
  408. L360:
  409. if (kt == 2) {
  410. goto L420;
  411. }
  412. s1 = temp[0];
  413. s2 = temp[1];
  414. trx = 2. / *x;
  415. dtm = fni;
  416. tm = (dtm + fnf) * trx;
  417. if (in == 0) {
  418. goto L390;
  419. }
  420. /* BACKWARD RECUR TO INDEX ALPHA+NN-1 */
  421. i__1 = in;
  422. for (i__ = 1; i__ <= i__1; ++i__) {
  423. s = s2;
  424. s2 = tm * s2 + s1;
  425. s1 = s;
  426. dtm += -1.;
  427. tm = (dtm + fnf) * trx;
  428. /* L380: */
  429. }
  430. y[nn] = s1;
  431. if (nn == 1) {
  432. return 0;
  433. }
  434. y[nn - 1] = s2;
  435. if (nn == 2) {
  436. return 0;
  437. }
  438. goto L400;
  439. L390:
  440. /* BACKWARD RECUR FROM INDEX ALPHA+NN-1 TO ALPHA */
  441. y[nn] = s1;
  442. y[nn - 1] = s2;
  443. if (nn == 2) {
  444. return 0;
  445. }
  446. L400:
  447. k = nn + 1;
  448. i__1 = nn;
  449. for (i__ = 3; i__ <= i__1; ++i__) {
  450. --k;
  451. y[k - 2] = tm * y[k - 1] + y[k];
  452. dtm += -1.;
  453. tm = (dtm + fnf) * trx;
  454. /* L410: */
  455. }
  456. return 0;
  457. L420:
  458. y[1] = temp[1];
  459. return 0;
  460. /* ASYMPTOTIC EXPANSION FOR X TO INFINITY */
  461. L430:
  462. earg = rttpi / sqrt(*x);
  463. if (*kode == 2) {
  464. goto L440;
  465. }
  466. if (*x > elim) {
  467. goto L610;
  468. }
  469. earg *= exp(*x);
  470. L440:
  471. etx = *x * 8.;
  472. is = kt;
  473. in = 0;
  474. fn = fnu;
  475. L450:
  476. dx = fni + fni;
  477. tm = 0.;
  478. if (fni == 0. && abs(fnf) < tol) {
  479. goto L460;
  480. }
  481. tm = fnf * 4. * (fni + fni + fnf);
  482. L460:
  483. dtm = dx * dx;
  484. s1 = etx;
  485. trx = dtm - 1.;
  486. dx = -(trx + tm) / etx;
  487. t = dx;
  488. s = dx + 1.;
  489. atol = tol * abs(s);
  490. s2 = 1.;
  491. ak = 8.;
  492. for (k = 1; k <= 25; ++k) {
  493. s1 += etx;
  494. s2 += ak;
  495. dx = dtm - s2;
  496. ap = dx + tm;
  497. t = -t * ap / s1;
  498. s += t;
  499. if (abs(t) <= atol) {
  500. goto L480;
  501. }
  502. ak += 8.;
  503. /* L470: */
  504. }
  505. L480:
  506. temp[is - 1] = s * earg;
  507. if (is == 2) {
  508. goto L360;
  509. }
  510. is = 2;
  511. fni += -1.;
  512. dfn = fni + fnf;
  513. fn = dfn;
  514. goto L450;
  515. /* BACKWARD RECURSION WITH NORMALIZATION BY */
  516. /* ASYMPTOTIC EXPANSION FOR NU TO INFINITY OR POWER SERIES. */
  517. L500:
  518. /* COMPUTATION OF LAST ORDER FOR SERIES NORMALIZATION */
  519. /* Computing MAX */
  520. d__1 = 3. - fn;
  521. akm = max(d__1,0.);
  522. km = (integer) akm;
  523. tfn = fn + km;
  524. ta = (gln + tfn - .9189385332 - .0833333333 / tfn) / (tfn + .5);
  525. ta = xo2l - ta;
  526. tb = -(1. - 1. / tfn) / tfn;
  527. ain = tolln / (-ta + sqrt(ta * ta - tolln * tb)) + 1.5;
  528. in = (integer) ain;
  529. in += km;
  530. goto L520;
  531. L510:
  532. /* COMPUTATION OF LAST ORDER FOR ASYMPTOTIC EXPANSION NORMALIZATION */
  533. t = 1. / (fn * ra);
  534. ain = tolln / (gln + sqrt(gln * gln + t * tolln)) + 1.5;
  535. in = (integer) ain;
  536. if (in > inlim) {
  537. goto L160;
  538. }
  539. L520:
  540. trx = 2. / *x;
  541. dtm = fni + in;
  542. tm = (dtm + fnf) * trx;
  543. ta = 0.;
  544. tb = tol;
  545. kk = 1;
  546. L530:
  547. /* BACKWARD RECUR UNINDEXED */
  548. i__1 = in;
  549. for (i__ = 1; i__ <= i__1; ++i__) {
  550. s = tb;
  551. tb = tm * tb + ta;
  552. ta = s;
  553. dtm += -1.;
  554. tm = (dtm + fnf) * trx;
  555. /* L540: */
  556. }
  557. /* NORMALIZATION */
  558. if (kk != 1) {
  559. goto L550;
  560. }
  561. ta = ta / tb * temp[2];
  562. tb = temp[2];
  563. kk = 2;
  564. in = ns;
  565. if (ns != 0) {
  566. goto L530;
  567. }
  568. L550:
  569. y[nn] = tb;
  570. *nz = *n - nn;
  571. if (nn == 1) {
  572. return 0;
  573. }
  574. tb = tm * tb + ta;
  575. k = nn - 1;
  576. y[k] = tb;
  577. if (nn == 2) {
  578. return 0;
  579. }
  580. dtm += -1.;
  581. tm = (dtm + fnf) * trx;
  582. km = k - 1;
  583. /* BACKWARD RECUR INDEXED */
  584. i__1 = km;
  585. for (i__ = 1; i__ <= i__1; ++i__) {
  586. y[k - 1] = tm * y[k] + y[k + 1];
  587. dtm += -1.;
  588. tm = (dtm + fnf) * trx;
  589. --k;
  590. /* L560: */
  591. }
  592. return 0;
  593. L570:
  594. xermsg_("SLATEC", "DBESI", "SCALING OPTION, KODE, NOT 1 OR 2.", &c__2, &
  595. c__1, (ftnlen)6, (ftnlen)5, (ftnlen)33);
  596. return 0;
  597. L580:
  598. xermsg_("SLATEC", "DBESI", "ORDER, ALPHA, LESS THAN ZERO.", &c__2, &c__1,
  599. (ftnlen)6, (ftnlen)5, (ftnlen)29);
  600. return 0;
  601. L590:
  602. xermsg_("SLATEC", "DBESI", "N LESS THAN ONE.", &c__2, &c__1, (ftnlen)6, (
  603. ftnlen)5, (ftnlen)16);
  604. return 0;
  605. L600:
  606. xermsg_("SLATEC", "DBESI", "X LESS THAN ZERO.", &c__2, &c__1, (ftnlen)6, (
  607. ftnlen)5, (ftnlen)17);
  608. return 0;
  609. L610:
  610. xermsg_("SLATEC", "DBESI", "OVERFLOW, X TOO LARGE FOR KODE = 1.", &c__6, &
  611. c__1, (ftnlen)6, (ftnlen)5, (ftnlen)35);
  612. return 0;
  613. } /* dbesi_ */