Skip to content

Commit

Permalink
#1900 - Add type parameters for zonotope (#2029)
Browse files Browse the repository at this point in the history
* add parameters for zonotope

* fix Zonotope from center and list of generators

* some fixes

* fix doctests

* Update src/Sets/Zonotope.jl

Co-Authored-By: Christian Schilling <schillic@informatik.uni-freiburg.de>

* Update Zonotope.jl

* fix conversion docs

* fix reach zonotopes code

* Update docs/src/man/reach_zonotopes_hybrid.md

* Update docs/src/lib/conversion.md

* try docs fix

* Update docs/src/lib/conversion.md

* update docstring

* fix method

Co-authored-by: Christian Schilling <schillic@informatik.uni-freiburg.de>
  • Loading branch information
mforets and schillic authored Mar 12, 2020
1 parent 55ae567 commit e34ec1f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 27 deletions.
2 changes: 1 addition & 1 deletion docs/src/lib/conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ convert(::Type{Zonotope}, ::AbstractHyperrectangle)
convert(::Type{Zonotope}, ::AbstractZonotope)
convert(::Type{IntervalArithmetic.IntervalBox}, ::AbstractHyperrectangle)
convert(::Type{Hyperrectangle}, ::IntervalArithmetic.IntervalBox)
convert(::Type{Zonotope}, ::CartesianProduct{N, Zonotope{N}, Zonotope{N}}) where {N<:Real}
convert(::Type{Zonotope}, ::CartesianProduct{N, ZN1, ZN2}) where {N<:Real, ZN1<:AbstractZonotope{N}, ZN2<:AbstractZonotope{N}}
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}}
Expand Down
3 changes: 2 additions & 1 deletion docs/src/man/reach_zonotopes_hybrid.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ using Plots, LazySets, LinearAlgebra
function reach_hybrid(As, Ts, init, δ, μ, T, max_order, instant_transitions)
# initialize queue with initial mode and states at time t=0
queue = [(init[1], init[2], 0.)]
queue = Vector{Tuple{Zonotope, Integer, Float64}}(undef, 1)
queue[1] = (init[1], init[2], 0.0)
res = Tuple{LazySet, Int}[]
while !isempty(queue)
Expand Down
56 changes: 35 additions & 21 deletions src/Sets/Zonotope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export Zonotope,
reduce_order

"""
Zonotope{N<:Real} <: AbstractZonotope{N}
Zonotope{N<:Real, VN<:AbstractVector{N}, MN<:AbstractMatrix{N}} <: AbstractZonotope{N}
Type that represents a zonotope.
Expand All @@ -29,9 +29,9 @@ segments.
Zonotopes can be equivalently described as the image of a unit infinity-norm
ball in ``\\mathbb{R}^n`` by an affine transformation.
Zonotopes can be constructed in two different ways: either passing the generators as a matrix, where
each column represents a generator, or passing a list of vectors where each vector represents a generator.
Below we illustrate both ways.
Zonotopes can be constructed in two different ways: either passing the generators
as a matrix, where each column represents a generator, or passing a list of vectors
where each vector represents a generator. Below we illustrate both ways.
The optional argument `remove_zero_generators` controls whether we remove zero
columns from the `generators` matrix. This option is active by default.
Expand All @@ -42,12 +42,25 @@ A two-dimensional zonotope with given center and set of generators:
```jldoctest zonotope_label
julia> Z = Zonotope([1.0, 0.0], [0.1 0.0; 0.0 0.1])
Zonotope{Float64}([1.0, 0.0], [0.1 0.0; 0.0 0.1])
Zonotope{Float64,Array{Float64,1},Array{Float64,2}}([1.0, 0.0], [0.1 0.0; 0.0 0.1])
julia> dim(Z)
2
julia> center(Z)
2-element Array{Float64,1}:
1.0
0.0
julia> genmat(Z)
2×2 Array{Float64,2}:
0.1 0.0
0.0 0.1
```
Here, each column of the second input corresponds to a generator.
Here, the first vector in the `Zonotope` constructor corresponds to the zonotope's
center, and each column of the second argument corresponds to a generator. The
functions `center` and `genmat` return the center and the generator matrix of this
zonotope respectively.
We can collect its vertices using `vertices_list`:
Expand Down Expand Up @@ -75,40 +88,41 @@ vectors, each vector representing a generator:
```jldoctest
julia> Z = Zonotope(ones(2), [[1., 0.], [0., 1.], [1., 1.]])
Zonotope{Float64}([1.0, 1.0], [1.0 0.0 1.0; 0.0 1.0 1.0])
Zonotope{Float64,Array{Float64,1},Array{Float64,2}}([1.0, 1.0], [1.0 0.0 1.0; 0.0 1.0 1.0])
julia> Z.generators
julia> genmat(Z)
2×3 Array{Float64,2}:
1.0 0.0 1.0
0.0 1.0 1.0
```
"""
struct Zonotope{N<:Real} <: AbstractZonotope{N}
center::AbstractVector{N}
generators::AbstractMatrix{N}

