Ejemplo n.º 1
0
def mypushout(X, Y):
    if X.has_coerce_map_from(Y):
        return X
    elif Y.has_coerce_map_from(X):
        return Y
    else:
        Z = pushout(X, Y)
        assert (is_NumberField(Z) if is_NumberField(X) and is_NumberField(Y)
                                  else True)
        return Z
Ejemplo n.º 2
0
 def extend_scalars(self, *pts):
     r"""
     Extend the ground field so that the new field contains pts.
     """
     Dops = self.parent()
     Pols = Dops.base_ring()
     Scalars = Pols.base_ring()
     if all(Scalars.has_coerce_map_from(pt.parent()) for pt in pts):
         return (self, ) + pts
     gen = Scalars.gen()
     try:
         # Largely redundant with the other branch, but may do a better job
         # in some cases, e.g. pushout(QQ, QQ(α)), where as_enf_elts() would
         # invent new generator names.
         NF0 = coercion_model.common_parent(Scalars, *pts)
         if not is_NumberField(NF0):
             raise CoercionException
         NF, hom = utilities.good_number_field(NF0)
         gen1 = hom(NF0.coerce(gen))
         pts1 = tuple(hom(NF0.coerce(pt)) for pt in pts)
     except (CoercionException, TypeError):
         NF, val1 = as_embedded_number_field_elements((gen, ) + pts)
         gen1, pts1 = val1[0], tuple(val1[1:])
     hom = Scalars.hom([gen1], codomain=NF)
     Dops1 = OreAlgebra(Pols.change_ring(NF), (Dops.variable_name(), {}, {
         Pols.gen(): Pols.one()
     }))
     dop1 = Dops1([pol.map_coefficients(hom) for pol in self])
     dop1 = PlainDifferentialOperator(dop1)
     assert dop1.base_ring().base_ring() is NF
     return (dop1, ) + pts1
Ejemplo n.º 3
0
    def _normalize_number_field_data(self, R):
        r"""
        Helper method which returns the defining data of the number field
        ``R``.

        EXAMPLES::

            sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone
            sage: R.<x> = QQ[]
            sage: K = R.quo(x^2 + 1)
            sage: pAdicValuation._normalize_number_field_data(K)
            (Rational Field,
             Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1,
             x^2 + 1)

        """
        from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
        from sage.rings.number_field.number_field import is_NumberField
        from sage.rings.fraction_field import is_FractionField
        if is_NumberField(R.fraction_field()):
            L = R.fraction_field()
            G = L.relative_polynomial()
            K = L.base_ring()
        elif is_PolynomialQuotientRing(R):
            from sage.categories.all import NumberFields
            if R.base_ring().fraction_field() not in NumberFields():
                raise NotImplementedError("can not normalize quotients over %r"%(R.base_ring(),))
            L = R.fraction_field()
            K = R.base_ring().fraction_field()
            G = R.modulus().change_ring(K)
        else:
            raise NotImplementedError("can not normalize %r"%(R,))

        return K, L, G
Ejemplo n.º 4
0
    def create_key_and_extra_args(self, R, prime=None, approximants=None):
        r"""
        Create a unique key identifying the valuation of ``R`` with respect to
        ``prime``.

        EXAMPLES::

            sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone
            sage: pAdicValuation(QQ, 2) # indirect doctest
            2-adic valuation

        """
        from sage.rings.all import ZZ, QQ
        from sage.rings.padics.padic_generic import pAdicGeneric
        from sage.rings.number_field.number_field import is_NumberField
        from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing

        if R.characteristic() != 0:
            # We do not support equal characteristic yet
            raise ValueError("R must be a ring of characteristic zero.")

        if R is ZZ or R is QQ:
            return self.create_key_for_integers(R, prime), {}
        elif isinstance(R, pAdicGeneric):
            return self.create_key_for_local_ring(R, prime), {}
        elif is_NumberField(R.fraction_field()) or is_PolynomialQuotientRing(R):
            return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants)
        else:
            raise NotImplementedError("p-adic valuations not implemented for %r"%(R,))
Ejemplo n.º 5
0
    def _normalize_number_field_data(self, R):
        r"""
        Helper method which returns the defining data of the number field
        ``R``.

        EXAMPLES::

            sage: R.<x> = QQ[]
            sage: K = R.quo(x^2 + 1)
            sage: valuations.pAdicValuation._normalize_number_field_data(K)
            (Rational Field,
             Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1,
             x^2 + 1)

        """
        from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
        from sage.rings.number_field.number_field import is_NumberField
        from sage.rings.fraction_field import is_FractionField
        if is_NumberField(R.fraction_field()):
            L = R.fraction_field()
            G = L.relative_polynomial()
            K = L.base_ring()
        elif is_PolynomialQuotientRing(R):
            from sage.categories.all import NumberFields
            if R.base_ring().fraction_field() not in NumberFields():
                raise NotImplementedError("can not normalize quotients over %r"%(R.base_ring(),))
            L = R.fraction_field()
            K = R.base_ring().fraction_field()
            G = R.modulus().change_ring(K)
        else:
            raise NotImplementedError("can not normalize %r"%(R,))

        return K, L, G
Ejemplo n.º 6
0
    def create_key_and_extra_args(self, R, prime=None, approximants=None):
        r"""
        Create a unique key identifying the valuation of ``R`` with respect to
        ``prime``.

        EXAMPLES::

            sage: QQ.valuation(2) # indirect doctest
            2-adic valuation

        """
        from sage.rings.all import ZZ, QQ
        from sage.rings.padics.padic_generic import pAdicGeneric
        from sage.rings.number_field.number_field import is_NumberField
        from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing

        if R.characteristic() != 0:
            # We do not support equal characteristic yet
            raise ValueError("R must be a ring of characteristic zero.")

        if R is ZZ or R is QQ:
            return self.create_key_for_integers(R, prime), {}
        elif isinstance(R, pAdicGeneric):
            return self.create_key_for_local_ring(R, prime), {}
        elif is_NumberField(R.fraction_field()) or is_PolynomialQuotientRing(R):
            return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants)
        else:
            raise NotImplementedError("p-adic valuations not implemented for %r"%(R,))
Ejemplo n.º 7
0
    def extensions(self, ring):
        r"""
        Return the extensions of this valuation to ``ring``.

        EXAMPLES::

            sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone
            sage: v = pAdicValuation(ZZ, 2)
            sage: v.extensions(GaussianIntegers())
            [2-adic valuation]

        TESTS::

            sage: R.<a> = QQ[]
            sage: L.<a> = QQ.extension(x^3 - 2)
            sage: R.<b> = L[]
            sage: M.<b> = L.extension(b^2 + 2*b + a)
            sage: pAdicValuation(M, 2)
            2-adic valuation

        Check that we can extend to a field written as a quotient::

            sage: R.<x> = QQ[]
            sage: K.<a> = QQ.extension(x^2 + 1)
            sage: R.<y> = K[]
            sage: L.<b> = R.quo(x^2 + a)
            sage: pAdicValuation(QQ, 2).extensions(L)
            [2-adic valuation]

        """
        if self.domain() is ring:
            return [self]
        domain_fraction_field = _fraction_field(self.domain())
        if domain_fraction_field is not self.domain():
            if domain_fraction_field.is_subring(ring):
                return pAdicValuation(domain_fraction_field, self).extensions(ring)
        if self.domain().is_subring(ring):
            from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
            if is_PolynomialQuotientRing(ring):
                if is_PolynomialQuotientRing(self.domain()):
                    if self.domain().modulus() == ring.modulus():
                        base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field()))
                        return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions]
                if ring.base_ring() is self.domain():
                    from sage.categories.all import IntegralDomains
                    if ring in IntegralDomains():
                        return self._extensions_to_quotient(ring)
                else:
                    return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
            from sage.rings.number_field.number_field import is_NumberField
            if is_NumberField(ring.fraction_field()):
                if ring.base_ring().fraction_field() is self.domain().fraction_field():
                    from valuation_space import DiscretePseudoValuationSpace
                    parent = DiscretePseudoValuationSpace(ring)
                    approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=True)
                    return [pAdicValuation(ring, approximant, approximants) for approximant in approximants]
                if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()):
                    return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
        return super(pAdicValuation_base, self).extensions(ring)
Ejemplo n.º 8
0
def residue_field(field, uniformiser):
    """
    Given a field, and a prime in its ring of integers, return the corresponding residue field.
    """
    R = field.ring_of_integers()
    I = R.ideal(uniformiser)
    if not field == QQ and is_NumberField(field):
        return field.residue_field(uniformiser)
    else:
        return R.quotient(I)
    def is_irred_rep(self, image, n, force=False):
        """
        Returns `True` if the map generated by mapping the generators to the matrices defined in
        `image` is an `n`-dimensional irreducible representation of `self`, and `False` otherwise.
        Like above, the entries of `image` must be `n`-by-`n` matrices with entries in the
        algebraic closure of the base field of `self`. Its length must match the number of
        generators of `self.`

        Use `force=True` if the function does not recognize the base field as computable, but the
        field is computable.
        """
        if (not force and self.base_field() not in NumberFields
                and self.base_field() not in FiniteFields):
            raise TypeError(
                'Base field must be computable. If %s is computable' %
                self.base_field() + ' then use force=True to bypass this.')

        if n not in ZZ or n < 1:
            raise ValueError('Dimension must be a positive integer.')

        if not self.is_rep(image, n): return False

        from sage.matrix.all import Matrix
        from sage.rings.number_field.number_field import is_NumberField
        import math

        M = MatrixSpace(self.base_field().algebraic_closure(), n, sparse=True)
        image = [M(image[i]).list() for i in range(len(image))]

        if n <= 6 and is_NumberField(self.base_field()): p = 2 * n
        else:
            p = int(
                math.floor(n *
                           math.sqrt(2 * n**2 / float(n - 1) + 1 / float(4)) +
                           n / float(2) - 3))

        prod_set = list(self._create_prod_set(image, n, p))
        prod_set.append(M.one())
        vector = [mat.list() for mat in prod_set]
        return 0 not in Matrix(vector).echelon_form().diagonal()
