@@ -10,7 +10,11 @@ function do_quadgk(f::F, s::NTuple{N,T}, n, atol, rtol, maxevals, nrm, segbuf) w
1010 if f isa BatchIntegrand
1111 segs = evalrules (f, s, x,w,gw, nrm)
1212 else
13- segs = ntuple (i -> evalrule (f, s[i],s[i+ 1 ], x,w,gw, nrm), Val {N-1} ())
13+ segs = ntuple (Val {N-1} ()) do i
14+ a, b = s[i], s[i+ 1 ]
15+ check_endpoint_roundoff (a, b, x, throw_error= true )
16+ evalrule (f, a,b, x,w,gw, nrm)
17+ end
1418 end
1519 if f isa InplaceIntegrand
1620 I = f. I .= segs[1 ]. I
5761function refine (f:: F , segs:: Vector{T} , I, E, numevals, x,w,gw,n, atol, rtol, maxevals, nrm) where {F, T}
5862 s = heappop! (segs, Reverse)
5963 mid = (s. a + s. b) / 2
64+
65+ # early return if integrand evaluated at endpoints
66+ if check_endpoint_roundoff (s. a, mid, x) || check_endpoint_roundoff (mid, s. b, x)
67+ heappush! (segs, s, Reverse)
68+ return segs
69+ end
70+
6071 s1 = evalrule (f, s. a, mid, x,w,gw, nrm)
6172 s2 = evalrule (f, mid, s. b, x,w,gw, nrm)
73+
6274 if f isa InplaceIntegrand
6375 I .= (I .- s. I) .+ s1. I .+ s2. I
6476 else
@@ -164,6 +176,16 @@ function handle_infinities(workfunc, f::InplaceIntegrand, s)
164176 return workfunc (f, s, identity)
165177end
166178
179+ function check_endpoint_roundoff (a, b, x; throw_error:: Bool = false )
180+ c = convert (eltype (x), 0.5 ) * (b- a)
181+ (eval_at_a = a == a + (1 + x[1 ])* c) && throw_error && throw_endpoint_error (a, a, b)
182+ (eval_at_b = b == a + (1 - x[1 ])* c) && throw_error && throw_endpoint_error (b, a, b)
183+ eval_at_a || eval_at_b
184+ end
185+ function throw_endpoint_error (x, a, b)
186+ throw (DomainError (x, " roundoff error detected near endpoint of the initial interval ($a , $b )" ))
187+ end
188+
167189# Gauss-Kronrod quadrature of f from a to b to c...
168190
169191"""
0 commit comments