Beispiel #1
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
Beispiel #2
0
    def express(self, a, prec=None):
        'Express the given number in terms of self'
        if self._min_poly is None:
            raise ValueError('Minimal polynomial is not known.')
        if prec is None:
            prec = self._default_precision
        p = self._min_poly
        z0, a0 = self(prec), a(prec)
        A = complex_to_lattice(z0, p.degree(), a0)
        v = A.LLL(delta=0.75)[0]
        v = list(v)[:-2]
        if v[-1] == 0:
            return None
        R = PolynomialRing(QQ, 'x')
        q = -R(v[:-1]) / v[-1]

        # Now we double-check
        z1, a1 = self(2 * prec), a(2 * prec)
        if acceptable_error(q, z1, a1, 0.2):
            return q
Beispiel #3
0
    def computation_roots(self):
        # Write these as p-adic series.  Start with helper
        def help_padic(n, p, prec):
            """
              Take an integer n, prime p, and precision prec, and return a 
              prec-tuple of the p-adic coefficients of j
            """
            n = int(n)
            res = [0 for j in range(prec)]
            while n < 0:
                n += p**prec
            for k in range(prec):
                res[k] = n % p
                n = (n - res[k]) / p
            return res

        # Second helper, in case some arrays are not extended by 0
        def getel(li, j):
            if j < len(li):
                return li[j]
            return 0

        myroots = self._data["QpRts"]
        p = self._data['QpRts-p']
        myroots = [[help_padic(z, p, self._data['QpRts-prec']) for z in t]
                   for t in myroots]
        myroots = [[[
            getel(root[j], r)
            for j in range(len(self._data['QpRts-minpoly']) - 1)
        ] for r in range(self._data['QpRts-prec'])] for root in myroots]
        myroots = [[coeff_to_poly(x, var='a') for x in root]
                   for root in myroots]
        # Use power series so degrees increase
        # Use formal p so we can make a power series
        PR = PowerSeriesRing(PolynomialRing(QQ, 'a'), 'p')
        myroots = [web_latex(PR(x), enclose=False) for x in myroots]
        # change p into its value
        myroots = [
            re.sub(r'([a)\d]) *p', r'\1\cdot ' + str(p), z) for z in myroots
        ]
        return [z.replace('p', str(p)) for z in myroots]
def num_denom_for_rational_function_field(f, R):
    r""" Return the numerator and denominator of a function field element.

    INPUT:

    - ``f`` -- an element of a rational function field over a field `K`
    - ``R`` -- an order in K

    OUTPUT: a pair `g, h` of univariate polynomials over `R` such that
    `f = g/h`.

    """
    # F = f.parent()
    # A = F._ring     It seems I don't need these lines
    B = PolynomialRing(R, 'x')
    g = f.numerator()
    a = common_denominator_of_polynomial(g, R)
    h = f.denominator()
    b = common_denominator_of_polynomial(g, R)
    c = lcm(a, b)
    return B(c * g), B(c * h)
Beispiel #5
0
 def divisor_data(P):
     R = PolynomialRing(QQ, ['x', 'z'])
     x = R('x')
     z = R('z')
     xP, yP = P[0], P[1]
     xden, yden = lcm([r[1] for r in xP]), lcm([r[1] for r in yP])
     xD = sum([
         ZZ(xden) * ZZ(xP[i][0]) / ZZ(xP[i][1]) * x**i *
         z**(len(xP) - i - 1) for i in range(len(xP))
     ])
     if str(xD.factor())[:4] == "(-1)":
         xD = -xD
     yD = sum([
         ZZ(yden) * ZZ(yP[i][0]) / ZZ(yP[i][1]) * x**i *
         z**(len(yP) - i - 1) for i in range(len(yP))
     ])
     return [
         str(xD.factor()).replace("**", "^").replace("*", ""),
         str(yden) + "y" if yden > 1 else "y",
         str(yD).replace("**", "^").replace("*", "")
     ], xD, yD, yden
