def zeta_function(self, var_name='T'):
        r""" Return the Zeta function of the curve.

        For any scheme `X` of finite type over `\mathbb{Z}`, the **arithmetic
        zeta funtion** of `X` is defined as the product

        .. MATH::

             \zeta(X,s) := \prod_x \frac{1}{1-N(x)^{-s}},

        where `x` runs over over all closed points of `X` and `N(x)`
        denotes the cardinality of the residue field of `x`.

        If `X` is a smooth projective curve over a field with
        `q` elements, then `\zeta(X,s) = Z(X,q^{-s})`,
        where `Z(X,T)` is a rational function in `T` of the form

        .. MATH::

               Z(X,T) =  \frac{P(T)}{(1-T)(1-qT)},

        for a polynomial `P` of degree `2g`, with some extra properties
        reflecting the Weil conjectures. See:

        - Hartshorn, *Algebraic Geometry*, Appendix C, Section 1.

        Note that that this makes only sense if the constant base
        field of self is finite, and that `Z(X,T)` depends on the
        choice of the constant base field (unlike the function
        `\zeta(X,s)`!).

        """
        if hasattr(self,"_zeta_function"):
            return self._zeta_function

        K = self._constant_base_field
        q = K.order()
        g = self.genus()
        S = PowerSeriesRing(ZZ, var_name, g+1)
        N = self.count_points(g)
        Z_series = S(1)
        for k in range(1,g+1):
            Z_series *= (1-S.gen()**k)**(-N[k])
        P = (Z_series*(1-S.gen())*(1-q*S.gen())).polynomial()
        c = range(2*g+1)
        for k in range(g+1):
            c[k] = P[k]
        for k in range(g+1,2*g+1):
            c[k] = c[2*g-k]*q**(k-g)
        R = P.parent()
        zeta = R(c)/(1-R.gen())/(1-q*R.gen())
        self._zeta_function = zeta
        return zeta
Exemple #2
0
def get_factor_over_nf(curve, prime_ideal, prime_number, conductor, accuracy):
    """                                                                         
    Returns the inverse of the factor corresponding to the given prime
    ideal in the Euler product expansion of the L-function at
    prime_ideal. Unless the accuracy doesn't need this expansion, and
    then returns 1 in power series ring.
    """
    P = PowerSeriesRing(ZZ, 'T')
    T = P.gen()
    q = prime_ideal.norm()
    inertial_deg = Integer(q).ord(prime_number)
    if inertial_deg > accuracy:
        return P(1)
    if prime_ideal.divides(conductor):
        a = curve.local_data(prime_ideal).bad_reduction_type()
        L = 1 - a * (T**inertial_deg)
    else:
        discriminant = curve.discriminant()
        if prime_ideal.divides(discriminant):
            a = q + 1 - curve.local_minimal_model(prime_ideal).reduction(
                prime_ideal).count_points()
        else:
            a = q + 1 - curve.reduction(prime_ideal).count_points()
        L = 1 - a * (T**inertial_deg) + q * (T**(2 * inertial_deg))
    return L
Exemple #3
0
 def set_from_coefficients(self, coeffs):
     QR = PowerSeriesRing(QQ,name='q',order='neglex')
     q = QR.gen()
     res = 0*q**0
     for n, c in coeffs.iteritems():
         res += c*q**n
     res = res.add_bigoh(len(coeffs.keys())+1)
     self.set_value(res)
Exemple #4
0
 def set_from_coefficients(self, coeffs):
     if not len(coeffs) == 0:
         QR = PowerSeriesRing(coeffs.values()[0].parent(),name='q',order='neglex')
         q = QR.gen()
         res = 0*q**0
         for n, c in coeffs.iteritems():
             res += c*q**n
         res = res.add_bigoh(len(coeffs.keys())+1)
         self.set_value(res)
Exemple #5
0
def euler_p_factor(root_list, PREC):
    ''' computes the coefficients of the pth Euler factor expanded as a geometric series
      ax^n is the Dirichlet series coefficient p^(-ns)
    '''
    PREC = floor(PREC)
    # return satake_list
    R = PowerSeriesRing(CF, 'x')
    x = R.gen()
    ep = ~R.prod([1 - a * x for a in root_list])
    return ep.O(PREC + 1)
Exemple #6
0
def hilbert_series_using_cand_wts(i, parity, prec=None):
    wts = load_cand_wts(i, parity)
    if prec is None:
        prec = max(wts[0])
    ps = PowerSeriesRing(QQ, names='t', default_prec=prec + 1)
    t = ps.gen()
    num = sum(t**a for a in wts[0])
    if len(wts) > 1:
        num -= sum(t**a for a in wts[1])
    dnm = (1 - t**2) * (1 - t**4) * (1 - t**6)
    return num / dnm
