Exemplo n.º 1
0
    def __init__(self, f, n, name='y'):

        R = f.parent()
        assert R.variable_name() != name, "variable names must be distinct"
        k = R.base_ring()
        assert k.characteristic() == 0 or ZZ(n).gcd(k.characteristic(
        )) == 1, "the characteristic of the base field must be prime to n"
        ff = f.factor()
        assert gcd(
            [m for g, m in ff] +
            [n]) == 1, "the equation y^n=f(x) must be absolutely irreducible"
        self._n = n
        self._f = f
        self._ff = ff
        self._name = name
        FX = FunctionField(k, R.variable_name())
        S = PolynomialRing(FX, 'T')
        T = S.gen()
        FY = FX.extension(T**n - FX(f), name)
        self._function_field = FY
        self._constant_base_field = k
        self._extra_extension_degree = ZZ(1)
        self._covering_degree = n
        self._coordinate_functions = self.coordinate_functions()
        self._field_of_constants_degree = ZZ(1)
        self._is_separable = True
Exemplo n.º 2
0
def make_function_field(k):
    r"""
    Return the function field corresponding to this field.

    INPUT:

    - ``k`` -- the residue field of a discrete valuation on a function field.

    OUTPUT:

    the field `k` as a function field; this is rather experimental..

    """
    from sage.rings.function_field.function_field import is_FunctionField
    if is_FunctionField(k):
        return k
    if hasattr(k, "base_field"):
        # it seems that k is an extension of a rational function field
        k0 = k.base_field()
        f0 = FunctionField(k0.base_ring(), k0.base().variable_name())
        G = k.modulus().change_ring(f0)
        # 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')
    else:
        # it seems that k is simply a rational function field
        return FunctionField(k.base_ring(), k.variable_name())
Exemplo n.º 3
0
 def Deltoid(cls, par_type='rational'):
     r"""
     Return a deltoid motion.
     """
     if par_type == 'rational':
         FF = FunctionField(QQ, 't')
         t = FF.gen()
         C = {
             _sage_const_0 : vector((_sage_const_0 , _sage_const_0 )),
             _sage_const_1 : vector((_sage_const_1 , _sage_const_0 )),
             _sage_const_2 : vector((_sage_const_4 *(t**_sage_const_2  - _sage_const_2
                                                     )/(t**_sage_const_2  + _sage_const_4 ), _sage_const_12 *t/(t**_sage_const_2  + _sage_const_4 ))),
             _sage_const_3 : vector(((t**_sage_const_4  - _sage_const_13 *t**_sage_const_2  + _sage_const_4
                                      )/(t**_sage_const_4  + _sage_const_5 *t**_sage_const_2  + _sage_const_4 ),
                                      _sage_const_6 *(t**_sage_const_3  - _sage_const_2 *t)/(t**_sage_const_4  + _sage_const_5 *t**_sage_const_2  + _sage_const_4 )))
             }
         G = FlexRiGraph([[0, 1], [1, 2], [2, 3], [0, 3]])
         return GraphMotion.ParametricMotion(G, C, 'rational', sampling_type='tan', check=False)
     elif par_type == 'symbolic':
         t = var('t')
         C = {
             _sage_const_0 : vector((_sage_const_0 , _sage_const_0 )),
             _sage_const_1 : vector((_sage_const_1 , _sage_const_0 )),
             _sage_const_2 : vector((_sage_const_4 *(t**_sage_const_2  - _sage_const_2
                                                     )/(t**_sage_const_2  + _sage_const_4 ), _sage_const_12 *t/(t**_sage_const_2  + _sage_const_4 ))),
             _sage_const_3 : vector(((t**_sage_const_4  - _sage_const_13 *t**_sage_const_2  + _sage_const_4
                                      )/(t**_sage_const_4  + _sage_const_5 *t**_sage_const_2  + _sage_const_4 ),
                                      _sage_const_6 *(t**_sage_const_3  - _sage_const_2 *t)/(t**_sage_const_4  + _sage_const_5 *t**_sage_const_2  + _sage_const_4 )))
             }
         G = FlexRiGraph([[0, 1], [1, 2], [2, 3], [0, 3]])
         return ParametricGraphMotion.ParametricMotion(G, C, 'symbolic', sampling_type='tan', check=False)
     else:
         raise exceptions.ValueError('Deltoid with par_type ' + str(par_type) + ' is not supported.')
Exemplo n.º 4
0
 def _test(self):
     from sage.all import FunctionField, QQ, PolynomialRing
     K = FunctionField(QQ, 'x')
     x = K.gen()
     R = PolynomialRing(K, 'y')
     y = R.gen()
     L = K.extension(y**3 - 1 / x**3 * y + 2 / x**4, 'y')
     v = K.valuation(x)
     v.extensions(L)
