Example #1
0
def get_number_field_integral_basis(c_string):
    r"""Get the integral basis for the field specified by the string.

    INPUT:
        c_string -- string, a string of comma-separated coefficients with no spaces: the coefficients of the normalized (using gp.polredabs) defining polynomial

    OUTPUT:
        fld_bool -- bool, True if the number field has a page in the LMFDB, False otherwise
        K_new -- number field, the number field with defining polynomial that is the normalized version (given by gp.polredabs) of the one with coefficients specified by c_string
        a -- number field element, generator for K_new
        the integral basis for K_new recorded on its LMFDB page 
    """
    C = getDBconnection()
    c_hash = field_coeffs_string_to_hash(c_string)
    field = C.numberfields.fields.find_one({'coeffhash':c_hash})
    fld_bool = True
    try:
        field['degree']
    except TypeError:
        fld_bool = False
    if fld_bool:
        field_str = field['coeffs']
        int_basis_str = field['zk']
        poly = coeffs_to_poly(field_str)
        K_new = NumberField(poly, names=('a',))
        (a,) = K_new._first_ngens(1)
        return fld_bool, K_new, a, [K_new(eval(preparse(el))) for el in int_basis_str]
    else:
        # could add polynomial to list of number fields missing from LMFDB here
        return fld_bool, None, None, None
Example #2
0
def find_field(pol, verbose=False):
    """
    pol is a string holding a list of coefficients, constant first, 1 last, e.g. '-2,0,1'

    Looks up this defining polynomial kn LMFDB and returns its label, or None
    """
    coeffs = str_to_list(pol)
    deg = len(coeffs)-1
    if deg==2:
        c, b, a = coeffs
        d = ZZ(b*b-4*a*c).squarefree_part()
        D = d if (d-1)%4==0 else 4*d
        absD = D.abs()
        s = 0 if d<0 else 2
        return '2.{}.{}.1'.format(s,absD)

    from lmfdb.number_fields.number_field import poly_to_field_label
    poly = Qx(coeffs)
    Flabel = poly_to_field_label(poly)
    if Flabel==None:
        print("********* field with polynomial {} is not in the database!".format(poly))
        K = NumberField(poly, 'a')
        poly = K.optimized_representation()[0].defining_polynomial()
        print("********* using optimised polynomial {}".format(poly))
        return poly_to_str(poly)
    else:
        if verbose:
            print("{} has label {}".format(pol,Flabel))
        return Flabel
Example #3
0
 def _check(k, j):
     M = vvsmf(j, k, prec)
     if M.dimension() > 0:
         self.assertEqual(M.dimension(), len(M.basis()))
         _chply = M.hecke_charpoly(2)
         for cply, _ in _chply.factor():
             K = NumberField(cply, names="a")
             a = K.gens()[0]
             f = M.eigenform_with_eigenvalue_t2(a)
             self.assert_hecke_eigen_values(f)
def upsert_embedding(id_number, skip = False):
    rowcc = db.mf_hecke_cc.lucky({'id':id_number}, projection=['an', 'hecke_orbit_code','id','lfunction_label', 'embedding_root_imag','embedding_root_real'])
    if rowcc is None:
        return
    if skip:
        if rowcc.get("embedding_root_imag", None) is not None:
            if rowcc.get("embedding_root_real", None) is not None:
                return
    row_embeddings =  {}
    hecke_orbit_code = rowcc['hecke_orbit_code']
    newform = db.mf_newforms.lucky({'hecke_orbit_code':hecke_orbit_code})
    if newform is None:
        # No newform in db
        return
    if newform['dim'] == 1:
        row_embeddings['embedding_root_imag'] = 0
        row_embeddings['embedding_root_real'] = 0
    elif newform['weight'] == 1:
        return
    elif newform.get('field_poly', None) is None:
	    return
    else:
        # print rowcc['lfunction_label']
        HF = NumberField(ZZx(newform['field_poly']), "v")
        numerators =  newform['hecke_ring_numerators']
        denominators = newform['hecke_ring_denominators']
        betas = [HF(elt)/denominators[i] for i, elt in enumerate(numerators)]

        embeddings = HF.complex_embeddings(prec=2000)
        an_nf = list(db.mf_hecke_nf.search({'hecke_orbit_code':hecke_orbit_code}, ['n','an'], sort=['n']))
        betas_embedded = [map(elt, betas) for elt in embeddings]
        CCC = betas_embedded[0][0].parent()
        qexp = [convert_eigenvals_to_qexp(elt, an_nf) for elt in betas_embedded]
        min_len = min(len(rowcc['an']), len(qexp[0]))
        an_cc = vector(CCC, map(lambda x: CCC(x[0], x[1]), rowcc['an'][:min_len]))
        #qexp_diff = [ (vector(CCC, elt[:min_len]) - an_cc).norm() for elt in qexp ]
        # normalized, to avoid the unstability comming from large weight
        qexp_diff = [ vector([(elt- an_cc[i])/elt.abs() for i, elt in enumerate(q) if elt != 0]).norm() for j,q in enumerate(qexp)]

        qexp_diff_sorted = sorted(qexp_diff)
        min_diff = qexp_diff_sorted[0]
        #print "min_diff = %.2e \t min_diff/2nd = %.2e" % (min_diff, min_diff/qexp_diff_sorted[1])

        #assuring that is something close to zero, and that no other value is close to it
        assert min_diff < 1e-6
        assert min_diff/qexp_diff_sorted[1] < 1e-15

        for i, elt in enumerate(qexp_diff):
            if elt == min_diff:
                row_embeddings['embedding_root_real'] = float(embeddings[i](HF.gen()).real())
                row_embeddings['embedding_root_imag'] = float(embeddings[i](HF.gen()).imag())
                break
    assert len(row_embeddings) == 2
    db.mf_hecke_cc.upsert({'id': rowcc['id']}, row_embeddings)
Example #5
0
 def test_web_latex_ideal_fact(self):
     r"""
     Checking utility: web_latex_ideal_fact
     """
     from sage.all import NumberField
     x = var('x')
     K = NumberField(x**2 - 5, 'a')
     a = K.gen()
     I = K.ideal(2/(5+a)).factor()
     self.assertEqual(web_latex_ideal_fact(I),
                      '\\( \\left(-a\\right)^{-1} \\)')
def Hecke_field_primes(fpol, ell, degree=None, verbose=False):
    """Given a polynomial fpol defining a number field K and a prime ell,
    return the list of primes of K above ell.  Set degree to a
    suitable positive integer to only return primes of that degree,
    e.g. degree=1 will only give primes whose residue field is
    GF(ell).
    """
    if verbose:
        print("Checking field poly {} at ell={}".format(fpol,ell))
    Qx = PolynomialRing(QQ,'x')
    K = NumberField(Qx(fpol), 'a_')
    ellK = K.primes_above(ell, degree=degree)
    if verbose:
        print("{} primes of norm {}".format(len(ellK),ell))
    return ellK
Example #7
0
def list_factored_to_factored_poly_otherorder(sfacts_fc_list, galois=False, vari = 'T', p = None):
    """
        Either return the polynomial in a nice factored form,
        or return a pair, with first entry the factored polynomial
        and the second entry a list describing the Galois groups
        of the factors.
        vari allows to choose the variable of the polynomial to be returned.
    """
    gal_list=[]
    ZZpT  = PolynomialRing(ZZ, ['p',vari], order = 'negdeglex')
    ZZT = PolynomialRing(ZZ, vari)
    outstr = ''
    for g, e in sfacts_fc_list:
        if galois:
            # hack because currently sage only handles monic polynomials:
            this_poly = ZZT(list(reversed(g)))
            this_degree = this_poly.degree()
            this_number_field = NumberField(this_poly, "a")
            this_gal = this_number_field.galois_group(type='pari')
            this_t_number = this_gal.group().__pari__()[2].sage()
            gal_list.append([this_degree, this_t_number])

        # casting from ZZT -> ZZpT
        if p is None:
            gtoprint = dict( zip( zip( [0]*len(g), range(len(g))), g) )
        else:
            gtoprint = {}
            for i, elt in enumerate(g):
                if elt != 0:
                    val =  ZZ(elt).valuation(p)
                    gtoprint[(val, i)] = elt/p**val
        glatex = latex(ZZpT(gtoprint))
        if  e > 1:
            outstr += '( %s )^{%d}' % (glatex, e)
        elif len(sfacts_fc_list) > 1:
            outstr += '( %s )' % (glatex,)
        else:
            outstr += glatex

    if galois:
        # 2 factors of degree 2
        if len(sfacts_fc_list)==2:
            if len(sfacts_fc_list[0][0]) == 3 and len(sfacts_fc_list[1][0]) == 3:
                troubletest = ZZT(sfacts_fc_list[0][0]).disc()*ZZT(sfacts_fc_list[1][0]).disc()
                if troubletest.is_square():
                    gal_list=[[2,1]]
        return outstr, gal_list
    return outstr