Exemple #7
0
def hilbert_series_using_dimension_formula(i, prec=10):
    '''
    This assumes dimension formula is true for weight (2, k) where k > 2
    and the dimesion for (1, k) k > 2 is zero.
    If one believes magma, the assumption for (2, k) can be checked for some cases.
    And the assumption for (1, k) can be checked by the construction.
    '''
    ps = PowerSeriesRing(QQ, names='t', default_prec=prec + 1)
    t = ps.gen()
    return (sum(dimension_cuspforms_sqrt5(a, a + 2 * i) * t**a for a in range(2, prec + 1)) +
            O(t**(prec + 1)))
Exemple #8
0
def hilbert_series_maybe(j, parity=None, prec=30):
    '''
    Returns a hilbert series which is equal to
    sum_{k > 0} M_{k, j}(Gamma_{2}) t^k
    modulo a polynomial of degree < 5.
    '''
    R = PowerSeriesRing(QQ, names="t", default_prec=prec)
    t = R.gen()
    dnm = R(t_dnm())
    nm = hilbert_series_num_maybe(j, parity=parity)
    return (nm + O(t ** prec)) / dnm
Exemple #9
0
def t_delete_terms_of_small_degrees(f):
    '''
    f is a polynomial of t.
    Returns a polynomial g which is congruent to f modulo t_dnm
    so that g/t_dnm does not have terms with degree < 4.
    '''
    R = PowerSeriesRing(QQ, names="t")
    S = PolynomialRing(QQ, names="t")
    t = R.gen()
    dnm = R(t_dnm())
    g = R(f / dnm) + O(t ** 4)
    a = S(sum([t ** i * g[i] for i in range(4)]))
    return f - t_dnm() * a
Exemple #10
0
def _dimension_Gamma0_4(wt):
    """
    Return the dimensions of subspaces of Siegel modular forms on $Gamma0(4)$.

    OUTPUT
        ("Total",)

    REMARK
        Not completely implemented
    """
    R = PowerSeriesRing(ZZ, 'x')
    x = R.gen().O(wt + 1)
    H_all = (1 + x**4) * (1 + x**11) / (1 - x**2)**3 / (1 - x**6)
    return (H_all[wt], )
Exemple #11
0
def _dimension_Gamma0_3(wt):
    """
    Return the dimensions of subspaces of Siegel modular forms on $Gamma0(3)$.

    OUTPUT
        ("Total")

    REMARK
        Only total dimension implemented.
    """
    R = PowerSeriesRing(ZZ, 'x')
    x = R.gen().O(wt + 1)
    H_all = (1 + 2 * x**4 + x**6 + x**15 *
             (1 + 2 * x**2 + x**6)) / (1 - x**2) / (1 - x**4) / (1 - x**6)**2
    return (H_all[wt], )
Exemple #12
0
def get_factor_over_nf(curve, prime_ideal, prime_number, conductor, accuracy):
    """                                                                         
    Returns the inverse of the factor corresponding to the given prime
    ideal in the Euler product expansion of the L-function at
    prime_ideal. Unless the accuracy doesn't need this expansion, and
    then returns 1 in power series ring.
    """
    P = PowerSeriesRing(ZZ, 'T')
    T = P.gen()
    q = prime_ideal.norm()
    inertial_deg = Integer(q).ord(prime_number)
    if inertial_deg > accuracy: 
        return P(1)
    if prime_ideal.divides(conductor):
        a = curve.local_data(prime_ideal).bad_reduction_type()
        L = 1 - a*(T**inertial_deg)
    else:
        discriminant = curve.discriminant()
        if prime_ideal.divides(discriminant):
            a = q + 1 - curve.local_minimal_model(prime_ideal).reduction(prime_ideal).count_points()
        else:
            a = q + 1 - curve.reduction(prime_ideal).count_points()
        L = 1 - a*(T**inertial_deg) + q*(T**(2*inertial_deg))
    return L
Exemple #13
0
def hilbert_series_using_dimension_formula(i, parity, prec=10):
    ps = PowerSeriesRing(QQ, names='t', default_prec=prec + 1)
    t = ps.gen()
    return (sum(
        cuspforms_dimension((a, a + 2 * i)) * t**a
        for a in range(2, prec + 1) if is_even(a + parity)) + O(t**(prec + 1)))
Exemple #14
0
def gen_func_maybe_cusp_num_t_power_srs(parity=None, prec=10):
    R = PolynomialRing(QQ, names="t")
    S = PowerSeriesRing(R, names="s", default_prec=prec)
    s = S.gen()
    num = gen_func_maybe_cusp_num_t(parity=parity)
    return S(num) + O(s ** prec)
