Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/hyperelliptic_curves/constructor.py
8820 views
1
"""
2
Hyperelliptic curve constructor
3
"""
4
5
#*****************************************************************************
6
# Copyright (C) 2006 David Kohel <[email protected]>
7
# Distributed under the terms of the GNU General Public License (GPL)
8
# http://www.gnu.org/licenses/
9
#*****************************************************************************
10
11
from sage.schemes.projective.projective_space import ProjectiveSpace
12
13
from hyperelliptic_generic import HyperellipticCurve_generic
14
from hyperelliptic_finite_field import HyperellipticCurve_finite_field
15
from hyperelliptic_rational_field import HyperellipticCurve_rational_field
16
from hyperelliptic_padic_field import HyperellipticCurve_padic_field
17
from hyperelliptic_g2_generic import HyperellipticCurve_g2_generic
18
from hyperelliptic_g2_finite_field import HyperellipticCurve_g2_finite_field
19
from hyperelliptic_g2_rational_field import HyperellipticCurve_g2_rational_field
20
from hyperelliptic_g2_padic_field import HyperellipticCurve_g2_padic_field
21
22
from sage.rings.padics.all import is_pAdicField
23
24
from sage.rings.rational_field import is_RationalField
25
from sage.rings.finite_rings.constructor import is_FiniteField
26
from sage.rings.polynomial.polynomial_element import is_Polynomial
27
28
29
def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):
30
r"""
31
Returns the hyperelliptic curve `y^2 + h y = f`, for
32
univariate polynomials `h` and `f`. If `h`
33
is not given, then it defaults to 0.
34
35
INPUT:
36
37
- ``f`` - univariate polynomial
38
39
- ``h`` - optional univariate polynomial
40
41
- ``names`` (default: ``["x","y"]``) - names for the
42
coordinate functions
43
44
- ``check_squarefree`` (default: ``True``) - test if
45
the input defines a hyperelliptic curve when f is
46
homogenized to degree `2g+2` and h to degree
47
`g+1` for some g.
48
49
.. WARNING::
50
51
When setting ``check_squarefree=False`` or using a base ring that is
52
not a field, the output curves are not to be trusted. For example, the
53
output of ``is_singular`` is always ``False``, without this being
54
properly tested in that case.
55
56
.. NOTE::
57
58
The words "hyperelliptic curve" are normally only used for curves of
59
genus at least two, but this class allows more general smooth double
60
covers of the projective line (conics and elliptic curves), even though
61
the class is not meant for those and some outputs may be incorrect.
62
63
EXAMPLES:
64
65
Basic examples::
66
67
sage: R.<x> = QQ[]
68
sage: HyperellipticCurve(x^5 + x + 1)
69
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
70
sage: HyperellipticCurve(x^19 + x + 1, x-2)
71
Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1
72
73
sage: k.<a> = GF(9); R.<x> = k[]
74
sage: HyperellipticCurve(x^3 + x - 1, x+a)
75
Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2
76
77
Characteristic two::
78
79
sage: P.<x> = GF(8,'a')[]
80
sage: HyperellipticCurve(x^7+1, x)
81
Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + x*y = x^7 + 1
82
sage: HyperellipticCurve(x^8+x^7+1, x^4+1)
83
Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1
84
85
sage: HyperellipticCurve(x^8+1, x)
86
Traceback (most recent call last):
87
...
88
ValueError: Not a hyperelliptic curve: highly singular at infinity.
89
90
sage: HyperellipticCurve(x^8+x^7+1, x^4)
91
Traceback (most recent call last):
92
...
93
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
94
95
sage: F.<t> = PowerSeriesRing(FiniteField(2))
96
sage: P.<x> = PolynomialRing(FractionField(F))
97
sage: HyperellipticCurve(x^5+t, x)
98
Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2 defined by y^2 + x*y = x^5 + t
99
100
We can change the names of the variables in the output::
101
102
sage: k.<a> = GF(9); R.<x> = k[]
103
sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y'])
104
Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2
105
106
This class also allows curves of genus zero or one, which are strictly
107
speaking not hyperelliptic::
108
109
sage: P.<x> = QQ[]
110
sage: HyperellipticCurve(x^2+1)
111
Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1
112
sage: HyperellipticCurve(x^4-1)
113
Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1
114
sage: HyperellipticCurve(x^3+2*x+2)
115
Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2
116
117
Double roots::
118
119
sage: P.<x> = GF(7)[]
120
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))
121
Traceback (most recent call last):
122
...
123
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
124
125
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)
126
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
127
128
The input for a (smooth) hyperelliptic curve of genus `g` should not
129
contain polynomials of degree greater than `2g+2`. In the following
130
example, the hyperelliptic curve has genus 2 and there exists a model
131
`y^2 = F` of degree 6, so the model `y^2 + yh = f` of degree 200 is not
132
allowed.::
133
134
sage: P.<x> = QQ[]
135
sage: h = x^100
136
sage: F = x^6+1
137
sage: f = F-h^2/4
138
sage: HyperellipticCurve(f, h)
139
Traceback (most recent call last):
140
...
141
ValueError: Not a hyperelliptic curve: highly singular at infinity.
142
143
sage: HyperellipticCurve(F)
144
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1
145
146
An example with a singularity over an inseparable extension of the
147
base field::
148
149
sage: F.<t> = GF(5)[]
150
sage: P.<x> = F[]
151
sage: HyperellipticCurve(x^5+t)
152
Traceback (most recent call last):
153
...
154
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
155
156
Input with integer coefficients creates objects with the integers
157
as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).
158
In other words, it is checked that the discriminant is non-zero, but it is
159
not checked whether the discriminant is a unit in `\ZZ^*`.::
160
161
sage: P.<x> = ZZ[]
162
sage: HyperellipticCurve(3*x^7+6*x+6)
163
Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
164
165
TESTS:
166
167
Check that `f` can be a constant (see :trac:`15516`)::
168
169
sage: R.<u> = PolynomialRing(Rationals())
170
sage: HyperellipticCurve(-12, u^4 + 7)
171
Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 7)*y = -12
172
173
"""
174
# F is the discriminant; use this for the type check
175
# rather than f and h, one of which might be constant.
176
F = h**2 + 4*f
177
if not is_Polynomial(F):
178
raise TypeError("Arguments f (= %s) and h (= %s) must be polynomials" % (f, h))
179
P = F.parent()
180
f = P(f)
181
h = P(h)
182
df = f.degree()
183
dh_2 = 2*h.degree()
184
if dh_2 < df:
185
g = (df-1)//2
186
else:
187
g = (dh_2-1)//2
188
if check_squarefree:
189
# Assuming we are working over a field, this checks that after
190
# resolving the singularity at infinity, we get a smooth double cover
191
# of P^1.
192
if P(2) == 0:
193
# characteristic 2
194
if h == 0:
195
raise ValueError, \
196
"In characteristic 2, argument h (= %s) must be non-zero."%h
197
if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2:
198
raise ValueError, "Not a hyperelliptic curve: " \
199
"highly singular at infinity."
200
should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2]
201
else:
202
# characteristic not 2
203
if not F.degree() in [2*g+1, 2*g+2]:
204
raise ValueError, "Not a hyperelliptic curve: " \
205
"highly singular at infinity."
206
should_be_coprime = [F, F.derivative()]
207
try:
208
smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree()==0
209
except (AttributeError, NotImplementedError, TypeError):
210
try:
211
smooth = should_be_coprime[0].resultant(should_be_coprime[1])!=0
212
except (AttributeError, NotImplementedError, TypeError):
213
raise NotImplementedError, "Cannot determine whether " \
214
"polynomials %s have a common root. Use " \
215
"check_squarefree=False to skip this check." % \
216
should_be_coprime
217
if not smooth:
218
raise ValueError, "Not a hyperelliptic curve: " \
219
"singularity in the provided affine patch."
220
R = P.base_ring()
221
PP = ProjectiveSpace(2, R)
222
if names is None:
223
names = ["x","y"]
224
if is_FiniteField(R):
225
if g == 2:
226
return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g)
227
else:
228
return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g)
229
elif is_RationalField(R):
230
if g == 2:
231
return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g)
232
else:
233
return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g)
234
elif is_pAdicField(R):
235
if g == 2:
236
return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g)
237
else:
238
return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g)
239
else:
240
if g == 2:
241
return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g)
242
else:
243
return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
244
245