Example #1
0
    def _call_(self, v):
        r"""
        EXAMPLE::

            sage: L.<b> = NumberField(x^4 + 3*x^2 + 1)
            sage: K = L.relativize(L.subfields(2)[0][1], 'a')
            sage: a0 = K.gen(); b0 = K.base_field().gen()
            sage: V, fr, to = K.relative_vector_space()
            sage: fr(to(a0 + 2*b0)), fr(V([0, 1])), fr(V([b0, 2*b0])) # indirect doctest
            (a0 + 2*b0, a0, 2*b0*a0 + b0)
        """
        # Given a relative vector space element, we have to
        # compute the corresponding number field element, in terms
        # of an absolute generator.
        w = self.__V(v).list()

        # First, construct from w a PARI polynomial in x with coefficients
        # that are polynomials in y:
        B = self.__B
        _, to_B = B.structure()
        # Apply to_B, so now each coefficient is in an absolute field,
        # and is expressed in terms of a polynomial in y, then make
        # the PARI poly in x.
        w = [pari(to_B(a).polynomial('y')) for a in w]
        h = pari(w).Polrev()

        # Next we write the poly in x over a poly in y in terms
        # of an absolute polynomial for the rnf.
        g = self.__R(self.__rnf.rnfeltreltoabs(h))
        return self.__K._element_class(self.__K, g)
Example #2
0
    def _call_(self, v):
        r"""
        EXAMPLE::

            sage: L.<b> = NumberField(x^4 + 3*x^2 + 1)
            sage: K = L.relativize(L.subfields(2)[0][1], 'a')
            sage: a0 = K.gen(); b0 = K.base_field().gen()
            sage: V, fr, to = K.relative_vector_space()
            sage: fr(to(a0 + 2*b0)), fr(V([0, 1])), fr(V([b0, 2*b0])) # indirect doctest
            (a0 + 2*b0, a0, 2*b0*a0 + b0)
        """
        # Given a relative vector space element, we have to
        # compute the corresponding number field element, in terms
        # of an absolute generator.
        w = self.__V(v).list()

        # First, construct from w a PARI polynomial in x with coefficients
        # that are polynomials in y:
        B = self.__B
        _, to_B = B.structure()
        # Apply to_B, so now each coefficient is in an absolute field,
        # and is expressed in terms of a polynomial in y, then make
        # the PARI poly in x.
        w = [pari(to_B(a).polynomial('y')) for a in w]
        h = pari(w).Polrev()

        # Next we write the poly in x over a poly in y in terms
        # of an absolute polynomial for the rnf.
        g = self.__R(self.__rnf.rnfeltreltoabs(h))
        return self.__K._element_class(self.__K, g)
Example #3
0
 def _pari_modulus(self):
     """
     EXAMPLES:
         sage: GF(3^4,'a')._pari_modulus()
         Mod(1, 3)*a^4 + Mod(2, 3)*a^3 + Mod(2, 3)        
     """
     f = pari(str(self.modulus()))
     return f.subst('x', 'a') * pari("Mod(1,%s)" % self.characteristic())
Example #4
0
 def _pari_modulus(self):
     """
     EXAMPLES:
         sage: GF(3^4,'a')._pari_modulus()
         Mod(1, 3)*a^4 + Mod(2, 3)*a^3 + Mod(2, 3)        
     """
     f = pari(str(self.modulus()))
     return f.subst('x', 'a') * pari("Mod(1,%s)"%self.characteristic())
Example #5
0
    def _element_constructor_(self, u):
        """
        Returns the abstract group element corresponding to the unit u.

        INPUT:

        - ``u`` -- Any object from which an element of the unit group's number
          field `K` may be constructed; an error is raised if an element of `K`
          cannot be constructed from u, or if the element constructed is not a
          unit.

        EXAMPLES::

            sage: x = polygen(QQ)
            sage: K.<a> = NumberField(x^2-38)
            sage: UK = UnitGroup(K)
            sage: UK(1)
            1
            sage: UK(-1)
            u0
            sage: UK.gens()
            (u0, u1)
            sage: UK.gens_values()
            [-1, 6*a - 37]
            sage: UK.ngens()
            2
            sage: [UK(u) for u in UK.gens()]
            [u0, u1]
            sage: [UK(u).exponents() for u in UK.gens()]
            [(1, 0), (0, 1)]
            sage: UK(a)
            Traceback (most recent call last):
            ...
            ValueError: a is not a unit
        """
        K = self.__number_field
        pK = self.__pari_number_field
        try:
            u = K(u)
        except TypeError:
            raise ValueError("%s is not an element of %s" % (u, K))
        if self.__S:
            m = pK.bnfissunit(self.__S_unit_data, pari(u)).mattranspose()
            if m.ncols() == 0:
                raise ValueError("%s is not an S-unit" % u)
        else:
            if not u.is_integral() or u.norm().abs() != 1:
                raise ValueError("%s is not a unit" % u)
            m = pK.bnfisunit(pari(u)).mattranspose()

        # convert column matrix to a list:
        m = [ZZ(m[0, i].python()) for i in range(m.ncols())]

        # NB pari puts the torsion after the fundamental units, before
        # the extra S-units but we have the torsion first:
        m = [m[self.__nfu]] + m[:self.__nfu] + m[self.__nfu + 1:]

        return self.element_class(self, m)
Example #6
0
def exponential_integral_1(x, n=0):
    r"""
    Returns the exponential integral `E_1(x)`. If the optional
    argument `n` is given, computes list of the first
    `n` values of the exponential integral
    `E_1(x m)`.
    
    The exponential integral `E_1(x)` is
    
    .. math::
    
                      E_1(x) = \int_{x}^{\infty} e^{-t}/t dt     
    
    
    
    INPUT:
    
    
    -  ``x`` - a positive real number
    
    -  ``n`` - (default: 0) a nonnegative integer; if
       nonzero, then return a list of values E_1(x\*m) for m =
       1,2,3,...,n. This is useful, e.g., when computing derivatives of
       L-functions.
    
    
    OUTPUT:
    
    
    -  ``float`` - if n is 0 (the default) or
    
    -  ``list`` - list of floats if n 0
    
    
    EXAMPLES::
    
        sage: exponential_integral_1(2)
        0.04890051070806112
        sage: w = exponential_integral_1(2,4); w
        [0.04890051070806112, 0.003779352409848906..., 0.00036008245216265873, 3.7665622843924...e-05]
    
    IMPLEMENTATION: We use the PARI C-library functions eint1 and
    veceint1.
    
    REFERENCE:

    - See page 262, Prop 5.6.12, of Cohen's book "A Course in
      Computational Algebraic Number Theory".
    
    REMARKS: When called with the optional argument n, the PARI
    C-library is fast for values of n up to some bound, then very very
    slow. For example, if x=5, then the computation takes less than a
    second for n=800000, and takes "forever" for n=900000.
    """
    if n <= 0:
        return float(pari(x).eint1())
    else:
        return [float(z) for z in pari(x).eint1(n)]
