Ejemplo n.º 1
0
    def _evalf_(self, x, parent):
        """
        EXAMPLES::

            sage: erf(2).n()
            0.995322265018953
            sage: erf(2).n(200)
            0.99532226501895273416206925636725292861089179704006007673835
            sage: erf(pi - 1/2*I).n(100)
            1.0000111669099367825726058952 + 1.6332655417638522934072124548e-6*I

        TESTS:

        Check that PARI/GP through the GP interface gives the same answer::

            sage: gp.set_real_precision(59)  # random
            38
            sage: print gp.eval("1 - erfc(1)"); print erf(1).n(200);
            0.84270079294971486934122063508260925929606699796630290845994
            0.84270079294971486934122063508260925929606699796630290845994
        """
        try:
            prec = parent.prec()
        except AttributeError: # not a Sage parent
            prec = 0
        return parent(1) - parent(pari(x).erfc(prec))
Ejemplo n.º 2
0
    def __init__(self, field, num_integer_primes=10000, max_iterations=100):
        r"""
        Construct a new iterator of small degree one primes.

        EXAMPLES::

            sage: x = QQ['x'].gen()
            sage: K.<a> = NumberField(x^2 - 3)
            sage: K.primes_of_degree_one_list(3) # random
            [Fractional ideal (2*a + 1), Fractional ideal (-a + 4), Fractional ideal (3*a + 2)]
        """
        self._field = field
        self._poly = self._field.absolute_field('b').defining_polynomial()
        self._poly = ZZ['x'](self._poly.denominator() *
                             self._poly())  # make integer polynomial

        # this uses that [ O_K : Z[a] ]^2 = | disc(f(x)) / disc(O_K) |
        self._prod_of_small_primes = ZZ(
            pari(
                'TEMPn = %s; TEMPps = primes(TEMPn); prod(X = 1, TEMPn, TEMPps[X])'
                % num_integer_primes))
        self._prod_of_small_primes //= self._prod_of_small_primes.gcd(
            self._poly.discriminant())

        self._integer_iter = iter(ZZ)
        self._queue = []
        self._max_iterations = max_iterations
Ejemplo n.º 3
0
 def _shortest_vectors(self, max_count=None, max_length=0):
     """
     Compute shortest vectors and their number and length (potentially).
     
     INPUT:
     
     - ``max_count`` -- maximum number of vectors to store in the result
       (default: all);
     - ``max_length`` -- maximal length of vectors to consider
       (default: 0, i.e., consider shortest vectors).
       
     OUTPUT:
     
     A triple consisting of the number of corresponding (shortest) vectors,
     their length, and a list of at most ``max_count`` such vectors. 
     
     TESTS::
     
         sage: L = Lattice([[1, 0], [0, 1]])
         sage: L.shortest_vectors_count()
         4
     """
     default = max_length == 0 and max_count == 0
     if default and self.__shortest_vectors is not None:
         return self.__shortest_vectors
     qf = self.reduced_inner_product_matrix()
     if max_count is None:
         # determine the number of shortest vectors
         max_count = self._shortest_vectors(max_length=max_length, max_count=0)[0] #self.degree()
     count, length, vectors = pari(qf).qfminim(0, max_count)
     result = count, length, vectors.python().columns()
     if default:
         self.__shortest_vectors = result
     return result
Ejemplo n.º 4
0
    def _evalf_(self, x, parent):
        """
        EXAMPLES::

            sage: erf(2).n()
            0.995322265018953
            sage: erf(2).n(200)
            0.99532226501895273416206925636725292861089179704006007673835
            sage: erf(pi - 1/2*I).n(100)
            1.0000111669099367825726058952 + 1.6332655417638522934072124548e-6*I

        TESTS:

        Check that PARI/GP through the GP interface gives the same answer::

            sage: gp.set_real_precision(59)  # random
            38
            sage: print gp.eval("1 - erfc(1)"); print erf(1).n(200);
            0.84270079294971486934122063508260925929606699796630290845994
            0.84270079294971486934122063508260925929606699796630290845994
        """
        try:
            prec = parent.prec()
        except AttributeError:  # not a Sage parent
            prec = 0
        return parent(1) - parent(pari(x).erfc(prec))
Ejemplo n.º 5
0
def qfparam(G, sol):
    r"""
    Parametrizes the conic defined by the matrix ``G``.

    INPUT:

     - ``G`` -- a `3 \times 3`-matrix over `\QQ`.

     - ``sol`` -- a triple of rational numbers providing a solution
       to sol*G*sol^t = 0.

    OUTPUT:

    A triple of polynomials that parametrizes all solutions of
    x*G*x^t = 0 up to scaling.

    ALGORITHM:

    Uses Denis Simon's pari script Qfparam.

    EXAMPLES::

        sage: from sage.quadratic_forms.qfsolve import qfsolve, qfparam
        sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
        [  0   0 -12]
        [  0 -12   0]
        [-12   0  -1]
        sage: sol = qfsolve(M);
        sage: ret = qfparam(M, sol); ret
        (-t^2 - 12, 24*t, 24*t^2)
        sage: ret[0].parent() is QQ['t']
        True
    """
    gp = _gp_for_simon()
    R = QQ['t']
    t = R.gen()
    s = 'Qfparam(%s, (%s)~)*[t^2,t,1]~' % (G._pari_(), pari(gp(sol))._pari_())
    ret = pari(gp(s))
    return tuple([R(r) for r in ret])
Ejemplo n.º 6
0
def qfparam(G, sol):
    r"""
    Parametrizes the conic defined by the matrix ``G``.

    INPUT:

     - ``G`` -- a `3 \times 3`-matrix over `\QQ`.

     - ``sol`` -- a triple of rational numbers providing a solution
       to sol*G*sol^t = 0.

    OUTPUT:

    A triple of polynomials that parametrizes all solutions of
    x*G*x^t = 0 up to scaling.

    ALGORITHM:

    Uses Denis Simon's pari script Qfparam.

    EXAMPLES::

        sage: from sage.quadratic_forms.qfsolve import qfsolve, qfparam
        sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
        [  0   0 -12]
        [  0 -12   0]
        [-12   0  -1]
        sage: sol = qfsolve(M);
        sage: ret = qfparam(M, sol); ret
        (-t^2 - 12, 24*t, 24*t^2)
        sage: ret[0].parent() is QQ['t']
        True
    """
    gp = _gp_for_simon()
    R = QQ['t']
    t = R.gen()
    s = 'Qfparam(%s, (%s)~)*[t^2,t,1]~' % (G._pari_(), pari(gp(sol))._pari_())
    ret = pari(gp(s))
    return tuple([R(r) for r in ret])
Ejemplo n.º 7
0
    def as_hom(self):
        r"""
        Return the homomorphism L -> L corresponding to self, where L is the
        Galois closure of the ambient number field.
        
        EXAMPLE::

            sage: G = QuadraticField(-7,'w').galois_group()
            sage: G[1].as_hom()
            Ring endomorphism of Number Field in w with defining polynomial x^2 + 7
            Defn: w |--> -w
        """
        L = self.parent().splitting_field()
        a = L(self.parent()._pari_data.galoispermtopol(pari(self.list()).Vecsmall()))
        return L.hom(a, L)
