dbsknu.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /* dbsknu.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__3 = 3;
  9. static integer const c__2 = 2;
  10. static integer const c__1 = 1;
  11. int dbsknu_(double const *x, double const *fnu, integer const *kode,
  12. integer const *n, double *y, integer *nz)
  13. {
  14. /* Initialized data */
  15. static double const x1 = 2.;
  16. static double const x2 = 17.;
  17. static double const pi = 3.14159265358979;
  18. static double const rthpi = 1.2533141373155;
  19. static double const cc[8] = { .577215664901533,-.0420026350340952,
  20. -.0421977345555443,.007218943246663,-2.152416741149e-4,
  21. -2.01348547807e-5,1.133027232e-6,6.116095e-9 };
  22. /* System generated locals */
  23. integer i__1;
  24. /* Local variables. Some initialized to avoid -Wmaybe-uninitialized */
  25. double a[160], b[160], f;
  26. integer i__, j, k;
  27. double p, q, s, a1, a2, g1, g2, p1, p2, s1, s2 = 0., t1, t2, fc, ak, bk,
  28. ck = 0., dk, fk;
  29. integer kk;
  30. double cx;
  31. integer nn;
  32. double ex, tm, pt, st, rx, fhs, fks, dnu, fmu;
  33. integer inu;
  34. double sqk, tol, smu, dnu2, coef, elim, flrx;
  35. integer iflag, koded;
  36. double etest;
  37. /* ***BEGIN PROLOGUE DBSKNU */
  38. /* ***SUBSIDIARY */
  39. /* ***PURPOSE Subsidiary to DBESK */
  40. /* ***LIBRARY SLATEC */
  41. /* ***TYPE DOUBLE PRECISION (BESKNU-S, DBSKNU-D) */
  42. /* ***AUTHOR Amos, D. E., (SNLA) */
  43. /* ***DESCRIPTION */
  44. /* Abstract **** A DOUBLE PRECISION routine **** */
  45. /* DBSKNU computes N member sequences of K Bessel functions */
  46. /* K/SUB(FNU+I-1)/(X), I=1,N for non-negative orders FNU and */
  47. /* positive X. Equations of the references are implemented on */
  48. /* small orders DNU for K/SUB(DNU)/(X) and K/SUB(DNU+1)/(X). */
  49. /* Forward recursion with the three term recursion relation */
  50. /* generates higher orders FNU+I-1, I=1,...,N. The parameter */
  51. /* KODE permits K/SUB(FNU+I-1)/(X) values or scaled values */
  52. /* EXP(X)*K/SUB(FNU+I-1)/(X), I=1,N to be returned. */
  53. /* To start the recursion FNU is normalized to the interval */
  54. /* -0.5.LE.DNU.LT.0.5. A special form of the power series is */
  55. /* implemented on 0.LT.X.LE.X1 while the Miller algorithm for the */
  56. /* K Bessel function in terms of the confluent hypergeometric */
  57. /* function U(FNU+0.5,2*FNU+1,X) is implemented on X1.LT.X.LE.X2. */
  58. /* For X.GT.X2, the asymptotic expansion for large X is used. */
  59. /* When FNU is a half odd integer, a special formula for */
  60. /* DNU=-0.5 and DNU+1.0=0.5 is used to start the recursion. */
  61. /* The maximum number of significant digits obtainable */
  62. /* is the smaller of 14 and the number of digits carried in */
  63. /* DOUBLE PRECISION arithmetic. */
  64. /* DBSKNU assumes that a significant digit SINH function is */
  65. /* available. */
  66. /* Description of Arguments */
  67. /* INPUT X,FNU are DOUBLE PRECISION */
  68. /* X - X.GT.0.0D0 */
  69. /* FNU - Order of initial K function, FNU.GE.0.0D0 */
  70. /* N - Number of members of the sequence, N.GE.1 */
  71. /* KODE - A parameter to indicate the scaling option */
  72. /* KODE= 1 returns */
  73. /* Y(I)= K/SUB(FNU+I-1)/(X) */
  74. /* I=1,...,N */
  75. /* = 2 returns */
  76. /* Y(I)=EXP(X)*K/SUB(FNU+I-1)/(X) */
  77. /* I=1,...,N */
  78. /* OUTPUT Y is DOUBLE PRECISION */
  79. /* Y - A vector whose first N components contain values */
  80. /* for the sequence */
  81. /* Y(I)= K/SUB(FNU+I-1)/(X), I=1,...,N or */
  82. /* Y(I)=EXP(X)*K/SUB(FNU+I-1)/(X), I=1,...,N */
  83. /* depending on KODE */
  84. /* NZ - Number of components set to zero due to */
  85. /* underflow, */
  86. /* NZ= 0 , normal return */
  87. /* NZ.NE.0 , first NZ components of Y set to zero */
  88. /* due to underflow, Y(I)=0.0D0,I=1,...,NZ */
  89. /* Error Conditions */
  90. /* Improper input arguments - a fatal error */
  91. /* Overflow - a fatal error */
  92. /* Underflow with KODE=1 - a non-fatal error (NZ.NE.0) */
  93. /* ***SEE ALSO DBESK */
  94. /* ***REFERENCES N. M. Temme, On the numerical evaluation of the modified */
  95. /* Bessel function of the third kind, Journal of */
  96. /* Computational Physics 19, (1975), pp. 324-337. */
  97. /* ***ROUTINES CALLED D1MACH, DGAMMA, I1MACH, XERMSG */
  98. /* ***REVISION HISTORY (YYMMDD) */
  99. /* 790201 DATE WRITTEN */
  100. /* 890531 Changed all specific intrinsics to generic. (WRB) */
  101. /* 890911 Removed unnecessary intrinsics. (WRB) */
  102. /* 891214 Prologue converted to Version 4.0 format. (BAB) */
  103. /* 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) */
  104. /* 900326 Removed duplicate information from DESCRIPTION section. */
  105. /* (WRB) */
  106. /* 900328 Added TYPE section. (WRB) */
  107. /* 900727 Added EXTERNAL statement. (WRB) */
  108. /* 910408 Updated the AUTHOR and REFERENCES sections. (WRB) */
  109. /* 920501 Reformatted the REFERENCES section. (WRB) */
  110. /* ***END PROLOGUE DBSKNU */
  111. /* Parameter adjustments */
  112. --y;
  113. /* Function Body */
  114. /* ***FIRST EXECUTABLE STATEMENT DBSKNU */
  115. kk = -i1mach_(15);
  116. elim = (kk * d1mach_(5) - 3.) * 2.303;
  117. ak = d1mach_(3);
  118. tol = max(ak,1e-15);
  119. if (*x <= 0.) {
  120. goto L350;
  121. }
  122. if (*fnu < 0.) {
  123. goto L360;
  124. }
  125. if (*kode < 1 || *kode > 2) {
  126. goto L370;
  127. }
  128. if (*n < 1) {
  129. goto L380;
  130. }
  131. *nz = 0;
  132. iflag = 0;
  133. koded = *kode;
  134. rx = 2. / *x;
  135. inu = (integer) (*fnu + .5);
  136. dnu = *fnu - inu;
  137. dnu2 = 0.;
  138. if (abs(dnu) == .5) {
  139. goto L120;
  140. }
  141. if (abs(dnu) < tol) {
  142. goto L10;
  143. }
  144. dnu2 = dnu * dnu;
  145. L10:
  146. if (*x > x1) {
  147. goto L120;
  148. }
  149. /* SERIES FOR X.LE.X1 */
  150. a1 = 1. - dnu;
  151. a2 = dnu + 1.;
  152. t1 = 1. / dgamma_(&a1);
  153. t2 = 1. / dgamma_(&a2);
  154. if (abs(dnu) > .1) {
  155. goto L40;
  156. }
  157. /* SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU) */
  158. s = cc[0];
  159. ak = 1.;
  160. for (k = 2; k <= 8; ++k) {
  161. ak *= dnu2;
  162. tm = cc[k - 1] * ak;
  163. s += tm;
  164. if (abs(tm) < tol) {
  165. goto L30;
  166. }
  167. /* L20: */
  168. }
  169. L30:
  170. g1 = -s;
  171. goto L50;
  172. L40:
  173. g1 = (t1 - t2) / (dnu + dnu);
  174. L50:
  175. g2 = (t1 + t2) * .5;
  176. smu = 1.;
  177. fc = 1.;
  178. flrx = log(rx);
  179. fmu = dnu * flrx;
  180. if (dnu == 0.) {
  181. goto L60;
  182. }
  183. fc = dnu * pi;
  184. fc /= sin(fc);
  185. if (fmu != 0.) {
  186. smu = sinh(fmu) / fmu;
  187. }
  188. L60:
  189. f = fc * (g1 * cosh(fmu) + g2 * flrx * smu);
  190. fc = exp(fmu);
  191. p = fc * .5 / t2;
  192. q = .5 / (fc * t1);
  193. ak = 1.;
  194. ck = 1.;
  195. bk = 1.;
  196. s1 = f;
  197. s2 = p;
  198. if (inu > 0 || *n > 1) {
  199. goto L90;
  200. }
  201. if (*x < tol) {
  202. goto L80;
  203. }
  204. cx = *x * *x * .25;
  205. L70:
  206. f = (ak * f + p + q) / (bk - dnu2);
  207. p /= ak - dnu;
  208. q /= ak + dnu;
  209. ck = ck * cx / ak;
  210. t1 = ck * f;
  211. s1 += t1;
  212. bk = bk + ak + ak + 1.;
  213. ak += 1.;
  214. s = abs(t1) / (abs(s1) + 1.);
  215. if (s > tol) {
  216. goto L70;
  217. }
  218. L80:
  219. y[1] = s1;
  220. if (koded == 1) {
  221. return 0;
  222. }
  223. y[1] = s1 * exp(*x);
  224. return 0;
  225. L90:
  226. if (*x < tol) {
  227. goto L110;
  228. }
  229. cx = *x * *x * .25;
  230. L100:
  231. f = (ak * f + p + q) / (bk - dnu2);
  232. p /= ak - dnu;
  233. q /= ak + dnu;
  234. ck = ck * cx / ak;
  235. t1 = ck * f;
  236. s1 += t1;
  237. t2 = ck * (p - ak * f);
  238. s2 += t2;
  239. bk = bk + ak + ak + 1.;
  240. ak += 1.;
  241. s = abs(t1) / (abs(s1) + 1.) + abs(t2) / (abs(s2) + 1.);
  242. if (s > tol) {
  243. goto L100;
  244. }
  245. L110:
  246. s2 *= rx;
  247. if (koded == 1) {
  248. goto L170;
  249. }
  250. f = exp(*x);
  251. s1 *= f;
  252. s2 *= f;
  253. goto L170;
  254. L120:
  255. coef = rthpi / sqrt(*x);
  256. if (koded == 2) {
  257. goto L130;
  258. }
  259. if (*x > elim) {
  260. goto L330;
  261. }
  262. coef *= exp(-(*x));
  263. L130:
  264. if (abs(dnu) == .5) {
  265. goto L340;
  266. }
  267. if (*x > x2) {
  268. goto L280;
  269. }
  270. /* MILLER ALGORITHM FOR X1.LT.X.LE.X2 */
  271. etest = cos(pi * dnu) / (pi * *x * tol);
  272. fks = 1.;
  273. fhs = .25;
  274. fk = 0.;
  275. ck = *x + *x + 2.;
  276. p1 = 0.;
  277. p2 = 1.;
  278. k = 0;
  279. L140:
  280. ++k;
  281. fk += 1.;
  282. ak = (fhs - dnu2) / (fks + fk);
  283. bk = ck / (fk + 1.);
  284. pt = p2;
  285. p2 = bk * p2 - ak * p1;
  286. p1 = pt;
  287. a[k - 1] = ak;
  288. b[k - 1] = bk;
  289. ck += 2.;
  290. fks = fks + fk + fk + 1.;
  291. fhs = fhs + fk + fk;
  292. if (etest > fk * p1) {
  293. goto L140;
  294. }
  295. kk = k;
  296. s = 1.;
  297. p1 = 0.;
  298. p2 = 1.;
  299. i__1 = k;
  300. for (i__ = 1; i__ <= i__1; ++i__) {
  301. pt = p2;
  302. p2 = (b[kk - 1] * p2 - p1) / a[kk - 1];
  303. p1 = pt;
  304. s += p2;
  305. --kk;
  306. /* L150: */
  307. }
  308. s1 = coef * (p2 / s);
  309. if (inu > 0 || *n > 1) {
  310. goto L160;
  311. }
  312. goto L200;
  313. L160:
  314. s2 = s1 * (*x + dnu + .5 - p1 / p2) / *x;
  315. /* FORWARD RECURSION ON THE THREE TERM RECURSION RELATION */
  316. L170:
  317. ck = (dnu + dnu + 2.) / *x;
  318. if (*n == 1) {
  319. --inu;
  320. }
  321. if (inu > 0) {
  322. goto L180;
  323. }
  324. if (*n > 1) {
  325. goto L200;
  326. }
  327. s1 = s2;
  328. goto L200;
  329. L180:
  330. i__1 = inu;
  331. for (i__ = 1; i__ <= i__1; ++i__) {
  332. st = s2;
  333. s2 = ck * s2 + s1;
  334. s1 = st;
  335. ck += rx;
  336. /* L190: */
  337. }
  338. if (*n == 1) {
  339. s1 = s2;
  340. }
  341. L200:
  342. if (iflag == 1) {
  343. goto L220;
  344. }
  345. y[1] = s1;
  346. if (*n == 1) {
  347. return 0;
  348. }
  349. y[2] = s2;
  350. if (*n == 2) {
  351. return 0;
  352. }
  353. i__1 = *n;
  354. for (i__ = 3; i__ <= i__1; ++i__) {
  355. y[i__] = ck * y[i__ - 1] + y[i__ - 2];
  356. ck += rx;
  357. /* L210: */
  358. }
  359. return 0;
  360. /* IFLAG=1 CASES */
  361. L220:
  362. s = -(*x) + log(s1);
  363. y[1] = 0.;
  364. *nz = 1;
  365. if (s < -elim) {
  366. goto L230;
  367. }
  368. y[1] = exp(s);
  369. *nz = 0;
  370. L230:
  371. if (*n == 1) {
  372. return 0;
  373. }
  374. s = -(*x) + log(s2);
  375. y[2] = 0.;
  376. ++(*nz);
  377. if (s < -elim) {
  378. goto L240;
  379. }
  380. --(*nz);
  381. y[2] = exp(s);
  382. L240:
  383. if (*n == 2) {
  384. return 0;
  385. }
  386. kk = 2;
  387. if (*nz < 2) {
  388. goto L260;
  389. }
  390. i__1 = *n;
  391. for (i__ = 3; i__ <= i__1; ++i__) {
  392. kk = i__;
  393. st = s2;
  394. s2 = ck * s2 + s1;
  395. s1 = st;
  396. ck += rx;
  397. s = -(*x) + log(s2);
  398. ++(*nz);
  399. y[i__] = 0.;
  400. if (s < -elim) {
  401. goto L250;
  402. }
  403. y[i__] = exp(s);
  404. --(*nz);
  405. goto L260;
  406. L250:
  407. ;
  408. }
  409. return 0;
  410. L260:
  411. if (kk == *n) {
  412. return 0;
  413. }
  414. s2 = s2 * ck + s1;
  415. ck += rx;
  416. ++kk;
  417. y[kk] = exp(-(*x) + log(s2));
  418. if (kk == *n) {
  419. return 0;
  420. }
  421. ++kk;
  422. i__1 = *n;
  423. for (i__ = kk; i__ <= i__1; ++i__) {
  424. y[i__] = ck * y[i__ - 1] + y[i__ - 2];
  425. ck += rx;
  426. /* L270: */
  427. }
  428. return 0;
  429. /* ASYMPTOTIC EXPANSION FOR LARGE X, X.GT.X2 */
  430. /* IFLAG=0 MEANS NO UNDERFLOW OCCURRED */
  431. /* IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH */
  432. /* KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD */
  433. /* RECURSION */
  434. L280:
  435. nn = 2;
  436. if (inu == 0 && *n == 1) {
  437. nn = 1;
  438. }
  439. dnu2 = dnu + dnu;
  440. fmu = 0.;
  441. if (abs(dnu2) < tol) {
  442. goto L290;
  443. }
  444. fmu = dnu2 * dnu2;
  445. L290:
  446. ex = *x * 8.;
  447. s2 = 0.;
  448. i__1 = nn;
  449. for (k = 1; k <= i__1; ++k) {
  450. s1 = s2;
  451. s = 1.;
  452. ak = 0.;
  453. ck = 1.;
  454. sqk = 1.;
  455. dk = ex;
  456. for (j = 1; j <= 30; ++j) {
  457. ck = ck * (fmu - sqk) / dk;
  458. s += ck;
  459. dk += ex;
  460. ak += 8.;
  461. sqk += ak;
  462. if (abs(ck) < tol) {
  463. goto L310;
  464. }
  465. /* L300: */
  466. }
  467. L310:
  468. s2 = s * coef;
  469. fmu = fmu + dnu * 8. + 4.;
  470. /* L320: */
  471. }
  472. if (nn > 1) {
  473. goto L170;
  474. }
  475. s1 = s2;
  476. goto L200;
  477. L330:
  478. koded = 2;
  479. iflag = 1;
  480. goto L120;
  481. /* FNU=HALF ODD INTEGER CASE */
  482. L340:
  483. s1 = coef;
  484. s2 = coef;
  485. goto L170;
  486. L350:
  487. xermsg_("SLATEC", "DBSKNU", "X NOT GREATER THAN ZERO", &c__2, &c__1, (
  488. ftnlen)6, (ftnlen)6, (ftnlen)23);
  489. return 0;
  490. L360:
  491. xermsg_("SLATEC", "DBSKNU", "FNU NOT ZERO OR POSITIVE", &c__2, &c__1, (
  492. ftnlen)6, (ftnlen)6, (ftnlen)24);
  493. return 0;
  494. L370:
  495. xermsg_("SLATEC", "DBSKNU", "KODE NOT 1 OR 2", &c__2, &c__1, (ftnlen)6, (
  496. ftnlen)6, (ftnlen)15);
  497. return 0;
  498. L380:
  499. xermsg_("SLATEC", "DBSKNU", "N NOT GREATER THAN 0", &c__2, &c__1, (ftnlen)
  500. 6, (ftnlen)6, (ftnlen)20);
  501. return 0;
  502. } /* dbsknu_ */