Exemplo n.º 5
0
 def time_is_semistable(self):
     K = FunctionField(QQ, 'x')
     x = K.gen()
     R = PolynomialRing(K, 'T')
     T = R.gen()
     f = 64 * x**3 * T - 64 * x**3 + 36 * x**2 * T**2 + 208 * x**2 * T + 192 * x**2 + 9 * x * T**3 + 72 * x * T**2 + 240 * x * T + 64 * x + T**4 + 9 * T**3 + 52 * T**2 + 48 * T
     L = K.extension(f, 'y')
     Y = SmoothProjectiveCurve(L)
     v = QQ.valuation(13)
     M = SemistableModel(Y, v)
     return M.is_semistable()
Exemplo n.º 6
0
 def _test(self):
     from sage.all import GF, FunctionField, PolynomialRing
     k = GF(4)
     a = k.gen()
     R = PolynomialRing(k, 'b')
     b = R.gen()
     l = k.extension(b**2 + b + a, 'b')
     K = FunctionField(l, 'x')
     x = K.gen()
     R = PolynomialRing(K, 't')
     t = R.gen()
     F = t * x
     F.factor(proof=False)
Exemplo n.º 7
0
 def _test(self):
     from sage.all import QQ, PolynomialRing, GaussValuation, FunctionField
     R = PolynomialRing(QQ, 'x')
     x = R.gen()
     v = GaussValuation(R, QQ.valuation(2))
     K = FunctionField(QQ, 'x')
     x = K.gen()
     v = K.valuation(v)
     K.valuation((v, K.hom(x/2), K.hom(2*x)))
Exemplo n.º 8
0
 def _test(self):
     from sage.all import PolynomialRing, QQ, NumberField, GaussValuation, FunctionField
     R = PolynomialRing(QQ, 'x')
     x = R.gen()
     K = NumberField(x**6 + 126 * x**3 + 126, 'pi')
     v = K.valuation(2)
     R = PolynomialRing(K, 'x')
     x = R.gen()
     v = GaussValuation(R, v).augmentation(x, QQ(2) / 3)
     F = FunctionField(K, 'x')
     x = F.gen()
     v = F.valuation(v)
     S = PolynomialRing(F, 'y')
     y = S.gen()
     w0 = GaussValuation(S, v)
     G = y**2 - x**3 - 3
     w1 = w0.mac_lane_step(G)[0]
     w1.mac_lane_step(G)
Exemplo n.º 9
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.º 10
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
Exemplo n.º 11
0
    def __init__(self, f, name='y'):

        R = f.parent()
        assert R.variable_name() != name, "variable names must be distinct"
        k = R.base_ring()
        assert k.characteristic() != 3,\
             "the characteristic of the base field must not be 3"
        assert f.gcd(f.derivative()).is_one(), "f must be separable"
        self._n = 3
        self._f = f
        self._ff = f.factor()
        self._name = name
        FX = FunctionField(k, R.variable_name())
        S = PolynomialRing(FX, 'T')
        T = S.gen()
        FY = FX.extension(T**3 - FX(f), name)
        self._function_field = FY
        self._constant_base_field = k
        self._extra_extension_degree = ZZ(1)
        self._covering_degree = 3
        self._coordinate_functions = self.coordinate_functions()
        self._field_of_constants_degree = ZZ(1)
        self._is_separable = True
Exemplo n.º 12
0
def base_change_of_function_field(F, L):
    r"""
    Return the base change of a function field with respect to an extension
    of the base field.

    INPUT:

    - ``F`` -- a function field over a field `K`
    - ``L`` -- a finite field extension of `K`

    OUTPUT:

    the function field `F_L:= F\otimes_K L`.

    It is not checked whether the result is really a function field.

    """
    F0 = F.base()
    F0L = FunctionField(L, F0.variable_name())
    if F0 == F:
        # F is a rational function field
        return F0L
    else:
        return F0L.extension(F.polynomial().change_ring(F0L), F.variable_name())