Ejemplo n.º 8
0
    def as_hom(self):
        r"""
        Return the homomorphism L -> L corresponding to self, where L is the
        Galois closure of the ambient number field.
        
        EXAMPLE::

            sage: G = QuadraticField(-7,'w').galois_group()
            sage: G[1].as_hom()
            Ring endomorphism of Number Field in w with defining polynomial x^2 + 7
            Defn: w |--> -w
        """
        L = self.parent().splitting_field()
        a = L(self.parent()._pari_data.galoispermtopol(
            pari(self.list()).Vecsmall()))
        return L.hom(a, L)
Ejemplo n.º 9
0
    def resultant(self, normalize=False):
        r"""
        Computes the resultant of the defining polynomials of ``self`` if ``self`` is a map on the projective line.

        If ``normalize`` is ``True``, then first normalize the coordinate
        functions with :meth:`normalize_coordinates`.

        INPUT:

        - ``normalize`` -- Boolean (optional - default: ``False``)

        OUTPUT:

        - an element of ``self.codomain().base_ring()``

        EXAMPLES::

            sage: P.<x,y> = ProjectiveSpace(QQ,1)
            sage: H = Hom(P,P)
            sage: f = H([x^2+y^2,6*y^2])
            sage: f.resultant()
            36

        ::

            sage: R.<t> = PolynomialRing(GF(17))
            sage: P.<x,y> = ProjectiveSpace(R,1)
            sage: H = Hom(P,P)
            sage: f = H([t*x^2+t*y^2,6*y^2])
            sage: f.resultant()
            2*t^2
        """
        if self.domain().dimension_relative() > 1:
            raise TypeError("Only for dimension 1, use self.primes_of_bad_reduction() to get bad primes")
        if normalize is True:
            F=copy(self)
            F.normalize_coordinates()
        else:
            F=self
        x=self.domain().gen(0)
        y=self.domain().gen(1)
        d=self.degree()
        f=F[0].substitute({y:1})
        g=F[1].substitute({y:1})
        res=(f.lc()**(d-g.degree())*g.lc()**(d-f.degree())*pari(f).polresultant(g,x))
        return(self.codomain().base_ring()(res))
Ejemplo n.º 10
0
    def resultant(self,normalize=False):
        r"""
        Computes the resultant of the defining polynomials of ``self`` if ``self`` is a map on the projective line.
        If ``normalize==True``, then first normalize the coordinate functions with ``normalize_coordinates()``.

        INPUT:

        - ``normalize`` -- Boolean (optional - default: ``False``)

        OUTPUT:

        - an element of ``self.codomain().base_ring()``

        EXAMPLES::

            sage: P.<x,y>=ProjectiveSpace(QQ,1)
            sage: H=Hom(P,P)
            sage: f=H([x^2+y^2,6*y^2])
            sage: f.resultant()
            36

        ::

            sage: R.<t>=PolynomialRing(GF(17))
            sage: P.<x,y>=ProjectiveSpace(R,1)
            sage: H=Hom(P,P)
            sage: f=H([t*x^2+t*y^2,6*y^2])
            sage: f.resultant()
            2*t^2
        """
        if self.domain().dimension_relative() > 1:
            raise TypeError("Only for dimension 1, use self.primes_of_bad_reduction() to get bad primes")
        if normalize==True:
            F=copy(self)
            F.normalize_coordinates()
        else:
            F=self
        x=self.domain().gen(0)
        y=self.domain().gen(1)
        d=self.degree()
        f=F[0].substitute({y:1})
        g=F[1].substitute({y:1})
        res=(f.lc()**(d-g.degree())*g.lc()**(d-f.degree())*pari(f).polresultant(g,x))
        return(self.codomain().base_ring()(res))
Ejemplo n.º 11
0
def qfsolve(G, factD=None):
    r"""
    Find a solution `x = (x_0,...,x_n)` to `x G x^t = 0` for an
    `n \times n`-matrix ``G`` over `\QQ`.

    If a solution exists, returns a tuple of rational numbers `x`.
    Otherwise, returns `-1` if no solutions exists over the reals or a
    prime `p` if no solution exists over the `p`-adic field `\QQ_p`.

    EXAMPLES::

        sage: from sage.quadratic_forms.qfsolve import qfsolve
        sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
        [  0   0 -12]
        [  0 -12   0]
        [-12   0  -1]
        sage: sol = qfsolve(M); sol
        (1, 0, 0)
        sage: sol[0].parent() is QQ
        True

        sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
        sage: ret = qfsolve(M); ret
        -1
        sage: ret.parent() is ZZ
        True

        sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, -7]])
        sage: qfsolve(M)
        7

        sage: M = Matrix(QQ, [[3, 0, 0, 0], [0, 5, 0, 0], [0, 0, -7, 0], [0, 0, 0, -11]])
        sage: qfsolve(M)
        (-3, 4, 3, 2)
    """
    gp = _gp_for_simon()
    if factD is not None:
        raise NotImplementedError, "qfsolve not implemented with parameter factD"
    ret = pari(gp('Qfsolve(%s)' % G._pari_()))
    if ret.type() == 't_COL':
        return tuple([QQ(r) for r in ret])
    return ZZ(ret)
Ejemplo n.º 12
0
def qfsolve(G, factD=None):
    r"""
    Find a solution `x = (x_0,...,x_n)` to `x G x^t = 0` for an
    `n \times n`-matrix ``G`` over `\QQ`.

    If a solution exists, returns a tuple of rational numbers `x`.
    Otherwise, returns `-1` if no solutions exists over the reals or a
    prime `p` if no solution exists over the `p`-adic field `\QQ_p`.

    EXAMPLES::

        sage: from sage.quadratic_forms.qfsolve import qfsolve
        sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
        [  0   0 -12]
        [  0 -12   0]
        [-12   0  -1]
        sage: sol = qfsolve(M); sol
        (1, 0, 0)
        sage: sol[0].parent() is QQ
        True

        sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
        sage: ret = qfsolve(M); ret
        -1
        sage: ret.parent() is ZZ
        True

        sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, -7]])
        sage: qfsolve(M)
        7

        sage: M = Matrix(QQ, [[3, 0, 0, 0], [0, 5, 0, 0], [0, 0, -7, 0], [0, 0, 0, -11]])
        sage: qfsolve(M)
        (-3, 4, 3, 2)
    """
    gp = _gp_for_simon()
    if factD is not None:
        raise NotImplementedError, "qfsolve not implemented with parameter factD"
    ret = pari(gp('Qfsolve(%s)' % G._pari_()))
    if ret.type() == 't_COL':
        return tuple([QQ(r) for r in ret])
    return ZZ(ret)
