Esempio n. 1
0
def show_ecnf1(nf):
    if nf == "1.1.1.1":
        return redirect(url_for("ec.rational_elliptic_curves", **request.args))
    if request.args:
        return elliptic_curve_search(data=request.args)
    start = 0
    count = 50
    try:
        nf_label = nf_string_to_label(nf)
    except ValueError:
        return search_input_error()
    query = {'field_label': nf_label}
    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if (start >= nres):
        start -= (1 + (start - nres) / count) * count
    if (start < 0):
        start = 0

    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC),
                       ('conductor_label', ASC), ('iso_nlabel', ASC),
                       ('number', ASC)]).skip(start).limit(count)

    bread = [('Elliptic Curves', url_for(".index")),
             (nf_label, url_for('.show_ecnf1', nf=nf_label))]

    res = list(res)
    for e in res:
        e['field_knowl'] = nf_display_knowl(e['field_label'],
                                            getDBConnection(),
                                            field_pretty(e['field_label']))
    info = {}
    info['field'] = nf_label
    info['query'] = query
    info['curves'] = res  # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    #don't risk recomputing all the ecnf stats just to show curves for a single number field
    #if nf_label:
    #info['stats'] = ecnf_field_summary(nf_label)
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (
                start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curves over %s' % field_pretty(nf_label)
    return render_template("ecnf-search-results.html",
                           info=info,
                           credit=ecnf_credit,
                           bread=bread,
                           title=t,
                           learnmore=learnmore_list())
Esempio n. 2
0
def show_ecnf1(nf):
    if nf == "1.1.1.1":
        return redirect(url_for("ec.rational_elliptic_curves", **request.args))
    if request.args:
        return elliptic_curve_search(data=request.args)
    start = 0
    count = 50
    try:
        nf_label = nf_string_to_label(nf)
    except ValueError:
        return search_input_error()
    query = {'field_label': nf_label}
    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0

    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count)

    bread = [('Elliptic Curves', url_for(".index")),
             (nf_label, url_for('.show_ecnf1', nf=nf_label))]

    res = list(res)
    for e in res:
        e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label']))
    info = {}
    info['field'] = nf_label
    info['query'] = query
    info['curves'] = res  # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    #don't risk recomputing all the ecnf stats just to show curves for a single number field
    #if nf_label:
        #info['stats'] = ecnf_field_summary(nf_label)
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curves over %s' % field_pretty(nf_label)
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t, learnmore=learnmore_list())
Esempio n. 3
0
    def make_torsion_growth(self):
        try:
            tor_gro = self.tor_gro
            self.torsion_growth_data_exists = True
        except AttributeError:
            self.torsion_growth_data_exists = False
            return

        self.tg = tg = {}
        tg['data'] = tgextra = []
        # find all base-changes of this curve in the database, if any
        from lmfdb.ecnf.WebEllipticCurve import db_ecnf
        bcs = [
            res['label']
            for res in db_ecnf().find({'base_change': self.lmfdb_label},
                                      projection={
                                          'label': True,
                                          '_id': False
                                      })
        ]
        bcfs = [lab.split("-")[0] for lab in bcs]
        for F, T in tor_gro.items():
            tg1 = {}
            tg1['bc'] = "Not in database"
            if ":" in F:
                F = F.replace(":", ".")
                field_data = nf_display_knowl(F, getDBConnection(),
                                              field_pretty(F))
                deg = int(F.split(".")[0])
                bcc = [x for x, y in zip(bcs, bcfs) if y == F]
                if bcc:
                    from lmfdb.ecnf.main import split_full_label
                    F, NN, I, C = split_full_label(bcc[0])
                    tg1['bc'] = bcc[0]
                    tg1['bc_url'] = url_for('ecnf.show_ecnf',
                                            nf=F,
                                            conductor_label=NN,
                                            class_label=I,
                                            number=C)
            else:
                field_data = web_latex_split_on_pm(
                    coeff_to_poly(string2list(F)))
                deg = F.count(",")
            tg1['d'] = deg
            tg1['f'] = field_data
            tg1['t'] = '\(' + ' \\times '.join(
                ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)'
            tg1['m'] = 0
            tgextra.append(tg1)

        tgextra.sort(key=lambda x: x['d'])
        tg['n'] = len(tgextra)
        lastd = 1
        for tg1 in tgextra:
            d = tg1['d']
            if d != lastd:
                tg1['m'] = len([x for x in tgextra if x['d'] == d])
                lastd = d
        tg['maxd'] = max(db_ecstats().find_one({'_id':
                                                'torsion_growth'})['degrees'])
Esempio n. 4
0
def field_display_gen(label, poly, disc=None, self_dual=None, truncate=0):
    """
    This function is used to display a number field knowl.  When the field
    is not in the LMFDB, it uses a dynamic knowl displaying the polynomial
    and discriminant.  Otherwise, it uses the standard LMFDB number field knowl.

    INPUT:

    - ``label`` -- the LMFDB label for the field (``None`` if not in the LMFDB)
    - ``poly`` -- the defining polynomial for the field as a list
    - ``disc`` -- the discriminant of the field, as a list of (p, e) pairs
    - ``truncate`` -- an integer, the maximum length of the field label before truncation.
        If 0, no truncation will occur.
    """
    if label is None:
        if poly:
            if self_dual:
                unit = ZZ(1)
            else:
                unit = ZZ(-1)**((len(poly)-1)//2)
            return polyquo_knowl(poly, disc, unit, 12)
        else:
            return ''
    else:
        name = field_pretty(label)
        if truncate and name == label and len(name) > truncate:
            parts = label.split('.')
            parts[2] = r'\(\cdots\)'
            name = '.'.join(parts)
        return nf_display_knowl(label, name)
Esempio n. 5
0
def field_label(F, pretty=True, check=False):
    r"""
      Returns the LMFDB label of the field F.
    """
    if F.absolute_degree() == 1:
        p = 'x'
    else:
        pp = F.absolute_polynomial()
        x = pp.parent().gen()
        p = str(pp).replace(str(x), 'x')
    l = poly_to_field_label(p)
    if l is None:
        if check:
            return False
        else:
            if pretty:
                return web_latex_split_on_pm(pp)
            else:
                return pp
    else:
        if check:
            return True
    if pretty:
        return field_pretty(l)
    else:
        return l
Esempio n. 6
0
def field_label(F, pretty = True, check=False):
    r"""
      Returns the LMFDB label of the field F.
    """
    if F.absolute_degree() == 1:
        p = 'x'
    else:
        pp = F.absolute_polynomial()
        x = pp.parent().gen()
        p = str(pp).replace(str(x), 'x')
    l = poly_to_field_label(p)
    if l is None:
        if check:
            return False
        else:
            if pretty:
                return web_latex_split_on_pm(pp)
            else:
                return pp
    else:
        if check:
            return True
    if pretty:
        return field_pretty(l)
    else:
        return l
Esempio n. 7
0
def get_nf_info(lab):
    r""" extract number field label from string and pretty"""
    try:
        label = nf_string_to_label(lab)
        pretty = field_pretty (label)
    except ValueError as err:
        raise ValueError(Markup("<span style='color:black'>%s</span> is not a valid number field label. %s" % (escape(lab),err)))
    return label, pretty
Esempio n. 8
0
def get_nf_info(lab):
    r""" extract number field label from string and pretty"""
    try:
        label = nf_string_to_label(lab)
        pretty = field_pretty (label)
    except ValueError as err:
        flash(Markup("Error: <span style='color:black'>%s</span> is not a valid number field. %s" % (lab,err)), "error")
        raise ValueError
    return label, pretty
Esempio n. 9
0
 def extend_from_db(self):
     setattr(self._value, "lmfdb_label", self._db_value)
     if not self._db_value is None and self._db_value != '':
         try:
             url =  url_for("number_fields.by_label", label=self._db_value)
         except RuntimeError:
             emf_logger.critical("could not set url for the label")
             url = ''
         setattr(self._value, "lmfdb_url",url)
         setattr(self._value, "lmfdb_pretty", field_pretty(self._db_value))
     else:
         if hasattr(self._value,'absolute_polynomial'):
             setattr(self._value, "lmfdb_pretty", web_latex_split_on_pm(self._value.absolute_polynomial()))
         elif self._value.absolute_degree()==1:
             setattr(self._value, "lmfdb_pretty", field_pretty('1.1.1.1'))
             setattr(self._value, "lmfdb_label", '1.1.1.1')
         else:
             emf_logger.critical("could not set lmfdb_pretty for the label")
Esempio n. 10
0
def index():
#    if 'jump' in request.args:
#        return show_ecnf1(request.args['label'])
    if len(request.args) > 0:
        return elliptic_curve_search(data=request.args)
    bread = get_bread()

# the dict data will hold additional information to be displayed on
# the main browse and search page

    data = {}

# data['fields'] holds data for a sample of number fields of different
# signatures for a general browse:

    data['fields'] = []
    # Rationals
    data['fields'].append(['the rational field', (('1.1.1.1', [url_for('ec.rational_elliptic_curves'), '$\Q$']),)])
    # Real quadratics (only a sample)
    rqfs = ['2.2.%s.1' % str(d) for d in [5, 89, 229, 497]]
    data['fields'].append(['real quadratic fields', ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)]) for nf in rqfs)])
    # Imaginary quadratics
    iqfs = ['2.0.%s.1' % str(d) for d in [4, 8, 3, 7, 11]]
    data['fields'].append(['imaginary quadratic fields', ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)]) for nf in iqfs)])
    # Cubics
    cubics = ['3.1.23.1']
    data['fields'].append(['cubic fields', ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)]) for nf in cubics)])

# data['highlights'] holds data (URL and descriptive text) for a
# sample of elliptic curves with interesting features:

    data['highlights'] = []
    data['highlights'].append(
        ['A curve with $C_3\\times C_3$ torsion',
         url_for('.show_ecnf', nf='2.0.3.1', class_label='a', conductor_label='[2268,36,18]', number=int(1))]
    )
    data['highlights'].append(
        ['A curve with $C_4\\times C_4$ torsion',
         url_for('.show_ecnf', nf='2.0.4.1', class_label='b', conductor_label='[5525,870,5]', number=int(9))]
    )
    data['highlights'].append(
        ['A curve with CM by $\\sqrt{-267}$',
         url_for('.show_ecnf', nf='2.2.89.1', class_label='a', conductor_label='81.1', number=int(1))]
    )
    data['highlights'].append(
        ['An isogeny class with isogenies of degree $3$ and $89$ (and $267$)',
         url_for('.show_ecnf_isoclass', nf='2.2.89.1', class_label='a', conductor_label='81.1')]
    )
    data['highlights'].append(
        ['A curve with everywhere good reduction, but no global minimal model',
         url_for('.show_ecnf', nf='2.2.229.1', class_label='a', conductor_label='1.1', number=int(1))]
    )

    return render_template("ecnf-index.html",
                           title="Elliptic Curves over Number Fields",
                           data=data,
                           bread=bread)
Esempio n. 11
0
def get_nf_info(lab):
    r""" extract number field label from string and pretty"""
    try:
        label = nf_string_to_label(lab)
        pretty = field_pretty(label)
    except ValueError as err:
        flash_error("%s is not a valid number field. %s", lab, err)
        raise ValueError
    return label, pretty
Esempio n. 12
0
def index():
#    if 'jump' in request.args:
#        return show_ecnf1(request.args['label'])
    if len(request.args) > 0:
        return elliptic_curve_search(data=request.args)
    bread = get_bread()

# the dict data will hold additional information to be displayed on
# the main browse and search page

    data = {}

# data['fields'] holds data for a sample of number fields of different
# signatures for a general browse:

    data['fields'] = []
    # Rationals
    data['fields'].append(['the rational field', (('1.1.1.1', [url_for('ec.rational_elliptic_curves'), '$\Q$']),)])
    # Real quadratics (only a sample)
    rqfs = ['2.2.%s.1' % str(d) for d in [5, 89, 229, 497]]
    data['fields'].append(['real quadratic fields', ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)]) for nf in rqfs)])
    # Imaginary quadratics
    iqfs = ['2.0.%s.1' % str(d) for d in [4, 8, 3, 7, 11]]
    data['fields'].append(['imaginary quadratic fields', ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)]) for nf in iqfs)])
    # Cubics
    cubics = ['3.1.23.1']
    data['fields'].append(['cubic fields', ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)]) for nf in cubics)])

# data['highlights'] holds data (URL and descriptive text) for a
# sample of elliptic curves with interesting features:

    data['highlights'] = []
    data['highlights'].append(
        ['A curve with $C_3\\times C_3$ torsion',
         url_for('.show_ecnf', nf='2.0.3.1', class_label='a', conductor_label='[2268,36,18]', number=int(1))]
    )
    data['highlights'].append(
        ['A curve with $C_4\\times C_4$ torsion',
         url_for('.show_ecnf', nf='2.0.4.1', class_label='b', conductor_label='[5525,870,5]', number=int(9))]
    )
    data['highlights'].append(
        ['A curve with CM by $\\sqrt{-267}$',
         url_for('.show_ecnf', nf='2.2.89.1', class_label='a', conductor_label='81.1', number=int(1))]
    )
    data['highlights'].append(
        ['An isogeny class with isogenies of degree $3$ and $89$ (and $267$)',
         url_for('.show_ecnf_isoclass', nf='2.2.89.1', class_label='a', conductor_label='81.1')]
    )
    data['highlights'].append(
        ['A curve with everywhere good reduction, but no global minimal model',
         url_for('.show_ecnf', nf='2.2.229.1', class_label='a', conductor_label='1.1', number=int(1))]
    )

    return render_template("ecnf-index.html",
                           title="Elliptic Curves over Number Fields",
                           data=data,
                           bread=bread)
Esempio n. 13
0
def get_nf_info(lab):
    r""" extract number field label from string and pretty"""
    try:
        label = nf_string_to_label(lab)
        pretty = field_pretty (label)
    except ValueError as err:
        flash(Markup("Error: <span style='color:black'>%s</span> is not a valid number field. %s" % (lab,err)), "error")
        raise ValueError
    return label, pretty
Esempio n. 14
0
 def field_display_gen(self, label, poly):
     if label is None:
         if poly:
             return polyquo_knowl(poly)
         else:
             return 'Unknown'
     elif label == u'1.1.1.1':  # rationals, special case
         return nf_display_knowl(label, name=r"\(\Q\)")
     else:
         return nf_display_knowl(label, field_pretty(label))
Esempio n. 15
0
    def make_torsion_growth(self):
        if self.tor_gro is None:
            self.torsion_growth_data_exists = False
            return
        tor_gro = self.tor_gro
        self.torsion_growth_data_exists = True
        self.tg = tg = {}
        tg['data'] = tgextra = []
        # find all base-changes of this curve in the database, if any
        bcs = list(
            db.ec_nfcurves.search(
                {'base_change': {
                    '$contains': [self.lmfdb_label]
                }},
                projection='label'))
        bcfs = [lab.split("-")[0] for lab in bcs]
        for F, T in tor_gro.items():
            tg1 = {}
            tg1['bc'] = "Not in database"
            if ":" in F:
                F = F.replace(":", ".")
                field_data = nf_display_knowl(F, field_pretty(F))
                deg = int(F.split(".")[0])
                bcc = [x for x, y in zip(bcs, bcfs) if y == F]
                if bcc:
                    from lmfdb.ecnf.main import split_full_label
                    F, NN, I, C = split_full_label(bcc[0])
                    tg1['bc'] = bcc[0]
                    tg1['bc_url'] = url_for('ecnf.show_ecnf',
                                            nf=F,
                                            conductor_label=NN,
                                            class_label=I,
                                            number=C)
            else:
                field_data = web_latex_split_on_pm(
                    coeff_to_poly(string2list(F)))
                deg = F.count(",")
            tg1['d'] = deg
            tg1['f'] = field_data
            tg1['t'] = '\(' + ' \\times '.join(
                ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)'
            tg1['m'] = 0
            tgextra.append(tg1)

        tgextra.sort(key=lambda x: x['d'])
        tg['n'] = len(tgextra)
        lastd = 1
        for tg1 in tgextra:
            d = tg1['d']
            if d != lastd:
                tg1['m'] = len([x for x in tgextra if x['d'] == d])
                lastd = d
        ## Hard code for now
        #tg['maxd'] = max(db.ec_curves.stats.get_oldstat('torsion_growth')['degrees'])
        tg['maxd'] = 7
