Пример #1
0
def get_new_and_oldspace_decomposition(k, N, xi=0):
    r"""
    Get decomposition of the new and oldspace S_k(N,xi) into submodules.



    """
    M = ModularSymbols(N, k, sign=1).cuspidal_submodule()
    L = list()
    L = [M.new_submodule().dimension()]
    check_dim = M.new_submodule().dimension()
    for d in divisors(N):
        if(d == 1):
            continue
        O = M.old_submodule(d)
        Od = O.dimension()
        if(d == N and k == 2 or Od == 0):
            continue
        S = ModularSymbols(ZZ(N / d), k, sign=1).cuspidal_submodule().new_submodule()
        Sd = S.dimension()
        if(Sd == 0):
            logger.info("%s, %s" % (O, Od))
            logger.info("%s, %s" % (S, Sd))
        mult = len(divisors(ZZ(d)))
        check_dim = check_dim + mult * Sd
        L.append((ZZ(N / d), mult, Sd))
    check_dim = check_dim - M.dimension()
    if(check_dim != 0):
        raise ArithmeticError("Something wrong! check_dim=%s" % check_dim)
    return str(M.dimension(), L)
Пример #2
0
def render_elliptic_modular_forms(level=0, weight=0, character=None, label='', **kwds):
    r"""
    Default input of same type as required. Note that for holomorphic modular forms: level=0 or weight=0 are non-existent.
    """
    if character is None and level == 0 and weight == 0:
        character = 0
    elif character is None:
        character = -1
    emf_logger.debug(
        "In render: level={0},weight={1},character={2},label={3}".format(level, weight, character, label))
    emf_logger.debug("args={0}".format(request.args))
    emf_logger.debug("args={0}".format(request.form))
    emf_logger.debug("met={0}".format(request.method))
    keys = ['download', 'jump_to']
    info = get_args(request, level, weight, character, label, keys=keys)
    level = info['level']
    weight = info['weight']
    character = info['character']
    label = info['label']
    emf_logger.debug("info={0}".format(info))
    emf_logger.debug("level=%s, %s" % (level, type(level)))
    emf_logger.debug("label=%s, %s" % (label, type(label)))
    emf_logger.debug("wt=%s, %s" % (weight, type(weight)))
    emf_logger.debug("character=%s, %s" % (character, type(character)))
    if 'download' in info:
        return get_downloads(**info)
    emf_logger.debug("info=%s" % info)
    ## Consistency of arguments>
    # if level<=0:  level=None
    # if weight<=0:  weight=None
    if 'jump_to' in info:  # try to find out which form we want to jump
        s = my_get(info, 'jump_to', '', str)
        emf_logger.info("info.keys1={0}".format(info.keys()))
        info.pop('jump_to')
        emf_logger.info("info.keys2={0}".format(info.keys()))
        args = extract_data_from_jump_to(s)
        emf_logger.debug("args=%s" % args)
        return redirect(url_for("emf.render_elliptic_modular_forms", **args), code=301)
        # return render_elliptic_modular_forms(**args)
    if level > 0 and weight > 0 and character > -1 and label != '':
        emf_logger.debug("info=%s" % info)
        return render_one_elliptic_modular_form(**info)
    if level > 0 and weight > 0 and character > -1:
        return render_elliptic_modular_form_space(**info)
    if level > 0 and weight > 0:
        return browse_elliptic_modular_forms(**info)
    if (level > 0 and weight == 0) or (weight > 0 and level == 0):
        emf_logger.debug("Have level or weight only!")
        return browse_elliptic_modular_forms(**info)
        # return render_elliptic_modular_form_navigation_wp(**info)
    # Otherwise we go to the main navigation page
    return render_elliptic_modular_form_navigation_wp(**info)
