I believe @Ralph_Smith is correct in why you get confusing results (with the ArbFloat example). The Newton iterations are converging quadratically but you are only increasing the tolerance linearly, so most of the time it does the same number of iterations. Indeed the Mathematica result is also not accurate to 100 digits.
As a starting point let me compute the root to high precision (using my personal ArbExtras.jl package).
using SpecialFunctions, Arblib, ArbExtras
setprecision(Arb, 1024)
# Note that ellipe doesn't support Arb arguments so we go through the complex version
f(x::Arb) = real(ellipe(Acb(x))) - 13 // 10
df(x::Arb) = real(ellipe(Acb(x)) - ellipk(Acb(x)))/(2*x)
r0 = setball(Arb, 0.597, 1e-3) # Some initial enclosure of the root
r = ArbExtras.refine_root(f, r0, df = df, verbose = true)
This gives the output
[ Info: enclosure: [0.60 +/- 4.01e-3]
[ Info: enclosure: [0.59710 +/- 4.44e-6]
[ Info: enclosure: [0.5970995262 +/- 7.95e-11]
[ Info: enclosure: [0.5970995261535437979056 +/- 4.12e-23]
[ Info: enclosure: [0.5970995261535437979056290157285245402529726426867 +/- 2.12e-50]
[ Info: enclosure: [0.597099526153543797905629015728524540252972642686704964664637691431394465487456318730673086362723578116701 +/- 5.30e-106]
[ Info: enclosure: [0.59709952615354379790562901572852454025297264268670496466463769143139446548745631873067308636272357811670124731820824719418900915095793285799996819422478713629021168865105270107934991811685519209186640529643684042652259 +/- 9.09e-219]
[ Info: enclosure: [0.597099526153543797905629015728524540252972642686704964664637691431394465487456318730673086362723578116701247318208247194189009150957932857999968194224787136290211688651052701079349918116855192091866405296436840426522586446300241603087130298569879618160424746435212787624616426552989938655802225368867561743 +/- 8.78e-307]
[ Info: enclosure: [0.597099526153543797905629015728524540252972642686704964664637691431394465487456318730673086362723578116701247318208247194189009150957932857999968194224787136290211688651052701079349918116855192091866405296436840426522586446300241603087130298569879618160424746435212787624616426552989938655802225368867561743 +/- 8.50e-307]
[ Info: diameter only improved from (637534209 * 2^-1047) to (620756993 * 2^-1047) - stopping early
[0.597099526153543797905629015728524540252972642686704964664637691431394465487456318730673086362723578116701247318208247194189009150957932857999968194224787136290211688651052701079349918116855192091866405296436840426522586446300241603087130298569879618160424746435212787624616426552989938655802225368867561743 +/- 8.50e-307]
We can see that the Mathematica solution is only accurate to about 80 digits.
julia> r - Arb("0.5970995261535437979056290157285245402529726426867049646646376914313944654874531279615647217356979859")
[3.190769108364627025592216701247318208247194189009150957932857999968194224787136290211688651052701079349918116855192091866405296436840426522586446300241603087130298569879618160424746435212787624616426552989938655802225368867561743e-78 +/- 8.53e-307]
This is also the same solution you code finds
setprecision(ArbFloat, bits=1000)
f(x) = elliptic_e(x) - 13 // 10
df(x) = (elliptic_e(x) - elliptic_k(x))/(2*x)
f_df_for_problem = (f, df)
prob = ZeroProblem(f_df_for_problem, ArbFloat.((0., 1.)))
tol_arr = ArbFloat.([1e-5, 1e-10, 1e-15, 1e-20, 1e-25, 1e-30])
sol_arr = map(tol_arr) do tol
solve(prob, Roots.LithBoonkkampIJzermanBracket(), rtol = tol)
end
# Very high precision enclosure of root
r = ArbFloat("0.597099526153543797905629015728524540252972642686704964664637691431394465487456318730673086362723578116701247318208247194189009150957932857999968194224787136290211688651052701079349918116855192091866405296436840426522586446300241603087130298569879618160424746435212787624616426552989938655802225368867561743")
# Show error for roots
sol_arr .- r
This gives the output
6-element Vector{ArbFloat{1024}}:
1.101830987408181890667755211574514881826117882386650477156856095255801747838866539359810422200848823088037092438226759563013846778015117614144511412083260196085434790806715349605824142279781614219020667403865081804905862617288346518126978284084381903510854053651780045544266684946154934721956960778503e-6
4.890235796098269886094746750943470118688768023424265459778149270207280703880883637756928902897501946940702325383547627861579105626711762075959504672976726128831360057337088609386672293334896682530707328643737555808770885624950154112424482385206495461376641200642920707794266798310707653185660986592683e-18
4.890235796098269886094746750943470118688768023424265459778149270207280703880883637756928902897501946940702325383547627861579105626711762075959504672976726128831360057337088609386672293334896682530707328643737555808770885624950154112424482385206495461376641200642920707794266798310707653185660986592683e-18
1.245373578596568724871677098026871781915477713895901244737175565618205629160447838989352550644230462223862825279454214426092289169636327266777080919747716291758468599027274227774655613574232951647168308530825712622544584789621990300686490037973155307065048439975236284273010927759324897508834604413348e-52
1.245373578596568724871677098026871781915477713895901244737175565618205629160447838989352550644230462223862825279454214426092289169636327266777080919747716291758468599027274227774655613574232951647168308530825712622544584789621990300686490037973155307065048439975236284273010927759324897508834604413348e-52
1.245373578596568724871677098026871781915477713895901244737175565618205629160447838989352550644230462223862825279454214426092289169636327266777080919747716291758468599027274227774655613574232951647168308530825712622544584789621990300686490037973155307065048439975236284273010927759324897508834604413348e-52
Notice how the error jumps from 1e-18
to 1e-52
between one step. Then it doesn’t improve further due to already satisfying the required tolerance.
Regarding why the version with ArbReal
returns ArbFloat
I would guess it is because they use the type float(ArbReal)
for the computations, which is ArbFloat
. For most Julia types float(T)
gives you a more capable type numerically so it is very commonly used is numerical code. For ArbReal
it instead gives you a less capable type, which is a bit unfortunate.