Skip to content

Commit

Permalink
Merge pull request #3244 from JuliaReach/schillic/move
Browse files Browse the repository at this point in the history
Move some code to interface files
  • Loading branch information
schillic authored Mar 17, 2023
2 parents 7e21373 + f62e30c commit d2b18a4
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 95 deletions.
22 changes: 22 additions & 0 deletions src/Interfaces/AbstractPolyhedron_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ isconvextype(::Type{<:AbstractPolyhedron}) = true

is_polyhedral(::AbstractPolyhedron) = true

"""
constraints_list(A::AbstractMatrix{N}, b::AbstractVector)
Convert a matrix-vector representation to a linear-constraint representation.
### Input
- `A` -- matrix
- `b` -- vector
### Output
A list of linear constraints.
"""
function constraints_list(A::AbstractMatrix, b::AbstractVector)
m = size(A, 1)
@assert m == length(b) "a matrix with $m rows is incompatible with a " *
"vector of length $(length(b))"

return [HalfSpace(A[i, :], b[i]) for i in 1:m]
end

"""
∈(x::AbstractVector, P::AbstractPolyhedron)
Expand Down
80 changes: 76 additions & 4 deletions src/Interfaces/AbstractZonotope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -421,19 +421,91 @@ function vertices_list(Z::AbstractZonotope; apply_convex_hull::Bool=true)

elseif n == 2
if p == 1
return _vertices_list_2D_order_one_half(c, G, apply_convex_hull=apply_convex_hull)
return _vertices_list_zonotope_2D_order_one_half(c, G, apply_convex_hull=apply_convex_hull)
elseif p == 2
return _vertices_list_2D_order_one(c, G, apply_convex_hull=apply_convex_hull)
return _vertices_list_zonotope_2D_order_one(c, G, apply_convex_hull=apply_convex_hull)
else
return _vertices_list_2D(c, G, apply_convex_hull=apply_convex_hull)
return _vertices_list_zonotope_2D(c, G, apply_convex_hull=apply_convex_hull)
end

else
Gred = remove_zero_columns(G)
return _vertices_list_iterative(c, Gred, apply_convex_hull=apply_convex_hull)
return _vertices_list_zonotope_iterative(c, Gred, apply_convex_hull=apply_convex_hull)
end
end

function _vertices_list_zonotope_2D(c::AbstractVector{N}, G::AbstractMatrix{N};
apply_convex_hull::Bool) where {N}
if same_sign(G)
return _vertices_list_zonotope_2D_positive(c, G, apply_convex_hull=apply_convex_hull)
else
# FIXME generalized 2D vertices list function is not implemented yet
# See LazySets#2209
return _vertices_list_zonotope_iterative(c, G, apply_convex_hull=apply_convex_hull)
end
end

function _vertices_list_zonotope_2D_positive(c::AbstractVector{N}, G::AbstractMatrix{N};
apply_convex_hull::Bool) where {N}
n, p = size(G)

# TODO special case p = 1 or p = 2 ?

sorted_G = sortslices(G, dims=2, by=x->atan(x[2], x[1]))
index = ones(N, p, 2*p)
@inbounds for i in 1:p
index[i, i+1:i+p-1] .= -one(N)
end
index[:, 1] .= -one(N)
V = sorted_G * index .+ c
vlist = [V[:, i] for i in 1:2*p]

if apply_convex_hull
convex_hull!(vlist)
end
return vlist
end

function _vertices_list_zonotope_iterative(c::VN, G::MN; apply_convex_hull::Bool
) where {N, VN<:AbstractVector{N}, MN<:AbstractMatrix{N}}
p = size(G, 2)
vlist = Vector{VN}()
sizehint!(vlist, 2^p)

for ξi in Iterators.product([(1, -1) for i = 1:p]...)
push!(vlist, c .+ G * collect(ξi))
end

return apply_convex_hull ? convex_hull!(vlist) : vlist
end

# special case 2D zonotope of order 1/2
function _vertices_list_zonotope_2D_order_one_half(c::VN, G::MN;
apply_convex_hull::Bool) where {N, VN<:AbstractVector{N}, MN}
vlist = Vector{VN}(undef, 2)
g = view(G, :, 1)
@inbounds begin
vlist[1] = c .+ g
vlist[2] = c .- g
end
return apply_convex_hull ? _two_points_2d!(vlist) : vlist
end

# special case 2D zonotope of order 1
function _vertices_list_zonotope_2D_order_one(c::VN, G::MN;
apply_convex_hull::Bool) where {N, VN<:AbstractVector{N}, MN}
vlist = Vector{VN}(undef, 4)
a = [one(N), one(N)]
b = [one(N), -one(N)]
@inbounds begin
vlist[1] = c .+ G * a
vlist[2] = c .- G * a
vlist[3] = c .+ G * b
vlist[4] = c .- G * b
end
return apply_convex_hull ? _four_points_2d!(vlist) : vlist
end

"""
constraints_list(P::AbstractZonotope)
Expand Down
22 changes: 0 additions & 22 deletions src/Sets/HalfSpace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -310,28 +310,6 @@ function constraints_list(hs::HalfSpace)
return [hs]
end

