Example #1
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
Example #2
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
Example #3
0
def modular_form_display(label, number):
    try:
        number = int(number)
    except:
        number = 10
    if number < 10:
        number = 10
    # if number > 100000:
    #     number = 20
    # if number > 50000:
    #     return "OK, I give up."
    # if number > 20000:
    #     return "This incident will be reported to the appropriate authorities."
    # if number > 9600:
    #     return "You have been banned from this website."
    # if number > 4800:
    #     return "Seriously."
    # if number > 2400:
    #     return "I mean it."
    # if number > 1200:
    #     return "Please stop poking me."
    if number > 1000:
        number = 1000
    C = lmfdb.base.getDBConnection()
    data = C.elliptic_curves.curves.find_one({'lmfdb_label': label})
    if data is None:
        return elliptic_curve_jump_error(label, {})
    ainvs = [int(a) for a in data['ainvs']]
    E = EllipticCurve(ainvs)
    modform = E.q_eigenform(number)
    modform_string = web_latex_split_on_pm(modform)
    return modform_string
Example #4
0
def modular_form_display(label, number):
    try:
        number = int(number)
    except:
        number = 10
    if number < 10:
        number = 10
    # if number > 100000:
    #     number = 20
    # if number > 50000:
    #     return "OK, I give up."
    # if number > 20000:
    #     return "This incident will be reported to the appropriate authorities."
    # if number > 9600:
    #     return "You have been banned from this website."
    # if number > 4800:
    #     return "Seriously."
    # if number > 2400:
    #     return "I mean it."
    # if number > 1200:
    #     return "Please stop poking me."
    if number > 1000:
        number = 1000
    data = db_ec().find_one({'lmfdb_label': label})
    if data is None:
        return elliptic_curve_jump_error(label, {})
    ainvs = [int(a) for a in data['ainvs']]
    E = EllipticCurve(ainvs)
    modform = E.q_eigenform(number)
    modform_string = web_latex_split_on_pm(modform)
    return modform_string
Example #5
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'])
Example #6
0
 def test_web_latex_split_on_pm(self):
     r"""
     Checking utility: web_latex_split_on_pm
     """
     x = var('x')
     f = x**2 + 1
     expected = '\\(x^{2} \\) \\(\\mathstrut +\\mathstrut  1 \\)'
     self.assertEqual(web_latex_split_on_pm(f), expected)
Example #7
0
 def test_web_latex_split_on_pm(self):
     r"""
     Checking utility: web_latex_split_on_pm
     """
     x = var('x')
     f = x**2 + 1
     expected = '\\(x^{2} \\) \\(\\mathstrut +\\mathstrut  1 \\)'
     self.assertEqual(web_latex_split_on_pm(f), expected)
Example #8
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
Example #9
0
 def q_expansion(self, prec_max=10):
     # Display the q-expansion, truncating to precision prec_max.  Will be inside \( \).
     if self.has_exact_qexp:
         prec = min(self.qexp_prec, prec_max)
         if self.dim == 1:
             s = web_latex_split_on_pm(web_latex(coeff_to_power_series([self.qexp[n][0] for n in range(prec)],prec=prec),enclose=False))
         else:
             s = self.eigs_as_seqseq_to_qexp(prec)
         return s
     else:
         return coeff_to_power_series([0,1], prec=2)._latex_()
Example #10
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()))
Example #11
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()))
Example #12
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
Example #13
0
def modular_form_display(label, number):
    try:
        number = int(number)
    except ValueError:
        number = 10
    if number < 10:
        number = 10
    if number > 1000:
        number = 1000
    ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label')
    if ainvs is None:
        return elliptic_curve_jump_error(label, {})
    E = EllipticCurve(ainvs)
    modform = E.q_eigenform(number)
    modform_string = web_latex_split_on_pm(modform)
    return modform_string
Example #14
0
def modular_form_display(label, number):
    try:
        number = int(number)
    except ValueError:
        number = 10
    if number < 10:
        number = 10
    if number > 1000:
        number = 1000
    data = db_ec().find_one({'lmfdb_label': label})
    if data is None:
        return elliptic_curve_jump_error(label, {})
    E = EllipticCurve(parse_ainvs(data['xainvs']))
    modform = E.q_eigenform(number)
    modform_string = web_latex_split_on_pm(modform)
    return modform_string
Example #15
0
def modular_form_display(label, number):
    try:
        number = int(number)
    except ValueError:
        number = 10
    if number < 10:
        number = 10
    if number > 1000:
        number = 1000
    data = db_ec().find_one({'lmfdb_label': label})
    if data is None:
        return elliptic_curve_jump_error(label, {})
    E = EllipticCurve(parse_ainvs(data['xainvs']))
    modform = E.q_eigenform(number)
    modform_string = web_latex_split_on_pm(modform)
    return modform_string
Example #16
0
def modular_form_display(label, number):
    try:
        number = int(number)
    except ValueError:
        number = 10
    if number < 10:
        number = 10
    if number > 1000:
        number = 1000
    ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label')
    if ainvs is None:
        return elliptic_curve_jump_error(label, {})
    E = EllipticCurve(ainvs)
    modform = E.q_eigenform(number)
    modform_string = web_latex_split_on_pm(modform)
    return modform_string
Example #17
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'])
Example #18
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
Example #19
0
def web_latex_poly(pol, name='x', keepzeta=False):
    """
    Change the name of the variable in a polynomial.  If keepzeta, then don't change
    the name of zetaN in the defining polynomial of a cyclotomic field.
    (keepzeta not implemented yet)
    """
    # the next few lines were adapted from the lines after line 117 of web_newforms.py 
    oldname = latex(pol.parent().gen())
    subfrom = oldname.strip() 
    subfrom = subfrom.replace("\\","\\\\")  
    subfrom = subfrom.replace("{","\\{")   # because x_{0} means somethgn in a regular expression
    if subfrom[0].isalpha():
        subfrom = "\\b" + subfrom
    subto = name.replace("\\","\\\\")  
    subto += " "
#    print "converting from",subfrom,"to", subto, "of", latex(pol)
    newpol = re.sub(subfrom, subto, latex(pol))
#    print "result is",newpol
    return web_latex_split_on_pm(newpol)
Example #20
0
def web_latex_poly(pol, name='x', keepzeta=False):
    """
    Change the name of the variable in a polynomial.  If keepzeta, then don't change
    the name of zetaN in the defining polynomial of a cyclotomic field.
    (keepzeta not implemented yet)
    """
    # the next few lines were adapted from the lines after line 117 of web_newforms.py 
    oldname = latex(pol.parent().gen())
    subfrom = oldname.strip() 
    subfrom = subfrom.replace("\\","\\\\")  
    subfrom = subfrom.replace("{","\\{")   # because x_{0} means somethgn in a regular expression
    if subfrom[0].isalpha():
        subfrom = "\\b" + subfrom
    subto = name.replace("\\","\\\\")  
    subto += " "
#    print "converting from",subfrom,"to", subto, "of", latex(pol)
    newpol = re.sub(subfrom, subto, latex(pol))
#    print "result is",newpol
    return web_latex_split_on_pm(newpol)
Example #21
0
 def display_hecke_cutters(self):
     polynomials = []
     truncated = False
     for p,F in self.hecke_cutters:
         cut = len(F) - 1
         count = 0
         while cut >= 0 and count < 8:
             if F[cut]:
                 count += 1
             cut -= 1
         if count < 8 or cut == 0 and abs(F[0]) < 100:
             F = latex(coeff_to_poly(F, 'T%s'%p))
         else:
             # truncate to the first 8 nonzero coefficients
             F = [0]*(cut+1) + F[cut+1:]
             F = latex(coeff_to_poly(F, 'T%s'%p)) + r' + \cdots'
             truncated = True
         polynomials.append(web_latex_split_on_pm(F))
     title = 'linear operator'
     if len(polynomials) > 1:
         title += 's'
     knowl = display_knowl('mf.elliptic.hecke_cutter', title=title)
     desc = "<p>This newform can be constructed as the "
     if truncated or len(polynomials) > 1:
         if len(polynomials) > 1:
             desc += "intersection of the kernels "
         else:
             desc += "kernel "
         desc += "of the following %s acting on %s:</p>\n<table>"
         desc = desc % (knowl, self.display_newspace())
         desc += "\n".join("<tr><td>%s</td></tr>" % F for F in polynomials) + "\n</table>"
     elif len(polynomials) == 1:
         desc += "kernel of the %s %s acting on %s."
         desc = desc % (knowl, polynomials[0], self.display_newspace())
     else:
         desc = r"<p>There are no other newforms in %s.</p>"%(self.display_newspace())
     return desc
Example #22
0
def print_q_expansion(list):
     list=[str(c) for c in list]
     Qb=PolynomialRing(QQ,'b')
     Qq=PowerSeriesRing(Qb['a'],'q')
     return web_latex_split_on_pm(Qq([c for c in list]).add_bigoh(len(list)))
