Skip to content

Commit 589a16f

Browse files
committed
Roots over local fields
1 parent 1347841 commit 589a16f

3 files changed

Lines changed: 392 additions & 17 deletions

File tree

src/LocalField.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ include("LocalField/neq.jl")
1212
include("LocalField/ResidueRing.jl")
1313
include("LocalField/LaurentSeries.jl")
1414
include("LocalField/PowerSeries.jl")
15+
include("LocalField/roots.jl")

src/LocalField/Poly.jl

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function lift(x::fqPolyRepPolyRingElem, Kt)
125125
return Kt(coeffs)
126126
end
127127

128-
function _content(f::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem}
128+
function _content(f::PolyRingElem{T}) where T <: Union{NonArchLocalFieldElemTypes, NonArchLocalFieldValuationRingElem}
129129
K = base_ring(f)
130130
@assert !iszero(f)
131131
c = coeff(f, 0)
@@ -135,19 +135,17 @@ function _content(f::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFiel
135135
i > length(f) && error("bad poly")
136136
c = coeff(f, i)
137137
end
138-
v = valuation(c)
139-
for j = i+1:degree(f)
138+
v = _valuation_integral(c)
139+
for j = i + 1:degree(f)
140140
c = coeff(f, j)
141141
if !iszero(c)
142-
v = min(v, valuation(c))
142+
v = min(v, _valuation_integral(c))
143143
end
144144
end
145145
if iszero(v)
146146
return one(K)
147147
end
148-
e = v*absolute_ramification_index(K)
149-
@assert isone(denominator(e))
150-
return uniformizer(K)^numerator(e)
148+
return uniformizer(K)^v
151149
end
152150

153151
function rem!(x::AbstractAlgebra.Generic.Poly{T}, y::AbstractAlgebra.Generic.Poly{T}, z::AbstractAlgebra.Generic.Poly{T}) where {T<:LocalFieldElem}
@@ -234,15 +232,15 @@ end
234232
################################################################################
235233

236234

237-
function Nemo.precision(g::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem, LocalFieldValuationRingElem}
235+
function Nemo.precision(g::PolyRingElem{<: Union{NonArchLocalFieldElemTypes, NonArchLocalFieldValuationRingElem}})
238236
N = precision(coeff(g, 0))
239237
for i = 1:degree(g)
238+
is_zero(coeff(g, i)) && continue
240239
N = min(N, precision(coeff(g, i)))
241240
end
242241
return N
243242
end
244243

245-
246244
function Base.gcd(f::Generic.Poly{T}, g::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem}
247245
if degree(f) < degree(g)
248246
f, g = g, f
@@ -726,11 +724,11 @@ end
726724
@doc raw"""
727725
characteristic_polynomial(f::Generic.Poly{T}, g::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem} -> Generic.Poly{T}
728726
729-
Computes $\mathrm{ResidueRingElem}_x(f(x), t- g(x))$.
727+
Compute $\mathrm{Res}_x(f(x), t - g(x))$.
730728
"""
731-
function characteristic_polynomial(f::Generic.Poly{T}, g::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem}
729+
function characteristic_polynomial(f::Generic.Poly{T}, g::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem, LocalFieldValuationRingResidueRingElem}
732730
Kt = parent(f)
733-
Ktx, x = polynomial_ring(Kt, "x")
731+
Ktx, x = polynomial_ring(Kt, "x", cached = false)
734732
fcoeffs = typeof(f)[Kt(coeff(f, i)) for i = 0:degree(f)]
735733
gcoeffs = typeof(f)[Kt(-coeff(g, i)) for i = 0:degree(g)]
736734
f1 = Ktx(fcoeffs)
@@ -918,6 +916,36 @@ mutable struct HenselCtxdr{S}
918916
end
919917
return HenselCtxQadic{S}(f, lfp)
920918
end
919+
920+
function HenselCtxdr{S}(f::PolyRingElem{S}, lfp::Vector{T}) where {S <: LocalFieldValuationRingResidueRingElem, T}
921+
R = base_ring(f)
922+
Rx = parent(f)
923+
K = _field(R)
924+
@assert residue_field(K)[1] === coefficient_ring(lfp[1])
925+
k, Ktok = residue_field(K)
926+
R1 = LocalFieldValuationRingResidueRing(valuation_ring(K), 1)
927+
R1x, _ = polynomial_ring(R1, "x", cached = false)
928+
i = 1
929+
la = Vector{typeof(f)}()
930+
n = length(lfp)
931+
while i < length(lfp)
932+
f1 = lfp[i]
933+
f2 = lfp[i+1]
934+
g, a, b = gcdx(f1, f2)
935+
@assert isone(g)
936+
push!(la, map_coefficients(x -> R1(Ktok\x), a, parent = R1x))
937+
push!(la, map_coefficients(x -> R1(Ktok\x), b, parent = R1x))
938+
push!(lfp, f1*f2)
939+
i += 2
940+
end
941+
942+
z = new{S}()
943+
z.f = f
944+
z.lf = map(x -> map_coefficients(y -> R1(Ktok\y), x, parent = R1x), lfp)
945+
z.la = la
946+
z.n = n
947+
return z
948+
end
921949
end
922950

923951
function lift(C::HenselCtxdr, mx::Int)
@@ -991,16 +1019,23 @@ end
9911019
################################################################################
9921020

9931021
@doc raw"""
994-
slope_factorization(f::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem} -> Dict{Generic.Poly{T}, Int}
1022+
slope_factorization(f::T) where {T <: PolyRingElem{<: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem}}} -> Dict{T, Int}
9951023
996-
Computes a factorization of $f$ such that every factor has a one-sided generalized Newton polygon.
997-
The output is a dictionary whose keys are the factors of $f$ and the corresponding value is the multiplicity.
1024+
Compute a factorization of $f$ such that every factor has a one-sided generalized Newton polygon.
1025+
The output is a dictionary whose keys are the factors of $f$ and the corresponding value is the
1026+
multiplicity.
9981027
"""
999-
function slope_factorization(f::Generic.Poly{T}) where T <: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem}
1028+
function slope_factorization(f::PolyRingElem{<: Union{PadicFieldElem, QadicFieldElem, LocalFieldElem}})
1029+
@assert all(c -> is_zero(c) || valuation(c) >= 0, coefficients(f)) "Coefficients must have non-negative valuation"
1030+
1031+
# Reference: Carlo Sircana, "Factoring polynomials over ZZ/(n)", Master's Thesis,
1032+
# Università di Pisa, 2016,
1033+
# http://poisson.phc.dm.unipi.it/~sircana/tesi1.pdf
1034+
# Section 2.1.1
10001035

10011036
K = base_ring(f)
10021037
Kt = parent(f)
1003-
fact = Dict{Generic.Poly{T}, Int}()
1038+
fact = Dict{typeof(f), Int}()
10041039
cf = _content(f)
10051040
f = divexact(f, cf)
10061041
if !iszero(valuation(leading_coefficient(f)))

0 commit comments

Comments
 (0)