Skip to content
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
2 changes: 1 addition & 1 deletion docs/src/PolyhedralGeometry/Polyhedra/auxiliary.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CurrentModule = Oscar
## Geometric data

```@docs
facets(P::Polyhedron)
facets(as::Type{T}, P::Polyhedron{S}) where {S<:scalar_types,T<:Union{AffineHalfspace{S},AffineHyperplane{S},Pair{R,S} where R,Polyhedron{S}}}
vertices(as::Type{PointVector{T}}, P::Polyhedron{T}) where {T<:scalar_types}
rays(as::Type{RayVector{T}}, P::Polyhedron{T}) where {T<:scalar_types}
rays_modulo_lineality(P::Polyhedron{T}) where T<:scalar_types
Expand Down
2 changes: 1 addition & 1 deletion docs/src/PolyhedralGeometry/Polyhedra/constructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ polyhedron(::Oscar.scalar_type_or_field, A::AnyVecOrMat, b::AbstractVector)
polyhedron(::Oscar.scalar_type_or_field, I::Union{Nothing, AbstractCollection[AffineHalfspace]}, E::Union{Nothing, AbstractCollection[AffineHyperplane]} = nothing)
```

The complete $H$-representation can be retrieved using [`facets`](@ref facets(as::Type{T}, P::Polyhedron{S}) where {S<:scalar_types,T<:Union{AffineHalfspace{S},Pair{R,S} where R,Polyhedron{S}}})
The complete $H$-representation can be retrieved using [`facets`](@ref facets(as::Type{T}, P::Polyhedron{S}) where {S<:scalar_types,T<:Union{AffineHalfspace{S},AffineHyperplane{S},Pair{R,S} where R,Polyhedron{S}}})
and [`affine_hull`](@ref affine_hull(P::Polyhedron{T}) where {T<:scalar_types}):
```jldoctest
julia> P = polyhedron(([-1 0; 1 0], [0,1]), ([0 1], [0]))
Expand Down
1 change: 1 addition & 0 deletions docs/src/PolyhedralGeometry/cones.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ ambient_dim(C::Cone)
Base.in(v::AbstractVector, C::Cone)
Base.issubset(C0::Cone{T}, C1::Cone{T}) where T<:scalar_types
facet_degrees(C::Cone)
facets(as::Type{<:Union{LinearHalfspace{T},LinearHyperplane{T},Cone{T}}}, C::Cone{T}) where {T<:scalar_types}
f_vector(C::Cone)
hilbert_basis(C::Cone{QQFieldElem})
codim(C::Cone)
Expand Down
11 changes: 10 additions & 1 deletion src/PolyhedralGeometry/Cone/properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ Return the facets of `C` in the format defined by `as`.

The allowed values for `as` are
* `Halfspace` (or its subtype `LinearHalfspace`),
* `Hyperplane` (or its subtype `LinearHyperplane1),
Comment thread
benlorenz marked this conversation as resolved.
* `Cone`.