Ejemplo n.º 10
0
    def create_object(self, version, key, **extra_args):
        r"""
        Create a `p`-adic valuation from ``key``.

        EXAMPLES::

            sage: ZZ.valuation(5) # indirect doctest
            5-adic valuation

        """
        from sage.rings.integer_ring import ZZ
        from sage.rings.rational_field import QQ
        from sage.rings.padics.padic_generic import pAdicGeneric
        from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
        from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
        from sage.rings.number_field.number_field import is_NumberField
        R = key[0]
        parent = DiscretePseudoValuationSpace(R)
        if isinstance(R, pAdicGeneric):
            assert (len(key) == 1)
            return parent.__make_element_class__(pAdicValuation_padic)(parent)
        elif R is ZZ or R is QQ:
            prime = key[1]
            assert (len(key) == 2)
            return parent.__make_element_class__(pAdicValuation_int)(parent,
                                                                     prime)
        else:
            v = key[1]
            approximants = extra_args['approximants']
            parent = DiscretePseudoValuationSpace(R)
            K = R.fraction_field()
            if is_NumberField(K):
                G = K.relative_polynomial()
            elif is_PolynomialQuotientRing(R):
                G = R.modulus()
            else:
                raise NotImplementedError
            return parent.__make_element_class__(pAdicFromLimitValuation)(
                parent, v, G.change_ring(R.base_ring()), approximants)
Ejemplo n.º 11
0
def field_format(field):
    """Print a nice representation of the given field object. This works
    correctly for number fields, but for fraction fields of polynomial
    rings we just pretend the base field are the complex numbers (for
    now)."""
    # print("debug field = {0}".format(field))
    if field == QQ:
        return ll("\\Q")
    elif is_NumberField(field):
        minpoly = field.defining_polynomial()
        g, = field.gens()
        # G, = minpoly.parent().gens()
        return (ll("K = \\Q(", g, ")") + ", where " +
                ll(g) + " has minimal polynomial " + ll(minpoly))
    elif is_FractionField(field):
        ring = field.ring_of_integers()
        if is_PolynomialRing(ring):
            return ll("\\C(", ring.gens()[0], ")")
        else:
            print("debug ring =  {0}".format(ring))
            raise UnknownField()
    else:
        raise UnknownField()
Ejemplo n.º 12
0
    def create_object(self, version, key, **kwds):
        """
        Create an object from a ``UniqueFactory`` key.

        EXAMPLES::

            sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2)))
            sage: type(E)
            <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>

        .. NOTE::

            Keyword arguments are currently only passed to the
            constructor for elliptic curves over `\\QQ`; elliptic
            curves over other fields do not support them.

        """
        R, x = key

        if R is rings.QQ:
            from .ell_rational_field import EllipticCurve_rational_field
            return EllipticCurve_rational_field(x, **kwds)
        elif is_NumberField(R):
            from .ell_number_field import EllipticCurve_number_field
            return EllipticCurve_number_field(R, x)
        elif rings.is_pAdicField(R):
            from .ell_padic_field import EllipticCurve_padic_field
            return EllipticCurve_padic_field(R, x)
        elif is_FiniteField(R) or (is_IntegerModRing(R)
                                   and R.characteristic().is_prime()):
            from .ell_finite_field import EllipticCurve_finite_field
            return EllipticCurve_finite_field(R, x)
        elif R in _Fields:
            from .ell_field import EllipticCurve_field
            return EllipticCurve_field(R, x)
        from .ell_generic import EllipticCurve_generic
        return EllipticCurve_generic(R, x)
Ejemplo n.º 13
0
    def create_object(self, version, key, **extra_args):
        r"""
        Create a `p`-adic valuation from ``key``.

        EXAMPLES::

            sage: ZZ.valuation(5) # indirect doctest
            5-adic valuation

        """
        from sage.rings.all import ZZ, QQ
        from sage.rings.padics.padic_generic import pAdicGeneric
        from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
        from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
        from sage.rings.number_field.number_field import is_NumberField
        R = key[0]
        parent = DiscretePseudoValuationSpace(R)
        if isinstance(R, pAdicGeneric):
            assert(len(key)==1)
            return parent.__make_element_class__(pAdicValuation_padic)(parent)
        elif R is ZZ or R is QQ:
            prime = key[1]
            assert(len(key)==2)
            return parent.__make_element_class__(pAdicValuation_int)(parent, prime)
        else:
            v = key[1]
            approximants = extra_args['approximants']
            parent = DiscretePseudoValuationSpace(R)
            K = R.fraction_field()
            if is_NumberField(K):
                G = K.relative_polynomial()
            elif is_PolynomialQuotientRing(R):
                G = R.modulus()
            else:
                raise NotImplementedError
            return parent.__make_element_class__(pAdicFromLimitValuation)(parent, v, G.change_ring(R.base_ring()), approximants)
Ejemplo n.º 14
0
    def create_object(self, version, key, **kwds):
        """
        Create an object from a ``UniqueFactory`` key.

        EXAMPLES::

            sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2)))
            sage: type(E)
            <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>

        .. NOTE::

            Keyword arguments are currently only passed to the
            constructor for elliptic curves over `\\QQ`; elliptic
            curves over other fields do not support them.

        """
        R, x = key

        if R is rings.QQ:
            from ell_rational_field import EllipticCurve_rational_field
            return EllipticCurve_rational_field(x, **kwds)
        elif is_NumberField(R):
            from ell_number_field import EllipticCurve_number_field
            return EllipticCurve_number_field(R, x)
        elif rings.is_pAdicField(R):
            from ell_padic_field import EllipticCurve_padic_field
            return EllipticCurve_padic_field(R, x)
        elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()):
            from ell_finite_field import EllipticCurve_finite_field
            return EllipticCurve_finite_field(R, x)
        elif R in _Fields:
            from ell_field import EllipticCurve_field
            return EllipticCurve_field(R, x)
        from ell_generic import EllipticCurve_generic
        return EllipticCurve_generic(R, x)
Ejemplo n.º 15
0
def PolynomialRing(base, var):
    if is_NumberField(base) and base is not QQ:
        return polyring.PolynomialRing_field(
            base, var, element_class=polyelt.Polynomial_generic_dense)
    else:
        return polyringconstr.PolynomialRing(base, var)
Ejemplo n.º 16
0
def check_prime(K,P):
    r"""
    Function to check that `P` determines a prime of `K`, and return that ideal.

    INPUT:

    - ``K`` -- a number field (including `\QQ`).

    - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``.

    OUTPUT:

    - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`.

    - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`.

    .. note::

       If `P` is not a prime and does not generate a prime, a TypeError is raised.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime
        sage: check_prime(QQ,3)
        3
        sage: check_prime(QQ,ZZ.ideal(31))
        31
        sage: K.<a>=NumberField(x^2-5)
        sage: check_prime(K,a)
        Fractional ideal (a)
        sage: check_prime(K,a+1)
        Fractional ideal (a + 1)
        sage: [check_prime(K,P) for P in K.primes_above(31)]
        [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)]
    """
    if K is QQ:
        if isinstance(P, (int,long,Integer)):
            P = Integer(P)
            if P.is_prime():
                return P
            else:
                raise TypeError("%s is not prime"%P)
        else:
            if is_Ideal(P) and P.base_ring() is ZZ and P.is_prime():
                return P.gen()
        raise TypeError("%s is not a prime ideal of %s"%(P,ZZ))

    if not is_NumberField(K):
        raise TypeError("%s is not a number field"%K)

    if is_NumberFieldFractionalIdeal(P):
        if P.is_prime():
            return P
        else:
            raise TypeError("%s is not a prime ideal of %s"%(P,K))

    if is_NumberFieldElement(P):
        if P in K:
            P = K.ideal(P)
        else:
            raise TypeError("%s is not an element of %s"%(P,K))
        if P.is_prime():
            return P
        else:
            raise TypeError("%s is not a prime ideal of %s"%(P,K))

    raise TypeError("%s is not a valid prime of %s"%(P,K))