Example #23
0
def render_field_webpage(args):
    data = None
    C = base.getDBConnection()
    info = {}
    bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]

    # This function should not be called unless label is set.
    label = clean_input(args['label'])
    nf = WebNumberField(label)
    data = {}
    if nf.is_null():
        bread.append(('Search results', ' '))
        info['err'] = 'There is no field with label %s in the database' % label
        info['label'] = args['label_orig'] if 'label_orig' in args else args['label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number()
    t = nf.galois_t()
    n = nf.degree()
    data['is_galois'] = nf.is_galois()
    data['is_abelian'] = nf.is_abelian()
    if nf.is_abelian():
        conductor = nf.conductor()
        data['conductor'] = conductor
        dirichlet_chars = nf.dirichlet_group()
        if len(dirichlet_chars)>0:
            data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,&middot;)$</a>' % (url_for('characters.render_Dirichletwebpage',modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars]
            data['dirichlet_group'] = r'$\lbrace$' + ', '.join(data['dirichlet_group']) + r'$\rbrace$'
        if data['conductor'].is_prime() or data['conductor'] == 1:
            data['conductor'] = "\(%s\)" % str(data['conductor'])
        else:
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), latex(data['conductor'].factor()))
    data['galois_group'] = group_display_knowl(n, t, C)
    data['cclasses'] = cclasses_display_knowl(n, t, C)
    data['character_table'] = character_table_display_knowl(n, t, C)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    data['coefficients'] = nf.coeffs()
    nf.make_code_snippets()
    D = nf.disc()
    ram_primes = D.prime_factors()
    data['disc_factor'] = nf.disc_factored_latex()
    if D.abs().is_prime() or D == 1:
        data['discriminant'] = "\(%s\)" % str(D)
    else:
        data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor'])
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['frob_data'], data['seeram'] = frobs(nf)
    data['phrase'] = group_phrase(n, t, C)
    zk = nf.zk()
    Ra = PolynomialRing(QQ, 'a')
    zk = [latex(Ra(x)) for x in zk]
    zk = ['$%s$' % x for x in zk]
    zk = ', '.join(zk)
    grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh() else ''
    # Short version for properties
    grh_lab = nf.short_grh_string()
    if 'Not' in str(data['class_number']):
        grh_lab=''
        grh_label=''
    pretty_label = field_pretty(label)
    if label != pretty_label:
        pretty_label = "%s: %s" % (label, pretty_label)

    info.update(data)
    if nf.degree() > 1:
        gpK = nf.gpK()
        rootof1coeff = gpK.nfrootsof1()[2]
        rootofunity = Ra(str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace('x','a'))
    else:
        rootofunity = Ra('-1')

    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.poly()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': web_latex(rootofunity),
        'fund_units': nf.units(),
        'grh_label': grh_label
    })

    bread.append(('%s' % info['label_raw'], ' '))
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    info['friends'] = []
    if nf.can_class_number():
        # hide ones that take a lond time to compute on the fly
        # note that the first degree 4 number field missed the zero of the zeta function
        if abs(D**n) < 50000000:
            info['friends'].append(('L-function', "/L/NumberField/%s" % label))
    info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t)))
    if 'dirichlet_group' in info:
        info['friends'].append(('Dirichlet group', url_for("characters.dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    info['learnmore'] = [('Global number field labels', url_for(
        ".render_labels_page")), 
        (Completename, url_for(".render_discriminants_page")),
        ('How data was computed', url_for(".how_computed_page"))]
    if info['signature'] == [0,1]:
        info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data")))
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

    if npr == 1:
        primes = 'prime'
    else:
        primes = 'primes'

    properties2 = [('Label', label),
                   ('Degree', '%s' % data['degree']),
                   ('Signature', '$%s$' % data['signature']),
                   ('Discriminant', '$%s$' % data['disc_factor']),
                   ('Ramified ' + primes + '', '$%s$' % ram_primes),
                   ('Class number', '%s %s' % (data['class_number'], grh_lab)),
                   ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)),
                   ('Galois Group', group_display_short(data['degree'], t, C))
                   ]
    from lmfdb.math_classes import NumberFieldGaloisGroup
    try:
        info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs'])
        v = nf.factor_perm_repn(info["tim_number_field"])
        def dopow(m):
            if m==0: return ''
            if m==1: return '*'
            return '*<sup>%d</sup>'% m

        info["mydecomp"] = [dopow(x) for x in v]
    except AttributeError:
        pass
#    del info['_id']
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), learnmore=info.pop('learnmore'), info=info)
Example #24
0
def print_q_expansion(list):
     list=[str(c) for c in list]
     Qa=PolynomialRing(QQ,'a')
     Qq=PowerSeriesRing(Qa,'q')
     return web_latex_split_on_pm(Qq([c for c in list]).add_bigoh(len(list)))
Example #25
0
 def nfpol(self):
     #return self.nf.web_poly()
     return web_latex_split_on_pm(self.k.polynomial())
Example #26
0
 def trace_expansion(self, prec_max=10):
     prec = min(len(self.traces)+1, prec_max)
     return web_latex_split_on_pm(web_latex(coeff_to_power_series([0] + self.traces[:prec-1],prec=prec),enclose=False))
