From b074993fa12f30abd41ba9e1c998090eb5054d28 Mon Sep 17 00:00:00 2001 From: schillic Date: Tue, 18 Jul 2023 21:51:30 +0200 Subject: [PATCH 1/5] fix bug in plot check --- src/LazyOperations/Intersection.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LazyOperations/Intersection.jl b/src/LazyOperations/Intersection.jl index f6becba70a..7335557941 100644 --- a/src/LazyOperations/Intersection.jl +++ b/src/LazyOperations/Intersection.jl @@ -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), ε) From 3feaad4cc9345da80b1ce1d29387bcbc63d517ab Mon Sep 17 00:00:00 2001 From: schillic Date: Tue, 18 Jul 2023 21:52:25 +0200 Subject: [PATCH 2/5] allow epsilon-close overapproximation of 1D sets --- src/Approximations/overapproximate.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Approximations/overapproximate.jl b/src/Approximations/overapproximate.jl index 52ccff7fb9..3dfbace713 100644 --- a/src/Approximations/overapproximate.jl +++ b/src/Approximations/overapproximate.jl @@ -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 From 612e8af39fa11205a3c2d88066cd2853ee5f82db Mon Sep 17 00:00:00 2001 From: schillic Date: Tue, 18 Jul 2023 22:11:50 +0200 Subject: [PATCH 3/5] fix list plotting of 1D set --- src/Plotting/plot_recipes.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Plotting/plot_recipes.jl b/src/Plotting/plot_recipes.jl index b4ccb9a251..6a4462b07a 100644 --- a/src/Plotting/plot_recipes.jl +++ b/src/Plotting/plot_recipes.jl @@ -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 From b77dc9b6f0eb31ea0d14d6f7883ebf235b41c1c9 Mon Sep 17 00:00:00 2001 From: schillic Date: Tue, 18 Jul 2023 21:52:42 +0200 Subject: [PATCH 4/5] test plot recipes in 1D --- test/Utils/plot.jl | 272 +++++++++++++++++++++++++-------------------- 1 file changed, 151 insertions(+), 121 deletions(-) diff --git a/test/Utils/plot.jl b/test/Utils/plot.jl index d1de7821e9..63d34c103b 100644 --- a/test/Utils/plot.jl +++ b/test/Utils/plot.jl @@ -1,129 +1,159 @@ -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 + + # ------------------------------------------- + # 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 == 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))) + + # 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) + + # infinite sets + hs = HalfSpace(v1, p1) + hp = Hyperplane(v1, p1) + uni = Universe{N}(n) + if n == 2 + l = Line2D(v1, p1) + end + + # 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) + # ------------------------------------------------------------------ + 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(uni) + if n == 2 + plot(l) + end + plot(ch) + plot(cha) + plot(sih) + plot(lm) + plot(rm) + plot(ms) + plot(msa) + plot(cms) + # the UnionSet(Array) recipe uses kwargs, which are not supported with the workaround we use here + @test_broken plot(us) + @test_broken plot(usa) + if n == 2 + plot(cp) + plot(cpa) + end + + if N == Float64 + plot(itsa) + end 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)]) From 4487db05772ddbedd5a70964c8faee2834bc5d3c Mon Sep 17 00:00:00 2001 From: schillic Date: Fri, 29 Nov 2024 19:29:51 +0100 Subject: [PATCH 5/5] test missing set types --- test/Utils/plot.jl | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/test/Utils/plot.jl b/test/Utils/plot.jl index 63d34c103b..0043869ca1 100644 --- a/test/Utils/plot.jl +++ b/test/Utils/plot.jl @@ -23,6 +23,9 @@ for N in [Float64, Float32, Rational{Int}] if n == 2 ls = LineSegment(v0, v1) end + if N <: AbstractFloat # `convert` not available for non-float + hpa = convert(HParallelotope, hr) + end # ------------------------------------------- # plot polytopes @@ -38,6 +41,9 @@ for N in [Float64, Float32, Rational{Int}] elseif n == 2 plot(ls) end + if N <: AbstractFloat + plot(hpa) + end if N == Rational{Int} # rationals do not support epsilon-close approximation @@ -48,6 +54,12 @@ for N in [Float64, Float32, Rational{Int}] 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) @@ -79,13 +91,16 @@ for N in [Float64, Float32, Rational{Int}] # empty set es = EmptySet{N}(n) - # infinite sets + # bounded sets hs = HalfSpace(v1, p1) hp = Hyperplane(v1, p1) + hph = HPolyhedron(constraints) uni = Universe{N}(n) + l = Line(v0, v1) if n == 2 - l = Line2D(v1, p1) + l2D = Line2D(v1, p1) end + sta = convert(Star, bi) # unary set operations sih = SymmetricIntervalHull(b1) @@ -112,6 +127,12 @@ for N in [Float64, Float32, Rational{Int}] # ------------------------------------------------------------------ # 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 @@ -126,10 +147,13 @@ for N in [Float64, Float32, Rational{Int}] plot(es) plot(hs) plot(hp) + plot(hph) plot(uni) + plot(l) if n == 2 - plot(l) + plot(l2D) end + plot(sta) plot(ch) plot(cha) plot(sih) @@ -138,17 +162,20 @@ for N in [Float64, Float32, Rational{Int}] plot(ms) plot(msa) plot(cms) - # the UnionSet(Array) recipe uses kwargs, which are not supported with the workaround we use here - @test_broken plot(us) - @test_broken plot(usa) 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