zseri.f

Go to the documentation of this file.
00001       SUBROUTINE ZSERI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM,
00002      * ALIM)
00003 C***BEGIN PROLOGUE  ZSERI
00004 C***REFER TO  ZBESI,ZBESK
00005 C
00006 C     ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
00007 C     MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE
00008 C     REGION CABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN.
00009 C     NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO
00010 C     DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE
00011 C     CONDITION CABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE
00012 C     COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ).
00013 C
00014 C***ROUTINES CALLED  DGAMLN,D1MACH,ZUCHK,XZABS,ZDIV,XZLOG,ZMLT
00015 C***END PROLOGUE  ZSERI
00016 C     COMPLEX AK1,CK,COEF,CONE,CRSC,CSCL,CZ,CZERO,HZ,RZ,S1,S2,Y,Z
00017       DOUBLE PRECISION AA, ACZ, AK, AK1I, AK1R, ALIM, ARM, ASCLE, ATOL,
00018      * AZ, CKI, CKR, COEFI, COEFR, CONEI, CONER, CRSCR, CZI, CZR, DFNU,
00019      * ELIM, FNU, FNUP, HZI, HZR, RAZ, RS, RTR1, RZI, RZR, S, SS, STI,
00020      * STR, S1I, S1R, S2I, S2R, TOL, YI, YR, WI, WR, ZEROI, ZEROR, ZI,
00021      * ZR, DGAMLN, D1MACH, XZABS
00022       INTEGER I, IB, IDUM, IFLAG, IL, K, KODE, L, M, N, NN, NZ, NW
00023       DIMENSION YR(N), YI(N), WR(2), WI(2)
00024       DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
00025 C
00026       NZ = 0
00027       AZ = XZABS(ZR,ZI)
00028       IF (AZ.EQ.0.0D0) GO TO 160
00029       ARM = 1.0D+3*D1MACH(1)
00030       RTR1 = DSQRT(ARM)
00031       CRSCR = 1.0D0
00032       IFLAG = 0
00033       IF (AZ.LT.ARM) GO TO 150
00034       HZR = 0.5D0*ZR
00035       HZI = 0.5D0*ZI
00036       CZR = ZEROR
00037       CZI = ZEROI
00038       IF (AZ.LE.RTR1) GO TO 10
00039       CALL ZMLT(HZR, HZI, HZR, HZI, CZR, CZI)
00040    10 CONTINUE
00041       ACZ = XZABS(CZR,CZI)
00042       NN = N
00043       CALL XZLOG(HZR, HZI, CKR, CKI, IDUM)
00044    20 CONTINUE
00045       DFNU = FNU + DBLE(FLOAT(NN-1))
00046       FNUP = DFNU + 1.0D0
00047 C-----------------------------------------------------------------------
00048 C     UNDERFLOW TEST
00049 C-----------------------------------------------------------------------
00050       AK1R = CKR*DFNU
00051       AK1I = CKI*DFNU
00052       AK = DGAMLN(FNUP,IDUM)
00053       AK1R = AK1R - AK
00054       IF (KODE.EQ.2) AK1R = AK1R - ZR
00055       IF (AK1R.GT.(-ELIM)) GO TO 40
00056    30 CONTINUE
00057       NZ = NZ + 1
00058       YR(NN) = ZEROR
00059       YI(NN) = ZEROI
00060       IF (ACZ.GT.DFNU) GO TO 190
00061       NN = NN - 1
00062       IF (NN.EQ.0) RETURN
00063       GO TO 20
00064    40 CONTINUE
00065       IF (AK1R.GT.(-ALIM)) GO TO 50
00066       IFLAG = 1
00067       SS = 1.0D0/TOL
00068       CRSCR = TOL
00069       ASCLE = ARM*SS
00070    50 CONTINUE
00071       AA = DEXP(AK1R)
00072       IF (IFLAG.EQ.1) AA = AA*SS
00073       COEFR = AA*DCOS(AK1I)
00074       COEFI = AA*DSIN(AK1I)
00075       ATOL = TOL*ACZ/FNUP
00076       IL = MIN0(2,NN)
00077       DO 90 I=1,IL
00078         DFNU = FNU + DBLE(FLOAT(NN-I))
00079         FNUP = DFNU + 1.0D0
00080         S1R = CONER
00081         S1I = CONEI
00082         IF (ACZ.LT.TOL*FNUP) GO TO 70
00083         AK1R = CONER
00084         AK1I = CONEI
00085         AK = FNUP + 2.0D0
00086         S = FNUP
00087         AA = 2.0D0
00088    60   CONTINUE
00089         RS = 1.0D0/S
00090         STR = AK1R*CZR - AK1I*CZI
00091         STI = AK1R*CZI + AK1I*CZR
00092         AK1R = STR*RS
00093         AK1I = STI*RS
00094         S1R = S1R + AK1R
00095         S1I = S1I + AK1I
00096         S = S + AK
00097         AK = AK + 2.0D0
00098         AA = AA*ACZ*RS
00099         IF (AA.GT.ATOL) GO TO 60
00100    70   CONTINUE
00101         S2R = S1R*COEFR - S1I*COEFI
00102         S2I = S1R*COEFI + S1I*COEFR
00103         WR(I) = S2R
00104         WI(I) = S2I
00105         IF (IFLAG.EQ.0) GO TO 80
00106         CALL ZUCHK(S2R, S2I, NW, ASCLE, TOL)
00107         IF (NW.NE.0) GO TO 30
00108    80   CONTINUE
00109         M = NN - I + 1
00110         YR(M) = S2R*CRSCR
00111         YI(M) = S2I*CRSCR
00112         IF (I.EQ.IL) GO TO 90
00113         CALL ZDIV(COEFR, COEFI, HZR, HZI, STR, STI)
00114         COEFR = STR*DFNU
00115         COEFI = STI*DFNU
00116    90 CONTINUE
00117       IF (NN.LE.2) RETURN
00118       K = NN - 2
00119       AK = DBLE(FLOAT(K))
00120       RAZ = 1.0D0/AZ
00121       STR = ZR*RAZ
00122       STI = -ZI*RAZ
00123       RZR = (STR+STR)*RAZ
00124       RZI = (STI+STI)*RAZ
00125       IF (IFLAG.EQ.1) GO TO 120
00126       IB = 3
00127   100 CONTINUE
00128       DO 110 I=IB,NN
00129         YR(K) = (AK+FNU)*(RZR*YR(K+1)-RZI*YI(K+1)) + YR(K+2)
00130         YI(K) = (AK+FNU)*(RZR*YI(K+1)+RZI*YR(K+1)) + YI(K+2)
00131         AK = AK - 1.0D0
00132         K = K - 1
00133   110 CONTINUE
00134       RETURN
00135 C-----------------------------------------------------------------------
00136 C     RECUR BACKWARD WITH SCALED VALUES
00137 C-----------------------------------------------------------------------
00138   120 CONTINUE
00139 C-----------------------------------------------------------------------
00140 C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE
00141 C     UNDERFLOW LIMIT = ASCLE = D1MACH(1)*SS*1.0D+3
00142 C-----------------------------------------------------------------------
00143       S1R = WR(1)
00144       S1I = WI(1)
00145       S2R = WR(2)
00146       S2I = WI(2)
00147       DO 130 L=3,NN
00148         CKR = S2R
00149         CKI = S2I
00150         S2R = S1R + (AK+FNU)*(RZR*CKR-RZI*CKI)
00151         S2I = S1I + (AK+FNU)*(RZR*CKI+RZI*CKR)
00152         S1R = CKR
00153         S1I = CKI
00154         CKR = S2R*CRSCR
00155         CKI = S2I*CRSCR
00156         YR(K) = CKR
00157         YI(K) = CKI
00158         AK = AK - 1.0D0
00159         K = K - 1
00160         IF (XZABS(CKR,CKI).GT.ASCLE) GO TO 140
00161   130 CONTINUE
00162       RETURN
00163   140 CONTINUE
00164       IB = L + 1
00165       IF (IB.GT.NN) RETURN
00166       GO TO 100
00167   150 CONTINUE
00168       NZ = N
00169       IF (FNU.EQ.0.0D0) NZ = NZ - 1
00170   160 CONTINUE
00171       YR(1) = ZEROR
00172       YI(1) = ZEROI
00173       IF (FNU.NE.0.0D0) GO TO 170
00174       YR(1) = CONER
00175       YI(1) = CONEI
00176   170 CONTINUE
00177       IF (N.EQ.1) RETURN
00178       DO 180 I=2,N
00179         YR(I) = ZEROR
00180         YI(I) = ZEROI
00181   180 CONTINUE
00182       RETURN
00183 C-----------------------------------------------------------------------
00184 C     RETURN WITH NZ.LT.0 IF CABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE
00185 C     THE CALCULATION IN CBINU WITH N=N-IABS(NZ)
00186 C-----------------------------------------------------------------------
00187   190 CONTINUE
00188       NZ = -NZ
00189       RETURN
00190       END
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines