Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revision of plotting #3657

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Approximations/overapproximate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@ end
Alias for `overapproximate(S, HPolygon, ε)`.
"""
function overapproximate(S::LazySet, ε::Real)
return overapproximate(S, HPolygon, ε)
if dim(S) == 1
return overapproximate(S, Interval)
else
return overapproximate(S, HPolygon, ε)
end
end

# special case: overapproximation of empty set
Expand Down
2 changes: 1 addition & 1 deletion src/LazyOperations/Intersection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ function plot_recipe(cap::Intersection{N}, ε::N=zero(N),
if isempty(cap)
return plot_recipe(EmptySet{N}(dim(cap)), ε)
elseif dim(cap) == 1
if !isconvextype(cap)
if !isconvextype(typeof(cap))
throw(ArgumentError("cannot plot a one-dimensional $(typeof(cap))"))
end
return plot_recipe(convert(Interval, cap), ε)
Expand Down
2 changes: 2 additions & 0 deletions src/Plotting/plot_recipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ function _plot_list_same_recipe(list::AbstractVector{VN}, ε::Real=N(PLOT_PRECIS
for Xi in list
if Xi isa Intersection
res = plot_recipe(Xi, ε, Nφ)
elseif dim(Xi) == 1
res = plot_recipe(Xi, ε)
else
# hard-code overapproximation here to avoid individual
# compilations for mixed sets
Expand Down
299 changes: 178 additions & 121 deletions test/Utils/plot.jl
Original file line number Diff line number Diff line change
@@ -1,129 +1,186 @@
using SparseArrays
using LinearAlgebra, SparseArrays
import Optim

for N in [Float64, Float32, Rational{Int}]
p0 = zero(N)
p1 = one(N)
v0 = zeros(N, 2)
v1 = ones(N, 2)

# ---------------
# set definitions
# ---------------

# bounded basic set types
b1 = Ball1(v0, p1)
bi = BallInf(v0, p1)
hr = Hyperrectangle(v0, v1)
itv = Interval(p0, p1)
ls = LineSegment(v0, v1)
st = Singleton(v1)
zt = Zonotope(v0, Diagonal(N[1, 1]))
zs = ZeroSet{N}(2)

# -------------------------------------------
# plot polytopes
# -------------------------------------------
plot(b1)
plot(bi)
plot(hr)
plot(itv)
plot(ls)
plot(st)
plot(zt)
plot(zs)

if N == Rational{Int}
# rationals do not support epsilon-close approximation
continue
end

# bounded basic set types which are not polytopes
b2 = Ball2(v0, p1)
bp = Ballp(N(1.5), v0, p1)
el = Ellipsoid(v0, Diagonal(N[1, 1]))

# unary set operations
spI = SparseMatrixCSC{N}(2I, 2, 2)
smIe = SparseMatrixExp(spI)
em = ExponentialMap(smIe, b2)
psme = ProjectionSparseMatrixExp(spI, smIe, spI)
epm = ExponentialProjectionMap(psme, b2)

# binary set operations
its = Intersection(b1, bi)
itsa = IntersectionArray([b1, bi])

# polygon/polytope types
constraints = [LinearConstraint([p1, p0], p1),
LinearConstraint([p0, p1], p1),
LinearConstraint([-p1, p0], p0),
LinearConstraint([p0, -p1], p0)]
hpg = HPolygon(constraints)
hpgo = HPolygonOpt(constraints)
hpt = HPolytope(constraints)
hpt_empty = HPolytope([HalfSpace(N[1, 0], N(0)), HalfSpace(N[-1, 0], N(-1)),
HalfSpace(N[0, 1], N(0)), HalfSpace(N[0, -1], N(0))])
vertices = vertices_list(bi)
vpg = VPolygon(vertices)
vpt = VPolytope(vertices)

# empty set
es = EmptySet{N}(2)

# infinite sets
hs = HalfSpace(v1, p1)
hp = Hyperplane(v1, p1)
l = Line2D(v1, p1)
uni = Universe{N}(2)

# unary set operations
sih = SymmetricIntervalHull(b1)
lm = LinearMap(N[2 1; 1 2], bi)
rm = ResetMap(bi, Dict(1 => N(1)))

# binary set operations
ch = ConvexHull(b1, bi)
cha = ConvexHullArray([b1, bi])

ms = MinkowskiSum(b1, bi)
msa = MinkowskiSumArray([b1, bi])
cms = CachedMinkowskiSumArray([b1, bi])
cp = CartesianProduct(itv, itv)
cpa = CartesianProductArray([itv, itv])

# ------------------------------------------------------------------
# plot using epsilon-close approximation (default threshold ε value)
# ------------------------------------------------------------------
if N == Float64 # Float32 requires promotion see #1304
plot(its)
end
plot(hpg)
plot(hpgo)
plot(hpt)
plot(hpt_empty)
plot(vpg)
plot(vpt)
plot(es)
plot(hs)
plot(hp)
plot(l)
plot(uni)
plot(ch)
plot(cha)
plot(sih)
plot(lm)
plot(rm)
plot(ms)
plot(msa)
plot(cms)
plot(cp)
plot(cpa)

if N == Float64
plot(itsa)
for n in [1, 2]
p0 = zero(N)
p1 = one(N)
v0 = zeros(N, n)
v1 = ones(N, n)

# ---------------
# set definitions
# ---------------

# bounded basic set types
b1 = Ball1(v0, p1)
bi = BallInf(v0, p1)
hr = Hyperrectangle(v0, v1)
st = Singleton(v1)
zt = Zonotope(v0, Diagonal(ones(N, n)))
zs = ZeroSet{N}(n)
itv = Interval(p0, p1)
if n == 2
ls = LineSegment(v0, v1)
end
if N <: AbstractFloat # `convert` not available for non-float
hpa = convert(HParallelotope, hr)
end

# -------------------------------------------
# plot polytopes
# -------------------------------------------
plot(b1)
plot(bi)
plot(hr)
plot(st)
plot(zt)
plot(zs)
if n == 1
plot(itv)
elseif n == 2
plot(ls)
end
if N <: AbstractFloat
plot(hpa)
end

if N == Rational{Int}
# rationals do not support epsilon-close approximation
continue
end

# bounded basic set types which are not polytopes
b2 = Ball2(v0, p1)
bp = Ballp(N(1.5), v0, p1)
el = Ellipsoid(v0, Diagonal(ones(N, n)))
# dpz = convert(DensePolynomialZonotope, zt) # TODO conversion currently missing
spz = convert(SparsePolynomialZonotope, zt)
sspz = convert(SimpleSparsePolynomialZonotope, zt)
if n == 2
ncp = Polygon([v0, v1])
end

# unary set operations
spI = SparseMatrixCSC{N}(2I, n, n)
smIe = SparseMatrixExp(spI)
em = ExponentialMap(smIe, b2)
psme = ProjectionSparseMatrixExp(spI, smIe, spI)
epm = ExponentialProjectionMap(psme, b2)

# binary set operations
its = Intersection(b1, bi)
itsa = IntersectionArray([b1, bi])

# polygon/polytope types
constraints = [LinearConstraint([p1, p0], p1),
LinearConstraint([p0, p1], p1),
LinearConstraint([-p1, p0], p0),
LinearConstraint([p0, -p1], p0)]
hpg = HPolygon(constraints)
hpgo = HPolygonOpt(constraints)
hpt = HPolytope(constraints)
hpt_empty = HPolytope([HalfSpace(N[1, 0], N(0)), HalfSpace(N[-1, 0], N(-1)),
HalfSpace(N[0, 1], N(0)), HalfSpace(N[0, -1], N(0))])
vlist = vertices_list(bi)
if n == 2
vpg = VPolygon(vlist)
end
vpt = VPolytope(vlist)

# empty set
es = EmptySet{N}(n)

# bounded sets
hs = HalfSpace(v1, p1)
hp = Hyperplane(v1, p1)
hph = HPolyhedron(constraints)
uni = Universe{N}(n)
l = Line(v0, v1)
if n == 2
l2D = Line2D(v1, p1)
end
sta = convert(Star, bi)

# unary set operations
sih = SymmetricIntervalHull(b1)
if n == 1
lm = LinearMap(hcat(N[2]), bi)
elseif n == 2
lm = LinearMap(N[2 1; 1 2], bi)
end
rm = ResetMap(bi, Dict(1 => N(1)))

# binary set operations
ch = ConvexHull(b1, bi)
cha = ConvexHullArray([b1, bi])
ms = MinkowskiSum(b1, bi)
msa = MinkowskiSumArray([b1, bi])
cms = CachedMinkowskiSumArray([b1, bi])
us = UnionSet(b1, bi)
usa = UnionSetArray([b1, bi])
if n == 2
cp = CartesianProduct(itv, itv)
cpa = CartesianProductArray([itv, itv])
end

# ------------------------------------------------------------------
# plot using epsilon-close approximation (default threshold ε value)
# ------------------------------------------------------------------
plot(b2)
plot(bp)
plot(el)
if n == 2
plot(ncp)
end
if N == Float64 # Float32 requires promotion see #1304
plot(its)
end
plot(hpg)
plot(hpgo)
plot(hpt)
plot(hpt_empty)
if n == 2
plot(vpg)
end
plot(vpt)
plot(es)
plot(hs)
plot(hp)
plot(hph)
plot(uni)
plot(l)
if n == 2
plot(l2D)
end
plot(sta)
plot(ch)
plot(cha)
plot(sih)
plot(lm)
plot(rm)
plot(ms)
plot(msa)
plot(cms)
if n == 2
plot(cp)
plot(cpa)
end
if N == Float64
plot(itsa)
end

# recipes using kwargs are not supported with the workaround we use here
# @test_broken plot(dpz)
@test_broken plot(spz)
@test_broken plot(sspz)
@test_broken plot(us)
@test_broken plot(usa)
end
end

using StaticArrays

for N in [Float64]
# test plot with static arrays input
Z = Zonotope(SA[N(1), N(0)], SA[N(1) N(0); N(0) N(1)])
Expand Down
Loading