-
Notifications
You must be signed in to change notification settings - Fork 17
Open
Description
Arb has acb_calc, where acb_calc_integrate
is provided.
I tried to wrap the function as follows
#src/float/integrate.jl
struct acb_calc_integrate_opt_struct
deg_limit::Cint #slong
eval_limit::Cint #slong
depth_limit::Cint #slong
use_heap::Cint #int
verbose::Cint #int
function acb_calc_integrate_opt_struct(deg_limit::Integer, eval_limit::Integer,
depth_limit::Integer, use_heap::Integer=0, verbose::Integer=0)
return new(deg_limit, eval_limit, depth_limit, use_heap, verbose)
end
function acb_calc_integrate_opt_struct()
opts = new()
ccall(@libarb(acb_calc_integrate_opt_init), Cvoid,
(Ref{acb_calc_integrate_opt_struct},), opts)
return opts
end
end
function acb_calc_func(out::Ptr{ArbComplex}, inp::Ptr{ArbComplex},
param::Ptr{Cvoid}, order::Cint, prec::Cint)
@assert iszero(order) # || isone(order) ← we'd need to verify holomorphicity
x = unsafe_load(inp)
f = unsafe_pointer_to_objref(param)
ccall(@libarb(acb_set), Cvoid, (Ptr{ArbComplex}, Ref{ArbComplex}), out, f(x))
return zero(Cint)
end
acb_calc_func_cfun() = @cfunction(acb_calc_func, Cint,
(Ptr{ArbComplex}, Ptr{ArbComplex}, Ptr{Cvoid}, Cint, Cint))
function acb_calc_integrate(res::ArbComplex, cfun, param,
a::ArbComplex, b::ArbComplex, rel_goal::Integer, abs_tol::Mag,
options::acb_calc_integrate_opt_struct, prec::Integer)
status = ccall(@libarb(acb_calc_integrate), Cint,
(Ref{ArbComplex}, # res
Ptr{Cvoid}, # cfun
Any, # param
Ref{ArbComplex}, # a
Ref{ArbComplex}, # b
Cint, # rel_goal
Ref{Mag}, # abs_tol
Ref{acb_calc_integrate_opt_struct}, # options
Cint, # prec
),
res, cfun, param, a, b, rel_goal, abs_tol, options, prec)
return status
end
function integrate(f, a::Number, b::Number;
rel_tol=0.0, abs_tol=precision(ArbComplex),
opts::acb_calc_integrate_opt_struct = acb_calc_integrate_opt_struct())
res = zero(ArbComplex)
status = integrate!(res, f, ArbComplex(a), ArbComplex(b);
rel_tol=rel_tol, abs_tol=abs_tol, opts=opts)
# status:
# ARB_CALC_SUCCESS = 0
# ARB_CALC_NO_CONVERGENCE = 2
if status == 2
@warn "Arb integrate did not achived convergence, the result might be incorrect"
end
return res
end
function integrate!(res::ArbComplex, f, a::ArbNumber, b::ArbNumber;
rel_tol=0.0, abs_tol=abs_tol=max(precision(a), precision(b)),
opts::acb_calc_integrate_opt_struct=acb_calc_integrate_opt_struct())
prec = max(workingprecision(a), workingprecision(b))
if rel_tol <= zero(rel_tol)
crel_goal = prec
else
# crel_goal = r where rel_tol ~2^-r
crel_goal = -(ArbFloat(rel_tol).exp)
end
return acb_calc_integrate(res, acb_calc_func_cfun(),
f, ArbComplex(a), ArbComplex(b),
crel_goal, Mag(abs_tol), opts, prec)
end
but the function evaluation segfaults at line y = f(x)
modifying the function to
function acb_calc_func(out::Ptr{ArbComplex}, inp::Ptr{ArbComplex},
param::Ptr{Cvoid}, order::Cint, prec::Cint)
@assert iszero(order) # || isone(order) ← we'd need to verify holomorphicity
x = unsafe_load(inp)
f = unsafe_pointer_to_objref(param)
println("f(2) = $(f(ArbComplex(2)))")
println("Loaded x from $inp")
println("x = $x")
y = f(x)
println("y = $y")
ccall(@libarb(acb_set), Cvoid, (Ptr{ArbComplex}, Ref{ArbComplex}), out, y)
return zero(Cint)
end
now segfaults at first access of the value of x
, i.e. at println("x = $x")
(f
works correctly).
I'm quite confused, since similar code in Nemo
https://github.com/wbhart/Nemo.jl/blob/5f96afc4af415df5985432b56bd1a972a0025d4b/src/arb/acb_calc.jl#L2 works as expected.
Probably crel_goal
and the default values here and there need adjusting as well.
Metadata
Metadata
Assignees
Labels
No labels