Skip to content

Commit

Permalink
Replace some setprecision!(::ParentObject)
Browse files Browse the repository at this point in the history
  • Loading branch information
joschmitt committed May 21, 2024
1 parent 60d03bf commit 66c77db
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 370 deletions.
97 changes: 48 additions & 49 deletions src/LocalField/Completions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ The map giving the embedding of $K$ into the completion, admits a pointwise
preimage to obtain a lift. Note, that the map is not well defined by this
data: $K$ will have $\deg P$ many embeddings.
The map is guaranteed to yield a relative precision of at least `preciscion`.
The map is guaranteed to yield a relative precision of at least `precision`.
"""
function completion(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, precision::Int = 64)
function completion(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, precision::Int = 64, Qp::Union{PadicField,Nothing} = nothing)
#to guarantee a rel_prec we need to account for the index (or the
#elementary divisor of the trace mat): the map
#is for the field (equation order), the precision is measured in the
Expand All @@ -189,9 +189,11 @@ function completion(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumF
f = degree(P)
e = ramification_index(P)
prec_padics = div(precision+e-1, e)
Qp = PadicField(minimum(P), prec_padics, cached = false)
if isnothing(Qp)
Qp = PadicField(minimum(P), prec_padics, cached = false)
end
Zp = maximal_order(Qp)
Qq, gQq = QadicField(minimum(P), f, prec_padics, cached = false)
Qq, gQq = unramified_extension(Qp, f, precision = prec_padics, cached = false)
Qqx, gQqx = polynomial_ring(Qq, "x")
q, mq = residue_field(Qq)
#F, mF = ResidueFieldSmall(OK, P)
Expand Down Expand Up @@ -264,54 +266,51 @@ function _solve_internal(gq_in_K, P, precision, Zp, Qq)
mul!(bK.num, bK.num, divexact(d, denominator(bK, copy = false)))
end

setprecision!(Zp, Hecke.precision(Zp) + valuation(Zp(denominator(MK))))

if true
#snf is slower (possibly) but has optimal precision loss.
#bad example is completion at prime over 2 in
# x^8 - 12*x^7 + 44*x^6 - 24*x^5 - 132*x^4 + 120*x^3 + 208*x^2 - 528*x + 724
# the can_solve... returns a precision of just 6 p-adic digits
# the snf gets 16 (both for the default precision)
# the det(M) has valuation 12, but the elem. divisors only 3
#TODO: rewrite can_solve? look at Avi's stuff?
# x M = b
# u*M*v = s
# x inv(u) u M v = b v
# x inv(u) s = b v
# x = b v inv(s) u
#lets try:
s, _u, v = snf_with_transform(MK.num)
bv = bK.num * v
bv = map_entries(Zp, bv)
for i=1:ncols(s)
bv[1, i] = divexact(bv[1, i], Zp(s[i,i]))
bv[2, i] = divexact(bv[2, i], Zp(s[i,i]))
end
xZp = bv * map_entries(Zp, _u[1:ncols(s), 1:ncols(s)])
else
MZp = map_entries(Zp, MK.num)
bZp = map_entries(Zp, bK.num)
fl, xZp = can_solve_with_solution(MZp, bZp, side = :left)
@assert fl
end
coeffs_eisenstein = Vector{QadicFieldElem}(undef, e+1)
gQq = gen(Qq)
for i = 1:e
coeff = zero(Qq)
for j = 0:f-1
coeff += (gQq^j)*xZp[1, j+1+(i-1)*f].x
return with_precision(Zp, Hecke.precision(Zp) + valuation(Zp(denominator(MK)))) do
if true
#snf is slower (possibly) but has optimal precision loss.
#bad example is completion at prime over 2 in
# x^8 - 12*x^7 + 44*x^6 - 24*x^5 - 132*x^4 + 120*x^3 + 208*x^2 - 528*x + 724
# the can_solve... returns a precision of just 6 p-adic digits
# the snf gets 16 (both for the default precision)
# the det(M) has valuation 12, but the elem. divisors only 3
#TODO: rewrite can_solve? look at Avi's stuff?
# x M = b
# u*M*v = s
# x inv(u) u M v = b v
# x inv(u) s = b v
# x = b v inv(s) u
#lets try:
s, _u, v = snf_with_transform(MK.num)
bv = bK.num * v
bv = map_entries(Zp, bv)
for i=1:ncols(s)
bv[1, i] = divexact(bv[1, i], Zp(s[i,i]))
bv[2, i] = divexact(bv[2, i], Zp(s[i,i]))
end
xZp = bv * map_entries(Zp, _u[1:ncols(s), 1:ncols(s)])
else
MZp = map_entries(Zp, MK.num)
bZp = map_entries(Zp, bK.num)
xZp = solve(MZp, bZp, side = :left)
end
coeffs_eisenstein[i] = -coeff
end
coeffs_eisenstein[e+1] = one(Qq)
if iszero(coeffs_eisenstein[1])
error("precision not high enough to obtain Esenstein polynomial")
end
return coeffs_eisenstein, xZp
coeffs_eisenstein = Vector{QadicFieldElem}(undef, e+1)
gQq = gen(Qq)
for i = 1:e
coeff = zero(Qq)
for j = 0:f-1
coeff += (gQq^j)*xZp[1, j+1+(i-1)*f].x
end
coeffs_eisenstein[i] = -coeff
end
coeffs_eisenstein[e+1] = one(Qq)
if iszero(coeffs_eisenstein[1])
error("precision not high enough to obtain Esenstein polynomial")
end
return coeffs_eisenstein, xZp
end # with_precision
end



function setprecision!(f::CompletionMap{LocalField{QadicFieldElem, EisensteinLocalField}, LocalFieldElem{QadicFieldElem, EisensteinLocalField}}, new_prec::Int)
P = prime(f)
OK = order(P)
Expand Down
77 changes: 47 additions & 30 deletions src/LocalField/Conjugates.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#XXX: valuation(Q(0)) == 0 !!!!!
function newton_lift(f::ZZPolyRingElem, r::QadicFieldElem, prec::Int = parent(r).prec_max, starting_prec::Int = 2)
function newton_lift(f::ZZPolyRingElem, r::QadicFieldElem, prec::Int = precision(parent(r)), starting_prec::Int = 2)
Q = parent(r)
n = prec
i = n
Expand All @@ -15,28 +15,26 @@ function newton_lift(f::ZZPolyRingElem, r::QadicFieldElem, prec::Int = parent(r)
o = Q(r)
s = qf(r)
o = inv(setprecision(qfs, 1)(o))
@assert r.N == 1
@assert precision(r) == 1
for p = reverse(chain)
setprecision!(r, p)
setprecision!(o, p)
setprecision!(Q, r.N)
if r.N > precision(Q)
setprecision!(qf, r.N)
setprecision!(qfs, r.N)
r = with_precision(Q, p) do
r - qf(r)*o
end
r = r - qf(r)*o
if r.N >= n
setprecision!(Q, n)
if precision(r) >= n
return r
end
o = o*(2-qfs(r)*o)
o = with_precision(Q, p) do
o*(2-qfs(r)*o)
end
end
return r
end

function newton_lift(f::ZZPolyRingElem, r::LocalFieldElem, precision::Int = parent(r).prec_max, starting_prec::Int = 2)
function newton_lift(f::ZZPolyRingElem, r::LocalFieldElem, prec::Int = precision(parent(r)), starting_prec::Int = 2)
Q = parent(r)
n = precision
n = prec
i = n
chain = [n]
while i > starting_prec
Expand All @@ -53,15 +51,17 @@ function newton_lift(f::ZZPolyRingElem, r::LocalFieldElem, precision::Int = pare
for p = reverse(chain)
r = setprecision!(r, p)
o = setprecision!(o, p)
setprecision!(Q, p)
setprecision!(qf, p)
setprecision!(qfs, p)
r = r - qf(r)*o
if Nemo.precision(r) >= n
setprecision!(Q, n)
r = with_precision(Q, p) do
return r - qf(r)*o
end
if precision(r) >= n
return r
end
o = o*(2-qfs(r)*o)
o = with_precision(Q, p) do
return o*(2-qfs(r)*o)
end
end
return r
end
Expand Down Expand Up @@ -93,10 +93,11 @@ function roots(C::qAdicRootCtx, n::Int = 10)
lf = factor_mod_pk(Array, C.H, n)
rt = QadicFieldElem[]
for Q = C.Q
setprecision!(Q, n)
for x = lf
if is_splitting(C) || degree(x[1]) == degree(Q)
append!(rt, roots(Q, x[1], max_roots = 1))
with_precision(Q, n) do
append!(rt, roots(Q, x[1], max_roots = 1))
end
end
end
end
Expand Down Expand Up @@ -222,12 +223,14 @@ end
function _conjugates(a::AbsSimpleNumFieldElem, C::qAdicConj, n::Int, op::Function)
R = roots(C.C, n)
@assert parent(a) == C.K
Zx = polynomial_ring(FlintZZ, cached = false)[1]
Zx = polynomial_ring(ZZ, cached = false)[1]
d = denominator(a)
f = Zx(d*a)
res = QadicFieldElem[]
for x = R
a = op(inv(parent(x)(d))*f(x))::QadicFieldElem
a = with_precision(parent(x), n) do
op(inv(parent(x)(d))*f(x))::QadicFieldElem
end
push!(res, a)
end
return res
Expand Down Expand Up @@ -272,11 +275,13 @@ function conjugates_log(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, C:
for (k, v) = a.fac
try
y = conjugates_log(k, C, n, flat = false, all = false)
# vy = v .* y but we need to be careful with the precision of v
vy = QadicFieldElem[parent(yy)(v, precision = n) * yy for yy in y]
if first
res = v .* y
res = vy
first = false
else
res += v .* y
res += vy
end
catch e
if isa(e, DivideError) || isa(e, DomainError)
Expand All @@ -286,11 +291,13 @@ function conjugates_log(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, C:
pe = prod(lp[i][1].gen_two^val[i] for i = 1:length(lp) if val[i] != 0)
aa = k//pe
y = conjugates_log(aa, C, n, all = false, flat = false)
# vy = v .* y but we need to be careful with the precision of v
vy = QadicFieldElem[parent(yy)(v, precision = n) * yy for yy in y]
if first
res = v .* y
res = vy
first = false
else
res += v .* y
res += vy
end
else
rethrow(e)
Expand All @@ -308,18 +315,22 @@ end

function special_gram(m::Vector{Vector{QadicFieldElem}})
g = Vector{PadicFieldElem}[]
if isempty(m)
return g
end
K = base_field(parent(m[1][1]))
for i = m
r = PadicFieldElem[]
for j = m
k = 1
S = 0
S = K()
while k <= length(i)
s = i[k] * j[k]
for l = 1:degree(parent(s))-1
s += i[k+l] * j[k+l]
end
S += coeff(s, 0)
@assert s == coeff(s, 0)
@assert length(s) == 1
k += degree(parent(s))
end
push!(r, S)
Expand Down Expand Up @@ -347,7 +358,11 @@ In either case, Leopold's conjecture states that the regulator is zero iff the u
"""
function regulator(u::Vector{T}, C::qAdicConj, n::Int = 10; flat::Bool = true) where {T<: Union{AbsSimpleNumFieldElem, FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}}}
c = map(x -> conjugates_log(x, C, n, all = !flat, flat = flat), u)
return det(transpose(matrix(special_gram(c))))
K = base_field(parent(c[1][1]))
sg = with_precision(K, n) do
special_gram(c)
end
return det(transpose(matrix(sg)))
end

