def render_isogeny_class(iso_class):
    info = {}
    credit = 'John Cremona'
    label = iso_class

    C = base.getDBConnection()
    data = C.ellcurves.isogeny.find_one({'label': label})
    if data is None:
        return "No such isogeny class"
    ainvs = [int(a) for a in data['ainvs_for_optimal_curve']]
    E = EllipticCurve(ainvs)
    info = {'label': label}
    info['optimal_ainvs'] = ainvs
    if 'imag' in data:
        info['imag'] = data['imag']
    if 'real' in data:
        info['real'] = data['real']
    info['rank'] = data['rank']
    info['isogeny_matrix'] = latex(matrix(eval(data['isogeny_matrix'])))
    info['modular_degree'] = data['degree']
    #info['f'] = ajax_more(E.q_eigenform, 10, 20, 50, 100, 250)
    info['f'] = web_latex(E.q_eigenform(10))
    G = E.isogeny_graph()
    n = G.num_verts()
    G.relabel(range(1, n + 1))  # proper cremona labels...
    info['graph_img'] = image_src(G.plot(edge_labels=True))
    curves = data['label_of_curves_in_the_class']
    info['curves'] = list(curves)
    info['download_qexp_url'] = url_for('download_qexp',
                                        limit=100,
                                        ainvs=','.join([str(a)
                                                        for a in ainvs]))
    info['download_all_url'] = url_for('download_all', label=str(label))
    friends = [('Elliptic Curve %s' % l, "/EllipticCurve/Q/%s" % l)
               for l in data['label_of_curves_in_the_class']]
    friends.append(('Quadratic Twist', "/quadratic_twists/%s" % (label)))
    friends.append(('Modular Form',
                    url_for("emf.render_classical_modular_form_from_label",
                            label="%s" % (label))))
    info['friends'] = friends

    t = "Elliptic Curve Isogeny Class %s" % info['label']
    bread = [('Elliptic Curves ', url_for("rational_elliptic_curves")),
             ('isogeny class %s' % info['label'], ' ')]

    return render_template("elliptic_curve/iso_class.html",
                           info=info,
                           bread=bread,
                           credit=credit,
                           title=t)
def padic_data():
    info = {}
    label = request.args['label']
    p = int(request.args['p'])
    info['p'] = p
    N, iso, number = cremona_label_regex.match(label).groups()
    #print N, iso, number
    if request.args['rank'] == '0':
        info['reg'] = 1
    elif number == '1':
        C = base.getDBConnection()
        data = C.ellcurves.padic_db.find_one({'label': N + iso, 'p': p})
        info['data'] = data
        if data is None:
            info['reg'] = 'no data'
        else:
            reg = sage.all.Qp(p, data['prec'])(int(data['unit'])) * sage.all.Integer(p)**int(data['val'])
            reg = reg.add_bigoh(min(data['prec'], data['prec'] + data['val']))
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("elliptic_curve/elliptic_curve_padic.html", info = info)
def render_isogeny_class(iso_class):
    info = {}
    credit = 'John Cremona'
    label=iso_class

    C = base.getDBConnection()
    data = C.ellcurves.isogeny.find_one({'label': label})
    if data is None:
        return "No such isogeny class"
    ainvs = [int(a) for a in data['ainvs_for_optimal_curve']]
    E = EllipticCurve(ainvs)
    info = {'label': label}
    info['optimal_ainvs'] = ainvs
    if 'imag' in data:
        info['imag']=data['imag']
    if 'real' in data:
        info['real']=data['real']
    info['rank'] = data['rank'] 
    info['isogeny_matrix']=latex(matrix(eval(data['isogeny_matrix'])))
    info['modular_degree']=data['degree']
    #info['f'] = ajax_more(E.q_eigenform, 10, 20, 50, 100, 250)
    info['f'] = web_latex(E.q_eigenform(10))
    G = E.isogeny_graph(); n = G.num_verts()
    G.relabel(range(1,n+1)) # proper cremona labels...
    info['graph_img'] = image_src(G.plot(edge_labels=True))
    curves = data['label_of_curves_in_the_class']
    info['curves'] = list(curves)
    info['download_qexp_url'] = url_for('download_qexp', limit=100, ainvs=','.join([str(a) for a in ainvs]))
    info['download_all_url'] = url_for('download_all', label=str(label))
    friends=[('Elliptic Curve %s' % l , "/EllipticCurve/Q/%s" % l) for l in data['label_of_curves_in_the_class']]
    friends.append(('Quadratic Twist', "/quadratic_twists/%s" % (label)))
    friends.append(('Modular Form', url_for("emf.render_classical_modular_form_from_label",label="%s" %(label))))
    info['friends'] = friends

    t= "Elliptic Curve Isogeny Class %s" % info['label']
    bread = [('Elliptic Curves ', url_for("rational_elliptic_curves")),('isogeny class %s' %info['label'],' ')]

    return render_template("elliptic_curve/iso_class.html", info = info,bread=bread, credit=credit,title = t)
