github.com/gopherd/gonum@v0.0.4/mathext/internal/amos/amoslib/zuoik.f (about)

     1        SUBROUTINE ZUOIK(ZR, ZI, FNU, KODE, IKFLG, N, YR, YI, NUF, TOL,
     2       * ELIM, ALIM)
     3  C***BEGIN PROLOGUE  ZUOIK
     4  C***REFER TO  ZBESI,ZBESK,ZBESH
     5  C
     6  C     ZUOIK COMPUTES THE LEADING TERMS OF THE UNIFORM ASYMPTOTIC
     7  C     EXPANSIONS FOR THE I AND K FUNCTIONS AND COMPARES THEM
     8  C     (IN LOGARITHMIC FORM) TO ALIM AND ELIM FOR OVER AND UNDERFLOW
     9  C     WHERE ALIM.LT.ELIM. IF THE MAGNITUDE, BASED ON THE LEADING
    10  C     EXPONENTIAL, IS LESS THAN ALIM OR GREATER THAN -ALIM, THEN
    11  C     THE RESULT IS ON SCALE. IF NOT, THEN A REFINED TEST USING OTHER
    12  C     MULTIPLIERS (IN LOGARITHMIC FORM) IS MADE BASED ON ELIM. HERE
    13  C     EXP(-ELIM)=SMALLEST MACHINE NUMBER*1.0E+3 AND EXP(-ALIM)=
    14  C     EXP(-ELIM)/TOL
    15  C
    16  C     IKFLG=1 MEANS THE I SEQUENCE IS TESTED
    17  C          =2 MEANS THE K SEQUENCE IS TESTED
    18  C     NUF = 0 MEANS THE LAST MEMBER OF THE SEQUENCE IS ON SCALE
    19  C         =-1 MEANS AN OVERFLOW WOULD OCCUR
    20  C     IKFLG=1 AND NUF.GT.0 MEANS THE LAST NUF Y VALUES WERE SET TO ZERO
    21  C             THE FIRST N-NUF VALUES MUST BE SET BY ANOTHER ROUTINE
    22  C     IKFLG=2 AND NUF.EQ.N MEANS ALL Y VALUES WERE SET TO ZERO
    23  C     IKFLG=2 AND 0.LT.NUF.LT.N NOT CONSIDERED. Y MUST BE SET BY
    24  C             ANOTHER ROUTINE
    25  C
    26  C***ROUTINES CALLED  ZUCHK,ZUNHJ,ZUNIK,D1MACH,ZABS,ZLOG
    27  C***END PROLOGUE  ZUOIK
    28  C     COMPLEX ARG,ASUM,BSUM,CWRK,CZ,CZERO,PHI,SUM,Y,Z,ZB,ZETA1,ZETA2,ZN,
    29  C    *ZR
    30        DOUBLE PRECISION AARG, AIC, ALIM, APHI, ARGI, ARGR, ASUMI, ASUMR,
    31       * ASCLE, AX, AY, BSUMI, BSUMR, CWRKI, CWRKR, CZI, CZR, ELIM, FNN,
    32       * FNU, GNN, GNU, PHII, PHIR, RCZ, STR, STI, SUMI, SUMR, TOL, YI,
    33       * YR, ZBI, ZBR, ZEROI, ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZI,
    34       * ZNI, ZNR, ZR, ZRI, ZRR, D1MACH, ZABS
    35        INTEGER I, IDUM, IFORM, IKFLG, INIT, KODE, N, NN, NUF, NW
    36        DIMENSION YR(N), YI(N), CWRKR(16), CWRKI(16)
    37        DATA ZEROR,ZEROI / 0.0D0, 0.0D0 /
    38        DATA AIC / 1.265512123484645396D+00 /
    39        NUF = 0
    40        NN = N
    41        ZRR = ZR
    42        ZRI = ZI
    43        IF (ZR.GE.0.0D0) GO TO 10
    44        ZRR = -ZR
    45        ZRI = -ZI
    46     10 CONTINUE
    47        ZBR = ZRR
    48        ZBI = ZRI
    49        AX = DABS(ZR)*1.7321D0
    50        AY = DABS(ZI)
    51        IFORM = 1
    52        IF (AY.GT.AX) IFORM = 2
    53        GNU = DMAX1(FNU,1.0D0)
    54        IF (IKFLG.EQ.1) GO TO 20
    55        FNN = DBLE(FLOAT(NN))
    56        GNN = FNU + FNN - 1.0D0
    57        GNU = DMAX1(GNN,FNN)
    58     20 CONTINUE
    59  C-----------------------------------------------------------------------
    60  C     ONLY THE MAGNITUDE OF ARG AND PHI ARE NEEDED ALONG WITH THE
    61  C     REAL PARTS OF ZETA1, ZETA2 AND ZB. NO ATTEMPT IS MADE TO GET
    62  C     THE SIGN OF THE IMAGINARY PART CORRECT.
    63  C-----------------------------------------------------------------------
    64        IF (IFORM.EQ.2) GO TO 30
    65        INIT = 0
    66        CALL ZUNIK(ZRR, ZRI, GNU, IKFLG, 1, TOL, INIT, PHIR, PHII,
    67       * ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
    68        CZR = -ZETA1R + ZETA2R
    69        CZI = -ZETA1I + ZETA2I
    70        GO TO 50
    71     30 CONTINUE
    72        ZNR = ZRI
    73        ZNI = -ZRR
    74        IF (ZI.GT.0.0D0) GO TO 40
    75        ZNR = -ZNR
    76     40 CONTINUE
    77        CALL ZUNHJ(ZNR, ZNI, GNU, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R,
    78       * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
    79        CZR = -ZETA1R + ZETA2R
    80        CZI = -ZETA1I + ZETA2I
    81        AARG = ZABS(CMPLX(ARGR,ARGI,kind=KIND(1.0D0)))
    82     50 CONTINUE
    83        IF (KODE.EQ.1) GO TO 60
    84        CZR = CZR - ZBR
    85        CZI = CZI - ZBI
    86     60 CONTINUE
    87        IF (IKFLG.EQ.1) GO TO 70
    88        CZR = -CZR
    89        CZI = -CZI
    90     70 CONTINUE
    91        APHI = ZABS(CMPLX(PHIR,PHII,kind=KIND(1.0D0)))
    92        RCZ = CZR
    93  C-----------------------------------------------------------------------
    94  C     OVERFLOW TEST
    95  C-----------------------------------------------------------------------
    96        IF (RCZ.GT.ELIM) GO TO 210
    97        IF (RCZ.LT.ALIM) GO TO 80
    98        RCZ = RCZ + DLOG(APHI)
    99        IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC
   100        IF (RCZ.GT.ELIM) GO TO 210
   101        GO TO 130
   102     80 CONTINUE
   103  C-----------------------------------------------------------------------
   104  C     UNDERFLOW TEST
   105  C-----------------------------------------------------------------------
   106        IF (RCZ.LT.(-ELIM)) GO TO 90
   107        IF (RCZ.GT.(-ALIM)) GO TO 130
   108        RCZ = RCZ + DLOG(APHI)
   109        IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC
   110        IF (RCZ.GT.(-ELIM)) GO TO 110
   111     90 CONTINUE
   112        DO 100 I=1,NN
   113          YR(I) = ZEROR
   114          YI(I) = ZEROI
   115    100 CONTINUE
   116        NUF = NN
   117        RETURN
   118    110 CONTINUE
   119        ASCLE = 1.0D+3*D1MACH(1)/TOL
   120        CALL ZLOG(PHIR, PHII, STR, STI, IDUM)
   121        CZR = CZR + STR
   122        CZI = CZI + STI
   123        IF (IFORM.EQ.1) GO TO 120
   124        CALL ZLOG(ARGR, ARGI, STR, STI, IDUM)
   125        CZR = CZR - 0.25D0*STR - AIC
   126        CZI = CZI - 0.25D0*STI
   127    120 CONTINUE
   128        AX = DEXP(RCZ)/TOL
   129        AY = CZI
   130        CZR = AX*DCOS(AY)
   131        CZI = AX*DSIN(AY)
   132        CALL ZUCHK(CZR, CZI, NW, ASCLE, TOL)
   133        IF (NW.NE.0) GO TO 90
   134    130 CONTINUE
   135        IF (IKFLG.EQ.2) RETURN
   136        IF (N.EQ.1) RETURN
   137  C-----------------------------------------------------------------------
   138  C     SET UNDERFLOWS ON I SEQUENCE
   139  C-----------------------------------------------------------------------
   140    140 CONTINUE
   141        GNU = FNU + DBLE(FLOAT(NN-1))
   142        IF (IFORM.EQ.2) GO TO 150
   143        INIT = 0
   144        CALL ZUNIK(ZRR, ZRI, GNU, IKFLG, 1, TOL, INIT, PHIR, PHII,
   145       * ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI)
   146        CZR = -ZETA1R + ZETA2R
   147        CZI = -ZETA1I + ZETA2I
   148        GO TO 160
   149    150 CONTINUE
   150        CALL ZUNHJ(ZNR, ZNI, GNU, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R,
   151       * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI)
   152        CZR = -ZETA1R + ZETA2R
   153        CZI = -ZETA1I + ZETA2I
   154        AARG = ZABS(CMPLX(ARGR,ARGI,kind=KIND(1.0D0)))
   155    160 CONTINUE
   156        IF (KODE.EQ.1) GO TO 170
   157        CZR = CZR - ZBR
   158        CZI = CZI - ZBI
   159    170 CONTINUE
   160        APHI = ZABS(CMPLX(PHIR,PHII,kind=KIND(1.0D0)))
   161        RCZ = CZR
   162        IF (RCZ.LT.(-ELIM)) GO TO 180
   163        IF (RCZ.GT.(-ALIM)) RETURN
   164        RCZ = RCZ + DLOG(APHI)
   165        IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC
   166        IF (RCZ.GT.(-ELIM)) GO TO 190
   167    180 CONTINUE
   168        YR(NN) = ZEROR
   169        YI(NN) = ZEROI
   170        NN = NN - 1
   171        NUF = NUF + 1
   172        IF (NN.EQ.0) RETURN
   173        GO TO 140
   174    190 CONTINUE
   175        ASCLE = 1.0D+3*D1MACH(1)/TOL
   176        CALL ZLOG(PHIR, PHII, STR, STI, IDUM)
   177        CZR = CZR + STR
   178        CZI = CZI + STI
   179        IF (IFORM.EQ.1) GO TO 200
   180        CALL ZLOG(ARGR, ARGI, STR, STI, IDUM)
   181        CZR = CZR - 0.25D0*STR - AIC
   182        CZI = CZI - 0.25D0*STI
   183    200 CONTINUE
   184        AX = DEXP(RCZ)/TOL
   185        AY = CZI
   186        CZR = AX*DCOS(AY)
   187        CZI = AX*DSIN(AY)
   188        CALL ZUCHK(CZR, CZI, NW, ASCLE, TOL)
   189        IF (NW.NE.0) GO TO 180
   190        RETURN
   191    210 CONTINUE
   192        NUF = -1
   193        RETURN
   194        END