Example #27
0
def render_field_webpage(args):
    data = None
    info = {}
    bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]

    # This function should not be called unless label is set.
    label = clean_input(args['label'])
    nf = WebNumberField(label)
    data = {}
    if nf.is_null():
        bread.append(('Search Results', ' '))
        info['err'] = 'There is no field with label %s in the database' % label
        info['label'] = args['label_orig'] if 'label_orig' in args else args['label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number_latex()
    ram_primes = nf.ramified_primes()
    t = nf.galois_t()
    n = nf.degree()
    data['is_galois'] = nf.is_galois()
    data['is_abelian'] = nf.is_abelian()
    if nf.is_abelian():
        conductor = nf.conductor()
        data['conductor'] = conductor
        dirichlet_chars = nf.dirichlet_group()
        if len(dirichlet_chars)>0:
            data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,&middot;)$</a>' % (url_for('characters.render_Dirichletwebpage',modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars]
            data['dirichlet_group'] = r'$\lbrace$' + ', '.join(data['dirichlet_group']) + r'$\rbrace$'
        if data['conductor'].is_prime() or data['conductor'] == 1:
            data['conductor'] = "\(%s\)" % str(data['conductor'])
        else:
            factored_conductor = factor_base_factor(data['conductor'], ram_primes)
            factored_conductor = factor_base_factorization_latex(factored_conductor)
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), factored_conductor)
    data['galois_group'] = group_display_knowl(n, t)
    data['cclasses'] = cclasses_display_knowl(n, t)
    data['character_table'] = character_table_display_knowl(n, t)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    data['coefficients'] = nf.coeffs()
    nf.make_code_snippets()
    D = nf.disc()
    data['disc_factor'] = nf.disc_factored_latex()
    if D.abs().is_prime() or D == 1:
        data['discriminant'] = "\(%s\)" % str(D)
    else:
        data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor'])
    data['frob_data'], data['seeram'] = frobs(nf)
    # Bad prime information
    npr = len(ram_primes)
    ramified_algebras_data = nf.ramified_algebras_data()
    if isinstance(ramified_algebras_data,str):
        loc_alg = ''
    else:
        # [label, latex, e, f, c, gal]
        loc_alg = ''
        for j in range(npr):
            if ramified_algebras_data[j] is None:
                loc_alg += '<tr><td>%s<td colspan="7">Data not computed'%str(ram_primes[j])
            else:
                mydat = ramified_algebras_data[j]
                p = ram_primes[j]
                loc_alg += '<tr><td rowspan="%d">$%s$</td>'%(len(mydat),str(p))
                mm = mydat[0]
                myurl = url_for('local_fields.by_label', label=mm[0])
                lab = mm[0]
                if mm[3]*mm[2]==1:
                    lab = r'$\Q_{%s}$'%str(p)
                loc_alg += '<td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7]))
                for mm in mydat[1:]:
                    lab = mm[0]
                    if mm[3]*mm[2]==1:
                        lab = r'$\Q_{%s}$'%str(p)
                    loc_alg += '<tr><td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7]))
        loc_alg += '</tbody></table>'

    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['phrase'] = group_phrase(n, t)
    zk = nf.zk()
    Ra = PolynomialRing(QQ, 'a')
    zk = [latex(Ra(x)) for x in zk]
    zk = ['$%s$' % x for x in zk]
    zk = ', '.join(zk)
    grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh() else ''
    # Short version for properties
    grh_lab = nf.short_grh_string()
    if 'Not' in str(data['class_number']):
        grh_lab=''
        grh_label=''
    pretty_label = field_pretty(label)
    if label != pretty_label:
        pretty_label = "%s: %s" % (label, pretty_label)

    info.update(data)
    if nf.degree() > 1:
        gpK = nf.gpK()
        rootof1coeff = gpK.nfrootsof1()
        rootofunityorder = int(rootof1coeff[1])
        rootof1coeff = rootof1coeff[2]
        rootofunity = web_latex(Ra(str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace('x','a'))) 
        rootofunity += ' (order $%d$)' % rootofunityorder
    else:
        rootofunity = web_latex(Ra('-1'))+ ' (order $2$)'

    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.poly()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': rootofunity,
        'fund_units': nf.units(),
        'grh_label': grh_label,
        'loc_alg': loc_alg
    })

    bread.append(('%s' % info['label_raw'], ' '))
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    info['friends'] = []
    if nf.can_class_number():
        # hide ones that take a lond time to compute on the fly
        # note that the first degree 4 number field missed the zero of the zeta function
        if abs(D**n) < 50000000:
            info['friends'].append(('L-function', "/L/NumberField/%s" % label))
    info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t)))
    if 'dirichlet_group' in info:
        info['friends'].append(('Dirichlet character group', url_for("characters.dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    resinfo=[]
    galois_closure = nf.galois_closure()
    if galois_closure[0]>0:
        if len(galois_closure[1])>0:
            resinfo.append(('gc', galois_closure[1]))
            if len(galois_closure[2]) > 0:
                info['friends'].append(('Galois closure',url_for(".by_label", label=galois_closure[2][0])))
        else:
            resinfo.append(('gc', [dnc]))

    sextic_twins = nf.sextic_twin()
    if sextic_twins[0]>0:
        if len(sextic_twins[1])>0:
            resinfo.append(('sex', r' $\times$ '.join(sextic_twins[1])))
        else:
            resinfo.append(('sex', dnc))

    siblings = nf.siblings()
    # [degsib list, label list]
    # first is list of [deg, num expected, list of knowls]
    if len(siblings[0])>0:
        for sibdeg in siblings[0]:
            if len(sibdeg[2]) ==0:
                sibdeg[2] = dnc
            else:
                sibdeg[2] = ', '.join(sibdeg[2])
                if len(sibdeg[2])<sibdeg[1]:
                    sibdeg[2] += ', some '+dnc
                
        resinfo.append(('sib', siblings[0]))
        for lab in siblings[1]:
            if lab != '':
                labparts = lab.split('.')
                info['friends'].append(("Degree %s sibling"%labparts[0] ,url_for(".by_label", label=lab)))

    arith_equiv = nf.arith_equiv()
    if arith_equiv[0]>0:
        if len(arith_equiv[1])>0:
            resinfo.append(('ae', ', '.join(arith_equiv[1]), len(arith_equiv[1])))
            for aelab in arith_equiv[2]:
                info['friends'].append(('Arithmetically equivalent sibling',url_for(".by_label", label=aelab)))
        else:
            resinfo.append(('ae', dnc, len(arith_equiv[1])))

    info['resinfo'] = resinfo
    learnmore = learnmore_list()
    #if info['signature'] == [0,1]:
    #    info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data")))
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

    if npr == 1:
        primes = 'prime'
    else:
        primes = 'primes'

    properties2 = [('Label', label),
                   ('Degree', '$%s$' % data['degree']),
                   ('Signature', '$%s$' % data['signature']),
                   ('Discriminant', '$%s$' % data['disc_factor']),
                   ('Ramified ' + primes + '', '$%s$' % ram_primes),
                   ('Class number', '%s %s' % (data['class_number'], grh_lab)),
                   ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)),
                   ('Galois Group', group_display_short(data['degree'], t))
                   ]
    downloads = []
    for lang in [["Magma","magma"], ["SageMath","sage"], ["Pari/GP", "gp"]]:
        downloads.append(('Download {} code'.format(lang[0]),
                          url_for(".nf_code_download", nf=label, download_type=lang[1])))
    from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup
    try:
        info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs'])
        v = nf.factor_perm_repn(info["tim_number_field"])
        def dopow(m):
            if m==0: return ''
            if m==1: return '*'
            return '*<sup>%d</sup>'% m

        info["mydecomp"] = [dopow(x) for x in v]
    except AttributeError:
        pass
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), downloads=downloads, learnmore=learnmore, info=info)
Example #28
0
 def defining_polynomial(self):
     if self.field_poly:
         return web_latex_split_on_pm(web_latex(coeff_to_poly(self.field_poly), enclose=False))
     return None
