zairy.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /* zairy.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__4 = 4;
  7. static integer const c__15 = 15;
  8. static integer const c__16 = 16;
  9. static integer const c__5 = 5;
  10. static integer const c__14 = 14;
  11. static integer const c__9 = 9;
  12. static integer const c__1 = 1;
  13. int zairy_(double *zr, double *zi, integer const *id,
  14. integer const *kode, double *air, double *aii, integer *nz, integer
  15. *ierr)
  16. {
  17. /* Initialized data */
  18. static double const tth = .666666666666666667;
  19. static double const c1 = .35502805388781724;
  20. static double const c2 = .258819403792806799;
  21. static double const coef = .183776298473930683;
  22. static double const zeror = 0.;
  23. static double const zeroi = 0.;
  24. static double const coner = 1.;
  25. static double const conei = 0.;
  26. /* System generated locals */
  27. integer i__1, i__2;
  28. double d__1;
  29. /* Local variables */
  30. integer k;
  31. double d1, d2;
  32. integer k1, k2;
  33. double aa, bb, ad, cc, ak, bk, ck, dk, az;
  34. integer nn;
  35. double rl;
  36. integer mr;
  37. double s1i, az3, s2i, s1r, s2r, z3i, z3r, dig, fid, cyi[1], r1m5, fnu,
  38. cyr[1], tol, sti, ptr, str, sfac, alim, elim, alaz, csqi;
  39. double atrm, ztai, csqr, ztar;
  40. double trm1i, trm2i, trm1r, trm2r;
  41. integer iflag;
  42. /* ***BEGIN PROLOGUE ZAIRY */
  43. /* ***PURPOSE Compute the Airy function Ai(z) or its derivative dAi/dz */
  44. /* for complex argument z. A scaling option is available */
  45. /* to help avoid underflow and overflow. */
  46. /* ***LIBRARY SLATEC */
  47. /* ***CATEGORY C10D */
  48. /* ***TYPE COMPLEX (CAIRY-C, ZAIRY-C) */
  49. /* ***KEYWORDS AIRY FUNCTION, BESSEL FUNCTION OF ORDER ONE THIRD, */
  50. /* BESSEL FUNCTION OF ORDER TWO THIRDS */
  51. /* ***AUTHOR Amos, D. E., (SNL) */
  52. /* ***DESCRIPTION */
  53. /* ***A DOUBLE PRECISION ROUTINE*** */
  54. /* On KODE=1, ZAIRY computes the complex Airy function Ai(z) */
  55. /* or its derivative dAi/dz on ID=0 or ID=1 respectively. On */
  56. /* KODE=2, a scaling option exp(zeta)*Ai(z) or exp(zeta)*dAi/dz */
  57. /* is provided to remove the exponential decay in -pi/3<arg(z) */
  58. /* <pi/3 and the exponential growth in pi/3<abs(arg(z))<pi where */
  59. /* zeta=(2/3)*z**(3/2). */
  60. /* While the Airy functions Ai(z) and dAi/dz are analytic in */
  61. /* the whole z-plane, the corresponding scaled functions defined */
  62. /* for KODE=2 have a cut along the negative real axis. */
  63. /* Input */
  64. /* ZR - DOUBLE PRECISION REAL part of argument Z */
  65. /* ZI - DOUBLE PRECISION imag part of argument Z */
  66. /* ID - Order of derivative, ID=0 or ID=1 */
  67. /* KODE - A parameter to indicate the scaling option */
  68. /* KODE=1 returns */
  69. /* AI=Ai(z) on ID=0 */
  70. /* AI=dAi/dz on ID=1 */
  71. /* at z=Z */
  72. /* =2 returns */
  73. /* AI=exp(zeta)*Ai(z) on ID=0 */
  74. /* AI=exp(zeta)*dAi/dz on ID=1 */
  75. /* at z=Z where zeta=(2/3)*z**(3/2) */
  76. /* Output */
  77. /* AIR - DOUBLE PRECISION REAL part of result */
  78. /* AII - DOUBLE PRECISION imag part of result */
  79. /* NZ - Underflow indicator */
  80. /* NZ=0 Normal return */
  81. /* NZ=1 AI=0 due to underflow in */
  82. /* -pi/3<arg(Z)<pi/3 on KODE=1 */
  83. /* IERR - Error flag */
  84. /* IERR=0 Normal return - COMPUTATION COMPLETED */
  85. /* IERR=1 Input error - NO COMPUTATION */
  86. /* IERR=2 Overflow - NO COMPUTATION */
  87. /* (Re(Z) too large with KODE=1) */
  88. /* IERR=3 Precision warning - COMPUTATION COMPLETED */
  89. /* (Result has less than half precision) */
  90. /* IERR=4 Precision error - NO COMPUTATION */
  91. /* (Result has no precision) */
  92. /* IERR=5 Algorithmic error - NO COMPUTATION */
  93. /* (Termination condition not met) */
  94. /* *Long Description: */
  95. /* Ai(z) and dAi/dz are computed from K Bessel functions by */
  96. /* Ai(z) = c*sqrt(z)*K(1/3,zeta) */
  97. /* dAi/dz = -c* z *K(2/3,zeta) */
  98. /* c = 1/(pi*sqrt(3)) */
  99. /* zeta = (2/3)*z**(3/2) */
  100. /* when abs(z)>1 and from power series when abs(z)<=1. */
  101. /* In most complex variable computation, one must evaluate ele- */
  102. /* mentary functions. When the magnitude of Z is large, losses */
  103. /* of significance by argument reduction occur. Consequently, if */
  104. /* the magnitude of ZETA=(2/3)*Z**(3/2) exceeds U1=SQRT(0.5/UR), */
  105. /* then losses exceeding half precision are likely and an error */
  106. /* flag IERR=3 is triggered where UR=MAX(D1MACH(4),1.0D-18) is */
  107. /* double precision unit roundoff limited to 18 digits precision. */
  108. /* Also, if the magnitude of ZETA is larger than U2=0.5/UR, then */
  109. /* all significance is lost and IERR=4. In order to use the INT */
  110. /* function, ZETA must be further restricted not to exceed */
  111. /* U3=I1MACH(9)=LARGEST INTEGER. Thus, the magnitude of ZETA */
  112. /* must be restricted by MIN(U2,U3). In IEEE arithmetic, U1,U2, */
  113. /* and U3 are approximately 2.0E+3, 4.2E+6, 2.1E+9 in single */
  114. /* precision and 4.7E+7, 2.3E+15, 2.1E+9 in double precision. */
  115. /* This makes U2 limiting is single precision and U3 limiting */
  116. /* in double precision. This means that the magnitude of Z */
  117. /* cannot exceed approximately 3.4E+4 in single precision and */
  118. /* 2.1E+6 in double precision. This also means that one can */
  119. /* expect to retain, in the worst cases on 32-bit machines, */
  120. /* no digits in single precision and only 6 digits in double */
  121. /* precision. */
  122. /* The approximate relative error in the magnitude of a complex */
  123. /* Bessel function can be expressed as P*10**S where P=MAX(UNIT */
  124. /* ROUNDOFF,1.0E-18) is the nominal precision and 10**S repre- */
  125. /* sents the increase in error due to argument reduction in the */
  126. /* elementary functions. Here, S=MAX(1,ABS(LOG10(ABS(Z))), */
  127. /* ABS(LOG10(FNU))) approximately (i.e., S=MAX(1,ABS(EXPONENT OF */
  128. /* ABS(Z),ABS(EXPONENT OF FNU)) ). However, the phase angle may */
  129. /* have only absolute accuracy. This is most likely to occur */
  130. /* when one component (in magnitude) is larger than the other by */
  131. /* several orders of magnitude. If one component is 10**K larger */
  132. /* than the other, then one can expect only MAX(ABS(LOG10(P))-K, */
  133. /* 0) significant digits; or, stated another way, when K exceeds */
  134. /* the exponent of P, no significant digits remain in the smaller */
  135. /* component. However, the phase angle retains absolute accuracy */
  136. /* because, in complex arithmetic with precision P, the smaller */
  137. /* component will not (as a rule) decrease below P times the */
  138. /* magnitude of the larger component. In these extreme cases, */
  139. /* the principal phase angle is on the order of +P, -P, PI/2-P, */
  140. /* or -PI/2+P. */
  141. /* ***REFERENCES 1. M. Abramowitz and I. A. Stegun, Handbook of Mathe- */
  142. /* matical Functions, National Bureau of Standards */
  143. /* Applied Mathematics Series 55, U. S. Department */
  144. /* of Commerce, Tenth Printing (1972) or later. */
  145. /* 2. D. E. Amos, Computation of Bessel Functions of */
  146. /* Complex Argument and Large Order, Report SAND83-0643, */
  147. /* Sandia National Laboratories, Albuquerque, NM, May */
  148. /* 1983. */
  149. /* 3. D. E. Amos, A Subroutine Package for Bessel Functions */
  150. /* of a Complex Argument and Nonnegative Order, Report */
  151. /* SAND85-1018, Sandia National Laboratory, Albuquerque, */
  152. /* NM, May 1985. */
  153. /* 4. D. E. Amos, A portable package for Bessel functions */
  154. /* of a complex argument and nonnegative order, ACM */
  155. /* Transactions on Mathematical Software, 12 (September */
  156. /* 1986), pp. 265-273. */
  157. /* ***ROUTINES CALLED D1MACH, I1MACH, ZABS, ZACAI, ZBKNU, ZEXP, ZSQRT */
  158. /* ***REVISION HISTORY (YYMMDD) */
  159. /* 830501 DATE WRITTEN */
  160. /* 890801 REVISION DATE from Version 3.2 */
  161. /* 910415 Prologue converted to Version 4.0 format. (BAB) */
  162. /* 920128 Category corrected. (WRB) */
  163. /* 920811 Prologue revised. (DWL) */
  164. /* 930122 Added ZEXP and ZSQRT to EXTERNAL statement. (RWC) */
  165. /* ***END PROLOGUE ZAIRY */
  166. /* COMPLEX AI,CONE,CSQ,CY,S1,S2,TRM1,TRM2,Z,ZTA,Z3 */
  167. /* ***FIRST EXECUTABLE STATEMENT ZAIRY */
  168. *ierr = 0;
  169. *nz = 0;
  170. if (*id < 0 || *id > 1) {
  171. *ierr = 1;
  172. }
  173. if (*kode < 1 || *kode > 2) {
  174. *ierr = 1;
  175. }
  176. if (*ierr != 0) {
  177. return 0;
  178. }
  179. az = zabs_(zr, zi);
  180. /* Computing MAX */
  181. d__1 = d1mach_(4);
  182. tol = max(d__1,1e-18);
  183. fid = (double) (*id);
  184. if (az > 1.) {
  185. goto L70;
  186. }
  187. /* ----------------------------------------------------------------------- */
  188. /* POWER SERIES FOR ABS(Z).LE.1. */
  189. /* ----------------------------------------------------------------------- */
  190. s1r = coner;
  191. s1i = conei;
  192. s2r = coner;
  193. s2i = conei;
  194. if (az < tol) {
  195. goto L170;
  196. }
  197. aa = az * az;
  198. if (aa < tol / az) {
  199. goto L40;
  200. }
  201. trm1r = coner;
  202. trm1i = conei;
  203. trm2r = coner;
  204. trm2i = conei;
  205. atrm = 1.;
  206. str = *zr * *zr - *zi * *zi;
  207. sti = *zr * *zi + *zi * *zr;
  208. z3r = str * *zr - sti * *zi;
  209. z3i = str * *zi + sti * *zr;
  210. az3 = az * aa;
  211. ak = fid + 2.;
  212. bk = 3. - fid - fid;
  213. ck = 4. - fid;
  214. dk = fid + 3. + fid;
  215. d1 = ak * dk;
  216. d2 = bk * ck;
  217. ad = min(d1,d2);
  218. ak = fid * 9. + 24.;
  219. bk = 30. - fid * 9.;
  220. for (k = 1; k <= 25; ++k) {
  221. str = (trm1r * z3r - trm1i * z3i) / d1;
  222. trm1i = (trm1r * z3i + trm1i * z3r) / d1;
  223. trm1r = str;
  224. s1r += trm1r;
  225. s1i += trm1i;
  226. str = (trm2r * z3r - trm2i * z3i) / d2;
  227. trm2i = (trm2r * z3i + trm2i * z3r) / d2;
  228. trm2r = str;
  229. s2r += trm2r;
  230. s2i += trm2i;
  231. atrm = atrm * az3 / ad;
  232. d1 += ak;
  233. d2 += bk;
  234. ad = min(d1,d2);
  235. if (atrm < tol * ad) {
  236. goto L40;
  237. }
  238. ak += 18.;
  239. bk += 18.;
  240. /* L30: */
  241. }
  242. L40:
  243. if (*id == 1) {
  244. goto L50;
  245. }
  246. *air = s1r * c1 - c2 * (*zr * s2r - *zi * s2i);
  247. *aii = s1i * c1 - c2 * (*zr * s2i + *zi * s2r);
  248. if (*kode == 1) {
  249. return 0;
  250. }
  251. zsqrt_(zr, zi, &str, &sti);
  252. ztar = tth * (*zr * str - *zi * sti);
  253. ztai = tth * (*zr * sti + *zi * str);
  254. zexp_(&ztar, &ztai, &str, &sti);
  255. ptr = *air * str - *aii * sti;
  256. *aii = *air * sti + *aii * str;
  257. *air = ptr;
  258. return 0;
  259. L50:
  260. *air = -s2r * c2;
  261. *aii = -s2i * c2;
  262. if (az <= tol) {
  263. goto L60;
  264. }
  265. str = *zr * s1r - *zi * s1i;
  266. sti = *zr * s1i + *zi * s1r;
  267. cc = c1 / (fid + 1.);
  268. *air += cc * (str * *zr - sti * *zi);
  269. *aii += cc * (str * *zi + sti * *zr);
  270. L60:
  271. if (*kode == 1) {
  272. return 0;
  273. }
  274. zsqrt_(zr, zi, &str, &sti);
  275. ztar = tth * (*zr * str - *zi * sti);
  276. ztai = tth * (*zr * sti + *zi * str);
  277. zexp_(&ztar, &ztai, &str, &sti);
  278. ptr = str * *air - sti * *aii;
  279. *aii = str * *aii + sti * *air;
  280. *air = ptr;
  281. return 0;
  282. /* ----------------------------------------------------------------------- */
  283. /* CASE FOR ABS(Z).GT.1.0 */
  284. /* ----------------------------------------------------------------------- */
  285. L70:
  286. fnu = (fid + 1.) / 3.;
  287. /* ----------------------------------------------------------------------- */
  288. /* SET PARAMETERS RELATED TO MACHINE CONSTANTS. */
  289. /* TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0D-18. */
  290. /* ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. */
  291. /* EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND */
  292. /* EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR */
  293. /* UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. */
  294. /* RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. */
  295. /* DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). */
  296. /* ----------------------------------------------------------------------- */
  297. k1 = i1mach_(15);
  298. k2 = i1mach_(16);
  299. r1m5 = d1mach_(5);
  300. /* Computing MIN */
  301. i__1 = abs(k1), i__2 = abs(k2);
  302. k = min(i__1,i__2);
  303. elim = (k * r1m5 - 3.) * 2.303;
  304. k1 = i1mach_(14) - 1;
  305. aa = r1m5 * k1;
  306. dig = min(aa,18.);
  307. aa *= 2.303;
  308. /* Computing MAX */
  309. d__1 = -aa;
  310. alim = elim + max(d__1,-41.45);
  311. rl = dig * 1.2 + 3.;
  312. alaz = log(az);
  313. /* ----------------------------------------------------------------------- */
  314. /* TEST FOR PROPER RANGE */
  315. /* ----------------------------------------------------------------------- */
  316. aa = .5 / tol;
  317. bb = i1mach_(9) * .5;
  318. aa = min(aa,bb);
  319. aa = f2c::pow_dd(&aa, &tth);
  320. if (az > aa) {
  321. goto L260;
  322. }
  323. aa = sqrt(aa);
  324. if (az > aa) {
  325. *ierr = 3;
  326. }
  327. zsqrt_(zr, zi, &csqr, &csqi);
  328. ztar = tth * (*zr * csqr - *zi * csqi);
  329. ztai = tth * (*zr * csqi + *zi * csqr);
  330. /* ----------------------------------------------------------------------- */
  331. /* RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL */
  332. /* ----------------------------------------------------------------------- */
  333. iflag = 0;
  334. sfac = 1.;
  335. ak = ztai;
  336. if (*zr >= 0.) {
  337. goto L80;
  338. }
  339. bk = ztar;
  340. ck = -abs(bk);
  341. ztar = ck;
  342. ztai = ak;
  343. L80:
  344. if (*zi != 0.) {
  345. goto L90;
  346. }
  347. if (*zr > 0.) {
  348. goto L90;
  349. }
  350. ztar = 0.;
  351. ztai = ak;
  352. L90:
  353. aa = ztar;
  354. if (aa >= 0. && *zr > 0.) {
  355. goto L110;
  356. }
  357. if (*kode == 2) {
  358. goto L100;
  359. }
  360. /* ----------------------------------------------------------------------- */
  361. /* OVERFLOW TEST */
  362. /* ----------------------------------------------------------------------- */
  363. if (aa > -alim) {
  364. goto L100;
  365. }
  366. aa = -aa + alaz * .25;
  367. iflag = 1;
  368. sfac = tol;
  369. if (aa > elim) {
  370. goto L270;
  371. }
  372. L100:
  373. /* ----------------------------------------------------------------------- */
  374. /* CBKNU AND CACON RETURN EXP(ZTA)*K(FNU,ZTA) ON KODE=2 */
  375. /* ----------------------------------------------------------------------- */
  376. mr = 1;
  377. if (*zi < 0.) {
  378. mr = -1;
  379. }
  380. zacai_(&ztar, &ztai, &fnu, kode, &mr, &c__1, cyr, cyi, &nn, &rl, &tol, &
  381. elim, &alim);
  382. if (nn < 0) {
  383. goto L280;
  384. }
  385. *nz += nn;
  386. goto L130;
  387. L110:
  388. if (*kode == 2) {
  389. goto L120;
  390. }
  391. /* ----------------------------------------------------------------------- */
  392. /* UNDERFLOW TEST */
  393. /* ----------------------------------------------------------------------- */
  394. if (aa < alim) {
  395. goto L120;
  396. }
  397. aa = -aa - alaz * .25;
  398. iflag = 2;
  399. sfac = 1. / tol;
  400. if (aa < -elim) {
  401. goto L210;
  402. }
  403. L120:
  404. zbknu_(&ztar, &ztai, &fnu, kode, &c__1, cyr, cyi, nz, &tol, &elim, &alim);
  405. L130:
  406. s1r = cyr[0] * coef;
  407. s1i = cyi[0] * coef;
  408. if (iflag != 0) {
  409. goto L150;
  410. }
  411. if (*id == 1) {
  412. goto L140;
  413. }
  414. *air = csqr * s1r - csqi * s1i;
  415. *aii = csqr * s1i + csqi * s1r;
  416. return 0;
  417. L140:
  418. *air = -(*zr * s1r - *zi * s1i);
  419. *aii = -(*zr * s1i + *zi * s1r);
  420. return 0;
  421. L150:
  422. s1r *= sfac;
  423. s1i *= sfac;
  424. if (*id == 1) {
  425. goto L160;
  426. }
  427. str = s1r * csqr - s1i * csqi;
  428. s1i = s1r * csqi + s1i * csqr;
  429. s1r = str;
  430. *air = s1r / sfac;
  431. *aii = s1i / sfac;
  432. return 0;
  433. L160:
  434. str = -(s1r * *zr - s1i * *zi);
  435. s1i = -(s1r * *zi + s1i * *zr);
  436. s1r = str;
  437. *air = s1r / sfac;
  438. *aii = s1i / sfac;
  439. return 0;
  440. L170:
  441. aa = d1mach_(1) * 1e3;
  442. s1r = zeror;
  443. s1i = zeroi;
  444. if (*id == 1) {
  445. goto L190;
  446. }
  447. if (az <= aa) {
  448. goto L180;
  449. }
  450. s1r = c2 * *zr;
  451. s1i = c2 * *zi;
  452. L180:
  453. *air = c1 - s1r;
  454. *aii = -s1i;
  455. return 0;
  456. L190:
  457. *air = -c2;
  458. *aii = 0.;
  459. aa = sqrt(aa);
  460. if (az <= aa) {
  461. goto L200;
  462. }
  463. s1r = (*zr * *zr - *zi * *zi) * .5;
  464. s1i = *zr * *zi;
  465. L200:
  466. *air += c1 * s1r;
  467. *aii += c1 * s1i;
  468. return 0;
  469. L210:
  470. *nz = 1;
  471. *air = zeror;
  472. *aii = zeroi;
  473. return 0;
  474. L270:
  475. *nz = 0;
  476. *ierr = 2;
  477. return 0;
  478. L280:
  479. if (nn == -1) {
  480. goto L270;
  481. }
  482. *nz = 0;
  483. *ierr = 5;
  484. return 0;
  485. L260:
  486. *ierr = 4;
  487. *nz = 0;
  488. return 0;
  489. } /* zairy_ */