Exemple #1
0
 def atkin_lehner_eigenvalues_for_all_cusps(self):
     r"""
     """
     self._atkin_lehner_eigenvalues_at_cusps = {}
     G = Gamma0(self.level)
     for c in Gamma0(self.level).cusps():
         aev = self.atkin_lehner_eigenvalues()
         if aev is None:
             self._atkin_lehner_eigenvalues_at_cusps = None
         else:
             for Q, ev in aev.items():
                 if G.are_equivalent(c, Q / self.level):
                     self._atkin_lehner_eigenvalues_at_cusps[c] = Q, ev
     return self._atkin_lehner_eigenvalues_at_cusps
Exemple #2
0
    def get_shift_and_width_for_coset(self, n):
        r"""
        Compute the shift and width of coset nr. n.
        """
        if self._shift.has_key(n) and self._width.has_key(n):
            return self._shift[n], self._width[n]
        if not is_squarefree(self._level):
            raise NotImplementedError, "Only square-free levels implemented"
        G = Gamma0(self._level)
        A = self.coset_rep(n)
        a = A[0, 0]
        c = A[1, 0]
        width = G.cusp_width(Cusp(a, c))
        if self._verbose > 0:
            print "width=", width
        Amat = Matrix(ZZ, 2, 2, A.matrix().list())
        h = -1
        for j in range(width):
            Th = Matrix(ZZ, 2, 2, [width, -j, 0, 1])
            W = Amat * Th
            if self._verbose > 1:
                print "W=", W

            if self.is_involution(W):
                h = j
                break
        if h < 0:
            raise ArithmeticError, "Could not find shift!"
        self._shift[n] = h
        self._width[n] = width
        return h, width
Exemple #3
0
def congruence_groups_between_gamma0_and_gamma1(N):
    """
    INPUT:
        
    - N - an integer
    
    OUTPUT:
        
    - The set of all congruence subgroups contained in Gamma0(N) that contain Gamma1(N)
    
    EXAMPLES::

        sage: from mdsage import *
        sage: congruence_groups_between_gamma0_and_gamma1(1)
        {Modular Group SL(2,Z)}
    
        sage: congruence_groups_between_gamma0_and_gamma1(15)
        {Congruence Subgroup Gamma_H(15) with H generated by [14],
         Congruence Subgroup Gamma_H(15) with H generated by [4, 11, 14],
         Congruence Subgroup Gamma0(15)}
    """
    if N == 1:
        return set([Gamma0(1)])
    level_N_modular_groups = set([])
    for gens in generators_of_subgroups_of_unit_group(Integers(N)):
        gens = gens+[-1]
        H = sage.modular.arithgroup.congroup_gammaH._list_subgroup(N,gens)
        G = GammaH(N,H)
        level_N_modular_groups.add(G)
    return level_N_modular_groups
Exemple #4
0
def get_geometric_data_Gamma0N(N):
    res = dict()
    G = Gamma0(N)
    res['index'] = G.index()
    res['genus'] = G.genus()
    res['cusps'] = G.cusps()
    res['nu2'] = G.nu2()
    res['nu3'] = G.nu3()
    return res
