Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/plane_conics/constructor.py
8820 views
1
r"""
2
Plane conic constructor
3
4
AUTHORS:
5
6
- Marco Streng (2010-07-20)
7
8
- Nick Alexander (2008-01-08)
9
10
"""
11
#*****************************************************************************
12
# Copyright (C) 2008 Nick Alexander <[email protected]>
13
# Copyright (C) 2009/2010 Marco Streng <[email protected]>
14
#
15
# Distributed under the terms of the GNU General Public License (GPL)
16
#
17
# This code is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
# General Public License for more details.
21
#
22
# The full text of the GPL is available at:
23
#
24
# http://www.gnu.org/licenses/
25
#*****************************************************************************
26
27
from sage.matrix.constructor import Matrix
28
from sage.modules.free_module_element import vector
29
from sage.quadratic_forms.all import is_QuadraticForm
30
from sage.rings.all import (PolynomialRing,
31
is_PrimeFiniteField
32
)
33
34
from sage.rings.integral_domain import is_IntegralDomain
35
from sage.rings.rational_field import is_RationalField
36
from sage.rings.finite_rings.constructor import is_FiniteField
37
from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial
38
39
from sage.rings.number_field.number_field import is_NumberField
40
from sage.schemes.projective.projective_space import ProjectiveSpace
41
from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field
42
from sage.schemes.affine.affine_point import SchemeMorphism_point_affine
43
from sage.structure.all import Sequence
44
from sage.structure.element import is_Matrix
45
46
from con_field import ProjectiveConic_field
47
from con_finite_field import ProjectiveConic_finite_field
48
from con_prime_finite_field import ProjectiveConic_prime_finite_field
49
from con_number_field import ProjectiveConic_number_field
50
from con_rational_field import ProjectiveConic_rational_field
51
52
def Conic(base_field, F=None, names=None, unique=True):
53
r"""
54
Return the plane projective conic curve defined by ``F``
55
over ``base_field``.
56
57
The input form ``Conic(F, names=None)`` is also accepted,
58
in which case the fraction field of the base ring of ``F``
59
is used as base field.
60
61
INPUT:
62
63
- ``base_field`` -- The base field of the conic.
64
65
- ``names`` -- a list, tuple, or comma separated string
66
of three variable names specifying the names
67
of the coordinate functions of the ambient
68
space `\Bold{P}^3`. If not specified or read
69
off from ``F``, then this defaults to ``'x,y,z'``.
70
71
- ``F`` -- a polynomial, list, matrix, ternary quadratic form,
72
or list or tuple of 5 points in the plane.
73
74
If ``F`` is a polynomial or quadratic form,
75
then the output is the curve in the projective plane
76
defined by ``F = 0``.
77
78
If ``F`` is a polynomial, then it must be a polynomial
79
of degree at most 2 in 2 variables, or a homogeneous
80
polynomial in of degree 2 in 3 variables.
81
82
If ``F`` is a matrix, then the output is the zero locus
83
of `(x,y,z) F (x,y,z)^t`.
84
85
If ``F`` is a list of coefficients, then it has
86
length 3 or 6 and gives the coefficients of
87
the monomials `x^2, y^2, z^2` or all 6 monomials
88
`x^2, xy, xz, y^2, yz, z^2` in lexicographic order.
89
90
If ``F`` is a list of 5 points in the plane, then the output
91
is a conic through those points.
92
93
- ``unique`` -- Used only if ``F`` is a list of points in the plane.
94
If the conic through the points is not unique, then
95
raise ``ValueError`` if and only if ``unique`` is True
96
97
OUTPUT:
98
99
A plane projective conic curve defined by ``F`` over a field.
100
101
EXAMPLES:
102
103
Conic curves given by polynomials ::
104
105
sage: X,Y,Z = QQ['X,Y,Z'].gens()
106
sage: Conic(X^2 - X*Y + Y^2 - Z^2)
107
Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2
108
sage: x,y = GF(7)['x,y'].gens()
109
sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W')
110
Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2
111
112
Conic curves given by matrices ::
113
114
sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z')
115
Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2
116
117
sage: x,y,z = GF(11)['x,y,z'].gens()
118
sage: C = Conic(x^2+y^2-2*z^2); C
119
Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2
120
sage: Conic(C.symmetric_matrix(), 'x,y,z')
121
Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2
122
123
Conics given by coefficients ::
124
125
sage: Conic(QQ, [1,2,3])
126
Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2
127
sage: Conic(GF(7), [1,2,3,4,5,6], 'X')
128
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
129
130
The conic through a set of points ::
131
132
sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C
133
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
134
sage: C.rational_point()
135
(10 : 2 : 1)
136
sage: C.point([3,4])
137
(3 : 4 : 1)
138
139
sage: a=AffineSpace(GF(13),2)
140
sage: Conic([a([x,x^2]) for x in range(5)])
141
Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z
142
"""
143
if not (is_IntegralDomain(base_field) or base_field == None):
144
if names is None:
145
names = F
146
F = base_field
147
base_field = None
148
if isinstance(F, (list,tuple)):
149
if len(F) == 1:
150
return Conic(base_field, F[0], names)
151
if names == None:
152
names = 'x,y,z'
153
if len(F) == 5:
154
L=[]
155
for f in F:
156
if isinstance(f, SchemeMorphism_point_affine):
157
C = Sequence(f, universe = base_field)
158
if len(C) != 2:
159
raise TypeError, "points in F (=%s) must be planar"%F
160
C.append(1)
161
elif isinstance(f, SchemeMorphism_point_projective_field):
162
C = Sequence(f, universe = base_field)
163
elif isinstance(f, (list, tuple)):
164
C = Sequence(f, universe = base_field)
165
if len(C) == 2:
166
C.append(1)
167
else:
168
raise TypeError, "F (=%s) must be a sequence of planar " \
169
"points" % F
170
if len(C) != 3:
171
raise TypeError, "points in F (=%s) must be planar" % F
172
P = C.universe()
173
if not is_IntegralDomain(P):
174
raise TypeError, "coordinates of points in F (=%s) must " \
175
"be in an integral domain" % F
176
L.append(Sequence([C[0]**2, C[0]*C[1], C[0]*C[2], C[1]**2,
177
C[1]*C[2], C[2]**2], P.fraction_field()))
178
M=Matrix(L)
179
if unique and M.rank() != 5:
180
raise ValueError, "points in F (=%s) do not define a unique " \
181
"conic" % F
182
con = Conic(base_field, Sequence(M.right_kernel().gen()), names)
183
con.point(F[0])
184
return con
185
F = Sequence(F, universe = base_field)
186
base_field = F.universe().fraction_field()
187
temp_ring = PolynomialRing(base_field, 3, names)
188
(x,y,z) = temp_ring.gens()
189
if len(F) == 3:
190
return Conic(F[0]*x**2 + F[1]*y**2 + F[2]*z**2)
191
if len(F) == 6:
192
return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \
193
F[4]*y*z + F[5]*z**2)
194
raise TypeError, "F (=%s) must be a sequence of 3 or 6" \
195
"coefficients" % F
196
if is_QuadraticForm(F):
197
F = F.matrix()
198
if is_Matrix(F) and F.is_square() and F.ncols() == 3:
199
if names == None:
200
names = 'x,y,z'
201
temp_ring = PolynomialRing(F.base_ring(), 3, names)
202
F = vector(temp_ring.gens()) * F * vector(temp_ring.gens())
203
204
if not is_MPolynomial(F):
205
raise TypeError, "F (=%s) must be a three-variable polynomial or " \
206
"a sequence of points or coefficients" % F
207
208
if F.total_degree() != 2:
209
raise TypeError, "F (=%s) must have degree 2" % F
210
211
if base_field == None:
212
base_field = F.base_ring()
213
if not is_IntegralDomain(base_field):
214
raise ValueError, "Base field (=%s) must be a field" % base_field
215
base_field = base_field.fraction_field()
216
if names == None:
217
names = F.parent().variable_names()
218
pol_ring = PolynomialRing(base_field, 3, names)
219
220
if F.parent().ngens() == 2:
221
(x,y,z) = pol_ring.gens()
222
F = pol_ring(F(x/z,y/z)*z**2)
223
224
if F == 0:
225
raise ValueError, "F must be nonzero over base field %s" % base_field
226
227
if F.total_degree() != 2:
228
raise TypeError, "F (=%s) must have degree 2 over base field %s" % \
229
(F, base_field)
230
231
if F.parent().ngens() == 3:
232
P2 = ProjectiveSpace(2, base_field, names)
233
if is_PrimeFiniteField(base_field):
234
return ProjectiveConic_prime_finite_field(P2, F)
235
if is_FiniteField(base_field):
236
return ProjectiveConic_finite_field(P2, F)
237
if is_RationalField(base_field):
238
return ProjectiveConic_rational_field(P2, F)
239
if is_NumberField(base_field):
240
return ProjectiveConic_number_field(P2, F)
241
return ProjectiveConic_field(P2, F)
242
243
raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
244
245