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

updates related to polymake 4.12 #3819

Merged
merged 9 commits into from
Jul 22, 2024
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ LazyArtifacts = "1.6"
Markdown = "1.6"
Nemo = "0.45.5"
Pkg = "1.6"
Polymake = "0.11.14"
Polymake = "0.11.19"
Random = "1.6"
RandomExtensions = "0.4.3"
Serialization = "1.6"
Expand Down
5 changes: 3 additions & 2 deletions src/Combinatorics/Graphs/functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,22 +342,23 @@ function reverse(e::Edge)
end


struct EdgeIterator
mutable struct EdgeIterator
pm_itr::Polymake.GraphEdgeIterator{T} where {T <: Union{Directed, Undirected}}
l::Int64
end
Base.length(eitr::EdgeIterator) = eitr.l
Base.eltype(::Type{EdgeIterator}) = Edge

function Base.iterate(eitr::EdgeIterator, index = 1)
if index > eitr.l
if eitr.l == 0 || Polymake.isdone(eitr.pm_itr)
return nothing
else
e = Polymake.get_element(eitr.pm_itr)
s = Polymake.first(e)
t = Polymake.last(e)
edge = Edge(s+1, t+1)
Polymake.increment(eitr.pm_itr)
eitr.l -= 1
return (edge, index+1)
end
end
Expand Down
18 changes: 9 additions & 9 deletions src/PolyhedralGeometry/Polyhedron/properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ julia> dim(P)
dim(P::Polyhedron) = Polymake.polytope.dim(pm_object(P))::Int

@doc raw"""
lattice_points(P::Polyhedron{QQFieldElem})
lattice_points(P::Polyhedron)

Return the integer points contained in the bounded polyhedron `P`.

Expand All @@ -757,15 +757,15 @@ julia> matrix(ZZ, lattice_points(S))
[2 0]
```
"""
function lattice_points(P::Polyhedron{QQFieldElem})
function lattice_points(P::Polyhedron)
@req pm_object(P).BOUNDED "Polyhedron not bounded"
return SubObjectIterator{PointVector{ZZRingElem}}(
P, _lattice_point, size(pm_object(P).LATTICE_POINTS_GENERATORS[1], 1)
)
end

_lattice_point(
T::Type{PointVector{ZZRingElem}}, P::Polyhedron{QQFieldElem}, i::Base.Integer
T::Type{PointVector{ZZRingElem}}, P::Polyhedron, i::Base.Integer
) = point_vector(ZZ, @view pm_object(P).LATTICE_POINTS_GENERATORS[1][i, 2:end])::T

_point_matrix(::Val{_lattice_point}, P::Polyhedron; homogenized=false) =
Expand All @@ -774,7 +774,7 @@ _point_matrix(::Val{_lattice_point}, P::Polyhedron; homogenized=false) =
_matrix_for_polymake(::Val{_lattice_point}) = _point_matrix

@doc raw"""
interior_lattice_points(P::Polyhedron{QQFieldElem})
interior_lattice_points(P::Polyhedron)

Return the integer points contained in the interior of the bounded polyhedron
`P`.
Expand All @@ -792,15 +792,15 @@ julia> matrix(ZZ, interior_lattice_points(c))
[0 0 0]
```
"""
function interior_lattice_points(P::Polyhedron{QQFieldElem})
function interior_lattice_points(P::Polyhedron)
@req pm_object(P).BOUNDED "Polyhedron not bounded"
return SubObjectIterator{PointVector{ZZRingElem}}(
P, _interior_lattice_point, size(pm_object(P).INTERIOR_LATTICE_POINTS, 1)
)
end

_interior_lattice_point(
T::Type{PointVector{ZZRingElem}}, P::Polyhedron{QQFieldElem}, i::Base.Integer
T::Type{PointVector{ZZRingElem}}, P::Polyhedron, i::Base.Integer
) = point_vector(ZZ, @view pm_object(P).INTERIOR_LATTICE_POINTS[i, 2:end])::T

_point_matrix(::Val{_interior_lattice_point}, P::Polyhedron; homogenized=false) =
Expand All @@ -813,7 +813,7 @@ _point_matrix(::Val{_interior_lattice_point}, P::Polyhedron; homogenized=false)
_matrix_for_polymake(::Val{_interior_lattice_point}) = _point_matrix