Example #29
0
    def make_curve(self):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these.

        # Old version: required constructing the actual elliptic curve
        # E, and computing some further data about it.

        # New version (May 2016): extra data fields now in the
        # database so we do not have to construct the curve or do any
        # computation with it on the fly.  As a failsafe the old way
        # is still included.

        data = self.data = {}
        try:
            data['ainvs'] = [int(c) for c in self.xainvs[1:-1].split(',')]
        except AttributeError:
            data['ainvs'] = [int(ai) for ai in self.ainvs]
        data['conductor'] = N = ZZ(self.conductor)
        data['j_invariant'] = QQ(str(self.jinv))
        data['j_inv_factor'] = latex(0)
        if data['j_invariant']:  # don't factor 0
            data['j_inv_factor'] = latex(data['j_invariant'].factor())
        data['j_inv_str'] = unicode(str(data['j_invariant']))
        data['j_inv_latex'] = web_latex(data['j_invariant'])
        mw = self.mw = {}
        mw['rank'] = self.rank
        mw['int_points'] = ''
        if self.xintcoords:
            a1, a2, a3, a4, a6 = [ZZ(a) for a in data['ainvs']]

            def lift_x(x):
                f = ((x + a2) * x + a4) * x + a6
                b = (a1 * x + a3)
                d = (b * b + 4 * f).sqrt()
                return (x, (-b + d) / 2)

            mw['int_points'] = ', '.join(
                web_latex(lift_x(x)) for x in self.xintcoords)

        mw['generators'] = ''
        mw['heights'] = []
        if self.gens:
            mw['generators'] = [
                web_latex(tuple(P)) for P in parse_points(self.gens)
            ]

        mw['tor_order'] = self.torsion
        tor_struct = [int(c) for c in self.torsion_structure]
        if mw['tor_order'] == 1:
            mw['tor_struct'] = '\mathrm{Trivial}'
            mw['tor_gens'] = ''
        else:
            mw['tor_struct'] = ' \\times '.join(
                ['\Z/{%s}\Z' % n for n in tor_struct])
            mw['tor_gens'] = ', '.join(
                web_latex(tuple(P))
                for P in parse_points(self.torsion_generators))

        # try to get all the data we need from the database entry (now in self)
        try:
            data['equation'] = self.equation
            local_data = self.local_data
            D = self.signD * prod(
                [ld['p']**ld['ord_disc'] for ld in local_data])
            data['disc'] = D
            Nfac = Factorization([(ZZ(ld['p']), ld['ord_cond'])
                                  for ld in local_data])
            Dfac = Factorization([(ZZ(ld['p']), ld['ord_disc'])
                                  for ld in local_data],
                                 unit=ZZ(self.signD))

            data['minq_D'] = minqD = self.min_quad_twist['disc']
            minq_label = self.min_quad_twist['label']
            data['minq_label'] = db_ec().find_one(
                {'label': minq_label}, ['lmfdb_label'])['lmfdb_label']
            data['minq_info'] = '(itself)' if minqD == 1 else '(by %s)' % minqD
            try:
                data['degree'] = self.degree
            except AttributeError:
                data['degree'] = 0  # invalid, but will be displayed nicely
            mw['heights'] = self.heights
            if self.number == 1:
                data['an'] = self.anlist
                data['ap'] = self.aplist
            else:
                r = db_ec().find_one({
                    'lmfdb_iso': self.lmfdb_iso,
                    'number': 1
                }, ['anlist', 'aplist'])
                data['an'] = r['anlist']
                data['ap'] = r['aplist']

        # otherwise fall back to computing it from the curve
        except AttributeError:
            self.E = EllipticCurve(data['ainvs'])
            data['equation'] = web_latex(self.E)
            data['disc'] = D = self.E.discriminant()
            Nfac = N.factor()
            Dfac = D.factor()
            bad_primes = [p for p, e in Nfac]
            try:
                data['degree'] = self.degree
            except AttributeError:
                try:
                    data['degree'] = self.E.modular_degree()
                except RuntimeError:
                    data['degree'] = 0  # invalid, but will be displayed nicely
            minq, minqD = self.E.minimal_quadratic_twist()
            data['minq_D'] = minqD
            if minqD == 1:
                data['minq_label'] = self.lmfdb_label
                data['minq_info'] = '(itself)'
            else:
                # This relies on the minimal twist being in the
                # database, which is true when the database only
                # contains the Cremona database.  It would be a good
                # idea if, when the database is extended, we ensured
                # that for any curve included, all twists of smaller
                # conductor are also included.
                minq_ainvs = [str(c) for c in minq.ainvs()]
                data['minq_label'] = db_ec().find_one(
                    {
                        'jinv': str(self.E.j_invariant()),
                        'ainvs': minq_ainvs
                    }, ['lmfdb_label'])['lmfdb_label']
                data['minq_info'] = '(by %s)' % minqD

            if self.gens:
                self.generators = [self.E(g) for g in parse_points(self.gens)]
                mw['heights'] = [P.height() for P in self.generators]

            data['an'] = self.E.anlist(20, python_ints=True)
            data['ap'] = self.E.aplist(100, python_ints=True)
            self.local_data = local_data = []
            for p in bad_primes:
                ld = self.E.local_data(p, algorithm="generic")
                local_data_p = {}
                local_data_p['p'] = p
                local_data_p['cp'] = ld.tamagawa_number()
                local_data_p['kod'] = web_latex(ld.kodaira_symbol()).replace(
                    '$', '')
                local_data_p['red'] = ld.bad_reduction_type()
                rootno = -ld.bad_reduction_type()
                if rootno == 0:
                    rootno = self.E.root_number(p)
                local_data_p['rootno'] = rootno
                local_data_p['ord_cond'] = ld.conductor_valuation()
                local_data_p['ord_disc'] = ld.discriminant_valuation()
                local_data_p['ord_den_j'] = max(
                    0, -self.E.j_invariant().valuation(p))
                local_data.append(local_data_p)

        # If we got the data from the database, the root numbers may
        # not have been stored there, so we have to compute them.  If
        # there are additive primes this means constructing the curve.
        for ld in self.local_data:
            if not 'rootno' in ld:
                rootno = -ld['red']
                if rootno == 0:
                    try:
                        E = self.E
                    except AttributeError:
                        self.E = E = EllipticCurve(data['ainvs'])
                    rootno = E.root_number(ld['p'])
                ld['rootno'] = rootno

        minq_N, minq_iso, minq_number = split_lmfdb_label(data['minq_label'])

        data['disc_factor'] = latex(Dfac)
        data['cond_factor'] = latex(Nfac)
        data['disc_latex'] = web_latex(D)
        data['cond_latex'] = web_latex(N)

        data['galois_images'] = [
            trim_galois_image_code(s) for s in self.mod_p_images
        ]
        data['non_maximal_primes'] = self.non_maximal_primes
        data['galois_data'] = [{
            'p': p,
            'image': im
        } for p, im in zip(data['non_maximal_primes'], data['galois_images'])]

        data['CMD'] = self.cm
        data['CM'] = "no"
        data['EndE'] = "\(\Z\)"
        if self.cm:
            data['cm_ramp'] = [
                p for p in ZZ(self.cm).support()
                if not p in self.non_surjective_primes
            ]
            data['cm_nramp'] = len(data['cm_ramp'])
            if data['cm_nramp'] == 1:
                data['cm_ramp'] = data['cm_ramp'][0]
            else:
                data['cm_ramp'] = ", ".join([str(p) for p in data['cm_ramp']])
            data['cm_sqf'] = ZZ(self.cm).squarefree_part()

            data['CM'] = "yes (\(D=%s\))" % data['CMD']
            if data['CMD'] % 4 == 0:
                d4 = ZZ(data['CMD']) // 4
                data['EndE'] = "\(\Z[\sqrt{%s}]\)" % d4
            else:
                data['EndE'] = "\(\Z[(1+\sqrt{%s})/2]\)" % data['CMD']
            data['ST'] = st_link_by_name(1, 2, 'N(U(1))')
        else:
            data['ST'] = st_link_by_name(1, 2, 'SU(2)')

        data['p_adic_primes'] = [
            p for i, p in enumerate(prime_range(5, 100))
            if (N * data['ap'][i]) % p != 0
        ]

        cond, iso, num = split_lmfdb_label(self.lmfdb_label)
        self.class_url = url_for(".by_double_iso_label",
                                 conductor=N,
                                 iso_label=iso)
        self.one_deg = ZZ(self.class_deg).is_prime()
        self.ncurves = db_ec().count({'lmfdb_iso': self.lmfdb_iso})
        isodegs = [str(d) for d in self.isogeny_degrees if d > 1]
        if len(isodegs) < 3:
            data['isogeny_degrees'] = " and ".join(isodegs)
        else:
            data['isogeny_degrees'] = " and ".join(
                [", ".join(isodegs[:-1]), isodegs[-1]])

        if self.twoadic_gens:
            from sage.matrix.all import Matrix
            data['twoadic_gen_matrices'] = ','.join(
                [latex(Matrix(2, 2, M)) for M in self.twoadic_gens])
            data[
                'twoadic_rouse_url'] = ROUSE_URL_PREFIX + self.twoadic_label + ".html"

        # Leading term of L-function & BSD data
        bsd = self.bsd = {}
        r = self.rank
        if r >= 2:
            bsd['lder_name'] = "L^{(%s)}(E,1)/%s!" % (r, r)
        elif r:
            bsd['lder_name'] = "L'(E,1)"
        else:
            bsd['lder_name'] = "L(E,1)"

        bsd['reg'] = self.regulator
        bsd['omega'] = self.real_period
        bsd['sha'] = int(0.1 + self.sha_an)
        bsd['lder'] = self.special_value

        # Optimality (the optimal curve in the class is the curve
        # whose Cremona label ends in '1' except for '990h' which was
        # labelled wrongly long ago)

        if self.iso == '990h':
            data['Gamma0optimal'] = bool(self.number == 3)
        else:
            data['Gamma0optimal'] = bool(self.number == 1)

        data['p_adic_data_exists'] = False
        if data['Gamma0optimal']:
            data['p_adic_data_exists'] = (padic_db().find({
                'lmfdb_iso':
                self.lmfdb_iso
            }).count()) > 0

        data['iwdata'] = []
        try:
            pp = [int(p) for p in self.iwdata]
            badp = [l['p'] for l in self.local_data]
            rtypes = [l['red'] for l in self.local_data]
            data[
                'iw_missing_flag'] = False  # flags that there is at least one "?" in the table
            data[
                'additive_shown'] = False  # flags that there is at least one additive prime in table
            for p in sorted(pp):
                rtype = ""
                if p in badp:
                    red = rtypes[badp.index(p)]
                    # Additive primes are excluded from the table
                    # if red==0:
                    #    continue
                    #rtype = ["nsmult","add", "smult"][1+red]
                    rtype = ["nonsplit", "add", "split"][1 + red]
                p = str(p)
                pdata = self.iwdata[p]
                if isinstance(pdata, type(u'?')):
                    if not rtype:
                        rtype = "ordinary" if pdata == "o?" else "ss"
                    if rtype == "add":
                        data['iwdata'] += [[p, rtype, "-", "-"]]
                        data['additive_shown'] = True
                    else:
                        data['iwdata'] += [[p, rtype, "?", "?"]]
                        data['iw_missing_flag'] = True
                else:
                    if len(pdata) == 2:
                        if not rtype:
                            rtype = "ordinary"
                        lambdas = str(pdata[0])
                        mus = str(pdata[1])
                    else:
                        rtype = "ss"
                        lambdas = ",".join([str(pdata[0]), str(pdata[1])])
                        mus = str(pdata[2])
                        mus = ",".join([mus, mus])
                    data['iwdata'] += [[p, rtype, lambdas, mus]]
        except AttributeError:
            # For curves with no Iwasawa data
            pass

        tamagawa_numbers = [ZZ(ld['cp']) for ld in local_data]
        cp_fac = [cp.factor() for cp in tamagawa_numbers]
        cp_fac = [
            latex(cp) if len(cp) < 2 else '(' + latex(cp) + ')'
            for cp in cp_fac
        ]
        bsd['tamagawa_factors'] = r'\cdot'.join(cp_fac)
        bsd['tamagawa_product'] = prod(tamagawa_numbers)

        # Torsion growth data

        data['torsion_growth_data_exists'] = False
        try:
            tg = self.tor_gro
            data['torsion_growth_data_exists'] = True
            data['tgx'] = tgextra = []
            # find all base-changes of this curve in the database, if any
            bcs = [
                res['label']
                for res in getDBConnection().elliptic_curves.nfcurves.find(
                    {'base_change': self.lmfdb_label},
                    projection={
                        'label': True,
                        '_id': False
                    })
            ]
            bcfs = [lab.split("-")[0] for lab in bcs]
            for F, T in tg.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'])
            data['ntgx'] = len(tgextra)
            lastd = 1
            for tg in tgextra:
                d = tg['d']
                if d != lastd:
                    tg['m'] = len([x for x in tgextra if x['d'] == d])
                    lastd = d
            data['tg_maxd'] = max(db_ecstats().find_one(
                {'_id': 'torsion_growth'})['degrees'])

        except AttributeError:
            pass  # we have no torsion growth data

        data['newform'] = web_latex(
            PowerSeriesRing(QQ, 'q')(data['an'], 20, check=True))
        data['newform_label'] = self.newform_label = newform_label(
            cond, 2, 1, iso)
        self.newform_link = url_for("emf.render_elliptic_modular_forms",
                                    level=cond,
                                    weight=2,
                                    character=1,
                                    label=iso)
        self.newform_exists_in_db = is_newform_in_db(self.newform_label)
        self._code = None

        self.class_url = url_for(".by_double_iso_label",
                                 conductor=N,
                                 iso_label=iso)
        self.friends = [('Isogeny class ' + self.lmfdb_iso, self.class_url),
                        ('Minimal quadratic twist %s %s' %
                         (data['minq_info'], data['minq_label']),
                         url_for(".by_triple_label",
                                 conductor=minq_N,
                                 iso_label=minq_iso,
                                 number=minq_number)),
                        ('All twists ',
                         url_for(".rational_elliptic_curves", jinv=self.jinv)),
                        ('L-function',
                         url_for("l_functions.l_function_ec_page",
                                 conductor_label=N,
                                 isogeny_class_label=iso))]
        if not self.cm:
            if N <= 300:
                self.friends += [('Symmetric square L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='2',
                                          conductor=N,
                                          isogeny=iso))]
            if N <= 50:
                self.friends += [('Symmetric cube L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='3',
                                          conductor=N,
                                          isogeny=iso))]
        if self.newform_exists_in_db:
            self.friends += [('Modular form ' + self.newform_label,
                              self.newform_link)]

        self.downloads = [('Download coefficients of q-expansion',
                           url_for(".download_EC_qexp",
                                   label=self.lmfdb_label,
                                   limit=1000)),
                          ('Download all stored data',
                           url_for(".download_EC_all",
                                   label=self.lmfdb_label)),
                          ('Download Magma code',
                           url_for(".ec_code_download",
                                   conductor=cond,
                                   iso=iso,
                                   number=num,
                                   label=self.lmfdb_label,
                                   download_type='magma')),
                          ('Download Sage code',
                           url_for(".ec_code_download",
                                   conductor=cond,
                                   iso=iso,
                                   number=num,
                                   label=self.lmfdb_label,
                                   download_type='sage')),
                          ('Download GP code',
                           url_for(".ec_code_download",
                                   conductor=cond,
                                   iso=iso,
                                   number=num,
                                   label=self.lmfdb_label,
                                   download_type='gp'))]

        try:
            self.plot = encode_plot(self.E.plot())
        except AttributeError:
            self.plot = encode_plot(EllipticCurve(data['ainvs']).plot())

        self.plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(
            self.plot)
        self.properties = [('Label', self.lmfdb_label), (None, self.plot_link),
                           ('Conductor', '\(%s\)' % data['conductor']),
                           ('Discriminant', '\(%s\)' % data['disc']),
                           ('j-invariant', '%s' % data['j_inv_latex']),
                           ('CM', '%s' % data['CM']),
                           ('Rank', '\(%s\)' % mw['rank']),
                           ('Torsion Structure', '\(%s\)' % mw['tor_struct'])]

        self.title = "Elliptic Curve %s (Cremona label %s)" % (
            self.lmfdb_label, self.label)

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso,
                       url_for(".by_double_iso_label",
                               conductor=N,
                               iso_label=iso)), ('%s' % num, ' ')]