def padic_data():
    info = {}
    label = request.args['label']
    p = int(request.args['p'])
    info['p'] = p
    N, iso, number = cremona_label_regex.match(label).groups()
    #print N, iso, number
    if request.args['rank'] == '0':
        info['reg'] = 1
    elif number == '1':
        C = base.getDBConnection()
        data = C.ellcurves.padic_db.find_one({'label': N + iso, 'p': p})
        info['data'] = data
        if data is None:
            info['reg'] = 'no data'
        else:
            reg = sage.all.Qp(p, data['prec'])(int(
                data['unit'])) * sage.all.Integer(p)**int(data['val'])
            reg = reg.add_bigoh(min(data['prec'], data['prec'] + data['val']))
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("elliptic_curve/elliptic_curve_padic.html",
                           info=info)
def render_field_webpage(args):
    data = None
    if 'label' in args:
        label = str(args['label'])
        import base
        C = base.getDBConnection()
        data = C.numberfields.fields.find_one({'label': label})
    if data is None:
        return "No such field: " + label + " in the database"
    info = {}

    try:
        info['count'] = args['count']
    except KeyError:
        info['count'] = 10
    K = coeff_to_nf(data['coefficients'])
    D = data['discriminant']
    h = data['class_number']
    data['galois_group'] = str(data['galois_group'][3])
    data['class_group_invs'] = data['class_group']
    if data['class_group_invs'] == []:
        data['class_group_invs'] = 'Trivial'
    data['class_group'] = str(AbelianGroup(data['class_group']))
    sig = data['signature']
    D = ZZ(data['discriminant'])
    ram_primes = D.prime_factors()
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    Gorder, Gsign, Gab = GG_data(data['galois_group'])
    if Gab:
        Gab = 'abelian'
    else:
        Gab = 'non-abelian'
    unit_rank = sig[0] + sig[1] - 1
    if unit_rank == 0:
        reg = 1
    else:
        reg = K.regulator()
    UK = K.unit_group()

    info.update(data)
    info.update({
        'label':
        field_pretty(label),
        'polynomial':
        web_latex(K.defining_polynomial()),
        'ram_primes':
        ram_primes,
        'integral_basis':
        web_latex(K.integral_basis()),
        'regulator':
        web_latex(reg),
        'unit_rank':
        unit_rank,
        'root_of_unity':
        web_latex(UK.torsion_generator()),
        'fund_units':
        ',  '.join([web_latex(u) for u in UK.fundamental_units()]),
        'Gorder':
        Gorder,
        'Gsign':
        Gsign,
        'Gab':
        Gab
    })
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    #    info['friends'] = [('L-function', '/')]
    info['friends'] = [('L-function', "/L/NumberField/%s" % label)]
    info['learnmore'] = [
        ('Number Field labels', url_for("render_labels_page")),
        ('Galois group labels', url_for("render_groups_page")),
        ('Discriminant ranges', url_for("render_discriminants_page"))
    ]
    bread = [('Number Fields', url_for("number_field_render_webpage")),
             ('%s' % info['label'], ' ')]
    t = "Number Field %s" % info['label']

    properties = ['<br>']
    properties.extend('<table>')
    properties.extend(
        '<tr><td align=left><b>Degree:</b><td align=left> %s</td>' %
        data['degree'])
    properties.extend(
        '<tr><td align=left><b>Signature:</b><td align=left>%s</td>' %
        data['signature'])
    properties.extend(
        '<tr><td align=left><b>Discriminant:</b><td align=left>%s</td>' %
        data['discriminant'])
    if npr == 1:
        properties.extend(
            '<tr><td align=left><b>Ramified prime:</b><td align=left>%s</td>' %
            ram_primes)
    else:
        if npr == 0:
            properties.extend(
                '<tr><td align=left><b>Ramified primes:</b><td align=left>%s</td>'
                % "None")
        else:
            properties.extend(
                '<tr><td align=left><b>Ramified primes:</b><td align=left>%s</td>'
                % ram_primes)
    properties.extend(
        '<tr><td align=left><b>Class number:</b><td align=left>%s</td>' %
        data['class_number'])
    properties.extend(
        '<tr><td align=left><b>Class group:</b><td align=left>%s</td>' %
        data['class_group_invs'])
    properties.extend(
        '<tr><td align=left><b>Galois group:</b><td align=left>%s</td>' %
        data['galois_group'])
    properties.extend('</table>')
    del info['_id']
    return render_template("number_field/number_field.html",
                           properties=properties,
                           credit=NF_credit,
                           title=t,
                           bread=bread,
                           friends=info.pop('friends'),
                           info=info)
