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
a
andb
. For finite results,a
,b
must be finite andf
must 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.
Users are responsible for verifying holomorphicity of f
.
Parameters:
take_prec
if true thenf
will be given the keyword argumentprec = prec
, useful for functions requiring an explicit precision to be given.rtol
relative toleranceatol
absolute tolerancewarn_on_no_convergence
set this to false to avoid printing a warning in case the integration doesn't converge.opts
aC_NULL
(using the default options), or an instance ofacb_calc_integrate_opt_struct
controlling 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]im
Arblib.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).res
is set to the result.The default precision is taken from
res
instead of froma
andb
.
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