Example #30
0
def render_hmf_webpage(**args):
    if 'data' in args:
        data = args['data']
        label = data['label']
    else:
        label = str(args['label'])
        data = get_hmf(label)
    if data is None:
        flash(Markup("Error: <span style='color:black'>%s</span> is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a" % args['label']), "error")
        return search_input_error()
    info = {}
    try:
        info['count'] = args['count']
    except KeyError:
        info['count'] = 50

    hmf_field = get_hmf_field(data['field_label'])
    gen_name = findvar(hmf_field['ideals'])
    nf = WebNumberField(data['field_label'], gen_name=gen_name)
    info['hmf_field'] = hmf_field
    info['field'] = nf
    info['base_galois_group'] = nf.galois_string()
    info['field_degree'] = nf.degree()
    info['field_disc'] = str(nf.disc())
    info['field_poly'] = teXify_pol(str(nf.poly()))

    info.update(data)

    info['downloads'] = [
        ('Modular form to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')),
        ('Eigenvalues to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage'))
        ]


    # figure out friends
    # first try to see if there is an instance of this HMF on Lfun db
    url = 'ModularForm/GL2/TotallyReal/{}/holomorphic/{}'.format(
            info['field_label'],
            info['label'])
    Lfun = get_lfunction_by_url(url)
    if Lfun:
        instances = get_instances_by_Lhash_and_trace_hash(Lfun['Lhash'],
                                                          Lfun['degree'],
                                                          Lfun['trace_hash'])

        # This will also add the EC/G2C, as this how the Lfun was computed
        info['friends'] = names_and_urls(instances, exclude={url})

        info['friends'] += [('L-function',
                            url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))]

    else:
        # if there is no instance
        # old code
        if hmf_field['narrow_class_no'] == 1 and nf.disc()**2 * data['level_norm'] < 40000:
            info['friends'] = [('L-function',
                                url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))]
        else:
            info['friends'] = [('L-function not available', "")]


        if data['dimension'] == 1:   # Try to attach associated elliptic curve
            lab = split_class_label(info['label'])
            ec_from_hmf = db.ec_nfcurves.lookup(label + '1')
            if ec_from_hmf is None:
                info['friends'] += [('Elliptic curve not available', "")]
            else:
                info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))]



    bread = [("Modular Forms", url_for('modular_forms')), ('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")),
        ('%s' % data['label'], ' ')]

    t = "Hilbert Cusp Form %s" % info['label']

    forms_dims = db.hmf_forms.search({'field_label': data['field_label'], 'level_ideal': data['level_ideal']}, projection='dimension')

    info['newspace_dimension'] = sum(forms_dims)

    # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues
    try:
        numeigs = request.args['numeigs']
        numeigs = int(numeigs)
    except:
        numeigs = 20
    info['numeigs'] = numeigs

    hecke_pol  = data['hecke_polynomial']
    eigs       = map(str, data['hecke_eigenvalues'])
    eigs = eigs[:min(len(eigs), numeigs)]
    AL_eigs    = data['AL_eigenvalues']

    primes = hmf_field['primes']
    n = min(len(eigs), len(primes))
    info['eigs'] = [{'eigenvalue': add_space_if_positive(teXify_pol(eigs[i])),
                     'prime_ideal': teXify_pol(primes[i]),
                     'prime_norm': primes[i][1:primes[i].index(',')]} for i in range(n)]

    try:
        display_eigs = request.args['display_eigs']
        if display_eigs in ['True', 'true', '1', 'yes']:
            display_eigs = True
        else:
            display_eigs = False
    except KeyError:
        display_eigs = False

    if 'numeigs' in request.args:
        display_eigs = True

    info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(hecke_pol))

    if not AL_eigs: # empty list
        if data['level_norm']==1: # OK, no bad primes
            info['AL_eigs'] = 'none'
        else:                     # not OK, AL eigs are missing
            info['AL_eigs'] = 'missing'
    else:
        info['AL_eigs'] = [{'eigenvalue': teXify_pol(al[1]),
                            'prime_ideal': teXify_pol(al[0]),
                            'prime_norm': al[0][1:al[0].index(',')]} for al in data['AL_eigenvalues']]

    max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']])
    display_eigs = display_eigs or (max_eig_len<=300)
    info['display_eigs'] = display_eigs
    if not display_eigs:
        for eig in info['eigs']:
            if len(eig['eigenvalue']) > 300:
                eig['eigenvalue'] = '...'

    info['level_ideal'] = teXify_pol(info['level_ideal'])

    if 'is_CM' in data:
        is_CM = data['is_CM']
    else:
        is_CM = '?'
    info['is_CM'] = is_CM

    if 'is_base_change' in data:
        is_base_change = data['is_base_change']
    else:
        is_base_change = '?'
    info['is_base_change'] = is_base_change

    if 'q_expansions' in data:
        info['q_expansions'] = data['q_expansions']

    properties2 = [('Base field', '%s' % info['field'].field_pretty()),
                   ('Weight', '%s' % data['weight']),
                   ('Level norm', '%s' % data['level_norm']),
                   ('Level', '$' + teXify_pol(data['level_ideal']) + '$'),
                   ('Label', '%s' % data['label']),
                   ('Dimension', '%s' % data['dimension']),
                   ('CM', is_CM),
                   ('Base change', is_base_change)
                   ]

    return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties2=properties2, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())