Exemple #5
0
    def __init__(self,
                 A,
                 B,
                 r,
                 s,
                 k=None,
                 number=0,
                 ch=None,
                 dual=False,
                 version=1,
                 **kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)

        EXAMPLE:
        
                
        """
        self._level = lcm(A, B)
        G = Gamma0(self._level)
        if k == None:
            k = (QQ(r) - QQ(s)) / QQ(2)
        self._weight = QQ(k)
        if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight -
                                                       QQ(1) / QQ(2)):
            self._half_integral_weight = 1
        else:
            self._half_integral_weight = 0
        MultiplierSystem.__init__(self,
                                  G,
                                  dimension=1,
                                  character=ch,
                                  dual=dual)
        number = number % 12
        if not is_even(number):
            raise ValueError("Need to have v_eta^(2(k+r)) with r even!")
        self._arg_num = A
        self._arg_den = B
        self._exp_num = r
        self._exp_den = s
        self._pow = QQ((self._weight + number))  ## k+r
        self._k_den = self._pow.denominator()
        self._k_num = self._pow.numerator()
        self._K = CyclotomicField(12 * self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num
        self._version = version
        self.is_consistent(k)  # test consistency
Exemple #6
0
 def _set_coset_reps(self):
     if is_prime(self._level):
         self._coset_reps[0] = SL2Z([1, 0, 0, 1])
         for n in range(self._level):
             self._coset_reps[n + 1] = SL2Z([0, -1, 1, n])
     else:
         G = Gamma0(self._level)
         n = 0
         for A in G.coset_reps():
             self._coset_reps[n] = A
             n += 1
Exemple #7
0
 def atkin_lehner(self, n):
     r"""
     Compute the Atkin-Lehner eigenvalue at the cusp of coset nr. n.
     """
     if not self._atkin_lehner.has_key(n):
         A = self.coset_rep(n)
         c = Cusp(A[0, 0], A[1, 0])
         G = Gamma0(self._level)
         for Q in divisors(self._level):
             cQ = Cusp(Q, self._level)
             if G.are_equivalent(c, cQ):
                 self._atkin_lehner[n] = self._f.atkin_lehner_eigenvalue(Q)
                 break
     return self._atkin_lehner[n]
Exemple #8
0
def print_geometric_data_Gamma0N(N):
    r""" Print data about Gamma0(N).
    """
    G = Gamma0(N)
    s = ""
    s = "<table>"
    s += "<tr><td>index:</td><td>%s</td></tr>" % G.index()
    s += "<tr><td>genus:</td><td>%s</td></tr>" % G.genus()
    s += "<tr><td>Cusps:</td><td>\(%s\)</td></tr>" % latex(G.cusps())
    s += "<tr><td colspan=\"2\">Number of elliptic fixed points</td></tr>"
    s += "<tr><td>order 2:</td><td>%s</td></tr>" % G.nu2()
    s += "<tr><td>order 3:</td><td>%s</td></tr>" % G.nu3()
    s += "</table>"
    return s
Exemple #9
0
def get_geometric_data(N, group=0):
    res = dict()
    if group == 0:
        G = Gamma0(N)
    elif group == 1:
        G = Gamma1(N)
    else:
        return None
    res['index'] = G.index()
    res['genus'] = G.genus()
    res['cusps'] = G.cusps()
    res['nu2'] = G.nu2()
    res['nu3'] = G.nu3()
    return res
Exemple #10
0
 def _get_coset_n(self, A):
     r"""
     Find n s.t. A in Gamma_0(N)A_n 
     """
     G = Gamma0(self._level)
     if A in G:
         return 0  ## Always use 0 for the trivial coset
     else:
         n = 0
         for n in range(self._dim):
             An = self.coset_rep(n)
             if A * An**-1 in G:
                 return n
             n += 1
     raise ArithmeticError, "Can not find coset of A={0}".format(A)
Exemple #11
0
    def __init__(self,
                 args=[1],
                 exponents=[1],
                 ch=None,
                 dual=False,
                 version=1,
                 **kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)

        EXAMPLE:
        
                
        """
        assert len(args) == len(exponents)
        self._level = lcm(args)
        G = Gamma0(self._level)
        k = sum([QQ(x) * QQ(1) / QQ(2) for x in exponents])
        self._weight = QQ(k)
        if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight -
                                                       QQ(1) / QQ(2)):
            self._half_integral_weight = 1
        else:
            self._half_integral_weight = 0
        MultiplierSystem.__init__(self,
                                  G,
                                  dimension=1,
                                  character=ch,
                                  dual=dual)
        self._arguments = args
        self._exponents = exponents
        self._pow = QQ((self._weight))  ## k+r
        self._k_den = self._weight.denominator()
        self._k_num = self._weight.numerator()
        self._K = CyclotomicField(12 * self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num
        self._version = version
        self.is_consistent(k)  # test consistency
Exemple #12
0
def is_formal_immersion(d, p):
    """This funtion returns an integer n such that we have a formall immersion in
    characteristic q != 2,p if and only if q does not divide n.
    """
    G = Gamma0(p)
    M = ModularSymbols(G, 2)
    S = M.cuspidal_subspace()
    I2 = M.hecke_operator(2) - 3
    if I2.matrix().rank() != S.dimension():
        raise RuntimeError(f"Formall immersion for d={d} p={p} failed"
                           "because I2 is not of the expected rank.")
    Te = R_dp(G.sturm_bound(), p).row_module()
    R = (R_dp(d, p).restrict_codomain(Te)).change_ring(ZZ)
    if R.rank() < d:
        return 0
    D = R.elementary_divisors()
    if D and D[-1]:
        return D[-1].prime_to_m_part(2)
    return 0
Exemple #13
0
def R_dp(d, p):
    """Return the formal immersion matrix
    Args:
        d ([int]): degree of number field
        p ([prime]): prime whose formal immersion properties we'd like to check
    Returns:
        [Matrix]: The Matrix whose rows are (T_2-3)*T_i e  for i <= d.
                  This is for verifying the linear independance in
                  Corollary 6.4 of Derickx-Kamienny-Stein-Stoll.
    """
    M = ModularSymbols(Gamma0(p), 2)
    S = M.cuspidal_subspace()
    S_int = S.integral_structure()
    e = M([0, oo])
    I2 = M.hecke_operator(2) - 3

    def get_row(i):
        return S_int.coordinate_vector(
            S_int(M.coordinate_vector(I2(M.hecke_operator(i)(e)))))

    return Matrix([get_row(i) for i in range(1, d + 1)]).change_ring(ZZ)
Exemple #14
0
 def is_involution(self, W, verbose=0):
     r"""
     Explicit test if W is an involution of Gamma0(self._level)
     """
     G = Gamma0(self._level)
     for g in G.gens():
         gg = Matrix(ZZ, 2, 2, g.matrix().list())
         g1 = W * gg * W**-1
         if verbose > 0:
             print "WgW^-1=", g1
         if g1 not in G:
             return False
     W2 = W * W
     c = gcd(W2.list())
     if c > 1:
         W2 = W2 / c
     if verbose > 0:
         print "W^2=", W2
     if W2 not in G:
         return False
     return True
Exemple #15
0
    def __init__(self, p, congruence_type=1, sign=1, algorithm="custom", verbose=False, dump_dir=None):
        """
        Create a Kamienny criterion object.

        INPUT:

            - `p` -- prime -- verify that there is no order p torsion
              over a degree `d` field
            - `sign` -- 1 (default),-1 or 0 -- the sign of the modular symbols space to use 
            - ``algorithm`` -- "default" or "custom" whether to use a custom (faster)
              integral structure algorithm or to use the sage builtin algortihm
            - ``verbose`` -- bool; whether to print extra stuff while
              running.

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29, algorithm="custom", verbose=False); C
            Kamienny's Criterion for p=29
            sage: C.use_custom_algorithm
            True
            sage: C.p
            29
            sage: C.verbose
            False        
        """
        self.verbose = verbose
        self.dump_dir = dump_dir
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("init")
        assert congruence_type == 0 or congruence_type == 1
        self.congruence_type=congruence_type
        try:
            p = ZZ(p)
            if congruence_type==0:
                self.congruence_group = Gamma0(p)
            if congruence_type==1:
                self.congruence_group = GammaH(p,[-1])
        except TypeError:
            self.congruence_group = GammaH(p.level(),[-1]+p._generators_for_H())
            self.congruence_type = ("H",self.congruence_group._list_of_elements_in_H())
            
        self.p = self.congruence_group.level()
  
        self.algorithm=algorithm
        self.sign=sign
        
        self.M = ModularSymbols(self.congruence_group, sign=sign)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "modsym")
        self.S = self.M.cuspidal_submodule()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "cuspsub")
        self.use_custom_algorithm = False
        if algorithm=="custom":
            self.use_custom_algorithm = True
        if self.use_custom_algorithm:
            int_struct = self.integral_cuspidal_subspace()
            if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "custom int_struct")
        else:    
            int_struct = self.S.integral_structure()
            if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "sage int_struct")
        self.S_integral = int_struct
        v = VectorSpace(GF(2), self.S.dimension()).random_element()
        self.v=v
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "rand_vect")
        if dump_dir:
            v.dump(dump_dir+"/vector%s_%s" % (p,congruence_type))
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "dump")
Exemple #16
0
def sturm_bound0(level, weight):
    return floor(weight * Gamma0(level).index() / 12)
 def init_dynamic_properties(self):
     if self.character.is_trivial():
         self.group = Gamma0(self.level)
     else:
         self.group = Gamma1(self.level)