Esempio n. 16
0
def end_field_statement(field_label, poly):
    if field_label == '1.1.1.1':
        return """All endomorphisms of the Jacobian are defined over \(\Q\)"""
    elif field_label != '':
        pretty = field_pretty(field_label)
        url = url_for("number_fields.by_label", label=field_label)
        return """Smallest field over which all endomorphisms are defined:<br>
        Galois number field \(K = \Q (a) \simeq \) <a href=%s>%s</a> with defining polynomial \(%s\)""" % (url, pretty, poly)
    else:
        return """Smallest field over which all endomorphisms are defined:<br>
        Galois number field \(K = \Q (a)\) with defining polynomial \(%s\)""" % poly
Esempio n. 17
0
def end_field_statement(field_label, poly):
    if field_label == '1.1.1.1':
        return """All endomorphisms of the Jacobian are defined over \(\Q\)"""
    elif field_label != '':
        pretty = field_pretty(field_label)
        url = url_for("number_fields.by_label", label=field_label)
        return """Smallest field over which all endomorphisms are defined:<br>
        Galois number field \(K = \Q (a) \simeq \) <a href=%s>%s</a> with defining polynomial \(%s\)""" % (url, pretty, poly)
    else:
        return """Smallest field over which all endomorphisms are defined:<br>
        Galois number field \(K = \Q (a)\) with defining polynomial \(%s\)""" % poly
Esempio n. 18
0
def index():
    #    if 'jump' in request.args:
    #        return show_ecnf1(request.args['label'])
    if len(request.args) > 0:
        return elliptic_curve_search(data=request.args)
    bread = get_bread()
    data = {}
    nfs = db_ecnf().distinct("field_label")
    nfs = ["2.0.4.1", "2.2.5.1", "3.1.23.1"]
    data["fields"] = [(nf, field_pretty(nf)) for nf in nfs if int(nf.split(".")[2]) < 200]
    return render_template("ecnf-index.html", title="Elliptic Curves over Number Fields", data=data, bread=bread)
Esempio n. 19
0
def show_ecnf1(nf):
    if nf == "1.1.1.1":
        return redirect(url_for("ec.rational_elliptic_curves", **request.args))
    if request.args:
        return elliptic_curve_search(data=request.args)
    start = 0
    count = 50
    nf_label = parse_field_string(nf)
    query = {"field_label": nf_label}
    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if start >= nres:
        start -= (1 + (start - nres) / count) * count
    if start < 0:
        start = 0
    res = (
        cursor.sort(
            [
                ("field_label", ASC),
                ("conductor_norm", ASC),
                ("conductor_label", ASC),
                ("iso_label", ASC),
                ("number", ASC),
            ]
        )
        .skip(start)
        .limit(count)
    )

    bread = [("Elliptic Curves", url_for(".index")), (nf_label, url_for(".show_ecnf1", nf=nf_label))]

    res = list(res)
    for e in res:
        e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), e["field_label"])
    info = {}
    info["field"] = nf_label
    info["query"] = query
    info["curves"] = res  # [ECNF(e) for e in res]
    info["number"] = nres
    info["start"] = start
    info["count"] = count
    info["more"] = int(start + count < nres)
    info["field_pretty"] = field_pretty
    info["web_ainvs"] = web_ainvs
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    t = "Elliptic Curves over %s" % field_pretty(nf_label)
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
Esempio n. 20
0
 def extend_from_db(self):
     setattr(self._value, "lmfdb_label", self._db_value)
     if not self._db_value is None and self._db_value != "":
         try:
             url = url_for("number_fields.by_label", label=self._db_value)
         except RuntimeError:
             emf_logger.critical("could not set url for the label")
             url = ""
         setattr(self._value, "lmfdb_url", url)
         setattr(self._value, "lmfdb_pretty", field_pretty(self._db_value))
     else:
         setattr(self._value, "lmfdb_pretty", web_latex_split_on_pm(self._value.absolute_polynomial()))
Esempio n. 21
0
def split_field_statement(is_simple_geom, field_label, poly):
    if is_simple_geom:
        return """Simple over \(\overline{\Q}\)"""
    elif field_label == '1.1.1.1':
        return """Splits over \(\Q\)"""
    elif field_label != '':
        pretty = field_pretty(field_label)
        url = url_for("number_fields.by_label", label=field_label)
        return """Splits over the number field \(\Q (b) \simeq \) <a href=%s>%s</a> with defining polynomial:<br>&nbsp;&nbsp;\(%s\)"""\
            % (url, pretty, poly)
    else:
        return """Splits over the number field \(\Q (b)\) with defining polynomial:<br>&nbsp;&nbsp;\(%s\)""" % poly
Esempio n. 22
0
def split_field_statement(is_simple_geom, field_label, poly):
    if is_simple_geom:
        return """Simple over \(\overline{\Q}\)"""
    elif field_label == '1.1.1.1':
        return """Splits over \(\Q\)"""
    elif field_label != '':
        pretty =  field_pretty(field_label)
        url = url_for("number_fields.by_label", label=field_label)
        return """Splits over the number field \(\Q (b) \simeq \) <a href=%s>%s</a> with defining polynomial:<br>&nbsp;&nbsp;\(%s\)"""\
            % (url, pretty, poly)
    else:
        return """Splits over the number field \(\Q (b)\) with defining polynomial:<br>&nbsp;&nbsp;\(%s\)""" % poly
Esempio n. 23
0
def index():
    #    if 'jump' in request.args:
    #        return show_ecnf1(request.args['label'])
    info = to_dict(request.args, search_array=ECNFSearchArray(), stats=ECNF_stats())
    if request.args:
        return elliptic_curve_search(info)
    bread = get_bread()

    # the dict data will hold additional information to be displayed on
    # the main browse and search page


    # info['fields'] holds data for a sample of number fields of different
    # signatures for a general browse:

    info['fields'] = []
    # Rationals
    # info['fields'].append(['the rational field', (('1.1.1.1', [url_for('ec.rational_elliptic_curves'), '$\Q$']),)]) # Removed due to ambiguity

    # Real quadratics (sample)
    rqfs = ['2.2.{}.1'.format(d) for d in [8, 12, 5, 24, 28, 40, 44, 13, 56, 60]]
    info['fields'].append(['By <a href="{}">real quadratic field</a>'.format(url_for('.statistics_by_signature', d=2, r=2)),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in rqfs)])

    # Imaginary quadratics (sample)
    iqfs = ['2.0.{}.1'.format(d) for d in [4, 8, 3, 7, 11, 19, 43]]
    info['fields'].append(['By <a href="{}">imaginary quadratic field</a>'.format(url_for('.statistics_by_signature', d=2, r=0)),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in iqfs)])

    # Cubics (sample)
    cubics = ['3.1.23.1'] + ['3.3.{}.1'.format(d) for d in [49,81,148,169,229,257,316]]
    info['fields'].append(['By <a href="{}">cubic field</a>'.format(url_for('.statistics_by_degree', d=3)),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in cubics)])

    # Quartics (sample)
    quartics = ['4.4.{}.1'.format(d) for d in [725,1125,1600,1957,2000,2048,2225,2304]]
    info['fields'].append(['By <a href="{}">totally real quartic field</a>'.format(url_for('.statistics_by_degree', d=4)),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in quartics)])

    # Quintics (sample)
    quintics = ['5.5.{}.1'.format(d) for d in [14641, 24217, 36497, 38569, 65657, 70601, 81509]]
    info['fields'].append(['By <a href="{}">totally real quintic field</a>'.format(url_for('.statistics_by_degree', d=5)),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in quintics)])

    # Sextics (sample)
    sextics = ['6.6.{}.1'.format(d) for d in [300125, 371293, 434581, 453789, 485125, 592661, 703493]]
    info['fields'].append(['By <a href="{}">totally real sextic field</a>'.format(url_for('.statistics_by_degree', d=6)),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in sextics)])

    return render_template("ecnf-index.html",
                           title="Elliptic curves over number fields",
                           info=info,
                           bread=bread, learnmore=learnmore_list())
Esempio n. 24
0
 def extend_from_db(self):
     setattr(self._value, "lmfdb_label", self._db_value)
     if not self._db_value is None and self._db_value != '':
         try:
             url = url_for("number_fields.by_label", label=self._db_value)
         except RuntimeError:
             emf_logger.critical("could not set url for the label")
             url = ''
         setattr(self._value, "lmfdb_url", url)
         setattr(self._value, "lmfdb_pretty", field_pretty(self._db_value))
     else:
         setattr(self._value, "lmfdb_pretty",
                 web_latex_split_on_pm(self._value.absolute_polynomial()))
Esempio n. 25
0
def spl_fod_statement(is_simple_geom, spl_fod_label, spl_fod_poly):
    if is_simple_geom:
        return """Simple over \(\overline{\Q}\)"""
    elif spl_fod_label == '1.1.1.1':
        return """Splits over \(\Q\)"""
    elif spl_fod_label != '':
        spl_fod_pretty =  field_pretty(spl_fod_label)
        spl_fod_url = url_for("number_fields.by_label", label=spl_fod_label)
        return """Splits over the number field \(\Q (b) \cong \) <a href=%s>%s</a> with defining polynomial:<br>&nbsp;&nbsp;\(%s\)"""\
            % (spl_fod_url, spl_fod_pretty, spl_fod_poly)
    else:
        return """Splits over the number field \(\Q (b)\) with defining polynomialL<br>&nbsp;&nbsp%s"""\
            % spl_fod_poly
Esempio n. 26
0
def spl_fod_statement(is_simple_geom, spl_fod_label, spl_fod_poly):
    if is_simple_geom:
        return """Simple over \(\overline{\Q}\)"""
    elif spl_fod_label == '1.1.1.1':
        return """Splits over \(\Q\)"""
    elif spl_fod_label != '':
        spl_fod_pretty = field_pretty(spl_fod_label)
        spl_fod_url = url_for("number_fields.by_label", label=spl_fod_label)
        return """Splits over the number field \(\Q (b) \cong \) <a href=%s>%s</a> with defining polynomial:<br>&nbsp;&nbsp;\(%s\)"""\
            % (spl_fod_url, spl_fod_pretty, spl_fod_poly)
    else:
        return """Splits over the number field \(\Q (b)\) with defining polynomialL<br>&nbsp;&nbsp%s"""\
            % spl_fod_poly
