forked from lcompilers/lpython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fixed_form1.f
212 lines (212 loc) · 6.24 KB
/
fixed_form1.f
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
subroutine dqawse(f,a,b,alfa,beta,integr,epsabs,epsrel,limit,
* result,abserr,neval,ier,alist,blist,rlist,elist,iord,last)
c***begin prologue dqawse
c***date written 800101 (yymmdd)
c***revision date 830518 (yymmdd)
c***category no. h2a2a1
c***keywords automatic integrator, special-purpose,
c algebraico-logarithmic end point singularities,
c clenshaw-curtis method
c***author piessens,robert,appl. math. & progr. div. - k.u.leuven
c de doncker,elise,appl. math. & progr. div. - k.u.leuven
c***purpose the routine calculates an approximation result to a given
c definite integral i = integral of f*w over (a,b),
c (where w shows a singular behaviour at the end points,
c see parameter integr).
c hopefully satisfying following claim for accuracy
c abs(i-result).le.max(epsabs,epsrel*abs(i)).
c***description
c
c integration of functions having algebraico-logarithmic
c end point singularities
c standard fortran subroutine
c double precision version
c***references (none)
c***routines called d1mach,dqc25s,dqmomo,dqpsrt
c***end prologue dqawse
c
double precision a,abserr,alfa,alist,area,area1,area12,area2,a1,
* a2,b,beta,blist,b1,b2,centre,dabs,dmax1,d1mach,elist,epmach,
* epsabs,epsrel,errbnd,errmax,error1,erro12,error2,errsum,f,
* resas1,resas2,result,rg,rh,ri,rj,rlist,uflow
integer ier,integr,iord,iroff1,iroff2,k,last,limit,maxerr,nev,
* neval,nrmax
c
external f
c
dimension alist(limit),blist(limit),rlist(limit),elist(limit),
* iord(limit),ri(25),rj(25),rh(25),rg(25)
c
c list of major variables
c -----------------------
c
c
c***first executable statement dqawse
epmach = d1mach(4)
uflow = d1mach(1)
c
c test on validity of parameters
c ------------------------------
c
ier = 6
neval = 0
last = 0
rlist(1) = 0.0d+00
elist(1) = 0.0d+00
iord(1) = 0
result = 0.0d+00
abserr = 0.0d+00
if(b.le.a.or.(epsabs.eq.0.0d+00.and.
* epsrel.lt.dmax1(0.5d+02*epmach,0.5d-28)).or.alfa.le.(-0.1d+01)
* .or.beta.le.(-0.1d+01).or.integr.lt.1.or.integr.gt.4.or.
* limit.lt.2) go to 999
ier = 0
c
c compute the modified chebyshev moments.
c
call dqmomo(alfa,beta,ri,rj,rg,rh,integr)
c
c integrate over the intervals (a,(a+b)/2) and ((a+b)/2,b).
c
centre = 0.5d+00*(b+a)
call dqc25s(f,a,b,a,centre,alfa,beta,ri,rj,rg,rh,area1,
* error1,resas1,integr,nev)
neval = nev
call dqc25s(f,a,b,centre,b,alfa,beta,ri,rj,rg,rh,area2,
* error2,resas2,integr,nev)
last = 2
neval = neval+nev
result = area1+area2
abserr = error1+error2
c
c test on accuracy.
c
errbnd = dmax1(epsabs,epsrel*dabs(result))
c
c initialization
c --------------
c
if(error2.gt.error1) go to 10
alist(1) = a
alist(2) = centre
blist(1) = centre
blist(2) = b
rlist(1) = area1
rlist(2) = area2
elist(1) = error1
elist(2) = error2
go to 20
10 alist(1) = centre
alist(2) = a
blist(1) = b
blist(2) = centre
rlist(1) = area2
rlist(2) = area1
elist(1) = error2
elist(2) = error1
20 iord(1) = 1
iord(2) = 2
if(limit.eq.2) ier = 1
if(abserr.le.errbnd.or.ier.eq.1) go to 999
errmax = elist(1)
maxerr = 1
nrmax = 1
area = result
errsum = abserr
iroff1 = 0
iroff2 = 0
c
c main do-loop
c ------------
c
do 60 last = 3,limit
c
c bisect the subinterval with largest error estimate.
c
a1 = alist(maxerr)
b1 = 0.5d+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
c
call dqc25s(f,a,b,a1,b1,alfa,beta,ri,rj,rg,rh,area1,
* error1,resas1,integr,nev)
neval = neval+nev
call dqc25s(f,a,b,a2,b2,alfa,beta,ri,rj,rg,rh,area2,
* error2,resas2,integr,nev)
neval = neval+nev
c
c improve previous approximations integral and error
c and test for accuracy.
c
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if(a.eq.a1.or.b.eq.b2) go to 30
if(resas1.eq.error1.or.resas2.eq.error2) go to 30
c
c test for roundoff error.
c
if(dabs(rlist(maxerr)-area12).lt.0.1d-04*dabs(area12)
* .and.erro12.ge.0.99d+00*errmax) iroff1 = iroff1+1
if(last.gt.10.and.erro12.gt.errmax) iroff2 = iroff2+1
30 rlist(maxerr) = area1
rlist(last) = area2
c
c test on accuracy.
c
errbnd = dmax1(epsabs,epsrel*dabs(area))
if(errsum.le.errbnd) go to 35
c
c set error flag in the case that the number of interval
c bisections exceeds limit.
c
if(last.eq.limit) ier = 1
c
c
c set error flag in the case of roundoff error.
c
if(iroff1.ge.6.or.iroff2.ge.20) ier = 2
c
c set error flag in the case of bad integrand behaviour
c at interior points of integration range.
c
if(dmax1(dabs(a1),dabs(b2)).le.(0.1d+01+0.1d+03*epmach)*
* (dabs(a2)+0.1d+04*uflow)) ier = 3
c
c append the newly-created intervals to the list.
c
35 if(error2.gt.error1) go to 40
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
go to 50
40 alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
c
c call subroutine dqpsrt to maintain the descending ordering
c in the list of error estimates and select the subinterval
c with largest error estimate (to be bisected next).
c
50 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
c ***jump out of do-loop
if (ier.ne.0.or.errsum.le.errbnd) go to 70
60 continue
c
c compute final result.
c ---------------------
c
70 result = 0.0d+00
do 80 k=1,last
result = result+rlist(k)
80 continue
abserr = errsum
999 return
end