Exemple #18
0
    def __init__(self, db, maassid, **kwds):
        r"""
        Setup a Maass form from maassid in the database db
        of the type MaassDB.
        OPTIONAL parameters:
        - dirichlet_c_only = 0 or 1
        -fnr = get the Dirichlet series coefficients of this function in self only
        - get_coeffs = False if we do not compute or fetch coefficients
        """
        mwf_logger.debug(
            "calling WebMaassform with DB={0} and maassid={1}, kwds={2}".format(db, maassid, kwds))
        self._db = db
        self.R = None
        self.symmetry = -1
        self.weight = 0
        self.character = 0
        self.level = 1
        self.table = {}
        self.coeffs = {}
        if not isinstance(maassid, (bson.objectid.ObjectId, str)):
            ids = db.find_Maass_form_id(id=maassid)
            if len(ids) == 0:
                raise KeyError("maassid %s not found in database"%maassid)
            mwf_logger.debug("maassid is not an objectid! {0}".format(maassid))
            maassid = ids[0]
        self._maassid = bson.objectid.ObjectId(maassid)
        mwf_logger.debug("_id={0}".format(self._maassid))
        ff = db.get_Maass_forms(id=self._maassid)
        # print "ff=",ff
        if len(ff) == 0:
            raise KeyError("massid %s not found in database"%maassid)
        f = ff[0]

        # print "f here=",f
        self.dim = f.get('Dim', 1)
        if self.dim == 0:
            self.dim = 1

        self.R = f.get('Eigenvalue', None)
        self.symmetry = f.get('Symmetry', -1)
        self.weight = f.get('Weight', 0)
        self.character = f.get('Character', 0)
        self.cusp_evs = f.get('Cusp_evs', [])
        self._fricke = f.get('Fricke', 0)
        self.error = f.get('Error', 0)
        self.level = f.get('Level', None)
        ## Contributor key
        self.contr = f.get('Contributor', '')
        md = db._mongo_db['metadata'].find_one({'c_name': self.contr})
        ## Contributor full name
        try:
            self.contributor_name = md.get('contributor', self.contr)
        except:
            self.contributor_name = self.contr
        self.num_coeff = f.get('Numc', 0)
        if self.R is None or self.level is None:
            return
        ## As default we assume we just have c(0)=1 and c(1)=1
        self._get_dirichlet_c_only = kwds.get('get_dirichlet_c_only', False)
        self._num_coeff0 = kwds.get('num_coeffs', self.num_coeff)
        self._get_coeffs = kwds.get('get_coeffs', True)
        self._fnr = kwds.get('fnr', 0)
        if self._get_coeffs:
            self.coeffs = f.get('Coefficient', [0, 1, 0, 0, 0])

            if self.coeffs != [0,1,0,0,0]:
                self.num_coeff = len(self.coeffs)

            if self._get_dirichlet_c_only:
                # if self.coeffs!=[0,1,0,0,0]:
                if len(self.coeffs) == 1:
                    self.coeffs = self.coeffs[0]
            else:
                res = {}
                for n in range(len(self.coeffs)):
                    res[n] = self.coeffs[n]
                self.coeffs = res
                self.coeffs = {0: {0: self.coeffs}}

        else:
            self.coeffs = {}
        coeff_id = f.get('coeff_id', None)
        nc = Gamma0(self.level).ncusps()
        self.M0 = f.get('M0', nc)
        mwf_logger.debug("coeffid={0}, get_coeffs={1}".format(coeff_id, self._get_coeffs))
        if coeff_id and self._get_coeffs:  # self.coeffs==[] and coeff_id:
            ## Let's see if we have coefficients stored
            C = self._db.get_coefficients({"_id": self._maassid})
            if len(C) >= 1:
                C = C[0]
                if self._get_dirichlet_c_only:
                    mwf_logger.debug("setting Dirichlet C!")
                    if self._fnr > len(C):
                        self._fnr = 0
                    if self._num_coeff0 > len(C[self._fnr][0]) - 1:
                        self._num_coeff0 = len(C[self._fnr][0]) - 1
                    self.coeffs = []
                    for j in range(1, self._num_coeff0 + 1):
                        self.coeffs.append(C[self._fnr][0][j])
                else:
                    mwf_logger.debug("setting C!")
                    self.coeffs = C
         ## Make sure that self.coeffs is only the current coefficients
        if self._get_coeffs and isinstance(self.coeffs, dict) and not self._get_dirichlet_c_only:
            if not isinstance(self.coeffs, dict):
                mwf_logger.warning("Coefficients s not a dict. Got:{0}".format(type(self.coeffs)))
            else:
                n1 = len(self.coeffs.keys())
                mwf_logger.debug("|coeff.keys()|:{0}".format(n1))
                if n1 != self.dim:
                    mwf_logger.warning("Got coefficient dict of wrong format!:dim={0} and len(c.keys())={1}".format(self.dim, n1))
                if n1 > 0:
                    for j in range(self.dim):
                        n2 = len(self.coeffs.get(j, {}).keys())
                        mwf_logger.debug("|coeff[{0}].keys()|:{1}".format(j, n2))
                        if n2 != nc:
                            mwf_logger.warning("Got coefficient dict of wrong format!:num cusps={0} and len(c[0].keys())={1}".format(nc, n2))

        self.nc = 1  # len(self.coeffs.keys())
        if not self._get_dirichlet_c_only:
            pass  # self.set_table()
        else:
            self.table = {}