Esempio n. 27
0
    def make_torsion_growth(self):
        if self.tor_gro is None:
            self.torsion_growth_data_exists = False
            return
        tor_gro = self.tor_gro
        self.torsion_growth_data_exists = True
        self.tg = tg = {}
        tg['data'] = tgextra = []
        # find all base-changes of this curve in the database, if any
        bcs = list(db.ec_nfcurves.search({'base_change': {'$contains': [self.lmfdb_label]}}, projection='label'))
        bcfs = [lab.split("-")[0] for lab in bcs]
        for F, T in tor_gro.items():
            tg1 = {}
            tg1['bc'] = "Not in database"
            if ":" in F:
                F = F.replace(":",".")
                field_data = nf_display_knowl(F, field_pretty(F))
                deg = int(F.split(".")[0])
                bcc = [x for x,y in zip(bcs, bcfs) if y==F]
                if bcc:
                    from lmfdb.ecnf.main import split_full_label
                    F, NN, I, C = split_full_label(bcc[0])
                    tg1['bc'] = bcc[0]
                    tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C)
            else:
                field_data = web_latex_split_on_pm(coeff_to_poly(string2list(F)))
                deg = F.count(",")
            tg1['d'] = deg
            tg1['f'] = field_data
            tg1['t'] = '\(' + ' \\times '.join(['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)'
            tg1['m'] = 0
            tgextra.append(tg1)

        tgextra.sort(key = lambda x: x['d'])
        tg['n'] = len(tgextra)
        lastd = 1
        for tg1 in tgextra:
            d = tg1['d']
            if d!=lastd:
                tg1['m'] = len([x for x in tgextra if x['d']==d])
                lastd = d

        ## Hard-code this for now.  While something like
        ## max(db.ec_curves.search({},projection='tor_degs')) might
        ## work, since 'tor_degs' is in the extra table it is very
        ## slow.  Note that the *only* place where this number is used
        ## is in the ec-curve template where it says "The number
        ## fields ... of degree up to {{data.tg.maxd}} such that...".
        
        tg['maxd'] = 7
Esempio n. 28
0
 def stats_for_field(self, F):
     forms = self.forms
     fields = self.fields
     # pipeline = [{"$match": {'field_label':F}},
     #             {"$project" : { 'level_norm' : 1 }},
     #             {"$group":{"_id":"level_norm", "nforms": {"$sum": 2}, "maxnorm" : {"$max": '$level_norm'}}}]
     # res = forms.aggregate(pipeline).next()
     res = [f['level_norm'] for f in forms.find({'field_label':F}, ['level_norm'])]
     stats = {}
     stats['nforms'] = len(res) # res['nforms']
     stats['maxnorm'] = max(res+[0]) # res['maxnorm']
     stats['field_knowl'] = nf_display_knowl(F, lmfdb.base.getDBConnection(), field_pretty(F))
     stats['forms'] = url_for('hmf.hilbert_modular_form_render_webpage', field_label=F)
     return stats
Esempio n. 29
0
 def field_summary(self, field):
     stats = self.field_normstats[field]
     ncurves = stats['ncurves']
     nclasses = stats['nclasses']
     max_norm = stats['max_norm']
     ec_knowl = self.ec_knowl if ncurves == 1 else self.ec_knowls
     iso_knowl = self.iso_knowl if ncurves == 1 else self.iso_knowls
     nf_knowl = self.nf_knowl if ncurves == 1 else self.nf_knowls
     cond_knowl = self.cond_knowl if ncurves == 1 else self.cond_knowls
     s = '' if max_norm == 1 else 'up to '
     norm_phrase = ' of norm {}{}.'.format(s, max_norm)
     return ''.join([
         r'The database currently contains {} '.format(ncurves), ec_knowl,
         r' defined over the ', nf_knowl,
         r' {}, in {} '.format(field_pretty(field), nclasses), iso_knowl,
         r', with ', cond_knowl, norm_phrase
     ])
Esempio n. 30
0
def ecnf_field_summary(field):
    stats = get_field_stats(field)
    s = '' if stats['ncurves'] == 1 else 's'
    ec_knowl = '<a knowl="ec">elliptic curve%s</a>' % s
    s = '' if stats['nclasses'] == 1 else 'es'
    iso_knowl = '<a knowl="ec.isogeny_class">isogeny class%s</a>' % s
    nf_knowl = '<a knowl="nf">number field</a>'
    s = '' if stats['maxnorm'] == 1 else 's'
    cond_knowl = '<a knowl="ec.conductor">conductor%s</a>' % s
    s = '' if stats['maxnorm'] == 1 else 'up to '
    return ''.join([
        r'The database currently contains %s ' % stats['ncurves'], ec_knowl,
        r' defined over the ', nf_knowl,
        r' %s, in %s ' % (field_pretty(field), stats['nclasses']), iso_knowl,
        r', with ', cond_knowl,
        r' of norm %s %s.' % (s, stats['maxnorm'])
    ])
Esempio n. 31
0
    def make_torsion_growth(self):
        try:
            tor_gro = self.tor_gro
            self.torsion_growth_data_exists = True
        except AttributeError:
            self.torsion_growth_data_exists = False
            return

        self.tg = tg = {}
        tg['data'] = tgextra = []
        # find all base-changes of this curve in the database, if any
        from lmfdb.ecnf.WebEllipticCurve import db_ecnf
        bcs = [res['label'] for res in  db_ecnf().find({'base_change': self.lmfdb_label}, projection={'label': True, '_id': False})]
        bcfs = [lab.split("-")[0] for lab in bcs]
        for F, T in tor_gro.items():
            tg1 = {}
            tg1['bc'] = "Not in database"
            if ":" in F:
                F = F.replace(":",".")
                field_data = nf_display_knowl(F, getDBConnection(), field_pretty(F))
                deg = int(F.split(".")[0])
                bcc = [x for x,y in zip(bcs, bcfs) if y==F]
                if bcc:
                    from lmfdb.ecnf.main import split_full_label
                    F, NN, I, C = split_full_label(bcc[0])
                    tg1['bc'] = bcc[0]
                    tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C)
            else:
                field_data = web_latex_split_on_pm(coeff_to_poly(string2list(F)))
                deg = F.count(",")
            tg1['d'] = deg
            tg1['f'] = field_data
            tg1['t'] = '\(' + ' \\times '.join(['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)'
            tg1['m'] = 0
            tgextra.append(tg1)

        tgextra.sort(key = lambda x: x['d'])
        tg['n'] = len(tgextra)
        lastd = 1
        for tg1 in tgextra:
            d = tg1['d']
            if d!=lastd:
                tg1['m'] = len([x for x in tgextra if x['d']==d])
                lastd = d
        tg['maxd'] = max(db_ecstats().find_one({'_id': 'torsion_growth'})['degrees'])
Esempio n. 32
0
    def make_torsion_growth(self):
        if self.tor_gro is None:
            self.torsion_growth_data_exists = False
            return
        tor_gro = self.tor_gro
        self.torsion_growth_data_exists = True
        self.tg = tg = {}
        tg['data'] = tgextra = []
        # find all base-changes of this curve in the database, if any
        bcs = list(db.ec_nfcurves.search({'base_change': {'$contains': [self.lmfdb_label]}}, projection='label'))
        bcfs = [lab.split("-")[0] for lab in bcs]
        for F, T in tor_gro.items():
            tg1 = {}
            tg1['bc'] = "Not in database"
            if ":" in F:
                F = F.replace(":",".")
                field_data = nf_display_knowl(F, field_pretty(F))
                deg = int(F.split(".")[0])
                bcc = [x for x,y in zip(bcs, bcfs) if y==F]
                if bcc:
                    from lmfdb.ecnf.main import split_full_label
                    F, NN, I, C = split_full_label(bcc[0])
                    tg1['bc'] = bcc[0]
                    tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C)
            else:
                field_data = web_latex_split_on_pm(coeff_to_poly(string2list(F)))
                deg = F.count(",")
            tg1['d'] = deg
            tg1['f'] = field_data
            tg1['t'] = '\(' + ' \\times '.join(['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)'
            tg1['m'] = 0
            tgextra.append(tg1)

        tgextra.sort(key = lambda x: x['d'])
        tg['n'] = len(tgextra)
        lastd = 1
        for tg1 in tgextra:
            d = tg1['d']
            if d!=lastd:
                tg1['m'] = len([x for x in tgextra if x['d']==d])
                lastd = d
        ## Hard code for now
        #tg['maxd'] = max(db.ec_curves.stats.get_oldstat('torsion_growth')['degrees'])
        tg['maxd'] = 7
Esempio n. 33
0
def ecnf_field_summary(field):
    stats = get_field_stats(field)
    s = '' if stats['ncurves']==1 else 's'
    ec_knowl = '<a knowl="ec">elliptic curve%s</a>' % s
    s = '' if stats['nclasses']==1 else 'es'
    iso_knowl = '<a knowl="ec.isogeny_class">isogeny class%s</a>' % s
    nf_knowl = '<a knowl="nf">number field</a>'
    s = '' if stats['maxnorm']==1 else 's'
    cond_knowl = '<a knowl="ec.conductor">conductor%s</a>' % s
    s = '' if stats['maxnorm']==1 else 'up to '
    return ''.join([r'The database currently contains %s ' % stats['ncurves'],
                    ec_knowl,
                    r' defined over the ',
                    nf_knowl,
                    r' %s, in %s ' % (field_pretty(field), stats['nclasses']),
                    iso_knowl,
                    r', with ',
                    cond_knowl,
                    r' of norm %s %s.' % (s,stats['maxnorm'])])
Esempio n. 34
0
def end_lattice_statement(lattice):
    statement = ''
    for ED in lattice:
        if ED[0][0]:
            # Add link and prettify if available:
            statement += """Over subfield \(F \simeq \) <a href=%s>%s</a> with generator \(%s\) with minimal polynomial \(%s\)"""\
                % (url_for("number_fields.by_label", label=ED[0][0]),
                   field_pretty(ED[0][0]), strlist_to_nfelt(ED[0][2], 'a'),
                   intlist_to_poly(ED[0][1]))
        else:
            statement += """Over subfield \(F\) with generator \(%s\) with minimal polynomial \(%s\)"""\
                % (strlist_to_nfelt(ED[0][2], 'a'), intlist_to_poly(ED[0][1]))
        statement += """:<br>"""
        statement += end_statement(ED[1], ED[2], field=r'F', ring=ED[3])
        statement += """Sato Tate group: %s""" % st_link_by_name(1,4,ED[4])
        statement += """<br>"""
        statement += gl2_simple_statement(ED[1], ED[2])
        statement += """<p></p>"""
    return statement
Esempio n. 35
0
def ecnf_field_summary(field):
    data = db.ec_nfcurves.stats.get_oldstat('conductor_norm_by_field')[field]
    ncurves = data['ncurves']
    s = '' if ncurves == 1 else 's'
    ec_knowl = '<a knowl="ec">elliptic curve{}</a>'.format(s)
    nclasses = data['nclasses']
    s = '' if nclasses == 1 else 'es'
    iso_knowl = '<a knowl="ec.isogeny_class">isogeny class{}</a>'.format(s)
    nf_knowl = '<a knowl="nf">number field</a>'
    max_norm = data['max_norm']
    s = '' if max_norm == 1 else 's'
    cond_knowl = '<a knowl="ec.conductor">conductor{}</a>'.format(s)
    s = '' if max_norm == 1 else 'up to '
    return ''.join([
        r'The database currently contains {} '.format(ncurves), ec_knowl,
        r' defined over the ', nf_knowl,
        r' {}, in {} '.format(field_pretty(field), nclasses), iso_knowl,
        r', with ', cond_knowl, r' of norm {} {}.'.format(s, data['max_norm'])
    ])
Esempio n. 36
0
def end_lattice_statement(lattice):
    statement = ''
    for ED in lattice:
        if ED[0][0]:
            # Add link and prettify if available:
            statement += """Over subfield \(F \simeq \) <a href=%s>%s</a> with generator \(%s\) with minimal polynomial \(%s\)"""\
                % (url_for("number_fields.by_label", label=ED[0][0]),
                   field_pretty(ED[0][0]), strlist_to_nfelt(ED[0][2], 'a'),
                   intlist_to_poly(ED[0][1]))
        else:
            statement += """Over subfield \(F\) with generator \(%s\) with minimal polynomial \(%s\)"""\
                % (strlist_to_nfelt(ED[0][2], 'a'), intlist_to_poly(ED[0][1]))
        statement += """:<br>"""
        statement += end_statement(ED[1], ED[2], field=r'F', ring=ED[3])
        statement += """Sato Tate group: %s""" % st_link_by_name(1, 4, ED[4])
        statement += """<br>"""
        statement += gl2_simple_statement(ED[1], ED[2])
        statement += """<p></p>"""
    return statement
Esempio n. 37
0
 def field_summary(self, field):
     stats = self.field_normstats[field]
     ncurves = stats['ncurves']
     nclasses = stats['nclasses']
     max_norm = stats['max_norm']
     ec_knowl = self.ec_knowl if ncurves==1 else self.ec_knowls
     iso_knowl = self.iso_knowl if ncurves==1 else self.iso_knowls
     nf_knowl = self.nf_knowl if ncurves==1 else self.nf_knowls
     cond_knowl = self.cond_knowl if ncurves==1 else self.cond_knowls
     s = '' if max_norm==1 else 'up to '
     norm_phrase = ' of norm {}{}.'.format(s, max_norm)
     return ''.join([r'The database currently contains {} '.format(ncurves),
                     ec_knowl,
                     r' defined over the ',
                     nf_knowl,
                     r' {}, in {} '.format(field_pretty(field), nclasses),
                     iso_knowl,
                     r', with ',
                     cond_knowl,
                     norm_phrase])
Esempio n. 38
0
def ecnf_field_summary(field):
    data = db_ecnfstats().find_one({'_id':'conductor_norm_by_field'})[field]
    ncurves = data['ncurves']
    s = '' if ncurves==1 else 's'
    ec_knowl = '<a knowl="ec">elliptic curve{}</a>'.format(s)
    nclasses = data['nclasses']
    s = '' if nclasses==1 else 'es'
    iso_knowl = '<a knowl="ec.isogeny_class">isogeny class{}</a>'.format(s)
    nf_knowl = '<a knowl="nf">number field</a>'
    max_norm = data['max_norm']
    s = '' if max_norm==1 else 's'
    cond_knowl = '<a knowl="ec.conductor">conductor{}</a>'.format(s)
    s = '' if max_norm==1 else 'up to '
    return ''.join([r'The database currently contains {} '.format(ncurves),
                    ec_knowl,
                    r' defined over the ',
                    nf_knowl,
                    r' {}, in {} '.format(field_pretty(field), nclasses),
                    iso_knowl,
                    r', with ',
                    cond_knowl,
                    r' of norm {} {}.'.format(s,data['max_norm'])])
Esempio n. 39
0
def show_ecnf1(nf):
    if request.args:
        return elliptic_curve_search(data=request.args)
    start = 0
    count = 20
    query = {'field_label' : nf}
    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0
    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count)

    bread = [('Elliptic Curves', url_for(".index")),
             (nf, url_for('.show_ecnf1', nf=nf))]

    res = list(res)
    for e in res:
        e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label'])
    info = {}
    info['field'] = nf
    info['query'] = query
    info['curves'] = res # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curves over %s' % field_pretty(nf)
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
Esempio n. 40
0
@search_wrap(template="hilbert_modular_form_search.html",
             table=db.hmf_forms,
             title='Hilbert modular form search results',
             err_title='Hilbert modular form search error',
             per_page=50,
             shortcuts={'jump': hilbert_modular_form_jump},
             projection=[
                 'field_label', 'short_label', 'label', 'level_ideal',
                 'dimension'
             ],
             cleaners={
                 "level_ideal":
                 lambda v: teXify_pol(v['level_ideal']),
                 "field_knowl":
                 lambda e: nf_display_knowl(e['field_label'],
                                            field_pretty(e['field_label']))
             },
             bread=lambda: get_bread("Search results"),
             learnmore=learnmore_list,
             url_for_label=url_for_label,
             credit=lambda: hmf_credit,
             properties=lambda: [])
def hilbert_modular_form_search(info, query):
    parse_nf_string(info, query, 'field_label', name="Field")
    parse_ints(info, query, 'deg', name='Field degree')
    parse_ints(info, query, 'disc', name="Field discriminant")
    parse_ints(info, query, 'dimension')
    parse_ints(info, query, 'level_norm', name="Level norm")
    parse_hmf_weight(info,
                     query,
                     'weight',
Esempio n. 41
0
    except ValueError:
        return redirect(url_for(".hilbert_modular_form_render_webpage"))


hmf_columns = SearchColumns([
    MultiProcessedCol(
        "label",
        "mf.hilbert.label",
        "Label", ["field_label", "label", "short_label"],
        lambda fld, label, short: '<a href="%s">%s</a>' % (url_for(
            'hmf.render_hmf_webpage', field_label=fld, label=label), short),
        default=True),
    ProcessedCol("field_label",
                 "nf",
                 "Base field",
                 lambda fld: nf_display_knowl(fld, field_pretty(fld)),
                 default=True),
    MathCol("deg", "nf.degree", "Field degree"),
    MathCol("disc", "nf.discriminant", "Field discriminant"),
    ProcessedCol("level_ideal",
                 "mf.hilbert.level_norm",
                 "Level",
                 teXify_pol,
                 mathmode=True,
                 default=True),
    MathCol("level_norm", "mf.level_norm", "Level norm"),
    MathCol("weight", "mf.hilbert.weight_vector", "Weight"),
    MathCol("dimension", "mf.hilbert.dimension", "Dimension", default=True),
    ProcessedCol("is_CM",
                 "mf.cm",
                 "CM",
Esempio n. 42
0
def elliptic_curve_search(**args):
    info = to_dict(args['data'])
    
    if 'download' in info and info['download'] != 0:
        return download_search(info)

    if not 'query' in info:
        info['query'] = {}
    
    bread = [('Elliptic Curves', url_for(".index")),
             ('Search Results', '.')]
    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        # This label should be a full isogeny class label or a full
        # curve label (including the field_label component)
        try:
            nf, cond_label, iso_label, number = split_full_label(label.strip())
        except ValueError:
            info['err'] = ''
            return search_input_error(info, bread)

        return show_ecnf(nf, cond_label, iso_label, number)

    query = {}

    try:
        parse_ints(info,query,'conductor_norm')
        parse_noop(info,query,'conductor_label')
        parse_nf_string(info,query,'field',name="base number field",qfield='field_label')
        parse_nf_elt(info,query,'jinv',name='j-invariant')
        parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order')
        parse_bracketed_posints(info,query,'torsion_structure',maxlength=2)
        if 'torsion_structure' in query and not 'torsion_order' in query:
            query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    except ValueError:
        return search_input_error(info, bread)

    if 'include_isogenous' in info and info['include_isogenous'] == 'off':
        info['number'] = 1
        query['number'] = 1

    if 'include_base_change' in info and info['include_base_change'] == 'off':
        query['base_change'] = []
    else:
        info['include_base_change'] = "on"

    if 'include_Q_curves' in info:
        if info['include_Q_curves'] == 'exclude':
            query['q_curve'] = False
        elif info['include_Q_curves'] == 'only':
            query['q_curve'] = True

    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne' : 0}

    info['query'] = query
    count = parse_count(info, 50)
    start = parse_start(info)

    # make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0
    
    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count)

    res = list(res)
    for e in res:
        e['numb'] = str(e['number'])
        e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label']))

    info['curves'] = res  # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curve search results'
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
Esempio n. 43
0
def elliptic_curve_search(info):

    if info.get('download') == '1' and info.get('Submit') and info.get(
            'query'):
        return download_search(info)

    if not 'query' in info:
        info['query'] = {}

    bread = info.get('bread', [('Elliptic Curves', url_for(".index")),
                               ('Search Results', '.')])
    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        # This label should be a full isogeny class label or a full
        # curve label (including the field_label component)
        try:
            nf, cond_label, iso_label, number = split_full_label(label.strip())
        except ValueError:
            info['err'] = ''
            return search_input_error(info, bread)

        return redirect(
            url_for(".show_ecnf",
                    nf=nf,
                    conductor_label=cond_label,
                    class_label=iso_label,
                    number=number), 301)

    query = {}

    if 'jinv' in info:
        if info.get('field', '').strip() == '2.2.5.1':
            info['jinv'] = info['jinv'].replace('phi', 'a')
        if info.get('field', '').strip() == '2.0.4.1':
            info['jinv'] = info['jinv'].replace('i', 'a')
    try:
        parse_ints(info, query, 'conductor_norm')
        parse_noop(info, query, 'conductor_label')
        parse_nf_string(info,
                        query,
                        'field',
                        name="base number field",
                        qfield='field_label')
        parse_nf_elt(info, query, 'jinv', name='j-invariant')
        parse_ints(info,
                   query,
                   'torsion',
                   name='Torsion order',
                   qfield='torsion_order')
        parse_bracketed_posints(info, query, 'torsion_structure', maxlength=2)
        if 'torsion_structure' in query and not 'torsion_order' in query:
            query['torsion_order'] = reduce(
                mul, [int(n) for n in query['torsion_structure']], 1)
        parse_ints(info, query, field='isodeg', qfield='isogeny_degrees')
    except (TypeError, ValueError):
        return search_input_error(info, bread)

    if query.get('jinv'):
        query['jinv'] = ','.join(query['jinv'])

    if query.get('field_label') == '1.1.1.1':
        return redirect(url_for("ec.rational_elliptic_curves", **request.args),
                        301)

    if 'include_isogenous' in info and info['include_isogenous'] == 'off':
        info['number'] = 1
        query['number'] = 1

    if 'include_base_change' in info and info['include_base_change'] == 'off':
        query['base_change'] = []
    else:
        info['include_base_change'] = "on"

    if 'include_Q_curves' in info:
        if info['include_Q_curves'] == 'exclude':
            query['q_curve'] = False
        elif info['include_Q_curves'] == 'only':
            query['q_curve'] = True

    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne': 0}

    info['query'] = query
    count = parse_count(info, 50)
    start = parse_start(info)

    # make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if (start >= nres):
        start -= (1 + (start - nres) / count) * count
    if (start < 0):
        start = 0

    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC),
                       ('conductor_label', ASC), ('iso_nlabel', ASC),
                       ('number', ASC)]).skip(start).limit(count)

    res = list(res)
    for e in res:
        e['numb'] = str(e['number'])
        e['field_knowl'] = nf_display_knowl(e['field_label'],
                                            getDBConnection(),
                                            field_pretty(e['field_label']))

    info['curves'] = res  # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (
                start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = info.get('title', 'Elliptic Curve search results')
    return render_template("ecnf-search-results.html",
                           info=info,
                           credit=ecnf_credit,
                           bread=bread,
                           title=t)
Esempio n. 44
0
            raise ValueError("A CM discriminant must be a fundamental discriminant of an imaginary quadratic field.")
    cm_list += [-el for el in cm_list]
    return cm_list

@search_parser
def parse_cm_list(inp, query, qfield):
    query[qfield] = {'$in': make_cm_query(inp)}

ecnf_columns = SearchColumns([
    MultiProcessedCol("label", "ec.curve_label", "Label",
                      ["short_label", "field_label", "conductor_label", "iso_label", "number"],
                      lambda label, field, conductor, iso, number: '<a href="%s">%s</a>' % (
                          url_for('.show_ecnf', nf=field, conductor_label=conductor, class_label=iso, number=number),
                          label),
                      default=True, align="center"),
    ProcessedCol("field_label", "nf", "Base field", lambda field: nf_display_knowl(field, field_pretty(field)), default=True, align="center"),
    MultiProcessedCol("conductor", "ec.conductor_label", "Conductor",
                      ["field_label", "conductor_label"],
                      lambda field, conductor: '<a href="%s">%s</a>' %(
                          url_for('.show_ecnf_conductor', nf=field, conductor_label=conductor),
                          conductor),
                      default=True, align="center"),
    MultiProcessedCol("iso_class", "ec.isogeny_class", "Isogeny class",
                      ["field_label", "conductor_label", "iso_label", "short_class_label"],
                      lambda field, conductor, iso, short_class_label: '<a href="%s">%s</a>' % (
                          url_for('.show_ecnf_isoclass', nf=field, conductor_label=conductor, class_label=iso),
                          short_class_label),
                      default=True, align="center"),
    MultiProcessedCol("ainvs", "ec.weierstrass_coeffs", "Weierstrass coefficients",
                      ["field_label", "conductor_label", "iso_label", "number", "ainvs"],
                      lambda field, conductor, iso, number, ainvs: '<a href="%s">%s</a>' % (
Esempio n. 45
0
def index():
    #    if 'jump' in request.args:
    #        return show_ecnf1(request.args['label'])
    if len(request.args) > 0:
        return elliptic_curve_search(to_dict(request.args))
    bread = get_bread()

    # the dict data will hold additional information to be displayed on
    # the main browse and search page

    data = {}

    # data['fields'] holds data for a sample of number fields of different
    # signatures for a general browse:

    ecnfstats = db_ecnfstats()
    fields_by_deg = ecnfstats.find_one({'_id':'fields_by_degree'})
    fields_by_sig = ecnfstats.find_one({'_id':'fields_by_signature'})
    data['fields'] = []
    # Rationals
    data['fields'].append(['the rational field', (('1.1.1.1', [url_for('ec.rational_elliptic_curves'), '$\Q$']),)])

    # Real quadratics (sample)
    rqfs = ['2.2.{}.1'.format(d) for d in [5, 89, 229, 497]]
    niqfs = len(fields_by_sig['0,1'])
    nrqfs = len(fields_by_sig['2,0'])
    data['fields'].append(['{} real quadratic fields, including'.format(nrqfs),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in rqfs)])

    # Imaginary quadratics (sample)
    iqfs = ['2.0.{}.1'.format(d) for d in [4, 8, 3, 7, 11]]
    data['fields'].append(['{} imaginary quadratic fields, including'.format(niqfs),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in iqfs)])

    # Cubics (sample)
    cubics = ['3.1.23.1'] + ['3.3.{}.1'.format(d) for d in [49,148,1957]]
    ncubics = len(fields_by_deg['3'])
    data['fields'].append(['{} cubic fields, including'.format(ncubics),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in cubics)])

    # Quartics (sample)
    quartics = ['4.4.{}.1'.format(d) for d in [725,2777,9909,19821]]
    nquartics = len(fields_by_deg['4'])
    data['fields'].append(['{} totally real quartic fields, including'.format(nquartics),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in quartics)])

    # Quintics (sample)
    quintics = ['5.5.{}.1'.format(d) for d in [14641, 24217, 36497, 38569, 65657]]
    nquintics = len(fields_by_deg['5'])
    data['fields'].append(['{} totally real quintic fields, including'.format(nquintics),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in quintics)])

    # Sextics (sample)
    sextics = ['6.6.{}.1'.format(d) for d in [300125, 371293, 434581, 453789, 485125]]
    nsextics = len(fields_by_deg['6'])
    data['fields'].append(['{} totally real sextic fields, including'.format(nsextics),
                           ((nf, [url_for('.show_ecnf1', nf=nf), field_pretty(nf)])
                            for nf in sextics)])

    data['degrees'] = sorted([int(d) for d in fields_by_deg.keys() if d!='_id'])

# data['highlights'] holds data (URL and descriptive text) for a
# sample of elliptic curves with interesting features:

    data['highlights'] = []
    data['highlights'].append(
        ['A curve with $C_3\\times C_3$ torsion',
         url_for('.show_ecnf', nf='2.0.3.1', class_label='a', conductor_label='2268.36.18', number=int(1))]
    )
    data['highlights'].append(
        ['A curve with $C_4\\times C_4$ torsion',
         url_for('.show_ecnf', nf='2.0.4.1', class_label='b', conductor_label='5525.870.5', number=int(9))]
    )
    data['highlights'].append(
        ['A curve with CM by $\\sqrt{-267}$',
         url_for('.show_ecnf', nf='2.2.89.1', class_label='a', conductor_label='81.1', number=int(1))]
    )
    data['highlights'].append(
        ['An isogeny class with isogenies of degree $3$ and $89$ (and $267$)',
         url_for('.show_ecnf_isoclass', nf='2.2.89.1', class_label='a', conductor_label='81.1')]
    )
    data['highlights'].append(
        ['A curve with everywhere good reduction, but no global minimal model',
         url_for('.show_ecnf', nf='2.2.229.1', class_label='a', conductor_label='1.1', number=int(1))]
    )

    return render_template("ecnf-index.html",
                           title="Elliptic Curves over Number Fields",
                           data=data,
                           bread=bread, learnmore=learnmore_list_remove('Completeness'))
Esempio n. 46
0
def end_statement(factorsQQ, factorsRR, field='', ring=None):
    # field is a latex string describing the basechange field (default is empty)
    # ring is optional, if unspecified only endomorphism algebra is described
    statement = '<table style="margin-left: 10px; margin-top: -12px">'
    factorsQQ_number = len(factorsQQ)
    factorsQQ_pretty = [field_pretty(fac[0]) for fac in factorsQQ if fac[0]]

    # endomorphism ring is an invariant of the curve but not the isogeny class, so we make it optional
    if ring:
        # First row: description of the endomorphism ring as an order in the endomorphism algebra
        statement += r"<tr><td>\(\End (J_{%s})\)</td><td>\(\simeq\)</td><td>" % field
        # First the case of a maximal order:
        if ring[0] == 1:
            # Single factor:
            if factorsQQ_number == 1:
                # Number field or not:
                if factorsQQ[0][2] == -1:
                    # Prettify in quadratic case:
                    if len(factorsQQ[0][1]) in [2, 3]:
                        statement += r"\(%s\)" % ring_pretty(
                            factorsQQ[0][1], 1)
                    else:
                        statement += r"the maximal order of \(\End (J_{%s}) \otimes \Q\)" % field
                else:
                    # Use M_2 over integers if this applies:
                    if factorsQQ[0][2] == 1 and factorsQQ[0][0] == '1.1.1.1':
                        statement += r"\(\mathrm{M}_2 (\Z)\)"
                    # TODO: Add flag that indicates whether we are over a PID, in
                    # which case we can use the following lines:
                    #if factorsQQ[0][2] == 1:
                    #    statement += (r"\(\mathrm{M}_2 (%s)\)"
                    #        % ring_pretty(factorsQQ[0][1], 1))
                    else:
                        statement += r"a maximal order of \(\End (J_{%s}) \otimes \Q\)" % field
            # If there are two factors, then they are both at most quadratic
            # and we can prettify them
            else:
                statement += r'\(' + r' \times '.join(
                    [ring_pretty(factorQQ[1], 1)
                     for factorQQ in factorsQQ]) + r'\)'
        # Then the case where there is still a single factor:
        elif factorsQQ_number == 1:
            # Number field case:
            if factorsQQ[0][2] == -1:
                # Prettify in quadratic case:
                if len(factorsQQ[0][1]) in [2, 3]:
                    statement += r"\(%s\)" % ring_pretty(
                        factorsQQ[0][1], ring[0])
                else:
                    statement += r"an order of conductor of norm \(%s\) in \(\End (J_{%s}) \otimes \Q\)" % (
                        ring[0], field)
            # Otherwise mention whether the order is Eichler:
            elif ring[1] == 1:
                statement += r"an Eichler order of index \(%s\) in a maximal order of \(\End (J_{%s}) \otimes \Q\)" % (
                    ring[0], field)
            else:
                statement += r"a non-Eichler order of index \(%s\) in a maximal order of \(\End (J_{%s}) \otimes \Q\)" % (
                    ring[0], field)
        # Finally the case of two factors. We can prettify to some extent, since we
        # can describe the maximal order here
        else:
            statement += r"an order of index \(%s\) in \(%s\)" % (
                ring[0], r' \times '.join(
                    [ring_pretty(factorQQ[1], 1) for factorQQ in factorsQQ]))
        # End of first row:
        statement += "</td></tr>"

    # Second row: description of endomorphism algebra factors (this is the first row if ring=None)
    statement += r"<tr><td>\(\End (J_{%s}) \otimes \Q \)</td><td>\(\simeq\)</td><td>" % field
    # In the case of only one factor we either get a number field or a
    # quaternion algebra:
    if factorsQQ_number == 1:
        # First we deal with the number field case,
        # in which we have set the discriminant to be -1
        if factorsQQ[0][2] == -1:
            # Prettify if labels available, otherwise return defining polynomial:
            if factorsQQ_pretty:
                statement += "<a href=%s>%s</a>" % (url_for(
                    "number_fields.by_label",
                    label=factorsQQ[0][0]), factorsQQ_pretty[0])
            else:
                statement += r"the number field with defining polynomial \(%s\)" % intlist_to_poly(
                    factorsQQ[0][1])
            # Detect CM by presence of a quartic polynomial:
            if len(factorsQQ[0][1]) == 5:
                statement += " (CM)"
                # TODO: Get the following line to work
                #statement += " ({{ KNOWL('ag.complex_multiplication', title='CM') }})"
        # Up next is the case of a matrix ring (trivial disciminant), with
        # labels and full prettification always available:
        elif factorsQQ[0][2] == 1:
            statement += r"\(\mathrm{M}_2(\)<a href=%s>%s</a>\()\)" % (url_for(
                "number_fields.by_label",
                label=factorsQQ[0][0]), factorsQQ_pretty[0])
        # And finally we deal with quaternion algebras over the rationals:
        else:
            statement += (
                "the quaternion algebra over <a href=%s>%s</a> of discriminant %s"
                % (url_for("number_fields.by_label", label=factorsQQ[0][0]),
                   factorsQQ_pretty[0], factorsQQ[0][2]))
    # If there are two factors, then we get two at most quadratic fields:
    else:
        statement += (r"<a href=%s>%s</a> \(\times\) <a href=%s>%s</a>" %
                      (url_for("number_fields.by_label",
                               label=factorsQQ[0][0]), factorsQQ_pretty[0],
                       url_for("number_fields.by_label",
                               label=factorsQQ[1][0]), factorsQQ_pretty[1]))
    # End of second row:
    statement += "</td></tr>"

    # Third row: description of algebra tensored with RR (this is the second row if ring=None)
    statement += r"<tr><td>\(\End (J_{%s}) \otimes \R\)</td><td>\(\simeq\)</td> <td>\(%s\)</td></tr>" % (
        field, factorsRR_raw_to_pretty(factorsRR))

    # End of statement:
    statement += "</table>"
    return statement
Esempio n. 47
0
    def make_object(self, curve, endo, tama, ratpts, is_curve):
        from lmfdb.genus2_curves.main import url_for_curve_label

        # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary
        # most of the data from the database gets polished/formatted before we put it in the data dictionary
        data = self.data = {}

        data['label'] = curve['label'] if is_curve else curve['class']
        data['slabel'] = data['label'].split('.')

        # set attributes common to curves and isogeny classes here
        data['Lhash'] = curve['Lhash']
        data['cond'] = ZZ(curve['cond'])
        data['cond_factor_latex'] = web_latex(factor(int(data['cond'])))
        data['analytic_rank'] = ZZ(curve['analytic_rank'])
        data['st_group'] = curve['st_group']
        data['st_group_link'] = st_link_by_name(1,4,data['st_group'])
        data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg'])
        data['is_gl2_type'] = curve['is_gl2_type']
        data['root_number'] = ZZ(curve['root_number'])
        data['lfunc_url'] = url_for("l_functions.l_function_genus2_page", cond=data['slabel'][0], x=data['slabel'][1])
        data['bad_lfactors'] = literal_eval(curve['bad_lfactors'])
        data['bad_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['bad_lfactors']]

        if is_curve:
            # invariants specific to curve
            data['class'] = curve['class']
            data['abs_disc'] = ZZ(curve['disc_key'][3:]) # use disc_key rather than abs_disc (will work when abs_disc > 2^63)
            data['disc'] = curve['disc_sign'] * curve['abs_disc']
            data['min_eqn'] = literal_eval(curve['eqn'])
            data['min_eqn_display'] = list_to_min_eqn(data['min_eqn'])
            data['disc_factor_latex'] = web_latex(factor(data['disc']))
            data['igusa_clebsch'] = [ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])]
            data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])]
            data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])]
            data['igusa_clebsch_factor_latex'] = [web_latex(zfactor(i)) for i in data['igusa_clebsch']]
            data['igusa_factor_latex'] = [ web_latex(zfactor(j)) for j in data['igusa'] ]
            data['aut_grp_id'] = curve['aut_grp_id']
            data['geom_aut_grp_id'] = curve['geom_aut_grp_id']
            data['num_rat_wpts'] = ZZ(curve['num_rat_wpts'])
            data['two_selmer_rank'] = ZZ(curve['two_selmer_rank'])
            data['has_square_sha'] = "square" if curve['has_square_sha'] else "twice a square"
            P = curve['non_solvable_places']
            if len(P):
                sz = "except over "
                sz += ", ".join([QpName(p) for p in P])
                last = " and"
                if len(P) > 2:
                    last = ", and"
                sz = last.join(sz.rsplit(",",1))
            else:
                sz = "everywhere"
            data['non_solvable_places'] = sz
            data['torsion_order'] = curve['torsion_order']
            data['torsion_factors'] = [ ZZ(a) for a in literal_eval(curve['torsion_subgroup']) ]
            if len(data['torsion_factors']) == 0:
                data['torsion_subgroup'] = '\mathrm{trivial}'
            else:
                data['torsion_subgroup'] = ' \\times '.join([ '\Z/{%s}\Z' % n for n in data['torsion_factors'] ])
            data['end_ring_base'] = endo['ring_base']
            data['end_ring_geom'] = endo['ring_geom']
            data['tama'] = ''
            for i in range(tama.count()):
            	item = tama.next()
            	if item['tamagawa_number'] > 0:
            		tamgwnr = str(item['tamagawa_number'])
            	else:
            		tamgwnr = 'N/A'
            	data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + ')'
            	if (i+1 < tama.count()):
            		data['tama'] += ', '
            if ratpts:
                if len(ratpts['rat_pts']):
                    data['rat_pts'] = ',  '.join(web_latex('(' +' : '.join(P) + ')') for P in ratpts['rat_pts'])
                data['rat_pts_v'] =  2 if ratpts['rat_pts_v'] else 1
                # data['mw_rank'] = ratpts['mw_rank']
                # data['mw_rank_v'] = ratpts['mw_rank_v']
            else:
                data['rat_pts_v'] = 0
            if curve['two_torsion_field'][0]:
                data['two_torsion_field_knowl'] = nf_display_knowl (curve['two_torsion_field'][0], getDBConnection(), field_pretty(curve['two_torsion_field'][0]))
            else:
                t = curve['two_torsion_field']
                data['two_torsion_field_knowl'] = """splitting field of \(%s\) with Galois group %s"""%(intlist_to_poly(t[1]),group_display_knowl(t[2][0],t[2][1],getDBConnection()))
        else:
            # invariants specific to isogeny class
            curves_data = g2c_db_curves().find({"class" : curve['class']},{'_id':int(0),'label':int(1),'eqn':int(1),'disc_key':int(1)}).sort([("disc_key", ASCENDING), ("label", ASCENDING)])
            if not curves_data:
                raise KeyError("No curves found in database for isogeny class %s of genus 2 curve %s." %(curve['class'],curve['label']))
            data['curves'] = [ {"label" : c['label'], "equation_formatted" : list_to_min_eqn(literal_eval(c['eqn'])), "url": url_for_curve_label(c['label'])} for c in curves_data ]
            lfunc_data = g2c_db_lfunction_by_hash(curve['Lhash'])
            if not lfunc_data:
                raise KeyError("No Lfunction found in database for isogeny class of genus 2 curve %s." %curve['label'])
            if lfunc_data and lfunc_data.get('euler_factors'):
                data['good_lfactors'] = [[nth_prime(n+1),lfunc_data['euler_factors'][n]] for n in range(len(lfunc_data['euler_factors'])) if nth_prime(n+1) < 30 and (data['cond'] % nth_prime(n+1))]
                data['good_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['good_lfactors']]
        # Endomorphism data over QQ:
        data['gl2_statement_base'] = gl2_statement_base(endo['factorsRR_base'], r'\(\Q\)')
        data['factorsQQ_base'] = endo['factorsQQ_base']
        data['factorsRR_base'] = endo['factorsRR_base']
        data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \
            end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None)

        # Field over which all endomorphisms are defined
        data['end_field_label'] = endo['fod_label']
        data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs'])
        data['end_field_statement'] = end_field_statement(data['end_field_label'], data['end_field_poly'])
        
        # Endomorphism data over QQbar:
        data['factorsQQ_geom'] = endo['factorsQQ_geom']
        data['factorsRR_geom'] = endo['factorsRR_geom']
        if data['end_field_label'] != '1.1.1.1':
            data['gl2_statement_geom'] = gl2_statement_base(data['factorsRR_geom'], r'\(\overline{\Q}\)')
            data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \
                end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None)
        data['real_geom_end_alg_name'] = end_alg_name(curve['real_geom_end_alg'])

        # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant):
        if is_curve:
            data['end_lattice'] = (endo['lattice'])[1:-1]
            if data['end_lattice']:
                data['end_lattice_statement'] = end_lattice_statement(data['end_lattice'])

        # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple)
        data['is_simple_geom'] = endo['is_simple_geom']
        data['split_field_label'] = endo['spl_fod_label']
        data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs'])
        data['split_field_statement'] = split_field_statement(data['is_simple_geom'], data['split_field_label'], data['split_field_poly'])

        # Elliptic curve factors for non-simple Jacobians
        if not data['is_simple_geom']:
            data['split_coeffs'] = endo['spl_facs_coeffs']
            if 'spl_facs_labels' in endo and len(endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']):
                data['split_labels'] = endo['spl_facs_labels']
            data['split_condnorms'] = endo['spl_facs_condnorms']
            data['split_statement'] = split_statement(data['split_coeffs'], data.get('split_labels'), data['split_condnorms'])

        # Properties
        self.properties = properties = [('Label', data['label'])]
        if is_curve:
            self.plot = encode_plot(eqn_list_to_curve_plot(data['min_eqn'], data['rat_pts'].split(',') if 'rat_pts' in data else []))
            plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(self.plot)

            properties += [
                (None, plot_link),
                ('Conductor',str(data['cond'])),
                ('Discriminant', str(data['disc'])),
                ]
        properties += [
            ('Sato-Tate group', data['st_group_link']),
            ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)', '\(%s\)' % data['real_geom_end_alg_name']),
            ('\(\\overline{\\Q}\)-simple', bool_pretty(data['is_simple_geom'])),
            ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])),
            ]

        # Friends
        self.friends = friends = [('L-function', data['lfunc_url'])]
        if is_curve:
            friends.append(('Isogeny class %s.%s' % (data['slabel'][0], data['slabel'][1]), url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1])))
        for friend in g2c_db_lfunction_instances().find({'Lhash':data['Lhash']},{'_id':False,'url':True}):
            if 'url' in friend:
                add_friend (friends, lfunction_friend_from_url(friend['url']))
            if 'urls' in friend:
                for url in friends['urls']:
                    add_friend (friends, lfunction_friend_from_url(friend['url']))
        if 'split_labels' in data:
            for friend_label in data['split_labels']:
                if is_curve:
                    add_friend (friends, ("Elliptic curve " + friend_label, url_for_ec(friend_label)))
                else:
                    add_friend (friends, ("EC isogeny class " + ec_label_class(friend_label), url_for_ec_class(friend_label)))
        if is_curve:
            friends.append(('Twists', url_for(".index_Q", g20 = str(data['g2'][0]), g21 = str(data['g2'][1]), g22 = str(data['g2'][2]))))

        # Breadcrumbs
        self.bread = bread = [
             ('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('%s' % data['slabel'][0], url_for(".by_conductor", cond=data['slabel'][0])),
             ('%s' % data['slabel'][1], url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))
             ]
        if is_curve:
            bread += [
                ('%s' % data['slabel'][2], url_for(".by_url_isogeny_class_discriminant", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2])),
                ('%s' % data['slabel'][3], url_for(".by_url_curve_label", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2], num=data['slabel'][3]))
                ]

        # Title
        self.title = "Genus 2 " + ("Curve " if is_curve else "Isogeny Class ") + data['label']

        # Code snippets (only for curves)
        if not is_curve:
            return
        self.code = code = {}
        code['show'] = {'sage':'','magma':''} # use default show names
        code['curve'] = {'sage':'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))'%(data['min_eqn'][0],data['min_eqn'][1]),
                              'magma':'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'%(data['min_eqn'][0],data['min_eqn'][1])}
        if data['abs_disc'] % 4096 == 0:
            ind2 = [a[0] for a in data['bad_lfactors']].index(2)
            bad2 = data['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation('+str(data['cond'])+',2),R!'+str(bad2)+'>*]'
        else:
            magma_cond_option = ''
        code['cond'] = {'magma': 'Conductor(LSeries(C%s)); Factorization($1);'% magma_cond_option}
        code['disc'] = {'magma':'Discriminant(C); Factorization(Integers()!$1);'}
        code['igusa_clebsch'] = {'sage':'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
                                      'magma':'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];'}
        code['igusa'] = {'magma':'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];'}
        code['g2'] = {'magma':'G2Invariants(C);'}
        code['aut'] = {'magma':'AutomorphismGroup(C); IdentifyGroup($1);'}
        code['autQbar'] = {'magma':'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'}
        code['num_rat_wpts'] = {'magma':'#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'}
        if ratpts:
            code['rat_pts'] = {'magma': '[' + ','.join(["C![%s,%s,%s]"%(p[0],p[1],p[2]) for p in ratpts['rat_pts']]) + '];' }
        code['two_selmer'] = {'magma':'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'}
        code['has_square_sha'] = {'magma':'HasSquareSha(Jacobian(C));'}
        code['locally_solvable'] = {'magma':'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'}
        code['torsion_subgroup'] = {'magma':'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'}
Esempio n. 48
0
def quad_field_knowl(disc):
    r = 2 if disc > 0 else 0
    field_label = "2.%d.%d.1" % (r, abs(disc))
    field_name = field_pretty(field_label)
    return nf_display_knowl(field_label, field_name)
Esempio n. 49
0
        return redirect(url_for("ecnf.index"))

def url_for_label(label):
    if label == 'random':
        return url_for(".random")
    nf, cond_label, iso_label, number = split_full_label(label.strip())
    return url_for(".show_ecnf", nf=nf, conductor_label=cond_label, class_label=iso_label, number=number)

@search_wrap(template="ecnf-search-results.html",
             table=db.ec_nfcurves,
             title='Elliptic curve search results',
             err_title='Elliptic curve search input error',
             shortcuts={'jump':elliptic_curve_jump,
                        'download':download_search},
             cleaners={'numb':lambda e: str(e['number']),
                       'field_knowl':lambda e: nf_display_knowl(e['field_label'], field_pretty(e['field_label']))},
             url_for_label=url_for_label,
             learnmore=learnmore_list,
             bread=lambda:[('Elliptic curves', url_for(".index")), ('Search results', '.')])
def elliptic_curve_search(info, query):
    parse_nf_string(info,query,'field',name="base number field",qfield='field_label')
    if query.get('field_label') == '1.1.1.1':
        return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301)

    parse_ints(info,query,'conductor_norm')
    parse_noop(info,query,'conductor_label')
    parse_ints(info,query,'rank')
    parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order')
    parse_bracketed_posints(info,query,'torsion_structure',maxlength=2)
    if 'torsion_structure' in query and not 'torsion_order' in query:
        t_o = 1