"""
constraints_list(A::AbstractMatrix{N}, b::AbstractVector)
Convert a matrix-vector representation to a linear-constraint representation.
### Input
- `A` -- matrix
- `b` -- vector
### Output
A list of linear constraints.
"""
function constraints_list(A::AbstractMatrix, b::AbstractVector)
m = size(A, 1)
@assert m == length(b) "a matrix with $m rows is incompatible with a " *
"vector of length $(length(b))"

return [HalfSpace(A[i, :], b[i]) for i in 1:m]
end

"""
constrained_dimensions(hs::HalfSpace)
Expand Down
68 changes: 0 additions & 68 deletions src/Sets/Zonotope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -458,74 +458,6 @@ function _bound_intersect_2D(Z::Zonotope, L::Line2D)
return element(singleton)[2]
end

function _vertices_list_2D(c::AbstractVector{N}, G::AbstractMatrix{N};
apply_convex_hull::Bool) where {N}
if same_sign(G)
return _vertices_list_2D_positive(c, G, apply_convex_hull=apply_convex_hull)
else
# FIXME generalized 2D vertices list function is not implemented yet
# See LazySets#2209
return _vertices_list_iterative(c, G, apply_convex_hull=apply_convex_hull)
end
end

function _vertices_list_2D_positive(c::AbstractVector{N}, G::AbstractMatrix{N};
apply_convex_hull::Bool) where {N}
n, p = size(G)

# TODO special case p = 1 or p = 2 ?

sorted_G = sortslices(G, dims=2, by=x->atan(x[2], x[1]))
index = ones(N, p, 2*p)
@inbounds for i in 1:p
index[i, i+1:i+p-1] .= -one(N)
end
index[:, 1] .= -one(N)
V = sorted_G * index .+ c
vlist = [V[:, i] for i in 1:2*p]

if apply_convex_hull
convex_hull!(vlist)
end
return vlist
end

function _vertices_list_iterative(c::VN, G::MN; apply_convex_hull::Bool) where {N, VN<:AbstractVector{N}, MN<:AbstractMatrix{N}}
p = size(G, 2)
vlist = Vector{VN}()
sizehint!(vlist, 2^p)

for ξi in Iterators.product([(1, -1) for i = 1:p]...)
push!(vlist, c .+ G * collect(ξi))
end

return apply_convex_hull ? convex_hull!(vlist) : vlist
end

# special case 2D zonotope of order 1/2
function _vertices_list_2D_order_one_half(c::VN, G::MN; apply_convex_hull::Bool) where {N, VN<:AbstractVector{N}, MN}
vlist = Vector{VN}(undef, 2)
g = view(G, :, 1)
@inbounds begin
vlist[1] = c .+ g
vlist[2] = c .- g
end
return apply_convex_hull ? _two_points_2d!(vlist) : vlist
end

# special case 2D zonotope of order 1
function _vertices_list_2D_order_one(c::VN, G::MN; apply_convex_hull::Bool) where {N, VN<:AbstractVector{N}, MN}
vlist = Vector{VN}(undef, 4)
a = [one(N), one(N)]
b = [one(N), -one(N)]
@inbounds begin
vlist[1] = c .+ G * a
vlist[2] = c .- G * a
vlist[3] = c .+ G * b
vlist[4] = c .- G * b
end
return apply_convex_hull ? _four_points_2d!(vlist) : vlist
end

"""
remove_redundant_generators(Z::Zonotope{N}) where {N}
Expand Down
2 changes: 1 addition & 1 deletion test/Sets/Zonotope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ for N in [Float64]
@test length(vlistZ) == 6

# option to not apply the convex hull operation
vlistZ = LazySets._vertices_list_iterative(Z.center, Z.generators, apply_convex_hull=false)
vlistZ = LazySets._vertices_list_zonotope_iterative(Z.center, Z.generators, apply_convex_hull=false)
@test length(vlistZ) == 8
@test ispermutation(convex_hull(vlistZ), [N[-2, -2], N[0, -2], N[2, 0], N[2, 2], N[0, 2], N[-2, 0]])

Expand Down

0 comments on commit d2b18a4

Please sign in to comment.