Example #8
0
def RM_and_notCM(ef, RM_coeff):
    QQt = PolynomialRing(QQ, 't')
    RM_field = NumberField(QQt(RM_coeff),'r')
    possible_CM = None;
    for p1 in ef:
        if len(p1) == 5:
            p = sqrt(p1[-1])
            if  QQt(p1).is_irreducible() and is_ordinary(p1) and is_totally_split(RM_field, p):
                N = NumberField(QQt(p1), "a")
                if possible_CM is None:
                    possible_CM = N;
                elif not N.is_isomorphic(possible_CM):
                    return True;
                else:
                    pass;
    return False
Example #9
0
 def test_ramanujan_conj(self):
     '''Test Ramanujan conjectures for eigenforms of determinant weights
     less than or equal to 29.
     '''
     prec = 6
     hpl = hilbert_series_maybe(10)
     for k in range(22, 30):
         if hpl[k] != 0:
             N = sym10_space(k, prec, data_directory=data_dir)
             self.assertEqual(N.dimension(), len(N.basis()))
             _chply = N.hecke_charpoly(2)
             for cply, _ in _chply.factor():
                 K = NumberField(cply, names="a")
                 a = K.gens()[0]
                 f = N.eigenform_with_eigenvalue_t2(a)
                 self.assert_ramanujan_conj_eigenform(f)
Example #10
0
def test_gothic_veech():
    x = polygen(QQ)
    K = NumberField(x**2 - 2, 'sqrt2', embedding=AA(2)**QQ((1, 2)))
    sqrt2 = K.gen()
    x = QQ((1, 2))
    y = 1
    a = x + y * sqrt2
    b = -3 * x - QQ((3, 2)) + 3 * y * sqrt2
    S = translation_surfaces.cathedral(a, b)
    O = GL2ROrbitClosure(S)
    assert O.ambient_stratum() == AbelianStratum(2, 2, 2)
    for d in O.decompositions(4, 50):
        assert d.parabolic()
        O.update_tangent_space_from_flow_decomposition(d)
    assert O.dimension() == O.absolute_dimension() == 2
    assert O.field_of_definition() == O.V2._isomorphic_vector_space.base_ring()
def test_D9_exact_real():
    pytest.importorskip('pyexactreal')

    from pyexactreal import ExactReals
    R = ExactReals(QQ)
    x = polygen(QQ)
    K = NumberField(x**3 - 2, 'a', embedding=AA(2)**QQ((1,3)))
    a = K.gen()
    S = translation_surfaces.mcmullen_genus2_prototype(2,1,0,-1,R.random_element([0.1, 0.2]))
    O = GL2ROrbitClosure(S)
    for d in O.decompositions(5):
        ncyl, nmin, nund = d.num_cylinders_minimals_undetermined()
        assert (nund == 0)
        assert ((nmin == 0) or (ncyl == 0 and 1 <= nmin <= 2))
        O.update_tangent_space_from_flow_decomposition(d)
    assert O.dimension() == 3
Example #12
0
 def create_small_record(self, min_prec=10, want_prec=100, max_length = 5242880, max_height_qexp = default_max_height):
     ### creates a duplicate record (fs) of this webnewform
     ### with lower precision to load faster on the web
     ### we aim to have at most max_length bytes
     ### but at least min_prec coefficients and we desire to have want_prec
     if min_prec>=self.prec:
         raise ValueError("Need higher precision, self.prec = {}".format(self.prec))
     if not hasattr(self, '_file_record_length'):
         self.update_from_db()
     l = self._file_record_length
         
     if l > max_length or self.prec > want_prec:
         nl = float(l)/float(self.prec)*float(want_prec)
         if nl > max_length:
             prec = max([floor(float(self.prec)/float(l)*float(max_length)), min_prec])
         else:
             prec = want_prec
         emf_logger.debug("Creating a new record with prec = {}".format(prec))
         self.prec = prec
         include_coeffs = self.complexity_of_first_nonvanishing_coefficients() <= default_max_height
         if include_coeffs:
             self.q_expansion = self.q_expansion.truncate_powerseries(prec)
             self._coefficients = {n:c for n,c in self._coefficients.iteritems() if n<prec}
         else:
             self.q_expansion = self.q_expansion.truncate_powerseries(1)
             self._coefficients = {}
             self.prec = 0
             self.coefficient_field = NumberField(self.absolute_polynomial, names=str(self.coefficient_field.gen()))
         self._embeddings['values'] = {n:c for n,c in self._embeddings['values'].iteritems() if n<prec}
         self._embeddings['prec'] = prec
         self.save_to_db()
Example #13
0
 def number_field(self):
     p = self._min_poly
     if p is None:
         raise ValueError('Minimal polynomial is not known.')
     q = p.change_ring(QQ)
     q = (1 / q.leading_coefficient()) * q
     return NumberField(q, 'z', embedding=self._approx_root)
def get_smallest_good_number_field(d):
    """
    Gets the smallest "good" number field of degree d, where "good" means

    - Galois over Q
    - Does not contain the Hilbert class field of an imaginary quadratic field

    and smallest is in terms of absolute value of discriminant. This connects to
    the LMFDB API for searching, and returns the correct hit.

    Output:

    - Delta_K - discriminant of number field
    - f_K - Definining polynomial of number field

    """
    the_url = SGNF_URL_TRUNK.format(str(d))
    data_this_degree = requests.get(url=the_url).json()["data"]
    for dat in data_this_degree:
        poly = R(dat["coeffs"])
        K = NumberField(poly, name="a")
        Delta_K = dat["disc_sign"] * dat["disc_abs"]
        _, contains_hilbert_class_field = contains_imaginary_quadratic_field(K)
        if not contains_hilbert_class_field:
            return (Delta_K, poly, K, dat["label"])
    raise NotImplementedError("need more hits")
Example #15
0
    def ramified_extension(self, n, embedding=False):
        r"""
        Return a purely ramified extension with given ramification degree.

        INPUT:

        - ``n`` -- a positive integer
        - ``embedding`` -- a boolean (default: ``False``)

        OUTPUT:

        A finite extension `L` of this p-adic field `K` such that `L/K` is
        purely ramified, of degree ``n``. If ``embedding`` is ``True`` then the
        pair `(L,\phi)` is returned, where `\phi:K\to L` is the canonical embedding.

        """
        P = self.polynomial()
        x = P.parent().gen()
        if self.is_Qp():
            P = x**n - self.p()
        else:
            P = P(x**n)
        L0 = NumberField(P, 'pi'+str(P.degree()), maximize_at_primes=[])
        vL = self.base_valuation().extension(L0)
        return FakepAdicCompletion(L0, vL)
Example #16
0
def _test_an_dict_over_Q(ainvs, B=100):
    """
    Test that the an_dict function works and gives the correct answer
    for an elliptic curve defined over QQ, by computing using the
    generic code in this file, and comparing with the output of Sage's
    anlist function for rational elliptic curves.
    """
    from sage.all import polygen, QQ, NumberField, EllipticCurve
    x = polygen(QQ,'x')
    F = NumberField(x - 1,'a'); a = F.gen()
    E = EllipticCurve(F, ainvs)
    EQ = EllipticCurve(QQ, ainvs)
    v = EQ.anlist(B)
    an = an_dict(E, B)
    for i, j in an.iteritems():
        assert j == v[i[0]]
Example #17
0
    def set_euler_factors(self):
        # Sets:
        # - euler_factors
        # - bad_lfactors
        bound = 100
        power = self.power
        if self.curve.genus() == 1:
            E = self.curve
            ZZT = PolynomialRing(ZZ, "T")
            T = ZZT.gen()
            K = E.base_field()
            if K == QQ:
                K = NumberField(T,"a") # making sure SAGE sees K as a numberfield
                E = E.change_ring(K)
            N = (E.conductor() * K.discriminant()**2).absolute_norm()
            assert N == self.conductor


            def get_eulerfactor(p):
                Lp = 1
                for f, _ in K.fractional_ideal(p).factor():
                    f = K.fractional_ideal(f)
                    if f.divides(N):
                        local_factor = (1 - E.local_data(f).bad_reduction_type() * T)
                        Lp *=  local_factor( T ** f.absolute_norm().valuation(p) )
                    else:
                        frob = ZZT(E.local_data(f).minimal_model().change_ring(f.residue_field()).frobenius_polynomial())
                        Lp *= frob.reverse()( T ** f.absolute_norm().valuation(p) )
                return list(map(int, Lp))

            if power > 1:
                euler_factors = {}
                for p, v in self.hard_factors.items():
                    euler_factors[p] = v
                for p in prime_range(bound):
                    if p in self.hard_factors:
                        continue
                    _, ma, p = euler_factors(p)
                    euler_factors[p] = sym_pol_ECQ(-ma, p, power)
            else:
                euler_factors = {p: get_eulerfactor(p) for p in prime_range(bound)}

        else:
            raise NotImplementedError("only implemented for genus 1 at the moment")

        self.euler_factors = [euler_factors[p] for p in prime_range(bound)]
        self.bad_lfactors = [[p, euler_factors[p]] for p in Integer(self.conductor).prime_divisors()]
