Arblib.integrate — Functionintegrate(f, a::Number, b::Number;
check_analytic::Bool = false,
take_prec::Bool = false,
prec = max(precision(a), precision(b)),
rtol = 0.0,
atol = 2.0^-prec,
warn_on_no_convergence = true,
opts::Union{acb_calc_integrate_opt_struct, Ptr{Cvoid}} = C_NULL)Computes a rigorous enclosure of the integral ∫ₐᵇ f(x) dx where f(x::AcbRef) is any (holomorphic) julia function. From Arb docs:
The integral follows a straight-line path between the complex numbers
aandb. For finite results,a,bmust be finite andfmust be bounded on the path of integration. To compute improper integrals, the user should therefore truncate the path of integration manually (or make a regularizing change of variables, if possible).
The error estimates used require that f is holomorphic on certain ellipses around the path of integration.
The integration algorithm combines direct interval enclosures, Gauss-Legendre quadrature where f is holomorphic, and adaptive subdivision. This strategy supports integrands with discontinuities while providing exponential convergence for typical piecewise holomorphic integrands.
In general the integration will work for any function which is holomorpic or meromorphic on the whole complex plane. For functions with branch cuts or other things which makes them non-holomorphic the argument check_analytic has to be set to true. In this case f will be given a keyword argument analytic::Bool, if analytic is false then nothing special has to be done, but if analytic is true then the output has to be non-finite (typically Acb(NaN)) if f is not holomorphic on the whole input ball.
Parameters:
take_precif true thenfwill be given the keyword argumentprec = prec, useful for functions requiring an explicit precision to be given.rtolrelative toleranceatolabsolute tolerancewarn_on_no_convergenceset this to false to avoid printing a warning in case the integration doesn't converge.optsaC_NULL(using the default options), or an instance ofacb_calc_integrate_opt_structcontrolling the algorithmic aspects of integration.
integrate does not guarantee to satisfy provided tolerances. But the integration result is guaranteed to be contained in the returned ball.
For more information please consider arblib documentation and the paper
Fredrik Johansson, Numerical integration in arbitrary-precision ball arithmetic, Mathematical Software – ICMS 2018 https://doi.org/10.1007/978-3-319-96418-8 https://arxiv.org/abs/1802.07942
See also: integrate!.
Examples
julia> Arblib.integrate(sin, 0, 10) # Integrate sin from 0 to 10
[1.83907152907645245225886394782406483451993016513316854683595373104879258687 +/- 5.15e-75]
julia> Arblib.integrate(z -> 1/z, Acb(1, -5), Acb(1, 5)) # Integrate 1/z from 1 - 5i to 1 + 5i
[+/- 2.02e-75] + [2.74680153389003172172254385288992229730199919179940161793956671182574846633 +/- 2.83e-75]im
julia> # Integrate √z from 1 - 5im to 1 + 5im, taking into account the branch cut at (-∞, 0]
julia> f = (z; analytic = false) -> begin
if analytic && Arblib.contains_nonpositive(real(z))
return Acb(NaN, prec = precision(z))
else
return sqrt(z)
end
end;
julia> Arblib.integrate(f, Acb(1, -5), Acb(1, 10), check_analytic = true, prec = 64)
[-9.0064084416559764 +/- 7.40e-17] + [23.8636067095598007 +/- 9.03e-17]imArblib.integrate! — Functionintegrate!(f!, res::Acb, a::Number, b::Number;
check_analytic::Bool = false,
take_prec::Bool = false,
prec::Integer = precision(res),
rtol = 0.0,
atol = 2.0^-prec,
warn_on_no_convergence = true,
opts::Union{acb_calc_integrate_opt_struct, Ptr{Cvoid}} = C_NULL,
)Like integrate, but make use of in-place operations. In particular, there are three differences from integrate:
The function
f!should be of the formf!(y, x) = set!(y, f(x)). That is, it writes the return value of the integandf(x)in-place into its first argumenty. (The return value off!is ignored).resis set to the result.The default precision is taken from
resinstead of fromaandb.
Examples
julia> Arblib.integrate!(Arblib.sin!, Acb(0), Acb(0), Acb(10)) # Integrate sin from 0 to 10
[1.83907152907645245225886394782406483451993016513316854683595373104879258687 +/- 5.15e-75]
julia> Arblib.integrate!(Arblib.inv!, Acb(0), Acb(1, -5), Acb(1, 5)) # Integrate 1/z from 1 - 5i to 1 + 5i
[+/- 2.02e-75] + [2.74680153389003172172254385288992229730199919179940161793956671182574846633 +/- 2.83e-75]im
julia> # Integrate √z from 1 - 5im to 1 + 5im, taking into account the branch cut at (-∞, 0]
julia> f! = (res, z; analytic = false) -> Arblib.sqrt_analytic!(res, z, analytic);
julia> Arblib.integrate!(f!, Acb(0), Acb(1, -5), Acb(1, 10), check_analytic = true, prec = 64)
[-9.0064084416559764 +/- 6.53e-17] + [23.8636067095598007 +/- 6.98e-17]im