Exemple #19
0
    def __init__(self, maass_id, **kwds):
        r"""
        Setup a Maass form from maass_id in the database db
        of the type MaassDB.
        OPTIONAL parameters:
        - dirichlet_c_only = 0 or 1
        -fnr = get the Dirichlet series coefficients of this function in self only
        - get_coeffs = False if we do not compute or fetch coefficients
        """
        self.R = None
        self.symmetry = -1
        self.weight = 0
        self.character = 0
        self.level = 1
        self.table = {}
        self.coeffs = {}
        self._maass_id = maass_id
        f = maass_db.lucky({'maass_id': maass_id})
        if f is None:
            raise KeyError("massid %s not found in database" % maass_id)

        # print "f here=",f
        self.dim = f.get('Dim', 1)
        if self.dim == 0:
            self.dim = 1

        self.R = f.get('Eigenvalue', None)
        self.symmetry = f.get('Symmetry', -1)
        self.weight = f.get('Weight', 0)
        self.character = f.get('Character', 0)
        self.cusp_evs = f.get('Cusp_evs', [])
        self._fricke = f.get('Fricke', 0)
        self.error = f.get('Error', 0)
        self.level = f.get('Level', None)
        ## Contributor key
        self.contr = f.get('Contributor', '')
        if self.contr == 'FS':
            self.contributor_name = 'Fredrik Stroemberg'
        elif self.contr == 'HT':
            self.contributor_name = 'Holger Then'
        else:
            self.contributor_name = self.contr
        self.num_coeff = f.get('Numc', 0)
        if self.R is None or self.level is None:
            return
        ## As default we assume we just have c(0)=1 and c(1)=1
        self._get_dirichlet_c_only = kwds.get('get_dirichlet_c_only', False)
        self._num_coeff0 = kwds.get('num_coeffs', self.num_coeff)
        self._get_coeffs = kwds.get('get_coeffs', True)
        self._fnr = kwds.get('fnr', 0)
        if self._get_coeffs:
            self.coeffs = f.get('Coefficient', [0, 1, 0, 0, 0])

            if self.coeffs != [0, 1, 0, 0, 0]:
                self.num_coeff = len(self.coeffs)

            if self._get_dirichlet_c_only:
                # if self.coeffs!=[0,1,0,0,0]:
                if len(self.coeffs) == 1:
                    self.coeffs = self.coeffs[0]
            else:
                res = {}
                for n in range(len(self.coeffs)):
                    res[n] = self.coeffs[n]
                self.coeffs = res
                self.coeffs = {0: {0: self.coeffs}}

        else:
            self.coeffs = {}
        nc = Gamma0(self.level).ncusps()
        self.M0 = f.get('M0', nc)
        mwf_logger.debug("maass_id={0}, get_coeffs={1}".format(
            maass_id, self._get_coeffs))
        if self._get_coeffs:  # self.coeffs==[] and maass_id:
            ## Let's see if we have coefficients stored
            C = maass_db.get_coefficients({"maass_id": self._maass_id})
            if C is not None:
                if self._get_dirichlet_c_only:
                    mwf_logger.debug("setting Dirichlet C!")
                    if self._fnr > len(C):
                        self._fnr = 0
                    if self._num_coeff0 > len(C[self._fnr][0]) - 1:
                        self._num_coeff0 = len(C[self._fnr][0]) - 1
                    self.coeffs = []
                    for j in range(1, self._num_coeff0 + 1):
                        self.coeffs.append(C[self._fnr][0][j])
                else:
                    mwf_logger.debug("setting C!")
                    self.coeffs = C
        ## Make sure that self.coeffs is only the current coefficients
        if self._get_coeffs and isinstance(
                self.coeffs, dict) and not self._get_dirichlet_c_only:
            if not isinstance(self.coeffs, dict):
                mwf_logger.warning("Coefficients s not a dict. Got:{0}".format(
                    type(self.coeffs)))
            else:
                n1 = len(self.coeffs.keys())
                mwf_logger.debug("|coeff.keys()|:{0}".format(n1))
                if n1 != self.dim:
                    mwf_logger.warning(
                        "Got coefficient dict of wrong format!:dim={0} and len(c.keys())={1}"
                        .format(self.dim, n1))
                if n1 > 0:
                    for j in range(self.dim):
                        n2 = len(self.coeffs.get(j, {}).keys())
                        mwf_logger.debug("|coeff[{0}].keys()|:{1}".format(
                            j, n2))
                        if n2 != nc:
                            mwf_logger.warning(
                                "Got coefficient dict of wrong format!:num cusps={0} and len(c[0].keys())={1}"
                                .format(nc, n2))

        self.nc = 1  # len(self.coeffs.keys())
        if not self._get_dirichlet_c_only:
            pass  # self.set_table()
        else:
            self.table = {}