Example #7
0
def exponential_integral_1(x, n=0):
    r"""
    Returns the exponential integral `E_1(x)`. If the optional
    argument `n` is given, computes list of the first
    `n` values of the exponential integral
    `E_1(x m)`.
    
    The exponential integral `E_1(x)` is
    
    .. math::
    
                      E_1(x) = \int_{x}^{\infty} e^{-t}/t dt     
    
    
    
    INPUT:
    
    
    -  ``x`` - a positive real number
    
    -  ``n`` - (default: 0) a nonnegative integer; if
       nonzero, then return a list of values E_1(x\*m) for m =
       1,2,3,...,n. This is useful, e.g., when computing derivatives of
       L-functions.
    
    
    OUTPUT:
    
    
    -  ``float`` - if n is 0 (the default) or
    
    -  ``list`` - list of floats if n 0
    
    
    EXAMPLES::
    
        sage: exponential_integral_1(2)
        0.04890051070806112
        sage: w = exponential_integral_1(2,4); w
        [0.04890051070806112, 0.003779352409848906..., 0.00036008245216265873, 3.7665622843924...e-05]
    
    IMPLEMENTATION: We use the PARI C-library functions eint1 and
    veceint1.
    
    REFERENCE:

    - See page 262, Prop 5.6.12, of Cohen's book "A Course in
      Computational Algebraic Number Theory".
    
    REMARKS: When called with the optional argument n, the PARI
    C-library is fast for values of n up to some bound, then very very
    slow. For example, if x=5, then the computation takes less than a
    second for n=800000, and takes "forever" for n=900000.
    """
    if n <= 0:
        return float(pari(x).eint1())
    else:
        return [float(z) for z in pari(x).eint1(n)]
Example #8
0
    def _element_constructor_(self, u):
        """
        Returns the abstract group element corresponding to the unit u.

        INPUT:

        - ``u`` -- Any object from which an element of the unit group's number
          field `K` may be constructed; an error is raised if an element of `K`
          cannot be constructed from u, or if the element constructed is not a
          unit.

        EXAMPLES::

            sage: x = polygen(QQ)
            sage: K.<a> = NumberField(x^2-38)
            sage: UK = UnitGroup(K)
            sage: UK(1)
            1
            sage: UK(-1)
            u0
            sage: UK.gens()
            (u0, u1)
            sage: UK.gens_values()
            [-1, 6*a - 37]
            sage: UK.ngens()
            2
            sage: [UK(u) for u in UK.gens()]
            [u0, u1]
            sage: [UK(u).exponents() for u in UK.gens()]
            [(1, 0), (0, 1)]
            sage: UK(a)
            Traceback (most recent call last):
            ...
            ValueError: a is not a unit
        """
        K = self.__number_field
        pK = self.__pari_number_field
        try:
            u = K(u)
        except TypeError:
            raise ValueError("%s is not an element of %s"%(u,K))
        if self.__S:
            m = pK.bnfissunit(self.__S_unit_data, pari(u)).mattranspose()
            if m.ncols()==0:
                raise ValueError("%s is not an S-unit"%u)
        else:
            if not u.is_integral() or u.norm().abs() != 1:
                raise ValueError("%s is not a unit"%u)
            m = pK.bnfisunit(pari(u)).mattranspose()

        # convert column matrix to a list:
        m = [ZZ(m[0,i].python()) for i in range(m.ncols())]

        # NB pari puts the torsion after the fundamental units, before
        # the extra S-units but we have the torsion first:
        m = [m[self.__nfu]] + m[:self.__nfu] + m[self.__nfu+1:]

        return self.element_class(self, m)
Example #9
0
    def _pari_modulus(self):
        """
        Return the modulus of ``self`` in a format for PARI.

        EXAMPLES::

            sage: GF(3^4,'a')._pari_modulus()
            Mod(1, 3)*a^4 + Mod(2, 3)*a^3 + Mod(2, 3)
        """
        f = pari(str(self.modulus()))
        return f.subst('x', 'a') * pari("Mod(1,%s)"%self.characteristic())
Example #10
0
    def _pari_modulus(self):
        """
        Return the modulus of ``self`` in a format for PARI.

        EXAMPLES::

            sage: GF(3^4,'a')._pari_modulus()
            Mod(1, 3)*a^4 + Mod(2, 3)*a^3 + Mod(2, 3)
        """
        f = pari(str(self.modulus()))
        return f.subst('x', 'a') * pari("Mod(1,%s)"%self.characteristic())
Example #11
0
    def _pari_modulus(self):
        """
        Return PARI object which is equivalent to the
        polynomial/modulus of ``self``.

        EXAMPLES::

            sage: k1.<a> = GF(2^16)
            sage: k1._pari_modulus()
            Mod(1, 2)*a^16 + Mod(1, 2)*a^5 + Mod(1, 2)*a^3 + Mod(1, 2)*a^2 + Mod(1, 2)
        """
        f = pari(str(self.modulus()))
        return f.subst('x', 'a') * pari("Mod(1,%s)" % self.characteristic())
Example #12
0
    def _pari_modulus(self):
        """
        Return PARI object which is equivalent to the
        polynomial/modulus of ``self``.

        EXAMPLES::

            sage: k1.<a> = GF(2^16)
            sage: k1._pari_modulus()
            Mod(1, 2)*a^16 + Mod(1, 2)*a^5 + Mod(1, 2)*a^3 + Mod(1, 2)*a^2 + Mod(1, 2)
        """
        f = pari(str(self.modulus()))
        return f.subst('x', 'a') * pari("Mod(1,%s)"%self.characteristic())
Example #13
0
    def _sage_(self):
        """
        Convert this GpElement into a Sage object, if possible.

        EXAMPLES::

            sage: gp(I).sage()
            i
            sage: gp(I).sage().parent()
            Maximal Order in Number Field in i with defining polynomial x^2 + 1

        ::

            sage: M = Matrix(ZZ,2,2,[1,2,3,4]); M
            [1 2]
            [3 4]
            sage: gp(M)
            [1, 2; 3, 4]
            sage: gp(M).sage()
            [1 2]
            [3 4]
            sage: gp(M).sage() == M
            True
        """
        return pari(str(self)).python()
Example #14
0
    def _ramgroups(self, P):
        """
        Compute ramification data using PARI.

        INPUT:

        - ``P`` -- a prime ideal

        OUTPUT:

        A PARI vector holding the decomposition group, inertia groups,
        and higher ramification groups.

        ALGORITHM:

        This uses the PARI function :pari:`idealramgroups`.

        EXAMPLES::

            sage: K.<a> = NumberField(x^4 - 2*x^2 + 2,'b').galois_closure()
            sage: P = K.ideal([17, a^2])
            sage: G = K.galois_group()
            sage: G._ramgroups(P)
            [[[Vecsmall([8, 7, 6, 5, 4, 3, 2, 1])], Vecsmall([2])]]
        """
        K = self.number_field()
        P = K.ideal_monoid()(P).pari_prime()
        return pari(K).idealramgroups(self._pari_data, P)
    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
        self._lc = self._poly.leading_coefficient()

        # this uses that [ O_K : Z[a] ]^2 = | disc(f(x)) / disc(O_K) |
        from sage.libs.pari.all import pari
        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._lc)

        self._integer_iter = iter(ZZ)
        self._queue = []
        self._max_iterations = max_iterations