function Zonotope(center::AbstractVector{N}, generators::AbstractMatrix{N};
remove_zero_generators::Bool=true) where {N<:Real}
struct Zonotope{N<:Real, VN<:AbstractVector{N}, MN<:AbstractMatrix{N}} <: AbstractZonotope{N}
center::VN
generators::MN

function Zonotope(center::VN, generators::MN;
remove_zero_generators::Bool=true) where {N<:Real,
VN<:AbstractVector{N},
MN<:AbstractMatrix{N}}
@assert length(center) == size(generators, 1) "the dimension of the " *
"center ($(length(center))) and the generators " *
"($(size(generators, 1))) need to match"
if remove_zero_generators
generators = delete_zero_columns!(generators)
end
new{N}(center, generators)
MT = typeof(generators)
new{N, VN, MT}(center, generators)
end
end

isoperationtype(::Type{<:Zonotope}) = false
isconvextype(::Type{<:Zonotope}) = true

# constructor from center and list of generators
Zonotope(center::AbstractVector{N}, generators_list::AbstractVector{VN};
remove_zero_generators::Bool=true
) where {N<:Real, VN<:AbstractVector{N}} =
Zonotope(center, hcat(generators_list...);
remove_zero_generators=remove_zero_generators)

function Zonotope(center::VN, generators_list::AbstractVector{VN};
remove_zero_generators::Bool=true) where {N<:Real, VN<:AbstractVector{N}}
return Zonotope(center, hcat(generators_list...); remove_zero_generators=remove_zero_generators)
end

# --- AbstractCentrallySymmetric interface functions ---

Expand Down
10 changes: 6 additions & 4 deletions src/convert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,8 @@ function convert(::Type{CartesianProductArray{N, Interval{N}}},
end

"""
convert(::Type{Zonotope}, cp::CartesianProduct{N, Zonotope{N}, Zonotope{N}}) where {N<:Real}
convert(::Type{Zonotope}, cp::CartesianProduct{N, ZN1, ZN2}
) where {N<:Real, ZN1<:AbstractZonotope{N}, ZN2<:AbstractZonotope{N}}
Converts the cartesian product of two zonotopes to a new zonotope.
Expand All @@ -701,10 +702,11 @@ The cartesian product is obtained by:
in the off-diagonal; for this reason, the generator matrix of the returned
zonotope is built as a sparse matrix.
"""
function convert(::Type{Zonotope}, cp::CartesianProduct{N, Zonotope{N}, Zonotope{N}}) where {N<:Real}
function convert(::Type{Zonotope}, cp::CartesianProduct{N, ZN1, ZN2}
) where {N<:Real, ZN1<:AbstractZonotope{N}, ZN2<:AbstractZonotope{N}}
Z1, Z2 = cp.X, cp.Y
c = vcat(Z1.center, Z2.center)
G = blockdiag(sparse(Z1.generators), sparse(Z2.generators))
c = vcat(center(Z1), center(Z2))
G = blockdiag(sparse(genmat(Z1)), sparse(genmat(Z2)))
return Zonotope(c, G)
end

Expand Down

0 comments on commit e34ec1f

Please sign in to comment.