Ejemplo n.º 17
0
def Conic(base_field, F=None, names=None, unique=True):
    r"""
    Return the plane projective conic curve defined by ``F``
    over ``base_field``.

    The input form ``Conic(F, names=None)`` is also accepted,
    in which case the fraction field of the base ring of ``F``
    is used as base field.

    INPUT:

    - ``base_field`` -- The base field of the conic.

    - ``names`` -- a list, tuple, or comma separated string
      of three variable names specifying the names
      of the coordinate functions of the ambient
      space `\Bold{P}^3`. If not specified or read
      off from ``F``, then this defaults to ``'x,y,z'``.

    - ``F`` -- a polynomial, list, matrix, ternary quadratic form,
      or list or tuple of 5 points in the plane.

                   If ``F`` is a polynomial or quadratic form,
                   then the output is the curve in the projective plane
                   defined by ``F = 0``.

                   If ``F`` is a polynomial, then it must be a polynomial
                   of degree at most 2 in 2 variables, or a homogeneous
                   polynomial in of degree 2 in 3 variables.

                   If ``F`` is a matrix, then the output is the zero locus
                   of `(x,y,z) F (x,y,z)^t`.

                   If ``F`` is a list of coefficients, then it has
                   length 3 or 6 and gives the coefficients of
                   the monomials `x^2, y^2, z^2` or all 6 monomials
                   `x^2, xy, xz, y^2, yz, z^2` in lexicographic order.

                   If ``F`` is a list of 5 points in the plane, then the output
                   is a conic through those points.

    - ``unique`` -- Used only if ``F`` is a list of points in the plane.
      If the conic through the points is not unique, then
      raise ``ValueError`` if and only if ``unique`` is True

    OUTPUT:

    A plane projective conic curve defined by ``F`` over a field.

    EXAMPLES:

    Conic curves given by polynomials ::

        sage: X,Y,Z = QQ['X,Y,Z'].gens()
        sage: Conic(X^2 - X*Y + Y^2 - Z^2)
        Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2
        sage: x,y = GF(7)['x,y'].gens()
        sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W')
        Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2

    Conic curves given by matrices ::

        sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z')
        Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2

        sage: x,y,z = GF(11)['x,y,z'].gens()
        sage: C = Conic(x^2+y^2-2*z^2); C
        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2
        sage: Conic(C.symmetric_matrix(), 'x,y,z')
        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2

    Conics given by coefficients ::

        sage: Conic(QQ, [1,2,3])
        Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2
        sage: Conic(GF(7), [1,2,3,4,5,6], 'X')
        Projective Conic Curve over Finite Field of size 7 defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2

    The conic through a set of points ::

        sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C
        Projective Conic Curve over Rational Field defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2
        sage: C.rational_point()
        (10 : 2 : 1)
        sage: C.point([3,4])
        (3 : 4 : 1)

        sage: a=AffineSpace(GF(13),2)
        sage: Conic([a([x,x^2]) for x in range(5)])
        Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z
    """
    if not (is_IntegralDomain(base_field) or base_field == None):
        if names is None:
            names = F
        F = base_field
        base_field = None
    if isinstance(F, (list,tuple)):
        if len(F) == 1:
            return Conic(base_field, F[0], names)
        if names == None:
            names = 'x,y,z'
        if len(F) == 5:
            L=[]
            for f in F:
                if isinstance(f, SchemeMorphism_point_affine):
                    C = Sequence(f, universe = base_field)
                    if len(C) != 2:
                        raise TypeError, "points in F (=%s) must be planar"%F
                    C.append(1)
                elif isinstance(f, SchemeMorphism_point_projective_field):
                    C = Sequence(f, universe = base_field)
                elif isinstance(f, (list, tuple)):
                    C = Sequence(f, universe = base_field)
                    if len(C) == 2:
                        C.append(1)
                else:
                    raise TypeError, "F (=%s) must be a sequence of planar " \
                                      "points" % F
                if len(C) != 3:
                    raise TypeError, "points in F (=%s) must be planar" % F
                P = C.universe()
                if not is_IntegralDomain(P):
                    raise TypeError, "coordinates of points in F (=%s) must " \
                                     "be in an integral domain" % F
                L.append(Sequence([C[0]**2, C[0]*C[1], C[0]*C[2], C[1]**2,
                                   C[1]*C[2], C[2]**2], P.fraction_field()))
            M=Matrix(L)
            if unique and M.rank() != 5:
                raise ValueError, "points in F (=%s) do not define a unique " \
                                   "conic" % F
            con = Conic(base_field, Sequence(M.right_kernel().gen()), names)
            con.point(F[0])
            return con
        F = Sequence(F, universe = base_field)
        base_field = F.universe().fraction_field()
        temp_ring = PolynomialRing(base_field, 3, names)
        (x,y,z) = temp_ring.gens()
        if len(F) == 3:
            return Conic(F[0]*x**2 + F[1]*y**2 + F[2]*z**2)
        if len(F) == 6:
            return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \
                         F[4]*y*z + F[5]*z**2)
        raise TypeError, "F (=%s) must be a sequence of 3 or 6" \
                         "coefficients" % F
    if is_QuadraticForm(F):
        F = F.matrix()
    if is_Matrix(F) and F.is_square() and F.ncols() == 3:
        if names == None:
            names = 'x,y,z'
        temp_ring = PolynomialRing(F.base_ring(), 3, names)
        F = vector(temp_ring.gens()) * F * vector(temp_ring.gens())

    if not is_MPolynomial(F):
        raise TypeError, "F (=%s) must be a three-variable polynomial or " \
                         "a sequence of points or coefficients" % F

    if F.total_degree() != 2:
        raise TypeError, "F (=%s) must have degree 2" % F

    if base_field == None:
        base_field = F.base_ring()
    if not is_IntegralDomain(base_field):
        raise ValueError, "Base field (=%s) must be a field" % base_field
    base_field = base_field.fraction_field()
    if names == None:
        names = F.parent().variable_names()
    pol_ring = PolynomialRing(base_field, 3, names)

    if F.parent().ngens() == 2:
        (x,y,z) = pol_ring.gens()
        F = pol_ring(F(x/z,y/z)*z**2)

    if F == 0:
        raise ValueError, "F must be nonzero over base field %s" % base_field

    if F.total_degree() != 2:
        raise TypeError, "F (=%s) must have degree 2 over base field %s" % \
                          (F, base_field)

    if F.parent().ngens() == 3:
        P2 = ProjectiveSpace(2, base_field, names)
        if is_PrimeFiniteField(base_field):
            return ProjectiveConic_prime_finite_field(P2, F)
        if is_FiniteField(base_field):
            return ProjectiveConic_finite_field(P2, F)
        if is_RationalField(base_field):
            return ProjectiveConic_rational_field(P2, F)
        if is_NumberField(base_field):
            return ProjectiveConic_number_field(P2, F)
        return ProjectiveConic_field(P2, F)

    raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
Ejemplo n.º 18
0
    def extensions(self, ring):
        r"""
        Return the extensions of this valuation to ``ring``.

        EXAMPLES::

            sage: v = ZZ.valuation(2)
            sage: v.extensions(GaussianIntegers())
            [2-adic valuation]

        TESTS::

            sage: R.<a> = QQ[]
            sage: L.<a> = QQ.extension(x^3 - 2)
            sage: R.<b> = L[]
            sage: M.<b> = L.extension(b^2 + 2*b + a)
            sage: M.valuation(2)
            2-adic valuation

        Check that we can extend to a field written as a quotient::

            sage: R.<x> = QQ[]
            sage: K.<a> = QQ.extension(x^2 + 1)
            sage: R.<y> = K[]
            sage: L.<b> = R.quo(x^2 + a)
            sage: QQ.valuation(2).extensions(L)
            [2-adic valuation]

        A case where there was at some point an internal error in the
        approximants code::

            sage: R.<x> = QQ[]
            sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8)
            sage: QQ.valuation(2).extensions(L)
            [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation,
             [ 2-adic valuation, v(x) = 1/2 ]-adic valuation]

        A case where the extension was incorrect at some point::

            sage: v = QQ.valuation(2)
            sage: L.<a> = NumberField(x^2 + 2)
            sage: M.<b> = L.extension(x^2 + 1)
            sage: w = v.extension(L).extension(M)
            sage: w(w.uniformizer())
            1/4

        A case where the extensions could not be separated at some point::

            sage: v = QQ.valuation(2)
            sage: R.<x> = QQ[]
            sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68
            sage: L.<a> = QQ.extension(F)
            sage: v.extensions(L)
            [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation,
             [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation]

        """
        if self.domain() is ring:
            return [self]
        domain_fraction_field = _fraction_field(self.domain())
        if domain_fraction_field is not self.domain():
            if domain_fraction_field.is_subring(ring):
                return pAdicValuation(domain_fraction_field, self).extensions(ring)
        if self.domain().is_subring(ring):
            from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
            if is_PolynomialQuotientRing(ring):
                if is_PolynomialQuotientRing(self.domain()):
                    if self.domain().modulus() == ring.modulus():
                        base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field()))
                        return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions]
                if ring.base_ring() is self.domain():
                    from sage.categories.all import IntegralDomains
                    if ring in IntegralDomains():
                        return self._extensions_to_quotient(ring)
                elif self.domain().is_subring(ring.base_ring()):
                    return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
            from sage.rings.number_field.number_field import is_NumberField
            if is_NumberField(ring.fraction_field()):
                if ring.base_ring().fraction_field() is self.domain().fraction_field():
                    from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
                    parent = DiscretePseudoValuationSpace(ring)
                    approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True)
                    return [pAdicValuation(ring, approximant, approximants) for approximant in approximants]
                if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()):
                    return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
        return super(pAdicValuation_base, self).extensions(ring)
    def has_irred_rep(self, n, gen_set=None, restrict=None, force=False):
        """
        Returns `True` if there exists an `n`-dimensional irreducible representation of `self`,
        and `False` otherwise. Of course, this function runs `has_rep(n, restrict)` to verify
        there is a representation in the first place, and returns `False` if not.

        The argument `restrict` may be used equivalenty to its use in `has_rep()`.

        The argument `gen_set` may be set to `'PBW'` or `'pbw'`, if `self` has an algebra basis
        similar to that of a Poincaré-Birkhoff-Witt basis.

        Alternatively, an explicit generating set for the algorithm implemented by this function
        can be given, as a tuple or array of `FreeAlgebraElements`. This is only useful if the
        package cannot reduce the elements of `self`, but they can be reduced in theory.

        Use `force=True` if the function does not recognize the base field as computable, but the
        field is computable.
        """
        if (not force and self.base_field() not in NumberFields
                and self.base_field() not in FiniteFields):
            raise TypeError(
                'Base field must be computable. If %s is computable' %
                self.base_field() + ' then use force=True to bypass this.')

        if n not in ZZ or n < 1:
            raise ValueError('Dimension must be a positive integer.')

        if not self.has_rep(n, restrict): return False
        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
        from sage.groups.all import SymmetricGroup
        import math

        B = PolynomialRing(self.base_field(), (self.ngens() * n**2 + 1),
                           'x',
                           order='deglex')
        M = MatrixSpace(B, n, sparse=True)

        gen_matrix = list()
        if not isinstance(restrict, (tuple, list)):
            restrict = [None for i in range(self.ngens())]
        if len(restrict) != self.ngens():
            raise ValueError(
                'Length of restrict does not match number of generators.')
        for i in range(self.ngens()):
            ith_gen_matrix = []
            for j in range(n):
                for k in range(n):
                    if restrict[i] == 'upper' and j > k:
                        ith_gen_matrix.append(B.zero())
                    elif restrict[i] == 'lower' and j < k:
                        ith_gen_matrix.append(B.zero())
                    elif restrict[i] == 'diagonal' and j != k:
                        ith_gen_matrix.append(B.zero())
                    else:
                        ith_gen_matrix.append(B.gen(j + (j + 1) * k +
                                                    i * n**2))
            gen_matrix.append(M(ith_gen_matrix))

        relB = list()
        for i in range(self.nrels()):
            relB += self._to_matrix(self.rel(i), M, gen_matrix).list()

        Z = FreeAlgebra(ZZ, 2 * n - 2, 'Y')
        standard_poly = Z(0)
        for s in SymmetricGroup(2 * n - 2).list():
            standard_poly += s.sign() * reduce(
                lambda x, y: x * y, [Z('Y%s' % (i - 1)) for i in s.tuple()])

        if n <= 6 and is_NumberField(self.base_field()): p = 2 * n
        else:
            p = int(
                math.floor(n *
                           math.sqrt(2 * n**2 / float(n - 1) + 1 / float(4)) +
                           n / float(2) - 3))

        if isinstance(gen_set, (tuple, list)):
            try:
                gen_set = [
                    self._to_matrix(elt, M, gen_matrix) for elt in gen_set
                ]
            except (NameError, TypeError) as error:
                print(error)

        if gen_set == None:
            word_gen_set = list(self._create_rep_gen_set(n, p))
            gen_set = [
                self._to_matrix(_to_element(self, [[word, self.one()]]), M,
                                gen_matrix) for word in word_gen_set
            ]

        elif gen_set == 'pbw' or gen_set == 'PBW':
            word_gen_set = list(self._create_pbw_rep_gen_set(n, p))
            gen_set = [
                self._to_matrix(_to_element(self, [[word, self.one()]]), M,
                                gen_matrix) for word in word_gen_set
            ]

        else:
            raise TypeError('Invalid generating set.')

        ordering = [i for i in range(2 * n - 2)]
        max_ordering = [
            len(gen_set) - (2 * n - 2) + i for i in range(2 * n - 2)
        ]
        ordering.insert(0, 0)
        max_ordering.insert(0, len(gen_set))
        rep_exists = False
        z = B.gen(B.ngens() - 1)

        while ordering[0] != max_ordering[0]:
            y = gen_set[ordering[0]].trace_of_product(
                standard_poly.subs({
                    Z('Y%s' % (j - 1)): gen_set[ordering[j]]
                    for j in range(1, 2 * n - 1)
                }))
            radB_test = relB + [B(1) - z * y]
            if B.one() not in B.ideal(radB_test):
                rep_exists = True
                break
            for i in range(2 * n - 2, -1, -1):
                if i != 0 and ordering[i] != max_ordering[i]:
                    ordering[i] += 1
                    break
                elif i == 0:
                    ordering[i] += 1
                    if ordering[i] != max_ordering[i]:
                        for j in range(1, 2 * n - 1):
                            ordering[j] = j - 1

        return rep_exists
Ejemplo n.º 20
0
def check_prime(K, P):
    r"""
    Function to check that `P` determines a prime of `K`, and return that ideal.

    INPUT:

    - ``K`` -- a number field (including `\QQ`).

    - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``.

    OUTPUT:

    - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`.

    - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`.

    .. NOTE::

        If `P` is not a prime and does not generate a prime, a ``TypeError``
        is raised.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime
        sage: check_prime(QQ,3)
        3
        sage: check_prime(QQ,QQ(3))
        3
        sage: check_prime(QQ,ZZ.ideal(31))
        31
        sage: K.<a> = NumberField(x^2-5)
        sage: check_prime(K,a)
        Fractional ideal (a)
        sage: check_prime(K,a+1)
        Fractional ideal (a + 1)
        sage: [check_prime(K,P) for P in K.primes_above(31)]
        [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)]
        sage: L.<b> = NumberField(x^2+3)
        sage: check_prime(K, L.ideal(5))
        Traceback (most recent call last):
        ...
        TypeError: The ideal Fractional ideal (5) is not a prime ideal of Number Field in a with defining polynomial x^2 - 5
        sage: check_prime(K, L.ideal(b))
        Traceback (most recent call last):
        ...
        TypeError: No compatible natural embeddings found for Number Field in a with defining polynomial x^2 - 5 and Number Field in b with defining polynomial x^2 + 3
    """
    if K is QQ:
        if P in ZZ or isinstance(P, integer_types + (Integer,)):
            P = Integer(P)
            if P.is_prime():
                return P
            else:
                raise TypeError("The element %s is not prime" % (P,))
        elif P in QQ:
            raise TypeError("The element %s is not prime" % (P,))
        elif is_Ideal(P) and P.base_ring() is ZZ:
            if P.is_prime():
                return P.gen()
            else:
                raise TypeError("The ideal %s is not a prime ideal of %s" % (P, ZZ))
        else:
            raise TypeError("%s is neither an element of QQ or an ideal of %s" % (P, ZZ))

    if not is_NumberField(K):
        raise TypeError("%s is not a number field" % (K,))

    if is_NumberFieldFractionalIdeal(P) or P in K:
        # if P is an ideal, making sure it is an fractional ideal of K
        P = K.fractional_ideal(P)
        if P.is_prime():
            return P
        else:
            raise TypeError("The ideal %s is not a prime ideal of %s" % (P, K))

    raise TypeError("%s is not a valid prime of %s" % (P, K))
