예제 #1
0
 def compute_from_startpoints(self, points, p = None, cut_nonsimple_aniso = True, fast = 1, **kwds):
     self._reduction = kwds.get('reduction', self._reduction)
     if NCPUS0 == 1:
         for a in points:
             self._compute_simple_modules_graph_from_startpoint(a, p, cut_nonsimple_aniso, fast)
     else:
         computations = self._compute_simple_modules_graph_from_startpoint_parallel([(a, p, cut_nonsimple_aniso, fast) for a in points])
         for r in computations:
             if not isinstance(r[1], SimpleModulesGraph):
                 logger.error("Got something else... {0}".format(r))
                 # print r
             else:
                 G = r[1]
                 logger.debug("simple from G: {0}".format(len(G._simple)))
                 logger.debug(G._simple)
                 self.add_vertices(G.vertices())
                 self.add_edges(G.edges())
                 self._vertex_colors[
                     self._nonsimple_color] += G._vertex_colors[G._nonsimple_color]
                 self._vertex_colors[
                     self._simple_color] += G._vertex_colors[G._simple_color]
                 self._simple = uniq(self._simple + G._simple)
                 for h in G._heights.keys():
                     if not self._heights.has_key(h):
                         self._heights[h] = G._heights[h]
                     else:
                         self._heights[h] = uniq(self._heights[h] + G._heights[h])
                         logger.info("Found {0} {1}-simple module{2} so far.".format(
                             len(self._simple), self._weight, "s" if len(self._simple) != 1 else ""))
     logger.info("Found in total {0} {1}-simple module{3} with p-rank <= {2}".format(
         len(self._simple), self._weight, self._rank_limit, "s" if len(self._simple) != 1 else ""))
     return 0
예제 #2
0
def aniso_dict_to_latex_table(d, max_per_table=10, include_weight=True):
    if include_weight:
        beginstr = r"\begin{tabularx}{llX} \toprule $k$ & signature & $k$-simple modules\\\midrule" + \
            "\n"
    else:
        beginstr = r"\begin{tabular}{llX} \toprule $k$ & signature & $k$-simple modules\\\midrule" + \
            "\n"
    endstr = r"\bottomrule\end{tabularx}" + "\n"
    s = beginstr
    ks = sorted(d.keys())
    for i in range(len(d.keys())):
        k = ks[i]
        sigs = uniq([_.signature() for _ in d[k]])
        for sig in sigs:
            if include_weight:
                s += "$" + str(k) + "$" + " & "
            s += " " + str(sig) + " & "
            ms = [m for m in d[k] if m.signature() == sig]
            ms = sorted(
                ms, lambda x, y: int(-1) if x.order() <= y.order() else int(1))
            for m in ms:
                s += str(FQM_vertex(m)).strip() + ", "
            s = s[:-2]
            s += r"\\\midrule" + "\n"
            if (i + 1) % max_per_table == 0:
                s += endstr + beginstr
    s += endstr
    return s
예제 #3
0
def aniso_dict_to_latex_table(d, max_per_table=10, include_weight=True):
    if include_weight:
        beginstr = r"\begin{tabularx}{llX} \toprule $k$ & signature & $k$-simple modules\\\midrule" + \
            "\n"
    else:
        beginstr = r"\begin{tabular}{llX} \toprule $k$ & signature & $k$-simple modules\\\midrule" + \
            "\n"
    endstr = r"\bottomrule\end{tabularx}" + "\n"
    s = beginstr
    ks = sorted(d.keys())
    for i in range(len(d.keys())):
        k = ks[i]
        sigs = uniq([_.signature() for _ in d[k]])
        for sig in sigs:
            if include_weight:
                s += "$" + str(k) + "$" + " & "
            s += " " + str(sig) + " & "
            ms = [m for m in d[k] if m.signature() == sig]
            ms = sorted(
                ms, lambda x, y: int(-1) if x.order() <= y.order() else int(1))
            for m in ms:
                s += str(FQM_vertex(m)).strip() + ", "
            s = s[:-2]
            s += r"\\\midrule" + "\n"
            if (i + 1) % max_per_table == 0:
                s += endstr + beginstr
    s += endstr
    return s
예제 #4
0
 def compute_from_startpoints(self,
                              points,
                              p=None,
                              cut_nonsimple_aniso=True,
                              fast=1,
                              **kwds):
     self._reduction = kwds.get('reduction', self._reduction)
     if NCPUS0 == 1:
         for a in points:
             self._compute_simple_modules_graph_from_startpoint(
                 a, p, cut_nonsimple_aniso, fast)
     else:
         computations = self._compute_simple_modules_graph_from_startpoint_parallel(
             [(a, p, cut_nonsimple_aniso, fast) for a in points])
         for r in computations:
             if not isinstance(r[1], SimpleModulesGraph):
                 logger.error("Got something else... {0}".format(r))
                 # print r
             else:
                 G = r[1]
                 logger.debug("simple from G: {0}".format(len(G._simple)))
                 logger.debug(G._simple)
                 self.add_vertices(G.vertices())
                 self.add_edges(G.edges())
                 self._vertex_colors[
                     self._nonsimple_color] += G._vertex_colors[
                         G._nonsimple_color]
                 self._vertex_colors[
                     self._simple_color] += G._vertex_colors[
                         G._simple_color]
                 self._simple = uniq(self._simple + G._simple)
                 for h in G._heights.keys():
                     if not self._heights.has_key(h):
                         self._heights[h] = G._heights[h]
                     else:
                         self._heights[h] = uniq(self._heights[h] +
                                                 G._heights[h])
                         logger.info(
                             "Found {0} {1}-simple module{2} so far.".
                             format(len(self._simple), self._weight,
                                    "s" if len(self._simple) != 1 else ""))
     logger.info(
         "Found in total {0} {1}-simple module{3} with p-rank <= {2}".
         format(len(self._simple), self._weight, self._rank_limit,
                "s" if len(self._simple) != 1 else ""))
     return 0
예제 #5
0
파일: find_simple.py 프로젝트: s-opitz/sfqm
def find_simple_anisotropic_parallel(num,
                                     s,
                                     weights=range(2,
                                                   Integer(27) / 2),
                                     dynamic=True,
                                     lower=1,
                                     only_2_n=False,
                                     reduction=False):
    r"""
      Test for anisotropic $k$-simple fqm's for $k$ in weights.

      INPUT::
        - num: upper bound
        - s: number of iterations
        - lower: lower bound
    """
    simple = dict()
    for kk in weights:
        simple[kk] = list()
    m = round(RR(num) / s)
    args = [(m * a + lower, min(m * (a + lower),
                                lower + num - 1), lower + num - 1, None, None,
             weights, True, dynamic, only_2_n, reduction) for a in range(s)]
    tests = find_simple_anisotropic_wrapper(args)
    done = 0

    #starttime = walltime()
    for test in tests:
        done += 1
        simple_part = test[1][0]
        if isinstance(simple_part, str):
            print "Result: ", test
            continue
        tt = test[1][1]
        for kk in simple_part.keys():
            print "Result from process: ", simple_part[kk]
            simple[kk] = uniq(simple[kk] + simple_part[kk])
        #tt = walltime(starttime)
        sl = [len(sp) for sp in simple.values()]
        num_simple = sum(sl)
        timeest = (s - done) * RR(tt) / RR(60)
        if timeest > 1:
            if timeest > 60:
                print("%g%% done, ETA: %d hour" +
                      ("s" if timeest / 60 >= 2 else "") +
                      ", %d minutes, simple lattices: %d") % (
                          RR(done) / RR(s) * 100, timeest / 60,
                          (timeest / 60).frac() * 60, num_simple)
            else:
                print("%g%% done, ETA: %d minute" +
                      ("s" if timeest >= 2 else "") + ", simple lattices: %d"
                      ) % (RR(done) / RR(s) * 100, timeest, num_simple)
        else:
            print "%g%% done, ETA: %d seconds, simple lattices: %d" % (
                RR(done) / RR(s) * 100, timeest * 60, num_simple)
    return simple
예제 #6
0
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))
    WMFS = None
    if level <= 0:
        info["error"] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level=level, weight=weight, cuspidal=True, character=character)
        emf_logger.debug("Created WebModFormSpace %s" % WMFS)
        if "download" in info and "tempfile" in info:
            save(WNF, info["tempfile"])
            info["filename"] = str(weight) + "-" + str(level) + "-" + str(character) + "-" + label + ".sobj"
            return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        # if isinstance(e,IndexError):
        info["error"] = e.message
        WMFS = None
    if WMFS is None:
        info["error"] = (
            "We are sorry. The sought space can not be found in the database. "
            + "<br> Detailed information: {0}".format(info.get("error", ""))
        )
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        # if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits):
        #    ## Try to add them here...
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F =
        #        WMFS.hecke_orbits.append(F)
        info = {"space": WMFS}
    #    info['old_decomposition'] = WMFS.oldspace_decomposition()

    ## For side-bar
    lifts = list()
    lifts.append(("Half-Integral Weight Forms", "/ModularForm/Mp2/Q"))
    lifts.append(("Siegel Modular Forms", "/ModularForm/GSp4/Q"))
    info["lifts"] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        friends.append(("Number field " + f.base_field_label(), f.base_field_url()))
        if f.coefficient_field_label(check=True):
            friends.append(("Number field " + f.coefficient_field_label(), f.coefficient_field_url()))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info["friends"] = friends

    return info
예제 #7
0
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))    
    WMFS = None
    if level <= 0:
        info['error'] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True,character = character)
        emf_logger.debug("Created WebModFormSpace %s"%WMFS)
        if 'download' in info and 'tempfile' in info:
            save(WNF,info['tempfile'])
            info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj'
            return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        #if isinstance(e,IndexError):
        info['error'] = e.message
        WMFS = None
    if WMFS is None:
        info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error',''))
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        #if WMFS.dimension_new_cusp_forms()<>len(WMFS.hecke_orbits):
        #    ## Try to add them here... 
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F = 
        #        WMFS.hecke_orbits.append(F)
        info = {'space':WMFS}
#    info['old_decomposition'] = WMFS.oldspace_decomposition()

    ## For side-bar
    lifts = list()
    lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q'))
    lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q'))
    info['lifts'] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        friends.append(('Number field ' + f.base_field_label(), f.base_field_url()))
        if f.coefficient_field_label(check=True):
            friends.append(('Number field ' + f.coefficient_field_label(), f.coefficient_field_url()))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info['friends'] = friends
    
    return info