Exemplo n.º 13
0
def make_function_field(K):
    r"""
    Return the function field isomorphic to this field, an isomorphism,
    and its inverse.

    INPUT:

    - ``K`` -- a field

    OUTPUT: A triple `(F,\phi,\psi)`, where `F` is a rational function field,
    `\phi:K\to F` is a field isomorphism and `\psi` the inverse of `\phi`.

    It is assumed that `K` is either the fraction field of a polynomial ring
    over a finite field `k`, or a finite simple extension of such a field.

    In the first case, `F=k_1(x)` is a rational function field over a finite
    field `k_1`, where `k_1` as an *absolute* finite field isomorphic to `k`.
    In the second case, `F` is a finite simple extension of a rational function
    field as in the first case.

    """
    from mclf.curves.smooth_projective_curves import make_finite_field
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    from sage.categories.function_fields import FunctionFields

    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, psi_base = make_function_field(K_base)
        if hasattr(K, "modulus"):
            G = K.modulus()
        else:
            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)))
        psi = F.hom(K.gen(), psi_base)
        return F, phi, psi
    else:
        # 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, psi_base = make_finite_field(k)
            F = FunctionField(k_new, K.variable_name())
            phi = K.hom(F.gen(), phi_base)
            psi = F.hom(K.gen(), psi_base)
            return F, phi, psi
        elif hasattr(K, "function_field"):
            F1 = K.function_field()
            phi1 = F1.coerce_map_from(K)
            psi1 = F1.hom(K.gen())
            F, phi2, psi2 = make_function_field(F1)
            phi = phi1.post_compose(phi2)
            psi = psi2.post_compose(psi1)
            return F, phi, psi
        else:
            raise NotImplementedError
Exemplo n.º 14
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
Exemplo n.º 15
0
def make_function_field(K):
    r"""
    Return the function field isomorphic to this field, an isomorphism,
    and its inverse.

    INPUT:

    - ``K`` -- a field

    OUTPUT: A triple `(F,\phi,\psi)`, where `F` is a rational function field,
    `\phi:K\to F` is a field isomorphism and `\psi` the inverse of `\phi`.

    It is assumed that `K` is either the fraction field of a polynomial ring
    over a finite field `k`, or a finite simple extension of such a field.

    In the first case, `F=k_1(x)` is a rational function field over a finite
    field `k_1`, where `k_1` as an *absolute* finite field isomorphic to `k`.
    In the second case, `F` is a finite simple extension of a rational function
    field as in the first case.

    .. NOTE::

        this command seems to be partly superflous by now, because the residue
        of a valuation is already of type "function field" whenever this makes sense.
        However, even if `K` is a function field over a finite field, it is not
        guaranteed that the constant base field is a 'true' finite field, and then
        it is important to change that.

    """
    from mclf.curves.smooth_projective_curves import make_finite_field
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    from sage.categories.function_fields import FunctionFields
    from sage.rings.function_field.function_field import is_FunctionField

    if is_FunctionField(K):
        k = K.constant_base_field()
        if k.is_finite() and hasattr(k, "base_field"):
            # k seems to be finite, but not a true finite field
            # we construct a true finite field k1 isomorphic to k
            # and F isomorphic to K with constant base field k1
            k1, phi, psi = make_finite_field(k)
            if hasattr(K, "polynomial"):
                # K is an extension of a rational function field
                K0 = K.rational_function_field()
                F0, phi0, psi0 = make_function_field(K0)
                f = K.polynomial().change_ring(phi0)
                F = F0.extension(f)
                return F, K.hom(F.gen(), phi0), F.hom(K.gen(), psi0)
            else:
                F = FunctionField(k1, K.variable_name())
                return F, K.hom(F.gen(), phi), F.hom(K.gen(), psi)
        else:
            return K, K.Hom(K).identity(), K.Hom(K).identity()

    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, psi_base = make_function_field(K_base)
        if hasattr(K, "modulus"):
            G = K.modulus()
        else:
            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)))
        psi = F.hom(K.gen(), psi_base)
        return F, phi, psi
    else:
        # 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, psi_base = make_finite_field(k)
            F = FunctionField(k_new, K.variable_name())
            phi = K.hom(F.gen(), phi_base)
            psi = F.hom(K.gen(), psi_base)
            return F, phi, psi
        elif hasattr(K, "function_field"):
            F1 = K.function_field()
            phi1 = F1.coerce_map_from(K)
            psi1 = F1.hom(K.gen())
            F, phi2, psi2 = make_function_field(F1)
            phi = phi1.post_compose(phi2)
            psi = psi2.post_compose(psi1)
            return F, phi, psi
        else:
            raise NotImplementedError