def render_curve_webpage_by_label(label):
    C = base.getDBConnection()
    data = C.ellcurves.curves.find_one({'label': label})
    if data is None:
        return "No such curve"
    info = {}
    ainvs = [int(a) for a in data['ainvs']]
    E = EllipticCurve(ainvs)
    label = data['label']
    N = ZZ(data['conductor'])
    iso_class = data['iso']
    rank = data['rank']
    j_invariant = E.j_invariant()
    #plot=E.plot()
    discriminant = E.discriminant()
    xintpoints_projective = [
        E.lift_x(x)
        for x in xintegral_point(data['x-coordinates_of_integral_points'])
    ]
    xintpoints = proj_to_aff(xintpoints_projective)
    G = E.torsion_subgroup().gens()

    if 'gens' in data:
        generator = parse_gens(data['gens'])
    if len(G) == 0:
        tor_struct = 'Trivial'
        tor_group = 'Trivial'
    else:
        tor_group = ' \\times '.join(
            ['\mathbb{Z}/{%s}\mathbb{Z}' % a.order() for a in G])
    if 'torsion_structure' in data:
        info['tor_structure'] = ' \\times '.join([
            '\mathbb{Z}/{%s}\mathbb{Z}' % int(a)
            for a in data['torsion_structure']
        ])
    else:
        info['tor_structure'] = tor_group

    info.update(data)
    if rank >= 2:
        lder_tex = "L%s(E,1)" % ("^{(" + str(rank) + ")}")
    elif rank == 1:
        lder_tex = "L%s(E,1)" % ("'" * rank)
    else:
        assert rank == 0
        lder_tex = "L(E,1)"
    info.update({
        'conductor':
        N,
        'disc_factor':
        latex(discriminant.factor()),
        'j_invar_factor':
        latex(j_invariant.factor()),
        'label':
        label,
        'isogeny':
        iso_class,
        'equation':
        web_latex(E),
        #'f': ajax_more(E.q_eigenform, 10, 20, 50, 100, 250),
        'f':
        web_latex(E.q_eigenform(10)),
        'generators':
        ','.join(web_latex(g) for g in generator) if 'gens' in data else ' ',
        'lder':
        lder_tex,
        'p_adic_primes': [
            p for p in sage.all.prime_range(5, 100)
            if E.is_ordinary(p) and not p.divides(N)
        ],
        'ainvs':
        format_ainvs(data['ainvs']),
        'tamagawa_numbers':
        r' \cdot '.join(str(sage.all.factor(c)) for c in E.tamagawa_numbers()),
        'cond_factor':
        latex(N.factor()),
        'xintegral_points':
        ','.join(web_latex(i_p) for i_p in xintpoints),
        'tor_gens':
        ','.join(web_latex(eval(g)) for g in data['torsion_generators'])
        if 'torsion_generators' in data else list(G)
    })
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', url_for("not_yet_implemented"))]
    info['friends'] = [('Isogeny class', "/EllipticCurve/Q/%s" % iso_class),
                       ('Modular Form',
                        url_for("emf.render_elliptic_modular_form_from_label",
                                label="%s" % (iso_class))),
                       ('L-function', "/L/EllipticCurve/Q/%s" % label)]
    info['learnmore'] = [('Elliptic Curves', url_for("not_yet_implemented"))]
    #info['plot'] = image_src(plot)
    info['plot'] = url_for('plot_ec', label=label)
    info['iso_class'] = data['iso']
    info['download_qexp_url'] = url_for('download_qexp',
                                        limit=100,
                                        ainvs=','.join([str(a)
                                                        for a in ainvs]))
    properties2 = [('Label', '%s' % label),
                   (None, '<img src="%s" width="200" height="150"/>' %
                    url_for('plot_ec', label=label)),
                   ('Conductor', '\(%s\)' % N),
                   ('Discriminant', '\(%s\)' % discriminant),
                   ('j-invariant', '\(%s\)' % j_invariant),
                   ('Rank', '\(%s\)' % rank),
                   ('Torsion Structure', '\(%s\)' % tor_group)]
    #properties.extend([ "prop %s = %s<br/>" % (_,_*1923) for _ in range(12) ])
    credit = 'John Cremona'
    t = "Elliptic Curve %s" % info['label']
    bread = [('Elliptic Curves ', url_for("rational_elliptic_curves")),
             ('Elliptic curves %s' % info['label'], ' ')]

    return render_template("elliptic_curve/elliptic_curve.html",
                           info=info,
                           properties2=properties2,
                           credit=credit,
                           bread=bread,
                           title=t)
