00001 00004 /* zbesi.f -- translated by f2c (version 19980516). 00005 You must link the resulting object file with the libraries: 00006 -lf2c -lm (in that order) 00007 */ 00008 00009 /* $Id: zbesi.c,v 1.2.2.3 2008/07/18 17:16:01 garloff Exp $ */ 00010 00011 #include "prototypes.h" 00012 #include "prototypes2.h" 00013 00014 /* Table of constant values */ 00015 00016 static integer c__4 = 4; 00017 static integer c__15 = 15; 00018 static integer c__16 = 16; 00019 static integer c__5 = 5; 00020 static integer c__14 = 14; 00021 static integer c__9 = 9; 00022 static integer c__1 = 1; 00023 00024 /* Subroutine */ int zbesi_(doublereal *zr, doublereal *zi, doublereal *fnu, integer *kode, integer *n, doublereal *cyr, doublereal *cyi, integer *nz, integer *ierr) 00025 { 00026 /* Initialized data */ 00027 00028 static doublereal pi = 3.14159265358979324; 00029 static doublereal coner = 1.; 00030 static doublereal conei = 0.; 00031 00032 /* System generated locals */ 00033 integer i__1, i__2; 00034 doublereal d__1, d__2; 00035 00036 /* Builtin functions */ 00037 double sqrt(double), cos(double), sin(double); 00038 00039 /* Local variables */ 00040 static doublereal alim, elim, atol, fnul, rtol; 00041 static integer i__, k; 00042 static doublereal ascle, csgni, csgnr; 00043 extern /* Subroutine */ int zbinu_(doublereal *zr, doublereal *zi, doublereal *fnu, integer *kode, integer *n, doublereal *cyr, doublereal *cyi, integer *nz, doublereal *rl, doublereal *fnul, doublereal *tol, doublereal *elim, doublereal *alim); 00044 static integer k1; 00045 extern doublereal d1mach_(integer*); 00046 static integer k2; 00047 extern integer i1mach_(integer*); 00048 static doublereal aa, bb, fn, az; 00049 static integer nn; 00050 static doublereal rl; 00051 extern doublereal myzabs_(doublereal *zr, doublereal *zi); 00052 static doublereal dig, arg, r1m5; 00053 static integer inu; 00054 static doublereal tol, sti, zni, str, znr; 00055 00056 /* ***BEGIN PROLOGUE ZBESI */ 00057 /* ***DATE WRITTEN 830501 (YYMMDD) */ 00058 /* ***REVISION DATE 890801 (YYMMDD) */ 00059 /* ***CATEGORY NO. B5K */ 00060 /* ***KEYWORDS I-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION, */ 00061 /* MODIFIED BESSEL FUNCTION OF THE FIRST KIND */ 00062 /* ***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES */ 00063 /* ***PURPOSE TO COMPUTE I-BESSEL FUNCTIONS OF COMPLEX ARGUMENT */ 00064 /* ***DESCRIPTION */ 00065 00066 /* ***A DOUBLE PRECISION ROUTINE*** */ 00067 /* ON KODE=1, ZBESI COMPUTES AN N MEMBER SEQUENCE OF COMPLEX */ 00068 /* BESSEL FUNCTIONS CY(J)=I(FNU+J-1,Z) FOR REAL, NONNEGATIVE */ 00069 /* ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z IN THE CUT PLANE */ 00070 /* -PI.LT.ARG(Z).LE.PI. ON KODE=2, ZBESI RETURNS THE SCALED */ 00071 /* FUNCTIONS */ 00072 00073 /* CY(J)=EXP(-ABS(X))*I(FNU+J-1,Z) J = 1,...,N , X=REAL(Z) */ 00074 00075 /* WITH THE EXPONENTIAL GROWTH REMOVED IN BOTH THE LEFT AND */ 00076 /* RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION */ 00077 /* ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS */ 00078 /* (REF. 1). */ 00079 00080 /* INPUT ZR,ZI,FNU ARE DOUBLE PRECISION */ 00081 /* ZR,ZI - Z=CMPLX(ZR,ZI), -PI.LT.ARG(Z).LE.PI */ 00082 /* FNU - ORDER OF INITIAL I FUNCTION, FNU.GE.0.0D0 */ 00083 /* KODE - A PARAMETER TO INDICATE THE SCALING OPTION */ 00084 /* KODE= 1 RETURNS */ 00085 /* CY(J)=I(FNU+J-1,Z), J=1,...,N */ 00086 /* = 2 RETURNS */ 00087 /* CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X)), J=1,...,N */ 00088 /* N - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1 */ 00089 00090 /* OUTPUT CYR,CYI ARE DOUBLE PRECISION */ 00091 /* CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS */ 00092 /* CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE */ 00093 /* CY(J)=I(FNU+J-1,Z) OR */ 00094 /* CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X)) J=1,...,N */ 00095 /* DEPENDING ON KODE, X=REAL(Z) */ 00096 /* NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW, */ 00097 /* NZ= 0 , NORMAL RETURN */ 00098 /* NZ.GT.0 , LAST NZ COMPONENTS OF CY SET TO ZERO */ 00099 /* TO UNDERFLOW, CY(J)=CMPLX(0.0D0,0.0D0) */ 00100 /* J = N-NZ+1,...,N */ 00101 /* IERR - ERROR FLAG */ 00102 /* IERR=0, NORMAL RETURN - COMPUTATION COMPLETED */ 00103 /* IERR=1, INPUT ERROR - NO COMPUTATION */ 00104 /* IERR=2, OVERFLOW - NO COMPUTATION, REAL(Z) TOO */ 00105 /* LARGE ON KODE=1 */ 00106 /* IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE */ 00107 /* BUT LOSSES OF SIGNIFCANCE BY ARGUMENT */ 00108 /* REDUCTION PRODUCE LESS THAN HALF OF MACHINE */ 00109 /* ACCURACY */ 00110 /* IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- */ 00111 /* TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- */ 00112 /* CANCE BY ARGUMENT REDUCTION */ 00113 /* IERR=5, ERROR - NO COMPUTATION, */ 00114 /* ALGORITHM TERMINATION CONDITION NOT MET */ 00115 00116 /* ***LONG DESCRIPTION */ 00117 00118 /* THE COMPUTATION IS CARRIED OUT BY THE POWER SERIES FOR */ 00119 /* SMALL CABS(Z), THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z), */ 00120 /* THE MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN AND A */ 00121 /* NEUMANN SERIES FOR IMTERMEDIATE MAGNITUDES, AND THE */ 00122 /* UNIFORM ASYMPTOTIC EXPANSIONS FOR I(FNU,Z) AND J(FNU,Z) */ 00123 /* FOR LARGE ORDERS. BACKWARD RECURRENCE IS USED TO GENERATE */ 00124 /* SEQUENCES OR REDUCE ORDERS WHEN NECESSARY. */ 00125 00126 /* THE CALCULATIONS ABOVE ARE DONE IN THE RIGHT HALF PLANE AND */ 00127 /* CONTINUED INTO THE LEFT HALF PLANE BY THE FORMULA */ 00128 00129 /* I(FNU,Z*EXP(M*PI)) = EXP(M*PI*FNU)*I(FNU,Z) REAL(Z).GT.0.0 */ 00130 /* M = +I OR -I, I**2=-1 */ 00131 00132 /* FOR NEGATIVE ORDERS,THE FORMULA */ 00133 00134 /* I(-FNU,Z) = I(FNU,Z) + (2/PI)*SIN(PI*FNU)*K(FNU,Z) */ 00135 00136 /* CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE */ 00137 /* THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE */ 00138 /* INTEGER,THE MAGNITUDE OF I(-FNU,Z)=I(FNU,Z) IS A LARGE */ 00139 /* NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER, */ 00140 /* K(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF */ 00141 /* TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY */ 00142 /* UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN */ 00143 /* OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE, */ 00144 /* LARGE MEANS FNU.GT.CABS(Z). */ 00145 00146 /* IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- */ 00147 /* MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS */ 00148 /* LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. */ 00149 /* CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN */ 00150 /* LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG */ 00151 /* IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS */ 00152 /* DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. */ 00153 /* IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS */ 00154 /* LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS */ 00155 /* MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE */ 00156 /* INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS */ 00157 /* RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 */ 00158 /* ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION */ 00159 /* ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION */ 00160 /* ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN */ 00161 /* THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT */ 00162 /* TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS */ 00163 /* IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. */ 00164 /* SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. */ 00165 00166 /* THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX */ 00167 /* BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT */ 00168 /* ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- */ 00169 /* SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE */ 00170 /* ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), */ 00171 /* ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF */ 00172 /* CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY */ 00173 /* HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN */ 00174 /* ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY */ 00175 /* SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER */ 00176 /* THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, */ 00177 /* 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS */ 00178 /* THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER */ 00179 /* COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY */ 00180 /* BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER */ 00181 /* COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE */ 00182 /* MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, */ 00183 /* THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, */ 00184 /* OR -PI/2+P. */ 00185 00186 /* ***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ */ 00187 /* AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF */ 00188 /* COMMERCE, 1955. */ 00189 00190 /* COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT */ 00191 /* BY D. E. AMOS, SAND83-0083, MAY, 1983. */ 00192 00193 /* COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT */ 00194 /* AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 */ 00195 00196 /* A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX */ 00197 /* ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- */ 00198 /* 1018, MAY, 1985 */ 00199 00200 /* A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX */ 00201 /* ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. */ 00202 /* MATH. SOFTWARE, 1986 */ 00203 00204 /* ***ROUTINES CALLED ZBINU,I1MACH,D1MACH */ 00205 /* ***END PROLOGUE ZBESI */ 00206 /* COMPLEX CONE,CSGN,CW,CY,CZERO,Z,ZN */ 00207 /* Parameter adjustments */ 00208 --cyi; 00209 --cyr; 00210 00211 /* Function Body */ 00212 00213 /* ***FIRST EXECUTABLE STATEMENT ZBESI */ 00214 *ierr = 0; 00215 *nz = 0; 00216 if (*fnu < 0.) { 00217 *ierr = 1; 00218 } 00219 if (*kode < 1 || *kode > 2) { 00220 *ierr = 1; 00221 } 00222 if (*n < 1) { 00223 *ierr = 1; 00224 } 00225 if (*ierr != 0) { 00226 return 0; 00227 } 00228 /* ----------------------------------------------------------------------- */ 00229 /* SET PARAMETERS RELATED TO MACHINE CONSTANTS. */ 00230 /* TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. */ 00231 /* ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. */ 00232 /* EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND */ 00233 /* EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR */ 00234 /* UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. */ 00235 /* RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. */ 00236 /* DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). */ 00237 /* FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU. */ 00238 /* ----------------------------------------------------------------------- */ 00239 /* Computing MAX */ 00240 d__1 = d1mach_(&c__4); 00241 tol = max(d__1,1e-18); 00242 k1 = i1mach_(&c__15); 00243 k2 = i1mach_(&c__16); 00244 r1m5 = d1mach_(&c__5); 00245 /* Computing MIN */ 00246 i__1 = abs(k1), i__2 = abs(k2); 00247 k = min(i__1,i__2); 00248 elim = ((doublereal) ((real) k) * r1m5 - 3.) * 2.303; 00249 k1 = i1mach_(&c__14) - 1; 00250 aa = r1m5 * (doublereal) ((real) k1); 00251 dig = min(aa,18.); 00252 aa *= 2.303; 00253 /* Computing MAX */ 00254 d__1 = -aa; 00255 alim = elim + max(d__1,-41.45); 00256 rl = dig * 1.2 + 3.; 00257 fnul = (dig - 3.) * 6. + 10.; 00258 /* ----------------------------------------------------------------------------- */ 00259 /* TEST FOR PROPER RANGE */ 00260 /* ----------------------------------------------------------------------- */ 00261 az = myzabs_(zr, zi); 00262 fn = *fnu + (doublereal) ((real) (*n - 1)); 00263 aa = .5 / tol; 00264 bb = (doublereal) ((real) i1mach_(&c__9)) * .5; 00265 aa = min(aa,bb); 00266 if (az > aa) { 00267 goto L260; 00268 } 00269 if (fn > aa) { 00270 goto L260; 00271 } 00272 aa = sqrt(aa); 00273 if (az > aa) { 00274 *ierr = 3; 00275 } 00276 if (fn > aa) { 00277 *ierr = 3; 00278 } 00279 znr = *zr; 00280 zni = *zi; 00281 csgnr = coner; 00282 csgni = conei; 00283 if (*zr >= 0.) { 00284 goto L40; 00285 } 00286 znr = -(*zr); 00287 zni = -(*zi); 00288 /* ----------------------------------------------------------------------- */ 00289 /* CALCULATE CSGN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE */ 00290 /* WHEN FNU IS LARGE */ 00291 /* ----------------------------------------------------------------------- */ 00292 inu = (integer) ((real) (*fnu)); 00293 arg = (*fnu - (doublereal) ((real) inu)) * pi; 00294 if (*zi < 0.) { 00295 arg = -arg; 00296 } 00297 csgnr = cos(arg); 00298 csgni = sin(arg); 00299 if (inu % 2 == 0) { 00300 goto L40; 00301 } 00302 csgnr = -csgnr; 00303 csgni = -csgni; 00304 L40: 00305 zbinu_(&znr, &zni, fnu, kode, n, &cyr[1], &cyi[1], nz, &rl, &fnul, &tol, & 00306 elim, &alim); 00307 if (*nz < 0) { 00308 goto L120; 00309 } 00310 if (*zr >= 0.) { 00311 return 0; 00312 } 00313 /* ----------------------------------------------------------------------- */ 00314 /* ANALYTIC CONTINUATION TO THE LEFT HALF PLANE */ 00315 /* ----------------------------------------------------------------------- */ 00316 nn = *n - *nz; 00317 if (nn == 0) { 00318 return 0; 00319 } 00320 rtol = 1. / tol; 00321 ascle = d1mach_(&c__1) * rtol * 1e3; 00322 i__1 = nn; 00323 for (i__ = 1; i__ <= i__1; ++i__) { 00324 /* STR = CYR(I)*CSGNR - CYI(I)*CSGNI */ 00325 /* CYI(I) = CYR(I)*CSGNI + CYI(I)*CSGNR */ 00326 /* CYR(I) = STR */ 00327 aa = cyr[i__]; 00328 bb = cyi[i__]; 00329 atol = 1.; 00330 /* Computing MAX */ 00331 d__1 = abs(aa), d__2 = abs(bb); 00332 if (max(d__1,d__2) > ascle) { 00333 goto L55; 00334 } 00335 aa *= rtol; 00336 bb *= rtol; 00337 atol = tol; 00338 L55: 00339 str = aa * csgnr - bb * csgni; 00340 sti = aa * csgni + bb * csgnr; 00341 cyr[i__] = str * atol; 00342 cyi[i__] = sti * atol; 00343 csgnr = -csgnr; 00344 csgni = -csgni; 00345 /* L50: */ 00346 } 00347 return 0; 00348 L120: 00349 if (*nz == -2) { 00350 goto L130; 00351 } 00352 *nz = 0; 00353 *ierr = 2; 00354 return 0; 00355 L130: 00356 *nz = 0; 00357 *ierr = 5; 00358 return 0; 00359 L260: 00360 *nz = 0; 00361 *ierr = 4; 00362 return 0; 00363 } /* zbesi_ */ 00364
1.5.6