Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/hyperelliptic_curves/invariants.py
8821 views
1
r"""
2
Compute invariants of quintics and sextics via ``Ueberschiebung''.
3
4
REFERENCES::
5
6
.. [M] Mestre, Jean-Francois. Construction de courbes de genre $2$ a
7
partir de leurs modules. (French) [Constructing genus-$2$ curves from
8
their moduli] Effective methods in algebraic geometry (Castiglioncello,
9
1990), 313--334, Progr. Math., 94, Birkhauser Boston, Boston, MA, 1991.
10
11
.. [I] Igusa, Jun-ichi. Arithmetic variety of moduli for genus two.
12
Ann. of Math. (2) 72 1960 612--649.
13
14
TODO::
15
16
* Implement invariants in small positive characteristic.
17
18
* Cardona-Quer and additional invariants for classifying automorphism groups.
19
20
AUTHOR::
21
22
* Nick Alexander
23
"""
24
25
from sage.rings.all import ZZ
26
from sage.rings.all import PolynomialRing
27
28
def diffxy(f, x, xtimes, y, ytimes):
29
r"""
30
Differentiate a polynomial ``f``, ``xtimes`` with respect to ``x``, and
31
```ytimes`` with respect to ``y``.
32
33
EXAMPLES::
34
sage: R.<u, v> = QQ[]
35
sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3, u, 0, v, 0)
36
u^2*v^3
37
sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3, u, 2, v, 1)
38
6*v^2
39
sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3, u, 2, v, 2)
40
12*v
41
sage: sage.schemes.hyperelliptic_curves.invariants.diffxy(u^2*v^3 + u^4*v^4, u, 2, v, 2)
42
144*u^2*v^2 + 12*v
43
"""
44
h = f
45
for i in range(xtimes): h = h.derivative(x)
46
for j in range(ytimes): h = h.derivative(y)
47
return h
48
49
def differential_operator(f, g, k):
50
r"""
51
Return the differential operator `(f g)_k` symbolically in the polynomial ring in ``dfdx, dfdy, dgdx, dgdy``.
52
53
This is defined by Mestre on p 315 [M]_:
54
`(f g)_k = \frac{(m - k)! (n - k)!}{m! n!} \left(
55
\frac{\del f}{\del x} \frac{\del g}{\del y} -
56
\frac{\del f}{\del y} \frac{\del g}{\del x} \right)^k ` .
57
58
EXAMPLES::
59
60
sage: from sage.schemes.hyperelliptic_curves.invariants import differential_operator
61
sage: R.<x, y> = QQ[]
62
sage: differential_operator(x, y, 0)
63
1
64
sage: differential_operator(x, y, 1)
65
-dfdy*dgdx + dfdx*dgdy
66
sage: differential_operator(x*y, x*y, 2)
67
1/4*dfdy^2*dgdx^2 - 1/2*dfdx*dfdy*dgdx*dgdy + 1/4*dfdx^2*dgdy^2
68
sage: differential_operator(x^2*y, x*y^2, 2)
69
1/36*dfdy^2*dgdx^2 - 1/18*dfdx*dfdy*dgdx*dgdy + 1/36*dfdx^2*dgdy^2
70
sage: differential_operator(x^2*y, x*y^2, 4)
71
1/576*dfdy^4*dgdx^4 - 1/144*dfdx*dfdy^3*dgdx^3*dgdy + 1/96*dfdx^2*dfdy^2*dgdx^2*dgdy^2 - 1/144*dfdx^3*dfdy*dgdx*dgdy^3 + 1/576*dfdx^4*dgdy^4
72
"""
73
(x, y) = f.parent().gens()
74
n = max(ZZ(f.degree()), ZZ(k))
75
m = max(ZZ(g.degree()), ZZ(k))
76
R, (fx, fy, gx, gy) = PolynomialRing(f.base_ring(), 4, 'dfdx,dfdy,dgdx,dgdy').objgens()
77
const = (m - k).factorial() * (n - k).factorial() / (m.factorial() * n.factorial())
78
U = f.base_ring()(const) * (fx*gy - fy*gx)**k
79
return U
80
81
def diffsymb(U, f, g):
82
r"""
83
Given a differential operator ``U`` in ``dfdx, dfdy, dgdx, dgdy``,
84
represented symbolically by ``U``, apply it to ``f, g``.
85
86
EXAMPLES::
87
88
sage: from sage.schemes.hyperelliptic_curves.invariants import diffsymb
89
sage: R.<x, y> = QQ[]
90
sage: S.<dfdx, dfdy, dgdx, dgdy> = QQ[]
91
sage: [ diffsymb(dd, x^2, y*0 + 1) for dd in S.gens() ]
92
[2*x, 0, 0, 0]
93
sage: [ diffsymb(dd, x*0 + 1, y^2) for dd in S.gens() ]
94
[0, 0, 0, 2*y]
95
sage: [ diffsymb(dd, x^2, y^2) for dd in S.gens() ]
96
[2*x*y^2, 0, 0, 2*x^2*y]
97
98
sage: diffsymb(dfdx + dfdy*dgdy, y*x^2, y^3)
99
2*x*y^4 + 3*x^2*y^2
100
"""
101
(x, y) = f.parent().gens()
102
R, (fx, fy, gx, gy) = PolynomialRing(f.base_ring(), 4, 'dfdx,dfdy,dgdx,dgdy').objgens()
103
res = 0
104
for coeff, mon in list(U):
105
mon = R(mon)
106
a = diffxy(f, x, mon.degree(fx), y, mon.degree(fy))
107
b = diffxy(g, x, mon.degree(gx), y, mon.degree(gy))
108
temp = coeff * a * b
109
res = res + temp
110
return res
111
112
def Ueberschiebung(f, g, k):
113
r"""
114
Return the differential operator `(f g)_k`.
115
116
This is defined by Mestre on page 315:
117
`(f g)_k = \frac{(m - k)! (n - k)!}{m! n!} \left(
118
\frac{\del f}{\del x} \frac{\del g}{\del y} -
119
\frac{\del f}{\del y} \frac{\del g}{\del x} \right)^k ` .
120
121
EXAMPLES::
122
123
sage: from sage.schemes.hyperelliptic_curves.invariants import Ueberschiebung as ub
124
sage: R.<x, y> = QQ[]
125
sage: ub(x, y, 0)
126
x*y
127
sage: ub(x^5 + 1, x^5 + 1, 1)
128
0
129
sage: ub(x^5 + 5*x + 1, x^5 + 5*x + 1, 0)
130
x^10 + 10*x^6 + 2*x^5 + 25*x^2 + 10*x + 1
131
"""
132
U = differential_operator(f, g, k)
133
# U is the (f g)_k = ... of Mestre, p315, symbolically
134
return diffsymb(U, f, g)
135
136
def ubs(f):
137
r"""
138
Given a sextic form `f`, return a dictionary of the invariants of Mestre, p 317 [M]_.
139
140
`f` may be homogeneous in two variables or inhomogeneous in one.
141
142
EXAMPLES::
143
144
sage: from sage.schemes.hyperelliptic_curves.invariants import ubs
145
sage: x = QQ['x'].0
146
sage: ubs(x^6 + 1)
147
{'A': 2, 'C': -2/9, 'B': 2/3, 'D': 0, 'f': x^6 + h^6, 'i': 2*x^2*h^2, 'Delta': -2/3*x^2*h^2, 'y1': 0, 'y3': 0, 'y2': 0}
148
149
sage: R.<u, v> = QQ[]
150
sage: ubs(u^6 + v^6)
151
{'A': 2, 'C': -2/9, 'B': 2/3, 'D': 0, 'f': u^6 + v^6, 'i': 2*u^2*v^2, 'Delta': -2/3*u^2*v^2, 'y1': 0, 'y3': 0, 'y2': 0}
152
153
sage: R.<t> = GF(31)[]
154
sage: ubs(t^6 + 2*t^5 + t^2 + 3*t + 1)
155
{'A': 0, 'C': -15, 'B': -12, 'D': -15, 'f': t^6 + 2*t^5*h + t^2*h^4 + 3*t*h^5 + h^6, 'i': -4*t^4 + 10*t^3*h + 2*t^2*h^2 - 9*t*h^3 - 7*h^4, 'Delta': -10*t^4 + 12*t^3*h + 7*t^2*h^2 - 5*t*h^3 + 2*h^4, 'y1': 4*t^2 - 10*t*h - 13*h^2, 'y3': 4*t^2 - 4*t*h - 9*h^2, 'y2': 6*t^2 - 4*t*h + 2*h^2}
156
"""
157
ub = Ueberschiebung
158
if f.parent().ngens() == 1:
159
f = PolynomialRing(f.parent().base_ring(), 1, f.parent().variable_name())(f)
160
x1, x2 = f.homogenize().parent().gens()
161
f = sum([ f[i]*x1**i*x2**(6-i) for i in range(7) ])
162
U = {}
163
U['f'] = f
164
U['i'] = ub(f, f, 4)
165
U['Delta'] = ub(U['i'], U['i'], 2)
166
U['y1'] = ub(f, U['i'], 4)
167
U['y2'] = ub(U['i'], U['y1'], 2)
168
U['y3'] = ub(U['i'], U['y2'], 2)
169
U['A'] = ub(f, f, 6)
170
U['B'] = ub(U['i'], U['i'], 4)
171
U['C'] = ub(U['i'], U['Delta'], 4)
172
U['D'] = ub(U['y3'], U['y1'], 2)
173
return U
174
175
def clebsch_to_igusa(A, B, C, D):
176
r"""
177
Convert Clebsch invariants `A, B, C, D` to Igusa invariants `I_2, I_4, I_6, I_{10}`.
178
179
EXAMPLES::
180
181
sage: from sage.schemes.hyperelliptic_curves.invariants import clebsch_to_igusa, igusa_to_clebsch
182
sage: clebsch_to_igusa(2, 3, 4, 5)
183
(-240, 17370, 231120, -103098906)
184
sage: igusa_to_clebsch(*clebsch_to_igusa(2, 3, 4, 5))
185
(2, 3, 4, 5)
186
187
sage: Cs = tuple(map(GF(31), (2, 3, 4, 5))); Cs
188
(2, 3, 4, 5)
189
sage: clebsch_to_igusa(*Cs)
190
(8, 10, 15, 26)
191
sage: igusa_to_clebsch(*clebsch_to_igusa(*Cs))
192
(2, 3, 4, 5)
193
"""
194
I2 = -120*A
195
I4 = -720*A**2 + 6750*B
196
I6 = 8640*A**3 - 108000*A*B + 202500*C
197
I10 = -62208*A**5 + 972000*A**3*B + 1620000*A**2*C - 3037500*A*B**2 - 6075000*B*C - 4556250*D
198
return (I2, I4, I6, I10)
199
200
def igusa_to_clebsch(I2, I4, I6, I10):
201
r"""
202
Convert Igusa invariants `I_2, I_4, I_6, I_{10}` to Clebsch invariants `A, B, C, D`.
203
204
EXAMPLES::
205
206
sage: from sage.schemes.hyperelliptic_curves.invariants import clebsch_to_igusa, igusa_to_clebsch
207
sage: igusa_to_clebsch(-2400, 173700, 23112000, -10309890600)
208
(20, 342/5, 2512/5, 43381012/1125)
209
sage: clebsch_to_igusa(*igusa_to_clebsch(-2400, 173700, 23112000, -10309890600))
210
(-2400, 173700, 23112000, -10309890600)
211
212
sage: Is = tuple(map(GF(31), (-2400, 173700, 23112000, -10309890600))); Is
213
(18, 7, 12, 27)
214
sage: igusa_to_clebsch(*Is)
215
(20, 25, 25, 12)
216
sage: clebsch_to_igusa(*igusa_to_clebsch(*Is))
217
(18, 7, 12, 27)
218
"""
219
A = -(+ I2) / 120
220
B = -(- I2**2 - 20*I4)/135000
221
C = -(+ I2**3 + 80*I2*I4 - 600*I6)/121500000
222
D = -(+ 9*I2**5 + 700*I2**3*I4 - 3600*I2**2*I6 - 12400*I2*I4**2 + 48000*I4*I6 + 10800000*I10) / 49207500000000
223
return (A, B, C, D)
224
225
226
def clebsch_invariants(f):
227
r"""
228
Given a sextic form `f`, return the Clebsch invariants `(A, B, C, D)` of Mestre, p 317, [M]_.
229
230
`f` may be homogeneous in two variables or inhomogeneous in one.
231
232
EXAMPLES::
233
234
sage: R.<x, y> = QQ[]
235
sage: clebsch_invariants(x^6 + y^6)
236
(2, 2/3, -2/9, 0)
237
sage: R.<x> = QQ[]
238
sage: clebsch_invariants(x^6 + x^5 + x^4 + x^2 + 2)
239
(62/15, 15434/5625, -236951/140625, 229930748/791015625)
240
241
sage: magma(x^6 + 1).ClebschInvariants() # optional - magma
242
[ 2, 2/3, -2/9, 0 ]
243
sage: magma(x^6 + x^5 + x^4 + x^2 + 2).ClebschInvariants() # optional - magma
244
[ 62/15, 15434/5625, -236951/140625, 229930748/791015625 ]
245
"""
246
R = f.parent().base_ring()
247
if R.characteristic() in [2, 3, 5]:
248
raise NotImplementedError, "Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5"
249
250
U = ubs(f)
251
L = U['A'], U['B'], U['C'], U['D']
252
assert all(t.is_constant() for t in L)
253
return tuple([ t.constant_coefficient() for t in L ])
254
255
def igusa_clebsch_invariants(f):
256
r"""
257
Given a sextic form `f`, return the Igusa-Clebsch invariants `I_2, I_4, I_6, I_{10}` of Igusa and Clebsch [I]_.
258
259
`f` may be homogeneous in two variables or inhomogeneous in one.
260
261
EXAMPLES::
262
263
sage: R.<x, y> = QQ[]
264
sage: igusa_clebsch_invariants(x^6 + y^6)
265
(-240, 1620, -119880, -46656)
266
sage: R.<x> = QQ[]
267
sage: igusa_clebsch_invariants(x^6 + x^5 + x^4 + x^2 + 2)
268
(-496, 6220, -955932, -1111784)
269
270
sage: magma(x^6 + 1).IgusaClebschInvariants() # optional - magma
271
[ -240, 1620, -119880, -46656 ]
272
sage: magma(x^6 + x^5 + x^4 + x^2 + 2).IgusaClebschInvariants() # optional - magma
273
[ -496, 6220, -955932, -1111784 ]
274
275
TESTS::
276
277
Let's check a symbolic example::
278
279
sage: R.<a, b, c, d, e> = QQ[]
280
sage: S.<x> = R[]
281
sage: igusa_clebsch_invariants(x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e)[0]
282
6*b^2 - 16*a*c + 40*d
283
284
sage: absolute_igusa_invariants_wamelen(GF(5)['x'](x^6 - 2*x))
285
Traceback (most recent call last):
286
...
287
NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5
288
"""
289
return clebsch_to_igusa(*clebsch_invariants(f))
290
291
def absolute_igusa_invariants_wamelen(f):
292
r"""
293
Given a sextic form `f`, return the three absolute Igusa invariants used by van Wamelen [W]_.
294
295
`f` may be homogeneous in two variables or inhomogeneous in one.
296
297
REFERENCES::
298
299
.. [W] van Wamelen, Paul. Examples of genus two CM curves defined
300
over the rationals.
301
Math. Comp. 68 (1999), no. 225, 307--320.
302
303
EXAMPLES::
304
305
sage: R.<x> = QQ[]
306
sage: absolute_igusa_invariants_wamelen(x^5 - 1)
307
(0, 0, 0)
308
309
The following example can be checked against van Wamelen's paper:
310
311
sage: i1, i2, i3 = absolute_igusa_invariants_wamelen(-x^5 + 3*x^4 + 2*x^3 - 6*x^2 - 3*x + 1)
312
sage: map(factor, (i1, i2, i3))
313
[2^7 * 3^15, 2^5 * 3^11 * 5, 2^4 * 3^9 * 31]
314
315
TESTS::
316
317
sage: absolute_igusa_invariants_wamelen(GF(3)['x'](x^5 - 2*x))
318
Traceback (most recent call last):
319
...
320
NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5
321
"""
322
I2, I4, I6, I10 = igusa_clebsch_invariants(f)
323
i1 = I2**5/I10
324
i2 = I2**3*I4/I10
325
i3 = I2**2*I6/I10
326
return (i1, i2, i3)
327
328
def absolute_igusa_invariants_kohel(f):
329
r"""
330
Given a sextic form `f`, return the three absolute Igusa invariants used by Kohel [K]_.
331
332
`f` may be homogeneous in two variables or inhomogeneous in one.
333
334
REFERENCES::
335
336
.. [K] Kohel, David. ECHIDNA: Databases for Elliptic Curves and Higher Dimensional Analogues.
337
Available at http://echidna.maths.usyd.edu.au/~kohel/dbs/
338
339
EXAMPLES::
340
341
sage: R.<x> = QQ[]
342
sage: absolute_igusa_invariants_kohel(x^5 - 1)
343
(0, 0, 0)
344
sage: absolute_igusa_invariants_kohel(x^5 - x)
345
(100, -20000, -2000)
346
347
The following example can be checked against Kohel's database [K]_:
348
349
sage: i1, i2, i3 = absolute_igusa_invariants_kohel(-x^5 + 3*x^4 + 2*x^3 - 6*x^2 - 3*x + 1)
350
sage: map(factor, (i1, i2, i3))
351
[2^2 * 3^5 * 5 * 31, 2^5 * 3^11 * 5, 2^4 * 3^9 * 31]
352
sage: map(factor, (150660, 28343520, 9762768))
353
[2^2 * 3^5 * 5 * 31, 2^5 * 3^11 * 5, 2^4 * 3^9 * 31]
354
355
TESTS::
356
357
sage: absolute_igusa_invariants_kohel(GF(2)['x'](x^5 - x))
358
Traceback (most recent call last):
359
...
360
NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5
361
"""
362
I2, I4, I6, I10 = igusa_clebsch_invariants(f)
363
i1 = I4*I6/I10
364
i2 = I2**3*I4/I10
365
i3 = I2**2*I6/I10
366
return (i1, i2, i3)
367
368