Example #31
0
def render_hmf_webpage(**args):
    if 'data' in args:
        data = args['data']
        label = data['label']
    else:
        label = str(args['label'])
        data = db_forms().find_one({'label': label})
    if data is None:
        flash(Markup("Error: <span style='color:black'>%s</span> is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a" % args['label']), "error")
        return search_input_error()
    info = {}
    try:
        info['count'] = args['count']
    except KeyError:
        info['count'] = 10

    try:
        numeigs = request.args['numeigs']
        numeigs = int(numeigs)
    except:
        numeigs = 20
    info['numeigs'] = numeigs

    hmf_field = db_fields().find_one({'label': data['field_label']})
    gen_name = findvar(hmf_field['ideals'])
    nf = WebNumberField(data['field_label'], gen_name=gen_name)
    info['hmf_field'] = hmf_field
    info['field'] = nf
    info['base_galois_group'] = nf.galois_string()
    info['field_degree'] = nf.degree()
    info['field_disc'] = str(nf.disc())
    info['field_poly'] = teXify_pol(str(nf.poly()))

    info.update(data)

    info['downloads'] = [
        ('Download to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')),
        ('Download to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage'))
        ]
    if hmf_field['narrow_class_no'] == 1 and nf.disc()**2 * data['level_norm'] < 40000:
        info['friends'] = [('L-function',
                            url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))]
    else:
        info['friends'] = [('L-function not available', "")]
    if data['dimension'] == 1:   # Try to attach associated elliptic curve
        lab = split_class_label(info['label'])
        ec_from_hmf = db_ecnf().find_one({"label": label + '1'})
        if ec_from_hmf == None:
            info['friends'] += [('Elliptic curve not available', "")]
        else:
            info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))]

    bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('%s' % data[
                                                                                         'label'], ' ')]

    t = "Hilbert Cusp Form %s" % info['label']

    forms_space = db_search().find(
        {'field_label': data['field_label'], 'level_ideal': data['level_ideal']},{'dimension':True})
    dim_space = 0
    for v in forms_space:
        dim_space += v['dimension']

    info['newspace_dimension'] = dim_space

    eigs = data['hecke_eigenvalues']
    eigs = eigs[:min(len(eigs), numeigs)]

    primes = hmf_field['primes']
    n = min(len(eigs), len(primes))
    info['eigs'] = [{'eigenvalue': teXify_pol(eigs[i]),
                     'prime_ideal': teXify_pol(primes[i]),
                     'prime_norm': primes[i][1:primes[i].index(',')]} for i in range(n)]

    try:
        display_eigs = request.args['display_eigs']
        if display_eigs in ['True', 'true', '1', 'yes']:
            display_eigs = True
        else:
            display_eigs = False
    except KeyError:
        display_eigs = False

    if 'numeigs' in request.args:
        display_eigs = True

    info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(info['hecke_polynomial']))

    if 'AL_eigenvalues_fixed' in data:
        if data['AL_eigenvalues_fixed'] == 'done':
            info['AL_eigs'] = [{'eigenvalue': teXify_pol(al[1]),
                                'prime_ideal': teXify_pol(al[0]),
                                'prime_norm': al[0][1:al[0].index(',')]} for al in data['AL_eigenvalues']]
        else:
            info['AL_eigs'] = [{'eigenvalue': '?', 'prime_ideal': '?'}]
    else:
        info['AL_eigs'] = [{'eigenvalue': '?', 'prime_ideal': '?'}]
    info['AL_eigs_count'] = len(info['AL_eigs']) != 0

    max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']])
    display_eigs = display_eigs or (max_eig_len<=300)
    info['display_eigs'] = display_eigs
    if not display_eigs:
        for eig in info['eigs']:
            if len(eig['eigenvalue']) > 300:
                eig['eigenvalue'] = '...'
        for eig in info['AL_eigs']:
            if len(eig['eigenvalue']) > 300:
                eig['eigenvalue'] = '...'

    info['level_ideal'] = teXify_pol(info['level_ideal'])

    if 'is_CM' in data:
        is_CM = data['is_CM']
    else:
        is_CM = '?'
    info['is_CM'] = is_CM

    if 'is_base_change' in data:
        is_base_change = data['is_base_change']
    else:
        is_base_change = '?'
    info['is_base_change'] = is_base_change

    if 'q_expansions' in data:
        info['q_expansions'] = data['q_expansions']

    properties2 = [('Base field', '%s' % info['field'].field_pretty()),
                   ('Weight', '%s' % data['weight']),
                   ('Level norm', '%s' % data['level_norm']),
                   ('Level', '$' + teXify_pol(data['level_ideal']) + '$'),
                   ('Label', '%s' % data['label']),
                   ('Dimension', '%s' % data['dimension']),
                   ('CM', is_CM),
                   ('Base change', is_base_change)
                   ]

    return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties2=properties2, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())
Example #32
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_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
Example #33
0
 def trace_expansion(self, prec_max=10):
     prec = min(self.texp_prec, prec_max)
     s = web_latex_split_on_pm(web_latex(coeff_to_power_series(self.texp[:prec], prec=prec), enclose=False))
     if too_big(self.texp[:prec], 10**24):
         s = make_bigint(s)
     return s
