Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/elliptic_curves/ell_local_data.py
8821 views
1
# -*- coding: utf-8 -*-
2
r"""
3
Local data for elliptic curves over number fields
4
5
Let `E` be an elliptic curve over a number field `K` (including `\QQ`).
6
There are several local invariants at a finite place `v` that
7
can be computed via Tate's algorithm (see [Sil2] IV.9.4 or [Ta]).
8
9
These include the type of reduction (good, additive, multiplicative),
10
a minimal equation of `E` over `K_v`,
11
the Tamagawa number `c_v`, defined to be the index `[E(K_v):E^0(K_v)]`
12
of the points with good reduction among the local points, and the
13
exponent of the conductor `f_v`.
14
15
The functions in this file will typically be called by using ``local_data``.
16
17
EXAMPLES::
18
19
sage: K.<i> = NumberField(x^2+1)
20
sage: E = EllipticCurve([(2+i)^2,(2+i)^7])
21
sage: pp = K.fractional_ideal(2+i)
22
sage: da = E.local_data(pp)
23
sage: da.has_bad_reduction()
24
True
25
sage: da.has_multiplicative_reduction()
26
False
27
sage: da.kodaira_symbol()
28
I0*
29
sage: da.tamagawa_number()
30
4
31
sage: da.minimal_model()
32
Elliptic Curve defined by y^2 = x^3 + (4*i+3)*x + (-29*i-278) over Number Field in i with defining polynomial x^2 + 1
33
34
An example to show how the Neron model can change as one extends the field::
35
36
sage: E = EllipticCurve([0,-1])
37
sage: E.local_data(2)
38
Local data at Principal ideal (2) of Integer Ring:
39
Reduction type: bad additive
40
Local minimal model: Elliptic Curve defined by y^2 = x^3 - 1 over Rational Field
41
Minimal discriminant valuation: 4
42
Conductor exponent: 4
43
Kodaira Symbol: II
44
Tamagawa Number: 1
45
46
sage: EK = E.base_extend(K)
47
sage: EK.local_data(1+i)
48
Local data at Fractional ideal (i + 1):
49
Reduction type: bad additive
50
Local minimal model: Elliptic Curve defined by y^2 = x^3 + (-1) over Number Field in i with defining polynomial x^2 + 1
51
Minimal discriminant valuation: 8
52
Conductor exponent: 2
53
Kodaira Symbol: IV*
54
Tamagawa Number: 3
55
56
Or how the minimal equation changes::
57
58
sage: E = EllipticCurve([0,8])
59
sage: E.is_minimal()
60
True
61
sage: EK = E.base_extend(K)
62
sage: da = EK.local_data(1+i)
63
sage: da.minimal_model()
64
Elliptic Curve defined by y^2 = x^3 + (-i) over Number Field in i with defining polynomial x^2 + 1
65
66
REFERENCES:
67
68
- [Sil2] Silverman, Joseph H., Advanced topics in the arithmetic of elliptic curves.
69
Graduate Texts in Mathematics, 151. Springer-Verlag, New York, 1994.
70
71
- [Ta] Tate, John, Algorithm for determining the type of a singular fiber in an elliptic pencil.
72
Modular functions of one variable, IV, pp. 33--52. Lecture Notes in Math., Vol. 476,
73
Springer, Berlin, 1975.
74
75
AUTHORS:
76
77
- John Cremona: First version 2008-09-21 (refactoring code from
78
``ell_number_field.py`` and ``ell_rational_field.py``)
79
80
- Chris Wuthrich: more documentation 2010-01
81
82
"""
83
84
#*****************************************************************************
85
# Copyright (C) 2005 William Stein <[email protected]>
86
#
87
# Distributed under the terms of the GNU General Public License (GPL)
88
#
89
# This code is distributed in the hope that it will be useful,
90
# but WITHOUT ANY WARRANTY; without even the implied warranty of
91
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
92
# General Public License for more details.
93
#
94
# The full text of the GPL is available at:
95
#
96
# http://www.gnu.org/licenses/
97
#*****************************************************************************
98
99
100
from sage.structure.sage_object import SageObject
101
from sage.misc.misc import verbose
102
103
from sage.rings.all import PolynomialRing, QQ, ZZ, Integer, is_NumberFieldElement, is_NumberFieldFractionalIdeal
104
105
from sage.rings.number_field.number_field import is_NumberField
106
from sage.rings.ideal import is_Ideal
107
108
from constructor import EllipticCurve
109
from kodaira_symbol import KodairaSymbol
110
111
class EllipticCurveLocalData(SageObject):
112
r"""
113
The class for the local reduction data of an elliptic curve.
114
115
Currently supported are elliptic curves defined over `\QQ`, and
116
elliptic curves defined over a number field, at an arbitrary prime
117
or prime ideal.
118
119
INPUT:
120
121
- ``E`` -- an elliptic curve defined over a number field, or `\QQ`.
122
123
- ``P`` -- a prime ideal of the field, or a prime integer if the field is `\QQ`.
124
125
- ``proof`` (bool)-- if True, only use provably correct
126
methods (default controlled by global proof module). Note
127
that the proof module is number_field, not elliptic_curves,
128
since the functions that actually need the flag are in
129
number fields.
130
131
- ``algorithm`` (string, default: "pari") -- Ignored unless the
132
base field is `\QQ`. If "pari", use the PARI C-library
133
``ellglobalred`` implementation of Tate's algorithm over
134
`\QQ`. If "generic", use the general number field
135
implementation.
136
137
.. note::
138
139
This function is not normally called directly by users, who
140
may access the data via methods of the EllipticCurve
141
classes.
142
143
EXAMPLES::
144
145
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
146
sage: E = EllipticCurve('14a1')
147
sage: EllipticCurveLocalData(E,2)
148
Local data at Principal ideal (2) of Integer Ring:
149
Reduction type: bad non-split multiplicative
150
Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
151
Minimal discriminant valuation: 6
152
Conductor exponent: 1
153
Kodaira Symbol: I6
154
Tamagawa Number: 2
155
156
"""
157
158
def __init__(self, E, P, proof=None, algorithm="pari", globally=False):
159
r"""
160
Initializes the reduction data for the elliptic curve `E` at the prime `P`.
161
162
INPUT:
163
164
- ``E`` -- an elliptic curve defined over a number field, or `\QQ`.
165
166
- ``P`` -- a prime ideal of the field, or a prime integer if the field is `\QQ`.
167
168
- ``proof`` (bool)-- if True, only use provably correct
169
methods (default controlled by global proof module). Note
170
that the proof module is number_field, not elliptic_curves,
171
since the functions that actually need the flag are in
172
number fields.
173
174
- ``algorithm`` (string, default: "pari") -- Ignored unless the
175
base field is `\QQ`. If "pari", use the PARI C-library
176
``ellglobalred`` implementation of Tate's algorithm over
177
`\QQ`. If "generic", use the general number field
178
implementation.
179
180
- ``globally`` (bool, default: False) -- If True, the algorithm
181
uses the generators of principal ideals rather than an arbitrary
182
uniformizer.
183
184
.. note::
185
186
This function is not normally called directly by users, who
187
may access the data via methods of the EllipticCurve
188
classes.
189
190
EXAMPLES::
191
192
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
193
sage: E = EllipticCurve('14a1')
194
sage: EllipticCurveLocalData(E,2)
195
Local data at Principal ideal (2) of Integer Ring:
196
Reduction type: bad non-split multiplicative
197
Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
198
Minimal discriminant valuation: 6
199
Conductor exponent: 1
200
Kodaira Symbol: I6
201
Tamagawa Number: 2
202
203
::
204
205
sage: EllipticCurveLocalData(E,2,algorithm="generic")
206
Local data at Principal ideal (2) of Integer Ring:
207
Reduction type: bad non-split multiplicative
208
Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
209
Minimal discriminant valuation: 6
210
Conductor exponent: 1
211
Kodaira Symbol: I6
212
Tamagawa Number: 2
213
214
::
215
216
sage: EllipticCurveLocalData(E,2,algorithm="pari")
217
Local data at Principal ideal (2) of Integer Ring:
218
Reduction type: bad non-split multiplicative
219
Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
220
Minimal discriminant valuation: 6
221
Conductor exponent: 1
222
Kodaira Symbol: I6
223
Tamagawa Number: 2
224
225
::
226
227
sage: EllipticCurveLocalData(E,2,algorithm="unknown")
228
Traceback (most recent call last):
229
...
230
ValueError: algorithm must be one of 'pari', 'generic'
231
232
::
233
234
sage: EllipticCurveLocalData(E,3)
235
Local data at Principal ideal (3) of Integer Ring:
236
Reduction type: good
237
Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
238
Minimal discriminant valuation: 0
239
Conductor exponent: 0
240
Kodaira Symbol: I0
241
Tamagawa Number: 1
242
243
::
244
245
sage: EllipticCurveLocalData(E,7)
246
Local data at Principal ideal (7) of Integer Ring:
247
Reduction type: bad split multiplicative
248
Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
249
Minimal discriminant valuation: 3
250
Conductor exponent: 1
251
Kodaira Symbol: I3
252
Tamagawa Number: 3
253
"""
254
self._curve = E
255
K = E.base_field()
256
p = check_prime(K,P) # error handling done in that function
257
if algorithm != "pari" and algorithm != "generic":
258
raise ValueError, "algorithm must be one of 'pari', 'generic'"
259
260
self._reduction_type = None
261
if K is QQ:
262
self._prime = ZZ.ideal(p)
263
else:
264
self._prime = p
265
266
if algorithm=="pari" and K is QQ:
267
Eint = E.integral_model()
268
data = Eint.pari_curve().elllocalred(p)
269
self._fp = data[0].python()
270
self._KS = KodairaSymbol(data[1].python())
271
self._cp = data[3].python()
272
# We use a global minimal model since we can:
273
self._Emin_reduced = Eint.minimal_model()
274
self._val_disc = self._Emin_reduced.discriminant().valuation(p)
275
if self._fp>0:
276
self._reduction_type = Eint.ap(p) # = 0,-1 or +1
277
else:
278
self._Emin, ch, self._val_disc, self._fp, self._KS, self._cp, self._split = self._tate(proof, globally)
279
if self._fp>0:
280
if self._Emin.c4().valuation(p)>0:
281
self._reduction_type = 0
282
elif self._split:
283
self._reduction_type = +1
284
else:
285
self._reduction_type = -1
286
287
def __repr__(self):
288
r"""
289
Returns the string representation of this reduction data.
290
291
EXAMPLES::
292
293
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
294
sage: E = EllipticCurve('14a1')
295
sage: EllipticCurveLocalData(E,2).__repr__()
296
'Local data at Principal ideal (2) of Integer Ring:\nReduction type: bad non-split multiplicative\nLocal minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field\nMinimal discriminant valuation: 6\nConductor exponent: 1\nKodaira Symbol: I6\nTamagawa Number: 2'
297
sage: EllipticCurveLocalData(E,3).__repr__()
298
'Local data at Principal ideal (3) of Integer Ring:\nReduction type: good\nLocal minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field\nMinimal discriminant valuation: 0\nConductor exponent: 0\nKodaira Symbol: I0\nTamagawa Number: 1'
299
sage: EllipticCurveLocalData(E,7).__repr__()
300
'Local data at Principal ideal (7) of Integer Ring:\nReduction type: bad split multiplicative\nLocal minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field\nMinimal discriminant valuation: 3\nConductor exponent: 1\nKodaira Symbol: I3\nTamagawa Number: 3'
301
"""
302
red_type = "good"
303
if not self._reduction_type is None:
304
red_type = ["bad non-split multiplicative","bad additive","bad split multiplicative"][1+self._reduction_type]
305
return "Local data at %s:\nReduction type: %s\nLocal minimal model: %s\nMinimal discriminant valuation: %s\nConductor exponent: %s\nKodaira Symbol: %s\nTamagawa Number: %s"%(self._prime,red_type,self.minimal_model(),self._val_disc,self._fp,self._KS,self._cp)
306
307
def minimal_model(self, reduce=True):
308
"""
309
Return the (local) minimal model from this local reduction data.
310
311
INPUT:
312
313
- ``reduce`` -- (default: True) if set to True and if the initial
314
elliptic curve had globally integral coefficients, then the
315
elliptic curve returned by Tate's algorithm will be "reduced" as
316
specified in _reduce_model() for curves over number fields.
317
318
EXAMPLES::
319
320
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
321
sage: E = EllipticCurve([0,0,0,0,64]); E
322
Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field
323
sage: data = EllipticCurveLocalData(E,2)
324
sage: data.minimal_model()
325
Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
326
sage: data.minimal_model() == E.local_minimal_model(2)
327
True
328
329
To demonstrate the behaviour of the parameter ``reduce``::
330
331
sage: K.<a> = NumberField(x^3+x+1)
332
sage: E = EllipticCurve(K, [0, 0, a, 0, 1])
333
sage: E.local_data(K.ideal(a-1)).minimal_model()
334
Elliptic Curve defined by y^2 + a*y = x^3 + 1 over Number Field in a with defining polynomial x^3 + x + 1
335
sage: E.local_data(K.ideal(a-1)).minimal_model(reduce=False)
336
Elliptic Curve defined by y^2 + (a+2)*y = x^3 + 3*x^2 + 3*x + (-a+1) over Number Field in a with defining polynomial x^3 + x + 1
337
338
sage: E = EllipticCurve([2, 1, 0, -2, -1])
339
sage: E.local_data(ZZ.ideal(2), algorithm="generic").minimal_model(reduce=False)
340
Elliptic Curve defined by y^2 + 2*x*y + 2*y = x^3 + x^2 - 4*x - 2 over Rational Field
341
sage: E.local_data(ZZ.ideal(2), algorithm="pari").minimal_model(reduce=False)
342
Traceback (most recent call last):
343
...
344
ValueError: the argument reduce must not be False if algorithm=pari is used
345
sage: E.local_data(ZZ.ideal(2), algorithm="generic").minimal_model()
346
Elliptic Curve defined by y^2 = x^3 - x^2 - 3*x + 2 over Rational Field
347
sage: E.local_data(ZZ.ideal(2), algorithm="pari").minimal_model()
348
Elliptic Curve defined by y^2 = x^3 - x^2 - 3*x + 2 over Rational Field
349
350
:trac:`14476`::
351
352
sage: t = QQ['t'].0
353
sage: K.<g> = NumberField(t^4 - t^3-3*t^2 - t +1)
354
sage: E = EllipticCurve([-2*g^3 + 10/3*g^2 + 3*g - 2/3, -11/9*g^3 + 34/9*g^2 - 7/3*g + 4/9, -11/9*g^3 + 34/9*g^2 - 7/3*g + 4/9, 0, 0])
355
sage: vv = K.fractional_ideal(g^2 - g - 2)
356
sage: E.local_data(vv).minimal_model()
357
Elliptic Curve defined by y^2 + (-2*g^3+10/3*g^2+3*g-2/3)*x*y + (-11/9*g^3+34/9*g^2-7/3*g+4/9)*y = x^3 + (-11/9*g^3+34/9*g^2-7/3*g+4/9)*x^2 over Number Field in g with defining polynomial t^4 - t^3 - 3*t^2 - t + 1
358
359
"""
360
if reduce:
361
try:
362
return self._Emin_reduced
363
except AttributeError:
364
pass
365
# trac 14476 we only reduce if the coefficients are globally integral
366
if all(a.is_integral() for a in self._Emin.a_invariants()):
367
self._Emin_reduced = self._Emin._reduce_model()
368
return self._Emin_reduced
369
else:
370
return self._Emin
371
else:
372
try:
373
return self._Emin
374
except AttributeError:
375
raise ValueError, "the argument reduce must not be False if algorithm=pari is used"
376
377
def prime(self):
378
"""
379
Return the prime ideal associated with this local reduction data.
380
381
EXAMPLES::
382
383
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
384
sage: E = EllipticCurve([0,0,0,0,64]); E
385
Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field
386
sage: data = EllipticCurveLocalData(E,2)
387
sage: data.prime()
388
Principal ideal (2) of Integer Ring
389
"""
390
return self._prime
391
392
def conductor_valuation(self):
393
"""
394
Return the valuation of the conductor from this local reduction data.
395
396
EXAMPLES::
397
398
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
399
sage: E = EllipticCurve([0,0,0,0,64]); E
400
Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field
401
sage: data = EllipticCurveLocalData(E,2)
402
sage: data.conductor_valuation()
403
2
404
"""
405
return self._fp
406
407
def kodaira_symbol(self):
408
r"""
409
Return the Kodaira symbol from this local reduction data.
410
411
EXAMPLES::
412
413
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
414
sage: E = EllipticCurve([0,0,0,0,64]); E
415
Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field
416
sage: data = EllipticCurveLocalData(E,2)
417
sage: data.kodaira_symbol()
418
IV
419
"""
420
return self._KS
421
422
def tamagawa_number(self):
423
r"""
424
Return the Tamagawa number from this local reduction data.
425
426
This is the index `[E(K_v):E^0(K_v)]`.
427
428
EXAMPLES::
429
430
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
431
sage: E = EllipticCurve([0,0,0,0,64]); E
432
Elliptic Curve defined by y^2 = x^3 + 64 over Rational Field
433
sage: data = EllipticCurveLocalData(E,2)
434
sage: data.tamagawa_number()
435
3
436
"""
437
return self._cp
438
439
def tamagawa_exponent(self):
440
r"""
441
Return the Tamagawa index from this local reduction data.
442
443
This is the exponent of `E(K_v)/E^0(K_v)`; in most cases it is
444
the same as the Tamagawa index.
445
446
EXAMPLES::
447
448
sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
449
sage: E = EllipticCurve('816a1')
450
sage: data = EllipticCurveLocalData(E,2)
451
sage: data.kodaira_symbol()
452
I2*
453
sage: data.tamagawa_number()
454
4
455
sage: data.tamagawa_exponent()
456
2
457
458
sage: E = EllipticCurve('200c4')
459
sage: data = EllipticCurveLocalData(E,5)
460
sage: data.kodaira_symbol()
461
I4*
462
sage: data.tamagawa_number()
463
4
464
sage: data.tamagawa_exponent()
465
2
466
"""
467
cp = self._cp
468
if cp!=4:
469
return cp
470
ks = self._KS
471
if ks._roman==1 and ks._n%2==0 and ks._starred:
472
return 2
473
return 4
474
475
def bad_reduction_type(self):
476
r"""
477
Return the type of bad reduction of this reduction data.
478
479
OUTPUT:
480
481
(int or ``None``):
482
483
- +1 for split multiplicative reduction
484
- -1 for non-split multiplicative reduction
485
- 0 for additive reduction
486
- ``None`` for good reduction
487
488
EXAMPLES::
489
490
sage: E=EllipticCurve('14a1')
491
sage: [(p,E.local_data(p).bad_reduction_type()) for p in prime_range(15)]
492
[(2, -1), (3, None), (5, None), (7, 1), (11, None), (13, None)]
493
494
sage: K.<a>=NumberField(x^3-2)
495
sage: P17a, P17b = [P for P,e in K.factor(17)]
496
sage: E = EllipticCurve([0,0,0,0,2*a+1])
497
sage: [(p,E.local_data(p).bad_reduction_type()) for p in [P17a,P17b]]
498
[(Fractional ideal (4*a^2 - 2*a + 1), None), (Fractional ideal (2*a + 1), 0)]
499
"""
500
return self._reduction_type
501
502
def has_good_reduction(self):
503
r"""
504
Return True if there is good reduction.
505
506
EXAMPLES::
507
508
sage: E = EllipticCurve('14a1')
509
sage: [(p,E.local_data(p).has_good_reduction()) for p in prime_range(15)]
510
[(2, False), (3, True), (5, True), (7, False), (11, True), (13, True)]
511
512
sage: K.<a> = NumberField(x^3-2)
513
sage: P17a, P17b = [P for P,e in K.factor(17)]
514
sage: E = EllipticCurve([0,0,0,0,2*a+1])
515
sage: [(p,E.local_data(p).has_good_reduction()) for p in [P17a,P17b]]
516
[(Fractional ideal (4*a^2 - 2*a + 1), True),
517
(Fractional ideal (2*a + 1), False)]
518
"""
519
return self._reduction_type is None
520
521
def has_bad_reduction(self):
522
r"""
523
Return True if there is bad reduction.
524
525
EXAMPLES::
526
527
sage: E = EllipticCurve('14a1')
528
sage: [(p,E.local_data(p).has_bad_reduction()) for p in prime_range(15)]
529
[(2, True), (3, False), (5, False), (7, True), (11, False), (13, False)]
530
531
::
532
533
sage: K.<a> = NumberField(x^3-2)
534
sage: P17a, P17b = [P for P,e in K.factor(17)]
535
sage: E = EllipticCurve([0,0,0,0,2*a+1])
536
sage: [(p,E.local_data(p).has_bad_reduction()) for p in [P17a,P17b]]
537
[(Fractional ideal (4*a^2 - 2*a + 1), False),
538
(Fractional ideal (2*a + 1), True)]
539
"""
540
return not self._reduction_type is None
541
542
def has_multiplicative_reduction(self):
543
r"""
544
Return True if there is multiplicative reduction.
545
546
.. note::
547
548
See also ``has_split_multiplicative_reduction()`` and
549
``has_nonsplit_multiplicative_reduction()``.
550
551
EXAMPLES::
552
553
sage: E = EllipticCurve('14a1')
554
sage: [(p,E.local_data(p).has_multiplicative_reduction()) for p in prime_range(15)]
555
[(2, True), (3, False), (5, False), (7, True), (11, False), (13, False)]
556
557
::
558
559
sage: K.<a> = NumberField(x^3-2)
560
sage: P17a, P17b = [P for P,e in K.factor(17)]
561
sage: E = EllipticCurve([0,0,0,0,2*a+1])
562
sage: [(p,E.local_data(p).has_multiplicative_reduction()) for p in [P17a,P17b]]
563
[(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)]
564
"""
565
return self._reduction_type in (-1,+1)
566
567
def has_split_multiplicative_reduction(self):
568
r"""
569
Return True if there is split multiplicative reduction.
570
571
EXAMPLES::
572
573
sage: E = EllipticCurve('14a1')
574
sage: [(p,E.local_data(p).has_split_multiplicative_reduction()) for p in prime_range(15)]
575
[(2, False), (3, False), (5, False), (7, True), (11, False), (13, False)]
576
577
::
578
579
sage: K.<a> = NumberField(x^3-2)
580
sage: P17a, P17b = [P for P,e in K.factor(17)]
581
sage: E = EllipticCurve([0,0,0,0,2*a+1])
582
sage: [(p,E.local_data(p).has_split_multiplicative_reduction()) for p in [P17a,P17b]]
583
[(Fractional ideal (4*a^2 - 2*a + 1), False),
584
(Fractional ideal (2*a + 1), False)]
585
"""
586
return self._reduction_type == +1
587
588
def has_nonsplit_multiplicative_reduction(self):
589
r"""
590
Return True if there is non-split multiplicative reduction.
591
592
EXAMPLES::
593
594
sage: E = EllipticCurve('14a1')
595
sage: [(p,E.local_data(p).has_nonsplit_multiplicative_reduction()) for p in prime_range(15)]
596
[(2, True), (3, False), (5, False), (7, False), (11, False), (13, False)]
597
598
::
599
600
sage: K.<a> = NumberField(x^3-2)
601
sage: P17a, P17b = [P for P,e in K.factor(17)]
602
sage: E = EllipticCurve([0,0,0,0,2*a+1])
603
sage: [(p,E.local_data(p).has_nonsplit_multiplicative_reduction()) for p in [P17a,P17b]]
604
[(Fractional ideal (4*a^2 - 2*a + 1), False), (Fractional ideal (2*a + 1), False)]
605
"""
606
return self._reduction_type == -1
607
608
def has_additive_reduction(self):
609
r"""
610
Return True if there is additive reduction.
611
612
EXAMPLES::
613
614
sage: E = EllipticCurve('27a1')
615
sage: [(p,E.local_data(p).has_additive_reduction()) for p in prime_range(15)]
616
[(2, False), (3, True), (5, False), (7, False), (11, False), (13, False)]
617
618
::
619
620
sage: K.<a> = NumberField(x^3-2)
621
sage: P17a, P17b = [P for P,e in K.factor(17)]
622
sage: E = EllipticCurve([0,0,0,0,2*a+1])
623
sage: [(p,E.local_data(p).has_additive_reduction()) for p in [P17a,P17b]]
624
[(Fractional ideal (4*a^2 - 2*a + 1), False),
625
(Fractional ideal (2*a + 1), True)]
626
"""
627
return self._reduction_type == 0
628
629
def _tate(self, proof = None, globally = False):
630
r"""
631
Tate's algorithm for an elliptic curve over a number field.
632
633
Computes both local reduction data at a prime ideal and a
634
local minimal model.
635
636
The model is not required to be integral on input. If `P` is
637
principal, uses a generator as uniformizer, so it will not
638
affect integrality or minimality at other primes. If `P` is not
639
principal, the minimal model returned will preserve
640
integrality at other primes, but not minimality.
641
642
The optional argument globally, when set to True, tells the algorithm to use the generator of the prime ideal if it is principal. Otherwise just any uniformizer will be used.
643
644
.. note::
645
646
Called only by ``EllipticCurveLocalData.__init__()``.
647
648
OUTPUT:
649
650
(tuple) ``(Emin, p, val_disc, fp, KS, cp)`` where:
651
652
- ``Emin`` (EllipticCurve) is a model (integral and) minimal at P
653
- ``p`` (int) is the residue characteristic
654
- ``val_disc`` (int) is the valuation of the local minimal discriminant
655
- ``fp`` (int) is the valuation of the conductor
656
- ``KS`` (string) is the Kodaira symbol
657
- ``cp`` (int) is the Tamagawa number
658
659
660
EXAMPLES (this raised a type error in sage prior to 4.4.4, see :trac:`7930`) ::
661
662
sage: E = EllipticCurve('99d1')
663
664
sage: R.<X> = QQ[]
665
sage: K.<t> = NumberField(X^3 + X^2 - 2*X - 1)
666
sage: L.<s> = NumberField(X^3 + X^2 - 36*X - 4)
667
668
sage: EK = E.base_extend(K)
669
sage: toK = EK.torsion_order()
670
sage: da = EK.local_data() # indirect doctest
671
672
sage: EL = E.base_extend(L)
673
sage: da = EL.local_data() # indirect doctest
674
675
EXAMPLES:
676
677
The following example shows that the bug at :trac:`9324` is fixed::
678
679
sage: K.<a> = NumberField(x^2-x+6)
680
sage: E = EllipticCurve([0,0,0,-53160*a-43995,-5067640*a+19402006])
681
sage: E.conductor() # indirect doctest
682
Fractional ideal (18, 6*a)
683
684
The following example shows that the bug at :trac:`9417` is fixed::
685
686
sage: K.<a> = NumberField(x^2+18*x+1)
687
sage: E = EllipticCurve(K, [0, -36, 0, 320, 0])
688
sage: E.tamagawa_number(K.ideal(2))
689
4
690
691
This is to show that the bug :trac: `11630` is fixed. (The computation of the class group would produce a warning)::
692
693
sage: K.<t> = NumberField(x^7-2*x+177)
694
sage: E = EllipticCurve([0,1,0,t,t])
695
sage: P = K.ideal(2,t^3 + t + 1)
696
sage: E.local_data(P).kodaira_symbol()
697
II
698
699
"""
700
E = self._curve
701
P = self._prime
702
K = E.base_ring()
703
OK = K.maximal_order()
704
t = verbose("Running Tate's algorithm with P = %s"%P, level=1)
705
F = OK.residue_field(P)
706
p = F.characteristic()
707
708
# In case P is not principal we mostly use a uniformiser which
709
# is globally integral (with positive valuation at some other
710
# primes); for this to work, it is essential that we can
711
# reduce (mod P) elements of K which are not integral (but are
712
# P-integral). However, if the model is non-minimal and we
713
# end up dividing a_i by pi^i then at that point we use a
714
# uniformiser pi which has non-positive valuation at all other
715
# primes, so that we can divide by it without losing
716
# integrality at other primes.
717
718
if globally:
719
principal_flag = P.is_principal()
720
else:
721
principal_flag = False
722
723
if (K is QQ) or principal_flag :
724
pi = P.gens_reduced()[0]
725
verbose("P is principal, generator pi = %s"%pi, t, 1)
726
else:
727
pi = K.uniformizer(P, 'positive')
728
verbose("uniformizer pi = %s"%pi, t, 1)
729
pi2 = pi*pi; pi3 = pi*pi2; pi4 = pi*pi3
730
pi_neg = None
731
prime = pi if K is QQ else P
732
733
pval = lambda x: x.valuation(prime)
734
pdiv = lambda x: x.is_zero() or pval(x) > 0
735
# Since ResidueField is cached in a way that
736
# does not care much about embeddings of number
737
# fields, it can happen that F.p.ring() is different
738
# from K. This is a problem: If F.p.ring() has no
739
# embedding but K has, then there is no coercion
740
# from F.p.ring().maximal_order() to K. But it is
741
# no problem to do an explicit conversion in that
742
# case (Simon King, trac ticket #8800).
743
744
from sage.categories.pushout import pushout, CoercionException
745
try:
746
if hasattr(F.p.ring(), 'maximal_order'): # it is not ZZ
747
_tmp_ = pushout(F.p.ring().maximal_order(),K)
748
pinv = lambda x: F.lift(~F(x))
749
proot = lambda x,e: F.lift(F(x).nth_root(e, extend = False, all = True)[0])
750
preduce = lambda x: F.lift(F(x))
751
except CoercionException: # the pushout does not exist, we need conversion
752
pinv = lambda x: K(F.lift(~F(x)))
753
proot = lambda x,e: K(F.lift(F(x).nth_root(e, extend = False, all = True)[0]))
754
preduce = lambda x: K(F.lift(F(x)))
755
756
def _pquadroots(a, b, c):
757
r"""
758
Local function returning True iff `ax^2 + bx + c` has roots modulo `P`
759
"""
760
(a, b, c) = (F(a), F(b), F(c))
761
if a == 0:
762
return (b != 0) or (c == 0)
763
elif p == 2:
764
return len(PolynomialRing(F, "x")([c,b,a]).roots()) > 0
765
else:
766
return (b**2 - 4*a*c).is_square()
767
def _pcubicroots(b, c, d):
768
r"""
769
Local function returning the number of roots of `x^3 +
770
b*x^2 + c*x + d` modulo `P`, counting multiplicities
771
"""
772
773
return sum([rr[1] for rr in PolynomialRing(F, 'x')([F(d), F(c), F(b), F(1)]).roots()],0)
774
775
if p == 2:
776
halfmodp = OK(Integer(0))
777
else:
778
halfmodp = pinv(Integer(2))
779
780
A = E.a_invariants()
781
A = [0, A[0], A[1], A[2], A[3], 0, A[4]]
782
indices = [1,2,3,4,6]
783
if min([pval(a) for a in A if a != 0]) < 0:
784
verbose("Non-integral model at P: valuations are %s; making integral"%([pval(a) for a in A if a != 0]), t, 1)
785
e = 0
786
for i in range(7):
787
if A[i] != 0:
788
e = max(e, (-pval(A[i])/i).ceil())
789
pie = pi**e
790
for i in range(7):
791
if A[i] != 0:
792
A[i] *= pie**i
793
verbose("P-integral model is %s, with valuations %s"%([A[i] for i in indices], [pval(A[i]) for i in indices]), t, 1)
794
795
split = None # only relevant for multiplicative reduction
796
797
(a1, a2, a3, a4, a6) = (A[1], A[2], A[3], A[4], A[6])
798
while True:
799
C = EllipticCurve([a1, a2, a3, a4, a6]);
800
(b2, b4, b6, b8) = C.b_invariants()
801
(c4, c6) = C.c_invariants()
802
delta = C.discriminant()
803
val_disc = pval(delta)
804
805
if val_disc == 0:
806
## Good reduction already
807
cp = 1
808
fp = 0
809
KS = KodairaSymbol("I0")
810
break #return
811
812
# Otherwise, we change coordinates so that p | a3, a4, a6
813
if p == 2:
814
if pdiv(b2):
815
r = proot(a4, 2)
816
t = proot(((r + a2)*r + a4)*r + a6, 2)
817
else:
818
temp = pinv(a1)
819
r = temp * a3
820
t = temp * (a4 + r*r)
821
elif p == 3:
822
if pdiv(b2):
823
r = proot(-b6, 3)
824
else:
825
r = -pinv(b2) * b4
826
t = a1 * r + a3
827
else:
828
if pdiv(c4):
829
r = -pinv(12) * b2
830
else:
831
r = -pinv(12*c4) * (c6 + b2 * c4)
832
t = -halfmodp * (a1 * r + a3)
833
r = preduce(r)
834
t = preduce(t)
835
verbose("Before first transform C = %s"%C)
836
verbose("[a1,a2,a3,a4,a6] = %s"%([a1, a2, a3, a4, a6]))
837
C = C.rst_transform(r, 0, t)
838
(a1, a2, a3, a4, a6) = C.a_invariants()
839
(b2, b4, b6, b8) = C.b_invariants()
840
if min([pval(a) for a in (a1, a2, a3, a4, a6) if a != 0]) < 0:
841
raise RuntimeError, "Non-integral model after first transform!"
842
verbose("After first transform %s\n, [a1,a2,a3,a4,a6] = %s\n, valuations = %s"%([r, 0, t], [a1, a2, a3, a4, a6], [pval(a1), pval(a2), pval(a3), pval(a4), pval(a6)]), t, 2)
843
if pval(a3) == 0:
844
raise RuntimeError, "p does not divide a3 after first transform!"
845
if pval(a4) == 0:
846
raise RuntimeError, "p does not divide a4 after first transform!"
847
if pval(a6) == 0:
848
raise RuntimeError, "p does not divide a6 after first transform!"
849
850
# Now we test for Types In, II, III, IV
851
# NB the c invariants never change.
852
853
if not pdiv(c4):
854
# Multiplicative reduction: Type In (n = val_disc)
855
split = False
856
if _pquadroots(1, a1, -a2):
857
cp = val_disc
858
split = True
859
elif Integer(2).divides(val_disc):
860
cp = 2
861
else:
862
cp = 1
863
KS = KodairaSymbol("I%s"%val_disc)
864
fp = 1
865
break #return
866
867
# Additive reduction
868
869
if pval(a6) < 2:
870
## Type II
871
KS = KodairaSymbol("II")
872
fp = val_disc
873
cp = 1
874
break #return
875
if pval(b8) < 3:
876
## Type III
877
KS = KodairaSymbol("III")
878
fp = val_disc - 1
879
cp = 2
880
break #return
881
if pval(b6) < 3:
882
## Type IV
883
cp = 1
884
a3t = preduce(a3/pi)
885
a6t = preduce(a6/pi2)
886
if _pquadroots(1, a3t, -a6t): cp = 3
887
KS = KodairaSymbol("IV")
888
fp = val_disc - 2
889
break #return
890
891
# If our curve is none of these types, we change coords so that
892
# p | a1, a2; p^2 | a3, a4; p^3 | a6
893
if p == 2:
894
s = proot(a2, 2) # so s^2=a2 (mod pi)
895
t = pi*proot(a6/pi2, 2) # so t^2=a6 (mod pi^3)
896
elif p == 3:
897
s = a1 # so a1'=2s+a1=3a1=0 (mod pi)
898
t = a3 # so a3'=2t+a3=3a3=0 (mod pi^2)
899
else:
900
s = -a1*halfmodp # so a1'=2s+a1=0 (mod pi)
901
t = -a3*halfmodp # so a3'=2t+a3=0 (mod pi^2)
902
C = C.rst_transform(0, s, t)
903
(a1, a2, a3, a4, a6) = C.a_invariants()
904
(b2, b4, b6, b8) = C.b_invariants()
905
verbose("After second transform %s\n[a1, a2, a3, a4, a6] = %s\nValuations: %s"%([0, s, t], [a1,a2,a3,a4,a6],[pval(a1),pval(a2),pval(a3),pval(a4),pval(a6)]), t, 2)
906
if pval(a1) == 0:
907
raise RuntimeError, "p does not divide a1 after second transform!"
908
if pval(a2) == 0:
909
raise RuntimeError, "p does not divide a2 after second transform!"
910
if pval(a3) < 2:
911
raise RuntimeError, "p^2 does not divide a3 after second transform!"
912
if pval(a4) < 2:
913
raise RuntimeError, "p^2 does not divide a4 after second transform!"
914
if pval(a6) < 3:
915
raise RuntimeError, "p^3 does not divide a6 after second transform!"
916
if min(pval(a1), pval(a2), pval(a3), pval(a4), pval(a6)) < 0:
917
raise RuntimeError, "Non-integral model after second transform!"
918
919
# Analyze roots of the cubic T^3 + bT^2 + cT + d = 0 mod P, where
920
# b = a2/p, c = a4/p^2, d = a6/p^3
921
b = preduce(a2/pi)
922
c = preduce(a4/pi2)
923
d = preduce(a6/pi3)
924
bb = b*b
925
cc = c*c
926
bc = b*c
927
w = 27*d*d - bb*cc + 4*b*bb*d - 18*bc*d + 4*c*cc
928
x = 3*c - bb
929
if pdiv(w):
930
if pdiv(x):
931
sw = 3
932
else:
933
sw = 2
934
else:
935
sw = 1
936
verbose("Analyzing roots of cubic T^3 + %s*T^2 + %s*T + %s, case %s"%(b, c, d, sw), t, 1)
937
if sw == 1:
938
## Three distinct roots - Type I*0
939
verbose("Distinct roots", t, 1)
940
KS = KodairaSymbol("I0*")
941
cp = 1 + _pcubicroots(b, c, d)
942
fp = val_disc - 4
943
break #return
944
elif sw == 2:
945
## One double root - Type I*m for some m
946
verbose("One double root", t, 1)
947
## Change coords so that the double root is T = 0 mod p
948
if p == 2:
949
r = proot(c, 2)
950
elif p == 3:
951
r = c * pinv(b)
952
else:
953
r = (bc - 9*d)*pinv(2*x)
954
r = pi * preduce(r)
955
C = C.rst_transform(r, 0, 0)
956
(a1, a2, a3, a4, a6) = C.a_invariants()
957
(b2, b4, b6, b8) = C.b_invariants()
958
# The rest of this branch is just to compute cp, fp, KS.
959
# We use pi to keep transforms integral.
960
ix = 3; iy = 3; mx = pi2; my = mx
961
while True:
962
a2t = preduce(a2 / pi)
963
a3t = preduce(a3 / my)
964
a4t = preduce(a4 / (pi*mx))
965
a6t = preduce(a6 / (mx*my))
966
if pdiv(a3t*a3t + 4*a6t):
967
if p == 2:
968
t = my*proot(a6t, 2)
969
else:
970
t = my*preduce(-a3t*halfmodp)
971
C = C.rst_transform(0, 0, t)
972
(a1, a2, a3, a4, a6) = C.a_invariants()
973
(b2, b4, b6, b8) = C.b_invariants()
974
my *= pi
975
iy += 1
976
a2t = preduce(a2 / pi)
977
a3t = preduce(a3/my)
978
a4t = preduce(a4/(pi*mx))
979
a6t = preduce(a6/(mx*my))
980
if pdiv(a4t*a4t - 4*a6t*a2t):
981
if p == 2:
982
r = mx*proot(a6t*pinv(a2t), 2)
983
else:
984
r = mx*preduce(-a4t*pinv(2*a2t))
985
C = C.rst_transform(r, 0, 0)
986
(a1, a2, a3, a4, a6) = C.a_invariants()
987
(b2, b4, b6, b8) = C.b_invariants()
988
mx *= pi
989
ix += 1 # and stay in loop
990
else:
991
if _pquadroots(a2t, a4t, a6t):
992
cp = 4
993
else:
994
cp = 2
995
break # exit loop
996
else:
997
if _pquadroots(1, a3t, -a6t):
998
cp = 4
999
else:
1000
cp = 2
1001
break
1002
KS = KodairaSymbol("I%s*"%(ix+iy-5))
1003
fp = val_disc - ix - iy + 1
1004
break #return
1005
else: # sw == 3
1006
## The cubic has a triple root
1007
verbose("Triple root", t, 1)
1008
## First we change coordinates so that T = 0 mod p
1009
if p == 2:
1010
r = b
1011
elif p == 3:
1012
r = proot(-d, 3)
1013
else:
1014
r = -b * pinv(3)
1015
r = pi*preduce(r)
1016
C = C.rst_transform(r, 0, 0)
1017
(a1, a2, a3, a4, a6) = C.a_invariants()
1018
(b2, b4, b6, b8) = C.b_invariants()
1019
verbose("After third transform %s\n[a1,a2,a3,a4,a6] = %s\nValuations: %s"%([r,0,0],[a1,a2,a3,a4,a6],[pval(ai) for ai in [a1,a2,a3,a4,a6]]), t, 2)
1020
if min(pval(ai) for ai in [a1,a2,a3,a4,a6]) < 0:
1021
raise RuntimeError, "Non-integral model after third transform!"
1022
if pval(a2) < 2 or pval(a4) < 3 or pval(a6) < 4:
1023
raise RuntimeError, "Cubic after transform does not have a triple root at 0"
1024
a3t = preduce(a3/pi2)
1025
a6t = preduce(a6/pi4)
1026
# We test for Type IV*
1027
if not pdiv(a3t*a3t + 4*a6t):
1028
cp = 3 if _pquadroots(1, a3t, -a6t) else 1
1029
KS = KodairaSymbol("IV*")
1030
fp = val_disc - 6
1031
break #return
1032
# Now change coordinates so that p^3|a3, p^5|a6
1033
if p==2:
1034
t = -pi2*proot(a6t, 2)
1035
else:
1036
t = pi2*preduce(-a3t*halfmodp)
1037
C = C.rst_transform(0, 0, t)
1038
(a1, a2, a3, a4, a6) = C.a_invariants()
1039
(b2, b4, b6, b8) = C.b_invariants()
1040
# We test for types III* and II*
1041
if pval(a4) < 4:
1042
## Type III*
1043
KS = KodairaSymbol("III*")
1044
fp = val_disc - 7
1045
cp = 2
1046
break #return
1047
if pval(a6) < 6:
1048
## Type II*
1049
KS = KodairaSymbol("II*")
1050
fp = val_disc - 8
1051
cp = 1
1052
break #return
1053
if pi_neg is None:
1054
if principal_flag:
1055
pi_neg = pi
1056
else:
1057
pi_neg = K.uniformizer(P, 'negative')
1058
pi_neg2 = pi_neg*pi_neg
1059
pi_neg3 = pi_neg*pi_neg2
1060
pi_neg4 = pi_neg*pi_neg3
1061
pi_neg6 = pi_neg4*pi_neg2
1062
a1 /= pi_neg
1063
a2 /= pi_neg2
1064
a3 /= pi_neg3
1065
a4 /= pi_neg4
1066
a6 /= pi_neg6
1067
verbose("Non-minimal equation, dividing out...\nNew model is %s"%([a1, a2, a3, a4, a6]), t, 1)
1068
return (C, p, val_disc, fp, KS, cp, split)
1069
1070
1071
def check_prime(K,P):
1072
r"""
1073
Function to check that `P` determines a prime of `K`, and return that ideal.
1074
1075
INPUT:
1076
1077
- ``K`` -- a number field (including `\QQ`).
1078
1079
- ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``.
1080
1081
OUTPUT:
1082
1083
- If ``K`` is `\QQ`: the prime integer equal to or which generates `P`.
1084
1085
- If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`.
1086
1087
.. note::
1088
1089
If `P` is not a prime and does not generate a prime, a TypeError is raised.
1090
1091
EXAMPLES::
1092
1093
sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime
1094
sage: check_prime(QQ,3)
1095
3
1096
sage: check_prime(QQ,ZZ.ideal(31))
1097
31
1098
sage: K.<a>=NumberField(x^2-5)
1099
sage: check_prime(K,a)
1100
Fractional ideal (a)
1101
sage: check_prime(K,a+1)
1102
Fractional ideal (a + 1)
1103
sage: [check_prime(K,P) for P in K.primes_above(31)]
1104
[Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)]
1105
"""
1106
if K is QQ:
1107
if isinstance(P, (int,long,Integer)):
1108
P = Integer(P)
1109
if P.is_prime():
1110
return P
1111
else:
1112
raise TypeError, "%s is not prime"%P
1113
else:
1114
if is_Ideal(P) and P.base_ring() is ZZ and P.is_prime():
1115
return P.gen()
1116
raise TypeError, "%s is not a prime ideal of %s"%(P,ZZ)
1117
1118
if not is_NumberField(K):
1119
raise TypeError, "%s is not a number field"%K
1120
1121
if is_NumberFieldFractionalIdeal(P):
1122
if P.is_prime():
1123
return P
1124
else:
1125
raise TypeError, "%s is not a prime ideal of %s"%(P,K)
1126
1127
if is_NumberFieldElement(P):
1128
if P in K:
1129
P = K.ideal(P)
1130
else:
1131
raise TypeError, "%s is not an element of %s"%(P,K)
1132
if P.is_prime():
1133
return P
1134
else:
1135
raise TypeError, "%s is not a prime ideal of %s"%(P,K)
1136
1137
raise TypeError, "%s is not a valid prime of %s"%(P,K)
1138
1139