From 616cfe2c4d196512cd4f9379181f9a16b06e4d0e Mon Sep 17 00:00:00 2001 From: maltezfaria Date: Tue, 18 Feb 2025 20:33:11 -0300 Subject: [PATCH] avoid recursion in extrapolate --- src/Richardson.jl | 10 ++++++++-- test/runtests.jl | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Richardson.jl b/src/Richardson.jl index a0b636f..a5bdd5f 100644 --- a/src/Richardson.jl +++ b/src/Richardson.jl @@ -75,9 +75,15 @@ function extrapolate(f, h_::Number; contract::Number=oftype(float(real(h_)), 0.1 atol::Real=0, rtol::Real = atol > zero(atol) ? zero(one(float(real(x0+h_)))) : sqrt(eps(typeof(one(float(real(x0+h_)))))), maxeval::Integer=typemax(Int), breaktol::Real=2) if isinf(x0) - # use a change of variables x = 1/u - return extrapolate(u -> f(inv(u)), inv(h_); rtol=rtol, atol=atol, maxeval=maxeval, contract = abs(contract) > 1 ? inv(contract) : contract, x0=inv(x0), power=power) + # use a change of variables x = 1/u + contract = abs(contract) > 1 ? inv(contract) : contract + _extrapolate(u -> f(inv(u)), inv(h_), contract, inv(x0), power, atol, rtol, maxeval, breaktol) + else + _extrapolate(f, h_, contract, x0, power, atol, rtol, maxeval, breaktol) end +end + +function _extrapolate(f, h_::Number, contract, x0, power, atol, rtol, maxeval, breaktol) (rtol ≥ 0 && atol ≥ zero(atol)) || throw(ArgumentError("rtol and atol must be nonnegative")) breaktol > 0 || throw(ArgumentError("breaktol must be positive")) 0 < abs(contract) < 1 || throw(ArgumentError("contract must be in (0,1)")) diff --git a/test/runtests.jl b/test/runtests.jl index cd98e7f..754b9a6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -127,3 +127,9 @@ end @test_throws ArgumentError extrapolate!([(sin(h)/h,h) for h in [1, 0.8, 1.3]]) @test_throws ArgumentError extrapolate!([(sin(h)/h,h) for h in [1, 0.8, 0.8]]) end + + +@testset "type stability" begin + @inferred extrapolate(x -> sin(x)/x, 1) + @inferred extrapolate(x -> sin(x)/x, 1.0) +end