Path: blob/master/src/sage/schemes/plane_conics/constructor.py
8820 views
r"""1Plane conic constructor23AUTHORS:45- Marco Streng (2010-07-20)67- Nick Alexander (2008-01-08)89"""10#*****************************************************************************11# Copyright (C) 2008 Nick Alexander <[email protected]>12# Copyright (C) 2009/2010 Marco Streng <[email protected]>13#14# Distributed under the terms of the GNU General Public License (GPL)15#16# This code is distributed in the hope that it will be useful,17# but WITHOUT ANY WARRANTY; without even the implied warranty of18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU19# General Public License for more details.20#21# The full text of the GPL is available at:22#23# http://www.gnu.org/licenses/24#*****************************************************************************2526from sage.matrix.constructor import Matrix27from sage.modules.free_module_element import vector28from sage.quadratic_forms.all import is_QuadraticForm29from sage.rings.all import (PolynomialRing,30is_PrimeFiniteField31)3233from sage.rings.integral_domain import is_IntegralDomain34from sage.rings.rational_field import is_RationalField35from sage.rings.finite_rings.constructor import is_FiniteField36from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial3738from sage.rings.number_field.number_field import is_NumberField39from sage.schemes.projective.projective_space import ProjectiveSpace40from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field41from sage.schemes.affine.affine_point import SchemeMorphism_point_affine42from sage.structure.all import Sequence43from sage.structure.element import is_Matrix4445from con_field import ProjectiveConic_field46from con_finite_field import ProjectiveConic_finite_field47from con_prime_finite_field import ProjectiveConic_prime_finite_field48from con_number_field import ProjectiveConic_number_field49from con_rational_field import ProjectiveConic_rational_field5051def Conic(base_field, F=None, names=None, unique=True):52r"""53Return the plane projective conic curve defined by ``F``54over ``base_field``.5556The input form ``Conic(F, names=None)`` is also accepted,57in which case the fraction field of the base ring of ``F``58is used as base field.5960INPUT:6162- ``base_field`` -- The base field of the conic.6364- ``names`` -- a list, tuple, or comma separated string65of three variable names specifying the names66of the coordinate functions of the ambient67space `\Bold{P}^3`. If not specified or read68off from ``F``, then this defaults to ``'x,y,z'``.6970- ``F`` -- a polynomial, list, matrix, ternary quadratic form,71or list or tuple of 5 points in the plane.7273If ``F`` is a polynomial or quadratic form,74then the output is the curve in the projective plane75defined by ``F = 0``.7677If ``F`` is a polynomial, then it must be a polynomial78of degree at most 2 in 2 variables, or a homogeneous79polynomial in of degree 2 in 3 variables.8081If ``F`` is a matrix, then the output is the zero locus82of `(x,y,z) F (x,y,z)^t`.8384If ``F`` is a list of coefficients, then it has85length 3 or 6 and gives the coefficients of86the monomials `x^2, y^2, z^2` or all 6 monomials87`x^2, xy, xz, y^2, yz, z^2` in lexicographic order.8889If ``F`` is a list of 5 points in the plane, then the output90is a conic through those points.9192- ``unique`` -- Used only if ``F`` is a list of points in the plane.93If the conic through the points is not unique, then94raise ``ValueError`` if and only if ``unique`` is True9596OUTPUT:9798A plane projective conic curve defined by ``F`` over a field.99100EXAMPLES:101102Conic curves given by polynomials ::103104sage: X,Y,Z = QQ['X,Y,Z'].gens()105sage: Conic(X^2 - X*Y + Y^2 - Z^2)106Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2107sage: x,y = GF(7)['x,y'].gens()108sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W')109Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2110111Conic curves given by matrices ::112113sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z')114Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2115116sage: x,y,z = GF(11)['x,y,z'].gens()117sage: C = Conic(x^2+y^2-2*z^2); C118Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2119sage: Conic(C.symmetric_matrix(), 'x,y,z')120Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2121122Conics given by coefficients ::123124sage: Conic(QQ, [1,2,3])125Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2126sage: Conic(GF(7), [1,2,3,4,5,6], 'X')127Projective 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^2128129The conic through a set of points ::130131sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C132Projective 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^2133sage: C.rational_point()134(10 : 2 : 1)135sage: C.point([3,4])136(3 : 4 : 1)137138sage: a=AffineSpace(GF(13),2)139sage: Conic([a([x,x^2]) for x in range(5)])140Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z141"""142if not (is_IntegralDomain(base_field) or base_field == None):143if names is None:144names = F145F = base_field146base_field = None147if isinstance(F, (list,tuple)):148if len(F) == 1:149return Conic(base_field, F[0], names)150if names == None:151names = 'x,y,z'152if len(F) == 5:153L=[]154for f in F:155if isinstance(f, SchemeMorphism_point_affine):156C = Sequence(f, universe = base_field)157if len(C) != 2:158raise TypeError, "points in F (=%s) must be planar"%F159C.append(1)160elif isinstance(f, SchemeMorphism_point_projective_field):161C = Sequence(f, universe = base_field)162elif isinstance(f, (list, tuple)):163C = Sequence(f, universe = base_field)164if len(C) == 2:165C.append(1)166else:167raise TypeError, "F (=%s) must be a sequence of planar " \168"points" % F169if len(C) != 3:170raise TypeError, "points in F (=%s) must be planar" % F171P = C.universe()172if not is_IntegralDomain(P):173raise TypeError, "coordinates of points in F (=%s) must " \174"be in an integral domain" % F175L.append(Sequence([C[0]**2, C[0]*C[1], C[0]*C[2], C[1]**2,176C[1]*C[2], C[2]**2], P.fraction_field()))177M=Matrix(L)178if unique and M.rank() != 5:179raise ValueError, "points in F (=%s) do not define a unique " \180"conic" % F181con = Conic(base_field, Sequence(M.right_kernel().gen()), names)182con.point(F[0])183return con184F = Sequence(F, universe = base_field)185base_field = F.universe().fraction_field()186temp_ring = PolynomialRing(base_field, 3, names)187(x,y,z) = temp_ring.gens()188if len(F) == 3:189return Conic(F[0]*x**2 + F[1]*y**2 + F[2]*z**2)190if len(F) == 6:191return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \192F[4]*y*z + F[5]*z**2)193raise TypeError, "F (=%s) must be a sequence of 3 or 6" \194"coefficients" % F195if is_QuadraticForm(F):196F = F.matrix()197if is_Matrix(F) and F.is_square() and F.ncols() == 3:198if names == None:199names = 'x,y,z'200temp_ring = PolynomialRing(F.base_ring(), 3, names)201F = vector(temp_ring.gens()) * F * vector(temp_ring.gens())202203if not is_MPolynomial(F):204raise TypeError, "F (=%s) must be a three-variable polynomial or " \205"a sequence of points or coefficients" % F206207if F.total_degree() != 2:208raise TypeError, "F (=%s) must have degree 2" % F209210if base_field == None:211base_field = F.base_ring()212if not is_IntegralDomain(base_field):213raise ValueError, "Base field (=%s) must be a field" % base_field214base_field = base_field.fraction_field()215if names == None:216names = F.parent().variable_names()217pol_ring = PolynomialRing(base_field, 3, names)218219if F.parent().ngens() == 2:220(x,y,z) = pol_ring.gens()221F = pol_ring(F(x/z,y/z)*z**2)222223if F == 0:224raise ValueError, "F must be nonzero over base field %s" % base_field225226if F.total_degree() != 2:227raise TypeError, "F (=%s) must have degree 2 over base field %s" % \228(F, base_field)229230if F.parent().ngens() == 3:231P2 = ProjectiveSpace(2, base_field, names)232if is_PrimeFiniteField(base_field):233return ProjectiveConic_prime_finite_field(P2, F)234if is_FiniteField(base_field):235return ProjectiveConic_finite_field(P2, F)236if is_RationalField(base_field):237return ProjectiveConic_rational_field(P2, F)238if is_NumberField(base_field):239return ProjectiveConic_number_field(P2, F)240return ProjectiveConic_field(P2, F)241242raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F243244245