Exemple #15
0
def anlist_over_sqrt5(E, bound):
    """
    Compute the Dirichlet L-series coefficients, up to and including
    a_bound.  The i-th element of the return list is a[i].

    INPUT:
        - E -- elliptic curve over Q(sqrt(5)), which must have
          defining polynomial `x^2-x-1`.
        - ``bound`` -- integer

    OUTPUT:
        - list of integers of length bound + 1

    EXAMPLES::

        sage: from psage.ellcurve.lseries.lseries_nf import anlist_over_sqrt5
        sage: K.<a> = NumberField(x^2-x-1); E = EllipticCurve([0,-a,a,0,0])
        sage: v = anlist_over_sqrt5(E, 50); v
        [0, 1, 0, 0, -2, -1, 0, 0, 0, -4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, -4, 0, 0, 0, 11, 0, -6, 0, 0, 0, 0, 8, 0, 0, 0, 0, -1, 0, 0, -6, 4, 0, 0, 0, -6, 0]
        sage: len(v)
        51

    This function isn't super fast, but at least it will work in a few
    seconds up to `10^4`::

        sage: t = cputime()
        sage: v = anlist_over_sqrt5(E, 10^4)
        sage: assert cputime(t) < 5
    """
    import aplist_sqrt5
    from psage.number_fields.sqrt5.prime import primes_of_bounded_norm, Prime

    # Compute all of the prime ideals of the ring of integers up to the given bound
    primes = primes_of_bounded_norm(bound+1)

    # Compute the traces of Frobenius: this is supposed to be the hard part
    v      = aplist_sqrt5.aplist(E, bound+1)

    # Compute information about the primes of bad reduction, in
    # particular the integers i such that primes[i] is a prime of bad
    # reduction.
    bad_primes = set([Prime(a.prime()) for a in E.local_data()])


    # We compute the local factors of the L-series as power series in ZZ[T].
    P = PowerSeriesRing(ZZ, 'T')
    T = P.gen()
    # Table of powers of T, so we don't have to compute T^4 (say) thousands of times.
    Tp = [T**i for i in range(5)]

    # For each prime, we write down the local factor.
    L_P = []
    for i, P in enumerate(primes):
        inertial_deg = 2 if P.is_inert() else 1
        a_p = v[i]
        if P in bad_primes:
            # bad reduction
            f = 1 - a_p*Tp[inertial_deg]
        else:
            # good reduction
            q = P.norm()
            f = 1 - a_p*Tp[inertial_deg] + q*Tp[2*inertial_deg]
        L_P.append(f)

    # Use the local factors of the L-series to compute the Dirichlet
    # series coefficients of prime-power index.
    coefficients = [0,1] + [0]*(bound-1)
    i = 0
    while i < len(primes):
        P = primes[i]
        if P.is_split():
            s = L_P[i] * L_P[i+1]
            i += 2
        else:
            s = L_P[i]
            i += 1
        p = P.p
        # We need enough terms t so that p^t > bound
        accuracy_p = int(math.floor(math.log(bound)/math.log(p))) + 1
        series_p = s.add_bigoh(accuracy_p)**(-1)
        for j in range(1, accuracy_p):
            coefficients[p**j] = series_p[j]

    # Using multiplicativity, fill in the non-prime power Dirichlet
    # series coefficients.
    extend_multiplicatively_generic(coefficients)
    return coefficients