Exemple #20
0
def draw_fundamental_domain(N,
                            group='Gamma0',
                            model="H",
                            axes=None,
                            filename=None,
                            **kwds):
    r""" Draw fundamental domain
    INPUT:
    - ''model'' -- (default ''H'')
    = ''H'' -- Upper halfplane
    = ''D'' -- Disk model
    - ''filename''-- filename to print to
    - ''**kwds''-- additional arguments to matplotlib
    - ''axes''  -- set geometry of output
    =[x0,x1,y0,y1] -- restrict figure to [x0,x1]x[y0,y1]

    EXAMPLES::

    sage: G=MySubgroup(Gamma0(3))
    sage: G.draw_fundamental_domain()

    """
    if group.strip() == 'Gamma0':
        G = Gamma0(N)
    elif group.strip() == 'Gamma1':
        G = Gamma1(N)
    elif group.strip() == 'Gamma':
        G = Gamma(N)
    else:
        raise ValueError('group must be one of: "Gamma0", "Gamma1", "Gamma"')
    s = "$" + latex(G) + "$"
    s = s.replace("mbox", "mathrm")
    s = s.replace("Bold", "mathbb")
    name = s
    # name ="$\mbox{SL}_{2}(\mathbb{Z})$"
    # need a "nice" set of coset representatives to draw a connected
    # fundamental domain. Only implemented for Gamma_0(N)
    coset_reps = nice_coset_reps(G)
    # if(group=='Gamma0'):
    # else:
    # coset_reps = list(G.coset_reps())
    from matplotlib.backends.backend_agg import FigureCanvasAgg
    if (model == "D"):
        g = _draw_funddom_d(coset_reps, format, I)
    else:
        g = _draw_funddom(coset_reps, format)
    if (axes is not None):
        [x0, x1, y0, y1] = axes
    elif (model == "D"):
        x0 = -1
        x1 = 1
        y0 = -1.1
        y1 = 1
    else:
        # find the width of the fundamental domain
        # w = 0  # self.cusp_width(Cusp(Infinity)) FIXME: w is never used
        wmin = 0
        wmax = 1
        max_x = RR(0.55)
        rho = CC(exp(2 * pi * I / 3))
        for V in coset_reps:
            ## we also compare the real parts of where rho and infinity are mapped
            r1 = (V.acton(rho)).real()
            if (V[1, 0] != 0):
                inf1 = RR(V[0, 0] / V[1, 0])
            else:
                inf1 = 0
            if (V[1, 0] == 0 and V[0, 0] == 1):
                if (V[0, 1] > wmax):
                    wmax = V[0, 1]
                if (V[0, 1] < wmin):
                    wmin = V[0, 1]
            if (max(r1, inf1) > max_x):
                max_x = max(r1, inf1)
            logging.debug("wmin,wmax=%s,%s" % (wmin, wmax))
        # x0=-1; x1=1; y0=-0.2; y1=1.5
        x0 = RR(-max_x)
        x1 = RR(max_x)
        y0 = RR(-0.15)
        y1 = RR(1.5)
        ## Draw the axes manually (since  can't figure out how to do it automatically)
    ax = line([[x0, 0.0], [x1, 0.0]], color='black')
    # ax = ax + line([[0.0,y0],[0.0,y1]],color='black')
    ## ticks
    ax = ax + line([[-0.5, -0.01], [-0.5, 0.01]], color='black')
    ax = ax + line([[0.5, -0.01], [0.5, 0.01]], color='black')
    g = g + ax
    if model == "H":
        t = text(name, (0, -0.1), fontsize=16, color='black')
        t = t + text(
            "$ -\\frac{1}{2} $", (-0.5, -0.1), fontsize=12, color='black')
        t = t + text(
            "$ \\frac{1}{2} $", (0.5, -0.1), fontsize=12, color='black')
    else:
        t = text(name, (0, -1.1), fontsize=16, color='black')
    g = g + t
    g.set_aspect_ratio(1)
    g.set_axes_range(x0, x1, y0, y1)
    g.axes(False)

    if (filename is not None):
        fig = g.matplotlib()
        fig.set_canvas(FigureCanvasAgg(fig))
        axes = fig.get_axes()[0]
        axes.minorticks_off()
        axes.set_yticks([])
        fig.savefig(filename, **kwds)
    else:
        return g
