def hecke_series(p, N, klist, m, modformsring=False, weightbound=6): r""" Returns the characteristic series modulo `p^m` of the Atkin operator `U_p` acting upon the space of p-adic overconvergent modular forms of level `\Gamma_0(N)` and weight ``klist``. The input ``klist`` may also be a list of weights congruent modulo `(p-1)`, in which case the output is the corresponding list of characteristic series for each `k` in ``klist``; this is faster than performing the computation separately for each `k`, since intermediate steps in the computation may be reused. If ``modformsring`` is True, then for `N > 1` the algorithm computes at one step ``ModularFormsRing(N).generators()``. This will often be faster but the algorithm will default to ``modformsring = False`` if the generators found are not p-adically integral. Note that ``modformsring`` is ignored for `N = 1` and the ring structure of modular forms is *always* used in this case. When ``modformsring`` is False and `N > 1`, `weightbound` is a bound set on the weight of generators for a certain subspace of modular forms. The algorithm will often be faster if ``weightbound = 4``, but it may fail to terminate for certain exceptional small values of `N`, when this bound is too small. The algorithm is based upon that described in [AGBL]_. INPUT: - ``p`` -- a prime greater than or equal to 5. - ``N`` -- a positive integer not divisible by `p`. - ``klist`` -- either a list of integers congruent modulo `(p-1)`, or a single integer. - ``m`` -- a positive integer. - ``modformsring`` -- ``True`` or ``False`` (optional, default ``False``). Ignored if `N = 1`. - ``weightbound`` -- a positive even integer (optional, default 6). Ignored if `N = 1` or ``modformsring`` is True. OUTPUT: Either a list of polynomials or a single polynomial over the integers modulo `p^m`. EXAMPLES:: sage: hecke_series(5,7,10000,5, modformsring = True) # long time (3.4s) 250*x^6 + 1825*x^5 + 2500*x^4 + 2184*x^3 + 1458*x^2 + 1157*x + 1 sage: hecke_series(7,3,10000,3, weightbound = 4) 196*x^4 + 294*x^3 + 197*x^2 + 341*x + 1 sage: hecke_series(19,1,[10000,10018],5) [1694173*x^4 + 2442526*x^3 + 1367943*x^2 + 1923654*x + 1, 130321*x^4 + 958816*x^3 + 2278233*x^2 + 1584827*x + 1] Check that silly weights are handled correctly:: sage: hecke_series(5, 7, [2, 3], 5) Traceback (most recent call last): ... ValueError: List of weights must be all congruent modulo p-1 = 4, but given list contains 2 and 3 which are not congruent sage: hecke_series(5, 7, [3], 5) [1] sage: hecke_series(5, 7, 3, 5) 1 """ # convert to sage integers p = ZZ(p) N = ZZ(N) m = ZZ(m) weightbound = ZZ(weightbound) oneweight = False # convert single weight to list if ((type(klist) == int) or (type(klist) == Integer)): klist = [klist] oneweight = True # input is single weight # algorithm may finish with false output unless: is_valid_weight_list(klist, p) if not p.is_prime(): raise ValueError, "p (=%s) is not prime" % p if p < 5: raise ValueError, "p = 2 and p = 3 not supported" if not N % p: raise ValueError, "Level (=%s) should be prime to p (=%s)" % (N, p) # return all 1 list for odd weights if klist[0] % 2 == 1: if oneweight: return 1 else: return [1 for i in xrange(len(klist))] if N == 1: Alist = level1_UpGj(p, klist, m) else: Alist = higher_level_UpGj(p, N, klist, m, modformsring, weightbound) Plist = [] for A in Alist: P = charpoly(A).reverse() Plist.append(P) if oneweight == True: return Plist[0] else: return Plist
def hecke_series(p,N,klist,m, modformsring = False, weightbound = 6): r""" Returns the characteristic series modulo `p^m` of the Atkin operator `U_p` acting upon the space of p-adic overconvergent modular forms of level `\Gamma_0(N)` and weight ``klist``. The input ``klist`` may also be a list of weights congruent modulo `(p-1)`, in which case the output is the corresponding list of characteristic series for each `k` in ``klist``; this is faster than performing the computation separately for each `k`, since intermediate steps in the computation may be reused. If ``modformsring`` is True, then for `N > 1` the algorithm computes at one step ``ModularFormsRing(N).generators()``. This will often be faster but the algorithm will default to ``modformsring = False`` if the generators found are not p-adically integral. Note that ``modformsring`` is ignored for `N = 1` and the ring structure of modular forms is *always* used in this case. When ``modformsring`` is False and `N > 1`, `weightbound` is a bound set on the weight of generators for a certain subspace of modular forms. The algorithm will often be faster if ``weightbound = 4``, but it may fail to terminate for certain exceptional small values of `N`, when this bound is too small. The algorithm is based upon that described in [AGBL]_. INPUT: - ``p`` -- a prime greater than or equal to 5. - ``N`` -- a positive integer not divisible by `p`. - ``klist`` -- either a list of integers congruent modulo `(p-1)`, or a single integer. - ``m`` -- a positive integer. - ``modformsring`` -- ``True`` or ``False`` (optional, default ``False``). Ignored if `N = 1`. - ``weightbound`` -- a positive even integer (optional, default 6). Ignored if `N = 1` or ``modformsring`` is True. OUTPUT: Either a list of polynomials or a single polynomial over the integers modulo `p^m`. EXAMPLES:: sage: hecke_series(5,7,10000,5, modformsring = True) # long time (3.4s) 250*x^6 + 1825*x^5 + 2500*x^4 + 2184*x^3 + 1458*x^2 + 1157*x + 1 sage: hecke_series(7,3,10000,3, weightbound = 4) 196*x^4 + 294*x^3 + 197*x^2 + 341*x + 1 sage: hecke_series(19,1,[10000,10018],5) [1694173*x^4 + 2442526*x^3 + 1367943*x^2 + 1923654*x + 1, 130321*x^4 + 958816*x^3 + 2278233*x^2 + 1584827*x + 1] Check that silly weights are handled correctly:: sage: hecke_series(5, 7, [2, 3], 5) Traceback (most recent call last): ... ValueError: List of weights must be all congruent modulo p-1 = 4, but given list contains 2 and 3 which are not congruent sage: hecke_series(5, 7, [3], 5) [1] sage: hecke_series(5, 7, 3, 5) 1 """ # convert to sage integers p = ZZ(p) N = ZZ(N) m = ZZ(m) weightbound = ZZ(weightbound) oneweight = False # convert single weight to list if ((isinstance(klist, int)) or (isinstance(klist, Integer))): klist = [klist] oneweight = True # input is single weight # algorithm may finish with false output unless: is_valid_weight_list(klist,p) if not p.is_prime(): raise ValueError("p (=%s) is not prime" % p) if p < 5: raise ValueError("p = 2 and p = 3 not supported") if not N%p: raise ValueError("Level (=%s) should be prime to p (=%s)" % (N, p)) # return all 1 list for odd weights if klist[0] % 2 == 1: if oneweight: return 1 else: return [1 for i in xrange(len(klist))] if N == 1: Alist = level1_UpGj(p,klist,m) else: Alist = higher_level_UpGj(p,N,klist,m,modformsring,weightbound) Plist = [] for A in Alist: P = charpoly(A).reverse() Plist.append(P) if oneweight == True: return Plist[0] else: return Plist