function regulator(K::AbsSimpleNumField, C::qAdicConj, n::Int = 10; flat::Bool = false)
Expand Down Expand Up @@ -529,6 +544,8 @@ function completion(K::AbsSimpleNumField, p::ZZRingElem, i::Int, n = 64)
@assert 0<i<= degree(K)

ca = conjugates(gen(K), C, n, all = true, flat = false)[i]
setprecision!(parent(ca), n)
setprecision!(base_field(parent(ca)), n)
return completion(K, ca)
end

Expand All @@ -537,7 +554,7 @@ function completion(K::AbsSimpleNumField, ca::QadicFieldElem)
C = qAdicConj(K, Int(p))
r = roots(C.C, precision(ca))
i = findfirst(x->parent(r[x]) == parent(ca) && r[x] == ca, 1:length(r))
Zx = polynomial_ring(FlintZZ, cached = false)[1]
Zx = polynomial_ring(ZZ, cached = false)[1]
function inj(a::AbsSimpleNumFieldElem)
d = denominator(a)
pr = precision(parent(ca))
Expand All @@ -564,7 +581,7 @@ function completion(K::AbsSimpleNumField, ca::QadicFieldElem)
for i=1:d
_num_setcoeff!(a, i-1, lift(ZZ, s[i, 1]))
end
f = defining_polynomial(parent(ca), FlintZZ)
f = defining_polynomial(parent(ca), ZZ)
fso = inv(derivative(f)(gen(R)))
o = matrix(GF(p), d, 1, [lift(ZZ, coeff(fso, j-1)) for j=1:d])
s = solve(m, o; side = :right)
Expand Down
Loading

0 comments on commit 66c77db

Please sign in to comment.