def __find_eisen_chars(character, k): """ Find all triples `(\psi_1, \psi_2, t)` that give rise to an Eisenstein series of the given weight and character. EXAMPLES:: sage: sage.modular.modform.eis_series.__find_eisen_chars(DirichletGroup(36).0, 4) [] sage: pars = sage.modular.modform.eis_series.__find_eisen_chars(DirichletGroup(36).0, 5) sage: [(x[0].values_on_gens(), x[1].values_on_gens(), x[2]) for x in pars] [((1, 1), (-1, 1), 1), ((1, 1), (-1, 1), 3), ((1, 1), (-1, 1), 9), ((1, -1), (-1, -1), 1), ((-1, 1), (1, 1), 1), ((-1, 1), (1, 1), 3), ((-1, 1), (1, 1), 9), ((-1, -1), (1, -1), 1)] """ N = character.modulus() if character.is_trivial(): if k%2 != 0: return [] char_inv = ~character V = [(character, char_inv, t) for t in divisors(N) if t>1] if k != 2: V.insert(0,(character, char_inv, 1)) if is_squarefree(N): return V # Now include all pairs (chi,chi^(-1)) such that cond(chi)^2 divides N: # TODO: Optimize -- this is presumably way too hard work below. G = dirichlet.DirichletGroup(N) for chi in G: if not chi.is_trivial(): f = chi.conductor() if N % (f**2) == 0: chi = chi.minimize_base_ring() chi_inv = ~chi for t in divisors(N//(f**2)): V.insert(0, (chi, chi_inv, t)) return V eps = character if eps(-1) != (-1)**k: return [] eps = eps.maximize_base_ring() G = eps.parent() # Find all pairs chi, psi such that: # # (1) cond(chi)*cond(psi) divides the level, and # # (2) chi*psi == eps, where eps is the nebentypus character of self. # # See [Miyake, Modular Forms] Lemma 7.1.1. K = G.base_ring() C = {} t0 = misc.cputime() for e in G: m = Integer(e.conductor()) if m in C: C[m].append(e) else: C[m] = [e] misc.verbose("Enumeration with conductors.",t0) params = [] for L in divisors(N): misc.verbose("divisor %s"%L) if L not in C: continue GL = C[L] for R in divisors(N/L): if R not in C: continue GR = C[R] for chi in GL: for psi in GR: if chi*psi == eps: chi0, psi0 = __common_minimal_basering(chi, psi) for t in divisors(N//(R*L)): if k != 1 or ((psi0, chi0, t) not in params): params.append( (chi0,psi0,t) ) return params
def __find_eisen_chars(character, k): """ Find all triples `(\psi_1, \psi_2, t)` that give rise to an Eisenstein series of the given weight and character. EXAMPLES:: sage: sage.modular.modform.eis_series.__find_eisen_chars(DirichletGroup(36).0, 4) [] sage: pars = sage.modular.modform.eis_series.__find_eisen_chars(DirichletGroup(36).0, 5) sage: [(x[0].values_on_gens(), x[1].values_on_gens(), x[2]) for x in pars] [((1, 1), (-1, 1), 1), ((1, 1), (-1, 1), 3), ((1, 1), (-1, 1), 9), ((1, -1), (-1, -1), 1), ((-1, 1), (1, 1), 1), ((-1, 1), (1, 1), 3), ((-1, 1), (1, 1), 9), ((-1, -1), (1, -1), 1)] """ N = character.modulus() if character.is_trivial(): if k % 2 != 0: return [] char_inv = ~character V = [(character, char_inv, t) for t in divisors(N) if t > 1] if k != 2: V.insert(0, (character, char_inv, 1)) if is_squarefree(N): return V # Now include all pairs (chi,chi^(-1)) such that cond(chi)^2 divides N: # TODO: Optimize -- this is presumably way too hard work below. G = dirichlet.DirichletGroup(N) for chi in G: if not chi.is_trivial(): f = chi.conductor() if N % (f**2) == 0: chi = chi.minimize_base_ring() chi_inv = ~chi for t in divisors(N // (f**2)): V.insert(0, (chi, chi_inv, t)) return V eps = character if eps(-1) != (-1)**k: return [] eps = eps.maximize_base_ring() G = eps.parent() # Find all pairs chi, psi such that: # # (1) cond(chi)*cond(psi) divides the level, and # # (2) chi*psi == eps, where eps is the nebentypus character of self. # # See [Miyake, Modular Forms] Lemma 7.1.1. K = G.base_ring() C = {} t0 = misc.cputime() for e in G: m = Integer(e.conductor()) if C.has_key(m): C[m].append(e) else: C[m] = [e] misc.verbose("Enumeration with conductors.", t0) params = [] for L in divisors(N): misc.verbose("divisor %s" % L) if not C.has_key(L): continue GL = C[L] for R in divisors(N / L): if not C.has_key(R): continue GR = C[R] for chi in GL: for psi in GR: if chi * psi == eps: chi0, psi0 = __common_minimal_basering(chi, psi) for t in divisors(N // (R * L)): if k != 1 or ((psi0, chi0, t) not in params): params.append((chi0, psi0, t)) return params