예제 #8
0
def set_info_for_web_newform(level=None,
                             weight=None,
                             character=None,
                             label=None,
                             **kwds):
    r"""
    Set the info for on modular form.

    """
    info = to_dict(kwds)
    info['level'] = level
    info['weight'] = weight
    info['character'] = character
    info['label'] = label
    if level is None or weight is None or character is None or label is None:
        s = "In set info for one form but do not have enough args!"
        s += "level={0},weight={1},character={2},label={3}".format(
            level, weight, character, label)
        emf_logger.critical(s)
    emf_logger.debug("In set_info_for_one_mf: info={0}".format(info))
    prec = my_get(info, 'prec', default_prec, int)
    bprec = my_get(info, 'bprec', default_display_bprec, int)
    emf_logger.debug("PREC: {0}".format(prec))
    emf_logger.debug("BITPREC: {0}".format(bprec))
    try:
        WNF = WebNewForm_cached(level=level,
                                weight=weight,
                                character=character,
                                label=label)
        emf_logger.critical("defined webnewform for rendering!")
        # if info.has_key('download') and info.has_key('tempfile'):
        #     WNF._save_to_file(info['tempfile'])
        #     info['filename']=str(weight)+'-'+str(level)+'-'+str(character)+'-'+label+'.sobj'
        #     return info
    except IndexError as e:
        WNF = None
        info['error'] = e.message
    url1 = url_for("emf.render_elliptic_modular_forms")
    url2 = url_for("emf.render_elliptic_modular_forms", level=level)
    url3 = url_for("emf.render_elliptic_modular_forms",
                   level=level,
                   weight=weight)
    url4 = url_for("emf.render_elliptic_modular_forms",
                   level=level,
                   weight=weight,
                   character=character)
    bread = [(EMF_TOP, url1)]
    bread.append(("of level %s" % level, url2))
    bread.append(("weight %s" % weight, url3))
    if int(character) == 0:
        bread.append(("trivial character", url4))
    else:
        bread.append(("\( %s \)" % (WNF.character.latex_name), url4))
    info['bread'] = bread

    properties2 = list()
    friends = list()
    space_url = url_for('emf.render_elliptic_modular_forms',
                        level=level,
                        weight=weight,
                        character=character)
    friends.append(
        ('\( S_{%s}(%s, %s)\)' %
         (WNF.weight, WNF.level, WNF.character.latex_name), space_url))
    if WNF.coefficient_field_label(check=True):
        friends.append(('Number field ' + WNF.coefficient_field_label(),
                        WNF.coefficient_field_url()))
    friends.append(
        ('Number field ' + WNF.base_field_label(), WNF.base_field_url()))
    friends = uniq(friends)
    friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)",
                    WNF.character.url()))

    if WNF.dimension == 0:
        info['error'] = "This space is empty!"


#    emf_logger.debug("WNF={0}".format(WNF))

#info['name'] = name
    info['title'] = 'Modular Form ' + WNF.hecke_orbit_label

    if 'error' in info:
        return info
    # info['name']=WNF._name
    ## Until we have figured out how to do the embeddings correctly we don't display the Satake
    ## parameters for non-trivial characters....

    cdeg = WNF.coefficient_field.absolute_degree()
    bdeg = WNF.base_ring.absolute_degree()
    if WNF.coefficient_field.absolute_degree() == 1:
        rdeg = 1
    else:
        rdeg = WNF.coefficient_field.relative_degree()
    if cdeg == 1:
        info['satake'] = WNF.satake
    info['qexp'] = WNF.q_expansion_latex(prec=10, name='a')
    info['qexp_display'] = url_for(".get_qexp_latex",
                                   level=level,
                                   weight=weight,
                                   character=character,
                                   label=label)

    # info['qexp'] = WNF.q_expansion_latex(prec=prec)
    #c_pol_st = str(WNF.absolute_polynomial)
    #b_pol_st = str(WNF.polynomial(type='base_ring',format='str'))
    #b_pol_ltx = str(WNF.polynomial(type='base_ring',format='latex'))
    #print "c=",c_pol_ltx
    #print "b=",b_pol_ltx
    if cdeg > 1:  ## Field is QQ
        if bdeg > 1 and rdeg > 1:
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = latex(p1)
            lgc = p1.variables()[0]
            c_pol_ltx = c_pol_ltx.replace(lgc, 'a')
            z = p1.base_ring().gens()[0]
            p2 = z.minpoly()
            b_pol_ltx = latex(p2)
            b_pol_ltx = b_pol_ltx.replace(latex(p2.variables()[0]), latex(z))
            info['polynomial_st'] = 'where \({0}=0\) and \({1}=0\).'.format(
                c_pol_ltx, b_pol_ltx)
        else:
            c_pol_ltx = latex(WNF.coefficient_field.relative_polynomial())
            lgc = str(
                latex(WNF.coefficient_field.relative_polynomial().variables()
                      [0]))
            c_pol_ltx = c_pol_ltx.replace(lgc, 'a')
            info['polynomial_st'] = 'where \({0}=0\)'.format(c_pol_ltx)
    else:
        info['polynomial_st'] = ''
    info['degree'] = int(cdeg)
    if cdeg == 1:
        info['is_rational'] = 1
    else:
        info['is_rational'] = 0
    # info['q_exp_embeddings'] = WNF.print_q_expansion_embeddings()
    # if(int(info['degree'])>1 and WNF.dimension()>1):
    #    s = 'One can embed it into \( \mathbb{C} \) as:'
    # bprec = 26
    # print s
    #    info['embeddings'] =  ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision'])
    # elif(int(info['degree'])>1):
    #    s = 'There are '+str(info['degree'])+' embeddings into \( \mathbb{C} \):'
    # bprec = 26
    # print s
    #    info['embeddings'] =  ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision'])
    # else:
    #    info['embeddings'] = ''
    emf_logger.debug("PREC2: {0}".format(prec))
    info['embeddings'] = WNF._embeddings[
        'values']  #q_expansion_embeddings(prec, bprec,format='latex')
    info['embeddings_len'] = len(info['embeddings'])
    properties2 = []
    if (ZZ(level)).is_squarefree():
        info['twist_info'] = WNF.twist_info
        if isinstance(info['twist_info'],
                      list) and len(info['twist_info']) > 0:
            info['is_minimal'] = info['twist_info'][0]
            if (info['twist_info'][0]):
                s = '- Is minimal<br>'
            else:
                s = '- Is a twist of lower level<br>'
            properties2 = [('Twist info', s)]
    else:
        info['twist_info'] = 'Twist info currently not available.'
        properties2 = [('Twist info', 'not available')]
    args = list()
    for x in range(5, 200, 10):
        args.append({'digits': x})
    alev = None
    CM = WNF._cm_values
    if CM is not None:
        if CM.has_key('tau') and len(CM['tau']) != 0:
            info['CM_values'] = CM
    info['is_cm'] = WNF.is_cm
    if WNF.is_cm is None:
        s = '- Unknown (insufficient data)<br>'
    elif WNF.is_cm is True:
        s = '- Is a CM-form<br>'
    else:
        s = '- Is not a CM-form<br>'
    properties2.append(('CM info', s))
    alev = WNF.atkin_lehner_eigenvalues()
    info['atkinlehner'] = None
    if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1:
        s1 = " Atkin-Lehner eigenvalues "
        s2 = ""
        for Q in alev.keys():
            s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q])
        properties2.append((s1, s2))
        emf_logger.debug("properties={0}".format(properties2))
        # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps()
        # if isinstance(alev,dict) and len(alev.keys())>0:
        #     emf_logger.debug("alev={0}".format(alev))
        #     info['atkinlehner'] = list()
        #     for Q in alev.keys():
        #         s = "\(" + latex(c) + "\)"
        #         Q = alev[c][0]
        #         ev = alev[c][1]
        #         info['atkinlehner'].append([Q, c, ev])
    if (level == 1):
        poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '')
        if poly <> '':
            d, monom, coeffs = poly
            emf_logger.critical("poly={0}".format(poly))

            info['explicit_formulas'] = '\('
            for i in range(d):
                c = QQ(coeffs[i])
                s = ""
                if d > 1 and i > 0 and c > 0:
                    s = "+"
                if c < 0:
                    s = "-"
                if c.denominator() > 1:
                    cc = "\\frac{{ {0} }}{{ {1} }}".format(
                        abs(c.numerator()), c.denominator())
                else:
                    cc = str(abs(c))
                s += "{0} \cdot ".format(cc)
                a = monom[i][0]
                b = monom[i][1]
                if a == 0 and b <> 0:
                    s += "E_6^{{ {0} }}".format(b)
                elif b == 0 and a <> 0:
                    s += "E_4^{{ {0} }}".format(a)
                else:
                    s += "E_4^{{ {0} }}E_6^{{ {1} }}".format(a, b)
                info['explicit_formulas'] += s
            info['explicit_formulas'] += " \)"
    cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + \
        '&label=' + str(label)
    if len(WNF.parent.hecke_orbits) > 1:
        for label_other in WNF.parent.hecke_orbits.keys():
            if (label_other != label):
                s = 'Modular form '
                if character:
                    s = s + str(level) + '.' + str(weight) + '.' + str(
                        character) + str(label_other)
                else:
                    s = s + str(level) + '.' + str(weight) + str(label_other)
                url = url_for('emf.render_elliptic_modular_forms',
                              level=level,
                              weight=weight,
                              character=character,
                              label=label_other)
                friends.append((s, url))

    s = 'L-Function '
    if character:
        s = s + str(level) + '.' + str(weight) + '.' + str(character) + str(
            label)
    else:
        s = s + str(level) + '.' + str(weight) + str(label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for('emf.render_elliptic_modular_forms',
                         level=level,
                         weight=weight,
                         character=character,
                         label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_cn()
    return info
예제 #9
0
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds):
    r"""
    Set the info for on modular form.

    """
    info = to_dict(kwds)
    info['level'] = level
    info['weight'] = weight
    info['character'] = character
    info['label'] = label
    if level is None or weight is None or character is None or label is None:
        s = "In set info for one form but do not have enough args!"
        s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label)
        emf_logger.critical(s)
    emf_logger.debug("In set_info_for_one_mf: info={0}".format(info))
    prec = my_get(info, 'prec', default_prec, int)
    bprec = my_get(info, 'bprec', default_display_bprec, int)
    emf_logger.debug("PREC: {0}".format(prec))
    emf_logger.debug("BITPREC: {0}".format(bprec))    
    try:
        WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label)
        if not WNF.has_updated():
            raise IndexError("Unfortunately, we do not have this newform in the database.")
        info['character_order'] = WNF.character.order
        info['code'] = WNF.code
        emf_logger.debug("defined webnewform for rendering!")
    except IndexError as e:
        info['error'] = e.message
    url0 = url_for("mf.modular_form_main_page")
    url1 = url_for("emf.render_elliptic_modular_forms")
    url2 = url_for("emf.render_elliptic_modular_forms", level=level)
    url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight)
    url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character)
    bread = [(MF_TOP, url0), (EMF_TOP, url1)]
    bread.append(("Level %s" % level, url2))
    bread.append(("Weight %s" % weight, url3))
    bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4))
    bread.append(("Newform %d.%d.%d.%s" % (level, weight, int(character), label),''))
    info['bread'] = bread
    
    properties2 = list()
    friends = list()
    space_url = url_for('emf.render_elliptic_modular_forms',level=level, weight=weight, character=character)
    friends.append(('\( S_{%s}(%s, %s)\)'%(WNF.weight, WNF.level, WNF.character.latex_name), space_url))
    if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url:
        friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url))
    if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label:
        friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url))
    friends = uniq(friends)
    friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url()))
    
    if WNF.dimension==0 and not info.has_key('error'):
        info['error'] = "This space is empty!"
    info['title'] = 'Newform ' + WNF.hecke_orbit_label
    info['learnmore'] = [('History of modular forms', url_for('.holomorphic_mf_history'))]    
    if 'error' in info:
        return info
    ## Until we have figured out how to do the embeddings correctly we don't display the Satake
    ## parameters for non-trivial characters....

    ## Example to illustrate the different cases
    ## base              = CyclotomicField(n) -- of degree phi(n) 
    ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m
    ##   we would then have cdeg = m*phi(n) and bdeg = phi(n)
    ##   and rdeg = m
    ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6)
    ## we get coefficient_field.relative_degree() == 2 although it should be 1
    cdeg = WNF.coefficient_field.absolute_degree()
    bdeg = WNF.base_ring.absolute_degree()
    if cdeg == 1:
        rdeg = 1
    else:
        ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result...
        ## 
        rdeg = QQ(cdeg)/QQ(bdeg)
    cf_is_QQ = (cdeg == 1)
    br_is_QQ = (bdeg == 1)
    if cf_is_QQ:
        info['satake'] = WNF.satake
    if WNF.complexity_of_first_nonvanishing_coefficients() > default_max_height:
        info['qexp'] = ""
        info['qexp_display'] = ''
        info['hide_qexp'] = True
        n,c = WNF.first_nonvanishing_coefficient()
        info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace())
        info['norm_nv'] = '\\approx ' + latex(WNF.first_nonvanishing_coefficient_norm().n())
        info['index_nv'] = n
    else:
        if WNF.prec < prec:
            #get WNF record at larger prec
            WNF.prec = prec
            WNF.update_from_db()
        info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ')
        info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label)
        info["hide_qexp"] = False
    info['max_cn_qexp'] = WNF.q_expansion.prec()
    ## All combinations should be tested...
    ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6)
    ## 13/3/8/a ->  base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring
    ## 13/4/3/a ->  base_ring = coefficient_field = QQ(zeta_3) 
    ## 13/4/1/a -> all rational
    ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17))
    ## These are variables which needs to be set properly below
    info['polvars'] = {'base_ring':'x','coefficient_field':'\\alpha'}
    if not cf_is_QQ:
        if rdeg>1: # not WNF.coefficient_field == WNF.base_ring:
            ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this.
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = web_latex_poly(p1, '\\alpha')  # make the variable \alpha
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            zeta = p1.base_ring().gens()[0]
#           p2 = zeta.minpoly() #this is not used anymore
#           b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore
            z1 = zeta.multiplicative_order() 
            info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'),c_pol_ltx_x, z1]
            if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label]
            if z1==4:
                info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(c_pol_ltx)
                info['polvars']['base_ring']='i'
            elif z1<=2:
                info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx)
            else:
                info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) '%(c_pol_ltx, z1,z1)
                info['polvars']['base_ring']='\zeta_{{ {0} }}'.format(z1)
                if z1==3:
                    info['polynomial_st'] += 'is a primitive cube root of unity.'
                else:
                    info['polynomial_st'] += 'is a primitive {0}-th root of unity.'.format(z1)
        elif not br_is_QQ:
            ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field
            ## generated by some \zeta_n 
            p1 = WNF.coefficient_field.absolute_polynomial()
            z1 = WNF.coefficient_field.gens()[0].multiplicative_order()
            c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1))
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x]
            if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label]
            if z1==4:
                info['polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format(c_pol_ltx)
                info['polvars']['coefficient_field']='i'
            elif z1<=2:
                info['polynomial_st'] = '' 
            else:
                info['polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format(z1)
                info['polvars']['coefficient_field']='\zeta_{{{0}}}'.format(z1)
                if z1==3:
                    info['polynomial_st'] += 'is a primitive cube root of unity.</div>'
                else:
                    info['polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format(z1)
    else:
        info['polynomial_st'] = ''
    if info["hide_qexp"]:
        info['polynomial_st'] = ''
    info['degree'] = int(cdeg)
    if cdeg==1:
        info['is_rational'] = 1
        info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ]
    else:
        info['is_rational'] = 0
    emf_logger.debug("PREC2: {0}".format(prec))
    info['embeddings'] = WNF._embeddings['values'] #q_expansion_embeddings(prec, bprec,format='latex')
    info['embeddings_len'] = len(info['embeddings'])
    properties2 = [('Level', str(level)),
                       ('Weight', str(weight)),
                       ('Character', '$' + WNF.character.latex_name + '$'),
                       ('Label', WNF.hecke_orbit_label),
                       ('Dimension of Galois orbit', str(WNF.dimension))]
    if (ZZ(level)).is_squarefree():
        info['twist_info'] = WNF.twist_info
        if isinstance(info['twist_info'], list) and len(info['twist_info'])>0:
            info['is_minimal'] = info['twist_info'][0]
            if(info['twist_info'][0]):
                s = 'Is minimal<br>'
            else:
                s = 'Is a twist of lower level<br>'
            properties2 += [('Twist info', s)]
    else:
        info['twist_info'] = 'Twist info currently not available.'
        properties2 += [('Twist info', 'not available')]
    args = list()
    for x in range(5, 200, 10):
        args.append({'digits': x})
    alev = None
    CM = WNF._cm_values
    if CM is not None:
        if CM.has_key('tau') and len(CM['tau']) != 0:
            info['CM_values'] = CM
    info['is_cm'] = WNF.is_cm
    if WNF.is_cm == 1:
        info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc)
        info['cm_disc'] = WNF.cm_disc
        info['cm_field_knowl'] = nf_display_knowl(info['cm_field'], getDBConnection(), field_pretty(info['cm_field']))
        info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"])
    if WNF.is_cm is None or WNF.is_cm==-1:
        s = '- Unknown (insufficient data)<br>'
    elif WNF.is_cm == 1:
        s = 'Yes<br>'
    else:
        s = 'No<br>'
    properties2.append(('CM', s))
    alev = WNF.atkin_lehner_eigenvalues()
    info['atkinlehner'] = None
    if isinstance(alev,dict) and len(alev.keys())>0 and level != 1:
        s1 = " Atkin-Lehner eigenvalues "
        s2 = ""
        for Q in alev.keys():
            s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q])
        properties2.append((s1, s2))
        emf_logger.debug("properties={0}".format(properties2))
        # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() 
        # if isinstance(alev,dict) and len(alev.keys())>0:
        #     emf_logger.debug("alev={0}".format(alev))
        #     info['atkinlehner'] = list()
        #     for Q in alev.keys():
        #         s = "\(" + latex(c) + "\)"
        #         Q = alev[c][0]
        #         ev = alev[c][1]
        #         info['atkinlehner'].append([Q, c, ev])
    if(level == 1):
        poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6','')
        if poly != '':
            d,monom,coeffs = poly
            emf_logger.critical("poly={0}".format(poly))
            info['explicit_formulas'] = '\('
            for i in range(len(coeffs)):
                c = QQ(coeffs[i])
                s = ""
                if d>1 and i >0 and c>0:
                    s="+"
                if c<0:
                    s="-"
                if c.denominator()>1:
                    cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()),c.denominator())
                else:
                    cc = str(abs(c))
                s += "{0} \cdot ".format(cc)
                a = monom[i][0]; b = monom[i][1]
                if a == 0 and b != 0:
                    s+="E_6^{{ {0} }}".format(b)
                elif b ==0 and a != 0:
                    s+="E_4^{{ {0} }}".format(a)
                else:
                    s+="E_4^{{ {0} }}E_6^{{ {1} }}".format(a,b)
                info['explicit_formulas'] += s
            info['explicit_formulas'] += " \)"            
    # cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + '&label=' + str(label) # never used
    if len(WNF.parent.hecke_orbits) > 1:
        for label_other in WNF.parent.hecke_orbits.keys():
            if(label_other != label):
                s = 'Modular form '
                if character:
                    s += newform_label(level,weight,character,label_other)
                else:
                    s += newform_label(level,weight,1,label_other)

                url = url_for('emf.render_elliptic_modular_forms', level=level,
                              weight=weight, character=character, label=label_other)
                friends.append((s, url))

    s = 'L-Function '
    if character:
        s += newform_label(level,weight,character,label)
    else:
        s += newform_label(level,weight,1,label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for(
        'emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_available_prec()
    return info
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))    
    WMFS = None
    if info.has_key('error'):
        return info
    if level <= 0:
        info['error'] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True)
        WMFS.update_from_db() ## Need to call an extra time for some reason...
        if not WMFS.has_updated():
            stop = False
            orbit = WMFS.character.character.galois_orbit()
            while not stop:
                if len(orbit) == 0:
                    stop = True
                    continue
                c = orbit.pop()
                if c.number() == WMFS.character.number:
                    continue
                print c.number()
                WMFS_rep = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = c.number(), update_from_db=True)
                if WMFS_rep.has_updated_from_db():
                    stop = True
                    info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character = c.number())
                    info['wmfs_rep_number'] =  c.number()
                    
        emf_logger.debug("Created WebModFormSpace %s"%WMFS)
        if 'download' in info and 'tempfile' in info:
            save(WNF,info['tempfile'])
            info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj'
            return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        #if isinstance(e,IndexError):
        info['error'] = e.message
        WMFS = None
    if WMFS is None:
        info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error',''))
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits):
        #    ## Try to add them here... 
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F = 
        #        WMFS.hecke_orbits.append(F)
        info['space'] = WMFS
#    info['old_decomposition'] = WMFS.oldspace_decomposition()
    info['oldspace_decomposition']=''
    try: 
        emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition))
        if WMFS.oldspace_decomposition != []:
            emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition))
            l = []
            for t in WMFS.oldspace_decomposition:
                emf_logger.debug("t={0}".format(t))
                N,k,chi,mult,d = t
                url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi)
                if chi != 1:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi)
                else:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N)
                l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url))
            if l != []:            
                s = "\\oplus ".join(l)
                info['oldspace_decomposition']=' $ {0} $'.format(s)
    except Exception as e:
        emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e))
    ## For side-bar
    lifts = list()
    lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q'))
    lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q'))
    info['lifts'] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        # catch the url being None or set to '':
        if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url:
            friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url))
        if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url:
            friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info['friends'] = friends
    
    return info
예제 #11
0
def set_info_for_web_newform(level=None,
                             weight=None,
                             character=None,
                             label=None,
                             **kwds):
    r"""
    Set the info for on modular form.

    """
    info = to_dict(kwds)
    info['level'] = level
    info['weight'] = weight
    info['character'] = character
    info['label'] = label
    if level is None or weight is None or character is None or label is None:
        s = "In set info for one form but do not have enough args!"
        s += "level={0},weight={1},character={2},label={3}".format(
            level, weight, character, label)
        emf_logger.critical(s)
    emf_logger.debug("In set_info_for_one_mf: info={0}".format(info))
    prec = my_get(info, 'prec', default_prec, int)
    bprec = my_get(info, 'bprec', default_display_bprec, int)
    emf_logger.debug("PREC: {0}".format(prec))
    emf_logger.debug("BITPREC: {0}".format(bprec))
    try:
        WNF = WebNewForm_cached(level=level,
                                weight=weight,
                                character=character,
                                label=label)
        if not WNF.has_updated():
            raise IndexError(
                "Unfortunately, we do not have this newform in the database.")
        info['character_order'] = WNF.character.order
        info['code'] = WNF.code
        emf_logger.debug("defined webnewform for rendering!")
    except IndexError as e:
        info['error'] = e.message
    url0 = url_for("mf.modular_form_main_page")
    url1 = url_for("emf.render_elliptic_modular_forms")
    url2 = url_for("emf.render_elliptic_modular_forms", level=level)
    url3 = url_for("emf.render_elliptic_modular_forms",
                   level=level,
                   weight=weight)
    url4 = url_for("emf.render_elliptic_modular_forms",
                   level=level,
                   weight=weight,
                   character=character)
    bread = [(MF_TOP, url0), (EMF_TOP, url1)]
    bread.append(("Level %s" % level, url2))
    bread.append(("Weight %s" % weight, url3))
    bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4))
    bread.append(
        ("Newform %d.%d.%d.%s" % (level, weight, int(character), label), ''))
    info['bread'] = bread

    properties2 = list()
    friends = list()
    space_url = url_for('emf.render_elliptic_modular_forms',
                        level=level,
                        weight=weight,
                        character=character)
    friends.append(
        ('\( S_{%s}(%s, %s)\)' %
         (WNF.weight, WNF.level, WNF.character.latex_name), space_url))
    if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url:
        friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty,
                        WNF.base_ring.lmfdb_url))
    if hasattr(WNF.coefficient_field,
               "lmfdb_url") and WNF.coefficient_field.lmfdb_label:
        friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty,
                        WNF.coefficient_field.lmfdb_url))
    friends = uniq(friends)
    friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)",
                    WNF.character.url()))

    if WNF.dimension == 0 and not info.has_key('error'):
        info['error'] = "This space is empty!"
    info['title'] = 'Newform ' + WNF.hecke_orbit_label
    info['learnmore'] = [('History of modular forms',
                          url_for('.holomorphic_mf_history'))]
    if 'error' in info:
        return info
    ## Until we have figured out how to do the embeddings correctly we don't display the Satake
    ## parameters for non-trivial characters....

    ## Example to illustrate the different cases
    ## base              = CyclotomicField(n) -- of degree phi(n)
    ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m
    ##   we would then have cdeg = m*phi(n) and bdeg = phi(n)
    ##   and rdeg = m
    ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6)
    ## we get coefficient_field.relative_degree() == 2 although it should be 1
    cdeg = WNF.coefficient_field.absolute_degree()
    bdeg = WNF.base_ring.absolute_degree()
    if cdeg == 1:
        rdeg = 1
    else:
        ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result...
        ##
        rdeg = QQ(cdeg) / QQ(bdeg)
    cf_is_QQ = (cdeg == 1)
    br_is_QQ = (bdeg == 1)
    if cf_is_QQ:
        info['satake'] = WNF.satake
    if WNF.complexity_of_first_nonvanishing_coefficients(
    ) > default_max_height:
        info['qexp'] = ""
        info['qexp_display'] = ''
        info['hide_qexp'] = True
        n, c = WNF.first_nonvanishing_coefficient()
        info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace())
        info['norm_nv'] = '\\approx ' + latex(
            WNF.first_nonvanishing_coefficient_norm().n())
        info['index_nv'] = n
    else:
        if WNF.prec < prec:
            #get WNF record at larger prec
            WNF.prec = prec
            WNF.update_from_db()
        info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ')
        info['qexp_display'] = url_for(".get_qexp_latex",
                                       level=level,
                                       weight=weight,
                                       character=character,
                                       label=label)
        info["hide_qexp"] = False
    info['max_cn_qexp'] = WNF.q_expansion.prec()
    ## All combinations should be tested...
    ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6)
    ## 13/3/8/a ->  base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring
    ## 13/4/3/a ->  base_ring = coefficient_field = QQ(zeta_3)
    ## 13/4/1/a -> all rational
    ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17))
    ## These are variables which needs to be set properly below
    info['polvars'] = {'base_ring': 'x', 'coefficient_field': '\\alpha'}
    if not cf_is_QQ:
        if rdeg > 1:  # not WNF.coefficient_field == WNF.base_ring:
            ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this.
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = web_latex_poly(p1,
                                       '\\alpha')  # make the variable \alpha
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            zeta = p1.base_ring().gens()[0]
            #           p2 = zeta.minpoly() #this is not used anymore
            #           b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore
            z1 = zeta.multiplicative_order()
            info['coeff_field'] = [
                WNF.coefficient_field.absolute_polynomial_latex('x'),
                c_pol_ltx_x, z1
            ]
            if hasattr(WNF.coefficient_field,
                       "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [
                    WNF.coefficient_field.lmfdb_url,
                    WNF.coefficient_field.lmfdb_pretty,
                    WNF.coefficient_field.lmfdb_label
                ]
            if z1 == 4:
                info[
                    'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(
                        c_pol_ltx)
                info['polvars']['base_ring'] = 'i'
            elif z1 <= 2:
                info[
                    'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(
                        c_pol_ltx)
            else:
                info[
                    'polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) ' % (
                        c_pol_ltx, z1, z1)
                info['polvars']['base_ring'] = '\zeta_{{ {0} }}'.format(z1)
                if z1 == 3:
                    info[
                        'polynomial_st'] += 'is a primitive cube root of unity.'
                else:
                    info[
                        'polynomial_st'] += 'is a primitive {0}-th root of unity.'.format(
                            z1)
        elif not br_is_QQ:
            ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field
            ## generated by some \zeta_n
            p1 = WNF.coefficient_field.absolute_polynomial()
            z1 = WNF.coefficient_field.gens()[0].multiplicative_order()
            c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1))
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            info['coeff_field'] = [
                WNF.coefficient_field.absolute_polynomial_latex('x'),
                c_pol_ltx_x
            ]
            if hasattr(WNF.coefficient_field,
                       "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [
                    WNF.coefficient_field.lmfdb_url,
                    WNF.coefficient_field.lmfdb_pretty,
                    WNF.coefficient_field.lmfdb_label
                ]
            if z1 == 4:
                info[
                    'polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format(
                        c_pol_ltx)
                info['polvars']['coefficient_field'] = 'i'
            elif z1 <= 2:
                info['polynomial_st'] = ''
            else:
                info[
                    'polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format(
                        z1)
                info['polvars']['coefficient_field'] = '\zeta_{{{0}}}'.format(
                    z1)
                if z1 == 3:
                    info[
                        'polynomial_st'] += 'is a primitive cube root of unity.</div>'
                else:
                    info[
                        'polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format(
                            z1)
    else:
        info['polynomial_st'] = ''
    if info["hide_qexp"]:
        info['polynomial_st'] = ''
    info['degree'] = int(cdeg)
    if cdeg == 1:
        info['is_rational'] = 1
        info['coeff_field_pretty'] = [
            WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty
        ]
    else:
        info['is_rational'] = 0
    emf_logger.debug("PREC2: {0}".format(prec))
    info['embeddings'] = WNF._embeddings[
        'values']  #q_expansion_embeddings(prec, bprec,format='latex')
    info['embeddings_len'] = len(info['embeddings'])
    properties2 = [('Level', str(level)), ('Weight', str(weight)),
                   ('Character', '$' + WNF.character.latex_name + '$'),
                   ('Label', WNF.hecke_orbit_label),
                   ('Dimension of Galois orbit', str(WNF.dimension))]
    if (ZZ(level)).is_squarefree():
        info['twist_info'] = WNF.twist_info
        if isinstance(info['twist_info'],
                      list) and len(info['twist_info']) > 0:
            info['is_minimal'] = info['twist_info'][0]
            if (info['twist_info'][0]):
                s = 'Is minimal<br>'
            else:
                s = 'Is a twist of lower level<br>'
            properties2 += [('Twist info', s)]
    else:
        info['twist_info'] = 'Twist info currently not available.'
        properties2 += [('Twist info', 'not available')]
    args = list()
    for x in range(5, 200, 10):
        args.append({'digits': x})
    alev = None
    CM = WNF._cm_values
    if CM is not None:
        if CM.has_key('tau') and len(CM['tau']) != 0:
            info['CM_values'] = CM
    info['is_cm'] = WNF.is_cm
    if WNF.is_cm == 1:
        info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc)
        info['cm_disc'] = WNF.cm_disc
        info['cm_field_knowl'] = nf_display_knowl(
            info['cm_field'], getDBConnection(),
            field_pretty(info['cm_field']))
        info['cm_field_url'] = url_for("number_fields.by_label",
                                       label=info["cm_field"])
    if WNF.is_cm is None or WNF.is_cm == -1:
        s = '- Unknown (insufficient data)<br>'
    elif WNF.is_cm == 1:
        s = 'Yes<br>'
    else:
        s = 'No<br>'
    properties2.append(('CM', s))
    alev = WNF.atkin_lehner_eigenvalues()
    info['atkinlehner'] = None
    if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1:
        s1 = " Atkin-Lehner eigenvalues "
        s2 = ""
        for Q in alev.keys():
            s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q])
        properties2.append((s1, s2))
        emf_logger.debug("properties={0}".format(properties2))
        # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps()
        # if isinstance(alev,dict) and len(alev.keys())>0:
        #     emf_logger.debug("alev={0}".format(alev))
        #     info['atkinlehner'] = list()
        #     for Q in alev.keys():
        #         s = "\(" + latex(c) + "\)"
        #         Q = alev[c][0]
        #         ev = alev[c][1]
        #         info['atkinlehner'].append([Q, c, ev])
    if (level == 1):
        poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '')
        if poly != '':
            d, monom, coeffs = poly
            emf_logger.critical("poly={0}".format(poly))
            info['explicit_formulas'] = '\('
            for i in range(len(coeffs)):
                c = QQ(coeffs[i])
                s = ""
                if d > 1 and i > 0 and c > 0:
                    s = "+"
                if c < 0:
                    s = "-"
                if c.denominator() > 1:
                    cc = "\\frac{{ {0} }}{{ {1} }}".format(
                        abs(c.numerator()), c.denominator())
                else:
                    cc = str(abs(c))
                s += "{0} \cdot ".format(cc)
                a = monom[i][0]
                b = monom[i][1]
                if a == 1:
                    a = ""
                if b == 1:
                    b = ""
                if a == 0 and b != 0:
                    s += "E_6^{{ {0} }}(z)".format(b)
                elif b == 0 and a != 0:
                    s += "E_4^{{ {0} }}(z)".format(a)
                else:
                    s += "E_4^{{ {0} }}(z) \cdot E_6^{{ {1} }}(z)".format(a, b)
                info['explicit_formulas'] += s
            info['explicit_formulas'] += " \)"
    # cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + '&label=' + str(label) # never used
    if len(WNF.parent.hecke_orbits) > 1:
        for label_other in WNF.parent.hecke_orbits.keys():
            if (label_other != label):
                s = 'Modular form '
                if character:
                    s += newform_label(level, weight, character, label_other)
                else:
                    s += newform_label(level, weight, 1, label_other)

                url = url_for('emf.render_elliptic_modular_forms',
                              level=level,
                              weight=weight,
                              character=character,
                              label=label_other)
                friends.append((s, url))

    s = 'L-Function '
    if character:
        s += newform_label(level, weight, character, label)
    else:
        s += newform_label(level, weight, 1, label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for('emf.render_elliptic_modular_forms',
                         level=level,
                         weight=weight,
                         character=character,
                         label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_available_prec()
    return info
예제 #12
0
def submatrix_configurations(S):
    configs = orbit(S)
    [m.set_immutable() for m in configs]
    return uniq(configs)
예제 #13
0
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))    
    WMFS = None
    if info.has_key('error'):
        return info
    if level <= 0:
        info['error'] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True)
        emf_logger.debug("Created WebModFormSpace %s"%WMFS)
        if not WMFS.has_updated():
            #get the representative we have in the db for this space (Galois conjugate)
            #note that this does not use the web_object infrastructure at all right now
            #which should be changed for sure!
            dimension_table_name = WebModFormSpace._dimension_table_name
            db_dim = getDBConnection()['modularforms2'][dimension_table_name]
            rep = db_dim.find_one({'level': level, 'weight': weight, 'character_orbit': {'$in': [character]}})
            if not rep is None and not rep['cchi'] == character: # don't link back to myself!
                info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=rep['cchi'])
                info['wmfs_rep_number'] =  rep['cchi']
        # FIXME: the variable WNF is not defined above, so the code below cannot work (I don't think it is ever used)
        # if 'download' in info and 'tempfile' in info:
        #     save(WNF,info['tempfile'])
        #     info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj'
        #     return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        #if isinstance(e,IndexError):
        info['error'] = e.message
        WMFS = None
    if WMFS is None:
        info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error',''))
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits):
        #    ## Try to add them here... 
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F = 
        #        WMFS.hecke_orbits.append(F)
        info['space'] = WMFS
        info['max_height'] = default_max_height
#    info['old_decomposition'] = WMFS.oldspace_decomposition()
    info['oldspace_decomposition']=''
    try: 
        emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition))
        if WMFS.oldspace_decomposition != []:
            emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition))
            l = []
            for t in WMFS.oldspace_decomposition:
                emf_logger.debug("t={0}".format(t))
                N,k,chi,mult,d = t
                url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi)
                if chi != 1:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi)
                else:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N)
                l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url))
            if l != []:            
                s = "\\oplus ".join(l)
                info['oldspace_decomposition']=' $ {0} $'.format(s)
    except Exception as e:
        emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e))
    ## For side-bar
    lifts = list()
    lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q'))
    lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q'))
    info['lifts'] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        # catch the url being None or set to '':
        if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url:
            friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url))
        if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url:
            friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info['friends'] = friends
    info['code'] = WMFS.code
    
    return info
예제 #14
0
    def _compute_simple_modules_graph_from_startpoint(self, s, p=None, cut_nonsimple_aniso=True, fast=1):
        # for forking this is necessary
        logger = get_logger(s)
        # print logger
        k = self._weight
        ###########################################################
        # Determine which primes need to be checked
        # According to the proof of Proposition XX in [BEF], we
        # only need to check primesnot dividing the 6*level(s),
        # for which prime_pol(s,p,k) <= 0.
        # For those primes, we check if there is any
        # k-simple fqm in s.C(p) and if not, we do not have to
        # consider p anymore.
        ###########################################################
        if p == None:
            p = 2
            N = Integer(6) * s.level()
            slp = N.prime_factors()
            for q in prime_range(next_prime(N) + 1):
                if not q in slp:
                    logger.info(
                        "Smallest prime not dividing 6*level({0}) = {1} is p = {2}".format(s, Integer(6) * s.level(), q))
                    p = q
                    break
            while prime_pol(s, p, k) <= 0 or p in slp:
                p = next_prime(p)
            p = uniq(prime_range(p) + slp)
        logger.info("Starting with s = {0} and primes = {1}".format(s, p))
        
        if isinstance(p, list):
            primes = p
        else:
            primes = [p]

        simple = s.is_simple(k, reduction = self._reduction, bound = self._bound)
        
        if not simple:
            logger.info("{0} is not simple.".format(s))

        # print simple
        s = FQM_vertex(s)
        # print s
        self.add_vertex(s)
        # print "added vertex ", s
        
        ############################################################
        # Starting from the list of primes we generated,
        # we now compute which primes we actually need to consider.
        # That is, the primes such that there is a fqm in s.C(p)
        # which is k-simple.
        ############################################################
        np = list()
        if cut_nonsimple_aniso and simple:
            for i in range(len(primes)):
                p = primes[i]
                fs = False
                for t in s.genus_symbol().C(p, False):
                    if t.is_simple(k, bound = self._bound):
                        fs = True
                        logger.debug("Setting fs = True")
                        break
                if fs:
                    np.append(p)
        primes = np
        # print "here", primes
        logger.info("primes for graph for {0}: {1}".format(s, primes))
        # if len(primes) == 0:
        #    return
        heights = self._heights
        h = 0
        if not heights.has_key(h):
            heights[h] = [s]
        else:
            if heights[h].count(s) == 0:
                heights[h].append(s)
        vertex_colors = self._vertex_colors
        nonsimple_color = self._nonsimple_color
        simple_color = self._simple_color
        # Bs contains the modules of the current level (= height = h)
        Bs = [s]
        # set the correct color for the vertex s
        if simple:
            if vertex_colors[simple_color].count(s) == 0:
                vertex_colors[simple_color].append(s)
        elif vertex_colors[nonsimple_color].count(s) == 0:
            vertex_colors[nonsimple_color].append(s)
        
        ###################################################
        # MAIN LOOP
        # we loop until we haven't found any simple fqm's
        ###################################################
        while simple:
            h = h + 1
            if not heights.has_key(h):
                heights[h] = list()
            # the list Bss will contain the k-simple modules of the next height level
            # recall that Bs contains the modules of the current height level
            Bss = list()
            simple = False
            # checklist = modules that we need to check for with .is_simple(k)
            # we assemble this list because afterwards
            # we check them in parallel
            checklist = []
            for s1 in Bs:
                Bs2 = list()
                for p in primes:
                    # check if we really need to check p for s1
                    # otherwise none of the fqm's in s1.C(p) are simple
                    # and we will not consider them.
                    if prime_pol(s1.genus_symbol(), p, k) <= 0:
                        Bs2 = Bs2 + s1.genus_symbol().C(p, False)
                    else:
                        logger.info(
                            "Skipping p = {0} for s1 = {1}".format(p, s1))
                        # print "Skipping p = {0} for s1 = {1}".format(p, s1)
                # print "Bs2 = ", Bs2
                # now we actually check the symbols in Bs2
                for s2 in Bs2:
                    if s2.max_rank() > self._rank_limit:
                        # we skip s2 if its minimal number of generators
                        # is > than the given rank_limit.
                        continue
                    s2 = FQM_vertex(s2)
                    skip = False
                    for v in self._heights[h]:
                        # we skip symbols that correspond to isomorphic modules
                        if v.genus_symbol().defines_isomorphic_module(s2.genus_symbol()):
                            skip = True
                            logger.debug(
                                "skipping {0} b/c isomorphic to {1}".format(s2.genus_symbol(), v.genus_symbol()))
                            s2 = v
                            break
                    if skip:
                        continue
                    if not skip:
                        self.add_vertex(s2)
                        heights[h].append(s2)
                    self.update_edges(s2, h, fast=fast)
                    # before using the actual dimension formula
                    # we check if there is already a non-k-simple neighbor
                    # (an incoming edge from a non-k-simple module)
                    # which would imply that s2 is not k-simple.
                    has_nonsimple_neighbor = False
                    for e in self.incoming_edges(s2):
                        if vertex_colors[nonsimple_color].count(e[0]) > 0:
                            has_nonsimple_neighbor = True
                            logger.debug(
                                "Has nonsimple neighbor: {0}".format(s2.genus_symbol()))
                            break
                    if has_nonsimple_neighbor:
                        #not simple
                        if not vertex_colors[nonsimple_color].count(s2) > 0:
                            vertex_colors[nonsimple_color].append(s2)
                    else:
                        checklist.append((s2, k, self._reduction, self._bound))
            logger.debug("checklist = {0}".format(checklist))
            # check the modules in checklist
            # for being k-simple
            # this is done in parallel
            # when a process returns
            # we add the vertex and give it its appropriate color
            if NCPUS1 == 1:
                checks = [([[s[0]]],check_simple(*s)) for s in checklist]
            else:
                checks = list(check_simple(checklist))
            logger.info("checks = {0}".format(checks))
            for check in checks:
                s2 = check[0][0][0]
                if check[1]:
                    simple = True
                    logger.info(
                        "Found simple module: {0}".format(s2.genus_symbol()))
                    Bss.append(s2)
                    if not vertex_colors[simple_color].count(s2) > 0:
                        vertex_colors[simple_color].append(s2)
                else:
                    if not vertex_colors[nonsimple_color].count(s2) > 0:
                        vertex_colors[nonsimple_color].append(s2)
            Bs = Bss
        simple = [v.genus_symbol() for v in vertex_colors[simple_color]]
        self._simple = uniq(simple)