def render_field_webpage(args):
    data = None
    if 'label' in args:
        label = str(args['label'])
        import base
        C = base.getDBConnection()
        data = C.numberfields.fields.find_one({'label': label})
    if data is None:
        return "No such field: " + label + " in the database"  
    info = {}

    try:
        info['count'] = args['count']
    except KeyError:
        info['count'] = 10
    K = coeff_to_nf(data['coefficients'])
    D = data['discriminant']
    h = data['class_number']
    data['galois_group'] = str(data['galois_group'][3])
    data['class_group_invs'] = data['class_group']
    if data['class_group_invs']==[]:
        data['class_group_invs']='Trivial'
    data['class_group'] = str(AbelianGroup(data['class_group']))
    sig = data['signature']
    D = ZZ(data['discriminant'])
    ram_primes = D.prime_factors()
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    Gorder,Gsign,Gab = GG_data(data['galois_group'])
    if Gab:
        Gab='abelian'
    else:
        Gab='non-abelian'
    unit_rank = sig[0]+sig[1]-1
    if unit_rank==0:
        reg = 1
    else:
        reg = K.regulator()
    UK = K.unit_group()
    
    info.update(data)
    info.update({
        'label': field_pretty(label),
        'polynomial': web_latex(K.defining_polynomial()),
        'ram_primes': ram_primes,
        'integral_basis': web_latex(K.integral_basis()),
        'regulator': web_latex(reg),
        'unit_rank': unit_rank,
        'root_of_unity': web_latex(UK.torsion_generator()),
        'fund_units': ',&nbsp; '.join([web_latex(u) for u in UK.fundamental_units()]),
        'Gorder': Gorder, 'Gsign': Gsign, 'Gab': Gab
        })
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
#    info['friends'] = [('L-function', '/')]
    info['friends'] = [('L-function', "/L/NumberField/%s" % label)]
    info['learnmore'] = [('Number Field labels', url_for("render_labels_page")), ('Galois group labels',url_for("render_groups_page")), ('Discriminant ranges',url_for("render_discriminants_page"))]
    bread = [('Number Fields', url_for("number_field_render_webpage")),('%s'%info['label'],' ')]
    t = "Number Field %s" % info['label']

    properties = ['<br>']
    properties.extend('<table>')
    properties.extend('<tr><td align=left><b>Degree:</b><td align=left> %s</td>'%data['degree'])
    properties.extend('<tr><td align=left><b>Signature:</b><td align=left>%s</td>'%data['signature'])
    properties.extend('<tr><td align=left><b>Discriminant:</b><td align=left>%s</td>'%data['discriminant'])
    if npr==1:
        properties.extend('<tr><td align=left><b>Ramified prime:</b><td align=left>%s</td>'%ram_primes)
    else:
        if npr==0:
            properties.extend('<tr><td align=left><b>Ramified primes:</b><td align=left>%s</td>'%"None")
        else:
            properties.extend('<tr><td align=left><b>Ramified primes:</b><td align=left>%s</td>'%ram_primes)
    properties.extend('<tr><td align=left><b>Class number:</b><td align=left>%s</td>'%data['class_number'])
    properties.extend('<tr><td align=left><b>Class group:</b><td align=left>%s</td>'%data['class_group_invs'])
    properties.extend('<tr><td align=left><b>Galois group:</b><td align=left>%s</td>'%data['galois_group'])
    properties.extend('</table>')
    del info['_id']
    return render_template("number_field/number_field.html", properties=properties, credit=NF_credit, title = t, bread=bread, friends=info.pop('friends'), info=info )