Exemple #21
0
    def __init__(self,
                 WR,
                 weight=QQ(1) / QQ(2),
                 use_symmetry=True,
                 group=SL2Z,
                 dual=False,
                 **kwargs):
        r"""
        WR should be a Weil representation.
        INPUT:
         - weight -- weight (should be consistent with the signature of self)
         - use_symmetry -- if False we do not symmetrize the functions with respect to Z
                        -- if True we need a compatible weight
        - 'group' -- Group to act on.
        """
        if isinstance(WR, (Integer, int)):
            #self.WR=WeilRepDiscriminantForm(WR)
            #self.WR=WeilModule(WR)
            self._weil_module = WeilModule(WR)
        elif hasattr(WR, "signature"):
            self._weil_module = WR
        else:
            raise ValueError("{0} is not a Weil module!".format(WR))
        self._sym_type = 0

        if group.level() != 1:
            raise NotImplementedError(
                "Only Weil representations of SL2Z implemented!")
        self._group = MySubgroup(Gamma0(1))
        self._dual = int(dual)
        self._sgn = (-1)**self._dual
        self.Qv = []
        self._weight = weight
        self._use_symmetry = use_symmetry
        self._kwargs = kwargs
        self._sgn = (-1)**int(dual)
        half = QQ(1) / QQ(2)
        threehalf = QQ(3) / QQ(2)
        if use_symmetry:
            ## First find weight mod 2:
            twok = QQ(2) * QQ(weight)
            if not twok.is_integral():
                raise ValueError(
                    "Only integral or half-integral weights implemented!")
            kmod2 = QQ(twok % 4) / QQ(2)
            if dual:
                sig_mod_4 = -self._weil_module.signature() % 4
            else:
                sig_mod_4 = self._weil_module.signature() % 4
            sym_type = 0
            if (kmod2, sig_mod_4) in [(half, 1), (threehalf, 3), (0, 0),
                                      (1, 2)]:
                sym_type = 1
            elif (kmod2, sig_mod_4) in [(half, 3), (threehalf, 1), (0, 2),
                                        (1, 0)]:
                sym_type = -1
            else:
                raise ValueError(
                    "The Weil module with signature {0} is incompatible with the weight {1}!"
                    .format(self._weil_module.signature(), weight))
            ## Deven and Dodd contains the indices for the even and odd basis
            Deven = []
            Dodd = []
            if sym_type == 1:
                self._D = self._weil_module.even_submodule(indices=1)
            else:  #sym_type==-1:
                self._D = self._weil_module.odd_submodule(indices=1)
            self._sym_type = sym_type
            dim = len(self._D)  #Dfinish-Dstart+1
        else:
            dim = len(self._weil_module.finite_quadratic_module().list())
            self._D = list(range(dim))
            self._sym_type = 0
        if hasattr(self._weil_module, "finite_quadratic_module"):
            #            for x in list(self._weil_module.finite_quadratic_module()):
            for x in self._weil_module.finite_quadratic_module():
                self.Qv.append(
                    self._weil_module.finite_quadratic_module().Q(x))
        else:
            self.Qv = self._weil_module.Qv
        ambient_rank = self._weil_module.rank()
        MultiplierSystem.__init__(self,
                                  self._group,
                                  dual=dual,
                                  dimension=dim,
                                  ambient_rank=ambient_rank)