Example #18
0
def test1(B=50):
    """
    Tests that the functions all run without crashing over a specific number field.
    Does not test that the output is correct.  That should be in
    another test.
    """
    from sage.all import polygen, QQ, NumberField, EllipticCurve
    x = polygen(QQ,'x')
    F = NumberField(x**2 - x - 1,'a'); a = F.gen()
    E = EllipticCurve([1,a+1,a,a,0])
    ap(E,F.ideal(3))
    primes_of_bounded_norm(F,B)
    ap_list(E,B)
    assert len(ap_list(E,B,primes=True)) == 2
    apd = ap_dict(E,B)
    reduced_rep(F.ideal(3))
    assert an_dict(E,B) == an_dict_from_ap(apd, E.conductor(), B)
Example #19
0
def make_base_field(rec):
    if rec["base_field"] == [-1, 1]:
        K = QQ  # is there a Sage version of RationalsAsNumberField()?
    else:
        R = PolynomialRing(QQ, "T")
        poly = R(rec["base_field"])
        K = NumberField(poly, "nu")
    return K
Example #20
0
def cli_handler(args):  # pylint: disable=redefined-outer-name

    f = R(args.f)

    K = NumberField(f, name="a")

    loglevel = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(
        format="%(asctime)s %(levelname)s: %(message)s",
        datefmt="%H:%M:%S",
        level=loglevel,
    )
    logging.debug("Debugging level for log messages set.")

    if args.dlmv:
        dlmv_bound = DLMV(K)
        logging.info(
            "DLMV bound for {} is:\n\n{}\n\nwhich is approximately {}".format(
                K, dlmv_bound, RR(dlmv_bound)))
    else:
        logging.warning(
            "Only checking Type 2 primes up to %s. "
            "To check all, use the PARI/GP script.",
            args.bound,
        )

        if args.norm_bound:
            norm_bound = args.norm_bound
            auto_stop_strategy = False
        else:
            norm_bound = 50  # still needed for Type 1
            auto_stop_strategy = True

        superset, type_3_fields = get_isogeny_primes(
            K,
            args.bound,
            args.ice,
            args.appendix_bound,
            norm_bound=norm_bound,
            auto_stop_strategy=auto_stop_strategy,
        )

        superset_list = list(superset)
        superset_list.sort()
        logging.info(f"superset = {superset_list}")

        possible_new_isog_primes = superset - EC_Q_ISOGENY_PRIMES
        possible_new_isog_primes_list = list(possible_new_isog_primes)
        possible_new_isog_primes_list.sort()
        logging.info(
            f"Possible new isogeny primes = {possible_new_isog_primes_list}")
        if type_3_fields:
            how_many_fields = len(type_3_fields)
            logging.info(
                f"Outside of the above set, any isogeny primes must be "
                f"of Momose Type 3 with imaginary quadratic field L, for L one "
                f"of the following {how_many_fields} field(s):\n {type_3_fields}"
            )
Example #21
0
 def test_Heckemethods(self):
     from sage.all import NumberField, var
     x = var('x')
     k = NumberField(x**3 - x**2 + x + 1, 'a')
     modlabel, numlabel = '82.-5a0+1a2', '5.3.3'
     mod = WebHecke.label2ideal(k, modlabel)
     assert WebHecke.ideal2label(mod) == modlabel
     num = WebHecke.label2number(numlabel)
     assert WebHecke.number2label(num) == numlabel
Example #22
0
 def _test(self):
     from sage.all import PolynomialRing, QQ, NumberField, GaussValuation, FunctionField
     R = PolynomialRing(QQ, 'x')
     x = R.gen()
     K = NumberField(x**6 + 126 * x**3 + 126, 'pi')
     v = K.valuation(2)
     R = PolynomialRing(K, 'x')
     x = R.gen()
     v = GaussValuation(R, v).augmentation(x, QQ(2) / 3)
     F = FunctionField(K, 'x')
     x = F.gen()
     v = F.valuation(v)
     S = PolynomialRing(F, 'y')
     y = S.gen()
     w0 = GaussValuation(S, v)
     G = y**2 - x**3 - 3
     w1 = w0.mac_lane_step(G)[0]
     w1.mac_lane_step(G)
Example #23
0
def test_nf():
    from sage.all import NumberField, QQ, AA, Rational, polygen
    from pyeantic.sage_conversion import sage_nf_to_eantic

    x = polygen(QQ)

    # linear
    K = NumberField(x - 3, 'x', embedding=QQ(3))
    L = sage_nf_to_eantic(K)

    # quadratic
    K = NumberField(2*x**2 - 3, 'A', embedding=AA(Rational((3,2)))**Rational((1,2)))
    L = sage_nf_to_eantic(K)

    # cubic
    p = x**3 - x**2 - x - 1
    s = p.roots(AA, False)[0]
    K = NumberField(x**3 - x**2 - x - 1, 's', embedding=s)
    L = sage_nf_to_eantic(K)
Example #24
0
def test_field_iso(pol1, pol2):
    if pol1 == pol2:
        return True
    if pol1.degree() != pol2.degree():
        return False
    assert pol1.is_irreducible() and pol2.is_irreducible()
    res = 0 < len(
        pol1.change_ring(PolynomialRing(NumberField(pol2, 'b'), 'y')).roots())
    #print("testing isomorphism of {} and {}: {}".format(pol1,pol2, res))
    return res
Example #25
0
    def test_download_sage(self):
        # A dimension 1 example
        L1 = self.tc.get(
            '/ModularForm/GL2/ImaginaryQuadratic/2.0.3.1/18333.3/a/download/sage'
        )
        L1_level = self.check_compile_and_get_level(L1)
        assert L1_level.norm() == Integer(18333)
        assert 'NN = ZF.ideal((6111, 3*a + 5052))' in L1.get_data(as_text=True)
        assert '(27*a-22,),(-29*a+15,),(-29*a+14,),(29*a-11,),(-29*a+18,),(-29*a+9,)' in L1.get_data(
            as_text=True)
        assert 'hecke_eigenvalues_array = [0, -1, 2, -1, 1, -3, 4, 0, -2, -8, 7, -9, -8, -4, -9, 8, 10, -11,' in L1.get_data(
            as_text=True)
        """
        Observe that example 1 above checks equality of the level norm between
        the loaded sage code and what appears on the homepage, but then checks
        for a particular presentation of that ideal in the text file. The problem
        with this is that the choice of generators for the ideal are not unique,
        and could potentially change from one sage release to the next. An
        alternative is to check for equality of the ideals themselves, and that
        is the strategy adopted in the following example.
        """

        # A dimension 2 example
        L2 = self.tc.get(
            '/ModularForm/GL2/ImaginaryQuadratic/2.0.4.1/377.1/a2/download/sage'
        )
        L2_level = self.check_compile_and_get_level(L2)

        P = PolynomialRing(QQ, 'x')
        g = P([1, 0, 1])
        F = NumberField(g, 'i')
        i = F.gen()
        ZF = F.ring_of_integers()

        L2_level_actual = ZF.ideal(
            (16 * i - 11))  # the level displayed on BMF homepage
        assert L2_level == L2_level_actual
        assert L2_level.norm() == 377
        assert '(2*i+3,),(i+4,),(i-4,),(-2*i+5,),(2*i+5,),(i+6,)' in L2.get_data(
            as_text=True)
        assert 'hecke_eigenvalues_array = [-z, 2*z, -1, 2*z+2, "not known", 2*z-1, 4, 2*z+3, "not known", 2*z+1, -2*z-5, -4*z+5, -4*z+5, 2*z+1, 2*z]' in L2.get_data(
            as_text=True)
Example #26
0
def IsGeometricallyNotSquareOfCM(LPolys):
    g = 2  # only for surfaces
    CMDisc = -1
    for p in range(2, maxP):  # loop over primes
        if LPolys[p] <> 0:
            q = LPolys[p]
            q = twistPolynomial(q, 2 * extensionBounds[g])
            if (q.is_square() == False):
                return True
            r = q.factor()
            r = r[0][0]
            if r.degree() == 2:
                if r.coefficients(sparse=False)[1] % p <> 0:
                    K = NumberField(r, 'u')
                    d = K.disc()
                    if CMDisc == -1:
                        CMDisc = d
                    if CMDisc <> d:
                        return True
    return False
Example #27
0
def number_field_from_dict(d):
    r"""
    INPUT:

    - 'd' -- {'base':F,'p':p,'g':g } where p is a polynomial in the variable(s) xN with coefficients in K. (The 'x' is just a convention)

    OUTPUT:

    - 'F' -- Number field extending K with relative minimal polynomial p.
    """
    K = d['base']; p=d['relative polynomial']; g=d['gens']
    if K=='QQ':
        K = QQ
    elif isinstance(K,dict):
        K = number_field_from_dict(K)
    else:
        raise ValueError,"Could not construct number field!"
    F = NumberField(K[g](p),names=g)
    if F.absolute_degree()==1:
        F = QQ
    return F