def render_curve_webpage_by_label(label):
    C = base.getDBConnection()
    data = C.ellcurves.curves.find_one({'label': label})
    if data is None:
        return "No such curve"    
    info = {}
    ainvs = [int(a) for a in data['ainvs']]
    E = EllipticCurve(ainvs)
    label=data['label']
    N = ZZ(data['conductor'])
    iso_class = data['iso']
    rank = data['rank']
    j_invariant=E.j_invariant()
    #plot=E.plot()
    discriminant=E.discriminant()
    xintpoints_projective=[E.lift_x(x) for x in xintegral_point(data['x-coordinates_of_integral_points'])]
    xintpoints=proj_to_aff(xintpoints_projective)
    G = E.torsion_subgroup().gens()
    
    if 'gens' in data:
        generator=parse_gens(data['gens'])
    if len(G) == 0:
        tor_struct = 'Trivial'
        tor_group='Trivial'
    else:
        tor_group=' \\times '.join(['\mathbb{Z}/{%s}\mathbb{Z}'%a.order() for a in G])
    if 'torsion_structure' in data:
        info['tor_structure']= ' \\times '.join(['\mathbb{Z}/{%s}\mathbb{Z}'% int(a) for a in data['torsion_structure']])
    else:
        info['tor_structure'] = tor_group
        
    info.update(data)
    if rank >=2:
        lder_tex = "L%s(E,1)" % ("^{("+str(rank)+")}")
    elif rank ==1:
        lder_tex = "L%s(E,1)" % ("'"*rank)
    else:
        assert rank == 0
        lder_tex = "L(E,1)"
    info.update({
        'conductor': N,
        'disc_factor': latex(discriminant.factor()),
        'j_invar_factor':latex(j_invariant.factor()),
        'label': label,
        'isogeny':iso_class,
        'equation': web_latex(E),
        #'f': ajax_more(E.q_eigenform, 10, 20, 50, 100, 250),
        'f' : web_latex(E.q_eigenform(10)),
        'generators':','.join(web_latex(g) for g in generator) if 'gens' in data else ' ',
        'lder'  : lder_tex,
        'p_adic_primes': [p for p in sage.all.prime_range(5,100) if E.is_ordinary(p) and not p.divides(N)],
        'ainvs': format_ainvs(data['ainvs']),
        'tamagawa_numbers': r' \cdot '.join(str(sage.all.factor(c)) for c in E.tamagawa_numbers()),
        'cond_factor':latex(N.factor()),
        'xintegral_points':','.join(web_latex(i_p) for i_p in xintpoints),
        'tor_gens':','.join(web_latex(eval(g)) for g in data['torsion_generators']) if 'torsion_generators' in data else list(G)
                        })
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', url_for("not_yet_implemented"))]
    info['friends'] = [('Isogeny class', "/EllipticCurve/Q/%s" % iso_class),
                       ('Modular Form', url_for("emf.render_elliptic_modular_form_from_label",label="%s" %(iso_class))),
                       ('L-function', "/L/EllipticCurve/Q/%s" % label)]
    info['learnmore'] = [('Elliptic Curves', url_for("not_yet_implemented"))]
    #info['plot'] = image_src(plot)
    info['plot'] = url_for('plot_ec', label=label)
    info['iso_class'] = data['iso']
    info['download_qexp_url'] = url_for('download_qexp', limit=100, ainvs=','.join([str(a) for a in ainvs]))
    properties2 = [('Label', '%s' % label),
                   (None, '<img src="%s" width="200" height="150"/>' % url_for('plot_ec', label=label) ),
                   ('Conductor', '\(%s\)' % N), 
                   ('Discriminant', '\(%s\)' % discriminant),
                   ('j-invariant', '\(%s\)' % j_invariant),
                   ('Rank', '\(%s\)' % rank),
                   ('Torsion Structure', '\(%s\)' % tor_group)
    ]
    #properties.extend([ "prop %s = %s<br/>" % (_,_*1923) for _ in range(12) ])
    credit = 'John Cremona'
    t = "Elliptic Curve %s" % info['label']
    bread = [('Elliptic Curves ', url_for("rational_elliptic_curves")),('Elliptic curves %s' %info['label'],' ')]

    return render_template("elliptic_curve/elliptic_curve.html", 
         info=info, properties2=properties2, credit=credit,bread=bread, title = t)