From bb16ebaea624bc20cc27861f83ea5ec5b2e346c2 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 4 Jan 2025 22:21:35 +0100 Subject: [PATCH 1/3] AbstractPolynomialZonotope: add 'convex_hull' --- .../lib/interfaces/AbstractPolynomialZonotope.md | 4 ++-- docs/src/lib/sets/DensePolynomialZonotope.md | 4 ++-- .../src/lib/sets/SimpleSparsePolynomialZonotope.md | 13 +------------ docs/src/lib/sets/SparsePolynomialZonotope.md | 4 ++-- src/ConcreteOperations/convex_hull.jl | 13 +++++++++++++ src/Interfaces/AbstractPolynomialZonotope.jl | 4 ++++ .../SimpleSparsePolynomialZonotope/convex_hull.jl | 14 -------------- 7 files changed, 24 insertions(+), 32 deletions(-) diff --git a/docs/src/lib/interfaces/AbstractPolynomialZonotope.md b/docs/src/lib/interfaces/AbstractPolynomialZonotope.md index 8a0386a06c..b04a229191 100644 --- a/docs/src/lib/interfaces/AbstractPolynomialZonotope.md +++ b/docs/src/lib/interfaces/AbstractPolynomialZonotope.md @@ -35,6 +35,7 @@ This interface defines the following functions: ```@docs ngens(::AbstractPolynomialZonotope) order(::AbstractPolynomialZonotope) +convex_hull(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope) ``` ```@meta @@ -44,6 +45,7 @@ CurrentModule = LazySets.API Undocumented implementations: * [`center`](@ref center(::LazySet, ::Int)) +* [`convex_hull`](@ref convex_hull(::LazySet)) * [`dim`](@ref dim(::LazySet)) * [`isboundedtype`](@ref isboundedtype(::Type{LazySet})) * [`isempty`](@ref isempty(::LazySet)) @@ -60,7 +62,6 @@ Inherited from [`LazySet`](@ref): * [`complement`](@ref complement(::LazySet)) * [`concretize`](@ref concretize(::LazySet)) * [`constraints`](@ref constraints(::LazySet)) -* [`convex_hull`](@ref convex_hull(::LazySet)) * `copy(::Type{LazySet})` * [`diameter`](@ref diameter(::LazySet, ::Real=Inf)) * [`eltype`](@ref eltype(::Type{<:LazySet})) @@ -93,7 +94,6 @@ Inherited from [`LazySet`](@ref): * [`ρ`](@ref ρ(::AbstractVector, ::LazySet)) * [`translate`](@ref translate(::LazySet, ::AbstractVector)) * [`cartesian_product`](@ref cartesian_product(::LazySet, ::LazySet)) -* [`convex_hull`](@ref convex_hull(::LazySet, ::LazySet)) * [`exact_sum`](@ref exact_sum(::LazySet, ::LazySet)) * [`≈`](@ref ≈(::LazySet, ::LazySet)) * [`isdisjoint`](@ref isdisjoint(::LazySet, ::LazySet)) diff --git a/docs/src/lib/sets/DensePolynomialZonotope.md b/docs/src/lib/sets/DensePolynomialZonotope.md index 966a983604..24af2304e6 100644 --- a/docs/src/lib/sets/DensePolynomialZonotope.md +++ b/docs/src/lib/sets/DensePolynomialZonotope.md @@ -37,7 +37,6 @@ Inherited from [`LazySet`](@ref): * [`complement`](@ref complement(::LazySet)) * [`concretize`](@ref concretize(::LazySet)) * [`constraints`](@ref constraints(::LazySet)) -* [`convex_hull`](@ref convex_hull(::LazySet)) * `copy(::Type{LazySet})` * [`diameter`](@ref diameter(::LazySet, ::Real=Inf)) * [`eltype`](@ref eltype(::Type{<:LazySet})) @@ -70,7 +69,6 @@ Inherited from [`LazySet`](@ref): * [`ρ`](@ref ρ(::AbstractVector, ::LazySet)) * [`translate`](@ref translate(::LazySet, ::AbstractVector)) * [`cartesian_product`](@ref cartesian_product(::LazySet, ::LazySet)) -* [`convex_hull`](@ref convex_hull(::LazySet, ::LazySet)) * [`exact_sum`](@ref exact_sum(::LazySet, ::LazySet)) * [`≈`](@ref ≈(::LazySet, ::LazySet)) * [`isdisjoint`](@ref isdisjoint(::LazySet, ::LazySet)) @@ -84,9 +82,11 @@ Inherited from [`LazySet`](@ref): Inherited from [`AbstractPolynomialZonotope`](@ref): * [`center`](@ref center(::AbstractPolynomialZonotope, ::Int)) +* [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope)) * [`dim`](@ref dim(::AbstractPolynomialZonotope)) * [`isboundedtype`](@ref isboundedtype(::Type{AbstractPolynomialZonotope})) * [`isempty`](@ref isempty(::AbstractPolynomialZonotope)) * [`isuniversal`](@ref isuniversal(::AbstractPolynomialZonotope)) * [`ngens`](@ref ngens(::AbstractPolynomialZonotope)) * [`order`](@ref dim(::AbstractPolynomialZonotope)) +* [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) diff --git a/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md b/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md index 24abc4e9b6..4365e51d1e 100644 --- a/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md +++ b/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md @@ -84,18 +84,6 @@ CurrentModule = LazySets.SimpleSparsePolynomialZonotopeModule cartesian_product(::SimpleSparsePolynomialZonotope, ::SimpleSparsePolynomialZonotope) ``` ```@meta -CurrentModule = LazySets -``` -```@docs; canonical=false -convex_hull(::LazySet, ::LazySet) -``` -```@meta -CurrentModule = LazySets.SimpleSparsePolynomialZonotopeModule -``` -```@docs -convex_hull(::SimpleSparsePolynomialZonotope, ::SimpleSparsePolynomialZonotope) -``` -```@meta CurrentModule = LazySets.API ``` ```@docs; canonical=false @@ -192,6 +180,7 @@ Inherited from [`AbstractPolynomialZonotope`](@ref): * [`isempty`](@ref isempty(::AbstractPolynomialZonotope)) * [`isuniversal`](@ref isuniversal(::AbstractPolynomialZonotope)) * [`order`](@ref order(::AbstractPolynomialZonotope)) +* [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) Inherited from [`AbstractSparsePolynomialZonotope`](@ref): * [`ngens_dep`](@ref ngens_dep(::AbstractSparsePolynomialZonotope)) diff --git a/docs/src/lib/sets/SparsePolynomialZonotope.md b/docs/src/lib/sets/SparsePolynomialZonotope.md index 39e5c3abad..8f3ec7e213 100644 --- a/docs/src/lib/sets/SparsePolynomialZonotope.md +++ b/docs/src/lib/sets/SparsePolynomialZonotope.md @@ -104,7 +104,6 @@ Inherited from [`LazySet`](@ref): * [`complement`](@ref complement(::LazySet)) * [`concretize`](@ref concretize(::LazySet)) * [`constraints`](@ref constraints(::LazySet)) -* [`convex_hull`](@ref convex_hull(::LazySet)) * `copy(::Type{LazySet})` * [`diameter`](@ref diameter(::LazySet, ::Real=Inf)) * [`eltype`](@ref eltype(::Type{<:LazySet})) @@ -134,7 +133,6 @@ Inherited from [`LazySet`](@ref): * [`sample`](@ref sample(::LazySet, ::Int=1)) * [`scale`](@ref scale(::Real, ::LazySet)) * [`σ`](@ref σ(::AbstractVector, ::LazySet)) -* [`convex_hull`](@ref convex_hull(::LazySet, ::LazySet)) * [`≈`](@ref ≈(::LazySet, ::LazySet)) * [`isdisjoint`](@ref isdisjoint(::LazySet, ::LazySet)) * [`==`](@ref ==(::LazySet, ::LazySet)) @@ -146,12 +144,14 @@ Inherited from [`LazySet`](@ref): Inherited from [`AbstractPolynomialZonotope`](@ref): * [`center`](@ref center(::AbstractPolynomialZonotope, ::Int)) +* [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope)) * [`dim`](@ref dim(::AbstractPolynomialZonotope)) * [`isboundedtype`](@ref isboundedtype(::Type{AbstractPolynomialZonotope})) * [`isempty`](@ref isempty(::AbstractPolynomialZonotope)) * [`isuniversal`](@ref isuniversal(::AbstractPolynomialZonotope)) * [`ngens`](@ref ngens(::AbstractPolynomialZonotope)) * [`order`](@ref order(::AbstractPolynomialZonotope)) +* [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) Inherited from [`AbstractSparsePolynomialZonotope`](@ref): * [`ngens_dep`](@ref ngens_dep(::AbstractSparsePolynomialZonotope)) diff --git a/src/ConcreteOperations/convex_hull.jl b/src/ConcreteOperations/convex_hull.jl index f908553261..54a54d393c 100644 --- a/src/ConcreteOperations/convex_hull.jl +++ b/src/ConcreteOperations/convex_hull.jl @@ -485,3 +485,16 @@ end @commutative function convex_hull(X::LazySet, ∅::EmptySet) return EmptySetModule._convex_hull_emptyset(∅, X) end + +""" +# Extended help + + convex_hull(PZ1::AbstractPolynomialZonotope, PZ2::AbstractPolynomialZonotope) + +### Output + +The tightest convex polynomial zonotope containing `P1` and `P2`. +""" +function convex_hull(PZ1::AbstractPolynomialZonotope, PZ2::AbstractPolynomialZonotope) + return linear_combination(convex_hull(PZ1), convex_hull(PZ2)) +end diff --git a/src/Interfaces/AbstractPolynomialZonotope.jl b/src/Interfaces/AbstractPolynomialZonotope.jl index 1e0f2c7923..1af7767738 100644 --- a/src/Interfaces/AbstractPolynomialZonotope.jl +++ b/src/Interfaces/AbstractPolynomialZonotope.jl @@ -128,3 +128,7 @@ dim(PZ::AbstractPolynomialZonotope) = length(center(PZ)) isempty(PZ::AbstractPolynomialZonotope) = false isuniversal(PZ::AbstractPolynomialZonotope) = false + +function convex_hull(PZ::AbstractPolynomialZonotope) + return convex_hull(convert(SimpleSparsePolynomialZonotope, PZ)) +end diff --git a/src/Sets/SimpleSparsePolynomialZonotope/convex_hull.jl b/src/Sets/SimpleSparsePolynomialZonotope/convex_hull.jl index 485b88a413..09f02cb12b 100644 --- a/src/Sets/SimpleSparsePolynomialZonotope/convex_hull.jl +++ b/src/Sets/SimpleSparsePolynomialZonotope/convex_hull.jl @@ -10,17 +10,3 @@ The tightest convex simple sparse polynomial zonotope containing `P`. function convex_hull(P::SimpleSparsePolynomialZonotope) return linear_combination(P, P) end - -""" -# Extended help - - convex_hull(P1::SimpleSparsePolynomialZonotope, - P2::SimpleSparsePolynomialZonotope) - -### Output - -The tightest convex simple sparse polynomial zonotope containing `P1` and `P2`. -""" -function convex_hull(P1::SimpleSparsePolynomialZonotope, P2::SimpleSparsePolynomialZonotope) - return linear_combination(linear_combination(P1, P1), linear_combination(P2, P2)) -end From 8a53a33b04b1ff906b5d8573112cf81f320be235 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 4 Jan 2025 22:31:16 +0100 Subject: [PATCH 2/3] AbstractPolynomialZonotope: add 'linear_combination' --- .../src/lib/interfaces/AbstractPolynomialZonotope.md | 1 + docs/src/lib/sets/DensePolynomialZonotope.md | 2 +- docs/src/lib/sets/SimpleSparsePolynomialZonotope.md | 1 - docs/src/lib/sets/SparsePolynomialZonotope.md | 2 +- src/ConcreteOperations/linear_combination.jl | 7 +++++++ test/Sets/SparsePolynomialZonotope.jl | 12 ++++++++++++ 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/src/lib/interfaces/AbstractPolynomialZonotope.md b/docs/src/lib/interfaces/AbstractPolynomialZonotope.md index b04a229191..2700ae6eee 100644 --- a/docs/src/lib/interfaces/AbstractPolynomialZonotope.md +++ b/docs/src/lib/interfaces/AbstractPolynomialZonotope.md @@ -50,6 +50,7 @@ Undocumented implementations: * [`isboundedtype`](@ref isboundedtype(::Type{LazySet})) * [`isempty`](@ref isempty(::LazySet)) * [`isuniversal`](@ref isuniversal(::LazySet)) +* [`linear_combination`](@ref linear_combination(::LazySet, ::LazySet)) ```@meta CurrentModule = LazySets diff --git a/docs/src/lib/sets/DensePolynomialZonotope.md b/docs/src/lib/sets/DensePolynomialZonotope.md index 24af2304e6..c27daab037 100644 --- a/docs/src/lib/sets/DensePolynomialZonotope.md +++ b/docs/src/lib/sets/DensePolynomialZonotope.md @@ -76,7 +76,6 @@ Inherited from [`LazySet`](@ref): * [`isequivalent`](@ref isequivalent(::LazySet, ::LazySet)) * [`⊂`](@ref ⊂(::LazySet, ::LazySet)) * [`⊆`](@ref ⊆(::LazySet, ::LazySet)) -* [`linear_combination`](@ref linear_combination(::LazySet, ::LazySet)) * [`minkowski_difference`](@ref minkowski_difference(::LazySet, ::LazySet)) * [`minkowski_sum`](@ref minkowski_sum(::LazySet, ::LazySet)) @@ -90,3 +89,4 @@ Inherited from [`AbstractPolynomialZonotope`](@ref): * [`ngens`](@ref ngens(::AbstractPolynomialZonotope)) * [`order`](@ref dim(::AbstractPolynomialZonotope)) * [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) +* [`linear_combination`](@ref linear_combination(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) diff --git a/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md b/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md index 4365e51d1e..76e0a6cf1c 100644 --- a/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md +++ b/docs/src/lib/sets/SimpleSparsePolynomialZonotope.md @@ -170,7 +170,6 @@ Inherited from [`LazySet`](@ref): * [`isequivalent`](@ref isequivalent(::LazySet, ::LazySet)) * [`⊂`](@ref ⊂(::LazySet, ::LazySet)) * [`⊆`](@ref ⊆(::LazySet, ::LazySet)) -* [`linear_combination`](@ref linear_combination(::LazySet, ::LazySet)) * [`minkowski_difference`](@ref minkowski_difference(::LazySet, ::LazySet)) Inherited from [`AbstractPolynomialZonotope`](@ref): diff --git a/docs/src/lib/sets/SparsePolynomialZonotope.md b/docs/src/lib/sets/SparsePolynomialZonotope.md index 8f3ec7e213..119dfa168a 100644 --- a/docs/src/lib/sets/SparsePolynomialZonotope.md +++ b/docs/src/lib/sets/SparsePolynomialZonotope.md @@ -139,7 +139,6 @@ Inherited from [`LazySet`](@ref): * [`isequivalent`](@ref isequivalent(::LazySet, ::LazySet)) * [`⊂`](@ref ⊂(::LazySet, ::LazySet)) * [`⊆`](@ref ⊆(::LazySet, ::LazySet)) -* [`linear_combination`](@ref linear_combination(::LazySet, ::LazySet)) * [`minkowski_difference`](@ref minkowski_difference(::LazySet, ::LazySet)) Inherited from [`AbstractPolynomialZonotope`](@ref): @@ -152,6 +151,7 @@ Inherited from [`AbstractPolynomialZonotope`](@ref): * [`ngens`](@ref ngens(::AbstractPolynomialZonotope)) * [`order`](@ref order(::AbstractPolynomialZonotope)) * [`convex_hull`](@ref convex_hull(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) +* [`linear_combination`](@ref linear_combination(::AbstractPolynomialZonotope, ::AbstractPolynomialZonotope)) Inherited from [`AbstractSparsePolynomialZonotope`](@ref): * [`ngens_dep`](@ref ngens_dep(::AbstractSparsePolynomialZonotope)) diff --git a/src/ConcreteOperations/linear_combination.jl b/src/ConcreteOperations/linear_combination.jl index 112a6ee999..250ae91fc8 100644 --- a/src/ConcreteOperations/linear_combination.jl +++ b/src/ConcreteOperations/linear_combination.jl @@ -29,3 +29,10 @@ end @commutative function linear_combination(∅::EmptySet, X::ConvexSet) return _linear_combination_emptyset(∅, X) end + +function linear_combination(P1::AbstractPolynomialZonotope, + P2::AbstractPolynomialZonotope) + SSPZ1 = convert(SimpleSparsePolynomialZonotope, P1) + SSPZ2 = convert(SimpleSparsePolynomialZonotope, P2) + return linear_combination(SSPZ1, SSPZ2) +end diff --git a/test/Sets/SparsePolynomialZonotope.jl b/test/Sets/SparsePolynomialZonotope.jl index ce9acc2aa1..df762ef1fd 100644 --- a/test/Sets/SparsePolynomialZonotope.jl +++ b/test/Sets/SparsePolynomialZonotope.jl @@ -141,6 +141,18 @@ for N in [Float64, Float32, Rational{Int}] @test isequivalent(overapproximate(PZ, Zonotope), Z) SSPZ2 = convert(SimpleSparsePolynomialZonotope, PZ) @test isequivalent(overapproximate(SSPZ2, Zonotope, dom2), Z) + + # Example 3.1.29 from thesis + PZ1 = SparsePolynomialZonotope(N[-5, 0], N[2 0 2; 0 2 2], Matrix{N}(undef, 2, 0), [1 0 1; 0 1 1]) + PZ2 = SparsePolynomialZonotope(N[3, 3], N[1 -2 2; 2 3 1], hcat(N[1//2; 0]), [1 0 2; 0 1 1]) + PZ_lc = linear_combination(PZ1, PZ2) + # no reasonable tests available here + @test PZ_lc isa SimpleSparsePolynomialZonotope{N} + @test center(PZ_lc) == N[-1, 3//2] + PZ_ch = convex_hull(PZ1, PZ2) + # no reasonable tests available here + @test PZ_ch isa SimpleSparsePolynomialZonotope{N} + @test center(PZ_ch) == N[-1, 3//2] end for N in [Float64] From ffd86e57ed83866f6fc7839b910e7c89ab0c4fc3 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 4 Jan 2025 23:01:07 +0100 Subject: [PATCH 3/3] add mixed zono/polyzono 'linear_combination' --- src/ConcreteOperations/linear_combination.jl | 4 ++++ test/Sets/SparsePolynomialZonotope.jl | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/ConcreteOperations/linear_combination.jl b/src/ConcreteOperations/linear_combination.jl index 250ae91fc8..dc813f5ba6 100644 --- a/src/ConcreteOperations/linear_combination.jl +++ b/src/ConcreteOperations/linear_combination.jl @@ -36,3 +36,7 @@ function linear_combination(P1::AbstractPolynomialZonotope, SSPZ2 = convert(SimpleSparsePolynomialZonotope, P2) return linear_combination(SSPZ1, SSPZ2) end + +@commutative function linear_combination(Z::AbstractZonotope, P::AbstractPolynomialZonotope) + return linear_combination(convert(SparsePolynomialZonotope, Z), P) +end diff --git a/test/Sets/SparsePolynomialZonotope.jl b/test/Sets/SparsePolynomialZonotope.jl index df762ef1fd..a48a4e227e 100644 --- a/test/Sets/SparsePolynomialZonotope.jl +++ b/test/Sets/SparsePolynomialZonotope.jl @@ -153,6 +153,9 @@ for N in [Float64, Float32, Rational{Int}] # no reasonable tests available here @test PZ_ch isa SimpleSparsePolynomialZonotope{N} @test center(PZ_ch) == N[-1, 3//2] + # mixed linear_combination + PZ_lc = linear_combination(PZ1, ZeroSet{N}(2)) + @test PZ_lc isa SimpleSparsePolynomialZonotope{N} end for N in [Float64]