Ejemplo n.º 13
0
    def __init__(self, field, num_integer_primes=10000, max_iterations=100):
        r"""
        Construct a new iterator of small degree one primes.

        EXAMPLES::

            sage: x = QQ['x'].gen()
            sage: K.<a> = NumberField(x^2 - 3)
            sage: K.primes_of_degree_one_list(3) # random
            [Fractional ideal (2*a + 1), Fractional ideal (-a + 4), Fractional ideal (3*a + 2)]
        """
        self._field = field
        self._poly = self._field.absolute_field('b').defining_polynomial()
        self._poly = ZZ['x'](self._poly.denominator() * self._poly()) # make integer polynomial

        # this uses that [ O_K : Z[a] ]^2 = | disc(f(x)) / disc(O_K) |
        self._prod_of_small_primes = ZZ(pari('TEMPn = %s; TEMPps = primes(TEMPn); prod(X = 1, TEMPn, TEMPps[X])' % num_integer_primes))
        self._prod_of_small_primes //= self._prod_of_small_primes.gcd(self._poly.discriminant())

        self._integer_iter = iter(ZZ)
        self._queue = []
        self._max_iterations = max_iterations
Ejemplo n.º 14
0
    def fixed_field(self):
        r"""
        Return the fixed field of this subgroup (as a subfield of the Galois
        closure of the number field associated to the ambient Galois group).

        EXAMPLE::

            sage: L.<a> = NumberField(x^4 + 1)
            sage: G = L.galois_group()
            sage: H = G.decomposition_group(L.primes_above(3)[0])
            sage: H.fixed_field()
            (Number Field in a0 with defining polynomial x^2 + 2, Ring morphism:
            From: Number Field in a0 with defining polynomial x^2 + 2
            To:   Number Field in a with defining polynomial x^4 + 1
            Defn: a0 |--> a^3 + a)

        """
        if self.order() == 1:
            return self._galois_closure  # work around a silly error

        vecs = [pari(g.list()).Vecsmall() for g in self._elts]
        v = self._ambient._pari_data.galoisfixedfield(vecs)
        x = self._galois_closure(v[1])
        return self._galois_closure.subfield(x)
Ejemplo n.º 15
0
    def fixed_field(self):
        r"""
        Return the fixed field of this subgroup (as a subfield of the Galois
        closure of the number field associated to the ambient Galois group).

        EXAMPLE::

            sage: L.<a> = NumberField(x^4 + 1)
            sage: G = L.galois_group()
            sage: H = G.decomposition_group(L.primes_above(3)[0])
            sage: H.fixed_field()
            (Number Field in a0 with defining polynomial x^2 + 2, Ring morphism:
            From: Number Field in a0 with defining polynomial x^2 + 2
            To:   Number Field in a with defining polynomial x^4 + 1
            Defn: a0 |--> a^3 + a)

        """
        if self.order() == 1:
            return self._galois_closure # work around a silly error
            
        vecs = [pari(g.list()).Vecsmall() for g in self._elts]
        v = self._ambient._pari_data.galoisfixedfield(vecs)
        x = self._galois_closure(v[1])
        return self._galois_closure.subfield(x)
Ejemplo n.º 16
0
def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False):
    r"""
    Enumerates *all* totally real fields of degree `n` with discriminant `\le B`,
    primitive or otherwise.
    
    EXAMPLES::
    
        sage: enumerate_totallyreal_fields_all(4, 2000)
        [[725, x^4 - x^3 - 3*x^2 + x + 1], 
        [1125, x^4 - x^3 - 4*x^2 + 4*x + 1], 
        [1600, x^4 - 6*x^2 + 4], 
        [1957, x^4 - 4*x^2 - x + 1], 
        [2000, x^4 - 5*x^2 + 5]]
    
    In practice most of these will be found by :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`, which is guaranteed to return all primitive fields but often returns many non-primitive ones as well. For instance, only one of the five fields in the example above is primitive, but :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim` finds four out of the five (the exception being `x^4 - 6x^2 + 4`).
    """

    S = []
    counts = [0, 0, 0]
    if len(divisors(n)) > 4:
        raise ValueError, "Only implemented for n = p*q with p,q prime"
    for d in divisors(n):
        if d > 1 and d < n:
            Sds = enumerate_totallyreal_fields_prim(
                d, int(math.floor((1. * B)**(1. * d / n))), verbose=verbose)
            for i in range(len(Sds)):
                if verbose:
                    print "=" * 80
                    print "Taking F =", Sds[i][1]
                F = NumberField(ZZx(Sds[i][1]), 't')
                T = enumerate_totallyreal_fields_rel(F,
                                                     n / d,
                                                     B,
                                                     verbose=verbose,
                                                     return_seqs=return_seqs)
                if return_seqs:
                    for i in range(3):
                        counts[i] += T[0][i]
                    S += [[t[0], pari(t[1]).Polrev()] for t in T[1]]
                else:
                    S += [[t[0], t[1]] for t in T]
                j = i + 1
                for E in enumerate_totallyreal_fields_prim(
                        n / d,
                        int(
                            math.floor((1. * B)**(1. / d) /
                                       (1. * Sds[i][0])**(n * 1. / d**2)))):
                    for EF in F.composite_fields(NumberField(ZZx(E[1]), 'u')):
                        if EF.degree() == n and EF.disc() <= B:
                            S.append(
                                [EF.disc(),
                                 pari(EF.absolute_polynomial())])
    S += enumerate_totallyreal_fields_prim(n, B, verbose=verbose)
    S.sort()
    weed_fields(S)

    # Output.
    if verbose:
        saveout = sys.stdout
        if type(verbose) == str:
            fsock = open(verbose, 'w')
            sys.stdout = fsock
        # Else, print to screen
        print "=" * 80
        print "Polynomials tested:", counts[0]
        print "Irreducible polynomials:", counts[1]
        print "Polynomials with nfdisc <= B:", counts[2]
        for i in range(len(S)):
            print S[i]
        if type(verbose) == str:
            fsock.close()
        sys.stdout = saveout

    if return_seqs:
        return [counts, [[s[0], s[1].reverse().Vec()] for s in S]]
    else:
        return S
