def as_polynomial_in_E4_and_E6(self,insert_in_db=True):
     r"""
     If self is on the full modular group writes self as a polynomial in E_4 and E_6.
     OUTPUT:
     -''X'' -- vector (x_1,...,x_n)
     with f = Sum_{i=0}^{k/6} x_(n-i) E_6^i * E_4^{k/4-i}
     i.e. x_i is the coefficient of E_6^(k/6-i)*
     """
     if(self.level() != 1):
         raise NotImplementedError("Only implemented for SL(2,Z). Need more generators in general.")
     if(self._as_polynomial_in_E4_and_E6 is not None and self._as_polynomial_in_E4_and_E6 != ''):
         return self._as_polynomial_in_E4_and_E6
     d = self._parent.dimension_modular_forms()  # dimension of space of modular forms
     k = self.weight()
     K = self.base_ring()
     l = list()
     # for n in range(d+1):
     #    l.append(self._f.q_expansion(d+2)[n])
     # v=vector(l) # (self._f.coefficients(d+1))
     v = vector(self.coefficients(range(d),insert_in_db=insert_in_db))
     d = dimension_modular_forms(1, k)
     lv = len(v)
     if(lv < d):
         raise ArithmeticError("not enough Fourier coeffs")
     e4 = EisensteinForms(1, 4).basis()[0].q_expansion(lv + 2)
     e6 = EisensteinForms(1, 6).basis()[0].q_expansion(lv + 2)
     m = Matrix(K, lv, d)
     lima = floor(k / 6)  # lima=k\6;
     if((lima - (k / 2)) % 2 == 1):
         lima = lima - 1
     poldeg = lima
     col = 0
     monomials = dict()
     while(lima >= 0):
         deg6 = ZZ(lima)
         deg4 = (ZZ((ZZ(k / 2) - 3 * lima) / 2))
         e6p = (e6 ** deg6)
         e4p = (e4 ** deg4)
         monomials[col] = [deg4, deg6]
         eis = e6p * e4p
         for i in range(1, lv + 1):
             m[i - 1, col] = eis.coefficients()[i - 1]
         lima = lima - 2
         col = col + 1
     if (col != d):
         raise ArithmeticError("bug dimension")
     # return [m,v]
     if self._verbose > 0:
         wmf_logger.debug("m={0}".format(m, type(m)))
         wmf_logger.debug("v={0}".format(v, type(v)))
     try:
         X = m.solve_right(v)
     except:
         return ""
     self._as_polynomial_in_E4_and_E6 = [poldeg, monomials, X]
     return [poldeg, monomials, X]
    def __init__(self, N=1, k=2, chi=1, label='', prec=10, bitprec=53, display_bprec=26,parent=None, data=None,compute=False, verbose=-1,get_from_db=True):
        r"""
        Init self as form with given label in S_k(N,chi)
        """
        super(WebNewForm_computing_class,self).__init__(N,k,chi,label,prec,bitprec,display_bprec,get_from_db=False)
        print "d=",self.__dict__
        wmf_logger.debug("WebNewForm with N,k,chi,label={0}".format( (N,k,chi,label)))

        self._as_factor = None
        self._prec_needed_for_lfunctions = None
        self.set_parent()
        self.set_newform_number()
        self.compute_additional_properties()
def _get_newform(N, k, chi, fi=None):
    r"""
    Get an element of the space of newforms, incuding some error handling.

    INPUT:

     - ''k'' -- positive integer : the weight
     - ''N'' -- positive integer (default 1) : level
     - ''chi'' -- non-neg. integer (default 0) use character nr. chi
     - ''fi'' -- integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi]. fi=-1 returns the whole list
     - ''prec'' -- integer (the number of coefficients to get)

    OUTPUT:

    -''t'' -- bool, returning True if we succesfully created the space and picked the wanted f
    -''f'' -- equals f if t=True, otherwise contains an error message.

    EXAMPLES::


        sage: _get_newform(16,10,1)
        (False, 'Could not construct space $S^{new}_{16}(10)$')
        sage: _get_newform(10,16,1)
        (True, q - 68*q^3 + 1510*q^5 + O(q^6))
        sage: _get_newform(10,16,3)
        (True, q + 156*q^3 + 870*q^5 + O(q^6))
        sage: _get_newform(10,16,4)
        (False, '')

     """
    t = False
    try:
        if(chi == 0):
            wmf_logger.debug("EXPLICITLY CALLING NEWFORMS!")
            S = Newforms(N, k, names='x')
        else:
            S = Newforms(DirichletGroup(N)[chi], k, names='x')
        if(fi >= 0 and fi < len(S)):
            f = S[fi]
            t = True
        elif(fi == -1 or fi is None):
            t = True
            return (t, S)
        else:
            f = ""
    except RuntimeError:
        if(chi == 0):
            f = "Could not construct space $S^{new}_{%s}(%s)$" % (k, N)
        else:
            f = "Could not construct space $S^{new}_{%s}(%s,\chi_{%s})$" % (k, N, chi)
    return (t, f)