Ejemplo n.º 21
0
def Conic(base_field, F=None, names=None, unique=True):
    r"""
    Return the plane projective conic curve defined by ``F``
    over ``base_field``.
    
    The input form ``Conic(F, names=None)`` is also accepted,
    in which case the fraction field of the base ring of ``F``
    is used as base field.

    INPUT:
    
    - ``base_field`` -- The base field of the conic.
    
    - ``names`` -- a list, tuple, or comma separated string
      of three variable names specifying the names
      of the coordinate functions of the ambient
      space `\Bold{P}^3`. If not specified or read
      off from ``F``, then this defaults to ``'x,y,z'``.

    - ``F`` -- a polynomial, list, matrix, ternary quadratic form,
      or list or tuple of 5 points in the plane.
                   
                   If ``F`` is a polynomial or quadratic form,
                   then the output is the curve in the projective plane
                   defined by ``F = 0``.

                   If ``F`` is a polynomial, then it must be a polynomial
                   of degree at most 2 in 2 variables, or a homogeneous
                   polynomial in of degree 2 in 3 variables.
                   
                   If ``F`` is a matrix, then the output is the zero locus
                   of `(x,y,z) F (x,y,z)^t`.
    
                   If ``F`` is a list of coefficients, then it has
                   length 3 or 6 and gives the coefficients of
                   the monomials `x^2, y^2, z^2` or all 6 monomials
                   `x^2, xy, xz, y^2, yz, z^2` in lexicographic order.

                   If ``F`` is a list of 5 points in the plane, then the output
                   is a conic through those points.
      
    - ``unique`` -- Used only if ``F`` is a list of points in the plane.
      If the conic through the points is not unique, then
      raise ``ValueError`` if and only if ``unique`` is True
                    
    OUTPUT:
    
    A plane projective conic curve defined by ``F`` over a field.
    
    EXAMPLES:
    
    Conic curves given by polynomials ::

        sage: X,Y,Z = QQ['X,Y,Z'].gens()
        sage: Conic(X^2 - X*Y + Y^2 - Z^2)
        Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2
        sage: x,y = GF(7)['x,y'].gens()
        sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W')
        Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2

    Conic curves given by matrices ::

        sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z')
        Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2

        sage: x,y,z = GF(11)['x,y,z'].gens()
        sage: C = Conic(x^2+y^2-2*z^2); C
        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2
        sage: Conic(C.symmetric_matrix(), 'x,y,z')
        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2

    Conics given by coefficients ::
    
        sage: Conic(QQ, [1,2,3])
        Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2
        sage: Conic(GF(7), [1,2,3,4,5,6], 'X')
        Projective Conic Curve over Finite Field of size 7 defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2
    
    The conic through a set of points ::

        sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C
        Projective Conic Curve over Rational Field defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2
        sage: C.rational_point()
        (10 : 2 : 1)
        sage: C.point([3,4])
        (3 : 4 : 1)

        sage: a=AffineSpace(GF(13),2)
        sage: Conic([a([x,x^2]) for x in range(5)])
        Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z
    """
    if not (is_IntegralDomain(base_field) or base_field == None):
        if names is None:
            names = F
        F = base_field
        base_field = None
    if isinstance(F, (list,tuple)):
        if len(F) == 1:
            return Conic(base_field, F[0], names)
        if names == None:
            names = 'x,y,z'
        if len(F) == 5:
            L=[]
            for f in F:
                if isinstance(f, SchemeMorphism_point_affine):
                    C = Sequence(f, universe = base_field)
                    if len(C) != 2:
                        raise TypeError, "points in F (=%s) must be planar"%F
                    C.append(1)
                elif isinstance(f, SchemeMorphism_point_projective_field):
                    C = Sequence(f, universe = base_field)
                elif isinstance(f, (list, tuple)):
                    C = Sequence(f, universe = base_field)
                    if len(C) == 2:
                        C.append(1)
                else:
                    raise TypeError, "F (=%s) must be a sequence of planar " \
                                      "points" % F
                if len(C) != 3:
                    raise TypeError, "points in F (=%s) must be planar" % F
                P = C.universe()
                if not is_IntegralDomain(P):
                    raise TypeError, "coordinates of points in F (=%s) must " \
                                     "be in an integral domain" % F
                L.append(Sequence([C[0]**2, C[0]*C[1], C[0]*C[2], C[1]**2,
                                   C[1]*C[2], C[2]**2], P.fraction_field()))
            M=Matrix(L)
            if unique and M.rank() != 5:
                raise ValueError, "points in F (=%s) do not define a unique " \
                                   "conic" % F
            con = Conic(base_field, Sequence(M.right_kernel().gen()), names)
            con.point(F[0])
            return con
        F = Sequence(F, universe = base_field)
        base_field = F.universe().fraction_field()
        temp_ring = PolynomialRing(base_field, 3, names)
        (x,y,z) = temp_ring.gens()
        if len(F) == 3:
            return Conic(F[0]*x**2 + F[1]*y**2 + F[2]*z**2)
        if len(F) == 6:
            return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \
                         F[4]*y*z + F[5]*z**2)
        raise TypeError, "F (=%s) must be a sequence of 3 or 6" \
                         "coefficients" % F
    if is_QuadraticForm(F):
        F = F.matrix()
    if is_Matrix(F) and F.is_square() and F.ncols() == 3:
        if names == None:
            names = 'x,y,z'
        temp_ring = PolynomialRing(F.base_ring(), 3, names)
        F = vector(temp_ring.gens()) * F * vector(temp_ring.gens())

    if not is_MPolynomial(F):
        raise TypeError, "F (=%s) must be a three-variable polynomial or " \
                         "a sequence of points or coefficients" % F

    if F.total_degree() != 2:
        raise TypeError, "F (=%s) must have degree 2" % F

    if base_field == None:
        base_field = F.base_ring()
    if not is_IntegralDomain(base_field):
        raise ValueError, "Base field (=%s) must be a field" % base_field
    base_field = base_field.fraction_field()
    if names == None:
        names = F.parent().variable_names()
    pol_ring = PolynomialRing(base_field, 3, names)

    if F.parent().ngens() == 2:
        (x,y,z) = pol_ring.gens()
        F = pol_ring(F(x/z,y/z)*z**2)    

    if F == 0:
        raise ValueError, "F must be nonzero over base field %s" % base_field

    if F.total_degree() != 2:
        raise TypeError, "F (=%s) must have degree 2 over base field %s" % \
                          (F, base_field)

    if F.parent().ngens() == 3:
        P2 = ProjectiveSpace(2, base_field, names)
        if is_PrimeFiniteField(base_field):
            return ProjectiveConic_prime_finite_field(P2, F)
        if is_FiniteField(base_field):
            return ProjectiveConic_finite_field(P2, F)
        if is_RationalField(base_field):
            return ProjectiveConic_rational_field(P2, F)
        if is_NumberField(base_field):
            return ProjectiveConic_number_field(P2, F)
        return ProjectiveConic_field(P2, F)

    raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
Ejemplo n.º 22
0
def check_prime(K,P):
    r"""
    Function to check that `P` determines a prime of `K`, and return that ideal.

    INPUT:

    - ``K`` -- a number field (including `\QQ`).

    - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``.

    OUTPUT:

    - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`.

    - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`.

    .. note::

       If `P` is not a prime and does not generate a prime, a TypeError is raised.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime
        sage: check_prime(QQ,3)
        3
        sage: check_prime(QQ,ZZ.ideal(31))
        31
        sage: K.<a>=NumberField(x^2-5)
        sage: check_prime(K,a)
        Fractional ideal (a)
        sage: check_prime(K,a+1)
        Fractional ideal (a + 1)
        sage: [check_prime(K,P) for P in K.primes_above(31)]
        [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)]
    """
    if K is QQ:
        if isinstance(P, (int,long,Integer)):
            P = Integer(P)
            if P.is_prime():
                return P
            else:
                raise TypeError("%s is not prime"%P)
        else:
            if is_Ideal(P) and P.base_ring() is ZZ and P.is_prime():
                return P.gen()
        raise TypeError("%s is not a prime ideal of %s"%(P,ZZ))

    if not is_NumberField(K):
        raise TypeError("%s is not a number field"%K)

    if is_NumberFieldFractionalIdeal(P):
        if P.is_prime():
            return P
        else:
            raise TypeError("%s is not a prime ideal of %s"%(P,K))

    if is_NumberFieldElement(P):
        if P in K:
            P = K.ideal(P)
        else:
            raise TypeError("%s is not an element of %s"%(P,K))
        if P.is_prime():
            return P
        else:
            raise TypeError("%s is not a prime ideal of %s"%(P,K))

    raise TypeError("%s is not a valid prime of %s"%(P,K))
Ejemplo n.º 23
0
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True):
    r"""
    Construct an elliptic curve.

    In Sage, an elliptic curve is always specified by its a-invariants

    .. math::

       y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6.

    INPUT:

    There are several ways to construct an elliptic curve:

    - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given
      a-invariants. The invariants are coerced into the parent of the
      first element. If all are integers, they are coerced into the
      rational numbers.

    - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`.

    - ``EllipticCurve(label)``: Returns the elliptic curve over Q from
      the Cremona database with the given label. The label is a
      string, such as ``"11a"`` or ``"37b2"``. The letters in the
      label *must* be lower case (Cremona's new labeling).

    - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic
      curve over ``R`` with given a-invariants. Here ``R`` can be an
      arbitrary ring. Note that addition need not be defined.

    - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return
      an elliptic curve with j-invariant ``j0``.

    - ``EllipticCurve(polynomial)``: Read off the a-invariants from
      the polynomial coefficients, see
      :func:`EllipticCurve_from_Weierstrass_polynomial`.

    In each case above where the input is a list of length 2 or 5, one
    can instead give a 2 or 5-tuple instead.

    EXAMPLES:

    We illustrate creating elliptic curves::

        sage: EllipticCurve([0,0,1,-1,0])
        Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

    We create a curve from a Cremona label::

        sage: EllipticCurve('37b2')
        Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field
        sage: EllipticCurve('5077a')
        Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
        sage: EllipticCurve('389a')
        Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field

    Old Cremona labels are allowed::

        sage: EllipticCurve('2400FF')
        Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field

    Unicode labels are allowed::

        sage: EllipticCurve(u'389a')
        Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field

    We create curves over a finite field as follows::

        sage: EllipticCurve([GF(5)(0),0,1,-1,0])
        Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
        sage: EllipticCurve(GF(5), [0, 0,1,-1,0])
        Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5

    Elliptic curves over `\ZZ/N\ZZ` with `N` prime are of type
    "elliptic curve over a finite field"::

        sage: F = Zmod(101)
        sage: EllipticCurve(F, [2, 3])
        Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101
        sage: E = EllipticCurve([F(2), F(3)])
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>
        sage: E.category()
        Category of schemes over Ring of integers modulo 101

    In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite
    are of type "generic elliptic curve"::

        sage: F = Zmod(95)
        sage: EllipticCurve(F, [2, 3])
        Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95
        sage: E = EllipticCurve([F(2), F(3)])
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'>
        sage: E.category()
        Category of schemes over Ring of integers modulo 95

    The following is a curve over the complex numbers::

        sage: E = EllipticCurve(CC, [0,0,1,-1,0])
        sage: E
        Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision
        sage: E.j_invariant()
        2988.97297297297

    We can also create elliptic curves by giving the Weierstrass equation::

        sage: x, y = var('x,y')
        sage: EllipticCurve(y^2 + y ==  x^3 + x - 9)
        Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field

        sage: R.<x,y> = GF(5)[]
        sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x)
        Elliptic Curve defined by y^2 + x*y  = x^3 + x^2 + 2 over Finite Field of size 5

    We can explicitly specify the `j`-invariant::

        sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label()
        Elliptic Curve defined by y^2 = x^3 - x over Rational Field
        1728
        '32a2'

        sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant()
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5
        2

    See :trac:`6657` ::

        sage: EllipticCurve(GF(144169),j=1728)
        Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169

    By default, when a rational value of `j` is given, the constructed
    curve is a minimal twist (minimal conductor for curves with that
    `j`-invariant).  This can be changed by setting the optional
    parameter ``minimal_twist``, which is True by default, to False::


        sage: EllipticCurve(j=100)
        Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
        sage: E =EllipticCurve(j=100); E
        Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
        sage: E.conductor()
        33129800
        sage: E.j_invariant()
        100
        sage: E =EllipticCurve(j=100, minimal_twist=False); E
        Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field
        sage: E.conductor()
        298168200
        sage: E.j_invariant()
        100

    Without this option, constructing the curve could take a long time
    since both `j` and `j-1728` have to be factored to compute the
    minimal twist (see :trac:`13100`)::

       sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False)
       sage: E.j_invariant() == 2^256+1
       True

    TESTS::

        sage: R = ZZ['u', 'v']
        sage: EllipticCurve(R, [1,1])
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v
        over Integer Ring

    We create a curve and a point over QQbar (see #6879)::

        sage: E = EllipticCurve(QQbar,[0,1])
        sage: E(0)
        (0 : 1 : 0)
        sage: E.base_field()
        Algebraic Field

        sage: E = EllipticCurve(RR,[1,2]); E; E.base_field()
        Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision
        Real Field with 53 bits of precision
        sage: EllipticCurve(CC,[3,4]); E; E.base_field()
        Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision
        Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision
        Real Field with 53 bits of precision
        sage: E = EllipticCurve(QQbar,[5,6]); E; E.base_field()
        Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field
        Algebraic Field

    See :trac:`6657` ::

        sage: EllipticCurve(3,j=1728)
        Traceback (most recent call last):
        ...
        ValueError: First parameter (if present) must be a ring when j is specified

        sage: EllipticCurve(GF(5),j=3/5)
        Traceback (most recent call last):
        ...
        ValueError: First parameter must be a ring containing 3/5

    If the universe of the coefficients is a general field, the object
    constructed has type EllipticCurve_field.  Otherwise it is
    EllipticCurve_generic.  See :trac:`9816` ::

        sage: E = EllipticCurve([QQbar(1),3]); E
        Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>

        sage: E = EllipticCurve([RR(1),3]); E
        Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 over Real Field with 53 bits of precision
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>

        sage: E = EllipticCurve([i,i]); E
        Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
        sage: E.category()
        Category of schemes over Symbolic Ring
        sage: SR in Fields()
        True

        sage: F = FractionField(PolynomialRing(QQ,'t'))
        sage: t = F.gen()
        sage: E = EllipticCurve([t,0]); E
        Elliptic Curve defined by y^2 = x^3 + t*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
        sage: E.category()
        Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field

    See :trac:`12517`::

        sage: E = EllipticCurve([1..5])
        sage: EllipticCurve(E.a_invariants())
        Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field

    See :trac:`11773`::

        sage: E = EllipticCurve()
        Traceback (most recent call last):
        ...
        TypeError: invalid input to EllipticCurve constructor

    """
    import ell_generic, ell_field, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field  # here to avoid circular includes

    if j is not None:
        if not x is None:
            if is_Ring(x):
                try:
                    j = x(j)
                except (ZeroDivisionError, ValueError, TypeError):
                    raise ValueError, "First parameter must be a ring containing %s" % j
            else:
                raise ValueError, "First parameter (if present) must be a ring when j is specified"
        return EllipticCurve_from_j(j, minimal_twist)

    if x is None:
        raise TypeError, "invalid input to EllipticCurve constructor"

    if is_SymbolicEquation(x):
        x = x.lhs() - x.rhs()

    if parent(x) is SR:
        x = x._polynomial_(rings.QQ['x', 'y'])

    if is_MPolynomial(x):
        if y is None:
            return EllipticCurve_from_Weierstrass_polynomial(x)
        else:
            return EllipticCurve_from_cubic(x, y, morphism=False)

    if is_Ring(x):
        if is_RationalField(x):
            return ell_rational_field.EllipticCurve_rational_field(x, y)
        elif is_FiniteField(x) or (is_IntegerModRing(x)
                                   and x.characteristic().is_prime()):
            return ell_finite_field.EllipticCurve_finite_field(x, y)
        elif rings.is_pAdicField(x):
            return ell_padic_field.EllipticCurve_padic_field(x, y)
        elif is_NumberField(x):
            return ell_number_field.EllipticCurve_number_field(x, y)
        elif x in _Fields:
            return ell_field.EllipticCurve_field(x, y)
        return ell_generic.EllipticCurve_generic(x, y)

    if isinstance(x, unicode):
        x = str(x)

    if isinstance(x, basestring):
        return ell_rational_field.EllipticCurve_rational_field(x)

    if is_RingElement(x) and y is None:
        raise TypeError, "invalid input to EllipticCurve constructor"

    if not isinstance(x, (list, tuple)):
        raise TypeError, "invalid input to EllipticCurve constructor"

    x = Sequence(x)
    if not (len(x) in [2, 5]):
        raise ValueError, "sequence of coefficients must have length 2 or 5"
    R = x.universe()

    if isinstance(x[0], (rings.Rational, rings.Integer, int, long)):
        return ell_rational_field.EllipticCurve_rational_field(x, y)

    elif is_NumberField(R):
        return ell_number_field.EllipticCurve_number_field(x, y)

    elif rings.is_pAdicField(R):
        return ell_padic_field.EllipticCurve_padic_field(x, y)

    elif is_FiniteField(R) or (is_IntegerModRing(R)
                               and R.characteristic().is_prime()):
        return ell_finite_field.EllipticCurve_finite_field(x, y)

    elif R in _Fields:
        return ell_field.EllipticCurve_field(x, y)

    return ell_generic.EllipticCurve_generic(x, y)