Ejemplo n.º 17
0
def enumerate_totallyreal_fields_rel(F,
                                     m,
                                     B,
                                     a=[],
                                     verbose=0,
                                     return_seqs=False):
    r"""
    This function enumerates (primitive) totally real field extensions of
    degree `m>1` of the totally real field F with discriminant `d \leq B`; 
    optionally one can specify the first few coefficients, where the sequence ``a``
    corresponds to a polynomial by
    
    ::
    
        a[d]*x^n + ... + a[0]*x^(n-d)
        
    if ``length(a) = d+1``, so in particular always ``a[d] = 1``.
    If verbose == 1 (or 2), then print to the screen (really) verbosely; if
    verbose is a string, then print verbosely to the file specified by verbose.
    If return_seqs, then return the polynomials as sequences (for easier
    exporting to a file).

    NOTE:
    This is guaranteed to give all primitive such fields, and 
    seems in practice to give many imprimitive ones.

    INPUT:
    
    - ``F`` -- number field, the base field
    - ``m`` -- integer, the degree
    - ``B`` -- integer, the discriminant bound
    - ``a`` -- list (default: []), the coefficient list to begin with
    - ``verbose`` -- boolean or string (default: 0)
    - ``return_seqs`` -- boolean (default: False)

    OUTPUT:
    
    the list of fields with entries [d,fabs,f], where
    d is the discriminant, fabs is an absolute defining polynomial,
    and f is a defining polynomial relative to F,
    sorted by discriminant.

    EXAMPLES::
    
        sage: ZZx = ZZ['x']
        sage: F.<t> = NumberField(x^2-2)
        sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
        [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]

    AUTHORS:
    
    - John Voight (2007-11-01)
    """

    if not isinstance(m, Integer):
        try:
            m = Integer(m)
        except:
            raise TypeError, "cannot coerce m (= %s) to an integer" % m
    if (m < 1):
        raise ValueError, "m must be at least 1."

    n = F.degree() * m

    # Initialize
    T = tr_data_rel(F, m, B, a)
    S = []
    Srel = []
    dB_odlyzko = odlyzko_bound_totallyreal(n)
    dB = math.ceil(40000 * dB_odlyzko**n)
    counts = [0, 0, 0, 0]

    # Trivial case
    if m == 1:
        g = pari(F.defining_polynomial()).reverse().Vec()
        if return_seqs:
            return [[0, 0, 0, 0], [1, g, [-1, 1]]]
        else:
            return [[1, pari('x-1'), g]]

    if verbose:
        saveout = sys.stdout
        if type(verbose) == str:
            fsock = open(verbose, 'w')
            sys.stdout = fsock
        # Else, print to screen
    f_out = [0] * m + [1]
    if verbose == 2:
        T.incr(f_out, verbose)
    else:
        T.incr(f_out)

    Fx = PolynomialRing(F, 'xF')

    nfF = pari(
        str(F.defining_polynomial()).replace('x', str(F.primitive_element())))
    parit = pari(str(F.primitive_element()))

    while f_out[m] <> 0:
        counts[0] += 1
        if verbose:
            print "==>", f_out,

        f_str = ''
        for i in range(len(f_out)):
            f_str += '(' + str(f_out[i]) + ')*x^' + str(i)
            if i < len(f_out) - 1:
                f_str += '+'
        nf = pari(f_str)
        if nf.poldegree('t') == 0:
            nf = nf.subst('x', 'x-t')
        nf = nf.polresultant(nfF, parit)
        d = nf.poldisc()
        counts[0] += 1
        if d > 0 and nf.polsturm_full() == n:
            da = int_has_small_square_divisor(Integer(d))
            if d > dB or d <= B * da:
                counts[1] += 1
                if nf.polisirreducible():
                    counts[2] += 1
                    [zk, d] = nf.nfbasis_d()

                    if d <= B:
                        if verbose:
                            print "has discriminant", d,

                        # Find a minimal lattice element
                        counts[3] += 1
                        ng = pari([nf, zk]).polredabs()

                        # Check if K is contained in the list.
                        found = False
                        ind = bisect.bisect_left(S, [d, ng])
                        while ind < len(S) and S[ind][0] == d:
                            if S[ind][1] == ng:
                                if verbose:
                                    print "but is not new"
                                found = True
                                break
                            ind += 1
                        if not found:
                            if verbose:
                                print "and is new!"
                            S.insert(ind, [d, ng])
                            Srel.insert(ind, Fx(f_out))
                    else:
                        if verbose:
                            print "has discriminant", abs(d), "> B"
                else:
                    if verbose:
                        print "is not absolutely irreducible"
            else:
                if verbose:
                    print "has discriminant", abs(
                        d), "with no large enough square divisor"
        else:
            if verbose:
                if d == 0:
                    print "is not squarefree"
                else:
                    print "is not totally real"
        if verbose == 2:
            T.incr(f_out, verbose=verbose)
        else:
            T.incr(f_out)

    # In the application of Smyth's theorem above, we exclude finitely
    # many possibilities which we must now throw back in.
    if m == 2:
        if Fx([-1, 1, 1]).is_irreducible():
            K = F.extension(Fx([-1, 1, 1]), 'tK')
            Kabs = K.absolute_field('tKabs')
            Kabs_pari = pari(Kabs.defining_polynomial())
            d = K.absolute_discriminant()
            if abs(d) <= B:
                ng = Kabs_pari.polredabs()
                ind = bisect.bisect_left(S, [d, ng])
                S.insert(ind, [d, ng])
                Srel.insert(ind, Fx([-1, 1, 1]))
        elif F.degree() == 2:
            for ff in [[1, -7, 13, -7, 1], [1, -8, 14, -7, 1]]:
                f = Fx(ff).factor()[0][0]
                K = F.extension(f, 'tK')
                Kabs = K.absolute_field('tKabs')
                Kabs_pari = pari(Kabs.defining_polynomial())
                d = K.absolute_discriminant()
                if abs(d) <= B:
                    ng = Kabs_pari.polredabs()
                    ind = bisect.bisect_left(S, [d, ng])
                    S.insert(ind, [d, ng])
                    Srel.insert(ind, f)
    elif m == 3:
        if Fx([-1, 6, -5, 1]).is_irreducible():
            K = F.extension(Fx([-1, 6, -5, 1]), 'tK')
            Kabs = K.absolute_field('tKabs')
            Kabs_pari = pari(Kabs.defining_polynomial())
            d = K.absolute_discriminant()
            if abs(d) <= B:
                ng = Kabs_pari.polredabs()
                ind = bisect.bisect_left(S, [d, ng])
                S.insert(ind, [d, ng])
                Srel.insert(ind, Fx([-1, 6, -5, 1]))

    # Now check for isomorphic fields
    S = [[S[i][0], S[i][1], Srel[i]] for i in range(len(S))]
    weed_fields(S)

    # Output.
    if verbose:
        print "=" * 80
        print "Polynomials tested:", counts[0]
        print "Irreducible polynomials:", counts[1]
        print "Polynomials with nfdisc <= B:", counts[2]
        for i in range(len(S)):
            print S[i]
        if type(verbose) == str:
            fsock.close()
        sys.stdout = saveout

    if return_seqs:
        return [
            counts, [[s[0], s[1].reverse().Vec(), s[2].coeffs()] for s in S]
        ]
    else:
        return S