Esempio n. 50
0
def set_info_for_web_newform(level=None,
                             weight=None,
                             character=None,
                             label=None,
                             **kwds):
    r"""
    Set the info for on modular form.

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

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

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

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

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

    s = 'L-Function '
    if character:
        s += newform_label(level, weight, character, label)
    else:
        s += newform_label(level, weight, 1, label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for('emf.render_elliptic_modular_forms',
                         level=level,
                         weight=weight,
                         character=character,
                         label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_available_prec()
    return info
Esempio n. 51
0
def index():
    #    if 'jump' in request.args:
    #        return show_ecnf1(request.args['label'])
    if len(request.args) > 0:
        return elliptic_curve_search(to_dict(request.args))
    bread = get_bread()

    # the dict data will hold additional information to be displayed on
    # the main browse and search page

    data = {}

    # data['fields'] holds data for a sample of number fields of different
    # signatures for a general browse:

    ecnfstats = db_ecnfstats()
    fields_by_deg = ecnfstats.find_one({'_id': 'fields_by_degree'})
    fields_by_sig = ecnfstats.find_one({'_id': 'fields_by_signature'})
    data['fields'] = []
    # Rationals
    data['fields'].append([
        'the rational field',
        (('1.1.1.1', [url_for('ec.rational_elliptic_curves'), '$\Q$']), )
    ])

    # Real quadratics (sample)
    rqfs = ['2.2.{}.1'.format(d) for d in [5, 89, 229, 497]]
    niqfs = len(fields_by_sig['0,1'])
    nrqfs = len(fields_by_sig['2,0'])
    data['fields'].append([
        '{} real quadratic fields, including'.format(nrqfs),
        ((nf, [url_for('.show_ecnf1', nf=nf),
               field_pretty(nf)]) for nf in rqfs)
    ])

    # Imaginary quadratics (sample)
    iqfs = ['2.0.{}.1'.format(d) for d in [4, 8, 3, 7, 11]]
    data['fields'].append([
        '{} imaginary quadratic fields, including'.format(niqfs),
        ((nf, [url_for('.show_ecnf1', nf=nf),
               field_pretty(nf)]) for nf in iqfs)
    ])

    # Cubics (sample)
    cubics = ['3.1.23.1'] + ['3.3.{}.1'.format(d) for d in [49, 148, 1957]]
    ncubics = len(fields_by_deg['3'])
    data['fields'].append([
        '{} cubic fields, including'.format(ncubics),
        ((nf, [url_for('.show_ecnf1', nf=nf),
               field_pretty(nf)]) for nf in cubics)
    ])

    # Quartics (sample)
    quartics = ['4.4.{}.1'.format(d) for d in [725, 2777, 9909, 19821]]
    nquartics = len(fields_by_deg['4'])
    data['fields'].append([
        '{} totally real quartic fields, including'.format(nquartics),
        ((nf, [url_for('.show_ecnf1', nf=nf),
               field_pretty(nf)]) for nf in quartics)
    ])

    # Quintics (sample)
    quintics = [
        '5.5.{}.1'.format(d) for d in [14641, 24217, 36497, 38569, 65657]
    ]
    nquintics = len(fields_by_deg['5'])
    data['fields'].append([
        '{} totally real quintic fields, including'.format(nquintics),
        ((nf, [url_for('.show_ecnf1', nf=nf),
               field_pretty(nf)]) for nf in quintics)
    ])

    # Sextics (sample)
    sextics = [
        '6.6.{}.1'.format(d) for d in [300125, 371293, 434581, 453789, 485125]
    ]
    nsextics = len(fields_by_deg['6'])
    data['fields'].append([
        '{} totally real sextic fields, including'.format(nsextics),
        ((nf, [url_for('.show_ecnf1', nf=nf),
               field_pretty(nf)]) for nf in sextics)
    ])

    data['degrees'] = sorted(
        [int(d) for d in fields_by_deg.keys() if d != '_id'])

    # data['highlights'] holds data (URL and descriptive text) for a
    # sample of elliptic curves with interesting features:

    data['highlights'] = []
    data['highlights'].append([
        'A curve with $C_3\\times C_3$ torsion',
        url_for('.show_ecnf',
                nf='2.0.3.1',
                class_label='a',
                conductor_label='2268.36.18',
                number=int(1))
    ])
    data['highlights'].append([
        'A curve with $C_4\\times C_4$ torsion',
        url_for('.show_ecnf',
                nf='2.0.4.1',
                class_label='b',
                conductor_label='5525.870.5',
                number=int(9))
    ])
    data['highlights'].append([
        'A curve with CM by $\\sqrt{-267}$',
        url_for('.show_ecnf',
                nf='2.2.89.1',
                class_label='a',
                conductor_label='81.1',
                number=int(1))
    ])
    data['highlights'].append([
        'An isogeny class with isogenies of degree $3$ and $89$ (and $267$)',
        url_for('.show_ecnf_isoclass',
                nf='2.2.89.1',
                class_label='a',
                conductor_label='81.1')
    ])
    data['highlights'].append([
        'A curve with everywhere good reduction, but no global minimal model',
        url_for('.show_ecnf',
                nf='2.2.229.1',
                class_label='a',
                conductor_label='1.1',
                number=int(1))
    ])

    return render_template("ecnf-index.html",
                           title="Elliptic Curves over Number Fields",
                           data=data,
                           bread=bread,
                           learnmore=learnmore_list_remove('Completeness'))
Esempio n. 52
0
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds):
    r"""
    Set the info for on modular form.

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

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

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

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

    s = 'L-Function '
    if character:
        s = s + str(level) + '.' + str(weight) + '.' + str(character) + str(label)
    else:
        s = s + str(level) + '.' + str(weight) + str(label)
    # url =
    # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s"
    # %(level,weight,character,label,0)
    url = '/L' + url_for(
        'emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label)
    if WNF.coefficient_field_degree > 1:
        for h in range(WNF.coefficient_field_degree):
            s0 = s + ".{0}".format(h)
            url0 = url + "{0}/".format(h)
            friends.append((s0, url0))
    else:
        friends.append((s, url))
    # if there is an elliptic curve over Q associated to self we also list that
    if WNF.weight == 2 and WNF.coefficient_field_degree == 1:
        llabel = str(level) + '.' + label
        s = 'Elliptic curve isogeny class ' + llabel
        url = '/EllipticCurve/Q/' + llabel
        friends.append((s, url))
    info['properties2'] = properties2
    info['friends'] = friends
    info['max_cn'] = WNF.max_cn()
    return info
Esempio n. 53
0
def render_sample_page(family, sam, args, bread):
    info = { 'args': to_dict(args), 'sam': sam, 'latex': latex, 'type':sam.type(), 'name':sam.name(), 'full_name': sam.full_name(), 'weight':sam.weight(), 'fdeg':sam.degree_of_field(), 'is_eigenform':sam.is_eigenform(), 'field_poly': sam.field_poly()}
    if sam.is_integral() != None:
        info['is_integral'] = sam.is_integral()
    if 'Sp4Z' in sam.collection():
        info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0)
    if 'Sp4Z_2' in sam.collection():
        info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2)
    info['space'] = '$'+family.latex_name.replace('k', '{' + str(sam.weight()) + '}')+'$'
    if 'space_url' in info:
        bread.append((info['space'], info['space_url']))
    info['space_href'] = '<a href="%s">%s</d>'%(info['space_url'],info['space']) if 'space_url' in info else info['space']
    if info['field_poly'].disc() < 10**10:
        label = poly_to_field_label(info['field_poly'])
        if label:
            info['field_label'] = label
            info['field_url'] = url_for('number_fields.by_label', label=label)
            info['field_href'] = '<a href="%s">%s</a>'%(info['field_url'], field_pretty(label))
    
    bread.append((info['name'], ''))
    title='Siegel modular forms sample ' + info['full_name']
    properties = [('Space', info['space_href']),
                  ('Name', info['name']),
                  ('Type', '<br>'.join(info['type'].split(','))),
                  ('Weight', str(info['weight'])),
                  ('Hecke eigenform', str(info['is_eigenform'])),
                  ('Field degree', str(info['fdeg']))]
    try:
        evs_to_show = parse_ints_to_list_flash(args.get('ev_index'), 'list of $l$')
        fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'), 'list of $\\det(F)$')
    except ValueError:
        evs_to_show = []
        fcs_to_show = []
    info['evs_to_show'] = sorted([n for n in (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10])])
    info['fcs_to_show'] = sorted([n for n in (fcs_to_show if len(fcs_to_show) else sam.available_Fourier_coefficients()[1:6])])
    info['evs_avail'] = [n for n in sam.available_eigenvalues()]
    info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()]

    # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant
    # otherwise sage may not even be able to factor the discriminant
    info['field'] = sam.field()
    if info['field_poly'].disc() < 10**80:
        null_ideal = sam.field().ring_of_integers().ideal(0)
        info['modulus'] = null_ideal
        modulus = args.get('modulus','').strip()
        m = 0
        if modulus:
            try:
                O = sam.field().ring_of_integers()
                m = O.ideal([O(str(b)) for b in modulus.split(',')])
            except Exception:
                info['error'] = True
                flash_error("Unable to construct modulus ideal from specified generators %s.", modulus)
            if m == 1:
                info['error'] = True
                flash_error("The ideal %s is the unit ideal, please specify a different modulus.", '('+modulus+')')
                m = 0
        info['modulus'] = m
        # Hack to reduce polynomials and to handle non integral stuff
        def redc(c):
            return m.reduce(c*c.denominator())/m.reduce(c.denominator())
        def redp(f):
            c = f.dict()
            return f.parent()(dict((e,redc(c[e])) for e in c))
        def safe_reduce(f):
            if not m:
                return latex(f)
            try:
                if f in sam.field():
                    return latex(redc(f))
                else:
                    return latex(redp(f))
            except ZeroDivisionError:
                return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}'
        info['reduce'] = safe_reduce
    else:
        info['reduce'] = latex
        
    # check that explicit formula is not ridiculously big
    if sam.explicit_formula():
        info['explicit_formula_bytes'] = len(sam.explicit_formula())
        if len(sam.explicit_formula()) < 100000:
            info['explicit_formula'] = sam.explicit_formula()
        
    return render_template("ModularForm_GSp4_Q_sample.html", title=title, bread=bread, properties2=properties, info=info)