Ejemplo n.º 24
0
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True):
    r"""
    Construct an elliptic curve.

    In Sage, an elliptic curve is always specified by its a-invariants

    .. math::

       y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6.

    INPUT:

    There are several ways to construct an elliptic curve:

    - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given
      a-invariants. The invariants are coerced into the parent of the
      first element. If all are integers, they are coerced into the
      rational numbers.

    - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`.

    - ``EllipticCurve(label)``: Returns the elliptic curve over Q from
      the Cremona database with the given label. The label is a
      string, such as ``"11a"`` or ``"37b2"``. The letters in the
      label *must* be lower case (Cremona's new labeling).

    - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic
      curve over ``R`` with given a-invariants. Here ``R`` can be an
      arbitrary ring. Note that addition need not be defined.

    - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return
      an elliptic curve with j-invariant ``j0``.

    - ``EllipticCurve(polynomial)``: Read off the a-invariants from
      the polynomial coefficients, see
      :func:`EllipticCurve_from_Weierstrass_polynomial`.

    In each case above where the input is a list of length 2 or 5, one
    can instead give a 2 or 5-tuple instead.

    EXAMPLES:

    We illustrate creating elliptic curves::

        sage: EllipticCurve([0,0,1,-1,0])
        Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

    We create a curve from a Cremona label::

        sage: EllipticCurve('37b2')
        Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field
        sage: EllipticCurve('5077a')
        Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
        sage: EllipticCurve('389a')
        Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field

    Old Cremona labels are allowed::

        sage: EllipticCurve('2400FF')
        Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field

    Unicode labels are allowed::

        sage: EllipticCurve(u'389a')
        Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field

    We create curves over a finite field as follows::

        sage: EllipticCurve([GF(5)(0),0,1,-1,0])
        Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
        sage: EllipticCurve(GF(5), [0, 0,1,-1,0])
        Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5

    Elliptic curves over `\ZZ/N\ZZ` with `N` prime are of type
    "elliptic curve over a finite field"::

        sage: F = Zmod(101)
        sage: EllipticCurve(F, [2, 3])
        Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101
        sage: E = EllipticCurve([F(2), F(3)])
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>
        sage: E.category()
        Category of schemes over Ring of integers modulo 101

    In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite
    are of type "generic elliptic curve"::

        sage: F = Zmod(95)
        sage: EllipticCurve(F, [2, 3])
        Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95
        sage: E = EllipticCurve([F(2), F(3)])
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'>
        sage: E.category()
        Category of schemes over Ring of integers modulo 95

    The following is a curve over the complex numbers::

        sage: E = EllipticCurve(CC, [0,0,1,-1,0])
        sage: E
        Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision
        sage: E.j_invariant()
        2988.97297297297

    We can also create elliptic curves by giving the Weierstrass equation::

        sage: x, y = var('x,y')
        sage: EllipticCurve(y^2 + y ==  x^3 + x - 9)
        Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field

        sage: R.<x,y> = GF(5)[]
        sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x)
        Elliptic Curve defined by y^2 + x*y  = x^3 + x^2 + 2 over Finite Field of size 5

    We can explicitly specify the `j`-invariant::

        sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label()
        Elliptic Curve defined by y^2 = x^3 - x over Rational Field
        1728
        '32a2'

        sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant()
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5
        2

    See :trac:`6657` ::

        sage: EllipticCurve(GF(144169),j=1728)
        Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169

    By default, when a rational value of `j` is given, the constructed
    curve is a minimal twist (minimal conductor for curves with that
    `j`-invariant).  This can be changed by setting the optional
    parameter ``minimal_twist``, which is True by default, to False::


        sage: EllipticCurve(j=100)
        Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
        sage: E =EllipticCurve(j=100); E
        Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
        sage: E.conductor()
        33129800
        sage: E.j_invariant()
        100
        sage: E =EllipticCurve(j=100, minimal_twist=False); E
        Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field
        sage: E.conductor()
        298168200
        sage: E.j_invariant()
        100

    Without this option, constructing the curve could take a long time
    since both `j` and `j-1728` have to be factored to compute the
    minimal twist (see :trac:`13100`)::

       sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False)
       sage: E.j_invariant() == 2^256+1
       True

    TESTS::

        sage: R = ZZ['u', 'v']
        sage: EllipticCurve(R, [1,1])
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v
        over Integer Ring

    We create a curve and a point over QQbar (see #6879)::

        sage: E = EllipticCurve(QQbar,[0,1])
        sage: E(0)
        (0 : 1 : 0)
        sage: E.base_field()
        Algebraic Field

        sage: E = EllipticCurve(RR,[1,2]); E; E.base_field()
        Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision
        Real Field with 53 bits of precision
        sage: EllipticCurve(CC,[3,4]); E; E.base_field()
        Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision
        Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision
        Real Field with 53 bits of precision
        sage: E = EllipticCurve(QQbar,[5,6]); E; E.base_field()
        Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field
        Algebraic Field

    See :trac:`6657` ::

        sage: EllipticCurve(3,j=1728)
        Traceback (most recent call last):
        ...
        ValueError: First parameter (if present) must be a ring when j is specified

        sage: EllipticCurve(GF(5),j=3/5)
        Traceback (most recent call last):
        ...
        ValueError: First parameter must be a ring containing 3/5

    If the universe of the coefficients is a general field, the object
    constructed has type EllipticCurve_field.  Otherwise it is
    EllipticCurve_generic.  See :trac:`9816` ::

        sage: E = EllipticCurve([QQbar(1),3]); E
        Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>

        sage: E = EllipticCurve([RR(1),3]); E
        Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 over Real Field with 53 bits of precision
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>

        sage: E = EllipticCurve([i,i]); E
        Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
        sage: E.category()
        Category of schemes over Symbolic Ring
        sage: SR in Fields()
        True

        sage: F = FractionField(PolynomialRing(QQ,'t'))
        sage: t = F.gen()
        sage: E = EllipticCurve([t,0]); E
        Elliptic Curve defined by y^2 = x^3 + t*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field
        sage: type(E)
        <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
        sage: E.category()
        Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field

    See :trac:`12517`::

        sage: E = EllipticCurve([1..5])
        sage: EllipticCurve(E.a_invariants())
        Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field

    See :trac:`11773`::

        sage: E = EllipticCurve()
        Traceback (most recent call last):
        ...
        TypeError: invalid input to EllipticCurve constructor

    """
    import ell_generic, ell_field, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field  # here to avoid circular includes

    if j is not None:
        if not x is None:
            if is_Ring(x):
                try:
                    j = x(j)
                except (ZeroDivisionError, ValueError, TypeError):
                    raise ValueError, "First parameter must be a ring containing %s"%j
            else:
                raise ValueError, "First parameter (if present) must be a ring when j is specified"
        return EllipticCurve_from_j(j, minimal_twist)

    if x is None:
        raise TypeError, "invalid input to EllipticCurve constructor"

    if is_SymbolicEquation(x):
        x = x.lhs() - x.rhs()

    if parent(x) is SR:
        x = x._polynomial_(rings.QQ['x', 'y'])

    if is_MPolynomial(x):
        if y is None:
            return EllipticCurve_from_Weierstrass_polynomial(x)
        else:
            return EllipticCurve_from_cubic(x, y, morphism=False)

    if is_Ring(x):
        if is_RationalField(x):
            return ell_rational_field.EllipticCurve_rational_field(x, y)
        elif is_FiniteField(x) or (is_IntegerModRing(x) and x.characteristic().is_prime()):
            return ell_finite_field.EllipticCurve_finite_field(x, y)
        elif rings.is_pAdicField(x):
            return ell_padic_field.EllipticCurve_padic_field(x, y)
        elif is_NumberField(x):
            return ell_number_field.EllipticCurve_number_field(x, y)
        elif x in _Fields:
            return ell_field.EllipticCurve_field(x, y)
        return ell_generic.EllipticCurve_generic(x, y)

    if isinstance(x, unicode):
        x = str(x)

    if isinstance(x, basestring):
        return ell_rational_field.EllipticCurve_rational_field(x)

    if is_RingElement(x) and y is None:
        raise TypeError, "invalid input to EllipticCurve constructor"

    if not isinstance(x, (list, tuple)):
        raise TypeError, "invalid input to EllipticCurve constructor"

    x = Sequence(x)
    if not (len(x) in [2,5]):
        raise ValueError, "sequence of coefficients must have length 2 or 5"
    R = x.universe()

    if isinstance(x[0], (rings.Rational, rings.Integer, int, long)):
        return ell_rational_field.EllipticCurve_rational_field(x, y)

    elif is_NumberField(R):
        return ell_number_field.EllipticCurve_number_field(x, y)

    elif rings.is_pAdicField(R):
        return ell_padic_field.EllipticCurve_padic_field(x, y)

    elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()):
        return ell_finite_field.EllipticCurve_finite_field(x, y)

    elif R in _Fields:
        return ell_field.EllipticCurve_field(x, y)

    return ell_generic.EllipticCurve_generic(x, y)
Ejemplo n.º 25
0
    def extensions(self, ring):
        r"""
        Return the extensions of this valuation to ``ring``.

        EXAMPLES::

            sage: v = ZZ.valuation(2)
            sage: v.extensions(GaussianIntegers())
            [2-adic valuation]

        TESTS::

            sage: R.<a> = QQ[]
            sage: L.<a> = QQ.extension(x^3 - 2)
            sage: R.<b> = L[]
            sage: M.<b> = L.extension(b^2 + 2*b + a)
            sage: M.valuation(2)
            2-adic valuation

        Check that we can extend to a field written as a quotient::

            sage: R.<x> = QQ[]
            sage: K.<a> = QQ.extension(x^2 + 1)
            sage: R.<y> = K[]
            sage: L.<b> = R.quo(x^2 + a)
            sage: QQ.valuation(2).extensions(L)
            [2-adic valuation]

        A case where there was at some point an internal error in the
        approximants code::

            sage: R.<x> = QQ[]
            sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8)
            sage: QQ.valuation(2).extensions(L)
            [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation,
             [ 2-adic valuation, v(x) = 1/2 ]-adic valuation]

        A case where the extension was incorrect at some point::

            sage: v = QQ.valuation(2)
            sage: L.<a> = NumberField(x^2 + 2)
            sage: M.<b> = L.extension(x^2 + 1)
            sage: w = v.extension(L).extension(M)
            sage: w(w.uniformizer())
            1/4

        A case where the extensions could not be separated at some point::

            sage: v = QQ.valuation(2)
            sage: R.<x> = QQ[]
            sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68
            sage: L.<a> = QQ.extension(F)
            sage: v.extensions(L)
            [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation,
             [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation]

        """
        if self.domain() is ring:
            return [self]
        domain_fraction_field = _fraction_field(self.domain())
        if domain_fraction_field is not self.domain():
            if domain_fraction_field.is_subring(ring):
                return pAdicValuation(domain_fraction_field,
                                      self).extensions(ring)
        if self.domain().is_subring(ring):
            from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing
            if is_PolynomialQuotientRing(ring):
                if is_PolynomialQuotientRing(self.domain()):
                    if self.domain().modulus() == ring.modulus():
                        base_extensions = self._base_valuation.extensions(
                            self._base_valuation.domain().change_ring(
                                self._base_valuation.domain().base_ring(
                                ).fraction_field()))
                        return [
                            pAdicValuation(ring, base._initial_approximation)
                            for base in base_extensions
                        ]
                if ring.base_ring() is self.domain():
                    from sage.categories.all import IntegralDomains
                    if ring in IntegralDomains():
                        return self._extensions_to_quotient(ring)
                elif self.domain().is_subring(ring.base_ring()):
                    return sum([
                        w.extensions(ring)
                        for w in self.extensions(ring.base_ring())
                    ], [])
            from sage.rings.number_field.number_field import is_NumberField
            if is_NumberField(ring.fraction_field()):
                if ring.base_ring().fraction_field() is self.domain(
                ).fraction_field():
                    from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
                    parent = DiscretePseudoValuationSpace(ring)
                    approximants = self.mac_lane_approximants(
                        ring.fraction_field().relative_polynomial(
                        ).change_ring(self.domain()),
                        assume_squarefree=True,
                        require_incomparability=True)
                    return [
                        pAdicValuation(ring, approximant, approximants)
                        for approximant in approximants
                    ]
                if ring.base_ring() is not ring and self.domain().is_subring(
                        ring.base_ring()):
                    return sum([
                        w.extensions(ring)
                        for w in self.extensions(ring.base_ring())
                    ], [])
        return super(pAdicValuation_base, self).extensions(ring)