Пример #3
0
def browse_elliptic_modular_forms(level=0, weight=0, character=-1, label='', limits=None, **kwds):
    r"""
    Renders the webpage for browsing modular forms of given level and/or weight.
    """
    emf_logger.debug("In browse_elliptic_modular_forms kwds: {0}".format(kwds))
    emf_logger.debug(
        "Input: level={0},weight={1},character={2},label={3}".format(level, weight, character, label))
    bread = [(EMF_TOP, url_for('emf.render_elliptic_modular_forms'))]
    # if level <0:
    #    level=None
    # if weight<0:
    #    weight=None
    info = dict()
    drawdomain = False
    if character == 0:
        info['grouptype'] = 0
        info['groupother'] = 1
        dimtbl = DimensionTable(0)
        if level <= N_max_Gamma0_fdraw:
            drawdomain = True
    else:
        info['grouptype'] = 1
        info['groupother'] = 0
        if level <= N_max_Gamma1_fdraw:
            drawdomain = True
        dimtbl = DimensionTable(1)
        emf_logger.info("level=%s, %s" % (level, type(level)))
    emf_logger.info("wt=%s, %s" % (weight, type(weight)))
    if level > 0:
        info['geometric'] = get_geometric_data(level, info['grouptype'])
        # if info.has_key('plot'):
        if drawdomain:
            info['fd_plot_url'] = url_for('emf.render_plot', level=level, grouptype=info['grouptype'])
            emf_logger.info("PLOT: %s" % info['fd_plot_url'])
    if level > 0 and weight == 0:
        # print "here1!"
        title = "Newforms for \(\Gamma_{0}({1})\)".format(info['grouptype'], level)
        level = int(level)
        info['level_min'] = level
        info['level_max'] = level
        info['weight_min'] = 1
        info['weight_max'] = 20
        # largs = [ {'level':level,'character':character,'weight_block':k} for k in range(100)]
        disp = ClassicalMFDisplay('modularforms')
        disp.set_table_browsing(limit=[(2, 12), (level, level)], keys=['Weight', 'Level'],
                                character=character, dimension_table=dimtbl, title='Dimension of cusp forms')
        tbl = disp._table
        if tbl is not None:
            info['browse_table'] = tbl
        # info['list_spaces']=ajax_more(make_table_of_spaces_fixed_level,*largs,text='more')
        bread.append(("Level %s" % level, url_for("emf.render_elliptic_modular_forms", level=level)))
        info['browse_type'] = " of level %s " % level
        info['title'] = title
        info['bread'] = bread
        info['level'] = level
        return render_template("emf_browse_fixed_level.html", **info)
    elif level == 0 and weight > 0:
        title = "Newforms of weight %s " % weight
        bread.append(("Weight %s" % level, url_for("emf.render_elliptic_modular_forms", weight=weight)))
        level = int(weight)
        info['level_min'] = 1
        info['level_max'] = 20
        info['weight_min'] = weight
        info['weight_max'] = weight
        # largs = [ {'level':level,'character':character,'weight_block':k} for k in range(100)]
        # info['show_all_characters']=1
        disp = ClassicalMFDisplay('modularforms')
        disp.set_table_browsing(
            limit=[(weight, weight), (info['level_min'], info['level_max'])], keys=['Weight', 'Level'],
            character=character, dimension_table=dimtbl, title='Dimension of cusp forms')
        tbl = disp._table
        if tbl is not None:
            info['browse_table'] = tbl
        # info['list_spaces']=ajax_more(make_table_of_spaces_fixed_level,*largs,text='more')
        info['title'] = title
        info['bread'] = bread
        info['level'] = level
        return render_template("emf_navigation.html", info=info, title=title, bread=bread)
    emf_logger.debug("here2!")
    info['level_min'] = level
    info['level_max'] = level
    info['weight_min'] = weight
    info['weight_max'] = weight
    return render_elliptic_modular_form_space_list_chars(level, weight)
Пример #4
0
def render_elliptic_modular_forms(level=None, weight=None, character=None, label=None,group=None, **kwds):
    r"""
    Default input of same type as required. Note that for holomorphic modular forms: level=0 or weight=0 are non-existent.
    """
    emf_logger.debug(
        "In render: level={0},weight={1},character={2},group={3},label={4}".format(level, weight, character, group, label))
    emf_logger.debug("args={0}".format(request.args))
    emf_logger.debug("args={0}".format(request.form))
    emf_logger.debug("met={0}".format(request.method))
    keys = ['download', 'jump_to']
    info = get_args(request, level, weight, character, group, label, keys=keys)
    valid = validate_parameters(level,weight,character,label,info)
    if isinstance(valid,basestring):
        return redirect(valid,code=301)
    level = info['level']; weight = info['weight']; character = info['character']
    #if info.has_key('error'):
    #    return render_elliptic_modular_form_navigation_wp(error=info['error'])
    emf_logger.debug("info={0}".format(info))
    emf_logger.debug("level=%s, %s" % (level, type(level)))
    emf_logger.debug("label=%s, %s" % (label, type(label)))
    emf_logger.debug("wt=%s, %s" % (weight, type(weight)))
    group = info.get('group',None)
    emf_logger.debug("group=%s, %s" % (group, type(group)))
    if group == 0:
        info['character'] = character = 1 # only trivial character for Gamma_0(N)
    try:
        if 'download' in info:
            return get_downloads(**info)
        emf_logger.debug("info=%s" % info)
        ## Consistency of arguments>
        # if level<=0:  level=None
        # if weight<=0:  weight=None
        if 'jump_to' in info:  # try to find out which form we want to jump
            s = my_get(info, 'jump_to', '', str)
            emf_logger.info("info.keys1={0}".format(info.keys()))
            info.pop('jump_to')
            emf_logger.info("info.keys2={0}".format(info.keys()))
            args = extract_data_from_jump_to(s)
            emf_logger.debug("args=%s" % args)
            return redirect(url_for("emf.render_elliptic_modular_forms", **args), code=301)
            # return render_elliptic_modular_forms(**args)
        emf_logger.debug("HERE! weight={0} level={1} char={2}".format(weight,level,character))
        if level > 0 and weight > 0 and character > 0:
            if label != '' and not label is None:
                return render_web_newform(**info)
            else:
                return render_web_modform_space(**info)
        if level > 0 and weight > 0 and (group != 0 or character == None):
            return render_web_modform_space_gamma1(**info)
        return render_elliptic_modular_form_navigation_wp(**info)
        # Otherwise we go to the main navigation page
    except IndexError as e: # catch everything here except KeyError below...
        emf_logger.debug("catching exceptions. info={0}".format(info))
        errst = str(e)
        ## Try to customise some of the error messages:
        if 'Character' and 'not exist' in errst:
            errst += " Please choose a character from the table below!"
            flash(errst,'error')
            return render_elliptic_modular_form_navigation_wp(**info)
        if 'WebNewForm_computing' in errst:
            errst = "The space {0}.{1}.{2} is not in the database!".format(level,weight,character)
            flash(errst)
        return render_elliptic_modular_form_navigation_wp()
    except KeyError as e:
        emf_logger.debug("catching exceptions. info={0}".format(info))
        errst = "The space {0}.{1}.{2} is not in the database!".format(level,weight,character)
        flash(errst)
        return render_elliptic_modular_form_navigation_wp()
Пример #5
0
def html_table(tbl):
    r""" Takes a dictonary and returns an html-table.

    INPUT:

    -''tbl'' -- dictionary with the following keys
              - headersh // horozontal headers
              - headersv // vertical headers
              - rows -- dictionary of rows of data

    """
    ncols = len(tbl["headersh"])
    nrows = len(tbl["headersv"])
    data = tbl['data']
    if(len(data) != nrows):
        logger.error("wrong number of rows!")
    for i in range(nrows):
        logger.info("len(%s)=%s" % (i, len(data[i])))
        if(len(data[i]) != ncols):
            logger.error("wrong number of cols [=%s]!" % ncols)

    if('atts' in tbl):
        s = "<table " + str(tbl['atts']) + ">\n"
    else:
        s = "<table>\n"
    format = dict()
    for i in range(ncols):
        format[i] = ''
        if('data_format' in tbl):
            if isinstance(tbl['data_format'], dict):
                if(i in tbl['data_format']):
                    format[i] = tbl['data_format'][i]
            elif(isinstance(tbl['data_format'], str)):
                format[i] = tbl['data_format']
    if('header' in tbl):
        s += "<thead><tr><th><td colspan=\"" + str(ncols) + "\">" + tbl['header'] + "</td></th></tr></thead>"
    s = s + "<tbody>"
    # smath="<span class=\"math\">"
    # check which type of content we have
    h1 = tbl['headersh'][0]
    sheaderh = ""
    sheaderv = ""
    h1 = tbl['headersv'][0]
    col_width = dict()
    if 'col_width' not in tbl:
        # use maximum width as default
        maxw = 0
        for k in range(ncols):
            for r in range(nrows):
                l = len_as_printed(str(data[r][k]))
                if l > maxw:
                    maxw = l
        l = l * 10.0  # use true font size?
        for k in range(ncols):
            col_width[k] = maxw
    else:
        for i in range(ncols):
            col_width[i] = 0
            if 'col_width' in tbl:
                if i in tbl['col_width']:
                    col_width[i] = tbl['col_width'][i]
    if("corner_label" in tbl):
        l = len_as_printed(str(tbl["corner_label"])) * 10
        row = "<tr><td width=\"%s\">" % l
        row += str(tbl["corner_label"]) + "</td>"
    else:
        row = "<tr><td></td>"
    for k in range(ncols):
        row = row + "<td>" + sheaderh + str(tbl['headersh'][k]) + "</td> \n"

    row = row + "</tr> \n"
    s = s + row
    for r in range(nrows):
        l = len_as_printed(str(tbl["headersv"][r])) * 10
        logger.info("l=%s  head=%s" % (l, tbl["headersv"]))
        row = "<tr><td width=\"%s\">" % l
        row += sheaderv + str(tbl['headersv'][r]) + "</td>"
        for k in range(ncols):
            wid = col_width[k]
            if format[k] == 'html' or format[k] == 'text':
                row = row + "\t<td halign=\"center\" width=\"" + str(wid) + "\">"
                if isinstance(data[r][k], list):
                    for ss in data[r][k]:
                        sss = str(ss)
                        if(len(sss) > 0):
                            row += sss
                else:
                    sss = str(data[r][k])
                    row += sss
                row = row + "</td> \n"
            else:
                row = row + "\t<td width=\"" + str(wid) + "\">"
                if isinstance(data[r][k], list):
                    for ss in data[r][k]:
                        sss = latex(ss)
                        if(len(sss) > 0):
                            row += "\(" + sss + "\)"
                else:
                    sss = latex(data[r][k])
                    if(len(sss) > 0):
                        row = row + "\(" + sss + "\)</td> \n"
                row += "</td>\n"
        # allow for different format in different columns
        row = row + "</tr> \n"
        s = s + row
    s = s + "</tbody></table>"
    return s
Пример #6
0
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0):
    r"""
    Checks if f is minimal and if not, returns the associated
    minimal form to precision prec.

    INPUT:

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

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

    EXAMPLES::



    """
    (t, f) = _get_newform(k, N, chi, fi)

    if(not t):
        return f
    if(is_squarefree(ZZ(N))):
        return [True, f]
    # We need to check all square factors of N
    logger.info("investigating: %s" % f)
    N_sqfree = squarefree_part(ZZ(N))
    Nsq = ZZ(N / N_sqfree)
    twist_candidates = list()
    KF = f.base_ring()
    # check how many Hecke eigenvalues we need to check
    max_nump = number_of_hecke_to_check(f)
    maxp = max(primes_first_n(max_nump))
    for d in divisors(N):
        # we look at all d such that d^2 divdes N
        if(not ZZ(d ** 2).divides(ZZ(N))):
            continue
        D = DirichletGroup(d)
        # check possible candidates to twist into f
        # g in S_k(M,chi) wit M=N/d^2
        M = ZZ(N / d ** 2)
        logger.info("Checking level %s" % M)
        for xig in range(euler_phi(M)):
            (t, glist) = _get_newform(k, M, xig)
            if(not t):
                return glist
            for g in glist:
                logger.debug("Comparing to function %s" % g)
                KG = g.base_ring()
                # we now see if twisting of g by xi in D gives us f
                for xi in D:
                    try:
                        for p in primes_first_n(max_nump):
                            if(ZZ(p).divides(ZZ(N))):
                                continue
                            bf = f.q_expansion(maxp + 1)[p]
                            bg = g.q_expansion(maxp + 1)[p]
                            if(bf == 0 and bg == 0):
                                continue
                            elif(bf == 0 and bg != 0 or bg == 0 and bf != 0):
                                raise StopIteration()
                            if(ZZ(p).divides(xi.conductor())):
                                raise ArithmeticError("")
                            xip = xi(p)
                            # make a preliminary check that the base rings match with respect to being
                            # real or not
                            try:
                                QQ(xip)
                                XF = QQ
                                if(KF != QQ or KG != QQ):
                                    raise StopIteration
                            except TypeError:
                                # we have a  non-rational (i.e. complex) value of the character
                                XF = xip.parent()
                                if((KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())):
                                    raise StopIteration
                            ## it is diffcult to compare elements from diferent rings in general but we make some checcks
                            # is it possible to see if there is a larger ring which everything can be
                            # coerced into?
                            ok = False
                            try:
                                a = KF(bg / xip)
                                b = KF(bf)
                                ok = True
                                if(a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            try:
                                a = KG(bg)
                                b = KG(xip * bf)
                                ok = True
                                if(a != b):
                                    raise StopIteration()
                            except TypeError:
                                pass
                            if(not ok):  # we could coerce and the coefficients were equal
                                return "Could not compare against possible candidates!"
                            # otherwise if we are here we are ok and found a candidate
                        twist_candidates.append([dd, g.q_expansion(prec), xi])
                    except StopIteration:
                        # they are not equal
                        pass
    # logger.debug("Candidates=%s" % twist_candidates)
    if(len(twist_candidates) == 0):
        return (True, None)
    else:
        return (False, twist_candidates)
Пример #7
0
def render_elliptic_modular_forms(level=None, weight=None, character=None, label=None,group=None, **kwds):
    r"""
    Default input of same type as required. Note that for holomorphic modular forms: level=0 or weight=0 are non-existent.
    """
    emf_logger.debug(
        "In render: level={0},weight={1},character={2},group={3},label={4}".format(level, weight, character, group, label))
    emf_logger.debug("args={0}".format(request.args))
    emf_logger.debug("args={0}".format(request.form))
    emf_logger.debug("met={0}".format(request.method))
    keys = ['download', 'jump_to']
    info = get_args(request, level, weight, character, group, label, keys=keys)
    valid = validate_parameters(level,weight,character,label,info)
    if isinstance(valid,basestring):
        return redirect(valid,code=301)
    level = info['level']; weight = info['weight']; character = info['character']
    #if info.has_key('error'):
    #    return render_elliptic_modular_form_navigation_wp(error=info['error'])
    emf_logger.debug("info={0}".format(info))
    emf_logger.debug("level=%s, %s" % (level, type(level)))
    emf_logger.debug("label=%s, %s" % (label, type(label)))
    emf_logger.debug("wt=%s, %s" % (weight, type(weight)))
    group = info.get('group',None)
    emf_logger.debug("group=%s, %s" % (group, type(group)))
    if group == 0:
        info['character'] = character = 1 # only trivial character for Gamma_0(N)
    try:
        if 'download' in info:
            return get_downloads(**info)
        emf_logger.debug("info=%s" % info)
        ## Consistency of arguments>
        # if level<=0:  level=None
        # if weight<=0:  weight=None
        if 'jump_to' in info:  # try to find out which form we want to jump
            s = my_get(info, 'jump_to', '', str)
            emf_logger.info("info.keys1={0}".format(info.keys()))
            info.pop('jump_to')
            emf_logger.info("info.keys2={0}".format(info.keys()))
            args = extract_data_from_jump_to(s)
            emf_logger.debug("args=%s" % args)
            return redirect(url_for("emf.render_elliptic_modular_forms", **args), code=301)
            # return render_elliptic_modular_forms(**args)
        emf_logger.debug("HERE! weight={0} level={1} char={2}".format(weight,level,character))
        if level > 0 and weight > 0 and character > 0:
            if label != '' and not label is None:
                return render_web_newform(**info)
            else:
                return render_web_modform_space(**info)
        if level > 0 and weight > 0 and (group != 0 or character == None):
            return render_web_modform_space_gamma1(**info)
        return render_elliptic_modular_form_navigation_wp(**info)
        # Otherwise we go to the main navigation page
    except IndexError as e: # catch everything here except KeyError below...
        emf_logger.debug("catching exceptions. info={0} e={1}".format(info,e))
        errst = str(e)
        ## Try to customise some of the error messages:
        if 'Character' and 'not exist' in errst:
            errst += " Please choose a character from the table below!"
            flash(errst,'error')
            return render_elliptic_modular_form_navigation_wp(**info)
        if 'WebNewForm_computing' in errst:
            errst = "The space {0}.{1}.{2} is not in the database!".format(level,weight,character)
            flash(errst)
        return render_elliptic_modular_form_navigation_wp()
    except KeyError as e:
        emf_logger.debug("catching exceptions. info={0} e={1}".format(info,e))
        errst = "The orbit {0} is not in the database!".format(newform_label(level,weight,character,label))
        flash(errst)
        return render_elliptic_modular_form_navigation_wp()
def browse_elliptic_modular_forms(level=0,
                                  weight=0,
                                  character=-1,
                                  label='',
                                  limits=None,
                                  **kwds):
    r"""
    Renders the webpage for browsing modular forms of given level and/or weight.
    """
    emf_logger.debug("In browse_elliptic_modular_forms kwds: {0}".format(kwds))
    emf_logger.debug(
        "Input: level={0},weight={1},character={2},label={3}".format(
            level, weight, character, label))
    bread = [(EMF_TOP, url_for('emf.render_elliptic_modular_forms'))]
    # if level <0:
    #    level=None
    # if weight<0:
    #    weight=None
    info = dict()
    drawdomain = False
    if character == 0:
        info['grouptype'] = 0
        info['groupother'] = 1
        dimtbl = DimensionTable(0)
        if level <= N_max_Gamma0_fdraw:
            drawdomain = True
    else:
        info['grouptype'] = 1
        info['groupother'] = 0
        if level <= N_max_Gamma1_fdraw:
            drawdomain = True
        dimtbl = DimensionTable(1)
        emf_logger.info("level=%s, %s" % (level, type(level)))
    emf_logger.info("wt=%s, %s" % (weight, type(weight)))
    if level > 0:
        info['geometric'] = get_geometric_data(level, info['grouptype'])
        # if info.has_key('plot'):
        if drawdomain:
            info['fd_plot_url'] = url_for('emf.render_plot',
                                          level=level,
                                          grouptype=info['grouptype'])
            emf_logger.info("PLOT: %s" % info['fd_plot_url'])
    if level > 0 and weight == 0:
        # print "here1!"
        title = "Newforms for \(\Gamma_{0}({1})\)".format(
            info['grouptype'], level)
        level = int(level)
        info['level_min'] = level
        info['level_max'] = level
        info['weight_min'] = 1
        info['weight_max'] = 20
        # largs = [ {'level':level,'character':character,'weight_block':k} for k in range(100)]
        disp = ClassicalMFDisplay('modularforms')
        disp.set_table_browsing(limit=[(2, 20), (level, level)],
                                keys=['Weight', 'Level'],
                                character=character,
                                dimension_table=dimtbl,
                                title='Dimension of cusp forms')
        tbl = disp._table
        if tbl is not None:
            info['browse_table'] = tbl
        # info['list_spaces']=ajax_more(make_table_of_spaces_fixed_level,*largs,text='more')
        bread.append(("Level %s" % level,
                      url_for("emf.render_elliptic_modular_forms",
                              level=level)))
        info['browse_type'] = " of level %s " % level
        info['title'] = title
        info['bread'] = bread
        info['level'] = level
        return render_template("emf_browse_fixed_level.html", **info)
    elif level == 0 and weight > 0:
        title = "Newforms of weight %s " % weight
        bread.append(("Weight %s" % level,
                      url_for("emf.render_elliptic_modular_forms",
                              weight=weight)))
        level = int(weight)
        info['level_min'] = 1
        info['level_max'] = 20
        info['weight_min'] = weight
        info['weight_max'] = weight
        # largs = [ {'level':level,'character':character,'weight_block':k} for k in range(100)]
        # info['show_all_characters']=1
        disp = ClassicalMFDisplay('modularforms')
        disp.set_table_browsing(limit=[(weight, weight),
                                       (info['level_min'], info['level_max'])],
                                keys=['Weight', 'Level'],
                                character=character,
                                dimension_table=dimtbl,
                                title='Dimension of cusp forms')
        tbl = disp._table
        if tbl is not None:
            info['browse_table'] = tbl
        # info['list_spaces']=ajax_more(make_table_of_spaces_fixed_level,*largs,text='more')
        info['title'] = title
        info['bread'] = bread
        info['level'] = level
        return render_template("emf_navigation.html",
                               info=info,
                               title=title,
                               bread=bread)
    emf_logger.debug("here2!")
    info['level_min'] = level
    info['level_max'] = level
    info['weight_min'] = weight
    info['weight_max'] = weight
    return render_elliptic_modular_form_space_list_chars(level, weight)