123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- *DECK CSERI
- SUBROUTINE CSERI (Z, FNU, KODE, N, Y, NZ, TOL, ELIM, ALIM)
- C***BEGIN PROLOGUE CSERI
- C***SUBSIDIARY
- C***PURPOSE Subsidiary to CBESI and CBESK
- C***LIBRARY SLATEC
- C***TYPE ALL (CSERI-A, ZSERI-A)
- C***AUTHOR Amos, D. E., (SNL)
- C***DESCRIPTION
- C
- C CSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
- C MEANS OF THE POWER SERIES FOR LARGE ABS(Z) IN THE
- C REGION ABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN.
- C NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO
- C DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE
- C CONDITION ABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE
- C COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ).
- C
- C***SEE ALSO CBESI, CBESK
- C***ROUTINES CALLED CUCHK, GAMLN, R1MACH
- C***REVISION HISTORY (YYMMDD)
- C 830501 DATE WRITTEN
- C 910415 Prologue converted to Version 4.0 format. (BAB)
- C***END PROLOGUE CSERI
- COMPLEX AK1, CK, COEF, CONE, CRSC, CZ, CZERO, HZ, RZ, S1, S2, W,
- * Y, Z
- REAL AA, ACZ, AK, ALIM, ARM, ASCLE, ATOL, AZ, DFNU, ELIM, FNU,
- * FNUP, RAK1, RS, RTR1, S, SS, TOL, X, GAMLN, R1MACH
- INTEGER I, IB, IDUM, IFLAG, IL, K, KODE, L, M, N, NN, NW, NZ
- DIMENSION Y(N), W(2)
- DATA CZERO, CONE / (0.0E0,0.0E0), (1.0E0,0.0E0) /
- C***FIRST EXECUTABLE STATEMENT CSERI
- NZ = 0
- AZ = ABS(Z)
- IF (AZ.EQ.0.0E0) GO TO 150
- X = REAL(Z)
- ARM = 1.0E+3*R1MACH(1)
- RTR1 = SQRT(ARM)
- CRSC = CMPLX(1.0E0,0.0E0)
- IFLAG = 0
- IF (AZ.LT.ARM) GO TO 140
- HZ = Z*CMPLX(0.5E0,0.0E0)
- CZ = CZERO
- IF (AZ.GT.RTR1) CZ = HZ*HZ
- ACZ = ABS(CZ)
- NN = N
- CK = CLOG(HZ)
- 10 CONTINUE
- DFNU = FNU + (NN-1)
- FNUP = DFNU + 1.0E0
- C-----------------------------------------------------------------------
- C UNDERFLOW TEST
- C-----------------------------------------------------------------------
- AK1 = CK*CMPLX(DFNU,0.0E0)
- AK = GAMLN(FNUP,IDUM)
- AK1 = AK1 - CMPLX(AK,0.0E0)
- IF (KODE.EQ.2) AK1 = AK1 - CMPLX(X,0.0E0)
- RAK1 = REAL(AK1)
- IF (RAK1.GT.(-ELIM)) GO TO 30
- 20 CONTINUE
- NZ = NZ + 1
- Y(NN) = CZERO
- IF (ACZ.GT.DFNU) GO TO 170
- NN = NN - 1
- IF (NN.EQ.0) RETURN
- GO TO 10
- 30 CONTINUE
- IF (RAK1.GT.(-ALIM)) GO TO 40
- IFLAG = 1
- SS = 1.0E0/TOL
- CRSC = CMPLX(TOL,0.0E0)
- ASCLE = ARM*SS
- 40 CONTINUE
- AK = AIMAG(AK1)
- AA = EXP(RAK1)
- IF (IFLAG.EQ.1) AA = AA*SS
- COEF = CMPLX(AA,0.0E0)*CMPLX(COS(AK),SIN(AK))
- ATOL = TOL*ACZ/FNUP
- IL = MIN(2,NN)
- DO 80 I=1,IL
- DFNU = FNU + (NN-I)
- FNUP = DFNU + 1.0E0
- S1 = CONE
- IF (ACZ.LT.TOL*FNUP) GO TO 60
- AK1 = CONE
- AK = FNUP + 2.0E0
- S = FNUP
- AA = 2.0E0
- 50 CONTINUE
- RS = 1.0E0/S
- AK1 = AK1*CZ*CMPLX(RS,0.0E0)
- S1 = S1 + AK1
- S = S + AK
- AK = AK + 2.0E0
- AA = AA*ACZ*RS
- IF (AA.GT.ATOL) GO TO 50
- 60 CONTINUE
- M = NN - I + 1
- S2 = S1*COEF
- W(I) = S2
- IF (IFLAG.EQ.0) GO TO 70
- CALL CUCHK(S2, NW, ASCLE, TOL)
- IF (NW.NE.0) GO TO 20
- 70 CONTINUE
- Y(M) = S2*CRSC
- IF (I.NE.IL) COEF = COEF*CMPLX(DFNU,0.0E0)/HZ
- 80 CONTINUE
- IF (NN.LE.2) RETURN
- K = NN - 2
- AK = K
- RZ = (CONE+CONE)/Z
- IF (IFLAG.EQ.1) GO TO 110
- IB = 3
- 90 CONTINUE
- DO 100 I=IB,NN
- Y(K) = CMPLX(AK+FNU,0.0E0)*RZ*Y(K+1) + Y(K+2)
- AK = AK - 1.0E0
- K = K - 1
- 100 CONTINUE
- RETURN
- C-----------------------------------------------------------------------
- C RECUR BACKWARD WITH SCALED VALUES
- C-----------------------------------------------------------------------
- 110 CONTINUE
- C-----------------------------------------------------------------------
- C EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE
- C UNDERFLOW LIMIT = ASCLE = R1MACH(1)*CSCL*1.0E+3
- C-----------------------------------------------------------------------
- S1 = W(1)
- S2 = W(2)
- DO 120 L=3,NN
- CK = S2
- S2 = S1 + CMPLX(AK+FNU,0.0E0)*RZ*S2
- S1 = CK
- CK = S2*CRSC
- Y(K) = CK
- AK = AK - 1.0E0
- K = K - 1
- IF (ABS(CK).GT.ASCLE) GO TO 130
- 120 CONTINUE
- RETURN
- 130 CONTINUE
- IB = L + 1
- IF (IB.GT.NN) RETURN
- GO TO 90
- 140 CONTINUE
- NZ = N
- IF (FNU.EQ.0.0E0) NZ = NZ - 1
- 150 CONTINUE
- Y(1) = CZERO
- IF (FNU.EQ.0.0E0) Y(1) = CONE
- IF (N.EQ.1) RETURN
- DO 160 I=2,N
- Y(I) = CZERO
- 160 CONTINUE
- RETURN
- C-----------------------------------------------------------------------
- C RETURN WITH NZ.LT.0 IF ABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE
- C THE CALCULATION IN CBINU WITH N=N-ABS(NZ)
- C-----------------------------------------------------------------------
- 170 CONTINUE
- NZ = -NZ
- RETURN
- END
|