Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect error estimate depending on a very specific value of a parameter #26

Closed
ikirill opened this issue Jul 8, 2018 · 6 comments
Closed

Comments

@ikirill
Copy link

ikirill commented Jul 8, 2018

I think there's something wrong with the way quadgk handles this integral, the error estimate is almost zero but the answer is substantially inaccurate. Just replacing 0.499 with 0.4999 fixes it:

julia> check(f,a,b) = let (x1,e1) = QuadGK.quadgk(f,a,b); (x2,e2) = QuadGK.quadgk(f,big(a),big(b)); (Float64(abs(x1-x2)), e1); end
check (generic function with 1 method)

julia> check(x -> exp(abs(x-0.499)), 0, 1)
(1.0000000833402914e-6, 2.220446049250313e-16)

julia> check(x -> exp(abs(x-0.4999)), 0, 1)
(7.284892445276705e-17, 1.1102230246251565e-16)

It's an easy integral, so zero error estimate can be expected, but there could be something going wrong with the integral value it actually returns.

@stevengj
Copy link
Member

stevengj commented Jul 8, 2018

It's not at all an "easy" integral, because the integrand has a slope discontinuity in the middle of the integration region. QuadGK, like essentially all integration algorithms, is best for smooth integrands. The discontinuity not only messes up the convergence rate, it also messes up the error estimate.

(It similarly screws up the BigFloat integral, so your error estimate is not accurate.)

@stevengj
Copy link
Member

stevengj commented Jul 8, 2018

An accurate way to do this integral is to break the integration interval up into the regions before and after the discontinuity:

julia> x1,e1 = QuadGK.quadgk(x -> exp(abs(x - 0.499)), 0, 1) # inaccurate
(1.297443190121581, 2.220446049250313e-16)

julia> x2,e2 = QuadGK.quadgk(x -> exp(abs(x - 0.499)), 0, 0.499, 1) # accurate
(1.2974441901216642, 1.1102230246251565e-16)

julia> x1-x2 # error
-1.0000000831844602e-6

The same procedure shows the error with 0.4999 is not 1e-17:

julia> x1,e1 = QuadGK.quadgk(x -> exp(abs(x - 0.4999)), 0, 1)
(1.297442547887469, 1.1102230246251565e-16)

julia> x2,e2 = QuadGK.quadgk(x -> exp(abs(x - 0.4999)), 0, 0.4999, 1)
(1.2974425578874689, 1.1102230246251565e-16)

julia> x1-x2
-9.99999993922529e-9

@ikirill
Copy link
Author

ikirill commented Jul 9, 2018

Yikes, I see, I messed that up, I thought the BigFloat version was okay.

@ikirill ikirill closed this as completed Jul 9, 2018
@ikirill
Copy link
Author

ikirill commented Jul 9, 2018

Would you consider the incorrect error estimate a bug on its own? (I was reading https://www.research-collection.ethz.ch/bitstream/handle/20.500.11850/13300/eth-65-02.pdf and just wanted to see what QuadGK would do on some of the test functions.)

@stevengj
Copy link
Member

stevengj commented Jul 9, 2018

I wouldn't consider that a bug, I would consider that an inherent limitation/tradeoff of Gauss–Kronrod adaptive quadrature. It would be great to have additional quadrature schemes, of course.

@stevengj
Copy link
Member

stevengj commented Jul 9, 2018

Note that if you have a non-smooth integrand, you are better off with a lower-order quadrature — for this integrand, I get about the same accuracy, a better error estimate, and about half as many function evaluations if I pass order=3 to quadgk (the default is order=7).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants