コード例 #1
0
ファイル: siegel_modular_form.py プロジェクト: mrubinst/lmfdb
def render_webpage(args={}):
    """
    Configure and return a template for the Siegel modular forms pages.
    """

    info = dict(args)
    # info['learnmore'] = [ ('Siegel modular forms', 'http://en.wikipedia.org/wiki/Siegel_modular_form')]
    info['learnmore'] = []
    bread = [('Siegel modular forms', url_for('ModularForm_GSp4_Q_top_level'))]

    if len(args) == 0:
        return render_template("ModularForm_GSp4_Q/ModularForm_GSp4_Q_navigation.html",
                               title='Siegel Modular Forms',
                               bread=bread,
                               **info)

    # possible keys for the URL
    group = args.get('group')
    character = args.get('character')
    weight = args.get('weight')
    level = args.get('level')
    form = args.get('form')
    page = args.get('page')
    weight_range = args.get('weight_range')
    ev_modulus = args.get('ev_modulus')
    fc_modulus = args.get('fc_modulus')

    # set info
    info['group'] = group
    info['form'] = form
    info['level'] = level

    # We check first the key 'group' since it is needed always
    tmp_parent_as_tex = '%s'
    if args['group']:

        if 'Sp4Z' == args['group']:
            info['parent_as_tex'] = 'M_{k,j}\\big({\\rm Sp}(4,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp4Z
            dimension = dimensions.dimension_Sp4Z
            info['generators'] = 'smf.Igusa_generators'

        elif 'Gamma0_2' == args['group']:
            info['parent_as_tex'] = 'M_{k,j}\\big(\\Gamma_0(2)\\big)'
            dimension = dimensions.dimension_Gamma0_2    

        elif 'Gamma1_2' == args['group']:
            info['parent_as_tex'] = 'M_{k,j}\\big(\\Gamma_1(2)\\big)'
            dimension = dimensions.dimension_Gamma1_2

        elif 'Gamma_2' == args['group']:
            info['parent_as_tex'] = 'M_{k,j}\\big(\\Gamma(2)\\big)'
            dimension = dimensions.dimension_Gamma_2

        elif 'Sp4Z_2' == args['group']:
            info['parent_as_tex'] = 'M_{k,2}\\big({\\rm Sp}(4,\\mathbb{Z})\\big)'
            dimension = siegel_core._dimension_Sp4Z_2

        elif 'Sp6Z' == args['group']:
            info['parent_as_tex'] = 'M_k\\big({\\rm Sp}(6,\\mathbb{Z})\\big)'
            dimension = siegel_core._dimension_Sp6Z

        elif 'Sp8Z' == args['group']:
            info['parent_as_tex'] = 'M_k\\big({\\rm Sp}(8,\\mathbb{Z})\\big)'
            dimension = siegel_core._dimension_Sp8Z

        elif 'Kp' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(K(p)\\big)'
            info['learnmore'] += [('Paramodular forms', 'http://math.lfc.edu/~yuen/paramodular/')]
            info['generators'] = 'smf.Kp_generators'
            dimension = siegel_core._dimension_Kp

        elif 'Gamma0_2' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(2)\\big)'
            dimension = siegel_core._dimension_Gamma0_2

        elif 'Gamma0_3' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(3)\\big)'
            dimension = siegel_core._dimension_Gamma0_3

        elif 'Gamma0_3_psi_3' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(3,\\psi_3)\\big)'
            dimension = siegel_core._dimension_Gamma0_3_psi_3

        elif 'Gamma0_4' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4

        elif 'Gamma0_4_psi_4' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(4,\\psi_4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4_psi_4

        elif 'Gamma0_4_half' == group:
            info['parent_as_tex'] = 'M_{k-1/2}\\big(\\Gamma_0(4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4_half

        else:
            info['error'] = 'Request for unavailable type of Siegel modular form'
            return render_template("ModularForm_GSp4_Q/None.html", **info)

        info['learnmore'] += [('The spaces \(' + info['parent_as_tex'] + '\)', url_for(
            'ModularForm_GSp4_Q_top_level', group=group, page='basic'))]
        bread += [('\(' + info['parent_as_tex'] + '\)', url_for('ModularForm_GSp4_Q_top_level',
                   group=group, page='forms'))]

    else:
        # some nonsense request came in, we answer by nonsense too
        return render_template("ModularForm_GSp4_Q/None.html")

        # We branch now according to the value of the key 'page'


    ##########################################################
    ## FORM COLLECTION REQUEST
    ##########################################################
    if page == 'forms':
        try:
            f = urllib.urlopen(DATA + group + '/available_eigenforms.p')
            go = pickle.load(f)
            f.close()
            forms_exist = True
        except (IOError, EOFError, KeyError):
            info['error'] = 'No data access'
            forms_exist = False
        if True == forms_exist:
            info['forms'] = [(k, [(form, go[k][form]) for form in go[k]]) for k in go]
        return render_template("ModularForm_GSp4_Q/ModularForm_GSp4_Q_forms.html",
                               title='Siegel modular forms \(' + info['parent_as_tex'] + '\)',
                               bread=bread, **info)

    if page == 'basic':
        bread += [('Basic information', url_for('ModularForm_GSp4_Q_top_level', group=group, page=page))]
        return render_template("ModularForm_GSp4_Q/ModularForm_GSp4_Q_basic.html",
                               title='Siegel modular forms basic information',
                               bread=bread, **info)


    ##########################################################
    ## DIMENSIONS REQUEST
    ##########################################################
    if page == 'dimensions':

        # We check whether the weight_range makes sense to us and, if so, dispatch it 
        info['weight_range'] = weight_range
        try:
            assert info['weight_range'], 'Please enter a valid argument'
            min_wt, max_wt, sym_pow = input_parser.kj_parser( weight_range)
            min_wt = Integer( min_wt)
            if None == max_wt or max_wt < min_wt:
                max_wt = min_wt
            if None == sym_pow:
                sym_pow = 0
            assert min_wt < 1000000 and (max_wt - min_wt + 1) * max_wt < 10000 and sym_pow < 1000, '%d-%d,%d: Input too large: Please enter smaller range or numbers.' % (max_wt, min_wt, sym_pow)
        except Exception as e:
            info['error'] = str(e)
            return render_template( "ModularForm_GSp4_Q/ModularForm_GSp4_Q_dimensions.html",
                                    title='Siegel modular forms dimensions \(' + info['parent_as_tex'] + '\)',
                                    bread=bread, **info)

        # A priori the request is reasonable, so we try to get the data for the answer 
        try:
            info['new_method'] = None
            if 'Gamma_2' == group or 'Gamma0_2' == group or 'Gamma1_2' == group or 'Sp4Z' == group:
                info['sym_pow'] = sym_pow
                info['table_headers'], info['dimensions'] = dimension( range( min_wt, max_wt + 1), sym_pow)
                ####### a hack ########
                info['new_method'] = 'new_method'
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, level=level, weight_range=weight_range))]
            elif 'Kp' == group:
                info['dimensions'] = [(k, dimension(k, tp=int(level))) for k in range(min_wt, max_wt + 1)]
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, level=level, weight_range=weight_range))]               
            else:
                info['dimensions'] = [(k, dimension(k)) for k in range(min_wt, max_wt + 1)]
                bread += [('Dimensions',
                          url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, weight_range=weight_range))]
        except Exception as e:
            info['error'] = 'Functional error: %s' % (str(e)) #(sys.exc_info()[0])
            return render_template( "ModularForm_GSp4_Q/ModularForm_GSp4_Q_dimensions.html",
                                    title='Siegel modular forms dimensions \(' + info['parent_as_tex'] + '\)',
                                    bread=bread, **info)

        # We provide some headers for the 'old' method and ask for rendering an answer
        if info['new_method']:
            info['table_headers'] = info['table_headers']

        elif 'Sp8Z' == group:
            info['table_headers'] = ['Weight', 'Total', 'Ikeda lifts', 'Miyawaki lifts', 'Other']

        elif 'Sp6Z' == group:
            info['table_headers'] = ['Weight', 'Total', 'Miyawaki lifts I', 'Miyawaki lifts II', 'Other']

        elif group == 'Kp':
            info['table_headers'] = ["Weight", "Total", "Gritsenko Lifts", "Nonlifts", "Oldforms"]

        elif 'Sp4Z_2' == group or 'Gamma0_4_half' == group:
            info['table_headers'] = ['Weight', 'Total', 'Non cusp', 'Cusp']

        else:
            info['table_headers'] = ["Weight", "Total", "Eisenstein", "Klingen", "Maass", "Interesting"]

        return render_template("ModularForm_GSp4_Q/ModularForm_GSp4_Q_dimensions.html",
                               title='Siegel modular forms dimensions \(' + info['parent_as_tex'] + '\)',
                               bread=bread, **info)


    ##########################################################
    ## SPECIFIC FORM REQUEST
    ##########################################################
    if page == 'specimen':
        info['weight'] = weight

        # try to load data
        try:
            file_name = weight + '_' + form + '.sobj'
            f_url = DATA + group + '/eigenforms/' + file_name
            # print 'fafaf %s'%f_url
            f = load(f_url)
            file_name = weight + '_' + form + '-ev.sobj'
            g_url = DATA + group + '/eigenvalues/' + file_name
            # print 'gagag %s'%g_url
            g = load(g_url)
            loaded = True
        except:
            info['error'] = 'Data not available'
            loaded = False
        print 'hahahah %s' % loaded
        if True == loaded:

            # throw out disc = 0 keys for cusp forms
            f_keys = f[2].keys()
            if 'Sp4Z' == group and 'E' != form and 'Klingen' != form:
                f_keys = filter(lambda (a, b, c): b ^ 2 < 4 * a * c, f_keys)

            # sort the table of Fourier coefficients by discriminant, forms in increasing lexicographic order
            if 'Sp8Z' != group and 'Sp6Z' != group:
                __disc = lambda (a, b, c): 4 * a * c - b ** 2
                __cmp = lambda (
                    a, b, c), (A, B, C): cmp((4 * a * c - b ** 2, a, b, c), (4 * A * C - B ** 2, A, B, C))
                f_keys.sort(cmp=__cmp)

            if 'Sp8Z' == group:
                # matrix index is given as [m11 m22 m33 m44 m12 m13 m23 m14 m24 m34]
                __mat = lambda (m11, m22, m33, m44, m12, m13, m23, m14, m24, m34): \
                    matrix(ZZ, 4, 4, [m11, m12, m13, m14, m12, m22, m23, m24,
                                      m13, m23, m33, m34, m14, m24, m34, m44])
                __disc = lambda i: __mat(i).det()
                __cmp = lambda f1, f2: cmp([__mat(f1).det()] + list(f1), [__mat(f2).det()] + list(f2))
                # print 'before: ', f_keys
                f_keys.sort(cmp=__cmp)
                # print f_keys

            if 'Sp6Z' == group:
                # matrix index is given as [m11/2 m22/2 m33/2 m12 m13 m23]
                __mat = lambda (a, b, c, d, e, f): \
                    matrix(ZZ, 3, 3, [2 * a, d, e, d, 2 * b, f, e, f, 2 * c])
                __disc = lambda i: __mat(i).det()
                __cmp = lambda f1, f2: cmp([__mat(f1).det()] + list(f1), [__mat(f2).det()] + list(f2))
                # print 'before: ', f_keys
                f_keys.sort(cmp=__cmp)
                # print f_keys

            # make the coefficients of the M_k(Sp(4,Z)) forms integral
            if 'Sp4Z' == group:  # or 'Sp4Z_2' == group:
                d = lcm(map(lambda n: denominator(n), f[1].coefficients()))
                f = list(f)
                f[1] *= d
                for k in f[2]:
                    f[2][k] *= d

            try:
                if not ev_modulus:
                    m = 0
                else:
                    m = int(ev_modulus)
                info['ev_modulus'] = m
                K = g[0].parent().fraction_field()
                if m != 0:
                    if QQ == K:
                        for i in g[1]:
                            g[1][i] = Integer(g[1][i]) % m
                    else:
                        I = K.ideal(m)
                        for i in g[1]:
                            g[1][i] = I.reduce(g[1][i])

            except:
                info['fc_modulus'] = 0
                pass

            try:
                if not fc_modulus:
                    m = 0
                else:
                    m = int(fc_modulus)
                info['fc_modulus'] = m
                K = g[0].parent().fraction_field()
                if m != 0:
                    if 'Sp4Z_2' == group:
                        if QQ == K:
                            for i in f_keys:
                                f[2][i] = sum((v[0] % m) * v[1] for v in list(f[2][i]))
                        else:
                            I = K.ideal(m)
                            for i in f_keys:
                                f[2][i] = sum(I.reduce(v[0]) * v[1] for v in list(f[2][i]))
                    else:
                        if QQ == K:
                            for i in f_keys:
                                f[2][i] = Integer(f[2][i]) % m
                        else:
                            I = K.ideal(m)
                            for i in f_keys:
                                f[2][i] = I.reduce(f[2][i])
            except:
                info['fc_modulus'] = 0
                pass

            info['the_form'] = [f[0].parent(), f[1],
                                [(l, g[1][l]) for l in g[1]],
                                [(i, f[2][i], __disc(i)) for i in f_keys],
                                f_url, g_url]
            # info['friends'] = [ ('Spin L-function', url_for('not_yet_implemented'))]#, \
