diff --git a/src/Approximations/decompositions.jl b/src/Approximations/decompositions.jl index fa1e9d5ac1..ed2f62df3e 100644 --- a/src/Approximations/decompositions.jl +++ b/src/Approximations/decompositions.jl @@ -659,3 +659,11 @@ function project(H::AbstractHyperrectangle, block::AbstractVector{Int}) πr = radius_hyperrectangle(H)[block] return Hyperrectangle(πc, πr, check_bounds=false) end + +function project(V::Union{<:VPolygon{N}, <:VPolytope{N}}, + block::AbstractVector{Int}) where {N} + n = dim(V) + M = projection_matrix(block, n, N) + πvertices = broadcast(v -> M * v, vertices_list(V)) + return VPolytope(πvertices) +end diff --git a/test/unit_Polygon.jl b/test/unit_Polygon.jl index 9738290859..27968f9201 100644 --- a/test/unit_Polygon.jl +++ b/test/unit_Polygon.jl @@ -391,6 +391,12 @@ for N in [Float64, Float32, Rational{Int}] m = N[4 0; 6 2; 4 4]' P = VPolygon(m) @test is_cyclic_permutation(vertices_list(P), [N[4, 0], N[6, 2], N[4, 4]]) + + # test concrete projection + V = VPolygon([N[0, 1], N[1, 0], N[-1, 0]]) + @test project(V, [1]) == VPolytope([N[-1], N[1], N[0]]) + V = VPolygon([N[1, 0], N[1, 1]]) + @test project(V, [1]) == VPolytope([N[1], N[1]]) end function same_constraints(v::Vector{<:LinearConstraint{N}})::Bool where N<:Real diff --git a/test/unit_Polytope.jl b/test/unit_Polytope.jl index bcab23e655..8bfb0fd3be 100644 --- a/test/unit_Polytope.jl +++ b/test/unit_Polytope.jl @@ -194,6 +194,11 @@ for N in [Float64, Rational{Int}, Float32] p[1] = N(5) # test that Pcopy is independent of P ( = deepcopy) @test Pcopy.vertices[1] == [N(1)] + + # test concrete projection + V = VPolytope([N[0, 0, 1], N[0, 1, 0], N[0, -1, 0], N[1, 0, 0]]) + @test project(V, [1]) == VPolytope([N[0], N[0], N[0], N[1]]) + @test project(V, [1, 2]) == VPolytope([N[0, 0], N[0, 1], N[0, -1], N[1, 0]]) end # default Float64 constructors