Esempio n. 54
0
def render_sample_page(family, sam, args, bread):
    info = {
        'args': to_dict(args),
        'sam': sam,
        'latex': latex,
        'type': sam.type(),
        'name': sam.name(),
        'full_name': sam.full_name(),
        'weight': sam.weight(),
        'fdeg': sam.degree_of_field(),
        'is_eigenform': sam.is_eigenform(),
        'field_poly': sam.field_poly()
    }
    if sam.is_integral() != None:
        info['is_integral'] = sam.is_integral()
    if 'Sp4Z' in sam.collection():
        info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0)
    if 'Sp4Z_2' in sam.collection():
        info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2)
    info['space'] = '$' + family.latex_name.replace(
        'k', '{' + str(sam.weight()) + '}') + '$'
    if 'space_url' in info:
        bread.append((info['space'], info['space_url']))
    info['space_href'] = '<a href="%s">%s</d>' % (
        info['space_url'],
        info['space']) if 'space_url' in info else info['space']
    if info['field_poly'].disc() < 10**10:
        label = poly_to_field_label(info['field_poly'])
        if label:
            info['field_label'] = label
            info['field_url'] = url_for('number_fields.by_label', label=label)
            info['field_href'] = '<a href="%s">%s</a>' % (info['field_url'],
                                                          field_pretty(label))

    bread.append((info['name'], ''))
    title = 'Siegel modular forms sample ' + info['full_name']
    properties = [('Space', info['space_href']), ('Name', info['name']),
                  ('Type', '<br>'.join(info['type'].split(','))),
                  ('Weight', str(info['weight'])),
                  ('Hecke eigenform', str(info['is_eigenform'])),
                  ('Field degree', str(info['fdeg']))]
    try:
        evs_to_show = parse_ints_to_list_flash(args.get('ev_index'),
                                               'list of $l$')
        fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'),
                                               'list of $\\det(F)$')
    except ValueError:
        evs_to_show = []
        fcs_to_show = []
    info['evs_to_show'] = sorted([
        n for n in
        (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10])
    ])
    info['fcs_to_show'] = sorted([
        n for n in (fcs_to_show if len(fcs_to_show) else sam.
                    available_Fourier_coefficients()[1:6])
    ])
    info['evs_avail'] = [n for n in sam.available_eigenvalues()]
    info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()]

    # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant
    # otherwise sage may not even be able to factor the discriminant
    info['field'] = sam.field()
    if info['field_poly'].disc() < 10**80:
        null_ideal = sam.field().ring_of_integers().ideal(0)
        info['modulus'] = null_ideal
        modulus = args.get('modulus', '').strip()
        m = 0
        if modulus:
            try:
                O = sam.field().ring_of_integers()
                m = O.ideal([O(str(b)) for b in modulus.split(',')])
            except Exception:
                info['error'] = True
                flash_error(
                    "Unable to construct modulus ideal from specified generators %s.",
                    modulus)
            if m == 1:
                info['error'] = True
                flash_error(
                    "The ideal %s is the unit ideal, please specify a different modulus.",
                    '(' + modulus + ')')
                m = 0
        info['modulus'] = m

        # Hack to reduce polynomials and to handle non integral stuff
        def redc(c):
            return m.reduce(c * c.denominator()) / m.reduce(c.denominator())

        def redp(f):
            c = f.dict()
            return f.parent()(dict((e, redc(c[e])) for e in c))

        def safe_reduce(f):
            if not m:
                return latex(f)
            try:
                if f in sam.field():
                    return latex(redc(f))
                else:
                    return latex(redp(f))
            except ZeroDivisionError:
                return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}'

        info['reduce'] = safe_reduce
    else:
        info['reduce'] = latex

    # check that explicit formula is not ridiculously big
    if sam.explicit_formula():
        info['explicit_formula_bytes'] = len(sam.explicit_formula())
        if len(sam.explicit_formula()) < 100000:
            info['explicit_formula'] = sam.explicit_formula()

    return render_template("ModularForm_GSp4_Q_sample.html",
                           title=title,
                           bread=bread,
                           properties2=properties,
                           info=info)