def WebNewForm_computing(N=1, k=2, chi=1, label='', prec=10, bitprec=53, display_bprec=26, parent=None, data=None, compute=False, verbose=-1,get_from_db=True):
    r"""
    Constructor for WebNewForms with added 'nicer' error message.
    """
    ## First check
    if chi == 1:
        if k % 2 == 1:
            wmf_logger.debug("Only zero function here with N,k,chi,label={0}.".format( (N,k,chi,label)))
            return 0
    if data is None: data = {}
    wmf_logger.debug("incoming data in construction : {0}".format(data.get('N'),data.get('k'),data.get('chi')))
    try: 
        F = WebNewForm_computing_class(N=N, k=k, chi=chi, label=label, prec=prec, bitprec = bitprec, display_bprec=display_bprec, parent = parent, data = data, compute = compute, verbose = verbose,get_from_db = get_from_db)
    except ArithmeticError as e:#Exception as e:
        wmf_logger.critical("Could not construct WebNewForm with N,k,chi,label={0}. Error: {1}".format( (N,k,chi,label),e))
        raise IndexError,"We are very sorry. The sought function could not be found in the database."
    return F
 def get_modular_symbols(self):
     r"""
     Get Modular Symbols from database they exist.
     """
     if not self._modular_symbols is None:
         return 
     modular_symbols = connect_to_modularforms_db('Modular_symbols.files')
     key = {'k': int(self._k), 'N': int(self._N), 'cchi': int(self._chi)}
     modular_symbols_from_db  = modular_symbols.find_one(key)
     wmf_logger.debug("found ms={0}".format(modular_symbols_from_db))
     if modular_symbols_from_db is None:
         ms = None
     else:
         id = modular_symbols_from_db['_id']
         fs = get_files_from_gridfs('Modular_symbols')
         ms = loads(fs.get(id).read())
         self._id = id
     self._modular_symbols = ms
 def twist_by(self, x):
     r"""
     twist self by a primitive Dirichlet character x
     """
     # xx = x.primitive()
     assert x.is_primitive()
     q = x.conductor()
     # what level will the twist live on?
     level = self.level()
     qq = self.character().conductor()
     new_level = lcm(self.level(), lcm(q * q, q * qq))
     D = DirichletGroup(new_level)
     new_x = D(self.character()) * D(x) * D(x)
     ix = D.list().index(new_x)
     #  the correct space
     NS = WebModFormSpace(self._k, new_level, ix, self._prec)
     # have to find whih form wee want
     NS.galois_decomposition()
     M = NS.sturm_bound() + len(divisors(new_level))
     C = self.coefficients(range(M))
     for label in NS._galois_orbits_labels:
         wmf_logger.debug("label={0}".format(label))
         FT = NS.f(label)
         CT = FT.f.coefficients(M)
         wmf_logger.debug("{0}".format(CT))
         K = FT.f.hecke_eigenvalue_field()
         try:
             for n in range(2, M):
                 if(new_level % n + 1 == 0):
                     continue
                 wmf_logger.debug("n={0}".format(n))
                 ct = CT[n]
                 c = K(x(n)) * K(C[n])
                 wmf_logger.debug("{0} {1}".format(ct, c))
                 if ct != c:
                     raise StopIteration()
         except StopIteration:
             pass
         else:
             wmf_logger.debug("Twist of f={0}".format(FT))
     return FT
    def __init__(self, N=1, k=2, chi=1, cuspidal=1, prec=10, bitprec=53, data=None, verbose=0,get_from_db=True):
        r"""
        Init self.

        INPUT:
        - 'k' -- weight
        - 'N' -- level
        - 'chi' -- character
        - 'cuspidal' -- 1 if space of cuspforms, 0 if all modforms
        """
        wmf_logger.debug("WebModFormSpace with k,N,chi={0}".format( (k,N,chi)))
        super(WebModFormSpace_computing_class,self).__init__(N,k,chi,cuspidal,prec,bitprec,data, verbose,get_from_db=False)
        ## In this subclass we add properties which are not
        ## supposed to be used on the web or stored in the database
        self._dimension = None
        self._dimension_oldspace = None
        self._newforms = None
        self._modular_symbols = None
        
        self.compute_additional_properties()
        self.insert_into_db()
 def insert_into_db(self):
     r"""
     Insert a dictionary of data for self into the database collection
     WebNewforms.files
     """
     wmf_logger.debug("inserting self into db! name={0}".format(self._name))
     C = connect_to_modularforms_db('WebNewforms.files')
     fs = get_files_from_gridfs('WebNewforms')
     s = {'name':self._name,'version':float(self._version)}
     rec = C.find_one(s)
     if rec:
         id = rec.get('_id')
     else:
         id = None
     if id<>None:
         wmf_logger.debug("Removing self from db with id={0}".format(id))
         fs.delete(id)
         
     fname = "webnewform-{0:0>5}-{1:0>3}-{2:0>3}-{3}".format(self._N,self._k,self._chi,self._label) 
     d = self.to_dict()
     d.pop('_ap',None)
     d.pop('_character',None)
     d.pop('_as_factor',None)
     id = fs.put(dumps(d),filename=fname,N=int(self._N),k=int(self._k),chi=int(self._chi),label=self._label,name=self._name,version=float(self._version))
     wmf_logger.debug("inserted :{0}".format(id))
 def _get_aps(self, prec=-1):
     r"""
     Get aps from database if they exist.
     """
     ap_files = connect_to_modularforms_db('ap.files')
     key = {'k': int(self._k), 'N': int(self._N), 'cchi': int(self._chi)}
     key['prec'] = {"$gt": int(prec - 1)}
     ap_from_db  = ap_files.find(key).sort("prec")
     wmf_logger.debug("finds={0}".format(ap_from_db))
     wmf_logger.debug("finds.count()={0}".format(ap_from_db.count()))
     fs = get_files_from_gridfs('ap')
     aplist = {}
     for i in range(len(self.labels())):
         aplist[self.labels()[i]]={}
     for rec in ap_from_db:
         wmf_logger.debug("rec={0}".format(rec))
         ni = rec.get('newform')
         if ni is None:
             for a in self.labels():
                 aplist[a][prec]=None
             return aplist
         a = self.labels()[ni]
         cur_prec = rec['prec']
         if aplist.get(a,{}).get(cur_prec,None) is None:
             aplist[a][prec]=loads(fs.get(rec['_id']).read())
         if cur_prec > prec and prec>0: # We are happy with these coefficients.
             return aplist
     return aplist
 def get_newform_factors(self):
     r"""
     Get New form factors from database they exist.
     """
     if not self._newforms is None and self._newforms == []:
         return 
     factors = connect_to_modularforms_db('Newform_factors.files')
     key = {'k': int(self._k), 'N': int(self._N), 'cchi': int(self._chi),}
     factors_from_db  = factors.find(key).sort('newform',int(1))
     wmf_logger.debug("found factors={0}".format(factors_from_db))
     self._newforms = {}
     if factors_from_db.count()==0:
         raise ValueError,"Space is not in database!"
     else:
         facts = []
         self._labels = []
         fs = get_files_from_gridfs('Newform_factors')
         for rec in factors_from_db:
             factor = loads(fs.get(rec['_id']).read())
             label = orbit_label(rec['newform'])
             self._galois_orbits_labels.append(label)
             self._newforms[label] = factor
