zseri.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* zseri.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__1 = 1;
  7. int zseri_(double *zr, double *zi, double const *fnu,
  8. integer const *kode, integer const *n, double *yr, double *yi, integer *
  9. nz, double *tol, double *elim, double *alim)
  10. {
  11. /* Initialized data */
  12. static double const zeror = 0.;
  13. static double const zeroi = 0.;
  14. static double const coner = 1.;
  15. static double const conei = 0.;
  16. /* System generated locals */
  17. integer i__1;
  18. /* Local variables */
  19. integer i__, k, l, m;
  20. double s, aa;
  21. integer ib;
  22. double ak;
  23. integer il;
  24. double az;
  25. integer nn;
  26. double wi[2], rs, ss;
  27. integer nw;
  28. double wr[2], s1i, s2i, s1r, s2r, cki, acz, arm, ckr, czi, hzi, raz,
  29. czr, sti, hzr, rzi, str, rzr, ak1i, ak1r, rtr1, dfnu;
  30. integer idum;
  31. double atol;
  32. double fnup;
  33. integer iflag;
  34. double coefi, ascle, coefr, crscr;
  35. /* ***BEGIN PROLOGUE ZSERI */
  36. /* ***SUBSIDIARY */
  37. /* ***PURPOSE Subsidiary to ZBESI and ZBESK */
  38. /* ***LIBRARY SLATEC */
  39. /* ***TYPE ALL (CSERI-A, ZSERI-A) */
  40. /* ***AUTHOR Amos, D. E., (SNL) */
  41. /* ***DESCRIPTION */
  42. /* ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY */
  43. /* MEANS OF THE POWER SERIES FOR LARGE ABS(Z) IN THE */
  44. /* REGION ABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN. */
  45. /* NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO */
  46. /* DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE */
  47. /* CONDITION ABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE */
  48. /* COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ). */
  49. /* ***SEE ALSO ZBESI, ZBESK */
  50. /* ***ROUTINES CALLED D1MACH, DGAMLN, ZABS, ZDIV, ZLOG, ZMLT, ZUCHK */
  51. /* ***REVISION HISTORY (YYMMDD) */
  52. /* 830501 DATE WRITTEN */
  53. /* 910415 Prologue converted to Version 4.0 format. (BAB) */
  54. /* 930122 Added ZLOG to EXTERNAL statement. (RWC) */
  55. /* ***END PROLOGUE ZSERI */
  56. /* COMPLEX AK1,CK,COEF,CONE,CRSC,CSCL,CZ,CZERO,HZ,RZ,S1,S2,Y,Z */
  57. /* Parameter adjustments */
  58. --yi;
  59. --yr;
  60. /* Function Body */
  61. /* ***FIRST EXECUTABLE STATEMENT ZSERI */
  62. *nz = 0;
  63. az = zabs_(zr, zi);
  64. if (az == 0.) {
  65. goto L160;
  66. }
  67. arm = d1mach_(1) * 1e3;
  68. rtr1 = sqrt(arm);
  69. crscr = 1.;
  70. iflag = 0;
  71. if (az < arm) {
  72. goto L150;
  73. }
  74. hzr = *zr * .5;
  75. hzi = *zi * .5;
  76. czr = zeror;
  77. czi = zeroi;
  78. if (az <= rtr1) {
  79. goto L10;
  80. }
  81. zmlt_(&hzr, &hzi, &hzr, &hzi, &czr, &czi);
  82. L10:
  83. acz = zabs_(&czr, &czi);
  84. nn = *n;
  85. zlog_(&hzr, &hzi, &ckr, &cki, &idum);
  86. L20:
  87. dfnu = *fnu + (nn - 1);
  88. fnup = dfnu + 1.;
  89. /* ----------------------------------------------------------------------- */
  90. /* UNDERFLOW TEST */
  91. /* ----------------------------------------------------------------------- */
  92. ak1r = ckr * dfnu;
  93. ak1i = cki * dfnu;
  94. ak = dgamln_(&fnup, &idum);
  95. ak1r -= ak;
  96. if (*kode == 2) {
  97. ak1r -= *zr;
  98. }
  99. if (ak1r > -(*elim)) {
  100. goto L40;
  101. }
  102. L30:
  103. ++(*nz);
  104. yr[nn] = zeror;
  105. yi[nn] = zeroi;
  106. if (acz > dfnu) {
  107. goto L190;
  108. }
  109. --nn;
  110. if (nn == 0) {
  111. return 0;
  112. }
  113. goto L20;
  114. L40:
  115. if (ak1r > -(*alim)) {
  116. goto L50;
  117. }
  118. iflag = 1;
  119. ss = 1. / *tol;
  120. crscr = *tol;
  121. ascle = arm * ss;
  122. L50:
  123. aa = exp(ak1r);
  124. if (iflag == 1) {
  125. aa *= ss;
  126. }
  127. coefr = aa * cos(ak1i);
  128. coefi = aa * sin(ak1i);
  129. atol = *tol * acz / fnup;
  130. il = min(2,nn);
  131. i__1 = il;
  132. for (i__ = 1; i__ <= i__1; ++i__) {
  133. dfnu = *fnu + (nn - i__);
  134. fnup = dfnu + 1.;
  135. s1r = coner;
  136. s1i = conei;
  137. if (acz < *tol * fnup) {
  138. goto L70;
  139. }
  140. ak1r = coner;
  141. ak1i = conei;
  142. ak = fnup + 2.;
  143. s = fnup;
  144. aa = 2.;
  145. L60:
  146. rs = 1. / s;
  147. str = ak1r * czr - ak1i * czi;
  148. sti = ak1r * czi + ak1i * czr;
  149. ak1r = str * rs;
  150. ak1i = sti * rs;
  151. s1r += ak1r;
  152. s1i += ak1i;
  153. s += ak;
  154. ak += 2.;
  155. aa = aa * acz * rs;
  156. if (aa > atol) {
  157. goto L60;
  158. }
  159. L70:
  160. s2r = s1r * coefr - s1i * coefi;
  161. s2i = s1r * coefi + s1i * coefr;
  162. wr[i__ - 1] = s2r;
  163. wi[i__ - 1] = s2i;
  164. if (iflag == 0) {
  165. goto L80;
  166. }
  167. zuchk_(&s2r, &s2i, &nw, &ascle, tol);
  168. if (nw != 0) {
  169. goto L30;
  170. }
  171. L80:
  172. m = nn - i__ + 1;
  173. yr[m] = s2r * crscr;
  174. yi[m] = s2i * crscr;
  175. if (i__ == il) {
  176. goto L90;
  177. }
  178. zdiv_(&coefr, &coefi, &hzr, &hzi, &str, &sti);
  179. coefr = str * dfnu;
  180. coefi = sti * dfnu;
  181. L90:
  182. ;
  183. }
  184. if (nn <= 2) {
  185. return 0;
  186. }
  187. k = nn - 2;
  188. ak = (double) k;
  189. raz = 1. / az;
  190. str = *zr * raz;
  191. sti = -(*zi) * raz;
  192. rzr = (str + str) * raz;
  193. rzi = (sti + sti) * raz;
  194. if (iflag == 1) {
  195. goto L120;
  196. }
  197. ib = 3;
  198. L100:
  199. i__1 = nn;
  200. for (i__ = ib; i__ <= i__1; ++i__) {
  201. yr[k] = (ak + *fnu) * (rzr * yr[k + 1] - rzi * yi[k + 1]) + yr[k + 2];
  202. yi[k] = (ak + *fnu) * (rzr * yi[k + 1] + rzi * yr[k + 1]) + yi[k + 2];
  203. ak += -1.;
  204. --k;
  205. /* L110: */
  206. }
  207. return 0;
  208. /* ----------------------------------------------------------------------- */
  209. /* RECUR BACKWARD WITH SCALED VALUES */
  210. /* ----------------------------------------------------------------------- */
  211. L120:
  212. /* ----------------------------------------------------------------------- */
  213. /* EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE */
  214. /* UNDERFLOW LIMIT = ASCLE = D1MACH(1)*SS*1.0D+3 */
  215. /* ----------------------------------------------------------------------- */
  216. s1r = wr[0];
  217. s1i = wi[0];
  218. s2r = wr[1];
  219. s2i = wi[1];
  220. i__1 = nn;
  221. for (l = 3; l <= i__1; ++l) {
  222. ckr = s2r;
  223. cki = s2i;
  224. s2r = s1r + (ak + *fnu) * (rzr * ckr - rzi * cki);
  225. s2i = s1i + (ak + *fnu) * (rzr * cki + rzi * ckr);
  226. s1r = ckr;
  227. s1i = cki;
  228. ckr = s2r * crscr;
  229. cki = s2i * crscr;
  230. yr[k] = ckr;
  231. yi[k] = cki;
  232. ak += -1.;
  233. --k;
  234. if (zabs_(&ckr, &cki) > ascle) {
  235. goto L140;
  236. }
  237. /* L130: */
  238. }
  239. return 0;
  240. L140:
  241. ib = l + 1;
  242. if (ib > nn) {
  243. return 0;
  244. }
  245. goto L100;
  246. L150:
  247. *nz = *n;
  248. if (*fnu == 0.) {
  249. --(*nz);
  250. }
  251. L160:
  252. yr[1] = zeror;
  253. yi[1] = zeroi;
  254. if (*fnu != 0.) {
  255. goto L170;
  256. }
  257. yr[1] = coner;
  258. yi[1] = conei;
  259. L170:
  260. if (*n == 1) {
  261. return 0;
  262. }
  263. i__1 = *n;
  264. for (i__ = 2; i__ <= i__1; ++i__) {
  265. yr[i__] = zeror;
  266. yi[i__] = zeroi;
  267. /* L180: */
  268. }
  269. return 0;
  270. /* ----------------------------------------------------------------------- */
  271. /* RETURN WITH NZ.LT.0 IF ABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE */
  272. /* THE CALCULATION IN CBINU WITH N=N-ABS(NZ) */
  273. /* ----------------------------------------------------------------------- */
  274. L190:
  275. *nz = -(*nz);
  276. return 0;
  277. } /* zseri_ */