Example #28
0
def number_field_from_dict(d):
    r"""
    INPUT:

    - 'd' -- {'base':F,'p':p,'g':g } where p is a polynomial in the variable(s) xN with coefficients in K. (The 'x' is just a convention)

    OUTPUT:

    - 'F' -- Number field extending K with relative minimal polynomial p.
    """
    K = d['base']; p=d['relative polynomial']; g=d['gens']
    if K=='QQ':
        K = QQ
    elif isinstance(K,dict):
        K = number_field_from_dict(K)
    else:
        raise ValueError,"Could not construct number field!"
    F = NumberField(K[g](p),names=g)
    if F.absolute_degree()==1:
        F = QQ
    return F
Example #29
0
def get_hmfs_hecke_field_and_eigenvals(label):
    """Get the Hecke field and eigenvalues for the Hilbert modular form with given label.

    INPUT:
        label -- string, the label of the Hilbert modular form

    OUTPUT:
        K_old -- number field, the field containing the Hecke eigenvalues
        e -- number field element, a generator for K_old over QQ
        eigenvals -- list, a list of the Hecke eigenvalues
    """
    C = getDBconnection()
    # Should I use find_one, or something else?
    R = PolynomialRing(QQ, names=('x'))
    form = C.hmfs.forms.find_one({'label': label})
    poly = R(str(form['hecke_polynomial']))
    K_old = NumberField(poly, names=('e', ))
    (e, ) = K_old._first_ngens(1)
    eigenvals_str = form['hecke_eigenvalues']
    eigenvals = [K_old(eval(preparse(el))) for el in eigenvals_str]
    return K_old, e, eigenvals
Example #30
0
def get_hmfs_hecke_field_and_eigenvals(label):
    """Get the Hecke field and eigenvalues for the Hilbert modular form with given label.

    INPUT:
        label -- string, the label of the Hilbert modular form

    OUTPUT:
        K_old -- number field, the field containing the Hecke eigenvalues
        e -- number field element, a generator for K_old over QQ
        eigenvals -- list, a list of the Hecke eigenvalues
    """
    C = getDBconnection()
    # Should I use find_one, or something else?
    R = PolynomialRing(QQ,names=('x'))
    form = C.hmfs.forms.find_one({'label':label})
    poly = R(str(form['hecke_polynomial']))
    K_old = NumberField(poly, names=('e',))
    (e,) = K_old._first_ngens(1)
    eigenvals_str = form['hecke_eigenvalues']
    eigenvals = [K_old(eval(preparse(el))) for el in eigenvals_str]
    return K_old, e, eigenvals
Example #31
0
def compare_data(d1,d2, keylist=['dims', 'traces', 'polys','ALs', 'eigdata'], verbose=False):
    assert d1.keys()==d1.keys()
    QX = PolynomialRing(QQ,'x')
    nforms = len(d1.keys())
    nstep = ZZ(max(1,int(nforms/20.0)))
    nf = 0
    print("Comparing data for {} newforms".format(nforms))
    for k in d1.keys():
        nf+=1
        if nf%nstep==0:
            print("compared {}/{} ({:0.3f}%)".format(nf,nforms,100.0*nf/nforms))
        if d1[k]!=d2[k]:
            for key in keylist:
                # take copies! we want to be able to change these without affecting the input dicts
                t1=copy(d1[k][key])
                t2=copy(d2[k][key])
                if key=='polys':
                    n=len(t1)
                    for i in range(n):
                        if t1[i]!=t2[i]:
                            pol1 = QX(t1[i])
                            pol2 = QX(t2[i])
                            F1 = NumberField(pol1,'a')
                            F2 = NumberField(pol2,'a')
                            if F1.is_isomorphic(F2):
                                pol1=pol2=F1.optimized_representation()[0].defining_polynomial()
                                t1[i]=t2[i]=list(pol1)

                if t1!=t2:
                    if key=='traces':
                        print("traces differ for {}: \nfirst #= {}, \nsecond #={}".format(k,[len(t) for t in t1],[len(t) for t in t2]))
                        print("first starts\t {}".format(t1[0][:10]))
                        print("second starts\t {}".format(t2[0][:10]))
                    elif key=='eigdata':
                        for f1,f2 in zip(t1,t2):
                            ok, reason = compare_eigdata(k,f1,f2,verbose)
                            if not ok:
                                print("an do not match for (N,k,o)={}: {}".format(k, reason))
                    else:
                        print("{} differ for {}: \nfirst  {}, \nsecond {}".format(key,k,t1,t2))
Example #32
0
def bestify_newform(nf, dmax=20, Detail=0):
    r"""
    Input is a dict with keys
     {
    'Nko',  'chipoly', 'SB', 'ALeigs', 'dim', 'traces', 'poly', 'eigdata'
    }
    (with ALeigs only when o=1 and eigdata only when 1<dim<=dmax)

    Here eigdata is a dict of the form

    'pol': list of d+1 coefficients of polynomial defining Hecke field F
    'bas': list of lists of rationals holding dxd matrix whose rows define a Q-basis for F in terms of the power basis
    'ancs': list of lists of d rationals giving coefficients of each a_n w.r.t. that basis
    'n': 0 (not yet set)
    'm': 0 (not yet set)

    Output adds 'best_poly' and applies a change of basis to eigdata
    changing 'pol' and 'bas' so the basis coefficients are w.r.t. the
    best_poly power basis and not the poly power basis.
    """
    Nko = nf['Nko']
    dim = nf['dim']
    if dim == 1:
        nf['best_poly'] = nf['poly']
        return nf
    if dim > dmax and dmax > 0:
        nf['best_poly'] = None
        return nf
    Qx = PolynomialRing(QQ, 'x')
    pari_Qx_poly_to_sage = lambda f: Qx(gen_to_sage(f.Vecrev()))
    poly = Qx(nf['poly'].list())
    if Detail:
        print("non-best poly for {} is {}".format(Nko, poly))
    nf['best_poly'] = best_poly = polredbest_stable(poly)
    if Detail:
        print("best_poly for {} is {}".format(Nko, best_poly))

    # Now the real work starts
    Fold = NumberField(poly, 'a')
    #print("Fold = {}".format(Fold))
    Fnew = NumberField(best_poly, 'b')
    #print("Fnew = {}".format(Fnew))
    iso = Fold.is_isomorphic(
        Fnew, isomorphism_maps=True)[1][0]  # we do not care which isomorphism
    #print("iso = {}".format(iso))
    iso = pari_Qx_poly_to_sage(iso)
    iso = Fold.hom([iso(Fnew.gen())])
    new_basis_matrix = [
        a.list()
        for a in [iso(b) for b in [Fold(co) for co in nf['eigdata']['bas']]]
    ]
    nf['eigdata']['bas'] = new_basis_matrix
    nf['eigdata']['pol'] = best_poly.list()
    return nf
Example #33
0
def field_from_label(lab):
    r"""
    Returns a number field from its LMFDB label. IQF only.

    INPUT:

    - ``s`` (string)-- an LMFDB field label of the form 2.0.d.1

    OUTPUT:

    A number field, Q(sqrt(-d)) with standard defining polynomial
    """
    K = NumberField(polys[lab], gen_names[lab])
    print("Created field from label {}: {}".format(lab, K))
    return K
Example #34
0
def decode_eigdata(k, ed, detail=1):
    if detail:
        print("Decoding eigdata for space {}".format(k))
    Qx = PolynomialRing(QQ,'x')
    pol = Qx(ed['poly'])
    F = NumberField(pol,'a')
    if detail:
        print("Field = {}".format(F))
    basis = [F(co) for co in ed['basis']]
    if detail:
        print("Basis = {}".format(basis))
    ans = [sum(b*a for a,b in zip(an,basis)) for an in ed['ans']]
    if detail:
        print("ans = {} (first 10 only)".format(ans[:10]))

    return {'field': F, 'basis': basis, 'ans': ans}
Example #35
0
def RankBoundProductEC(LPolys):
    g = 2                           # only for surfaces
    NotSquareCM = IsGeometricallyNotSquareOfCM(LPolys)
    if NotSquareCM == False :
    return 8;

    IsSquare = True

    for p in range (2,maxP):
      if LPolys[p] <> 0 :
        q = LPolys[p]
        q = twistPolynomial(q, 2*extensionBounds[g])

        if(q.is_square() == False) :
            IsSquare = False
        break

    if IsSquare :
        return 4

    FoundDifferentDiscriminants = False
    Initialized = False
    Discriminants = {}

    for p in range (2,maxP):
      if LPolys[p] <> 0 :
        q = LPolys[p]
        q = twistPolynomial(q, 2*extensionBounds[g])
    if(q.is_square() == False) :
            r = q.factor()
        l1 = r[0][0];
        l2 = r[1][0];
        if l1.degree() == 2 and l2.degree() == 2:
            if l1.coefficients(sparse = False)[1] % p <> 0 and l2.coefficients(sparse = False)[2] % p <> 0 :
            K1 = NumberField(l1, 'u1');
            K2 = NumberField(l2, 'u2');
            d1 = K1.discriminant()
            d2 = K2.discriminant()
            if d1 <> d2 :
                FoundDifferentDiscriminants = True
            if not Initialized :
                Initialized = True
                Discriminants = {d1, d2}
            Discriminants = Discriminants.intersection({d1, d2})
            if len(Discriminants) == 0 :
                break;

    if FoundDifferentDiscriminants :
    return 2 + len(Discriminants)
    else :
    if len(Discriminants) == 0 :
        return 2;
    else :
        return 4;