@doc raw"""
boundary_lattice_points(P::Polyhedron{QQFieldElem})
boundary_lattice_points(P::Polyhedron)

Return the integer points contained in the boundary of the bounded polyhedron
`P`.
Expand Down Expand Up @@ -841,15 +841,15 @@ julia> matrix(ZZ, boundary_lattice_points(c))
[ 1 0 0]
```
"""
function boundary_lattice_points(P::Polyhedron{QQFieldElem})
function boundary_lattice_points(P::Polyhedron)
@req pm_object(P).BOUNDED "Polyhedron not bounded"
return SubObjectIterator{PointVector{ZZRingElem}}(
P, _boundary_lattice_point, size(pm_object(P).BOUNDARY_LATTICE_POINTS, 1)
)
end

_boundary_lattice_point(
T::Type{PointVector{ZZRingElem}}, P::Polyhedron{QQFieldElem}, i::Base.Integer
T::Type{PointVector{ZZRingElem}}, P::Polyhedron, i::Base.Integer
) = point_vector(ZZ, @view pm_object(P).BOUNDARY_LATTICE_POINTS[i, 2:end])::T

_point_matrix(::Val{_boundary_lattice_point}, P::Polyhedron; homogenized=false) =
Expand Down
8 changes: 8 additions & 0 deletions src/PolyhedralGeometry/helpers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,14 @@ end

# oscarnumber helpers

function Polymake._fieldelem_to_floor(e::Union{EmbeddedNumFieldElem,QQBarFieldElem})
return BigInt(floor(ZZRingElem, e))
end

function Polymake._fieldelem_to_ceil(e::Union{EmbeddedNumFieldElem,QQBarFieldElem})
return BigInt(ceil(ZZRingElem, e))
end

function Polymake._fieldelem_to_rational(e::EmbeddedNumFieldElem)
return Rational{BigInt}(QQ(e))
end
Expand Down
21 changes: 20 additions & 1 deletion src/Serialization/polymake.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ _pmdata_for_oscar(v::Polymake.Vector{<:Polymake.Rational}, coeff::Field) = colle

_pmdata_for_oscar(v::Polymake.SparseVector, coeff::Field) = _pmdata_for_oscar(Polymake.common.dense(v), coeff)

_pmdata_for_oscar(nm::Polymake.NodeMap, coeff::Field) = _pmdata_for_oscar(Polymake.Array(nm), coeff)
_pmdata_for_oscar(bd::Polymake.BasicDecoration, coeff::Field) = (_pmdata_for_oscar(Polymake.decoration_face(bd), coeff), _pmdata_for_oscar(Polymake.decoration_rank(bd), coeff))

_pmdata_for_oscar(s::Polymake.Integer, coeff::Field) = ZZ(s)
_pmdata_for_oscar(s::Polymake.Rational, coeff::Field) = QQ(s)
_pmdata_for_oscar(s::Polymake.OscarNumber, coeff::Field) = coeff(s)
Expand All @@ -106,6 +109,8 @@ _pmdata_for_oscar(s::Polymake.TropicalNumber{A}, coeff::Field) where A = tropica
_pmdata_for_oscar(s::Polymake.CxxWrap.StdString, coeff::Field) = String(s)

_pmdata_for_oscar(a::Polymake.Array, coeff::Field) = [_pmdata_for_oscar(e, coeff) for e in a]
_pmdata_for_oscar(a::Polymake.Array{T}, coeff::Field) where T <: Union{Polymake.Matrix, Polymake.Vector} = Tuple(_pmdata_for_oscar.(a, Ref(coeff)))

_pmdata_for_oscar(s::Polymake.Set, coeff::Field) = Set(_pmdata_for_oscar(e, coeff) for e in s)


Expand Down Expand Up @@ -145,16 +150,30 @@ function _polyhedral_object_as_dict(x::Oscar.PolyhedralObjectUnion)
end

function _load_bigobject_from_dict!(obj::Polymake.BigObject, dict::Dict, parent_key::String="")
delay_loading = Tuple{String,Any}[]
for (k, v) in dict
key_str = parent_key == "" ? k : parent_key * "." * k
first(k) == '_' && continue

