def _new_group_from_level(self, level): r""" Return a new group of the same type (Gamma0, Gamma1, or GammaH) as self of the given level. In the case that self is of type GammaH, we take the largest H inside `(\ZZ/ \text{level}\ZZ)^\times` which maps to H, namely its inverse image under the natural reduction map. EXAMPLES:: sage: G = Gamma0(20) sage: G._new_group_from_level(4) Congruence Subgroup Gamma0(4) sage: G._new_group_from_level(40) Congruence Subgroup Gamma0(40) sage: G = Gamma1(10) sage: G._new_group_from_level(6) Traceback (most recent call last): ... ValueError: one level must divide the other sage: G = GammaH(50,[7]); G Congruence Subgroup Gamma_H(50) with H generated by [7] sage: G._new_group_from_level(25) Congruence Subgroup Gamma_H(25) with H generated by [7] sage: G._new_group_from_level(10) Congruence Subgroup Gamma0(10) sage: G._new_group_from_level(100) Congruence Subgroup Gamma_H(100) with H generated by [7, 57] """ from congroup_gamma0 import is_Gamma0 from congroup_gamma1 import is_Gamma1 from congroup_gammaH import is_GammaH from all import Gamma0, Gamma1, GammaH N = self.level() if (level % N) and (N % level): raise ValueError, "one level must divide the other" if is_Gamma0(self): return Gamma0(level) elif is_Gamma1(self): return Gamma1(level) elif is_GammaH(self): H = self._generators_for_H() if level > N: d = level // N diffs = [N * i for i in range(d)] newH = [h + diff for h in H for diff in diffs] return GammaH(level, [x for x in newH if gcd(level, x) == 1]) else: return GammaH(level, [h % level for h in H]) else: raise NotImplementedError
def _new_group_from_level(self, level): r""" Return a new group of the same type (Gamma0, Gamma1, or GammaH) as self of the given level. In the case that self is of type GammaH, we take the largest H inside `(\ZZ/ \text{level}\ZZ)^\times` which maps to H, namely its inverse image under the natural reduction map. EXAMPLES:: sage: G = Gamma0(20) sage: G._new_group_from_level(4) Congruence Subgroup Gamma0(4) sage: G._new_group_from_level(40) Congruence Subgroup Gamma0(40) sage: G = Gamma1(10) sage: G._new_group_from_level(6) Traceback (most recent call last): ... ValueError: one level must divide the other sage: G = GammaH(50,[7]); G Congruence Subgroup Gamma_H(50) with H generated by [7] sage: G._new_group_from_level(25) Congruence Subgroup Gamma_H(25) with H generated by [7] sage: G._new_group_from_level(10) Congruence Subgroup Gamma0(10) sage: G._new_group_from_level(100) Congruence Subgroup Gamma_H(100) with H generated by [7, 57] """ from congroup_gamma0 import is_Gamma0 from congroup_gamma1 import is_Gamma1 from congroup_gammaH import is_GammaH from all import Gamma0, Gamma1, GammaH N = self.level() if (level % N) and (N % level): raise ValueError, "one level must divide the other" if is_Gamma0(self): return Gamma0(level) elif is_Gamma1(self): return Gamma1(level) elif is_GammaH(self): H = self._generators_for_H() if level > N: d = level // N diffs = [N * i for i in range(d)] newH = [h + diff for h in H for diff in diffs] return GammaH(level, [x for x in newH if gcd(level, x) == 1]) else: return GammaH(level, [h % level for h in H]) else: raise NotImplementedError
def is_subgroup(self, right): """ Return True if self is a subgroup of right. EXAMPLES:: sage: G = Gamma0(20) sage: G.is_subgroup(SL2Z) True sage: G.is_subgroup(Gamma0(4)) True sage: G.is_subgroup(Gamma0(20)) True sage: G.is_subgroup(Gamma0(7)) False sage: G.is_subgroup(Gamma1(20)) False sage: G.is_subgroup(GammaH(40, [])) False sage: Gamma0(80).is_subgroup(GammaH(40, [31, 21, 17])) True sage: Gamma0(2).is_subgroup(Gamma1(2)) True """ if right.level() == 1: return True if is_Gamma0(right): return self.level() % right.level() == 0 if is_Gamma1(right): if right.level() >= 3: return False elif right.level() == 2: return self.level() == 2 # case level 1 dealt with above else: return GammaH_class.is_subgroup(self, right)
def is_subgroup(self, right): """ Return True if self is a subgroup of right. EXAMPLES:: sage: G = Gamma0(20) sage: G.is_subgroup(SL2Z) True sage: G.is_subgroup(Gamma0(4)) True sage: G.is_subgroup(Gamma0(20)) True sage: G.is_subgroup(Gamma0(7)) False sage: G.is_subgroup(Gamma1(20)) False sage: G.is_subgroup(GammaH(40, [])) False sage: Gamma0(80).is_subgroup(GammaH(40, [31, 21, 17])) True sage: Gamma0(2).is_subgroup(Gamma1(2)) True """ if right.level() == 1: return True if is_Gamma0(right): return self.level() % right.level() == 0 if is_Gamma1(right): if right.level() >= 3: return False elif right.level() == 2: return self.level() == 2 # case level 1 dealt with above else: return GammaH_class.is_subgroup(self, right)