Exemple #16
0
def anlist_over_sqrt5(E, bound):
    """
    Compute the Dirichlet L-series coefficients, up to and including
    a_bound.  The i-th element of the return list is a[i].

    INPUT:
        - E -- elliptic curve over Q(sqrt(5)), which must have
          defining polynomial `x^2-x-1`.
        - ``bound`` -- integer

    OUTPUT:
        - list of integers of length bound + 1

    EXAMPLES::

        sage: from psage.ellcurve.lseries.lseries_nf import anlist_over_sqrt5
        sage: K.<a> = NumberField(x^2-x-1); E = EllipticCurve([0,-a,a,0,0])
        sage: v = anlist_over_sqrt5(E, 50); v
        [0, 1, 0, 0, -2, -1, 0, 0, 0, -4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, -4, 0, 0, 0, 11, 0, -6, 0, 0, 0, 0, 8, 0, 0, 0, 0, -1, 0, 0, -6, 4, 0, 0, 0, -6, 0]
        sage: len(v)
        51

    This function isn't super fast, but at least it will work in a few
    seconds up to `10^4`::

        sage: t = cputime()
        sage: v = anlist_over_sqrt5(E, 10^4)
        sage: assert cputime(t) < 5
    """
    from . import aplist_sqrt5
    from psage.number_fields.sqrt5.prime import primes_of_bounded_norm, Prime

    # Compute all of the prime ideals of the ring of integers up to the given bound
    primes = primes_of_bounded_norm(bound + 1)

    # Compute the traces of Frobenius: this is supposed to be the hard part
    v = aplist_sqrt5.aplist(E, bound + 1)

    # Compute information about the primes of bad reduction, in
    # particular the integers i such that primes[i] is a prime of bad
    # reduction.
    bad_primes = set([Prime(a.prime()) for a in E.local_data()])

    # We compute the local factors of the L-series as power series in ZZ[T].
    P = PowerSeriesRing(ZZ, 'T')
    T = P.gen()
    # Table of powers of T, so we don't have to compute T^4 (say) thousands of times.
    Tp = [T**i for i in range(5)]

    # For each prime, we write down the local factor.
    L_P = []
    for i, P in enumerate(primes):
        inertial_deg = 2 if P.is_inert() else 1
        a_p = v[i]
        if P in bad_primes:
            # bad reduction
            f = 1 - a_p * Tp[inertial_deg]
        else:
            # good reduction
            q = P.norm()
            f = 1 - a_p * Tp[inertial_deg] + q * Tp[2 * inertial_deg]
        L_P.append(f)

    # Use the local factors of the L-series to compute the Dirichlet
    # series coefficients of prime-power index.
    coefficients = [0, 1] + [0] * (bound - 1)
    i = 0
    while i < len(primes):
        P = primes[i]
        if P.is_split():
            s = L_P[i] * L_P[i + 1]
            i += 2
        else:
            s = L_P[i]
            i += 1
        p = P.p
        # We need enough terms t so that p^t > bound
        accuracy_p = int(math.floor(old_div(math.log(bound), math.log(p)))) + 1
        series_p = s.add_bigoh(accuracy_p)**(-1)
        for j in range(1, accuracy_p):
            coefficients[p**j] = series_p[j]

    # Using multiplicativity, fill in the non-prime power Dirichlet
    # series coefficients.
    extend_multiplicatively_generic(coefficients)
    return coefficients
Exemple #17
0
def verify_algebraically_PS(g, P0, alpha, trace_and_norm, verbose=True):
    # input:
    # * P0 (only necessary to shift the series)
    # * [trace_numerator, trace_denominator, norm_numerator, norm_denominator]
    # output:
    # a boolean
    if verbose:
        print "verify_algebraically()"
    L = P0.base_ring()
    assert alpha.base_ring() is L
    L_poly = PolynomialRing(L, "xL")
    xL = L_poly.gen()
    # shifting the series makes our life easier
    trace_numerator, trace_denominator, norm_numerator, norm_denominator = [
        L_poly(coeff)(L_poly.gen() + P0[0]) for coeff in trace_and_norm
    ]
    L_fpoly = L_poly.fraction_field()
    trace = L_fpoly(trace_numerator) / L_fpoly(trace_denominator)
    norm = L_fpoly(norm_numerator) / L_fpoly(norm_denominator)

    Xpoly = L_poly([norm(0), -trace(0), 1])
    if verbose:
        print "xpoly = %s" % Xpoly

    if Xpoly.is_irreducible():
        M = Xpoly.root_field("c")
    else:
        # this avoids bifurcation later on in the code
        M = NumberField(xL, "c")
    if verbose:
        print M

    xi_degree = max(
        [elt.degree() for elt in [trace_denominator, norm_denominator]])
    D = 2 * xi_degree
    hard_bound = D + (4 + 2)
    soft_bound = hard_bound + 5
    M_ps = PowerSeriesRing(M, "T", default_prec=soft_bound)
    T = M_ps.gen()
    Tsub = T + P0[0]

    trace_M = M_ps(trace)
    norm_M = M_ps(norm)
    sqrtdisc = sqrt(trace_M**2 - 4 * norm_M)
    x1 = (trace_M - sqrtdisc) / 2
    x2 = (trace_M + sqrtdisc) / 2

    y1 = sqrt(g(x1))

    y2 = sqrt(g(x2))

    iy = 1 / sqrt(g(Tsub))

    dx1 = x1.derivative(T)
    dx2 = x2.derivative(T)

    dx1_y1 = dx1 / y1
    dx2_y2 = dx2 / y2

    eq1 = Matrix([[-2 * M_ps(alpha.row(0).list())(Tsub) * iy, dx1_y1, dx2_y2]])
    eq2 = Matrix(
        [[-2 * M_ps(alpha.row(1).list())(Tsub) * iy, x1 * dx1_y1,
          x2 * dx2_y2]])
    branches = Matrix([[1, 1, 1], [1, 1, -1], [1, -1, 1], [1, -1,
                                                           -1]]).transpose()
    meq1 = eq1 * branches
    meq2 = eq2 * branches
    algzero = False
    for j in range(4):
        if meq1[0, j] == 0 and meq2[0, j] == 0:
            algzero = True
            break
    if verbose:
        print "Done, verify_algebraically()  = %s" % algzero
    return algzero