Example #16
0
    def _complex_mpfr_field_(self, CC):
        """
        Return ComplexField element of self.

        INPUT:

        - ``CC`` -- a Complex or Real Field.

        EXAMPLES::

            sage: z = gp(1+15*I); z
            1 + 15*I
            sage: z._complex_mpfr_field_(CC)
            1.00000000000000 + 15.0000000000000*I
            sage: CC(z) # CC(gp(1+15*I))
            1.00000000000000 + 15.0000000000000*I
            sage: CC(gp(11243.9812+15*I))
            11243.9812000000 + 15.0000000000000*I
            sage: ComplexField(10)(gp(11243.9812+15*I))
            11000. + 15.*I
        """
        # Multiplying by CC(1) is necessary here since
        # sage: pari(gp(1+I)).sage().parent()
        # Maximal Order in Number Field in i with defining polynomial x^2 + 1
        return CC((CC(1) * pari(self)).sage())
Example #17
0
    def _sage_(self):
        """
        Convert this GpElement into a Sage object, if possible.

        EXAMPLES::

            sage: gp(I).sage()
            i
            sage: gp(I).sage().parent()
            Number Field in i with defining polynomial x^2 + 1 with i = 1*I

        ::

            sage: M = Matrix(ZZ,2,2,[1,2,3,4]); M
            [1 2]
            [3 4]
            sage: gp(M)
            [1, 2; 3, 4]
            sage: gp(M).sage()
            [1 2]
            [3 4]
            sage: gp(M).sage() == M
            True

        Conversion of strings::

           sage: s = gp('"foo"')
           sage: s.sage()
           'foo'
           sage: type(s.sage())
           <type 'str'>
        """
        if self.is_string():
            return str(self)
        return pari(str(self)).sage()