예제 #15
0
    def _compute_simple_modules_graph_from_startpoint(self,
                                                      s,
                                                      p=None,
                                                      cut_nonsimple_aniso=True,
                                                      fast=1):
        # for forking this is necessary
        logger = get_logger(s)
        # print logger
        k = self._weight
        ###########################################################
        # Determine which primes need to be checked
        # According to the proof of Proposition XX in [BEF], we
        # only need to check primesnot dividing the 6*level(s),
        # for which prime_pol(s,p,k) <= 0.
        # For those primes, we check if there is any
        # k-simple fqm in s.C(p) and if not, we do not have to
        # consider p anymore.
        ###########################################################
        if p == None:
            p = 2
            N = Integer(6) * s.level()
            slp = N.prime_factors()
            for q in prime_range(next_prime(N) + 1):
                if not q in slp:
                    logger.info(
                        "Smallest prime not dividing 6*level({0}) = {1} is p = {2}"
                        .format(s,
                                Integer(6) * s.level(), q))
                    p = q
                    break
            while prime_pol(s, p, k) <= 0 or p in slp:
                p = next_prime(p)
            p = uniq(prime_range(p) + slp)
        logger.info("Starting with s = {0} and primes = {1}".format(s, p))

        if isinstance(p, list):
            primes = p
        else:
            primes = [p]

        simple = s.is_simple(k, reduction=self._reduction, bound=self._bound)

        if not simple:
            logger.info("{0} is not simple.".format(s))

        # print simple
        s = FQM_vertex(s)
        # print s
        self.add_vertex(s)
        # print "added vertex ", s

        ############################################################
        # Starting from the list of primes we generated,
        # we now compute which primes we actually need to consider.
        # That is, the primes such that there is a fqm in s.C(p)
        # which is k-simple.
        ############################################################
        np = list()
        if cut_nonsimple_aniso and simple:
            for i in range(len(primes)):
                p = primes[i]
                fs = False
                for t in s.genus_symbol().C(p, False):
                    if t.is_simple(k, bound=self._bound):
                        fs = True
                        logger.debug("Setting fs = True")
                        break
                if fs:
                    np.append(p)
        primes = np
        # print "here", primes
        logger.info("primes for graph for {0}: {1}".format(s, primes))
        # if len(primes) == 0:
        #    return
        heights = self._heights
        h = 0
        if not heights.has_key(h):
            heights[h] = [s]
        else:
            if heights[h].count(s) == 0:
                heights[h].append(s)
        vertex_colors = self._vertex_colors
        nonsimple_color = self._nonsimple_color
        simple_color = self._simple_color
        # Bs contains the modules of the current level (= height = h)
        Bs = [s]
        # set the correct color for the vertex s
        if simple:
            if vertex_colors[simple_color].count(s) == 0:
                vertex_colors[simple_color].append(s)
        elif vertex_colors[nonsimple_color].count(s) == 0:
            vertex_colors[nonsimple_color].append(s)

        ###################################################
        # MAIN LOOP
        # we loop until we haven't found any simple fqm's
        ###################################################
        while simple:
            h = h + 1
            if not heights.has_key(h):
                heights[h] = list()
            # the list Bss will contain the k-simple modules of the next height level
            # recall that Bs contains the modules of the current height level
            Bss = list()
            simple = False
            # checklist = modules that we need to check for with .is_simple(k)
            # we assemble this list because afterwards
            # we check them in parallel
            checklist = []
            for s1 in Bs:
                Bs2 = list()
                for p in primes:
                    # check if we really need to check p for s1
                    # otherwise none of the fqm's in s1.C(p) are simple
                    # and we will not consider them.
                    if prime_pol(s1.genus_symbol(), p, k) <= 0:
                        Bs2 = Bs2 + s1.genus_symbol().C(p, False)
                    else:
                        logger.info("Skipping p = {0} for s1 = {1}".format(
                            p, s1))
                        # print "Skipping p = {0} for s1 = {1}".format(p, s1)
                # print "Bs2 = ", Bs2
                # now we actually check the symbols in Bs2
                for s2 in Bs2:
                    if s2.max_rank() > self._rank_limit:
                        # we skip s2 if its minimal number of generators
                        # is > than the given rank_limit.
                        continue
                    s2 = FQM_vertex(s2)
                    skip = False
                    for v in self._heights[h]:
                        # we skip symbols that correspond to isomorphic modules
                        if v.genus_symbol().defines_isomorphic_module(
                                s2.genus_symbol()):
                            skip = True
                            logger.debug(
                                "skipping {0} b/c isomorphic to {1}".format(
                                    s2.genus_symbol(), v.genus_symbol()))
                            s2 = v
                            break
                    if skip:
                        continue
                    if not skip:
                        self.add_vertex(s2)
                        heights[h].append(s2)
                    self.update_edges(s2, h, fast=fast)
                    # before using the actual dimension formula
                    # we check if there is already a non-k-simple neighbor
                    # (an incoming edge from a non-k-simple module)
                    # which would imply that s2 is not k-simple.
                    has_nonsimple_neighbor = False
                    for e in self.incoming_edges(s2):
                        if vertex_colors[nonsimple_color].count(e[0]) > 0:
                            has_nonsimple_neighbor = True
                            logger.debug("Has nonsimple neighbor: {0}".format(
                                s2.genus_symbol()))
                            break
                    if has_nonsimple_neighbor:
                        #not simple
                        if not vertex_colors[nonsimple_color].count(s2) > 0:
                            vertex_colors[nonsimple_color].append(s2)
                    else:
                        checklist.append((s2, k, self._reduction, self._bound))
            logger.debug("checklist = {0}".format(checklist))
            # check the modules in checklist
            # for being k-simple
            # this is done in parallel
            # when a process returns
            # we add the vertex and give it its appropriate color
            if NCPUS1 == 1:
                checks = [([[s[0]]], check_simple(*s)) for s in checklist]
            else:
                checks = list(check_simple(checklist))
            logger.info("checks = {0}".format(checks))
            for check in checks:
                s2 = check[0][0][0]
                if check[1]:
                    simple = True
                    logger.info("Found simple module: {0}".format(
                        s2.genus_symbol()))
                    Bss.append(s2)
                    if not vertex_colors[simple_color].count(s2) > 0:
                        vertex_colors[simple_color].append(s2)
                else:
                    if not vertex_colors[nonsimple_color].count(s2) > 0:
                        vertex_colors[nonsimple_color].append(s2)
            Bs = Bss
        simple = [v.genus_symbol() for v in vertex_colors[simple_color]]
        self._simple = uniq(simple)
예제 #16
0
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))    
    WMFS = None
    if info.has_key('error'):
        return info
    if level <= 0:
        info['error'] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True)
        if not WMFS.has_updated():
            stop = False
            orbit = WMFS.character.character.galois_orbit()
            while not stop:
                if len(orbit) == 0:
                    stop = True
                    continue
                c = orbit.pop()
                if c.number() == WMFS.character.number:
                    continue
                print c.number()
                WMFS_rep = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = c.number(), update_from_db=True)
                if WMFS_rep.has_updated_from_db():
                    stop = True
                    info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character = c.number())
                    info['wmfs_rep_number'] =  c.number()
                    
        emf_logger.debug("Created WebModFormSpace %s"%WMFS)
        if 'download' in info and 'tempfile' in info:
            save(WNF,info['tempfile'])
            info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj'
            return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        #if isinstance(e,IndexError):
        info['error'] = e.message
        WMFS = None
    if WMFS is None:
        info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error',''))
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits):
        #    ## Try to add them here... 
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F = 
        #        WMFS.hecke_orbits.append(F)
        info['space'] = WMFS
#    info['old_decomposition'] = WMFS.oldspace_decomposition()

    ## For side-bar
    lifts = list()
    lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q'))
    lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q'))
    info['lifts'] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        # catch the url being None or set to '':
        if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url:
            friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url))
        if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url:
            friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info['friends'] = friends
    
    return info
