Ejemplo n.º 1
0
    def generators(self):
        r"""
        Return generators for this congruence subgroup.

        The result is cached.

        EXAMPLE::

            sage: for g in Gamma0(3).generators():
            ...     print g
            ...     print '---'
            [1 1]
            [0 1]
            ---
            [-1  0]
            [ 0 -1]
            ---
            ...
            ---
            [ 1  0]
            [-3  1]
            ---
        """
        from sage.modular.modsym.p1list import P1List
        from congroup_pyx import generators_helper
        level = self.level()
        if level == 1: # P1List isn't very happy working mod 1
            return [ self([0,-1,1,0]), self([1,1,0,1]) ]
        gen_list = generators_helper(P1List(level), level, Mat2Z)
        return [self(g, check=False) for g in gen_list]
    def get_representatives(self, t, N):
        r"""
        A helper function used in hecke_coeff that computes the right
        coset representatives of $\Gamma^0(t) \cap \Gamma_0(N) \ Gamma_0(N)$ where
        $\Gamma^0(t)$ is the subgroup of $SL(2,Z)$ where the upper right hand
        corner is divisible by $t$.

        NOTE
            We use the bijection $\Gamma^0(t)\SL(2,Z) \rightarrow P^1(\Z/t\Z)$
            given by $A \mapsto [1:0]A$.
        """
        if t == 1: return [(1, 0, 0, 1)]

        rep_list = []

        for (x, y) in P1List(t):
            ## we know that (N, x, y) = 1
            N1 = gcd(N, x)
            if N1 != 1:
                x = x + t * N // N1

            ## we calculate a pair c,d satisfying a minimality condition
            ## to make later multiplications cheaper
            (_, d, c) = Integer(x)._xgcd(Integer(N * y), minimal=True)

            #print (x, y, -N * c, d)
            rep_list.append((x, y, -N * c, d))

        return rep_list
Ejemplo n.º 3
0
    def generators(self, algorithm="farey"):
        r"""
        Return generators for this congruence subgroup.

        INPUT:

        - ``algorithm`` (string): either ``farey`` (default) or
          ``todd-coxeter``.

        If ``algorithm`` is set to ``"farey"``, then the generators will be
        calculated using Farey symbols, which will always return a *minimal*
        generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for
        more information.

        If ``algorithm`` is set to ``"todd-coxeter"``, a simpler algorithm
        based on Todd-Coxeter enumeration will be used. This tends to return
        far larger sets of generators.

        EXAMPLE::

            sage: Gamma0(3).generators()
            [
            [1 1]  [-1  1]
            [0 1], [-3  2]
            ]
            sage: Gamma0(3).generators(algorithm="todd-coxeter")
            [
            [1 1]  [-1  0]  [ 1 -1]  [1 0]  [1 1]  [-1  0]  [ 1  0]
            [0 1], [ 0 -1], [ 0  1], [3 1], [0 1], [ 3 -1], [-3  1]
            ]
            sage: SL2Z.gens()
            (
            [ 0 -1]  [1 1]
            [ 1  0], [0 1]
            )
        """
        if self.level() == 1:
            # we return a fixed set of generators for SL2Z, for historical
            # reasons, which aren't the ones the Farey symbol code gives
            return [self([0, -1, 1, 0]), self([1, 1, 0, 1])]

        elif algorithm == "farey":
            return self.farey_symbol().generators()

        elif algorithm == "todd-coxeter":
            from sage.modular.modsym.p1list import P1List
            from .congroup import generators_helper
            level = self.level()
            if level == 1:  # P1List isn't very happy working mod 1
                return [self([0, -1, 1, 0]), self([1, 1, 0, 1])]
            gen_list = generators_helper(P1List(level), level)
            return [self(g, check=False) for g in gen_list]

        else:
            raise ValueError(
                "Unknown algorithm '%s' (should be either 'farey' or 'todd-coxeter')"
                % algorithm)
