diff --git a/docs/src/lib/conversion.md b/docs/src/lib/conversion.md index 4267bb518c..728f0f268b 100644 --- a/docs/src/lib/conversion.md +++ b/docs/src/lib/conversion.md @@ -43,5 +43,9 @@ convert(::Type{Zonotope}, ::CartesianProduct{N, Zonotope{N}, Zonotope{N}}) where convert(::Type{Hyperrectangle}, ::CartesianProduct{N, HN1, HN2}) where {N<:Real, HN1<:AbstractHyperrectangle{N}, HN2<:AbstractHyperrectangle{N}} convert(::Type{Zonotope}, ::CartesianProduct{N, HN1, HN2}) where {N<:Real, HN1<:AbstractHyperrectangle{N}, HN2<:AbstractHyperrectangle{N}} convert(::Type{Zonotope}, ::CartesianProductArray{N, HN}) where {N<:Real, HN<:AbstractHyperrectangle{N}} -convert(::Type{Zonotope}, ::LinearMap{N, SN, NM, MAT}) where {N, SN<:AbstractHyperrectangle{N}, NM, MAT<:AbstractMatrix{N}} +convert(::Type{Zonotope}, ::LinearMap{N, SN}) where {N, SN<:AbstractHyperrectangle{N}} +convert(::Type{Zonotope}, ::LinearMap{N, CartesianProduct{N, HN1, HN2}}) where {N, HN1<:AbstractHyperrectangle{N}, HN2<:AbstractHyperrectangle{N}} +convert(::Type{Zonotope}, ::LinearMap{N, CartesianProductArray{N, HN}}) where {N, HN<:AbstractHyperrectangle{N}} ``` + + diff --git a/src/convert.jl b/src/convert.jl index 642b059c7a..f0fef4f77f 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -305,8 +305,8 @@ end """ convert(::Type{Zonotope}, - S::LinearMap{N, SN, NM, MAT} - ) where {N, SN<:AbstractHyperrectangle{N}, NM, MAT<:AbstractMatrix{N}} + S::LinearMap{N, SN} + ) where {N, SN<:AbstractHyperrectangle{N}} Converts the lazy linear map of a hyperrectangular set to a zonotope. @@ -324,11 +324,64 @@ A zonotope. This method first converts the hyperrectangular set to a zonotope, and then applies the (concrete) linear map to the zonotope. """ +function convert(::Type{Zonotope}, S::LinearMap{N, SN} + ) where {N, SN<:AbstractHyperrectangle{N}} + return linear_map(S.M, convert(Zonotope, S.X)) +end + +""" + convert(::Type{Zonotope}, S::LinearMap{N, CartesianProduct{N, HN1, HN2}} + ) where {N, HN1<:AbstractHyperrectangle{N}, + HN2<:AbstractHyperrectangle{N}} + +Converts the lazy linear map of the cartesian product of two hyperrectangular +sets to a zonotope. + +### Input + +- `Zonotope` -- type, used for dispatch +- `S` -- linear map of the cartesian product of hyperrectangular sets + +### Output + +A zonotope. + +### Algorithm + +This method first converts the cartesian product to a zonotope, and then +applies the (concrete) linear map to the zonotope. +""" function convert(::Type{Zonotope}, - S::LinearMap{N, SN, NM, MAT} - ) where {N, SN<:AbstractHyperrectangle{N}, NM, MAT<:AbstractMatrix{N}} - Xz = convert(Zonotope, S.X) - return linear_map(S.M, Xz) + S::LinearMap{N, CartesianProduct{N, HN1, HN2}} + ) where {N, HN1<:AbstractHyperrectangle{N}, + HN2<:AbstractHyperrectangle{N}} + return linear_map(S.M, convert(Zonotope, S.X)) +end + +""" + convert(::Type{Zonotope},S::LinearMap{N, CartesianProductArray{N, HN}} + ) where {N, HN<:AbstractHyperrectangle{N}} + +Converts the lazy linear map of the cartesian product of a finite number of +hyperrectangular sets to a zonotope. + +### Input + +- `Zonotope` -- type, used for dispatch +- `S` -- linear map of a `CartesianProductArray` of hyperrectangular sets + +### Output + +A zonotope. + +### Algorithm + +This method first converts the cartesian product array to a zonotope, and then +applies the (concrete) linear map to the zonotope. +""" +function convert(::Type{Zonotope}, S::LinearMap{N, CartesianProductArray{N, HN}} + ) where {N, HN<:AbstractHyperrectangle{N}} + return linear_map(S.M, convert(Zonotope, S.X)) end """ diff --git a/test/unit_Zonotope.jl b/test/unit_Zonotope.jl index 53c07bcbbf..94a1b852a6 100644 --- a/test/unit_Zonotope.jl +++ b/test/unit_Zonotope.jl @@ -129,6 +129,17 @@ for N in [Float64, Rational{Int}, Float32] Z = convert(Zonotope, M * B) @test Z isa Zonotope && Z.center == N[0] && Z.generators == hcat(N[1]) + # conversion of the lazy linear map of the cartesian product of hyperrectangular + # sets to a zonotope + B = BallInf(N[0], N(1)) + M = N[1 0; 0 -1] + Z = convert(Zonotope, M * (B × B)) + @test Z isa Zonotope && Z.center == N[0, 0] && Z.generators == M + + # same for CPA + Z2 = convert(Zonotope, M * CartesianProductArray([B, B])) + @test Z2 == Z + # list of constraints Z = Zonotope(zeros(N, 3), Matrix(N(1)*I, 3, 3)) B = BallInf(zeros(N, 3), N(1)) # equivalent to Z