Example #34
0
def render_field_webpage(args):
    data = None
    info = {}
    bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]

    # This function should not be called unless label is set.
    label = clean_input(args['label'])
    nf = WebNumberField(label)
    data = {}
    if nf.is_null():
        bread.append(('Search Results', ' '))
        info['err'] = 'There is no field with label %s in the database' % label
        info['label'] = args['label_orig'] if 'label_orig' in args else args[
            'label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number_latex()
    ram_primes = nf.ramified_primes()
    t = nf.galois_t()
    n = nf.degree()
    data['is_galois'] = nf.is_galois()
    data['is_abelian'] = nf.is_abelian()
    if nf.is_abelian():
        conductor = nf.conductor()
        data['conductor'] = conductor
        dirichlet_chars = nf.dirichlet_group()
        if len(dirichlet_chars) > 0:
            data['dirichlet_group'] = [
                '<a href = "%s">$\chi_{%s}(%s,&middot;)$</a>' %
                (url_for('characters.render_Dirichletwebpage',
                         modulus=data['conductor'],
                         number=j), data['conductor'], j)
                for j in dirichlet_chars
            ]
            data['dirichlet_group'] = r'$\lbrace$' + ', '.join(
                data['dirichlet_group']) + r'$\rbrace$'
        if data['conductor'].is_prime() or data['conductor'] == 1:
            data['conductor'] = "\(%s\)" % str(data['conductor'])
        else:
            factored_conductor = factor_base_factor(data['conductor'],
                                                    ram_primes)
            factored_conductor = factor_base_factorization_latex(
                factored_conductor)
            data['conductor'] = "\(%s=%s\)" % (str(
                data['conductor']), factored_conductor)
    data['galois_group'] = group_display_knowl(n, t)
    data['cclasses'] = cclasses_display_knowl(n, t)
    data['character_table'] = character_table_display_knowl(n, t)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    data['coefficients'] = nf.coeffs()
    nf.make_code_snippets()
    D = nf.disc()
    data['disc_factor'] = nf.disc_factored_latex()
    if D.abs().is_prime() or D == 1:
        data['discriminant'] = "\(%s\)" % str(D)
    else:
        data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor'])
    data['frob_data'], data['seeram'] = frobs(nf)
    # Bad prime information
    npr = len(ram_primes)
    ramified_algebras_data = nf.ramified_algebras_data()
    if isinstance(ramified_algebras_data, str):
        loc_alg = ''
    else:
        # [label, latex, e, f, c, gal]
        loc_alg = ''
        for j in range(npr):
            if ramified_algebras_data[j] is None:
                loc_alg += '<tr><td>%s<td colspan="7">Data not computed' % str(
                    ram_primes[j])
            else:
                mydat = ramified_algebras_data[j]
                p = ram_primes[j]
                loc_alg += '<tr><td rowspan="%d">$%s$</td>' % (len(mydat),
                                                               str(p))
                mm = mydat[0]
                myurl = url_for('local_fields.by_label', label=mm[0])
                lab = mm[0]
                if mm[3] * mm[2] == 1:
                    lab = r'$\Q_{%s}$' % str(p)
                loc_alg += '<td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$' % (
                    myurl, lab, mm[1], mm[2], mm[3], mm[4], mm[5],
                    show_slope_content(mm[8], mm[6], mm[7]))
                for mm in mydat[1:]:
                    lab = mm[0]
                    if mm[3] * mm[2] == 1:
                        lab = r'$\Q_{%s}$' % str(p)
                    loc_alg += '<tr><td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$' % (
                        myurl, lab, mm[1], mm[2], mm[3], mm[4], mm[5],
                        show_slope_content(mm[8], mm[6], mm[7]))
        loc_alg += '</tbody></table>'

    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['phrase'] = group_phrase(n, t)
    zk = nf.zk()
    Ra = PolynomialRing(QQ, 'a')
    zk = [latex(Ra(x)) for x in zk]
    zk = ['$%s$' % x for x in zk]
    zk = ', '.join(zk)
    grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh(
    ) else ''
    # Short version for properties
    grh_lab = nf.short_grh_string()
    if 'Not' in str(data['class_number']):
        grh_lab = ''
        grh_label = ''
    pretty_label = field_pretty(label)
    if label != pretty_label:
        pretty_label = "%s: %s" % (label, pretty_label)

    info.update(data)
    if nf.degree() > 1:
        gpK = nf.gpK()
        rootof1coeff = gpK.nfrootsof1()
        rootofunityorder = int(rootof1coeff[1])
        rootof1coeff = rootof1coeff[2]
        rootofunity = web_latex(
            Ra(
                str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace(
                    'x', 'a')))
        rootofunity += ' (order $%d$)' % rootofunityorder
    else:
        rootofunity = web_latex(Ra('-1')) + ' (order $2$)'

    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.poly()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': rootofunity,
        'fund_units': nf.units(),
        'grh_label': grh_label,
        'loc_alg': loc_alg
    })

    bread.append(('%s' % info['label_raw'], ' '))
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    info['friends'] = []
    if nf.can_class_number():
        # hide ones that take a lond time to compute on the fly
        # note that the first degree 4 number field missed the zero of the zeta function
        if abs(D**n) < 50000000:
            info['friends'].append(('L-function', "/L/NumberField/%s" % label))
    info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t)))
    if 'dirichlet_group' in info:
        info['friends'].append(('Dirichlet character group',
                                url_for("characters.dirichlet_group_table",
                                        modulus=int(conductor),
                                        char_number_list=','.join(
                                            [str(a) for a in dirichlet_chars]),
                                        poly=info['polynomial'])))
    resinfo = []
    galois_closure = nf.galois_closure()
    if galois_closure[0] > 0:
        if len(galois_closure[1]) > 0:
            resinfo.append(('gc', galois_closure[1]))
            if len(galois_closure[2]) > 0:
                info['friends'].append(('Galois closure',
                                        url_for(".by_label",
                                                label=galois_closure[2][0])))
        else:
            resinfo.append(('gc', [dnc]))

    sextic_twins = nf.sextic_twin()
    if sextic_twins[0] > 0:
        if len(sextic_twins[1]) > 0:
            resinfo.append(('sex', r' $\times$ '.join(sextic_twins[1])))
        else:
            resinfo.append(('sex', dnc))

    siblings = nf.siblings()
    # [degsib list, label list]
    # first is list of [deg, num expected, list of knowls]
    if len(siblings[0]) > 0:
        for sibdeg in siblings[0]:
            if len(sibdeg[2]) == 0:
                sibdeg[2] = dnc
            else:
                sibdeg[2] = ', '.join(sibdeg[2])
                if len(sibdeg[2]) < sibdeg[1]:
                    sibdeg[2] += ', some ' + dnc

        resinfo.append(('sib', siblings[0]))
        for lab in siblings[1]:
            if lab != '':
                labparts = lab.split('.')
                info['friends'].append(("Degree %s sibling" % labparts[0],
                                        url_for(".by_label", label=lab)))

    arith_equiv = nf.arith_equiv()
    if arith_equiv[0] > 0:
        if len(arith_equiv[1]) > 0:
            resinfo.append(
                ('ae', ', '.join(arith_equiv[1]), len(arith_equiv[1])))
            for aelab in arith_equiv[2]:
                info['friends'].append(('Arithmetically equivalent sibling',
                                        url_for(".by_label", label=aelab)))
        else:
            resinfo.append(('ae', dnc, len(arith_equiv[1])))

    info['resinfo'] = resinfo
    learnmore = learnmore_list()
    #if info['signature'] == [0,1]:
    #    info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data")))
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

    if npr == 1:
        primes = 'prime'
    else:
        primes = 'primes'

    properties2 = [('Label', label), ('Degree', '$%s$' % data['degree']),
                   ('Signature', '$%s$' % data['signature']),
                   ('Discriminant', '$%s$' % data['disc_factor']),
                   ('Ramified ' + primes + '', '$%s$' % ram_primes),
                   ('Class number', '%s %s' % (data['class_number'], grh_lab)),
                   ('Class group',
                    '%s %s' % (data['class_group_invs'], grh_lab)),
                   ('Galois Group', group_display_short(data['degree'], t))]
    downloads = []
    for lang in [["Magma", "magma"], ["SageMath", "sage"], ["Pari/GP", "gp"]]:
        downloads.append(('Download {} code'.format(lang[0]),
                          url_for(".nf_code_download",
                                  nf=label,
                                  download_type=lang[1])))
    from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup
    try:
        info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs'])
        v = nf.factor_perm_repn(info["tim_number_field"])

        def dopow(m):
            if m == 0: return ''
            if m == 1: return '*'
            return '*<sup>%d</sup>' % m

        info["mydecomp"] = [dopow(x) for x in v]
    except AttributeError:
        pass
    return render_template("number_field.html",
                           properties2=properties2,
                           credit=NF_credit,
                           title=title,
                           bread=bread,
                           code=nf.code,
                           friends=info.pop('friends'),
                           downloads=downloads,
                           learnmore=learnmore,
                           info=info)
Example #35
0
def print_q_expansion(list):
    list = [str(c) for c in list]
    Qb = PolynomialRing(QQ, 'b')
    b = QQ['b'].gen()
    Qq = PowerSeriesRing(Qb['a'], 'q')
    return web_latex_split_on_pm(Qq([c for c in list]).add_bigoh(len(list)))
Example #36
0
def render_hmf_webpage(**args):
    if 'data' in args:
        data = args['data']
        label = data['label']
    else:
        label = str(args['label'])
        data = get_hmf(label)
    if data is None:
        flash_error(
            "%s is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a",
            args['label'])
        return search_input_error()
    info = {}
    try:
        info['count'] = args['count']
    except KeyError:
        info['count'] = 50

    hmf_field = get_hmf_field(data['field_label'])
    gen_name = findvar(hmf_field['ideals'])
    nf = WebNumberField(data['field_label'], gen_name=gen_name)
    info['hmf_field'] = hmf_field
    info['field'] = nf
    info['base_galois_group'] = nf.galois_string()
    info['field_degree'] = nf.degree()
    info['field_disc'] = str(nf.disc())
    info['field_poly'] = teXify_pol(str(nf.poly()))

    info.update(data)

    info['downloads'] = [('Modular form to Magma',
                          url_for(".render_hmf_webpage_download",
                                  field_label=info['field_label'],
                                  label=info['label'],
                                  download_type='magma')),
                         ('Eigenvalues to Sage',
                          url_for(".render_hmf_webpage_download",
                                  field_label=info['field_label'],
                                  label=info['label'],
                                  download_type='sage'))]

    # figure out friends
    # first try to see if there is an instance of this HMF on Lfun db
    url = 'ModularForm/GL2/TotallyReal/{}/holomorphic/{}'.format(
        info['field_label'], info['label'])
    Lfun = get_lfunction_by_url(url)
    if Lfun:
        instances = get_instances_by_Lhash_and_trace_hash(
            Lfun['Lhash'], Lfun['degree'], Lfun['trace_hash'])

        # This will also add the EC/G2C, as this how the Lfun was computed
        info['friends'] = names_and_urls(instances, exclude={url})

        info['friends'] += [('L-function',
                             url_for("l_functions.l_function_hmf_page",
                                     field=info['field_label'],
                                     label=info['label'],
                                     character='0',
                                     number='0'))]

    else:
        # if there is no instance
        # old code
        if hmf_field['narrow_class_no'] == 1 and nf.disc(
        )**2 * data['level_norm'] < 40000:
            info['friends'] = [('L-function',
                                url_for("l_functions.l_function_hmf_page",
                                        field=info['field_label'],
                                        label=info['label'],
                                        character='0',
                                        number='0'))]
        else:
            info['friends'] = [('L-function not available', "")]

        if data['dimension'] == 1:  # Try to attach associated elliptic curve
            lab = split_class_label(info['label'])
            ec_from_hmf = db.ec_nfcurves.lookup(label + '1')
            if ec_from_hmf is None:
                info['friends'] += [('Elliptic curve not available', "")]
            else:
                info['friends'] += [('Isogeny class ' + info['label'],
                                     url_for("ecnf.show_ecnf_isoclass",
                                             nf=lab[0],
                                             conductor_label=lab[1],
                                             class_label=lab[2]))]

    bread = [("Modular Forms", url_for('modular_forms')),
             ('Hilbert Modular Forms',
              url_for(".hilbert_modular_form_render_webpage")),
             ('%s' % data['label'], ' ')]

    t = "Hilbert Cusp Form %s" % info['label']

    forms_dims = db.hmf_forms.search(
        {
            'field_label': data['field_label'],
            'level_ideal': data['level_ideal']
        },
        projection='dimension')

    info['newspace_dimension'] = sum(forms_dims)

    # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues
    try:
        numeigs = request.args['numeigs']
        numeigs = int(numeigs)
    except:
        numeigs = 20
    info['numeigs'] = numeigs

    hecke_pol = data['hecke_polynomial']
    eigs = map(str, data['hecke_eigenvalues'])
    eigs = eigs[:min(len(eigs), numeigs)]
    AL_eigs = data['AL_eigenvalues']

    primes = hmf_field['primes']
    n = min(len(eigs), len(primes))
    info['eigs'] = [{
        'eigenvalue': add_space_if_positive(teXify_pol(eigs[i])),
        'prime_ideal': teXify_pol(primes[i]),
        'prime_norm': primes[i][1:primes[i].index(',')]
    } for i in range(n)]

    try:
        display_eigs = request.args['display_eigs']
        if display_eigs in ['True', 'true', '1', 'yes']:
            display_eigs = True
        else:
            display_eigs = False
    except KeyError:
        display_eigs = False

    if 'numeigs' in request.args:
        display_eigs = True

    info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(hecke_pol))

    if not AL_eigs:  # empty list
        if data['level_norm'] == 1:  # OK, no bad primes
            info['AL_eigs'] = 'none'
        else:  # not OK, AL eigs are missing
            info['AL_eigs'] = 'missing'
    else:
        info['AL_eigs'] = [{
            'eigenvalue': teXify_pol(al[1]),
            'prime_ideal': teXify_pol(al[0]),
            'prime_norm': al[0][1:al[0].index(',')]
        } for al in data['AL_eigenvalues']]

    max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']])
    display_eigs = display_eigs or (max_eig_len <= 300)
    info['display_eigs'] = display_eigs
    if not display_eigs:
        for eig in info['eigs']:
            if len(eig['eigenvalue']) > 300:
                eig['eigenvalue'] = '...'

    info['level_ideal'] = teXify_pol(info['level_ideal'])

    if 'is_CM' in data:
        is_CM = data['is_CM']
    else:
        is_CM = '?'
    info['is_CM'] = is_CM

    if 'is_base_change' in data:
        is_base_change = data['is_base_change']
    else:
        is_base_change = '?'
    info['is_base_change'] = is_base_change

    if 'q_expansions' in data:
        info['q_expansions'] = data['q_expansions']

    properties2 = [('Base field', '%s' % info['field'].field_pretty()),
                   ('Weight', '%s' % data['weight']),
                   ('Level norm', '%s' % data['level_norm']),
                   ('Level', '$' + teXify_pol(data['level_ideal']) + '$'),
                   ('Label', '%s' % data['label']),
                   ('Dimension', '%s' % data['dimension']), ('CM', is_CM),
                   ('Base change', is_base_change)]

    return render_template("hilbert_modular_form.html",
                           downloads=info["downloads"],
                           info=info,
                           properties2=properties2,
                           credit=hmf_credit,
                           title=t,
                           bread=bread,
                           friends=info['friends'],
                           learnmore=learnmore_list())
