def CongruenceSubgroup_constructor(*args): r""" Attempt to create a congruence subgroup from the given data. The allowed inputs are as follows: - A :class:`~sage.groups.matrix_gps.matrix_group.MatrixGroup` object. This must be a group of matrices over `\ZZ / N\ZZ` for some `N`, with determinant 1, in which case the function will return the group of matrices in `SL(2, \ZZ)` whose reduction mod `N` is in the given group. - A list of matrices over `\ZZ / N\ZZ` for some `N`. The function will then compute the subgroup of `SL(2, \ZZ)` generated by these matrices, and proceed as above. - An integer `N` and a list of matrices (over any ring coercible to `\ZZ / N\ZZ`, e.g. over `\ZZ`). The matrices will then be coerced to `\ZZ / N\ZZ`. The function checks that the input G is valid. It then tests to see if `G` is the preimage mod `N` of some group of matrices modulo a proper divisor `M` of `N`, in which case it replaces `G` with this group before continuing. EXAMPLES:: sage: from sage.modular.arithgroup.congroup_generic import CongruenceSubgroup_constructor as CS sage: CS(2, [[1,1,0,1]]) Congruence subgroup of SL(2,Z) of level 2, preimage of: Matrix group over Ring of integers modulo 2 with 1 generators ( [1 1] [0 1] ) sage: CS([matrix(Zmod(2), 2, [1,1,0,1])]) Congruence subgroup of SL(2,Z) of level 2, preimage of: Matrix group over Ring of integers modulo 2 with 1 generators ( [1 1] [0 1] ) sage: CS(MatrixGroup([matrix(Zmod(2), 2, [1,1,0,1])])) Congruence subgroup of SL(2,Z) of level 2, preimage of: Matrix group over Ring of integers modulo 2 with 1 generators ( [1 1] [0 1] ) sage: CS(SL(2, 2)) Modular Group SL(2,Z) Some invalid inputs:: sage: CS(SU(2, 7)) Traceback (most recent call last): ... TypeError: Ring of definition must be Z / NZ for some N """ from sage.groups.matrix_gps.matrix_group import is_MatrixGroup if is_MatrixGroup(args[0]): G = args[0] elif type(args[0]) == type([]): G = MatrixGroup(args[0]) elif args[0] in ZZ: M = MatrixSpace(Zmod(args[0]), 2) G = MatrixGroup([M(x) for x in args[1]]) R = G.matrix_space().base_ring() if not hasattr(R, "cover_ring") or R.cover_ring() != ZZ: raise TypeError, "Ring of definition must be Z / NZ for some N" if not all([x.matrix().det() == 1 for x in G.gens()]): raise ValueError, "Group must be contained in SL(2, Z / N)" GG = _minimize_level(G) if GG in ZZ: from all import Gamma return Gamma(GG) else: return CongruenceSubgroupFromGroup(GG)
def CongruenceSubgroup_constructor(*args): r""" Attempt to create a congruence subgroup from the given data. The allowed inputs are as follows: - A :class:`~sage.groups.matrix_gps.matrix_group.MatrixGroup` object. This must be a group of matrices over `\ZZ / N\ZZ` for some `N`, with determinant 1, in which case the function will return the group of matrices in `SL(2, \ZZ)` whose reduction mod `N` is in the given group. - A list of matrices over `\ZZ / N\ZZ` for some `N`. The function will then compute the subgroup of `SL(2, \ZZ)` generated by these matrices, and proceed as above. - An integer `N` and a list of matrices (over any ring coercible to `\ZZ / N\ZZ`, e.g. over `\ZZ`). The matrices will then be coerced to `\ZZ / N\ZZ`. The function checks that the input G is valid. It then tests to see if `G` is the preimage mod `N` of some group of matrices modulo a proper divisor `M` of `N`, in which case it replaces `G` with this group before continuing. EXAMPLES:: sage: from sage.modular.arithgroup.congroup_generic import CongruenceSubgroup_constructor as CS sage: CS(2, [[1,1,0,1]]) Congruence subgroup of SL(2,Z) of level 2, preimage of: Matrix group over Ring of integers modulo 2 with 1 generators ( [1 1] [0 1] ) sage: CS([matrix(Zmod(2), 2, [1,1,0,1])]) Congruence subgroup of SL(2,Z) of level 2, preimage of: Matrix group over Ring of integers modulo 2 with 1 generators ( [1 1] [0 1] ) sage: CS(MatrixGroup([matrix(Zmod(2), 2, [1,1,0,1])])) Congruence subgroup of SL(2,Z) of level 2, preimage of: Matrix group over Ring of integers modulo 2 with 1 generators ( [1 1] [0 1] ) sage: CS(SL(2, 2)) Modular Group SL(2,Z) Some invalid inputs:: sage: CS(SU(2, 7)) Traceback (most recent call last): ... TypeError: Ring of definition must be Z / NZ for some N """ from sage.groups.matrix_gps.matrix_group import is_MatrixGroup if is_MatrixGroup(args[0]): G = args[0] elif isinstance(args[0], list): G = MatrixGroup(args[0]) elif args[0] in ZZ: M = MatrixSpace(Zmod(args[0]), 2) G = MatrixGroup([M(x) for x in args[1]]) R = G.matrix_space().base_ring() if not hasattr(R, "cover_ring") or R.cover_ring() != ZZ: raise TypeError("Ring of definition must be Z / NZ for some N") if not all([x.matrix().det() == 1 for x in G.gens()]): raise ValueError("Group must be contained in SL(2, Z / N)") GG = _minimize_level(G) if GG in ZZ: from .all import Gamma return Gamma(GG) else: return CongruenceSubgroupFromGroup(GG)