Path: blob/master/sage/schemes/elliptic_curves/ell_egros.py
4159 views
"""1Construction of elliptic curves with good reduction outside a finite2set of primes34A theorem of Shafarevich states that, over a number field `K`, given5any finite set `S` of primes of `K`, there are (up to isomorphism)6only a finite set of elliptic curves defined over `K` with good7reduction at all primes outside `S`. An explicit form of the theorem8with an algorithm for finding this finite set was given in "Finding9all elliptic curves with good reduction outside a given set of primes"10by John Cremona and Mark Lingham, Experimental Mathematics 16 No.311(2007), 303-312. The method requires computation of the class and12unit groups of `K` as well as all the `S`-integral points on a13collection of auxiliary elliptic curves defined over `K`.1415This implementation (April 2009) is only for the case `K=\Q`, where in16many cases the determination of the necessary sets of `S`-integral17points is possible. The main user-level function is18EllipticCurves_with_good_reduction_outside_S(), defined in19constrictor.py. Users should note carefully the following points:2021(1) the number of auxiliary curves to be considered is exponential in22the size of `S` (specifically, `2.6**s` where `s=|S|`).2324(2) For some of the auxiliary curves it is impossible at present to25provably find all the `S`-integral points using the current26algorithms, which rely on first finding a basis for their Mordell-Weil27groups using 2-descent. A warning is output in cases where the set of28points (and hence the final output) is not guaranteed to be complete.29Using the "proof=False" flag suppresses these warnings.3031EXAMPLES: We find all elliptic curves with good reduction outside 2,32listing the label of each:3334sage: [e.label() for e in EllipticCurves_with_good_reduction_outside_S([2])]35['32a1',36'32a2',37'32a3',38'32a4',39'64a1',40'64a2',41'64a3',42'64a4',43'128a1',44'128a2',45'128b1',46'128b2',47'128c1',48'128c2',49'128d1',50'128d2',51'256a1',52'256a2',53'256b1',54'256b2',55'256c1',56'256c2',57'256d1',58'256d2']5960Secondly we try the same with `S={11}`; note that warning messages are61printed without proof=False (unless the optional database is62installed: two of the auxiliary curves whose Mordell-Weil bases are63required have conductors 13068 and 52272 so are in the database)::6465sage: [e.label() for e in EllipticCurves_with_good_reduction_outside_S([11], proof=False)] # long time (13s on sage.math, 2011)66['11a1', '11a2', '11a3', '121a1', '121a2', '121b1', '121b2', '121c1', '121c2', '121d1', '121d2', '121d3']676869AUTHORS:70* John Cremona (6 April 2009): initial version (over Q only).71"""7273#*****************************************************************************74# Copyright (C) 2009 John Cremona <[email protected]>75#76# Distributed under the terms of the GNU General Public License (GPL)77#78# This code is distributed in the hope that it will be useful,79# but WITHOUT ANY WARRANTY; without even the implied warranty of80# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU81# General Public License for more details.82#83# The full text of the GPL is available at:84#85# http://www.gnu.org/licenses/86#*****************************************************************************8788from sage.misc.misc import prod89from sage.misc.all import xmrange90from sage.rings.all import QQ91from constructor import EllipticCurve, EllipticCurve_from_j9293def is_possible_j(j,S=[]):94r"""95Tests if the rational `j` is a possible `j`-invariant of an96elliptic curve with good reduction outside `S`.9798.. note::99100The condition used is necessary but not sufficient unless S101contains both 2 and 3.102103EXAMPLES::104sage: from sage.schemes.elliptic_curves.ell_egros import is_possible_j105sage: is_possible_j(0,[])106False107sage: is_possible_j(1728,[])108True109sage: is_possible_j(-4096/11,[11])110True111"""112j = QQ(j)113return (j.is_zero() and 3 in S) \114or (j==1728) \115or (j.is_S_integral(S) \116and j.prime_to_S_part(S).is_nth_power(3) \117and (j-1728).prime_to_S_part(S).abs().is_square())118119120def curve_cmp(E1,E2):121r"""122Comparison function for elliptic curves over `Q`.123124Order by label if in the database, else first by conductor, then125by c_invariants.126"""127t = cmp(E1.conductor(),E2.conductor())128if t:129return t130131# Now they have the same conductor132try:133from sage.databases.cremona import parse_cremona_label, class_to_int134k1 = parse_cremona_label(E1.label())135k2 = parse_cremona_label(E2.label())136t = cmp(class_to_int(k1[1]),class_to_int(k2[1]))137if t:138return t139return cmp(k1[2],k2[2])140except RuntimeError: # if not in database, label() will fail141pass142143return cmp(E1.ainvs(),E2.ainvs())144145def egros_from_j_1728(S=[]):146r"""147Given a list of primes S, returns a list of elliptic curves over Q148with j-invariant 1728 and good reduction outside S, by checking149all relevant quartic twists.150151INPUT:152153- S - list of primes (default: empty list).154155.. note::156157Primality of elements of S is not checked, and the output158is undefined if S is not a list or contains non-primes.159160OUTPUT:161162A sorted list of all elliptic curves defined over `Q` with163`j`-invariant equal to `1728` and with good reduction at164all primes outside the list ``S``.165166EXAMPLES::167168sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j_1728169sage: egros_from_j_1728([])170[]171sage: egros_from_j_1728([3])172[]173sage: [e.cremona_label() for e in egros_from_j_1728([2])]174['32a1', '32a2', '64a1', '64a4', '256b1', '256b2', '256c1', '256c2']175176"""177Elist=[]178no2 = not 2 in S179for ei in xmrange([2] + [4]*len(S)):180u = prod([p**e for p,e in zip([-1]+S,ei)],QQ(1))181if no2:182u*=4 ## make sure 12|val(D,2)183Eu = EllipticCurve([0,0,0,u,0]).minimal_model()184if Eu.has_good_reduction_outside_S(S):185Elist += [Eu]186Elist.sort(cmp=curve_cmp)187return Elist188189def egros_from_j_0(S=[]):190r"""191Given a list of primes S, returns a list of elliptic curves over Q192with j-invariant 0 and good reduction outside S, by checking all193relevant sextic twists.194195INPUT:196197- S - list of primes (default: empty list).198199.. note::200201Primality of elements of S is not checked, and the output202is undefined if S is not a list or contains non-primes.203204OUTPUT:205206A sorted list of all elliptic curves defined over `Q` with207`j`-invariant equal to `0` and with good reduction at208all primes outside the list ``S``.209210EXAMPLES::211212sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j_0213sage: egros_from_j_0([])214[]215sage: egros_from_j_0([2])216[]217sage: [e.label() for e in egros_from_j_0([3])]218['27a1', '27a3', '243a1', '243a2', '243b1', '243b2']219sage: len(egros_from_j_0([2,3,5]))220432221"""222Elist=[]223if not 3 in S:224return Elist225no2 = not 2 in S226for ei in xmrange([2] + [6]*len(S)):227u = prod([p**e for p,e in zip([-1]+S,ei)],QQ(1))228if no2:229u*=16 ## make sure 12|val(D,2)230Eu = EllipticCurve([0,0,0,0,u]).minimal_model()231if Eu.has_good_reduction_outside_S(S):232Elist += [Eu]233Elist.sort(cmp=curve_cmp)234return Elist235236def egros_from_j(j,S=[]):237r"""238Given a rational j and a list of primes S, returns a list of239elliptic curves over Q with j-invariant j and good reduction240outside S, by checking all relevant quadratic twists.241242INPUT:243244- j - a rational number.245246- S - list of primes (default: empty list).247248.. note::249250Primality of elements of S is not checked, and the output251is undefined if S is not a list or contains non-primes.252253OUTPUT:254255A sorted list of all elliptic curves defined over `Q` with256`j`-invariant equal to `j` and with good reduction at257all primes outside the list ``S``.258259EXAMPLES::260261sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j262sage: [e.label() for e in egros_from_j(0,[3])]263['27a1', '27a3', '243a1', '243a2', '243b1', '243b2']264sage: [e.label() for e in egros_from_j(1728,[2])]265['32a1', '32a2', '64a1', '64a4', '256b1', '256b2', '256c1', '256c2']266sage: elist=egros_from_j(-4096/11,[11])267sage: [e.label() for e in elist]268['11a3', '121d1']269270"""271if j == 1728:272return egros_from_j_1728(S)273274if j == 0:275return egros_from_j_0(S)276277# Now j != 0, 1728278279E = EllipticCurve_from_j(j)280Elist=[]281282for ei in xmrange([2]*(1+len(S))):283u = prod([p**e for p,e in zip(reversed([-1]+S),ei)],QQ(1))284Eu = E.quadratic_twist(u).minimal_model()285if Eu.has_good_reduction_outside_S(S):286Elist += [Eu]287288Elist.sort(cmp=curve_cmp)289return Elist290291def egros_from_jlist(jlist,S=[]):292r"""293Given a list of rational j and a list of primes S, returns a list294of elliptic curves over Q with j-invariant in the list and good295reduction outside S.296297INPUT:298299- j - list of rational numbers.300301- S - list of primes (default: empty list).302303.. note::304305Primality of elements of S is not checked, and the output306is undefined if S is not a list or contains non-primes.307308OUTPUT:309310A sorted list of all elliptic curves defined over `Q` with311`j`-invariant in the list ``jlist`` and with good reduction at312all primes outside the list ``S``.313314EXAMPLES::315316sage: from sage.schemes.elliptic_curves.ell_egros import egros_get_j, egros_from_jlist317sage: jlist=egros_get_j([3])318sage: elist=egros_from_jlist(jlist,[3])319sage: [e.label() for e in elist]320['27a1', '27a2', '27a3', '27a4', '243a1', '243a2', '243b1', '243b2']321sage: [e.ainvs() for e in elist]322[(0, 0, 1, 0, -7),323(0, 0, 1, -270, -1708),324(0, 0, 1, 0, 0),325(0, 0, 1, -30, 63),326(0, 0, 1, 0, -1),327(0, 0, 1, 0, 20),328(0, 0, 1, 0, 2),329(0, 0, 1, 0, -61)]330"""331elist = sum([egros_from_j(j,S) for j in jlist],[])332elist.sort(cmp=curve_cmp)333return elist334335def egros_get_j(S=[], proof=None, verbose=False):336r"""337Returns a list of rational `j` such that all elliptic curves338defined over `Q` with good reduction outside `S` have339`j`-invariant in the list, sorted by height.340341INPUT:342343- ``S`` - list of primes (default: empty list).344345- ``proof`` - True/False (default True): the MW basis for346auxiliary curves will be computed with this proof flag.347348- ``verbose`` - True/False (default False): if True, some349details of the computation will be output.350351.. note::352353Proof flag: The algorithm used requires determining all354S-integral points on several auxiliary curves, which in turn355requires the computation of their generators. This is not356always possible (even in theory) using current knowledge.357358The value of this flag is passed to the function which359computes generators of various auxiliary elliptic curves, in360order to find their S-integral points. Set to False if the361default (True) causes warning messages, but note that you can362then not rely on the set of invariants returned being363complete.364365EXAMPLES::366367sage: from sage.schemes.elliptic_curves.ell_egros import egros_get_j368sage: egros_get_j([])369[1728]370sage: egros_get_j([2])371[128, 432, -864, 1728, 3375/2, -3456, 6912, 8000, 10976, -35937/4, 287496, -784446336, -189613868625/128]372sage: egros_get_j([3])373[0, -576, 1536, 1728, -5184, -13824, 21952/9, -41472, 140608/3, -12288000]374sage: jlist=egros_get_j([2,3]); len(jlist) # long time (30s)37583376377"""378if not all([p.is_prime() for p in S]):379raise ValueError, "Elements of S must be prime."380381if proof is None:382from sage.structure.proof.proof import get_flag383proof = get_flag(proof, "elliptic_curve")384else:385proof = bool(proof)386387if verbose:388import sys # so we can flush stdout for debugging389390SS = [-1] + S391392jlist=[]393wcount=0394nw = 6**len(S) * 2395396if verbose:397print "Finding possible j invariants for S = ",S398print "Using ", nw, " twists of base curve"399sys.stdout.flush()400401for ei in xmrange([6]*len(S) + [2]):402w = prod([p**e for p,e in zip(reversed(SS),ei)],QQ(1))403wcount+=1404if verbose:405print "Curve #",wcount, "/",nw,":";406print "w = ",w,"=",w.factor()407sys.stdout.flush()408a6 = -1728*w409d2 = 0410d3 = 0411u0 = (2**d2)*(3**d3)412E = EllipticCurve([0,0,0,0,a6])413# This curve may not be minimal at 2 or 3, but the414# S-integral_points function requires minimality at primes in415# S, so we find a new model which is p-minimal at both 2 and 3416# if they are in S. Note that the isomorphism between models417# will preserve S-integrality of points.418E2 = E.local_minimal_model(2) if 2 in S else E419E23 = E2.local_minimal_model(3) if 3 in S else E2420urst = E23.isomorphism_to(E)421422try:423pts = E23.S_integral_points(S,proof=proof)424except RuntimeError:425pts=[]426print "Failed to find S-integral points on ",E23.ainvs()427if proof:428if verbose:429print "--trying again with proof=False"430sys.stdout.flush()431pts = E23.S_integral_points(S,proof=False)432if verbose:433print "--done"434if verbose:435print len(pts), " S-integral points: ",pts436sys.stdout.flush()437for P in pts:438P = urst(P)439x = P[0]440y = P[1]441j = x**3 /w442assert j-1728 == y**2 /w443if is_possible_j(j,S):444if not j in jlist:445if verbose:446print "Adding possible j = ",j447sys.stdout.flush()448jlist += [j]449else:450if True: #verbose:451print "Discarding illegal j = ",j452sys.stdout.flush()453height_cmp = lambda j1,j2: cmp(j1.height(),j2.height())454jlist.sort(cmp=height_cmp)455return jlist456457458459