Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/elliptic_curves/ell_field.py
4145 views
1
r"""
2
Elliptic curves over a general field
3
4
This module defines the class ``EllipticCurve_field``, based on
5
``EllipticCurve_generic``, for elliptic curves over general fields.
6
7
"""
8
9
#*****************************************************************************
10
# Copyright (C) 2006 William Stein <[email protected]>
11
#
12
# Distributed under the terms of the GNU General Public License (GPL)
13
#
14
# http://www.gnu.org/licenses/
15
#*****************************************************************************
16
17
import ell_generic
18
import sage.rings.all as rings
19
from constructor import EllipticCurve
20
21
from ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel
22
from ell_wp import weierstrass_p
23
24
class EllipticCurve_field(ell_generic.EllipticCurve_generic):
25
26
base_field = ell_generic.EllipticCurve_generic.base_ring
27
28
# Twists: rewritten by John Cremona as follows:
29
#
30
# Quadratic twist allowed except when char=2, j=0
31
# Quartic twist allowed only if j=1728!=0 (so char!=2,3)
32
# Sextic twist allowed only if j=0!=1728 (so char!=2,3)
33
#
34
# More complicated twists exist in theory for char=2,3 and
35
# j=0=1728, but I have never worked them out or seen them used!
36
#
37
38
r"""
39
Twists: rewritten by John Cremona as follows:
40
41
The following twists are implemented:
42
43
- Quadratic twist: except when char=2 and `j=0`.
44
- Quartic twist: only if `j=1728\not=0` (so not if char=2,3).
45
- Sextic twist: only if `j=0\not=1728` (so not if char=2,3).
46
47
More complicated twists exist in theory for char=2,3 and j=0=1728,
48
but are not implemented.
49
"""
50
51
def quadratic_twist(self, D=None):
52
"""
53
Return the quadratic twist of this curve by ``D``.
54
55
INPUT:
56
57
- ``D`` (default None) the twisting parameter (see below).
58
59
In characteristics other than 2, `D` must be nonzero, and the
60
twist is isomorphic to self after adjoining `\sqrt(D)` to the
61
base.
62
63
In characteristic 2, `D` is arbitrary, and the twist is
64
isomorphic to self after adjoining a root of `x^2+x+D` to the
65
base.
66
67
In characteristic 2 when `j=0`, this is not implemented.
68
69
If the base field `F` is finite, `D` need not be specified,
70
and the curve returned is the unique curve (up to isomorphism)
71
defined over `F` isomorphic to the original curve over the
72
quadratic extension of `F` but not over `F` itself. Over
73
infinite fields, an error is raised if `D` is not given.
74
75
EXAMPLES::
76
77
sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E
78
Elliptic Curve defined by y^2 + x*y = x^3 + 107*x + 340 over Finite Field of size 1103
79
sage: F=E.quadratic_twist(-1); F
80
Elliptic Curve defined by y^2 = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 1103
81
sage: E.is_isomorphic(F)
82
False
83
sage: E.is_isomorphic(F,GF(1103^2,'a'))
84
True
85
86
A characteristic 2 example::
87
88
sage: E=EllipticCurve(GF(2),[1,0,1,1,1])
89
sage: E1=E.quadratic_twist(1)
90
sage: E.is_isomorphic(E1)
91
False
92
sage: E.is_isomorphic(E1,GF(4,'a'))
93
True
94
95
Over finite fields, the twisting parameter may be omitted::
96
97
sage: k.<a> = GF(2^10)
98
sage: E = EllipticCurve(k,[a^2,a,1,a+1,1])
99
sage: Et = E.quadratic_twist()
100
sage: Et # random (only determined up to isomorphism)
101
Elliptic Curve defined by y^2 + x*y = x^3 + (a^7+a^4+a^3+a^2+a+1)*x^2 + (a^8+a^6+a^4+1) over Finite Field in a of size 2^10
102
sage: E.is_isomorphic(Et)
103
False
104
sage: E.j_invariant()==Et.j_invariant()
105
True
106
107
sage: p=next_prime(10^10)
108
sage: k = GF(p)
109
sage: E = EllipticCurve(k,[1,2,3,4,5])
110
sage: Et = E.quadratic_twist()
111
sage: Et # random (only determined up to isomorphism)
112
Elliptic Curve defined by y^2 = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 over Finite Field of size 10000000019
113
sage: E.is_isomorphic(Et)
114
False
115
sage: k2 = GF(p^2,'a')
116
sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2))
117
True
118
"""
119
K=self.base_ring()
120
char=K.characteristic()
121
122
if D is None:
123
if K.is_finite():
124
x = rings.polygen(K)
125
if char==2:
126
# We find D such that x^2+x+D is irreducible. If the
127
# degree is odd we can take D=1; otherwise it suffices to
128
# consider odd powers of a generator.
129
D = K(1)
130
if K.degree()%2==0:
131
D = K.gen()
132
a = D**2
133
while len((x**2+x+D).roots())>0:
134
D *= a
135
else:
136
# We could take a multiplicative generator but
137
# that might be expensive to compute; otherwise
138
# half the elements will do
139
D = K.random_element()
140
while len((x**2-D).roots())>0:
141
D = K.random_element()
142
else:
143
raise ValueError, "twisting parameter D must be specified over infinite fields."
144
else:
145
try:
146
D=K(D)
147
except ValueError:
148
raise ValueError, "twisting parameter D must be in the base field."
149
150
if char!=2 and D.is_zero():
151
raise ValueError, "twisting parameter D must be nonzero when characteristic is not 2"
152
153
if char!=2:
154
b2,b4,b6,b8=self.b_invariants()
155
# E is isomorphic to [0,b2,0,8*b4,16*b6]
156
return EllipticCurve(K,[0,b2*D,0,8*b4*D**2,16*b6*D**3])
157
158
# now char==2
159
if self.j_invariant() !=0: # iff a1!=0
160
a1,a2,a3,a4,a6=self.ainvs()
161
E0=self.change_weierstrass_model(a1,a3/a1,0,(a1**2*a4+a3**2)/a1**3)
162
# which has the form = [1,A2,0,0,A6]
163
assert E0.a1()==K(1)
164
assert E0.a3()==K(0)
165
assert E0.a4()==K(0)
166
return EllipticCurve(K,[1,E0.a2()+D,0,0,E0.a6()])
167
else:
168
raise ValueError, "Quadratic twist not implemented in char 2 when j=0"
169
170
def two_torsion_rank(self):
171
r"""
172
Return the dimension of the 2-torsion subgroup of
173
`E(K)`.
174
175
This will be 0, 1 or 2.
176
177
EXAMPLES::
178
179
sage: E=EllipticCurve('11a1')
180
sage: E.two_torsion_rank()
181
0
182
sage: K.<alpha>=QQ.extension(E.division_polynomial(2).monic())
183
sage: E.base_extend(K).two_torsion_rank()
184
1
185
sage: E.reduction(53).two_torsion_rank()
186
2
187
188
::
189
190
sage: E = EllipticCurve('14a1')
191
sage: E.two_torsion_rank()
192
1
193
sage: K.<alpha>=QQ.extension(E.division_polynomial(2).monic().factor()[1][0])
194
sage: E.base_extend(K).two_torsion_rank()
195
2
196
197
::
198
199
sage: EllipticCurve('15a1').two_torsion_rank()
200
2
201
202
"""
203
f=self.division_polynomial(rings.Integer(2))
204
n=len(f.roots())+1
205
return rings.Integer(n).ord(rings.Integer(2))
206
207
208
def quartic_twist(self, D):
209
r"""
210
Return the quartic twist of this curve by `D`.
211
212
INPUT:
213
214
- ``D`` (must be nonzero) -- the twisting parameter..
215
216
.. note::
217
218
The characteristic must not be 2 or 3, and the `j`-invariant must be 1728.
219
220
EXAMPLES::
221
222
sage: E=EllipticCurve_from_j(GF(13)(1728)); E
223
Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 13
224
sage: E1=E.quartic_twist(2); E1
225
Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 13
226
sage: E.is_isomorphic(E1)
227
False
228
sage: E.is_isomorphic(E1,GF(13^2,'a'))
229
False
230
sage: E.is_isomorphic(E1,GF(13^4,'a'))
231
True
232
"""
233
K=self.base_ring()
234
char=K.characteristic()
235
D=K(D)
236
237
if char==2 or char==3:
238
raise ValueError, "Quartic twist not defined in chars 2,3"
239
240
if self.j_invariant() !=K(1728):
241
raise ValueError, "Quartic twist not defined when j!=1728"
242
243
if D.is_zero():
244
raise ValueError, "quartic twist requires a nonzero argument"
245
246
c4,c6=self.c_invariants()
247
# E is isomorphic to [0,0,0,-27*c4,0]
248
assert c6==0
249
return EllipticCurve(K,[0,0,0,-27*c4*D,0])
250
251
def sextic_twist(self, D):
252
r"""
253
Return the quartic twist of this curve by `D`.
254
255
INPUT:
256
257
- ``D`` (must be nonzero) -- the twisting parameter..
258
259
.. note::
260
261
The characteristic must not be 2 or 3, and the `j`-invariant must be 0.
262
263
EXAMPLES::
264
265
sage: E=EllipticCurve_from_j(GF(13)(0)); E
266
Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13
267
sage: E1=E.sextic_twist(2); E1
268
Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13
269
sage: E.is_isomorphic(E1)
270
False
271
sage: E.is_isomorphic(E1,GF(13^2,'a'))
272
False
273
sage: E.is_isomorphic(E1,GF(13^4,'a'))
274
False
275
sage: E.is_isomorphic(E1,GF(13^6,'a'))
276
True
277
"""
278
K=self.base_ring()
279
char=K.characteristic()
280
D=K(D)
281
282
if char==2 or char==3:
283
raise ValueError, "Sextic twist not defined in chars 2,3"
284
285
if self.j_invariant() !=K(0):
286
raise ValueError, "Sextic twist not defined when j!=0"
287
288
if D.is_zero():
289
raise ValueError, "Sextic twist requires a nonzero argument"
290
291
c4,c6=self.c_invariants()
292
# E is isomorphic to [0,0,0,0,-54*c6]
293
assert c4==0
294
return EllipticCurve(K,[0,0,0,0,-54*c6*D])
295
296
def is_quadratic_twist(self, other):
297
r"""
298
Determine whether this curve is a quadratic twist of another.
299
300
INPUT:
301
302
- ``other`` -- an elliptic curves with the same base field as self.
303
304
OUTPUT:
305
306
Either 0, if the curves are not quadratic twists, or `D` if
307
``other`` is ``self.quadratic_twist(D)`` (up to isomorphism).
308
If ``self`` and ``other`` are isomorphic, returns 1.
309
310
If the curves are defined over `\mathbb{Q}`, the output `D` is
311
a squarefree integer.
312
313
.. note::
314
315
Not fully implemented in characteristic 2, or in
316
characteristic 3 when both `j`-invariants are 0.
317
318
EXAMPLES::
319
320
sage: E = EllipticCurve('11a1')
321
sage: Et = E.quadratic_twist(-24)
322
sage: E.is_quadratic_twist(Et)
323
-6
324
325
sage: E1=EllipticCurve([0,0,1,0,0])
326
sage: E1.j_invariant()
327
0
328
sage: E2=EllipticCurve([0,0,0,0,2])
329
sage: E1.is_quadratic_twist(E2)
330
2
331
sage: E1.is_quadratic_twist(E1)
332
1
333
sage: type(E1.is_quadratic_twist(E1)) == type(E1.is_quadratic_twist(E2)) #trac 6574
334
True
335
336
::
337
338
sage: E1=EllipticCurve([0,0,0,1,0])
339
sage: E1.j_invariant()
340
1728
341
sage: E2=EllipticCurve([0,0,0,2,0])
342
sage: E1.is_quadratic_twist(E2)
343
0
344
sage: E2=EllipticCurve([0,0,0,25,0])
345
sage: E1.is_quadratic_twist(E2)
346
5
347
348
::
349
350
sage: F = GF(101)
351
sage: E1 = EllipticCurve(F,[4,7])
352
sage: E2 = E1.quadratic_twist()
353
sage: D = E1.is_quadratic_twist(E2); D!=0
354
True
355
sage: F = GF(101)
356
sage: E1 = EllipticCurve(F,[4,7])
357
sage: E2 = E1.quadratic_twist()
358
sage: D = E1.is_quadratic_twist(E2)
359
sage: E1.quadratic_twist(D).is_isomorphic(E2)
360
True
361
sage: E1.is_isomorphic(E2)
362
False
363
sage: F2 = GF(101^2,'a')
364
sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2))
365
True
366
367
A characteristic 3 example::
368
369
sage: F = GF(3^5,'a')
370
sage: E1 = EllipticCurve_from_j(F(1))
371
sage: E2 = E1.quadratic_twist(-1)
372
sage: D = E1.is_quadratic_twist(E2); D!=0
373
True
374
sage: E1.quadratic_twist(D).is_isomorphic(E2)
375
True
376
377
::
378
379
sage: E1 = EllipticCurve_from_j(F(0))
380
sage: E2 = E1.quadratic_twist()
381
sage: D = E1.is_quadratic_twist(E2); D
382
1
383
sage: E1.is_isomorphic(E2)
384
True
385
386
"""
387
from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
388
E = self
389
F = other
390
if not is_EllipticCurve(E) or not is_EllipticCurve(F):
391
raise ValueError, "arguments are not elliptic curves"
392
K = E.base_ring()
393
zero = K.zero_element()
394
if not K == F.base_ring():
395
return zero
396
j=E.j_invariant()
397
if j != F.j_invariant():
398
return zero
399
400
if E.is_isomorphic(F):
401
if K is rings.QQ:
402
return rings.ZZ(1)
403
return K.one_element()
404
405
char=K.characteristic()
406
407
if char==2:
408
raise NotImplementedError, "not implemented in characteristic 2"
409
elif char==3:
410
if j==0:
411
raise NotImplementedError, "not implemented in characteristic 3 for curves of j-invariant 0"
412
D = E.b2()/F.b2()
413
414
else:
415
# now char!=2,3:
416
c4E,c6E = E.c_invariants()
417
c4F,c6F = F.c_invariants()
418
419
if j==0:
420
um = c6E/c6F
421
x=rings.polygen(K)
422
ulist=(x**3-um).roots(multiplicities=False)
423
if len(ulist)==0:
424
D = zero
425
else:
426
D = ulist[0]
427
elif j==1728:
428
um=c4E/c4F
429
x=rings.polygen(K)
430
ulist=(x**2-um).roots(multiplicities=False)
431
if len(ulist)==0:
432
D = zero
433
else:
434
D = ulist[0]
435
else:
436
D = (c6E*c4F)/(c6F*c4E)
437
438
# Normalization of output:
439
440
if D.is_zero():
441
return D
442
443
if K is rings.QQ:
444
D = D.squarefree_part()
445
446
assert E.quadratic_twist(D).is_isomorphic(F)
447
448
return D
449
450
def is_quartic_twist(self, other):
451
r"""
452
Determine whether this curve is a quartic twist of another.
453
454
INPUT:
455
456
- ``other`` -- an elliptic curves with the same base field as self.
457
458
OUTPUT:
459
460
Either 0, if the curves are not quartic twists, or `D` if
461
``other`` is ``self.quartic_twist(D)`` (up to isomorphism).
462
If ``self`` and ``other`` are isomorphic, returns 1.
463
464
.. note::
465
466
Not fully implemented in characteristics 2 or 3.
467
468
EXAMPLES::
469
470
sage: E = EllipticCurve_from_j(GF(13)(1728))
471
sage: E1 = E.quartic_twist(2)
472
sage: D = E.is_quartic_twist(E1); D!=0
473
True
474
sage: E.quartic_twist(D).is_isomorphic(E1)
475
True
476
477
::
478
479
sage: E = EllipticCurve_from_j(1728)
480
sage: E1 = E.quartic_twist(12345)
481
sage: D = E.is_quartic_twist(E1); D
482
15999120
483
sage: (D/12345).is_perfect_power(4)
484
True
485
"""
486
from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
487
E = self
488
F = other
489
if not is_EllipticCurve(E) or not is_EllipticCurve(F):
490
raise ValueError, "arguments are not elliptic curves"
491
K = E.base_ring()
492
zero = K.zero_element()
493
if not K == F.base_ring():
494
return zero
495
j=E.j_invariant()
496
if j != F.j_invariant() or j!=K(1728):
497
return zero
498
499
if E.is_isomorphic(F):
500
return K.one_element()
501
502
char=K.characteristic()
503
504
if char==2:
505
raise NotImplementedError, "not implemented in characteristic 2"
506
elif char==3:
507
raise NotImplementedError, "not implemented in characteristic 3"
508
else:
509
# now char!=2,3:
510
D = F.c4()/E.c4()
511
512
if D.is_zero():
513
return D
514
515
assert E.quartic_twist(D).is_isomorphic(F)
516
517
return D
518
519
def is_sextic_twist(self, other):
520
r"""
521
Determine whether this curve is a sextic twist of another.
522
523
INPUT:
524
525
- ``other`` -- an elliptic curves with the same base field as self.
526
527
OUTPUT:
528
529
Either 0, if the curves are not sextic twists, or `D` if
530
``other`` is ``self.sextic_twist(D)`` (up to isomorphism).
531
If ``self`` and ``other`` are isomorphic, returns 1.
532
533
.. note::
534
535
Not fully implemented in characteristics 2 or 3.
536
537
EXAMPLES::
538
539
sage: E = EllipticCurve_from_j(GF(13)(0))
540
sage: E1 = E.sextic_twist(2)
541
sage: D = E.is_sextic_twist(E1); D!=0
542
True
543
sage: E.sextic_twist(D).is_isomorphic(E1)
544
True
545
546
::
547
548
sage: E = EllipticCurve_from_j(0)
549
sage: E1 = E.sextic_twist(12345)
550
sage: D = E.is_sextic_twist(E1); D
551
575968320
552
sage: (D/12345).is_perfect_power(6)
553
True
554
"""
555
from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
556
E = self
557
F = other
558
if not is_EllipticCurve(E) or not is_EllipticCurve(F):
559
raise ValueError, "arguments are not elliptic curves"
560
K = E.base_ring()
561
zero = K.zero_element()
562
if not K == F.base_ring():
563
return zero
564
j=E.j_invariant()
565
if j != F.j_invariant() or not j.is_zero():
566
return zero
567
568
if E.is_isomorphic(F):
569
return K.one_element()
570
571
char=K.characteristic()
572
573
if char==2:
574
raise NotImplementedError, "not implemented in characteristic 2"
575
elif char==3:
576
raise NotImplementedError, "not implemented in characteristic 3"
577
else:
578
# now char!=2,3:
579
D = F.c6()/E.c6()
580
581
if D.is_zero():
582
return D
583
584
assert E.sextic_twist(D).is_isomorphic(F)
585
586
return D
587
588
def descend_to(self, K, f=None):
589
r"""
590
Given a subfield `K` and an elliptic curve self defined over a field `L`,
591
this function determines whether there exists an elliptic curve over `K`
592
which is isomorphic over `L` to self. If one exists, it finds it.
593
594
INPUT:
595
596
- `K` -- a subfield of the base field of self.
597
- `f` -- an embedding of `K` into the base field of self.
598
599
OUTPUT:
600
601
Either an elliptic curve defined over `K` which is isomorphic to self
602
or None if no such curve exists.
603
604
.. NOTE::
605
606
This only works over number fields and QQ.
607
608
EXAMPLES::
609
610
sage: E = EllipticCurve([1,2,3,4,5])
611
sage: E.descend_to(ZZ)
612
Traceback (most recent call last):
613
...
614
TypeError: Input must be a field.
615
616
::
617
618
sage: F.<b> = QuadraticField(23)
619
sage: G.<a> = F.extension(x^3+5)
620
sage: E = EllipticCurve(j=1728*b).change_ring(G)
621
sage: E.descend_to(F)
622
Elliptic Curve defined by y^2 = x^3 + (8957952*b-206032896)*x + (-247669456896*b+474699792384) over Number Field in b with defining polynomial x^2 - 23
623
624
::
625
626
sage: L.<a> = NumberField(x^4 - 7)
627
sage: K.<b> = NumberField(x^2 - 7)
628
sage: E = EllipticCurve([a^6,0])
629
sage: E.descend_to(K)
630
Elliptic Curve defined by y^2 = x^3 + 1296/49*b*x over Number Field in b with defining polynomial x^2 - 7
631
632
::
633
634
sage: K.<a> = QuadraticField(17)
635
sage: E = EllipticCurve(j = 2*a)
636
sage: print E.descend_to(QQ)
637
None
638
"""
639
if not K.is_field():
640
raise TypeError, "Input must be a field."
641
if self.base_field()==K:
642
return self
643
j = self.j_invariant()
644
from sage.rings.all import QQ
645
if K == QQ:
646
f = QQ.embeddings(self.base_field())[0]
647
if j in QQ:
648
jbase = QQ(j)
649
else:
650
return None
651
elif f == None:
652
embeddings = K.embeddings(self.base_field())
653
if len(embeddings) == 0:
654
raise TypeError, "Input must be a subfield of the base field of the curve."
655
for g in embeddings:
656
try:
657
jbase = g.preimage(j)
658
f = g
659
break
660
except:
661
pass
662
if f == None:
663
return None
664
else:
665
try:
666
jbase = f.preimage(j)
667
except:
668
return None
669
E = EllipticCurve(j=jbase)
670
E2 = EllipticCurve(self.base_field(), [f(a) for a in E.a_invariants()])
671
if jbase==0:
672
d = self.is_sextic_twist(E2)
673
if d == 1:
674
return E
675
if d == 0:
676
return None
677
Etwist = E2.sextic_twist(d)
678
elif jbase==1728:
679
d = self.is_quartic_twist(E2)
680
if d == 1:
681
return E
682
if d == 0:
683
return None
684
Etwist = E2.quartic_twist(d)
685
else:
686
d = self.is_quadratic_twist(E2)
687
if d == 1:
688
return E
689
if d == 0:
690
return None
691
Etwist = E2.quadratic_twist(d)
692
if Etwist.is_isomorphic(self):
693
try:
694
Eout = EllipticCurve(K, [f.preimage(a) for a in Etwist.a_invariants()])
695
except:
696
return None
697
else:
698
return Eout
699
700
def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True):
701
r"""
702
Returns an elliptic curve isogeny from self.
703
704
The isogeny can be determined in two ways, either by a
705
polynomial or a set of torsion points. The methods used are:
706
707
- Velu's Formulas: Velu's original formulas for computing
708
isogenies. This algorithm is selected by giving as the
709
``kernel`` parameter a point or a list of points which
710
generate a finite subgroup.
711
712
- Kohel's Formulas: Kohel's original formulas for computing
713
isogenies. This algorithm is selected by giving as the
714
``kernel`` parameter a polynomial (or a coefficient list
715
(little endian)) which will define the kernel of the
716
isogeny.
717
718
INPUT:
719
720
- ``E`` - an elliptic curve, the domain of the isogeny to
721
initialize.
722
723
- ``kernel`` - a kernel, either a point in ``E``, a list of points
724
in ``E``, a univariate kernel polynomial or ``None``.
725
If initiating from a domain/codomain, this must be
726
set to None. Validity of input is *not* fully checked.
727
728
- ``codomain`` - an elliptic curve (default:None). If ``kernel`` is
729
None, then this must be the codomain of a separable
730
normalized isogeny, furthermore, ``degree`` must be
731
the degree of the isogeny from ``E`` to ``codomain``.
732
If ``kernel`` is not None, then this must be
733
isomorphic to the codomain of the normalized separable
734
isogeny defined by ``kernel``, in this case, the
735
isogeny is post composed with an isomorphism so that
736
this parameter is the codomain.
737
738
- ``degree`` - an integer (default:None). If ``kernel`` is None,
739
then this is the degree of the isogeny from ``E`` to
740
``codomain``. If ``kernel`` is not None, then this is
741
used to determine whether or not to skip a gcd of the
742
kernel polynomial with the two torsion polynomial of
743
``E``.
744
745
- ``model`` - a string (default:None). Only supported variable is
746
"minimal", in which case if``E`` is a curve over the
747
rationals, then the codomain is set to be the unique
748
global minimum model.
749
750
- ``check`` (default: True) does some partial checks that the
751
input is valid (e.g., that the points
752
defined by the kernel polynomial are
753
torsion); however, invalid input can in some
754
cases still pass, since that the points define
755
a group is not checked.
756
757
OUTPUT:
758
759
An isogeny between elliptic curves. This is a morphism of curves.
760
761
EXAMPLES::
762
763
sage: F = GF(2^5, 'alpha'); alpha = F.gen()
764
sage: E = EllipticCurve(F, [1,0,1,1,1])
765
sage: R.<x> = F[]
766
sage: phi = E.isogeny(x+1)
767
sage: phi.rational_maps()
768
((x^2 + x + 1)/(x + 1), (x^2*y + x)/(x^2 + 1))
769
770
sage: E = EllipticCurve('11a1')
771
sage: P = E.torsion_points()[1]
772
sage: E.isogeny(P)
773
Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field
774
775
sage: E = EllipticCurve(GF(19),[1,1])
776
sage: P = E(15,3); Q = E(2,12);
777
sage: (P.order(), Q.order())
778
(7, 3)
779
sage: phi = E.isogeny([P,Q]); phi
780
Isogeny of degree 21 from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19
781
sage: phi(E.random_point()) # all points defined over GF(19) are in the kernel
782
(0 : 1 : 0)
783
784
785
# not all polynomials define a finite subgroup trac #6384
786
sage: E = EllipticCurve(GF(31),[1,0,0,1,2])
787
sage: phi = E.isogeny([14,27,4,1])
788
Traceback (most recent call last):
789
...
790
ValueError: The polynomial does not define a finite subgroup of the elliptic curve.
791
792
An example in which we construct an invalid morphism, which
793
illustrates that the check for correctness of the input is not
794
sufficient. (See trac 11578.)::
795
796
sage: R.<x> = QQ[]
797
sage: K.<a> = NumberField(x^2-x-1)
798
sage: E = EllipticCurve(K, [-13392, -1080432])
799
sage: R.<x> = K[]
800
sage: phi = E.isogeny( (x-564)*(x - 396/5*a + 348/5) )
801
sage: phi.codomain().conductor().norm().factor()
802
5^2 * 11^2 * 3271 * 15806939 * 4169267639351
803
sage: phi.domain().conductor().norm().factor()
804
11^2
805
"""
806
return EllipticCurveIsogeny(self, kernel, codomain, degree, model, check=check)
807
808
809
def isogeny_codomain(self, kernel, degree=None):
810
r"""
811
Returns the codomain of the isogeny from self with given
812
kernel.
813
814
INPUT:
815
816
- ``kernel`` - Either a list of points in the kernel of the isogeny,
817
or a kernel polynomial (specified as a either a
818
univariate polynomial or a coefficient list.)
819
820
- ``degree`` - an integer, (default:None) optionally specified degree
821
of the kernel.
822
823
OUTPUT:
824
825
An elliptic curve, the codomain of the separable normalized
826
isogeny from this kernel
827
828
EXAMPLES::
829
830
sage: E = EllipticCurve('17a1')
831
sage: R.<x> = QQ[]
832
sage: E2 = E.isogeny_codomain(x - 11/4); E2
833
Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1461/16*x - 19681/64 over Rational Field
834
835
"""
836
return isogeny_codomain_from_kernel(self, kernel, degree=None)
837
838
def isogenies_prime_degree(self, l=None):
839
"""
840
Generic code, valid for all fields, for those l for which the
841
modular curve has genus 0.
842
843
INPUT:
844
845
- ``l`` -- either None, a prime or a list of primes, from [2,3,5,7,13].
846
847
OUTPUT:
848
849
(list) All `l`-isogenies for the given `l` with domain self.
850
851
METHOD:
852
853
Calls the generic function
854
``isogenies_prime_degree_genus_0()``. This requires that
855
certain operations have been implemented over the base field,
856
such as root-finding for univariate polynomials.
857
858
EXAMPLES::
859
860
sage: F = QQbar
861
sage: E = EllipticCurve(F, [1,18]); E
862
Elliptic Curve defined by y^2 = x^3 + x + 18 over Algebraic Field
863
864
sage: F = CC
865
sage: E = EllipticCurve(F, [1,18]); E
866
Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision
867
sage: E.isogenies_prime_degree(11)
868
Traceback (most recent call last):
869
...
870
NotImplementedError: This code could be implemented for general complex fields, but has not been yet.
871
872
Examples over finite fields::
873
874
sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8])
875
sage: E.isogenies_prime_degree()
876
[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003]
877
sage: E.isogenies_prime_degree(2)
878
[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003]
879
sage: E.isogenies_prime_degree(3)
880
[]
881
sage: E.isogenies_prime_degree(5)
882
[]
883
sage: E.isogenies_prime_degree(7)
884
[]
885
sage: E.isogenies_prime_degree(13)
886
[Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003,
887
Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003]
888
889
sage: E.isogenies_prime_degree([2, 3, 5, 7, 13])
890
[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003]
891
sage: E.isogenies_prime_degree([2, 4])
892
Traceback (most recent call last):
893
...
894
ValueError: 4 is not prime.
895
sage: E.isogenies_prime_degree([2, 29])
896
Traceback (most recent call last):
897
...
898
NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.
899
sage: E.isogenies_prime_degree(4)
900
Traceback (most recent call last):
901
...
902
ValueError: 4 is not prime.
903
sage: E.isogenies_prime_degree(11)
904
Traceback (most recent call last):
905
...
906
NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.
907
908
sage: E = EllipticCurve(GF(17),[2,0])
909
sage: E.isogenies_prime_degree(3)
910
[]
911
sage: E.isogenies_prime_degree(2)
912
[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 17, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 9 over Finite Field of size 17, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 8 over Finite Field of size 17]
913
914
sage: E = EllipticCurve(GF(13^4, 'a'),[2,8])
915
sage: E.isogenies_prime_degree(2)
916
[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (8*a^3+2*a^2+7*a+5)*x + (12*a^3+3*a^2+4*a+4) over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (5*a^3+11*a^2+6*a+11)*x + (a^3+10*a^2+9*a) over Finite Field in a of size 13^4]
917
918
sage: E.isogenies_prime_degree(3)
919
[Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field in a of size 13^4]
920
sage: E.isogenies_prime_degree([2, 3, 5, 7, 13])
921
Traceback (most recent call last):
922
...
923
NotImplementedError: 2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.
924
sage: E.isogenies_prime_degree([2, 3, 5, 7])
925
[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (8*a^3+2*a^2+7*a+5)*x + (12*a^3+3*a^2+4*a+4) over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (5*a^3+11*a^2+6*a+11)*x + (a^3+10*a^2+9*a) over Finite Field in a of size 13^4, Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field in a of size 13^4, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 3*x + 11 over Finite Field in a of size 13^4, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 9*x + 2 over Finite Field in a of size 13^4]
926
927
Examples over number fields (other than QQ)::
928
929
sage: QQroot2.<e> = NumberField(x^2-2)
930
sage: E = EllipticCurve(QQroot2,[1,1])
931
sage: E.isogenies_prime_degree(11)
932
Traceback (most recent call last):
933
...
934
NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.
935
sage: E.isogenies_prime_degree(5)
936
[]
937
938
sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E
939
Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2
940
sage: E.isogenies_prime_degree(2)
941
[Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-36)*x + (-70) over Number Field in e with defining polynomial x^2 - 2]
942
sage: E.isogenies_prime_degree(3)
943
[Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-171)*x + (-874) over Number Field in e with defining polynomial x^2 - 2, Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-128/3)*x + 5662/27 over Number Field in e with defining polynomial x^2 - 2]
944
945
946
"""
947
F = self.base_ring()
948
if rings.is_RealField(F):
949
raise NotImplementedError, "This code could be implemented for general real fields, but has not been yet."
950
if rings.is_ComplexField(F):
951
raise NotImplementedError, "This code could be implemented for general complex fields, but has not been yet."
952
if F == rings.QQbar:
953
raise NotImplementedError, "This code could be implemented for QQbar, but has not been yet."
954
955
from ell_curve_isogeny import isogenies_prime_degree_genus_0
956
if l is None:
957
l = [2, 3, 5, 7, 13]
958
if l in [2, 3, 5, 7, 13]:
959
return isogenies_prime_degree_genus_0(self, l)
960
if type(l) != list:
961
if l.is_prime():
962
raise NotImplementedError, "Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented."
963
else:
964
raise ValueError, "%s is not prime."%l
965
isogs = []
966
i = 0
967
while i<len(l):
968
isogenies = [f for f in self.isogenies_prime_degree(l[i]) if not f in isogs]
969
isogs.extend(isogenies)
970
i = i+1
971
return isogs
972
973
def is_isogenous(self, other, field=None):
974
"""
975
Returns whether or not self is isogenous to other.
976
977
INPUT:
978
979
- ``other`` -- another elliptic curve.
980
981
- ``field`` (default None) -- Currently not implemented. A
982
field containing the base fields of the two elliptic curves
983
onto which the two curves may be extended to test if they
984
are isogenous over this field. By default is_isogenous will
985
not try to find this field unless one of the curves can be
986
be extended into the base field of the other, in which case
987
it will test over the larger base field.
988
989
OUTPUT:
990
991
(bool) True if there is an isogeny from curve ``self`` to
992
curve ``other`` defined over ``field``.
993
994
METHOD:
995
996
Over general fields this is only implemented in trivial cases.
997
998
EXAMPLES::
999
1000
sage: E1 = EllipticCurve(CC, [1,18]); E1
1001
Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision
1002
sage: E2 = EllipticCurve(CC, [2,7]); E2
1003
Elliptic Curve defined by y^2 = x^3 + 2.00000000000000*x + 7.00000000000000 over Complex Field with 53 bits of precision
1004
sage: E1.is_isogenous(E2)
1005
Traceback (most recent call last):
1006
...
1007
NotImplementedError: Only implemented for isomorphic curves over general fields.
1008
1009
sage: E1 = EllipticCurve(Frac(PolynomialRing(ZZ,'t')), [2,19]); E1
1010
Elliptic Curve defined by y^2 = x^3 + 2*x + 19 over Fraction Field of Univariate Polynomial Ring in t over Integer Ring
1011
sage: E2 = EllipticCurve(CC, [23,4]); E2
1012
Elliptic Curve defined by y^2 = x^3 + 23.0000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision
1013
sage: E1.is_isogenous(E2)
1014
Traceback (most recent call last):
1015
...
1016
NotImplementedError: Only implemented for isomorphic curves over general fields.
1017
"""
1018
from ell_generic import is_EllipticCurve
1019
if not is_EllipticCurve(other):
1020
raise ValueError, "Second argument is not an Elliptic Curve."
1021
if self.is_isomorphic(other):
1022
return True
1023
else:
1024
raise NotImplementedError, "Only implemented for isomorphic curves over general fields."
1025
1026
def weierstrass_p(self, prec=20, algorithm=None):
1027
r"""
1028
Computes the Weierstrass `\wp`-function of the elliptic curve.
1029
1030
INPUT:
1031
1032
- ``mprec`` - precision
1033
1034
- ``algorithm`` - string (default:``None``) an algorithm identifier
1035
indicating using the ``pari``, ``fast`` or ``quadratic``
1036
algorithm. If the algorithm is ``None``, then this
1037
function determines the best algorithm to use.
1038
1039
OUTPUT:
1040
1041
a Laurent series in one variable `z` with coefficients in the
1042
base field `k` of `E`.
1043
1044
EXAMPLES::
1045
1046
sage: E = EllipticCurve('11a1')
1047
sage: E.weierstrass_p(prec=10)
1048
z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + O(z^10)
1049
sage: E.weierstrass_p(prec=8)
1050
z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8)
1051
sage: Esh = E.short_weierstrass_model()
1052
sage: Esh.weierstrass_p(prec=8)
1053
z^-2 + 13392/5*z^2 + 1080432/7*z^4 + 59781888/25*z^6 + O(z^8)
1054
1055
sage: E.weierstrass_p(prec=8, algorithm='pari')
1056
z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8)
1057
sage: E.weierstrass_p(prec=8, algorithm='quadratic')
1058
z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8)
1059
1060
sage: k = GF(101)
1061
sage: E = EllipticCurve(k, [2,3])
1062
sage: E.weierstrass_p(prec=30)
1063
z^-2 + 40*z^2 + 14*z^4 + 62*z^6 + 15*z^8 + 47*z^10 + 66*z^12 + 61*z^14 + 79*z^16 + 98*z^18 + 93*z^20 + 82*z^22 + 15*z^24 + 71*z^26 + 27*z^28 + O(z^30)
1064
1065
sage: k = GF(11)
1066
sage: E = EllipticCurve(k, [1,1])
1067
sage: E.weierstrass_p(prec=6, algorithm='fast')
1068
z^-2 + 2*z^2 + 3*z^4 + O(z^6)
1069
sage: E.weierstrass_p(prec=7, algorithm='fast')
1070
Traceback (most recent call last):
1071
...
1072
ValueError: For computing the Weierstrass p-function via the fast algorithm, the characteristic (11) of the underlying field must be greater than prec + 4 = 11.
1073
sage: E.weierstrass_p(prec=8 ,algorithm='pari')
1074
z^-2 + 2*z^2 + 3*z^4 + 5*z^6 + O(z^8)
1075
sage: E.weierstrass_p(prec=9, algorithm='pari')
1076
Traceback (most recent call last):
1077
...
1078
ValueError: For computing the Weierstrass p-function via pari, the characteristic (11) of the underlying field must be greater than prec + 2 = 11.
1079
1080
"""
1081
return weierstrass_p(self, prec=prec, algorithm=algorithm)
1082
1083
1084
def hasse_invariant(self):
1085
r"""
1086
Returns the Hasse invariant of this elliptic curve.
1087
1088
OUTPUT:
1089
1090
The Hasse invariant of this elliptic curve, as an element of
1091
the base field. This is only defined over fields of positive
1092
characteristic, and is an element of the field which is zero
1093
if and only if the curve is supersingular. Over a field of
1094
characteristic zero, where the Hasse invariant is undefined,
1095
a ``ValueError`` is returned.
1096
1097
EXAMPLES::
1098
1099
sage: E = EllipticCurve([Mod(1,2),Mod(1,2),0,0,Mod(1,2)])
1100
sage: E.hasse_invariant()
1101
1
1102
sage: E = EllipticCurve([0,0,Mod(1,3),Mod(1,3),Mod(1,3)])
1103
sage: E.hasse_invariant()
1104
0
1105
sage: E = EllipticCurve([0,0,Mod(1,5),0,Mod(2,5)])
1106
sage: E.hasse_invariant()
1107
0
1108
sage: E = EllipticCurve([0,0,Mod(1,5),Mod(1,5),Mod(2,5)])
1109
sage: E.hasse_invariant()
1110
2
1111
1112
Some examples over larger fields::
1113
1114
sage: EllipticCurve(GF(101),[0,0,0,0,1]).hasse_invariant()
1115
0
1116
sage: EllipticCurve(GF(101),[0,0,0,1,1]).hasse_invariant()
1117
98
1118
sage: EllipticCurve(GF(103),[0,0,0,0,1]).hasse_invariant()
1119
20
1120
sage: EllipticCurve(GF(103),[0,0,0,1,1]).hasse_invariant()
1121
17
1122
sage: F.<a> = GF(107^2)
1123
sage: EllipticCurve(F,[0,0,0,a,1]).hasse_invariant()
1124
62*a + 75
1125
sage: EllipticCurve(F,[0,0,0,0,a]).hasse_invariant()
1126
0
1127
1128
Over fields of characteristic zero, the Hasse invariant is
1129
undefined::
1130
1131
sage: E = EllipticCurve([0,0,0,0,1])
1132
sage: E.hasse_invariant()
1133
Traceback (most recent call last):
1134
...
1135
ValueError: Hasse invariant only defined in positive characteristic
1136
"""
1137
k = self.base_field()
1138
p = k.characteristic()
1139
if p == 0:
1140
raise ValueError('Hasse invariant only defined in positive characteristic')
1141
elif p == 2:
1142
return self.a1()
1143
elif p == 3:
1144
return self.b2()
1145
elif p == 5:
1146
return self.c4()
1147
elif p == 7:
1148
return -self.c6()
1149
else:
1150
R = k['x']
1151
x = R.gen()
1152
E = self.short_weierstrass_model()
1153
f=(x**3+E.a4()*x+E.a6())**((p-1)//2)
1154
return f.coeffs()[p-1]
1155
1156