Skip to content

Commit

Permalink
Trac #11630: Local data of elliptic curves should not do any global work
Browse files Browse the repository at this point in the history
... unless asked to do so.

I am talking about the line 687 in
sage.scheme.elliptic_curves_ell_local_data  which reads

{{{
        principal_flag = P.is_principal()
        if principal_flag:
            pi = P.gens_reduced()[0]
            verbose("P is principal, generator pi = %s"%pi, t, 1)
        else:
            pi = K.uniformizer(P, 'positive')
            verbose("P is not principal, uniformizer pi = %s"%pi, t, 1)
}}}

While it can be useful, especially when one wants a global minimal
model, it is often very harmful. If the class group of the field is huge
or difficult to compute, one will not be able to determine the fibres of
the Neron model, simply because of this line.

One should add a switch which is by default set to use the second case
and only if needed to the first case.

Of course, in an ideal world Tate's algorithm should be implemented for
any elliptic curve over a local field, rather than a number field.

URL: http://trac.sagemath.org/11630
Reported by: wuthrich
Ticket author(s): Chris Wuthrich
Reviewer(s): John Cremona, PatchBot
  • Loading branch information
Release Manager authored and vbraun committed Jan 5, 2014
2 parents 8a2f0f9 + d2d3457 commit 1d1e1e4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
40 changes: 29 additions & 11 deletions src/sage/schemes/elliptic_curves/ell_local_data.py
Expand Up @@ -61,7 +61,7 @@
sage: EK = E.base_extend(K)
sage: da = EK.local_data(1+i)
sage: da.minimal_model()
Elliptic Curve defined by y^2 = x^3 + i over Number Field in i with defining polynomial x^2 + 1
Elliptic Curve defined by y^2 = x^3 + (-i) over Number Field in i with defining polynomial x^2 + 1
REFERENCES:
Expand Down Expand Up @@ -154,8 +154,8 @@ class EllipticCurveLocalData(SageObject):
Tamagawa Number: 2
"""

def __init__(self, E, P, proof=None, algorithm="pari"):
def __init__(self, E, P, proof=None, algorithm="pari", globally=False):
r"""
Initializes the reduction data for the elliptic curve `E` at the prime `P`.
Expand All @@ -176,6 +176,10 @@ def __init__(self, E, P, proof=None, algorithm="pari"):
``ellglobalred`` implementation of Tate's algorithm over
`\QQ`. If "generic", use the general number field
implementation.
- ``globally`` (bool, default: False) -- If True, the algorithm
uses the generators of principal ideals rather than an arbitrary
uniformizer.
.. note::
Expand Down Expand Up @@ -271,7 +275,7 @@ def __init__(self, E, P, proof=None, algorithm="pari"):
if self._fp>0:
self._reduction_type = Eint.ap(p) # = 0,-1 or +1
else:
self._Emin, ch, self._val_disc, self._fp, self._KS, self._cp, self._split = self._tate(proof)
self._Emin, ch, self._val_disc, self._fp, self._KS, self._cp, self._split = self._tate(proof, globally)
if self._fp>0:
if self._Emin.c4().valuation(p)>0:
self._reduction_type = 0
Expand Down Expand Up @@ -621,8 +625,8 @@ def has_additive_reduction(self):
(Fractional ideal (2*a + 1), True)]
"""
return self._reduction_type == 0

def _tate(self, proof = None):
def _tate(self, proof = None, globally = False):
r"""
Tate's algorithm for an elliptic curve over a number field.
Expand All @@ -635,7 +639,9 @@ def _tate(self, proof = None):
principal, the minimal model returned will preserve
integrality at other primes, but not minimality.
.. note::
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.
.. note::
Called only by ``EllipticCurveLocalData.__init__()``.
Expand Down Expand Up @@ -682,6 +688,14 @@ def _tate(self, proof = None):
sage: E.tamagawa_number(K.ideal(2))
4
This is to show that the bug :trac: `11630` is fixed. (The computation of the class group would produce a warning)::
sage: K.<t> = NumberField(x^7-2*x+177)
sage: E = EllipticCurve([0,1,0,t,t])
sage: P = K.ideal(2,t^3 + t + 1)
sage: E.local_data(P).kodaira_symbol()
II
"""
E = self._curve
P = self._prime
Expand All @@ -700,14 +714,18 @@ def _tate(self, proof = None):
# uniformiser pi which has non-positive valuation at all other
# primes, so that we can divide by it without losing
# integrality at other primes.

principal_flag = P.is_principal()
if principal_flag:

if globally:
principal_flag = P.is_principal()
else:
principal_flag = False

if (K is QQ) or principal_flag :
pi = P.gens_reduced()[0]
verbose("P is principal, generator pi = %s"%pi, t, 1)
else:
pi = K.uniformizer(P, 'positive')
verbose("P is not principal, uniformizer pi = %s"%pi, t, 1)
verbose("uniformizer pi = %s"%pi, t, 1)
pi2 = pi*pi; pi3 = pi*pi2; pi4 = pi*pi3
pi_neg = None
prime = pi if K is QQ else P
Expand Down
34 changes: 21 additions & 13 deletions src/sage/schemes/elliptic_curves/ell_number_field.py
Expand Up @@ -682,7 +682,7 @@ def _reduce_model(self):

return self.rst_transform(r, s, t)

def local_data(self, P=None, proof = None, algorithm="pari"):
def local_data(self, P=None, proof=None, algorithm="pari", globally=False):
r"""
Local data for this elliptic curve at the prime `P`.
Expand All @@ -701,6 +701,13 @@ def local_data(self, P=None, proof = None, algorithm="pari"):
`\QQ`. If "generic", use the general number field
implementation.
- ``globally`` -- whether the local algorithm uses global generators
for the prime ideals. Default is False, which won't require any
information about the class group. If True, a generator for `P`
will be used if `P` is principal. Otherwise, or if ``globally``
is False, the minimal model returned will preserve integrality
at other primes, but not minimality.
OUTPUT:
If `P` is specified, returns the ``EllipticCurveLocalData``
Expand All @@ -712,12 +719,6 @@ def local_data(self, P=None, proof = None, algorithm="pari"):
The model is not required to be integral on input.
For principal `P`, a generator is used as a uniformizer,
and integrality or minimality at other primes is not
affected. For non-principal `P`, the minimal model
returned will preserve integrality at other primes, but not
minimality.
EXAMPLES::
sage: K.<i> = NumberField(x^2+1)
Expand Down Expand Up @@ -770,9 +771,9 @@ def local_data(self, P=None, proof = None, algorithm="pari"):
from sage.schemes.elliptic_curves.ell_local_data import check_prime
P = check_prime(self.base_field(),P)