##                                 ('Standard L-function', url_for('not_yet_implemented')), \
##                                 ('First Fourier-Jacobi coefficient', url_for('not_yet_implemented'))]

        location = url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, weight=weight, form=form)
        info['form_name'] = form
        bread += [(weight + '_' + form, location)]
        return render_template("ModularForm_GSp4_Q/ModularForm_GSp4_Q_specimen.html",
                               title='Siegel modular form ' + weight + '_' + form,
                               bread=bread, **info)

    # if a nonexisting page was requested return the homepage of Siegel modular forms
    return render_webpage()
コード例 #2
0
def render_webpage(args={}):
    """
    Configure and return a template for the Siegel modular forms pages.
    """
    info = dict(args)
    # info['learnmore'] = [ ('Siegel modular forms', 'http://en.wikipedia.org/wiki/Siegel_modular_form')]
    info['learnmore'] = []
    bread = [('Siegel modular forms', url_for('ModularForm_GSp4_Q_top_level'))]

    if len(args) == 0:
        return render_template("ModularForm_GSp4_Q_navigation.html",
                               title='Siegel Modular Forms',
                               bread=bread,
                               **info)

    # possible keys for the URL
    group = args.get('group')
    character = args.get('character')
    weight = args.get('weight')
    level = args.get('level')
    form = args.get('form')
    page = args.get('page')
    weight_range = args.get('weight_range')

    # set info
    info['group'] = group
    info['form'] = form
    info['level'] = level

    # We check first the key 'group' since it is needed always
    tmp_parent_as_tex = '%s'
    if args['group']:

        if 'Sp4Z' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big({\\rm Sp}(4,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp4Z
            dimension = dimensions.dimension_Sp4Z
            info['generators'] = 'smf.Igusa_generators'

        elif 'Gamma0_2' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big(\\Gamma_0(2)\\big)'
            dimension = dimensions.dimension_Gamma0_2

        elif 'Gamma1_2' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big(\\Gamma_1(2)\\big)'
            dimension = dimensions.dimension_Gamma1_2

        elif 'Gamma_2' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big(\\Gamma(2)\\big)'
            dimension = dimensions.dimension_Gamma_2

        elif 'Sp4Z_2' == args['group']:
            info[
                'parent_as_tex'] = 'M_{k,2}\\big({\\rm Sp}(4,\\mathbb{Z})\\big)'
            dimension = siegel_core._dimension_Sp4Z_2

        elif 'Sp6Z' == args['group']:
            info['parent_as_tex'] = 'M_k\\big({\\rm Sp}(6,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp6Z
            dimension = dimensions.dimension_Sp6Z

        elif 'Sp8Z' == args['group']:
            info['parent_as_tex'] = 'M_k\\big({\\rm Sp}(8,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp8Z
            dimension = dimensions.dimension_Sp8Z

        elif 'Gamma0_4_half' == group:
            info['parent_as_tex'] = 'M_{k-1/2}\\big(\\Gamma_0(4)\\big)'
            # dimension = siegel_core._dimension_Gamma0_4_half
            dimension = dimensions.dimension_Gamma0_4_half

        elif 'Kp' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(K(p)\\big)'
            info['learnmore'] += [('Paramodular forms',
                                   'http://math.lfc.edu/~yuen/paramodular/')]
            info['generators'] = 'smf.Kp_generators'
            dimension = siegel_core._dimension_Kp

        elif 'Gamma0_2' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(2)\\big)'
            dimension = siegel_core._dimension_Gamma0_2

        elif 'Gamma0_3' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(3)\\big)'
            dimension = siegel_core._dimension_Gamma0_3

        elif 'Gamma0_3_psi_3' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(3,\\psi_3)\\big)'
            dimension = siegel_core._dimension_Gamma0_3_psi_3

        elif 'Gamma0_4' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4

        elif 'Gamma0_4_psi_4' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(4,\\psi_4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4_psi_4

        else:
            info[
                'error'] = 'Request for unavailable type of Siegel modular form'
            return render_template("None.html", **info)

        info['learnmore'] += [('The spaces \(' + info['parent_as_tex'] + '\)',
                               url_for('ModularForm_GSp4_Q_top_level',
                                       group=group,
                                       page='basic'))]
        bread += [('\(' + info['parent_as_tex'] + '\)',
                   url_for('ModularForm_GSp4_Q_top_level',
                           group=group,
                           page='forms'))]

    else:
        # some nonsense request came in, we answer by nonsense too
        return render_template("None.html")

        # We branch now according to the value of the key 'page'

    ##########################################################
    ## FORM COLLECTION REQUEST
    ##########################################################
    if page == 'forms':
        try:
            f = urllib.urlopen(DATA + group + '/available_eigenforms.p')
            go = pickle.load(f)
            f.close()
            forms_exist = True
        except (IOError, EOFError, KeyError):
            info['error'] = 'No data access'
            forms_exist = False
        if True == forms_exist:
            info['forms'] = [(k, [(form, go[k][form]) for form in go[k]])
                             for k in go]
        return render_template("ModularForm_GSp4_Q_forms.html",
                               title='Siegel modular forms \(' +
                               info['parent_as_tex'] + '\)',
                               bread=bread,
                               **info)

    if page == 'basic':
        bread += [('Basic information',
                   url_for('ModularForm_GSp4_Q_top_level',
                           group=group,
                           page=page))]
        return render_template("ModularForm_GSp4_Q_basic.html",
                               title='Siegel modular forms basic information',
                               bread=bread,
                               **info)

    ##########################################################
    ## DIMENSIONS REQUEST
    ##########################################################
    if page == 'dimensions':

        # We check whether the weight_range makes sense to us and, if so, dispatch it
        info['weight_range'] = weight_range
        try:
            assert info['weight_range'], 'Please enter a valid argument'
            min_wt, max_wt, sym_pow = input_parser.kj_parser(weight_range)
            min_wt = Integer(min_wt)
            if None == max_wt or max_wt < min_wt:
                max_wt = min_wt
            if None == sym_pow:
                sym_pow = 0
            assert min_wt < 1000000 and (
                max_wt - min_wt + 1
            ) * max_wt < 10000 and sym_pow < 1000, '%d-%d,%d: Input too large: Please enter smaller range or numbers.' % (
                max_wt, min_wt, sym_pow)
        except Exception as e:
            info['error'] = str(e)
            return render_template("ModularForm_GSp4_Q_dimensions.html",
                                   title='Siegel modular forms dimensions \(' +
                                   info['parent_as_tex'] + '\)',
                                   bread=bread,
                                   **info)

        # A priori the request is reasonable, so we try to get the data for the answer
        try:
            info['new_method'] = None
            if 'Gamma_2' == group or 'Gamma0_2' == group or 'Gamma1_2' == group or 'Sp4Z' == group or 'Sp6Z' == group or 'Sp8Z' == group or 'Gamma0_4_half' == group:
                info['sym_pow'] = sym_pow
                info['table_headers'], info['dimensions'] = dimension(
                    range(min_wt, max_wt + 1), sym_pow)
                ####### a hack ########
                info['new_method'] = 'new_method'
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level',
                                   group=group,
                                   page=page,
                                   level=level,
                                   weight_range=weight_range))]
            elif 'Kp' == group:
                info['dimensions'] = [(k, dimension(k, tp=int(level)))
                                      for k in range(min_wt, max_wt + 1)]
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level',
                                   group=group,
                                   page=page,
                                   level=level,
                                   weight_range=weight_range))]
            else:
                info['dimensions'] = [(k, dimension(k))
                                      for k in range(min_wt, max_wt + 1)]
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level',
                                   group=group,
                                   page=page,
                                   weight_range=weight_range))]
        except Exception as e:
            info['error'] = 'Functional error: %s' % (str(e)
                                                      )  #(sys.exc_info()[0])
            return render_template("ModularForm_GSp4_Q_dimensions.html",
                                   title='Siegel modular forms dimensions \(' +
                                   info['parent_as_tex'] + '\)',
                                   bread=bread,
                                   **info)

        # We provide some headers for the 'old' method and ask for rendering an answer
        if info['new_method']:
            info['table_headers'] = info['table_headers']

        # elif 'Sp8Z' == group:
        #     info['table_headers'] = ['Weight', 'Total', 'Ikeda lifts', 'Miyawaki lifts', 'Other']

        elif 'Sp6Z' == group:
            info['table_headers'] = [
                'Weight', 'Total', 'Miyawaki lifts I', 'Miyawaki lifts II',
                'Other'
            ]

        elif group == 'Kp':
            info['table_headers'] = [
                "Weight", "Total", "Gritsenko Lifts", "Nonlifts", "Oldforms"
            ]

        elif 'Sp4Z_2' == group or 'Gamma0_4_half' == group:
            info['table_headers'] = ['Weight', 'Total', 'Non cusp', 'Cusp']

        else:
            info['table_headers'] = [
                "Weight", "Total", "Eisenstein", "Klingen", "Maass",
                "Interesting"
            ]

        return render_template("ModularForm_GSp4_Q_dimensions.html",
                               title='Siegel modular forms dimensions \(' +
                               info['parent_as_tex'] + '\)',
                               bread=bread,
                               **info)

    ##########################################################
    ## SPECIFIC FORM REQUEST
    ##########################################################
    if page == 'specimen':
        info['weight'] = weight
        ev_modulus = args.get('emod')
        fc_modulus = args.get('fcmod')
        erange = args.get('erange')
        fcrange = args.get('fcrange')

        # try to load data
        if 'Kp' == group or 'Sp4Z_2' == group or 'Sp4Z' == group:
            # fetch from mongodb
            try:
                smple = sample.Sample([group], weight + '_' + form)
                f = (smple.field()(0), smple.explicit_formula(),
                     smple.Fourier_coefficients()
                     if smple.Fourier_coefficients() else {})
                g = (smple.field()(0),
                     smple.eigenvalues() if smple.eigenvalues() else {})

                file_name = weight + '_' + form + '.sobj'
                f_url = DATA + group + '/eigenforms/' + file_name
                file_name = weight + '_' + form + '-ev.sobj'
                g_url = DATA + group + '/eigenvalues/' + file_name

                loaded = True
            except Exception as e:
                info['error'] = 'Data not available: %s %s' % (str(e), weight +
                                                               '_' + form)
                loaded = False
        else:
            try:
                file_name = weight + '_' + form + '.sobj'
                f_url = DATA + group + '/eigenforms/' + file_name
                # print 'fafaf %s'%f_url
                f = load(f_url)
                file_name = weight + '_' + form + '-ev.sobj'
                g_url = DATA + group + '/eigenvalues/' + file_name
                # print 'gagag %s'%g_url
                g = load(g_url)
                loaded = True
            except:
                info['error'] = 'Data not available'
                loaded = False

        if True == loaded:

            # define specific methods for computing discriminant and ordering of form
            if 'Sp8Z' != group and 'Sp6Z' != group:  # with current data this is all degree 2 SMFs
                __disc = lambda (a, b, c): 4 * a * c - b**2
                __cmp = lambda (a, b, c), (A, B, C): cmp(
                    (4 * a * c - b**2, a, b, c), (4 * A * C - B**2, A, B, C))

            if 'Sp8Z' == group:
                # matrix index is given as [m11 m22 m33 m44 m12 m13 m23 m14 m24 m34]
                __mat = lambda (m11, m22, m33, m44, m12, m13, m23, m14, m24, m34): \
                    matrix(ZZ, 4, 4, [m11, m12, m13, m14, m12, m22, m23, m24,
                                      m13, m23, m33, m34, m14, m24, m34, m44])
                __disc = lambda i: __mat(i).det()
                __cmp = lambda f1, f2: cmp([__mat(f1).det()] + list(f1),
                                           [__mat(f2).det()] + list(f2))

            if 'Sp6Z' == group:
                # matrix index is given as [m11/2 m22/2 m33/2 m12 m13 m23]
                __mat = lambda (a, b, c, d, e, f): \
                    matrix(ZZ, 3, 3, [2 * a, d, e, d, 2 * b, f, e, f, 2 * c])
                __disc = lambda i: __mat(i).det()
                __cmp = lambda f1, f2: cmp([__mat(f1).det()] + list(f1),
                                           [__mat(f2).det()] + list(f2))

            # make the coefficients of the M_k(Sp(4,Z)) forms integral
            # if 'Sp4Z' == group:  # or 'Sp4Z_2' == group:
            #     d = lcm(map(lambda n: denominator(n), f[1].coefficients()))
            #     f = list(f)
            #     f[1] *= d
            #     for k in f[2]:
            #         f[2][k] *= d

            # replace generator with a to make things prettier
            if isinstance(f[0].parent(), Field):
                if f[0].parent() != QQ:
                    gen = str(f[0].parent().gen())
                    info['gen_coeff_field'] = teXify_pol(
                        str(f[0].parent().gen()).replace(gen, 'a'))
                    info['poly_coeff_field'] = teXify_pol(
                        str(f[0].parent().polynomial()).replace(gen, 'a'))
                    info['poly_in_gens'] = teXify_pol(
                        str(f[1]).replace(gen, 'a'))
                else:
                    info['poly_in_gens'] = teXify_pol(str(f[1]))
            else:
                # coefficient field is not a sage field, so just assume its supposed to be rationals
                info['poly_in_gens'] = teXify_pol(str(f[1]))

            # isolate requested eigenvalue indices
            if erange == 'all':
                filt_evals = g[1]
                eval_index = filt_evals.keys()
                info['erangedesc'] = 'all available eigenvalues'
            else:
                if erange:
                    spliterange = erange.split('-')
                    if len(spliterange) > 1 and spliterange[0].isdigit(
                    ) and spliterange[1].isdigit():
                        elow, ehigh = int(spliterange[0]), int(spliterange[1])
                        # filter out to have eigenvalues in [elow, ehigh]
                        filt_evals = {
                            n: lam
                            for n, lam in g[1].iteritems()
                            if int(n) >= elow and int(n) <= ehigh
                        }
                        eval_index = filt_evals.keys()
                        info[
                            'erangedesc'] = 'eigenvalues with $n$ in [' + ` elow ` + ', ' + ` ehigh ` + ']'
                else:
                    # can't make sense of the range, return a default
                    info['erange'] = ''
                    filt_evals = g[1]
                    eval_index = filt_evals.keys()[0:20]
                    info['erangedesc'] = 'the first few eigenvalues'

            # prepare formatted eigenvalues
            ftd_evals = []
            try:
                if not ev_modulus:
                    m = 0
                else:
                    m = int(ev_modulus)
                info['ev_modulus'] = m
                K = g[0].parent().fraction_field()
                if m != 0:
                    if QQ == K:
                        for i in eval_index:
                            rdcd_eval = Integer(g[1][i]) % m
                            ftd_evals.append(
                                (str(i), teXify_pol(str(rdcd_eval))))
                    else:
                        I = K.ideal(m)
                        for i in eval_index:
                            rdcd_eval = I.reduce(g[1][i])
                            ftd_evals.append(
                                (str(i),
                                 teXify_pol(str(rdcd_eval).replace(gen, 'a'))))
                    info['emoddesc'] = 'reduced modulo ' + ` m ` + '.'
                else:
                    for i in eval_index:
                        if QQ == K:
                            ftd_evals.append(
                                (str(i), teXify_pol(str(g[1][i]))))
                        else:
                            ftd_evals.append(
                                (str(i),
                                 teXify_pol(str(g[1][i]).replace(gen, 'a'))))
                    info['emoddesc'] = 'with no reduction.'
            except:
                pass

            if (fcrange == 'all'):
                filt_fcs = f[2]
                fc_index = filt_fcs.keys()
                fc_index.sort(cmp=__cmp)
                info['fcrangedesc'] = 'all available Fourier coefficients'
            else:
                if fcrange:
                    splitfcrange = fcrange.split('-')
                    if len(splitfcrange) > 1 and splitfcrange[0].isdigit(
                    ) and splitfcrange[1].isdigit():
                        fclow, fchigh = int(splitfcrange[0]), int(
                            splitfcrange[1])
                        filt_fcs = {
                            n: fc
                            for n, fc in f[2].iteritems()
                            if __disc(n) >= fclow and __disc(n) <= fchigh
                        }
                        fc_index = filt_fcs.keys()
                        fc_index.sort(cmp=__cmp)
                        info[
                            'fcrangedesc'] = 'Fourier coefficients with index such that $D$ is in [' + ` fclow ` + ', ' + ` fchigh ` + ']'
                else:
                    # can't make sense of the range, return a default
                    info['fcrange'] = ''
                    filt_fcs = f[2]
                    fc_index = filt_fcs.keys()
                    fc_index.sort(cmp=__cmp)
                    fc_index = fc_index[0:20]
                    info['fcrangedesc'] = 'the first few Fourier coefficients'

            # prepare formatted fourier coefficients
            ftd_fcs = []
            try:
                if not fc_modulus:
                    m = 0
                else:
                    m = int(fc_modulus)
                info['fc_modulus'] = m
                K = g[0].parent().fraction_field()
                if m != 0:
                    if 'Sp4Z_2' == group:
                        if QQ == K:
                            for i in fc_index:
                                ftd_fc = sum(
                                    (v[0] % m) * v[1] for v in list(f[2][i]))
                                ftd_fcs.append(
                                    (str(i), teXify_pol(str(ftd_fc)),
                                     str(__disc(i))))
                        else:
                            I = K.ideal(m)
                            for i in fc_index:
                                ftd_fc = sum(
                                    I.reduce(v[0]) * v[1]
                                    for v in list(f[2][i]))
                                ftd_fcs.append(
                                    (str(i),
                                     teXify_pol(str(ftd_fc).replace(gen, 'a')),
                                     str(__disc(i))))
                    else:
                        if QQ == K:
                            for i in fc_index:
                                ftd_fc = Integer(f[2][i]) % m
                                ftd_fcs.append(
                                    (str(i), teXify_pol(str(ftd_fc)),
                                     str(__disc(i))))
                        else:
                            I = K.ideal(m)
                            for i in fc_index:
                                ftd_fc = I.reduce(f[2][i])
                                ftd_fcs.append(
                                    (str(i),
                                     teXify_pol(str(ftd_fc).replace(gen, 'a')),
                                     str(__disc(i))))
                    info['fcmoddesc'] = 'reduced modulo ' + ` m ` + '.'
                else:
                    for i in fc_index:
                        ftd_fc = f[2][i]
                        if QQ == K:
                            ftd_fcs.append((str(i), teXify_pol(str(ftd_fc)),
                                            str(__disc(i))))
                        else:
                            ftd_fcs.append(
                                (str(i),
                                 teXify_pol(str(ftd_fc).replace(gen, 'a')),
                                 str(__disc(i))))
                    info['fcmoddesc'] = 'with no reduction.'
            except:
                pass

            location = url_for('ModularForm_GSp4_Q_top_level',
                               group=group,
                               page=page,
                               weight=weight,
                               form=form)
            properties2 = [('Species', '$' + info['parent_as_tex'] + '$'),
                           ('Weight', '%s' % weight)]

            # if implemented, add L-function to friends
            if 'Sp4Z' == group:
                numEmbeddings = f[0].parent().degree()
                friends = []

                if form.endswith('E'):
                    # form is a Siegel-Eisenstein series, nothing interesting
                    # to show here
                    pass

                elif form.endswith('Klingen'):
                    # form is a Klingen-Eisenstein series, so plausibly could
                    # link to the elliptic cusp form on the boundary it comes
                    # from
                    pass

                elif form.endswith('Maass'):
                    # link the the underlying elliptic modular form.  This
                    # datum is not included with the modular form, so just
                    # link to the unique Galois orbit of full level and
                    # weight 2k-2 (this code assumes Maeda).
                    ellWeight = 2 * int(weight) - 2
                    friends.append(
                        ('Elliptic modular form',
                         '/ModularForm/GL2/Q/holomorphic/1/' + str(ellWeight)))
                else:
                    # there are no other lifts to full level, so the L-function
                    # is primitive and therefore interesting
                    for embedding in range(0, numEmbeddings):
                        friends.append(
                            ('Spin L-function for ' + str(weight) + '_' +
                             form + '.' + str(embedding),
                             '/L/ModularForm/GSp/Q/Sp4Z/specimen/' +
                             str(weight) + '/' + form + '/' + str(embedding)))
            else:
                friends = []
            #TODO implement remaining spin L-functions, standard L-functions,
            # and first Fourier-Jacobi coefficient

            downloads = [('Fourier coefficients', f_url),
                         ('Eigenvalues', g_url)]

            location = url_for('ModularForm_GSp4_Q_top_level',
                               group=group,
                               page=page,
                               weight=weight,
                               form=form)
            bread += [(weight + '_' + form, location)]

            info['ftd_evals'] = ftd_evals
            info['ftd_fcs'] = ftd_fcs
            info['location'] = location
            info['form_name'] = form

            return render_template("ModularForm_GSp4_Q_specimen.html",
                                   title='Siegel modular form ' + weight +
                                   '_' + form,
                                   bread=bread,
                                   properties2=properties2,
                                   friends=friends,
                                   downloads=downloads,
                                   **info)

    # if a nonexisting page was requested return the homepage of Siegel modular forms
    return render_webpage()
