diff --git a/docs/src/lib/operations.md b/docs/src/lib/operations.md index d388ace301..b694e0fd00 100644 --- a/docs/src/lib/operations.md +++ b/docs/src/lib/operations.md @@ -109,6 +109,7 @@ isempty(::Intersection) ∈(::AbstractVector{Real}, ::Intersection{Real}) isempty_known(::Intersection) set_isempty!(::Intersection, ::Bool) +swap(::Intersection) use_precise_ρ _projection ``` diff --git a/src/Approximations/overapproximate.jl b/src/Approximations/overapproximate.jl index d771bcf83c..f2befa89dc 100644 --- a/src/Approximations/overapproximate.jl +++ b/src/Approximations/overapproximate.jl @@ -305,5 +305,5 @@ function overapproximate(cap::Intersection{N, dir::AbstractDirections{N}; kwargs... ) where {N<:Real} - return overapproximate(cap.Y ∩ cap.X, dir; kwargs...) + return overapproximate(swap(cap), dir; kwargs...) end diff --git a/src/Intersection.jl b/src/Intersection.jl index 54a0a7582e..40b18bce50 100644 --- a/src/Intersection.jl +++ b/src/Intersection.jl @@ -3,6 +3,7 @@ import Base: isempty, ∈, ∩ export Intersection, isempty_known, set_isempty!, + swap, use_precise_ρ, IntersectionArray, array @@ -92,11 +93,14 @@ struct Intersection{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N} cache::IntersectionCache # default constructor with dimension check - function Intersection{N, S1, S2}(X::S1, Y::S2) where + function Intersection{N, S1, S2}(X::S1, + Y::S2; + cache::IntersectionCache=IntersectionCache() + ) where {N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} @assert dim(X) == dim(Y) "sets in an intersection must have the same " * "dimension" - return new{N, S1, S2}(X, Y, IntersectionCache()) + return new{N, S1, S2}(X, Y, cache) end end @@ -150,6 +154,30 @@ function set_isempty!(cap::Intersection, isempty::Bool) return set_isempty!(cap.cache, isempty) end +""" + swap(cap::Intersection{N, S1, S2})::Intersection{N} where {N<:Real, S1, S2} + +Return a new `Intersection` object with the arguments swapped. + +### Input + +- `cap` -- intersection of two convex sets + +### Output + +A new `Intersection` object with the arguments swapped. +The old cache is shared between the old and new objects. + +### Notes + +The advantage of using this function instead of manually swapping the arguments +is that the cache is shared. +""" +function swap(cap::Intersection{N, S1, S2} + )::Intersection{N} where {N<:Real, S1, S2} + return Intersection{N, S2, S1}(cap.Y, cap.X, cache=cap.cache) +end + # --- LazySet interface functions --- @@ -351,7 +379,7 @@ function ρ(d::AbstractVector{N}, <:LazySet{N}}; algorithm::String="line_search", kwargs...) where N<:Real - return ρ_helper(d, cap.Y ∩ cap.X, algorithm; kwargs...) + return ρ_helper(d, swap(cap), algorithm; kwargs...) end """ @@ -407,7 +435,7 @@ end function ρ(d::AbstractVector{N}, cap::Intersection{N, <:AbstractPolytope{N}, <:LazySet{N}}; kwargs...) where {N<:Real} - return ρ(d, cap.Y ∩ cap.X; kwargs...) + return ρ(d, swap(cap); kwargs...) end # disambiguation @@ -436,7 +464,7 @@ function ρ(d::AbstractVector{N}, <:AbstractPolytope{N}}; algorithm::String="line_search", kwargs...) where N<:Real - return ρ_helper(d, cap.Y ∩ cap.X, algorithm; kwargs...) + return ρ_helper(d, swap(cap), algorithm; kwargs...) end """