if v isa Dict
_load_bigobject_from_dict!(obj, v, key_str)
else
Polymake.take(obj, key_str, convert(Polymake.PolymakeType, v))
pmv = convert(Polymake.PolymakeType, v)
bot = Polymake.bigobject_type(obj)
# NodeMaps need extra treatment since the constructor doesn't accept polymake c++ arrays
# and we can't create a nodemap from scratch without the graph
# so we convert it to a pure perl array and delay loading until the end of this level
if pmv isa Polymake.Array && Polymake.bigobject_prop_type(bot, key_str) in ["NodeMap", "EdgeMap"]
pmv = Polymake.as_perl_array_of_array(pmv)
push!(delay_loading, (key_str, pmv))
else
Polymake.take(obj, key_str, pmv)
end
end
end
for (k, v) in delay_loading
Polymake.take(obj, k, v)
end
if haskey(dict, "_description")
Polymake.setdescription!(obj, dict["_description"])
end
Expand Down
10 changes: 10 additions & 0 deletions test/Combinatorics/Graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@
@test n_vertices(G2) == 13
@test n_edges(G2) == 5

ei = edges(G2)
@test length(ei) == 5

ee = collect(ei)
@test length(ei) == 0
@test collect(ei) == Edge[]

GG2 = graph_from_edges(Undirected, ee, 13)
@test is_isomorphic(G2, GG2)

end

@testset "adjacency_matrix laplacian_matrix" begin
Expand Down
2 changes: 1 addition & 1 deletion test/PolyhedralGeometry/polyhedron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
@test !([-1, -1] in Q0)
@test n_vertices(Q0) == 3
@test n_vertices.(faces(Q0, 1)) == [2, 2, 2]
if T == QQFieldElem
@test lattice_points(Q0) isa SubObjectIterator{PointVector{ZZRingElem}}
@test point_matrix(lattice_points(Q0)) == matrix(ZZ, [0 0; 0 1; 1 0])
@test matrix(ZZ, lattice_points(Q0)) == matrix(ZZ, [0 0; 0 1; 1 0])
Expand All @@ -63,6 +62,7 @@
@test length(boundary_lattice_points(square)) == 8
@test boundary_lattice_points(square) ==
[[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]]
if T == QQFieldElem
@test is_smooth(Q0)
@test is_normal(Q0)
@test is_lattice_polytope(Q0)
Expand Down
5 changes: 5 additions & 0 deletions test/PolyhedralGeometry/scalar_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
@test _edge_length_for_test.(faces(sd, 1)) == repeat([4], 18)
# scaling the Polyhedron by 3 yields edge lengths of 6
@test _edge_length_for_test.(faces(3 * sd, 1)) == repeat([36], 18)
# there are 11 lattice points
@test length(lattice_points(sd)) == 11

let pc = polyhedral_complex(
E, IncidenceMatrix(facets(sd)), vertices(sd); non_redundant=true
)
Expand All @@ -62,6 +65,8 @@
@test number_of_vertices(qp) == 3
@test number_of_facets(qp) == 3

@test length(lattice_points(qp)) == 1

@testset "Scalar detection" begin
let j = johnson_solid(12)
@test j isa Polyhedron{QQFieldElem}
Expand Down
15 changes: 11 additions & 4 deletions test/Serialization/PolyhedralGeometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,30 @@ using Oscar: _integer_variables

@testset "Polyhedron" begin
square = cube(2)
f_vector(square)
test_save_load_roundtrip(path, square) do loaded
@test n_vertices(square) == n_vertices(loaded)
@test dim(square) == dim(loaded)
@test square == loaded
@test Polymake.exists(Oscar.pm_object(loaded), "HASSE_DIAGRAM.DECORATION")
end

n2 = (QQBarField()(5))^(QQ(4//5))
c = cube(QQBarField(), 3, -1, n2)
test_save_load_roundtrip(path, square) do loaded
@test n_vertices(square) == n_vertices(loaded)
@test dim(square) == dim(loaded)
@test square == loaded
f_vector(c)
lattice_points(c)
test_save_load_roundtrip(path, c) do loaded
@test n_vertices(c) == n_vertices(loaded)
@test dim(c) == dim(loaded)
@test c == loaded
@test Polymake.exists(Oscar.pm_object(loaded), "HASSE_DIAGRAM.DECORATION")
end

d_hedron = dodecahedron()
facets(d_hedron)
vertices(d_hedron)
f_vector(d_hedron)
lattice_points(d_hedron)

dict_ps = Dict{String, Any}(
"unprecise" => polyhedron(
Expand Down
Loading