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

PolyhedralGeometry: Format most of the files #3591

Merged
merged 3 commits into from
Apr 12, 2024
Merged
Changes from 1 commit
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
Next Next commit
PolyhedralGeometry: Format most of the files that aren't being worked…
… on right now
lkastner committed Apr 11, 2024
commit ab444bbc46b5493588b2c3217ed35d86396d1260
110 changes: 80 additions & 30 deletions src/PolyhedralGeometry/Cone/constructors.jl
Original file line number Diff line number Diff line change
@@ -8,13 +8,13 @@
#interior description?

struct Cone{T} <: PolyhedralObject{T} #a real polymake polyhedron
pm_cone::Polymake.BigObject
parent_field::Field
# only allowing scalar_types;
# can be improved by testing if the template type of the `BigObject` corresponds to `T`
Cone{T}(c::Polymake.BigObject, f::Field) where T<:scalar_types = new{T}(c, f)
Cone{QQFieldElem}(c::Polymake.BigObject) = new{QQFieldElem}(c, QQ)
pm_cone::Polymake.BigObject
parent_field::Field

# only allowing scalar_types;
# can be improved by testing if the template type of the `BigObject` corresponds to `T`
Cone{T}(c::Polymake.BigObject, f::Field) where {T<:scalar_types} = new{T}(c, f)
Cone{QQFieldElem}(c::Polymake.BigObject) = new{QQFieldElem}(c, QQ)
end

# default scalar type: `QQFieldElem`
@@ -23,8 +23,8 @@ cone(x...; kwargs...) = Cone{QQFieldElem}(x...; kwargs...)
# Automatic detection of corresponding OSCAR scalar type;
# Avoid, if possible, to increase type stability
function cone(p::Polymake.BigObject)
T, f = _detect_scalar_and_field(Cone, p)
return Cone{T}(p, f)
T, f = _detect_scalar_and_field(Cone, p)
return Cone{T}(p, f)
end

@doc raw"""
@@ -62,36 +62,63 @@ julia> HS = positive_hull(R, L)
Polyhedral cone in ambient dimension 2
```
"""
function positive_hull(f::scalar_type_or_field, R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false)
function positive_hull(
f::scalar_type_or_field,
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
)
parent_field, scalar_type = _determine_parent_and_scalar(f, R, L)
inputrays = remove_zero_rows(unhomogenized_matrix(R))
if isnothing(L) || isempty(L)
L = Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, _ambient_dim(R))
end