Example #36
0
def absolute_number_field(maxdeg=10):
    """
    Return an absolute extension of QQ of degree at most 10.

    EXAMPLES::

        sage: import sage.rings.tests
        sage: sage.rings.tests.absolute_number_field()
        Number Field in a with defining polynomial x^5 + 82*x^4 - 46*x^3 + 39*x^2 - x - 41
    """
    from sage.all import ZZ, NumberField
    R = ZZ['x']
    while True:
        f = R.random_element(degree=ZZ.random_element(x=1,y=maxdeg),x=-100,y=100)
        if f.degree() <= 0: continue
        f = f + R.gen()**(f.degree()+1)  # make monic
        if f.is_irreducible():
            return NumberField(f, 'a')
Example #37
0
def rational_unimodular_representation(ideal):
    R = ideal.ring()
    vars = list(R.gens())
    J = giac(ideal.gens())
    rur = J.gbasis(vars, 'rur')
    # Yikes: giacpy_sage vs the giac interface give different types.
    # So using repr.
    if repr(rur[0]) != 'rur':
        raise ValueError(('Could not find RUR, got %r instead. '
                          'Is the variety 0-dimensional?') % rur[0])

    # [x.sage() for rur[4:]] doesn't work with the giac interface (it tries
    # to convert the slicing to a giac expression that giac does not understand)
    #
    # However, rur.sage()[0] gave some trouble, too.
    #
    # So we convert with .sage() after having checked we have rur, but before
    # we inspect the other items.
    rur = rur.sage()

    # Defining polynomial of number field, as a symbolic expression.
    p = rur[2]
    assert len(p.variables()) == 1
    v = p.variables()[0]

    S = PolynomialRing(QQ, repr(v))
    T = PolynomialRing(QQ, 'x')
    p = T(S(p))
    p = p / p.leading_coefficient()

    ans = []
    for q, e in p.factor():
        K = NumberField(q, 'a')

        def toK(f):
            return K(T(S(f)))

        denom = toK(rur[3])
        rep = [toK(f) / denom for f in rur[4:]]
        sub_dict = dict(zip(vars, rep))
        assert all(g.subs(sub_dict) == 0 for g in ideal.gens())
        ans.append((K, sub_dict))

    return ans
Example #38
0
def field_from_label(lab):
    r"""
    Returns a number field from its LMFDB label.  Only for 5 IQFs at present.
    """
    global the_fields
    if lab in the_fields:
        return the_fields[lab]
    x = polygen(QQ)
    deg, s, abs_disc, _ = lab.split(".")
    assert deg == '2'
    assert s == '0'
    d = -ZZ(abs_disc)
    t = d % 4
    assert t in [0, 1]
    pol = x**2 - t * x + (t - d) // 4
    K = NumberField(pol, 'a')
    print "Created field from label %s: %s" % (lab, K)
    the_fields[lab] = K
    return K
Example #39
0
def field_intersection_list(defining_polynomials):
    # try to just use discriminants of the first 1000 polynomials
    D = 0
    for f in defining_polynomials[:1000]:
        D = GCD(D, f.discriminant())
        if D == 1:
            return f.parent().gen()

    L = NumberField(defining_polynomials[0], 'a')
    for f in defining_polynomials:
        K = NumberField(f, 'b')
        # the 1st argument should be the 'smaller' field
        L = NumberField(field_intersection(L, K), 'a')

        if L.degree() == 1:
            return f.parent().gen()
    else:
        return polredabs(L.absolute_polynomial())
Example #40
0
def nf_lookup(label):
    r"""
    Returns a NumberField from its label, caching the result.
    """
    global nf_lookup_table, special_names
    #print "Looking up number field with label %s" % label
    if label in nf_lookup_table:
        #print "We already have it: %s" % nf_lookup_table[label]
        return nf_lookup_table[label]
    #print "We do not have it yet, finding in database..."
    field = C.numberfields.fields.find_one({'label': label})
    if not field:
        raise ValueError("Invalid field label: %s" % label)
    #print "Found it!"
    coeffs = [ZZ(c) for c in field['coeffs'].split(",")]
    gen_name = special_names.get(label, 'a')
    K = NumberField(PolynomialRing(QQ, 'x')(coeffs), gen_name)
    #print "The field with label %s is %s" % (label, K)
    nf_lookup_table[label] = K
    return K
Example #41
0
def _alpha20_3():
    x = var("x")
    K = NumberField(x ** 2 - ZZ(1378464) * x + ZZ(328189501440), "alpha20_3")
    return K.gens()[0]
def upsert_embedding(id_number, skip = True):
    rowcc = db.mf_hecke_cc.lucky({'id':id_number}, projection=['an_normalized', 'hecke_orbit_code','id','lfunction_label', 'embedding_root_imag','embedding_root_real'])
    if rowcc is None:
        return
    if skip:
        if rowcc.get("embedding_root_imag", None) is not None:
            if rowcc.get("embedding_root_real", None) is not None:
                return
    row_embeddings =  {}
    hecke_orbit_code = rowcc['hecke_orbit_code']
    newform = db.mf_newforms.lucky({'hecke_orbit_code':hecke_orbit_code},['label','weight','field_poly','dim'])
    if newform is None:
        # No newform in db
        return
    if newform['dim'] == 1:
        row_embeddings['embedding_root_imag'] = 0
        row_embeddings['embedding_root_real'] = 0
    elif newform['weight'] == 1:
        return
    elif newform.get('field_poly', None) is None:
	    return
    else:
        # print rowcc['lfunction_label']
        HF = NumberField(ZZx(newform['field_poly']), "v")
        hecke_nf = db.mf_hecke_nf.lucky({'hecke_orbit_code':hecke_orbit_code}, ['hecke_ring_cyclotomic_generator','an','field_poly','hecke_ring_numerators','hecke_ring_denominators', 'hecke_ring_power_basis'])
        assert hecke_nf is not None
        assert newform['field_poly'] == hecke_nf['field_poly']
        assert hecke_nf['hecke_ring_cyclotomic_generator'] == 0
        if hecke_nf['hecke_ring_power_basis']:
            v = HF.gens()[0]
            betas = [ v**i for i in range(len(newform['field_poly'])) ]
        else:
            numerators =  hecke_nf.get('hecke_ring_numerators')
            denominators = hecke_nf.get('hecke_ring_denominators')
            betas = [HF(elt)/denominators[i] for i, elt in enumerate(numerators)]

        embeddings = HF.complex_embeddings(prec=2000)
        an_nf = hecke_nf['an']
        betas_embedded = [map(elt, betas) for elt in embeddings]
        CCC = betas_embedded[0][0].parent()
        normalization = -CCC(newform['weight'] - 1).real()/2
        qexp = [convert_eigenvals_to_qexp(elt, an_nf, normalization) for elt in betas_embedded]
        min_len = min(len(rowcc['an_normalized']), len(qexp[0]))
        an_cc = vector(CCC, map(lambda x: CCC(x[0], x[1]), rowcc['an_normalized'][:min_len]))
        #qexp_diff = [ (vector(CCC, elt[:min_len]) - an_cc).norm() for elt in qexp ]
        # normalized, to avoid the unstability comming from large weight
        qexp_diff = [ vector([(elt- an_cc[i])/elt.abs() for i, elt in enumerate(q) if elt != 0]).norm() for j,q in enumerate(qexp)]

        qexp_diff_sorted = sorted(qexp_diff)
        min_diff = qexp_diff_sorted[0]

        #assuring that is something close to zero, and that no other value is close to it
        assert min_diff < 1e-6 and min_diff/qexp_diff_sorted[1] < 1e-15, "id = %d label = %s\nmin_diff = %.2e \t min_diff/2nd = %.2e\nan_cc = %s\nqexp = %s" % (id_number, rowcc['lfunction_label'], min_diff, min_diff/qexp_diff_sorted[1], vector(ComplexField(20), an_cc[:5]), matrix(ComplexField(20), [elt[:5] for elt in qexp]))

        for i, elt in enumerate(qexp_diff):
            if elt == min_diff:
                row_embeddings['embedding_root_real'] = float(embeddings[i](HF.gen()).real())
                row_embeddings['embedding_root_imag'] = float(embeddings[i](HF.gen()).imag())
                break
    assert len(row_embeddings) == 2
    db.mf_hecke_cc.upsert({'id': rowcc['id']}, row_embeddings)
