Path: blob/master/src/sage/schemes/elliptic_curves/ell_rational_field.py
8820 views
# -*- coding: utf-8 -*-1"""2Elliptic curves over the rational numbers34AUTHORS:56- William Stein (2005): first version78- William Stein (2006-02-26): fixed Lseries_extended which didn't work9because of changes elsewhere in Sage.1011- David Harvey (2006-09): Added padic_E2, padic_sigma, padic_height,12padic_regulator methods.1314- David Harvey (2007-02): reworked padic-height related code1516- Christian Wuthrich (2007): added padic sha computation1718- David Roe (2007-09): moved sha, l-series and p-adic functionality to19separate files.2021- John Cremona (2008-01)2223- Tobias Nagel and Michael Mardaus (2008-07): added integral_points2425- John Cremona (2008-07): further work on integral_points2627- Christian Wuthrich (2010-01): moved Galois reps and modular28parametrization in a separate file2930- Simon Spicer (2013-03): Added code for modular degrees and congruence31numbers of higher level3233"""3435##############################################################################36# Copyright (C) 2005,2006,2007 William Stein <[email protected]>37#38# Distributed under the terms of the GNU General Public License (GPL)39#40# This code is distributed in the hope that it will be useful,41# but WITHOUT ANY WARRANTY; without even the implied warranty of42# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU43# General Public License for more details.44#45# The full text of the GPL is available at:46#47# http://www.gnu.org/licenses/48##############################################################################4950import constructor51import BSD52from ell_generic import is_EllipticCurve53import ell_modular_symbols54from ell_number_field import EllipticCurve_number_field55import ell_point56import ell_tate_curve57import ell_torsion58import heegner59from gp_simon import simon_two_descent60from lseries_ell import Lseries_ell61import mod5family62from modular_parametrization import ModularParameterization63import padic_lseries64import padics6566from sage.modular.modsym.modsym import ModularSymbols6768import sage.modular.modform.constructor69import sage.modular.modform.element70import sage.libs.mwrank.all as mwrank71import sage.databases.cremona7273import sage.rings.arith as arith74import sage.rings.all as rings75from sage.rings.all import (76PowerSeriesRing,77infinity as oo,78ZZ, QQ,79Integer,80IntegerRing, RealField,81ComplexField, RationalField)8283import sage.misc.misc as misc84from sage.misc.all import verbose8586from sage.misc.functional import log8788import sage.matrix.all as matrix89from sage.libs.pari.all import pari, PariError90from sage.functions.other import gamma_inc91from math import sqrt92from sage.interfaces.all import gp93from sage.misc.cachefunc import cached_method94from copy import copy9596Q = RationalField()97C = ComplexField()98R = RealField()99Z = IntegerRing()100IR = rings.RealIntervalField(20)101102_MAX_HEIGHT=21103104# complex multiplication dictionary:105# CMJ is a dict of pairs (j,D) where j is a rational CM j-invariant106# and D is the corresponding quadratic discriminant107108CMJ={ 0: -3, 54000: -12, -12288000: -27, 1728: -4, 287496: -16,109-3375: -7, 16581375: -28, 8000: -8, -32768: -11, -884736: -19,110-884736000: -43, -147197952000: -67, -262537412640768000: -163}111112113class EllipticCurve_rational_field(EllipticCurve_number_field):114r"""115Elliptic curve over the Rational Field.116117INPUT:118119- ``ainvs`` (list or string) -- either `[a_1,a_2,a_3,a_4,a_6]` or120`[a_4,a_6]` (with `a_1=a_2=a_3=0`) or a valid label from the121database.122123.. note::124125See constructor.py for more variants.126127EXAMPLES:128129Construction from Weierstrass coefficients (`a`-invariants), long form::130131sage: E = EllipticCurve([1,2,3,4,5]); E132Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field133134Construction from Weierstrass coefficients (`a`-invariants),135short form (sets `a_1=a_2=a_3=0`)::136137sage: EllipticCurve([4,5]).ainvs()138(0, 0, 0, 4, 5)139140Construction from a database label::141142sage: EllipticCurve('389a1')143Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field144145"""146def __init__(self, ainvs, extra=None):147r"""148Constructor for the EllipticCurve_rational_field class.149150INPUT:151152- ``ainvs`` (list or string) -- either `[a_1,a_2,a_3,a_4,a_6]`153or `[a_4,a_6]` (with `a_1=a_2=a_3=0`) or a valid label from154the database.155156.. note::157158See constructor.py for more variants.159160EXAMPLES::161162sage: E = EllipticCurve([1,2,3,4,5]); E163Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field164165Constructor from `[a_4,a_6]` sets `a_1=a_2=a_3=0`::166167sage: EllipticCurve([4,5]).ainvs()168(0, 0, 0, 4, 5)169170Constructor from a Cremona label::171172sage: EllipticCurve('389a1')173Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field174175Constructor from an LMFDB label::176177sage: EllipticCurve('462.f3')178Elliptic Curve defined by y^2 + x*y = x^3 - 363*x + 1305 over Rational Field179180TESTS:181182When constructing a curve from the large database using a183label, we must be careful that the copied generators have the184right curve (see #10999: the following used not to work when185the large database was installed)::186187sage: E=EllipticCurve('389a1')188sage: [P.curve() is E for P in E.gens()]189[True, True]190191"""192if extra != None: # possibility of two arguments (the first would be the field)193ainvs = extra194self.__np = {}195self.__gens = {}196self.__rank = {}197self.__regulator = {}198self.__generalized_modular_degree = {}199self.__generalized_congruence_number = {}200self._isoclass = {}201if isinstance(ainvs, str):202label = ainvs203X = sage.databases.cremona.CremonaDatabase()[label]204EllipticCurve_number_field.__init__(self, Q, list(X.a_invariants()))205for attr in ['rank', 'torsion_order', 'cremona_label', 'conductor',206'modular_degree', 'gens', 'regulator']:207s = "_EllipticCurve_rational_field__"+attr208if hasattr(X,s):209if attr == 'gens': # see #10999210gens_dict = getattr(X, s)211for boo in gens_dict.keys():212gens_dict[boo] = [self(P) for P in gens_dict[boo]]213setattr(self, s, gens_dict)214else:215setattr(self, s, getattr(X, s))216if hasattr(X,'_lmfdb_label'):217self._lmfdb_label = X._lmfdb_label218return219EllipticCurve_number_field.__init__(self, Q, ainvs)220if self.base_ring() != Q:221raise TypeError, "Base field (=%s) must be the Rational Field."%self.base_ring()222223def _set_rank(self, r):224"""225Internal function to set the cached rank of this elliptic curve to226r.227228.. warning::229230No checking is done! Not intended for use by users.231232EXAMPLES::233234sage: E = EllipticCurve('37a1')235sage: E._set_rank(99) # bogus value -- not checked236sage: E.rank() # returns bogus cached value23799238sage: E._EllipticCurve_rational_field__rank={} # undo the damage239sage: E.rank() # the correct rank2401241"""242self.__rank = {}243self.__rank[True] = Integer(r)244245def _set_torsion_order(self, t):246"""247Internal function to set the cached torsion order of this elliptic248curve to t.249250.. warning::251252No checking is done! Not intended for use by users.253254EXAMPLES::255256sage: E=EllipticCurve('37a1')257sage: E._set_torsion_order(99) # bogus value -- not checked258sage: E.torsion_order() # returns bogus cached value25999260sage: T = E.torsion_subgroup() # causes actual torsion to be computed261sage: E.torsion_order() # the correct value2621263"""264self.__torsion_order = Integer(t)265266def _set_cremona_label(self, L):267"""268Internal function to set the cached label of this elliptic curve to269L.270271.. warning::272273No checking is done! Not intended for use by users.274275EXAMPLES::276277sage: E=EllipticCurve('37a1')278sage: E._set_cremona_label('bogus')279sage: E.label()280'bogus'281sage: E.database_curve().label()282'37a1'283sage: E.label() # no change284'bogus'285sage: E._set_cremona_label(E.database_curve().label())286sage: E.label() # now it is correct287'37a1'288"""289self.__cremona_label = L290291def _set_conductor(self, N):292"""293Internal function to set the cached conductor of this elliptic294curve to N.295296.. warning::297298No checking is done! Not intended for use by users.299Setting to the wrong value will cause strange problems (see300examples).301302EXAMPLES::303304sage: E=EllipticCurve('37a1')305sage: E._set_conductor(99) # bogus value -- not checked306sage: E.conductor() # returns bogus cached value30799308"""309self.__conductor_pari = Integer(N)310311def _set_modular_degree(self, deg):312"""313Internal function to set the cached modular degree of this elliptic314curve to deg.315316.. warning::317318No checking is done!319320EXAMPLES::321322sage: E=EllipticCurve('5077a1')323sage: E.modular_degree()3241984325sage: E._set_modular_degree(123456789)326sage: E.modular_degree()327123456789328sage: E._set_modular_degree(E.database_curve().modular_degree())329sage: E.modular_degree()3301984331"""332self.__modular_degree = Integer(deg)333334def _set_gens(self, gens):335"""336Internal function to set the cached generators of this elliptic337curve to gens.338339.. warning::340341No checking is done!342343EXAMPLES::344345sage: E=EllipticCurve('5077a1')346sage: E.rank()3473348sage: E.gens() # random349[(-2 : 3 : 1), (-7/4 : 25/8 : 1), (1 : -1 : 1)]350sage: E._set_gens([]) # bogus list351sage: E.rank() # unchanged3523353sage: E._set_gens([E(-2,3), E(-1,3), E(0,2)])354sage: E.gens()355[(-2 : 3 : 1), (-1 : 3 : 1), (0 : 2 : 1)]356"""357self.__gens = {}358self.__gens[True] = [self.point(x, check=True) for x in gens]359self.__gens[True].sort()360361362def is_p_integral(self, p):363r"""364Returns True if this elliptic curve has `p`-integral365coefficients.366367INPUT:368369370- ``p`` - a prime integer371372373EXAMPLES::374375sage: E=EllipticCurve(QQ,[1,1]); E376Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field377sage: E.is_p_integral(2)378True379sage: E2=E.change_weierstrass_model(2,0,0,0); E2380Elliptic Curve defined by y^2 = x^3 + 1/16*x + 1/64 over Rational Field381sage: E2.is_p_integral(2)382False383sage: E2.is_p_integral(3)384True385"""386if not arith.is_prime(p):387raise ArithmeticError, "p must be prime"388if self.is_integral():389return True390return bool(misc.mul([x.valuation(p) >= 0 for x in self.ainvs()]))391392def is_integral(self):393"""394Returns True if this elliptic curve has integral coefficients (in395Z)396397EXAMPLES::398399sage: E=EllipticCurve(QQ,[1,1]); E400Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field401sage: E.is_integral()402True403sage: E2=E.change_weierstrass_model(2,0,0,0); E2404Elliptic Curve defined by y^2 = x^3 + 1/16*x + 1/64 over Rational Field405sage: E2.is_integral()406False407"""408try:409return self.__is_integral410except AttributeError:411one = Integer(1)412self.__is_integral = bool(misc.mul([x.denominator() == 1 for x in self.ainvs()]))413return self.__is_integral414415416def mwrank(self, options=''):417r"""418Run Cremona's mwrank program on this elliptic curve and return the419result as a string.420421INPUT:422423424- ``options`` (string) -- run-time options passed when starting mwrank.425The format is as follows (see below for examples of usage):426427- ``-v n`` (verbosity level) sets verbosity to n (default=1)428- ``-o`` (PARI/GP style output flag) turns ON extra PARI/GP short output (default is OFF)429- ``-p n`` (precision) sets precision to `n` decimals (default=15)430- ``-b n`` (quartic bound) bound on quartic point search (default=10)431- ``-x n`` (n_aux) number of aux primes used for sieving (default=6)432- ``-l`` (generator list flag) turns ON listing of points (default ON unless v=0)433- ``-s`` (selmer_only flag) if set, computes Selmer rank only (default: not set)434- ``-d`` (skip_2nd_descent flag) if set, skips the second descent for curves with 2-torsion (default: not set)435- ``-S n`` (sat_bd) upper bound on saturation primes (default=100, -1 for automatic)436437OUTPUT:438439- ``string`` - output of mwrank on this curve440441442.. note::443444The output is a raw string and completely illegible using445automatic display, so it is recommended to use print for446legible output.447448EXAMPLES::449450sage: E = EllipticCurve('37a1')451sage: E.mwrank() #random452...453sage: print E.mwrank()454Curve [0,0,1,-1,0] : Basic pair: I=48, J=-432455disc=255744456...457Generator 1 is [0:-1:1]; height 0.05111...458459Regulator = 0.05111...460461The rank and full Mordell-Weil basis have been determined unconditionally.462...463464Options to mwrank can be passed::465466sage: E = EllipticCurve([0,0,0,877,0])467468Run mwrank with 'verbose' flag set to 0 but list generators if469found470471::472473sage: print E.mwrank('-v0 -l')474Curve [0,0,0,877,0] : 0 <= rank <= 1475Regulator = 1476477Run mwrank again, this time with a higher bound for point searching478on homogeneous spaces::479480sage: print E.mwrank('-v0 -l -b11')481Curve [0,0,0,877,0] : Rank = 1482Generator 1 is [29604565304828237474403861024284371796799791624792913256602210:-256256267988926809388776834045513089648669153204356603464786949:490078023219787588959802933995928925096061616470779979261000]; height 95.980371987964483Regulator = 95.980371987964484"""485if options == "":486from sage.interfaces.all import mwrank487else:488from sage.interfaces.all import Mwrank489mwrank = Mwrank(options=options)490return mwrank(list(self.a_invariants()))491492def conductor(self, algorithm="pari"):493"""494Returns the conductor of the elliptic curve.495496INPUT:497498499- ``algorithm`` - str, (default: "pari")500501- ``"pari"`` - use the PARI C-library ellglobalred502implementation of Tate's algorithm503504- ``"mwrank"`` - use Cremona's mwrank implementation505of Tate's algorithm; can be faster if the curve has integer506coefficients (TODO: limited to small conductor until mwrank gets507integer factorization)508509- ``"gp"`` - use the GP interpreter.510511- ``"generic"`` - use the general number field512implementation513514- ``"all"`` - use all four implementations, verify515that the results are the same (or raise an error), and output the516common value.517518519EXAMPLE::520521sage: E = EllipticCurve([1, -1, 1, -29372, -1932937])522sage: E.conductor(algorithm="pari")5233006524sage: E.conductor(algorithm="mwrank")5253006526sage: E.conductor(algorithm="gp")5273006528sage: E.conductor(algorithm="generic")5293006530sage: E.conductor(algorithm="all")5313006532533.. note::534535The conductor computed using each algorithm is cached536separately. Thus calling ``E.conductor('pari')``, then537``E.conductor('mwrank')`` and getting the same result538checks that both systems compute the same answer.539"""540541if algorithm == "pari":542try:543return self.__conductor_pari544except AttributeError:545self.__conductor_pari = Integer(self.pari_mincurve().ellglobalred()[0])546return self.__conductor_pari547548elif algorithm == "gp":549try:550return self.__conductor_gp551except AttributeError:552self.__conductor_gp = Integer(gp.eval('ellglobalred(ellinit(%s,0))[1]'%list(self.a_invariants())))553return self.__conductor_gp554555elif algorithm == "mwrank":556try:557return self.__conductor_mwrank558except AttributeError:559if self.is_integral():560self.__conductor_mwrank = Integer(self.mwrank_curve().conductor())561else:562self.__conductor_mwrank = Integer(self.minimal_model().mwrank_curve().conductor())563return self.__conductor_mwrank564565elif algorithm == "generic":566try:567return self.__conductor_generic568except AttributeError:569self.__conductor_generic = sage.schemes.elliptic_curves.ell_number_field.EllipticCurve_number_field.conductor(self).gen()570return self.__conductor_generic571572elif algorithm == "all":573N1 = self.conductor("pari")574N2 = self.conductor("mwrank")575N3 = self.conductor("gp")576N4 = self.conductor("generic")577if N1 != N2 or N2 != N3 or N2 != N4:578raise ArithmeticError, "PARI, mwrank, gp and Sage compute different conductors (%s,%s,%s,%3) for %s"%(579N1, N2, N3, N4, self)580return N1581else:582raise RuntimeError, "algorithm '%s' is not known."%algorithm583584####################################################################585# Access to PARI curves related to this curve.586####################################################################587588def pari_curve(self, prec=None, factor=1):589"""590Return the PARI curve corresponding to this elliptic curve.591592INPUT:593594595- ``prec`` - The precision of quantities calculated for the596returned curve, in bits. If None, defaults to factor597multiplied by the precision of the largest cached curve (or598a small default precision depending on the curve if none yet599computed).600601- ``factor`` - The factor by which to increase the602precision over the maximum previously computed precision. Only used603if prec (which gives an explicit precision) is None.604605606EXAMPLES::607608sage: E = EllipticCurve([0, 0, 1, -1, 0])609sage: e = E.pari_curve()610sage: type(e)611<type 'sage.libs.pari.gen.gen'>612sage: e.type()613't_VEC'614sage: e.ellan(10)615[1, -2, -3, 2, -2, 6, -1, 0, 6, 4]616617::618619sage: E = EllipticCurve(RationalField(), ['1/3', '2/3'])620sage: e = E.pari_curve(prec=100)621sage: E._pari_curve.has_key(100)622True623sage: e.type()624't_VEC'625sage: e[:5]626[0, 0, 0, 1/3, 2/3]627628This shows that the bug uncovered by trac:`3954` is fixed::629630sage: E._pari_curve.has_key(100)631True632633::634635sage: E = EllipticCurve('37a1')636sage: Epari = E.pari_curve()637sage: Epari[14].python().prec()63864639sage: [a.precision() for a in Epari]640[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4] # 32-bit641[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3] # 64-bit642sage: Epari = E.pari_curve(factor=2)643sage: Epari[14].python().prec()644128645646This shows that the bug uncovered by trac`4715` is fixed::647648sage: Ep = EllipticCurve('903b3').pari_curve()649650When the curve coefficients are large, a larger precision is651required (see :trac:`13163`)::652653sage: E = EllipticCurve([4382696457564794691603442338788106497, 28, 3992, 16777216, 298])654sage: E.pari_curve(prec=64)655Traceback (most recent call last):656...657PariError: precision too low in ellinit658sage: E.pari_curve() # automatically choose the right precision659[4382696457564794691603442338788106497, 28, 3992, 16777216, 298, ...]660sage: E.minimal_model()661Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 7686423934083797390675981169229171907674183588326184511391146727143672423167091484392497987721106542488224058921302964259990799229848935835464702*x + 8202280443553761483773108648734271851215988504820214784899752662100459663011709992446860978259617135893103951840830254045837355547141096270521198994389833928471736723050112419004202643591202131091441454709193394358885 over Rational Field662"""663try:664# if the PARI curve has already been computed to this665# precision, returned the cached copy666return self._pari_curve[prec]667except AttributeError:668self._pari_curve = {}669except KeyError:670pass671672# Double the precision if needed?673retry_prec = False674675if prec is None:676if len(self._pari_curve) == 0:677# No curves computed yet678prec = 64679retry_prec = True680else:681# Take largest cached precision682prec = max(self._pari_curve.keys())683if factor == 1:684return self._pari_curve[prec]685prec = int(prec * factor)686687pari_invariants = pari(self.a_invariants())688while True:689try:690self._pari_curve[prec] = pari_invariants.ellinit(precision=prec)691return self._pari_curve[prec]692except PariError as e:693if retry_prec and 'precision too low' in str(e):694# Retry with double precision695prec *= 2696else:697raise698699def pari_mincurve(self, prec=None, factor=1):700"""701Return the PARI curve corresponding to a minimal model for this702elliptic curve.703704INPUT:705706707- ``prec`` - The precision of quantities calculated for the708returned curve, in bits. If None, defaults to factor709multiplied by the precision of the largest cached curve (or710the default real precision if none yet computed).711712- ``factor`` - The factor by which to increase the713precision over the maximum previously computed precision. Only used714if prec (which gives an explicit precision) is None.715716717EXAMPLES::718719sage: E = EllipticCurve(RationalField(), ['1/3', '2/3'])720sage: e = E.pari_mincurve()721sage: e[:5]722[0, 0, 0, 27, 486]723sage: E.conductor()72447232725sage: e.ellglobalred()726[47232, [1, 0, 0, 0], 2]727"""728try:729# if the PARI curve has already been computed to this730# precision, returned the cached copy731return self._pari_mincurve[prec]732except AttributeError:733# no PARI curves have been computed for this elliptic curve734self._pari_mincurve = {}735except KeyError:736# PARI curves are cached for this elliptic curve, but they737# are not of the requested precision (or prec = None)738if prec is None:739L = self._pari_mincurve.keys()740L.sort()741if factor == 1:742return self._pari_mincurve[L[-1]]743else:744prec = int(factor * L[-1])745e = self.pari_curve(prec)746mc, change = e.ellminimalmodel()747self._pari_mincurve[prec] = mc748# self.__min_transform = change749return mc750751def database_curve(self):752"""753Return the curve in the elliptic curve database isomorphic to this754curve, if possible. Otherwise raise a RuntimeError exception.755756EXAMPLES::757758sage: E = EllipticCurve([0,1,2,3,4])759sage: E.database_curve()760Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 5 over Rational Field761762.. note::763764The model of the curve in the database can be different765from the Weierstrass model for this curve, e.g., database766models are always minimal.767"""768try:769return self.__database_curve770except AttributeError:771misc.verbose("Looking up %s in the database."%self)772D = sage.databases.cremona.CremonaDatabase()773ainvs = list(self.minimal_model().ainvs())774try:775self.__database_curve = D.elliptic_curve_from_ainvs(ainvs)776except RuntimeError:777raise RuntimeError, "Elliptic curve %s not in the database."%self778return self.__database_curve779780781def Np(self, p):782r"""783The number of points on `E` modulo `p`.784785INPUT:786787- ``p`` (int) -- a prime, not necessarily of good reduction.788789790OUTPUT:791792(int) The number ofpoints on the reduction of `E` modulo `p`793(including the singular point when `p` is a prime of bad794reduction).795796EXAMPLES::797798sage: E = EllipticCurve([0, -1, 1, -10, -20])799sage: E.Np(2)8005801sage: E.Np(3)8025803sage: E.conductor()80411805sage: E.Np(11)80611807808This even works when the prime is large::809810sage: E = EllipticCurve('37a')811sage: E.Np(next_prime(10^30))8121000000000000001426441464441649813"""814if self.conductor() % p == 0:815return p + 1 - self.ap(p)816return p+1 - self.ap(p)817818#def __pari_double_prec(self):819# EllipticCurve_number_field._EllipticCurve__pari_double_prec(self)820# try:821# del self._pari_mincurve822# except AttributeError:823# pass824825####################################################################826# Access to mwrank827####################################################################828def mwrank_curve(self, verbose=False):829"""830Construct an mwrank_EllipticCurve from this elliptic curve831832The resulting mwrank_EllipticCurve has available methods from John833Cremona's eclib library.834835EXAMPLES::836837sage: E=EllipticCurve('11a1')838sage: EE=E.mwrank_curve()839sage: EE840y^2+ y = x^3 - x^2 - 10*x - 20841sage: type(EE)842<class 'sage.libs.mwrank.interface.mwrank_EllipticCurve'>843sage: EE.isogeny_class()844([[0, -1, 1, -10, -20], [0, -1, 1, -7820, -263580], [0, -1, 1, 0, 0]],845[[0, 5, 5], [5, 0, 0], [5, 0, 0]])846"""847try:848return self.__mwrank_curve849except AttributeError:850pass851self.__mwrank_curve = mwrank.mwrank_EllipticCurve(852list(self.ainvs()), verbose=verbose)853return self.__mwrank_curve854855def two_descent(self, verbose=True,856selmer_only = False,857first_limit = 20,858second_limit = 8,859n_aux = -1,860second_descent = 1):861"""862Compute 2-descent data for this curve.863864INPUT:865866867- ``verbose`` - (default: True) print what mwrank is868doing. If False, **no output** is printed.869870- ``selmer_only`` - (default: False) selmer_only871switch872873- ``first_limit`` - (default: 20) firstlim is bound874on x+z second_limit- (default: 8) secondlim is bound on log max875x,z , i.e. logarithmic876877- ``n_aux`` - (default: -1) n_aux only relevant for878general 2-descent when 2-torsion trivial; n_aux=-1 causes default879to be used (depends on method)880881- ``second_descent`` - (default: True)882second_descent only relevant for descent via 2-isogeny883884885OUTPUT:886887Returns ``True`` if the descent succeeded, i.e. if the lower bound and888the upper bound for the rank are the same. In this case, generators and889the rank are cached. A return value of ``False`` indicates that either890rational points were not found, or that Sha[2] is nontrivial and mwrank891was unable to determine this for sure.892893EXAMPLES::894895sage: E=EllipticCurve('37a1')896sage: E.two_descent(verbose=False)897True898899"""900misc.verbose("Calling mwrank C++ library.")901C = self.mwrank_curve()902C.two_descent(verbose, selmer_only,903first_limit, second_limit,904n_aux, second_descent)905if C.certain():906self.__gens[True] = [self.point(x, check=True) for x in C.gens()]907self.__gens[True].sort()908self.__rank[True] = len(self.__gens[True])909return C.certain()910911####################################################################912# Etc.913####################################################################914915def aplist(self, n, python_ints=False):916r"""917The Fourier coefficients `a_p` of the modular form918attached to this elliptic curve, for all primes `p\leq n`.919920INPUT:921922923- ``n`` - integer924925- ``python_ints`` - bool (default: False); if True926return a list of Python ints instead of Sage integers.927928929OUTPUT: list of integers930931EXAMPLES::932933sage: e = EllipticCurve('37a')934sage: e.aplist(1)935[]936sage: e.aplist(2)937[-2]938sage: e.aplist(10)939[-2, -3, -2, -1]940sage: v = e.aplist(13); v941[-2, -3, -2, -1, -5, -2]942sage: type(v[0])943<type 'sage.rings.integer.Integer'>944sage: type(e.aplist(13, python_ints=True)[0])945<type 'int'>946"""947e = self.pari_mincurve()948v = e.ellaplist(n, python_ints=True)949if python_ints:950return v951else:952return [Integer(a) for a in v]953954955956def anlist(self, n, python_ints=False):957"""958The Fourier coefficients up to and including `a_n` of the959modular form attached to this elliptic curve. The i-th element of960the return list is a[i].961962INPUT:963964965- ``n`` - integer966967- ``python_ints`` - bool (default: False); if True968return a list of Python ints instead of Sage integers.969970971OUTPUT: list of integers972973EXAMPLES::974975sage: E = EllipticCurve([0, -1, 1, -10, -20])976sage: E.anlist(3)977[0, 1, -2, -1]978979::980981sage: E = EllipticCurve([0,1])982sage: E.anlist(20)983[0, 1, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 8, 0]984"""985n = int(n)986e = self.pari_mincurve()987if n >= 2147483648:988raise RuntimeError, "anlist: n (=%s) must be < 2147483648."%n989990v = [0] + e.ellan(n, python_ints=True)991if not python_ints:992v = [Integer(x) for x in v]993return v994995996# There is some overheard associated with coercing the PARI997# list back to Python, but it's not bad. It's better to do it998# this way instead of trying to eval the whole list, since the999# int conversion is done very sensibly. NOTE: This would fail1000# if a_n won't fit in a C int, i.e., is bigger than1001# 2147483648; however, we wouldn't realistically compute1002# anlist for n that large anyway.1003#1004# Some relevant timings:1005#1006# E <--> [0, 1, 1, -2, 0] 389A1007# E = EllipticCurve([0, 1, 1, -2, 0]); // Sage or MAGMA1008# e = E.pari_mincurve()1009# f = ellinit([0,1,1,-2,0]);1010#1011# Computation Time (1.6Ghz Pentium-4m laptop)1012# time v:=TracesOfFrobenius(E,10000); // MAGMA 0.1201013# gettime;v=ellan(f,10000);gettime/1000 0.0461014# time v=e.ellan (10000) 0.041015# time v=E.anlist(10000) 0.0710161017# time v:=TracesOfFrobenius(E,100000); // MAGMA 1.6201018# gettime;v=ellan(f,100000);gettime/1000 0.6761019# time v=e.ellan (100000) 0.71020# time v=E.anlist(100000) 0.8310211022# time v:=TracesOfFrobenius(E,1000000); // MAGMA 20.8501023# gettime;v=ellan(f,1000000);gettime/1000 9.2381024# time v=e.ellan (1000000) 9.611025# time v=E.anlist(1000000) 10.95 (13.171 in cygwin vmware)10261027# time v:=TracesOfFrobenius(E,10000000); //MAGMA 257.8501028# gettime;v=ellan(f,10000000);gettime/1000 FAILS no matter how many allocatemem()'s!!1029# time v=e.ellan (10000000) 139.371030# time v=E.anlist(10000000) 136.321031#1032# The last Sage comp retries with stack size 40MB,1033# 80MB, 160MB, and succeeds last time. It's very interesting that this1034# last computation is *not* possible in GP, but works in py_pari!1035#10361037def q_expansion(self, prec):1038r"""1039Return the `q`-expansion to precision prec of the newform1040attached to this elliptic curve.10411042INPUT:104310441045- ``prec`` - an integer104610471048OUTPUT:10491050a power series (in the variable 'q')10511052.. note::10531054If you want the output to be a modular form and not just a1055`q`-expansion, use :meth:`.modular_form`.10561057EXAMPLES::10581059sage: E=EllipticCurve('37a1')1060sage: E.q_expansion(20)1061q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + 4*q^10 - 5*q^11 - 6*q^12 - 2*q^13 + 2*q^14 + 6*q^15 - 4*q^16 - 12*q^18 + O(q^20)1062"""1063return PowerSeriesRing(Q, 'q')(self.anlist(prec), prec, check=True)10641065def modular_form(self):1066r"""1067Return the cuspidal modular form associated to this elliptic1068curve.10691070EXAMPLES::10711072sage: E = EllipticCurve('37a')1073sage: f = E.modular_form()1074sage: f1075q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)10761077If you need to see more terms in the `q`-expansion::10781079sage: f.q_expansion(20)1080q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + 4*q^10 - 5*q^11 - 6*q^12 - 2*q^13 + 2*q^14 + 6*q^15 - 4*q^16 - 12*q^18 + O(q^20)10811082.. note::10831084If you just want the `q`-expansion, use1085:meth:`.q_expansion`.1086"""1087try:1088return self.__modular_form1089except AttributeError:1090M = sage.modular.modform.constructor.ModularForms(self.conductor(),weight=2)1091f = sage.modular.modform.element.ModularFormElement_elliptic_curve(M, self)1092self.__modular_form = f1093return f10941095def modular_symbol_space(self, sign=1, base_ring=Q, bound=None):1096r"""1097Return the space of cuspidal modular symbols associated to this1098elliptic curve, with given sign and base ring.10991100INPUT:110111021103- ``sign`` - 0, -1, or 111041105- ``base_ring`` - a ring110611071108EXAMPLES::11091110sage: f = EllipticCurve('37b')1111sage: f.modular_symbol_space()1112Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(37) of weight 2 with sign 1 over Rational Field1113sage: f.modular_symbol_space(-1)1114Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(37) of weight 2 with sign -1 over Rational Field1115sage: f.modular_symbol_space(0, bound=3)1116Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field11171118.. note::11191120If you just want the `q`-expansion, use1121:meth:`.q_expansion`.1122"""1123typ = (sign, base_ring)1124try:1125return self.__modular_symbol_space[typ]1126except AttributeError:1127self.__modular_symbol_space = {}1128except KeyError:1129pass1130M = ell_modular_symbols.modular_symbol_space(self, sign, base_ring, bound=bound)1131self.__modular_symbol_space[typ] = M1132return M11331134def modular_symbol(self, sign=1, use_eclib = False, normalize = "L_ratio"):1135r"""1136Return the modular symbol associated to this elliptic curve,1137with given sign and base ring. This is the map that sends `r/s`1138to a fixed multiple of the integral of `2 \pi i f(z) dz`1139from `\infty` to `r/s`, normalized so that all values of this map take1140values in `\QQ`.11411142The normalization is such that for sign +1,1143the value at the cusp 0 is equal to the quotient of `L(E,1)`1144by the least positive period of `E` (unlike in ``L_ratio``1145of ``lseries()``, where the value is also divided by the1146number of connected components of `E(\RR)`). In particular the1147modular symbol depends on `E` and not only the isogeny class of `E`.11481149INPUT:11501151- ``sign`` - 1 (default) or -111521153- ``use_eclib`` - (default: False); if True the computation is1154done with John Cremona's implementation of modular1155symbols in ``eclib``11561157- ``normalize`` - (default: 'L_ratio'); either 'L_ratio',1158'period', or 'none';1159For 'L_ratio', the modular symbol tries to normalized correctly1160as explained above by comparing it to ``L_ratio`` for the1161curve and some small twists.1162The normalization 'period' is only available if1163``use_eclib=False``. It uses the ``integral_period_map`` for modular1164symbols and is known to be equal to the above normalization1165up to the sign and a possible power of 2.1166For 'none', the modular symbol is almost certainly1167not correctly normalized, i.e. all values will be a1168fixed scalar multiple of what they should be. But1169the initial computation of the modular symbol is1170much faster if ``use_eclib=False``, though evaluation of1171it after computing it won't be any faster.11721173EXAMPLES::11741175sage: E=EllipticCurve('37a1')1176sage: M=E.modular_symbol(); M1177Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field1178sage: M(1/2)117901180sage: M(1/5)1181111821183::11841185sage: E=EllipticCurve('121b1')1186sage: M=E.modular_symbol()1187Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1, 2 or -2.1188sage: M(1/7)1189-1/211901191::11921193sage: E=EllipticCurve('11a1')1194sage: E.modular_symbol()(0)11951/51196sage: E=EllipticCurve('11a2')1197sage: E.modular_symbol()(0)119811199sage: E=EllipticCurve('11a3')1200sage: E.modular_symbol()(0)12011/2512021203::12041205sage: E=EllipticCurve('11a2')1206sage: E.modular_symbol(use_eclib=True, normalize='L_ratio')(0)120711208sage: E.modular_symbol(use_eclib=True, normalize='none')(0)12092/51210sage: E.modular_symbol(use_eclib=True, normalize='period')(0)1211Traceback (most recent call last):1212...1213ValueError: no normalization 'period' known for modular symbols using John Cremona's eclib1214sage: E.modular_symbol(use_eclib=False, normalize='L_ratio')(0)121511216sage: E.modular_symbol(use_eclib=False, normalize='none')(0)121711218sage: E.modular_symbol(use_eclib=False, normalize='period')(0)1219112201221::12221223sage: E=EllipticCurve('11a3')1224sage: E.modular_symbol(use_eclib=True, normalize='L_ratio')(0)12251/251226sage: E.modular_symbol(use_eclib=True, normalize='none')(0)12272/51228sage: E.modular_symbol(use_eclib=True, normalize='period')(0)1229Traceback (most recent call last):1230...1231ValueError: no normalization 'period' known for modular symbols using John Cremona's eclib1232sage: E.modular_symbol(use_eclib=False, normalize='L_ratio')(0)12331/251234sage: E.modular_symbol(use_eclib=False, normalize='none')(0)123511236sage: E.modular_symbol(use_eclib=False, normalize='period')(0)12371/2512381239"""1240typ = (sign, normalize, use_eclib)1241try:1242return self.__modular_symbol[typ]1243except AttributeError:1244self.__modular_symbol = {}1245except KeyError:1246pass1247if use_eclib :1248M = ell_modular_symbols.ModularSymbolECLIB(self, sign, normalize=normalize)1249else :1250M = ell_modular_symbols.ModularSymbolSage(self, sign, normalize=normalize)1251self.__modular_symbol[typ] = M1252return M12531254padic_lseries = padics.padic_lseries12551256def newform(self):1257r"""1258Same as ``self.modular_form()``.12591260EXAMPLES::12611262sage: E=EllipticCurve('37a1')1263sage: E.newform()1264q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)1265sage: E.newform() == E.modular_form()1266True1267"""1268return self.modular_form()12691270def q_eigenform(self, prec):1271r"""1272Synonym for ``self.q_expansion(prec)``.12731274EXAMPLES::12751276sage: E=EllipticCurve('37a1')1277sage: E.q_eigenform(10)1278q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + O(q^10)1279sage: E.q_eigenform(10) == E.q_expansion(10)1280True1281"""1282return self.q_expansion(prec)12831284def analytic_rank(self, algorithm="pari", leading_coefficient=False):1285r"""1286Return an integer that is *probably* the analytic rank of this1287elliptic curve. If leading_coefficient is ``True`` (only implemented1288for PARI), return a tuple `(rank, lead)` where `lead` is the value of1289the first non-zero derivative of the L-function of the elliptic1290curve.12911292INPUT:12931294- algorithm -12951296- 'pari' (default) - use the PARI library function.12971298- 'sympow' -use Watkins's program sympow12991300- 'rubinstein' - use Rubinstein's L-function C++ program lcalc.13011302- 'magma' - use MAGMA13031304- 'all' - compute with all other free algorithms, check that1305the answers agree, and return the common answer.13061307.. note::13081309If the curve is loaded from the large Cremona database,1310then the modular degree is taken from the database.13111312Of the three above, probably Rubinstein's is the most1313efficient (in some limited testing I've done).13141315.. note::13161317It is an open problem to *prove* that *any* particular1318elliptic curve has analytic rank `\geq 4`.13191320EXAMPLES::13211322sage: E = EllipticCurve('389a')1323sage: E.analytic_rank(algorithm='pari')132421325sage: E.analytic_rank(algorithm='rubinstein')132621327sage: E.analytic_rank(algorithm='sympow')132821329sage: E.analytic_rank(algorithm='magma') # optional - magma133021331sage: E.analytic_rank(algorithm='all')1332213331334With the optional parameter leading_coefficient set to ``True``, a1335tuple of both the analytic rank and the leading term of the1336L-series at `s = 1` is returned::13371338sage: EllipticCurve([0,-1,1,-10,-20]).analytic_rank(leading_coefficient=True)1339(0, 0.25384186085591068...)1340sage: EllipticCurve([0,0,1,-1,0]).analytic_rank(leading_coefficient=True)1341(1, 0.30599977383405230...)1342sage: EllipticCurve([0,1,1,-2,0]).analytic_rank(leading_coefficient=True)1343(2, 1.518633000576853...)1344sage: EllipticCurve([0,0,1,-7,6]).analytic_rank(leading_coefficient=True)1345(3, 10.39109940071580...)1346sage: EllipticCurve([0,0,1,-7,36]).analytic_rank(leading_coefficient=True)1347(4, 196.170903794579...)13481349TESTS:13501351When the input is horrendous, some of the algorithms just bomb out with a RuntimeError::13521353sage: EllipticCurve([1234567,89101112]).analytic_rank(algorithm='rubinstein')1354Traceback (most recent call last):1355...1356RuntimeError: unable to compute analytic rank using rubinstein algorithm ('unable to convert x (= 6.19283e+19 and is too large) to an integer')1357sage: EllipticCurve([1234567,89101112]).analytic_rank(algorithm='sympow')1358Traceback (most recent call last):1359...1360RuntimeError: failed to compute analytic rank1361"""1362if algorithm == 'pari':1363rank_lead = self.pari_curve().ellanalyticrank()1364if leading_coefficient:1365return (rings.Integer(rank_lead[0]), rank_lead[1].python())1366else:1367return rings.Integer(self.pari_curve().ellanalyticrank()[0])1368elif algorithm == 'rubinstein':1369if leading_coefficient:1370raise NotImplementedError, "Cannot compute leading coefficient using rubinstein algorithm"1371try:1372from sage.lfunctions.lcalc import lcalc1373return lcalc.analytic_rank(L=self)1374except TypeError,msg:1375raise RuntimeError, "unable to compute analytic rank using rubinstein algorithm ('%s')"%msg1376elif algorithm == 'sympow':1377if leading_coefficient:1378raise NotImplementedError, "Cannot compute leading coefficient using sympow"1379from sage.lfunctions.sympow import sympow1380return sympow.analytic_rank(self)[0]1381elif algorithm == 'magma':1382if leading_coefficient:1383raise NotImplementedError, "Cannot compute leading coefficient using magma"1384from sage.interfaces.all import magma1385return rings.Integer(magma(self).AnalyticRank())1386elif algorithm == 'all':1387if leading_coefficient:1388S = set([self.analytic_rank('pari', True)])1389else:1390S = set([self.analytic_rank('pari'),1391self.analytic_rank('rubinstein'), self.analytic_rank('sympow')])1392if len(S) != 1:1393raise RuntimeError, "Bug in analytic_rank; algorithms don't agree! (E=%s)"%self1394return list(S)[0]1395else:1396raise ValueError, "algorithm %s not defined"%algorithm139713981399def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, limbigprime=30):1400r"""1401Computes a lower bound for the rank of the Mordell-Weil group `E(Q)`,1402the rank of the 2-Selmer group, and a list of points of infinite order on1403`E(Q)`.14041405INPUT:140614071408- ``verbose`` - integer, 0,1,2,3; (default: 0), the1409verbosity level14101411- ``lim1`` - (default: 5) limite des points triviaux1412sur les quartiques14131414- ``lim3`` - (default: 50) limite des points sur les1415quartiques ELS14161417- ``limtriv`` - (default: 10) limite des points1418triviaux sur la courbe elliptique14191420- ``maxprob`` - (default: 20)14211422- ``limbigprime`` - (default: 30) to distinguish1423between small and large prime numbers. Use probabilistic tests for1424large primes. If 0, don't any probabilistic tests.142514261427OUTPUT:142814291430- ``integer`` - lower bound on the rank of self14311432- ``integer`` - the dimension of the 2-Selmer group.1433This is an upper bound to the rank, but it is not sharp in general.14341435- ``list`` - list of points of infinite order in `E(Q)`.14361437To obtain a list of generators, use E.gens().143814391440IMPLEMENTATION: Uses Denis Simon's PARI/GP scripts from1441http://www.math.unicaen.fr/~simon/14421443EXAMPLES: These computations use pseudo-random numbers, so we set1444the seed for reproducible testing.14451446We compute the ranks of the curves of lowest known conductor up to1447rank `8`. Amazingly, each of these computations finishes1448almost instantly!14491450::14511452sage: E = EllipticCurve('11a1')1453sage: set_random_seed(0)1454sage: E.simon_two_descent()1455(0, 0, [])1456sage: E = EllipticCurve('37a1')1457sage: set_random_seed(0)1458sage: E.simon_two_descent()1459(1, 1, [(0 : 0 : 1)])1460sage: E = EllipticCurve('389a1')1461sage: set_random_seed(0)1462sage: E.simon_two_descent()1463(2, 2, [(1 : 0 : 1), (-11/9 : -55/27 : 1)])1464sage: E = EllipticCurve('5077a1')1465sage: set_random_seed(0)1466sage: E.simon_two_descent()1467(3, 3, [(1 : -1 : 1), (2 : 0 : 1), (0 : 2 : 1)])14681469In this example Simon's program does not find any points, though it1470does correctly compute the rank of the 2-Selmer group.14711472::14731474sage: E = EllipticCurve([1, -1, 0, -751055859, -7922219731979])1475sage: set_random_seed(0)1476sage: E.simon_two_descent()1477(1, 1, [])14781479The rest of these entries were taken from Tom Womack's page1480http://tom.womack.net/maths/conductors.htm14811482::14831484sage: E = EllipticCurve([1, -1, 0, -79, 289])1485sage: set_random_seed(0)1486sage: E.simon_two_descent()1487(4, 4, [(4 : 3 : 1), (5 : -2 : 1), (6 : -1 : 1), (8 : 7 : 1)])1488sage: E = EllipticCurve([0, 0, 1, -79, 342])1489sage: set_random_seed(0)1490sage: E.simon_two_descent() # long time (9s on sage.math, 2011)1491(5, 5, [(5 : 8 : 1), (4 : 9 : 1), (3 : 11 : 1), (-1 : 20 : 1), (-6 : -25 : 1)])1492sage: E = EllipticCurve([1, 1, 0, -2582, 48720])1493sage: set_random_seed(0)1494sage: r, s, G = E.simon_two_descent(); r,s1495(6, 6)1496sage: E = EllipticCurve([0, 0, 0, -10012, 346900])1497sage: set_random_seed(0)1498sage: r, s, G = E.simon_two_descent(); r,s1499(7, 7)1500sage: E = EllipticCurve([0, 0, 1, -23737, 960366])1501sage: set_random_seed(0)1502sage: r, s, G = E.simon_two_descent(); r,s1503(8, 8)15041505Example from :trac: `10832`::15061507sage: E = EllipticCurve([1,0,0,-6664,86543])1508sage: E.simon_two_descent()1509(2, 3, [(-73 : -394 : 1), (323/4 : 1891/8 : 1)])1510sage: E.rank()151121512sage: E.gens()1513[(-73 : -394 : 1), (323/4 : 1891/8 : 1)]15141515Example where the lower bound is known to be 11516despite that the algorithm has not found any1517points of infinite order ::15181519sage: E = EllipticCurve([1, 1, 0, -23611790086, 1396491910863060])1520sage: E.simon_two_descent()1521(1, 2, [])1522sage: E.rank()152311524sage: E.gens() # uses mwrank1525[(4311692542083/48594841 : -13035144436525227/338754636611 : 1)]15261527Example for :trac: `5153`::15281529sage: E = EllipticCurve([3,0])1530sage: E.simon_two_descent()1531(1, 2, [(3 : 6 : 1)])15321533"""1534verbose = int(verbose)1535t = simon_two_descent(self, verbose=verbose, lim1=lim1, lim3=lim3, limtriv=limtriv,1536maxprob=maxprob, limbigprime=limbigprime)1537if t=='fail':1538raise RuntimeError, 'Run-time error in simon_two_descent.'1539if verbose>0:1540print "simon_two_descent returns", t1541rank_low_bd = rings.Integer(t[0])1542two_selmer_rank = rings.Integer(t[1])1543pts = [self(P) for P in t[2]]1544pts = [P for P in pts if P.has_infinite_order()]1545if rank_low_bd == two_selmer_rank - self.two_torsion_rank():1546if verbose>0:1547print "Rank determined successfully, saturating..."1548gens = self.saturation(pts)[0]1549if len(gens) == rank_low_bd:1550self.__gens[True] = gens1551self.__gens[True].sort()1552self.__rank[True] = rank_low_bd15531554return rank_low_bd, two_selmer_rank, pts15551556two_descent_simon = simon_two_descent15571558def three_selmer_rank(self, algorithm='UseSUnits'):1559r"""1560Return the 3-selmer rank of this elliptic curve, computed using1561Magma.15621563INPUT:156415651566- ``algorithm`` - 'Heuristic' (which is usually much1567faster in large examples), 'FindCubeRoots', or 'UseSUnits'1568(default)156915701571OUTPUT: nonnegative integer15721573EXAMPLES: A rank 0 curve::15741575sage: EllipticCurve('11a').three_selmer_rank() # optional - magma1576015771578A rank 0 curve with rational 3-isogeny but no 3-torsion15791580::15811582sage: EllipticCurve('14a3').three_selmer_rank() # optional - magma1583015841585A rank 0 curve with rational 3-torsion::15861587sage: EllipticCurve('14a1').three_selmer_rank() # optional - magma1588115891590A rank 1 curve with rational 3-isogeny::15911592sage: EllipticCurve('91b').three_selmer_rank() # optional - magma1593215941595A rank 0 curve with nontrivial 3-Sha. The Heuristic option makes1596this about twice as fast as without it.15971598::15991600sage: EllipticCurve('681b').three_selmer_rank(algorithm='Heuristic') # long time (10 seconds); optional - magma160121602"""1603from sage.interfaces.all import magma1604E = magma(self)1605return Integer(E.ThreeSelmerGroup(MethodForFinalStep = magma('"%s"'%algorithm)).Ngens())16061607def rank(self, use_database=False, verbose=False,1608only_use_mwrank=True,1609algorithm='mwrank_lib',1610proof=None):1611"""1612Return the rank of this elliptic curve, assuming no conjectures.16131614If we fail to provably compute the rank, raises a RuntimeError1615exception.16161617INPUT:161816191620- ``use_database (bool)`` - (default: False), if1621True, try to look up the regulator in the Cremona database.16221623- ``verbose`` - (default: None), if specified changes1624the verbosity of mwrank computations. algorithm -16251626- ``- 'mwrank_shell'`` - call mwrank shell command16271628- ``- 'mwrank_lib'`` - call mwrank c library16291630- ``only_use_mwrank`` - (default: True) if False try1631using analytic rank methods first.16321633- ``proof`` - bool or None (default: None, see1634proof.elliptic_curve or sage.structure.proof). Note that results1635obtained from databases are considered proof = True163616371638OUTPUT:163916401641- ``rank (int)`` - the rank of the elliptic curve.164216431644IMPLEMENTATION: Uses L-functions, mwrank, and databases.16451646EXAMPLES::16471648sage: EllipticCurve('11a').rank()164901650sage: EllipticCurve('37a').rank()165111652sage: EllipticCurve('389a').rank()165321654sage: EllipticCurve('5077a').rank()165531656sage: EllipticCurve([1, -1, 0, -79, 289]).rank() # This will use the default proof behavior of True165741658sage: EllipticCurve([0, 0, 1, -79, 342]).rank(proof=False)165951660sage: EllipticCurve([0, 0, 1, -79, 342]).simon_two_descent()[0] # long time (7s on sage.math, 2012)1661516621663Examples with denominators in defining equations::16641665sage: E = EllipticCurve([0, 0, 0, 0, -675/4])1666sage: E.rank()166701668sage: E = EllipticCurve([0, 0, 1/2, 0, -1/5])1669sage: E.rank()167011671sage: E.minimal_model().rank()1672116731674A large example where mwrank doesn't determine the result with certainty::16751676sage: EllipticCurve([1,0,0,0,37455]).rank(proof=False)167701678sage: EllipticCurve([1,0,0,0,37455]).rank(proof=True)1679Traceback (most recent call last):1680...1681RuntimeError: Rank not provably correct.1682"""1683if proof is None:1684from sage.structure.proof.proof import get_flag1685proof = get_flag(proof, "elliptic_curve")1686else:1687proof = bool(proof)1688try:1689return self.__rank[proof]1690except KeyError:1691if proof is False and self.__rank.has_key(True):1692return self.__rank[True]1693if use_database:1694try:1695self.__rank[True] = self.database_curve().rank()1696return self.__rank[True]1697except (AttributeError, RuntimeError):1698pass1699if not only_use_mwrank:1700N = self.conductor()1701prec = int(4*float(sqrt(N))) + 101702if self.root_number() == 1:1703L, err = self.lseries().at1(prec)1704if abs(L) > err + R(0.0001): # definitely doesn't vanish1705misc.verbose("rank 0 because L(E,1)=%s"%L)1706self.__rank[proof] = 01707return self.__rank[proof]1708else:1709Lprime, err = self.lseries().deriv_at1(prec)1710if abs(Lprime) > err + R(0.0001): # definitely doesn't vanish1711misc.verbose("rank 1 because L'(E,1)=%s"%Lprime)1712self.__rank[proof] = 11713return self.__rank[proof]17141715if algorithm == 'mwrank_lib':1716misc.verbose("using mwrank lib")1717if self.is_integral(): E = self1718else: E = self.integral_model()1719C = E.mwrank_curve()1720C.set_verbose(verbose)1721r = C.rank()1722if C.certain():1723proof = True1724else:1725if proof:1726print "Unable to compute the rank with certainty (lower bound=%s)."%C.rank()1727print "This could be because Sha(E/Q)[2] is nontrivial."1728print "Try calling something like two_descent(second_limit=13) on the"1729print "curve then trying this command again. You could also try rank"1730print "with only_use_mwrank=False."1731del E.__mwrank_curve1732raise RuntimeError, 'Rank not provably correct.'1733else:1734misc.verbose("Warning -- rank not proven correct", level=1)1735self.__rank[proof] = r1736elif algorithm == 'mwrank_shell':1737misc.verbose("using mwrank shell")1738X = self.mwrank()1739if 'determined unconditionally' not in X or 'only a lower bound of' in X:1740if proof:1741X= "".join(X.split("\n")[-4:-2])1742print X1743raise RuntimeError, 'Rank not provably correct.'1744else:1745misc.verbose("Warning -- rank not proven correct", level=1)17461747s = "lower bound of"1748X = X[X.rfind(s)+len(s)+1:]1749r = Integer(X.split()[0])1750else:1751if proof is False:1752proof = True #since we actually provably found the rank1753match = 'Rank ='1754i = X.find(match)1755if i == -1:1756match = 'found points of rank'1757i = X.find(match)1758if i == -1:1759raise RuntimeError, "%s\nbug -- tried to find 'Rank =' or 'found points of rank' in mwrank output but couldn't."%X1760j = i + X[i:].find('\n')1761r = Integer(X[i+len(match)+1:j])1762self.__rank[proof] = r17631764return self.__rank[proof]17651766def gens(self, verbose=False, rank1_search=10,1767algorithm='mwrank_lib',1768only_use_mwrank=True,1769proof = None,1770use_database = True,1771descent_second_limit=12,1772sat_bound = 1000):1773"""1774Compute and return generators for the Mordell-Weil group E(Q)1775*modulo* torsion.17761777.. warning::17781779If the program fails to give a provably correct result, it1780prints a warning message, but does not raise an1781exception. Use the gens_certain command to find out if this1782warning message was printed.17831784INPUT:178517861787- ``verbose`` - (default: None), if specified changes1788the verbosity of mwrank computations.17891790- ``rank1_search`` - (default: 10), if the curve has1791analytic rank 1, try to find a generator by a direct search up to1792this logarithmic height. If this fails the usual mwrank procedure1793is called. algorithm -17941795- ``- 'mwrank_shell' (default)`` - call mwrank shell1796command17971798- ``- 'mwrank_lib'`` - call mwrank c library17991800- ``only_use_mwrank`` - bool (default True) if1801False, attempts to first use more naive, natively implemented1802methods.18031804- ``proof`` - bool or None (default None, see1805proof.elliptic_curve or sage.structure.proof).18061807- ``use_database`` - bool (default True) if True,1808attempts to find curve and gens in the (optional) database18091810- ``descent_second_limit`` - (default: 12)- used in 2-descent18111812- ``sat_bound`` - (default: 1000) - bound on primes used in1813saturation. If the computed bound on the index of the1814points found by two-descent in the Mordell-Weil group is1815greater than this, a warning message will be displayed.18161817OUTPUT:181818191820- ``generators`` - List of generators for the1821Mordell-Weil group modulo torsion.182218231824IMPLEMENTATION: Uses Cremona's mwrank C library.18251826EXAMPLES::18271828sage: E = EllipticCurve('389a')1829sage: E.gens() # random output1830[(-1 : 1 : 1), (0 : 0 : 1)]18311832A non-integral example::18331834sage: E = EllipticCurve([-3/8,-2/3])1835sage: E.gens() # random (up to sign)1836[(10/9 : 29/54 : 1)]18371838A non-minimal example::18391840sage: E = EllipticCurve('389a1')1841sage: E1 = E.change_weierstrass_model([1/20,0,0,0]); E11842Elliptic Curve defined by y^2 + 8000*y = x^3 + 400*x^2 - 320000*x over Rational Field1843sage: E1.gens() # random (if database not used)1844[(-400 : 8000 : 1), (0 : -8000 : 1)]1845"""1846if proof is None:1847from sage.structure.proof.proof import get_flag1848proof = get_flag(proof, "elliptic_curve")1849else:1850proof = bool(proof)18511852# If the gens are already cached, return them:1853try:1854return list(self.__gens[proof]) # return copy so not changed1855except AttributeError:1856pass1857except KeyError:1858if proof is False and self.__gens.has_key(True):1859return self.__gens[True]18601861# At this point, either self.__gens does not exist, or1862# self.__gens[False] exists but not self.__gens[True], and1863# proof is True18641865# If the optional extended database is installed and an1866# isomorphic curve is in the database then its gens will be1867# known; if only the default database is installed, the rank1868# will be known but not the gens.18691870if use_database:1871try:1872E = self.database_curve()1873iso = E.isomorphism_to(self)1874try:1875self.__gens[True] = [iso(P) for P in E.__gens[True]]1876return self.__gens[True]1877except (KeyError,AttributeError): # database curve does not have the gens1878pass1879except (RuntimeError, KeyError): # curve or gens not in database1880pass18811882if self.conductor() > 10**7:1883only_use_mwrank = True18841885if not only_use_mwrank:1886try:1887misc.verbose("Trying to compute rank.")1888r = self.rank(only_use_mwrank = False)1889misc.verbose("Got r = %s."%r)1890if r == 0:1891misc.verbose("Rank = 0, so done.")1892self.__gens[True] = []1893return self.__gens[True]1894if r == 1 and rank1_search:1895misc.verbose("Rank = 1, so using direct search.")1896h = 61897while h <= rank1_search:1898misc.verbose("Trying direct search up to height %s"%h)1899G = self.point_search(h, verbose)1900G = [P for P in G if P.order() == oo]1901if len(G) > 0:1902misc.verbose("Direct search succeeded.")1903G, _, _ = self.saturation(G, verbose=verbose)1904misc.verbose("Computed saturation.")1905self.__gens[True] = G1906return self.__gens[True]1907h += 21908misc.verbose("Direct search FAILED.")1909except RuntimeError:1910pass1911# end if (not_use_mwrank)1912if algorithm == "mwrank_lib":1913misc.verbose("Calling mwrank C++ library.")1914if not self.is_integral():1915xterm = 1; yterm = 11916ai = self.a_invariants()1917for a in ai:1918if not a.is_integral():1919for p, _ in a.denom().factor():1920e = min([(ai[i].valuation(p)/[1,2,3,4,6][i]) for i in range(5)]).floor()1921ai = [ai[i]/p**(e*[1,2,3,4,6][i]) for i in range(5)]1922xterm *= p**(2*e)1923yterm *= p**(3*e)1924E = constructor.EllipticCurve(list(ai))1925else:1926E = self; xterm = 1; yterm = 11927C = E.mwrank_curve(verbose)1928if not (verbose is None):1929C.set_verbose(verbose)1930C.two_descent(verbose=verbose, second_limit=descent_second_limit)1931C.saturate(bound=sat_bound)1932G = C.gens()1933if proof is True and C.certain() is False:1934del self.__mwrank_curve1935raise RuntimeError, "Unable to compute the rank, hence generators, with certainty (lower bound=%s, generators found=%s). This could be because Sha(E/Q)[2] is nontrivial."%(C.rank(),G) + \1936"\nTry increasing descent_second_limit then trying this command again."1937else:1938proof = C.certain()1939G = [[x*xterm,y*yterm,z] for x,y,z in G]1940else:1941# when gens() calls mwrank it passes the command-line1942# parameter "-p 100" which helps curves with large1943# coefficients and 2-torsion and is otherwise harmless.1944# This is pending a more intelligent handling of mwrank1945# options in gens() (which is nontrivial since gens() needs1946# to parse the output from mwrank and this is seriously1947# affected by what parameters the user passes!).1948# In fact it would be much better to avoid the mwrank console at1949# all for gens() and just use the library. This is in1950# progress (see trac #1949).1951X = self.mwrank('-p 100 -S '+str(sat_bound))1952misc.verbose("Calling mwrank shell.")1953if not 'The rank and full Mordell-Weil basis have been determined unconditionally' in X:1954msg = 'Generators not provably computed.'1955if proof:1956raise RuntimeError, '%s\n%s'%(X,msg)1957else:1958misc.verbose("Warning -- %s"%msg, level=1)1959elif proof is False:1960proof = True1961G = []1962i = X.find('Generator ')1963while i != -1:1964j = i + X[i:].find(';')1965k = i + X[i:].find('[')1966G.append(eval(X[k:j].replace(':',',')))1967X = X[j:]1968i = X.find('Generator ')1969####1970self.__gens[proof] = [self.point(x, check=True) for x in G]1971self.__gens[proof].sort()1972self.__rank[proof] = len(self.__gens[proof])1973return self.__gens[proof]19741975def gens_certain(self):1976"""1977Return True if the generators have been proven correct.19781979EXAMPLES::19801981sage: E=EllipticCurve('37a1')1982sage: E.gens() # random (up to sign)1983[(0 : -1 : 1)]1984sage: E.gens_certain()1985True1986"""1987return self.__gens.has_key(True)19881989def ngens(self, proof = None):1990"""1991Return the number of generators of this elliptic curve.19921993.. note::19941995See :meth:'.gens' for further documentation. The function1996:meth:`.ngens` calls :meth:`.gens` if not already done, but1997only with default parameters. Better results may be1998obtained by calling ``mwrank()`` with carefully chosen1999parameters.20002001EXAMPLES::20022003sage: E=EllipticCurve('37a1')2004sage: E.ngens()2005120062007TO DO: This example should not cause a run-time error.20082009::20102011sage: E=EllipticCurve([0,0,0,877,0])2012sage: # E.ngens() ######## causes run-time error20132014::20152016sage: print E.mwrank('-v0 -b12 -l')2017Curve [0,0,0,877,0] : Rank = 12018Generator 1 is [29604565304828237474403861024284371796799791624792913256602210:-256256267988926809388776834045513089648669153204356603464786949:490078023219787588959802933995928925096061616470779979261000]; height 95.9803719879642019Regulator = 95.980...2020"""2021return len(self.gens(proof = proof))20222023def regulator(self, use_database=True, proof=None, precision=None,2024descent_second_limit=12, verbose=False):2025"""2026Returns the regulator of this curve, which must be defined over Q.20272028INPUT:202920302031- ``use_database`` - bool (default: False), if True,2032try to look up the generators in the Cremona database.20332034- ``proof`` - bool or None (default: None, see2035proof.[tab] or sage.structure.proof). Note that results from2036databases are considered proof = True20372038- ``precision`` - int or None (default: None): the2039precision in bits of the result (default real precision if None)20402041- ``descent_second_limit`` - (default: 12)- used in 2-descent20422043- ``verbose`` - whether to print mwrank's verbose output20442045EXAMPLES::20462047sage: E = EllipticCurve([0, 0, 1, -1, 0])2048sage: E.regulator()20490.05111140823996882050sage: EllipticCurve('11a').regulator()20511.000000000000002052sage: EllipticCurve('37a').regulator()20530.05111140823996882054sage: EllipticCurve('389a').regulator()20550.1524601779431442056sage: EllipticCurve('5077a').regulator()20570.41714355875838...2058sage: EllipticCurve([1, -1, 0, -79, 289]).regulator()20591.504344888275282060sage: EllipticCurve([0, 0, 1, -79, 342]).regulator(proof=False) # long time (6s on sage.math, 2011)206114.790527570131...2062"""2063if precision is None:2064RR = rings.RealField()2065precision = RR.precision()2066else:2067RR = rings.RealField(precision)20682069if proof is None:2070from sage.structure.proof.proof import get_flag2071proof = get_flag(proof, "elliptic_curve")2072else:2073proof = bool(proof)20742075# We return a cached value if it exists and has sufficient precision:2076try:2077reg = self.__regulator[proof]2078if reg.parent().precision() >= precision:2079return RR(reg)2080else: # Found regulator value but precision is too low2081pass2082except KeyError:2083if proof is False and self.__regulator.has_key(True):2084reg = self.__regulator[True]2085if reg.parent().precision() >= precision:2086return RR(reg)2087else: # Found regulator value but precision is too low2088pass20892090# Next we find the gens, taking them from the database if they2091# are there and use_database is True, else computing them:20922093G = self.gens(proof=proof, use_database=use_database, descent_second_limit=descent_second_limit, verbose=verbose)20942095# Finally compute the regulator of the generators found:20962097self.__regulator[proof] = self.regulator_of_points(G,precision=precision)2098return self.__regulator[proof]20992100def saturation(self, points, verbose=False, max_prime=0, odd_primes_only=False):2101"""2102Given a list of rational points on E, compute the saturation in2103E(Q) of the subgroup they generate.21042105INPUT:210621072108- ``points (list)`` - list of points on E21092110- ``verbose (bool)`` - (default: False), if True, give2111verbose output21122113- ``max_prime (int)`` - (default: 0), saturation is2114performed for all primes up to max_prime. If max_prime==0,2115perform saturation at *all* primes, i.e., compute the true2116saturation.21172118- ``odd_primes_only (bool)`` - only do saturation at2119odd primes212021212122OUTPUT:212321242125- ``saturation (list)`` - points that form a basis for2126the saturation21272128- ``index (int)`` - the index of the group generated2129by points in their saturation21302131- ``regulator (real with default precision)`` -2132regulator of saturated points.213321342135ALGORITHM: Uses Cremona's ``mwrank`` package. With ``max_prime=0``,2136we call ``mwrank`` with successively larger prime bounds until the full2137saturation is provably found. The results of saturation at the2138previous primes is stored in each case, so this should be2139reasonably fast.21402141EXAMPLES::21422143sage: E=EllipticCurve('37a1')2144sage: P=E(0,0)2145sage: Q=5*P; Q2146(1/4 : -5/8 : 1)2147sage: E.saturation([Q])2148([(0 : 0 : 1)], 5, 0.0511114082399688)21492150TESTS:21512152See :trac:`10590`. This example would loop forever at default precision::21532154sage: E = EllipticCurve([1, 0, 1, -977842, -372252745])2155sage: P = E([-192128125858676194585718821667542660822323528626273/336995568430319276695106602174283479617040716649, 70208213492933395764907328787228427430477177498927549075405076353624188436/195630373799784831667835900062564586429333568841391304129067339731164107, 1])2156sage: P.height()2157113.3029109260802158sage: E.saturation([P])2159([(-192128125858676194585718821667542660822323528626273/336995568430319276695106602174283479617040716649 : 70208213492933395764907328787228427430477177498927549075405076353624188436/195630373799784831667835900062564586429333568841391304129067339731164107 : 1)], 1, 113.302910926080)2160sage: (Q,), ind, reg = E.saturation([2*P]) # needs higher precision, handled by eclib2161sage: 2*Q == 2*P2162True2163sage: ind216422165sage: reg2166113.30291092608021672168See :trac:`10840`. This used to cause eclib to crash since the2169curve is non-minimal at 2::21702171sage: E = EllipticCurve([0,0,0,-13711473216,0])2172sage: P = E([-19992,16313472])2173sage: Q = E([-24108,-17791704])2174sage: R = E([-97104,-20391840])2175sage: S = E([-113288,-9969344])2176sage: E.saturation([P,Q,R,S])2177([(-19992 : 16313472 : 1), (-24108 : -17791704 : 1), (-97104 : -20391840 : 1), (-113288 : -9969344 : 1)], 1, 172.792031341679)21782179"""2180if not isinstance(points, list):2181raise TypeError, "points (=%s) must be a list."%points2182if len(points) == 0:2183return [], None, R(1)21842185v = []2186for P in points:2187if not isinstance(P, ell_point.EllipticCurvePoint_field):2188P = self(P)2189elif P.curve() != self:2190raise ArithmeticError, "point (=%s) must be %s."%(P,self)21912192minimal = True2193if not self.is_minimal():2194minimal = False2195Emin = self.minimal_model()2196phi = self.isomorphism_to(Emin)2197points = [phi(P) for P in points]2198else:2199Emin = self22002201for P in points:2202x, y = P.xy()2203d = x.denominator().lcm(y.denominator())2204v.append((x*d, y*d, d))22052206c = Emin.mwrank_curve()2207mw = mwrank.mwrank_MordellWeil(c, verbose)2208mw.process(v)2209repeat_until_saturated = False2210if max_prime == 0:2211repeat_until_saturated = True2212max_prime = 99732213from sage.libs.all import mwrank_get_precision, mwrank_set_precision2214prec0 = mwrank_get_precision()2215prec = 1002216if prec0<prec:2217mwrank_set_precision(prec)2218else:2219prec = prec02220while True:2221ok, index, unsat = mw.saturate(max_prime=max_prime, odd_primes_only = odd_primes_only)2222reg = mw.regulator()2223if ok or not repeat_until_saturated: break2224max_prime = arith.next_prime(max_prime + 1000)2225prec += 502226#print "Increasing precision to ",prec," and max_prime to ",max_prime2227mwrank_set_precision(prec)2228if prec!=prec0: mwrank_set_precision(prec0)2229#print "precision was originally ",prec0," and is now ",mwrank_get_precision()2230sat = mw.points()2231sat = [Emin(P) for P in sat]2232if not minimal:2233phi_inv = ~phi2234sat = [phi_inv(P) for P in sat]2235reg = self.regulator_of_points(sat)2236return sat, index, R(reg)223722382239def CPS_height_bound(self):2240r"""2241Return the Cremona-Prickett-Siksek height bound. This is a2242floating point number B such that if P is a rational point on2243the curve, then `h(P) \le \hat{h}(P) + B`, where `h(P)` is2244the naive logarithmic height of `P` and `\hat{h}(P)` is the2245canonical height.22462247SEE ALSO: silverman_height_bound for a bound that also works for2248points over number fields.22492250EXAMPLES::22512252sage: E = EllipticCurve("11a")2253sage: E.CPS_height_bound()22542.87747432735804452255sage: E = EllipticCurve("5077a")2256sage: E.CPS_height_bound()22570.02258sage: E = EllipticCurve([1,2,3,4,1])2259sage: E.CPS_height_bound()2260Traceback (most recent call last):2261...2262RuntimeError: curve must be minimal.2263sage: F = E.quadratic_twist(-19)2264sage: F2265Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 1376*x - 130 over Rational Field2266sage: F.CPS_height_bound()22670.655515837697285222682269IMPLEMENTATION:2270Call the corresponding mwrank C++ library function. Note that2271the formula in the [CPS] paper is given for number fields. It's2272only the implementation in Sage that restricts to the rational2273field.2274"""2275if not self.is_minimal():2276raise RuntimeError, "curve must be minimal."2277return self.mwrank_curve().CPS_height_bound()227822792280def silverman_height_bound(self, algorithm='default'):2281r"""2282Return the Silverman height bound. This is a positive real2283(floating point) number B such that for all points `P` on the2284curve over any number field, `|h(P) - \hat{h}(P)| \leq B`,2285where `h(P)` is the naive logarithmic height of `P` and2286`\hat{h}(P)` is the canonical height.22872288INPUT:22892290- ``algorithm`` --22912292- 'default' (default) -- compute using a Python2293implementation in Sage22942295- 'mwrank' -- use a C++ implementation in the mwrank2296library22972298NOTES:22992300- The CPS_height_bound is often better (i.e. smaller) than2301the Silverman bound, but it only applies for points over2302the base field, whereas the Silverman bound works over2303all number fields.23042305- The Silverman bound is also fairly straightforward to2306compute over number fields, but isn't implemented here.23072308- Silverman's paper is 'The Difference Between the Weil2309Height and the Canonical Height on Elliptic Curves',2310Math. Comp., Volume 55, Number 192, pages 723-743. We2311use a correction by Bremner with 0.973 replaced by 0.961,2312as explained in the source code to mwrank (htconst.cc).23132314EXAMPLES::23152316sage: E=EllipticCurve('37a1')2317sage: E.silverman_height_bound()23184.8254007581809182319sage: E.silverman_height_bound(algorithm='mwrank')23204.8254007581809182321sage: E.CPS_height_bound()23220.163970761030469152323"""2324if algorithm == 'default':2325Delta = self.discriminant()2326j = self.j_invariant()2327b2 = self.b2()2328twostar = 2 if b2 else 12329from math import log2330def h(x):2331return log(max(abs(x.numerator()), abs(x.denominator())))2332def h_oo(x):2333return log(max(abs(x),1))2334mu = h(Delta)/12 + h_oo(j)/12 + h_oo(b2/12)/2 + log(twostar)/22335lower = 2*(-h(j)/24 - mu - 0.961)2336upper = 2*(mu + 1.07)2337return max(abs(lower), abs(upper))2338elif algorithm == 'mwrank':2339return self.mwrank_curve().silverman_bound()2340else:2341raise ValueError, "unknown algorithm '%s'"%algorithm2342234323442345def point_search(self, height_limit, verbose=False, rank_bound=None):2346"""2347Search for points on a curve up to an input bound on the naive2348logarithmic height.23492350INPUT:235123522353- ``height_limit (float)`` - bound on naive height23542355- ``verbose (bool)`` - (default: False)23562357If True, report on each point as found together with linear2358relations between the points found and the saturation process.23592360If False, just return the result.23612362- ``rank_bound (bool)`` - (default: None)23632364If provided, stop searching for points once we find this many2365independent nontorsion points.23662367OUTPUT: points (list) - list of independent points which generate2368the subgroup of the Mordell-Weil group generated by the points2369found and then saturated.23702371.. warning::23722373height_limit is logarithmic, so increasing by 1 will cause2374the running time to increase by a factor of approximately23754.5 (=exp(1.5)).23762377IMPLEMENTATION: Uses Michael Stoll's ratpoints library.23782379EXAMPLES::23802381sage: E=EllipticCurve('389a1')2382sage: E.point_search(5, verbose=False)2383[(-1 : 1 : 1), (-3/4 : 7/8 : 1)]23842385Increasing the height_limit takes longer, but finds no more2386points::23872388sage: E.point_search(10, verbose=False)2389[(-1 : 1 : 1), (-3/4 : 7/8 : 1)]23902391In fact this curve has rank 2 so no more than 2 points will ever be2392output, but we are not using this fact.23932394::23952396sage: E.saturation(_)2397([(-1 : 1 : 1), (-3/4 : 7/8 : 1)], 1, 0.152460177943144)23982399What this shows is that if the rank is 2 then the points listed do2400generate the Mordell-Weil group (mod torsion). Finally,24012402::24032404sage: E.rank()2405224062407If we only need one independent generator::24082409sage: E.point_search(5, verbose=False, rank_bound=1)2410[(-2 : 0 : 1)]24112412"""2413from sage.libs.ratpoints import ratpoints2414from sage.functions.all import exp2415from sage.rings.arith import GCD2416H = exp(float(height_limit)) # max(|p|,|q|) <= H, if x = p/q coprime2417coeffs = [16*self.b6(), 8*self.b4(), self.b2(), 1]2418points = []2419a1 = self.a1()2420a3 = self.a3()2421new_H = H*2 # since we change the x-coord by 2 below2422for X,Y,Z in ratpoints(coeffs, new_H, verbose):2423if Z == 0: continue2424z = 2*Z2425x = X/22426y = (Y/z - a1*x - a3*z)/22427d = GCD((x,y,z))2428x = x/d2429if max(x.numerator().abs(), x.denominator().abs()) <= H:2430y = y/d2431z = z/d2432points.append(self((x,y,z)))2433if rank_bound is not None:2434points = self.saturation(points, verbose=verbose)[0]2435if len(points) == rank_bound:2436break2437if rank_bound is None:2438points = self.saturation(points, verbose=verbose)[0]2439return points244024412442def selmer_rank(self):2443"""2444The rank of the 2-Selmer group of the curve.24452446EXAMPLE: The following is the curve 960D1, which has rank 0, but2447Sha of order 4.24482449::24502451sage: E = EllipticCurve([0, -1, 0, -900, -10098])2452sage: E.selmer_rank()2453324542455Here the Selmer rank is equal to the 2-torsion rank (=1) plus2456the 2-rank of Sha (=2), and the rank itself is zero::24572458sage: E.rank()2459024602461In contrast, for the curve 571A, also with rank 0 and Sha of2462order 4, we get a worse bound::24632464sage: E = EllipticCurve([0, -1, 1, -929, -10595])2465sage: E.selmer_rank()246622467sage: E.rank_bound()2468224692470To establish that the rank is in fact 0 in this case, we would2471need to carry out a higher descent::24722473sage: E.three_selmer_rank() # optional: magma2474024752476Or use the L-function to compute the analytic rank::24772478sage: E.rank(only_use_mwrank=False)2479024802481"""2482try:2483return self.__selmer_rank2484except AttributeError:2485C = self.mwrank_curve()2486self.__selmer_rank = C.selmer_rank()2487return self.__selmer_rank248824892490def rank_bound(self):2491"""2492Upper bound on the rank of the curve, computed using24932-descent. In many cases, this is the actual rank of the2494curve. If the curve has no 2-torsion it is the same as the24952-selmer rank.24962497EXAMPLE: The following is the curve 960D1, which has rank 0, but2498Sha of order 4.24992500::25012502sage: E = EllipticCurve([0, -1, 0, -900, -10098])2503sage: E.rank_bound()2504025052506It gives 0 instead of 2, because it knows Sha is nontrivial. In2507contrast, for the curve 571A, also with rank 0 and Sha of order 4,2508we get a worse bound::25092510sage: E = EllipticCurve([0, -1, 1, -929, -10595])2511sage: E.rank_bound()251222513sage: E.rank(only_use_mwrank=False) # uses L-function2514025152516"""2517try:2518return self.__rank_bound2519except AttributeError:2520C = self.mwrank_curve()2521self.__rank_bound = C.rank_bound()2522return self.__rank_bound252325242525def an(self, n):2526"""2527The n-th Fourier coefficient of the modular form corresponding to2528this elliptic curve, where n is a positive integer.25292530EXAMPLES::25312532sage: E=EllipticCurve('37a1')2533sage: [E.an(n) for n in range(20) if n>0]2534[1, -2, -3, 2, -2, 6, -1, 0, 6, 4, -5, -6, -2, 2, 6, -4, 0, -12, 0]2535"""2536return Integer(self.pari_mincurve().ellak(n))25372538def ap(self, p):2539"""2540The p-th Fourier coefficient of the modular form corresponding to2541this elliptic curve, where p is prime.25422543EXAMPLES::25442545sage: E=EllipticCurve('37a1')2546sage: [E.ap(p) for p in prime_range(50)]2547[-2, -3, -2, -1, -5, -2, 0, 0, 2, 6, -4, -1, -9, 2, -9]2548"""2549if not arith.is_prime(p):2550raise ArithmeticError, "p must be prime"2551return Integer(self.pari_mincurve().ellap(p))25522553def quadratic_twist(self, D):2554"""2555Return the quadratic twist of this elliptic curve by D.25562557D must be a nonzero rational number.25582559.. note::25602561This function overrides the generic ``quadratic_twist()``2562function for elliptic curves, returning a minimal model.25632564EXAMPLES::25652566sage: E=EllipticCurve('37a1')2567sage: E2=E.quadratic_twist(2); E22568Elliptic Curve defined by y^2 = x^3 - 4*x + 2 over Rational Field2569sage: E2.conductor()257023682571sage: E2.quadratic_twist(2) == E2572True2573"""2574return EllipticCurve_number_field.quadratic_twist(self, D).minimal_model()25752576def minimal_model(self):2577r"""2578Return the unique minimal Weierstrass equation for this elliptic2579curve. This is the model with minimal discriminant and2580`a_1,a_2,a_3 \in \{0,\pm 1\}`.25812582EXAMPLES::25832584sage: E=EllipticCurve([10,100,1000,10000,1000000])2585sage: E.minimal_model()2586Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Rational Field2587"""2588try:2589return self.__minimal_model2590except AttributeError:2591F = self.pari_mincurve()2592self.__minimal_model = EllipticCurve_rational_field([Q(F[i]) for i in range(5)])2593return self.__minimal_model25942595def is_minimal(self):2596r"""2597Return True iff this elliptic curve is a reduced minimal model.25982599The unique minimal Weierstrass equation for this elliptic curve.2600This is the model with minimal discriminant and2601`a_1,a_2,a_3 \in \{0,\pm 1\}`.26022603TO DO: This is not very efficient since it just computes the2604minimal model and compares. A better implementation using the Kraus2605conditions would be preferable.26062607EXAMPLES::26082609sage: E=EllipticCurve([10,100,1000,10000,1000000])2610sage: E.is_minimal()2611False2612sage: E=E.minimal_model()2613sage: E.is_minimal()2614True2615"""2616return self.ainvs() == self.minimal_model().ainvs()26172618def is_p_minimal(self, p):2619"""2620Tests if curve is p-minimal at a given prime p.26212622INPUT: p - a primeOUTPUT: True - if curve is p-minimal262326242625- ``False`` - if curve isn't p-minimal262626272628EXAMPLES::26292630sage: E = EllipticCurve('441a2')2631sage: E.is_p_minimal(7)2632True26332634::26352636sage: E = EllipticCurve([0,0,0,0,(2*5*11)**10])2637sage: [E.is_p_minimal(p) for p in prime_range(2,24)]2638[False, True, False, True, False, True, True, True, True]2639"""2640if not p.is_prime():2641raise ValueError,"p must be prime"2642if not self.is_p_integral(p):2643return False2644if p > 3:2645return ((self.discriminant().valuation(p) < 12) or (self.c4().valuation(p) < 4))2646# else p = 2,32647Emin = self.minimal_model()2648return self.discriminant().valuation(p) == Emin.discriminant().valuation(p)26492650# Duplicate!2651#2652# def is_integral(self):2653# for n in self.ainvs():2654# if n.denominator() != 1:2655# return False2656# return True26572658def kodaira_type(self, p):2659"""2660Local Kodaira type of the elliptic curve at `p`.26612662INPUT:26632664- p, an integral prime266526662667OUTPUT:266826692670- the Kodaira type of this elliptic curve at p,2671as a KodairaSymbol.267226732674EXAMPLES::26752676sage: E = EllipticCurve('124a')2677sage: E.kodaira_type(2)2678IV2679"""2680return self.local_data(p).kodaira_symbol()26812682kodaira_symbol = kodaira_type26832684def kodaira_type_old(self, p):2685"""2686Local Kodaira type of the elliptic curve at `p`.26872688INPUT:268926902691- p, an integral prime269226932694OUTPUT:26952696- the kodaira type of this elliptic curve at p,2697as a KodairaSymbol.26982699EXAMPLES::27002701sage: E = EllipticCurve('124a')2702sage: E.kodaira_type_old(2)2703IV2704"""2705if not arith.is_prime(p):2706raise ArithmeticError, "p must be prime"2707try:2708self.__kodaira_type2709except AttributeError:2710self.__kodaira_type = {}2711self.__tamagawa_number = {}2712if not self.__kodaira_type.has_key(p):2713v = self.pari_mincurve().elllocalred(p)2714from kodaira_symbol import KodairaSymbol2715self.__kodaira_type[p] = KodairaSymbol(v[1])2716self.__tamagawa_number[p] = Integer(v[3])2717return self.__kodaira_type[p]27182719def tamagawa_number(self, p):2720r"""2721The Tamagawa number of the elliptic curve at `p`.27222723This is the order of the component group2724`E(\QQ_p)/E^0(\QQ_p)`.27252726EXAMPLES::27272728sage: E = EllipticCurve('11a')2729sage: E.tamagawa_number(11)273052731sage: E = EllipticCurve('37b')2732sage: E.tamagawa_number(37)273332734"""2735return self.local_data(p).tamagawa_number()27362737def tamagawa_number_old(self, p):2738r"""2739The Tamagawa number of the elliptic curve at `p`.27402741This is the order of the component group2742`E(\QQ_p)/E^0(\QQ_p)`.27432744EXAMPLES::27452746sage: E = EllipticCurve('11a')2747sage: E.tamagawa_number_old(11)274852749sage: E = EllipticCurve('37b')2750sage: E.tamagawa_number_old(37)275132752"""2753if not arith.is_prime(p):2754raise ArithmeticError, "p must be prime"2755try:2756return self.__tamagawa_number[p]2757except (AttributeError, KeyError):2758self.kodaira_type_old(p)2759return self.__tamagawa_number[p]27602761def tamagawa_exponent(self, p):2762"""2763The Tamagawa index of the elliptic curve at `p`.27642765This is the index of the component group2766`E(\QQ_p)/E^0(\QQ_p)`. It equals the2767Tamagawa number (as the component group is cyclic) except for types2768`I_m^*` (`m` even) when the group can be2769`C_2 \times C_2`.27702771EXAMPLES::27722773sage: E = EllipticCurve('816a1')2774sage: E.tamagawa_number(2)277542776sage: E.tamagawa_exponent(2)277722778sage: E.kodaira_symbol(2)2779I2*27802781::27822783sage: E = EllipticCurve('200c4')2784sage: E.kodaira_symbol(5)2785I4*2786sage: E.tamagawa_number(5)278742788sage: E.tamagawa_exponent(5)2789227902791See #4715::27922793sage: E=EllipticCurve('117a3')2794sage: E.tamagawa_exponent(13)279542796"""2797if not arith.is_prime(p):2798raise ArithmeticError, "p must be prime"2799cp = self.tamagawa_number(p)2800if not cp==4:2801return cp2802ks = self.kodaira_type(p)2803if ks._roman==1 and ks._n%2==0 and ks._starred:2804return 22805return 428062807def tamagawa_product(self):2808"""2809Returns the product of the Tamagawa numbers.28102811EXAMPLES::28122813sage: E = EllipticCurve('54a')2814sage: E.tamagawa_product ()281532816"""2817try:2818return self.__tamagawa_product2819except AttributeError:2820self.__tamagawa_product = Integer(self.pari_mincurve().ellglobalred()[2].python())2821return self.__tamagawa_product28222823def real_components(self):2824"""2825Returns 1 if there is 1 real component and 2 if there are 2.28262827EXAMPLES::28282829sage: E = EllipticCurve('37a')2830sage: E.real_components ()283122832sage: E = EllipticCurve('37b')2833sage: E.real_components ()283422835sage: E = EllipticCurve('11a')2836sage: E.real_components ()283712838"""2839invs = self.short_weierstrass_model().ainvs()2840x = rings.polygen(self.base_ring())2841f = x**3 + invs[3]*x + invs[4]2842if f.discriminant() > 0:2843return 22844else:2845return 128462847def has_good_reduction_outside_S(self,S=[]):2848r"""2849Tests if this elliptic curve has good reduction outside `S`.28502851INPUT:28522853- S - list of primes (default: empty list).28542855.. note::28562857Primality of elements of S is not checked, and the output2858is undefined if S is not a list or contains non-primes.28592860This only tests the given model, so should only be applied to2861minimal models.28622863EXAMPLES::28642865sage: EllipticCurve('11a1').has_good_reduction_outside_S([11])2866True2867sage: EllipticCurve('11a1').has_good_reduction_outside_S([2])2868False2869sage: EllipticCurve('2310a1').has_good_reduction_outside_S([2,3,5,7])2870False2871sage: EllipticCurve('2310a1').has_good_reduction_outside_S([2,3,5,7,11])2872True2873"""2874return self.discriminant().is_S_unit(S)28752876def period_lattice(self, embedding=None):2877r"""2878Returns the period lattice of the elliptic curve with respect to2879the differential `dx/(2y + a_1x + a_3)`.28802881INPUT:28822883- ``embedding`` - ignored (for compatibility with the2884period_lattice function for elliptic_curve_number_field)28852886OUTPUT:28872888(period lattice) The PeriodLattice_ell object associated to2889this elliptic curve (with respect to the natural embedding of2890`\QQ` into `\RR`).28912892EXAMPLES::28932894sage: E = EllipticCurve('37a')2895sage: E.period_lattice()2896Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field2897"""2898try:2899return self._period_lattice2900except AttributeError:2901from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell2902self._period_lattice = PeriodLattice_ell(self)2903return self._period_lattice29042905def elliptic_exponential(self, z, embedding=None):2906r"""2907Computes the elliptic exponential of a complex number with respect to the elliptic curve.29082909INPUT:29102911- ``z`` (complex) -- a complex number29122913- ``embedding`` - ignored (for compatibility with the2914period_lattice function for elliptic_curve_number_field)29152916OUTPUT:29172918The image of `z` modulo `L` under the Weierstrass parametrization2919`\CC/L \to E(\CC)`.29202921.. note::29222923The precision is that of the input ``z``, or the default2924precision of 53 bits if ``z`` is exact.29252926EXAMPLES::29272928sage: E = EllipticCurve([1,1,1,-8,6])2929sage: P = E([1,-2])2930sage: z = P.elliptic_logarithm() # default precision is 100 here2931sage: E.elliptic_exponential(z)2932(1.0000000000000000000000000000 : -2.0000000000000000000000000000 : 1.0000000000000000000000000000)2933sage: z = E([1,-2]).elliptic_logarithm(precision=201)2934sage: E.elliptic_exponential(z)2935(1.00000000000000000000000000000000000000000000000000000000000 : -2.00000000000000000000000000000000000000000000000000000000000 : 1.00000000000000000000000000000000000000000000000000000000000)29362937::29382939sage: E = EllipticCurve('389a')2940sage: Q = E([3,5])2941sage: E.elliptic_exponential(Q.elliptic_logarithm())2942(3.0000000000000000000000000000 : 5.0000000000000000000000000000 : 1.0000000000000000000000000000)2943sage: P = E([-1,1])2944sage: P.elliptic_logarithm()29450.47934825019021931612953301006 + 0.98586885077582410221120384908*I2946sage: E.elliptic_exponential(P.elliptic_logarithm())2947(-1.0000000000000000000000000000 : 1.0000000000000000000000000000 : 1.0000000000000000000000000000)294829492950Some torsion examples::29512952sage: w1,w2 = E.period_lattice().basis()2953sage: E.two_division_polynomial().roots(CC,multiplicities=False)2954[-2.0403022002854..., 0.13540924022175..., 0.90489296006371...]2955sage: [E.elliptic_exponential((a*w1+b*w2)/2)[0] for a,b in [(0,1),(1,1),(1,0)]]2956[-2.0403022002854..., 0.13540924022175..., 0.90489296006371...]29572958sage: E.division_polynomial(3).roots(CC,multiplicities=False)2959[-2.88288879135...,29601.39292799513...,29610.078313731444316... - 0.492840991709...*I,29620.078313731444316... + 0.492840991709...*I]2963sage: [E.elliptic_exponential((a*w1+b*w2)/3)[0] for a,b in [(0,1),(1,0),(1,1),(2,1)]]2964[-2.8828887913533..., 1.39292799513138,29650.0783137314443... - 0.492840991709...*I,29660.0783137314443... + 0.492840991709...*I]29672968Observe that this is a group homomorphism (modulo rounding error)::29692970sage: z = CC.random_element()2971sage: 2 * E.elliptic_exponential(z)2972(-1.52184235874404 - 0.0581413944316544*I : 0.948655866506124 - 0.0381469928565030*I : 1.00000000000000)2973sage: E.elliptic_exponential(2 * z)2974(-1.52184235874404 - 0.0581413944316562*I : 0.948655866506128 - 0.0381469928565034*I : 1.00000000000000)2975"""2976return self.period_lattice().elliptic_exponential(z)29772978def lseries(self):2979"""2980Returns the L-series of this elliptic curve.29812982Further documentation is available for the functions which apply to2983the L-series.29842985EXAMPLES::29862987sage: E=EllipticCurve('37a1')2988sage: E.lseries()2989Complex L-series of the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field2990"""2991try:2992return self.__lseries2993except AttributeError:2994from lseries_ell import Lseries_ell2995self.__lseries = Lseries_ell(self)2996return self.__lseries29972998def Lambda(self, s, prec):2999r"""3000Returns the value of the Lambda-series of the elliptic curve E at3001s, where s can be any complex number.30023003IMPLEMENTATION: Fairly *slow* computation using the definitions3004and implemented in Python.30053006Uses prec terms of the power series.30073008EXAMPLES::30093010sage: E = EllipticCurve('389a')3011sage: E.Lambda(1.4+0.5*I, 50)3012-0.354172680517... + 0.874518681720...*I3013"""3014from sage.all import pi30153016s = C(s)3017N = self.conductor()3018pi = R(pi)3019a = self.anlist(prec)3020eps = self.root_number()3021sqrtN = float(N.sqrt())3022def _F(n, t):3023return gamma_inc(t+1, 2*pi*n/sqrtN) * C(sqrtN/(2*pi*n))**(t+1)3024return sum([a[n]*(_F(n,s-1) + eps*_F(n,1-s)) for n in xrange(1,prec+1)])30253026def is_local_integral_model(self,*p):3027r"""3028Tests if self is integral at the prime `p`, or at all the3029primes if `p` is a list or tuple of primes30303031EXAMPLES::30323033sage: E=EllipticCurve([1/2,1/5,1/5,1/5,1/5])3034sage: [E.is_local_integral_model(p) for p in (2,3,5)]3035[False, True, False]3036sage: E.is_local_integral_model(2,3,5)3037False3038sage: Eint2=E.local_integral_model(2)3039sage: Eint2.is_local_integral_model(2)3040True3041"""3042if len(p)==1: p=p[0]3043if isinstance(p,(tuple,list)):3044return misc.forall(p, lambda x : self.is_local_integral_model(x))[0]3045assert p.is_prime(), "p must be prime in is_local_integral_model()"3046return misc.forall(self.ainvs(), lambda x : x.valuation(p) >= 0)[0]30473048def local_integral_model(self,p):3049r"""3050Return a model of self which is integral at the prime `p`.30513052EXAMPLES::30533054sage: E=EllipticCurve([0, 0, 1/216, -7/1296, 1/7776])3055sage: E.local_integral_model(2)3056Elliptic Curve defined by y^2 + 1/27*y = x^3 - 7/81*x + 2/243 over Rational Field3057sage: E.local_integral_model(3)3058Elliptic Curve defined by y^2 + 1/8*y = x^3 - 7/16*x + 3/32 over Rational Field3059sage: E.local_integral_model(2).local_integral_model(3) == EllipticCurve('5077a1')3060True3061"""3062assert p.is_prime(), "p must be prime in local_integral_model()"3063ai = self.a_invariants()3064e = min([(ai[i].valuation(p)/[1,2,3,4,6][i]) for i in range(5)]).floor()3065return constructor.EllipticCurve([ai[i]/p**(e*[1,2,3,4,6][i]) for i in range(5)])30663067def is_global_integral_model(self):3068r"""3069Return true iff self is integral at all primes.30703071EXAMPLES::30723073sage: E=EllipticCurve([1/2,1/5,1/5,1/5,1/5])3074sage: E.is_global_integral_model()3075False3076sage: Emin=E.global_integral_model()3077sage: Emin.is_global_integral_model()3078True3079"""3080return self.is_integral()30813082def global_integral_model(self):3083r"""3084Return a model of self which is integral at all primes.30853086EXAMPLES::30873088sage: E = EllipticCurve([0, 0, 1/216, -7/1296, 1/7776])3089sage: F = E.global_integral_model(); F3090Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field3091sage: F == EllipticCurve('5077a1')3092True3093"""3094ai = self.a_invariants()3095for a in ai:3096if not a.is_integral():3097for p, _ in a.denom().factor():3098e = min([(ai[i].valuation(p)/[1,2,3,4,6][i]) for i in range(5)]).floor()3099ai = [ai[i]/p**(e*[1,2,3,4,6][i]) for i in range(5)]3100for z in ai:3101assert z.denominator() == 1, "bug in global_integral_model: %s" % ai3102return constructor.EllipticCurve(list(ai))31033104integral_model = global_integral_model31053106def integral_short_weierstrass_model(self):3107r"""3108Return a model of the form `y^2 = x^3 + ax + b` for this3109curve with `a,b\in\ZZ`.31103111EXAMPLES::31123113sage: E = EllipticCurve('17a1')3114sage: E.integral_short_weierstrass_model()3115Elliptic Curve defined by y^2 = x^3 - 11*x - 890 over Rational Field3116"""3117F = self.minimal_model().short_weierstrass_model()3118_,_,_,A,B = F.ainvs()3119for p in [2,3]:3120e=min(A.valuation(p)/4,B.valuation(p)/6).floor()3121A /= Integer(p**(4*e))3122B /= Integer(p**(6*e))3123return constructor.EllipticCurve([A,B])31243125# deprecated function replaced by integral_short_weierstrass_model, see trac 3974.3126def integral_weierstrass_model(self):3127r"""3128Return a model of the form `y^2 = x^3 + ax + b` for this3129curve with `a,b\in\ZZ`.31303131Note that this function is deprecated, and that you should use3132integral_short_weierstrass_model instead as this will be3133disappearing in the near future.31343135EXAMPLES::31363137sage: E = EllipticCurve('17a1')3138sage: E.integral_weierstrass_model() #random3139doctest:1: DeprecationWarning: integral_weierstrass_model is deprecated, use integral_short_weierstrass_model instead!3140Elliptic Curve defined by y^2 = x^3 - 11*x - 890 over Rational Field3141"""3142from sage.misc.superseded import deprecation3143deprecation(3974, "integral_weierstrass_model is deprecated, use integral_short_weierstrass_model instead!")3144return self.integral_short_weierstrass_model()314531463147def _generalized_congmod_numbers(self, M, invariant="both"):3148"""3149Internal method to compute the generalized modular degree and congruence number3150at level `MN`, where `N` is the conductor of `E`.3151Values obtained are cached.31523153This function is called by self.modular_degree() and self.congruence_number() when3154`M>1`. Since so much of the computation of the two values is shared, this method3155by default computes and caches both.31563157INPUT:31583159- ``M`` - Non-negative integer; this function is only ever called on M>1, although3160the algorithm works fine for the case `M==1`31613162- ``invariant`` - String; default "both". Options are:31633164- "both" - Both modular degree and congruence number at level `MN` are computed31653166- "moddeg" - Only modular degree is computed31673168- "congnum" - Only congruence number is computed31693170OUTPUT:31713172- A dictionary containing either the modular degree (a positive integer) at index "moddeg",3173or the congruence number (a positive integer) at index "congnum", or both.31743175As far as we know there is no other implementation for this algorithm, so as yet3176there is nothing to check the below examples against.31773178EXAMPLES::31793180sage: E = EllipticCurve('37a')3181sage: for M in range(2,8): print(M,E.modular_degree(M=M),E.congruence_number(M=M)) # long time (22s on 2009 MBP)3182(2, 5, 20)3183(3, 7, 28)3184(4, 50, 400)3185(5, 32, 128)3186(6, 1225, 19600)3187(7, 63, 252)3188"""3189# Check invariant specification before we get going3190if invariant not in ["moddeg", "congnum", "both"]:3191raise ValueError("Invalid invariant specification")31923193# Cuspidal space at level MN3194N = self.conductor()3195S = ModularSymbols(N*M,sign=1).cuspidal_subspace()31963197# Cut out the subspace by hitting it with T_p for enough p3198A = S3199d = self.dimension()*arith.sigma(M,0)3200p = 23201while A.dimension() > d:3202while N*M % p == 0:3203p = arith.next_prime(p)3204Tp = A.hecke_operator(p)3205A = (Tp - self.ap(p)).kernel()3206p = arith.next_prime(p)3207B = A.complement().cuspidal_submodule()32083209L = {}3210if invariant in ["moddeg", "both"]:3211V = A.integral_structure()3212W = B.integral_structure()3213moddeg = (V + W).index_in(S.integral_structure())3214L["moddeg"] = moddeg3215self.__generalized_modular_degree[M] = moddeg32163217if invariant in ["congnum", "both"]:3218congnum = A.congruence_number(B)3219L["congnum"] = congnum3220self.__generalized_congruence_number[M] = congnum32213222return L322332243225def modular_degree(self, algorithm='sympow', M=1):3226r"""3227Return the modular degree at level `MN` of this elliptic curve. The case3228`M==1` corresponds to the classical definition of modular degree.32293230When `M>1`, the function returns the degree of the map from `X_0(MN) \to A`, where3231A is the abelian variety generated by embeddings of `E` into `J_0(MN)`.32323233The result is cached. Subsequent calls, even with a different3234algorithm, just returned the cached result. The algorithm argument is ignored3235when `M>1`.32363237INPUT:32383239- ``algorithm`` - string:32403241- ``'sympow'`` - (default) use Mark Watkin's (newer) C3242program sympow32433244- ``'magma'`` - requires that MAGMA be installed (also3245implemented by Mark Watkins)32463247- ``M`` - Non-negative integer; the modular degree at level `MN` is returned3248(see above)32493250.. note::32513252On 64-bit computers ec does not work, so Sage uses sympow3253even if ec is selected on a 64-bit computer.32543255The correctness of this function when called with algorithm "sympow"3256is subject to the following three hypothesis:325732583259- Manin's conjecture: the Manin constant is 132603261- Steven's conjecture: the `X_1(N)`-optimal quotient is3262the curve with minimal Faltings height. (This is proved in most3263cases.)32643265- The modular degree fits in a machine double, so it better be3266less than about 50-some bits. (If you use sympow this constraint3267does not apply.)326832693270Moreover for all algorithms, computing a certain value of an3271`L`-function 'uses a heuristic method that discerns when3272the real-number approximation to the modular degree is within3273epsilon [=0.01 for algorithm='sympow'] of the same integer for 33274consecutive trials (which occur maybe every 25000 coefficients or3275so). Probably it could just round at some point. For rigour, you3276would need to bound the tail by assuming (essentially) that all the3277`a_n` are as large as possible, but in practice they3278exhibit significant (square root) cancellation. One difficulty is3279that it doesn't do the sum in 1-2-3-4 order; it uses32801-2-4-8--3-6-12-24-9-18- (Euler product style) instead, and so you3281have to guess ahead of time at what point to curtail this3282expansion.' (Quote from an email of Mark Watkins.)32833284.. note::32853286If the curve is loaded from the large Cremona database,3287then the modular degree is taken from the database.32883289EXAMPLES::32903291sage: E = EllipticCurve([0, -1, 1, -10, -20])3292sage: E3293Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field3294sage: E.modular_degree()329513296sage: E = EllipticCurve('5077a')3297sage: E.modular_degree()329819843299sage: factor(1984)33002^6 * 3133013302::33033304sage: EllipticCurve([0, 0, 1, -7, 6]).modular_degree()330519843306sage: EllipticCurve([0, 0, 1, -7, 6]).modular_degree(algorithm='sympow')330719843308sage: EllipticCurve([0, 0, 1, -7, 6]).modular_degree(algorithm='magma') # optional - magma3309198433103311We compute the modular degree of the curve with rank 4 having3312smallest (known) conductor::33133314sage: E = EllipticCurve([1, -1, 0, -79, 289])3315sage: factor(E.conductor()) # conductor is 23444633162 * 1172233317sage: factor(E.modular_degree())33182^7 * 261733193320Higher level cases::33213322sage: E = EllipticCurve('11a')3323sage: for M in range(1,11): print(E.modular_degree(M=M)) # long time (20s on 2009 MBP)332413325133263332723328733294533301233311633325433332453334"""3335# Case 1: standard modular degree3336if M==1:3337try:3338return self.__modular_degree33393340except AttributeError:3341if algorithm == 'sympow':3342from sage.lfunctions.all import sympow3343m = sympow.modular_degree(self)3344elif algorithm == 'magma':3345from sage.interfaces.all import magma3346m = rings.Integer(magma(self).ModularDegree())3347else:3348raise ValueError, "unknown algorithm %s"%algorithm3349self.__modular_degree = m3350return m33513352# Case 2: M > 13353else:3354try:3355return self.__generalized_modular_degree[M]3356except KeyError:3357# self._generalized_congmod_numbers() also populates cache3358return self._generalized_congmod_numbers(M)["moddeg"]335933603361def modular_parametrization(self):3362r"""3363Returns the modular parametrization of this elliptic curve, which is3364a map from `X_0(N)` to self, where `N` is the conductor of self.33653366EXAMPLES::33673368sage: E = EllipticCurve('15a')3369sage: phi = E.modular_parametrization(); phi3370Modular parameterization from the upper half plane to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 over Rational Field3371sage: z = 0.1 + 0.2j3372sage: phi(z)3373(8.20822465478531 - 13.1562816054682*I : -8.79855099049364 + 69.4006129342200*I : 1.00000000000000)33743375This map is actually a map on `X_0(N)`, so equivalent representatives3376in the upper half plane map to the same point::33773378sage: phi((-7*z-1)/(15*z+2))3379(8.20822465478524 - 13.1562816054681*I : -8.79855099049... + 69.4006129342...*I : 1.00000000000000)33803381We can also get a series expansion of this modular parameterization::33823383sage: E=EllipticCurve('389a1')3384sage: X,Y=E.modular_parametrization().power_series()3385sage: X3386q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + 173*q^8 + 251*q^9 + 379*q^10 + 560*q^11 + 824*q^12 + 1199*q^13 + 1773*q^14 + 2548*q^15 + 3722*q^16 + 5374*q^17 + O(q^18)3387sage: Y3388-q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 - 861*q^7 - 1383*q^8 - 2218*q^9 - 3472*q^10 - 5451*q^11 - 8447*q^12 - 13020*q^13 - 19923*q^14 - 30403*q^15 - 46003*q^16 + O(q^17)33893390The following should give 0, but only approximately::33913392sage: q = X.parent().gen()3393sage: E.defining_polynomial()(X,Y,1) + O(q^11) == 03394True3395"""3396return ModularParameterization(self)33973398def congruence_number(self, M=1):3399r"""3400The case `M==1` corresponds to the classical definition of congruence number:3401Let `X` be the subspace of `S_2(\Gamma_0(N))` spanned by the newform3402associated with this elliptic curve, and `Y` be orthogonal compliment3403of `X` under the Petersson inner product. Let `S_X` and `S_Y` be the3404intersections of `X` and `Y` with `S_2(\Gamma_0(N), \ZZ)`. The congruence3405number is defined to be `[S_X \oplus S_Y : S_2(\Gamma_0(N),\ZZ)]`.3406It measures congruences between `f` and elements of `S_2(\Gamma_0(N),\ZZ)`3407orthogonal to `f`.34083409The congruence number for higher levels, when M>1, is defined as above, but3410instead considers `X` to be the subspace of `S_2(\Gamma_0(MN))` spanned by3411embeddings into `S_2(\Gamma_0(MN))` of the newform associated with this3412elliptic curve; this subspace has dimension `\sigma_0(M)`, i.e. the number3413of divisors of `M`. Let `Y` be the orthogonal complement in `S_2(\Gamma_0(MN))`3414of `X` under the Petersson inner product, and `S_X` and `S_Y` the intersections3415of `X` and `Y` with `S_2(\Gamma_0(MN), \ZZ)` respectively. Then the congruence3416number at level `MN` is `[S_X \oplus S_Y : S_2(\Gamma_0(MN),\ZZ)]`.34173418INPUT:34193420- ``M`` - Non-negative integer; congruence number is computed at level `MN`,3421where `N` is the conductor of self.34223423EXAMPLES::34243425sage: E = EllipticCurve('37a')3426sage: E.congruence_number()342723428sage: E.congruence_number()342923430sage: E = EllipticCurve('54b')3431sage: E.congruence_number()343263433sage: E.modular_degree()343423435sage: E = EllipticCurve('242a1')3436sage: E.modular_degree()3437163438sage: E.congruence_number() # long time (4s on sage.math, 2011)343917634403441Higher level cases::34423443sage: E = EllipticCurve('11a')3444sage: for M in range(1,11): print(E.congruence_number(M)) # long time (20s on 2009 MBP)344513446134473344823449734504534511234524345318345424534553456It is a theorem of Ribet that the congruence number (at level `N`) is equal3457to the modular degree in the case of square free conductor. It is a conjecture3458of Agashe, Ribet, and Stein that `ord_p(c_f/m_f) \le ord_p(N)/2`.34593460TESTS::34613462sage: E = EllipticCurve('11a')3463sage: E.congruence_number()346413465"""3466# Case 1: M==13467if M==1:3468try:3469return self.__congruence_number3470except AttributeError:3471pass3472# Currently this is *much* faster to compute3473m = self.modular_degree()3474if self.conductor().is_squarefree():3475self.__congruence_number = m3476else:3477W = self.modular_symbol_space(sign=1)3478V = W.complement().cuspidal_subspace()3479self.__congruence_number = W.congruence_number(V)3480if not m.divides(self.__congruence_number):3481# We should never get here3482raise ValueError, "BUG in modular degree or congruence number computation of: %s" % self3483return self.__congruence_number34843485# Case 2: M > 13486else:3487try:3488return self.__generalized_congruence_number[M]3489except KeyError:3490# self._generalized_congmod_numbers() also populates cache3491return self._generalized_congmod_numbers(M)["congnum"]349234933494def cremona_label(self, space=False):3495"""3496Return the Cremona label associated to (the minimal model) of this3497curve, if it is known. If not, raise a RuntimeError exception.34983499EXAMPLES::35003501sage: E=EllipticCurve('389a1')3502sage: E.cremona_label()3503'389a1'35043505The default database only contains conductors up to 10000, so any3506curve with conductor greater than that will cause an error to be3507raised. The optional package ``database_cremona_ellcurve``3508contains many more curves.35093510::35113512sage: E = EllipticCurve([1, -1, 0, -79, 289])3513sage: E.conductor()35142344463515sage: E.cremona_label() # optional - database_cremona_ellcurve3516'234446a1'3517sage: E = EllipticCurve((0, 0, 1, -79, 342))3518sage: E.conductor()3519190478513520sage: E.cremona_label()3521Traceback (most recent call last):3522...3523RuntimeError: Cremona label not known for Elliptic Curve defined by y^2 + y = x^3 - 79*x + 342 over Rational Field.3524"""3525try:3526if not space:3527return self.__cremona_label.replace(' ','')3528return self.__cremona_label3529except AttributeError:3530try:3531X = self.database_curve()3532except RuntimeError:3533raise RuntimeError, "Cremona label not known for %s."%self3534self.__cremona_label = X.__cremona_label3535return self.cremona_label(space)35363537label = cremona_label35383539def reduction(self,p):3540"""3541Return the reduction of the elliptic curve at a prime of good3542reduction.35433544.. note::35453546The actual reduction is done in ``self.change_ring(GF(p))``;3547the reduction is performed after changing to a model which3548is minimal at p.35493550INPUT:35513552- ``p`` - a (positive) prime number355335543555OUTPUT: an elliptic curve over the finite field GF(p)35563557EXAMPLES::35583559sage: E = EllipticCurve('389a1')3560sage: E.reduction(2)3561Elliptic Curve defined by y^2 + y = x^3 + x^2 over Finite Field of size 23562sage: E.reduction(3)3563Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 33564sage: E.reduction(5)3565Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x over Finite Field of size 53566sage: E.reduction(38)3567Traceback (most recent call last):3568...3569AttributeError: p must be prime.3570sage: E.reduction(389)3571Traceback (most recent call last):3572...3573AttributeError: The curve must have good reduction at p.3574sage: E=EllipticCurve([5^4,5^6])3575sage: E.reduction(5)3576Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 53577"""3578p = rings.Integer(p)3579if not p.is_prime():3580raise AttributeError, "p must be prime."3581disc = self.discriminant()3582if not disc.valuation(p) == 0:3583local_data=self.local_data(p)3584if local_data.has_good_reduction():3585return local_data.minimal_model().change_ring(rings.GF(p))3586raise AttributeError, "The curve must have good reduction at p."3587return self.change_ring(rings.GF(p))35883589def torsion_order(self):3590"""3591Return the order of the torsion subgroup.35923593EXAMPLES::35943595sage: e = EllipticCurve('11a')3596sage: e.torsion_order()359753598sage: type(e.torsion_order())3599<type 'sage.rings.integer.Integer'>3600sage: e = EllipticCurve([1,2,3,4,5])3601sage: e.torsion_order()360213603sage: type(e.torsion_order())3604<type 'sage.rings.integer.Integer'>3605"""3606try:3607return self.__torsion_order3608except AttributeError:3609self.__torsion_order = self.torsion_subgroup().order()3610return self.__torsion_order36113612def _torsion_bound(self,number_of_places = 20):3613r"""3614Computes an upper bound on the order of the torsion group of the3615elliptic curve by counting points modulo several primes of good3616reduction. Note that the upper bound returned by this function is a3617multiple of the order of the torsion group.36183619INPUT:362036213622- ``number_of_places (default = 20)`` - the number3623of places that will be used to find the bound362436253626OUTPUT:362736283629- ``integer`` - the upper bound363036313632EXAMPLES:3633"""3634E = self3635bound = Integer(0)3636k = 03637p = Integer(2) # will run through odd primes3638while k < number_of_places :3639p = p.next_prime()3640# check if the formal group at the place is torsion-free3641# if so the torsion injects into the reduction3642while not E.is_local_integral_model(p) or not E.is_good(p): p = p.next_prime()3643bound = arith.gcd(bound,E.reduction(p).cardinality())3644if bound == 1:3645return bound3646k += 13647return bound364836493650def torsion_subgroup(self, algorithm="pari"):3651"""3652Returns the torsion subgroup of this elliptic curve.36533654INPUT:365536563657- ``algorithm`` - string:36583659- ``"pari"`` - (default) use the PARI library36603661- ``"doud"`` - use Doud's algorithm36623663- ``"lutz_nagell"`` - use the Lutz-Nagell theorem366436653666OUTPUT: The EllipticCurveTorsionSubgroup instance associated to3667this elliptic curve.36683669.. note::36703671To see the torsion points as a list, use :meth:`.torsion_points`.36723673EXAMPLES::36743675sage: EllipticCurve('11a').torsion_subgroup()3676Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field3677sage: EllipticCurve('37b').torsion_subgroup()3678Torsion Subgroup isomorphic to Z/3 associated to the Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field36793680::36813682sage: e = EllipticCurve([-1386747,368636886]);e3683Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over Rational Field3684sage: G = e.torsion_subgroup(); G3685Torsion Subgroup isomorphic to Z/2 + Z/8 associated to the Elliptic3686Curve defined by y^2 = x^3 - 1386747*x + 368636886 over3687Rational Field3688sage: G.03689(1227 : 22680 : 1)3690sage: G.13691(282 : 0 : 1)3692sage: list(G)3693[(0 : 1 : 0), (1227 : 22680 : 1), (2307 : -97200 : 1), (8787 : 816480 : 1), (1011 : 0 : 1), (8787 : -816480 : 1), (2307 : 97200 : 1), (1227 : -22680 : 1), (282 : 0 : 1), (-933 : 29160 : 1), (-285 : -27216 : 1), (147 : 12960 : 1), (-1293 : 0 : 1), (147 : -12960 : 1), (-285 : 27216 : 1), (-933 : -29160 : 1)]3694"""3695try:3696return self.__torsion_subgroup3697except AttributeError:3698self.__torsion_subgroup = ell_torsion.EllipticCurveTorsionSubgroup(self, algorithm)3699self.__torsion_order = self.__torsion_subgroup.order()3700return self.__torsion_subgroup37013702def torsion_points(self, algorithm="pari"):3703"""3704Returns the torsion points of this elliptic curve as a sorted3705list.37063707INPUT:370837093710- ``algorithm`` - string:37113712- "pari" - (default) use the PARI library37133714- "doud" - use Doud's algorithm37153716- "lutz_nagell" - use the Lutz-Nagell theorem371737183719OUTPUT: A list of all the torsion points on this elliptic curve.37203721EXAMPLES::37223723sage: EllipticCurve('11a').torsion_points()3724[(0 : 1 : 0), (5 : -6 : 1), (5 : 5 : 1), (16 : -61 : 1), (16 : 60 : 1)]3725sage: EllipticCurve('37b').torsion_points()3726[(0 : 1 : 0), (8 : -19 : 1), (8 : 18 : 1)]37273728::37293730sage: E=EllipticCurve([-1386747,368636886])3731sage: T=E.torsion_subgroup(); T3732Torsion Subgroup isomorphic to Z/2 + Z/8 associated to the Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over Rational Field3733sage: T == E.torsion_subgroup(algorithm="doud")3734True3735sage: T == E.torsion_subgroup(algorithm="lutz_nagell")3736True3737sage: E.torsion_points()3738[(-1293 : 0 : 1),3739(-933 : -29160 : 1),3740(-933 : 29160 : 1),3741(-285 : -27216 : 1),3742(-285 : 27216 : 1),3743(0 : 1 : 0),3744(147 : -12960 : 1),3745(147 : 12960 : 1),3746(282 : 0 : 1),3747(1011 : 0 : 1),3748(1227 : -22680 : 1),3749(1227 : 22680 : 1),3750(2307 : -97200 : 1),3751(2307 : 97200 : 1),3752(8787 : -816480 : 1),3753(8787 : 816480 : 1)]3754"""3755return sorted(self.torsion_subgroup(algorithm).points())37563757## def newform_eval(self, z, prec):3758## """3759## The value of the newform attached to this elliptic curve at3760## the point z in the complex upper half plane, computed using3761## prec terms of the power series expansion. Note that the power3762## series need not converge well near the real axis.3763## """3764## raise NotImplementedError37653766@cached_method3767def root_number(self, p=None):3768"""3769Returns the root number of this elliptic curve.37703771This is 1 if the order of vanishing of the L-function L(E,s) at 13772is even, and -1 if it is odd.37733774INPUT::37753776- `p` -- optional, default (None); if given, return the local3777root number at `p`37783779EXAMPLES::37803781sage: EllipticCurve('11a1').root_number()378213783sage: EllipticCurve('37a1').root_number()3784-13785sage: EllipticCurve('389a1').root_number()378613787sage: type(EllipticCurve('389a1').root_number())3788<type 'sage.rings.integer.Integer'>37893790sage: E = EllipticCurve('100a1')3791sage: E.root_number(2)3792-13793sage: E.root_number(5)379413795sage: E.root_number(7)3796137973798The root number is cached::37993800sage: E.root_number(2) is E.root_number(2)3801True3802sage: E.root_number()380313804"""3805e = self.pari_mincurve()3806if p is None:3807return Integer(e.ellrootno())3808else:3809return Integer(e.ellrootno(p))38103811def has_cm(self):3812"""3813Returns True iff this elliptic curve has Complex Multiplication.38143815EXAMPLES::38163817sage: E=EllipticCurve('37a1')3818sage: E.has_cm()3819False3820sage: E=EllipticCurve('32a1')3821sage: E.has_cm()3822True3823sage: E.j_invariant()382417283825"""38263827return CMJ.has_key(self.j_invariant())38283829def cm_discriminant(self):3830"""3831Returns the associated quadratic discriminant if this elliptic3832curve has Complex Multiplication.38333834A ValueError is raised if the curve does not have CM (see the3835function has_cm()).38363837EXAMPLES::38383839sage: E=EllipticCurve('32a1')3840sage: E.cm_discriminant()3841-43842sage: E=EllipticCurve('121b1')3843sage: E.cm_discriminant()3844-113845sage: E=EllipticCurve('37a1')3846sage: E.cm_discriminant()3847Traceback (most recent call last):3848...3849ValueError: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field does not have CM3850"""38513852try:3853return CMJ[self.j_invariant()]3854except KeyError:3855raise ValueError, "%s does not have CM"%self385638573858def quadratic_twist(self, D):3859"""3860Return the global minimal model of the quadratic twist of this3861curve by D.38623863EXAMPLES::38643865sage: E=EllipticCurve('37a1')3866sage: E7=E.quadratic_twist(7); E73867Elliptic Curve defined by y^2 = x^3 - 784*x + 5488 over Rational Field3868sage: E7.conductor()3869290083870sage: E7.quadratic_twist(7) == E3871True3872"""3873return EllipticCurve_number_field.quadratic_twist(self, D).minimal_model()38743875def minimal_quadratic_twist(self):3876r"""3877Determines a quadratic twist with minimal conductor. Returns a3878global minimal model of the twist and the fundamental3879discriminant of the quadratic field over which they are3880isomorphic.38813882.. note::38833884If there is more than one curve with minimal conductor, the3885one returned is the one with smallest label (if in the3886database), or the one with minimal `a`-invariant list3887(otherwise).38883889.. note::38903891For curves with `j`-invariant 0 or 1728 the curve returned3892is the minimal quadratic twist, not necessarily the minimal3893twist (which would have conductor 27 or 32 respectively).38943895EXAMPLES::38963897sage: E = EllipticCurve('121d1')3898sage: E.minimal_quadratic_twist()3899(Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field, -11)3900sage: Et, D = EllipticCurve('32a1').minimal_quadratic_twist()3901sage: D3902139033904sage: E = EllipticCurve('11a1')3905sage: Et, D = E.quadratic_twist(-24).minimal_quadratic_twist()3906sage: E == Et3907True3908sage: D3909-2439103911sage: E = EllipticCurve([0,0,0,0,1000])3912sage: E.minimal_quadratic_twist()3913(Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field, 40)3914sage: E = EllipticCurve([0,0,0,1600,0])3915sage: E.minimal_quadratic_twist()3916(Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field, 5)39173918If the curve has square-free conductor then it is already minimal (see :trac:`14060`)::39193920sage: E = cremona_optimal_curves([2*3*5*7*11]).next()3921sage: (E, 1) == E.minimal_quadratic_twist()3922True39233924An example where the minimal quadratic twist is not the3925minimal twist (which has conductor 27)::39263927sage: E = EllipticCurve([0,0,0,0,7])3928sage: E.j_invariant()392903930sage: E.minimal_quadratic_twist()[0].conductor()393152923932"""3933if self.conductor().is_squarefree():3934return self, Integer(1)3935j = self.j_invariant()3936if j!=0 and j!=1728:3937# the constructor from j will give the minimal twist3938Et = constructor.EllipticCurve_from_j(j)3939else:3940if j==0: # divide c6 by largest cube3941c = -2*self.c6()3942for p in c.support():3943e = c.valuation(p)//33944c /= p**(3*e)3945E1 = constructor.EllipticCurve([0,0,0,0,c])3946elif j==1728: # divide c4 by largest square3947c = -3*self.c4()3948for p in c.support():3949e = c.valuation(p)//23950c /= p**(2*e)3951E1 = constructor.EllipticCurve([0,0,0,c,0])3952tw = [-1,2,-2,3,-3,6,-6]3953Elist = [E1] + [E1.quadratic_twist(t) for t in tw]3954crv_cmp = lambda E,F: cmp(E.conductor(),F.conductor())3955Elist.sort(cmp=crv_cmp)3956Et = Elist[0]39573958Et = Et.minimal_model()39593960D = self.is_quadratic_twist(Et) # 1 or square-free3961if D % 4 != 1:3962D *= 439633964return Et, D396539663967##########################################################3968# Isogeny class3969##########################################################3970def isogeny_class(self, algorithm="sage", order=None):3971r"""3972Returns the `\QQ`-isogeny class of this elliptic curve.39733974INPUT:39753976- ``algorithm`` - string: one of the following:39773978- "database" - use the Cremona database (only works if3979curve is isomorphic to a curve in the database)39803981- "sage" (default) - use the native Sage implementation.39823983- ``order`` -- None, string, or list of curves (default:3984None): If not None then the curves in the class are3985reordered after being computed. Note that if the order is3986None then the resulting order will depend on the algorithm.39873988- if ``order`` is "database" or "sage", then the reordering3989is so that the order of curves matches the order produced3990by that algorithm.39913992- if ``order`` is "lmfdb" then the curves are sorted3993lexicographically by a-invariants, in the LMFDB database.39943995- if ``order`` is a list of curves, then the curves in the3996class are reordered to be isomorphic with the specified3997list of curves.39983999OUTPUT:40004001An instance of the class4002:class:`sage.schemes.elliptic_curves.isogeny_class.IsogenyClass_EC_Rational`.4003This object models a list of minimal models (with containment,4004index, etc based on isomorphism classes). It also has methods4005for computing the isogeny matrix and the list of isogenies4006between curves in this class.40074008.. note::40094010The curves in the isogeny class will all be standard4011minimal models.40124013EXAMPLES::40144015sage: isocls = EllipticCurve('37b').isogeny_class(order="lmfdb")4016sage: isocls4017Elliptic curve isogeny class 37b4018sage: isocls.curves4019(Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field,4020Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field,4021Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field)4022sage: isocls.matrix()4023[1 3 9]4024[3 1 3]4025[9 3 1]40264027::40284029sage: isocls = EllipticCurve('37b').isogeny_class('database', order="lmfdb"); isocls.curves4030(Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field,4031Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field,4032Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field)40334034This is an example of a curve with a `37`-isogeny::40354036sage: E = EllipticCurve([1,1,1,-8,6])4037sage: isocls = E.isogeny_class(); isocls4038Isogeny class of Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field4039sage: isocls.matrix()4040[ 1 37]4041[37 1]4042sage: print "\n".join([repr(E) for E in isocls.curves])4043Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field4044Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 208083*x - 36621194 over Rational Field40454046This curve had numerous `2`-isogenies::40474048sage: e=EllipticCurve([1,0,0,-39,90])4049sage: isocls = e.isogeny_class(); isocls.matrix()4050[1 2 4 4 8 8]4051[2 1 2 2 4 4]4052[4 2 1 4 8 8]4053[4 2 4 1 2 2]4054[8 4 8 2 1 4]4055[8 4 8 2 4 1]40564057See http://math.harvard.edu/~elkies/nature.html for more4058interesting examples of isogeny structures.40594060::40614062sage: E = EllipticCurve(j = -262537412640768000)4063sage: isocls = E.isogeny_class(); isocls.matrix()4064[ 1 163]4065[163 1]4066sage: print "\n".join([repr(C) for C in isocls.curves])4067Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field4068Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field406940704071The degrees of isogenies are invariant under twists::40724073sage: E = EllipticCurve(j = -262537412640768000)4074sage: E1 = E.quadratic_twist(6584935282)4075sage: isocls = E1.isogeny_class(); isocls.matrix()4076[ 1 163]4077[163 1]4078sage: E1.conductor()40791843309296671206365333049640804081::40824083sage: E = EllipticCurve('14a1')4084sage: isocls = E.isogeny_class(); isocls.matrix()4085[ 1 2 3 3 6 6]4086[ 2 1 6 6 3 3]4087[ 3 6 1 9 2 18]4088[ 3 6 9 1 18 2]4089[ 6 3 2 18 1 9]4090[ 6 3 18 2 9 1]4091sage: print "\n".join([repr(C) for C in isocls.curves])4092Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field4093Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field4094Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field4095Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field4096Elliptic Curve defined by y^2 + x*y + y = x^3 - 11*x + 12 over Rational Field4097Elliptic Curve defined by y^2 + x*y + y = x^3 - 2731*x - 55146 over Rational Field4098sage: isocls2 = isocls.reorder('lmfdb'); isocls2.matrix()4099[ 1 2 3 9 18 6]4100[ 2 1 6 18 9 3]4101[ 3 6 1 3 6 2]4102[ 9 18 3 1 2 6]4103[18 9 6 2 1 3]4104[ 6 3 2 6 3 1]4105sage: print "\n".join([repr(C) for C in isocls2.curves])4106Elliptic Curve defined by y^2 + x*y + y = x^3 - 2731*x - 55146 over Rational Field4107Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field4108Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field4109Elliptic Curve defined by y^2 + x*y + y = x^3 - 11*x + 12 over Rational Field4110Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field4111Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field41124113::41144115sage: E = EllipticCurve('11a1')4116sage: isocls = E.isogeny_class(); isocls.matrix()4117[ 1 5 5]4118[ 5 1 25]4119[ 5 25 1]4120sage: f = isocls.isogenies()[0][1]; f.kernel_polynomial()4121x^2 + x - 29/54122"""4123try:4124isoclass = self._isoclass[algorithm]4125except KeyError:4126from sage.schemes.elliptic_curves.isogeny_class import IsogenyClass_EC_Rational4127if hasattr(self, "_lmfdb_label") and self._lmfdb_label:4128label = self._lmfdb_label[:-1]4129elif hasattr(self, "_EllipticCurve_rational_field__cremona_label") and self.__cremona_label:4130label = self.__cremona_label[:-1]4131else:4132label = None41334134isoclass = IsogenyClass_EC_Rational(self, algorithm, label)4135self._isoclass[algorithm] = isoclass41364137if order:4138isoclass = isoclass.reorder(order)41394140return isoclass41414142def isogenies_prime_degree(self, l=None):4143r"""4144Returns a list of `\ell`-isogenies from self, where `\ell` is a4145prime.41464147INPUT:41484149- ``l`` -- either None or a prime or a list of primes.41504151OUTPUT:41524153(list) `\ell`-isogenies for the given `\ell` or if `\ell` is None, all4154`\ell`-isogenies.41554156.. note::41574158The codomains of the isogenies returned are standard4159minimal models. This is because the functions4160:meth:`isogenies_prime_degree_genus_0()` and4161:meth:`isogenies_sporadic_Q()` are implemented that way for4162curves defined over `\QQ`.41634164EXAMPLES::41654166sage: E = EllipticCurve([45,32])4167sage: E.isogenies_prime_degree()4168[]4169sage: E = EllipticCurve(j = -262537412640768000)4170sage: E.isogenies_prime_degree()4171[Isogeny of degree 163 from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field]4172sage: E1 = E.quadratic_twist(6584935282)4173sage: E1.isogenies_prime_degree()4174[Isogeny of degree 163 from Elliptic Curve defined by y^2 = x^3 - 94285835957031797981376080*x + 352385311612420041387338054224547830898 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 2505080375542377840567181069520*x - 1526091631109553256978090116318797845018020806 over Rational Field]41754176sage: E = EllipticCurve('14a1')4177sage: E.isogenies_prime_degree(2)4178[Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field]4179sage: E.isogenies_prime_degree(3)4180[Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field, Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field]4181sage: E.isogenies_prime_degree(5)4182[]4183sage: E.isogenies_prime_degree(11)4184[]4185sage: E.isogenies_prime_degree(29)4186[]4187sage: E.isogenies_prime_degree(4)4188Traceback (most recent call last):4189...4190ValueError: 4 is not prime.41914192"""4193from isogeny_small_degree import isogenies_prime_degree_genus_0, isogenies_sporadic_Q41944195if l in [2, 3, 5, 7, 13]:4196return isogenies_prime_degree_genus_0(self, l)4197elif l != None and type(l) != list:4198try:4199if l.is_prime(proof=False):4200return isogenies_sporadic_Q(self, l)4201else:4202raise ValueError("%s is not prime."%l)4203except AttributeError:4204raise ValueError("%s is not prime."%l)4205if l == None:4206isogs = isogenies_prime_degree_genus_0(self)4207if isogs != []:4208return isogs4209else:4210return isogenies_sporadic_Q(self)4211if type(l) == list:4212isogs = []4213i = 04214while i<len(l):4215isogenies = [f for f in self.isogenies_prime_degree(l[i]) if not f in isogs]4216isogs.extend(isogenies)4217i = i+14218return isogs42194220def is_isogenous(self, other, proof=True, maxp=200):4221"""4222Returns whether or not self is isogenous to other.42234224INPUT:42254226- ``other`` -- another elliptic curve.42274228- ``proof`` (default True) -- If ``False``, the function will4229return ``True`` whenever the two curves have the same4230conductor and are isogenous modulo `p` for `p` up to ``maxp``.4231If ``True``, this test is followed by a rigorous test (which4232may be more time-consuming).42334234- ``maxp`` (int, default 200) -- The maximum prime `p` for4235which isogeny modulo `p` will be checked.42364237OUTPUT:42384239(bool) True if there is an isogeny from curve ``self`` to4240curve ``other``.42414242METHOD:42434244First the conductors are compared as well as the Traces of4245Frobenius for good primes up to ``maxp``. If any of these4246tests fail, ``False`` is returned. If they all pass and4247``proof`` is ``False`` then ``True`` is returned, otherwise a4248complete set of curves isogenous to ``self`` is computed and4249``other`` is checked for isomorphism with any of these,42504251EXAMPLES::42524253sage: E1 = EllipticCurve('14a1')4254sage: E6 = EllipticCurve('14a6')4255sage: E1.is_isogenous(E6)4256True4257sage: E1.is_isogenous(EllipticCurve('11a1'))4258False42594260::42614262sage: EllipticCurve('37a1').is_isogenous(EllipticCurve('37b1'))4263False42644265::42664267sage: E = EllipticCurve([2, 16])4268sage: EE = EllipticCurve([87, 45])4269sage: E.is_isogenous(EE)4270False4271"""4272if not is_EllipticCurve(other):4273raise ValueError, "Second argument is not an Elliptic Curve."4274if not other.base_field() is QQ:4275raise ValueError, "If first argument is an elliptic curve over QQ then the second argument must be also."42764277if self.is_isomorphic(other):4278return True42794280E1 = self.minimal_model()4281E2 = other.minimal_model()4282D1 = E1.discriminant()4283D2 = E2.discriminant()42844285if any([E1.change_ring(rings.GF(p)).cardinality() != E2.change_ring(rings.GF(p)).cardinality() for p in [p for p in rings.prime_range(2,maxp) if D1.valuation(p) == 0 and D2.valuation(p) == 0]]):4286return False42874288if E1.conductor() != E2.conductor():4289return False42904291if not proof:4292return True4293else:4294return E2 in E1.isogeny_class().curves42954296def isogeny_degree(self, other):4297"""4298Returns the minimal degree of an isogeny between self and4299other.43004301INPUT:43024303- ``other`` -- another elliptic curve.43044305OUTPUT:43064307(int) The minimal degree of an isogeny from ``self`` to4308``other``, or 0 if the curves are not isogenous.43094310EXAMPLES::43114312sage: E = EllipticCurve([-1056, 13552])4313sage: E2 = EllipticCurve([-127776, -18037712])4314sage: E.isogeny_degree(E2)43151143164317::43184319sage: E1 = EllipticCurve('14a1')4320sage: E2 = EllipticCurve('14a2')4321sage: E3 = EllipticCurve('14a3')4322sage: E4 = EllipticCurve('14a4')4323sage: E5 = EllipticCurve('14a5')4324sage: E6 = EllipticCurve('14a6')4325sage: E3.isogeny_degree(E1)432634327sage: E3.isogeny_degree(E2)432864329sage: E3.isogeny_degree(E3)433014331sage: E3.isogeny_degree(E4)433294333sage: E3.isogeny_degree(E5)433424335sage: E3.isogeny_degree(E6)43361843374338::43394340sage: E1 = EllipticCurve('30a1')4341sage: E2 = EllipticCurve('30a2')4342sage: E3 = EllipticCurve('30a3')4343sage: E4 = EllipticCurve('30a4')4344sage: E5 = EllipticCurve('30a5')4345sage: E6 = EllipticCurve('30a6')4346sage: E7 = EllipticCurve('30a7')4347sage: E8 = EllipticCurve('30a8')4348sage: E1.isogeny_degree(E1)434914350sage: E1.isogeny_degree(E2)435124352sage: E1.isogeny_degree(E3)435334354sage: E1.isogeny_degree(E4)435544356sage: E1.isogeny_degree(E5)435744358sage: E1.isogeny_degree(E6)435964360sage: E1.isogeny_degree(E7)4361124362sage: E1.isogeny_degree(E8)43631243644365::43664367sage: E1 = EllipticCurve('15a1')4368sage: E2 = EllipticCurve('15a2')4369sage: E3 = EllipticCurve('15a3')4370sage: E4 = EllipticCurve('15a4')4371sage: E5 = EllipticCurve('15a5')4372sage: E6 = EllipticCurve('15a6')4373sage: E7 = EllipticCurve('15a7')4374sage: E8 = EllipticCurve('15a8')4375sage: E1.isogeny_degree(E1)437614377sage: E7.isogeny_degree(E2)437884379sage: E7.isogeny_degree(E3)438024381sage: E7.isogeny_degree(E4)438284383sage: E7.isogeny_degree(E5)4384164385sage: E7.isogeny_degree(E6)4386164387sage: E7.isogeny_degree(E8)43884438943900 is returned when the curves are not isogenous::43914392sage: A = EllipticCurve('37a1')4393sage: B = EllipticCurve('37b1')4394sage: A.isogeny_degree(B)439504396sage: A.is_isogenous(B)4397False4398"""4399E1 = self.minimal_model()4400E2 = other.minimal_model()44014402if not E1.is_isogenous(E2, proof=False):4403return Integer(0)44044405isocls = E1.isogeny_class()4406try:4407return isocls.matrix(fill=True)[0,isocls.index(E2)]4408except ValueError:4409return Integer(0)44104411#4412# The following function can be implemented once composition of4413# isogenies has been implemented.4414#4415# def contruct_isogeny(self, other):4416# """4417# Returns an isogeny from self to other if the two curves are in4418# the same isogeny class.4419# """442044214422def optimal_curve(self):4423"""4424Given an elliptic curve that is in the installed Cremona4425database, return the optimal curve isogenous to it.44264427EXAMPLES:44284429The following curve is not optimal::44304431sage: E = EllipticCurve('11a2'); E4432Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field4433sage: E.optimal_curve()4434Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field4435sage: E.optimal_curve().cremona_label()4436'11a1'44374438Note that 990h is the special case where the optimal curve4439isn't the first in the Cremona labeling::44404441sage: E = EllipticCurve('990h4'); E4442Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 6112*x - 41533 over Rational Field4443sage: F = E.optimal_curve(); F4444Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1568*x - 4669 over Rational Field4445sage: F.cremona_label()4446'990h3'4447sage: EllipticCurve('990a1').optimal_curve().cremona_label() # a isn't h.4448'990a1'44494450If the input curve is optimal, this function returns that4451curve (not just a copy of it or a curve isomorphic to it!)::44524453sage: E = EllipticCurve('37a1')4454sage: E.optimal_curve() is E4455True44564457Also, if this curve is optimal but not given by a minimal4458model, this curve will still be returned, so this function4459need not return a minimal model in general.44604461::44624463sage: F = E.short_weierstrass_model(); F4464Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field4465sage: F.optimal_curve()4466Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field4467"""4468label = self.cremona_label()4469N, isogeny, number = sage.databases.cremona.parse_cremona_label(label)4470if N == 990 and isogeny == 'h':4471optimal_label = '990h3'4472else:4473optimal_label = '%s%s1'%(N,isogeny)4474if optimal_label == label: return self4475return constructor.EllipticCurve(optimal_label)44764477def isogeny_graph(self, order=None):4478r"""4479Return a graph representing the isogeny class of this elliptic4480curve, where the vertices are isogenous curves over4481`\QQ` and the edges are prime degree isogenies.44824483.. note:44844485The vertices are labeled 1 to n rather than 0 to n-1 to4486correspond to LMFDB and Cremona labels.44874488EXAMPLES::44894490sage: LL = []4491sage: for e in cremona_optimal_curves(range(1, 38)): # long time4492....: G = e.isogeny_graph()4493....: already = False4494....: for H in LL:4495....: if G.is_isomorphic(H):4496....: already = True4497....: break4498....: if not already:4499....: LL.append(G)4500sage: graphs_list.show_graphs(LL) # long time45014502::45034504sage: E = EllipticCurve('195a')4505sage: G = E.isogeny_graph()4506sage: for v in G: print v, G.get_vertex(v)4507...45081 Elliptic Curve defined by y^2 + x*y = x^3 - 110*x + 435 over Rational Field45092 Elliptic Curve defined by y^2 + x*y = x^3 - 115*x + 392 over Rational Field45103 Elliptic Curve defined by y^2 + x*y = x^3 + 210*x + 2277 over Rational Field45114 Elliptic Curve defined by y^2 + x*y = x^3 - 520*x - 4225 over Rational Field45125 Elliptic Curve defined by y^2 + x*y = x^3 + 605*x - 19750 over Rational Field45136 Elliptic Curve defined by y^2 + x*y = x^3 - 8125*x - 282568 over Rational Field45147 Elliptic Curve defined by y^2 + x*y = x^3 - 7930*x - 296725 over Rational Field45158 Elliptic Curve defined by y^2 + x*y = x^3 - 130000*x - 18051943 over Rational Field4516sage: G.plot(edge_labels=True)4517"""4518return self.isogeny_class(order=order).graph()45194520def manin_constant(self):4521r"""4522Return the Manin constant of this elliptic curve. If `\phi: X_0(N) \to E` is the modular4523parametrization of minimal degree, then the Manin constant `c` is defined to be the rational4524number `c` such that `\phi^*(\omega_E) = c\cdot \omega_f` where `\omega_E` is a Neron differential and `\omega_f = f(q) dq/q` is the differential on `X_0(N)` corresponding to the4525newform `f` attached to the isogeny class of `E`.45264527It is known that the Manin constant is an integer. It is conjectured that in each class there is at least one, more precisely the so-called strong Weil curve or `X_0(N)`-optimal curve, that has Manin constant `1`.45284529OUTPUT:45304531an integer45324533This function only works if the curve is in the installed4534Cremona database. Sage includes by default a small databases;4535for the full database you have to install an optional package.45364537EXAMPLES::45384539sage: EllipticCurve('11a1').manin_constant()454014541sage: EllipticCurve('11a2').manin_constant()454214543sage: EllipticCurve('11a3').manin_constant()4544545454546Check that it works even if the curve is non-minimal::45474548sage: EllipticCurve('11a3').change_weierstrass_model([1/35,0,0,0]).manin_constant()4549545504551Rather complicated examples (see #12080) ::45524553sage: [ EllipticCurve('27a%s'%i).manin_constant() for i in [1,2,3,4]]4554[1, 1, 3, 3]4555sage: [ EllipticCurve('80b%s'%i).manin_constant() for i in [1,2,3,4]]4556[1, 2, 1, 2]45574558"""4559from sage.databases.cremona import CremonaDatabase45604561if self.conductor() > CremonaDatabase().largest_conductor():4562raise NotImplementedError, "The Manin constant can only be evaluated for curves in Cremona's tables. If you have not done so, you may wish to install the optional large database."45634564E = self.minimal_model()4565C = self.optimal_curve()4566m = C.isogeny_class().matrix()4567ma = max(max(x) for x in m)4568OmC = C.period_lattice().basis()4569OmE = E.period_lattice().basis()4570q_plus = QQ(gp.bestappr(OmE[0]/OmC[0],ma+1) )4571n_plus = q_plus.numerator()45724573cinf_E = E.real_components()4574cinf_C = C.real_components()4575OmC_minus = OmC[1].imag()4576if cinf_C == 1:4577OmC_minus *= 24578OmE_minus = OmE[1].imag()4579if cinf_E == 1:4580OmE_minus *= 24581q_minus = QQ(gp.bestappr(OmE_minus/OmC_minus, ma+1))4582n_minus = q_minus.numerator()4583n = ZZ(n_minus * n_plus)45844585if cinf_C == cinf_E:4586return n4587# otherwise they have different number of connected component and we have to adjust for this4588elif cinf_C > cinf_E:4589if ZZ(n_plus) % 2 == 0 and ZZ(n_minus) % 2 == 0:4590return n // 24591else:4592return n4593else: #if cinf_C < cinf_E:4594if q_plus.denominator() % 2 == 0 and q_minus.denominator() % 2 == 0:4595return n4596else:4597return n*245984599def _shortest_paths(self):4600r"""4601Technical internal function that returns the list of isogenies4602curves and corresponding dictionary of shortest isogeny paths4603from self to each other curve in the isogeny class.46044605OUTPUT:46064607list, dict46084609EXAMPLES::46104611sage: EllipticCurve('11a1')._shortest_paths()4612((Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field,4613Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field,4614Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field),4615{0: 0, 1: 5, 2: 5})4616sage: EllipticCurve('11a2')._shortest_paths()4617((Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field,4618Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field,4619Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field),4620{0: 0, 1: 5, 2: 25})4621"""4622from sage.graphs.graph import Graph4623isocls = self.isogeny_class()4624M = isocls.matrix(fill=True).change_ring(rings.RR)4625# see trac #4889 for nebulous M.list() --> M.entries() change...4626# Take logs here since shortest path minimizes the *sum* of the weights -- not the product.4627M = M.parent()([a.log() if a else 0 for a in M.list()])4628G = Graph(M, format='weighted_adjacency_matrix')4629G.set_vertices(dict([(v,isocls[v]) for v in G.vertices()]))4630v = G.shortest_path_lengths(0, by_weight=True, weight_sums=True)4631# Now exponentiate and round to get degrees of isogenies4632v = dict([(i, j.exp().round() if j else 0) for i,j in v.iteritems()])4633return isocls.curves, v46344635def _multiple_of_degree_of_isogeny_to_optimal_curve(self):4636r"""4637Internal function returning an integer m such that the degree of4638the isogeny between this curve and the optimal curve in its4639isogeny class is a divisor of m.46404641.. warning::46424643The result is *not* provably correct, in the4644sense that when the numbers are huge isogenies could be4645missed because of precision issues.46464647EXAMPLES::46484649sage: E = EllipticCurve('11a1')4650sage: E._multiple_of_degree_of_isogeny_to_optimal_curve()465154652sage: E = EllipticCurve('11a2')4653sage: E._multiple_of_degree_of_isogeny_to_optimal_curve()4654254655sage: E = EllipticCurve('11a3')4656sage: E._multiple_of_degree_of_isogeny_to_optimal_curve()4657254658"""4659_, v = self._shortest_paths()4660# Compute the degree of an isogeny from self to anything else4661# in the isogeny class of self. Assuming the isogeny4662# enumeration is complete (which need not be the case a priori!), the LCM4663# of these numbers is a multiple of the degree of the isogeny4664# to the optimal curve.4665v = [deg for num, deg in v.iteritems() if deg] # get just the degrees4666return arith.LCM(v)46674668##########################################################4669# Galois Representations4670##########################################################46714672def galois_representation(self):4673r"""4674The compatible family of the Galois representation4675attached to this elliptic curve.46764677Given an elliptic curve `E` over `\QQ`4678and a rational prime number `p`, the `p^n`-torsion4679`E[p^n]` points of `E` is a representation of the4680absolute Galois group of `\QQ`. As `n` varies4681we obtain the Tate module `T_p E` which is a4682a representation of `G_K` on a free `\ZZ_p`-module4683of rank `2`. As `p` varies the representations4684are compatible.46854686EXAMPLES::46874688sage: rho = EllipticCurve('11a1').galois_representation()4689sage: rho4690Compatible family of Galois representations associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field4691sage: rho.is_irreducible(7)4692True4693sage: rho.is_irreducible(5)4694False4695sage: rho.is_surjective(11)4696True4697sage: rho.non_surjective()4698[5]4699sage: rho = EllipticCurve('37a1').galois_representation()4700sage: rho.non_surjective()4701[]4702sage: rho = EllipticCurve('27a1').galois_representation()4703sage: rho.is_irreducible(7)4704True4705sage: rho.non_surjective() # cm-curve4706[0]47074708"""4709try:4710return self.__rho4711except AttributeError:4712from gal_reps import GaloisRepresentation4713self.__rho = GaloisRepresentation(self)4714return self.__rho47154716# deprecated as it should be the is_reducible for a scheme (and hence return False always).4717def is_reducible(self, p):4718"""4719Return True if the mod-p representation attached to E is4720reducible.47214722Note that this function is deprecated, and that you should use4723galois_representation().is_reducible(p) instead as this will be4724disappearing in the near future.47254726EXAMPLES::47274728sage: EllipticCurve('20a1').is_reducible(3) #random4729doctest:1: DeprecationWarning: is_reducible is deprecated, use galois_representation().is_reducible(p) instead!4730True47314732"""4733from sage.misc.superseded import deprecation4734deprecation(8118, "is_reducible is deprecated, use galois_representation().is_reducible(p) instead!")4735return self.galois_representation().is_reducible(p)47364737# deprecated as it should be the is_irreducible for a scheme (and hence return True always).4738def is_irreducible(self, p):4739"""4740Return True if the mod p representation is irreducible.47414742Note that this function is deprecated, and that you should use4743galois_representation().is_irreducible(p) instead as this will be4744disappearing in the near future.47454746EXAMPLES::47474748sage: EllipticCurve('20a1').is_irreducible(7) #random4749doctest:1: DeprecationWarning: is_irreducible is deprecated, use galois_representation().is_irreducible(p) instead!4750True47514752"""4753from sage.misc.superseded import deprecation4754deprecation(8118, "is_irreducible is deprecated, use galois_representation().is_irreducible(p) instead!")4755return self.galois_representation().is_irreducible(p)47564757# deprecated4758def is_surjective(self, p, A=1000):4759r"""4760Returns true if the mod p representation is surjective47614762Note that this function is deprecated, and that you should use4763galois_representation().is_surjective(p) instead as this will be4764disappearing in the near future.47654766EXAMPLES::47674768sage: EllipticCurve('20a1').is_surjective(7) #random4769doctest:1: DeprecationWarning: is_surjective is deprecated, use galois_representation().is_surjective(p) instead!4770True47714772"""4773from sage.misc.superseded import deprecation4774deprecation(8118, "is_surjective is deprecated, use galois_representation().is_surjective(p) instead!")4775return self.galois_representation().is_surjective(p,A)47764777# deprecated4778def reducible_primes(self):4779r"""4780Returns a list of reducible primes.47814782Note that this function is deprecated, and that you should use4783galois_representation().reducible_primes() instead as this will be4784disappearing in the near future.47854786EXAMPLES::47874788sage: EllipticCurve('20a1').reducible_primes() #random4789doctest:1: DeprecationWarning: reducible_primes is deprecated, use galois_representation().reducible_primes() instead!4790[2,3]47914792"""4793from sage.misc.superseded import deprecation4794deprecation(8118, "reducible_primes is deprecated, use galois_representation().reducible_primes() instead!")4795return self.galois_representation().reducible_primes()47964797# deprecated4798def non_surjective(self, A=1000):4799r"""4800Returns a list of primes p for which the Galois representation mod p is not surjective.48014802Note that this function is deprecated, and that you should use4803galois_representation().non_surjective() instead as this will be4804disappearing in the near future.48054806EXAMPLES::48074808sage: EllipticCurve('20a1').non_surjective() #random4809doctest:1: DeprecationWarning: non_surjective is deprecated, use galois_representation().non_surjective() instead!4810[2,3]48114812"""4813from sage.misc.superseded import deprecation4814deprecation(8118, "non_surjective is deprecated, use galois_representation().non_surjective() instead!")4815return self.galois_representation().non_surjective()48164817def is_semistable(self):4818"""4819Return True iff this elliptic curve is semi-stable at all primes.48204821EXAMPLES::48224823sage: E=EllipticCurve('37a1')4824sage: E.is_semistable()4825True4826sage: E=EllipticCurve('90a1')4827sage: E.is_semistable()4828False4829"""4830return self.conductor().is_squarefree()48314832def is_ordinary(self, p, ell=None):4833"""4834Return True precisely when the mod-p representation attached to4835this elliptic curve is ordinary at ell.48364837INPUT:48384839- ``p`` - a prime ell - a prime (default: p)48404841OUTPUT: bool48424843EXAMPLES::48444845sage: E=EllipticCurve('37a1')4846sage: E.is_ordinary(37)4847True4848sage: E=EllipticCurve('32a1')4849sage: E.is_ordinary(2)4850False4851sage: [p for p in prime_range(50) if E.is_ordinary(p)]4852[5, 13, 17, 29, 37, 41]48534854"""4855if ell is None:4856ell = p4857return self.ap(ell) % p != 048584859def is_good(self, p, check=True):4860"""4861Return True if `p` is a prime of good reduction for4862`E`.48634864INPUT:48654866- ``p`` - a prime48674868OUTPUT: bool48694870EXAMPLES::48714872sage: e = EllipticCurve('11a')4873sage: e.is_good(-8)4874Traceback (most recent call last):4875...4876ValueError: p must be prime4877sage: e.is_good(-8, check=False)4878True48794880"""4881if check:4882if not arith.is_prime(p):4883raise ValueError, "p must be prime"4884return self.conductor() % p != 0488548864887def is_supersingular(self, p, ell=None):4888"""4889Return True precisely when p is a prime of good reduction and the4890mod-p representation attached to this elliptic curve is4891supersingular at ell.48924893INPUT:48944895- ``p`` - a prime ell - a prime (default: p)48964897OUTPUT: bool48984899EXAMPLES::49004901sage: E=EllipticCurve('37a1')4902sage: E.is_supersingular(37)4903False4904sage: E=EllipticCurve('32a1')4905sage: E.is_supersingular(2)4906False4907sage: E.is_supersingular(7)4908True4909sage: [p for p in prime_range(50) if E.is_supersingular(p)]4910[3, 7, 11, 19, 23, 31, 43, 47]49114912"""4913if ell is None:4914ell = p4915return self.is_good(p) and not self.is_ordinary(p, ell)49164917def supersingular_primes(self, B):4918"""4919Return a list of all supersingular primes for this elliptic curve4920up to and possibly including B.49214922EXAMPLES::49234924sage: e = EllipticCurve('11a')4925sage: e.aplist(20)4926[-2, -1, 1, -2, 1, 4, -2, 0]4927sage: e.supersingular_primes(1000)4928[2, 19, 29, 199, 569, 809]49294930::49314932sage: e = EllipticCurve('27a')4933sage: e.aplist(20)4934[0, 0, 0, -1, 0, 5, 0, -7]4935sage: e.supersingular_primes(97)4936[2, 5, 11, 17, 23, 29, 41, 47, 53, 59, 71, 83, 89]4937sage: e.ordinary_primes(97)4938[7, 13, 19, 31, 37, 43, 61, 67, 73, 79, 97]4939sage: e.supersingular_primes(3)4940[2]4941sage: e.supersingular_primes(2)4942[2]4943sage: e.supersingular_primes(1)4944[]4945"""4946v = self.aplist(max(B, 3))4947P = rings.prime_range(max(B,3)+1)4948N = self.conductor()4949return [P[i] for i in [0,1] if P[i] <= B and v[i]%P[i]==0 and N%P[i] != 0] + \4950[P[i] for i in range(2,len(v)) if v[i] == 0 and N%P[i] != 0]49514952def ordinary_primes(self, B):4953"""4954Return a list of all ordinary primes for this elliptic curve up to4955and possibly including B.49564957EXAMPLES::49584959sage: e = EllipticCurve('11a')4960sage: e.aplist(20)4961[-2, -1, 1, -2, 1, 4, -2, 0]4962sage: e.ordinary_primes(97)4963[3, 5, 7, 11, 13, 17, 23, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]4964sage: e = EllipticCurve('49a')4965sage: e.aplist(20)4966[1, 0, 0, 0, 4, 0, 0, 0]4967sage: e.supersingular_primes(97)4968[3, 5, 13, 17, 19, 31, 41, 47, 59, 61, 73, 83, 89, 97]4969sage: e.ordinary_primes(97)4970[2, 11, 23, 29, 37, 43, 53, 67, 71, 79]4971sage: e.ordinary_primes(3)4972[2]4973sage: e.ordinary_primes(2)4974[2]4975sage: e.ordinary_primes(1)4976[]4977"""4978v = self.aplist(max(B, 3) )4979P = rings.prime_range(max(B,3) +1)4980return [P[i] for i in [0,1] if P[i] <= B and v[i]%P[i]!=0] +\4981[P[i] for i in range(2,len(v)) if v[i] != 0]49824983def eval_modular_form(self, points, prec):4984"""4985Evaluate the modular form of this elliptic curve at points in CC49864987INPUT:498849894990- ``points`` - a list of points in the half-plane of4991convergence49924993- ``prec`` - precision499449954996OUTPUT: A list of values L(E,s) for s in points49974998.. note::49995000Better examples are welcome.50015002EXAMPLES::50035004sage: E=EllipticCurve('37a1')5005sage: E.eval_modular_form([1.5+I,2.0+I,2.5+I],0.000001)5006[0, 0, 0]5007"""5008if not isinstance(points, (list,xrange)):5009try:5010points = list(points)5011except TypeError:5012return self.eval_modular_form([points],prec)5013an = self.pari_mincurve().ellan(prec)5014s = 05015c = pari('2 * Pi * I')5016ans = []5017for z in points:5018s = pari(0)5019r0 = (c*z).exp()5020r = r05021for n in xrange(1,prec):5022s += an[n-1]*r5023r *= r05024ans.append(s.python())5025return ans502650275028########################################################################5029# The Tate-Shafarevich group5030########################################################################50315032def sha(self):5033"""5034Return an object of class5035'sage.schemes.elliptic_curves.sha_tate.Sha' attached to this5036elliptic curve.50375038This can be used in functions related to bounding the order of Sha5039(The Tate-Shafarevich group of the curve).50405041EXAMPLES::50425043sage: E=EllipticCurve('37a1')5044sage: S=E.sha()5045sage: S5046Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field5047sage: S.bound_kolyvagin()5048([2], 1)5049"""5050try:5051return self.__sha5052except AttributeError:5053from sha_tate import Sha5054self.__sha = Sha(self)5055return self.__sha50565057#################################################################################5058# Functions related to Heegner points#################################################################################5059heegner_point = heegner.ell_heegner_point5060kolyvagin_point = heegner.kolyvagin_point50615062heegner_discriminants = heegner.ell_heegner_discriminants5063heegner_discriminants_list = heegner.ell_heegner_discriminants_list5064satisfies_heegner_hypothesis = heegner.satisfies_heegner_hypothesis50655066heegner_point_height = heegner.heegner_point_height50675068heegner_index = heegner.heegner_index5069_adjust_heegner_index = heegner._adjust_heegner_index5070heegner_index_bound = heegner.heegner_index_bound5071_heegner_index_in_EK = heegner._heegner_index_in_EK50725073heegner_sha_an = heegner.heegner_sha_an50745075_heegner_forms_list = heegner._heegner_forms_list5076_heegner_best_tau = heegner._heegner_best_tau50775078#################################################################################5079# p-adic functions5080#################################################################################50815082padic_regulator = padics.padic_regulator50835084padic_height_pairing_matrix = padics.padic_height_pairing_matrix50855086padic_height = padics.padic_height5087padic_height_via_multiply = padics.padic_height_via_multiply50885089padic_sigma = padics.padic_sigma5090padic_sigma_truncated = padics.padic_sigma_truncated50915092padic_E2 = padics.padic_E250935094matrix_of_frobenius = padics.matrix_of_frobenius50955096# def weierstrass_p(self):5097# # TODO: add allowing negative valuations for power series5098# return 1/t**2 + a1/t + rings.frac(1,12)*(a1-8*a2) -a3*t \5099# - (a4+a1*a3)*t**2 + O(t**3)510051015102def mod5family(self):5103"""5104Return the family of all elliptic curves with the same mod-55105representation as self.51065107EXAMPLES::51085109sage: E=EllipticCurve('32a1')5110sage: E.mod5family()5111Elliptic Curve defined by y^2 = x^3 + 4*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field5112"""5113E = self.short_weierstrass_model()5114a = E.a4()5115b = E.a6()5116return mod5family.mod5family(a,b)51175118def tate_curve(self, p):5119r"""5120Creates the Tate Curve over the `p`-adics associated to5121this elliptic curves.51225123This Tate curve a `p`-adic curve with split multiplicative5124reduction of the form `y^2+xy=x^3+s_4 x+s_6` which is5125isomorphic to the given curve over the algebraic closure of5126`\QQ_p`. Its points over `\QQ_p`5127are isomorphic to `\QQ_p^{\times}/q^{\ZZ}`5128for a certain parameter `q\in\ZZ_p`.51295130INPUT:51315132p - a prime where the curve has multiplicative reduction.51335134EXAMPLES::51355136sage: e = EllipticCurve('130a1')5137sage: e.tate_curve(2)51382-adic Tate curve associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field51395140The input curve must have multiplicative reduction at the prime.51415142::51435144sage: e.tate_curve(3)5145Traceback (most recent call last):5146...5147ValueError: The elliptic curve must have multiplicative reduction at 351485149We compute with `p=5`::51505151sage: T = e.tate_curve(5); T51525-adic Tate curve associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field51535154We find the Tate parameter `q`::51555156sage: T.parameter(prec=5)51573*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8)51585159We compute the `\mathcal{L}`-invariant of the curve::51605161sage: T.L_invariant(prec=10)51625^3 + 4*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 3*5^8 + 5^9 + O(5^10)5163"""5164try:5165return self._tate_curve[p]5166except AttributeError:5167self._tate_curve = {}5168except KeyError:5169pass51705171Eq = ell_tate_curve.TateCurve(self,p)5172self._tate_curve[p] = Eq5173return Eq51745175def height(self, precision=None):5176"""5177Returns the real height of this elliptic curve. This is used in5178integral_points()51795180INPUT:518151825183- ``precision`` - desired real precision of the result5184(default real precision if None)518551865187EXAMPLES::51885189sage: E=EllipticCurve('5077a1')5190sage: E.height()519117.45133347988965192sage: E.height(100)519317.4513334798896127025085793995194sage: E=EllipticCurve([0,0,0,0,1])5195sage: E.height()51961.386294361119895197sage: E=EllipticCurve([0,0,0,1,0])5198sage: E.height()51997.454719949364005200"""5201if precision is None:5202precision = RealField().precision()5203R = RealField(precision)5204c4 = self.c4()5205c6 = self.c6()5206j = self.j_invariant()5207log_g2 = R((c4/12)).abs().log()5208log_g3 = R((c6/216)).abs().log()52095210if j == 0:5211h_j = R(1)5212else:5213h_j = max(log(R(abs(j.numerator()))), log(R(abs(j.denominator()))))5214if (self.c4() != 0) and (self.c6() != 0):5215h_gs = max(1, log_g2, log_g3)5216elif c4 == 0:5217if c6 == 0:5218return max(1,h_j)5219h_gs = max(1, log_g3)5220else:5221h_gs = max(1, log_g2)5222return max(R(1),h_j, h_gs)52235224def antilogarithm(self, z, max_denominator=None):5225r"""5226Returns the rational point (if any) associated to this complex5227number; the inverse of the elliptic logarithm function.52285229INPUT:52305231- ``z`` -- a complex number representing an element of5232`\CC/L` where `L` is the period lattice of the elliptic curve52335234- ``max_denominator`` (int or None) -- parameter controlling5235the attempted conversion of real numbers to rationals. If5236None, ``simplest_rational()`` will be used; otherwise,5237``nearby_rational()`` will be used with this value of5238``max_denominator``.52395240OUTPUT:52415242- point on the curve: the rational point which is the5243image of `z` under the Weierstrass parametrization, if it5244exists and can be determined from `z` and the given value5245of max_denominator (if any); otherwise a ValueError exception5246is raised.52475248EXAMPLES::52495250sage: E = EllipticCurve('389a')5251sage: P = E(-1,1)5252sage: z = P.elliptic_logarithm()5253sage: E.antilogarithm(z)5254(-1 : 1 : 1)5255sage: Q = E(0,-1)5256sage: z = Q.elliptic_logarithm()5257sage: E.antilogarithm(z)5258Traceback (most recent call last):5259...5260ValueError: approximated point not on the curve5261sage: E.antilogarithm(z, max_denominator=10)5262(0 : -1 : 1)52635264sage: E = EllipticCurve('11a1')5265sage: w1,w2 = E.period_lattice().basis()5266sage: [E.antilogarithm(a*w1/5,1) for a in range(5)]5267[(0 : 1 : 0), (16 : -61 : 1), (5 : -6 : 1), (5 : 5 : 1), (16 : 60 : 1)]5268"""5269if z.is_zero():5270return self(0)5271expZ = self.elliptic_exponential(z)5272xy = [t.real() for t in expZ[:2]]5273if max_denominator is None:5274xy = [t.simplest_rational() for t in xy]5275else:5276xy = [t.nearby_rational(max_denominator=max_denominator) for t in xy]5277try:5278return self(xy)5279except TypeError:5280raise ValueError, "approximated point not on the curve"52815282def integral_x_coords_in_interval(self,xmin,xmax):5283r"""5284Returns the set of integers `x` with `xmin\le x\le xmax` which are5285`x`-coordinates of rational points on this curve.52865287INPUT:52885289- ``xmin``, ``xmax`` (integers) -- two integers.52905291OUTPUT:52925293(set) The set of integers `x` with `xmin\le x\le xmax` which5294are `x`-coordinates of rational points on the elliptic curve.52955296EXAMPLES::52975298sage: E = EllipticCurve([0, 0, 1, -7, 6])5299sage: xset = E.integral_x_coords_in_interval(-100,100)5300sage: xlist = list(xset); xlist.sort(); xlist5301[-3, -2, -1, 0, 1, 2, 3, 4, 8, 11, 14, 21, 37, 52, 93]5302"""5303from sage.libs.ratpoints import ratpoints5304xmin=Integer(xmin)5305xmax=Integer(xmax)5306coeffs = self.division_polynomial(2).coeffs()5307H = max(xmin.abs(), xmax.abs())5308return set([x for x,y,z in ratpoints(coeffs, H, max_x_denom=1, intervals=[[xmin,xmax]]) if z])53095310prove_BSD = BSD.prove_BSD53115312def integral_points(self, mw_base='auto', both_signs=False, verbose=False):5313"""5314Computes all integral points (up to sign) on this elliptic curve.53155316INPUT:531753185319- ``mw_base`` - list of EllipticCurvePoint generating5320the Mordell-Weil group of E (default: 'auto' - calls self.gens())53215322- ``both_signs`` - True/False (default False): if5323True the output contains both P and -P, otherwise only one of each5324pair.53255326- ``verbose`` - True/False (default False): if True,5327some details of the computation are output532853295330OUTPUT: A sorted list of all the integral points on E (up to sign5331unless both_signs is True)53325333.. note::53345335The complexity increases exponentially in the rank of curve5336E. The computation time (but not the output!) depends on5337the Mordell-Weil basis. If mw_base is given but is not a5338basis for the Mordell-Weil group (modulo torsion), integral5339points which are not in the subgroup generated by the given5340points will almost certainly not be listed.53415342EXAMPLES: A curve of rank 3 with no torsion points53435344::53455346sage: E=EllipticCurve([0,0,1,-7,6])5347sage: P1=E.point((2,0)); P2=E.point((-1,3)); P3=E.point((4,6))5348sage: a=E.integral_points([P1,P2,P3]); a5349[(-3 : 0 : 1), (-2 : 3 : 1), (-1 : 3 : 1), (0 : 2 : 1), (1 : 0 : 1), (2 : 0 : 1), (3 : 3 : 1), (4 : 6 : 1), (8 : 21 : 1), (11 : 35 : 1), (14 : 51 : 1), (21 : 95 : 1), (37 : 224 : 1), (52 : 374 : 1), (93 : 896 : 1), (342 : 6324 : 1), (406 : 8180 : 1), (816 : 23309 : 1)]53505351::53525353sage: a = E.integral_points([P1,P2,P3], verbose=True)5354Using mw_basis [(2 : 0 : 1), (3 : -4 : 1), (8 : -22 : 1)]5355e1,e2,e3: -3.0124303725933... 1.0658205476962... 1.946609824897105356Minimal eigenvalue of height pairing matrix: 0.63792081458500...5357x-coords of points on compact component with -3 <=x<= 15358[-3, -2, -1, 0, 1]5359x-coords of points on non-compact component with 2 <=x<= 65360[2, 3, 4]5361starting search of remaining points using coefficient bound 55362x-coords of extra integral points:5363[2, 3, 4, 8, 11, 14, 21, 37, 52, 93, 342, 406, 816]5364Total number of integral points: 1853655366It is not necessary to specify mw_base; if it is not provided,5367then the Mordell-Weil basis must be computed, which may take5368much longer.53695370::53715372sage: E=EllipticCurve([0,0,1,-7,6])5373sage: a=E.integral_points(both_signs=True); a5374[(-3 : -1 : 1), (-3 : 0 : 1), (-2 : -4 : 1), (-2 : 3 : 1), (-1 : -4 : 1), (-1 : 3 : 1), (0 : -3 : 1), (0 : 2 : 1), (1 : -1 : 1), (1 : 0 : 1), (2 : -1 : 1), (2 : 0 : 1), (3 : -4 : 1), (3 : 3 : 1), (4 : -7 : 1), (4 : 6 : 1), (8 : -22 : 1), (8 : 21 : 1), (11 : -36 : 1), (11 : 35 : 1), (14 : -52 : 1), (14 : 51 : 1), (21 : -96 : 1), (21 : 95 : 1), (37 : -225 : 1), (37 : 224 : 1), (52 : -375 : 1), (52 : 374 : 1), (93 : -897 : 1), (93 : 896 : 1), (342 : -6325 : 1), (342 : 6324 : 1), (406 : -8181 : 1), (406 : 8180 : 1), (816 : -23310 : 1), (816 : 23309 : 1)]53755376An example with negative discriminant::53775378sage: EllipticCurve('900d1').integral_points()5379[(-11 : 27 : 1), (-4 : 34 : 1), (4 : 18 : 1), (16 : 54 : 1)]53805381Another example with rank 5 and no torsion points::53825383sage: E=EllipticCurve([-879984,319138704])5384sage: P1=E.point((540,1188)); P2=E.point((576,1836))5385sage: P3=E.point((468,3132)); P4=E.point((612,3132))5386sage: P5=E.point((432,4428))5387sage: a=E.integral_points([P1,P2,P3,P4,P5]); len(a) # long time (18s on sage.math, 2011)53885453895390TESTS:53915392The bug reported on trac #4525 is now fixed::53935394sage: EllipticCurve('91b1').integral_points()5395[(-1 : 3 : 1), (1 : 0 : 1), (3 : 4 : 1)]53965397::53985399sage: [len(e.integral_points(both_signs=False)) for e in cremona_curves([11..100])] # long time (15s on sage.math, 2011)5400[2, 0, 2, 3, 2, 1, 3, 0, 2, 4, 2, 4, 3, 0, 0, 1, 2, 1, 2, 0, 2, 1, 0, 1, 3, 3, 1, 1, 4, 2, 3, 2, 0, 0, 5, 3, 2, 2, 1, 1, 1, 0, 1, 3, 0, 1, 0, 1, 1, 3, 6, 1, 2, 2, 2, 0, 0, 2, 3, 1, 2, 2, 1, 1, 0, 3, 2, 1, 0, 1, 0, 1, 3, 3, 1, 1, 5, 1, 0, 1, 1, 0, 1, 2, 0, 2, 0, 1, 1, 3, 1, 2, 2, 4, 4, 2, 1, 0, 0, 5, 1, 0, 1, 2, 0, 2, 2, 0, 0, 0, 1, 0, 3, 1, 5, 1, 2, 4, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 0, 0, 1, 0, 1, 1, 4, 1, 0, 1, 1, 0, 4, 2, 0, 1, 1, 2, 3, 1, 1, 1, 1, 6, 2, 1, 1, 0, 2, 0, 6, 2, 0, 4, 2, 2, 0, 0, 1, 2, 0, 2, 1, 0, 3, 1, 2, 1, 4, 6, 3, 2, 1, 0, 2, 2, 0, 0, 5, 4, 1, 0, 0, 1, 0, 2, 2, 0, 0, 2, 3, 1, 3, 1, 1, 0, 1, 0, 0, 1, 2, 2, 0, 2, 0, 0, 1, 2, 0, 0, 4, 1, 0, 1, 1, 0, 1, 2, 0, 1, 4, 3, 1, 2, 2, 1, 1, 1, 1, 6, 3, 3, 3, 3, 1, 1, 1, 1, 1, 0, 7, 3, 0, 1, 3, 2, 1, 0, 3, 2, 1, 0, 2, 2, 6, 0, 0, 6, 2, 2, 3, 3, 5, 5, 1, 0, 6, 1, 0, 3, 1, 1, 2, 3, 1, 2, 1, 1, 0, 1, 0, 1, 0, 5, 5, 2, 2, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1]54015402The bug reported at #4897 is now fixed::54035404sage: [P[0] for P in EllipticCurve([0,0,0,-468,2592]).integral_points()]5405[-24, -18, -14, -6, -3, 4, 6, 18, 21, 24, 36, 46, 102, 168, 186, 381, 1476, 2034, 67246]54065407.. note::54085409This function uses the algorithm given in [Co1].54105411REFERENCES:54125413- [Co1] Cohen H., Number Theory Vol I: Tools and Diophantine5414Equations GTM 239, Springer 200754155416AUTHORS:54175418- Michael Mardaus (2008-07)54195420- Tobias Nagel (2008-07)54215422- John Cremona (2008-07)5423"""5424#####################################################################5425# INPUT CHECK #######################################################5426if not self.is_integral():5427raise ValueError, "integral_points() can only be called on an integral model"54285429if mw_base=='auto':5430mw_base = self.gens()5431r = len(mw_base)5432else:5433try:5434r = len(mw_base)5435except TypeError:5436raise TypeError, 'mw_base must be a list'5437if not all([P.curve() is self for P in mw_base]):5438raise ValueError, "points are not on the correct curve"54395440tors_points = self.torsion_points()54415442# END INPUT-CHECK####################################################5443#####################################################################54445445#####################################################################5446# INTERNAL FUNCTIONS ################################################54475448############################## begin ################################5449def point_preprocessing(free,tor):5450r"""5451Transforms the mw_basis ``free`` into a `\ZZ`-basis for5452`E(\QQ)\cap E^0(`\RR)`. If there is a torsion point on the5453"egg" we add it to any of the gens on the egg; otherwise5454we replace the free generators with generators of a5455subgroup of index 2.5456"""5457r = len(free)5458newfree = [Q for Q in free] # copy5459tor_egg = [T for T in tor if not T.is_on_identity_component()]5460free_id = [P.is_on_identity_component() for P in free]5461if any(tor_egg):5462T = tor_egg[0]5463for i in range(r):5464if not free_id[i]:5465newfree[i] += T5466else:5467if not all(free_id):5468i0 = free_id.index(False)5469P = free[i0]5470for i in range(r):5471if not free_id[i]:5472if i==i0:5473newfree[i] = 2*newfree[i]5474else:5475newfree[i] += P5476return newfree5477############################## end ################################54785479# END Internal functions #############################################5480######################################################################54815482if (r == 0):5483int_points = [P for P in tors_points if not P.is_zero()]5484int_points = [P for P in int_points if P[0].is_integral()]5485if not both_signs:5486xlist = set([P[0] for P in int_points])5487int_points = [self.lift_x(x) for x in xlist]5488int_points.sort()5489if verbose:5490print 'Total number of integral points:',len(int_points)5491return int_points54925493if verbose:5494import sys # so we can flush stdout for debugging54955496g2 = self.c4()/125497g3 = self.c6()/2165498disc = self.discriminant()5499j = self.j_invariant()5500b2 = self.b2()55015502Qx = rings.PolynomialRing(RationalField(),'x')5503pol = Qx([-self.c6()/216,-self.c4()/12,0,4])5504if disc > 0: # two real component -> 3 roots in RR5505#on curve 897e4, only one root is found with default precision!5506RR = R5507prec = RR.precision()5508ei = pol.roots(RR,multiplicities=False)5509while len(ei)<3:5510prec*=25511RR=RealField(prec)5512ei = pol.roots(RR,multiplicities=False)5513e1,e2,e3 = ei5514if r >= 1: #preprocessing of mw_base only necessary if rank > 05515mw_base = point_preprocessing(mw_base, tors_points)5516#at most one point in E^{egg}55175518elif disc < 0: # one real component => 1 root in RR (=: e3),5519# 2 roots in C (e1,e2)5520roots = pol.roots(C,multiplicities=False)5521e3 = pol.roots(R,multiplicities=False)[0]5522roots.remove(e3)5523e1,e2 = roots55245525from sage.all import pi5526e = R(1).exp()5527pi = R(pi)55285529M = self.height_pairing_matrix(mw_base)5530mw_base, U = self.lll_reduce(mw_base,M)5531M = U.transpose()*M*U55325533if verbose:5534print "Using mw_basis ",mw_base5535print "e1,e2,e3: ",e1,e2,e35536sys.stdout.flush()55375538# Algorithm presented in [Co1]5539h_E = self.height()5540w1, w2 = self.period_lattice().basis()5541mu = R(disc).abs().log() / 65542if j!=0:5543mu += max(R(1),R(j).abs().log()) / 65544if b2!=0:5545mu += max(R(1),R(b2).abs().log())5546mu += log(R(2))5547else:5548mu += 155495550c1 = (mu + 2.14).exp()5551c2 = min(M.charpoly ().roots(multiplicities=False))5552if verbose:5553print "Minimal eigenvalue of height pairing matrix: ", c25554sys.stdout.flush()55555556c3 = (w1**2)*R(b2).abs()/48 + 85557c5 = (c1*c3).sqrt()5558c7 = abs((3*pi)/((w1**2) * (w1/w2).imag()))55595560mw_base_log = [] #contains \Phi(Q_i)5561mod_h_list = [] #contains h_m(Q_i)5562c9_help_list = []5563for i in range(0,r):5564mw_base_log.append(mw_base[i].elliptic_logarithm().abs())5565mod_h_list.append(max(mw_base[i].height(),h_E,c7*mw_base_log[i]**2))5566c9_help_list.append((mod_h_list[i]).sqrt()/mw_base_log[i])5567c8 = max(e*h_E,max(mod_h_list))5568c9 = e/c7.sqrt() * min(c9_help_list)5569n=r+15570c10 = R(2 * 10**(8+7*n) * R((2/e)**(2 * n**2)) * (n+1)**(4 * n**2 + 10 * n) * log(c9)**(-2*n - 1) * misc.prod(mod_h_list))55715572top = Z(128) #arbitrary first upper bound5573bottom = Z(0)5574log_c9=log(c9); log_c5=log(c5)5575log_r_top = log(R(r*(10**top)))5576# if verbose:5577# print "[bottom,top] = ",[bottom,top]55785579while R(c10*(log_r_top+log_c9)*(log(log_r_top)+h_E+log_c9)**(n+1)) > R(c2/2 * (10**top)**2 - log_c5):5580#initial bound 'top' too small, upshift of search interval5581bottom = top5582top = 2*top5583while top >= bottom: #binary-search like search for fitting exponent (bound)5584# if verbose:5585# print "[bottom,top] = ",[bottom,top]5586bound = (bottom + (top - bottom)/2).floor()5587log_r_bound = log(R(r*(10**bound)))5588if R(c10*(log_r_bound+log_c9)*(log(log_r_bound)+h_E+log_c9)**(n+1)) > R(c2/2 * (10**bound)**2 - log_c5):5589bottom = bound + 15590else:5591top = bound - 155925593H_q = R(10)**bound5594break_cond = 0 #at least one reduction step5595#reduction via LLL5596M = matrix.MatrixSpace(Z,n)5597while break_cond < 0.9: #as long as the improvement of the new bound in comparison to the old is greater than 10%5598c = R((H_q**n)*10) #c has to be greater than H_q^n5599m = copy(M.identity_matrix())5600for i in range(r):5601m[i, r] = R(c*mw_base_log[i]).round()5602m[r,r] = max(Z(1),R(c*w1).round()) #ensures that m isn't singular56035604#LLL - implemented in sage - operates on rows not on columns5605m_LLL = m.LLL()5606m_gram = m_LLL.gram_schmidt()[0]5607b1_norm = R(m_LLL.row(0).norm())56085609#compute constant c1 ~ c1_LLL of Corollary 2.3.17 and hence d(L,0)^2 ~ d_L_05610c1_LLL = -15611for i in range(n):5612tmp = R(b1_norm/(m_gram.row(i).norm()))5613if tmp > c1_LLL:5614c1_LLL = tmp56155616if c1_LLL < 0:5617raise RuntimeError, 'Unexpected intermediate result. Please try another Mordell-Weil base'56185619d_L_0 = R(b1_norm**2 / c1_LLL)56205621#Reducing of upper bound5622Q = r * H_q**25623T = (1 + (3/2*r*H_q))/25624if d_L_0 < R(T**2+Q):5625d_L_0 = 10*(T**2*Q)5626low_bound = R(((d_L_0 - Q).sqrt() - T)/c)56275628#new bound according to low_bound and upper bound5629#[c_5 exp((-c_2*H_q^2)/2)] provided by Corollary 8.7.35630if low_bound != 0:5631H_q_new = R((log(low_bound/c5)/(-c2/2))).sqrt()5632H_q_new = H_q_new.ceil()5633if H_q_new == 1:5634break_cond = 1 # stops reduction5635else:5636break_cond = R(H_q_new/H_q)5637H_q = H_q_new5638else:5639break_cond = 1 # stops reduction, so using last H_q > 05640#END LLL-Reduction loop56415642b2_12 = b2/125643if disc > 0:5644##Points in egg have X(P) between e1 and e2 [X(P)=x(P)+b2/12]:5645x_int_points = self.integral_x_coords_in_interval((e1-b2_12).ceil(), (e2-b2_12).floor())5646if verbose:5647print 'x-coords of points on compact component with ',(e1-b2_12).ceil(),'<=x<=',(e2-b2_12).floor()5648L = list(x_int_points) # to have the order5649L.sort() # deterministic for doctests!5650print L5651sys.stdout.flush()5652else:5653x_int_points = set()56545655##Points in noncompact component with X(P)< 2*max(|e1|,|e2|,|e3|) , espec. X(P)>=e35656x0 = (e3-b2_12).ceil()5657x1 = (2*max(abs(e1),abs(e2),abs(e3)) - b2_12).ceil()5658x_int_points2 = self.integral_x_coords_in_interval(x0, x1)5659x_int_points = x_int_points.union(x_int_points2)5660if verbose:5661print 'x-coords of points on non-compact component with ',x0,'<=x<=',x1-15662L = list(x_int_points2)5663L.sort()5664print L5665sys.stdout.flush()56665667if verbose:5668print 'starting search of remaining points using coefficient bound ',H_q5669sys.stdout.flush()5670x_int_points3 = integral_points_with_bounded_mw_coeffs(self,mw_base,H_q)5671x_int_points = x_int_points.union(x_int_points3)5672if verbose:5673print 'x-coords of extra integral points:'5674L = list(x_int_points3)5675L.sort()5676print L5677sys.stdout.flush()56785679if len(tors_points)>1:5680x_int_points_t = set()5681for x in x_int_points:5682P = self.lift_x(x)5683for T in tors_points:5684Q = P+T5685if not Q.is_zero() and Q[0].is_integral():5686x_int_points_t = x_int_points_t.union([Q[0]])5687x_int_points = x_int_points.union(x_int_points_t)56885689# Now we have all the x-coordinates of integral points, and we5690# construct the points, depending on the parameter both_signs:5691if both_signs:5692int_points = sum([self.lift_x(x,all=True) for x in x_int_points],[])5693else:5694int_points = [self.lift_x(x) for x in x_int_points]5695int_points.sort()5696if verbose:5697print 'Total number of integral points:',len(int_points)5698return int_points56995700def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, proof=None):5701"""5702Computes all S-integral points (up to sign) on this elliptic curve.57035704INPUT:57055706- ``S`` - list of primes57075708- ``mw_base`` - list of EllipticCurvePoint generating the5709Mordell-Weil group of E (default: 'auto' - calls5710:meth:`.gens`)57115712- ``both_signs`` - True/False (default False): if True the5713output contains both P and -P, otherwise only one of each5714pair.57155716- ``verbose`` - True/False (default False): if True, some5717details of the computation are output.57185719- ``proof`` - True/False (default True): if True ALL5720S-integral points will be returned. If False, the MW basis5721will be computed with the proof=False flag, and also the5722time-consuming final call to5723S_integral_x_coords_with_abs_bounded_by(abs_bound) is5724omitted. Use this only if the computation takes too long,5725but be warned that then it cannot be guaranteed that all5726S-integral points will be found.57275728OUTPUT:57295730A sorted list of all the S-integral points on E (up to sign5731unless both_signs is True)57325733.. note::57345735The complexity increases exponentially in the rank of curve5736E and in the length of S. The computation time (but not5737the output!) depends on the Mordell-Weil basis. If mw_base5738is given but is not a basis for the Mordell-Weil group5739(modulo torsion), S-integral points which are not in the5740subgroup generated by the given points will almost5741certainly not be listed.57425743EXAMPLES:57445745A curve of rank 3 with no torsion points::57465747sage: E=EllipticCurve([0,0,1,-7,6])5748sage: P1=E.point((2,0)); P2=E.point((-1,3)); P3=E.point((4,6))5749sage: a=E.S_integral_points(S=[2,3], mw_base=[P1,P2,P3], verbose=True);a5750max_S: 3 len_S: 3 len_tors: 15751lambda 0.485997517468...5752k1,k2,k3,k4 6.68597129142710e234 1.31952866480763 3.31908110593519e9 2.42767548272846e175753p= 2 : trying with p_prec = 305754mw_base_p_log_val = [2, 2, 1]5755min_psi = 2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^11 + 2^12 + 2^13 + 2^16 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^24 + 2^28 + O(2^30)5756p= 3 : trying with p_prec = 305757mw_base_p_log_val = [1, 2, 1]5758min_psi = 3 + 3^2 + 2*3^3 + 3^6 + 2*3^7 + 2*3^8 + 3^9 + 2*3^11 + 2*3^12 + 2*3^13 + 3^15 + 2*3^16 + 3^18 + 2*3^19 + 2*3^22 + 2*3^23 + 2*3^24 + 2*3^27 + 3^28 + 3^29 + O(3^30)5759mw_base [(1 : -1 : 1), (2 : 0 : 1), (0 : -3 : 1)]5760mw_base_log [0.667789378224099, 0.552642660712417, 0.818477222895703]5761mp [5, 7]5762mw_base_p_log [[2^2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^14 + 2^15 + 2^18 + 2^19 + 2^24 + 2^29 + O(2^30), 2^2 + 2^3 + 2^5 + 2^6 + 2^9 + 2^11 + 2^12 + 2^14 + 2^15 + 2^16 + 2^18 + 2^20 + 2^22 + 2^23 + 2^26 + 2^27 + 2^29 + O(2^30), 2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^11 + 2^12 + 2^13 + 2^16 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^24 + 2^28 + O(2^30)], [2*3^2 + 2*3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 3^12 + 2*3^14 + 3^15 + 3^17 + 2*3^19 + 2*3^23 + 3^25 + 3^28 + O(3^30), 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 2*3^7 + 2*3^8 + 3^10 + 2*3^12 + 3^13 + 2*3^14 + 3^15 + 3^18 + 3^22 + 3^25 + 2*3^26 + 3^27 + 3^28 + O(3^30), 3 + 3^2 + 2*3^3 + 3^6 + 2*3^7 + 2*3^8 + 3^9 + 2*3^11 + 2*3^12 + 2*3^13 + 3^15 + 2*3^16 + 3^18 + 2*3^19 + 2*3^22 + 2*3^23 + 2*3^24 + 2*3^27 + 3^28 + 3^29 + O(3^30)]]5763k5,k6,k7 0.321154513240... 1.55246328915... 0.161999172489...5764initial bound 2.6227097483365...e1175765bound_list [58, 58, 58]5766bound_list [8, 9, 9]5767bound_list [8, 7, 7]5768bound_list [8, 7, 7]5769starting search of points using coefficient bound 85770x-coords of S-integral points via linear combination of mw_base and torsion:5771[-3, -26/9, -8159/2916, -2759/1024, -151/64, -1343/576, -2, -7/4, -1, -47/256, 0, 1/4, 4/9, 9/16, 58/81, 7/9, 6169/6561, 1, 17/16, 2, 33/16, 172/81, 9/4, 25/9, 3, 31/9, 4, 25/4, 1793/256, 8, 625/64, 11, 14, 21, 37, 52, 6142/81, 93, 4537/36, 342, 406, 816, 207331217/4096]5772starting search of extra S-integer points with absolute value bounded by 3.893219649794205773x-coords of points with bounded absolute value5774[-3, -2, -1, 0, 1, 2]5775Total number of S-integral points: 435776[(-3 : 0 : 1), (-26/9 : 28/27 : 1), (-8159/2916 : 233461/157464 : 1), (-2759/1024 : 60819/32768 : 1), (-151/64 : 1333/512 : 1), (-1343/576 : 36575/13824 : 1), (-2 : 3 : 1), (-7/4 : 25/8 : 1), (-1 : 3 : 1), (-47/256 : 9191/4096 : 1), (0 : 2 : 1), (1/4 : 13/8 : 1), (4/9 : 35/27 : 1), (9/16 : 69/64 : 1), (58/81 : 559/729 : 1), (7/9 : 17/27 : 1), (6169/6561 : 109871/531441 : 1), (1 : 0 : 1), (17/16 : -25/64 : 1), (2 : 0 : 1), (33/16 : 17/64 : 1), (172/81 : 350/729 : 1), (9/4 : 7/8 : 1), (25/9 : 64/27 : 1), (3 : 3 : 1), (31/9 : 116/27 : 1), (4 : 6 : 1), (25/4 : 111/8 : 1), (1793/256 : 68991/4096 : 1), (8 : 21 : 1), (625/64 : 14839/512 : 1), (11 : 35 : 1), (14 : 51 : 1), (21 : 95 : 1), (37 : 224 : 1), (52 : 374 : 1), (6142/81 : 480700/729 : 1), (93 : 896 : 1), (4537/36 : 305425/216 : 1), (342 : 6324 : 1), (406 : 8180 : 1), (816 : 23309 : 1), (207331217/4096 : 2985362173625/262144 : 1)]57775778It is not necessary to specify mw_base; if it is not provided,5779then the Mordell-Weil basis must be computed, which may take5780much longer.57815782::57835784sage: a = E.S_integral_points([2,3])5785sage: len(a)57864357875788An example with negative discriminant::57895790sage: EllipticCurve('900d1').S_integral_points([17], both_signs=True)5791[(-11 : -27 : 1), (-11 : 27 : 1), (-4 : -34 : 1), (-4 : 34 : 1), (4 : -18 : 1), (4 : 18 : 1), (2636/289 : -98786/4913 : 1), (2636/289 : 98786/4913 : 1), (16 : -54 : 1), (16 : 54 : 1)]57925793Output checked with Magma (corrected in 3 cases)::57945795sage: [len(e.S_integral_points([2], both_signs=False)) for e in cremona_curves([11..100])] # long time (17s on sage.math, 2011)5796[2, 0, 2, 3, 3, 1, 3, 1, 3, 5, 3, 5, 4, 1, 1, 2, 2, 2, 3, 1, 2, 1, 0, 1, 3, 3, 1, 1, 5, 3, 4, 2, 1, 1, 5, 3, 2, 2, 1, 1, 1, 0, 1, 3, 0, 1, 0, 1, 1, 3, 7, 1, 3, 3, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 1, 3, 3, 1, 1, 1, 0, 1, 3, 3, 1, 1, 7, 1, 0, 1, 1, 0, 1, 2, 0, 3, 1, 2, 1, 3, 1, 2, 2, 4, 5, 3, 2, 1, 1, 6, 1, 0, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 3, 1, 5, 1, 2, 4, 1, 1, 1, 1, 1, 0, 1, 0, 2, 2, 0, 0, 1, 0, 1, 1, 6, 1, 0, 1, 1, 0, 4, 3, 1, 2, 1, 2, 3, 1, 1, 1, 1, 8, 3, 1, 2, 1, 2, 0, 8, 2, 0, 6, 2, 3, 1, 1, 1, 3, 1, 3, 2, 1, 3, 1, 2, 1, 6, 9, 3, 3, 1, 1, 2, 3, 1, 1, 5, 5, 1, 1, 0, 1, 1, 2, 3, 1, 1, 2, 3, 1, 3, 1, 1, 1, 1, 0, 0, 1, 3, 3, 1, 3, 1, 1, 2, 2, 0, 0, 6, 1, 0, 1, 1, 1, 1, 3, 1, 2, 6, 3, 1, 2, 2, 1, 1, 1, 1, 7, 5, 4, 3, 3, 1, 1, 1, 1, 1, 1, 8, 5, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 2, 3, 6, 1, 1, 7, 3, 3, 4, 5, 9, 6, 1, 0, 7, 1, 1, 3, 1, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 7, 8, 2, 3, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1]57975798An example from [PZGH]::57995800sage: E = EllipticCurve([0,0,0,-172,505])5801sage: E.rank(), len(E.S_integral_points([3,5,7])) # long time (5s on sage.math, 2011)5802(4, 72)58035804This is curve "7690e1" which failed until \#4805 was fixed::58055806sage: EllipticCurve([1,1,1,-301,-1821]).S_integral_points([13,2])5807[(-13 : 16 : 1),5808(-9 : 20 : 1),5809(-7 : 4 : 1),5810(21 : 30 : 1),5811(23 : 52 : 1),5812(63 : 452 : 1),5813(71 : 548 : 1),5814(87 : 756 : 1),5815(2711 : 139828 : 1),5816(7323 : 623052 : 1),5817(17687 : 2343476 : 1)]58185819REFERENCES:58205821- [PZGH] Petho A., Zimmer H.G., Gebel J. and Herrmann E.,5822Computing all S-integral points on elliptic curves5823Math. Proc. Camb. Phil. Soc. (1999), 127, 383-40258245825- Some parts of this implementation are partially based on the5826function integral_points()58275828AUTHORS:58295830- Tobias Nagel (2008-12)58315832- Michael Mardaus (2008-12)58335834- John Cremona (2008-12)5835"""5836# INPUT CHECK #######################################################58375838if proof is None:5839from sage.structure.proof.proof import get_flag5840proof = get_flag(proof, "elliptic_curve")5841else:5842proof = bool(proof)584358445845if not self.is_integral():5846raise ValueError, "S_integral_points() can only be called on an integral model"5847if not all([self.is_p_minimal(s) for s in S]):5848raise ValueError, "%s must be p-minimal for all primes in S"%self58495850try:5851len_S = len(S)5852if len_S == 0:5853return self.integral_points(mw_base, both_signs, verbose)5854if not all([s.is_prime() for s in S]):5855raise ValueError, "All elements of S must be prime"5856S.sort()5857except TypeError:5858raise TypeError, 'S must be a list of primes'5859except AttributeError:#catches: <tuple>.sort(), <!ZZ>.is_prime()5860raise AttributeError,'S must be a list of primes'58615862if mw_base=='auto':5863if verbose:5864print "Starting computation of MW basis"5865mw_base = self.gens(proof=proof)5866r = len(mw_base)5867if verbose:5868print "Finished computation of MW basis; rank is ",r5869else:5870try:5871r = len(mw_base)5872except TypeError:5873raise TypeError, 'mw_base must be a list'5874if not all([P.curve() is self for P in mw_base]):5875raise ValueError, "mw_base-points are not on the correct curve"58765877#End Input-Check ######################################################58785879#Internal functions ###################################################5880def reduction_at(p):5881r"""5882Reducing the bound `H_q` at the finite place p in S via LLL5883"""5884indexp = S.index(p)5885pc = Z(p**(R(c.log()/log(p,e)).ceil()))5886m = copy(M.identity_matrix())5887for i in range(r):5888try:5889m[i, r] = Z((beta[indexp][i])%pc)5890except ZeroDivisionError: #If Inverse doesn't exist, change denominator (which is only approx)5891val_nu = (beta[indexp][i]).numerator()5892val_de = (beta[indexp][i]).denominator()5893m[i, r] = Z((val_nu/(val_de+1))%pc)5894m[r,r] = max(Z(1), pc)58955896#LLL - implemented in sage - operates on rows not on columns5897m_LLL = m.LLL()5898m_gram = m_LLL.gram_schmidt()[0]5899b1_norm = R(m_LLL.row(0).norm())59005901c1_LLL = -15902for i in range(n):5903tmp = R(b1_norm/(m_gram.row(i).norm()))5904if tmp > c1_LLL:5905c1_LLL = tmp5906if c1_LLL < 0:5907raise RuntimeError, 'Unexpected intermediate result. Please try another Mordell-Weil base'5908d_L_0 = R(b1_norm**2 / c1_LLL)59095910#Reducing of upper bound5911Q = r * H_q**25912T = (1 + (3/2*r*H_q))/25913if d_L_0 < R(T**2+Q):5914d_L_0 = 10*(T**2*Q)5915low_bound = R(((d_L_0 - Q).sqrt() - T)/c)59165917##new bound according to low_bound and upper bound5918##[k5*k6 exp(-k7**H_q^2)]5919if low_bound != 0:5920H_q_infinity = R(((low_bound/(k6)).log()/(-k7)).sqrt())5921return (H_q_infinity.ceil())5922else:5923return (H_q)5924#<-------------------------------------------------------------------------5925#>-------------------------------------------------------------------------5926def S_integral_points_with_bounded_mw_coeffs():5927r"""5928Returns the set of S-integers x which are x-coordinates of5929points on the curve which are linear combinations of the5930generators (basis and torsion points) with coefficients5931bounded by `H_q`. The bound `H_q` will be computed at5932runtime.5933(Modified version of integral_points_with_bounded_mw_coeffs() in5934integral_points() )59355936TODO: Make this more efficient. In the case ``S=[]`` we5937worked over the reals and only computed a combination5938exactly if the real coordinates were approximately5939integral. We need a version of this which works for5940S-integral points, probably by finding a bound on the5941denominator.5942"""5943from sage.groups.generic import multiples5944xs=set()5945N=H_q59465947def test(P):5948"""5949Record x-coord of a point if S-integral.5950"""5951if not P.is_zero():5952xP = P[0]5953if xP.is_S_integral(S):5954xs.add(xP)59555956def test_with_T(R):5957"""5958Record x-coords of a 'point+torsion' if S-integral.5959"""5960for T in tors_points:5961test(R+T)59625963# For small rank and small H_q perform simple search5964if r==1 and N<=10:5965for P in multiples(mw_base[0],N+1):5966test_with_T(P)5967return xs59685969# explicit computation and testing linear combinations5970# ni loops through all tuples (n_1,...,n_r) with |n_i| <= N5971# stops when (0,0,...,0) is reached because after that, only inverse points of5972# previously tested points would be tested59735974E0=E(0)5975ni = [-N for i in range(r)]5976mw_baseN = [-N*P for P in mw_base]5977Pi = [0 for j in range(r)]5978Pi[0] = mw_baseN[0]5979for i in range(1,r):5980Pi[i] = Pi[i-1] + mw_baseN[i]59815982while True:5983if all([n==0 for n in ni]):5984test_with_T(E0)5985break59865987# test the ni-combination which is Pi[r-1]5988test_with_T(Pi[r-1])59895990# increment indices and stored points5991i0 = r-15992while ni[i0]==N:5993ni[i0] = -N5994i0 -= 15995ni[i0] += 15996if all([n==0 for n in ni[0:i0+1]]):5997Pi[i0] = E05998else:5999Pi[i0] += mw_base[i0]6000for i in range(i0+1,r):6001Pi[i] = Pi[i-1] + mw_baseN[i]60026003return xs6004#<-------------------------------------------------------------------------6005#>-------------------------------------------------------------------------6006def S_integral_x_coords_with_abs_bounded_by(abs_bound):6007r"""6008Extra search of points with `|x|< ` abs_bound, assuming6009that `x` is `S`-integral and `|x|\ge|x|_q` for all primes6010`q` in `S`. (Such points are not covered by the main part6011of the code). We know60126013.. math::60146015x=\frac{\xi}{\p_1^{\alpha_1} \cdot \dots \cdot \p_s^{\alpha_s}},\ (gcd(\xi,\p_i)=1),\ p_i \in S60166017so a bound of `\alpha_i` can be found in terms of6018abs_bound. Additionally each `\alpha` must be even, giving6019another restriction. This gives a finite list of6020denominators to test, and for each, a range of numerators.6021All candidates for `x` resulting from this theory are then6022tested, and a list of the ones which are `x`-coordinates6023of (`S`-integral) points is returned.60246025TODO: Make this more efficient. If we had an efficient6026function for searching for integral points (for example,6027by wrapping Stoll's ratpoint program) then it should be6028better to scale the equation by the maximum denominator6029and search for integral points on the scaled model.60306031"""6032x_min = min(self.two_division_polynomial().roots(R,multiplicities=False))6033x_min_neg = bool(x_min<0)6034x_min_pos = not x_min_neg6035log_ab = R(abs_bound.log())6036alpha = [(log_ab/R(log(p,e))).floor() for p in S]6037if all([alpha_i <= 1 for alpha_i in alpha]): # so alpha_i must be 0 to satisfy that denominator is a square6038return set([x for x in range(-abs_bound,abs_bound) if E.is_x_coord(x)])6039else:6040xs = []6041alpha_max_even = [y-y%2 for y in alpha]6042p_pow_alpha = []6043list_alpha = []6044for i in range(len_S-1):6045list_alpha.append(range(0,alpha_max_even[i]+2,2))6046p_pow_alpha.append([S[i]**list_alpha[i][j] for j in range(len(list_alpha[i]))])6047if verbose:6048print list_alpha, p_pow_alpha6049# denom_maxpa is a list of pairs (d,q) where d runs6050# through possible denominators, and q=p^a is the6051# maximum prime power divisor of d:6052denom_maxpa = [(misc.prod(tmp),max(tmp)) for tmp in cartesian_product_iterator(p_pow_alpha)]6053# The maximum denominator is this (not used):6054# denom = [misc.prod([pp[-1] for pp in p_pow_alpha],1)]6055for de,maxpa in denom_maxpa:6056n_max = (abs_bound*de).ceil()6057n_min = maxpa*de6058if x_min_pos:6059pos_n_only = True6060if x_min > maxpa:6061n_min = (x_min*de).floor()6062else:6063pos_n_only = False6064neg_n_max = (x_min.abs()*de).ceil()60656066# if verbose:6067# print "testing denominator ",de6068# print "numerator bounds = ",(n_min,n_max)60696070for n in misc.xsrange(n_min,n_max+1):6071tmp = n/de # to save time, do not check de is the exact denominator6072if E.is_x_coord(tmp):6073xs+=[tmp]6074if not pos_n_only:6075if n <= neg_n_max:6076if E.is_x_coord(-tmp):6077xs+=[-tmp]60786079return set(xs)6080#<-------------------------------------------------------------------------6081#End internal functions ###############################################6082from sage.misc.all import cartesian_product_iterator60836084E = self6085tors_points = E.torsion_points()60866087if (r==0):#only Torsionpoints to consider6088int_points = [P for P in tors_points if not P.is_zero()]6089int_points = [P for P in int_points if P[0].is_S_integral(S)]6090if not both_signs:6091xlist = set([P[0] for P in int_points])6092int_points = [E.lift_x(x) for x in xlist]6093int_points.sort()6094if verbose:6095print 'Total number of S-integral points:',len(int_points)6096return int_points60976098if verbose:6099import sys # so we can flush stdout for debugging61006101e = R(1).exp()6102a1, a2, a3, a4, a6 = E.a_invariants()6103b2, b4, b6, b8 = E.b_invariants()6104c4, c6 = E.c_invariants()6105disc = E.discriminant()6106#internal function is doing only a comparison of E and E.short_weierstass_model() so the following is easier6107if a1 == a2 == a3 == 0:6108is_short = True6109else:6110is_short = False61116112w1, w2 = E.period_lattice().basis()61136114Qx = rings.PolynomialRing(RationalField(),'x')6115pol = Qx([-54*c6,-27*c4,0,1])6116if disc > 0: # two real component -> 3 roots in RR6117# it is possible that only one root is found with default precision! (see integral_points())6118RR = R6119prec = RR.precision()6120ei = pol.roots(RR,multiplicities=False)6121while len(ei)<3:6122prec*=26123RR=RealField(prec)6124ei = pol.roots(RR,multiplicities=False)6125e1,e2,e3 = ei6126elif disc < 0: # one real component => 1 root in RR (=: e3),6127# 2 roots in C (e1,e2)6128roots = pol.roots(C,multiplicities=False)6129e3 = pol.roots(R,multiplicities=False)[0]6130roots.remove(e3)6131e1,e2 = roots61326133len_tors = len(tors_points)6134n = r + 161356136M = E.height_pairing_matrix(mw_base)6137mw_base, U = E.lll_reduce(mw_base,M)6138M = U.transpose()*M*U61396140# NB "lambda" is a reserved word in Python!6141lamda = min(M.charpoly(algorithm="hessenberg").roots(multiplicities = False))6142max_S = max(S)6143len_S += 1 #Counting infinity (always "included" in S)6144if verbose:6145print 'max_S:',max_S,'len_S:',len_S,'len_tors:',len_tors6146print 'lambda',lamda6147sys.stdout.flush()61486149if is_short:6150disc_0_abs = R((4*a4**3 + 27*a6**2).abs())6151k4 = R(10**4 * max(16*a4**2, 256*disc_0_abs.sqrt()**3))6152k3 = R(32/3 * disc_0_abs.sqrt() * (8 + 0.5*disc_0_abs.log())**4)6153else:6154disc_sh = R(E.short_weierstrass_model().discriminant()) #computes y^2=x^3 -27c4x -54c66155k4 = R(20**4 * max(3**6 * c4**2, 16*(disc_sh.abs().sqrt())**3))6156k3 = R(32/3 * disc_sh.abs().sqrt() * (8 + 0.5*disc_sh.abs().log())**4)615761586159k2 = max(R(b2.abs()), R(b4.abs().sqrt()), R(b6.abs()**(1/3)), R(b8.abs()**(1/4))).log()6160k1 = R(7 * 10**(38*len_S+49)) * R(len_S**(20*len_S+15)) * max_S**24 * R(max(1,log(max_S, e))**(4*len_S - 2)) * k3 * k3.log()**2 * ((20*len_S - 19)*k3 + (e*k4).log()) + 2*R(2*b2.abs()+6).log()61616162if verbose:6163print 'k1,k2,k3,k4',k1,k2,k3,k46164sys.stdout.flush()6165#H_q -> [PZGH]:N_0 (due to consistency to integral_points())6166H_q = R(((k1/2+k2)/lamda).sqrt())61676168#computation of logs6169mw_base_log = [(pts.elliptic_logarithm().abs())*(len_tors/w1) for pts in mw_base]6170mw_base_p_log = []6171beta = []6172mp=[]6173tmp = 06174for p in S:6175Np = E.Np(p)6176cp = E.tamagawa_exponent(p)6177mp_temp = Z(len_tors).lcm(cp*Np)6178mp.append(mp_temp) #only necessary because of verbose below6179p_prec=30+E.discriminant().valuation(p)6180p_prec_ok=False6181while not p_prec_ok:6182if verbose:6183print "p=",p,": trying with p_prec = ",p_prec6184try:6185mw_base_p_log.append([mp_temp*(pts.padic_elliptic_logarithm(p,absprec=p_prec)) for pts in mw_base])6186p_prec_ok=True6187except ValueError:6188p_prec *= 26189#reorder mw_base_p: last value has minimal valuation at p6190mw_base_p_log_val = [mw_base_p_log[tmp][i].valuation() for i in range(r)]6191if verbose:6192print "mw_base_p_log_val = ",mw_base_p_log_val6193min_index = mw_base_p_log_val.index(min(mw_base_p_log_val))6194min_psi = mw_base_p_log[tmp][min_index]6195if verbose:6196print "min_psi = ",min_psi6197mw_base_p_log[tmp].remove(min_psi)6198mw_base_p_log[tmp].append(min_psi)6199#beta needed for reduction at p later on6200try:6201beta.append([-mw_base_p_log[tmp][j]/min_psi for j in range(r)])6202except ValueError:6203# e.g. mw_base_p_log[tmp]==[0]: can occur e.g. [?]'172c6, S=[2]6204beta.append([0] for j in range(r))6205tmp +=162066207if verbose:6208print 'mw_base',mw_base6209print 'mw_base_log', mw_base_log6210print 'mp', mp6211print 'mw_base_p_log',mw_base_p_log6212#print 'beta', beta6213sys.stdout.flush()62146215#constants in reduction (not needed to be computed every reduction step)6216k5 = R((2*len_tors)/(3*w1))6217k6 = R((k2/len_S).exp())6218k7 = R(lamda/len_S)62196220if verbose:6221print 'k5,k6,k7',k5,k6,k76222sys.stdout.flush()62236224break_cond = 06225M = matrix.MatrixSpace(Z,n)6226#Reduction of initial bound6227if verbose:6228print 'initial bound',H_q6229sys.stdout.flush()62306231while break_cond < 0.9:6232#reduction at infinity6233bound_list=[]6234c = R((H_q**n)*100)6235m = copy(M.identity_matrix())6236for i in range(r):6237m[i, r] = R(c*mw_base_log[i]).round()6238m[r,r] = max(Z(1), R(c*w1).round())6239#LLL - implemented in sage - operates on rows not on columns6240m_LLL = m.LLL()6241m_gram = m_LLL.gram_schmidt()[0]6242b1_norm = R(m_LLL.row(0).norm())62436244#compute constant c1_LLL (cf. integral_points())6245c1_LLL = -16246for i in range(n):6247tmp = R(b1_norm/(m_gram.row(i).norm()))6248if tmp > c1_LLL:6249c1_LLL = tmp6250if c1_LLL < 0:6251raise RuntimeError, 'Unexpected intermediate result. Please try another Mordell-Weil base'6252d_L_0 = R(b1_norm**2 / c1_LLL)62536254#Reducing of upper bound6255Q = r * H_q**26256T = (1 + (3/2*r*H_q))/26257if d_L_0 < R(T**2+Q):6258d_L_0 = 10*(T**2*Q)6259low_bound = R(((d_L_0 - Q).sqrt() - T)/c)62606261##new bound according to low_bound and upper bound6262##[k5*k6 exp(-k7**H_q^2)]6263if low_bound != 0:6264H_q_infinity = R(((low_bound/(k5*k6)).log()/(-k7)).abs().sqrt())6265bound_list.append(H_q_infinity.ceil())6266else:6267bound_list.append(H_q)62686269##reduction for finite places in S6270for p in S:6271bound_list.append(reduction_at(p))62726273if verbose:6274print 'bound_list',bound_list6275sys.stdout.flush()62766277H_q_new = max(bound_list)6278if (H_q_new > H_q): #no improvement6279break_cond = 1 #stop reduction6280elif (H_q_new == 1): #best possible H_q6281H_q = H_q_new6282break_cond = 1 #stop6283else:6284break_cond = R(H_q_new/H_q)6285H_q = H_q_new6286#end of reductions62876288#search of S-integral points6289#step1: via linear combination and H_q6290x_S_int_points = set()6291if verbose:6292print 'starting search of points using coefficient bound ',H_q6293sys.stdout.flush()6294x_S_int_points1 = S_integral_points_with_bounded_mw_coeffs()6295x_S_int_points = x_S_int_points.union(x_S_int_points1)6296if verbose:6297print 'x-coords of S-integral points via linear combination of mw_base and torsion:'6298L = list(x_S_int_points1)6299L.sort()6300print L6301sys.stdout.flush()63026303#step 2: Extra search6304if e3 < 0:6305M = R( max((27*c4).abs().sqrt(), R((54*c6).abs()**(1/3)) / R(2**(1/3))-1) )6306else:6307M = R(0)6308e0 = max(e1+e2, 2*e3) + M6309abs_bound = R((max(0,e0)+6*b2.abs())/36)63106311if proof:6312if verbose:6313print 'starting search of extra S-integer points with absolute value bounded by',abs_bound6314sys.stdout.flush()6315if abs_bound != 0:6316x_S_int_points2 = S_integral_x_coords_with_abs_bounded_by(abs_bound)6317x_S_int_points = x_S_int_points.union(x_S_int_points2)6318if verbose:6319print 'x-coords of points with bounded absolute value'6320L = list(x_S_int_points2)6321L.sort()6322print L6323sys.stdout.flush()63246325if len(tors_points)>1:6326x_S_int_points_t = set()6327for x in x_S_int_points:6328P = E.lift_x(x)6329for T in tors_points:6330Q = P+T6331if not Q.is_zero() and Q[0].is_S_integral(S):6332x_S_int_points_t = x_S_int_points_t.union([Q[0]])6333x_S_int_points = x_S_int_points.union(x_S_int_points_t)63346335# All x values collected, now considering "both_signs"6336if both_signs:6337S_int_points = sum([self.lift_x(x,all=True) for x in x_S_int_points],[])6338else:6339S_int_points = [self.lift_x(x) for x in x_S_int_points]6340S_int_points.sort()6341if verbose:6342print 'Total number of S-integral points:',len(S_int_points)6343return S_int_points634463456346def cremona_curves(conductors):6347"""6348Return iterator over all known curves (in database) with conductor6349in the list of conductors.63506351EXAMPLES::63526353sage: [(E.label(), E.rank()) for E in cremona_curves(srange(35,40))]6354[('35a1', 0),6355('35a2', 0),6356('35a3', 0),6357('36a1', 0),6358('36a2', 0),6359('36a3', 0),6360('36a4', 0),6361('37a1', 1),6362('37b1', 0),6363('37b2', 0),6364('37b3', 0),6365('38a1', 0),6366('38a2', 0),6367('38a3', 0),6368('38b1', 0),6369('38b2', 0),6370('39a1', 0),6371('39a2', 0),6372('39a3', 0),6373('39a4', 0)]6374"""6375if isinstance(conductors, (int,long, rings.RingElement)):6376conductors = [conductors]6377return sage.databases.cremona.CremonaDatabase().iter(conductors)63786379def cremona_optimal_curves(conductors):6380"""6381Return iterator over all known optimal curves (in database) with6382conductor in the list of conductors.63836384EXAMPLES::63856386sage: [(E.label(), E.rank()) for E in cremona_optimal_curves(srange(35,40))]6387[('35a1', 0),6388('36a1', 0),6389('37a1', 1),6390('37b1', 0),6391('38a1', 0),6392('38b1', 0),6393('39a1', 0)]63946395There is one case -- 990h3 -- when the optimal curve isn't labeled with a 1::63966397sage: [e.cremona_label() for e in cremona_optimal_curves([990])]6398['990a1', '990b1', '990c1', '990d1', '990e1', '990f1', '990g1', '990h3', '990i1', '990j1', '990k1', '990l1']63996400"""6401if isinstance(conductors, (int,long,rings.RingElement)):6402conductors = [conductors]6403return sage.databases.cremona.CremonaDatabase().iter_optimal(conductors)64046405def integral_points_with_bounded_mw_coeffs(E, mw_base, N):6406r"""6407Returns the set of integers `x` which are6408`x`-coordinates of points on the curve `E` which6409are linear combinations of the generators (basis and torsion6410points) with coefficients bounded by `N`.6411"""6412from sage.groups.generic import multiples6413xs=set()6414tors_points = E.torsion_points()6415r = len(mw_base)64166417def use(P):6418"""6419Helper function to record x-coord of a point if integral.6420"""6421if not P.is_zero():6422xP = P[0]6423if xP.is_integral():6424xs.add(xP)64256426def use_t(R):6427"""6428Helper function to record x-coords of a point +torsion if6429integral.6430"""6431for T in tors_points:6432use(R+T)64336434# We use a naive method when the number of possibilities is small:64356436if r==1 and N<=10:6437for P in multiples(mw_base[0],N+1):6438use_t(P)6439return xs64406441# Otherwise it is very very much faster to first compute6442# the linear combinations over RR, and only compute them as6443# rational points if they are approximately integral.64446445# Note: making eps larger here will dramatically increase6446# the running time. If evidence arises that integral6447# points are being missed, it would be better to increase6448# the real precision than to increase eps.64496450def is_approx_integral(P):6451r"""6452Local function, returns True if the real point `P` is approximately integral.6453"""6454eps = 0.00016455return (abs(P[0]-P[0].round()))<eps and (abs(P[1]-P[1].round()))<eps64566457RR = RealField(100) #(100)6458ER = E.change_ring(RR)6459ER0 = ER(0)64606461# Note: doing [ER(P) for P in mw_base] sometimes fails. The6462# following way is harder, since we have to make sure we don't use6463# -P instead of P, but is safer.64646465Rgens = [ER.lift_x(P[0]) for P in mw_base]6466for i in range(r):6467if abs(Rgens[i][1]-mw_base[i][1])>abs((-Rgens[i])[1]-mw_base[i][1]):6468Rgens[i] = -Rgens[i]64696470# the ni loop through all tuples (a1,a2,...,ar) with6471# |ai|<=N, but we stop immediately after using the tuple6472# (0,0,...,0).64736474# Initialization:6475ni = [-N for i in range(r)]6476RgensN = [-N*P for P in Rgens]6477# RPi[i] = -N*(Rgens[0]+...+Rgens[i])6478RPi = [0 for j in range(r)]6479RPi[0] = RgensN[0]6480for i in range(1,r):6481RPi[i] = RPi[i-1] + RgensN[i]64826483tors_points_R = map(ER, tors_points)6484while True:6485if all([n==0 for n in ni]):6486use_t(E(0))6487break64886489# test the ni-combination which is RPi[r-1]6490RP = RPi[r-1]64916492for T, TR in zip(tors_points, tors_points_R):6493if is_approx_integral(RP + TR):6494P = sum([ni[i]*mw_base[i] for i in range(r)],T)6495use(P)64966497# increment indices and stored points6498i0 = r-16499while ni[i0]==N:6500ni[i0] = -N6501i0 -= 16502ni[i0] += 16503# The next lines are to prevent rounding error: (-P)+P behaves6504# badly for real points!6505if all([n==0 for n in ni[0:i0+1]]):6506RPi[i0] = ER06507else:6508RPi[i0] += Rgens[i0]6509for i in range(i0+1,r):6510RPi[i] = RPi[i-1] + RgensN[i]65116512return xs6513651465156516