Skip to content

Commit b5ce885

Browse files
edtreloKolaru
andauthored
Add iterate method for Root objects (#190)
* Implement iterate method for Root object * Add tests for the iterate method for Root objects --------- Co-authored-by: Benoît Richard <kolaru@hotmail.com>
1 parent 97c70c9 commit b5ce885

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

src/root_object.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,18 @@ IntervalArithmetic.isnai(r::Root) = isnai_region(root_region(r))
5454
function Base.:(==)(r1::Root, r2::Root)
5555
root_status(r1) != root_status(r2) && return false
5656
return isequal_region(root_region(r1), root_region(r2))
57-
end
57+
end
58+
59+
big(a::Root) = Root(big(a.interval), a.status)
60+
61+
"""
62+
Base.iterate(r::Root [, state])
63+
64+
Return successively the root region and status,
65+
allowing to unpack the root object as `region, status = root`.
66+
"""
67+
function Base.iterate(r::Root{T}, state::Integer=1) where {T}
68+
state == 1 && return (r.region, 2)
69+
state == 2 && return (r.status, 3)
70+
return nothing
71+
end

test/roots.jl

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,65 @@ end
310310
rts = roots(f, interval(0, 1) ; abstol = 1e-10, max_iteration)
311311
@test length(rts) <= max_iteration
312312
end
313+
end
314+
315+
# straightforward method for unpacking the elements of a root.
316+
function unpacking(r::Root{T}) where T
317+
return (r.region, r.status)
318+
end
319+
320+
@testset "Unpacking roots" begin
321+
@testset "1D" begin
322+
g(x) = cos(x) * sin(1 / x)
323+
324+
for r in roots(g, interval(0.05, 1))
325+
x, status = r
326+
@test isa(x, Interval)
327+
@test isa(status, Symbol)
328+
329+
# unpack using the straightforward method.
330+
unx, uns = unpacking(r)
331+
@test isequal_interval(x, unx)
332+
@test status == uns
333+
end
334+
335+
# function with two roots
336+
f(x) = x^2 - 1
337+
for r in roots(f, interval(-2, 2))
338+
x, status = r
339+
@test status == :unique
340+
end
341+
end
342+
343+
@testset "2D" begin
344+
f(x, y) = SVector(x^2 + y^2 - 1, y - 2x)
345+
f(X) = f(X...)
346+
X = SVector(interval(-6, 6), interval(-6, 6))
347+
348+
for (x, status) in roots(f, X)
349+
@test isa(x, SVector{2, <:Interval})
350+
@test isa(status, Symbol)
351+
end
352+
end
353+
354+
@testset "3D" begin
355+
h(x, y, z) = SVector(x^2 + y^2 + z^2 - 1, y - 2x, z - 2x)
356+
h(X) = h(X...)
357+
X = SVector(interval(-6, 6), interval(-6, 6), interval(-6, 6)) # cube in R^3
358+
359+
myroots = []
360+
unroots = []
361+
362+
for (x, status) in roots(h, X)
363+
@test isa(x, SVector{3, <:Interval})
364+
@test isa(status, Symbol)
365+
append!(myroots, x)
366+
end
367+
368+
for (x, status) in unpacking.(roots(h, X))
369+
append!(unroots, x)
370+
end
371+
372+
@test all(isequal_interval.(myroots, unroots))
373+
end
313374
end

0 commit comments

Comments
 (0)