Ejemplo n.º 4
0
    def schmidt_t5_eigenvalue_numerical(self, t):
        (tau1, z, tau2) = t
        from sage.libs.mpmath import mp
        from sage.libs.mpmath.mp import exp, pi
        from sage.libs.mpmath.mp import j as i

        if not Integer(self.__level()).is_prime():
            raise ValueError("T_5 is only unique if the level is a prime")

        precision = ParamodularFormD2Filter_trace(self.precision())

        s = Sequence([tau1, z, tau2])
        if not is_ComplexField(s):
            mp_precision = 30
        else:
            mp_precision = ceil(3.33 * s.universe().precision())
        mp.dps = mp_precision

        p1list = P1List(self.level())

        ## Prepare the operation for d_1(N)
        ## We have to invert the lifts since we will later use apply_GL_to_form
        d1_matrices = [p1list.lift_to_sl2z(i) for i in range(len(p1list))]
        d1_matrices = [(a_b_c_d[3], -a_b_c_d[1], -a_b_c_d[2], a_b_c_d[0])
                       for a_b_c_d in d1_matrices]

        ## Prepare the evaluation points corresponding to d_02(N)
        d2_points = list()
        for i in range(len(p1list())):
            (a, b, c, d) = p1list.lift_to_sl2z(i)
            tau1p = (a * tau1 + b) / (c * tau1 + d)
            zp = z / (c * tau1 + d)
            tau2p = tau2 - c * z**2 / (c * tau1 + d)

            (e_tau1p, e_zp, e_tau2p) = (exp(2 * pi * i * tau1p),
                                        exp(2 * pi * i * zp),
                                        exp(2 * pi * i * tau2p))
            d2_points.append((e_tau1p, e_zp, e_tau2p))

        (e_tau1, e_z, e_tau2) = (exp(2 * pi * i * tau1), exp(2 * pi * i * z),
                                 exp(2 * pi * i * tau2))

        self_value = s.universe().zero()
        trans_value = s.universe().zero()

        for k in precision:
            (a, b, c) = apply_GL_to_form(self._P1List()(k[1]), k[0])

            self_value = self_value + self[k] * e_tau1**a * e_z**b * e_tau2**c
            for m in d1_matrices:
                (ap, bp, cp) = apply_GL_to_form(m, (a, b, c))

                for (e_tau1p, e_zp, e_tau2p) in d2_points:
                    trans_value = trans_value + self[((
                        ap, bp, cp), 0)] * e_tau1p**ap * e_zp**bp * e_tau2p**cp

        return trans_value / self_value
 def __init__(self, level, reduced = True) :
     if level == 1 :
         ## P1List(1) does not accept 1 as an index which is what we consider the
         ## unit element in GL(2, ZZ)
         raise NotImplementedError( "Level must not be 1")
     self.__level = level
     self.__reduced = reduced
     
     self.__p1list = P1List(level)
    def __init__(self, precision, level, reduced = True) :
        self.__level = level
        
        if isinstance(precision, ParamodularFormD2Filter_trace) :
            precision = precision.index()
        elif isinstance(precision, ParamodularFormD2Filter_discriminant) :
            if precision.index() is infinity :
                precision = infinity
            else :
                precision = isqrt(precision.index() - 1) + 1 

        self.__trace = precision
        self.__reduced = reduced
        self.__p1list = P1List(level)
Ejemplo n.º 7
0
    def get_P1List(self):
        """
        Generates the projective line of O_F/N, where N is an ideal specified
        in the input, or computed from a parent object (e.g. arithmetic group).
        """
        N = self.level

        ## Return object representing Projective line over O_F/N
        if hasattr(N,'number_field'): ## Base field not Q
            # from sage.modular.modsym.p1list_nf import P1NFList
            from .my_p1list_nf import P1NFList
            return P1NFList(N)
        else:   ## Base field Q
            from sage.modular.modsym.p1list import P1List
            return P1List(N)
    def __init__(self, disc, level, reduced = True) :
        self.__level = level
        
        if isinstance(disc, ParamodularFormD2Filter_discriminant) :
            disc = disc.index()

        if disc is infinity :
            self.__disc = disc
        else :
            oDmod = (-disc + 1) % (4 * level)
            Dmod = oDmod
            while Dmod > 0 :
                if not Mod(Dmod, 4 * level) :
                    Dmod = Dmod - 1
                else :
                    break
            
            self.__disc = disc - (oDmod - Dmod)
             
        self.__reduced = reduced
        
        self.__p1list = P1List(level)
Ejemplo n.º 9
0
 from sage.libs.mpmath.mp import exp, pi
 from sage.libs.mpmath.mp import j as i
 
 if not Integer(self.__level()).is_prime() :
     raise ValueError, "T_5 is only unique if the level is a prime"
 
 precision = ParamodularFormD2Filter_trace(self.precision())
 
 s = Sequence([tau1, z, tau2])
 if not is_ComplexField(s) :
     mp_precision = 30
 else :
     mp_precision = ceil(3.33 * s.universe().precision())
 mp.dps = mp_precision
 
 p1list = P1List(self.level())
 
 ## Prepare the operation for d_1(N)
 ## We have to invert the lifts since we will later use apply_GL_to_form
 d1_matrices = [p1list.lift_to_sl2z(i) for i in xrange(len(p1list))]
 d1_matrices = map(lambda (a,b,c,d): (d,-b,-c,a), d1_matrices)
 
 ## Prepare the evaluation points corresponding to d_02(N)
 d2_points = list()
 for i in xrange(len(p1list())) :
     (a, b, c, d) = p1list.lift_to_sl2z(i)
     tau1p = (a * tau1 + b) / (c * tau1 + d)
     zp = z / (c * tau1 + d)
     tau2p = tau2 - c * z**2 / (c * tau1 + d)
     
     (e_tau1p, e_zp, e_tau2p) = (exp(2 * pi * i * tau1p), exp(2 * pi * i * zp), exp(2 * pi * i * tau2p))