Example #37
0
 def trace_expansion(self, prec_max=10):
     prec = min(self.texp_prec, prec_max)
     return web_latex_split_on_pm(web_latex(coeff_to_power_series(self.texp[:prec], prec=prec), enclose=False))
Example #38
0
 def trace_expansion(self, prec_max=10):
     prec = min(len(self.traces) + 1, prec_max)
     return web_latex_split_on_pm(
         web_latex(coeff_to_power_series([0] + self.traces[:prec - 1],
                                         prec=prec),
                   enclose=False))
Example #39
0
def render_hmf_webpage(**args):
    if 'data' in args:
        data = args['data']
        label = data['label']
    else:
        label = str(args['label'])
        data = get_hmf(label)
    if data is None:
        flash(
            Markup(
                "Error: <span style='color:black'>%s</span> is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a"
                % args['label']), "error")
        return search_input_error()
    info = {}
    try:
        info['count'] = args['count']
    except KeyError:
        info['count'] = 10

    hmf_field = get_hmf_field(data['field_label'])
    gen_name = findvar(hmf_field['ideals'])
    nf = WebNumberField(data['field_label'], gen_name=gen_name)
    info['hmf_field'] = hmf_field
    info['field'] = nf
    info['base_galois_group'] = nf.galois_string()
    info['field_degree'] = nf.degree()
    info['field_disc'] = str(nf.disc())
    info['field_poly'] = teXify_pol(str(nf.poly()))

    info.update(data)

    info['downloads'] = [('Download to Magma',
                          url_for(".render_hmf_webpage_download",
                                  field_label=info['field_label'],
                                  label=info['label'],
                                  download_type='magma')),
                         ('Download to Sage',
                          url_for(".render_hmf_webpage_download",
                                  field_label=info['field_label'],
                                  label=info['label'],
                                  download_type='sage'))]
    if hmf_field['narrow_class_no'] == 1 and nf.disc(
    )**2 * data['level_norm'] < 40000:
        info['friends'] = [('L-function',
                            url_for("l_functions.l_function_hmf_page",
                                    field=info['field_label'],
                                    label=info['label'],
                                    character='0',
                                    number='0'))]
    else:
        info['friends'] = [('L-function not available', "")]
    if data['dimension'] == 1:  # Try to attach associated elliptic curve
        lab = split_class_label(info['label'])
        ec_from_hmf = db_ecnf().find_one({"label": label + '1'})
        if ec_from_hmf == None:
            info['friends'] += [('Elliptic curve not available', "")]
        else:
            info['friends'] += [('Isogeny class ' + info['label'],
                                 url_for("ecnf.show_ecnf_isoclass",
                                         nf=lab[0],
                                         conductor_label=lab[1],
                                         class_label=lab[2]))]

    bread = [('Hilbert Modular Forms',
              url_for(".hilbert_modular_form_render_webpage")),
             ('%s' % data['label'], ' ')]

    t = "Hilbert Cusp Form %s" % info['label']

    forms_space = db_search().find(
        {
            'field_label': data['field_label'],
            'level_ideal': data['level_ideal']
        }, {'dimension': True})
    dim_space = 0
    for v in forms_space:
        dim_space += v['dimension']

    info['newspace_dimension'] = dim_space

    # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues
    try:
        numeigs = request.args['numeigs']
        numeigs = int(numeigs)
    except:
        numeigs = 20
    info['numeigs'] = numeigs

    hecke_pol = data['hecke_polynomial']
    eigs = data['hecke_eigenvalues']
    eigs = eigs[:min(len(eigs), numeigs)]
    AL_eigs = data['AL_eigenvalues']

    primes = hmf_field['primes']
    n = min(len(eigs), len(primes))
    info['eigs'] = [{
        'eigenvalue': teXify_pol(eigs[i]),
        'prime_ideal': teXify_pol(primes[i]),
        'prime_norm': primes[i][1:primes[i].index(',')]
    } for i in range(n)]

    try:
        display_eigs = request.args['display_eigs']
        if display_eigs in ['True', 'true', '1', 'yes']:
            display_eigs = True
        else:
            display_eigs = False
    except KeyError:
        display_eigs = False

    if 'numeigs' in request.args:
        display_eigs = True

    info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(hecke_pol))

    if not AL_eigs:  # empty list
        if data['level_norm'] == 1:  # OK, no bad primes
            info['AL_eigs'] = 'none'
        else:  # not OK, AL eigs are missing
            info['AL_eigs'] = 'missing'
    else:
        info['AL_eigs'] = [{
            'eigenvalue': teXify_pol(al[1]),
            'prime_ideal': teXify_pol(al[0]),
            'prime_norm': al[0][1:al[0].index(',')]
        } for al in data['AL_eigenvalues']]

    max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']])
    display_eigs = display_eigs or (max_eig_len <= 300)
    info['display_eigs'] = display_eigs
    if not display_eigs:
        for eig in info['eigs']:
            if len(eig['eigenvalue']) > 300:
                eig['eigenvalue'] = '...'

    info['level_ideal'] = teXify_pol(info['level_ideal'])

    if 'is_CM' in data:
        is_CM = data['is_CM']
    else:
        is_CM = '?'
    info['is_CM'] = is_CM

    if 'is_base_change' in data:
        is_base_change = data['is_base_change']
    else:
        is_base_change = '?'
    info['is_base_change'] = is_base_change

    if 'q_expansions' in data:
        info['q_expansions'] = data['q_expansions']

    properties2 = [('Base field', '%s' % info['field'].field_pretty()),
                   ('Weight', '%s' % data['weight']),
                   ('Level norm', '%s' % data['level_norm']),
                   ('Level', '$' + teXify_pol(data['level_ideal']) + '$'),
                   ('Label', '%s' % data['label']),
                   ('Dimension', '%s' % data['dimension']), ('CM', is_CM),
                   ('Base change', is_base_change)]

    return render_template("hilbert_modular_form.html",
                           downloads=info["downloads"],
                           info=info,
                           properties2=properties2,
                           credit=hmf_credit,
                           title=t,
                           bread=bread,
                           friends=info['friends'],
                           learnmore=learnmore_list())