Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1900 - Add type parameters for zonotope #2029

Merged
merged 14 commits into from
Mar 12, 2020
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