Skip to content

Commit

Permalink
PolyhedralGeometry: more operators on fans and complexes
Browse files Browse the repository at this point in the history
  • Loading branch information
YueRen committed Jan 10, 2025
1 parent 43499a7 commit 8617554
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/PolyhedralGeometry/PolyhedralComplex/standard_constructions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,73 @@ function k_skeleton(PC::PolyhedralComplex{T}, k::Int) where {T<:scalar_types}
)
return PolyhedralComplex{T}(ksk, coefficient_field(PC))
end


###############################################################################
## Scalar product
###############################################################################

function *(c::QQFieldElem, Sigma::PolyhedralComplex)
# if scalar is zero, return polyhedral complex consisting only of the origin
if iszero(c)
return polyhedral_complex(convex_hull(zero_matrix(QQ,1,ambient_dim(Sigma))))
end

# if scalar is non-zero, multiple all vertices and rays by said scalar
SigmaVertsAndRays = vertices_and_rays(Sigma)
SigmaRayIndices = findall(vr -> vr isa RayVector, SigmaVertsAndRays)
SigmaLineality = lineality_space(Sigma)
SigmaIncidence = maximal_polyhedra(IncidenceMatrix,Sigma)
return polyhedral_complex(SigmaIncidence, multiply_by_nonzero_scalar.(SigmaVertsAndRays,c), SigmaRayIndices, SigmaLineality)
end
*(c::ZZRingElem, Sigma::PolyhedralComplex) = QQ(c)*Sigma
*(c::Rational, Sigma::PolyhedralComplex) = QQ(c)*Sigma
*(c::Int, Sigma::PolyhedralComplex) = QQ(c)*Sigma

*(Sigma::PolyhedralComplex,c::QQFieldElem) = c*Sigma
*(Sigma::PolyhedralComplex,c::ZZRingElem) = QQ(c)*Sigma
*(Sigma::PolyhedralComplex,c::Rational) = QQ(c)*Sigma
*(Sigma::PolyhedralComplex,c::Int) = QQ(c)*Sigma

###############################################################################
## Negation
###############################################################################

function -(Sigma::PolyhedralComplex)
SigmaVertsAndRays = vertices_and_rays(Sigma)
SigmaRayIndices = findall(vr -> vr isa RayVector, SigmaVertsAndRays)
SigmaLineality = lineality_space(Sigma)
SigmaIncidence = maximal_polyhedra(IncidenceMatrix,Sigma)
return polyhedral_complex(SigmaIncidence, -SigmaVertsAndRays, SigmaRayIndices, SigmaLineality)
end

###############################################################################
## Translation
###############################################################################

function translate_by_vector(u::PointVector{QQFieldElem}, v::Vector{QQFieldElem})
return u .+ v
end
function translate_by_vector(u::RayVector{QQFieldElem}, ::Vector{QQFieldElem})
return u
end
function +(v::Vector{QQFieldElem}, Sigma::PolyhedralComplex)
@req length(v)==ambient_dim(Sigma) "ambient dimension mismatch"
SigmaVertsAndRays = vertices_and_rays(Sigma)
SigmaRayIndices = findall(vr -> vr isa RayVector, SigmaVertsAndRays)
SigmaLineality = lineality_space(Sigma)
SigmaIncidence = maximal_polyhedra(IncidenceMatrix,Sigma)
return polyhedral_complex(SigmaIncidence, translate_by_vector.(SigmaVertsAndRays,Ref(v)), SigmaRayIndices, SigmaLineality)
end
+(v::Vector{ZZRingElem}, Sigma::PolyhedralComplex) = QQ.(v)+Sigma
+(v::Vector{Rational}, Sigma::PolyhedralComplex) = QQ.(v)+Sigma
+(v::Vector{Int}, Sigma::PolyhedralComplex) = QQ.(v)+Sigma

+(Sigma::PolyhedralComplex, v::Vector{QQFieldElem}) = v+Sigma
+(Sigma::PolyhedralComplex, v::Vector{ZZRingElem}) = QQ.(v)+Sigma
+(Sigma::PolyhedralComplex, v::Vector{Rational}) = QQ.(v)+Sigma
+(Sigma::PolyhedralComplex, v::Vector{Int}) = QQ.(v)+Sigma

