Skip to content

Commit

Permalink
thorough rewriting of reduction_trees
Browse files Browse the repository at this point in the history
In this new version of reduction_trees, 
the maps between different components
(inertial, lower and upper) are constructed
in a systematic way and such that they are 
compatible with the maps of generic fibers.

All components are created as curves over an
*absolute* finite fields, thus fixing issue MCLF#103
and adressing in aprt issue MCLF#66. This is done
by using the helper functions and  
`make_finite_fields` which turns a finite field into an absolute fielte, 
and `make_function_fields`
which turns a function field into a 'true' function
field over an absolute finite field. 

There should be more doctests and internal 
consistency test.
  • Loading branch information
swewers committed Aug 22, 2018
1 parent 238013c commit 8844501
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 100 deletions.
21 changes: 19 additions & 2 deletions mclf/curves/morphisms_of_smooth_projective_curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ def __init__(self, X, Y, phi=None):
self._Y = Y
if phi==None:
assert FY.is_subring(FX), "the function field of Y has to be a subfield of the function field of X"
self._phi = None
self._phi = FX.coerce_map_from(FY)
else:
assert phi.domain() is FY, "the domain of phi must be %s"%FY
assert phi.codomain() is FX, "the codomain of phi must be %s"%FX
self._phi = phi


Expand All @@ -113,6 +115,7 @@ def __repr__(self):
else:
return "morphism from %s \nto %s,\ndetermined by %s"%(self.domain(), self.codomain(), self._phi)


def domain(self):
r""" Return the domain of this morphism.
"""
Expand All @@ -125,6 +128,20 @@ def codomain(self):
return self._Y


def pulback_map(self):
r""" Return the induced inclusion of function fields.
"""
return self._phi


def pullback(self, f):
r""" Return the pullback of a function under this morphism.
"""
return self.pullback_map(f)


def fiber(self, P):
r"""
Return the fiber of this map over the point `P` (without multiplicities).
Expand All @@ -142,7 +159,7 @@ def fiber(self, P):
FX = X.function_field()
FY = self.codomain().function_field()
v = P.valuation()
if self._phi==None:
if FY.is_subring(FX):
# FY is a subfield of FX
return [PointOnSmoothProjectiveCurve(self.domain(), w) for w in v.extensions(FX)]
else:
Expand Down
40 changes: 24 additions & 16 deletions mclf/curves/smooth_projective_curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -1239,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 Expand Up @@ -1287,7 +1287,7 @@ def extension_of_finite_field(K, n):
assert K.is_field()
assert K.is_finite()
q = K.order()
R = PolynomialRing(K, 'z')
R = PolynomialRing(K, 'z'+str(n))
z = R.gen()
# we look for a small number e dividing q^n-1 but not q-1
e = min([d for d in (q**n-1).divisors() if not d.divides(q-1)])
Expand All @@ -1304,8 +1304,8 @@ def make_finite_field(k):
- ``k`` -- a finite field
OUTPUT: a pair `(k_1,\phi)` where `k_1` is a 'true' finite field
and `\phi` is an isomorphism from `k` to `k_1`.
OUTPUT: a triple `(k_1,\phi,\psi)` where `k_1` is a 'true' finite field,
`\phi` is an isomorphism from `k` to `k_1` and `\psi` is the inverse of `\phi`.
This function is useful when `k` is constructed as a tower of extensions
with a finite field as a base field.
Expand All @@ -1315,22 +1315,30 @@ def make_finite_field(k):

assert k.is_field()
assert k.is_finite()
if k in FiniteFields:
return k, k.hom(k.gen(), k)
if not hasattr(k, "base_field"):
return k, k.hom(k), k.hom(k)
else:
k0 = k.base_field()
G = k.modulus()
assert G.parent().base_ring() is k0
k0_new, phi0 = make_finite_field(k0)
k0_new, phi0, _ = make_finite_field(k0)
G_new = G.map_coefficients(phi0, k0_new)
k_new = k0_new.extension(G_new.degree())
alpha = G_new.roots(k_new)[0][0]
Pk0 = k.cover_ring()
Pk0_new = k0_new[Pk0.variable_name()]
psi1 = Pk0.hom(phi0, Pk0_new)
psi2 = Pk0_new.hom(alpha, k_new)
psi = psi1.post_compose(psi2)
# psi: Pk0 --> k_new
phi = k.hom(Pk0.gen(), Pk0, check=False)
phi = phi.post_compose(psi)
return k_new, phi
try:
phi = k.hom(alpha, k_new)
except Exception:
Pk0 = k.cover_ring()
Pk0_new = k0_new[Pk0.variable_name()]
psi1 = Pk0.hom(phi0, Pk0_new)
psi2 = Pk0_new.hom(alpha, k_new)
psi = psi1.post_compose(psi2)
# psi: Pk0 --> k_new
phi = k.hom(Pk0.gen(), Pk0, check=False)
phi = phi.post_compose(psi)
alpha_new = k_new.gen()
for alpha, e in alpha_new.minpoly().roots(k):
if phi(alpha) == alpha_new:
break
phi_inverse = k_new.hom(alpha, k)
return k_new, phi, phi_inverse
Loading

0 comments on commit 8844501

Please sign in to comment.