From abd7274a595414511fcdf946c51524fa5fff42f9 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 13 Mar 2023 17:27:36 +0100 Subject: [PATCH] move vertices_list helper functions (and rename) --- src/Interfaces/AbstractZonotope.jl | 80 ++++++++++++++++++++++++++++-- src/Sets/Zonotope.jl | 68 ------------------------- test/Sets/Zonotope.jl | 2 +- 3 files changed, 77 insertions(+), 73 deletions(-) diff --git a/src/Interfaces/AbstractZonotope.jl b/src/Interfaces/AbstractZonotope.jl index ac750922ff..8b978e4ccb 100644 --- a/src/Interfaces/AbstractZonotope.jl +++ b/src/Interfaces/AbstractZonotope.jl @@ -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) diff --git a/src/Sets/Zonotope.jl b/src/Sets/Zonotope.jl index ab747bbf64..6486f7ad23 100644 --- a/src/Sets/Zonotope.jl +++ b/src/Sets/Zonotope.jl @@ -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} diff --git a/test/Sets/Zonotope.jl b/test/Sets/Zonotope.jl index ba921c76d1..4481223c0e 100644 --- a/test/Sets/Zonotope.jl +++ b/test/Sets/Zonotope.jl @@ -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]])