# Examples
Expand All @@ -549,13 +550,19 @@ julia> f = facets(Halfspace, c)
-x_2 + x_3 <= 0
```
"""
facets(as::Type{<:Union{LinearHalfspace{T},Cone{T}}}, C::Cone{T}) where {T<:scalar_types} =
facets(
as::Type{<:Union{LinearHalfspace{T},LinearHyperplane{T},Cone{T}}}, C::Cone{T}
) where {T<:scalar_types} =
SubObjectIterator{as}(C, _facet_cone, n_facets(C))

_facet_cone(
U::Type{LinearHalfspace{T}}, C::Cone{T}, i::Base.Integer
) where {T<:scalar_types} =
linear_halfspace(coefficient_field(C), -pm_object(C).FACETS[[i], :])::U
_facet_cone(
U::Type{LinearHyperplane{T}}, C::Cone{T}, i::Base.Integer
) where {T<:scalar_types} =
linear_hyperplane(coefficient_field(C), -pm_object(C).FACETS[[i], :])::U

_facet_cone(::Type{Cone{T}}, C::Cone{T}, i::Base.Integer) where {T<:scalar_types} =
Cone{T}(Polymake.polytope.facet(pm_object(C), i - 1), coefficient_field(C))
Expand All @@ -572,6 +579,8 @@ facets(C::Cone{T}) where {T<:scalar_types} = facets(LinearHalfspace{T}, C)

facets(::Type{<:Halfspace}, C::Cone{T}) where {T<:scalar_types} =
facets(LinearHalfspace{T}, C)
facets(::Type{<:Hyperplane}, C::Cone{T}) where {T<:scalar_types} =
facets(LinearHyperplane{T}, C)

facets(::Type{Cone}, C::Cone{T}) where {T<:scalar_types} = facets(Cone{T}, C)

Expand Down
34 changes: 13 additions & 21 deletions src/PolyhedralGeometry/Polyhedron/properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ Return the facets of `P` in the format defined by `as`.

The allowed values for `as` are
* `Halfspace` (or its subtype `AffineHalfspace`),
* `Hyperplane` (or its subtype `AffineHyperplane`),
* `Polyhedron`,
* `Pair`.

Expand Down Expand Up @@ -521,7 +522,10 @@ x_3 <= 1
"""
facets(
as::Type{T}, P::Polyhedron{S}
) where {S<:scalar_types,T<:Union{AffineHalfspace{S},Pair{R,S} where R,Polyhedron{S}}} =
) where {
S<:scalar_types,
T<:Union{AffineHalfspace{S},AffineHyperplane{S},Pair{R,S} where R,Polyhedron{S}},
} =
SubObjectIterator{as}(P, _facet_polyhedron, n_facets(P))

function _facet_polyhedron(
Expand All @@ -545,6 +549,12 @@ function _facet_polyhedron(
coefficient_field(P),
)
end
function _facet_polyhedron(
U::Type{AffineHyperplane{S}}, P::Polyhedron{S}, i::Base.Integer
) where {S<:scalar_types}
h = decompose_hdata(view(pm_object(P).FACETS, [_facet_index(pm_object(P), i)], :))
return affine_hyperplane(coefficient_field(P), h[1], h[2][])::U
end

_affine_inequality_matrix(::Val{_facet_polyhedron}, P::Polyhedron) =
-_remove_facet_at_infinity(pm_object(P))
Expand Down Expand Up @@ -582,30 +592,12 @@ facets(::Type{<:Pair}, P::Polyhedron{T}) where {T<:scalar_types} =
facets(::Type{Polyhedron}, P::Polyhedron{T}) where {T<:scalar_types} =
facets(Polyhedron{T}, P)

@doc raw"""
facets(P::Polyhedron)

Return the facets of `P` as halfspaces.

# Examples
We can retrieve the six facets of the 3-dimensional cube this way:
```jldoctest
julia> C = cube(3);

julia> facets(C)
6-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^3 described by:
-x_1 <= 1
x_1 <= 1
-x_2 <= 1
x_2 <= 1
-x_3 <= 1
x_3 <= 1
```
"""
facets(P::Polyhedron{T}) where {T<:scalar_types} = facets(AffineHalfspace{T}, P)

facets(::Type{<:Halfspace}, P::Polyhedron{T}) where {T<:scalar_types} =
facets(AffineHalfspace{T}, P)
facets(::Type{<:Hyperplane}, P::Polyhedron{T}) where {T<:scalar_types} =
facets(AffineHyperplane{T}, P)

function _facet_index(P::Polymake.BigObject, i::Base.Integer)
i < _facet_at_infinity(P) && return i
Expand Down
9 changes: 9 additions & 0 deletions src/PolyhedralGeometry/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ function Base.:(==)(x::Hyperplane, y::Hyperplane)
return (r .* ax == ay) && (r * negbias(x) == negbias(y))
end

Base.in(x::AbstractVector, y::Hyperplane) = (dot(x, normal_vector(y)) == negbias(y))
Base.in(x::AbstractVector, y::Halfspace) = (dot(x, normal_vector(y)) <= negbias(y))
# A ray vector needs a base point for containment in an affine space, so we
# just error when this combination is tested.
Base.in(x::RayVector, y::T) where {T<:Union{AffineHalfspace,
AffineHyperplane}} =
throw(ArgumentError("Containment of RayVector in affine spaces is not
well-defined."))

Base.hash(x::T, h::UInt) where {T<:Union{AffineHalfspace,AffineHyperplane}} =
hash((x.a, x.b), hash(T, h))

Expand Down
2 changes: 2 additions & 0 deletions test/PolyhedralGeometry/cone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@

@test n_facets(Cone5) == 4
@test relative_interior_point(Cone1) == f.([1//2, 1//2])
@test length(findall(f->[1,0,0] in f, facets(Hyperplane, Cone5))) == 2
@test length(findall(f->[1,0,0] in f, facets(Halfspace, Cone5))) == 4
end

@testset "constructors" begin
Expand Down
5 changes: 5 additions & 0 deletions test/PolyhedralGeometry/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@
soi2 = SubObjectIterator{PointVector{QQFieldElem}}(c, _testSOI, 4)
@test_throws ArgumentError point_matrix(soi2)
end
@testset "RayVector" begin
rv = ray_vector([1,0,0])
F = facets(cube(3))
@test_throws ArgumentError rv in F[1]
end
end
2 changes: 2 additions & 0 deletions test/PolyhedralGeometry/polyhedron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@

@test dim(full) == ambient_dim(full)
@test lineality_dim(full) == 3
@test length(findall(f-> [1,0] in f, facets(Hyperplane, Q0))) == 2
@test length(findall(f-> [1,0] in f, facets(Halfspace, Q0))) == 3
end

@testset "volume" begin
Expand Down