예제 #1
0
 def download_newform(self, label, lang='text'):
     data = db.mf_newforms.lookup(label)
     if data is None:
         return abort(404, "Label not found: %s" % label)
     form = WebNewform(data)
     form.setup_cc_data({'m': '1-%s' % form.dim})
     if form.has_exact_qexp:
         data['qexp'] = form.qexp
         data['traces'] = form.texp
     if form.has_complex_qexp:
         data['complex_embeddings'] = form.cc_data
     return self._wrap(Json.dumps(data),
                       label,
                       lang=lang,
                       title='Stored data for newform %s,' % (label))
예제 #2
0
파일: download.py 프로젝트: LMFDB/lmfdb
 def download_newform(self, label, lang='text'):
     data = db.mf_newforms.lookup(label)
     if data is None:
         return abort(404, "Label not found: %s"%label)
     form = WebNewform(data)
     form.setup_cc_data({'m':'1-%s'%form.dim})
     if form.has_exact_qexp:
         data['qexp'] = form.qexp
         data['traces'] = form.texp
     if form.has_complex_qexp:
         data['complex_embeddings'] = form.cc_data
     return self._wrap(Json.dumps(data),
                       label,
                       lang=lang,
                       title='Stored data for newform %s,'%(label))
예제 #3
0
def galois_rep_from_path(p):
    if p[0]=='EllipticCurve':
        # create the sage elliptic curve then create Galois rep object
        ainvs = db.ec_curves.lucky({'lmfdb_label':p[2]+"."+p[3]+p[4]}, 'ainvs')
        E = EllipticCurve(ainvs)
        return GaloisRepresentation(E)

    elif (p[0]=='Character' and p[1]=='Dirichlet'):
        dirichletArgs = {'type':'Dirichlet', 'modulus':int(p[2]), 'number':int(p[3])}
        chi = WebDirichletCharacter(**dirichletArgs)
        return GaloisRepresentation(chi)
 
    elif (p[0]=='ModularForm'):
        level = int(p[4])
        weight = int(p[5])
        conrey_label = p[6] # this should be zero; TODO check this is the case
        hecke_orbit = p[7] # this is a, b, c, etc.; chooses the galois orbit
        embedding = p[8] # this is the embedding of that galois orbit
        label = convert_newformlabel_from_conrey(str(level)+"."+str(weight)+"."+str(conrey_label)+"."+hecke_orbit)
        form = WebNewform(label)
        return GaloisRepresentation([form, ZZ(embedding)])

    elif (p[0]=='ArtinRepresentation'):
        dim = p[1]
        conductor = p[2]
        index = p[3]
        rho = ArtinRepresentation(dim, conductor, index)
        return GaloisRepresentation(rho)
    else:
        return
예제 #4
0
    def download_newform_to_magma(self, label, lang='magma'):
        data = db.mf_newforms.lookup(label)
        if data is None:
            return abort(404, "Label not found: %s" % label)
        newform = WebNewform(data)
        hecke_nf = self._get_hecke_nf(label)

        out = []
        newlines = [''] * 2
        if newform.has_exact_qexp:
            out += self._magma_ConvertToHeckeField(newform,
                                                   hecke_nf) + newlines

        out += self._magma_MakeCharacters(newform, hecke_nf) + newlines

        if newform.has_exact_qexp:
            # to return errors
            # this line will never be ran if the data is correct
            if not isinstance(hecke_nf, dict):  # pragma: no cover
                return hecke_nf  # pragma: no cover
            out += self._magma_ExtendMultiplicatively() + newlines
            out += self._magma_qexpCoeffs(newform, hecke_nf) + newlines

            # The Sturm bound is not enough precision; see Github issue 4354
            # prec = db.mf_newspaces.lucky({'label': newform.space_label}, 'sturm_bound')
            out += self._magma_MakeNewformModFrm(newform, hecke_nf) + newlines
        if newform.hecke_cutters is not None and newform.weight > 1:
            out += self._magma_MakeNewformModSym(newform, hecke_nf)

        outstr = "\n".join(out)

        return self._wrap(outstr,
                          label,
                          lang=lang,
                          title='Make newform %s in Magma,' % (label))
예제 #5
0
 def download_newform(self, label, lang='text'):
     data = db.mf_newforms.lookup(label)
     if data is None:
         return abort(404, "Label not found: %s" % label)
     form = WebNewform(data)
     if form.has_exact_qexp:
         data['qexp'] = form.qexp
         data['traces'] = form.texp
     return self._wrap(Json.dumps(data),
                       label,
                       lang=lang,
                       title='Stored data for newform %s,' % (label))
