Skip to content

Commit bfd84fb

Browse files
authored
Merge pull request #65 from JuliaIntervals/lb/iss64
Add deriv as another parameter of roots (instead of a keyword arg)
2 parents 13bc215 + 71ca13e commit bfd84fb

File tree

2 files changed

+51
-29
lines changed

2 files changed

+51
-29
lines changed

src/roots.jl

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ IntervalLike{T} = Union{Interval{T}, IntervalBox{T}}
119119
NewtonLike = Union{Type{Newton}, Type{Krawczyk}}
120120

121121
"""
122-
roots(f, X, contractor, tol=1e-3 ; deriv=nothing)
122+
roots(f, X, contractor, tol=1e-3)
123+
roots(f, deriv, X, contractor, tol=1e-3)
123124
124125
Uses a generic branch and prune routine to find in principle all isolated roots of a function
125126
`f:R^n → R^n` in a box `X`, or a vector of boxes.
@@ -134,36 +135,45 @@ Inputs:
134135
135136
"""
136137
# Contractor specific `roots` functions
137-
function roots(f, X::IntervalLike{T}, ::Type{Bisection}, tol::Float64=1e-3; deriv = nothing) where {T}
138+
function roots(f, X::IntervalLike{T}, ::Type{Bisection}, tol::Float64=1e-3) where {T}
138139
branch_and_prune(X, Bisection(f), tol)
139140
end
140141

141-
function roots(f, X::Interval{T}, C::NewtonLike, tol::Float64=1e-3; deriv = nothing) where {T}
142+
function roots(f, X::Interval{T}, C::NewtonLike, tol::Float64=1e-3) where {T}
142143

143-
if deriv == nothing
144-
deriv = x -> ForwardDiff.derivative(f, x)
145-
end
144+
deriv = x -> ForwardDiff.derivative(f, x)
145+
146+
roots(f, deriv, X, C, tol)
147+
end
146148

149+
function roots(f, deriv, X::Interval{T}, C::NewtonLike, tol::Float64=1e-3) where {T}
147150
branch_and_prune(X, C(f, deriv), tol)
148151
end
149152

150-
function roots(f, X::IntervalBox{T}, C::NewtonLike, tol::Float64=1e-3; deriv = nothing) where {T}
153+
function roots(f, X::IntervalBox{T}, C::NewtonLike, tol::Float64=1e-3) where {T}
151154

152-
if deriv == nothing
153-
deriv = x -> ForwardDiff.jacobian(f, x)
154-
end
155+
deriv = x -> ForwardDiff.jacobian(f, x)
155156

157+
roots(f, deriv, X, C, tol)
158+
end
159+
160+
function roots(f, deriv, X::IntervalBox{T}, C::NewtonLike, tol::Float64=1e-3) where {T}
156161
branch_and_prune(X, C(f, deriv), tol)
157162
end
158163

159-
roots(f, r::Root, contractor::Type{C}, tol::Float64=1e-3; deriv = nothing) where {C<:Contractor} = roots(f, r.interval, contractor, tol; deriv = deriv)
164+
roots(f, r::Root, contractor::Type{C}, tol::Float64=1e-3) where {C<:Contractor} =
165+
roots(f, r.interval, contractor, tol)
166+
roots(f, deriv, r::Root, contractor::Type{C}, tol::Float64=1e-3) where {C<:Contractor} =
167+
roots(f, deriv, r.interval, contractor, tol)
160168

161169

162170
# Acting on a Vector:
163171

164172
# TODO: Use previous status information about roots:
165-
roots(f, V::Vector{Root{T}}, contractor::Type{C}, tol::Float64=1e-3;
166-
deriv = nothing) where {T, C<:Contractor} = vcat(roots.(f, V, contractor, tol; deriv = deriv)...)
173+
roots(f, V::Vector{Root{T}}, contractor::Type{C}, tol::Float64=1e-3) where {T, C<:Contractor} =
174+
vcat(roots.(f, V, contractor, tol)...)
175+
roots(f, deriv, V::Vector{Root{T}}, contractor::Type{C}, tol::Float64=1e-3) where {T, C<:Contractor} =
176+
vcat(roots.(f, deriv, V, contractor, tol)...)
167177

168178

169179

