def multiplicative_subgroups(self): r""" Return generators for each subgroup of `(\ZZ/N\ZZ)^*`. EXAMPLES:: sage: Integers(5).multiplicative_subgroups() ([2], [4], []) sage: Integers(15).multiplicative_subgroups() ([11, 7], [4, 11], [8], [11], [14], [7], [4], []) sage: Integers(2).multiplicative_subgroups() ([],) sage: len(Integers(341).multiplicative_subgroups()) 80 """ from sage.groups.abelian_gps.abelian_group import AbelianGroup from sage.misc.misc import mul U = self.unit_gens() G = AbelianGroup([x.multiplicative_order() for x in U]) rawsubs = G.subgroups() mysubs = [] for G in rawsubs: mysubs.append([]) for s in G.gens(): mysubs[-1].append( mul([U[i]**s.list()[i] for i in xrange(len(U))])) return tuple(mysubs) # make it immutable, so that we can cache
def multiplicative_subgroups(self): r""" Return generators for each subgroup of `(\ZZ/N\ZZ)^*`. EXAMPLES:: sage: Integers(5).multiplicative_subgroups() ([2], [4], []) sage: Integers(15).multiplicative_subgroups() ([11, 7], [4, 11], [8], [11], [14], [7], [4], []) sage: Integers(2).multiplicative_subgroups() ([],) sage: len(Integers(341).multiplicative_subgroups()) 80 """ from sage.groups.abelian_gps.abelian_group import AbelianGroup from sage.misc.misc import mul U = self.unit_gens() G = AbelianGroup([x.multiplicative_order() for x in U]) rawsubs = G.subgroups() mysubs = [] for G in rawsubs: mysubs.append([]) for s in G.gens(): mysubs[-1].append(mul([U[i] ** s.list()[i] for i in xrange(len(U))])) return tuple(mysubs) # make it immutable, so that we can cache
def CohenOesterle(eps, k): r""" Compute the Cohen-Oesterle function associate to eps, `k`. This is a summand in the formula for the dimension of the space of cusp forms of weight `2` with character `\varepsilon`. INPUT: - ``eps`` - Dirichlet character - ``k`` - integer OUTPUT: element of the base ring of eps. EXAMPLES:: sage: G.<eps> = DirichletGroup(7) sage: sage.modular.dims.CohenOesterle(eps, 2) -2/3 sage: sage.modular.dims.CohenOesterle(eps, 4) -1 """ N = eps.modulus() facN = factor(N) f = eps.conductor() gamma_k = 0 if k % 4 == 2: gamma_k = frac(-1, 4) elif k % 4 == 0: gamma_k = frac(1, 4) mu_k = 0 if k % 3 == 2: mu_k = frac(-1, 3) elif k % 3 == 0: mu_k = frac(1, 3) def _lambda(r, s, p): """ Used internally by the CohenOesterle function. INPUT: - ``r, s, p`` - integers OUTPUT: Integer EXAMPLES: (indirect doctest) :: sage: K = CyclotomicField(3) sage: eps = DirichletGroup(7*43,K).0^2 sage: sage.modular.dims.CohenOesterle(eps,2) -4/3 """ if 2 * s <= r: if r % 2 == 0: return p**(r // 2) + p**((r // 2) - 1) return 2 * p**((r - 1) // 2) return 2 * (p**(r - s)) #end def of lambda K = eps.base_ring() return K(frac(-1,2) * mul([_lambda(r,valuation(f,p),p) for p, r in facN]) + \ gamma_k * mul([CO_delta(r,p,N,eps) for p, r in facN]) + \ mu_k * mul([CO_nu(r,p,N,eps) for p, r in facN]))
def CohenOesterle(eps, k): r""" Compute the Cohen-Oesterle function associate to eps, `k`. This is a summand in the formula for the dimension of the space of cusp forms of weight `2` with character `\varepsilon`. INPUT: - ``eps`` - Dirichlet character - ``k`` - integer OUTPUT: element of the base ring of eps. EXAMPLES:: sage: G.<eps> = DirichletGroup(7) sage: sage.modular.dims.CohenOesterle(eps, 2) -2/3 sage: sage.modular.dims.CohenOesterle(eps, 4) -1 """ N = eps.modulus() facN = factor(N) f = eps.conductor() gamma_k = 0 if k%4==2: gamma_k = frac(-1,4) elif k%4==0: gamma_k = frac(1,4) mu_k = 0 if k%3==2: mu_k = frac(-1,3) elif k%3==0: mu_k = frac(1,3) def _lambda(r,s,p): """ Used internally by the CohenOesterle function. INPUT: - ``r, s, p`` - integers OUTPUT: Integer EXAMPLES: (indirect doctest) :: sage: K = CyclotomicField(3) sage: eps = DirichletGroup(7*43,K).0^2 sage: sage.modular.dims.CohenOesterle(eps,2) -4/3 """ if 2*s<=r: if r%2==0: return p**(r//2) + p**((r//2)-1) return 2*p**((r-1)//2) return 2*(p**(r-s)) #end def of lambda K = eps.base_ring() return K(frac(-1,2) * mul([_lambda(r,valuation(f,p),p) for p, r in facN]) + \ gamma_k * mul([CO_delta(r,p,N,eps) for p, r in facN]) + \ mu_k * mul([CO_nu(r,p,N,eps) for p, r in facN]))