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

Polyhedral: add hash method for Cone + Polyhedron #2955

Merged
merged 7 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/PolyhedralGeometry/linear_programs.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ julia> V = optimal_vertex(LP)

```@docs
feasible_region(lp::LinearProgram)
ambient_dim(lp::LinearProgram)
objective_function(lp::LinearProgram{T}; as::Symbol = :pair) where T<:scalar_types
solve_lp(LP::LinearProgram)
optimal_value(lp::LinearProgram{T}) where T<:scalar_types
Expand Down
2 changes: 2 additions & 0 deletions docs/src/PolyhedralGeometry/mixed_integer_linear_programs.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ mixed_integer_linear_program

## Functions
```@docs
feasible_region(milp::MixedIntegerLinearProgram)
ambient_dim(milp::MixedIntegerLinearProgram)
optimal_value(milp::MixedIntegerLinearProgram{T}) where T<:scalar_types
optimal_solution
solve_milp
Expand Down
15 changes: 10 additions & 5 deletions src/PolyhedralGeometry/Cone/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,18 @@ cone(f::scalar_type_or_field, x...) = positive_hull(f, x...)


function ==(C0::Cone{T}, C1::Cone{T}) where T<:scalar_types
# TODO: Remove the following 3 lines, see #758
for pair in Iterators.product([C0, C1], ["RAYS", "FACETS"])
Polymake.give(pm_object(pair[1]),pair[2])
end
return Polymake.polytope.equal_polyhedra(pm_object(C0), pm_object(C1))
return Polymake.polytope.equal_polyhedra(pm_object(C0), pm_object(C1))::Bool
end

# For a proper hash function for cones we should use a "normal form",
# which would require a potentially expensive convex hull computation
# (and even that is not enough). But hash methods should be fast, so we
# just consider the ambient dimension and the precise type of the cone.
function Base.hash(x::T, h::UInt) where {T <: Cone}
h = hash(ambient_dim(x), h)
h = hash(T, h)
return h
end

@doc raw"""
cone_from_inequalities([::Union{Type{T}, Field} = QQFieldElem,] I::AbstractCollection[LinearHalfspace] [, E::AbstractCollection[LinearHyperplane]]; non_redundant::Bool = false)
Expand Down
10 changes: 10 additions & 0 deletions src/PolyhedralGeometry/Polyhedron/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ function ==(P0::Polyhedron{T}, P1::Polyhedron{T}) where T<:scalar_types
Polymake.polytope.equal_polyhedra(pm_object(P0), pm_object(P1))
end

# For a proper hash function for cones we should use a "normal form",
# which would require a potentially expensive convex hull computation
# (and even that is not enough). But hash methods should be fast, so we
# just consider the ambient dimension and the precise type of the polyhedron.
function Base.hash(x::T, h::UInt) where {T <: Polyhedron}
h = hash(ambient_dim(x), h)
h = hash(T, h)
return h
end

### Construct polyhedron from V-data, as the convex hull of points, rays and lineality.
@doc raw"""
convex_hull([::Union{Type{T}, Field} = QQFieldElem,] V [, R [, L]]; non_redundant::Bool = false)
Expand Down
7 changes: 7 additions & 0 deletions src/PolyhedralGeometry/linear_program.jl
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,10 @@ Return a pair `(m,v)` where the optimal value `m` of the objective
`nothing`.
"""
solve_lp(lp::LinearProgram) = optimal_value(lp), optimal_vertex(lp)

@doc raw"""
ambient_dim(LP::LinearProgram)

Return the ambient dimension of the feasible reagion of `LP`.
"""
ambient_dim(lp::LinearProgram) = ambient_dim(feasible_region(lp))
7 changes: 7 additions & 0 deletions src/PolyhedralGeometry/mixed_integer_linear_program.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,10 @@ julia> solve_milp(milp)
```
"""
solve_milp(milp::MixedIntegerLinearProgram) = optimal_value(milp), optimal_solution(milp)

@doc raw"""
ambient_dim(MILP::MixedIntegerLinearProgram)

Return the ambient dimension of the feasible reagion of `MILP`.
"""
ambient_dim(milp::MixedIntegerLinearProgram) = ambient_dim(feasible_region(milp))
3 changes: 3 additions & 0 deletions test/PolyhedralGeometry/cone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
@test is_fulldimensional(Cone2)
@test Cone2 == Cone3
@test Cone4 != Cone2

@test length(unique([Cone2, Cone3, Cone4])) == 2

@test dim(Cone4) == 2
@test dim(Cone2) == 3
@test ambient_dim(Cone2) == 3
Expand Down
4 changes: 4 additions & 0 deletions test/PolyhedralGeometry/linear_program.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
@test LP2 isa LinearProgram{T}
@test LP3 isa LinearProgram{T}

@test ambient_dim(LP1) == 2

@test solve_lp(LP1)==(4,[1,1])
@test solve_lp(LP2)==(-1,[-1,-1])
if T == QQFieldElem
Expand All @@ -43,6 +45,8 @@
@test MILP2 isa MixedIntegerLinearProgram{T}
@test MILP3 isa MixedIntegerLinearProgram{T}

@test ambient_dim(MILP3) == 3

@test solve_milp(MILP1)==(11//2,[1,3//2])
@test solve_milp(MILP2)==(-1,[-1,-1])
@test string(solve_milp(MILP3))==string("(inf, nothing)")
Expand Down
11 changes: 5 additions & 6 deletions test/PolyhedralGeometry/polyhedron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@
@test vertex_sizes(Q1)[1] == 2
@test length(vertex_sizes(Q2)) == 0

@test length(unique([cube(2), cube(2), simplex(2), simplex(2)])) == 2
end

@testset "volume" begin
Expand Down Expand Up @@ -221,12 +222,10 @@
@test upper_bound_h_vector(4,8) == [1, 4, 10, 4 ,1]
A = archimedean_solid("cuboctahedron")
@test count(F -> nvertices(F) == 3, faces(A, 2)) == 8
# due to GLIBCXX issues with the outdated julia-shipped libstdc++
# we run this only where recent CompilerSupportLibraries are available
if VERSION >= v"1.6"
C = catalan_solid("triakis_tetrahedron")
@test count(F -> nvertices(F) == 3, faces(C, 2)) == 12
end

C = catalan_solid("triakis_tetrahedron")
@test count(F -> nvertices(F) == 3, faces(C, 2)) == 12

@test polyhedron(facets(A)) == A
b1 = birkhoff_polytope(3)
b2 = birkhoff_polytope(3, even = true)
Expand Down
Loading