Exemplo n.º 1
0
    def lower_components(self, u=Infinity):
        r"""
        Return the lower components relative to a given extension of the base field.

        INPUT:

        - ``u`` -- an integer, or ``Infinity`` (default: ``Infinity``)

        OUTPUT: the list of lower components of the model of the reduction tree
        lying over this base component. If `u=\infty` then these components
        are computed over the splitting field of the base component. Otherwise,
        `u` is assumed to be a break in the ramification filtration of the
        splitting field, and then we use the corresponding subfield.

        The entries of the list correspond to the irreducible components of the
        special fiber of the `v_L`-model `\mathcal{X}` (the normalization of
        `\mathcal{X}_0`) lying over the given inertial component.

        """
        if u in self._lower_components.keys():
            return self._lower_components[u]
            # we have already computed this before!

        L = self.splitting_field()
        if u == Infinity:
            vL = L.valuation()
        else:
            L = L.ramification_subfield(u)
            vL = L.valuation()

        FX = self.berkovich_line().function_field()
        L = vL.domain()      # actually, this is the number field underlying L
        FXL = FunctionField(L, FX.variable_name())
        XL = BerkovichLine(FXL, vL)
        f, s = self.type_II_point().discoid()
        f = FXL(f)

        v0 = self.valuation()
        F0 = self.function_field()
        x0 = FXL(v0.lift(v0.residue_field().gen()))
        k0 = F0.constant_base_field()
        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())
            # we need to find the correct inclusion of F0 into F1
            if k0.is_prime_field():
                phi = F0.hom(F1(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)
            lower_components.append(LowerComponent(self, vL, v, phi))
        self._lower_components[u] = lower_components
        return lower_components
Exemplo n.º 2
0
    def __init__(self, Y, vK):

        K = vK.domain()
        assert Y.constant_base_field(
        ) == K, "K must be the constant base field of Y"
        self._original_model_of_curve = Y
        self._base_valuation = vK

        # we compute the branch locus and, if it is not contained in the
        # standard unit disk, we change the model of Y
        # actually, this should be done with a call Y.branch_locus()
        FY = Y.function_field()
        FX = Y.rational_function_field()
        F = FY.polynomial()
        assert F.base_ring() == FX
        X = BerkovichLine(FX, vK)
        Delta = F.discriminant()

        self._curve = Y
        self._berkovich_line = X

        T = BerkovichTree(X)
        T = T.adapt_to_function(Delta)
        T = T.permanent_completion()
        reduction_tree = ReductionTree(Y, vK, T)

        self._reduction_tree = reduction_tree
Exemplo n.º 3
0
    def __init__(self, Y, vK):

        p = vK.residue_field().characteristic()
        assert p == Y.covering_degree()
        assert isinstance(Y, SuperellipticCurve)
        f = Y.polynomial()
        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"
        self._p = p
        self._base_valuation = vK
        v0 = GaussValuation(R, vK)
        phi, psi, f1 = v0.monic_integral_model(f)
        # now f1 = phi(f).monic()
        if f1 != f.monic():
            print(
                "We make the coordinate change (x --> %s) in order to work with an integral polynomial f"
                % phi(R.gen()))
            self._f = f1
            a = phi(f).leading_coefficient()
            pi = vK.uniformizer()
            m = (vK(a) / p).floor()
            a = pi**(-p * m) * a
            self._a = a
            FX = FunctionField(vK.domain(), R.variable_name())
            S = PolynomialRing(FX, 'T')
            T = S.gen()
            FY = FX.extension(T**p - FX(a * f1), 'y')
            self._FX = FX
            self._FY = FY
            Y = SmoothProjectiveCurve(FY)
            self._curve = Y
        else:
            self._f = f.monic()
            self._a = vK.domain().one()
            self._FY = Y.function_field()
            self._FX = Y.rational_function_field()
            self._curve = Y
        X = BerkovichLine(self._FX, vK)
        self._X = X
 def __init__(self, v_K, var_name="x"):
     from sage.rings.function_field.constructor import FunctionField
     from mclf.berkovich.berkovich_line import BerkovichLine
     from mclf.berkovich.berkovich_trees import BerkovichTree
     self._base_valuation = v_K
     K = v_K.domain()
     self._base_field = K
     F = FunctionField(K, var_name)
     self._function_field = F
     X_K = BerkovichLine(F, v_K)
     T = BerkovichTree(X_K)
     self._berkovich_line = X_K
     self._tree = T
     self._vertical_components = []
     self._horizontal_components = []
     # the flag '_changed' indicated whether the model has been changed after
     # the last computation of the intersection numbers
     self._changed = False
     self._is_rnc = False
     self._is_minimal_rnc = False
Exemplo n.º 5
0
    def lower_components(self, u=Infinity):
        r"""
        Return the lower components relative to a given extension of the base field.

        INPUT:

        - ``u`` -- an integer, or ``Infinity`` (default: ``Infinity``)

        OUTPUT: the list of lower components of the model of the reduction tree
        lying over this base component. If `u=\infty` then these components
        are computed over the splitting field of the base component. Otherwise,
        `u` is assumed to be a break in the ramification filtration of the
        splitting field, and then we use the corresponding subfield.

        The entries of the list correspond to the irreducible components of the
        special fiber of the `v_L`-model `\mathcal{X}` (the normalization of
        `\mathcal{X}_0`) lying over the given inertial component. By definition,
        the constant base field of these components is the residue field of
        `v_L` (and it may differ from its field of constants).

        """
        if u in self._lower_components.keys():
            return self._lower_components[u]
            # we have already computed this before!

        L = self.splitting_field()
        if u == Infinity:
            vL = L.valuation()
        else:
            L = L.ramification_subfield(u)
            vL = L.valuation()

        # we construct the base change of the underlying Berkovich line
        # to L:
        FX = self.berkovich_line().function_field()
        L = vL.domain()      # actually, this is the number field underlying L
        FXL = FunctionField(L, FX.variable_name())
        # test that FX is a subring of FXL
        assert FX.is_subring(FXL)
        # hence there is a natural coercion morphism
        XL = BerkovichLine(FXL, vL)
        # the representation of xi as a discoid on X, which is defined
        # by an inequality v(f) >= s:
        f, s = self.type_II_point().discoid()
        # the lower components correspon to the connected components of
        # the base change to L of the discoid defining the inertial component:
        f = FXL(f)
        lower_valuations = [xi.valuation() for xi in XL.points_from_inequality(f, s)]

        # some preparation:
        v0 = self.valuation()
        F0 = self.function_field()
        x0 = FXL(v0.lift(v0.residue_field().gen()))
        # x0 is a lift to FXL of the canonical coordinate on the
        # inertial component; we need it to find the natural map from the
        # lower components to the inertial component.
        k0 = F0.constant_base_field()
        theta0 = FXL(v0.lift(k0.gen()))

        # now we construct the lower components:
        lower_components = []
        for v in lower_valuations:
            F1, to_F1, _ = make_function_field(v.residue_field())
            # we need to find the correct inclusion phi of F0 into F1
            if k0.is_prime_field():
                # we don't have to worry about the right embedding of the
                # constant base field
                phi = F0.hom(to_F1(v.reduce(x0)))
            else:
                k1 = F1.constant_base_field()
                # we have to be careful about the correct embedding of k0 into k1
                phi_base = k0.hom([k1(to_F1(v.reduce(theta0)))])
                # now phi is determined by phi_base and the image of the
                # natural coordinate of F0
                phi = F0.hom(to_F1(v.reduce(x0)), phi_base)
            lower_components.append(LowerComponent(self, vL, v, phi))
        self._lower_components[u] = lower_components
        return lower_components