Exemplo n.º 16
0
def _dimension_Gamma_2(wt_range, j, group='Gamma(2)'):
    """
    Return the dict
    {(k-> partition ->  [ d(k), e(k), c(k)] for k in wt_range]},
    where d(k), e(k), c(k) are the dimensions
    of the $p$-canonical part of $M_{k,j}(\Gamma(2))$ and its subspaces of
    Non-cusp forms and Cusp forms.
    """

    partitions = [
        u'6', u'51', u'42', u'411', u'33', u'321', u'3111', u'222', u'2211',
        u'21111', u'111111'
    ]
    latex_names = {
        'Gamma(2)': '\\Gamma(2)',
        'Gamma0(2)': '\\Gamma_0(2)',
        'Gamma1(2)': '\\Gamma_1(2)',
        'Sp4(Z)': '\\mathrm{Sp}(4,\mathbb{Z})'
    }

    if is_odd(j):
        dct = dict(
            (k, dict((h, [0, 0, 0]) for h in partitions)) for k in wt_range)
        for k in dct:
            dct[k]['All'] = [0, 0, 0]
        partitions.insert(0, 'All')
        return partitions, dct

    if 'Sp4(Z)' == group and 2 == j and wt_range[0] < 4:
        wt_range1 = [k for k in wt_range if k < 4]
        wt_range2 = [k for k in wt_range if k >= 4]
        if wt_range2 != []:
            headers, dct = _dimension_Gamma_2(wt_range2, j, group)
        else:
            headers, dct = ['Total', 'Non cusp', 'Cusp'], {}
        for k in wt_range1:
            dct[k] = dict([(h, 0) for h in headers])
        return headers, dct

    if j >= 2 and wt_range[0] < 4:
        raise NotImplementedError(
            "Dimensions of \(M_{k,j}(%s)\) for <span style='color:black'>\(k<4\)</span> and <span style='color:black'>\(j\ge 2\)</span> not implemented"
            % latex_names.get(group, group))

    query = {'sym_power': str(j), 'group': 'Gamma(2)', 'space': 'total'}
    db_total = smf_db_dimensions().find_one(query)
    if not db_total:
        raise NotImplementedError(
            'Dimensions of \(M_{k,j}\) for \(j=%d\) not implemented' % j)
    query['space'] = 'cusp'
    db_cusp = smf_db_dimensions().find_one(query)
    if not db_cusp:
        raise NotImplementedError(
            'Dimensions of \(M_{k,j}\) for \(j=%d\) not implemented' % j)

    P = PowerSeriesRing(ZZ, default_prec=wt_range[-1] + 1, names=('t'))
    Qt = FunctionField(QQ, names=('t'))
    total = dict()
    cusp = dict()
    for p in partitions:
        f = Qt(str(db_total[p]))
        total[p] = P(f.numerator()) / P(f.denominator())
        f = Qt(str(db_cusp[p]))
        cusp[p] = P(f.numerator()) / P(f.denominator())

    if 'Gamma(2)' == group:
        dct = dict(
            (k,
             dict((p, [total[p][k], total[p][k] - cusp[p][k], cusp[p][k]])
                  for p in partitions)) for k in wt_range)
        for k in dct:
            dct[k]['All'] = [
                sum(dct[k][p][i] for p in dct[k]) for i in range(3)
            ]

        partitions.insert(0, 'All')
        headers = partitions

    elif 'Gamma1(2)' == group:
        ps = {
            '3': ['6', '42', '222'],
            '21': ['51', '42', '321'],
            '111': ['411', '33']
        }

        dct = dict((k,
                    dict((p, [
                        sum(total[q][k] for q in ps[p]),
                        sum(total[q][k] - cusp[q][k] for q in ps[p]),
                        sum(cusp[q][k] for q in ps[p]),
                    ]) for p in ps)) for k in wt_range)
        for k in dct:
            dct[k]['All'] = [
                sum(dct[k][p][i] for p in dct[k]) for i in range(3)
            ]

        headers = ps.keys()
        headers.sort(reverse=True)
        headers.insert(0, 'All')

    elif 'Gamma0(2)' == group:
        headers = ['Total', 'Non cusp', 'Cusp']
        ps = ['6', '42', '222']
        dct = dict((k, {
            'Total': sum(total[p][k] for p in ps),
            'Non cusp': sum(total[p][k] - cusp[p][k] for p in ps),
            'Cusp': sum(cusp[p][k] for p in ps)
        }) for k in wt_range)

    elif 'Sp4(Z)' == group:
        headers = ['Total', 'Non cusp', 'Cusp']
        p = '6'
        dct = dict((k, {
            'Total': total[p][k],
            'Non cusp': total[p][k] - cusp[p][k],
            'Cusp': cusp[p][k]
        }) for k in wt_range)
    else:
        raise NotImplementedError('Dimension for %s not implemented' % group)

    return headers, dct
Exemplo n.º 17
0
# Utility functions:
#
# - pp as generator of function field over QQ
# - substitution in ratonal function, star involution
# - lists of monic and non-monic polys and forms over any base F
# - roots of a polynomial or binary form
# - affine linear combinations

from sage.all import (FunctionField, QQ, PolynomialRing, ProjectiveSpace,
                      VectorSpace, infinity)
from collections import Counter

Qp = FunctionField(QQ, 'p')
pp = Qp.gen()


def subs(f, p):
    """Substitute p for the variable of the rational function f.
    """
    if f in QQ:
        return f
    n = f.numerator()(p)
    d = f.denominator()(p)
    if d:
        return n / d
    else:
        return infinity


def star(r):
    return r if r in QQ else subs(r, 1 / pp)