Blame view
fvn_fnlib/db1slr.f
7.41 KB
f6bacaf83 ChW 11/09: ANSI c... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
SUBROUTINE DB1SLR(X,NB,IZE,B,NCALC) C THIS ROUTINE CALCULATES BESSEL FUNCTIONS I AND J OF REAL C ARGUMENT AND INTEGER ORDER. C C C EXPLANATION OF VARIABLES IN THE CALLING SEQUENCE C C X DOUBLE PRECISION REAL ARGUMENT FOR WHICH I*S OR J*S C ARE TO BE CALCULATED. IF I*S ARE TO BE CALCULATED, C ABS(X) MUST BE LESS THAN EXPARG (WHICH SEE BELOW). C NB INTEGER TYPE. 1 + HIGHEST ORDER TO BE CALCULATED. C IT MUST BE POSITIVE. C IZE INTEGER TYPE. ZERO IF J*S ARE TO BE CALCULATED, 1 C IF I*S ARE TO BE CALCULATED. C B DOUBLE PRECISION VECTOR OF LENGTH NB, NEED NOT BE C INITIALIZED BY USER. IF THE ROUTINE TERMINATES C NORMALLY (NCALC=NB), IT RETURNS J(OR I)-SUB-ZERO C THROUGH J(OR I)-SUB-NB-MINUS-ONE OF X IN THIS C VECTOR. C NCALC INTEGER TYPE, NEED NOT BE INITIALIZED BY USER. C BEFORE USING THE RESULTS, THE USER SHOULD CHECK THAT C NCALC=NB, I.E. ALL ORDERS HAVE BEEN CALCULATED TO C THE DESIRED ACCURACY. SEE ERROR RETURNS BELOW. C C C EXPLANATION OF MACHINE-DEPENDENT CONSTANTS C C NSIG DECIMAL SIGNIFICANCE DESIRED. SHOULD BE SET TO C IFIX(ALOG10(2)*NBIT+1), WHERE NBIT IS THE NUMBER OF C BITS IN THE MANTISSA OF A DOUBLE PRECISION VARIABLE. C SETTING NSIG LOWER WILL RESULT IN DECREASED ACCURACY C WHILE SETTING NSIG HIGHER WILL INCREASE CPU TIME C WITHOUT INCREASING ACCURACY. THE TRUNCATION ERROR C IS LIMITED TO T=.5*10**-NSIG FOR J*S OF ORDER LESS C THAN ARGUMENT, AND TO A RELATIVE ERROR OF T FOR C I*S AND THE OTHER J*S. C NTEN LARGEST INTEGER K SUCH THAT 10**K IS MACHINE- C REPRESENTABLE IN DOUBLE PRECISION. C LARGEX UPPER LIMIT ON THE MAGNITUDE OF X. BEAR IN MIND C THAT IF ABS(X)=N, THEN AT LEAST N ITERATIONS OF THE C BACKWARD RECURSION WILL BE EXECUTED. C EXPARG LARGEST DOUBLE PRECISION ARGUMENT THAT THE LIBRARY C DEXP ROUTINE CAN HANDLE. C C PORT NOTE, SEPTEMBER 8,1976 - C THE LARGEX AND EXPARG TESTS ARE MADE IN THE OUTER ROUTINES - C DBESRJ AND DBESRI, WHICH CALL DB1SLR. C C C ERROR RETURNS C C PORT NOTE, SEPTEMBER 8, 1976 - C THE NOTES BELOW ARE KEPT IN FOR THE RECORD, BUT, AS ABOVE, C THE ACTUAL TESTS ARE NOW IN THE OUTER CALLING ROUTINES. C C LET G DENOTE EITHER I OR J. C IN CASE OF AN ERROR, NCALC.NE.NB, AND NOT ALL G*S C ARE CALCULATED TO THE DESIRED ACCURACY. C IF NCALC.LT.0, AN ARGUMENT IS OUT OF RANGE. NB.LE.0 C OR IZE IS NEITHER 0 NOR 1 OR IZE=1 AND ABS(X).GE.EXPARG. C IN THIS CASE, THE B-VECTOR IS NOT CALCULATED, AND NCALC C IS SET TO MIN0(NB,0)-1 SO NCALC.NE.NB. C NB.GT.NCALC.GT.0 WILL OCCUR IF NB.GT.MAGX AND ABS(G- C SUB-NB-OF-X/G-SUB-MAGX+NP-OF-X).LT.10.**(NTEN/2), I.E. NB C IS MUCH GREATER THAN MAGX. IN THIS CASE, B(N) IS CALCU- C LATED TO THE DESIRED ACCURACY FOR N.LE.NCALC, BUT FOR C NCALC.LT.N.LE.NB, PRECISION IS LOST. IF N.GT.NCALC AND C ABS(B(NCALC)/B(N)).EQ.10**-K, THEN THE LAST K SIGNIFICANT C FIGURES OF B(N) ARE ERRONEOUS. IF THE USER WISHES TO C CALCULATE B(N) TO HIGHER ACCURACY, HE SHOULD USE AN C ASYMPTOTIC FORMULA FOR LARGE ORDER. C DOUBLE PRECISION DLOG10, DSQRT, DEXP, 1 X,B,P,TEST,TEMPA,TEMPB,TEMPC,SIGN,SUM,TOVER, 2 PLAST,POLD,PSAVE,PSAVEL,D1MACH DIMENSION B(NB) DATA NSIG/0/, NTEN/0/ IF(NSIG .NE. 0) GO TO 1 NSIG = IFIX(-ALOG10(SNGL(D1MACH(3)))+1.) NTEN = DLOG10(D1MACH(2)) 1 TEMPA=DABS(X) MAGX=IFIX(SNGL(TEMPA)) C SIGN=DBLE(FLOAT(1-2*IZE)) NCALC=NB C USE 2-TERM ASCENDING SERIES FOR SMALL X IF(TEMPA**4.LT..1D0**NSIG) GO TO 30 C INITIALIZE THE CALCULATION OF P*S NBMX=NB-MAGX N=MAGX+1 PLAST=1.D0 P=DBLE(FLOAT(2*N))/TEMPA C CALCULATE GENERAL SIGNIFICANCE TEST TEST=2.D0*1.D1**NSIG IF(IZE.EQ.1.AND.2*MAGX.GT.5*NSIG) TEST=DSQRT(TEST*P) IF(IZE.EQ.1.AND.2*MAGX.LE.5*NSIG) TEST=TEST/1.585**MAGX M=0 IF(NBMX.LT.3) GO TO 4 C CALCULATE P*S UNTIL N=NB-1. CHECK FOR POSSIBLE OVERFLOW. TOVER=1.D1**(NTEN-NSIG) NSTART=MAGX+2 NEND=NB-1 DO 3 N=NSTART,NEND POLD=PLAST PLAST=P P=DBLE(FLOAT(2*N))*PLAST/TEMPA-SIGN*POLD IF(P-TOVER) 3,3,5 3 CONTINUE C CALCULATE SPECIAL SIGNIFICANCE TEST FOR NBMX.GT.2. TEST=DMAX1(TEST,DSQRT(PLAST*1.D1**NSIG)*DSQRT(2.D0*P)) C CALCULATE P*S UNTIL SIGNIFICANCE TEST PASSES 4 N=N+1 POLD=PLAST PLAST=P P=DBLE(FLOAT(2*N))*PLAST/TEMPA-SIGN*POLD IF(P.LT.TEST) GO TO 4 IF(IZE.EQ.1.OR.M.EQ.1) GO TO 12 C FOR J*S, A STRONG VARIANT OF THE TEST IS NECESSARY. C CALCULATE IT, AND CALCULATE P*S UNTIL THIS TEST IS PASSED. M=1 TEMPB=P/PLAST TEMPC=DBLE(FLOAT(N+1))/TEMPA IF(TEMPB+1.D0/TEMPB.GT.2.D0*TEMPC)TEMPB=TEMPC+DSQRT(TEMPC**2-1.D0) TEST=TEST/DSQRT(TEMPB-1.D0/TEMPB) IF(P-TEST) 4,12,12 C TO AVOID OVERFLOW, DIVIDE P*S BY TOVER. CALCULATE P*S C UNTIL ABS(P).GT.1. 5 TOVER=1.D1**NTEN P=P/TOVER PLAST=PLAST/TOVER PSAVE=P PSAVEL=PLAST NSTART=N+1 6 N=N+1 POLD=PLAST PLAST=P P=DBLE(FLOAT(2*N))*PLAST/TEMPA-SIGN*POLD IF(P.LE.1.D0) GO TO 6 TEMPB=DBLE(FLOAT(2*N))/TEMPA IF(IZE.EQ.1) GO TO 8 TEMPC=.5D0*TEMPB TEMPB=PLAST/POLD IF(TEMPB+1.D0/TEMPB.GT.2.D0*TEMPC)TEMPB=TEMPC+DSQRT(TEMPC**2-1.D0) C CALCULATE BACKWARD TEST, AND FIND NCALC, THE HIGHEST N C SUCH THAT THE TEST IS PASSED. 8 TEST=.5D0*POLD*PLAST*(1.D0-1.D0/TEMPB**2)/1.D1**NSIG P=PLAST*TOVER N=N-1 NEND=MIN0(NB,N) DO 9 NCALC=NSTART,NEND POLD=PSAVEL PSAVEL=PSAVE PSAVE=DBLE(FLOAT(2*N))*PSAVEL/TEMPA-SIGN*POLD IF(PSAVE*PSAVEL-TEST) 9,9,10 9 CONTINUE NCALC=NEND+1 10 NCALC=NCALC-1 C THE SUM B(1)+2B(3)+2B(5)... IS USED TO NORMALIZE. M, THE C COEFFICIENT OF B(N), IS INITIALIZED TO 2 OR 0. 12 N=N+1 M=2*N-4*(N/2) C INITIALIZE THE BACKWARD RECURSION AND THE NORMALIZATION C SUM TEMPB=0.D0 TEMPA=1.D0/P SUM=DBLE(FLOAT(M))*TEMPA NEND=N-NB IF(NEND) 17,15,13 C RECUR BACKWARD VIA DIFFERENCE EQUATION, CALCULATING (BUT C NOT STORING) B(N), UNTIL N=NB. 13 DO 14 L=1,NEND N=N-1 TEMPC=TEMPB TEMPB=TEMPA TEMPA=(DBLE(FLOAT(2*N))*TEMPB)/X-SIGN*TEMPC M=2-M 14 SUM=SUM+DBLE(FLOAT(M))*TEMPA C STORE B(NB) 15 B(N)=TEMPA IF(NB.GT.1) GO TO 16 C NB=1. SINCE 2*TEMPA WAS ADDED TO THE SUM, TEMPA MUST BE C SUBTRACTED SUM=SUM-TEMPA GO TO 23 C CALCULATE AND STORE B(NB-1) 16 N=N-1 B(N) =(DBLE(FLOAT(2*N))*TEMPA)/X-SIGN*TEMPB IF(N.EQ.1) GO TO 22 M=2-M SUM=SUM+DBLE(FLOAT(M))*B(N) GO TO 19 C N.LT.NB, SO STORE B(N) AND SET HIGHER ORDERS TO ZERO 17 B(N)=TEMPA NEND=-NEND DO 18 L=1,NEND K=N+L 18 B(K)=0.D0 19 NEND=N-2 IF(NEND.EQ.0) GO TO 21 C CALCULATE VIA DIFFERENCE EQUATION AND STORE B(N), C UNTIL N=2 DO 20 L=1,NEND N=N-1 B(N)=(DBLE(FLOAT(2*N))*B(N+1))/X-SIGN*B(N+2) M=2-M 20 SUM=SUM+DBLE(FLOAT(M))*B(N) C CALCULATE B(1) 21 B(1)=2.D0*B(2)/X-SIGN*B(3) 22 SUM=SUM+B(1) C NORMALIZE--IF IZE=1, DIVIDE SUM BY COSH(X). DIVIDE ALL C B(N) BY SUM. 23 IF(IZE.EQ.0) GO TO 25 TEMPA=DEXP(DABS(X)) SUM=2.D0*SUM/(TEMPA+1.D0/TEMPA) 25 DO 26 N=1,NB 26 B(N)=B(N)/SUM RETURN C C TWO-TERM ASCENDING SERIES FOR SMALL X 30 TEMPA=1.D0 TEMPB=-.25D0*X*X*SIGN B(1)=1.D0+TEMPB IF(NB.EQ.1) GO TO 32 DO 31 N=2,NB TEMPA=TEMPA*X/DBLE(FLOAT(2*N-2)) 31 B(N)=TEMPA*(1.D0+TEMPB/DBLE(FLOAT(N))) 32 RETURN END |