예제 #17
0
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds):
    r"""
    Set the info for on modular form.

    """
    info = to_dict(kwds)
    info["level"] = level
    info["weight"] = weight
    info["character"] = character
    info["label"] = label
    if level is None or weight is None or character is None or label is None:
        s = "In set info for one form but do not have enough args!"
        s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label)
        emf_logger.critical(s)
    emf_logger.debug("In set_info_for_one_mf: info={0}".format(info))
    prec = my_get(info, "prec", default_prec, int)
    bprec = my_get(info, "bprec", default_display_bprec, int)
    emf_logger.debug("PREC: {0}".format(prec))
    emf_logger.debug("BITPREC: {0}".format(bprec))
    try:
        WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label)
        emf_logger.critical("defined webnewform for rendering!")
        # if info.has_key('download') and info.has_key('tempfile'):
        #     WNF._save_to_file(info['tempfile'])
        #     info['filename']=str(weight)+'-'+str(level)+'-'+str(character)+'-'+label+'.sobj'
        #     return info
    except IndexError as e:
        WNF = None
        info["error"] = e.message
    url1 = url_for("emf.render_elliptic_modular_forms")
    url2 = url_for("emf.render_elliptic_modular_forms", level=level)
    url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight)
    url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character)
    bread = [(EMF_TOP, url1)]
    bread.append(("of level %s" % level, url2))
    bread.append(("weight %s" % weight, url3))
    if int(character) == 0:
        bread.append(("trivial character", url4))
    else:
        bread.append(("\( %s \)" % (WNF.character.latex_name), url4))
    info["bread"] = bread

    properties2 = list()
    friends = list()
    space_url = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character)
    friends.append(("\( S_{%s}(%s, %s)\)" % (WNF.weight, WNF.level, WNF.character.latex_name), space_url))
    if WNF.coefficient_field_label(check=True):
        friends.append(("Number field " + WNF.coefficient_field_label(), WNF.coefficient_field_url()))
    friends.append(("Number field " + WNF.base_field_label(), WNF.base_field_url()))
    friends = uniq(friends)
    friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url()))

    if WNF.dimension == 0:
        info["error"] = "This space is empty!"

    #    emf_logger.debug("WNF={0}".format(WNF))

    # info['name'] = name
    info["title"] = "Modular Form " + WNF.hecke_orbit_label

    if "error" in info:
        return info
    # info['name']=WNF._name
    ## Until we have figured out how to do the embeddings correctly we don't display the Satake
    ## parameters for non-trivial characters....

    cdeg = WNF.coefficient_field.absolute_degree()
    bdeg = WNF.base_ring.absolute_degree()
    if WNF.coefficient_field.absolute_degree() == 1:
        rdeg = 1
    else:
        rdeg = WNF.coefficient_field.relative_degree()
    if cdeg == 1:
        info["satake"] = WNF.satake
    info["qexp"] = WNF.q_expansion_latex(prec=10, name="a")
    info["qexp_display"] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label)

    # info['qexp'] = WNF.q_expansion_latex(prec=prec)
    # c_pol_st = str(WNF.absolute_polynomial)
    # b_pol_st = str(WNF.polynomial(type='base_ring',format='str'))
    # b_pol_ltx = str(WNF.polynomial(type='base_ring',format='latex'))
    # print "c=",c_pol_ltx
    # print "b=",b_pol_ltx
    if cdeg > 1:  ## Field is QQ
        if bdeg > 1 and rdeg > 1:
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = latex(p1)
            lgc = p1.variables()[0]
            c_pol_ltx = c_pol_ltx.replace(lgc, "a")
            z = p1.base_ring().gens()[0]
            p2 = z.minpoly()
            b_pol_ltx = latex(p2)
            b_pol_ltx = b_pol_ltx.replace(latex(p2.variables()[0]), latex(z))
            info["polynomial_st"] = "where \({0}=0\) and \({1}=0\).".format(c_pol_ltx, b_pol_ltx)
        else:
            c_pol_ltx = latex(WNF.coefficient_field.relative_polynomial())
            lgc = str(latex(WNF.coefficient_field.relative_polynomial().variables()[0]))
            c_pol_ltx = c_pol_ltx.replace(lgc, "a")
            info["polynomial_st"] = "where \({0}=0\)".format(c_pol_ltx)
    else:
        info["polynomial_st"] = ""
    info["degree"] = int(cdeg)
    if cdeg == 1:
        info["is_rational"] = 1
    else:
        info["is_rational"] = 0
    # info['q_exp_embeddings'] = WNF.print_q_expansion_embeddings()
    # if(int(info['degree'])>1 and WNF.dimension()>1):
    #    s = 'One can embed it into \( \mathbb{C} \) as:'
    # bprec = 26
    # print s
    #    info['embeddings'] =  ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision'])
    # elif(int(info['degree'])>1):
    #    s = 'There are '+str(info['degree'])+' embeddings into \( \mathbb{C} \):'
    # bprec = 26
    # print s
    #    info['embeddings'] =  ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision'])
    # else:
    #    info['embeddings'] = ''
    emf_logger.debug("PREC2: {0}".format(prec))
    info["embeddings"] = WNF._embeddings["values"]  # q_expansion_embeddings(prec, bprec,format='latex')
    info["embeddings_len"] = len(info["embeddings"])
    properties2 = []
    if (ZZ(level)).is_squarefree():
        info["twist_info"] = WNF.twist_info
        if isinstance(info["twist_info"], list) and len(info["twist_info"]) > 0:
            info["is_minimal"] = info["twist_info"][0]
            if info["twist_info"][0]:
                s = "- Is minimal<br>"
            else:
                s = "- Is a twist of lower level<br>"
            properties2 = [("Twist info", s)]
    else:
        info["twist_info"] = "Twist info currently not available."
        properties2 = [("Twist info", "not available")]
    args = list()
    for x in range(5, 200, 10):
        args.append({"digits": x})
    alev = None
    CM = WNF._cm_values
    if CM is not None:
        if CM.has_key("tau") and len(CM["tau"]) != 0:
            info["CM_values"] = CM
    info["is_cm"] = WNF.is_cm
    if WNF.is_cm is None:
        s = "- Unknown (insufficient data)<br>"
    elif WNF.is_cm is True:
        s = "- Is a CM-form<br>"
    else:
        s = "- Is not a CM-form<br>"
    properties2.append(("CM info", s))
    alev = WNF.atkin_lehner_eigenvalues()
    info["atkinlehner"] = None
    if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1:
        s1 = " Atkin-Lehner eigenvalues "
        s2 = ""
        for Q in alev.keys():
            s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q])
        properties2.append((s1, s2))
        emf_logger.debug("properties={0}".format(properties2))
        # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps()
        # if isinstance(alev,dict) and len(alev.keys())>0:
        #     emf_logger.debug("alev={0}".format(alev))
        #     info['atkinlehner'] = list()
        #     for Q in alev.keys():
        #         s = "\(" + latex(c) + "\)"
        #         Q = alev[c][0]
        #         ev = alev[c][1]
        #         info['atkinlehner'].append([Q, c, ev])
    if level == 1:
        poly = WNF.explicit_formulas.get("as_polynomial_in_E4_and_E6", "")
        if poly != "":
            d, monom, coeffs = poly
            emf_logger.critical("poly={0}".format(poly))

            info["explicit_formulas"] = "\("
            for i in range(d):
                c = QQ(coeffs[i])
                s = ""
                if d > 1 and i > 0 and c > 0:
                    s = "+"
                if c < 0:
                    s = "-"
                if c.denominator() > 1:
                    cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()), c.denominator())
                else:
                    cc = str(abs(c))
                s += "{0} \cdot ".format(cc)
                a = monom[i][0]
                b = monom[i][1]
                if a == 0 and b != 0:
                    s += "E_6^{{ {0} }}".format(b)
                elif b == 0 and a != 0:
                    s += "E_4^{{ {0} }}".format(a)
                else:
                    s += "E_4^{{ {0} }}E_6^{{ {1} }}".format(a, b)
                info["explicit_formulas"] += s
            info["explicit_formulas"] += " \)"
    cur_url = (
        "?&level=" + str(level) + "&weight=" + str(weight) + "&character=" + str(character) + "&label=" + str(label)
    )
    if len(WNF.parent.hecke_orbits) > 1:
        for label_other in WNF.parent.hecke_orbits.keys():
            if label_other != label:
                s = "Modular form "
                if character:
                    s = s + str(level) + "." + str(weight) + "." + str(character) + str(label_other)
                else:
                    s = s + str(level) + "." + str(weight) + str(label_other)
                url = url_for(
                    "emf.render_elliptic_modular_forms",
                    level=level,
                    weight=weight,
                    character=character,
                    label=label_other,
                )
                friends.append((s, url))

    s = "L-Function "
    if character:
        s = s + str(level) + "." + str(weight) + "." + str(character) + str(label)
    else:
        s = s + str(level) + "." + str(weight) + str(label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = "/L" + url_for(
        "emf.render_elliptic_modular_forms", level=level, weight=weight, character=character, label=label
    )
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + "." + label
        s = "Elliptic curve isogeny class " + llabel
        url = "/EllipticCurve/Q/" + llabel
        friends.append((s, url))
    info["properties2"] = properties2
    info["friends"] = friends
    info["max_cn"] = WNF.max_cn()
    return info
예제 #18
0
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))    
    WMFS = None
    if info.has_key('error'):
        return info
    if level <= 0:
        info['error'] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True)
        emf_logger.debug("Created WebModFormSpace %s"%WMFS)
        if not WMFS.has_updated():
            #get the representative we have in the db for this space (Galois conjugate)
            #note that this does not use the web_object infrastructure at all right now
            #which should be changed for sure!
            dimension_table_name = WebModFormSpace._dimension_table_name
            db_dim = getDBConnection()['modularforms2'][dimension_table_name]
            rep = db_dim.find_one({'level': level, 'weight': weight, 'character_orbit': {'$in': [character]}})
            if not rep is None and not rep['cchi'] == character: # don't link back to myself!
                info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=rep['cchi'])
                info['wmfs_rep_number'] =  rep['cchi']
        # FIXME: the variable WNF is not defined above, so the code below cannot work (I don't think it is ever used)
        # if 'download' in info and 'tempfile' in info:
        #     save(WNF,info['tempfile'])
        #     info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj'
        #     return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        #if isinstance(e,IndexError):
        info['error'] = e.message
        WMFS = None
    if WMFS is None:
        info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error',''))
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits):
        #    ## Try to add them here... 
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F = 
        #        WMFS.hecke_orbits.append(F)
        info['space'] = WMFS
        info['max_height'] = default_max_height
#    info['old_decomposition'] = WMFS.oldspace_decomposition()
    info['oldspace_decomposition']=''
    try: 
        emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition))
        if WMFS.oldspace_decomposition != []:
            emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition))
            l = []
            for t in WMFS.oldspace_decomposition:
                emf_logger.debug("t={0}".format(t))
                N,k,chi,mult,d = t
                url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi)
                if chi != 1:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi)
                else:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N)
                l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url))
            if l != []:            
                s = "\\oplus ".join(l)
                info['oldspace_decomposition']=' $ {0} $'.format(s)
    except Exception as e:
        emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e))
    ## For side-bar
    lifts = list()
    lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q'))
    lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q'))
    info['lifts'] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        # catch the url being None or set to '':
        if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url:
            friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url))
        if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url:
            friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info['friends'] = friends
    info['code'] = WMFS.code
    
    return info