Beispiel #6
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
Beispiel #7
0
def list_to_factored_poly_otherorder(s, 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.
    """
    if len(s) == 1:
        if galois:
            return [str(s[0]), [[0,0]]]
        return str(s[0])
    ZZT = PolynomialRing(ZZ, vari)
    sfacts = ZZT(s).factor()
    sfacts_fc = [[g, e] for g, e in sfacts]
    if sfacts.unit() == -1:
        sfacts_fc[0][0] *= -1
    # if the factor is -1+T^2, replace it by 1-T^2
    # this should happen an even number of times, mod powers
    sfacts_fc_list = [[(-g).list() if g[0] == -1 else g.list(), e] for g, e in sfacts_fc]
    return list_factored_to_factored_poly_otherorder(sfacts_fc_list, galois, vari, p)
Beispiel #8
0
def eqn_list_to_curve_plot(L):
    xpoly_rng = PolynomialRing(QQ,'x')
    poly_tup = [xpoly_rng(tup) for tup in L]
    f = poly_tup[0]
    h = poly_tup[1]
    g = f+h**2/4
    if len(g.real_roots())==0 and g(0)<0:
        return text("$X(\mathbb{R})=\emptyset$",(1,1),fontsize=50)
    X0 = [real(z[0]) for z in g.base_extend(CC).roots()]+[real(z[0]) for z in g.derivative().base_extend(CC).roots()]
    a,b = inflate_interval(min(X0),max(X0),1.5)
    groots = [a]+g.real_roots()+[b]
    if b-a<1e-7:
        a=-3
        b=3
        groots=[a,b]
    ngints = len(groots)-1
    plotzones = []
    npts = 100
    for j in range(ngints):
        c = groots[j]
        d = groots[j+1]
        if g((c+d)/2)<0:
            continue
        (c,d) = inflate_interval(c,d,1.1)
        s = (d-c)/npts
        u = c
        yvals = []
        for i in range(npts+1):
            v = g(u)
            if v>0:
                v = sqrt(v)
                w = -h(u)/2
                yvals.append(w+v)
                yvals.append(w-v)
            u += s
        (m,M) = inflate_interval(min(yvals),max(yvals),1.2)
        plotzones.append((c,d,m,M))
    x = var('x')
    y = var('y')
    return sum(implicit_plot(y**2+y*h(x)-f(x),(x,R[0],R[1]),(y,R[2],R[3]),aspect_ratio='automatic',plot_points=500) for R in plotzones)
Beispiel #9
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))
Beispiel #10
0
    def minpoly_over_unramified_subextension(self, N):
        r"""
        Return the minimal polynomial of the standard uniformizer of this `p`-adic
        number field `K`, relative to the maximal unramified subfield,
        as a polynomial over `K` itself.

        INPUT:

        - ``N`` -- a positive integer

        OUTPUT:

        A polynomial `P` over the number field `K_0` underlying `K`. `P` is an
        approximation (with precision ``N``) of the minimal polynomial
        of the standard uniformizer `\pi` of `K`, relative to the maximal
        unramified subfield `K_{nr}` of `K`. Moreover, `P(\pi)=0` holds exactly.

        If the approximation is sufficient (note: this still has to be made
        precise) then `P` has a root `\pi_1` in `K` which is also a uniformizer of `K`, and `K = K_{nr}[\pi_1]`.

        NOTE:

        To check that `P` is ok, it should suffice to see that `P` is "Eisenstein
        over `K_nr`" and has a root in `K`. Unfortunately, the coefficient will
        likely not lie in `K_{nr}` exactly, and so this criterion probably makes
        no sense.

        """
        K0 = self.number_field()
        R = PolynomialRing(K0, 'x')
        x = R.gen()
        e = self.ramification_degree()
        m = self.inertia_degree()
        if m == 1:
            return self.polynomial().change_ring(K0)

        zeta = self.integral_basis_of_unramified_subfield(N)
        S = self.base_change_matrix(precision=N, integral_basis="mixed")
        P = x**e - sum( sum(S[e,i+e*j]*zeta[j] for j in range(m))*x**i for i in range(e))
        return self.reduce_polynomial(P, N)
Beispiel #11
0
def InsolublePlaces(f, h=0):
    # List of primes at which the curve y²+h(x)*y=f(x) is not soluble
    # Assumes f and h have integer coefficients
    S = []  # List of primes at which not soluble
    # Get eqn of the form y²=F(x)
    F = f
    if h:
        F = 4 * f + h**2
    # Do we have a rational point an Infty ?
    if F.degree() % 2 or F.leading_coefficient().is_square():
        return []
    # Treat case of RR
    if F.leading_coefficient() < 0 and F.number_of_real_roots() == 0:
        S.append(0)
    # Remove squares from lc(F)
    d = F.degree()
    lc = F.leading_coefficient()
    t = F.variables()[0]
    a = lc.squarefree_part()  # lc/a is a square
    a = lc // a
    Zx = PolynomialRing(ZZ, 'x')
    F = Zx(a**(d - 1) * F(t / a))
    # Find primes of bad reduction for our model
    D = F.disc()
    P = Set(D.prime_divisors())
    # Add primes at which Weil bounds do not guarantee a mod p point
    g = (d - 2) // 2
    Weil = []
    p = 2
    while (p + 1)**2 <= 4 * g**2 * p:
        Weil.append(p)
        p = next_prime(p)
    P = P.union(Set(Weil))
    # Test for solubility
    for p in P:
        if not IsSolubleAt(F, p):
            S.append(p)
    S.sort()
    return S
Beispiel #12
0
def qexp_as_nf_elt(self, prec=None):
    assert self.has_exact_qexp
    if prec is None:
        qexp = self.qexp
    else:
        qexp = self.qexp[:prec + 1]
    if self.dim == 1:
        return [QQ(i[0]) for i in self.qexp]

    R = PolynomialRing(QQ, 'x')
    K = QQ.extension(R(self.field_poly), 'a')
    if self.hecke_ring_power_basis:
        return [K(c) for c in qexp]
    else:
        # need to add code to hande cyclotomic_generators
        assert self.hecke_ring_numerators, self.hecke_ring_denominators
        basis_data = zip(self.hecke_ring_numerators,
                         self.hecke_ring_denominators)
        betas = [K([ZZ(c) / den for c in num]) for num, den in basis_data]
        return [
            sum(c * beta for c, beta in zip(coeffs, betas)) for coeffs in qexp
        ]
Beispiel #13
0
def _mixed_volume_gfan(gen):
    """
    Use gfan to compute the mixed volume of a collection of polytopes.
    Just like Khovanskii, we use the normalised mixed volume which satisfies
    mixed_volume([P,...,P]) = volume(P).
    """

    P = list(gen)
    n = len(P)

    if any(Q.ambient_dim() != n for Q in P):
        raise TypeError(
            'Number of polytopes and ambient dimension do not match')

    if n == 0:
        return 0
    elif n == 1:
        return P[0].volume()

    R = PolynomialRing(QQ, 'x', n)
    I = R.ideal([sum(monomial_exp(R, e) for e in Q.vertices()) for Q in P])
    return ZZ.one() / Integer(factorial(n)) * I.groebner_fan().mixed_volume()
def repair_fields(D):
    F = hmf_fields.find_one({"label": '2.2.' + str(D) + '.1'})

    P = PolynomialRing(Rationals(), 'w')
    # P is used implicitly in the eval() calls below.  When these are
    # removed, this will not longer be neceesary, but until then the
    # assert statement is for pyflakes.
    assert P

    primes = F['primes']
    primes = [[int(eval(p)[0]), int(eval(p)[1]), str(eval(p)[2])] for p in primes]
    F['primes'] = primes

    hmff = file("data_2_" + (4 - len(str(D))) * '0' + str(D))

    # Parse field data
    for i in range(7):
        v = hmff.readline()
    ideals = eval(v[10:][:-2])
    ideals = [[p[0], p[1], str(p[2])] for p in ideals]
    F['ideals'] = ideals
    hmf_fields.save(F)
Beispiel #15
0
    def time_6_8(self):
        r"""
        TESTS::
 
            sage: import henselization
            sage: from henselization.benchmarks.splitting_fields import SplittingField
            sage: SplittingField().time_6_8()
            Factoring T^6 + 168*T^5 - 209*T^4 + 52*T^3 + 26*T^2 + 8*T - 14 over a field of degree 1 * 1…
            …factors with degrees [4, 1, 1]
            Found totally ramified part of degree 4
            Factoring T^6 + 168*T^5 - 209*T^4 + 52*T^3 + 26*T^2 + 8*T - 14 over a field of degree 1 * 4…
            …factors with degrees [2, 1, 1, 1, 1]
            Found totally ramified part of degree 2
            Factoring T^6 + 168*T^5 - 209*T^4 + 52*T^3 + 26*T^2 + 8*T - 14 over a field of degree 1 * 8…
            …factors with degrees [1, 1, 1, 1, 1, 1]

        """
        K = QQ.henselization(2)
        R = PolynomialRing(K, 'T')
        T = R.gen()
        f = T**6 + 168 * T**5 - 209 * T**4 + 52 * T**3 + 26 * T**2 + 8 * T - 14
        splitting_field(f)
Beispiel #16
0
    def test_download_sage(self):

        # A dimension 1 example
        L1_sage_code = self.tc.get(
            '/ModularForm/GL2/ImaginaryQuadratic/2.0.3.1/18333.3/a/download/sage'
        ).get_data(as_text=True)
        L1_level = self.check_sage_compiles_and_extract_var(L1_sage_code, 'NN')
        assert L1_level.norm() == Integer(18333)
        assert 'NN = ZF.ideal((6111, 3*a + 5052))' in L1_sage_code
        assert '(27*a-22,),(-29*a+15,),(-29*a+14,),(29*a-11,),(-29*a+18,),(-29*a+9,)' in L1_sage_code
        assert 'hecke_eigenvalues_array = [0, -1, 2, -1, 1, -3, 4, 0, -2, -8, 7, -9, -8, -4, -9, 8, 10, -11,' in L1_sage_code
        """
        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_sage_code = self.tc.get(
            '/ModularForm/GL2/ImaginaryQuadratic/2.0.4.1/377.1/a2/download/sage'
        ).get_data(as_text=True)
        L2_level = self.check_sage_compiles_and_extract_var(L2_sage_code, 'NN')

        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_sage_code
        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_sage_code
Beispiel #17
0
def test_masur_veech_edge_weight():
    from surface_dynamics.topological_recursion import MasurVeechTR
    from sage.all import PolynomialRing

    R = PolynomialRing(QQ, 't')
    t = R.gen()
    MV = MasurVeechTR(edge_weight=t)
    for g, n, value in [
        (0, 3, R.one()), (0, 4, t), (0, 5, QQ((4, 9)) * t + QQ((5, 9)) * t**2),
        (0, 6, QQ((8, 27)) * t + QQ((4, 9)) * t**2 + QQ((7, 27)) * t**3),
        (1, 1, t), (1, 2, QQ((5, 9)) * t + QQ((4, 9)) * t**2),
        (1, 3, QQ((4, 9)) * t + QQ((13, 33)) * t**2 + QQ((16, 99)) * t**3),
        (2, 1, QQ((76, 261)) * t + QQ((125, 261)) * t**2 + QQ(
            (440, 2349)) * t**3 + QQ((100, 2349)) * t**4),
        (2, 2, QQ((296, 1011)) * t + QQ((19748, 45495)) * t**2 + QQ(
            (9127, 45495)) * t**3 + QQ((560, 9099)) * t**4 + QQ(
                (100, 9099)) * t**5)
    ]:
        p = MV.F(g, n, (0, ) * n)
        assert parent(p) is R
        p /= p(1)
        assert p == value, (g, n, p, value)
Beispiel #18
0
def NF_embedding_algdep(z, numberfield, ithcomplex_embedding = 0, known_bits=None ):
    """
    Input:
        z \in Complex Number
        numberfield a NumberField
        ithcomplex_embedding uses the i-th embedding of self in the complex numbers
        known_bits to pass to algdep
    Output:
        returns z in terms of generators for the numberfield respecting the embedding

    Examples:
        QQx.<x> = QQ[]
        L.<a> = NumberField(x**2 + 3)
        NF_embedding_algdep(ComplexField(100)(2*sqrt(-3) + 1000000), L)
    """
    polynomialnf = PolynomialRing(numberfield, "W");

    if known_bits is None:
        prec = z.prec()*0.8
    else:
        prec = known_bits

    algdepnf = polynomialnf( algdep(z, numberfield.absolute_degree(), known_bits = known_bits) )
    #print algdepnf, algdepnf.roots()
    #if ithcomplex_embedding is None and numberfield.degree() > 1:
    #    ithcomplex_embedding = len(numberfield.complex_embeddings()) - 1

    minvalue = +Infinity;
    minarg = None;
    if numberfield.absolute_degree() > 1:
        for r, _ in algdepnf.roots():
            diff = (z  - r.complex_embedding(prec = prec, i = ithcomplex_embedding)).abs()
            if diff < minvalue:
                minvalue = diff;
                minarg = r
    else:
        minarg = algdepnf.roots()[0][0]
    assert almost_equal(z, minarg,  ithcomplex_embedding = ithcomplex_embedding, prec = known_bits), "z =? %s" % minarg;
    return minarg
Beispiel #19
0
 def __init__(self, K, L, approximation=None):
     if isinstance(approximation, MacLaneLimitValuation):
         # v = apprximation determines phi uniquely
         v = approximation
         assert v(K.polynomial()) == Infinity
     else:
         if approximation == None:
             R = PolynomialRing(L.number_field(), 'x')
             v0 = GaussValuation(R, L.valuation())
         else:
             v0 = approximation
         # now we have to find a limit valuation v such that v(P_K)=infinity
         # which is approximated by v0
         P = R(K.polynomial())
         V = [v0]
         done = False
         while len(V) > 0 and not done > 0:
             V_new = []
             for v in V:
                 if v.phi().degree() == 1:
                     if v.effective_degree(P) == 1 or v.mu() == Infinity:
                         V_new = [v]
                         done = True
                         break
                     else:
                         V_new += v.mac_lane_step(P,
                                                  assume_squarefree=True,
                                                  check=False)
             V = V_new
         if len(V) == 0:
             raise AssertionError("no embedding exists")
         else:
             v = V[0]
     # now v is an approximation of an irreducible factor of P of degree 1
     v = LimitValuation(v, P)
     self._domain = K
     self._target = L
     self._limit_valuation = v
Beispiel #20
0
def Relative_Splitting_Field_Extra(fs, bound=0):
    bound_set = (bound != 0)
    F = magma.BaseRing(fs[1])
    overQQ = (magma.Degree(F) == 1)
    if overQQ:
        R = PolynomialRing(QQ, 'x')
    fs = sorted(fs, key=lambda f: -magma.Degree(f))
    K = F
    for f in fs:
        if not magma.HasRoot(f, K):
            for tup in magma.Factorization(f, K):
                K = magma.ExtendRelativeSplittingField(K, F, tup[1])
                if overQQ:
                    g = magma.DefiningPolynomial(K)
                    g = R(str(gp.polredabs(R(magma.Eltseq(g)))))
                    K = magma.NumberField(g)
                else:
                    K = magma.ClearFieldDenominator(K)
                if bound_set and magma.Degree(K) >= bound:
                    K = magma.DefineOrExtendInfinitePlaceFunction(K)
                    return K
    K = magma.DefineOrExtendInfinitePlaceFunction(K)
    return K
Beispiel #21
0
 def get_local_algebra(self, p):
     local_algebra_dict = self._data.get('loc_algebras', None)
     if local_algebra_dict is None:
         return None
     if str(p) in local_algebra_dict:
         R = PolynomialRing(QQ, 'x')
         palg = local_algebra_dict[str(p)]
         palgs = [R(str(s)) for s in palg.split(',')]
         palgs = [
             list2string([int(c) for c in pol.coefficients(sparse=False)])
             for pol in palgs
         ]
         palgs = [lfdb().find_one({'p': p, 'coeffs': c}) for c in palgs]
         return [[
             f['label'],
             latex(R(string2list(f['coeffs']))),
             int(f['e']),
             int(f['f']),
             int(f['c']),
             group_display_knowl(f['gal'][0], f['gal'][1], db()), f['t'],
             f['u'], f['slopes']
         ] for f in palgs]
     return None
Beispiel #22
0
    def __init__(self, f, name='y'):

        R = f.parent()
        assert R.variable_name() != name, "variable names must be distinct"
        k = R.base_ring()
        assert k.characteristic() != 3,\
             "the characteristic of the base field must not be 3"
        assert f.gcd(f.derivative()).is_one(), "f must be separable"
        self._n = 3
        self._f = f
        self._ff = f.factor()
        self._name = name
        FX = FunctionField(k, R.variable_name())
        S = PolynomialRing(FX, 'T')
        T = S.gen()
        FY = FX.extension(T**3 - FX(f), name)
        self._function_field = FY
        self._constant_base_field = k
        self._extra_extension_degree = ZZ(1)
        self._covering_degree = 3
        self._coordinate_functions = self.coordinate_functions()
        self._field_of_constants_degree = ZZ(1)
        self._is_separable = True
Beispiel #23
0
def solve(M, n, a, m):
    # I need to import it in the function otherwise multiprocessing doesn't find it in its context
    from sage_functions import coppersmith_howgrave_univariate

    base = int(65537)
    # the known part of p: 65537^a * M^-1 (mod N)
    known = int(pow(base, a, M) * inverse_mod(M, n))
    # Create the polynom f(x)
    F = PolynomialRing(Zmod(n), implementation="NTL", names=("x",))
    (x,) = F._first_ngens(1)
    pol = x + known
    beta = 0.1
    t = m + 1
    # Upper bound for the small root x0
    XX = floor(2 * n ** 0.5 / M)
    # Find a small root (x0 = k) using Coppersmith's algorithm
    roots = coppersmith_howgrave_univariate(pol, n, beta, m, t, XX)
    # There will be no roots for an incorrect guess of a.
    for k in roots:
        # reconstruct p from the recovered k
        p = int(k * M + pow(base, a, M))
        if n % p == 0:
            return p, n // p
Beispiel #24
0
    def __init__(self, f, n, name='y'):

        R = f.parent()
        assert R.variable_name() != name, "variable names must be distinct"
        k = R.base_ring()
        assert k.characteristic() == 0 or ZZ(n).gcd(k.characteristic()) == 1, "the characteristic of the base field must be prime to n"
        ff = f.factor()
        assert gcd([m for g, m in ff]+[n]) == 1, "the equation y^n=f(x) must be absolutely irreducible"
        self._n = n
        self._f = f
        self._ff = ff
        self._name = name
        FX = FunctionField(k, R.variable_name())
        S = PolynomialRing(FX, 'T')
        T = S.gen()
        FY = FX.extension(T**n - FX(f), name)
        self._function_field = FY
        self._constant_base_field = k
        self._extra_extension_degree = ZZ(1)
        self._covering_degree = n
        self._coordinate_functions = self.coordinate_functions()
        self._field_of_constants_degree = ZZ(1)
        self._is_separable = True
Beispiel #25
0
def taylor_processor_naive(new_ring, Phi, scalar, alpha, I, omega):
    k = alpha.nrows() - 1
    tau = SR.var('tau')
    y = [SR('y%d' % i) for i in range(k + 1)]

    R = PolynomialRing(QQ, len(y), y)
    beta = [a * Phi for a in alpha]

    def f(i):
        if i == 0:
            return QQ(scalar) * y[0] * exp(tau * omega[0])
        elif i in I:
            return 1 / (1 - exp(tau * omega[i]))
        else:
            return 1 / (1 - y[i] * exp(tau * omega[i]))

    h = prod(f(i) for i in range(k + 1))

    # Get constant term of h as a Laurent series in tau.
    g = h.series(tau, 1).truncate().collect(tau).coefficient(tau, 0)
    g = g.factor() if g else g
    yield CyclotomicRationalFunction.from_split_expression(
        g, y, R).monomial_substitution(new_ring, beta)
Beispiel #26
0
 def check_roots_are_roots(self, rec, verbose=False):
     """
     check that  embedding_root_real, and embedding_root_image  approximate a root of field_poly
     """
     poly = PolynomialRing(ZZ, "x")(rec['field_poly'])
     dpoly = poly.derivative()
     dbroots = db.mf_hecke_cc.search({'hecke_orbit_code': rec['hecke_orbit_code']}, ["embedding_root_real", "embedding_root_imag"])
     dbroots = [CCC(root["embedding_root_real"], root["embedding_root_imag"]) for root in dbroots]
     if len(dbroots) != poly.degree():
         if verbose:
             print("Wrong number of roots")
         return False
     for r in dbroots:
         # f is irreducible, so all roots are simple and checking relative error is the way to go
         if poly(r)/dpoly(r) > 1e-11:
             # It's still possible that the roots are correct; it could just be a problem of numerical instability
             print(r, poly(r)/dpoly(r))
             break
     else:
         return True
     roots = poly.roots(CCC, multiplicities=False)
     # greedily match.  The degrees are all at most 20, so it's okay to use a quadratic algorithm
     while len(roots) > 0:
         best_dist = infinity
         r = roots[0]
         for i, s in enumerate(dbroots):
             dist = abs(r-s)
             if dist < best_dist:
                 best_dist, best_i = dist, i
         # The dim 1 case where poly=x is handled correctly in the earlier loop, so r != 0.
         if best_dist/abs(r) > 1e-13:
             if verbose:
                 print("Roots mismatch", sorted(roots), sorted(dbroots))
             return False
         roots.pop(0)
         dbroots.pop(best_i)
     return True
Beispiel #27
0
def test_skipper_prec(skipper=Skipper4, kyber=Kyber, l=None):
    """Test precision prediction by construction worst case instance (?)

    :param skipper: Skipper instance
    :param kyber: Kyber instance for parameters such as `n` and `q`
    :param l: bits of precision to use

    TESTS::

        sage: test_skipper_prec(Skipper4, Kyber)
        sage: l = ceil(Skipper4.prec(Kyber)) - 1
        sage: test_skipper_prec(Skipper4, Kyber, l=l)
        Traceback (most recent call last):
        ...
        AssertionError

        sage: test_skipper_prec(Skipper2Negated, Kyber)
        sage: l = ceil(Skipper2Negated.prec(Kyber)) - 1
        sage: test_skipper_prec(Skipper2Negated, Kyber, l=l)
        Traceback (most recent call last):
        ...
        AssertionError

    """
    n, q, k, eta = kyber.n, kyber.q, kyber.k, kyber.eta
    R, x = PolynomialRing(ZZ, "x").objgen()
    f = R(kyber.f)

    # attempt to construct a worst-case instance
    a = vector(R, k, [R([q // 2 for _ in range(n)]) for _ in range(k)])
    b = vector(R, k, [R([eta for _ in range(n)]) for _ in range(k)])
    c = R([eta for _ in range(n)])

    d0 = (a * b + c) % f
    d1 = skipper.muladd(kyber, a, b, c, l=l)
    assert (d0 == d1)
Beispiel #28
0
def p2sage(s):
    """Convert s to something sensible in Sage.  Can handle objects
    (including strings) representing integers, reals, complexes (in
    terms of 'i' or 'I'), polynomials in 'a' with integer
    coefficients, or lists of the above.
    """
    z = s
    if type(z) in [list, tuple]:
        return [p2sage(t) for t in z]
    else:
        Qa = PolynomialRing(RationalField(),"a")
        for f in [ZZ, RR, CC, Qa]:
            try:
                return f(z)
            # SyntaxError is raised by CC('??')
            # NameError is raised by CC('a')
            except (ValueError, TypeError, NameError, SyntaxError):
                try:
                    return f(str(z))
                except (ValueError, TypeError, NameError, SyntaxError):
                    pass
        if z!='??':
            logger.error('Error converting "{}" in p2sage'.format(z))
        return z
Beispiel #29
0
def nf_data(**args):
    label = args['nf']
    nf = WebNumberField(label)
    data = '/* Data is in the following format\n'
    data += '   Note, if the class group has not been computed, it, the class number, the fundamental units, regulator and whether grh was assumed are all 0.\n'
    data += '[polynomial,\ndegree,\nt-number of Galois group,\nsignature [r,s],\ndiscriminant,\nlist of ramifying primes,\nintegral basis as polynomials in a,\n1 if it is a cm field otherwise 0,\nclass number,\nclass group structure,\n1 if grh was assumed and 0 if not,\nfundamental units,\nregulator,\nlist of subfields each as a pair [polynomial, number of subfields isomorphic to one defined by this polynomial]\n]'
    data += '\n*/\n\n'
    zk = nf.zk()
    Ra = PolynomialRing(QQ, 'a')
    zk = [str(Ra(x)) for x in zk]
    zk = ', '.join(zk)
    units = str(unlatex(nf.units()))
    units = units.replace('&nbsp;', ' ')
    subs = nf.subfields()
    subs = [[coeff_to_poly(string2list(z[0])), z[1]] for z in subs]

    # Now add actual data
    data += '[%s, ' % nf.poly()
    data += '%s, ' % nf.degree()
    data += '%s, ' % nf.galois_t()
    data += '%s, ' % nf.signature()
    data += '%s, ' % nf.disc()
    data += '%s, ' % nf.ramified_primes()
    data += '[%s], ' % zk
    data += '%s, ' % str(1 if nf.is_cm_field() else 0)
    if nf.can_class_number():
        data += '%s, ' % nf.class_number()
        data += '%s, ' % nf.class_group_invariants_raw()
        data += '%s, ' % (1 if nf.used_grh() else 0)
        data += '[%s], ' % units
        data += '%s, ' % nf.regulator()
    else:
        data += '0,0,0,0,0, '
    data += '%s' % subs
    data += ']'
    return data
Beispiel #30
0
def tensor_charpoly(f, g):
    r"""
    INPUT:

    - ``f`` -- the characteristic polynomial of a linear transformation

    - ``g`` -- the characteristic polynomial of a linear transformation

    OUTPUT: the characteristic polynomial of the tensor product of the linear transformations

    EXAMPLES::

    sage: x = PolynomialRing(ZZ,"x").gen();
    sage: tensor_charpoly((x - 3) * (x + 2),  (x - 7) * (x + 5))
    (x - 21) * (x - 10) * (x + 14) * (x + 15)

    """

    R = PolynomialRing(g.parent(), "y")
    y = R.gen()
    #x = g.parent().gen()
    A = f(y)
    B = R(g.homogenize(y))
    return B.resultant(A)