-
git-svn-id: https://lxsd.femto-st.fr/svn/fvn@58 b657c933-2333-4658-acf2-d3c7c2708721
db1slr.f
7.41 KB
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