Check for Disjointness of Sets
The function isdisjoint checks whether the intersection of two sets is empty. It can optionally produce a witness if the intersection is nonempty.
Examples
We use the following four sets for illustration.
using LazySets, LazySets.Approximations, Plots
B1 = Ball1(-ones(2), 1.)
B2 = Ball2(ones(2), 1.)
BI = BallInf(zeros(2), 1.)
H = Hyperrectangle(ones(2), ones(2))
sets = [B1, B2, BI, H]
function plot_sets(sets)
for S in sets
println(S)
plot!(S, 1e-2, fillalpha=0.1)
end
end
function plot_points(points, prefix)
for i in eachindex(points)
p = points[i]
num_occur = length(findfirst(x -> x == p, points[1:i]))
x = p[1]
y = p[2]
if num_occur == 1
x += 0.15
elseif num_occur == 2
y += 0.15
elseif num_occur == 3
x -= 0.15
else
y -= 0.15
end
plot!(Singleton(p))
plot!(annotations=(x, y, text("$(prefix)$(i)")))
end
end
plot1 = plot()
plot_sets(sets)
plot1println(isdisjoint(BI, H))
w1 = isdisjoint(BI, H, true)[2]
println(isdisjoint(B1, BI))
w2 = isdisjoint(B1, BI, true)[2]
println(isdisjoint(B1, H))false
false
truewitnesses = [w1, w2]
plot1 = plot()
plot_sets(sets)
plot_points(witnesses, "w")
plot1Methods
Base.isdisjoint — Methodisdisjoint(X::LazySet, Y::LazySet, [witness]::Bool=false)Check whether two sets are disjoint (i.e., do not intersect), and optionally compute a witness.
Input
X– setY– setwitness– (optional, default:false) compute a witness if activated
Output
- If the
witnessoption is deactivated:trueiff $X ∩ Y = ∅$ - If the
witnessoption is activated:(true, [])iff $X ∩ Y = ∅$(false, v)iff $X ∩ Y ≠ ∅$ for some $v ∈ X ∩ Y$
Notes
The convenience alias is_intersection_empty is also available.
Base.isdisjoint — FunctionExtended help
isdisjoint(X::LazySet, S::AbstractSingleton, [witness]::Bool=false)Algorithm
Let $S = \{s\}$. Then $S ∩ X = ∅$ iff $s ∉ X$.
Base.isdisjoint — FunctionExtended help
isdisjoint(Z::AbstractZonotope, H::Hyperplane, [witness]::Bool=false)Algorithm
$Z ∩ H = ∅$ iff $(b - a⋅c) ∉ \left[ ± ∑_{i=1}^p |a⋅g_i| \right]$, where $a$, $b$ are the hyperplane coefficients, $c$ is the zonotope's center, and $g_i$ are the zonotope's generators.
For witness production we fall back to a less efficient implementation for general sets as the first argument.
Base.isdisjoint — FunctionExtended help
isdisjoint(X::LazySet, hp::Hyperplane, [witness]::Bool=false)Notes
This implementation assumes that the set X is convex.
Algorithm
A convex set intersects with a hyperplane iff the support function in the negative resp. positive direction of the hyperplane's normal vector $a$ is to the left resp. right of the hyperplane's constraint $b$:
\[-ρ(-a, X) ≤ b ≤ ρ(a, X)\]
For witness generation, we compute a line connecting the support vectors to the left and right, and then take the intersection of the line with the hyperplane. We follow this algorithm for the line-hyperplane intersection.
Base.isdisjoint — FunctionExtended help
isdisjoint(X::LazySet, hs::HalfSpace, [witness]::Bool=false)Algorithm
A set intersects with a half-space iff the support function in the negative direction of the half-space's normal vector $a$ is less than the constraint $b$ of the half-space: $-ρ(-a, X) ≤ b$.
For compact set X, we equivalently have that the support vector in the negative direction $-a$ is contained in the half-space: $σ(-a) ∈ hs$. The support vector is thus also a witness if the sets are not disjoint.
Base.isdisjoint — FunctionExtended help
isdisjoint(P::AbstractPolyhedron, X::LazySet, [witness]::Bool=false;
[solver]=nothing, [algorithm]="exact")Input
solver– (optional, default:nothing) the backend used to solve the linear programalgorithm– (optional, default:"exact") algorithm keyword, one of: *"exact" (exact, uses a feasibility LP) *"sufficient" (sufficient, uses half-space checks)
Notes
For algorithm == "exact", we assume that constraints_list(X) is defined. For algorithm == "sufficient", witness production is not supported.
For solver == nothing, we fall back to default_lp_solver(N).
Algorithm
For algorithm == "exact", see isempty(P::HPoly, ::Bool).
For algorithm == "sufficient", we rely on the intersection check between the set X and each constraint in P. This requires one support-function evaluation of X for each constraint of P. With this algorithm, the method may return false even in the case where the intersection is empty. On the other hand, if the algorithm returns true, then it is guaranteed that the intersection is empty.
Base.isdisjoint — FunctionExtended help
isdisjoint(C::Complement, X::LazySet, [witness]::Bool=false)Algorithm
We fall back to X ⊆ C.X, which can be justified as follows:
\[ X ∩ Y^C = ∅ ⟺ X ⊆ Y\]
Base.isdisjoint — FunctionExtended help
isdisjoint(cpa::CartesianProductArray, P::AbstractPolyhedron,
[witness]::Bool=false)Notes
This implementation assumes that the sets in the Cartesian product cpa are polyhedral.
cpa– Cartesian products of a finite number of polytopes
Algorithm
We first identify the blocks of cpa in which P is constrained. Then we project cpa to those blocks and convert the result to an HPolytope (or HPolyhedron if the set type is not known to be bounded) Q. Finally we determine whether Q and the projected P intersect.
Base.isdisjoint — FunctionExtended help
isdisjoint(X::CartesianProductArray, Y::CartesianProductArray,
[witness]::Bool=false)Notes
The implementation requires (and checks) that the Cartesian products have the same block structure.
Witness production is currently not supported.
Base.isdisjoint — FunctionExtended help
isdisjoint(cpa::CartesianProductArray, H::AbstractHyperrectangle,
[witness]::Bool=false)Algorithm
The sets cpa and H are disjoint if and only if at least one block of cpa and the corresponding projection of H are disjoint. We perform these checks sequentially.