# Vector addition for polyhedral fans
+(Sigma::PolyhedralFan, v::Vector) = polyhedral_complex(Sigma)+v
+(v::Vector, Sigma::PolyhedralFan) = v+polyhedral_complex(Sigma)
43 changes: 43 additions & 0 deletions src/PolyhedralGeometry/PolyhedralFan/standard_constructions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,46 @@ function arrangement_polynomial(
F = parent(first(A))
return arrangement_polynomial(ring, matrix(F, A); hyperplanes)
end

###############################################################################
## Scalar multiplication
###############################################################################

function multiply_by_nonzero_scalar(u::PointVector{QQFieldElem}, c::QQFieldElem)
return u .* c
end
function multiply_by_nonzero_scalar(u::RayVector{QQFieldElem}, c::QQFieldElem)
return (c<0 ? -u : u)
end

function *(c::QQFieldElem, Sigma::PolyhedralFan)
# if scalar is zero, return polyhedral complex consisting only of the origin
if iszero(c)
return polyhedral_complex(convex_hull(zero_matrix(QQ,1,ambient_dim(Sigma))))
end

# if scalar is non-zero, multiple all vertices and rays by said scalar
SigmaRays = first(rays_modulo_lineality(Sigma))
SigmaLineality = lineality_space(Sigma)
SigmaIncidence = maximal_cones(IncidenceMatrix,Sigma)
return polyhedral_fan(SigmaIncidence, multiply_by_nonzero_scalar.(SigmaRays,c), SigmaLineality)
end
*(c::ZZRingElem, Sigma::PolyhedralFan) = QQ(c)*Sigma
*(c::Rational, Sigma::PolyhedralFan) = QQ(c)*Sigma
*(c::Int, Sigma::PolyhedralFan) = QQ(c)*Sigma

*(Sigma::PolyhedralFan,c::QQFieldElem) = c*Sigma
*(Sigma::PolyhedralFan,c::ZZRingElem) = QQ(c)*Sigma
*(Sigma::PolyhedralFan,c::Rational) = QQ(c)*Sigma
*(Sigma::PolyhedralFan,c::Int) = QQ(c)*Sigma

###############################################################################
## Negation
###############################################################################

function -(Sigma::PolyhedralFan)
SigmaRays = first(rays_modulo_lineality(Sigma))
SigmaLineality = lineality_space(Sigma)
SigmaIncidence = maximal_cones(IncidenceMatrix,Sigma)
return polyhedral_fan(SigmaIncidence, -SigmaRays, SigmaLineality)
end
23 changes: 23 additions & 0 deletions test/PolyhedralGeometry/polyhedral_complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,27 @@
@test n_maximal_polyhedra(vrep) == n_maximal_polyhedra(hrep)
end
end

@testset "Binary operations" begin
PCshifted = PC + [1, 1]
@test dim(PCshifted) == dim(PC)
@test ambient_dim(PCshifted) == ambient_dim(PC)
@test lineality_dim(PCshifted) == lineality_dim(PC)
@test issetequal(rays(PCshifted), rays(PC))
@test n_maximal_cones(PCshifted) == n_maximal_polyhedra(PC)

PCscaled = 2*PC
@test dim(PCscaled) == dim(PC)
@test ambient_dim(PCscaled) == ambient_dim(PC)
@test lineality_dim(PCscaled) == lineality_dim(PC)
@test issetequal(rays(PCscaled), rays(PC))
@test n_maximal_cones(PCscaled) == n_maximal_polyhedra(PC)

PCnegated = -PC
@test dim(PCnegated) == dim(PC)
@test ambient_dim(PCnegated) == ambient_dim(PC)
@test lineality_dim(PCnegated) == lineality_dim(PC)
@test issetequal(rays(PCnegated), rays(PC))
@test n_maximal_cones(PCnegated) == n_maximal_polyhedra(PC)
end
end
9 changes: 9 additions & 0 deletions test/PolyhedralGeometry/polyhedral_fan.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,15 @@ end
sff1 = star_subdivision(ff, w1)
@test number_of_maximal_cones(sff0) == 2
@test number_of_maximal_cones(sff1) == 3

f = normal_fan(cube(2))
fMinus = -f
@test n_rays(fMinus) == n_rays(f)
@test n_maximal_cones(fMinus) == n_maximal_cones(f)

fMinus = -1*f
@test n_rays(fMinus) == n_rays(f)
@test n_maximal_cones(fMinus) == n_maximal_cones(f)
end

@testset "Defining polynomial of hyperplane arrangement from matrix" begin
Expand Down

0 comments on commit 8617554

Please sign in to comment.