Skip to content

Commit 38a83a3

Browse files
authored
TropicalGeometry: add roots(::PolyRingElem{<:TropicalSemiringElem}) (#4781)
1 parent fef3745 commit 38a83a3

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

Diff for: docs/src/TropicalGeometry/semiring.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ convention(T::TropicalSemiring{typeof(min)})
2323
Other functions related to `TropicalSemiring`, matrices, and polynomials thereover include:
2424
```@docs
2525
det(A::AbstractAlgebra.Generic.MatSpaceElem{<: Oscar.TropicalSemiringElem})
26+
roots(f::PolyRingElem{TropicalSemiringElem{minOrMax}}) where {minOrMax <: Union{typeof(min),typeof(max)}}
2627
tropical_polynomial(f::MPolyRingElem, nu::TropicalSemiringMap)
2728
```

Diff for: src/TropicalGeometry/poly.jl

+59-1
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,69 @@ end
7878
###
7979
# Disabling ideals in tropical polyomial rings
8080
###
81-
function MPolyIdeal(R::Ring, g::Vector{Generic.MPoly{TropicalSemiringElem{minOrMax}}}) where {minOrMax}
81+
function MPolyIdeal(::Ring, ::Vector{Generic.MPoly{TropicalSemiringElem{minOrMax}}}) where {minOrMax <: Union{typeof(min),typeof(max)}}
8282
error("Ideals over tropical semirings not supported")
8383
end
8484

8585

86+
###
87+
# Roots of univariate tropical polynomials
88+
###
89+
"""
90+
roots(f::PolyRingElem{<:TropicalSemiringElem})
91+
92+
Return the tropical roots of a univariate tropical polynomial `f`, i.e., the variable values where
93+
the min or max is attained at least twice.
94+
95+
# Examples
96+
97+
```jldoctest
98+
julia> R,x = polynomial_ring(tropical_semiring(min),:x)
99+
(Univariate polynomial ring in x over min tropical semiring, x)
100+
101+
julia> f = 1*x^2+x+0
102+
(1)*x^2 + x + (0)
103+
104+
julia> roots(f)
105+
2-element Vector{QQFieldElem}:
106+
0
107+
-1
108+
109+
julia> R,x = polynomial_ring(tropical_semiring(max),:x)
110+
(Univariate polynomial ring in x over max tropical semiring, x)
111+
112+
julia> f = 1*x^2+x+0
113+
(1)*x^2 + x + (0)
114+
115+
julia> roots(f)
116+
1-element Vector{QQFieldElem}:
117+
-1//2
118+
119+
```
120+
"""
121+
function roots(f::PolyRingElem{TropicalSemiringElem{minOrMax}}) where {minOrMax <: Union{typeof(min),typeof(max)}}
122+
# Construct either the lower (min) or upper (max) convex hull of degrees and coefficients
123+
# Example: for min(1+2x,x,0) it is conv({(2,1), (1,0), (0,0)}) + RR_{>=0}*(0,1)
124+
# for max(1+2x,x,0) it is conv({(2,1), (1,0), (0,0)}) + RR_{>=0}*(0,-1)
125+
# Note: univariate polynomials also enumerate over zero coefficients, necessitating !iszero(c) below
126+
valsAndExps = [ QQFieldElem[first(d),QQ(c)] for (d,c) in zip(exponents(f),coefficients(f)) if !iszero(c) ]
127+
128+
if length(valsAndExps)<2
129+
return QQFieldElem[] # return empty set if f not at least binomial
130+
end
131+
132+
s = minOrMax==typeof(min) ? 1 : -1 # +1 if min, -1 if max
133+
hullDirection = s*[0 1]
134+
newtonPolygon = convex_hull(valsAndExps,hullDirection)
135+
136+
# The negated slopes of the lower (min) or upper (max) edges are when function value is attained at least twice
137+
# Example: for min(1+2x,x,0) it is -1 and 0, for max(1+2x,x,0) it is -1/2
138+
F = affine_inequality_matrix(facets(newtonPolygon))
139+
negatedSlopes = [ F[i,2]/F[i,3] for i in 1:nrows(F) if s*F[i,3]<0 ]
140+
return negatedSlopes
141+
end
142+
143+
86144

87145
################################################################################
88146
#

Diff for: test/TropicalGeometry/poly.jl

+5
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@
88
@test issetequal(coefficients(tropf),tropical_semiring(nu).([0,1,2]))
99
@test issetequal(exponents(tropf),[[1,0],[0,1],[0,0]])
1010
end
11+
12+
@testset "roots(::PolyRingElem{<:TropicalSemiringElem}) edge cases" begin
13+
R, t = polynomial_ring(tropical_semiring(), "t")
14+
@test isempty(roots(t))
15+
end
1116
end

0 commit comments

Comments
 (0)