Skip to content

Commit d6a303a

Browse files
committed
Make quadgk type stable
Due to the reuse of some variables, there was a slowdown in the case of infinite limits.
1 parent 4ba21aa commit d6a303a

File tree

1 file changed

+11
-18
lines changed

1 file changed

+11
-18
lines changed

base/quadgk.jl

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function do_quadgk{Tw}(f, s, n, ::Type{Tw}, abstol, reltol, maxevals, nrm)
9797
map(x -> isinf(x) ? copysign(one(x), x) : 2x / (1+hypot(1,2x)), s),
9898
n, Tw, abstol, reltol, maxevals, nrm)
9999
end
100-
s0,si = inf1 ? (s2,s1) : (s1,s2)
100+
s0::eltype(s),si = inf1 ? (s2,s1) : (s1,s2)
101101
if si < 0 # x = s0 - t/(1-t)
102102
return do_quadgk(t -> begin den = 1 / (1 - t);
103103
f(s0 - t*den) * den*den; end,
@@ -113,7 +113,7 @@ function do_quadgk{Tw}(f, s, n, ::Type{Tw}, abstol, reltol, maxevals, nrm)
113113
end
114114

115115
key = rulekey(Tw,n)
116-
x,w,gw = haskey(rulecache, key) ? rulecache[key] :
116+
x::Vector{Tw}, w::Vector{Tw}, gw::Vector{Tw} = haskey(rulecache, key) ? rulecache[key] :
117117
(rulecache[key] = kronrod(Tw, n))
118118
segs = Segment[]
119119
for i in 1:length(s) - 1
@@ -129,14 +129,14 @@ function do_quadgk{Tw}(f, s, n, ::Type{Tw}, abstol, reltol, maxevals, nrm)
129129
# Pop the biggest-error segment and subdivide (h-adaptation)
130130
# until convergence is achieved or maxevals is exceeded.
131131
while E > abstol && E > reltol * nrm(I) && numevals < maxevals
132-
s = heappop!(segs, Reverse)
133-
mid = (s.a + s.b) * 0.5
134-
s1 = evalrule(f, s.a, mid, x,w,gw, nrm)
135-
s2 = evalrule(f, mid, s.b, x,w,gw, nrm)
136-
heappush!(segs, s1, Reverse)
137-
heappush!(segs, s2, Reverse)
138-
I = (I - s.I) + s1.I + s2.I
139-
E = (E - s.E) + s1.E + s2.E
132+
seg = heappop!(segs, Reverse)
133+
mid = (seg.a + seg.b) * 0.5
134+
seg1 = evalrule(f, seg.a, mid, x,w,gw, nrm)
135+
seg2 = evalrule(f, mid, seg.b, x,w,gw, nrm)
136+
heappush!(segs, seg1, Reverse)
137+
heappush!(segs, seg2, Reverse)
138+
I = (I - seg.I) + seg1.I + seg2.I
139+
E = (E - seg.E) + seg1.E + seg2.E
140140
numevals += 4n+2
141141
end
142142
# re-sum (paranoia about accumulated roundoff)
@@ -221,14 +221,7 @@ transformation is performed internally to map the infinite interval to a finite
221221
"""
222222
# generic version: determine precision from a combination of
223223
# all the integration-segment endpoints
224-
function quadgk(f, a, b, c...; kws...)
225-
T = promote_type(typeof(float(a)), typeof(b))
226-
for x in c
227-
T = promote_type(T, typeof(x))
228-
end
229-
cT = map(T, c)
230-
quadgk(f, convert(T, a), convert(T, b), cT...; kws...)
231-
end
224+
quadgk(f, a, b, c...; kws...) = quadgk(f, promote(float(a),float(b),c...)...; kws...)
232225

233226
###########################################################################
234227
# Gauss-Kronrod integration-weight computation for arbitrary floating-point

0 commit comments

Comments
 (0)