Ejemplo n.º 18
0
    def __init__(self, F, m, B, a=None):
        r"""
        Initialization routine (constructor).

        INPUT:
        
        - ``F`` -- number field, the base field
        - ``m`` -- integer, the relative degree
        - ``B`` -- integer, the discriminant bound
        - ``a`` -- list (default: []), the coefficient list to begin with,
          corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))``.

        OUTPUT:
        
        the data initialized to begin enumeration of totally real fields
        with base field F, degree n, discriminant bounded by B, and starting 
        with coefficients a.

        EXAMPLES::
        
            sage: F.<t> = NumberField(x^2-2)
            sage: T = sage.rings.number_field.totallyreal_rel.tr_data_rel(F, 2, 2000)
        """
        if a is None:  # don't make the stupid noob mistake of putting a=[]
            a = []  # in the function signature above.

        # Initialize constants.
        self.m = m
        d = F.degree()
        self.d = d
        self.n = m * d
        self.B = B
        self.gamma = hermite_constant(self.n - self.d)

        self.F = F
        self.Z_F = F.maximal_order()
        self.Foo = F.real_embeddings()
        self.dF = abs(F.disc())
        self.Fx = PolynomialRing(F, 'xF')

        self.beta = [[]] * m
        self.gnk = [[]] * m

        self.trace_elts = []

        Z_Fbasis = self.Z_F.basis()

        # Initialize variables.
        if a == []:
            # No starting input, all polynomials will be found; initialize to zero.
            self.a = [0] * m + [1]
            self.amaxvals = [[]] * m
            anm1s = [[i] for i in range(0, m // 2 + 1)]
            for i in range(1, self.d):
                for j in range(len(anm1s)):
                    anm1s[j] = [anm1s[j] + [i] for i in range(m)]
                anm1s = sum(anm1s, [])
            anm1s = [
                sum([Z_Fbasis[i] * a[i] for i in range(self.d)]) for a in anm1s
            ]
            # Minimize trace in class.
            import numpy
            for i in range(len(anm1s)):
                Q = [[v(m * x) for v in self.Foo] + [0]
                     for x in Z_Fbasis] + [[v(anm1s[i])
                                            for v in self.Foo] + [10**6]]
                pari_string = '[' + ';'.join(
                    [','.join(["%s" % ii for ii in row])
                     for row in zip(*Q)]) + ']'
                adj = pari(pari_string).qflll()[self.d]
                anm1s[i] += sum([
                    m * Z_Fbasis[ii] * int(adj[ii]) // int(adj[self.d])
                    for ii in range(self.d)
                ])

            self.amaxvals[m - 1] = anm1s
            self.a[m - 1] = self.amaxvals[m - 1].pop()
            self.k = m - 2

            bl = math.ceil(1.7719 * self.n)
            br = max([1./m*(am1**2).trace() + \
                            self.gamma*(1./(m**d)*self.B/self.dF)**(1./(self.n-d)) for am1 in anm1s])
            br = math.floor(br)
            T2s = self.F._positive_integral_elements_with_trace([bl, br])
            self.trace_elts.append([bl, br, T2s])

        elif len(a) <= m + 1:
            # First few coefficients have been specified.
            # The value of k is the largest index of the coefficients of a which is
            # currently unknown; e.g., if k == -1, then we can iterate
            # over polynomials, and if k == n-1, then we have finished iterating.
            if a[len(a) - 1] <> 1:
                raise ValueError, "a[len(a)-1](=%s) must be 1 so polynomial is monic" % a[
                    len(a) - 1]

            raise NotImplementedError, "These have not been checked."

            k = m - len(a)
            self.k = k
            a = [0] * (k + 1) + a
            self.amaxvals = [[]] * m
            for i in range(0, n + 1):
                self.a[i] = a[i]

            # Bounds come from an application of Lagrange multipliers in degrees 2,3.
            self.b_lower = [
                -1. / m * (v(self.a[m - 1]) + (m - 1.) * math.sqrt(
                    v(self.a[m - 1])**2 - 2. *
                    (1 + 1. / (m - 1)) * v(self.a[m - 2]))) for v in self.Foo
            ]
            self.b_upper = [
                -1. / m * (v(self.a[m - 1]) - (m - 1.) * math.sqrt(
                    v(self.a[m - 1])**2 - 2. *
                    (1 + 1. / (m - 1)) * v(self.a[m - 2]))) for v in self.Foo
            ]
            if k < m - 2:
                bminmax = [
                    lagrange_degree_3(n, v(self.a[m - 1]), v(self.a[m - 2]),
                                      v(self.a[m - 3])) for v in self.Foo
                ]
                self.b_lower = bminmax[0]
                self.b_upper = bminmax[1]

            # Annoying, but must reverse coefficients for numpy.
            gnk = [binomial(j, k + 2) * a[j] for j in range(k + 2, n + 1)]
            self.beta[k + 1] = [[self.b_lower] + numpy.roots(
                [v(gnk[i])
                 for i in range(len(gnk))].reverse()).tolist().sort() +
                                [self.b_upper] for v in self.Foo]

            # Now to really initialize gnk.
            self.gnk[k + 1] = [
                [0] +
                [binomial(j, k + 1) * v(a[j]) for j in range(k + 2, m + 1)]
                for v in self.Foo
            ]
        else:
            # Bad input!
            raise ValueError, "a has length %s > m+1" % len(a)
Ejemplo n.º 19
0
def pari(x):
    """
    Return the pari object constructed from a Sage object.

    The work is done by the __call__ method of the class PariInstance,
    which in turn passes the work to any class which has its own
    method _pari_().

    EXAMPLES::

        sage: pari([2,3,5])
        [2, 3, 5]
        sage: pari(Matrix(2,2,range(4)))
        [0, 1; 2, 3]
        sage: pari(x^2-3)
        x^2 - 3

    ::

        sage: a = pari(1); a, a.type()
        (1, 't_INT')
        sage: a = pari(1/2); a, a.type()
        (1/2, 't_FRAC')
        sage: a = pari(1/2); a, a.type()
        (1/2, 't_FRAC')

    Conversion from reals uses the real's own precision, here 53 bits (the default)::

        sage: a = pari(1.2); a, a.type(), a.precision()
        (1.20000000000000, 't_REAL', 4) # 32-bit
        (1.20000000000000, 't_REAL', 3) # 64-bit

    Conversion from strings uses the current pari real precision.  By
    default this is 4 words, 38 digits, 128 bits on 64-bit machines
    and 5 words, 19 digits, 64 bits on 32-bit machines. ::

        sage: a = pari('1.2'); a, a.type(), a.precision()
        (1.20000000000000, 't_REAL', 5) # 32-bit
        (1.20000000000000, 't_REAL', 4) # 64-bit

    Conversion from matrices is supported, but not from vectors; use
    lists instead::

        sage: a = pari(matrix(2,3,[1,2,3,4,5,6])); a, a.type()
        ([1, 2, 3; 4, 5, 6], 't_MAT')

        sage: v = vector([1.2,3.4,5.6])
        sage: v.pari()
        Traceback (most recent call last):
        ...
        AttributeError: 'sage.modules.free_module_element.FreeModuleElement_generic_dense' object has no attribute 'pari'
        sage: b = pari(list(v)); b,b.type()
        ([1.20000000000000, 3.40000000000000, 5.60000000000000], 't_VEC')

    Some more exotic examples::

        sage: K.<a> = NumberField(x^3 - 2)
        sage: pari(K)
        [y^3 - 2, [1, 1], -108, 1, [[1, 1.25992104989487, 1.58740105196820; 1, -0.629960524947437 - 1.09112363597172*I, -0.793700525984100 + 1.37472963699860*I], [1, 1.25992104989487, 1.58740105196820; 1, -1.72108416091916, 0.581029111014503; 1, 0.461163111024285, -2.16843016298270], [1, 1, 2; 1, -2, 1; 1, 0, -2], [3, 0, 0; 0, 0, 6; 0, 6, 0], [6, 0, 0; 0, 6, 0; 0, 0, 3], [2, 0, 0; 0, 0, 1; 0, 1, 0], [2, [0, 0, 2; 1, 0, 0; 0, 1, 0]]], [1.25992104989487, -0.629960524947437 - 1.09112363597172*I], [1, y, y^2], [1, 0, 0; 0, 1, 0; 0, 0, 1], [1, 0, 0, 0, 0, 2, 0, 2, 0; 0, 1, 0, 1, 0, 0, 0, 0, 2; 0, 0, 1, 0, 1, 0, 1, 0, 0]]

        sage: E = EllipticCurve('37a1')
        sage: pari(E)
        [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, [0.837565435283323, 0.269594436405445, -1.10715987168877]~, 2.99345864623196, -2.45138938198679*I, 0.942638555913623, 1.32703057887968*I, 7.33813274078958]

    Conversion from basic Python types::

        sage: pari(int(-5))
        -5
        sage: pari(long(2**150))
        1427247692705959881058285969449495136382746624
        sage: pari(float(pi))
        3.14159265358979
        sage: pari(complex(exp(pi*I/4)))
        0.707106781186548 + 0.707106781186547*I
        sage: pari(False)
        0
        sage: pari(True)
        1

    Some commands are just executed without returning a value::

        sage: pari("dummy = 0; kill(dummy)")
        sage: type(pari("dummy = 0; kill(dummy)"))
        <type 'NoneType'>
    """
    return gen.pari(x)
Ejemplo n.º 20
0
def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False):
    r"""
    Enumerates *all* totally real fields of degree `n` with discriminant `\le B`,
    primitive or otherwise.
    
    EXAMPLES::
    
        sage: enumerate_totallyreal_fields_all(4, 2000)
        [[725, x^4 - x^3 - 3*x^2 + x + 1], 
        [1125, x^4 - x^3 - 4*x^2 + 4*x + 1], 
        [1600, x^4 - 6*x^2 + 4], 
        [1957, x^4 - 4*x^2 - x + 1], 
        [2000, x^4 - 5*x^2 + 5]]
    
    In practice most of these will be found by :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`, which is guaranteed to return all primitive fields but often returns many non-primitive ones as well. For instance, only one of the five fields in the example above is primitive, but :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim` finds four out of the five (the exception being `x^4 - 6x^2 + 4`).
    """

    S = []
    counts = [0, 0, 0]
    if len(divisors(n)) > 4:
        raise ValueError, "Only implemented for n = p*q with p,q prime"
    for d in divisors(n):
        if d > 1 and d < n:
            Sds = enumerate_totallyreal_fields_prim(d, int(math.floor((1.0 * B) ** (1.0 * d / n))), verbose=verbose)
            for i in range(len(Sds)):
                if verbose:
                    print "=" * 80
                    print "Taking F =", Sds[i][1]
                F = NumberField(ZZx(Sds[i][1]), "t")
                T = enumerate_totallyreal_fields_rel(F, n / d, B, verbose=verbose, return_seqs=return_seqs)
                if return_seqs:
                    for i in range(3):
                        counts[i] += T[0][i]
                    S += [[t[0], pari(t[1]).Polrev()] for t in T[1]]
                else:
                    S += [[t[0], t[1]] for t in T]
                j = i + 1
                for E in enumerate_totallyreal_fields_prim(
                    n / d, int(math.floor((1.0 * B) ** (1.0 / d) / (1.0 * Sds[i][0]) ** (n * 1.0 / d ** 2)))
                ):
                    for EF in F.composite_fields(NumberField(ZZx(E[1]), "u")):
                        if EF.degree() == n and EF.disc() <= B:
                            S.append([EF.disc(), pari(EF.absolute_polynomial())])
    S += enumerate_totallyreal_fields_prim(n, B, verbose=verbose)
    S.sort()
    weed_fields(S)

    # Output.
    if verbose:
        saveout = sys.stdout
        if type(verbose) == str:
            fsock = open(verbose, "w")
            sys.stdout = fsock
        # Else, print to screen
        print "=" * 80
        print "Polynomials tested:", counts[0]
        print "Irreducible polynomials:", counts[1]
        print "Polynomials with nfdisc <= B:", counts[2]
        for i in range(len(S)):
            print S[i]
        if type(verbose) == str:
            fsock.close()
        sys.stdout = saveout

    if return_seqs:
        return [counts, [[s[0], s[1].reverse().Vec()] for s in S]]
    else:
        return S
Ejemplo n.º 21
0
def enumerate_totallyreal_fields_rel(F, m, B, a=[], verbose=0, return_seqs=False):
    r"""
    This function enumerates (primitive) totally real field extensions of
    degree `m>1` of the totally real field F with discriminant `d \leq B`; 
    optionally one can specify the first few coefficients, where the sequence ``a``
    corresponds to a polynomial by
    
    ::
    
        a[d]*x^n + ... + a[0]*x^(n-d)
        
    if ``length(a) = d+1``, so in particular always ``a[d] = 1``.
    If verbose == 1 (or 2), then print to the screen (really) verbosely; if
    verbose is a string, then print verbosely to the file specified by verbose.
    If return_seqs, then return the polynomials as sequences (for easier
    exporting to a file).

    NOTE:
    This is guaranteed to give all primitive such fields, and 
    seems in practice to give many imprimitive ones.

    INPUT:
    
    - ``F`` -- number field, the base field
    - ``m`` -- integer, the degree
    - ``B`` -- integer, the discriminant bound
    - ``a`` -- list (default: []), the coefficient list to begin with
    - ``verbose`` -- boolean or string (default: 0)
    - ``return_seqs`` -- boolean (default: False)

    OUTPUT:
    
    the list of fields with entries [d,fabs,f], where
    d is the discriminant, fabs is an absolute defining polynomial,
    and f is a defining polynomial relative to F,
    sorted by discriminant.

    EXAMPLES::
    
        sage: ZZx = ZZ['x']
        sage: F.<t> = NumberField(x^2-2)
        sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
        [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]

    AUTHORS:
    
    - John Voight (2007-11-01)
    """

    if not isinstance(m, Integer):
        try:
            m = Integer(m)
        except TypeError:
            raise TypeError, "cannot coerce m (= %s) to an integer" % m
    if m < 1:
        raise ValueError, "m must be at least 1."

    n = F.degree() * m

    # Initialize
    T = tr_data_rel(F, m, B, a)
    S = []
    Srel = []
    dB_odlyzko = odlyzko_bound_totallyreal(n)
    dB = math.ceil(40000 * dB_odlyzko ** n)
    counts = [0, 0, 0, 0]

    # Trivial case
    if m == 1:
        g = pari(F.defining_polynomial()).reverse().Vec()
        if return_seqs:
            return [[0, 0, 0, 0], [1, g, [-1, 1]]]
        else:
            return [[1, pari("x-1"), g]]

    if verbose:
        saveout = sys.stdout
        if type(verbose) == str:
            fsock = open(verbose, "w")
            sys.stdout = fsock
        # Else, print to screen
    f_out = [0] * m + [1]
    if verbose == 2:
        T.incr(f_out, verbose)
    else:
        T.incr(f_out)

    Fx = PolynomialRing(F, "xF")

    nfF = pari(str(F.defining_polynomial()).replace("x", str(F.primitive_element())))
    parit = pari(str(F.primitive_element()))

    while f_out[m] <> 0:
        counts[0] += 1
        if verbose:
            print "==>", f_out,

        f_str = ""
        for i in range(len(f_out)):
            f_str += "(" + str(f_out[i]) + ")*x^" + str(i)
            if i < len(f_out) - 1:
                f_str += "+"
        nf = pari(f_str)
        if nf.poldegree("t") == 0:
            nf = nf.subst("x", "x-t")
        nf = nf.polresultant(nfF, parit)
        d = nf.poldisc()
        counts[0] += 1
        if d > 0 and nf.polsturm_full() == n:
            da = int_has_small_square_divisor(Integer(d))
            if d > dB or d <= B * da:
                counts[1] += 1
                if nf.polisirreducible():
                    counts[2] += 1
                    [zk, d] = nf.nfbasis_d()

                    if d <= B:
                        if verbose:
                            print "has discriminant", d,

                        # Find a minimal lattice element
                        counts[3] += 1
                        ng = pari([nf, zk]).polredabs()

                        # Check if K is contained in the list.
                        found = False
                        ind = bisect.bisect_left(S, [d, ng])
                        while ind < len(S) and S[ind][0] == d:
                            if S[ind][1] == ng:
                                if verbose:
                                    print "but is not new"
                                found = True
                                break
                            ind += 1
                        if not found:
                            if verbose:
                                print "and is new!"
                            S.insert(ind, [d, ng])
                            Srel.insert(ind, Fx(f_out))
                    else:
                        if verbose:
                            print "has discriminant", abs(d), "> B"
                else:
                    if verbose:
                        print "is not absolutely irreducible"
            else:
                if verbose:
                    print "has discriminant", abs(d), "with no large enough square divisor"
        else:
            if verbose:
                if d == 0:
                    print "is not squarefree"
                else:
                    print "is not totally real"
        if verbose == 2:
            T.incr(f_out, verbose=verbose)
        else:
            T.incr(f_out)

    # In the application of Smyth's theorem above, we exclude finitely
    # many possibilities which we must now throw back in.
    if m == 2:
        if Fx([-1, 1, 1]).is_irreducible():
            K = F.extension(Fx([-1, 1, 1]), "tK")
            Kabs = K.absolute_field("tKabs")
            Kabs_pari = pari(Kabs.defining_polynomial())
            d = K.absolute_discriminant()
            if abs(d) <= B:
                ng = Kabs_pari.polredabs()
                ind = bisect.bisect_left(S, [d, ng])
                S.insert(ind, [d, ng])
                Srel.insert(ind, Fx([-1, 1, 1]))
        elif F.degree() == 2:
            for ff in [[1, -7, 13, -7, 1], [1, -8, 14, -7, 1]]:
                f = Fx(ff).factor()[0][0]
                K = F.extension(f, "tK")
                Kabs = K.absolute_field("tKabs")
                Kabs_pari = pari(Kabs.defining_polynomial())
                d = K.absolute_discriminant()
                if abs(d) <= B:
                    ng = Kabs_pari.polredabs()
                    ind = bisect.bisect_left(S, [d, ng])
                    S.insert(ind, [d, ng])
                    Srel.insert(ind, f)
    elif m == 3:
        if Fx([-1, 6, -5, 1]).is_irreducible():
            K = F.extension(Fx([-1, 6, -5, 1]), "tK")
            Kabs = K.absolute_field("tKabs")
            Kabs_pari = pari(Kabs.defining_polynomial())
            d = K.absolute_discriminant()
            if abs(d) <= B:
                ng = Kabs_pari.polredabs()
                ind = bisect.bisect_left(S, [d, ng])
                S.insert(ind, [d, ng])
                Srel.insert(ind, Fx([-1, 6, -5, 1]))

    # Now check for isomorphic fields
    S = [[S[i][0], S[i][1], Srel[i]] for i in range(len(S))]
    weed_fields(S)

    # Output.
    if verbose:
        print "=" * 80
        print "Polynomials tested:", counts[0]
        print "Irreducible polynomials:", counts[1]
        print "Polynomials with nfdisc <= B:", counts[2]
        for i in range(len(S)):
            print S[i]
        if type(verbose) == str:
            fsock.close()
        sys.stdout = saveout

    if return_seqs:
        return [counts, [[s[0], s[1].reverse().Vec(), s[2].coeffs()] for s in S]]
    else:
        return S
Ejemplo n.º 22
0
    def __init__(self, F, m, B, a=None):
        r"""
        Initialization routine (constructor).

        INPUT:
        
        - ``F`` -- number field, the base field
        - ``m`` -- integer, the relative degree
        - ``B`` -- integer, the discriminant bound
        - ``a`` -- list (default: []), the coefficient list to begin with,
          corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))``.

        OUTPUT:
        
        the data initialized to begin enumeration of totally real fields
        with base field F, degree n, discriminant bounded by B, and starting 
        with coefficients a.

        EXAMPLES::
        
            sage: F.<t> = NumberField(x^2-2)
            sage: T = sage.rings.number_field.totallyreal_rel.tr_data_rel(F, 2, 2000)
        """
        if a is None:  # don't make the stupid noob mistake of putting a=[]
            a = []  # in the function signature above.

        # Initialize constants.
        self.m = m
        d = F.degree()
        self.d = d
        self.n = m * d
        self.B = B
        self.gamma = hermite_constant(self.n - self.d)

        self.F = F
        self.Z_F = F.maximal_order()
        self.Foo = F.real_embeddings()
        self.dF = abs(F.disc())
        self.Fx = PolynomialRing(F, "xF")

        self.beta = [[]] * m
        self.gnk = [[]] * m

        self.trace_elts = []

        Z_Fbasis = self.Z_F.basis()

        # Initialize variables.
        if a == []:
            # No starting input, all polynomials will be found; initialize to zero.
            self.a = [0] * m + [1]
            self.amaxvals = [[]] * m
            anm1s = [[i] for i in range(0, m // 2 + 1)]
            for i in range(1, self.d):
                for j in range(len(anm1s)):
                    anm1s[j] = [anm1s[j] + [i] for i in range(m)]
                anm1s = sum(anm1s, [])
            anm1s = [sum([Z_Fbasis[i] * a[i] for i in range(self.d)]) for a in anm1s]
            # Minimize trace in class.
            import numpy

            for i in range(len(anm1s)):
                Q = [[v(m * x) for v in self.Foo] + [0] for x in Z_Fbasis] + [
                    [v(anm1s[i]) for v in self.Foo] + [10 ** 6]
                ]
                pari_string = "[" + ";".join([",".join(["%s" % ii for ii in row]) for row in zip(*Q)]) + "]"
                adj = pari(pari_string).qflll()[self.d]
                anm1s[i] += sum([m * Z_Fbasis[ii] * int(adj[ii]) // int(adj[self.d]) for ii in range(self.d)])

            self.amaxvals[m - 1] = anm1s
            self.a[m - 1] = self.amaxvals[m - 1].pop()
            self.k = m - 2

            bl = math.ceil(1.7719 * self.n)
            br = max(
                [
                    1.0 / m * (am1 ** 2).trace()
                    + self.gamma * (1.0 / (m ** d) * self.B / self.dF) ** (1.0 / (self.n - d))
                    for am1 in anm1s
                ]
            )
            br = math.floor(br)
            T2s = self.F._positive_integral_elements_with_trace([bl, br])
            self.trace_elts.append([bl, br, T2s])

        elif len(a) <= m + 1:
            # First few coefficients have been specified.
            # The value of k is the largest index of the coefficients of a which is
            # currently unknown; e.g., if k == -1, then we can iterate
            # over polynomials, and if k == n-1, then we have finished iterating.
            if a[len(a) - 1] <> 1:
                raise ValueError, "a[len(a)-1](=%s) must be 1 so polynomial is monic" % a[len(a) - 1]

            raise NotImplementedError, "These have not been checked."

            k = m - len(a)
            self.k = k
            a = [0] * (k + 1) + a
            self.amaxvals = [[]] * m
            for i in range(0, n + 1):
                self.a[i] = a[i]

            # Bounds come from an application of Lagrange multipliers in degrees 2,3.
            self.b_lower = [
                -1.0
                / m
                * (
                    v(self.a[m - 1])
                    + (m - 1.0) * math.sqrt(v(self.a[m - 1]) ** 2 - 2.0 * (1 + 1.0 / (m - 1)) * v(self.a[m - 2]))
                )
                for v in self.Foo
            ]
            self.b_upper = [
                -1.0
                / m
                * (
                    v(self.a[m - 1])
                    - (m - 1.0) * math.sqrt(v(self.a[m - 1]) ** 2 - 2.0 * (1 + 1.0 / (m - 1)) * v(self.a[m - 2]))
                )
                for v in self.Foo
            ]
            if k < m - 2:
                bminmax = [lagrange_degree_3(n, v(self.a[m - 1]), v(self.a[m - 2]), v(self.a[m - 3])) for v in self.Foo]
                self.b_lower = bminmax[0]
                self.b_upper = bminmax[1]

            # Annoying, but must reverse coefficients for numpy.
            gnk = [binomial(j, k + 2) * a[j] for j in range(k + 2, n + 1)]
            self.beta[k + 1] = [
                [self.b_lower]
                + numpy.roots([v(gnk[i]) for i in range(len(gnk))].reverse()).tolist().sort()
                + [self.b_upper]
                for v in self.Foo
            ]

            # Now to really initialize gnk.
            self.gnk[k + 1] = [[0] + [binomial(j, k + 1) * v(a[j]) for j in range(k + 2, m + 1)] for v in self.Foo]
        else:
            # Bad input!
            raise ValueError, "a has length %s > m+1" % len(a)
Ejemplo n.º 23
0
def pari(x):
    """
    Return the pari object constructed from a Sage object.

    The work is done by the __call__ method of the class PariInstance,
    which in turn passes the work to any class which has its own
    method _pari_().

    EXAMPLES::
        
        sage: pari([2,3,5])
        [2, 3, 5]
        sage: pari(Matrix(2,2,range(4)))
        [0, 1; 2, 3]
        sage: pari(x^2-3)
        x^2 - 3
    
    ::

        sage: a = pari(1); a, a.type()
        (1, 't_INT')
        sage: a = pari(1/2); a, a.type()
        (1/2, 't_FRAC')
        sage: a = pari(1/2); a, a.type()
        (1/2, 't_FRAC')

    Conversion from reals uses the real's own precision, here 53 bits (the default)::

        sage: a = pari(1.2); a, a.type(), a.precision()
        (1.20000000000000, 't_REAL', 4) # 32-bit
        (1.20000000000000, 't_REAL', 3) # 64-bit

    Conversion from strings uses the current pari real precision.  By
    default this is 4 words, 38 digits, 128 bits on 64-bit machines
    and 5 words, 19 digits, 64 bits on 32-bit machines. ::
    
        sage: a = pari('1.2'); a, a.type(), a.precision()
        (1.20000000000000, 't_REAL', 5) # 32-bit
        (1.20000000000000, 't_REAL', 4) # 64-bit

    Conversion from matrices is supported, but not from vectors; use
    lists instead::
    
        sage: a = pari(matrix(2,3,[1,2,3,4,5,6])); a, a.type()
        ([1, 2, 3; 4, 5, 6], 't_MAT')

        sage: v = vector([1.2,3.4,5.6])
        sage: v.pari()
        Traceback (most recent call last):
        ...
        AttributeError: 'sage.modules.free_module_element.FreeModuleElement_generic_dense' object has no attribute 'pari'
        sage: b = pari(list(v)); b,b.type()
        ([1.20000000000000, 3.40000000000000, 5.60000000000000], 't_VEC')

    Some more exotic examples::

        sage: K.<a> = NumberField(x^3 - 2)
        sage: pari(K)
        [y^3 - 2, [1, 1], -108, 1, [[1, 1.25992104989487, 1.58740105196820; 1, -0.629960524947437 - 1.09112363597172*I, -0.793700525984100 + 1.37472963699860*I], [1, 1.25992104989487, 1.58740105196820; 1, -1.72108416091916, 0.581029111014503; 1, 0.461163111024285, -2.16843016298270], [1, 1, 2; 1, -2, 1; 1, 0, -2], [3, 0, 0; 0, 0, 6; 0, 6, 0], [6, 0, 0; 0, 6, 0; 0, 0, 3], [2, 0, 0; 0, 0, 1; 0, 1, 0], [2, [0, 0, 2; 1, 0, 0; 0, 1, 0]]], [1.25992104989487, -0.629960524947437 - 1.09112363597172*I], [1, y, y^2], [1, 0, 0; 0, 1, 0; 0, 0, 1], [1, 0, 0, 0, 0, 2, 0, 2, 0; 0, 1, 0, 1, 0, 0, 0, 0, 2; 0, 0, 1, 0, 1, 0, 1, 0, 0]]
    
        sage: E = EllipticCurve('37a1')
        sage: pari(E)
        [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, [0.837565435283323, 0.269594436405445, -1.10715987168877]~, 2.99345864623196, -2.45138938198679*I, 0.942638555913623, 1.32703057887968*I, 7.33813274078958]

    Conversion from basic Python types::

        sage: pari(int(-5))
        -5
        sage: pari(long(2**150))
        1427247692705959881058285969449495136382746624
        sage: pari(float(pi))
        3.14159265358979
        sage: pari(complex(exp(pi*I/4)))
        0.707106781186548 + 0.707106781186547*I
        sage: pari(False)
        0
        sage: pari(True)
        1
        
    Some commands are just executed without returning a value::
    
        sage: pari("dummy = 0; kill(dummy)")
        sage: type(pari("dummy = 0; kill(dummy)"))
        <type 'NoneType'>
    """
    return gen.pari(x)
Ejemplo n.º 24
0
 def classno(d):
     """Return the class number of the order of discriminant d."""
     # There is currently no qfbclassno method in gen.pyx, hence the string.
     return Integer(pari('qfbclassno(%s,%s)' % (d, 1 if proof else 0)))
Ejemplo n.º 25
0
Archivo: cm.py Proyecto: dagss/sage
 def classno(d):
     """Return the class number of the order of discriminant d."""
     # There is currently no qfbclassno method in gen.pyx, hence the string.
     return Integer(pari('qfbclassno(%s,%s)'%(d, 1 if proof else 0)))