def __find_eisen_chars_gammaH(N, H, k): """ Find all triples `(\psi_1, \psi_2, t)` that give rise to an Eisenstein series of weight `k` on `\Gamma_H(N)`. EXAMPLES:: sage: pars = sage.modular.modform.eis_series.__find_eisen_chars_gammaH(15, [2], 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), 1), ((1, -1), (-1, 1), 1), ((-1, -1), (1, 1), 1)] """ params = [] for chi in dirichlet.DirichletGroup(N): if all([chi(h) == 1 for h in H]): params += __find_eisen_chars(chi, k) return params
def _modular_symbols_space_character(self): """ Return a random space of modular symbols for Gamma1, with (possibly trivial) character, random sign, and weight a random choice from self.weights. EXAMPLES: sage: sage.modular.modsym.tests.Test()._modular_symbols_space_character() # random level = 18, weight = 3, sign = 0 Modular Symbols space of dimension 0 and level 18, weight 3, character [1, zeta6 - 1], sign 0, over Cyclotomic Field of order 6 and degree 2 """ level, weight, sign = self._level_weight_sign() G = dirichlet.DirichletGroup(level) eps = G.random_element() M = modsym.ModularSymbols(eps, weight, sign) self.current_space = M return M
def __find_eisen_chars_gamma1(N, k): """ Find all triples `(\psi_1, \psi_2, t)` that give rise to an Eisenstein series of weight `k` on `\Gamma_1(N)`. EXAMPLES:: sage: pars = sage.modular.modform.eis_series.__find_eisen_chars_gamma1(12, 4) 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), 2), ((1, 1), (1, 1), 3), ((1, 1), (1, 1), 4), ((1, 1), (1, 1), 6), ((1, 1), (1, 1), 12), ((1, 1), (-1, -1), 1), ((-1, -1), (1, 1), 1), ((-1, 1), (1, -1), 1), ((1, -1), (-1, 1), 1)] sage: pars = sage.modular.modform.eis_series.__find_eisen_chars_gamma1(12, 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), 1), ((-1, 1), (1, 1), 3), ((1, 1), (1, -1), 1), ((1, 1), (1, -1), 2), ((1, 1), (1, -1), 4), ((1, -1), (1, 1), 1), ((1, -1), (1, 1), 2), ((1, -1), (1, 1), 4)] """ pairs = [] s = (-1)**k G = dirichlet.DirichletGroup(N) E = list(G) parity = [c(-1) for c in E] for i in range(len(E)): for j in range(i,len(E)): if parity[i]*parity[j] == s and N % (E[i].conductor()*E[j].conductor()) == 0: chi, psi = __common_minimal_basering(E[i], E[j]) if k != 1: pairs.append((chi, psi)) if i!=j: pairs.append((psi,chi)) else: # if weight is 1 then (chi, psi) and (chi, psi) are the # same form if psi.is_trivial() and not chi.is_trivial(): # need to put the trivial character first to get the L-value right pairs.append((psi, chi)) else: pairs.append((chi, psi)) #end fors #end if triples = [] D = divisors(N) for chi, psi in pairs: c_chi = chi.conductor() c_psi = psi.conductor() D = divisors(N/(c_chi * c_psi)) if (k==2 and chi.is_trivial() and psi.is_trivial()): D.remove(1) chi, psi = __common_minimal_basering(chi, psi) for t in D: triples.append((chi, psi, t)) return triples
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 = cputime() for e in G: m = Integer(e.conductor()) if m in C: C[m].append(e) else: C[m] = [e] verbose("Enumeration with conductors.", t0) params = [] for L in divisors(N): 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