def break_line_at(s, brpt=20):
    r"""
    Breaks a line containing math 'smartly' at brpt characters.
    With smartly we mean that we break at + or - but keep brackets
    together
    """
    sl = list()
    stmp = ''
    left_par = 0
    #wmf_logger.debug('Break at line, Input ={0}'.format(s))
    for i in range(len(s)):
        if s[i] == '(':  # go to the matching case
            left_par = 1
        elif s[i] == ')' and left_par == 1:
            left_par = 0
        if left_par == 0 and (s[i] == '+' or s[i] == '-'):
            sl.append(stmp)
            stmp = ''
        stmp = stmp + s[i]
        if i == len(s) - 1:
            sl.append(stmp)
    wmf_logger.debug('sl={0}'.format(sl))

    # sl now contains a split  e.g. into terms in the q-expansion
    # we now have to join as many as fits on the line
    res = list()
    stmp = ''
    for j in range(len(sl)):
        l = len_as_printed(stmp) + len_as_printed(sl[j])
        #wmf_logger.debug("l={0}".format(l))
        if l < brpt:
            stmp = join([stmp, sl[j]])
        else:
            res.append(stmp)
            stmp = sl[j]
        if j == len(sl) - 1:
            res.append(stmp)
    return res
 def set_q_expansion_embeddings(self, prec=10, bitprec=53,format='numeric',display_bprec=26,insert_in_db=True):
     r""" Compute all embeddings of self into C which are in the same space as self.
     Return 0 if we didn't compute anything new, otherwise return 1.
     """
     wmf_logger.debug("computing embeddings of q-expansions : has {0} embedded coeffs. Want : {1} with bitprec={2}".format(len(self._embeddings),prec,bitprec))
     if display_bprec > bitprec:
         display_bprec = bitprec
     ## First check if we have sufficient data
     if self._embeddings['prec'] >= prec or self._embeddings['bitprec'] >= bitprec:
         return 0 ## We should already have sufficient data.
     ## Else we compute new embeddings.
     CF = ComplexField(bitprec)
     # First wee if we need higher precision, in which case we reset all coefficients:
     if self._embeddings['bitprec'] < bitprec:
         self._embeddings['values']=[]
         self._embeddings['latex']=[]
         self._embeddings['prec']=0
     # See if we have need of more coefficients
     nstart = len(self._embeddings)
     wmf_logger.debug("Should have {0} embeddings".format(self._embeddings['prec']))
     wmf_logger.debug("Computing new stuff !")
     for n in range(self._embeddings['prec'],prec):
         try:
             cn = self.coefficient(n)
         except IndexError:
             break
         if hasattr(cn, 'complex_embeddings'):
             cn_emb = cn.complex_embeddings(bitprec)
         else:
             cn_emb = [ CF(cn) for i in range(deg) ]
         self._embeddings['values'].append(cn_emb)
     self._embeddings['prec'] = len(self._embeddings['values'])
     # See if we also need to recompute the latex strings
     if display_bprec > self._embeddings['bitprec']:
         self._embeddings['latex'] = []  ## Have to redo these
     numc = len(self._embeddings['latex'])
     for n in range(numc,prec):
         cn_emb = []
         for x in self._embeddings['values'][n]:
             t = my_complex_latex(x,display_bprec)
         cn_emb_latex.append(t)
         self._embeddidngs['latex'].append(cn_emb)
     wmf_logger.debug("has embeddings_latex:{0}".format(nstart))
     return 1
 def galois_decomposition(self):
     r"""
     We compose the new subspace into galois orbits of new cusp forms.
     """
     from sage.monoids.all import AlphabeticStrings
     if(len(self._galois_decomposition) != 0):
         return self._galois_decomposition
     if '_HeckeModule_free_module__decomposition' in self._newspace.__dict__:
         L = self._newspace.decomposition()
     else:
         decomp = self.newform_factors()
         if len(decomp)>0:
             L = filter(lambda x: x.is_new() and x.is_cuspidal(), decomp)
             wmf_logger.debug("found L:{0}".format(L))
         elif self._computation_too_hard():
             L = []
             raise IndexError,"No decomposition was found in the database!"
             wmf_logger.debug("no decomp in database!")
         else: # compute
             L = self._newspace.decomposition()
             wmf_logger.debug("newspace :".format(self._newspace))                                
             wmf_logger.debug("computed L:".format(L))
     self._galois_decomposition = L
     # we also label the compnents
     x = AlphabeticStrings().gens()
     for j in range(len(L)):
         if(j < 26):
             label = str(x[j]).lower()
         else:
             j1 = j % 26
             j2 = floor(QQ(j) / QQ(26))
             label = str(x[j1]).lower()
             label = label + str(j2)
         if label not in self._galois_orbits_labels:
             self._galois_orbits_labels.append(label)
     return L
 def get_from_db(self):
     r"""
     Fetch dictionary data from the database.
     """
     db = connect_to_modularforms_db('WebModformspace.files')
     s = {'name':self._name,'version':emf_version}
     wmf_logger.debug("Looking in DB for rec={0}".format(s))
     f = db.find_one(s)
     wmf_logger.debug("Found rec={0}".format(f))
     if f<>None:
         id = f.get('_id')
         fs = get_files_from_gridfs('WebModformspace')
         f = fs.get(id)
         wmf_logger.debug("Getting rec={0}".format(f))
         d = loads(f.read())
         return d
     return {}
 def insert_into_db(self):
     r"""
     Insert a dictionary of data for self into the collection WebModularforms.files
     """
     wmf_logger.debug("inserting self into db! name={0}".format(self._name))
     db = connect_to_modularforms_db('WebModformspace.files')
     fs = get_files_from_gridfs('WebModformspace')
     s = {'name':self._name,'version':emf_version}
     rec = db.find_one(s)
     if rec:
         id = rec.get('_id')
     else:
         id = None
     if id<>None:
         wmf_logger.debug("Removing self from db with id={0}".format(id))
         fs.delete(id)
         
     fname = "webmodformspace-{0:0>5}-{1:0>3}-{2:0>3}".format(self._N,self._k,self._chi) 
     d = self.to_dict()
     d.pop('_ap',None) # Since the ap's are already in the database we don't need them here
     id = fs.put(dumps(d),filename=fname,N=int(self._N),k=int(self._k),chi=int(self._chi),name=self._name,version=emf_version)
     wmf_logger.debug("inserted :{0}".format(id))
    def set_oldspace_decomposition(self):
        r"""
        Get decomposition of the oldspace in self into submodules.

        """
        if not (self._oldspace_decomposition is None or self._oldspace_decomposition == []):
            return
        N = self._N
        k = self._k
        M = self._modular_symbols.cuspidal_submodule()
        L = list()
        L = []
        check_dim = self.dimension_newspace()
        if(check_dim == self.dimension()):
            return L
        if(self._verbose > 1):
            wmf_logger.debug("check_dim:={0}".format(check_dim))
        for d in divisors(N):
            if(d == 1):
                continue
            q = N.divide_knowing_divisible_by(d)
            if(self._verbose > 1):
                wmf_logger.debug("d={0}".format(d))
            # since there is a bug in the current version of sage
            # we have to try this...
            try:
                O = M.old_submodule(d)
            except AttributeError:
                O = M.zero_submodule()
            Od = O.dimension()
            if(self._verbose > 1):
                wmf_logger.debug("O={0}".format(O))
                wmf_logger.debug("Od={0}".format(Od))
            if(d == N and k == 2 or Od == 0):
                continue
            if self.character().is_trivial():
                # S=ModularSymbols(ZZ(N/d),k,sign=1).cuspidal_submodule().new_submodule(); Sd=S.dimension()
                wmf_logger.debug("q={0},{1}".format(q, type(q)))
                wmf_logger.debug("k={0},{1}".format(k, type(k)))
                Sd = dimension_new_cusp_forms(q, k)
                if(self._verbose > 1):
                    wmf_logger.debug("Sd={0}".format(Sd))
                if Sd > 0:
                    mult = len(divisors(ZZ(d)))
                    check_dim = check_dim + mult * Sd
                    L.append((q, 0, mult, Sd))
            else:
                xd = self.character().decomposition()
                for xx in xd:
                    if xx.modulus() == q:
                        Sd = dimension_new_cusp_forms(xx, k)
                        if Sd > 0:
                            # identify this character for internal storage... should be optimized
                            x_k = self.conrey_character(xx).number()
                            mult = len(divisors(ZZ(d)))
                            check_dim = check_dim + mult * Sd
                            L.append((q, x_k, mult, Sd))
            if(self._verbose > 1):
                wmf_logger.debug("mult={0},N/d={1},Sd={2}".format(mult, ZZ(N / d), Sd))
                wmf_logger.debug("check_dim={0}".format(check_dim))
        check_dim = check_dim - M.dimension()
        if(check_dim != 0):
            raise ArithmeticError("Something wrong! check_dim=%s" % check_dim)
        self._oldspace_decomposition = L
    def compute_satake_parameters_numeric(self, prec=10, bits=53,insert_in_db=True):
        r""" Compute the Satake parameters and return an html-table.

        We only do satake parameters for primes p primitive to the level.
        By defintion the S. parameters are given as the roots of
         X^2 - c(p)X + chi(p)*p^(k-1) if (p,N)=1

        INPUT:
        -''prec'' -- compute parameters for p <=prec
        -''bits'' -- do real embedings intoi field of bits precision

        """
        if self.character().order()>2:
            ## We only implement this for trival or quadratic characters.
            ## Otherwise there is difficulty to figure out what the embeddings mean... 
            return 
        K = self.coefficient_field()
        degree = self.degree()
        RF = RealField(bits)
        CF = ComplexField(bits)
        ps = prime_range(prec)

        self._satake['ps'] = []
        alphas = dict()
        thetas = dict()
        aps = list()
        tps = list()
        k = self.weight()

        for j in range(degree):
            alphas[j] = dict()
            thetas[j] = dict()
        for j in xrange(len(ps)):
            p = ps[j]
            try:
                ap = self.coefficient(p) 
            except IndexError:
                break
            # Remove bad primes
            if p.divides(self.level()):
                continue
            self._satake['ps'].append(p)
            chip = self.character().value(p)
            wmf_logger.debug("p={0}".format(p))
            wmf_logger.debug("chip={0} of type={1}".format(chip,type(chip)))
            if hasattr(chip,'complex_embeddings'):
                wmf_logger.debug("embeddings(chip)={0}".format(chip.complex_embeddings()))
            wmf_logger.debug("ap={0}".format(ap))
            wmf_logger.debug("K={0}".format(K))                        
            
            # ap=self._f.coefficients(ZZ(prec))[p]
            if K.absolute_degree()==1:
                f1 = QQ(4 * chip * p ** (k - 1) - ap ** 2)
                alpha_p = (QQ(ap) + I * f1.sqrt()) / QQ(2)
                ab = RF(p ** ((k - 1) / 2))
                norm_alpha = alpha_p / ab
                t_p = CF(norm_alpha).argument()
                thetas[0][p] = t_p
                alphas[0][p] = (alpha_p / ab).n(bits)
            else:
                for jj in range(degree):
                    app = ap.complex_embeddings(bits)[jj]
                    wmf_logger.debug("chip={0}".format(chip))
                    wmf_logger.debug("app={0}".format(app))
                    wmf_logger.debug("jj={0}".format(jj))            
                    if not hasattr(chip,'complex_embeddings'):
                        f1 = (4 * CF(chip) * p ** (k - 1) - app ** 2)
                    else:
                        f1 = (4 * chip.complex_embeddings(bits)[jj] * p ** (k - 1) - app ** 2)
                    alpha_p = (app + I * abs(f1).sqrt())
                    # ab=RF(/RF(2)))
                    # alpha_p=alpha_p/RealField(bits)(2)
                    wmf_logger.debug("f1={0}".format(f1))
                    
                    alpha_p = alpha_p / RF(2)
                    wmf_logger.debug("alpha_p={0}".format(alpha_p))                    
                    t_p = CF(alpha_p).argument()
                    # tps.append(t_p)
                    # aps.append(alpha_p)
                    alphas[jj][p] = alpha_p
                    thetas[jj][p] = t_p
        self._satake['alphas'] = alphas
        self._satake['thetas'] = thetas
        self._satake['alphas_latex'] = dict()
        self._satake['thetas_latex'] = dict()
        for j in self._satake['alphas'].keys():
            self._satake['alphas_latex'][j] = dict()
            for p in self._satake['alphas'][j].keys():
                s = latex(self._satake['alphas'][j][p])
                self._satake['alphas_latex'][j][p] = s
        for j in self._satake['thetas'].keys():
            self._satake['thetas_latex'][j] = dict()
            for p in self._satake['thetas'][j].keys():
                s = latex(self._satake['thetas'][j][p])
                self._satake['thetas_latex'][j][p] = s

        wmf_logger.debug("satake=".format(self._satake))
        return self._satake
 def compute_cm_values_numeric(self,digits=12,insert_in_db=True):
     r"""
     Compute CM-values numerically.
     """
     if isinstance(self._cm_values,dict) and self._cm_values  <> {}:
         return self._cm_values
      # the points we want are i and rho. More can be added later...
     bits = ceil(int(digits) * int(4))
     CF = ComplexField(bits)
     RF = ComplexField(bits)
     eps = RF(10 ** - (digits + 1))
     if(self._verbose > 1):
         wmf_logger.debug("eps={0}".format(eps))
     K = self.base_ring()
     # recall that
     degree = self.degree()
     cm_vals = dict()
     rho = CyclotomicField(3).gen()
     zi = CyclotomicField(4).gen()
     points = [rho, zi]
     maxprec = 1000  # max size of q-expansion
     minprec = 10  # max size of q-expansion
     for tau in points:
         q = CF(exp(2 * pi * I * tau))
         fexp = dict()
         cm_vals[tau] = dict()
         if(tau == I and self.level() == -1):
             # cv=    #"Exact(soon...)" #_cohen_exact_formula(k)
             for h in range(degree):
                 cm_vals[tau][h] = cv
             continue
         if K.absolute_degree()==1:
             v1 = CF(0)
             v2 = CF(1)
             try:
                 for prec in range(minprec, maxprec, 10):
                     if(self._verbose > 1):
                         wmf_logger.debug("prec={0}".format(prec))
                     v2 = self.as_factor().q_eigenform(prec).truncate(prec)(q)
                     err = abs(v2 - v1)
                     if(self._verbose > 1):
                         wmf_logger.debug("err={0}".format(err))
                     if(err < eps):
                         raise StopIteration()
                     v1 = v2
                 cm_vals[tau][0] = None
             except StopIteration:
                 cm_vals[tau][0] = v2
         else:
             v1 = dict()
             v2 = dict()
             err = dict()
             for h in range(degree):
                 v1[h] = 1
                 v2[h] = 0
             try:
                 for prec in range(minprec, maxprec, 10):
                     if(self._verbose > 1):
                         wmf_logger.debug("prec={0}".format(prec))
                     c = self.coefficients(range(prec),insert_in_db=insert_in_db)
                     for h in range(degree):
                         fexp[h] = list()
                         v2[h] = 0
                         for n in range(prec):
                             cn = c[n]
                             if hasattr(cn, 'complex_embeddings'):
                                 cc = cn.complex_embeddings(CF.prec())[h]
                             else:
                                 cc = CF(cn)
                             v2[h] = v2[h] + cc * q ** n
                         err[h] = abs(v2[h] - v1[h])
                         if(self._verbose > 1):
                             wmf_logger.debug("v1[{0}]={1}".format(h,v1[h]))
                             wmf_logger.debug("v2[{0}]={1}".format(h,v2[h]))
                             wmf_logger.debug("err[{0}]={2}".format(h,err[h]))
                         if(max(err.values()) < eps):
                             raise StopIteration()
                         v1[h] = v2[h]
             except StopIteration:
                 pass
             for h in range(degree):
                 if(err[h] < eps):
                     cm_vals[tau][h] = v2[h]
                 else:
                     cm_vals[tau][h] = None
     self._cm_values = cm_vals
 def compute_additional_properties(self):
     r"""
     Compute everything we need.
     """
     wmf_logger.debug("Update ap's")
     self._get_aps()
     wmf_logger.debug("compute q-expansion")
     prec = self._prec_needed_for_lfunctions()
     self.set_q_expansion_embeddings(prec=prec)
     wmf_logger.debug("as polynomial")
     if self._N == 1:
         self.as_polynomial_in_E4_and_E6()
     wmf_logger.debug("compute twist info")
     self.twist_info()
     wmf_logger.debug("compute CM-values")
     self.compute_cm_values_numeric()
     wmf_logger.debug("Get Atkin-Lehner evs")
     self.get_atkin_lehner_eigenvalues()
     wmf_logger.debug("compute Satake parameters")
     self.set_is_CM()
     wmf_logger.debug("compute Satake parameters")
     self.compute_satake_parameters_numeric()
     self.set_dimensions()
     self.coefficient_field()
     self.get_base_ring()
     #c = self.coefficients(self.prec(),insert_in_db=False)
     self.insert_into_db()
    def set_twist_info(self, prec=10,insert_in_db=True):
        r"""
        Try to find forms of lower level which get twisted into self.
        OUTPUT:

        -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form.
        The actual minimal one is the first element of this list.
             t is set to True if self is minimal and False otherwise


        EXAMPLES::



        """
        if(len(self._twist_info) > 0):
            return self._twist_info
        N = self.level()
        k = self.weight()
        if(is_squarefree(ZZ(N))):
            self._twist_info = [True, None ]
            return [True, None]

        # We need to check all square factors of N
        twist_candidates = list()
        KF = self.base_ring()
        # check how many Hecke eigenvalues we need to check
        max_nump = self._number_of_hecke_eigenvalues_to_check()
        maxp = max(primes_first_n(max_nump))
        for d in divisors(N):
            if(d == 1):
                continue
            # we look at all d such that d^2 divdes N
            if(not ZZ(d ** 2).divides(ZZ(N))):
                continue
            D = DirichletGroup(d)
            # check possible candidates to twist into f
            # g in S_k(M,chi) wit M=N/d^2
            M = ZZ(N / d ** 2)
            if(self._verbose > 0):
                wmf_logger.debug("Checking level {0}".format(M))
            for xig in range(euler_phi(M)):
                (t, glist) = _get_newform(M,k, xig)
                if(not t):
                    return glist
                for g in glist:
                    if(self._verbose > 1):
                        wmf_logger.debug("Comparing to function {0}".format(g))
                    KG = g.base_ring()
                    # we now see if twisting of g by xi in D gives us f
                    for xi in D:
                        try:
                            for p in primes_first_n(max_nump):
                                if(ZZ(p).divides(ZZ(N))):
                                    continue
                                bf = self.as_factor().q_eigenform(maxp + 1, names='x')[p]
                                bg = g.q_expansion(maxp + 1)[p]
                                if(bf == 0 and bg == 0):
                                    continue
                                elif(bf == 0 and bg != 0 or bg == 0 and bf != 0):
                                    raise StopIteration()
                                if(ZZ(p).divides(xi.conductor())):
                                    raise ArithmeticError("")
                                xip = xi(p)
                                # make a preliminary check that the base rings match with respect to being
                                # real or not
                                try:
                                    QQ(xip)
                                    XF = QQ
                                    if(KF != QQ or KG != QQ):
                                        raise StopIteration
                                except TypeError:
                                    # we have a  non-rational (i.e. complex) value of the character
                                    XF = xip.parent()
                                    if((KF.absolute_degree() == 1 or KF.is_totally_real()) and (KG.absolute_degre() == 1 or KG.is_totally_real())):
                                        raise StopIteration
                            ## it is diffcult to compare elements from diferent rings in general but we make some checcks
                            # is it possible to see if there is a larger ring which everything can be
                            # coerced into?
                                ok = False
                                try:
                                    a = KF(bg / xip)
                                    b = KF(bf)
                                    ok = True
                                    if(a != b):
                                        raise StopIteration()
                                except TypeError:
                                    pass
                                try:
                                    a = KG(bg)
                                    b = KG(xip * bf)
                                    ok = True
                                    if(a != b):
                                        raise StopIteration()
                                except TypeError:
                                    pass
                                if(not ok):  # we could coerce and the coefficients were equal
                                    return "Could not compare against possible candidates!"
                                # otherwise if we are here we are ok and found a candidate
                            twist_candidates.append([M, g.q_expansion(prec), xi])
                        except StopIteration:
                            # they are not equal
                            pass
        wmf_logger.debug("Candidates=v{0}".format(twist_candidates))
        self._twist_info = (False, twist_candidates)
        if(len(twist_candidates) == 0):
            self._twist_info = [True, None]
        else:
            self._twist_info = [False, twist_candidates]
        return self._twist_info