Exemple #22
0
    def __init__(self, G, v=None, **kwargs):
        r"""
        G should be a subgroup of PSL(2,Z).

        EXAMPLE::

        sage: te=TestMultiplier(Gamma0(2),weight=1/2)
        sage: r=InducedRepresentation(Gamma0(2),v=te)

        """
        dim = len(list(G.coset_reps()))
        MultiplierSystem.__init__(self, Gamma0(1), dimension=dim)
        self._induced_from = G
        # setup the action on S and T (should be faster...)
        self.v = v
        if v != None:

            k = v.order()
            if k > 2:
                K = CyclotomicField(k)
            else:
                K = ZZ
            self.S = matrix(K, dim, dim)
            self.T = matrix(K, dim, dim)
        else:
            self.S = matrix(dim, dim)
            self.T = matrix(dim, dim)
        S, T = SL2Z.gens()
        if hasattr(G, "coset_reps"):
            if isinstance(G.coset_reps(), list):
                Vl = G.coset_reps()
            else:
                Vl = list(G.coset_reps())
        elif hasattr(G, "_G"):
            Vl = list(G._G.coset_reps())
        else:
            raise ValueError(
                "Could not get coset representatives from {0}!".format(G))
        self.repsT = dict()
        self.repsS = dict()
        for i in range(dim):
            Vi = Vl[i]
            for j in range(dim):
                Vj = Vl[j]
                BS = Vi * S * Vj**-1
                BT = Vi * T * Vj**-1
                #print "i,j
                #print "ViSVj^-1=",BS
                #print "ViTVj^-1=",BT
                if BS in G:
                    if v != None:
                        vS = v(BS)
                    else:
                        vS = 1
                    self.S[i, j] = vS
                    self.repsS[(i, j)] = BS
                if BT in G:
                    if v != None:
                        vT = v(BT)
                    else:
                        vT = 1
                    self.T[i, j] = vT
                    self.repsT[(i, j)] = BT
Exemple #23
0
def sturm_bound0(level, weight):
    return (weight * Gamma0(level).index()) // 12