Example #18
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).

        EXAMPLES::

            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 with a0 = a^3 + a,
             Ring morphism:
               From: Number Field in a0 with defining polynomial x^2 + 2 with a0 = a^3 + a
               To:   Number Field in a with defining polynomial x^4 + 1
               Defn: a0 |--> a^3 + a)

        An embedding is returned also if the subgroup is trivial
        (:trac:`26817`)::

            sage: H = G.subgroup([G.identity()])
            sage: H.fixed_field()
            (Number Field in a0 with defining polynomial x^4 + 1 with a0 = a,
             Ring morphism:
               From: Number Field in a0 with defining polynomial x^4 + 1 with a0 = a
               To:   Number Field in a with defining polynomial x^4 + 1
               Defn: a0 |--> a)
        """
        vecs = [pari(g.domain()).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)
Example #19
0
    def __mul__(self, right):
        """
        Gauss composition of binary quadratic forms.  The result is
        not reduced.

        EXAMPLES:

        We explicitly compute in the group of classes of positive
        definite binary quadratic forms of discriminant -23.

        ::

            sage: R = BinaryQF_reduced_representatives(-23); R
            [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2]
            sage: R[0] * R[0]
            x^2 + x*y + 6*y^2
            sage: R[1] * R[1]
            4*x^2 + 3*x*y + 2*y^2
            sage: (R[1] * R[1]).reduced_form()
            2*x^2 + x*y + 3*y^2
            sage: (R[1] * R[1] * R[1]).reduced_form()
            x^2 + x*y + 6*y^2

        """
        if not isinstance(right, BinaryQF):
            raise TypeError, "both self and right must be binary quadratic forms"
        # There could be more elegant ways, but qfbcompraw isn't
        # wrapped yet in the PARI C library.  We may as well settle
        # for the below, until somebody simply implements composition
        # from scratch in Cython.
        v = list(pari('qfbcompraw(%s,%s)'%(self._pari_init_(),
                                           right._pari_init_())))
        return BinaryQF(v)
Example #20
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).

        EXAMPLES::

            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 with a0 = a^3 + a,
             Ring morphism:
               From: Number Field in a0 with defining polynomial x^2 + 2 with a0 = a^3 + a
               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.domain()).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)
Example #21
0
    def reduced_form(self):
        """
        Return the unique reduced form equivalent to ``self``. See also
        :meth:`~is_reduced`.

        EXAMPLES::

            sage: a = BinaryQF([33,11,5])
            sage: a.is_reduced()
            False
            sage: b = a.reduced_form(); b
            5*x^2 - x*y + 27*y^2
            sage: b.is_reduced()
            True

            sage: a = BinaryQF([15,0,15])
            sage: a.is_reduced()
            True
            sage: b = a.reduced_form(); b
            15*x^2 + 15*y^2
            sage: b.is_reduced()
            True
        """
        if self.discriminant() >= 0 or self._a < 0:
            raise NotImplementedError, "only implemented for positive definite forms"
        if not self.is_reduced():
            v = list(
                pari('Vec(qfbred(Qfb(%s,%s,%s)))' %
                     (self._a, self._b, self._c)))
            return BinaryQF(v)
        else:
            return self
Example #22
0
    def _complex_mpfr_field_(self, CC):
        """
        Return ComplexField element of self.

        INPUT:

        - ``CC`` -- a Complex or Real Field.

        EXAMPLES::

            sage: z = gp(1+15*I); z
            1 + 15*I
            sage: z._complex_mpfr_field_(CC)
            1.00000000000000 + 15.0000000000000*I
            sage: CC(z) # CC(gp(1+15*I))
            1.00000000000000 + 15.0000000000000*I
            sage: CC(gp(11243.9812+15*I))
            11243.9812000000 + 15.0000000000000*I
            sage: ComplexField(10)(gp(11243.9812+15*I))
            11000. + 15.*I
        """
        # Multiplying by CC(1) is necessary here since
        # sage: pari(gp(1+I)).sage().parent()
        # Maximal Order in Number Field in i with defining polynomial x^2 + 1

        return CC((CC(1)*pari(self))._sage_())
Example #23
0
    def __mul__(self, right):
        """
        Gauss composition of binary quadratic forms.  The result is
        not reduced.

        EXAMPLES:

        We explicitly compute in the group of classes of positive
        definite binary quadratic forms of discriminant -23.

        ::

            sage: R = BinaryQF_reduced_representatives(-23); R
            [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2]
            sage: R[0] * R[0]
            x^2 + x*y + 6*y^2
            sage: R[1] * R[1]
            4*x^2 + 3*x*y + 2*y^2
            sage: (R[1] * R[1]).reduced_form()
            2*x^2 + x*y + 3*y^2
            sage: (R[1] * R[1] * R[1]).reduced_form()
            x^2 + x*y + 6*y^2

        """
        if not isinstance(right, BinaryQF):
            raise TypeError, "both self and right must be binary quadratic forms"
        # There could be more elegant ways, but qfbcompraw isn't
        # wrapped yet in the PARI C library.  We may as well settle
        # for the below, until somebody simply implements composition
        # from scratch in Cython.
        v = list(
            pari('qfbcompraw(%s,%s)' %
                 (self._pari_init_(), right._pari_init_())))
        return BinaryQF(v)
Example #24
0
    def reduced_form(self):
        """
        Return the unique reduced form equivalent to ``self``. See also
        :meth:`~is_reduced`.

        EXAMPLES::

            sage: a = BinaryQF([33,11,5])
            sage: a.is_reduced()
            False
            sage: b = a.reduced_form(); b
            5*x^2 - x*y + 27*y^2
            sage: b.is_reduced()
            True

            sage: a = BinaryQF([15,0,15])
            sage: a.is_reduced()
            True
            sage: b = a.reduced_form(); b
            15*x^2 + 15*y^2
            sage: b.is_reduced()
            True
        """
        if self.discriminant() >= 0 or self._a < 0:
            raise NotImplementedError, "only implemented for positive definite forms"
        if not self.is_reduced():
            v = list(pari('Vec(qfbred(Qfb(%s,%s,%s)))'%(self._a,self._b,self._c)))
            return BinaryQF(v)
        else:
            return self
Example #25
0
    def _sage_(self):
        """
        Convert this GpElement into a Sage object, if possible.

        EXAMPLES::

            sage: gp(I).sage()
            i
            sage: gp(I).sage().parent()
            Number Field in i with defining polynomial x^2 + 1

        ::

            sage: M = Matrix(ZZ,2,2,[1,2,3,4]); M
            [1 2]
            [3 4]
            sage: gp(M)
            [1, 2; 3, 4]
            sage: gp(M).sage()
            [1 2]
            [3 4]
            sage: gp(M).sage() == M
            True
        """
        return pari(str(self)).python()
    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) |
        from sage.libs.pari.all import pari

        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
Example #27
0
def pari(x):
    """
    Return the PARI object constructed from a Sage/Python object.

    This is deprecated, import ``pari`` from ``sage.libs.pari.all``.
    """
    from sage.misc.superseded import deprecation
    deprecation(17451, 'gen_py.pari is deprecated, use sage.libs.pari.all.pari instead')
    from sage.libs.pari.all import pari
    return pari(x)
Example #28
0
    def __float__(self):
        """
        Return Python float.

        EXAMPLES::

            sage: float(gp(10))
            10.0
        """
        return float(pari(str(self)))
Example #29
0
    def __float__(self):
        """
        Return Python float.

        EXAMPLES::

            sage: float(gp(10))
            10.0
        """
        return float(pari(str(self)))
Example #30
0
def pari(x):
    """
    Return the PARI object constructed from a Sage/Python object.

    This is deprecated, import ``pari`` from ``sage.libs.pari.all``.
    """
    from sage.misc.superseded import deprecation
    deprecation(17451, 'gen_py.pari is deprecated, use sage.libs.pari.all.pari instead')
    from sage.libs.pari.all import pari
    return pari(x)
Example #31
0
    def _call_(self, alpha):
        """
        TESTS::

            sage: K.<a> = NumberField(x^5+2)
            sage: R.<y> = K[]
            sage: D.<x0> = K.extension(y + a + 1)
            sage: D(a)
            a
            sage: V, from_V, to_V = D.relative_vector_space()
            sage: to_V(a) # indirect doctest
            (a)
            sage: to_V(a^3) # indirect doctest
            (a^3)
            sage: to_V(x0) # indirect doctest
            (-a - 1)

            sage: K.<a> = QuadraticField(-3)
            sage: L.<b> = K.extension(x-5)
            sage: L(a)
            a
            sage: a*b
            5*a
            sage: b
            5
            sage: V, from_V, to_V = L.relative_vector_space()
            sage: to_V(a) # indirect doctest
            (a)
        """
        # An element of a relative number field is represented
        # internally by an absolute polynomial over QQ.
        alpha = self.__K(alpha)

        # f is the absolute polynomial that defines this number field
        # element
        f = alpha.polynomial('x')
        g = self.__rnf.rnfeltabstorel(pari(f)).lift().lift()
        # Now g is a relative polynomial that defines this element.
        # This g is a polynomial in a pari variable x with
        # coefficients polynomials in a variable y.  These
        # coefficients define the coordinates of the vector we are
        # constructing.

        # The list v below has the coefficients that are the
        # components of the vector we are constructing, but each is
        # converted into polynomials in a variable x, which we will
        # use to define elements of the base field.
        (x, y) = (self.__x, self.__y)
        v = [g.polcoeff(i).subst(x,y) for i in range(self.__n)]
        B,from_B, _ = self.__B
        w = [from_B(B(z)) for z in v]

        # Now w gives the coefficients.
        return self.__V(w)
Example #32
0
    def _call_(self, alpha):
        """
        TESTS::

            sage: K.<a> = NumberField(x^5+2)
            sage: R.<y> = K[]
            sage: D.<x0> = K.extension(y + a + 1)
            sage: D(a)
            a
            sage: V, from_V, to_V = D.relative_vector_space()
            sage: to_V(a) # indirect doctest
            (a)
            sage: to_V(a^3) # indirect doctest
            (a^3)
            sage: to_V(x0) # indirect doctest
            (-a - 1)

            sage: K.<a> = QuadraticField(-3)
            sage: L.<b> = K.extension(x-5)
            sage: L(a)
            a
            sage: a*b
            5*a
            sage: b
            5
            sage: V, from_V, to_V = L.relative_vector_space()
            sage: to_V(a) # indirect doctest
            (a)
        """
        # An element of a relative number field is represented
        # internally by an absolute polynomial over QQ.
        alpha = self.__K(alpha)

        # f is the absolute polynomial that defines this number field
        # element
        f = alpha.polynomial('x')
        g = self.__rnf.rnfeltabstorel(pari(f)).lift().lift()
        # Now g is a relative polynomial that defines this element.
        # This g is a polynomial in a pari variable x with
        # coefficients polynomials in a variable y.  These
        # coefficients define the coordinates of the vector we are
        # constructing.

        # The list v below has the coefficients that are the
        # components of the vector we are constructing, but each is
        # converted into polynomials in a variable x, which we will
        # use to define elements of the base field.
        (x, y) = (self.__x, self.__y)
        v = [g.polcoeff(i).subst(x, y) for i in range(self.__n)]
        B, from_B, _ = self.__B
        w = [from_B(B(z)) for z in v]

        # Now w gives the coefficients.
        return self.__V(w)
def representation_number_list(self, B):
    """
    Return the vector of representation numbers < B.

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ,[1,1,1,1,1,1,1,1])
        sage: Q.representation_number_list(10)
        [1, 16, 112, 448, 1136, 2016, 3136, 5504, 9328, 12112]
    """
    ans = pari(1).concat(self.__pari__().qfrep(B - 1, 1) * 2)
    return ans.sage()
Example #34
0
    def _pari_(self):
        """
        Return PARI list corresponding to this continued fraction.

        EXAMPLES::

            sage: c = continued_fraction(0.12345); c
            [0, 8, 9, 1, 21, 1, 1]
            sage: pari(c)
            [0, 8, 9, 1, 21, 1, 1]
        """
        return pari(self._x)
Example #35
0
    def __init__(self, K, V):
        r"""
        EXAMPLE::

            sage: L.<b> = NumberField(x^4 + 3*x^2 + 1)
            sage: K = L.relativize(L.subfields(2)[0][1], 'a')
            sage: V, fr, to = K.relative_vector_space()
            sage: to
            Isomorphism map:
              From: Number Field in a0 with defining polynomial x^2 - b0*x + 1 over its base field
              To:   Vector space of dimension 2 over Number Field in b0 with defining polynomial x^2 + 1
        """
        self.__V = V
        self.__K = K
        self.__rnf = K.pari_rnf()
        self.__zero = QQ(0)
        self.__n = K.relative_degree()
        self.__x = pari("'x")
        self.__y = pari("'y")
        self.__B = K.absolute_base_field()
        NumberFieldIsomorphism.__init__(self, Hom(K, V))
Example #36
0
    def __init__(self, K, V):
        r"""
        EXAMPLE::

            sage: L.<b> = NumberField(x^4 + 3*x^2 + 1)
            sage: K = L.relativize(L.subfields(2)[0][1], 'a')
            sage: V, fr, to = K.relative_vector_space()
            sage: to
            Isomorphism map:
              From: Number Field in a0 with defining polynomial x^2 - b0*x + 1 over its base field
              To:   Vector space of dimension 2 over Number Field in b0 with defining polynomial x^2 + 1
        """
        self.__V = V
        self.__K = K
        self.__rnf = K.pari_rnf()
        self.__zero = QQ(0)
        self.__n = K.relative_degree()
        self.__x = pari("'x")
        self.__y = pari("'y")
        self.__B = K.absolute_base_field()
        NumberFieldIsomorphism.__init__(self, Hom(K, V))
Example #37
0
    def _pari_(self):
        """
        Return PARI list corresponding to this continued fraction.

        EXAMPLES::

            sage: c = continued_fraction(0.12345); c
            [0, 8, 9, 1, 21, 1, 1]
            sage: pari(c)
            [0, 8, 9, 1, 21, 1, 1]
        """
        return pari(self._x)
Example #38
0
    def __pari__(self):
        """
        Return a PARI representation of ``self``.

        EXAMPLES::

            sage: Cusp(1, 0).__pari__()
            +oo
            sage: pari(Cusp(3, 2))
            3/2
        """
        b = self.__b
        return pari(self.__a / b) if b else pari.oo()
Example #39
0
def elliptic_j(z):
    r"""
   Returns the elliptic modular `j`-function evaluated at `z`.

   INPUT:

   - ``z`` (complex) -- a complex number with positive imaginary part.

   OUTPUT:

   (complex) The value of `j(z)`.

   ALGORITHM:

   Calls the ``pari`` function ``ellj()``.

   AUTHOR:

   John Cremona

   EXAMPLES::

       sage: elliptic_j(CC(i))
       1728.00000000000
       sage: elliptic_j(sqrt(-2.0))
       8000.00000000000
       sage: z = ComplexField(100)(1,sqrt(11))/2
       sage: elliptic_j(z)
       -32768.000...
       sage: elliptic_j(z).real().round()
       -32768

    ::

       sage: tau = (1 + sqrt(-163))/2
       sage: (-elliptic_j(tau.n(100)).real().round())^(1/3)
       640320

   """
    CC = z.parent()
    from sage.rings.complex_field import is_ComplexField

    if not is_ComplexField(CC):
        CC = ComplexField()
        try:
            z = CC(z)
        except ValueError:
            raise ValueError("elliptic_j only defined for complex arguments.")
    from sage.libs.all import pari

    return CC(pari(z).ellj())
Example #40
0
    def _pari_order(self):
        """
        Return the pari integer representing the order of this ring.

        EXAMPLES::

            sage: Zmod(87)._pari_order()
            87
        """
        try:
            return self.__pari_order
        except AttributeError:
            self.__pari_order = pari(self.order())
            return self.__pari_order
Example #41
0
    def _pari_order(self):
        """
        Return the pari integer representing the order of this ring.

        EXAMPLES::

            sage: Zmod(87)._pari_order()
            87
        """
        try:
            return self.__pari_order
        except AttributeError:
            self.__pari_order = pari(self.order())
            return self.__pari_order
Example #42
0
def hypergeometric_U(alpha, beta, x, algorithm="pari", prec=53):
    r"""
    Default is a wrap of PARI's hyperu(alpha,beta,x) function.
    Optionally, algorithm = "scipy" can be used.

    The confluent hypergeometric function `y = U(a,b,x)` is
    defined to be the solution to Kummer's differential equation

    .. math::

             xy'' + (b-x)y' - ay = 0.

    This satisfies `U(a,b,x) \sim x^{-a}`, as
    `x\rightarrow \infty`, and is sometimes denoted
    ``x^{-a}2_F_0(a,1+a-b,-1/x)``. This is not the same as Kummer's
    `M`-hypergeometric function, denoted sometimes as
    ``_1F_1(alpha,beta,x)``, though it satisfies the same DE that
    `U` does.

    .. warning::

       In the literature, both are called "Kummer confluent
       hypergeometric" functions.

    EXAMPLES::

        sage: hypergeometric_U(1,1,1,"scipy")
        0.596347362323...
        sage: hypergeometric_U(1,1,1)
        0.59634736232319...
        sage: hypergeometric_U(1,1,1,"pari",70)
        0.59634736232319407434...
    """
    if algorithm == "scipy":
        if prec != 53:
            raise ValueError("for the scipy algorithm the precision must be 53")
        import scipy.special

        ans = str(scipy.special.hyperu(float(alpha), float(beta), float(x)))
        ans = ans.replace("(", "")
        ans = ans.replace(")", "")
        ans = ans.replace("j", "*I")
        return sage_eval(ans)
    elif algorithm == "pari":
        from sage.libs.pari.all import pari

        R = RealField(prec)
        return R(pari(R(alpha)).hyperu(R(beta), R(x), precision=prec))
    else:
        raise ValueError("unknown algorithm '%s'" % algorithm)
Example #43
0
def elliptic_j(z):
   r"""
   Returns the elliptic modular `j`-function evaluated at `z`.

   INPUT:

   - ``z`` (complex) -- a complex number with positive imaginary part.

   OUTPUT:

   (complex) The value of `j(z)`.

   ALGORITHM:

   Calls the ``pari`` function ``ellj()``.

   AUTHOR:

   John Cremona

   EXAMPLES::

       sage: elliptic_j(CC(i))
       1728.00000000000
       sage: elliptic_j(sqrt(-2.0))
       8000.00000000000
       sage: z = ComplexField(100)(1,sqrt(11))/2
       sage: elliptic_j(z)
       -32768.000...
       sage: elliptic_j(z).real().round()
       -32768

    ::

       sage: tau = (1 + sqrt(-163))/2
       sage: (-elliptic_j(tau.n(100)).real().round())^(1/3)
       640320

   """
   CC = z.parent()
   from sage.rings.complex_field import is_ComplexField
   if not is_ComplexField(CC):
      CC = ComplexField()
      try:
         z = CC(z)
      except ValueError:
         raise ValueError("elliptic_j only defined for complex arguments.")
   from sage.libs.all import pari
   return CC(pari(z).ellj())
Example #44
0
def hypergeometric_U(alpha, beta, x, algorithm="pari", prec=53):
    r"""
    Default is a wrap of PARI's hyperu(alpha,beta,x) function.
    Optionally, algorithm = "scipy" can be used.

    The confluent hypergeometric function `y = U(a,b,x)` is
    defined to be the solution to Kummer's differential equation

    .. math::

             xy'' + (b-x)y' - ay = 0.

    This satisfies `U(a,b,x) \sim x^{-a}`, as
    `x\rightarrow \infty`, and is sometimes denoted
    ``x^{-a}2_F_0(a,1+a-b,-1/x)``. This is not the same as Kummer's
    `M`-hypergeometric function, denoted sometimes as
    ``_1F_1(alpha,beta,x)``, though it satisfies the same DE that
    `U` does.

    .. warning::

       In the literature, both are called "Kummer confluent
       hypergeometric" functions.

    EXAMPLES::

        sage: hypergeometric_U(1,1,1,"scipy")
        0.596347362323...
        sage: hypergeometric_U(1,1,1)
        0.59634736232319...
        sage: hypergeometric_U(1,1,1,"pari",70)
        0.59634736232319407434...
    """
    if algorithm == "scipy":
        if prec != 53:
            raise ValueError(
                "for the scipy algorithm the precision must be 53")
        import scipy.special
        ans = str(scipy.special.hyperu(float(alpha), float(beta), float(x)))
        ans = ans.replace("(", "")
        ans = ans.replace(")", "")
        ans = ans.replace("j", "*I")
        return sage_eval(ans)
    elif algorithm == 'pari':
        from sage.libs.pari.all import pari
        R = RealField(prec)
        return R(pari(R(alpha)).hyperu(R(beta), R(x), precision=prec))
    else:
        raise ValueError("unknown algorithm '%s'" % algorithm)
Example #45
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.domain()).Vecsmall()))
        return L.hom(a, L)
Example #46
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.domain()).Vecsmall()))
        return L.hom(a, L)
Example #47
0
 def __init__(self, x, parent=None):
     """
     EXAMPLES:
         sage: R = PariRing()
         sage: f = R('x^3 + 1/2')
         sage: f
         x^3 + 1/2
         sage: type(f)
         <class 'sage.rings.pari_ring.PariRing_with_category.element_class'>
         sage: loads(f.dumps()) == f
         True
     """
     if parent is None:
         parent = _inst
     ring_element.RingElement.__init__(self, parent)
     self.__x = pari.pari(x)
Example #48
0
 def __init__(self, x, parent=None):
     """
     EXAMPLES:
         sage: R = PariRing()
         sage: f = R('x^3 + 1/2')
         sage: f
         x^3 + 1/2
         sage: type(f)
         <class 'sage.rings.pari_ring.PariRing_with_category.element_class'>
         sage: loads(f.dumps()) == f
         True
     """
     if parent is None:
         parent = _inst
     ring_element.RingElement.__init__(self, parent)
     self.__x = pari.pari(x)
    def __init__(self, p, modulus, name=None):
        """
        Create a finite field of characteristic `p` defined by the
        polynomial ``modulus``, with distinguished generator called
        ``name``.

        EXAMPLE::

            sage: from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt
            sage: R.<x> = PolynomialRing(GF(3))
            sage: k = FiniteField_pari_ffelt(3, x^2 + 2*x + 2, 'a'); k
            Finite Field in a of size 3^2
        """
        import constructor
        from sage.libs.pari.all import pari
        from sage.rings.integer import Integer
        from sage.structure.proof.all import arithmetic
        proof = arithmetic()

        p = Integer(p)
        if ((p < 2)
            or (proof and not p.is_prime())
            or (not proof and not p.is_pseudoprime())):
            raise ArithmeticError("p must be a prime number")
        Fp = constructor.FiniteField(p)

        if name is None:
            name = modulus.variable_name()

        FiniteField.__init__(self, base=Fp, names=name, normalize=True)

        modulus = self.polynomial_ring()(modulus)
        n = modulus.degree()
        if n < 2:
            raise ValueError("the degree must be at least 2")

        self._modulus = modulus
        self._degree = n
        self._card = p ** n
        self._kwargs = {}

        self._gen_pari = pari(modulus).ffgen()
        self._zero_element = self.element_class(self, 0)
        self._one_element = self.element_class(self, 1)
        self._gen = self.element_class(self, self._gen_pari)
Example #50
0
    def __init__(self, p, modulus, name=None):
        """
        Create a finite field of characteristic `p` defined by the
        polynomial ``modulus``, with distinguished generator called
        ``name``.

        EXAMPLE::

            sage: from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt
            sage: R.<x> = PolynomialRing(GF(3))
            sage: k = FiniteField_pari_ffelt(3, x^2 + 2*x + 2, 'a'); k
            Finite Field in a of size 3^2
        """
        import constructor
        from sage.libs.pari.all import pari
        from sage.rings.integer import Integer
        from sage.structure.proof.all import arithmetic
        proof = arithmetic()

        p = Integer(p)
        if ((p < 2) or (proof and not p.is_prime())
                or (not proof and not p.is_pseudoprime())):
            raise ArithmeticError("p must be a prime number")
        Fp = constructor.FiniteField(p)

        if name is None:
            name = modulus.variable_name()

        FiniteField.__init__(self, base=Fp, names=name, normalize=True)

        modulus = self.polynomial_ring()(modulus)
        n = modulus.degree()
        if n < 2:
            raise ValueError("the degree must be at least 2")

        self._modulus = modulus
        self._degree = n
        self._card = p**n
        self._kwargs = {}

        self._gen_pari = pari(modulus).ffgen()
        self._zero_element = self.element_class(self, 0)
        self._one_element = self.element_class(self, 1)
        self._gen = self.element_class(self, self._gen_pari)
Example #51
0
    def _call_(self, v):
        r"""
        EXAMPLES::

            sage: L.<b> = NumberField(x^4 + 3*x^2 + 1)
            sage: K = L.relativize(L.subfields(2)[0][1], 'a')
            sage: a0 = K.gen(); b0 = K.base_field().gen()
            sage: V, fr, to = K.relative_vector_space()
            sage: fr(to(a0 + 2*b0)), fr(V([0, 1])), fr(V([b0, 2*b0])) # indirect doctest
            (a + 2*b0, a, 2*b0*a + b0)
        """
        K = self.codomain()
        B = K.base_field().absolute_field('a')
        # Convert v to a PARI polynomial in x with coefficients that
        # are polynomials in y.
        _, to_B = B.structure()
        h = pari([to_B(a).__pari__('y') for a in v]).Polrev()
        # Rewrite the polynomial in terms of an absolute generator for
        # the relative number field.
        g = K._pari_rnfeq()._eltreltoabs(h)
        return K._element_class(K, g)
Example #52
0
File: maps.py Project: yjjcc/sage
    def _call_(self, v):
        r"""
        EXAMPLES::

            sage: L.<b> = NumberField(x^4 + 3*x^2 + 1)
            sage: K = L.relativize(L.subfields(2)[0][1], 'a')
            sage: a0 = K.gen(); b0 = K.base_field().gen()
            sage: V, fr, to = K.relative_vector_space()
            sage: fr(to(a0 + 2*b0)), fr(V([0, 1])), fr(V([b0, 2*b0])) # indirect doctest
            (a + 2*b0, a, 2*b0*a + b0)
        """
        K = self.codomain()
        B = K.base_field().absolute_field('a')
        # Convert v to a PARI polynomial in x with coefficients that
        # are polynomials in y.
        _, to_B = B.structure()
        h = pari([to_B(a).__pari__('y') for a in v]).Polrev()
        # Rewrite the polynomial in terms of an absolute generator for
        # the relative number field.
        g = K._pari_rnfeq()._eltreltoabs(h)
        return K._element_class(K, g)
Example #53
0
def exp_int(t):
    r"""
    The exponential integral `\int_t^\infty e^{-x}/x dx` (t
    belongs to RR).  This function is deprecated - please use
    ``Ei`` or ``exponential_integral_1`` as needed instead.

    EXAMPLES::
        
        sage: exp_int(6)
        doctest:...: DeprecationWarning: The method exp_int() is deprecated. Use -Ei(-x) or exponential_integral_1(x) as needed instead.
        0.000360082452162659
    """
    from sage.misc.misc import deprecation
    deprecation("The method exp_int() is deprecated. Use -Ei(-x) or exponential_integral_1(x) as needed instead.")
    try:
        return t.eint1()
    except AttributeError:
        from sage.libs.pari.all import pari
        try:
            return pari(t).eint1()
        except:
            raise NotImplementedError
Example #54
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.

        EXAMPLES::

            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

        TESTS:

        Number fields defined by non-monic and non-integral
        polynomials are supported (:trac:`252`)::

            sage: R.<x> = QQ[]
            sage: f = 7/9*x^3 + 7/3*x^2 - 56*x + 123
            sage: K.<a> = NumberField(f)
            sage: G = K.galois_group()
            sage: G[1].as_hom()
            Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
              Defn: a |--> -7/15*a^2 - 18/5*a + 96/5
            sage: prod(x - sigma(a) for sigma in G) == f.monic()
            True
        """
        G = self.parent()
        L = G.splitting_field()
        # First compute the image of the standard generator of the
        # PARI number field.
        a = G._pari_data.galoispermtopol(pari(self.domain()).Vecsmall())
        # Now convert this to a conjugate of the standard generator of
        # the Sage number field.
        P = L._pari_absolute_structure()[1].lift()
        a = L(P(a.Mod(L.pari_polynomial('y'))))
        return L.hom(a, L)
