diff --git a/src/Approximations/overapproximate.jl b/src/Approximations/overapproximate.jl index a17b2a734f..975186e67e 100644 --- a/src/Approximations/overapproximate.jl +++ b/src/Approximations/overapproximate.jl @@ -133,6 +133,37 @@ function overapproximate(S::ConvexHull{N, Zonotope{N}, Zonotope{N}}, return Zonotope(center, generators) end +""" + overapproximate(Z::Zonotope, ::Type{<:Hyperrectangle})::Hyperrectangle + +Return a tight overapproximation of a zonotope with an axis-aligned box. + +### Input + +- `Z` -- zonotope +- `Hyperrectangle` -- type for dispatch + +### Output + +A hyperrectangle. + +### Algorithm + +This function implements the method in [Section 5.1.2, 1]. A zonotope +``Z = ⟨c, G⟩`` can be overapproximated tightly by an axis-aligned box +(i.e. a `Hyperrectangle`) such that its center is ``c`` and the radius along +dimension ``i`` is the column-sum of the absolute values of the ``i``-th row +of ``G`` for ``i = 1,…, p``, where ``p`` is the number of generators of ``Z``. + +[1] *Althoff, M., Stursberg, O., & Buss, M. (2010). Computing reachable sets of +hybrid systems using a combination of zonotopes and polytopes. Nonlinear analysis: +hybrid systems, 4(2), 233-249.* +""" +function overapproximate(Z::Zonotope, ::Type{<:Hyperrectangle})::Hyperrectangle + r = Compat.sum(abs.(Z.generators), dims=2)[:] + return Hyperrectangle(Z.center, r) +end + """ overapproximate(X::LazySet{N}, dir::AbstractDirections{N})::HPolytope{N} where {N} diff --git a/test/unit_overapproximate.jl b/test/unit_overapproximate.jl index 345a7ac2c2..7c5486be98 100644 --- a/test/unit_overapproximate.jl +++ b/test/unit_overapproximate.jl @@ -1,4 +1,4 @@ -import LazySets.Approximations.overapproximate +import LazySets.Approximations: overapproximate, box_approximation for N in [Float64, Rational{Int}, Float32] # overapproximating a set of type T1 with an unsupported type T2 is the @@ -37,6 +37,12 @@ for N in [Float64, Rational{Int}, Float32] for d in [N[1], N[-1]] @test σ(d, p)[1] ≈ σ(d, b)[1] end + + # approximation with an axis-aligned hyperrectangle + Z = Zonotope(N[-1.0, -1.0], N[-1/2 0; -1.2 -1]) + Zoa = overapproximate(Z, Hyperrectangle) # faster o.a. + Zba = box_approximation(Z) # default o.a. implementation that uses supp function + @test Zoa.center ≈ Zba.center && Zoa.radius ≈ Zba.radius end # tests that do not work with Rational{Int}