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))
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)
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
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)
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