示例#1
0
文件: homset.py 项目: dagss/sage
    def points(self, B=0):
        """
        Return some or all rational points of a projective scheme.

        INPUT:

        - `B` -- integer (optional, default=0). The bound for the
          coordinates.

        OUTPUT:

        A list of points. Over a finite field, all points are
        returned. Over an infinite field, all points satisfying the
        bound are returned.

        EXAMPLES::
        
            sage: P1 = ProjectiveSpace(GF(2),1)
            sage: F.<a> = GF(4,'a')
            sage: P1(F).points()
            [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)]
        """
        from sage.schemes.generic.rational_point import enum_projective_rational_field
        from sage.schemes.generic.rational_point import enum_projective_finite_field
        R = self.value_ring()
        if is_RationalField(R):
            if not B > 0:
                raise TypeError, "A positive bound B (= %s) must be specified."%B
            return enum_projective_rational_field(self,B)
        elif is_FiniteField(R):
            return enum_projective_finite_field(self.extended_codomain())
        else:
            raise TypeError, "Unable to enumerate points over %s."%R
示例#2
0
    def points(self, B=0):
        """
        Return some or all rational points of a projective scheme.

        INPUT:

        - `B` -- integer (optional, default=0). The bound for the
          coordinates.

        OUTPUT:

        A list of points. Over a finite field, all points are
        returned. Over an infinite field, all points satisfying the
        bound are returned.

        EXAMPLES::
        
            sage: P1 = ProjectiveSpace(GF(2),1)
            sage: F.<a> = GF(4,'a')
            sage: P1(F).points()
            [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)]
        """
        from sage.schemes.generic.rational_point import enum_projective_rational_field
        from sage.schemes.generic.rational_point import enum_projective_finite_field
        R = self.value_ring()
        if is_RationalField(R):
            if not B > 0:
                raise TypeError, "A positive bound B (= %s) must be specified."%B
            return enum_projective_rational_field(self,B)
        elif is_FiniteField(R):
            return enum_projective_finite_field(self.extended_codomain())
        else:
            raise TypeError, "Unable to enumerate points over %s."%R
示例#3
0
 def __init__(self, X, P, codomain = None, check = False):
     r"""
     Create the discrete probability space with probabilities on the
     space X given by the dictionary P with values in the field
     real_field.
     
     EXAMPLES::
     
         sage: S = [ i for i in range(16) ] 
         sage: P = {}
                sage: for i in range(15): P[i] = 2^(-i-1)
         sage: P[15] = 2^-16 
         sage: X = DiscreteProbabilitySpace(S,P)
         sage: X.domain()
         (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
         sage: X.set()
         {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
         sage: X.entropy()
                1.9997253418
     
     A probability space can be defined on any list of elements.
     
     EXAMPLES::
     
         sage: AZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
         sage: S = [ AZ[i] for i in range(26) ]
         sage: P = { 'A':1/2, 'B':1/4, 'C':1/4 }
         sage: X = DiscreteProbabilitySpace(S,P)
         sage: X
         Discrete probability space defined by {'A': 1/2, 'C': 1/4, 'B': 1/4}
         sage: X.entropy()
                1.5
     """
     if codomain is None:
         codomain = RealField()
     if not is_RealField(codomain) and not is_RationalField(codomain):
         raise TypeError, "Argument codomain (= %s) must be the reals or rationals" % codomain
     if check:
         one = sum([ P[x] for x in P.keys() ])
         if is_RationalField(codomain):    
             if not one == 1:
                 raise TypeError, "Argument P (= %s) does not define a probability function"
         else:
             if not Abs(one-1) < 2^(-codomain.precision()+1):
                 raise TypeError, "Argument P (= %s) does not define a probability function"
     ProbabilitySpace_generic.__init__(self, X, codomain)
     DiscreteRandomVariable.__init__(self, self, P, codomain, check)
示例#4
0
 def __init__(self, X, P, codomain=None, check=False):
     r"""
     Create the discrete probability space with probabilities on the
     space X given by the dictionary P with values in the field
     real_field.
     
     EXAMPLES::
     
         sage: S = [ i for i in range(16) ] 
         sage: P = {}
                sage: for i in range(15): P[i] = 2^(-i-1)
         sage: P[15] = 2^-16 
         sage: X = DiscreteProbabilitySpace(S,P)
         sage: X.domain()
         (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
         sage: X.set()
         {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
         sage: X.entropy()
                1.9997253418
     
     A probability space can be defined on any list of elements.
     
     EXAMPLES::
     
         sage: AZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
         sage: S = [ AZ[i] for i in range(26) ]
         sage: P = { 'A':1/2, 'B':1/4, 'C':1/4 }
         sage: X = DiscreteProbabilitySpace(S,P)
         sage: X
         Discrete probability space defined by {'A': 1/2, 'C': 1/4, 'B': 1/4}
         sage: X.entropy()
                1.5
     """
     if codomain is None:
         codomain = RealField()
     if not is_RealField(codomain) and not is_RationalField(codomain):
         raise TypeError, "Argument codomain (= %s) must be the reals or rationals" % codomain
     if check:
         one = sum([P[x] for x in P.keys()])
         if is_RationalField(codomain):
             if not one == 1:
                 raise TypeError, "Argument P (= %s) does not define a probability function"
         else:
             if not Abs(one - 1) < 2 ^ (-codomain.precision() + 1):
                 raise TypeError, "Argument P (= %s) does not define a probability function"
     ProbabilitySpace_generic.__init__(self, X, codomain)
     DiscreteRandomVariable.__init__(self, self, P, codomain, check)
示例#5
0
def relation_matrix_wtk_g0(syms, sign, field, sparse):
    r"""
    Compute the matrix of relations. Despite the name, this is used for all
    spaces (not just for Gamma0). For a description of the algorithm, see the
    docstring for ``compute_presentation``.

    INPUT:

    - ``syms``: sage.modular.modsym.manin_symbols.ManinSymbolList object

    - ``sign``: integer (0, 1 or -1)

    - ``field``: the base field (non-field base rings not supported at present)

    - ``sparse``: (True or False) whether to use sparse arithmetic.

    Note that ManinSymbolList objects already have a specific weight, so there
    is no need for an extra ``weight`` parameter.

    OUTPUT: a pair (R, mod) where

    - R is a matrix as output by ``T_relation_matrix_wtk_g0``

    - mod is a set of 2-term relations as output by ``sparse_2term_quotient``

    EXAMPLE::

        sage: L =  sage.modular.modsym.manin_symbols.ManinSymbolList_gamma0(8,2)
        sage: A = sage.modular.modsym.relation_matrix.relation_matrix_wtk_g0(L, 0, GF(2), True); A
        (
        [0 0 0 0 0 0 0 0 1 0 0 0]
        [0 0 0 0 0 0 0 0 1 1 1 0]
        [0 0 0 0 0 0 1 0 0 1 1 0]
        [0 0 0 0 0 0 1 0 0 0 0 0], [(1, 1), (1, 1), (8, 1), (10, 1), (6, 1), (11, 1), (6, 1), (9, 1), (8, 1), (9, 1), (10, 1), (11, 1)]
        )
        sage: A[0].is_sparse()
        True
    """
    rels = modS_relations(syms)
    if sign != 0:
        # Let rels = rels union I relations.
        rels.update(modI_relations(syms, sign))

    if syms._apply_S_only_0pm1() and rings.is_RationalField(field):
        import relation_matrix_pyx
        mod = relation_matrix_pyx.sparse_2term_quotient_only_pm1(
            rels, len(syms))
    else:
        mod = sparse_2term_quotient(rels, len(syms), field)

    R = T_relation_matrix_wtk_g0(syms, mod, field, sparse)
    return R, mod
示例#6
0
def relation_matrix_wtk_g0(syms, sign, field, sparse):
    r"""
    Compute the matrix of relations. Despite the name, this is used for all
    spaces (not just for Gamma0). For a description of the algorithm, see the
    docstring for ``compute_presentation``.

    INPUT:

    - ``syms``: sage.modular.modsym.manin_symbols.ManinSymbolList object

    - ``sign``: integer (0, 1 or -1)

    - ``field``: the base field (non-field base rings not supported at present)

    - ``sparse``: (True or False) whether to use sparse arithmetic.

    Note that ManinSymbolList objects already have a specific weight, so there
    is no need for an extra ``weight`` parameter.

    OUTPUT: a pair (R, mod) where

    - R is a matrix as output by ``T_relation_matrix_wtk_g0``

    - mod is a set of 2-term relations as output by ``sparse_2term_quotient``

    EXAMPLE::

        sage: L =  sage.modular.modsym.manin_symbols.ManinSymbolList_gamma0(8,2)
        sage: A = sage.modular.modsym.relation_matrix.relation_matrix_wtk_g0(L, 0, GF(2), True); A
        (
        [0 0 0 0 0 0 0 0 1 0 0 0]
        [0 0 0 0 0 0 0 0 1 1 1 0]
        [0 0 0 0 0 0 1 0 0 1 1 0]
        [0 0 0 0 0 0 1 0 0 0 0 0], [(1, 1), (1, 1), (8, 1), (10, 1), (6, 1), (11, 1), (6, 1), (9, 1), (8, 1), (9, 1), (10, 1), (11, 1)]
        )
        sage: A[0].is_sparse()
        True
    """
    rels = modS_relations(syms)
    if sign != 0:
        # Let rels = rels union I relations.
        rels.update(modI_relations(syms, sign))

    if syms._apply_S_only_0pm1() and rings.is_RationalField(field):
        import relation_matrix_pyx

        mod = relation_matrix_pyx.sparse_2term_quotient_only_pm1(rels, len(syms))
    else:
        mod = sparse_2term_quotient(rels, len(syms), field)

    R = T_relation_matrix_wtk_g0(syms, mod, field, sparse)
    return R, mod
示例#7
0
    def points(self, B=0):
        r"""
        Return some or all rational points of an affine scheme.

        INPUT:

        - ``B`` -- integer (optional, default: 0). The bound for the
          height of the coordinates.

        OUTPUT:

        - If the base ring is a finite field: all points of the scheme,
          given by coordinate tuples.

        - If the base ring is `\QQ` or `\ZZ`: the subset of points whose
          coordinates have height ``B`` or less.

        EXAMPLES: The bug reported at #11526 is fixed::

            sage: A2 = AffineSpace(ZZ,2)
            sage: F = GF(3)
            sage: A2(F).points()
            [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

            sage: R = ZZ
            sage: A.<x,y> = R[]
            sage: I = A.ideal(x^2-y^2-1)
            sage: V = AffineSpace(R,2)
            sage: X = V.subscheme(I)
            sage: M = X(R)
            sage: M.points(1)
            [(-1, 0), (1, 0)]
        """
        R = self.value_ring()
        if is_RationalField(R) or R == ZZ:
            if not B > 0:
                raise TypeError, "A positive bound B (= %s) must be specified."%B
            from sage.schemes.generic.rational_point import enum_affine_rational_field
            return enum_affine_rational_field(self,B)
        elif is_FiniteField(R):
            from sage.schemes.generic.rational_point import enum_affine_finite_field
            return enum_affine_finite_field(self)
        else:
            raise TypeError, "Unable to enumerate points over %s."%R
示例#8
0
文件: homset.py 项目: dagss/sage
    def points(self, B=0):
        r"""
        Return some or all rational points of an affine scheme.

        INPUT:

        - ``B`` -- integer (optional, default: 0). The bound for the
          height of the coordinates.

        OUTPUT:

        - If the base ring is a finite field: all points of the scheme,
          given by coordinate tuples.

        - If the base ring is `\QQ` or `\ZZ`: the subset of points whose
          coordinates have height ``B`` or less.

        EXAMPLES: The bug reported at #11526 is fixed::

            sage: A2 = AffineSpace(ZZ,2)
            sage: F = GF(3)
            sage: A2(F).points()
            [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

            sage: R = ZZ
            sage: A.<x,y> = R[]
            sage: I = A.ideal(x^2-y^2-1)
            sage: V = AffineSpace(R,2)
            sage: X = V.subscheme(I)
            sage: M = X(R)
            sage: M.points(1)
            [(-1, 0), (1, 0)]
        """
        R = self.value_ring()
        if is_RationalField(R) or R == ZZ:
            if not B > 0:
                raise TypeError, "A positive bound B (= %s) must be specified."%B
            from sage.schemes.generic.rational_point import enum_affine_rational_field
            return enum_affine_rational_field(self,B)
        elif is_FiniteField(R):
            from sage.schemes.generic.rational_point import enum_affine_finite_field
            return enum_affine_finite_field(self)
        else:
            raise TypeError, "Unable to enumerate points over %s."%R
示例#9
0
def EllipticCurve(x=None, y=None, j=None):
    r"""
    There are several ways to construct an elliptic curve:
    
    .. math::
    
       y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6.       
    
    
    - 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 a1=a2=a3=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): Return an elliptic curve with j-invariant
      `j`.  Warning: this is deprecated.  Use ``EllipticCurve_from_j(j)`` 
      or ``EllipticCurve(j=j)`` instead.         

    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

    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


    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: is_field(SR)
        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
    """
    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 rings.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)

    assert x is not None
    
    if is_SymbolicEquation(x):
        x = x.lhs() - x.rhs()
    
    if parent(x) is SR:
        x = x._polynomial_(rings.QQ['x', 'y'])
    
    if rings.is_MPolynomial(x) and y is None:
        f = x
        if f.degree() != 3:
            raise ValueError, "Elliptic curves must be defined by a cubic polynomial."
        if f.degrees() == (3,2):
            x, y = f.parent().gens()
        elif f.degree() == (2,3):
            y, x = f.parent().gens()
        elif len(f.parent().gens()) == 2 or len(f.parent().gens()) == 3 and f.is_homogeneous():
            # We'd need a point too...
            raise NotImplementedError, "Construction of an elliptic curve from a generic cubic not yet implemented."
        else:
            raise ValueError, "Defining polynomial must be a cubic polynomial in two variables."

        try:
            if f.coefficient(x**3) < 0:
                f = -f
            # is there a nicer way to extract the coefficients?
            a1 = a2 = a3 = a4 = a6 = 0
            for coeff, mon in f:
                if mon == x**3:
                    assert coeff == 1
                elif mon == x**2:
                    a2 = coeff
                elif mon == x:
                    a4 = coeff
                elif mon == 1:
                    a6 = coeff
                elif mon == y**2:
                    assert coeff == -1
                elif mon == x*y:
                    a1 = -coeff
                elif mon == y:
                    a3 = -coeff
                else:
                    assert False
            return EllipticCurve([a1, a2, a3, a4, a6])
        except AssertionError:
            raise NotImplementedError, "Construction of an elliptic curve from a generic cubic not yet implemented."
    
    if rings.is_Ring(x):
        if rings.is_RationalField(x):
            return ell_rational_field.EllipticCurve_rational_field(x, y)
        elif rings.is_FiniteField(x) or (rings.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 rings.is_NumberField(x):
            return ell_number_field.EllipticCurve_number_field(x, y)
        elif rings.is_Field(x):
            return ell_field.EllipticCurve_field(x, y)
        return ell_generic.EllipticCurve_generic(x, y)

    if isinstance(x, unicode):
        x = str(x)
        
    if isinstance(x, str):
        return ell_rational_field.EllipticCurve_rational_field(x)
        
    if rings.is_RingElement(x) and y is None:
        from sage.misc.misc import deprecation
        deprecation("'EllipticCurve(j)' is deprecated; use 'EllipticCurve_from_j(j)' or 'EllipticCurve(j=j)' instead.")
        # Fixed for all characteristics and cases by John Cremona
        j=x
        F=j.parent().fraction_field()
        char=F.characteristic()
        if char==2:
            if j==0:
                return EllipticCurve(F, [ 0, 0, 1, 0, 0 ])
            else:
                return EllipticCurve(F, [ 1, 0, 0, 0, 1/j ])
        if char==3:
            if j==0:
                return EllipticCurve(F, [ 0, 0, 0, 1, 0 ])
            else:
                return EllipticCurve(F, [ 0, j, 0, 0, -j**2 ])
        if j == 0:
            return EllipticCurve(F, [ 0, 0, 0, 0, 1 ])
        if j == 1728:
            return EllipticCurve(F, [ 0, 0, 0, 1, 0 ])
        k=j-1728
        return EllipticCurve(F, [0,0,0,-3*j*k, -2*j*k**2])

    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 rings.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 rings.is_FiniteField(R) or (rings.is_IntegerModRing(R) and R.characteristic().is_prime()):
        return ell_finite_field.EllipticCurve_finite_field(x, y)

    elif rings.is_Field(R):
        return ell_field.EllipticCurve_field(x, y)

    return ell_generic.EllipticCurve_generic(x, y)
示例#10
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
示例#11
0
def HyperellipticCurve(f,h=None,names=None,PP=None):
    r"""
    Returns the hyperelliptic curve `y^2 + h y = f`, for
    univariate polynomials `h` and `f`. If `h`
    is not given, then it defaults to 0.
    
    INPUT:
    
    
    -  ``f`` - univariate polynomial
    
    -  ``h`` - optional univariate polynomial
    
    
    EXAMPLES: A curve with and without the h term::
    
        sage: R.<x> = QQ[]
        sage: HyperellipticCurve(x^5 + x + 1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
        sage: HyperellipticCurve(x^19 + x + 1, x-2)
        Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1
    
    A curve over a non-prime finite field::
    
        sage: k.<a> = GF(9); R.<x> = k[]
        sage: HyperellipticCurve(x^3 + x - 1, x+a)
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2
    
    Here's one where we change the names of the vars in the homogeneous
    polynomial::
    
        sage: k.<a> = GF(9); R.<x> = k[]    
        sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y'])
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2
    """
    if not is_Polynomial(f):
        raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials"%(f,h)
    P = f.parent()
    if h is None:
        h = P(0)
        g = (f.degree()-1)%2
    try:
        h = P(h)
    except TypeError:
        raise TypeError, \
              "Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h)
    df = f.degree()
    dh_2 = 2*h.degree()
    if dh_2 < df:
        g = (df-1)//2
    elif df < dh_2:
        g = (dh_2-1)//2
    else:
        a0 = f.leading_coefficient()
        b0 = h.leading_coefficient()
        A0 = 4*a0 + b0^2
        if A0 != 0:
            g = (df-1)//2
        else:
            if P(2) == 0:
                raise TypeError, "Arguments define a curve with finite singularity."
            f0 = 4*f + h^2
            d0 = f0.degree()
            g = (d0-1)//2
    R = P.base_ring()
    PP = ProjectiveSpace(2, R)
    if names is None:
        names = ["x","y"]
    if is_FiniteField(R):
        if g == 2:
            return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g)
    elif is_RationalField(R):
        if g == 2:
            return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g)
    elif is_pAdicField(R):
        if g == 2:
            return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g)
    else:
        if g == 2:
            return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
示例#12
0
def ProjectiveSpace(n, R=None, names='x'):
    r"""
    Return projective space of dimension `n` over the ring `R`.

    EXAMPLES: The dimension and ring can be given in either order.

    ::

        sage: ProjectiveSpace(3, QQ)
        Projective Space of dimension 3 over Rational Field
        sage: ProjectiveSpace(5, QQ)
        Projective Space of dimension 5 over Rational Field
        sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P
        Projective Space of dimension 2 over Rational Field
        sage: P.coordinate_ring()
        Multivariate Polynomial Ring in X, Y, Z over Rational Field

    The divide operator does base extension.

    ::

        sage: ProjectiveSpace(5)/GF(17)
        Projective Space of dimension 5 over Finite Field of size 17

    The default base ring is `\ZZ`.

    ::

        sage: ProjectiveSpace(5)
        Projective Space of dimension 5 over Integer Ring

    There is also an projective space associated each polynomial ring.

    ::

        sage: R = GF(7)['x,y,z']
        sage: P = ProjectiveSpace(R); P
        Projective Space of dimension 2 over Finite Field of size 7
        sage: P.coordinate_ring()
        Multivariate Polynomial Ring in x, y, z over Finite Field of size 7
        sage: P.coordinate_ring() is R
        True

    ::

        sage: ProjectiveSpace(3, Zp(5), 'y')
        Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20

    ::

        sage: ProjectiveSpace(2,QQ,'x,y,z')
        Projective Space of dimension 2 over Rational Field

    ::

        sage: PS.<x,y>=ProjectiveSpace(1,CC)
        sage: PS
        Projective Space of dimension 1 over Complex Field with 53 bits of precision

    Projective spaces are not cached, i.e., there can be several with
    the same base ring and dimension (to facilitate gluing
    constructions).
    """
    if is_MPolynomialRing(n) and R is None:
        A = ProjectiveSpace(n.ngens() - 1, n.base_ring())
        A._coordinate_ring = n
        return A
    if isinstance(R, (int, long, Integer)):
        n, R = R, n
    if R is None:
        R = ZZ  # default is the integers
    if R in _Fields:
        if is_FiniteField(R):
            return ProjectiveSpace_finite_field(n, R, names)
        if is_RationalField(R):
            return ProjectiveSpace_rational_field(n, R, names)
        else:
            return ProjectiveSpace_field(n, R, names)
    elif is_CommutativeRing(R):
        return ProjectiveSpace_ring(n, R, names)
    else:
        raise TypeError, "R (=%s) must be a commutative ring" % R
