From 2c72086419e55c98ad4d2630bdab6c4db2223a95 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 29 Jul 2023 21:25:59 +0200 Subject: [PATCH] better 1D linear_map of AbstractZonotope --- src/Interfaces/AbstractZonotope.jl | 21 +++++++++++++++++++++ test/Sets/Zonotope.jl | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/src/Interfaces/AbstractZonotope.jl b/src/Interfaces/AbstractZonotope.jl index 4f2e43e836..9ed54b8f64 100644 --- a/src/Interfaces/AbstractZonotope.jl +++ b/src/Interfaces/AbstractZonotope.jl @@ -306,6 +306,27 @@ function linear_map(M::AbstractMatrix, Z::AbstractZonotope) @assert dim(Z) == size(M, 2) "a linear map of size $(size(M)) cannot be " * "applied to a set of dimension $(dim(Z))" + if size(M, 1) == 1 + # yields only one generator + return _linear_map_zonotope_1D(M, Z) + else + return _linear_map_zonotope_nD(M, Z) + end +end + +function _linear_map_zonotope_1D(M::AbstractMatrix, Z::LazySet) + N = promote_type(eltype(M), eltype(Z)) + c = M * center(Z) + gi = zero(N) + @inbounds for g in generators(Z) + for i in eachindex(g) + gi += M[1, i] * g[i] + end + end + return Zonotope(c, hcat(gi)) +end + +function _linear_map_zonotope_nD(M::AbstractMatrix, Z::LazySet) c = M * center(Z) gi = M * genmat(Z) return Zonotope(c, gi) diff --git a/test/Sets/Zonotope.jl b/test/Sets/Zonotope.jl index ecb796179d..e3d918337a 100644 --- a/test/Sets/Zonotope.jl +++ b/test/Sets/Zonotope.jl @@ -95,6 +95,10 @@ for N in [Float64, Rational{Int}, Float32] Z5 = scale(1 // 2, Z3) @test Z5.center == N[0, 1] @test Z5.generators == N[1//2 1//2 1//2 0; -1//2 1//2 0 1//2] + # 1D simplifies to 1 generator + M = N[1 1;] + Z6 = linear_map(M, Z3) + @test ngens(Z6) == 1 && genmat(Z6) == hcat(N[4]) # in-place linear map Zin = convert(Zonotope, BallInf(zeros(N, 2), N(1)))