Example #43
0
class WebNewForm(WebObject, CachedRepresentation):

    _key = ['level', 'weight', 'character', 'label', 'version']
    _file_key = ['hecke_orbit_label','version']
    _file_key_multi = ['prec']
    if emf_version > 1.3:
        _collection_name = 'webnewforms2'
    else:
        _collection_name = 'webnewforms'

    def __init__(self, level=1, weight=12, character=1, label='a', prec=0, parent=None, update_from_db=True,**kwargs):
        emf_logger.debug("In WebNewForm {0}".format((level,weight,character,label,parent,update_from_db)))
        if isinstance(level,basestring) or kwargs.has_key('hecke_orbit_label'):
            hecke_orbit_label = kwargs.get('hecke_orbit_label', level)
            level,weight,character,label = parse_newform_label(hecke_orbit_label)
        self._reduction = (type(self),(level,weight,character,label),{'parent':parent,'update_from_db':update_from_db})
        if isinstance(character, WebChar):
            character_number = character.number
        else:
            character_number = character
            character = None if parent is None else parent.character
            if not isinstance(label,basestring):
                if isinstance(label,(int,Integer)):
                    label = cremona_letter_code(label)
                else:
                    raise ValueError,"Need label either string or integer! We got:{0}".format(label)

        emf_logger.debug("Before init properties 0")
        self._properties = WebProperties(
            WebInt('level', value=level),
            WebInt('weight', value=weight),
            WebCharProperty('character', modulus=level,
                            number=character_number,
                            value = character,
                            include_in_update = True if character is None
                            else False),
            WebStr('character_naming_scheme', value='Conrey'),
            WebStr('sage_version', value=''),
            WebStr('hecke_orbit_label', default_value=newform_label(level, weight, character_number, label)),
            WebStr('label', default_value=label),
            WebInt('dimension'),
            WebqExp('q_expansion'),
            WebCoeffs('_coefficients'),
            WebDict('_embeddings'),
            WebInt('prec',value=0, save_to_db=False, save_to_fs=True), 
            WebNumberField('base_ring'),
            WebNumberField('coefficient_field'),
            WebInt('coefficient_field_degree'),
            WebList('twist_info', required = False),
            WebInt('is_cm', required = False),
            WebInt('cm_disc', required = False, default_value=0),
            WebDict('_cm_values',required=False),
            WebBool('is_cuspidal',default_value=True),
            WebDict('satake', required=False),
            WebDict('_atkin_lehner_eigenvalues', required=False),
            WebBool('is_rational'),
            WebPoly('absolute_polynomial'),
            WebFloat('version', value=float(emf_version), save_to_fs=True),
            WebDict('explicit_formulas',required=False),
            WebDate('creation_date',value=None),
            WebModFormSpaceProperty('parent', value=parent,
                                    level = level,
                                    weight = weight,
                                    character = character_number,
                                    update_hecke_orbits=False,
                                    update_from_db=update_from_db)
#                                    include_in_update = True if parent is None
#                                    else False),
            )

        self._add_to_fs_query = {'prec': {'$gt': int(prec-1)}}

        super(WebNewForm, self).__init__(
            update_from_db=update_from_db,
            **kwargs
            )

        self._add_to_fs_query = {'prec': {'$gt': int(self.prec-1)}}
        
        # We're setting the WebEigenvalues property after calling __init__ of the base class
        # because it will set hecke_orbit_label from the db first

        ## 
        ## We don't init the eigenvalues (since E*v is slow)
        ## unless we (later) request a coefficient which is not
        ## in self._coefficients
        
        self.eigenvalues = WebEigenvalues(self.hecke_orbit_label, prec = self.prec, \
                                              init_dynamic_properties=False, \
                                              update_from_db = False)

        self.make_code_snippets()

    def update_from_db(self, ignore_precision = False, ignore_precision_if_failed = True, **kwargs):
        # this finds the (file) record with the
        # lowest precision (=smallest record)
        # above or equal to self.prec
        if not ignore_precision:
            self._add_to_fs_query = {'prec': {'$gt': int(self.prec-1)}}
            self._sort_files = [('prec', pymongo.ASCENDING)]
        else:
            # However, if ignore_precision is True,
            # then we just ignore this field
            # This is for compatibility reasons
            # as older versions did not have the prec stored in the fs
            file_key_multi = self._file_key_multi
            self._file_key_multi = None
            self._add_to_fs_query = None
            self._sort_files = []
        super(WebNewForm,self).update_from_db(**kwargs)
        if not self.has_updated() and ignore_precision_if_failed:
            self.update_from_db(ignore_precision = True, ignore_precision_if_failed = False)
        if ignore_precision:
            # restore file_key_multi
            self._file_key_multi = file_key_multi
            self._sort_files = [('prec', pymongo.ASCENDING)]
        #remember the precision we just got from the db for queries
        self._add_to_fs_query = {'prec': {'$gt': int(self.prec-1)}}

    def __repr__(self):
        if self.dimension == 0:
            s = "Zero "
        else:
            s = ""
        s = "WebNewform in S_{0}({1},chi_{2}) with label {3}".format(self.weight,self.level,self.character.number,self.label)
        return s

    def init_dynamic_properties(self):
        if self.q_expansion is not None:
            if not self.q_expansion.prec >= self.prec:
                self._properties['q_expansion'].set_from_coefficients(self._coefficients)
            self._properties['q_expansion'].maxprec = self.prec
        
    def q_expansion_latex(self, prec=None, name=None):
        return self._properties['q_expansion'].latex(prec, name, keepzeta=True)

    def value(self, z, embedding=0):
        if self.prec == 0:
            return 0
        else:
            q = exp(2*CC.pi()*CC(0,1)*z)
            return sum(self.coefficient_embedding(n,embedding)*q**n for n in range(self.prec))
            
    
    def coefficient(self, n):
        r"""
          Return coefficient nr. n
        """
        #emf_logger.debug("In coefficient: n={0}".format(n))
        if n==0:
            if self.is_cuspidal:
                return 0
        c = self._coefficients.get(n, None)
        if c is None:
            c = self.coefficients([n])[0] 
        return c

    def first_nonvanishing_coefficient(self, return_index = True):
        r"""
         Return the first Fourier coefficient of self
         of index >1 that does not vanish.
         if return_index is True, we also return the index of that coefficient
        """
        return self._coefficients.first_nonvanishing_coefficient(return_index=return_index)

    def first_nonvanishing_coefficient_norm(self):
        return self._coefficients.first_nonvanishing_coefficient_norm()

    def first_nonvanishing_coefficient_trace(self):
        return self._coefficients.first_nonvanishing_coefficient_trace()

    def complexity_of_first_nonvanishing_coefficients(self, number_of_coefficients=4):
        return self._coefficients.coefficient_complexity(number_of_coefficients)

    def coefficient_embeddings(self, n):
        r"""
          Return all emneddings of the coefficient a(n) of self.
        """
        if not 'values' in self._embeddings:
            raise ValueError('We do not have any embeddings. for coefficient a({})'.format(n))
        else:
            if n < self.prec:
                return self._embeddings['values'][n]
            else:
                raise ValueError('We do not have coefficient a({})'.format(n))

    def coefficient_embedding(self,n,i):
        r"""
        Return the i-th complex embedding of coefficient C(n).
        Note that if it is not in the dictionary we compute the embedding (but not the coefficient).
        """
        if not 'values' in self._embeddings:
            self._embeddings['values'] = {}
        if not 'bitprec' in self._embeddings:
            self._embeddings['bitprec'] = {}
        embc = self._embeddings['values'].get(n,None)
        bitprec = self._embeddings['bitprec']
        if embc is None:
            c = self.coefficient(n)
            if hasattr(c,"complex_embeddings"):
                embc = c.complex_embeddings(bitprec)
            else:
                embc = [ComplexField(bitprec)(c) for x in range(self.coefficient_field_degree)]
            self._embeddings['values'][n]=embc
        else:
            if len(embc) < self.coefficient_field_degree:
                embc = [embc[0] for x in range(self.coefficient_field_degree)]
                self._embeddings['values'][n]=embc
        if i > len(embc):
            raise ValueError,"Embedding nr. {0} does not exist of a number field of degree {1},embc={2}".format(i,self.coefficient_field_degree,embc)
        return embc[i]
        
        
    def coefficients(self, nrange=range(1, 10), save_to_db=False):
        r"""
         Gives the coefficients in a range.
         We assume that the self._ap containing Hecke eigenvalues
         are stored.
        """
        if len(nrange) == 0:
            return []
        if not isinstance(nrange, list):
            M = nrange
            nrange = range(0, M)
        if len(nrange) > 1:
            emf_logger.debug("getting coeffs in range {0}--{1}".format(nrange[0],nrange[-1]))
        else:
            emf_logger.debug("getting coeffs in range {0}--{0}".format(nrange[0]))
        res = []
        recompute = False
        for n in nrange:
            c = self._coefficients.get(n, None)
            #emf_logger.debug("c({0}) in self._coefficients={1}".format(n,c))            
            if c is None:
                if n == 0 and self.is_cuspidal:
                    c = 0
                else:
                    recompute = True
                    c = self.coefficient_n_recursive(n)
                    self._coefficients[n] = c
            res.append(c)
        if recompute and save_to_db:
            self.save_to_db(update=True)
        return res
       
    def coefficient_n_recursive(self, n):
        r"""
          Reimplement the recursive algorithm in sage modular/hecke/module.py
          We do this because of a bug in sage with .eigenvalue()
        """
        from sage.all import factor
        ev = self.eigenvalues

        c2 = self._coefficients.get(2)
        if c2 is not None:
            K = c2.parent()
        else:
            if ev.max_coefficient_in_db() >= 2:
                if not ev.has_eigenvalue(2):
                    ev.init_dynamic_properties()
            else:
                raise StopIteration,"Newform does not have eigenvalue a(2)!"
            self._coefficients[2]=ev[2]
            K = ev[2].parent()
        prod = K(1)
        if K.absolute_degree()>1 and K.is_relative():
            KZ = K.base_field()
        else:
            KZ = K
        #emf_logger.debug("K= {0}".format(K))
        F = factor(n)
        for p, r in F:
            #emf_logger.debug("parent_char_val[{0}]={1}".format(p,self.parent.character_used_in_computation.value(p)))
            #emf_logger.debug("char_val[{0}]={1}".format(p,self.character.value(p)))
            (p, r) = (int(p), int(r))
            pr = p**r
            cp = self._coefficients.get(p)
            if cp is None:
                if ev.has_eigenvalue(p):
                    cp = ev[p]
                elif ev.max_coefficient_in_db() >= p:
                    ev.init_dynamic_properties()
                    cp = ev[p]
            #emf_logger.debug("c{0} = {1}, parent={2}".format(p,cp,cp.parent()))
            if cp is None:
                raise IndexError,"p={0} is outside the range of computed primes (primes up to {1})! for label:{2}".format(p,max(ev.primes()),self.label)
            if self._coefficients.get(pr) is None:
                if r == 1:
                    c = cp
                else:
                    # a_{p^r} := a_p * a_{p^{r-1}} - eps(p)p^{k-1} a_{p^{r-2}}
                    apr1 = self.coefficient_n_recursive(pr//p)
                    #ap = self.coefficient_n_recursive(p)
                    apr2 = self.coefficient_n_recursive(pr//(p*p))
                    val = self.character.value(p)
                    if val == 0:
                        c = cp*apr1
                    else:
                        eps = KZ(val)
                        c = cp*apr1 - eps*(p**(self.weight-1)) * apr2
                    #emf_logger.debug("c({0})={1}".format(pr,c))
                            #ev[pr]=c
                self._coefficients[pr]=c
            try:
                prod *= K(self._coefficients[pr])
            except:
                if hasattr(self._coefficients[pr],'vector'):
                    if len(self._coefficients[pr].vector()) == len(K.power_basis()):
                        prod *= K(self._coefficients[pr].vector())
                    else:
                        emf_logger.debug("vec={0}".format(self._coefficients[pr].vector()))
                        raise ArithmeticError,"Wrong size of vectors!"
                else:
                    raise ArithmeticError,"Can not compute product of coefficients!"
            
        return prod

    def available_precs(self):
        r"""
        The precision is the number of computed Fourier coefficients.
        We have several records in the database for each newform, 
        each in a different precision.
        This method returns a list of the precisions that are available in the database for this newform.
        """
        files = self.get_file_list()
        try:
            return [x['prec'] for x in files]
        except KeyError:
            #backwards compatibility
            try:
                return [self.get_db_record()['prec']]
            except KeyError:
                return [self.prec]

    def max_available_prec(self):
        try:
            ps = self.available_precs()
        except IndexError:
            ps = [0]
        return max(ps)

    def delete_file_with_prec(self, prec):
        files = self.get_file_list({'prec': int(prec)})
        for f in files:
            self._files.delete(f['_id'])

    def max_cn(self):
        r"""
        The largest N for which we are sure that we can compute a(n) for all 1<=n<=N
        """
        return self.eigenvalues.max_coefficient_in_db()

        #if self.eigenvalues.primes()==[]:
        #    return 1
        #return max(self.eigenvalues.primes()) + 1

    def atkin_lehner_eigenvalue(self, Q):
        r""" Return the Atkin-Lehner eigenvalues of self
        corresponding to Q|N
        """
        if not (self.character.is_trivial() or self.character.order == 2):
            return None
        
        l = self.atkin_lehner_eigenvalues()
        return l.get(Q)

    def atkin_lehner_eigenvalues(self):
        r""" Return the Atkin-Lehner eigenvalues of self.

           EXAMPLES::

           sage: get_atkin_lehner_eigenvalues(4,14,0)
           '{2: 1, 14: 1, 7: 1}'
           sage: get_atkin_lehner_eigenvalues(4,14,1)
           '{2: -1, 14: 1, 7: -1}'

        """
        if not (self.character.is_trivial() or self.character.order == 2):
            return None
        
        if(len(self._atkin_lehner_eigenvalues.keys()) > 0):
            return self._atkin_lehner_eigenvalues

    def atkin_lehner_eigenvalues_for_all_cusps(self):
        r"""
        """
        self._atkin_lehner_eigenvalues_at_cusps = {}
        G =Gamma0(self.level)
        for c in Gamma0(self.level).cusps():
            aev = self.atkin_lehner_eigenvalues()
            if aev is None:
                self._atkin_lehner_eigenvalues_at_cusps = None
            else:
                for Q,ev in aev.items():
                    if G.are_equivalent(c,Q/self.level):
                        self._atkin_lehner_eigenvalues_at_cusps[c] = Q,ev
        return self._atkin_lehner_eigenvalues_at_cusps
        
    def url(self):
        return url_for('emf.render_elliptic_modular_forms', level=self.level, weight=self.weight, character=self.character.number, label=self.label)

    def create_small_record(self, min_prec=10, want_prec=100, max_length = 5242880, max_height_qexp = default_max_height):
        ### creates a duplicate record (fs) of this webnewform
        ### with lower precision to load faster on the web
        ### we aim to have at most max_length bytes
        ### but at least min_prec coefficients and we desire to have want_prec
        if min_prec>=self.prec:
            raise ValueError("Need higher precision, self.prec = {}".format(self.prec))
        if not hasattr(self, '_file_record_length'):
            self.update_from_db()
        l = self._file_record_length
            
        if l > max_length or self.prec > want_prec:
            nl = float(l)/float(self.prec)*float(want_prec)
            if nl > max_length:
                prec = max([floor(float(self.prec)/float(l)*float(max_length)), min_prec])
            else:
                prec = want_prec
            emf_logger.debug("Creating a new record with prec = {}".format(prec))
            self.prec = prec
            include_coeffs = self.complexity_of_first_nonvanishing_coefficients() <= default_max_height
            if include_coeffs:
                self.q_expansion = self.q_expansion.truncate_powerseries(prec)
                self._coefficients = {n:c for n,c in self._coefficients.iteritems() if n<prec}
            else:
                self.q_expansion = self.q_expansion.truncate_powerseries(1)
                self._coefficients = {}
                self.prec = 0
                self.coefficient_field = NumberField(self.absolute_polynomial, names=str(self.coefficient_field.gen()))
            self._embeddings['values'] = {n:c for n,c in self._embeddings['values'].iteritems() if n<prec}
            self._embeddings['prec'] = prec
            self.save_to_db()

    def download_to_sage(self, prec=None):
        r"""
        Minimal version for now to download to sage.
        Does not work for high values of prec for large degree number fields (timeout).
        """
        if prec is None:
            prec = self.prec
        s = "var('x')\n"
        if self.base_ring.absolute_degree() > 1:
            s += "K.<{brgen}>=NumberField({crpol})\n".format(brgen=str(self.base_ring.gen()), crpol=self.base_ring.polynomial().change_variable_name('x'))
        if self.coefficient_field.is_absolute():
            if self.coefficient_field.absolute_degree() > 1:
                s +=  "L.<{cfgen}> = NumberField({cfpol})\n".format(
                    cfgen=str(self.coefficient_field.gen()), cfpol=self.absolute_polynomial
                  )
        elif self.coefficient_field.relative_degree() > 1:
            s += "y = polygen(K)\n"
            s +=  "L.<{cfgen}> = NumberField({cfpol})\n".format(
                  cfgen=str(self.coefficient_field.gen()), cfpol=self.coefficient_field.relative_polynomial().change_variable_name('y')
                  )
        s = s + "D = DirichletGroup({N})\n".format(
            N = self.level
            )
        C = self.character.sage_character.parent()
        s = s + "f = {{'coefficients': {coeffs}, 'level' : {level}, 'weight': {weight}, 'character': D.Element(D,vector({elt})), 'label': '{label}','dimension': {dim}, 'is_cm': {cm} , 'cm_discriminant': {cm_disc}, 'atkin_lehner': {al}, 'explicit_formulas': {ep}}}".format(coeffs = self.coefficients(range(prec)),
            level=self.level, weight=self.weight, elt = list(self.character.sage_character.element()), label=self.hecke_orbit_label, dim=self.dimension, cm=self.is_cm, cm_disc=None if not self.is_cm else self.cm_disc , al=self.atkin_lehner_eigenvalues(),
            ep = self.explicit_formulas
            )
        s = s + "\n\n#EXAMPLE\n"
        s = s + "#sage: f['coefficients'][7]\n#{}\n".format(self.coefficient(7))
        s = s + "#sage: f['character']\n#{}".format(self.character.sage_character)
        emf_logger.debug("Generated sage file for {}".format(self.hecke_orbit_label))
        return s

    def sage_newform_number(self):
        ##store this in the db!!
        return orbit_index_from_label(self.label)

    def make_code_snippets(self):
        self.code = deepcopy(self.parent.code)
        self.code['show'] = {'sage':''}
        # Fill in placeholders for this specific newform:
        self.code['f']['sage'] = self.code['f']['sage'].format(newform_number=self.sage_newform_number())

        #self.code['f']['sage'] = self.code['f']['sage'].split("\n")
        # remove final empty line
        if len(self.code['f']['sage'][-1])==0:
            self.code['f']['sage'] = self.code['f']['sage'][:-1]

    def dump_coefficients(self, prec):
        if prec is None:
            prec = self.prec
        return dumps(self.coefficients(range(prec)))
Example #44
0
def session():
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(bind=engine)
    return Session()

########################################################
# Convenience functions to use the database
########################################################
from sage.all import (QQ, ZZ, NumberField, polygen, dumps, gcd, parallel, divisors,
                      cartesian_product_iterator)
from sage.rings.all import is_Ideal
from psage.modform.hilbert.sqrt5.hmf import primes_of_bounded_norm
from psage.number_fields.sqrt5.prime import Prime

x = polygen(QQ, 'x')
F = NumberField(x**2 - x - 1, 'a')
a = F.gen()

def ideal_to_tuple(N):
    v = N.free_module().echelonized_basis_matrix().list()
    return int(v[0]), int(v[1]), int(v[3])

def tuple_to_ideal(t):
    return F.ideal([t[0] + a*t[1], t[2] + a*t[2]])

def fast_ideal(P):
    return Prime(P) if is_Ideal(P) else P
    
def store_space(s, H):
    """
    s = session
Example #45
0
def list_to_factored_poly_otherorder(s, galois=False, vari = 'T'):
    """ Either return the polynomial in a nice factored form,
        or return a pair, with first entry the factored polynomial
        and the second entry a list describing the Galois groups
        of the factors.
        vari allows to choose the variable of the polynomial to be returned.
    """
    gal_list=[]
    if len(s) == 1:
        if galois:
            return [str(s[0]), [[0,0]]]
        return str(s[0])
    sfacts = factor(PolynomialRing(ZZ, 'T')(s))
    sfacts_fc = [[v[0],v[1]] for v in sfacts]
    if sfacts.unit() == -1:
        sfacts_fc[0][0] *= -1
    outstr = ''
    x = var('x')
    for v in sfacts_fc:
        this_poly = v[0]
        # if the factor is -1+T^2, replace it by 1-T^2
        # this should happen an even number of times, mod powers
        if this_poly.substitute(T=0) == -1:
            this_poly = -1*this_poly
            v[0] = this_poly
        if galois:
            this_degree = this_poly.degree()
                # hack because currently sage only handles monic polynomials:
            this_poly = expand(x**this_degree*this_poly.substitute(T=1/x))
            this_number_field = NumberField(this_poly, "a")
            this_gal = this_number_field.galois_group(type='pari')
            this_t_number = this_gal.group().__pari__()[2].sage()
            gal_list.append([this_degree, this_t_number])
        vcf = v[0].list()
        started = False
        if len(sfacts) > 1 or v[1] > 1:
            outstr += '('
        for i in range(len(vcf)):
            if vcf[i] != 0:
                if started and vcf[i] > 0:
                    outstr += '+'
                started = True
                if i == 0:
                    outstr += str(vcf[i])
                else:
                    if abs(vcf[i]) != 1:
                        outstr += str(vcf[i])
                    elif vcf[i] == -1:
                        outstr += '-'
                    if i == 1:
                        outstr += vari #instead of putting in T for the variable, put in a variable of your choice
                    elif i > 1:
                        outstr += vari + '^{' + str(i) + '}'
        if len(sfacts) > 1 or v[1] > 1:
            outstr += ')'
        if v[1] > 1:
            outstr += '^{' + str(v[1]) + '}'
    if galois:
        if galois and len(sfacts_fc)==2:
            if sfacts[0][0].degree()==2 and sfacts[1][0].degree()==2:
                troubletest = sfacts[0][0].disc()*sfacts[1][0].disc()
                if troubletest.is_square():
                    gal_list=[[2,1]]
        return [outstr, gal_list]
    return outstr
Example #46
0
def find_newform_label(level,weight,character,field,aps):
    r"""
    Find the label of the newform orbit in the database which matches the input.
    
    INPUT:
    - 'level'     -- the level,
    - 'weight'    -- the weight
    - 'character' -- the character'
    - 'field'     -- the field, given in terms of a list of integer coefficients for the absolute polynomial  
    - 'aps'       -- the coefficients - given as a dictionary of lists giving the coefficient in terms of the generator of the field as above.
    
    
    EXAMPLE:
    
    sage: find_newform_label(9,16,1,[-119880,0,1],{2:[0,1]})
    u'e'
    sage: find_newform_label(71,2,1,[-3,-4,1,1],{3:[0,-1,0]})
    u'a'
    sage: find_newform_label(71,2,1,[-3,-4,1,1],{5:[5,1,-1]})
    u'a'
    
    NOTE: We implicitly assume that the input given is correct in the sense that 
        if there is a unique orbit with a coefficient field of the same degree as the input
        then we simply return that label. (This will save a lot of time...)
        
    """
    from web_modform_space import WebModFormSpace
    from sage.all import NumberField,QQ
    M = WebModFormSpace(level=level,weight=weight,character=character)
    if M.dimension_new_cusp_forms==1:
        return 'a'
    orbits = M.hecke_orbits
    ## construct field from field input... 
    if not isinstance(field,list):
        raise ValueError,"Need to give field as a list!"
    if not isinstance(aps,dict):
        raise ValueError,"Need to give aps as a dict!"
    if field == [1]:
        NF = QQ
    else:
        NF = NumberField(QQ['x'](field),names='x')
    degree_of_input = NF.absolute_degree()
    degrees = map(lambda x:x[1].coefficient_field_degree,orbits.viewitems())
    if degrees.count(degree_of_input)==0:
        raise ValueError,"No newform with this level, weight, character and field degree!"
    if degrees.count(degree_of_input)==1:
        ## If there is a unique mathcing field we return this orbit label.
        l = filter(lambda x: x[1].coefficient_field_degree==degree_of_input,orbits.viewitems() )
        return l[0][0]
    aps_input = { p: NF(a) for p,a in aps.viewitems()}
    possible_labels = orbits.keys()
    for label,f in orbits.viewitems():
        if f.coefficient_field_degree != degree_of_input:
            possible_labels.remove(label)
            continue
        try:
            for p,ap_input in aps_input.viewitems():
                if f.coefficient_field == QQ:
                    homs = [lambda x: x]
                else:
                    homs = f.coefficient(p).parent().Hom(NF)
                for h in homs:
                    ap = h(f.coefficient(p))
                    if ap_input != ap:
                        possible_labels.remove(label)
                        raise StopIteration
        except StopIteration:
            continue
    if len(possible_labels) > 1:
        raise ArithmeticError,"Not sufficient data (or errors) to determine orbit!"
    if len(possible_labels) == 0:
        raise ArithmeticError,"Not sufficient data (or errors) to determine orbit! NO matching label found!"
    return possible_labels[0]
Example #47
0
    sage: c = F.primes_above(389)[0]
    sage: T = hecke_ops(c, TH)
    sage: for nm,p,t in T:
    ...       print nm, p, t.charpoly().factor()
    5 a + 2 (x - 6) * (x^2 + 4*x - 1) * (x^2 - x - 4)^2
    9 3 (x - 10) * (x^2 + 3*x - 9) * (x^4 - 5*x^3 + 3*x^2 + 6*x - 4)
    11 a + 3 (x - 12) * (x + 3)^2 * (x^4 - 17*x^2 + 68)
    11 2*a + 3 (x - 12) * (x^2 + 5*x + 5) * (x^4 - x^3 - 23*x^2 + 18*x + 52)
"""


from sage.all import (NumberField, polygen, QQ, ZZ, QuaternionAlgebra,
                      cached_function, disk_cached_function)

x = polygen(QQ,'x')
F = NumberField(x**2 - x -1, 'a')
O_F = F.ring_of_integers()
B = QuaternionAlgebra(F, -1, -1, 'i,j,k')

def modp_splitting(p):
    """
    INPUT:
        
        - p -- ideal of the number field K = B.base() with ring O of integers.
        
    OUTPUT:
        
        - matrices I, J in M_2(O/p) such that i |--> I and j |--> J defines 
          an algebra morphism, i.e., I^2=a, J^2=b, I*J=-J*I.

    EXAMPLES::    
Example #48
0
def _a47():
    x = var("x")
    K = NumberField(
        x ** 3 - x ** 2 - ZZ(524706) * x + ZZ(103406706), names="a47")
    return K.gens()[0]