예제 #19
0
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds):
    r"""
    Set the info for on modular form.

    """
    info = to_dict(kwds)
    info['level'] = level
    info['weight'] = weight
    info['character'] = character
    info['label'] = label
    if level is None or weight is None or character is None or label is None:
        s = "In set info for one form but do not have enough args!"
        s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label)
        emf_logger.critical(s)
    emf_logger.debug("In set_info_for_one_mf: info={0}".format(info))
    prec = my_get(info, 'prec', default_prec, int)
    bprec = my_get(info, 'bprec', default_display_bprec, int)
    emf_logger.debug("PREC: {0}".format(prec))
    emf_logger.debug("BITPREC: {0}".format(bprec))    
    try:
        WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label)
        emf_logger.critical("defined webnewform for rendering!")
        # if info.has_key('download') and info.has_key('tempfile'):
        #     WNF._save_to_file(info['tempfile'])
        #     info['filename']=str(weight)+'-'+str(level)+'-'+str(character)+'-'+label+'.sobj'
        #     return info
    except IndexError as e:
        WNF = None
        info['error'] = e.message
    url1 = url_for("emf.render_elliptic_modular_forms")
    url2 = url_for("emf.render_elliptic_modular_forms", level=level)
    url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight)
    url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character)
    bread = [(EMF_TOP, url1)]
    bread.append(("of level %s" % level, url2))
    bread.append(("weight %s" % weight, url3))
    if int(character) == 0:
        bread.append(("trivial character", url4))
    else:
        bread.append(("\( %s \)" % (WNF.character.latex_name), url4))
    info['bread'] = bread
    
    properties2 = list()
    friends = list()
    space_url = url_for('emf.render_elliptic_modular_forms',level=level, weight=weight, character=character)
    friends.append(('\( S_{%s}(%s, %s)\)'%(WNF.weight, WNF.level, WNF.character.latex_name), space_url))
    if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url:
        friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url))
    if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label:
        friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url))
    friends = uniq(friends)
    friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url()))
    
    if WNF.dimension==0:
        info['error'] = "This space is empty!"

#    emf_logger.debug("WNF={0}".format(WNF))    

    #info['name'] = name
    info['title'] = 'Modular Form ' + WNF.hecke_orbit_label
    
    if 'error' in info:
        return info
    # info['name']=WNF._name
    ## Until we have figured out how to do the embeddings correctly we don't display the Satake
    ## parameters for non-trivial characters....

    cdeg = WNF.coefficient_field.absolute_degree()
    bdeg = WNF.base_ring.absolute_degree()
    if cdeg == 1:
        rdeg = 1
    else:
        rdeg = WNF.coefficient_field.relative_degree()
    cf_is_QQ = (cdeg == 1)
    br_is_QQ = (bdeg == 1)
    if cf_is_QQ:
        info['satake'] = WNF.satake
    info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ')
    info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label)
    info['max_cn_qexp'] = WNF.q_expansion.prec()

    if not cf_is_QQ:
        if not br_is_QQ and rdeg>1: # not WNF.coefficient_field == WNF.base_ring:
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = web_latex_poly(p1, '\\alpha')  # make the variable \alpha
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            zeta = p1.base_ring().gens()[0]
#           p2 = zeta.minpoly() #this is not used anymore
#           b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore
            z1 = zeta.multiplicative_order() 
            info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'),c_pol_ltx_x, z1]
            if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label]
            if z1==4:
                info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(c_pol_ltx)
            elif z1<=2:
                info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx)
            else:
                info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\).'%(c_pol_ltx, z1,z1)
        else:
            p1 = WNF.coefficient_field.relative_polynomial()
            c_pol_ltx = web_latex_poly(p1, '\\alpha')
            c_pol_ltx_x = web_latex_poly(p1, 'x')
            z1 = p1.base_ring().gens()[0].multiplicative_order()
            info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x, z1]
            if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url:
                info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label]
            if z1==4:
                info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).'.format(c_pol_ltx)
            elif z1<=2:
                info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx)
            else:
                info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\).'%(c_pol_ltx, z1,z1)
    else:
        info['polynomial_st'] = ''
    info['degree'] = int(cdeg)
    if cdeg==1:
        info['is_rational'] = 1
        info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ]
    else:
        info['is_rational'] = 0
    # info['q_exp_embeddings'] = WNF.print_q_expansion_embeddings()
    # if(int(info['degree'])>1 and WNF.dimension()>1):
    #    s = 'One can embed it into \( \mathbb{C} \) as:'
        # bprec = 26
        # print s
    #    info['embeddings'] =  ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision'])
    # elif(int(info['degree'])>1):
    #    s = 'There are '+str(info['degree'])+' embeddings into \( \mathbb{C} \):'
        # bprec = 26
        # print s
    #    info['embeddings'] =  ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision'])
    # else:
    #    info['embeddings'] = ''
    emf_logger.debug("PREC2: {0}".format(prec))
    info['embeddings'] = WNF._embeddings['values'] #q_expansion_embeddings(prec, bprec,format='latex')
    info['embeddings_len'] = len(info['embeddings'])
    properties2 = []
    if (ZZ(level)).is_squarefree():
        info['twist_info'] = WNF.twist_info
        if isinstance(info['twist_info'], list) and len(info['twist_info'])>0:
            info['is_minimal'] = info['twist_info'][0]
            if(info['twist_info'][0]):
                s = 'Is minimal<br>'
            else:
                s = 'Is a twist of lower level<br>'
            properties2 = [('Twist info', s)]
    else:
        info['twist_info'] = 'Twist info currently not available.'
        properties2 = [('Twist info', 'not available')]
    args = list()
    for x in range(5, 200, 10):
        args.append({'digits': x})
    alev = None
    CM = WNF._cm_values
    if CM is not None:
        if CM.has_key('tau') and len(CM['tau']) != 0:
            info['CM_values'] = CM
    info['is_cm'] = WNF.is_cm
    if WNF.is_cm:
        info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc)
        info['cm_disc'] = WNF.cm_disc
        info['cm_field_knowl'] = nf_display_knowl(info['cm_field'], getDBConnection(), field_pretty(info['cm_field']))
        info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"])
    if WNF.is_cm is None:
        s = '- Unknown (insufficient data)<br>'
    elif WNF.is_cm:
        s = 'Is a CM-form<br>'
    else:
        s = 'Is not a CM-form<br>'
    properties2.append(('CM info', s))
    alev = WNF.atkin_lehner_eigenvalues()
    info['atkinlehner'] = None
    if isinstance(alev,dict) and len(alev.keys())>0 and level != 1:
        s1 = " Atkin-Lehner eigenvalues "
        s2 = ""
        for Q in alev.keys():
            s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q])
        properties2.append((s1, s2))
        emf_logger.debug("properties={0}".format(properties2))
        # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() 
        # if isinstance(alev,dict) and len(alev.keys())>0:
        #     emf_logger.debug("alev={0}".format(alev))
        #     info['atkinlehner'] = list()
        #     for Q in alev.keys():
        #         s = "\(" + latex(c) + "\)"
        #         Q = alev[c][0]
        #         ev = alev[c][1]
        #         info['atkinlehner'].append([Q, c, ev])
    if(level == 1):
        poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6','')
        if poly != '':
            d,monom,coeffs = poly
            emf_logger.critical("poly={0}".format(poly))
            info['explicit_formulas'] = '\('
            for i in range(len(coeffs)):
                c = QQ(coeffs[i])
                s = ""
                if d>1 and i >0 and c>0:
                    s="+"
                if c<0:
                    s="-"
                if c.denominator()>1:
                    cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()),c.denominator())
                else:
                    cc = str(abs(c))
                s += "{0} \cdot ".format(cc)
                a = monom[i][0]; b = monom[i][1]
                if a == 0 and b != 0:
                    s+="E_6^{{ {0} }}".format(b)
                elif b ==0 and a != 0:
                    s+="E_4^{{ {0} }}".format(a)
                else:
                    s+="E_4^{{ {0} }}E_6^{{ {1} }}".format(a,b)
                info['explicit_formulas'] += s
            info['explicit_formulas'] += " \)"            
    cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + \
        '&label=' + str(label)
    if len(WNF.parent.hecke_orbits) > 1:
        for label_other in WNF.parent.hecke_orbits.keys():
            if(label_other != label):
                s = 'Modular form '
                if character:
                    s = s + str(level) + '.' + str(weight) + '.' + str(character) + str(label_other)
                else:
                    s = s + str(level) + '.' + str(weight) + str(label_other)
                url = url_for('emf.render_elliptic_modular_forms', level=level,
                              weight=weight, character=character, label=label_other)
                friends.append((s, url))

    s = 'L-Function '
    if character:
        s = s + str(level) + '.' + str(weight) + '.' + str(character) + str(label)
    else:
        s = s + str(level) + '.' + str(weight) + str(label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for(
        'emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_cn()
    return info
예제 #20
0
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds):
    r"""
      Set information about a space of modular forms.
    """
    info = dict()
    emf_logger.debug("info={0}".format(info))    
    WMFS = None
    if info.has_key('error'):
        return info
    if level <= 0:
        info['error'] = "Got wrong level: %s " % level
        return info
    try:
        WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True)
        if not WMFS.has_updated():
            WMFS.update_from_db() ## Need to call an extra time for some reason...
        if not WMFS.has_updated():
            stop = False
            orbit = WMFS.character.character.galois_orbit()
            while not stop:
                if len(orbit) == 0:
                    stop = True
                    continue
                c = orbit.pop()
                if c.number() == WMFS.character.number:
                    continue
                print c.number()
                WMFS_rep = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = c.number(), update_from_db=True)
                if WMFS_rep.has_updated_from_db():
                    stop = True
                    info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character = c.number())
                    info['wmfs_rep_number'] =  c.number()
                    
        emf_logger.debug("Created WebModFormSpace %s"%WMFS)
        if 'download' in info and 'tempfile' in info:
            save(WNF,info['tempfile'])
            info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj'
            return info
    except ValueError as e:
        emf_logger.debug(e)
        emf_logger.debug(e.message)
        #if isinstance(e,IndexError):
        info['error'] = e.message
        WMFS = None
    if WMFS is None:
        info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error',''))
        return info
    else:
        ### Somehow the Hecke orbits are sometimes not in the space...
        #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits):
        #    ## Try to add them here... 
        #    for d in range(len(WMFS.dimension_new_cusp_forms())):
        #        F = 
        #        WMFS.hecke_orbits.append(F)
        info['space'] = WMFS
        info['max_height'] = default_max_height
#    info['old_decomposition'] = WMFS.oldspace_decomposition()
    info['oldspace_decomposition']=''
    try: 
        emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition))
        if WMFS.oldspace_decomposition != []:
            emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition))
            l = []
            for t in WMFS.oldspace_decomposition:
                emf_logger.debug("t={0}".format(t))
                N,k,chi,mult,d = t
                url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi)
                if chi != 1:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi)
                else:
                    sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N)
                l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url))
            if l != []:            
                s = "\\oplus ".join(l)
                info['oldspace_decomposition']=' $ {0} $'.format(s)
    except Exception as e:
        emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e))
    ## For side-bar
    lifts = list()
    lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q'))
    lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q'))
    info['lifts'] = lifts
    friends = list()
    for label in WMFS.hecke_orbits:
        f = WMFS.hecke_orbits[label]
        # catch the url being None or set to '':
        if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url:
            friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url))
        if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url:
            friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url))
    friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url()))
    friends = uniq(friends)
    info['friends'] = friends
    
    return info