github.com/gopherd/gonum@v0.0.4/mathext/internal/amos/amoslib/zmlri.f (about) 1 SUBROUTINE ZMLRI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL) 2 C***BEGIN PROLOGUE ZMLRI 3 C***REFER TO ZBESI,ZBESK 4 C 5 C ZMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY THE 6 C MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES. 7 C 8 C***ROUTINES CALLED DGAMLN,D1MACH,ZABS,ZEXP,ZLOG,ZMLT 9 C***END PROLOGUE ZMLRI 10 C COMPLEX CK,CNORM,CONE,CTWO,CZERO,PT,P1,P2,RZ,SUM,Y,Z 11 DOUBLE PRECISION ACK, AK, AP, AT, AZ, BK, CKI, CKR, CNORMI, 12 * CNORMR, CONEI, CONER, FKAP, FKK, FLAM, FNF, FNU, PTI, PTR, P1I, 13 * P1R, P2I, P2R, RAZ, RHO, RHO2, RZI, RZR, SCLE, STI, STR, SUMI, 14 * SUMR, TFNF, TOL, TST, YI, YR, ZEROI, ZEROR, ZI, ZR, DGAMLN, 15 * D1MACH, ZABS 16 INTEGER I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, KODE, M, N, NZ 17 DIMENSION YR(N), YI(N) 18 DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 / 19 SCLE = D1MACH(1)/TOL 20 NZ=0 21 AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) 22 IAZ = INT(SNGL(AZ)) 23 IFNU = INT(SNGL(FNU)) 24 INU = IFNU + N - 1 25 AT = DBLE(FLOAT(IAZ)) + 1.0D0 26 RAZ = 1.0D0/AZ 27 STR = ZR*RAZ 28 STI = -ZI*RAZ 29 CKR = STR*AT*RAZ 30 CKI = STI*AT*RAZ 31 RZR = (STR+STR)*RAZ 32 RZI = (STI+STI)*RAZ 33 P1R = ZEROR 34 P1I = ZEROI 35 P2R = CONER 36 P2I = CONEI 37 ACK = (AT+1.0D0)*RAZ 38 RHO = ACK + DSQRT(ACK*ACK-1.0D0) 39 RHO2 = RHO*RHO 40 TST = (RHO2+RHO2)/((RHO2-1.0D0)*(RHO-1.0D0)) 41 TST = TST/TOL 42 C----------------------------------------------------------------------- 43 C COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES 44 C----------------------------------------------------------------------- 45 AK = AT 46 DO 10 I=1,80 47 PTR = P2R 48 PTI = P2I 49 P2R = P1R - (CKR*PTR-CKI*PTI) 50 P2I = P1I - (CKI*PTR+CKR*PTI) 51 P1R = PTR 52 P1I = PTI 53 CKR = CKR + RZR 54 CKI = CKI + RZI 55 AP = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) 56 IF (AP.GT.TST*AK*AK) THEN 57 GO TO 20 58 END IF 59 AK = AK + 1.0D0 60 10 CONTINUE 61 GO TO 110 62 20 CONTINUE 63 I = I + 1 64 K = 0 65 IF (INU.LT.IAZ) GO TO 40 66 C----------------------------------------------------------------------- 67 C COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS 68 C----------------------------------------------------------------------- 69 P1R = ZEROR 70 P1I = ZEROI 71 P2R = CONER 72 P2I = CONEI 73 AT = DBLE(FLOAT(INU)) + 1.0D0 74 STR = ZR*RAZ 75 STI = -ZI*RAZ 76 CKR = STR*AT*RAZ 77 CKI = STI*AT*RAZ 78 ACK = AT*RAZ 79 TST = DSQRT(ACK/TOL) 80 ITIME = 1 81 DO 30 K=1,80 82 PTR = P2R 83 PTI = P2I 84 P2R = P1R - (CKR*PTR-CKI*PTI) 85 P2I = P1I - (CKR*PTI+CKI*PTR) 86 P1R = PTR 87 P1I = PTI 88 CKR = CKR + RZR 89 CKI = CKI + RZI 90 AP = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) 91 IF (AP.LT.TST) GO TO 30 92 IF (ITIME.EQ.2) GO TO 40 93 ACK = ZABS(CMPLX(CKR,CKI,kind=KIND(1.0D0))) 94 FLAM = ACK + DSQRT(ACK*ACK-1.0D0) 95 FKAP = AP/ZABS(CMPLX(P1R,P1I,kind=KIND(1.0D0))) 96 RHO = DMIN1(FLAM,FKAP) 97 TST = TST*DSQRT(RHO/(RHO*RHO-1.0D0)) 98 ITIME = 2 99 30 CONTINUE 100 GO TO 110 101 40 CONTINUE 102 C----------------------------------------------------------------------- 103 C BACKWARD RECURRENCE AND SUM NORMALIZING RELATION 104 C----------------------------------------------------------------------- 105 K = K + 1 106 KK = MAX0(I+IAZ,K+INU) 107 FKK = DBLE(FLOAT(KK)) 108 P1R = ZEROR 109 P1I = ZEROI 110 C----------------------------------------------------------------------- 111 C SCALE P2 AND SUM BY SCLE 112 C----------------------------------------------------------------------- 113 P2R = SCLE 114 P2I = ZEROI 115 FNF = FNU - DBLE(FLOAT(IFNU)) 116 TFNF = FNF + FNF 117 BK = DGAMLN(FKK+TFNF+1.0D0,IDUM) - DGAMLN(FKK+1.0D0,IDUM) - 118 * DGAMLN(TFNF+1.0D0,IDUM) 119 BK = DEXP(BK) 120 SUMR = ZEROR 121 SUMI = ZEROI 122 KM = KK - INU 123 DO 50 I=1,KM 124 PTR = P2R 125 PTI = P2I 126 P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) 127 P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) 128 P1R = PTR 129 P1I = PTI 130 AK = 1.0D0 - TFNF/(FKK+TFNF) 131 ACK = BK*AK 132 SUMR = SUMR + (ACK+BK)*P1R 133 SUMI = SUMI + (ACK+BK)*P1I 134 BK = ACK 135 FKK = FKK - 1.0D0 136 50 CONTINUE 137 YR(N) = P2R 138 YI(N) = P2I 139 IF (N.EQ.1) GO TO 70 140 DO 60 I=2,N 141 PTR = P2R 142 PTI = P2I 143 P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) 144 P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) 145 P1R = PTR 146 P1I = PTI 147 AK = 1.0D0 - TFNF/(FKK+TFNF) 148 ACK = BK*AK 149 SUMR = SUMR + (ACK+BK)*P1R 150 SUMI = SUMI + (ACK+BK)*P1I 151 BK = ACK 152 FKK = FKK - 1.0D0 153 M = N - I + 1 154 YR(M) = P2R 155 YI(M) = P2I 156 60 CONTINUE 157 70 CONTINUE 158 IF (IFNU.LE.0) GO TO 90 159 DO 80 I=1,IFNU 160 PTR = P2R 161 PTI = P2I 162 P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) 163 P2I = P1I + (FKK+FNF)*(RZR*PTI+RZI*PTR) 164 P1R = PTR 165 P1I = PTI 166 AK = 1.0D0 - TFNF/(FKK+TFNF) 167 ACK = BK*AK 168 SUMR = SUMR + (ACK+BK)*P1R 169 SUMI = SUMI + (ACK+BK)*P1I 170 BK = ACK 171 FKK = FKK - 1.0D0 172 80 CONTINUE 173 90 CONTINUE 174 PTR = ZR 175 PTI = ZI 176 IF (KODE.EQ.2) PTR = ZEROR 177 CALL ZLOG(RZR, RZI, STR, STI, IDUM) 178 P1R = -FNF*STR + PTR 179 P1I = -FNF*STI + PTI 180 AP = DGAMLN(1.0D0+FNF,IDUM) 181 PTR = P1R - AP 182 PTI = P1I 183 C----------------------------------------------------------------------- 184 C THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW 185 C IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES 186 C----------------------------------------------------------------------- 187 P2R = P2R + SUMR 188 P2I = P2I + SUMI 189 AP = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) 190 P1R = 1.0D0/AP 191 CALL ZEXP(PTR, PTI, STR, STI) 192 CKR = STR*P1R 193 CKI = STI*P1R 194 PTR = P2R*P1R 195 PTI = -P2I*P1R 196 CALL ZMLT(CKR, CKI, PTR, PTI, CNORMR, CNORMI) 197 DO 100 I=1,N 198 STR = YR(I)*CNORMR - YI(I)*CNORMI 199 YI(I) = YR(I)*CNORMI + YI(I)*CNORMR 200 YR(I) = STR 201 100 CONTINUE 202 RETURN 203 110 CONTINUE 204 NZ=-2 205 RETURN 206 END