@@ -179,22 +189,30 @@ function roots(f, Xc::Complex{Interval{T}}, contractor::Type{C},
179189
return [Root(Complex(root.interval...), root.status) for root in rts]
180190
end
181191

182-
function roots(f, Xc::Complex{Interval{T}}, C::NewtonLike, tol::Float64=1e-3;
183-
deriv = nothing) where {T}
192+
function roots(f, Xc::Complex{Interval{T}}, C::NewtonLike, tol::Float64=1e-3) where {T}
184193

185194
g = realify(f)
186195

187-
if deriv == nothing
188-
g_prime = x -> ForwardDiff.jacobian(g, x)
189-
else
190-
g_prime = realify_derivative(deriv)
191-
end
196+
g_prime = x -> ForwardDiff.jacobian(g, x)
197+
198+
Y = IntervalBox(reim(Xc))
199+
rts = roots(g, g_prime, Y, C, tol)
200+
201+
return [Root(Complex(root.interval...), root.status) for root in rts]
202+
end
203+
204+
function roots(f, deriv, Xc::Complex{Interval{T}}, C::NewtonLike, tol::Float64=1e-3) where {T}
205+
206+
g = realify(f)
207+
208+
g_prime = realify_derivative(deriv)
192209

193210
Y = IntervalBox(reim(Xc))
194-
rts = roots(g, Y, C, tol; deriv=g_prime)
211+
rts = roots(g, g_prime, Y, C, tol)
195212

196213
return [Root(Complex(root.interval...), root.status) for root in rts]
197214
end
198215

199216
# Default
200-
roots(f, X, tol::Float64=1e-15; deriv = nothing) = roots(f, X, Newton, tol; deriv = deriv)
217+
roots(f::F, deriv::F, X, tol::Float64=1e-15) where {F<:Function} = roots(f, deriv, X, Newton, tol)
218+
roots(f::F, X, tol::Float64=1e-15) where {F<:Function} = roots(f, X, Newton, tol)

test/roots.jl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ function all_unique(rts)
66
all(root_status.(rts) .== :unique)
77
end
88

9-
function test_newtonlike(f, X, method, nsol, tol=1e-3; deriv=nothing)
9+
function test_newtonlike(f, deriv, X, method, nsol, tol=1e-3)
1010
rts = roots(f, X, method)
1111
@test length(rts) == nsol
1212
@test all_unique(rts)
13-
@test rts == roots(f, X, method; deriv = deriv)
13+
@test rts == roots(f, deriv, X, method)
1414
end
1515

1616
newtonlike_methods = [Newton, Krawczyk]
@@ -30,7 +30,7 @@ newtonlike_methods = [Newton, Krawczyk]
3030
@test all_unique(rts)
3131

3232
for method in newtonlike_methods
33-
test_newtonlike(sin, -5..5, method, 3; deriv=cos)
33+
test_newtonlike(sin, cos, -5..5, method, 3)
3434
end
3535

3636
# Infinite interval
@@ -49,7 +49,8 @@ end
4949
@test length(rts) == 4
5050

5151
for method in newtonlike_methods
52-
test_newtonlike(f, X, method, 2; deriv = xx -> ForwardDiff.jacobian(f, xx))
52+
deriv = xx -> ForwardDiff.jacobian(f, xx)
53+
test_newtonlike(f, deriv, X, method, 2)
5354
end
5455

5556
# Infinite interval
@@ -78,7 +79,8 @@ end
7879
rts = roots(g, XX, method)
7980
@test length(rts) == 4
8081
@test all_unique(rts)
81-
@test rts == roots(g, XX, method; deriv = xx -> ForwardDiff.jacobian(g, xx))
82+
deriv = xx -> ForwardDiff.jacobian(g, xx)
83+
@test rts == roots(g, deriv, XX, method)
8284
end
8385
end
8486

@@ -89,7 +91,8 @@ end
8991
tol = 1e-5
9092

9193
for method in newtonlike_methods
92-
test_newtonlike(gradf, XX, method, 25, tol; deriv = xx -> ForwardDiff.jacobian(gradf, xx))
94+
deriv = xx -> ForwardDiff.jacobian(gradf, xx)
95+
test_newtonlike(gradf, deriv, XX, method, 25, tol)
9396
end
9497
end
9598

@@ -107,7 +110,8 @@ end
107110
@test length(rts) == 7
108111

109112
for method in newtonlike_methods
110-
test_newtonlike(f, Xc, method, 3; deriv = z -> 3*z^2)
113+
deriv = z -> 3*z^2
114+
test_newtonlike(f, deriv, Xc, method, 3)
111115
end
112116
end
113117

0 commit comments

Comments
 (0)