Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 43 additions & 5 deletions mclf/semistable_reduction/superp_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,21 @@
sage: Y2.is_semistable()
True

By default, an error is raised if the polynomial `f` defining the curve has
degree divisible by `p`. You can override this as follows:

TO DO:
sage: Y = SuperellipticCurve(x^4 + x + 1, 2)
sage: Y2 = SuperpModel(Y, v_2, check=False)
sage: Y2
semistable model of superelliptic curve Y: y^2 = x^4 + x + 1 over Rational Field, with respect to 2-adic valuation

- more doctests
But note that the computation of the etale locus and hence also of the
semistable reduction may now give an incorrect result.

sage: Y2.etale_locus()
The empty set
sage: Y2.is_semistable()
False

"""

Expand Down Expand Up @@ -153,10 +163,14 @@ class SuperpModel(SemistableModel):

- ``Y`` -- a superelliptic curve over a field `K`
- ``vK`` -- a discrete valuation on `K`
- ``check`` -- a boolean (default: ``True``)

The field `K` must be of characteristic `0` and the residue characteristic
of ``vK`` must be a prime `p` which is equal to the covering degree of `Y`.

If ``check`` is ``True`` (the default) then violation of the latter condition
raises an error.

OUTPUT: the object representing a semistable model of `Y`.


Expand All @@ -178,7 +192,7 @@ class SuperpModel(SemistableModel):

"""

def __init__(self, Y, vK):
def __init__(self, Y, vK, check=True):

p = vK.residue_field().characteristic()
assert p == Y.covering_degree()
Expand All @@ -187,7 +201,7 @@ def __init__(self, Y, vK):
R = f.parent()
assert R.base_ring() is vK.domain(), "the domain of vK must be the base field of f"
assert p == vK.residue_field().characteristic(), "the exponent p must be the residue characteristic of vK"
assert not p.divides(f.degree()), "the degree of f must be prime to p"
assert not check or not p.divides(f.degree()), "the degree of f must be prime to p"
self._p = p
self._base_valuation = vK
v0 = GaussValuation(R, vK)
Expand Down Expand Up @@ -270,8 +284,14 @@ def etale_locus(self):
and of degree prime to `p`. The motivation for this restriction, and its
result is that the etale locus is contained in the closed unit disk.

UPDATE: in the current version we test the possibility to remove the
requirement that the degree of `f` be prime to `p`. We do this with a
'hack', see below. For a clean solution we would need a version of
``valuative_function`` where the domain is allowed to be an *open*
discoid.

"""
from mclf.berkovich.piecewise_affine_functions import Discoid, valuative_function
from mclf.berkovich.piecewise_affine_functions import Domain, Discoid, open_discoid, valuative_function
from mclf.berkovich.affinoid_domain import UnionOfDomains

if hasattr(self, "_etale_locus"):
Expand Down Expand Up @@ -306,7 +326,25 @@ def etale_locus(self):
valuative_function(
D, ([(c[pl], k*(p - 1)), (c[k], -pl*(p - 1))], -p*(k - pl)*v_K(pi)))
for k in range(m + 1, n + 1) if k != pl]
self._delta = delta
U_list = [delta[i].affinoid_domain() for i in range(len(delta))]
if p.divides(n):
f1 = f.reverse()
x = X.function_field().gen()
H1, G1 = p_approximation_generic(f1, p)
c1 = [G1[k](1/x) for k in range(n+1)]
# print(f"c1 = {c1}")
xi = X.point_from_discoid(1/x, 1/10)
D1 = Discoid(xi, xi1=X.infty()) # this is a hack!
delta1 = [valuative_function(D1, ([(c1[pl], p - 1)], -p*v_K(pi)))]
# delta1 = []
delta1 += [
valuative_function(
D1, ([(c1[pl], k*(p - 1)), (c1[k], -pl*(p - 1))], -p*(k - pl)*v_K(pi)))
for k in range(m + 1, n + 1) if k != pl]
self._delta1 = delta1
U_list += [delta1[i].affinoid_domain() for i in range(len(delta1))]

X_et = UnionOfDomains(U_list)
self._etale_locus = X_et
return X_et
Expand Down