Esempio n. 55
0
File: main.py Progetto: LMFDB/lmfdb
    try:
        nf, cond_label, iso_label, number = split_full_label(label.strip())
    except ValueError:
        info['err'] = ''
        return redirect(url_for("ecnf.index"))

    return redirect(url_for(".show_ecnf", nf=nf, conductor_label=cond_label, class_label=iso_label, number=number), 301)

@search_wrap(template="ecnf-search-results.html",
             table=db.ec_nfcurves,
             title='Elliptic Curve Search Results',
             err_title='Elliptic Curve Search Input Error',
             shortcuts={'jump':elliptic_curve_jump,
                        'download':download_search},
             cleaners={'numb':lambda e: str(e['number']),
                       'field_knowl':lambda e: nf_display_knowl(e['field_label'], field_pretty(e['field_label']))},
             bread=lambda:[('Elliptic Curves', url_for(".index")), ('Search Results', '.')],
             credit=lambda:ecnf_credit)
def elliptic_curve_search(info, query):
    parse_nf_string(info,query,'field',name="base number field",qfield='field_label')
    if query.get('field_label') == '1.1.1.1':
        return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301)

    parse_ints(info,query,'conductor_norm')
    parse_noop(info,query,'conductor_label')
    parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order')
    parse_bracketed_posints(info,query,'torsion_structure',maxlength=2)
    if 'torsion_structure' in query and not 'torsion_order' in query:
        query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')