Example #55
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.

        EXAMPLES::

            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 with w = 2.645751311064591?*I
              Defn: w |--> -w

        TESTS:

        Number fields defined by non-monic and non-integral
        polynomials are supported (:trac:`252`)::

            sage: R.<x> = QQ[]
            sage: f = 7/9*x^3 + 7/3*x^2 - 56*x + 123
            sage: K.<a> = NumberField(f)
            sage: G = K.galois_group()
            sage: G[1].as_hom()
            Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
              Defn: a |--> -7/15*a^2 - 18/5*a + 96/5
            sage: prod(x - sigma(a) for sigma in G) == f.monic()
            True
        """
        G = self.parent()
        L = G.splitting_field()
        # First compute the image of the standard generator of the
        # PARI number field.
        a = G._pari_data.galoispermtopol(pari(self.domain()).Vecsmall())
        # Now convert this to a conjugate of the standard generator of
        # the Sage number field.
        P = L._pari_absolute_structure()[1].lift()
        a = L(P(a.Mod(L.pari_polynomial('y'))))
        return L.hom(a, L)
Example #56
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).

        EXAMPLES::

            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.domain()).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)
Example #57
0
def pari(x):
    """
    Return the PARI object constructed from a Sage/Python object.

    For Sage types, this uses the `_pari_()` method on the object if
    possible and otherwise it uses the string representation.

    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::

        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 96 bits on 32-bit systems and 128 bits on
    64-bit systems::

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

    But we can change this precision::

        sage: pari.set_real_precision(35)  # precision in decimal digits
        15
        sage: a = pari('1.2'); a, a.type(), a.precision()
        (1.2000000000000000000000000000000000, 't_REAL', 6)  # 32-bit
        (1.2000000000000000000000000000000000, 't_REAL', 4)  # 64-bit

    Set the precision to 15 digits for the remaining tests::

        sage: pari.set_real_precision(15)
        35

    Conversion from matrices is supported, but not from vectors;
    use lists or tuples 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: pari(v)
        Traceback (most recent call last):
        ...
        PariError: syntax error, unexpected ')', expecting )-> or ','
        sage: b = pari(list(v)); b,b.type()
        ([1.20000000000000, 3.40000000000000, 5.60000000000000], 't_VEC')
        sage: b = pari(tuple(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, 0.461163111024285, -2.16843016298270; 1, -1.72108416091916, 0.581029111014503], [1, 1, 2; 1, 0, -2; 1, -2, 1], [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, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]]

    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'>

    TESTS::

        sage: pari(None)
        Traceback (most recent call last):
        ...
        ValueError: Cannot convert None to pari
    """
    from sage.libs.pari.all import pari
    return pari(x)
    def _element_constructor_(self, x):
        r"""
        Coerce ``x`` into the finite field.
        
        INPUT:

        - ``x`` -- object

        OUTPUT:

        If possible, makes a finite field element from ``x``.

        EXAMPLES::

            sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
            sage: k = FiniteField_ext_pari(3^4, 'a')
            sage: b = k(5) # indirect doctest
            sage: b.parent()
            Finite Field in a of size 3^4
            sage: a = k.gen()
            sage: k(a + 2)
            a + 2

        Univariate polynomials coerce into finite fields by evaluating
        the polynomial at the field's generator::

            sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
            sage: R.<x> = QQ[]
            sage: k, a = FiniteField_ext_pari(5^2, 'a').objgen()
            sage: k(R(2/3))
            4
            sage: k(x^2)
            a + 3
            sage: R.<x> = GF(5)[]
            sage: k(x^3-2*x+1)
            2*a + 4

            sage: x = polygen(QQ)
            sage: k(x^25)
            a

            sage: Q, q = FiniteField_ext_pari(5^7, 'q').objgen()
            sage: L = GF(5)
            sage: LL.<xx> = L[]
            sage: Q(xx^2 + 2*xx + 4)
            q^2 + 2*q + 4

        Multivariate polynomials only coerce if constant::

            sage: R = k['x,y,z']; R
            Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 5^2
            sage: k(R(2))
            2
            sage: R = QQ['x,y,z']
            sage: k(R(1/5))
            Traceback (most recent call last):
            ...
            TypeError: unable to coerce

        Gap elements can also be coerced into finite fields::

            sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
            sage: F = FiniteField_ext_pari(8, 'a')
            sage: a = F.multiplicative_generator(); a
            a
            sage: b = gap(a^3); b
            Z(2^3)^3
            sage: F(b)
            a + 1
            sage: a^3
            a + 1

            sage: a = GF(13)(gap('0*Z(13)')); a
            0
            sage: a.parent()
            Finite Field of size 13
            
            sage: F = GF(16, 'a')
            sage: F(gap('Z(16)^3'))
            a^3
            sage: F(gap('Z(16)^2'))
            a^2

        You can also call a finite extension field with a string 
        to produce an element of that field, like this::

            sage: k = GF(2^8, 'a')
            sage: k('a^200')
            a^4 + a^3 + a^2
            
        This is especially useful for fast conversions from Singular etc.
        to ``FiniteField_ext_pariElements``.

        AUTHORS:

        - David Joyner (2005-11)
        - Martin Albrecht (2006-01-23)
        - Martin Albrecht (2006-03-06): added coercion from string
        """
        if isinstance(x, element_ext_pari.FiniteField_ext_pariElement):
            if x.parent() is self:
                return x
            elif x.parent() == self:
                # canonically isomorphic finite fields
                return element_ext_pari.FiniteField_ext_pariElement(self, x)
            else:
                # This is where we *would* do coercion from one finite field to another...
                raise TypeError, "no coercion defined"

        elif sage.interfaces.gap.is_GapElement(x):
            from sage.interfaces.gap import gfq_gap_to_sage
            try:
                return gfq_gap_to_sage(x, self)
            except (ValueError, IndexError, TypeError):
                raise TypeError, "no coercion defined"
            
        if isinstance(x, (int, long, integer.Integer, rational.Rational,
                          pari.pari_gen, list)):
            
            return element_ext_pari.FiniteField_ext_pariElement(self, x)

        elif isinstance(x, multi_polynomial_element.MPolynomial):
            if x.is_constant():
                return self(x.constant_coefficient())
            else:
                raise TypeError, "no coercion defined"

        elif isinstance(x, polynomial_element.Polynomial):
            if x.is_constant():
                return self(x.constant_coefficient())
            else:
                return x.change_ring(self)(self.gen())

        elif isinstance(x, str):
            x = x.replace(self.variable_name(),'a')
            x = pari.pari(x)
            t = x.type()
            if t == 't_POL':
                if (x.variable() == 'a' \
                    and x.polcoeff(0).type()[2] == 'I'): #t_INT and t_INTMOD
                    return self(x)
            if t[2] == 'I': #t_INT and t_INTMOD
                return self(x)
            raise TypeError, "string element does not match this finite field"
            
        try:
            if x.parent() == self.vector_space():
                x = pari.pari('+'.join(['%s*a^%s'%(x[i], i) for i in range(self.degree())]))
                return element_ext_pari.FiniteField_ext_pariElement(self, x)
        except AttributeError:
            pass
        try:
            return element_ext_pari.FiniteField_ext_pariElement(self, integer.Integer(x))
        except TypeError, msg:
            raise TypeError, "%s\nno coercion defined"%msg
    def __init__(self, q, name, modulus=None):
        """
        Create finite field of order `q` with variable printed as name.
            
        EXAMPLES::

            sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
            sage: k = FiniteField_ext_pari(9, 'a'); k
            Finite Field in a of size 3^2
        """
        if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import()
        from constructor import FiniteField as GF
        q = integer.Integer(q)
        if q < 2:
            raise ArithmeticError, "q must be a prime power"
        from sage.structure.proof.all import arithmetic
        proof = arithmetic()
        if proof:
            F = q.factor()
        else:
            from sage.rings.arith import is_pseudoprime_small_power
            F = is_pseudoprime_small_power(q, get_data=True)
        if len(F) != 1:
            raise ArithmeticError, "q must be a prime power"

        if F[0][1] > 1:
            base_ring = GF(F[0][0])
        else:
            raise ValueError, "The size of the finite field must not be prime."
            #base_ring = self
            
        FiniteField_generic.__init__(self, base_ring, name, normalize=True)

        self._kwargs = {}
        self.__char = F[0][0]
        self.__pari_one = pari.pari(1).Mod(self.__char)
        self.__degree = integer.Integer(F[0][1])
        self.__order = q
        self.__is_field = True

        if modulus is None or modulus == "default":
            from constructor import exists_conway_polynomial
            if exists_conway_polynomial(self.__char, self.__degree):
                modulus = "conway"
            else:
                modulus = "random"

        if isinstance(modulus,str):
            if modulus == "conway":
                from constructor import conway_polynomial
                modulus = conway_polynomial(self.__char, self.__degree)
            elif modulus == "random":
                # The following is fast/deterministic, but has serious problems since
                # it crashes on 64-bit machines, and I can't figure out why:
                #     self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name())
                # So instead we iterate through random polys until we find an irreducible one.

                R = GF(self.__char)['x']
                while True:
                    modulus = R.random_element(self.__degree)
                    modulus = modulus.monic()
                    if modulus.degree() == self.__degree and modulus.is_irreducible():
                        break
            else:
                raise ValueError("Modulus parameter not understood")

        elif isinstance(modulus, (list, tuple)):
            modulus = GF(self.__char)['x'](modulus)
        elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus):
            if modulus.parent() is not base_ring:
                modulus = modulus.change_ring(base_ring)
        else:
            raise ValueError("Modulus parameter not understood")

        self.__modulus = modulus
        f = pari.pari(str(modulus))
        self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one
        self.__gen = element_ext_pari.FiniteField_ext_pariElement(self, pari.pari('a'))

        self._zero_element = self._element_constructor_(0)
        self._one_element = self._element_constructor_(1)