Closed cbruder closed 6 years ago
The trouble is that it's having difficulty converging to the requested tolerance. It subdivides the integration more and more at the edges until it evaluates the integrand at the endpoint due to roundoff error. If you request a lower tolerance, then it gives the expected result:
julia> Cubature.hquadrature(x-> 1/sqrt(1-x^2),0.0,1.0,reltol=1e-6)
(1.570796265139041, 1.2599034852724116e-6)
The HCubature package uses a similar algorithm with a slightly different error estimation scheme, and can converge to slightly better tolerance on this integrand, but it still runs into trouble if you request too small of an error:
julia> HCubature.hquadrature(x-> 1/sqrt(1-x^2),0.0,1.0,rtol=1e-9)
(1.5707963193638252, 1.360839997999477e-9)
julia> HCubature.hquadrature(x-> 1/sqrt(1-x^2),0.0,1.0,rtol=1e-10)
(Inf, Inf)
If you want to do this kind of singular integral to high accuracy, ultimately you need a specialized quadrature scheme that removes the singularity.
For this particular kind of singularity, a standard technique would be Gauss–Chebyshev quadrature ... those weights can be computed by e.g. https://github.com/ajt60gaibb/FastGaussQuadrature.jl (or you can just use the formula from Wikipedia).
many thanks!
A good way to diagnose this is simply to print the integrand evaluations. Define p(f) = x -> let y = f(x); println("f($x) = $y"); y; end
and then you can do hquadrature(p(x-> 1/sqrt(1-x^2)),0.0,1.0)
If hquadrature only evaluates the integrand at the interior of the domain I would expect pi/2 in this example.