Esempio n. 56
0
    def make_object(self, curve, endo, tama, ratpts, is_curve):
        from lmfdb.genus2_curves.main import url_for_curve_label

        # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary
        # most of the data from the database gets polished/formatted before we put it in the data dictionary
        data = self.data = {}

        data['label'] = curve['label'] if is_curve else curve['class']
        data['slabel'] = data['label'].split('.')

        # set attributes common to curves and isogeny classes here
        data['Lhash'] = str(curve['Lhash'])
        data['cond'] = ZZ(curve['cond'])
        data['cond_factor_latex'] = web_latex(factor(int(
            data['cond']))).replace(r"-1 \cdot", "-")
        data['analytic_rank'] = ZZ(curve['analytic_rank'])
        data['mw_rank'] = ZZ(0) if curve.get('mw_rank') is None else ZZ(
            curve['mw_rank'])  # 0 will be marked as a lower bound
        data['mw_rank_proved'] = curve['mw_rank_proved']
        data['analytic_rank_proved'] = curve['analytic_rank_proved']
        data['hasse_weil_proved'] = curve['hasse_weil_proved']
        data['st_group'] = curve['st_group']
        data['st_group_link'] = st_link_by_name(1, 4, data['st_group'])
        data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg'])
        data['is_gl2_type'] = curve['is_gl2_type']
        data['root_number'] = ZZ(curve['root_number'])
        data['lfunc_url'] = url_for("l_functions.l_function_genus2_page",
                                    cond=data['slabel'][0],
                                    x=data['slabel'][1])
        data['bad_lfactors'] = literal_eval(curve['bad_lfactors'])
        data['bad_lfactors_pretty'] = [(c[0],
                                        list_to_factored_poly_otherorder(c[1]))
                                       for c in data['bad_lfactors']]
        if is_curve:
            # invariants specific to curve
            data['class'] = curve['class']
            data['abs_disc'] = ZZ(curve['abs_disc'])
            data['disc'] = curve['disc_sign'] * data['abs_disc']
            data['min_eqn'] = literal_eval(curve['eqn'])
            data['min_eqn_display'] = min_eqns_pretty(data['min_eqn'])
            data['disc_factor_latex'] = web_latex(factor(
                data['disc'])).replace(r"-1 \cdot", "-")
            data['igusa_clebsch'] = [
                ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])
            ]
            data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])]
            data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])]
            data['igusa_clebsch_factor_latex'] = [
                web_latex(zfactor(i)).replace(r"-1 \cdot", "-")
                for i in data['igusa_clebsch']
            ]
            data['igusa_factor_latex'] = [
                web_latex(zfactor(j)).replace(r"-1 \cdot", "-")
                for j in data['igusa']
            ]
            data['aut_grp'] = small_group_label_display_knowl(
                '%d.%d' % tuple(literal_eval(curve['aut_grp_id'])))
            data['geom_aut_grp'] = small_group_label_display_knowl(
                '%d.%d' % tuple(literal_eval(curve['geom_aut_grp_id'])))
            data['num_rat_wpts'] = ZZ(curve['num_rat_wpts'])
            data['has_square_sha'] = "square" if curve[
                'has_square_sha'] else "twice a square"
            P = curve['non_solvable_places']
            if len(P):
                sz = "except over "
                sz += ", ".join([QpName(p) for p in P])
                last = " and"
                if len(P) > 2:
                    last = ", and"
                sz = last.join(sz.rsplit(",", 1))
            else:
                sz = "everywhere"
            data['non_solvable_places'] = sz
            data['two_selmer_rank'] = ZZ(curve['two_selmer_rank'])
            data['torsion_order'] = curve['torsion_order']

            data['end_ring_base'] = endo['ring_base']
            data['end_ring_geom'] = endo['ring_geom']
            data['real_period'] = decimal_pretty(str(curve['real_period']))
            data['regulator'] = decimal_pretty(
                str(curve['regulator']
                    )) if curve['regulator'] > -0.5 else 'unknown'
            if data['mw_rank'] == 0 and data['mw_rank_proved']:
                data['regulator'] = '1'  # display an exact 1 when we know this

            data['tamagawa_product'] = ZZ(
                curve['tamagawa_product']) if curve.get(
                    'tamagawa_product') else 0
            data['analytic_sha'] = ZZ(
                curve['analytic_sha']) if curve.get('analytic_sha') else 0
            data['leading_coeff'] = decimal_pretty(
                str(curve['leading_coeff']
                    )) if curve['leading_coeff'] else 'unknown'

            data['rat_pts'] = ratpts['rat_pts']
            data['rat_pts_v'] = ratpts['rat_pts_v']
            data['rat_pts_table'] = ratpts_table(ratpts['rat_pts'],
                                                 ratpts['rat_pts_v'])

            data['mw_gens_v'] = ratpts['mw_gens_v']
            lower = len([n for n in ratpts['mw_invs'] if n == 0])
            upper = data['analytic_rank']
            invs = ratpts[
                'mw_invs'] if data['mw_gens_v'] or lower >= upper else [
                    0 for n in range(upper - lower)
                ] + ratpts['mw_invs']
            if len(invs) == 0:
                data['mw_group'] = 'trivial'
            else:
                data['mw_group'] = r'\(' + r' \times '.join([
                    (r'\Z' if n == 0 else r'\Z/{%s}\Z' % n) for n in invs
                ]) + r'\)'
            if lower >= upper:
                data['mw_gens_table'] = mw_gens_table(ratpts['mw_invs'],
                                                      ratpts['mw_gens'],
                                                      ratpts['mw_heights'],
                                                      ratpts['rat_pts'])

            if curve['two_torsion_field'][0]:
                data['two_torsion_field_knowl'] = nf_display_knowl(
                    curve['two_torsion_field'][0],
                    field_pretty(curve['two_torsion_field'][0]))
            else:
                t = curve['two_torsion_field']
                data[
                    'two_torsion_field_knowl'] = r"splitting field of \(%s\) with Galois group %s" % (
                        intlist_to_poly(
                            t[1]), group_display_knowl(t[2][0], t[2][1]))

            tamalist = [[item['p'], item['tamagawa_number']] for item in tama]
            data['local_table'] = local_table(data['abs_disc'], data['cond'],
                                              tamalist,
                                              data['bad_lfactors_pretty'])

        else:
            # invariants specific to isogeny class
            curves_data = list(
                db.g2c_curves.search({"class": curve['class']},
                                     ['label', 'eqn']))
            if not curves_data:
                raise KeyError(
                    "No curves found in database for isogeny class %s of genus 2 curve %s."
                    % (curve['class'], curve['label']))
            data['curves'] = [{
                "label":
                c['label'],
                "equation_formatted":
                min_eqn_pretty(literal_eval(c['eqn'])),
                "url":
                url_for_curve_label(c['label'])
            } for c in curves_data]
            lfunc_data = db.lfunc_lfunctions.lucky(
                {'Lhash': str(curve['Lhash'])})
            if not lfunc_data:
                raise KeyError(
                    "No Lfunction found in database for isogeny class of genus 2 curve %s."
                    % curve['label'])
            if lfunc_data and lfunc_data.get('euler_factors'):
                data['good_lfactors'] = [
                    [nth_prime(n + 1), lfunc_data['euler_factors'][n]]
                    for n in range(len(lfunc_data['euler_factors']))
                    if nth_prime(n + 1) < 30 and (data['cond'] %
                                                  nth_prime(n + 1))
                ]
                data['good_lfactors_pretty'] = [
                    (c[0], list_to_factored_poly_otherorder(c[1]))
                    for c in data['good_lfactors']
                ]

        # Endomorphism data over QQ:
        data['gl2_statement_base'] = gl2_statement_base(
            endo['factorsRR_base'], r'\(\Q\)')
        data['factorsQQ_base'] = endo['factorsQQ_base']
        data['factorsRR_base'] = endo['factorsRR_base']
        data['end_statement_base'] = (
            r"Endomorphism %s over \(\Q\):<br>" %
            ("ring" if is_curve else "algebra") +
            end_statement(data['factorsQQ_base'],
                          endo['factorsRR_base'],
                          ring=data['end_ring_base'] if is_curve else None))

        # Field over which all endomorphisms are defined
        data['end_field_label'] = endo['fod_label']
        data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs'])
        data['end_field_statement'] = end_field_statement(
            data['end_field_label'], data['end_field_poly'])

        # Endomorphism data over QQbar:
        data['factorsQQ_geom'] = endo['factorsQQ_geom']
        data['factorsRR_geom'] = endo['factorsRR_geom']
        if data['end_field_label'] != '1.1.1.1':
            data['gl2_statement_geom'] = gl2_statement_base(
                data['factorsRR_geom'], r'\(\overline{\Q}\)')
            data['end_statement_geom'] = (
                r"Endomorphism %s over \(\overline{\Q}\):" %
                ("ring" if is_curve else "algebra") + end_statement(
                    data['factorsQQ_geom'],
                    data['factorsRR_geom'],
                    field=r'\overline{\Q}',
                    ring=data['end_ring_geom'] if is_curve else None))
        data['real_geom_end_alg_name'] = real_geom_end_alg_name(
            curve['real_geom_end_alg'])
        data['geom_end_alg_name'] = geom_end_alg_name(curve['geom_end_alg'])

        # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant):
        if is_curve:
            data['end_lattice'] = (endo['lattice'])[1:-1]
            if data['end_lattice']:
                data['end_lattice_statement'] = end_lattice_statement(
                    data['end_lattice'])

        # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple)
        data['is_simple_geom'] = endo['is_simple_geom']
        data['split_field_label'] = endo['spl_fod_label']
        data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs'])
        data['split_field_statement'] = split_field_statement(
            data['is_simple_geom'], data['split_field_label'],
            data['split_field_poly'])

        # Elliptic curve factors for non-simple Jacobians
        if not data['is_simple_geom']:
            data['split_coeffs'] = endo['spl_facs_coeffs']
            if 'spl_facs_labels' in endo and len(
                    endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']):
                data['split_labels'] = endo['spl_facs_labels']
            data['split_condnorms'] = endo['spl_facs_condnorms']
            data['split_statement'] = split_statement(data['split_coeffs'],
                                                      data.get('split_labels'),
                                                      data['split_condnorms'])

        # Properties
        self.properties = properties = [('Label', data['label'])]
        if is_curve:
            plot_from_db = db.g2c_plots.lucky({"label": curve['label']})
            if (plot_from_db is None):
                self.plot = encode_plot(
                    eqn_list_to_curve_plot(
                        data['min_eqn'], ratpts['rat_pts'] if ratpts else []))
            else:
                self.plot = plot_from_db['plot']
            plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(
                self.plot)

            properties += [
                (None, plot_link),
                ('Conductor', str(data['cond'])),
                ('Discriminant', str(data['disc'])),
            ]
            if data['mw_rank_proved']:
                properties += [('Mordell-Weil group', data['mw_group'])]
        properties += [
            ('Sato-Tate group', data['st_group_link']),
            (r'\(\End(J_{\overline{\Q}}) \otimes \R\)',
             r'\(%s\)' % data['real_geom_end_alg_name']),
            (r'\(\End(J_{\overline{\Q}}) \otimes \Q\)',
             r'\(%s\)' % data['geom_end_alg_name']),
            (r'\(\overline{\Q}\)-simple', bool_pretty(data['is_simple_geom'])),
            (r'\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])),
        ]

        # Friends
        self.friends = friends = []
        if is_curve:
            friends.append(('Isogeny class %s.%s' %
                            (data['slabel'][0], data['slabel'][1]),
                            url_for(".by_url_isogeny_class_label",
                                    cond=data['slabel'][0],
                                    alpha=data['slabel'][1])))

        # first deal with EC
        ecs = []
        if 'split_labels' in data:
            for friend_label in data['split_labels']:
                if is_curve:
                    ecs.append(("Elliptic curve " + friend_label,
                                url_for_ec(friend_label)))
                else:
                    ecs.append(
                        ("Isogeny class " + ec_label_class(friend_label),
                         url_for_ec_class(friend_label)))

        ecs.sort(key=lambda x: key_for_numerically_sort(x[0]))

        # then again EC from lfun
        instances = []
        for elt in db.lfunc_instances.search(
            {
                'Lhash': data['Lhash'],
                'type': 'ECQP'
            }, 'url'):
            instances.extend(elt.split('|'))

        # and then the other isogeny friends
        instances.extend([
            elt['url'] for elt in get_instances_by_Lhash_and_trace_hash(
                data["Lhash"], 4, int(data["Lhash"]))
        ])
        exclude = {
            elt[1].rstrip('/').lstrip('/')
            for elt in self.friends if elt[1]
        }
        exclude.add(data['lfunc_url'].lstrip('/L/').rstrip('/'))
        for elt in ecs + names_and_urls(instances, exclude=exclude):
            # because of the splitting we must use G2C specific code
            add_friend(friends, elt)
        if is_curve:
            friends.append(('Twists',
                            url_for(".index_Q",
                                    g20=str(data['g2'][0]),
                                    g21=str(data['g2'][1]),
                                    g22=str(data['g2'][2]))))

        friends.append(('L-function', data['lfunc_url']))

        # Breadcrumbs
        self.bread = bread = [('Genus 2 Curves', url_for(".index")),
                              (r'$\Q$', url_for(".index_Q")),
                              ('%s' % data['slabel'][0],
                               url_for(".by_conductor",
                                       cond=data['slabel'][0])),
                              ('%s' % data['slabel'][1],
                               url_for(".by_url_isogeny_class_label",
                                       cond=data['slabel'][0],
                                       alpha=data['slabel'][1]))]
        if is_curve:
            bread += [('%s' % data['slabel'][2],
                       url_for(".by_url_isogeny_class_discriminant",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2])),
                      ('%s' % data['slabel'][3],
                       url_for(".by_url_curve_label",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2],
                               num=data['slabel'][3]))]

        # Title
        self.title = "Genus 2 " + ("Curve " if is_curve else
                                   "Isogeny Class ") + data['label']

        # Code snippets (only for curves)
        if not is_curve:
            return
        self.code = code = {}
        code['show'] = {'sage': '', 'magma': ''}  # use default show names
        f, h = fh = data['min_eqn']
        g = simplify_hyperelliptic(fh)
        code['curve'] = {
            'sage':
            'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s));'
            % (f, h),
            'magma':
            'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'
            % (f, h)
        }
        code['simple_curve'] = {
            'sage': 'X = HyperellipticCurve(R(%s))' % (g),
            'magma': 'X,pi:= SimplifiedModel(C);'
        }
        if data['abs_disc'] % 4096 == 0:
            ind2 = [a[0] for a in data['bad_lfactors']].index(2)
            bad2 = data['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation(' + str(
                data['cond']) + ',2),R!' + str(bad2) + '>*]'
        else:
            magma_cond_option = ''
        code['cond'] = {
            'magma':
            'Conductor(LSeries(C%s)); Factorization($1);' % magma_cond_option
        }
        code['disc'] = {
            'magma': 'Discriminant(C); Factorization(Integers()!$1);'
        }
        code['geom_inv'] = {
            'sage':
            'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
            'magma':
            'IgusaClebschInvariants(C); IgusaInvariants(C); G2Invariants(C);'
        }
        code['aut'] = {'magma': 'AutomorphismGroup(C); IdentifyGroup($1);'}
        code['autQbar'] = {
            'magma':
            'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'
        }
        code['num_rat_wpts'] = {
            'magma': '#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'
        }
        if ratpts:
            code['rat_pts'] = {
                'magma':
                '[' + ','.join([
                    "C![%s,%s,%s]" % (p[0], p[1], p[2])
                    for p in ratpts['rat_pts']
                ]) + '];'
            }
        code['mw_group'] = {'magma': 'MordellWeilGroupGenus2(Jacobian(C));'}
        code['two_selmer'] = {
            'magma': 'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'
        }
        code['has_square_sha'] = {'magma': 'HasSquareSha(Jacobian(C));'}
        code['locally_solvable'] = {
            'magma':
            'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'
        }
        code['torsion_subgroup'] = {
            'magma':
            'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'
        }
Esempio n. 57
0
    def make_torsion_growth(self):
        try:
            tor_gro = self.tor_gro
        except AttributeError:  # for curves with norsion growth data
            tor_gro = None
        if tor_gro is None:
            self.torsion_growth_data_exists = False
            return
        self.torsion_growth_data_exists = True
        self.tg = tg = {}
        tg['data'] = tgextra = []
        # find all base-changes of this curve in the database, if any
        bcs = list(
            db.ec_nfcurves.search(
                {'base_change': {
                    '$contains': [self.lmfdb_label]
                }},
                projection='label'))
        bcfs = [lab.split("-")[0] for lab in bcs]
        for F, T in tor_gro.items():
            tg1 = {}
            tg1['bc'] = "Not in database"
            # mongo did not allow "." in a dict key so we changed (e.g.) '3.1.44.1' to '3:1:44:1'
            # Here we change it back (but this code also works in case the fields already use ".")
            F = F.replace(":", ".")
            if "." in F:
                field_data = nf_display_knowl(F, field_pretty(F))
                deg = int(F.split(".")[0])
                bcc = [x for x, y in zip(bcs, bcfs) if y == F]
                if bcc:
                    from lmfdb.ecnf.main import split_full_label
                    F, NN, I, C = split_full_label(bcc[0])
                    tg1['bc'] = bcc[0]
                    tg1['bc_url'] = url_for('ecnf.show_ecnf',
                                            nf=F,
                                            conductor_label=NN,
                                            class_label=I,
                                            number=C)
            else:
                field_data = web_latex(coeff_to_poly(string2list(F)))
                deg = F.count(",")
            tg1['d'] = deg
            tg1['f'] = field_data
            tg1['t'] = '\(' + ' \\times '.join(
                ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)'
            tg1['m'] = 0
            tgextra.append(tg1)

        tgextra.sort(key=lambda x: x['d'])
        tg['n'] = len(tgextra)
        lastd = 1
        for tg1 in tgextra:
            d = tg1['d']
            if d != lastd:
                tg1['m'] = len([x for x in tgextra if x['d'] == d])
                lastd = d

        ## Hard-code this for now.  While something like
        ## max(db.ec_curves.search({},projection='tor_degs')) might
        ## work, since 'tor_degs' is in the extra table it is very
        ## slow.  Note that the *only* place where this number is used
        ## is in the ec-curve template where it says "The number
        ## fields ... of degree up to {{data.tg.maxd}} such that...".

        tg['maxd'] = 7
Esempio n. 58
0
def end_statement(factorsQQ, factorsRR, field='', ring=None):
    # field is a latex string describing the basechange field (default is empty)
    # ring is optional, if unspecified only endomorphism algebra is described
    statement = """<table class="g2">"""
    factorsQQ_number = len(factorsQQ)
    factorsQQ_pretty = [ field_pretty(fac[0]) for fac in factorsQQ if fac[0] ]

    # endomorphism ring is an invariant of the curve but not the isogeny class, so we make it optional
    if ring:
        # First row: description of the endomorphism ring as an order in the endomorphism algebra
        statement += """<tr><td>\(\End (J_{%s})\)</td><td>\(\simeq\)</td><td>""" % field
        # First the case of a maximal order:
        if ring[0] == 1:
            # Single factor:
            if factorsQQ_number == 1:
                # Number field or not:
                if factorsQQ[0][2] == -1:
                    # Prettify in quadratic case:
                    if len(factorsQQ[0][1]) in [2, 3]:
                        statement += """\(%s\)""" % ring_pretty(factorsQQ[0][1], 1)
                    else:
                        statement += """the maximal order of \(\End (J_{%s}) \otimes \Q\)""" % field
                else:
                    # Use M_2 over integers if this applies:
                    if factorsQQ[0][2] == 1 and factorsQQ[0][0] == '1.1.1.1':
                        statement += """\(\mathrm{M}_2 (\Z)\)"""
                    # TODO: Add flag that indicates whether we are over a PID, in
                    # which case we can use the following lines:
                    #if factorsQQ[0][2] == 1:
                    #    statement += """\(\mathrm{M}_2 (%s)\)"""\
                    #        % ring_pretty(factorsQQ[0][1], 1)
                    else:
                        statement += """a maximal order of \(\End (J_{%s}) \otimes \Q\)""" % field
            # If there are two factors, then they are both at most quadratic
            # and we can prettify them
            else:
                statement += r'\(' + ' \\times '.join([ ring_pretty(factorQQ[1], 1) for factorQQ in factorsQQ ]) + r'\)'
        # Then the case where there is still a single factor:
        elif factorsQQ_number == 1:
            # Number field case:
            if factorsQQ[0][2] == -1:
                # Prettify in quadratic case:
                if len(factorsQQ[0][1]) in [2, 3]:
                    statement += """\(%s\)""" % ring_pretty(factorsQQ[0][1], ring[0])
                else:
                    statement += """an order of conductor of norm \(%s\) in \(\End (J_{%s}) \otimes \Q\)""" % (ring[0], field)
            # Otherwise mention whether the order is Eichler:
            elif ring[1] == 1:
                statement += """an Eichler order of index \(%s\) in a maximal order of \(\End (J_{%s}) \otimes \Q\)""" % (ring[0], field)
            else:
                statement += """a non-Eichler order of index \(%s\) in a maximal order of \(\End (J_{%s}) \otimes \Q\)""" % (ring[0], field)
        # Finally the case of two factors. We can prettify to some extent, since we
        # can describe the maximal order here
        else:
            statement += """an order of index \(%s\) in \(%s\)""" % (ring[0], ' \\times '.join([ ring_pretty(factorQQ[1], 1) for factorQQ in factorsQQ ]))
        # End of first row:
        statement += """</td></tr>"""

    # Second row: description of endomorphism algebra factors (this is the first row if ring=None)
    statement += """<tr><td>\(\End (J_{%s}) \otimes \Q \)</td><td>\(\simeq\)</td><td>""" % field
    # In the case of only one factor we either get a number field or a
    # quaternion algebra:
    if factorsQQ_number == 1:
        # First we deal with the number field case,
        # in which we have set the discriminant to be -1
        if factorsQQ[0][2] == -1:
            # Prettify if labels available, otherwise return defining polynomial:
            if factorsQQ_pretty:
                statement += """<a href=%s>%s</a>""" % (url_for("number_fields.by_label", label=factorsQQ[0][0]), factorsQQ_pretty[0])
            else:
                statement += """the number field with defining polynomial \(%s\)""" % intlist_to_poly(factorsQQ[0][1])
            # Detect CM by presence of a quartic polynomial:
            if len(factorsQQ[0][1]) == 5:
                statement += """ (CM)"""
                # TODO: Get the following line to work
                #statement += """ ({{ KNOWL('ag.complex_multiplication', title='CM') }})"""
        # Up next is the case of a matrix ring (trivial disciminant), with
        # labels and full prettification always available:
        elif factorsQQ[0][2] == 1:
            statement += """\(\mathrm{M}_2(\)<a href=%s>%s</a>\()\)""" % (url_for("number_fields.by_label", label=factorsQQ[0][0]), factorsQQ_pretty[0])
        # And finally we deal with quaternion algebras over the rationals:
        else:
            statement += """the quaternion algebra over <a href=%s>%s</a> of discriminant %s"""\
                % (url_for("number_fields.by_label", label=factorsQQ[0][0]), factorsQQ_pretty[0], factorsQQ[0][2])
    # If there are two factors, then we get two at most quadratic fields:
    else:
        statement += """<a href=%s>%s</a> \(\\times\) <a href=%s>%s</a>"""\
            % (url_for("number_fields.by_label", label=factorsQQ[0][0]), 
                factorsQQ_pretty[0], url_for("number_fields.by_label",
                label=factorsQQ[1][0]), factorsQQ_pretty[1])
    # End of second row:
    statement += """</td></tr>"""

    # Third row: description of algebra tensored with RR (this is the second row if ring=None)
    statement += """<tr><td>\(\End (J_{%s}) \otimes \R\)</td><td>\(\simeq\)</td> <td>\(%s\)</td></tr>""" % (field, factorsRR_raw_to_pretty(factorsRR))

    # End of statement:
    statement += """</table>"""
    return statement
Esempio n. 59
0
    def make_object(self, curve, endo, tama, ratpts, is_curve):
        from lmfdb.genus2_curves.main import url_for_curve_label

        # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary
        # most of the data from the database gets polished/formatted before we put it in the data dictionary
        data = self.data = {}

        data['label'] = curve['label'] if is_curve else curve['class']
        data['slabel'] = data['label'].split('.')

        # set attributes common to curves and isogeny classes here
        data['Lhash'] = str(curve['Lhash'])
        data['cond'] = ZZ(curve['cond'])
        data['cond_factor_latex'] = web_latex(factor(int(data['cond'])))
        data['analytic_rank'] = ZZ(curve['analytic_rank'])
        data['st_group'] = curve['st_group']
        data['st_group_link'] = st_link_by_name(1, 4, data['st_group'])
        data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg'])
        data['is_gl2_type'] = curve['is_gl2_type']
        data['root_number'] = ZZ(curve['root_number'])
        data['lfunc_url'] = url_for("l_functions.l_function_genus2_page",
                                    cond=data['slabel'][0],
                                    x=data['slabel'][1])
        data['bad_lfactors'] = literal_eval(curve['bad_lfactors'])
        data['bad_lfactors_pretty'] = [(c[0],
                                        list_to_factored_poly_otherorder(c[1]))
                                       for c in data['bad_lfactors']]

        if is_curve:
            # invariants specific to curve
            data['class'] = curve['class']
            data['abs_disc'] = ZZ(curve['abs_disc'])
            data['disc'] = curve['disc_sign'] * data['abs_disc']
            data['min_eqn'] = literal_eval(curve['eqn'])
            data['min_eqn_display'] = list_to_min_eqn(data['min_eqn'])
            data['disc_factor_latex'] = web_latex(factor(data['disc']))
            data['igusa_clebsch'] = [
                ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])
            ]
            data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])]
            data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])]
            data['igusa_clebsch_factor_latex'] = [
                web_latex(zfactor(i)) for i in data['igusa_clebsch']
            ]
            data['igusa_factor_latex'] = [
                web_latex(zfactor(j)) for j in data['igusa']
            ]
            data['aut_grp_id'] = curve['aut_grp_id']
            data['geom_aut_grp_id'] = curve['geom_aut_grp_id']
            data['num_rat_wpts'] = ZZ(curve['num_rat_wpts'])
            data['two_selmer_rank'] = ZZ(curve['two_selmer_rank'])
            data['has_square_sha'] = "square" if curve[
                'has_square_sha'] else "twice a square"
            P = curve['non_solvable_places']
            if len(P):
                sz = "except over "
                sz += ", ".join([QpName(p) for p in P])
                last = " and"
                if len(P) > 2:
                    last = ", and"
                sz = last.join(sz.rsplit(",", 1))
            else:
                sz = "everywhere"
            data['non_solvable_places'] = sz
            data['torsion_order'] = curve['torsion_order']
            data['torsion_factors'] = [
                ZZ(a) for a in literal_eval(curve['torsion_subgroup'])
            ]
            if len(data['torsion_factors']) == 0:
                data['torsion_subgroup'] = '\mathrm{trivial}'
            else:
                data['torsion_subgroup'] = ' \\times '.join(
                    ['\Z/{%s}\Z' % n for n in data['torsion_factors']])
            data['end_ring_base'] = endo['ring_base']
            data['end_ring_geom'] = endo['ring_geom']
            data['tama'] = ''
            for item in tama:
                if item['tamagawa_number'] > 0:
                    tamgwnr = str(item['tamagawa_number'])
                else:
                    tamgwnr = 'N/A'
                data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + '), '
            data['tama'] = data['tama'][:-2]  # trim last ", "
            if ratpts:
                if len(ratpts['rat_pts']):
                    data['rat_pts'] = ',  '.join(
                        web_latex('(' + ' : '.join(map(str, P)) + ')')
                        for P in ratpts['rat_pts'])
                data['rat_pts_v'] = 2 if ratpts['rat_pts_v'] else 1
                # data['mw_rank'] = ratpts['mw_rank']
                # data['mw_rank_v'] = ratpts['mw_rank_v']
            else:
                data['rat_pts_v'] = 0
            if curve['two_torsion_field'][0]:
                data['two_torsion_field_knowl'] = nf_display_knowl(
                    curve['two_torsion_field'][0],
                    field_pretty(curve['two_torsion_field'][0]))
            else:
                t = curve['two_torsion_field']
                data[
                    'two_torsion_field_knowl'] = """splitting field of \(%s\) with Galois group %s""" % (
                        intlist_to_poly(
                            t[1]), group_display_knowl(t[2][0], t[2][1]))
        else:
            # invariants specific to isogeny class
            curves_data = list(
                db.g2c_curves.search({"class": curve['class']},
                                     ['label', 'eqn']))
            if not curves_data:
                raise KeyError(
                    "No curves found in database for isogeny class %s of genus 2 curve %s."
                    % (curve['class'], curve['label']))
            data['curves'] = [{
                "label":
                c['label'],
                "equation_formatted":
                list_to_min_eqn(literal_eval(c['eqn'])),
                "url":
                url_for_curve_label(c['label'])
            } for c in curves_data]
            lfunc_data = db.lfunc_lfunctions.lucky(
                {'Lhash': str(curve['Lhash'])})
            if not lfunc_data:
                raise KeyError(
                    "No Lfunction found in database for isogeny class of genus 2 curve %s."
                    % curve['label'])
            if lfunc_data and lfunc_data.get('euler_factors'):
                data['good_lfactors'] = [
                    [nth_prime(n + 1), lfunc_data['euler_factors'][n]]
                    for n in range(len(lfunc_data['euler_factors']))
                    if nth_prime(n + 1) < 30 and (data['cond'] %
                                                  nth_prime(n + 1))
                ]
                data['good_lfactors_pretty'] = [
                    (c[0], list_to_factored_poly_otherorder(c[1]))
                    for c in data['good_lfactors']
                ]
        # Endomorphism data over QQ:
        data['gl2_statement_base'] = gl2_statement_base(
            endo['factorsRR_base'], r'\(\Q\)')
        data['factorsQQ_base'] = endo['factorsQQ_base']
        data['factorsRR_base'] = endo['factorsRR_base']
        data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \
            end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None)

        # Field over which all endomorphisms are defined
        data['end_field_label'] = endo['fod_label']
        data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs'])
        data['end_field_statement'] = end_field_statement(
            data['end_field_label'], data['end_field_poly'])

        # Endomorphism data over QQbar:
        data['factorsQQ_geom'] = endo['factorsQQ_geom']
        data['factorsRR_geom'] = endo['factorsRR_geom']
        if data['end_field_label'] != '1.1.1.1':
            data['gl2_statement_geom'] = gl2_statement_base(
                data['factorsRR_geom'], r'\(\overline{\Q}\)')
            data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \
                end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None)
        data['real_geom_end_alg_name'] = end_alg_name(
            curve['real_geom_end_alg'])

        # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant):
        if is_curve:
            data['end_lattice'] = (endo['lattice'])[1:-1]
            if data['end_lattice']:
                data['end_lattice_statement'] = end_lattice_statement(
                    data['end_lattice'])

        # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple)
        data['is_simple_geom'] = endo['is_simple_geom']
        data['split_field_label'] = endo['spl_fod_label']
        data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs'])
        data['split_field_statement'] = split_field_statement(
            data['is_simple_geom'], data['split_field_label'],
            data['split_field_poly'])

        # Elliptic curve factors for non-simple Jacobians
        if not data['is_simple_geom']:
            data['split_coeffs'] = endo['spl_facs_coeffs']
            if 'spl_facs_labels' in endo and len(
                    endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']):
                data['split_labels'] = endo['spl_facs_labels']
            data['split_condnorms'] = endo['spl_facs_condnorms']
            data['split_statement'] = split_statement(data['split_coeffs'],
                                                      data.get('split_labels'),
                                                      data['split_condnorms'])

        # Properties
        self.properties = properties = [('Label', data['label'])]
        if is_curve:
            self.plot = encode_plot(
                eqn_list_to_curve_plot(
                    data['min_eqn'],
                    data['rat_pts'].split(',') if 'rat_pts' in data else []))
            plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(
                self.plot)

            properties += [
                (None, plot_link),
                ('Conductor', str(data['cond'])),
                ('Discriminant', str(data['disc'])),
            ]
        properties += [
            ('Sato-Tate group', data['st_group_link']),
            ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)',
             '\(%s\)' % data['real_geom_end_alg_name']),
            ('\(\\overline{\\Q}\)-simple',
             bool_pretty(data['is_simple_geom'])),
            ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])),
        ]

        # Friends
        self.friends = friends = [('L-function', data['lfunc_url'])]
        if is_curve:
            friends.append(('Isogeny class %s.%s' %
                            (data['slabel'][0], data['slabel'][1]),
                            url_for(".by_url_isogeny_class_label",
                                    cond=data['slabel'][0],
                                    alpha=data['slabel'][1])))
        for friend_url in db.lfunc_instances.search({'Lhash': data['Lhash']},
                                                    'url'):
            if '|' in friend_url:
                for url in friend_url.split('|'):
                    add_friend(friends, lfunction_friend_from_url(url))
            else:
                add_friend(friends, lfunction_friend_from_url(friend_url))
        if 'split_labels' in data:
            for friend_label in data['split_labels']:
                if is_curve:
                    add_friend(friends, ("Elliptic curve " + friend_label,
                                         url_for_ec(friend_label)))
                else:
                    add_friend(
                        friends,
                        ("EC isogeny class " + ec_label_class(friend_label),
                         url_for_ec_class(friend_label)))
        if is_curve:
            friends.append(('Twists',
                            url_for(".index_Q",
                                    g20=str(data['g2'][0]),
                                    g21=str(data['g2'][1]),
                                    g22=str(data['g2'][2]))))

        # Breadcrumbs
        self.bread = bread = [('Genus 2 Curves', url_for(".index")),
                              ('$\Q$', url_for(".index_Q")),
                              ('%s' % data['slabel'][0],
                               url_for(".by_conductor",
                                       cond=data['slabel'][0])),
                              ('%s' % data['slabel'][1],
                               url_for(".by_url_isogeny_class_label",
                                       cond=data['slabel'][0],
                                       alpha=data['slabel'][1]))]
        if is_curve:
            bread += [('%s' % data['slabel'][2],
                       url_for(".by_url_isogeny_class_discriminant",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2])),
                      ('%s' % data['slabel'][3],
                       url_for(".by_url_curve_label",
                               cond=data['slabel'][0],
                               alpha=data['slabel'][1],
                               disc=data['slabel'][2],
                               num=data['slabel'][3]))]

        # Title
        self.title = "Genus 2 " + ("Curve " if is_curve else
                                   "Isogeny Class ") + data['label']

        # Code snippets (only for curves)
        if not is_curve:
            return
        self.code = code = {}
        code['show'] = {'sage': '', 'magma': ''}  # use default show names
        code['curve'] = {
            'sage':
            'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))'
            % (data['min_eqn'][0], data['min_eqn'][1]),
            'magma':
            'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'
            % (data['min_eqn'][0], data['min_eqn'][1])
        }
        if data['abs_disc'] % 4096 == 0:
            ind2 = [a[0] for a in data['bad_lfactors']].index(2)
            bad2 = data['bad_lfactors'][ind2][1]
            magma_cond_option = ': ExcFactors:=[*<2,Valuation(' + str(
                data['cond']) + ',2),R!' + str(bad2) + '>*]'
        else:
            magma_cond_option = ''
        code['cond'] = {
            'magma':
            'Conductor(LSeries(C%s)); Factorization($1);' % magma_cond_option
        }
        code['disc'] = {
            'magma': 'Discriminant(C); Factorization(Integers()!$1);'
        }
        code['igusa_clebsch'] = {
            'sage':
            'C.igusa_clebsch_invariants(); [factor(a) for a in _]',
            'magma':
            'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];'
        }
        code['igusa'] = {
            'magma':
            'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];'
        }
        code['g2'] = {'magma': 'G2Invariants(C);'}
        code['aut'] = {'magma': 'AutomorphismGroup(C); IdentifyGroup($1);'}
        code['autQbar'] = {
            'magma':
            'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'
        }
        code['num_rat_wpts'] = {
            'magma': '#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'
        }
        if ratpts:
            code['rat_pts'] = {
                'magma':
                '[' + ','.join([
                    "C![%s,%s,%s]" % (p[0], p[1], p[2])
                    for p in ratpts['rat_pts']
                ]) + '];'
            }
        code['two_selmer'] = {
            'magma': 'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'
        }
        code['has_square_sha'] = {'magma': 'HasSquareSha(Jacobian(C));'}
        code['locally_solvable'] = {
            'magma':
            'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'
        }
        code['torsion_subgroup'] = {
            'magma':
            'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'
        }