Example #1
0
    def is_subgroup(self, right):
        """
        Return True if self is a subgroup of right.

        EXAMPLES::

            sage: Gamma1(3).is_subgroup(SL2Z)
            True
            sage: Gamma1(3).is_subgroup(Gamma1(5))
            False
            sage: Gamma1(3).is_subgroup(Gamma1(6))
            False
            sage: Gamma1(6).is_subgroup(Gamma1(3))
            True
            sage: Gamma1(6).is_subgroup(Gamma0(2))
            True
            sage: Gamma1(80).is_subgroup(GammaH(40, []))
            True
            sage: Gamma1(80).is_subgroup(GammaH(40, [21]))
            True
        """
        if right.level() == 1:
            return True
        if is_GammaH(right):
            return self.level() % right.level() == 0
        else:
            raise NotImplementedError
Example #2
0
    def is_subgroup(self, right):
        """
        Return True if self is a subgroup of right.

        EXAMPLES::

            sage: Gamma1(3).is_subgroup(SL2Z)
            True
            sage: Gamma1(3).is_subgroup(Gamma1(5))
            False
            sage: Gamma1(3).is_subgroup(Gamma1(6))
            False
            sage: Gamma1(6).is_subgroup(Gamma1(3))
            True
            sage: Gamma1(6).is_subgroup(Gamma0(2))
            True
            sage: Gamma1(80).is_subgroup(GammaH(40, []))
            True
            sage: Gamma1(80).is_subgroup(GammaH(40, [21]))
            True
        """
        if right.level() == 1:
            return True
        if is_GammaH(right):
            return self.level() % right.level() == 0
        else:
            raise NotImplementedError
Example #3
0
    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
Example #4
0
    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
Example #5
0
    def __cmp__(self, other):
        """
        Compare self to other.

        The ordering on congruence subgroups of the form `\Gamma_H(N)` for
        some H is first by level and then by the subgroup H. In
        particular, this means that we have `\Gamma_1(N) < \Gamma_H(N) <
        \Gamma_0(N)` for every nontrivial subgroup H.

        EXAMPLES::

            sage: G = Gamma1(86)
            sage: G.__cmp__(G)
            0
            sage: G.__cmp__(GammaH(86, [11])) is not 0
            True
            sage: Gamma1(12) < Gamma0(12)
            True
            sage: Gamma1(10) < Gamma1(12)
            True
            sage: Gamma1(11) == GammaH(11, [])
            True
            sage: Gamma1(1) == SL2Z
            True
            sage: Gamma1(2) == Gamma0(2)
            True
        """
        from all import is_GammaH
        if not is_CongruenceSubgroup(other):
            return cmp(type(self), type(other))

        c = cmp(self.level(), other.level())
        if c: return c

        # Since Gamma1(N) is GammaH(N) for H all of (Z/N)^\times,
        # we know how to compare it to any other GammaH without having
        # to look at self._list_of_elements_in_H().
        if is_GammaH(other):
            if is_Gamma1(other):
                return 0
            else:
                H = other._generators_for_H()
                return cmp(0,len(H))
        return cmp(type(self), type(other))
Example #6
0
    def __cmp__(self, other):
        """
        Compare self to other.

        The ordering on congruence subgroups of the form `\Gamma_H(N)` for
        some H is first by level and then by the subgroup H. In
        particular, this means that we have `\Gamma_1(N) < \Gamma_H(N) <
        \Gamma_0(N)` for every nontrivial subgroup H.

        EXAMPLES::

            sage: G = Gamma1(86)
            sage: G.__cmp__(G)
            0
            sage: G.__cmp__(GammaH(86, [11])) is not 0
            True
            sage: Gamma1(12) < Gamma0(12)
            True
            sage: Gamma1(10) < Gamma1(12)
            True
            sage: Gamma1(11) == GammaH(11, [])
            True
            sage: Gamma1(1) == SL2Z
            True
            sage: Gamma1(2) == Gamma0(2)
            True
        """
        from all import is_GammaH
        if not is_CongruenceSubgroup(other):
            return cmp(type(self), type(other))

        c = cmp(self.level(), other.level())
        if c: return c

        # Since Gamma1(N) is GammaH(N) for H all of (Z/N)^\times,
        # we know how to compare it to any other GammaH without having
        # to look at self._list_of_elements_in_H().
        if is_GammaH(other):
            if is_Gamma1(other):
                return 0
            else:
                H = other._generators_for_H()
                return cmp(0, len(H))
        return cmp(type(self), type(other))