Ejemplo n.º 1
0
def pretty_print_field(field, base, str_field='F'):
    if field[0] in QQ:
        base = [-1, 1]
        str_field = 'QQ'
        if len(field) == 3:
            c, b, a = field
            D = b**2 - 4 * a * c
            return '%s (sqrt(%s))' % (str_field, squarefree_part(D))
    if len(field) == 2:
        return '%s' % str_field
    return '%s [x] / (%s)' % (str_field,
                              pretty_print_polynomial_list(field, base))
Ejemplo n.º 2
0
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0):
    r"""
    Checks if f is minimal and if not, returns the associated
    minimal form to precision prec.

    INPUT:

    - ''k'' -- positive integer : the weight
    - ''N'' -- positive integer (default 1) : level
    - ''chi'' -- non-neg. integer (default 0) use character nr. chi
    - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]
    - ''prec'' -- integer (the number of coefficients to get)
    - ''verbose'' -- integer
    OUTPUT:

    -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form.
              The actual minimal one is the first element of this list.

    EXAMPLES::



    """
    (t, f) = _get_newform(k, N, chi, fi)

    if (not t):
        return f
    if (is_squarefree(ZZ(N))):
        return [True, f]
    # We need to check all square factors of N
    logger.debug("investigating: %s" % f)
    N_sqfree = squarefree_part(ZZ(N))
    Nsq = ZZ(N / N_sqfree)
    twist_candidates = list()
    KF = f.base_ring()
    # check how many Hecke eigenvalues we need to check
    max_nump = number_of_hecke_to_check(f)
    maxp = max(primes_first_n(max_nump))
    for d in divisors(N):
        # we look at all d such that d^2 divdes N
        if (not ZZ(d**2).divides(ZZ(N))):
            continue
        D = DirichletGroup(d)
        # check possible candidates to twist into f
        # g in S_k(M,chi) wit M=N/d^2
        M = ZZ(N / d**2)
        logger.debug("Checking level %s" % M)
        for xig in range(euler_phi(M)):
            (t, glist) = _get_newform(k, M, xig)
            if (not t):
                return glist
            for g in glist:
                logger.debug("Comparing to function %s" % g)
                KG = g.base_ring()
                # we now see if twisting of g by xi in D gives us f
                for xi in D:
                    try:
                        for p in primes_first_n(max_nump):
                            if (ZZ(p).divides(ZZ(N))):
                                continue
                            bf = f.q_expansion(maxp + 1)[p]
                            bg = g.q_expansion(maxp + 1)[p]
                            if (bf == 0 and bg == 0):
                                continue
                            elif (bf == 0 and bg != 0 or bg == 0 and bf != 0):
                                raise StopIteration()
                            if (ZZ(p).divides(xi.conductor())):
                                raise ArithmeticError("")
                            xip = xi(p)
                            # make a preliminary check that the base rings match with respect to being
                            # real or not
                            try:
                                QQ(xip)
                                XF = QQ
                                if (KF != QQ or KG != QQ):
                                    raise StopIteration
                            except TypeError:
                                # we have a  non-rational (i.e. complex) value of the character
                                XF = xip.parent()
                                if ((KF == QQ or KF.is_totally_real()) and
                                    (KG == QQ or KG.is_totally_real())):
                                    raise StopIteration
                            ## it is diffcult to compare elements from diferent rings in general but we make some checcks
                            # is it possible to see if there is a larger ring which everything can be
                            # coerced into?
                            ok = False
                            try:
                                a = KF(bg / xip)
                                b = KF(bf)
                                ok = True
                                if (a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            try:
                                a = KG(bg)
                                b = KG(xip * bf)
                                ok = True
                                if (a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            if (
                                    not ok
                            ):  # we could coerce and the coefficients were equal
                                return "Could not compare against possible candidates!"
                            # otherwise if we are here we are ok and found a candidate
                        twist_candidates.append([dd, g.q_expansion(prec), xi])
                    except StopIteration:
                        # they are not equal
                        pass
    # logger.debug("Candidates=%s" % twist_candidates)
    if (len(twist_candidates) == 0):
        return (True, None)
    else:
        return (False, twist_candidates)
Ejemplo n.º 3
0
 def _dimension_formula(self,k,eps=1,cuspidal=1):
     ep = 0
     N = self._N
     if (2*k) % 4 == 1: ep = 1
     if (2*k) % 4 == 3: ep = -1
     if ep==0: return 0,0
     if eps==-1:
         ep = -ep
     twok = ZZ(2*k)
     K0 = 1
     sqf = ZZ(N).divide_knowing_divisible_by(squarefree_part(N))
     if sqf>12:
         b2 = max(sqf.divisors())
     else:
         b2 = 1
     b = sqrt(b2)
     if ep==1:
         K0 = floor(QQ(b+2)/QQ(2))
     else:
         # print "b=",b
         K0 = floor(QQ(b-1)/QQ(2))
     if is_even(N):
         e2 = ep*kronecker(2,twok)/QQ(4)
     else:
         e2 = 0
     N2 = odd_part(N)
     N22 = ZZ(N).divide_knowing_divisible_by(N2)
     k3 = kronecker(3,twok)
     if gcd(3,N)>1:
         if eps==1:
             e3 = -ep*kronecker(-3,4*k+ep-1)/QQ(3)
         else:
             e3 = -1*ep*kronecker(-3,4*k+ep+1)/QQ(3)
         #e3 = -1/3*ep
     else:
         f1 = kronecker(3,2*N22)*kronecker(-12,N2) - ep
         f2 = kronecker(-3,twok+1)
         e3 = f1*f2/QQ(6)
     ID = QQ(N+ep)*(k-1)/QQ(12)
     P = 0
     for d in ZZ(4*N).divisors():
         dm4=d % 4
         if dm4== 2 or dm4 == 1:
             h = 0
         elif d == 3:
             h = QQ(1)/QQ(3)
         elif d == 4:
             h = QQ(1)/QQ(2)
         else:
             h = class_nr_pos_def_qf(-d)
         if self._verbose>1:
             print "h({0})={1}".format(d,h)
         if h<>0:
             P= P + h
     P = QQ(P)/QQ(4)
     if self._verbose>0:
         print "P=",P
     P=P + QQ(ep)*kronecker(-4,N)/QQ(8)
     if eps==-1:
         P = -P
     if self._verbose>0:
         print "P=",P
     # P = -2*N**2 + N*(twok+10-ep*3) +(twok+10)*ep-1
     if self._verbose>0:
         print "ID=",ID
     P =  P - QQ(1)/QQ(2*K0)
     # P = QQ(P)/QQ(24) - K0
     # P = P - K0
     res = ID + P + e2 + e3
     if self._verbose>1:
         print "twok=",twok
         print "K0=",K0
         print "ep=",ep
         print "e2=",e2
         print "e3=",e3
         print "P=",P
     if cuspidal==0:
         res = res + K0
     return res   #,ep
Ejemplo n.º 4
0
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0):
    r"""
    Checks if f is minimal and if not, returns the associated
    minimal form to precision prec.

    INPUT:

    - ''k'' -- positive integer : the weight
    - ''N'' -- positive integer (default 1) : level
    - ''chi'' -- non-neg. integer (default 0) use character nr. chi
    - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]
    - ''prec'' -- integer (the number of coefficients to get)
    - ''verbose'' -- integer
    OUTPUT:

    -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form.
              The actual minimal one is the first element of this list.

    EXAMPLES::



    """
    (t, f) = _get_newform(k, N, chi, fi)

    if(not t):
        return f
    if(is_squarefree(ZZ(N))):
        return [True, f]
    # We need to check all square factors of N
    logger.debug("investigating: %s" % f)
    N_sqfree = squarefree_part(ZZ(N))
    Nsq = ZZ(N / N_sqfree)
    twist_candidates = list()
    KF = f.base_ring()
    # check how many Hecke eigenvalues we need to check
    max_nump = number_of_hecke_to_check(f)
    maxp = max(primes_first_n(max_nump))
    for d in divisors(N):
        # we look at all d such that d^2 divdes N
        if(not ZZ(d ** 2).divides(ZZ(N))):
            continue
        D = DirichletGroup(d)
        # check possible candidates to twist into f
        # g in S_k(M,chi) wit M=N/d^2
        M = ZZ(N / d ** 2)
        logger.debug("Checking level %s" % M)
        for xig in range(euler_phi(M)):
            (t, glist) = _get_newform(k, M, xig)
            if(not t):
                return glist
            for g in glist:
                logger.debug("Comparing to function %s" % g)
                KG = g.base_ring()
                # we now see if twisting of g by xi in D gives us f
                for xi in D:
                    try:
                        for p in primes_first_n(max_nump):
                            if(ZZ(p).divides(ZZ(N))):
                                continue
                            bf = f.q_expansion(maxp + 1)[p]
                            bg = g.q_expansion(maxp + 1)[p]
                            if(bf == 0 and bg == 0):
                                continue
                            elif(bf == 0 and bg != 0 or bg == 0 and bf != 0):
                                raise StopIteration()
                            if(ZZ(p).divides(xi.conductor())):
                                raise ArithmeticError("")
                            xip = xi(p)
                            # make a preliminary check that the base rings match with respect to being
                            # real or not
                            try:
                                QQ(xip)
                                XF = QQ
                                if(KF != QQ or KG != QQ):
                                    raise StopIteration
                            except TypeError:
                                # we have a  non-rational (i.e. complex) value of the character
                                XF = xip.parent()
                                if((KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())):
                                    raise StopIteration
                            ## it is diffcult to compare elements from diferent rings in general but we make some checcks
                            # is it possible to see if there is a larger ring which everything can be
                            # coerced into?
                            ok = False
                            try:
                                a = KF(bg / xip)
                                b = KF(bf)
                                ok = True
                                if(a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            try:
                                a = KG(bg)
                                b = KG(xip * bf)
                                ok = True
                                if(a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            if(not ok):  # we could coerce and the coefficients were equal
                                return "Could not compare against possible candidates!"
                            # otherwise if we are here we are ok and found a candidate
                        twist_candidates.append([dd, g.q_expansion(prec), xi])
                    except StopIteration:
                        # they are not equal
                        pass
    # logger.debug("Candidates=%s" % twist_candidates)
    if(len(twist_candidates) == 0):
        return (True, None)
    else:
        return (False, twist_candidates)
Ejemplo n.º 5
0
 def _dimension_formula(self,k,eps=1,cuspidal=1):
     ep = 0
     N = self._N
     if (2*k) % 4 == 1: ep = 1
     if (2*k) % 4 == 3: ep = -1
     if ep==0: return 0,0
     if eps==-1:
         ep = -ep
     twok = ZZ(2*k)
     K0 = 1
     sqf = ZZ(N).divide_knowing_divisible_by(squarefree_part(N))
     if sqf>12:
         b2 = max(sqf.divisors())
     else:
         b2 = 1
     b = sqrt(b2)
     if ep==1:
         K0 = floor(QQ(b+2)/QQ(2))
     else:
         # print "b=",b
         K0 = floor(QQ(b-1)/QQ(2))
     if is_even(N):
         e2 = ep*kronecker(2,twok)/QQ(4)
     else:
         e2 = 0
     N2 = odd_part(N)
     N22 = ZZ(N).divide_knowing_divisible_by(N2)
     k3 = kronecker(3,twok)
     if gcd(3,N)>1:
         if eps==1:
             e3 = -ep*kronecker(-3,4*k+ep-1)/QQ(3)
         else:
             e3 = -1*ep*kronecker(-3,4*k+ep+1)/QQ(3)
         #e3 = -1/3*ep
     else:
         f1 = kronecker(3,2*N22)*kronecker(-12,N2) - ep
         f2 = kronecker(-3,twok+1)
         e3 = f1*f2/QQ(6)
     ID = QQ(N+ep)*(k-1)/QQ(12)
     P = 0
     for d in ZZ(4*N).divisors():
         dm4=d % 4
         if dm4== 2 or dm4 == 1:
             h = 0
         elif d == 3:
             h = QQ(1)/QQ(3)
         elif d == 4:
             h = QQ(1)/QQ(2)
         else:
             h = class_nr_pos_def_qf(-d)
         if self._verbose>1:
             print("h({0})={1}".format(d,h))
         if h!=0:
             P= P + h
     P = QQ(P)/QQ(4)
     if self._verbose>0:
         print("P={0}".format(P))
     P=P + QQ(ep)*kronecker(-4,N)/QQ(8)
     if eps==-1:
         P = -P
     if self._verbose>0:
         print("P={0}".format(P))
     # P = -2*N**2 + N*(twok+10-ep*3) +(twok+10)*ep-1
     if self._verbose>0:
         print("ID={0}".format(ID))
     P =  P - QQ(1)/QQ(2*K0)
     # P = QQ(P)/QQ(24) - K0
     # P = P - K0
     res = ID + P + e2 + e3
     if self._verbose>1:
         print("twok={0}".format(twok))
         print("K0={0}".format(K0))
         print("ep={0}".format(ep))
         print("e2={0}".format(e2))
         print("e3={0}".format(e3))
         print("P={0}".format(P))
     if cuspidal==0:
         res = res + K0
     return res   #,ep