コード例 #3
0
ファイル: siegel_modular_form.py プロジェクト: arbooker/lmfdb
def render_webpage(args={}):
    """
    Configure and return a template for the Siegel modular forms pages.
    """
    info = dict(args)
    # info['learnmore'] = [ ('Siegel modular forms', 'http://en.wikipedia.org/wiki/Siegel_modular_form')]
    info['learnmore'] = []
    bread = [('Siegel modular forms', url_for('ModularForm_GSp4_Q_top_level'))]

    if len(args) == 0:
        return render_template("ModularForm_GSp4_Q_navigation.html",
                               title='Siegel Modular Forms',
                               bread=bread,
                               **info)

    # possible keys for the URL
    group = args.get('group')
    character = args.get('character')
    weight = args.get('weight')
    level = args.get('level')
    form = args.get('form')
    page = args.get('page')
    weight_range = args.get('weight_range')

    # set info
    info['group'] = group
    info['form'] = form
    info['level'] = level

    # We check first the key 'group' since it is needed always
    tmp_parent_as_tex = '%s'
    if args['group']:

        if 'Sp4Z' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big({\\rm Sp}(4,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp4Z
            dimension = dimensions.dimension_Sp4Z
            info['generators'] = 'smf.Igusa_generators'

        elif 'Gamma0_2' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big(\\Gamma_0(2)\\big)'
            dimension = dimensions.dimension_Gamma0_2    

        elif 'Gamma1_2' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big(\\Gamma_1(2)\\big)'
            dimension = dimensions.dimension_Gamma1_2

        elif 'Gamma_2' == args['group']:
            info['parent_as_tex'] = 'M_{k}\\big(\\Gamma(2)\\big)'
            dimension = dimensions.dimension_Gamma_2

        elif 'Sp4Z_2' == args['group']:
            info['parent_as_tex'] = 'M_{k,2}\\big({\\rm Sp}(4,\\mathbb{Z})\\big)'
            dimension = siegel_core._dimension_Sp4Z_2

        elif 'Sp6Z' == args['group']:
            info['parent_as_tex'] = 'M_k\\big({\\rm Sp}(6,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp6Z
            dimension = dimensions.dimension_Sp6Z

        elif 'Sp8Z' == args['group']:
            info['parent_as_tex'] = 'M_k\\big({\\rm Sp}(8,\\mathbb{Z})\\big)'
            # dimension = siegel_core._dimension_Sp8Z
            dimension = dimensions.dimension_Sp8Z

        elif 'Gamma0_4_half' == group:
            info['parent_as_tex'] = 'M_{k-1/2}\\big(\\Gamma_0(4)\\big)'
            # dimension = siegel_core._dimension_Gamma0_4_half
            dimension = dimensions.dimension_Gamma0_4_half

        elif 'Kp' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(K(p)\\big)'
            info['learnmore'] += [('Paramodular forms', 'http://math.lfc.edu/~yuen/paramodular/')]
            info['generators'] = 'smf.Kp_generators'
            dimension = siegel_core._dimension_Kp

        elif 'Gamma0_2' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(2)\\big)'
            dimension = siegel_core._dimension_Gamma0_2

        elif 'Gamma0_3' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(3)\\big)'
            dimension = siegel_core._dimension_Gamma0_3

        elif 'Gamma0_3_psi_3' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(3,\\psi_3)\\big)'
            dimension = siegel_core._dimension_Gamma0_3_psi_3

        elif 'Gamma0_4' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4

        elif 'Gamma0_4_psi_4' == args['group']:
            info['parent_as_tex'] = 'M_k\\big(\\Gamma_0(4,\\psi_4)\\big)'
            dimension = siegel_core._dimension_Gamma0_4_psi_4

 

        else:
            info['error'] = 'Request for unavailable type of Siegel modular form'
            return render_template("None.html", **info)

        info['learnmore'] += [('The spaces \(' + info['parent_as_tex'] + '\)', url_for(
            'ModularForm_GSp4_Q_top_level', group=group, page='basic'))]
        bread += [('\(' + info['parent_as_tex'] + '\)', url_for('ModularForm_GSp4_Q_top_level',
                   group=group, page='forms'))]

    else:
        # some nonsense request came in, we answer by nonsense too
        return render_template("None.html")

        # We branch now according to the value of the key 'page'


    ##########################################################
    ## FORM COLLECTION REQUEST
    ##########################################################
    if page == 'forms':
        try:
            f = urllib.urlopen(DATA + group + '/available_eigenforms.p')
            go = pickle.load(f)
            f.close()
            forms_exist = True
        except (IOError, EOFError, KeyError):
            info['error'] = 'No data access'
            forms_exist = False
        if True == forms_exist:
            info['forms'] = [(k, [(form, go[k][form]) for form in go[k]]) for k in go]
        return render_template("ModularForm_GSp4_Q_forms.html",
                               title='Siegel modular forms \(' + info['parent_as_tex'] + '\)',
                               bread=bread, **info)

    if page == 'basic':
        bread += [('Basic information', url_for('ModularForm_GSp4_Q_top_level', group=group, page=page))]
        return render_template("ModularForm_GSp4_Q_basic.html",
                               title='Siegel modular forms basic information',
                               bread=bread, **info)


    ##########################################################
    ## DIMENSIONS REQUEST
    ##########################################################
    if page == 'dimensions':

        # We check whether the weight_range makes sense to us and, if so, dispatch it 
        info['weight_range'] = weight_range
        try:
            assert info['weight_range'], 'Please enter a valid argument'
            min_wt, max_wt, sym_pow = input_parser.kj_parser( weight_range)
            min_wt = Integer( min_wt)
            if None == max_wt or max_wt < min_wt:
                max_wt = min_wt
            if None == sym_pow:
                sym_pow = 0
            assert min_wt < 1000000 and (max_wt - min_wt + 1) * max_wt < 10000 and sym_pow < 1000, '%d-%d,%d: Input too large: Please enter smaller range or numbers.' % (max_wt, min_wt, sym_pow)
        except Exception as e:
            info['error'] = str(e)
            return render_template( "ModularForm_GSp4_Q_dimensions.html",
                                    title='Siegel modular forms dimensions \(' + info['parent_as_tex'] + '\)',
                                    bread=bread, **info)

        # A priori the request is reasonable, so we try to get the data for the answer 
        try:
            info['new_method'] = None
            if 'Gamma_2' == group or 'Gamma0_2' == group or 'Gamma1_2' == group or 'Sp4Z' == group or 'Sp6Z' == group or 'Sp8Z' == group or 'Gamma0_4_half' == group:
                info['sym_pow'] = sym_pow
                info['table_headers'], info['dimensions'] = dimension( range( min_wt, max_wt + 1), sym_pow)
                ####### a hack ########
                info['new_method'] = 'new_method'
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, level=level, weight_range=weight_range))]
            elif 'Kp' == group:
                info['dimensions'] = [(k, dimension(k, tp=int(level))) for k in range(min_wt, max_wt + 1)]
                bread += [('Dimensions',
                           url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, level=level, weight_range=weight_range))]               
            else:
                info['dimensions'] = [(k, dimension(k)) for k in range(min_wt, max_wt + 1)]
                bread += [('Dimensions',
                          url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, weight_range=weight_range))]
        except Exception as e:
            info['error'] = 'Functional error: %s' % (str(e)) #(sys.exc_info()[0])
            return render_template( "ModularForm_GSp4_Q_dimensions.html",
                                    title='Siegel modular forms dimensions \(' + info['parent_as_tex'] + '\)',
                                    bread=bread, **info)

        # We provide some headers for the 'old' method and ask for rendering an answer
        if info['new_method']:
            info['table_headers'] = info['table_headers']

        # elif 'Sp8Z' == group:
        #     info['table_headers'] = ['Weight', 'Total', 'Ikeda lifts', 'Miyawaki lifts', 'Other']

        elif 'Sp6Z' == group:
            info['table_headers'] = ['Weight', 'Total', 'Miyawaki lifts I', 'Miyawaki lifts II', 'Other']

        elif group == 'Kp':
            info['table_headers'] = ["Weight", "Total", "Gritsenko Lifts", "Nonlifts", "Oldforms"]

        elif 'Sp4Z_2' == group or 'Gamma0_4_half' == group:
            info['table_headers'] = ['Weight', 'Total', 'Non cusp', 'Cusp']

        else:
            info['table_headers'] = ["Weight", "Total", "Eisenstein", "Klingen", "Maass", "Interesting"]

        return render_template("ModularForm_GSp4_Q_dimensions.html",
                               title='Siegel modular forms dimensions \(' + info['parent_as_tex'] + '\)',
                               bread=bread, **info)


    ##########################################################
    ## SPECIFIC FORM REQUEST
    ##########################################################
    if page == 'specimen':
        info['weight'] = weight
        ev_modulus = args.get('emod')
        fc_modulus = args.get('fcmod')
        erange = args.get('erange')
        fcrange = args.get('fcrange')

        # try to load data
        if 'Kp' == group or 'Sp4Z_2' == group or 'Sp4Z' == group:
            # fetch from mongodb
            try:
                smple = sample.Sample( [group], weight + '_' + form)
                f = (smple.field()(0), smple.explicit_formula(), smple.Fourier_coefficients() if smple.Fourier_coefficients() else {})
                g = (smple.field()(0), smple.eigenvalues() if smple.eigenvalues() else {})

                file_name = weight + '_' + form + '.sobj'
                f_url = DATA + group + '/eigenforms/' + file_name
                file_name = weight + '_' + form + '-ev.sobj'
                g_url = DATA + group + '/eigenvalues/' + file_name

                loaded = True
            except Exception as e:
                info['error'] = 'Data not available: %s %s' % (str(e), weight + '_' + form)
                loaded = False
        else:
            try:
                file_name = weight + '_' + form + '.sobj'
                f_url = DATA + group + '/eigenforms/' + file_name
                # print 'fafaf %s'%f_url
                f = load(f_url)
                file_name = weight + '_' + form + '-ev.sobj'
                g_url = DATA + group + '/eigenvalues/' + file_name
                # print 'gagag %s'%g_url
                g = load(g_url)
                loaded = True
            except:
                info['error'] = 'Data not available'
                loaded = False

        if True == loaded:

            # define specific methods for computing discriminant and ordering of form
            if 'Sp8Z' != group and 'Sp6Z' != group: # with current data this is all degree 2 SMFs
                __disc = lambda (a, b, c): 4 * a * c - b ** 2
                __cmp = lambda (
                    a, b, c), (A, B, C): cmp((4 * a * c - b ** 2, a, b, c), (4 * A * C - B ** 2, A, B, C))

            if 'Sp8Z' == group:
                # matrix index is given as [m11 m22 m33 m44 m12 m13 m23 m14 m24 m34]
                __mat = lambda (m11, m22, m33, m44, m12, m13, m23, m14, m24, m34): \
                    matrix(ZZ, 4, 4, [m11, m12, m13, m14, m12, m22, m23, m24,
                                      m13, m23, m33, m34, m14, m24, m34, m44])
                __disc = lambda i: __mat(i).det()
                __cmp = lambda f1, f2: cmp([__mat(f1).det()] + list(f1), [__mat(f2).det()] + list(f2))

            if 'Sp6Z' == group:
                # matrix index is given as [m11/2 m22/2 m33/2 m12 m13 m23]
                __mat = lambda (a, b, c, d, e, f): \
                    matrix(ZZ, 3, 3, [2 * a, d, e, d, 2 * b, f, e, f, 2 * c])
                __disc = lambda i: __mat(i).det()
                __cmp = lambda f1, f2: cmp([__mat(f1).det()] + list(f1), [__mat(f2).det()] + list(f2))

            # make the coefficients of the M_k(Sp(4,Z)) forms integral
            # if 'Sp4Z' == group:  # or 'Sp4Z_2' == group:
            #     d = lcm(map(lambda n: denominator(n), f[1].coefficients()))
            #     f = list(f)
            #     f[1] *= d
            #     for k in f[2]:
            #         f[2][k] *= d

            # replace generator with a to make things prettier 
            if isinstance(f[0].parent(), Field):
                if f[0].parent()!=QQ:
                    gen = str(f[0].parent().gen())
                    info['gen_coeff_field'] = teXify_pol(str(f[0].parent().gen()).replace(gen, 'a'))
                    info['poly_coeff_field'] = teXify_pol(str(f[0].parent().polynomial()).replace(gen, 'a'))
                    info['poly_in_gens'] = teXify_pol(str(f[1]).replace(gen, 'a'))
                else:
                    info['poly_in_gens'] = teXify_pol(str(f[1]))
            else:
                # coefficient field is not a sage field, so just assume its supposed to be rationals
                info['poly_in_gens'] = teXify_pol(str(f[1]))

            # isolate requested eigenvalue indices
            if erange=='all':
                filt_evals = g[1]
                eval_index = filt_evals.keys()
                info['erangedesc']= 'all available eigenvalues'
            else:
                if erange:
                    spliterange = erange.split('-')
                    if len(spliterange)>1 and spliterange[0].isdigit() and spliterange[1].isdigit():
                        elow, ehigh = int(spliterange[0]), int(spliterange[1])
                        # filter out to have eigenvalues in [elow, ehigh]
                        filt_evals = {n: lam for n, lam in g[1].iteritems() if int(n)>=elow and int(n)<=ehigh}
                        eval_index = filt_evals.keys()
                        info['erangedesc'] = 'eigenvalues with $n$ in [' + `elow` + ', ' + `ehigh` + ']'
                else:
                    # can't make sense of the range, return a default
                    info['erange'] = ''
                    filt_evals = g[1]
                    eval_index = filt_evals.keys()[0:20]
                    info['erangedesc'] = 'the first few eigenvalues'

            # prepare formatted eigenvalues
            ftd_evals = []
            try:
                if not ev_modulus:
                    m = 0
                else:
                    m = int(ev_modulus)
                info['ev_modulus'] = m
                K = g[0].parent().fraction_field()
                if m != 0:
                    if QQ == K:
                        for i in eval_index:
                            rdcd_eval = Integer(g[1][i]) % m
                            ftd_evals.append((str(i), teXify_pol(str(rdcd_eval))))
                    else:
                        I = K.ideal(m)
                        for i in eval_index:
                            rdcd_eval = I.reduce(g[1][i])
                            ftd_evals.append((str(i), teXify_pol(str(rdcd_eval).replace(gen, 'a'))))
                    info['emoddesc'] = 'reduced modulo ' + `m` + '.'
                else:
                    for i in eval_index:
                        if QQ == K:
                            ftd_evals.append((str(i), teXify_pol(str(g[1][i]))))
                        else:
                            ftd_evals.append((str(i), teXify_pol(str(g[1][i]).replace(gen, 'a'))))
                    info['emoddesc'] = 'with no reduction.'     
            except:
                pass

            if (fcrange=='all'):
                filt_fcs = f[2]
                fc_index = filt_fcs.keys()
                fc_index.sort(cmp=__cmp)
                info['fcrangedesc'] = 'all available Fourier coefficients'
            else:
                if fcrange:
                    splitfcrange = fcrange.split('-')
                    if len(splitfcrange)>1 and splitfcrange[0].isdigit() and splitfcrange[1].isdigit():
                        fclow, fchigh = int(splitfcrange[0]), int(splitfcrange[1])
                        filt_fcs = {n: fc for n, fc in f[2].iteritems() if __disc(n)>=fclow and __disc(n)<=fchigh}
                        fc_index = filt_fcs.keys()
                        fc_index.sort(cmp=__cmp)
                        info['fcrangedesc'] = 'Fourier coefficients with index such that $D$ is in [' + `fclow` + ', ' + `fchigh` + ']'
                else:
                    # can't make sense of the range, return a default
                    info['fcrange'] = '' 
                    filt_fcs = f[2]
                    fc_index = filt_fcs.keys()
                    fc_index.sort(cmp=__cmp)
                    fc_index = fc_index[0:20]
                    info['fcrangedesc'] = 'the first few Fourier coefficients'

            # prepare formatted fourier coefficients
            ftd_fcs = []
            try:
                if not fc_modulus:
                    m = 0
                else:
                    m = int(fc_modulus)
                info['fc_modulus'] = m
                K = g[0].parent().fraction_field()
                if m != 0:
                    if 'Sp4Z_2' == group:
                        if QQ == K:
                            for i in fc_index:
                                ftd_fc =  sum((v[0] % m) * v[1] for v in list(f[2][i]))
                                ftd_fcs.append((str(i), 
                                               teXify_pol(str(ftd_fc)), 
                                               str(__disc(i))))
                        else:
                            I = K.ideal(m)
                            for i in fc_index:
                                ftd_fc = sum(I.reduce(v[0]) * v[1] for v in list(f[2][i]))
                                ftd_fcs.append((str(i), 
                                                teXify_pol(str(ftd_fc).replace(gen, 'a')), 
                                                str(__disc(i))))
                    else:
                        if QQ == K:
                            for i in fc_index:
                                ftd_fc = Integer(f[2][i]) % m
                                ftd_fcs.append((str(i), 
                                                teXify_pol(str(ftd_fc)), 
                                                str(__disc(i))))
                        else:
                            I = K.ideal(m)
                            for i in fc_index:
                                ftd_fc = I.reduce(f[2][i])
                                ftd_fcs.append((str(i), 
                                                teXify_pol(str(ftd_fc).replace(gen, 'a')), 
                                                str(__disc(i))))
                    info['fcmoddesc'] = 'reduced modulo ' + `m` + '.'
                else:
                    for i in fc_index:
                        ftd_fc = f[2][i]
                        if QQ == K:
                            ftd_fcs.append((str(i),
                                            teXify_pol(str(ftd_fc)),
                                            str(__disc(i))))
                        else:
                            ftd_fcs.append((str(i), 
                                            teXify_pol(str(ftd_fc).replace(gen, 'a')), 
                                            str(__disc(i))))
                    info['fcmoddesc'] = 'with no reduction.'
            except:
                pass


            location = url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, weight=weight, form=form)
            properties2 = [('Species', '$' + info['parent_as_tex'] + '$'),
                          ('Weight', '%s' % weight)]

            # if implemented, add L-function to friends
            if 'Sp4Z'== group:
                numEmbeddings = f[0].parent().degree()
                friends = []

                if form.endswith('E'):
                    # form is a Siegel-Eisenstein series, nothing interesting
                    # to show here
                    pass                   
 
                elif form.endswith('Klingen'):
                    # form is a Klingen-Eisenstein series, so plausibly could 
                    # link to the elliptic cusp form on the boundary it comes
                    # from
                    pass

                elif form.endswith('Maass'):
                    # link the the underlying elliptic modular form.  This
                    # datum is not included with the modular form, so just
                    # link to the unique Galois orbit of full level and
                    # weight 2k-2 (this code assumes Maeda).
                    ellWeight = 2*int(weight) - 2
                    friends.append(('Elliptic modular form',
                      '/ModularForm/GL2/Q/holomorphic/1/' + str(ellWeight)))
                else:
                    # there are no other lifts to full level, so the L-function
                    # is primitive and therefore interesting
                    for embedding in range(0, numEmbeddings):
                        friends.append(('Spin L-function for ' 
                          + str(weight) + '_' + form + '.' + str(embedding), 
                          '/L/ModularForm/GSp/Q/Sp4Z/specimen/'
                          + str(weight) + '/' + form + '/' + str(embedding))) 
            else:
                friends = []            
            #TODO implement remaining spin L-functions, standard L-functions,
            # and first Fourier-Jacobi coefficient

            downloads = [('Fourier coefficients', f_url),
                             ('Eigenvalues', g_url)]

            location = url_for('ModularForm_GSp4_Q_top_level', group=group, page=page, weight=weight, form=form)
            bread += [(weight + '_' + form, location)]

            info['ftd_evals'] = ftd_evals
            info['ftd_fcs'] = ftd_fcs
            info['location'] = location
            info['form_name'] = form

            return render_template("ModularForm_GSp4_Q_specimen.html", 
                 title = 'Siegel modular form ' + weight + '_' + form,
                 bread=bread, properties2=properties2, friends=friends, downloads=downloads, **info) 

    # if a nonexisting page was requested return the homepage of Siegel modular forms
    return render_webpage()