github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/mathext/internal/amos/amoslib/zseri.f (about)

     1        SUBROUTINE ZSERI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM,
     2       * ALIM)
     3  C***BEGIN PROLOGUE  ZSERI
     4  C***REFER TO  ZBESI,ZBESK
     5  C
     6  C     ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY
     7  C     MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE
     8  C     REGION CABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN.
     9  C     NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO
    10  C     DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE
    11  C     CONDITION CABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE
    12  C     COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ).
    13  C
    14  C***ROUTINES CALLED  DGAMLN,D1MACH,ZUCHK,ZABS,ZDIV,ZLOG,ZMLT
    15  C***END PROLOGUE  ZSERI
    16  C     COMPLEX AK1,CK,COEF,CONE,CRSC,CSCL,CZ,CZERO,HZ,RZ,S1,S2,Y,Z
    17        DOUBLE PRECISION AA, ACZ, AK, AK1I, AK1R, ALIM, ARM, ASCLE, ATOL,
    18       * AZ, CKI, CKR, COEFI, COEFR, CONEI, CONER, CRSCR, CZI, CZR, DFNU,
    19       * ELIM, FNU, FNUP, HZI, HZR, RAZ, RS, RTR1, RZI, RZR, S, SS, STI,
    20       * STR, S1I, S1R, S2I, S2R, TOL, YI, YR, WI, WR, ZEROI, ZEROR, ZI,
    21       * ZR, DGAMLN, D1MACH, ZABS
    22        INTEGER I, IB, IDUM, IFLAG, IL, K, KODE, L, M, N, NN, NZ, NW
    23        DIMENSION YR(N), YI(N), WR(2), WI(2)
    24        DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 /
    25  C
    26  
    27        NZ = 0
    28        AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0)))
    29        IF (AZ.EQ.0.0D0) GO TO 160
    30        ARM = 1.0D+3*D1MACH(1)
    31        RTR1 = DSQRT(ARM)
    32        CRSCR = 1.0D0
    33        IFLAG = 0
    34        IF (AZ.LT.ARM) THEN
    35          GO TO 150
    36        END IF
    37        HZR = 0.5D0*ZR
    38        HZI = 0.5D0*ZI
    39        CZR = ZEROR
    40        CZI = ZEROI
    41        IF (AZ.LE.RTR1) GO TO 10
    42        CALL ZMLT(HZR, HZI, HZR, HZI, CZR, CZI)
    43     10 CONTINUE
    44        ACZ = ZABS(CMPLX(CZR,CZI,kind=KIND(1.0D0)))
    45        NN = N
    46        CALL ZLOG(HZR, HZI, CKR, CKI, IDUM)
    47     20 CONTINUE
    48        DFNU = FNU + DBLE(FLOAT(NN-1))
    49        FNUP = DFNU + 1.0D0
    50  C-----------------------------------------------------------------------
    51  C     UNDERFLOW TEST
    52  C-----------------------------------------------------------------------
    53        AK1R = CKR*DFNU
    54        AK1I = CKI*DFNU
    55        AK = DGAMLN(FNUP,IDUM)
    56        AK1R = AK1R - AK
    57        IF (KODE.EQ.2) AK1R = AK1R - ZR
    58        IF (AK1R.GT.(-ELIM)) GO TO 40
    59     30 CONTINUE
    60        NZ = NZ + 1
    61        YR(NN) = ZEROR
    62        YI(NN) = ZEROI
    63        IF (ACZ.GT.DFNU) GO TO 190
    64        NN = NN - 1
    65        IF (NN.EQ.0) RETURN
    66        GO TO 20
    67     40 CONTINUE
    68        IF (AK1R.GT.(-ALIM)) GO TO 50
    69        IFLAG = 1
    70        SS = 1.0D0/TOL
    71        CRSCR = TOL
    72        ASCLE = ARM*SS
    73     50 CONTINUE
    74        AA = DEXP(AK1R)
    75        IF (IFLAG.EQ.1) AA = AA*SS
    76        COEFR = AA*DCOS(AK1I)
    77        COEFI = AA*DSIN(AK1I)
    78        ATOL = TOL*ACZ/FNUP
    79        IL = MIN0(2,NN)
    80        DO 90 I=1,IL
    81          DFNU = FNU + DBLE(FLOAT(NN-I))
    82          FNUP = DFNU + 1.0D0
    83          S1R = CONER
    84          S1I = CONEI
    85          IF (ACZ.LT.TOL*FNUP) GO TO 70
    86          AK1R = CONER
    87          AK1I = CONEI
    88          AK = FNUP + 2.0D0
    89          S = FNUP
    90          AA = 2.0D0
    91     60   CONTINUE
    92          RS = 1.0D0/S
    93          STR = AK1R*CZR - AK1I*CZI
    94          STI = AK1R*CZI + AK1I*CZR
    95          AK1R = STR*RS
    96          AK1I = STI*RS
    97          S1R = S1R + AK1R
    98          S1I = S1I + AK1I
    99          S = S + AK
   100          AK = AK + 2.0D0
   101          AA = AA*ACZ*RS
   102          IF (AA.GT.ATOL) GO TO 60
   103     70   CONTINUE
   104          S2R = S1R*COEFR - S1I*COEFI
   105          S2I = S1R*COEFI + S1I*COEFR
   106          WR(I) = S2R
   107          WI(I) = S2I
   108          IF (IFLAG.EQ.0) GO TO 80
   109          CALL ZUCHK(S2R, S2I, NW, ASCLE, TOL)
   110          IF (NW.NE.0) GO TO 30
   111     80   CONTINUE
   112          M = NN - I + 1
   113          YR(M) = S2R*CRSCR
   114          YI(M) = S2I*CRSCR
   115          IF (I.EQ.IL) GO TO 90
   116          CALL ZDIV(COEFR, COEFI, HZR, HZI, STR, STI)
   117          COEFR = STR*DFNU
   118          COEFI = STI*DFNU
   119     90 CONTINUE
   120        IF (NN.LE.2) THEN
   121          RETURN
   122        END IF
   123        K = NN - 2
   124        AK = DBLE(FLOAT(K))
   125        RAZ = 1.0D0/AZ
   126        STR = ZR*RAZ
   127        STI = -ZI*RAZ
   128        RZR = (STR+STR)*RAZ
   129        RZI = (STI+STI)*RAZ
   130        IF (IFLAG.EQ.1) GO TO 120
   131        IB = 3
   132    100 CONTINUE
   133        DO 110 I=IB,NN
   134          YR(K) = (AK+FNU)*(RZR*YR(K+1)-RZI*YI(K+1)) + YR(K+2)
   135          YI(K) = (AK+FNU)*(RZR*YI(K+1)+RZI*YR(K+1)) + YI(K+2)
   136          AK = AK - 1.0D0
   137          K = K - 1
   138    110 CONTINUE
   139        RETURN
   140  C-----------------------------------------------------------------------
   141  C     RECUR BACKWARD WITH SCALED VALUES
   142  C-----------------------------------------------------------------------
   143    120 CONTINUE
   144  C-----------------------------------------------------------------------
   145  C     EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE
   146  C     UNDERFLOW LIMIT = ASCLE = D1MACH(1)*SS*1.0D+3
   147  C-----------------------------------------------------------------------
   148        S1R = WR(1)
   149        S1I = WI(1)
   150        S2R = WR(2)
   151        S2I = WI(2)
   152        DO 130 L=3,NN
   153          CKR = S2R
   154          CKI = S2I
   155          S2R = S1R + (AK+FNU)*(RZR*CKR-RZI*CKI)
   156          S2I = S1I + (AK+FNU)*(RZR*CKI+RZI*CKR)
   157          S1R = CKR
   158          S1I = CKI
   159          CKR = S2R*CRSCR
   160          CKI = S2I*CRSCR
   161          YR(K) = CKR
   162          YI(K) = CKI
   163          AK = AK - 1.0D0
   164          K = K - 1
   165          IF (ZABS(CMPLX(CKR,CKI,kind=KIND(1.0D0))).GT.ASCLE) GO TO 140
   166    130 CONTINUE
   167        RETURN
   168    140 CONTINUE
   169        IB = L + 1
   170        IF (IB.GT.NN) RETURN
   171        GO TO 100
   172    150 CONTINUE
   173        NZ = N
   174        IF (FNU.EQ.0.0D0) NZ = NZ - 1
   175    160 CONTINUE
   176        YR(1) = ZEROR
   177        YI(1) = ZEROI
   178        IF (FNU.NE.0.0D0) GO TO 170
   179        YR(1) = CONER
   180        YI(1) = CONEI
   181    170 CONTINUE
   182        IF (N.EQ.1) RETURN
   183        DO 180 I=2,N
   184          YR(I) = ZEROR
   185          YI(I) = ZEROI
   186    180 CONTINUE
   187        RETURN
   188  C-----------------------------------------------------------------------
   189  C     RETURN WITH NZ.LT.0 IF CABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE
   190  C     THE CALCULATION IN CBINU WITH N=N-IABS(NZ)
   191  C-----------------------------------------------------------------------
   192    190 CONTINUE
   193        NZ = -NZ
   194        RETURN
   195        END