GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
cairy.f
Go to the documentation of this file.
1 SUBROUTINE cairy(Z, ID, KODE, AI, NZ, IERR)
2C***BEGIN PROLOGUE CAIRY
3C***DATE WRITTEN 830501 (YYMMDD)
4C***REVISION DATE 890801 (YYMMDD)
5C***CATEGORY NO. B5K
6C***KEYWORDS AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD
7C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES
8C***PURPOSE TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z
9C***DESCRIPTION
10C
11C ON KODE=1, CAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR
12C ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON
13C KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)*
14C DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN
15C -PI/3.LT.ARG(Z).LT.PI/3 AND THE EXPONENTIAL GROWTH IN
16C PI/3.LT.ABS(ARG(Z)).LT.PI WHERE ZTA=(2/3)*Z*CSQRT(Z)
17C
18C WHILE THE AIRY FUNCTIONS AI(Z) AND DAI(Z)/DZ ARE ANALYTIC IN
19C THE WHOLE Z PLANE, THE CORRESPONDING SCALED FUNCTIONS DEFINED
20C FOR KODE=2 HAVE A CUT ALONG THE NEGATIVE REAL AXIS.
21C DEFINITIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF
22C MATHEMATICAL FUNCTIONS (REF. 1).
23C
24C INPUT
25C Z - Z=CMPLX(X,Y)
26C ID - ORDER OF DERIVATIVE, ID=0 OR ID=1
27C KODE - A PARAMETER TO INDICATE THE SCALING OPTION
28C KODE= 1 RETURNS
29C AI=AI(Z) ON ID=0 OR
30C AI=DAI(Z)/DZ ON ID=1
31C = 2 RETURNS
32C AI=CEXP(ZTA)*AI(Z) ON ID=0 OR
33C AI=CEXP(ZTA)*DAI(Z)/DZ ON ID=1 WHERE
34C ZTA=(2/3)*Z*CSQRT(Z)
35C
36C OUTPUT
37C AI - COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND
38C KODE
39C NZ - UNDERFLOW INDICATOR
40C NZ= 0 , NORMAL RETURN
41C NZ= 1 , AI=CMPLX(0.0,0.0) DUE TO UNDERFLOW IN
42C -PI/3.LT.ARG(Z).LT.PI/3 ON KODE=1
43C IERR - ERROR FLAG
44C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
45C IERR=1, INPUT ERROR - NO COMPUTATION
46C IERR=2, OVERFLOW - NO COMPUTATION, REAL(ZTA)
47C TOO LARGE WITH KODE=1.
48C IERR=3, CABS(Z) LARGE - COMPUTATION COMPLETED
49C LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION
50C PRODUCE LESS THAN HALF OF MACHINE ACCURACY
51C IERR=4, CABS(Z) TOO LARGE - NO COMPUTATION
52C COMPLETE LOSS OF ACCURACY BY ARGUMENT
53C REDUCTION
54C IERR=5, ERROR - NO COMPUTATION,
55C ALGORITHM TERMINATION CONDITION NOT MET
56C
57C
58C***LONG DESCRIPTION
59C
60C AI AND DAI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE K BESSEL
61C FUNCTIONS BY
62C
63C AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA)
64C C=1.0/(PI*SQRT(3.0))
65C ZTA=(2/3)*Z**(3/2)
66C
67C WITH THE POWER SERIES FOR CABS(Z).LE.1.0.
68C
69C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE-
70C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES
71C OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF
72C THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR),
73C THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR
74C FLAG IERR=3 IS TRIGGERED WHERE UR=R1MACH(4)=UNIT ROUNDOFF.
75C ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN
76C ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT
77C FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE
78C LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA
79C MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2,
80C AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE
81C PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE
82C PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT-
83C ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG-
84C NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN
85C DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN
86C EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES,
87C NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE
88C PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER
89C MACHINES.
90C
91C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX
92C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT
93C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE-
94C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE
95C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))),
96C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF
97C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY
98C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN
99C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY
100C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER
101C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K,
102C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS
103C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER
104C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY
105C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER
106C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE
107C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES,
108C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P,
109C OR -PI/2+P.
110C
111C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ
112C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF
113C COMMERCE, 1955.
114C
115C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT
116C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983
117C
118C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
119C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85-
120C 1018, MAY, 1985
121C
122C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX
123C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS.
124C MATH. SOFTWARE, 1986
125C
126C***ROUTINES CALLED CACAI,CBKNU,I1MACH,R1MACH
127C***END PROLOGUE CAIRY
128 COMPLEX AI, CONE, CSQ, CY, S1, S2, TRM1, TRM2, Z, ZTA, Z3
129 REAL AA, AD, AK, ALIM, ATRM, AZ, AZ3, BK, CK, COEF, C1, C2, DIG,
130 * DK, D1, D2, ELIM, FID, FNU, RL, R1M5, SFAC, TOL, TTH, ZI, ZR,
131 * Z3I, Z3R, R1MACH, BB, ALAZ
132 INTEGER ID, IERR, IFLAG, K, KODE, K1, K2, MR, NN, NZ, I1MACH
133 dimension cy(1)
134 DATA tth, c1, c2, coef /6.66666666666666667e-01,
135 * 3.55028053887817240e-01,2.58819403792806799e-01,
136 * 1.83776298473930683e-01/
137 DATA cone / (1.0e0,0.0e0) /
138C***FIRST EXECUTABLE STATEMENT CAIRY
139 ierr = 0
140 nz=0
141 IF (id.LT.0 .OR. id.GT.1) ierr=1
142 IF (kode.LT.1 .OR. kode.GT.2) ierr=1
143 IF (ierr.NE.0) RETURN
144 az = cabs(z)
145 tol = amax1(r1mach(4),1.0e-18)
146 fid = float(id)
147 IF (az.GT.1.0e0) GO TO 60
148C-----------------------------------------------------------------------
149C POWER SERIES FOR CABS(Z).LE.1.
150C-----------------------------------------------------------------------
151 s1 = cone
152 s2 = cone
153 IF (az.LT.tol) GO TO 160
154 aa = az*az
155 IF (aa.LT.tol/az) GO TO 40
156 trm1 = cone
157 trm2 = cone
158 atrm = 1.0e0
159 z3 = z*z*z
160 az3 = az*aa
161 ak = 2.0e0 + fid
162 bk = 3.0e0 - fid - fid
163 ck = 4.0e0 - fid
164 dk = 3.0e0 + fid + fid
165 d1 = ak*dk
166 d2 = bk*ck
167 ad = amin1(d1,d2)
168 ak = 24.0e0 + 9.0e0*fid
169 bk = 30.0e0 - 9.0e0*fid
170 z3r = real(z3)
171 z3i = aimag(z3)
172 DO 30 k=1,25
173 trm1 = trm1*cmplx(z3r/d1,z3i/d1)
174 s1 = s1 + trm1
175 trm2 = trm2*cmplx(z3r/d2,z3i/d2)
176 s2 = s2 + trm2
177 atrm = atrm*az3/ad
178 d1 = d1 + ak
179 d2 = d2 + bk
180 ad = amin1(d1,d2)
181 IF (atrm.LT.tol*ad) GO TO 40
182 ak = ak + 18.0e0
183 bk = bk + 18.0e0
184 30 CONTINUE
185 40 CONTINUE
186 IF (id.EQ.1) GO TO 50
187 ai = s1*cmplx(c1,0.0e0) - z*s2*cmplx(c2,0.0e0)
188 IF (kode.EQ.1) RETURN
189 zta = z*csqrt(z)*cmplx(tth,0.0e0)
190 ai = ai*cexp(zta)
191 RETURN
192 50 CONTINUE
193 ai = -s2*cmplx(c2,0.0e0)
194 IF (az.GT.tol) ai = ai + z*z*s1*cmplx(c1/(1.0e0+fid),0.0e0)
195 IF (kode.EQ.1) RETURN
196 zta = z*csqrt(z)*cmplx(tth,0.0e0)
197 ai = ai*cexp(zta)
198 RETURN
199C-----------------------------------------------------------------------
200C CASE FOR CABS(Z).GT.1.0
201C-----------------------------------------------------------------------
202 60 CONTINUE
203 fnu = (1.0e0+fid)/3.0e0
204C-----------------------------------------------------------------------
205C SET PARAMETERS RELATED TO MACHINE CONSTANTS.
206C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18.
207C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT.
208C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND
209C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR
210C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE.
211C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z.
212C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG).
213C-----------------------------------------------------------------------
214 k1 = i1mach(12)
215 k2 = i1mach(13)
216 r1m5 = r1mach(5)
217 k = min0(iabs(k1),iabs(k2))
218 elim = 2.303e0*(float(k)*r1m5-3.0e0)
219 k1 = i1mach(11) - 1
220 aa = r1m5*float(k1)
221 dig = amin1(aa,18.0e0)
222 aa = aa*2.303e0
223 alim = elim + amax1(-aa,-41.45e0)
224 rl = 1.2e0*dig + 3.0e0
225 alaz=alog(az)
226C-----------------------------------------------------------------------
227C TEST FOR RANGE
228C-----------------------------------------------------------------------
229 aa=0.5e0/tol
230 bb=float(i1mach(9))*0.5e0
231 aa=amin1(aa,bb)
232 aa=aa**tth
233 IF (az.GT.aa) GO TO 260
234 aa=sqrt(aa)
235 IF (az.GT.aa) ierr=3
236 csq=csqrt(z)
237 zta=z*csq*cmplx(tth,0.0e0)
238C-----------------------------------------------------------------------
239C RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL
240C-----------------------------------------------------------------------
241 iflag = 0
242 sfac = 1.0e0
243 zi = aimag(z)
244 zr = real(z)
245 ak = aimag(zta)
246 IF (zr.GE.0.0e0) GO TO 70
247 bk = real(zta)
248 ck = -abs(bk)
249 zta = cmplx(ck,ak)
250 70 CONTINUE
251 IF (zi.NE.0.0e0) GO TO 80
252 IF (zr.GT.0.0e0) GO TO 80
253 zta = cmplx(0.0e0,ak)
254 80 CONTINUE
255 aa = real(zta)
256 IF (aa.GE.0.0e0 .AND. zr.GT.0.0e0) GO TO 100
257 IF (kode.EQ.2) GO TO 90
258C-----------------------------------------------------------------------
259C OVERFLOW TEST
260C-----------------------------------------------------------------------
261 IF (aa.GT.(-alim)) GO TO 90
262 aa = -aa + 0.25e0*alaz
263 iflag = 1
264 sfac = tol
265 IF (aa.GT.elim) GO TO 240
266 90 CONTINUE
267C-----------------------------------------------------------------------
268C CBKNU AND CACAI RETURN EXP(ZTA)*K(FNU,ZTA) ON KODE=2
269C-----------------------------------------------------------------------
270 mr = 1
271 IF (zi.LT.0.0e0) mr = -1
272 CALL cacai(zta, fnu, kode, mr, 1, cy, nn, rl, tol, elim, alim)
273 IF (nn.LT.0) GO TO 250
274 nz = nz + nn
275 GO TO 120
276 100 CONTINUE
277 IF (kode.EQ.2) GO TO 110
278C-----------------------------------------------------------------------
279C UNDERFLOW TEST
280C-----------------------------------------------------------------------
281 IF (aa.LT.alim) GO TO 110
282 aa = -aa - 0.25e0*alaz
283 iflag = 2
284 sfac = 1.0e0/tol
285 IF (aa.LT.(-elim)) GO TO 180
286 110 CONTINUE
287 CALL cbknu(zta, fnu, kode, 1, cy, nz, tol, elim, alim)
288 120 CONTINUE
289 s1 = cy(1)*cmplx(coef,0.0e0)
290 IF (iflag.NE.0) GO TO 140
291 IF (id.EQ.1) GO TO 130
292 ai = csq*s1
293 RETURN
294 130 ai = -z*s1
295 RETURN
296 140 CONTINUE
297 s1 = s1*cmplx(sfac,0.0e0)
298 IF (id.EQ.1) GO TO 150
299 s1 = s1*csq
300 ai = s1*cmplx(1.0e0/sfac,0.0e0)
301 RETURN
302 150 CONTINUE
303 s1 = -s1*z
304 ai = s1*cmplx(1.0e0/sfac,0.0e0)
305 RETURN
306 160 CONTINUE
307 aa = 1.0e+3*r1mach(1)
308 s1 = cmplx(0.0e0,0.0e0)
309 IF (id.EQ.1) GO TO 170
310 IF (az.GT.aa) s1 = cmplx(c2,0.0e0)*z
311 ai = cmplx(c1,0.0e0) - s1
312 RETURN
313 170 CONTINUE
314 ai = -cmplx(c2,0.0e0)
315 aa = sqrt(aa)
316 IF (az.GT.aa) s1 = z*z*cmplx(0.5e0,0.0e0)
317 ai = ai + s1*cmplx(c1,0.0e0)
318 RETURN
319 180 CONTINUE
320 nz = 1
321 ai = cmplx(0.0e0,0.0e0)
322 RETURN
323 240 CONTINUE
324 nz = 0
325 ierr=2
326 RETURN
327 250 CONTINUE
328 IF(nn.EQ.(-1)) GO TO 240
329 nz=0
330 ierr=5
331 RETURN
332 260 CONTINUE
333 ierr=4
334 nz=0
335 RETURN
336 END
double complex cmplx
Definition Faddeeva.cc:227
subroutine cacai(z, fnu, kode, mr, n, y, nz, rl, tol, elim, alim)
Definition cacai.f:2
subroutine cairy(z, id, kode, ai, nz, ierr)
Definition cairy.f:2
subroutine cbknu(z, fnu, kode, n, y, nz, tol, elim, alim)
Definition cbknu.f:2
ColumnVector real(const ComplexColumnVector &a)