@@ -603,6 +603,84 @@ function overapproximate(P::VPolygon, ::Type{<:LinearMap{N,<:Hyperrectangle}}) w
603603 return LinearMap (R, min_rectangle)
604604end
605605
606+ """
607+ overapproximate(P::SparsePolynomialZonotope{N}, ::Type{<:VPolytope}) where {N}
608+
609+
610+ Overapproximate a sparse polynomial zonotope with a polytope in vertex representation.
611+
612+ ### Input
613+
614+ - `P` -- sparse polynomial zonotope
615+ - `VPolytope` -- target type
616+
617+ ### Output
618+
619+ A `VPolytope` that overapproximates the sparse polynomial zonotope.
620+
621+ ### Algorithm
622+
623+ This method implements [Kochdumper21a; Proposition 3.1.15](@citet).
624+ The idea is to split `P` into a linear and nonlinear part (such that `P = P₁ ⊕ P₂`).
625+ The nonlinear part is enclosed by a zonotope. Then we combine the vertices
626+ of both sets and finally apply a convex-hull algorithm.
627+ """
628+ function overapproximate (P:: SparsePolynomialZonotope{N} , :: Type{<:VPolytope} ) where {N}
629+ c = center (P)
630+ G = genmat_dep (P)
631+ GI = genmat_indep (P)
632+ E = expmat (P)
633+ idx = P. idx
634+
635+ H = [j for j in 1 : size (E, 2 ) if any (E[:, j] .> 1 )]
636+ K = setdiff (1 : size (E, 2 ), H)
637+
638+ if ! isempty (H)
639+ SPZ₂ = SparsePolynomialZonotope (c, G[:, H], zeros (N, length (c), 0 ), E[:, H], idx)
640+ Z = overapproximate (SPZ₂, Zonotope)
641+ c_z = center (Z)
642+ GI_mod = hcat (GI, genmat (Z))
643+ else
644+ c_z = c
645+ GI_mod = GI
646+ end
647+
648+ G_mod = G[:, K]
649+ E_mod = E[:, K]
650+
651+ # P̄ = SparsePolynomialZonotope(c_z, G_mod, GI_mod, E_mod, idx)
652+ # Compute vertices of a Z-representation
653+ p = size (E, 1 )
654+ dep_params = Iterators. product (fill ([- one (N), one (N)], p)... )
655+ indep_params = Iterators. product (fill ([- one (N), one (N)], size (GI_mod, 2 ))... )
656+
657+ V = Vector {Vector{N}} ()
658+ for α in dep_params
659+ dep_term = zeros (N, size (c))
660+ for j in axes (G_mod, 2 )
661+ prod = one (N)
662+ for k in 1 : p
663+ if E_mod[k, j] == 1
664+ prod *= α[k]
665+ end
666+ end
667+ dep_term += prod * G_mod[:, j]
668+ end
669+ for β in indep_params
670+ indep_term = zeros (N, size (c))
671+ for j in axes (GI_mod, 2 )
672+ indep_term += β[j] * GI_mod[:, j]
673+ end
674+ point = c_z + dep_term + indep_term
675+ push! (V, point)
676+ end
677+ end
678+
679+ convex_hull! (V)
680+
681+ return VPolytope (V)
682+ end
683+
606684# function to be loaded by Requires
607685function load_paving_overapproximation ()
608686 return quote
0 commit comments