Exemple #24
0
    def __init__(self, f, prec=53, verbose=0, data={}):
        r"""
        Initialize the period polynomial of f.

        INPUT:
         - `f` -- Newform
         - ``
        
        EXAMPLES:

        # First elliptic curve

        sage: f=Newforms(11,2)[0]             
        sage: pp=PeriodPolynomial(f,prec=103)
        sage: L=f.cuspform_lseries()
        sage: pp.petersson_norm()
        0.00390834565612459898524738548154 - 5.53300833748482053164300189100e-35*I
        sage: pp.special_value(1)            
        0.253841860855910684337758923267
        sage: L(1)
        0.253841860855911

        # We can also study rationality of the coefficients of the 
        sage: pp.test_rationality()
        P(f 0)^+/omega_+=1.00000000000000000000000000000
        P(f 0)^-/omega_-=0
        P(f 1)^+/omega_+=-1.00000000000000000000000000000
        P(f 1)^-/omega_-=0
        P(f 2)^+/omega_+=0
        P(f 2)^-/omega_-=1.27412157006452456511355616309e-31 + 1.01489446868406102099789763444e-28*I
        P(f 3)^+/omega_+=-5.00000000000000000000000000133
        P(f 3)^-/omega_-=-1.16793587723237638257725820700e-60 + 8.24993716616779655911027615609e-29*I
        P(f 4)^+/omega_+=-2.50000000000000000000000000073
        P(f 4)^-/omega_-=-3.39765752017206550696948310188e-32 + 2.39999999999999999999999999940*I
        P(f 5)^+/omega_+=2.50000000000000000000000000073
        P(f 5)^-/omega_-=-3.39765752017206550696948310188e-32 + 2.39999999999999999999999999940*I
        P(f 6)^+/omega_+=5.00000000000000000000000000133
        P(f 6)^-/omega_-=1.16793587723237638257725820700e-60 - 8.24993716616779655911027615609e-29*I
        P(f 7)^+/omega_+=5.00000000000000000000000000133
        P(f 7)^-/omega_-=-1.16793587723237638257725820700e-60 + 8.24993716616779655911027615609e-29*I
        P(f 8)^+/omega_+=2.50000000000000000000000000073
        P(f 8)^-/omega_-=3.39765752017206550696948310188e-32 - 2.39999999999999999999999999940*I
        P(f 9)^+/omega_+=-2.50000000000000000000000000073
        P(f 9)^-/omega_-=3.39765752017206550696948310188e-32 - 2.39999999999999999999999999940*I
        P(f10)^+/omega_+=-5.00000000000000000000000000133
        P(f10)^-/omega_-=1.16793587723237638257725820700e-60 - 8.24993716616779655911027615609e-29*I
        P(f11)^+/omega_+=0
        P(f11)^-/omega_-=-1.27412157006452456511355616309e-31 - 1.01489446868406102099789763444e-28*I
        o1= 0.0404001869188632792144191985239*I
        o2= -1.36955018267536771772869542629e-33 - 0.0967407815209822856536332369020*I

        
        sage: f=Newforms(5,8,names='a')[0];f
        q - 14*q^2 - 48*q^3 + 68*q^4 + 125*q^5 + O(q^6)
        sage: L=f.cuspform_lseries()  
        sage: pp=PeriodPolynomial(f,prec=103)
        sage: pp.special_value(4)
        -3.34183629241748201816194829811e-29 + 8.45531852674217908762910051272e-60*I
        sage: pp.special_value(3)
        -0.729970592499451187790964533256 + 2.56020879251697431818575640846e-31*I
        sage: L(3)                  
        -0.729970592499451
        sage: L(4)
        0.000000000000000
        
        



        """
        self._f = f
        self._level = None
        if data <> {}:
            self.init_from_dict(data)
        if self._level == None:
            self._level = f.level()
            self._k = f.weight()
            self._w = self._k - 2
            self._verbose = verbose
            self._polynomials = {}
            self._prec = prec
            self._rks = {}
            self._coset_reps = {}
            self._dim = Gamma0(self._level).index()
            self._coefficients_at_coset = {}
            self._base_coeffs = []
            self._base_coeffs_embedding = []
            self._M = {}
            self._M0 = 0
            self._width = {}
            self._shift = {}
            self._atkin_lehner = {}
            self._integrals = {}
            self._pplus = {}
            self._pminus = {}
            self._peterson_norm = 0
            self._canonical_periods = []
        # Check
        assert is_squarefree(self._level)
        ## Some numerical definitions
        self._RF = RealField(prec)
        self._eps = self._RF(2)**-self._RF(prec)
        self._pi = self._RF.pi()