示例#13
0
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True):
    r"""
    There are several ways to construct an elliptic curve:
    
    .. math::
    
       y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6.       
    
    
    - 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 a1=a2=a3=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`.

    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 rings.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 rings.is_MPolynomial(x) and y is None:
        f = x
        if f.degree() != 3:
            raise ValueError, "Elliptic curves must be defined by a cubic polynomial."
        if f.degrees() == (3,2):
            x, y = f.parent().gens()
        elif f.degree() == (2,3):
            y, x = f.parent().gens()
        elif len(f.parent().gens()) == 2 or len(f.parent().gens()) == 3 and f.is_homogeneous():
            # We'd need a point too...
            raise NotImplementedError, "Construction of an elliptic curve from a generic cubic not yet implemented."
        else:
            raise ValueError, "Defining polynomial must be a cubic polynomial in two variables."

        try:
            if f.coefficient(x**3) < 0:
                f = -f
            # is there a nicer way to extract the coefficients?
            a1 = a2 = a3 = a4 = a6 = 0
            for coeff, mon in f:
                if mon == x**3:
                    assert coeff == 1
                elif mon == x**2:
                    a2 = coeff
                elif mon == x:
                    a4 = coeff
                elif mon == 1:
                    a6 = coeff
                elif mon == y**2:
                    assert coeff == -1
                elif mon == x*y:
                    a1 = -coeff
                elif mon == y:
                    a3 = -coeff
                else:
                    assert False
            return EllipticCurve([a1, a2, a3, a4, a6])
        except AssertionError:
            raise NotImplementedError, "Construction of an elliptic curve from a generic cubic not yet implemented."
    
    if rings.is_Ring(x):
        if rings.is_RationalField(x):
            return ell_rational_field.EllipticCurve_rational_field(x, y)
        elif rings.is_FiniteField(x) or (rings.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 rings.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, str):
        return ell_rational_field.EllipticCurve_rational_field(x)

    if rings.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 rings.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 rings.is_FiniteField(R) or (rings.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)
示例#14
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 rings.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 rings.is_MPolynomial(x):
        if y is None:
            return EllipticCurve_from_Weierstrass_polynomial(x)
        else:
            return EllipticCurve_from_cubic(x, y, morphism=False)

    if rings.is_Ring(x):
        if rings.is_RationalField(x):
            return ell_rational_field.EllipticCurve_rational_field(x, y)
        elif rings.is_FiniteField(x) or (rings.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 rings.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 rings.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 rings.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 rings.is_FiniteField(R) or (rings.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)
示例#15
0
    def has_rational_point(self, point = False, obstruction = False,
                           algorithm = 'default', read_cache = True):
        r"""
        Returns ``True`` if and only if ``self`` has a point
        defined over its base field `B`.

        If ``point`` and ``obstruction`` are both False (default),
        then the output is a boolean ``out`` saying whether ``self``
        has a rational point.

        If ``point`` or ``obstruction`` is True, then the output is
        a pair ``(out, S)``, where ``out`` is as above and:

         - if ``point`` is True and ``self`` has a rational point,
           then ``S`` is a rational point,

         - if ``obstruction`` is True, ``self`` has no rational point,
           then ``S`` is a prime or infinite place of `B` such that no
           rational point exists over the completion at ``S``.

        Points and obstructions are cached whenever they are found.
        Cached information is used for the output if available, but only
        if ``read_cache`` is True.

        ALGORITHM:

        The parameter ``algorithm``
        specifies the algorithm to be used:

         - ``'rnfisnorm'`` -- Use PARI's rnfisnorm
           (cannot be combined with ``obstruction = True``)

         - ``'local'`` -- Check if a local solution exists for all primes
           and infinite places of `B` and apply the Hasse principle.
           (Cannot be combined with ``point = True``.)

         - ``'default'`` -- Use algorithm ``'rnfisnorm'`` first.
           Then, if no point exists and obstructions are requested, use
           algorithm ``'local'`` to find an obstruction.

         - ``'magma'`` (requires Magma to be installed) --
           delegates the task to the Magma computer algebra
           system.


        EXAMPLES:

        An example over `\QQ` ::

            sage: C = Conic(QQ, [1, 113922743, -310146482690273725409])
            sage: C.has_rational_point(point = True)
            (True, (-76842858034579/5424 : -5316144401/5424 : 1))
            sage: C.has_rational_point(algorithm = 'local', read_cache = False)
            True

        Examples over number fields ::

            sage: K.<i> = QuadraticField(-1)
            sage: C = Conic(K, [1, 3, -5])
            sage: C.has_rational_point(point = True, obstruction = True)
            (False, Fractional ideal (-i - 2))
            sage: C.has_rational_point(algorithm = "rnfisnorm")
            False
            sage: C.has_rational_point(algorithm = "rnfisnorm", obstruction = True, read_cache=False)
            Traceback (most recent call last):
            ...
            ValueError: Algorithm rnfisnorm cannot be combined with obstruction = True in has_rational_point

            sage: P.<x> = QQ[]
            sage: L.<b> = NumberField(x^3-5)
            sage: C = Conic(L, [1, 2, -3])
            sage: C.has_rational_point(point = True, algorithm = 'rnfisnorm')
            (True, (5/3 : -1/3 : 1))

            sage: K.<a> = NumberField(x^4+2)
            sage: Conic(QQ, [4,5,6]).has_rational_point()
            False
            sage: Conic(K, [4,5,6]).has_rational_point()
            True
            sage: Conic(K, [4,5,6]).has_rational_point(algorithm='magma', read_cache=False) # optional - magma
            True

        TESTS:

        Create a bunch of conics over number fields and check whether
        ``has_rational_point`` runs without errors for algorithms
        ``'rnfisnorm'`` and ``'local'``. Check if all points returned are
        valid. If Magma is available, then also check if the output agrees with
        Magma. ::

            sage: P.<X> = QQ[]
            sage: Q = P.fraction_field()
            sage: c = [1, X/2, 1/X]
            sage: l = Sequence(cartesian_product_iterator([c for i in range(3)]))
            sage: l = l + [[X, 1, 1, 1, 1, 1]] + [[X, 1/5, 1, 1, 2, 1]]
            sage: K.<a> = QuadraticField(-23)
            sage: L.<b> = QuadraticField(19)
            sage: M.<c> = NumberField(X^3+3*X+1)
            sage: m = [[Q(b)(F.gen()) for b in a] for a in l for F in [K, L, M]]
            sage: d = []
            sage: c = []
            sage: c = [Conic(a) for a in m if a != [0,0,0]]
            sage: d = [C.has_rational_point(algorithm = 'rnfisnorm', point = True) for C in c] # long time: 3.3 seconds
            sage: all([c[k].defining_polynomial()(Sequence(d[k][1])) == 0 for k in range(len(d)) if d[k][0]])
            True
            sage: [C.has_rational_point(algorithm='local', read_cache=False) for C in c] == [o[0] for o in d] # long time: 5 seconds
            True
            sage: [C.has_rational_point(algorithm = 'magma', read_cache=False) for C in c] == [o[0] for o in d] # long time: 3 seconds, optional - magma
            True

        Create a bunch of conics that are known to have rational points
        already over `\QQ` and check if points are found by
        ``has_rational_point``. ::

            sage: l = Sequence(cartesian_product_iterator([[-1, 0, 1] for i in range(3)]))
            sage: K.<a> = QuadraticField(-23)
            sage: L.<b> = QuadraticField(19)
            sage: M.<c> = NumberField(x^5+3*x+1)
            sage: m = [[F(b) for b in a] for a in l for F in [K, L, M]]
            sage: c = [Conic(a) for a in m if a != [0,0,0] and a != [1,1,1] and a != [-1,-1,-1]]
            sage: assert all([C.has_rational_point(algorithm = 'rnfisnorm') for C in c])
            sage: assert all([C.defining_polynomial()(Sequence(C.has_rational_point(point = True)[1])) == 0 for C in c])
            sage: assert all([C.has_rational_point(algorithm='local', read_cache=False) for C in c]) # long time: 1 second
        """
        if read_cache:
            if self._rational_point is not None:
                if point or obstruction:
                    return True, self._rational_point
                else:
                    return True
            if self._local_obstruction is not None:
                if point or obstruction:
                    return False, self._local_obstruction
                else:
                    return False
            if (not point) and self._finite_obstructions == [] and \
               self._infinite_obstructions == []:
                if obstruction:
                    return True, None
                return True
        if self.has_singular_point():
            if point:
                return self.has_singular_point(point = True)
            if obstruction:
                return True, None
            return True
        B = self.base_ring()

        if algorithm == 'default':
            ret = self.has_rational_point(point=True, obstruction=False,
                                          algorithm='rnfisnorm',
                                          read_cache=False)
            if ret[0]:
                if point or obstruction:
                    return ret
                return True
            if obstruction:
                ret = self.has_rational_point(point=False, obstruction=True,
                                              algorithm='local',
                                              read_cache=False)
                if ret[0]:
                    raise RuntimeError, "Outputs of algorithms in " \
                                        "has_rational_point disagree " \
                                        "for conic %s" % self
                return ret
            if point:
                return False, None
            return False

        if algorithm == 'local':
            if point:
                raise ValueError, "Algorithm 'local' cannot be combined " \
                                  "with point = True in has_rational_point"
            obs = self.local_obstructions(infinite = True, finite = False,
                                          read_cache = read_cache)
            if obs != []:
                if obstruction:
                    return False, obs[0]
                return False
            obs = self.local_obstructions(read_cache = read_cache)
            if obs == []:
                if obstruction:
                    return True, None
                return True
            if obstruction:
                return False, obs[0]
            return False
        if algorithm == 'rnfisnorm':
            from sage.modules.free_module_element import vector
            if obstruction:
                raise ValueError, "Algorithm rnfisnorm cannot be combined " \
                                  "with obstruction = True in " \
                                  "has_rational_point"
            D, T = self.diagonal_matrix()
            abc = [D[0,0], D[1,1], D[2,2]]
            for j in range(3):
                if abc[j] == 0:
                    pt = self.point(T*vector({2:0,j:1}))
                    if point or obstruction:
                        return True, pt
                    return True
            if (-abc[1]/abc[0]).is_square():
                pt = self.point(T*vector([(-abc[1]/abc[0]).sqrt(), 1, 0]))
                if point or obstruction:
                    return True, pt
                return True
            if (-abc[2]/abc[0]).is_square():
                pt = self.point(T*vector([(-abc[2]/abc[0]).sqrt(), 0, 1]))
                if point or obstruction:
                    return True, pt
                return True
            if is_RationalField(B):
                K = B
                [KtoB, BtoK] = [K.hom(K) for i in range(2)]
            else:
                K = B.absolute_field('Y')
                [KtoB, BtoK] = K.structure()
            X = PolynomialRing(K, 'X').gen()
            d = BtoK(-abc[1]/abc[0])
            den = d.denominator()
            L = K.extension(X**2 - d*den**2, names='y')
            isnorm = BtoK(-abc[2]/abc[0]).is_norm(L, element=True)
            if isnorm[0]:

                pt = self.point(T*vector([KtoB(isnorm[1][0]),
                                          KtoB(isnorm[1][1]*den), 1]))
                if point:
                    return True, pt
                return True
            if point:
                return False, None
            return False
        if algorithm == 'qfsolve':
            raise TypeError, "Algorithm qfsolve in has_rational_point only " \
                                 "for conics over QQ, not over %s" % B
        if obstruction:
            raise ValueError, "Invalid combination: obstruction=True and " \
                                 "algorithm=%s" % algorithm

        return ProjectiveConic_field.has_rational_point(self, point = point,
                           algorithm = algorithm, read_cache = False)
示例#16
0
文件: constructor.py 项目: dagss/sage
def HyperellipticCurve(f, h=None, names=None, PP=None, check_squarefree=True):
    r"""
    Returns the hyperelliptic curve `y^2 + h y = f`, for
    univariate polynomials `h` and `f`. If `h`
    is not given, then it defaults to 0.
    
    INPUT:
    
    -  ``f`` - univariate polynomial
    
    -  ``h`` - optional univariate polynomial

    -  ``names``  (default: ``["x","y"]``) - names for the
       coordinate functions

    -  ``check_squarefree`` (default: ``True``) - test if
       the input defines a hyperelliptic curve when f is
       homogenized to degree `2g+2` and h to degree
       `g+1` for some g.

    .. WARNING::

        When setting ``check_squarefree=False`` or using a base ring that is
        not a field, the output curves are not to be trusted. For example, the
        output of ``is_singular`` is always ``False``, without this being
        properly tested in that case.

    .. NOTE::

        The words "hyperelliptic curve" are normally only used for curves of
        genus at least two, but this class allows more general smooth double
        covers of the projective line (conics and elliptic curves), even though
        the class is not meant for those and some outputs may be incorrect.
    
    EXAMPLES:

    Basic examples::

        sage: R.<x> = QQ[]
        sage: HyperellipticCurve(x^5 + x + 1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
        sage: HyperellipticCurve(x^19 + x + 1, x-2)
        Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1

        sage: k.<a> = GF(9); R.<x> = k[]
        sage: HyperellipticCurve(x^3 + x - 1, x+a)
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2

    Characteristic two::

        sage: P.<x> = GF(8,'a')[]
        sage: HyperellipticCurve(x^7+1, x)
        Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + x*y = x^7 + 1
        sage: HyperellipticCurve(x^8+x^7+1, x^4+1)
        Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1

        sage: HyperellipticCurve(x^8+1, x)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: highly singular at infinity.

        sage: HyperellipticCurve(x^8+x^7+1, x^4)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.

        sage: F.<t> = PowerSeriesRing(FiniteField(2))
        sage: P.<x> = PolynomialRing(FractionField(F))
        sage: HyperellipticCurve(x^5+t, x)
        Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2 defined by y^2 + x*y = x^5 + t

    We can change the names of the variables in the output::

        sage: k.<a> = GF(9); R.<x> = k[]    
        sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y'])
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2

    This class also allows curves of genus zero or one, which are strictly
    speaking not hyperelliptic::

        sage: P.<x> = QQ[]
        sage: HyperellipticCurve(x^2+1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1
        sage: HyperellipticCurve(x^4-1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1
        sage: HyperellipticCurve(x^3+2*x+2)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2

    Double roots::

        sage: P.<x> = GF(7)[]
        sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.

        sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)
        Hyperelliptic Curve over Finite Field of size 7 defined by y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3

    The input for a (smooth) hyperelliptic curve of genus `g` should not
    contain polynomials of degree greater than `2g+2`. In the following
    example, the hyperelliptic curve has genus 2 and there exists a model
    `y^2 = F` of degree 6, so the model `y^2 + yh = f` of degree 200 is not
    allowed.::

        sage: P.<x> = QQ[]
        sage: h = x^100
        sage: F = x^6+1
        sage: f = F-h^2/4
        sage: HyperellipticCurve(f, h)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: highly singular at infinity.

        sage: HyperellipticCurve(F)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1

    An example with a singularity over an inseparable extension of the
    base field::

        sage: F.<t> = GF(5)[]
        sage: P.<x> = F[]
        sage: HyperellipticCurve(x^5+t)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.

    Input with integer coefficients creates objects with the integers
    as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).
    In other words, it is checked that the discriminant is non-zero, but it is
    not checked whether the discriminant is a unit in `\ZZ^*`.::

        sage: P.<x> = ZZ[]
        sage: HyperellipticCurve(3*x^7+6*x+6)
        Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
    """
    if (not is_Polynomial(f)) or f == 0:
        raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials " \
                         "and f must be non-zero" % (f,h)
    P = f.parent()
    if h is None:
        h = P(0)
    try:
        h = P(h)
    except TypeError:
        raise TypeError, \
              "Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h)
    df = f.degree()
    dh_2 = 2*h.degree()
    if dh_2 < df:
        g = (df-1)//2
    else:
        g = (dh_2-1)//2
    if check_squarefree:
        # Assuming we are working over a field, this checks that after
        # resolving the singularity at infinity, we get a smooth double cover
        # of P^1.
        if P(2) == 0:
            # characteristic 2
            if h == 0:
                raise ValueError, \
                   "In characteristic 2, argument h (= %s) must be non-zero."%h
            if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2:
                raise ValueError, "Not a hyperelliptic curve: " \
                                  "highly singular at infinity."
            should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2]
        else:
            # characteristic not 2
            F = f + h**2/4
            if not F.degree() in [2*g+1, 2*g+2]:
                raise ValueError, "Not a hyperelliptic curve: " \
                                  "highly singular at infinity."
            should_be_coprime = [F, F.derivative()]
        try:
            smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree()==0
        except (AttributeError, NotImplementedError, TypeError):
            try:
                smooth = should_be_coprime[0].resultant(should_be_coprime[1])!=0
            except (AttributeError, NotImplementedError, TypeError):
                raise NotImplementedError, "Cannot determine whether " \
                      "polynomials %s have a common root. Use " \
                      "check_squarefree=False to skip this check." % \
                      should_be_coprime
        if not smooth:
            raise ValueError, "Not a hyperelliptic curve: " \
                              "singularity in the provided affine patch."
    R = P.base_ring()
    PP = ProjectiveSpace(2, R)
    if names is None:
        names = ["x","y"]
    if is_FiniteField(R):
        if g == 2:
            return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g)
    elif is_RationalField(R):
        if g == 2:
            return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g)
    elif is_pAdicField(R):
        if g == 2:
            return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g)
    else:
        if g == 2:
            return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
示例#17
0
def ProjectiveSpace(n, R=None, names='x'):
    r"""
    Return projective space of dimension `n` over the ring `R`.

    EXAMPLES: The dimension and ring can be given in either order.

    ::

        sage: ProjectiveSpace(3, QQ)
        Projective Space of dimension 3 over Rational Field
        sage: ProjectiveSpace(5, QQ)
        Projective Space of dimension 5 over Rational Field
        sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P
        Projective Space of dimension 2 over Rational Field
        sage: P.coordinate_ring()
        Multivariate Polynomial Ring in X, Y, Z over Rational Field

    The divide operator does base extension.

    ::

        sage: ProjectiveSpace(5)/GF(17)
        Projective Space of dimension 5 over Finite Field of size 17

    The default base ring is `\ZZ`.

    ::

        sage: ProjectiveSpace(5)
        Projective Space of dimension 5 over Integer Ring

    There is also an projective space associated each polynomial ring.

    ::

        sage: R = GF(7)['x,y,z']
        sage: P = ProjectiveSpace(R); P
        Projective Space of dimension 2 over Finite Field of size 7
        sage: P.coordinate_ring()
        Multivariate Polynomial Ring in x, y, z over Finite Field of size 7
        sage: P.coordinate_ring() is R
        True

    ::

        sage: ProjectiveSpace(3, Zp(5), 'y')
        Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20

    ::

        sage: ProjectiveSpace(2,QQ,'x,y,z')
        Projective Space of dimension 2 over Rational Field

    ::

        sage: PS.<x,y>=ProjectiveSpace(1,CC)
        sage: PS
        Projective Space of dimension 1 over Complex Field with 53 bits of precision

    Projective spaces are not cached, i.e., there can be several with
    the same base ring and dimension (to facilitate gluing
    constructions).
    """
    if is_MPolynomialRing(n) and R is None:
        A = ProjectiveSpace(n.ngens()-1, n.base_ring())
        A._coordinate_ring = n
        return A
    if isinstance(R, (int, long, Integer)):
        n, R = R, n
    if R is None:
        R = ZZ  # default is the integers
    if R in _Fields:
        if is_FiniteField(R):
            return ProjectiveSpace_finite_field(n, R, names)
        if is_RationalField(R):
            return ProjectiveSpace_rational_field(n, R, names)
        else:
            return ProjectiveSpace_field(n, R, names)
    elif is_CommutativeRing(R):
        return ProjectiveSpace_ring(n, R, names)
    else:
        raise TypeError("R (=%s) must be a commutative ring"%R)
示例#18
0
def HyperellipticCurve(f, h=None, names=None, PP=None, check_squarefree=True):
    r"""
    Returns the hyperelliptic curve `y^2 + h y = f`, for
    univariate polynomials `h` and `f`. If `h`
    is not given, then it defaults to 0.
    
    INPUT:
    
    -  ``f`` - univariate polynomial
    
    -  ``h`` - optional univariate polynomial

    -  ``names``  (default: ``["x","y"]``) - names for the
       coordinate functions

    -  ``check_squarefree`` (default: ``True``) - test if
       the input defines a hyperelliptic curve when f is
       homogenized to degree `2g+2` and h to degree
       `g+1` for some g.

    .. WARNING::

        When setting ``check_squarefree=False`` or using a base ring that is
        not a field, the output curves are not to be trusted. For example, the
        output of ``is_singular`` is always ``False``, without this being
        properly tested in that case.

    .. NOTE::

        The words "hyperelliptic curve" are normally only used for curves of
        genus at least two, but this class allows more general smooth double
        covers of the projective line (conics and elliptic curves), even though
        the class is not meant for those and some outputs may be incorrect.
    
    EXAMPLES:

    Basic examples::

        sage: R.<x> = QQ[]
        sage: HyperellipticCurve(x^5 + x + 1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
        sage: HyperellipticCurve(x^19 + x + 1, x-2)
        Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1

        sage: k.<a> = GF(9); R.<x> = k[]
        sage: HyperellipticCurve(x^3 + x - 1, x+a)
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2

    Characteristic two::

        sage: P.<x> = GF(8,'a')[]
        sage: HyperellipticCurve(x^7+1, x)
        Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + x*y = x^7 + 1
        sage: HyperellipticCurve(x^8+x^7+1, x^4+1)
        Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1

        sage: HyperellipticCurve(x^8+1, x)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: highly singular at infinity.

        sage: HyperellipticCurve(x^8+x^7+1, x^4)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.

        sage: F.<t> = PowerSeriesRing(FiniteField(2))
        sage: P.<x> = PolynomialRing(FractionField(F))
        sage: HyperellipticCurve(x^5+t, x)
        Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2 defined by y^2 + x*y = x^5 + t

    We can change the names of the variables in the output::

        sage: k.<a> = GF(9); R.<x> = k[]    
        sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y'])
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2

    This class also allows curves of genus zero or one, which are strictly
    speaking not hyperelliptic::

        sage: P.<x> = QQ[]
        sage: HyperellipticCurve(x^2+1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1
        sage: HyperellipticCurve(x^4-1)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1
        sage: HyperellipticCurve(x^3+2*x+2)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2

    Double roots::

        sage: P.<x> = GF(7)[]
        sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.

        sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)
        Hyperelliptic Curve over Finite Field of size 7 defined by y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3

    The input for a (smooth) hyperelliptic curve of genus `g` should not
    contain polynomials of degree greater than `2g+2`. In the following
    example, the hyperelliptic curve has genus 2 and there exists a model
    `y^2 = F` of degree 6, so the model `y^2 + yh = f` of degree 200 is not
    allowed.::

        sage: P.<x> = QQ[]
        sage: h = x^100
        sage: F = x^6+1
        sage: f = F-h^2/4
        sage: HyperellipticCurve(f, h)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: highly singular at infinity.

        sage: HyperellipticCurve(F)
        Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1

    An example with a singularity over an inseparable extension of the
    base field::

        sage: F.<t> = GF(5)[]
        sage: P.<x> = F[]
        sage: HyperellipticCurve(x^5+t)
        Traceback (most recent call last):
        ...
        ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.

    Input with integer coefficients creates objects with the integers
    as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).
    In other words, it is checked that the discriminant is non-zero, but it is
    not checked whether the discriminant is a unit in `\ZZ^*`.::

        sage: P.<x> = ZZ[]
        sage: HyperellipticCurve(3*x^7+6*x+6)
        Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
    """
    if (not is_Polynomial(f)) or f == 0:
        raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials " \
                         "and f must be non-zero" % (f,h)
    P = f.parent()
    if h is None:
        h = P(0)
    try:
        h = P(h)
    except TypeError:
        raise TypeError, \
              "Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h)
    df = f.degree()
    dh_2 = 2 * h.degree()
    if dh_2 < df:
        g = (df - 1) // 2
    else:
        g = (dh_2 - 1) // 2
    if check_squarefree:
        # Assuming we are working over a field, this checks that after
        # resolving the singularity at infinity, we get a smooth double cover
        # of P^1.
        if P(2) == 0:
            # characteristic 2
            if h == 0:
                raise ValueError, \
                   "In characteristic 2, argument h (= %s) must be non-zero."%h
            if h[g + 1] == 0 and f[2 * g + 1]**2 == f[2 * g + 2] * h[g]**2:
                raise ValueError, "Not a hyperelliptic curve: " \
                                  "highly singular at infinity."
            should_be_coprime = [h, f * h.derivative()**2 + f.derivative()**2]
        else:
            # characteristic not 2
            F = f + h**2 / 4
            if not F.degree() in [2 * g + 1, 2 * g + 2]:
                raise ValueError, "Not a hyperelliptic curve: " \
                                  "highly singular at infinity."
            should_be_coprime = [F, F.derivative()]
        try:
            smooth = should_be_coprime[0].gcd(
                should_be_coprime[1]).degree() == 0
        except (AttributeError, NotImplementedError, TypeError):
            try:
                smooth = should_be_coprime[0].resultant(
                    should_be_coprime[1]) != 0
            except (AttributeError, NotImplementedError, TypeError):
                raise NotImplementedError, "Cannot determine whether " \
                      "polynomials %s have a common root. Use " \
                      "check_squarefree=False to skip this check." % \
                      should_be_coprime
        if not smooth:
            raise ValueError, "Not a hyperelliptic curve: " \
                              "singularity in the provided affine patch."
    R = P.base_ring()
    PP = ProjectiveSpace(2, R)
    if names is None:
        names = ["x", "y"]
    if is_FiniteField(R):
        if g == 2:
            return HyperellipticCurve_g2_finite_field(PP,
                                                      f,
                                                      h,
                                                      names=names,
                                                      genus=g)
        else:
            return HyperellipticCurve_finite_field(PP,
                                                   f,
                                                   h,
                                                   names=names,
                                                   genus=g)
    elif is_RationalField(R):
        if g == 2:
            return HyperellipticCurve_g2_rational_field(PP,
                                                        f,
                                                        h,
                                                        names=names,
                                                        genus=g)
        else:
            return HyperellipticCurve_rational_field(PP,
                                                     f,
                                                     h,
                                                     names=names,
                                                     genus=g)
    elif is_pAdicField(R):
        if g == 2:
            return HyperellipticCurve_g2_padic_field(PP,
                                                     f,
                                                     h,
                                                     names=names,
                                                     genus=g)
        else:
            return HyperellipticCurve_padic_field(PP,
                                                  f,
                                                  h,
                                                  names=names,
                                                  genus=g)
    else:
        if g == 2:
            return HyperellipticCurve_g2_generic(PP,
                                                 f,
                                                 h,
                                                 names=names,
                                                 genus=g)
        else:
            return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
示例#19
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
示例#20
0
def EllipticCurve(x=None, y=None, j=None):
    r"""
    There are several ways to construct an elliptic curve:
    
    .. math::
    
       y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6.       
    
    
    - 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 a1=a2=a3=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): Return an elliptic curve with j-invariant
      `j`.  Warning: this is deprecated.  Use ``EllipticCurve_from_j(j)`` 
      or ``EllipticCurve(j=j)`` 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

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


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

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

        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'>
        sage: is_field(SR)
        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'>


    """
    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 rings.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)

    assert x is not None
    
    if is_SymbolicEquation(x):
        x = x.lhs() - x.rhs()
    
    if parent(x) is SR:
        x = x._polynomial_(rings.QQ['x', 'y'])
    
    if rings.is_MPolynomial(x) and y is None:
        f = x
        if f.degree() != 3:
            raise ValueError, "Elliptic curves must be defined by a cubic polynomial."
        if f.degrees() == (3,2):
            x, y = f.parent().gens()
        elif f.degree() == (2,3):
            y, x = f.parent().gens()
        elif len(f.parent().gens()) == 2 or len(f.parent().gens()) == 3 and f.is_homogeneous():
            # We'd need a point too...
            raise NotImplementedError, "Construction of an elliptic curve from a generic cubic not yet implemented."
        else:
            raise ValueError, "Defining polynomial must be a cubic polynomial in two variables."

        try:
            if f.coefficient(x**3) < 0:
                f = -f
            # is there a nicer way to extract the coefficients?
            a1 = a2 = a3 = a4 = a6 = 0
            for coeff, mon in f:
                if mon == x**3:
                    assert coeff == 1
                elif mon == x**2:
                    a2 = coeff
                elif mon == x:
                    a4 = coeff
                elif mon == 1:
                    a6 = coeff
                elif mon == y**2:
                    assert coeff == -1
                elif mon == x*y:
                    a1 = -coeff
                elif mon == y:
                    a3 = -coeff
                else:
                    assert False
            return EllipticCurve([a1, a2, a3, a4, a6])
        except AssertionError:
            raise NotImplementedError, "Construction of an elliptic curve from a generic cubic not yet implemented."
    
    if rings.is_Ring(x):
        if rings.is_RationalField(x):
            return ell_rational_field.EllipticCurve_rational_field(x, y)
        elif rings.is_FiniteField(x) or (rings.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 rings.is_NumberField(x):
            return ell_number_field.EllipticCurve_number_field(x, y)
        elif rings.is_Field(x):
            return ell_field.EllipticCurve_field(x, y)
        return ell_generic.EllipticCurve_generic(x, y)

    if isinstance(x, unicode):
        x = str(x)
        
    if isinstance(x, str):
        return ell_rational_field.EllipticCurve_rational_field(x)
        
    if rings.is_RingElement(x) and y is None:
        from sage.misc.misc import deprecation
        deprecation("'EllipticCurve(j)' is deprecated; use 'EllipticCurve_from_j(j)' or 'EllipticCurve(j=j)' instead.")
        # Fixed for all characteristics and cases by John Cremona
        j=x
        F=j.parent().fraction_field()
        char=F.characteristic()
        if char==2:
            if j==0:
                return EllipticCurve(F, [ 0, 0, 1, 0, 0 ])
            else:
                return EllipticCurve(F, [ 1, 0, 0, 0, 1/j ])
        if char==3:
            if j==0:
                return EllipticCurve(F, [ 0, 0, 0, 1, 0 ])
            else:
                return EllipticCurve(F, [ 0, j, 0, 0, -j**2 ])
        if j == 0:
            return EllipticCurve(F, [ 0, 0, 0, 0, 1 ])
        if j == 1728:
            return EllipticCurve(F, [ 0, 0, 0, 1, 0 ])
        k=j-1728
        return EllipticCurve(F, [0,0,0,-3*j*k, -2*j*k**2])

    if not isinstance(x,list):
        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 rings.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 rings.is_FiniteField(R) or (rings.is_IntegerModRing(R) and R.characteristic().is_prime()):
        return ell_finite_field.EllipticCurve_finite_field(x, y)

    elif rings.is_Field(R):
        return ell_field.EllipticCurve_field(x, y)

    return ell_generic.EllipticCurve_generic(x, y)