return self._get_local_data(P,proof,algorithm)
return self._get_local_data(P,proof,algorithm,globally)

def _get_local_data(self, P, proof, algorithm="pari"):
def _get_local_data(self, P, proof, algorithm="pari", globally=False):
r"""
Internal function to create data for this elliptic curve at the prime `P`.
Expand All @@ -795,6 +796,13 @@ def _get_local_data(self, P, proof, algorithm="pari"):
`\QQ`. If "generic", use the general number field
implementation.
- ``globally`` -- whether the local algorithm uses global generators
for the prime ideals. Default is False, which won't require any
information about the class group. If True, a generator for `P`
will be used if `P` is principal. Otherwise, or if ``globally``
is False, the minimal model returned will preserve integrality
at other primes, but not minimality.
EXAMPLES::
sage: K.<i> = NumberField(x^2+1)
Expand All @@ -818,14 +826,14 @@ def _get_local_data(self, P, proof, algorithm="pari"):
False
"""
try:
return self._local_data[P, proof, algorithm]
return self._local_data[P, proof, algorithm, globally]
except AttributeError:
self._local_data = {}
except KeyError:
pass
from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
self._local_data[P, proof, algorithm] = EllipticCurveLocalData(self, P, proof, algorithm)
return self._local_data[P, proof, algorithm]
self._local_data[P, proof, algorithm, globally] = EllipticCurveLocalData(self, P, proof, algorithm, globally)
return self._local_data[P, proof, algorithm, globally]

def local_minimal_model(self, P, proof = None, algorithm="pari"):
r"""
Expand Down Expand Up @@ -1375,7 +1383,7 @@ def global_minimal_model(self, proof = None):
E = self.global_integral_model()
primes = E.base_ring()(E.discriminant()).support()
for P in primes:
E = E.local_data(P,proof).minimal_model()
E = E.local_data(P,proof, globally=True).minimal_model()
return E._reduce_model()

def reduction(self,place):
Expand Down

0 comments on commit 1d1e1e4

Please sign in to comment.