Skip to content

Commit

Permalink
next try
Browse files Browse the repository at this point in the history
there is now a new version of 
`make_finite_field` and `make_function_field`,
which is a hack to solve issue MCLF#103. Adaptions
to this in several places. 

It may be an option to keep these two functions
in an experimental version until https://trac.sagemath.org/ticket/26103 
is completed.
However, the whole module `reduction_trees` needs to 
be reviewed first.
  • Loading branch information
swewers committed Aug 21, 2018
1 parent 7d6f6db commit 238013c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 67 deletions.
5 changes: 1 addition & 4 deletions mclf/curves/smooth_projective_curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -1205,9 +1205,6 @@ def field_of_constant_degree_of_polynomial(G, return_field=False):
d = 1 # will be the degree of the field of constants at the end
for p in primes(2,n+1):
while p.divides(n):
# attention: the latter condition is just to make this
# feasable; the result of this function is therefore
# not provably correct!
try:
K1 = K.extension(p)
except:
Expand Down Expand Up @@ -1242,7 +1239,7 @@ def field_of_constant_degree_of_polynomial(G, return_field=False):
v = GaussValuation(G.parent(), v0)
if v(G) == 0:
Gb = v.reduce(G)
Fb = make_function_field(Gb.base_ring())
Fb, _ = make_function_field(Gb.base_ring())
Gb = Gb.change_ring(Fb)
if Gb.is_irreducible():
dp = field_of_constant_degree_of_polynomial(Gb)
Expand Down
125 changes: 62 additions & 63 deletions mclf/semistable_reduction/reduction_trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ def __init__(self, R, xi, is_separable=True):
self._subtree = subtree
self._xi = xi
self._valuation = xi.valuation()
self._curve = SmoothProjectiveCurve(make_function_field(xi.valuation().residue_field()))
F, _ = make_function_field(xi.valuation().residue_field())
self._curve = SmoothProjectiveCurve(F)
self._lower_components = {}
self._upper_components = {}
self._reduction_genus = {}
Expand Down Expand Up @@ -615,15 +616,15 @@ def lower_components(self, u=Infinity):
lower_valuations = [xi.valuation() for xi in XL.points_from_inequality(f, s)]
lower_components = []
for v in lower_valuations:
F1 = make_function_field(v.residue_field())
F1, eta = make_function_field(v.residue_field())
# we need to find the correct inclusion of F0 into F1
if k0.is_prime_field():
phi = F0.hom(F1(v.reduce(x0)))
phi = F0.hom(eta(v.reduce(x0)))
else:
k1 = F1.constant_base_field()
theta0 = FXL(v0.lift(k0.gen()))
psi = k0.hom([k1(F1(v.reduce(theta0)))])
phi = F0.hom(F1(v.reduce(x0)), psi)
psi = k0.hom([k1(eta(v.reduce(theta0)))])
phi = F0.hom(eta(v.reduce(x0)), psi)
lower_components.append(LowerComponent(self, vL, v, phi))
self._lower_components[u] = lower_components
return lower_components
Expand Down Expand Up @@ -875,13 +876,14 @@ class LowerComponent(ReductionComponent):
"""
def __init__(self, Z0, vL, v, phi):
from mclf.curves.smooth_projective_curves import make_finite_field
self._inertial_component = Z0
self._valuation = v
self._base_valuation = vL
F = make_function_field(v.residue_field())
F, _ = make_function_field(v.residue_field())
self._function_field = F
self._constant_base_field = vL.residue_field()
self._curve = SmoothProjectiveCurve(F, vL.residue_field())
self._constant_base_field, _ = make_finite_field(vL.residue_field())
self._curve = SmoothProjectiveCurve(F, self._constant_base_field)
self._phi = phi


Expand Down Expand Up @@ -991,7 +993,7 @@ def __init__(self, Z, v):
self._inertial_component = Z.inertial_component()
self._base_valuation = Z.base_valuation()
self._valuation = v
self._function_field = make_function_field(v.residue_field())
self._function_field, _ = make_function_field(v.residue_field())
self._constant_base_field = Z.constant_base_field()
self._curve = SmoothProjectiveCurve(self._function_field, Z.constant_base_field())

Expand Down Expand Up @@ -1064,71 +1066,68 @@ def base_change_of_function_field(F, L):
return F0L.extension(F.polynomial().change_ring(F0L), F.variable_name())


def make_function_field(k):
def make_function_field(K):
r"""
Return the function field corresponding to this field.
Return the function field isomorphic to this field, and an isomorphism.
INPUT:
- ``k`` -- the residue field of a discrete valuation on a function field.
- ``K`` -- a field
OUTPUT:
OUTPUT: A pair `(F,\phi)`, where `F` is a rational function field
and `\phi:K\to F` is a field isomorphism.
the field `k` as a function field over the 'natural' constant base field.
It is assumed that such a pair exists. The typical case where we use this
is when `K` is the residue field of a nonstandard valuation on a function
field, corresponding to a type II point on the corresponding Berkovich curve.
Then `F=k(x)` is a rational function field over a finite field `k`. Note that
we will realize `k` as an absolute finite field.
"""
from mclf.curves.smooth_projective_curves import make_finite_field
from sage.categories.finite_fields import FiniteFields
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.categories.function_fields import FunctionFields

if hasattr(k, "modulus") or hasattr(k, "polynomial"):
# it seems that k is an extension of a rational function field
k0 = k.base_field()
if hasattr(k0, "constant_base_field"):
l = k0.constant_base_field()
else:
l = k0.base_ring()
if l.is_finite() and not l in FiniteFields:
l1, phi0 = make_finite_field(l)
# now l1 is an isomorphic field and phi0:l-->l1 an isomorphism
else:
l1 = l
phi0 = l.hom(l.gen(), l)
# this is the identity on l
f0 = FunctionField(l1, k0.variable_name())
try:
phi = k0.hom(f0.gen(), phi0)
# the typical reason why this fails is that
# k0 is the fraction field of a polynomial ring
except:
k1 = FunctionField(l, k0.variable_name())
phi1 = k0.base().hom(k1.gen(), k1)
# phi1:k0 --> k1
phi2 = k1.hom(f0.gen(), phi0)
# phi2:k1 --> f0
# phi = phi1.post_compose(phi2)
phi = lambda f: phi2(phi1(f.numerator()))/phi2(phi1(f.denominator()))
# phi: k0 --> f0
if hasattr(k, "modulus"):
G = k.modulus()

if hasattr(K, "modulus") or hasattr(K, "polynomial"):
# we hope that K is a simple finite extension of a field which is
# isomorphic to a rational function field
K_base = K.base_field()
F_base, phi_base = make_function_field(K_base)
if hasattr(K, "modulus"):
G = K.modulus()
else:
G = k.polynomial()
# assert G.base_ring() == phi.domain(), "G in %s, phi on %s"%(G.base_ring(), phi.domain())
R = PolynomialRing(f0, G.parent().variable_name())
G = R([phi(c) for c in G.list()])
# G *should* be irreducible, but unfortunately this is sometimes
# not true, due to a bug in Sage's factoring
assert G.is_irreducible(), "G must be irreducible! This problem is probably caused by a bug in Sage's factoring."
return f0.extension(G, 'y')
G = K.polynomial()
R = G.parent()
R_new = PolynomialRing(F_base, R.variable_name())
G_new = R_new([phi_base(c) for c in G.list()])
assert G_new.is_irreducible(), "G must be irreducible!"
# F = F_base.extension(G_new, R.variable_name())
F = F_base.extension(G_new, 'y')
# phi0 = R.hom(F.gen(), F)
# to construct phi:K=K_0[x]/(G) --> F=F_0[y]/(G),
# we first 'map' from K to K_0[x]
phi = K.hom(R.gen(), R, check=False)
# then from K_0[x] to F_0[y]
psi = R.hom(phi_base, R_new)
# then from F_0[y] to F = F_0[y]/(G)
phi = phi.post_compose(psi.post_compose(R_new.hom(F.gen(),F)))
return F, phi
else:
# it seems that k is simply a rational function field
if hasattr(k, "constant_base_field"):
l = k.constant_base_field()
else:
l = k.base_ring()
if l.is_finite() and not l in FiniteFields:
l1, _ = make_finite_field(l)
# now l1 is an isomorphic field
# we hope that K is isomorphic to a rational function field over a
# finite field
if K in FunctionFields():
# K is already a function field
k = K.constant_base_field()
k_new, phi_base = make_finite_field(k)
F = FunctionField(k_new, K.variable_name())
phi = K.hom(F.gen(), phi_base)
return F, phi
elif hasattr(K, "function_field"):
F1 = K.function_field()
phi1 = F1.coerce_map_from(K)
F, phi2 = make_function_field(F1)
phi = phi1.post_compose(phi2)
return F, phi
else:
l1 = l
return FunctionField(l1, k.base().variable_name())
raise NotImplementedError

0 comments on commit 238013c

Please sign in to comment.