if non_redundant
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(RAYS = inputrays, LINEALITY_SPACE = unhomogenized_matrix(L),), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
RAYS=inputrays, LINEALITY_SPACE=unhomogenized_matrix(L)
),
parent_field,
)
else
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(INPUT_RAYS = inputrays, INPUT_LINEALITY = unhomogenized_matrix(L),), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
INPUT_RAYS=inputrays, INPUT_LINEALITY=unhomogenized_matrix(L)
),
parent_field,
)
end
end
# Redirect everything to the above constructor, use QQFieldElem as default for the
# scalar type T.
positive_hull(R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(f::scalar_type_or_field, R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) = positive_hull(f, R, L; non_redundant=non_redundant)
positive_hull(
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(
f::scalar_type_or_field,
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
) = positive_hull(f, R, L; non_redundant=non_redundant)
cone(f::scalar_type_or_field, x...) = positive_hull(f, x...)


function ==(C0::Cone{T}, C1::Cone{T}) where T<:scalar_types
return Polymake.polytope.equal_polyhedra(pm_object(C0), pm_object(C1))::Bool
function ==(C0::Cone{T}, C1::Cone{T}) where {T<:scalar_types}
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}
function Base.hash(x::T, h::UInt) where {T<:Cone}
h = hash(ambient_dim(x), h)
h = hash(T, h)
return h
@@ -120,15 +147,34 @@ julia> rays(C)
[1, 1]
```
"""
function cone_from_inequalities(f::scalar_type_or_field, I::AbstractCollection[LinearHalfspace], E::Union{Nothing, AbstractCollection[LinearHyperplane]} = nothing; non_redundant::Bool = false)
function cone_from_inequalities(
f::scalar_type_or_field,
I::AbstractCollection[LinearHalfspace],
E::Union{Nothing,AbstractCollection[LinearHyperplane]}=nothing;
non_redundant::Bool=false,
)
parent_field, scalar_type = _determine_parent_and_scalar(f, I, E)
IM = -linear_matrix_for_polymake(I)
EM = isnothing(E) || isempty(E) ? Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(IM, 2)) : linear_matrix_for_polymake(E)
EM = if isnothing(E) || isempty(E)
Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(IM, 2))
else
linear_matrix_for_polymake(E)
end

if non_redundant
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(FACETS = IM, LINEAR_SPAN = EM), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
FACETS=IM, LINEAR_SPAN=EM
),
parent_field,
)
else
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(INEQUALITIES = IM, EQUATIONS = EM), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
INEQUALITIES=IM, EQUATIONS=EM
),
parent_field,
)
end
end

@@ -157,16 +203,21 @@ julia> dim(C)
1
```
"""
function cone_from_equations(f::scalar_type_or_field, E::AbstractCollection[LinearHyperplane]; non_redundant::Bool = false)
function cone_from_equations(
f::scalar_type_or_field,
E::AbstractCollection[LinearHyperplane];
non_redundant::Bool=false,
)
parent_field, scalar_type = _determine_parent_and_scalar(f, E)
EM = linear_matrix_for_polymake(E)
IM = Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(EM, 2))
return cone_from_inequalities(f, IM, EM; non_redundant = non_redundant)
return cone_from_inequalities(f, IM, EM; non_redundant=non_redundant)
end

cone_from_inequalities(x...) = cone_from_inequalities(QQFieldElem, x...)

cone_from_equations(E::AbstractCollection[LinearHyperplane]; non_redundant::Bool = false) = cone_from_equations(_guess_fieldelem_type(E), E; non_redundant = non_redundant)
cone_from_equations(E::AbstractCollection[LinearHyperplane]; non_redundant::Bool=false) =
cone_from_equations(_guess_fieldelem_type(E), E; non_redundant=non_redundant)

"""
pm_object(C::Cone)
@@ -175,16 +226,15 @@ Get the underlying polymake `Cone`.
"""
pm_object(C::Cone) = C.pm_cone


###############################################################################
###############################################################################
### Display
###############################################################################
###############################################################################

function Base.show(io::IO, C::Cone{T}) where T<:scalar_types
print(io, "Polyhedral cone in ambient dimension $(ambient_dim(C))")
T != QQFieldElem && print(io, " with $T type coefficients")
function Base.show(io::IO, C::Cone{T}) where {T<:scalar_types}
print(io, "Polyhedral cone in ambient dimension $(ambient_dim(C))")
T != QQFieldElem && print(io, " with $T type coefficients")
end

Polymake.visual(C::Cone; opts...) = Polymake.visual(pm_object(C); opts...)
11 changes: 6 additions & 5 deletions src/PolyhedralGeometry/Cone/properties.jl
Original file line number Diff line number Diff line change
@@ -645,11 +645,12 @@ _hilbert_generator(
T::Type{PointVector{ZZRingElem}}, C::Cone{QQFieldElem}, i::Base.Integer
) = point_vector(ZZ, view(pm_object(C).HILBERT_BASIS_GENERATORS[1], i, :))::T

_generator_matrix(::Val{_hilbert_generator}, C::Cone; homogenized=false) = if homogenized
homogenize(pm_object(C).HILBERT_BASIS_GENERATORS[1], 0)
else
pm_object(C).HILBERT_BASIS_GENERATORS[1]
end
_generator_matrix(::Val{_hilbert_generator}, C::Cone; homogenized=false) =
if homogenized
homogenize(pm_object(C).HILBERT_BASIS_GENERATORS[1], 0)
else
pm_object(C).HILBERT_BASIS_GENERATORS[1]
end

_matrix_for_polymake(::Val{_hilbert_generator}) = _generator_matrix

82 changes: 41 additions & 41 deletions src/PolyhedralGeometry/Cone/standard_constructions.jl
Original file line number Diff line number Diff line change
@@ -27,13 +27,12 @@ julia> dim(C01)
```
"""
function intersect(C::Cone...)
T, f = _promote_scalar_field((coefficient_field(c) for c in C)...)
pmo = [pm_object(c) for c in C]
return Cone{T}(Polymake.polytope.intersection(pmo...), f)
T, f = _promote_scalar_field((coefficient_field(c) for c in C)...)
pmo = [pm_object(c) for c in C]
return Cone{T}(Polymake.polytope.intersection(pmo...), f)
end
intersect(C::AbstractVector{<:Cone}) = intersect(C...)


@doc raw"""
polarize(C::Cone)

@@ -54,11 +53,10 @@ julia> rays(Cv)
[0, 1]
```
"""
function polarize(C::Cone{T}) where T<:scalar_types
return Cone{T}(Polymake.polytope.polarize(pm_object(C)), coefficient_field(C))
function polarize(C::Cone{T}) where {T<:scalar_types}
return Cone{T}(Polymake.polytope.polarize(pm_object(C)), coefficient_field(C))
end


@doc raw"""
transform(C::Cone{T}, A::AbstractMatrix) where T<:scalar_types

@@ -94,49 +92,51 @@ julia> c == ctt
true
```
"""
function transform(C::Cone{T}, A::Union{AbstractMatrix{<:Union{Number, FieldElem}}, MatElem{<:FieldElem}}) where {T<:scalar_types}
function transform(
C::Cone{T}, A::Union{AbstractMatrix{<:Union{Number,FieldElem}},MatElem{<:FieldElem}}
) where {T<:scalar_types}
@assert ambient_dim(C) == nrows(A) "Incompatible dimension of cone and transformation matrix"
@assert nrows(A) == ncols(A) "Transformation matrix must be square"
@assert Polymake.common.rank(A) == nrows(A) "Transformation matrix must have full rank."
return _transform(C, A)
end

function _transform(C::Cone{T}, A::AbstractMatrix{<:FieldElem}) where T<:scalar_types
U, f = _promote_scalar_field(A)
V, g = _promote_scalar_field(coefficient_field(C), f)
OT = _scalar_type_to_polymake(V)
raymod = Polymake.Matrix{OT}(permutedims(A))
facetmod = Polymake.Matrix{OT}(Polymake.common.inv(permutedims(raymod)))
return _transform(C, raymod, facetmod, g)
function _transform(C::Cone{T}, A::AbstractMatrix{<:FieldElem}) where {T<:scalar_types}
U, f = _promote_scalar_field(A)
V, g = _promote_scalar_field(coefficient_field(C), f)
OT = _scalar_type_to_polymake(V)
raymod = Polymake.Matrix{OT}(permutedims(A))
facetmod = Polymake.Matrix{OT}(Polymake.common.inv(permutedims(raymod)))
return _transform(C, raymod, facetmod, g)
end
function _transform(C::Cone{T}, A::AbstractMatrix{<:Number}) where T<:scalar_types
OT = _scalar_type_to_polymake(T)
raymod = Polymake.Matrix{OT}(permutedims(A))
facetmod = Polymake.Matrix{OT}(Polymake.common.inv(permutedims(raymod)))
return _transform(C, raymod, facetmod, coefficient_field(C))
function _transform(C::Cone{T}, A::AbstractMatrix{<:Number}) where {T<:scalar_types}
OT = _scalar_type_to_polymake(T)
raymod = Polymake.Matrix{OT}(permutedims(A))
facetmod = Polymake.Matrix{OT}(Polymake.common.inv(permutedims(raymod)))
return _transform(C, raymod, facetmod, coefficient_field(C))
end
function _transform(C::Cone{T}, A::MatElem{U}) where {T<:scalar_types, U<:FieldElem}
V, f = _promote_scalar_field(coefficient_field(C), base_ring(A))
OT = _scalar_type_to_polymake(V)
raymod = Polymake.Matrix{OT}(transpose(A))
facetmod = Polymake.Matrix{OT}(inv(A))
return _transform(C, raymod, facetmod, f)
function _transform(C::Cone{T}, A::MatElem{U}) where {T<:scalar_types,U<:FieldElem}
V, f = _promote_scalar_field(coefficient_field(C), base_ring(A))
OT = _scalar_type_to_polymake(V)
raymod = Polymake.Matrix{OT}(transpose(A))
facetmod = Polymake.Matrix{OT}(inv(A))
return _transform(C, raymod, facetmod, f)
end
function _transform(C::Cone{T}, raymod, facetmod, f::Field) where T<:scalar_types
U = elem_type(f)
OT = _scalar_type_to_polymake(U)
result = Polymake.polytope.Cone{OT}()
for prop in ("RAYS", "INPUT_RAYS", "LINEALITY_SPACE", "INPUT_LINEALITY")
if Polymake.exists(pm_object(C), prop)
resultprop = Polymake.Matrix{OT}(Polymake.give(pm_object(C), prop) * raymod)
Polymake.take(result, prop, resultprop)
end
function _transform(C::Cone{T}, raymod, facetmod, f::Field) where {T<:scalar_types}
U = elem_type(f)
OT = _scalar_type_to_polymake(U)
result = Polymake.polytope.Cone{OT}()
for prop in ("RAYS", "INPUT_RAYS", "LINEALITY_SPACE", "INPUT_LINEALITY")
if Polymake.exists(pm_object(C), prop)
resultprop = Polymake.Matrix{OT}(Polymake.give(pm_object(C), prop) * raymod)
Polymake.take(result, prop, resultprop)
end
for prop in ("INEQUALITIES", "EQUATIONS", "LINEAR_SPAN", "FACETS")
if Polymake.exists(pm_object(C), prop)
resultprop = Polymake.Matrix{OT}(Polymake.give(pm_object(C), prop) * facetmod)
Polymake.take(result, prop, resultprop)
end
end
for prop in ("INEQUALITIES", "EQUATIONS", "LINEAR_SPAN", "FACETS")
if Polymake.exists(pm_object(C), prop)
resultprop = Polymake.Matrix{OT}(Polymake.give(pm_object(C), prop) * facetmod)
Polymake.take(result, prop, resultprop)
end
return Cone{U}(result, f)
end
return Cone{U}(result, f)
end
Loading