예제 #6
0
def windingelement_hecke_cutter_projected(data, extra_cutter_bound=None):
    "Creates winding element projected to the subspace where the hecke cutter condition of the data is satisfied"
    M = modular_symbols_ambient_from_lmfdb_mf(data)
    #dim = M.dimension()
    S = M.cuspidal_subspace()
    K = M.base_ring()
    R = PolynomialRing(K, "x")
    cutters = data[u'hecke_cutters']
    cutters_maxp = cutters[-1][0] if cutters else 1
    weight = data[u'weight']
    assert weight % 2 == 0
    cuts_eisenstein = False
    winding_element = M.modular_symbol([weight // 2 - 1, 0, oo]).element()

    if extra_cutter_bound:
        N = data[u'level']
        wn = WebNewform(data)
        #qexp = qexp_as_nf_elt(wn,prec=extra_cutter_bound)
        for p in prime_range(cutters_maxp, extra_cutter_bound):
            if N % p == 0:
                continue
            cutters.append([p, qexp_as_nf_elt(wn)[p].minpoly().list()])

    for c in cutters:
        p = c[0]
        fM = M.hecke_polynomial(p)
        fS = S.hecke_polynomial(p)
        cutter = gcd(R(c[1]), fS)
        assert not cutter.is_constant()
        for cp, ce in cutter.factor():
            assert ce == 1
            e = fM.valuation(cp)
            if fS.valuation(cp) == e:
                cuts_eisenstein = True
            winding_element = polynomial_matrix_apply(fM // cp**e,
                                                      M.hecke_matrix(p),
                                                      winding_element)
            if winding_element == 0:
                return winding_element
            #print fS.valuation(cp),fM.valuation(cp),ce

        assert cuts_eisenstein
    return winding_element
예제 #7
0
def render_newform_webpage(label):
    try:
        newform = WebNewform.by_label(label)
    except (KeyError, ValueError) as err:
        return abort(404, err.args)
    info = to_dict(request.args)
    info['format'] = info.get('format',
                              'embed' if newform.dim > 1 else 'satake')
    p, maxp = 2, 10
    if info['format'] in ['satake', 'satake_angle']:
        while p <= maxp:
            if newform.level % p == 0:
                maxp = next_prime(maxp)
            p = next_prime(p)
    errs = []
    info['n'] = info.get('n', '2-%s' % maxp)
    try:
        info['CC_n'] = integer_options(info['n'], 1000)
    except (ValueError, TypeError) as err:
        info['n'] = '2-%s' % maxp
        info['CC_n'] = range(2, maxp + 1)
        if err.args and err.args[0] == 'Too many options':
            errs.append(r"Only \(a_n\) up to %s are available" %
                        (newform.cqexp_prec - 1))
        else:
            errs.append(
                "<span style='color:black'>n</span> must be an integer, range of integers or comma separated list of integers"
            )
    maxm = min(newform.dim, 20)
    info['m'] = info.get('m', '1-%s' % maxm)
    try:
        info['CC_m'] = integer_options(info['m'], 1000)
    except (ValueError, TypeError) as err:
        info['m'] = '1-%s' % maxm
        info['CC_m'] = range(1, maxm + 1)
        if err.args and err.args[0] == 'Too many options':
            errs.append(
                'Web interface only supports 1000 embeddings at a time.  Use download link to get more (may take some time).'
            )
        else:
            errs.append(
                "<span style='color:black'>Embeddings</span> must be an integer, range of integers or comma separated list of integers"
            )
    try:
        info['prec'] = int(info.get('prec', 6))
        if info['prec'] < 1 or info['prec'] > 15:
            raise ValueError
    except (ValueError, TypeError):
        info['prec'] = 6
        errs.append(
            "<span style='color:black'>Precision</span> must be a positive integer, at most 15 (for higher precision, use the download button)"
        )
    newform.setup_cc_data(info)
    if newform.cqexp_prec != 0 and max(info['CC_n']) >= newform.cqexp_prec:
        errs.append(r"Only \(a_n\) up to %s are available" %
                    (newform.cqexp_prec - 1))
    if errs:
        flash(Markup("<br>".join(errs)), "error")
    return render_template("cmf_newform.html",
                           info=info,
                           newform=newform,
                           properties2=newform.properties,
                           downloads=newform.downloads,
                           credit=credit(),
                           bread=newform.bread,
                           learnmore=learnmore_list(),
                           title=newform.title,
                           friends=newform.friends)
def get_forms(N, k, ell, max_dim=50, verbose=False):
    """
    Input: N (level), k (weight), ell (prime); and a verbosity flag

    Output: 2 lists of newforms of level N, weight k, whose character
    chi has order compatible with ell.

    (1) forms for which we have the Hecke field and which have at
    least one mod-ell reduction.  The reductions are stored as an
    attribute (.reductions) for each of these newforms.

    (2) forms for which we do not have the Hecke field in the
    database, for which we currently do nothing.

    """
    if N%ell==0:
        return [], []
    nfs  = db.mf_newforms
    heckes = db.mf_hecke_nf # for more ap
    forms  = [WebNewform.by_label(f_label) for f_label in
              nfs.search({'level':N, 'weight':k}, projection='label')]
    if verbose:
        print("forms with (N,k)=({},{}): {}".format(N,k,[f.label for f in forms]))

    # omit forms whose character order is invalid:
    
    forms = [f for f in forms if char_order_valid(f.char_order, ell)]
    if verbose:
        print("After char order check, forms with (N,k,ell)=({},{},{}): {}".format(N,k,ell,[(f.label,f.dim) for f in forms]))

    # for forms with no Hecke field, try to read from a data file

    forms_with_no_field = [f for f in forms if f.field_poly is None]

    if forms_with_no_field:
        if verbose:
            print("Before reading data files, {} forms have no Hecke field data: {}".format(len(forms_with_no_field), [f.label for f in forms_with_no_field]))

        for f in forms:
            if f.field_poly is None and f.dim <= max_dim:
                if verbose:
                    print("looking for a data file for form {}".format(f.label))
                f = get_form_data_from_file(f, max_dim=max_dim, verbose=verbose)

        forms_with_no_field = [(f.label,f.dim,ell) for f in forms if f.field_poly is None]
        if verbose:
            print("After reading data files, {} forms have no Hecke field data".format(len(forms_with_no_field)))

    # Now exclude any forms which still have no Hecke data:

    forms = [f for f in forms if f.field_poly]
    
    # find all mod-ell reduction maps from the Hecke order

    Qx = PolynomialRing(QQ,'x')
    for f in forms:
        f.hecke_field = NumberField(Qx(f.field_poly), 'a_')
        if verbose:
            print("making reductions for {} mod {}".format(f.label, ell))
            print("Hecke field is {}".format(f.hecke_field))
        f.reductions = make_reductions(f, ell, verbose)
        if verbose:
            print("finished making reductions for {} mod {}".format(f.label, ell))

        try:
            assert f.an
        except AttributeError:
            # get extra ap from the second table:
            anap = heckes.lucky({'label':f.label}, projection=['ap','an'])
            f.an = anap['an']
            f.ap = anap['ap']

            if verbose:
                nap = len(f.ap)
                print("Found {} ap and {} an in the second table".format(nap,len(f.an)))
        
    # Exclude forms with no mod-ell reductions:
        
    forms = [f for f in forms if f.reductions]
    if forms and verbose:
        print("{}.{} forms with mod-{} reductions:".format(N,k,ell))
        for f in forms:
            print("{} has {} reductions mod {}".format(f.label,len(f.reductions), ell))

    return forms, forms_with_no_field
예제 #9
0
def paintSvgHoloGeneral(Nmin, Nmax, kmin, kmax, imagewidth, imageheight):
    # the import must be here to avoid circular import
    from lmfdb.classical_modular_forms.web_newform import WebNewform
    from lmfdb.classical_modular_forms.web_space import WebGamma1Space
    xfactor = 90
    yfactor = 30
    extraSpace = 20
    ticlength = 4
    radius = 3.3
    xdotspacing = 0.30  # horizontal spacing of dots
    ydotspacing = 0.11  # vertical spacing of dots
    # colourplus = signtocolour(1) # not used
    # colourminus = signtocolour(-1) # not used
    maxdots = 5  # max number of dots to display

    ans = svgBegin()

    xMax = int(Nmax)
    yMax = int(kmax)
    width = xfactor * xMax + extraSpace
    height = yfactor * yMax + extraSpace

    # make the coordinate system
    ans += paintCSHoloTMP(width, height, xMax, yMax, xfactor, yfactor,
                          ticlength)
    alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

    # create appearanceinfo, common to all points
    appearanceinfo = []

    # loop over levels and weights, using plotsector to put the appropriate dots at each lattice point
    for x in range(int(Nmin), int(Nmax) + 1):  # x is the level
        for y in range(int(kmin), int(kmax) + 1, 2):  # y is the weight
            # lid = "(" + str(x) + "," + str(y) + ")" # not used
            # linkurl = "/L/ModularForm/GL2/Q/holomorphic/" + str(y) + "/" + str(x) + "/1/" # not used
            WS = WebGamma1Space(
                level=x,
                weight=y)  # space of modular forms of weight y, level x
            galois_orbits = WS.decomp  # make a list of Galois orbits
            numlabels = len(galois_orbits)  # one label per Galois orbit
            thelabels = alphabet[
                0:
                numlabels]  # list of labels for the Galois orbits for weight y, level x
            # countplus = 0   # count how many Galois orbits have sign Plus (+ 1) (not used)
            # countminus = 0   # count how many Galois orbits have sign Minus (- 1) (not used)
            # ybaseplus = y  # baseline y-coord for plus cases (not used)
            # ybaseminus = y  # baseline y-coord for minus cases (not used)
            # numpluslabels = 0 # not used
            # numminuslabels = 0 # not used
            # plotsector requires three dictionaries: dimensioninfo, appearanceinfo, and urlinfo
            # create dimensioninfo
            dimensioninfo = {}
            dimensioninfo['offset'] = [0, height]
            dimensioninfo['scale'] = [xfactor, -1 * yfactor]
            dimensioninfo['vertexlocation'] = [x, y]
            dimensioninfo['maxdots'] = maxdots
            dimensioninfo['dotspacing'] = [xdotspacing, ydotspacing]
            dimensioninfo['edge'] = [[0, 1], [1, 0]
                                     ]  # unit vectors defining edges of sector
            # dimensioninfo['edgelength'] = [float(dimensioninfo['scale'][0])/float(Nmax), float(dimensioninfo['scale'][1])/float(kmax)] #add comment
            dimensioninfo['edgelength'] = [0.5, 0.5]
            dimensioninfo['dotradius'] = radius
            dimensioninfo[
                'connectinglinewidth'] = dimensioninfo['dotradius'] / 1.5
            dimensioninfo['firstdotoffset'] = [0.0, 0.0]
            #
            appearanceinfo = {}
            # appearanceinfo['edgewidth'] = dimensioninfo['dotspacing'][0]/1.0  #just a guess
            appearanceinfo['edgewidth'] = [0, 0]  # remove the sector edges
            appearanceinfo['edgestyle'] = 'stroke-dasharray:3,3'
            appearanceinfo['edgecolor'] = 'rgb(202,202,102)'
            appearanceinfo['fontsize'] = 'font-size:11px'
            appearanceinfo['fontweight'] = ""
            #
            urlinfo = {'base': '/L/ModularForm/GL2/Q/holomorphic?'}
            urlinfo['space'] = {'weight': y}
            urlinfo['space']['level'] = x
            urlinfo['space']['character'] = 0
            #
            # scale = 1 # not used
            # Symmetry types: +1 or -1
            symmetrytype = [1, -1]
            for signtmp in symmetrytype:
                # urlinfo['space']['orbits'] = [ [] for label in thelabels ] # initialise
                # an empty list for each orbit
                urlinfo['space']['orbits'] = []
                for label in thelabels:  # looping over Galois orbit: one label per orbit
                    # do '+' case first
                    MF = WebNewform.by_label(
                        label=label
                    )  # one of the Galois orbits for weight y, level x
                    numberwithlabel = MF.degree(
                    )  # number of forms in the Galois orbit
                    if x == 1:  # For level 1, the sign is always plus
                        signfe = 1
                    else:
                        # signfe = -1
                        frickeeigenvalue = prod(MF.atkin_lehner_eigenvalues(
                        ).values())  # gives Fricke eigenvalue
                        signfe = frickeeigenvalue * (-1)**float(
                            y / 2)  # sign of functional equation
                    if signfe == signtmp:  # we find an orbit with sign of "signtmp"
                        if signfe == 1:
                            dimensioninfo['edge'] = [[0, 1], [1, 0]]
                            # unit vectors defining edges of sector for signfe positive
                        else:
                            # dimensioninfo['edge'] = [[0,1],[-1,0]]     # unit vectors defining edges
                            # of sector for signfe negative
                            dimensioninfo['edge'] = [[0, -1], [-1, 0]]
                            # unit vectors defining edges of sector for signfe negative
                        dimensioninfo['dotspacing'] = [
                            signfe * xdotspacing, ydotspacing
                        ]
                        dimensioninfo['firstdotoffset'] = [
                            0.5 * (dimensioninfo['dotspacing'][0] *
                                   dimensioninfo['edge'][0][0] +
                                   dimensioninfo['dotspacing'][1] *
                                   dimensioninfo['edge'][1][0]), 0
                        ]
                        signcolour = signtocolour(signfe)
                        appearanceinfo['edgecolor'] = signcolour
                        orbitdescriptionlist = []
                        for n in range(numberwithlabel):
                            orbitdescriptionlist.append({
                                'label': label,
                                'number': n,
                                'color': signcolour
                            })
                        urlinfo['space']['orbits'].append(orbitdescriptionlist)
                # urlinfo['space']['orbits'][0][0]['color'] = signtocolour(-1)
                # appearanceinfo['orbitcolor'] = 'rgb(102,102,102)'
                    ans += plotsector(dimensioninfo, appearanceinfo, urlinfo)

    ans += svgEnd()
    return (ans)