Skip to content

Commit

Permalink
TropicalGeometry: tropical_variety overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
YueRen committed Aug 31, 2024
1 parent 87a56fb commit 6ad31a3
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/TropicalGeometry/TropicalGeometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ include("variety_binomial.jl")
include("variety_principal.jl")
include("variety_affine_linear.jl")
include("variety_zerodimensional.jl")
include("variety_equidimensional.jl")
include("variety_prime.jl")
include("intersection.jl")
include("groebner_fan.jl")
68 changes: 45 additions & 23 deletions src/TropicalGeometry/variety.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ end
#
################################################################################

function Base.show(io::IO, tv::TropicalVariety{typeof(min), true})
function Base.show(io::IO, ::TropicalVariety{typeof(min), true})
print(io, "Min tropical variety")
end
function Base.show(io::IO, tv::TropicalVariety{typeof(max), true})
function Base.show(io::IO, ::TropicalVariety{typeof(max), true})
print(io, "Max tropical variety")
end

Expand All @@ -40,7 +40,7 @@ end
################################################################################

@doc raw"""
tropical_variety(Sigma::PolyhedralComplex, mult, minOrMax::Union{typeof(min),typeof(max)}=min)
tropical_variety(Sigma::PolyhedralComplex, mult::Vector{ZZRingElem}, minOrMax::Union{typeof(min),typeof(max)}=min)
Return the `TropicalVariety` whose polyhedral complex is `Sigma` with multiplicities `mult` and convention `minOrMax`. Here, `mult` is optional can be specified as a `Vector{ZZRingElem}` which represents a list of multiplicities on the maximal polyhedra in the order of `maximal_polyhedra(Sigma)`. If `mult` is unspecified, then all multiplicities are set to one.
Expand Down Expand Up @@ -133,21 +133,37 @@ If `nu==nothing`, will compute with respect to the trivial valuation and min con
If `weighted_polyhedral_complex_only==true`, will not cache any additional information.
!!! warning
Assumes that `I` is equi-dimensional. Only special cases supported:
- any valuation: `I` principal, binomial, affine linear
- trivial and p-adic valuation only: `I` general
Experimental feature, only special cases supported:
- any coefficient field and any valuation: `I` principal, binomial, or affine linear
- QQ and trivial / p-adic valuation only: `I` prime
# Examples
```jldoctest
julia> R,(x,y) = QQ["x","y"];
julia> R,(x,y,z) = QQ["x","y","z"];
julia> I = ideal([(x^2+y)*(x+y^2)*(x+y)]);
julia> nu_2 = tropical_semiring_map(QQ,2)
Map into Min tropical semiring encoding the 2-adic valuation on Rational field
julia> tropical_variety(I)
3-element Vector{TropicalVariety}:
Min tropical variety
Min tropical variety
Min tropical variety
julia> f1 = 8*x^2 + x*y + x*z + x + 8*y^2 + y*z + y + 8*z^2 + z + 8;
julia> f2 = x + 1;
julia> I = ideal([f1,f2]);
julia> TropI_0 = tropical_variety(I)
Min tropical variety
julia> vertices(TropI_0)
1-element SubObjectIterator{PointVector{QQFieldElem}}:
[0, 0, 0]
julia> TropI_2 = tropical_variety(I,nu_2)
Min tropical variety
julia> vertices(TropI_2)
2-element SubObjectIterator{PointVector{QQFieldElem}}:
[0, -3, 3]
[0, 3, -3]
```
"""
Expand All @@ -171,7 +187,7 @@ function tropical_variety(I::MPolyIdeal, nu::Union{TropicalSemiringMap,Nothing}=
end

# I general
return tropical_variety_equidimensional(I,nu,weighted_polyhedral_complex_only=weighted_polyhedral_complex_only)
return tropical_variety_prime(I,nu,weighted_polyhedral_complex_only=weighted_polyhedral_complex_only)
end


Expand Down Expand Up @@ -206,13 +222,14 @@ function homogenize_pre_tropicalization(I::MPolyIdeal)
end


function dehomogenize_post_tropicalization(Sigma::PolyhedralComplex)
@req lineality_dim(Sigma)>0 "dehomogenizing polyhedral complex without lineality"
function dehomogenize_post_tropicalization(TropV::TropicalVarietySupertype)

@req lineality_dim(TropV)>0 "dehomogenizing polyhedral complex without lineality"

###
# Construct hyperplane {first coord = 0}
###
n = ambient_dim(Sigma)
n = ambient_dim(TropV)
zerothUnitRowVector = zeros(Int,1,n)
zerothUnitRowVector[1,1] = 1
dehomogenisingHyperplane = polyhedron((zeros(Int,0,n),zeros(Int,0)), (zerothUnitRowVector,[0]))
Expand All @@ -224,7 +241,7 @@ function dehomogenize_post_tropicalization(Sigma::PolyhedralComplex)
dehomogenizedVertices = Vector{QQFieldElem}[]
incidenceMatrixRays = Vector{Int}[]
dehomogenizedRays = Vector{QQFieldElem}[]
for sigma in maximal_polyhedra(Sigma)
for sigma in maximal_polyhedra(TropV)
sigmaDehomogenized = intersect(sigma,dehomogenisingHyperplane)
incidenceVectorVertices = Int[]
V,_ = minimal_faces(sigmaDehomogenized)
Expand Down Expand Up @@ -267,12 +284,17 @@ function dehomogenize_post_tropicalization(Sigma::PolyhedralComplex)
###
# Dehomogenize lineality space
###
sigma = first(maximal_polyhedra(Sigma))
sigma = first(maximal_polyhedra(TropV))
sigmaDehomogenized = intersect(sigma,dehomogenisingHyperplane)
dehomogenizedLineality = [linealityVector[2:end] for linealityVector in lineality_space(sigmaDehomogenized)]

return polyhedral_complex(incidenceMatrixVerticesAndRays,
dehomogenizedVerticesAndRays,
collect(length(dehomogenizedVertices)+1:length(dehomogenizedVertices)+length(dehomogenizedRays)),
dehomogenizedLineality)
SigmaDehom = polyhedral_complex(incidenceMatrixVerticesAndRays,
dehomogenizedVerticesAndRays,
collect(length(dehomogenizedVertices)+1:length(dehomogenizedVertices)+length(dehomogenizedRays)),
dehomogenizedLineality)

TropVDehom = tropical_variety(SigmaDehom,multiplicities(TropV),convention(TropV))
# TropVDehom.__attrs = deepcopy(TropV.__attrs) # TODO: not working, how to copy all attributes?
return TropVDehom

end
34 changes: 9 additions & 25 deletions src/TropicalGeometry/variety_affine_linear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,16 @@
################################################################################

function tropical_variety_affine_linear(I::MPolyIdeal,nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)
###
# Compute reduced Groebner basis (usually already cached),
# and check whether the linear polynomials have a constant term
###
R = base_ring(I)
# compute a reduced GB to check whether I is homogeneous
G = groebner_basis(I,complete_reduction=true)
if min(total_degree.(Iterators.flatten(collect.(terms.(G))))...)==1
# input homogneeous, construct TropicalVariety via TropicalLinearSpace
TropV = tropical_variety(tropical_linear_space(I,nu,weighted_polyhedral_complex_only=weighted_polyhedral_complex_only))
if !weighted_polyhedral_complex_only
set_attribute!(TropV,:algebraic_ideal,I)
set_attribute!(TropV,:tropical_semiring_map,nu)
end
return TropV
else
# input inhomogeneous, homogenise first
Ih = homogenize_pre_tropicalization(I)
TropLh = tropical_linear_space(Ih,nu,weighted_polyhedral_complex_only=true)
Sigma = dehomogenize_post_tropicalization(polyhedral_complex(TropLh))

multiplicities = ones(ZZRingElem, n_maximal_polyhedra(Sigma))
TropV = tropical_variety(Sigma,multiplicities)
if !weighted_polyhedral_complex_only
set_attribute!(TropV,:algebraic_ideal,I)
set_attribute!(TropV,:tropical_semiring_map,nu)
end
return TropV
if all(Oscar._is_homogeneous.(G))
# input homogneeous, construct TropicalVariety via TropicalLinearSpace
return tropical_variety(tropical_linear_space(I,nu,weighted_polyhedral_complex_only=weighted_polyhedral_complex_only))
end

# input inhomogeneous, homogenise first
Ih = homogenize_pre_tropicalization(I)
TropLh = tropical_linear_space(Ih,nu,weighted_polyhedral_complex_only=true)
return dehomogenize_post_tropicalization(TropLh)
end
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
################################################################################
#
# Tropicalization of equi-dimensional ideals
# Tropicalization of prime ideals
#
# WARNING: assumes without test that `I` is equi-dimensional
# WARNING: assumes without test that `I` is prime
#
################################################################################

function tropical_variety_equidimensional(I::MPolyIdeal, nu::TropicalSemiringMap{QQField,Nothing,<:Union{typeof(min),typeof(max)}}; weighted_polyhedral_complex_only::Bool=false)
return tropical_variety_equidimensional_singular(I,nu; weighted_polyhedral_complex_only=weighted_polyhedral_complex_only)
function tropical_variety_prime(I::MPolyIdeal, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)
# compute a reduced GB to check whether I is homogeneous
G = groebner_basis(I,complete_reduction=true)

if all(Oscar._is_homogeneous.(G))
return tropical_variety_prime_singular(I,nu; weighted_polyhedral_complex_only=weighted_polyhedral_complex_only)
end

Ih = homogenize_pre_tropicalization(I)
TropIh = tropical_variety_prime_singular(Ih,nu,weighted_polyhedral_complex_only=weighted_polyhedral_complex_only)
return dehomogenize_post_tropicalization(TropIh)
end

# trivial valuation case
function tropical_variety_equidimensional_singular(I::MPolyIdeal, nu::TropicalSemiringMap{QQField,Nothing,<:Union{typeof(min),typeof(max)}}; weighted_polyhedral_complex_only::Bool=false)
# trivial valuation
function tropical_variety_prime_singular(I::MPolyIdeal, nu::TropicalSemiringMap{QQField,Nothing,<:Union{typeof(min),typeof(max)}}; weighted_polyhedral_complex_only::Bool=false)
R = base_ring(I)
singularCommand = join(["ring r=0,("*join(string.(symbols(R)),",")*"),dp;",
"ideal I = "*join(string.(gens(I)), ",")*";",
Expand All @@ -29,7 +38,8 @@ function tropical_variety_equidimensional_singular(I::MPolyIdeal, nu::TropicalSe
return TropI
end

function tropical_variety_equidimensional_singular(I::MPolyIdeal, nu::TropicalSemiringMap{QQField,ZZRingElem,<:Union{typeof(min),typeof(max)}}; weighted_polyhedral_complex_only::Bool=false)
# p-adic valuation
function tropical_variety_prime_singular(I::MPolyIdeal, nu::TropicalSemiringMap{QQField,ZZRingElem,<:Union{typeof(min),typeof(max)}}; weighted_polyhedral_complex_only::Bool=false)
R = base_ring(I)
singularCommand = join(["ring r=0,("*join(string.(symbols(R)),",")*"),dp;",
"ideal I = "*join(string.(gens(I)), ",")*";",
Expand All @@ -53,6 +63,9 @@ end
# if dehomogenizeFan==true, the gfan fan is a homogenized polyhedral complex, and we need to dehomogenize it
function gfan_fan_string_to_oscar_complex(input_string::String, negateFan::Bool=false, dehomogenizeFan::Bool=false)

# Extracting AMBIENT_DIM
ambientDim = parse(Int, match(r"AMBIENT_DIM\n(\d+)", input_string).captures[1])

# Extracting the RAYS, LINEALITY_SPACE and MAXIMAL_CONES sections
stringsParsed = Vector{SubString{String}}[]
for regexp in [r"RAYS\n([\s\S]*?)\nN_RAYS", r"LINEALITY_SPACE\n([\s\S]*?)\nORTH_LINEALITY_SPACE", r"MAXIMAL_CONES\n([\s\S]*)"]
Expand All @@ -64,14 +77,29 @@ function gfan_fan_string_to_oscar_complex(input_string::String, negateFan::Bool=

# Convert Rays and ORTH_LINEALITY_SPACE to matrices
# and negate if necessary
rayGenerators = matrix(QQ,[parse.(Int, split(line)) for line in stringsParsed[1]])
linealityGenerators = matrix(QQ,[parse.(Int, split(line)) for line in stringsParsed[2]])
rayGenerators = [parse.(Int, split(line)) for line in stringsParsed[1]]
if isempty(rayGenerators)
rayGenerators = zero_matrix(QQ,0,ambientDim)
else
rayGenerators = matrix(QQ,rayGenerators)
end
if negateFan
rayGenerators *= -1
end

linealityGenerators = [parse.(Int, split(line)) for line in stringsParsed[2]]
if isempty(linealityGenerators)
linealityGenerators = zero_matrix(QQ,0,ambientDim)
else
linealityGenerators = matrix(QQ,linealityGenerators)
end

# Convert MAXIMAL_CONES to a Vector{Vector{Int}}
coneIncidences = [parse.(Int, split(replace(line, r"[{}]" => ""), r"\s+")) .+ 1 for line in stringsParsed[3]]
if length(stringsParsed[3])==1 && first(stringsParsed[3])=="{}"
coneIncidences = [Int[]]
else
coneIncidences = [parse.(Int, split(replace(line, r"[{}]" => ""), r"\s+")) .+ 1 for line in stringsParsed[3]]
end

if dehomogenizeFan
# if the singular fan is a homogenized polyhedral complex,
Expand Down
32 changes: 28 additions & 4 deletions test/TropicalGeometry/variety.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
R,(x,y,z,w) = QQ["x","y","z","w"]
I = ideal(R,[x+2*y,z+4*w])
nu = tropical_semiring_map(QQ,2)
TropV = first(tropical_variety(I,nu))
TropV = tropical_variety(I,nu)
TropL = tropical_linear_space(I,nu)
@test issetequal(maximal_polyhedra(TropV),maximal_polyhedra(TropL))
nu = tropical_semiring_map(QQ,2,max)
TropV = first(tropical_variety(I,nu))
TropV = tropical_variety(I,nu)
TropL = tropical_linear_space(I,nu)
@test issetequal(maximal_polyhedra(TropV),maximal_polyhedra(TropL))
end
Expand All @@ -33,12 +33,36 @@
f = x*y*z+2
nu = tropical_semiring_map(QQ,2)
TropH = tropical_hypersurface(f,nu)
TropV = first(tropical_variety(ideal(R,f),nu))
TropV = tropical_variety(ideal(R,f),nu)
@test issetequal(maximal_polyhedra(TropH),maximal_polyhedra(TropV))
nu = tropical_semiring_map(QQ,2,max)
TropV = first(tropical_variety(ideal(R,f),nu))
TropV = tropical_variety(ideal(R,f),nu)
TropH = tropical_hypersurface(f,nu)
@test issetequal(maximal_polyhedra(TropH),maximal_polyhedra(TropV))
end

# running tropical_variety and all its subroutines
@testset "testing tropical_variety" begin

# principal ideals
R,(x,y,z) = QQ["x","y","z"]
f = x^2+y^2+z^2+1
TropV = tropical_variety(ideal(R,f))
@test f_vector(TropV) == [1,4,6]

# binomial ideals
f = x^2+1
g = y^2+1
TropV = tropical_variety(ideal(R,[f,g]))
@test f_vector(TropV) == [0,1]

# affine linear ideals
f = x+z+1
g = y+z+1
TropV = tropical_variety(ideal(R,[f,g]))
@test f_vector(TropV) == [1,3]

# general ideals, see doctests

end
end

0 comments on commit 6ad31a3

Please sign in to comment.