Ejemplo n.º 26
0
def check_prime(K,P):
    r"""
    Function to check that `P` determines a prime of `K`, and return that ideal.

    INPUT:

    - ``K`` -- a number field (including `\QQ`).

    - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``.

    OUTPUT:

    - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`.

    - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`.

    .. note::

       If `P` is not a prime and does not generate a prime, a TypeError is raised.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime
        sage: check_prime(QQ,3)
        3
        sage: check_prime(QQ,QQ(3))
        3
        sage: check_prime(QQ,ZZ.ideal(31))
        31
        sage: K.<a>=NumberField(x^2-5)
        sage: check_prime(K,a)
        Fractional ideal (a)
        sage: check_prime(K,a+1)
        Fractional ideal (a + 1)
        sage: [check_prime(K,P) for P in K.primes_above(31)]
        [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)]
        sage: L.<b> = NumberField(x^2+3)
        sage: check_prime(K, L.ideal(5))
        Traceback (most recent call last):
        ..
        TypeError: The ideal Fractional ideal (5) is not a prime ideal of Number Field in a with defining polynomial x^2 - 5
        sage: check_prime(K, L.ideal(b))
        Traceback (most recent call last):
        TypeError: No compatible natural embeddings found for Number Field in a with defining polynomial x^2 - 5 and Number Field in b with defining polynomial x^2 + 3
    """
    if K is QQ:
        if P in ZZ or isinstance(P, integer_types + (Integer,)):
            P = Integer(P)
            if P.is_prime():
                return P
            else:
                raise TypeError("The element %s is not prime" % (P,) )
        elif P in QQ:
            raise TypeError("The element %s is not prime" % (P,) )
        elif is_Ideal(P) and P.base_ring() is ZZ:
            if P.is_prime():
                return P.gen()
            else:
                raise TypeError("The ideal %s is not a prime ideal of %s" % (P, ZZ))
        else:
            raise TypeError("%s is neither an element of QQ or an ideal of %s" % (P, ZZ))

    if not is_NumberField(K):
        raise TypeError("%s is not a number field" % (K,) )

    if is_NumberFieldFractionalIdeal(P) or P in K:
        # if P is an ideal, making sure it is an fractional ideal of K
        P = K.fractional_ideal(P)
        if P.is_prime():
            return P
        else:
            raise TypeError("The ideal %s is not a prime ideal of %s" % (P, K))

    raise TypeError("%s is not a valid prime of %s" % (P, K))
Ejemplo n.º 27
0
    def __init__(self, diffop, dz, derivatives, nterms_est):

        deq_Scalars = diffop.base_ring().base_ring()
        E = dz.parent()
        if deq_Scalars.characteristic() != 0:
            raise ValueError("only makes sense for scalar rings of "
                             "characteristic 0")
        assert deq_Scalars is dz.parent() or deq_Scalars != dz.parent()

        #### Recurrence operator

        # Reduce to the case of a number field generated by an algebraic
        # integer. This is mainly intended to avoid computing gcds (due to
        # denominators in the representation of number field elements) in the
        # product tree, but could also be useful to extend the field using Pari
        # in the future.
        NF_rec, AlgInts_rec = _number_field_with_integer_gen(deq_Scalars)
        # ore_algebra currently does not support orders as scalar rings
        Pols = PolynomialRing(NF_rec, 'n')
        Rops, Sn = ore_algebra.OreAlgebra(Pols, 'Sn').objgen()
        # Using the primitive part here would break the computation of
        # residuals! (Cf. local_solutions.)
        # recop = diffop.to_S(Rops).primitive_part().numerator()
        recop = diffop.to_S(Rops)
        recop = lcm([p.denominator() for p in recop.coefficients()]) * recop
        # Ensure that ordrec >= orddeq. When the homomorphic image of diffop in
        # Rops is divisible by Sn, it can happen that the recop (e.g., after
        # normalization to Sn-valuation 0) has order < orddeq, and our strategy
        # of using vectors of coefficients of the form [u(n-s'), ..., u(n+r-1)]
        # with s'=s-r does not work in this case.
        orddelta = recop.order() - diffop.order()
        if orddelta < 0:
            recop = Sn**(-orddelta) * recop

        #### Choose computation domains

        if ((isinstance(E, (RealBallField, ComplexBallField)) or E is QQ
             or utilities.is_QQi(E) or E is RLF or E is CLF)
                and (deq_Scalars is QQ or utilities.is_QQi(deq_Scalars))):
            # Special-case QQ and QQ[i] to use arb matrices
            # (overwrites AlgInts_rec)
            self.StepMatrix_class = StepMatrix_arb
            self.binsplit_threshold = 8
            # Working precision. We typically want operations on exact balls to
            # be exact, so that overshooting shouldn't be a problem.
            # XXX Less clear in the case dz ∈ XBF!
            # XXX The rough estimate below ignores the height of rec and dz.
            # prec = nterms_est*(recop.degree()*nterms_est.nbits()
            #                    + recop.order().nbits() + 1)
            prec = 8 + nterms_est * (1 + ZZ(ZZ(recop.order()).nbits()).nbits())
            if (E is QQ or isinstance(E, RealBallField)) and deq_Scalars is QQ:
                AlgInts_rec = AlgInts_pow = RealBallField(prec)
            else:
                AlgInts_rec = AlgInts_pow = ComplexBallField(prec)
            if is_NumberField(E):
                pow_den = AlgInts_pow(dz.denominator())
            else:
                pow_den = AlgInts_pow.one()
        else:
            self.StepMatrix_class = StepMatrix_generic
            self.binsplit_threshold = 64
            if is_NumberField(E):
                # In fact we should probably do something similar for dz in any
                # finite-dimensional Q-algebra. (But how?)
                NF_pow, AlgInts_pow = _number_field_with_integer_gen(E)
                pow_den = NF_pow(dz).denominator()
            else:
                # This includes the case E = ZZ, but dz could live in pretty
                # much any algebra over deq_Scalars (including matrices,
                # intervals...). Then the computation of sums_row may take time,
                # but we still hope to gain something on the computation of the
                # coefficients and/or limit interval blow-up thanks to the use
                # of binary splitting.
                AlgInts_pow = E
                pow_den = ZZ.one()
            assert pow_den.parent() is ZZ
        assert AlgInts_pow is AlgInts_rec or AlgInts_pow != AlgInts_rec

        #### Recurrence matrix

        self.recop = recop

        self.orddeq = diffop.order()
        self.ordrec = recop.order()
        self.orddelta = self.ordrec - self.orddeq

        Pols_rec, n = PolynomialRing(AlgInts_rec, 'n').objgen()
        self.rec_coeffs = [
            -Pols_rec(recop[i])(n - self.orddelta) for i in xrange(self.ordrec)
        ]
        self.rec_den = Pols_rec(recop.leading_coefficient())(n - self.orddelta)
        # Guard against various problems related to number field embeddings and
        # uniqueness
        assert Pols_rec.base_ring() is AlgInts_rec
        assert self.rec_den.base_ring() is AlgInts_rec
        assert self.rec_den(
            self.rec_den.base_ring().zero()).parent() is AlgInts_rec

        # Also store a version of the recurrence operator of the form
        # b[0](n) + b[1](n) S^(-1) + ··· + b[s](n) S^(-s).
        # This is convenient to share code with other implementations, or at
        # least make the implementations easier to compare.
        # XXX: understand what to do about variable names!
        self.bwrec = [
            recop[self.ordrec - k](Rops.base_ring().gen() - self.ordrec)
            for k in xrange(self.ordrec + 1)
        ]

        #### Power of dz. Note that this part does not depend on n.

        # If we extend the removal of denominators above to algebras other than
        # number fields, it would probably make more sense to move this into
        # the caller. --> support dz in non-com ring (mat)? power series work
        # only over com rings
        Series_pow = PolynomialRing(AlgInts_pow, 'delta')
        self.pow_num = Series_pow([pow_den * dz, pow_den])
        self.pow_den = pow_den
        self.derivatives = derivatives

        #### Partial sums

        # We need a parent containing both the coefficients of the operator and
        # the evaluation point.
        # XXX: Is this the correct way to get one? Should we use
        # canonical_coercion()? Something else?
        # XXX: This is not powerful enough to find a number field containing
        # two given number fields (both given with embeddings into CC)

        # Work around #14982 (fixed) + weaknesses of the coercion framework for orders
        #Series_sums = sage.categories.pushout.pushout(AlgInts_rec, Series_pow)
        try:
            AlgInts_sums = sage.categories.pushout.pushout(
                AlgInts_rec, AlgInts_pow)
        except sage.structure.coerce_exceptions.CoercionException:
            AlgInts_sums = sage.categories.pushout.pushout(NF_rec, AlgInts_pow)
        assert AlgInts_sums is AlgInts_rec or AlgInts_sums != AlgInts_rec
        assert AlgInts_sums is AlgInts_pow or AlgInts_sums != AlgInts_pow

        Series_sums = PolynomialRing(AlgInts_sums, 'delta')
        assert Series_sums.base_ring() is AlgInts_sums
        # for speed
        self.Series_sums = Series_sums
        self.series_class_sums = type(Series_sums.gen())

        self.Mat_rec = MatrixSpace(AlgInts_rec, self.ordrec, self.ordrec)
        self.Mat_sums_row = MatrixSpace(Series_sums, 1, self.ordrec)
        self.Mat_series_sums = self.Mat_rec.change_ring(Series_sums)