Path: blob/master/src/sage/schemes/elliptic_curves/BSD.py
8821 views
# -*- coding: utf-8 -*-1#import ell_point2#import formal_group3#import ell_torsion4#from ell_generic import EllipticCurve_generic, is_EllipticCurve5#from ell_number_field import EllipticCurve_number_field67#import sage.groups.all8import sage.rings.arith as arith9import sage.rings.all as rings10from sage.rings.all import ZZ, Infinity11from sage.functions.all import ceil1213class BSD_data:14"""15Helper class used to keep track of information in proving BSD.1617EXAMPLE::1819sage: from sage.schemes.elliptic_curves.BSD import BSD_data20sage: D = BSD_data()21sage: D.Sha is None22True23sage: D.curve=EllipticCurve('11a')24sage: D.update()25sage: D.Sha26Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field2728"""29def __init__(self):30self.curve = None31self.two_tor_rk = None32self.Sha = None33self.sha_an = None34self.N = None3536self.rank = None37self.gens = None38self.bounds = {} # p : (low_bd, up_bd) bounds on ord_p(#sha)39self.primes = None # BSD(E,p) holds for odd primes p outside this set40self.heegner_indexes = {} # D : I_K, K = QQ(\sqrt(D))41self.heegner_index_upper_bound = {} # D : M, I_K <= M42self.N_factorization = None43self.proof = {}4445def update(self):46"""47Updates some properties from ``curve``.4849EXAMPLE::5051sage: from sage.schemes.elliptic_curves.BSD import BSD_data52sage: D = BSD_data()53sage: D.Sha is None54True55sage: D.curve=EllipticCurve('11a')56sage: D.update()57sage: D.Sha58Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field59"""60self.two_tor_rk = self.curve.two_torsion_rank()61self.Sha = self.curve.sha()62self.sha_an = self.Sha.an(use_database=True)63self.N = self.curve.conductor()6465def simon_two_descent_work(E, two_tor_rk):66"""67Prepares the output from Simon two-descent.6869INPUT:7071- ``E`` - an elliptic curve7273- ``two_tor_rk`` - its two-torsion rank7475OUTPUT:7677- a lower bound on the rank7879- an upper bound on the rank8081- a lower bound on the rank of Sha[2]8283- an upper bound on the rank of Sha[2]8485- a list of the generators found8687EXAMPLES::8889sage: from sage.schemes.elliptic_curves.BSD import simon_two_descent_work90sage: E = EllipticCurve('14a')91sage: simon_two_descent_work(E, E.two_torsion_rank())92(0, 0, 0, 0, [])93sage: E = EllipticCurve('37a')94sage: simon_two_descent_work(E, E.two_torsion_rank())95(1, 1, 0, 0, [(0 : 0 : 1)])9697"""98rank_lower_bd, two_sel_rk, gens = E.simon_two_descent()99rank_upper_bd = two_sel_rk - two_tor_rk100gens = [P for P in gens if P.additive_order() == Infinity]101return rank_lower_bd, rank_upper_bd, 0, rank_upper_bd - rank_lower_bd, gens102103def mwrank_two_descent_work(E, two_tor_rk):104"""105Prepares the output from mwrank two-descent.106107INPUT:108109- ``E`` - an elliptic curve110111- ``two_tor_rk`` - its two-torsion rank112113OUTPUT:114115- a lower bound on the rank116117- an upper bound on the rank118119- a lower bound on the rank of Sha[2]120121- an upper bound on the rank of Sha[2]122123- a list of the generators found124125EXAMPLES::126127sage: from sage.schemes.elliptic_curves.BSD import mwrank_two_descent_work128sage: E = EllipticCurve('14a')129sage: mwrank_two_descent_work(E, E.two_torsion_rank())130(0, 0, 0, 0, [])131sage: E = EllipticCurve('37a')132sage: mwrank_two_descent_work(E, E.two_torsion_rank())133(1, 1, 0, 0, [(0 : -1 : 1)])134135"""136MWRC = E.mwrank_curve()137rank_upper_bd = MWRC.rank_bound()138rank_lower_bd = MWRC.rank()139gens = [E(P) for P in MWRC.gens()]140sha2_lower_bd = MWRC.selmer_rank() - two_tor_rk - rank_upper_bd141sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd142return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens143144def native_two_isogeny_descent_work(E, two_tor_rk):145"""146Prepares the output from two-descent by two-isogeny.147148INPUT:149150- ``E`` - an elliptic curve151152- ``two_tor_rk`` - its two-torsion rank153154OUTPUT:155156- a lower bound on the rank157158- an upper bound on the rank159160- a lower bound on the rank of Sha[2]161162- an upper bound on the rank of Sha[2]163164- a list of the generators found (currently None, since we don't store them)165166EXAMPLES::167168sage: from sage.schemes.elliptic_curves.BSD import native_two_isogeny_descent_work169sage: E = EllipticCurve('14a')170sage: native_two_isogeny_descent_work(E, E.two_torsion_rank())171(0, 0, 0, 0, None)172sage: E = EllipticCurve('65a')173sage: native_two_isogeny_descent_work(E, E.two_torsion_rank())174(1, 1, 0, 0, None)175176"""177from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny178n1, n2, n1p, n2p = two_descent_by_two_isogeny(E)179# bring n1 and n1p up to the nearest power of two180two = ZZ(2) # otherwise "log" is symbolic >.<181e1 = ceil(ZZ(n1).log(two))182e1p = ceil(ZZ(n1p).log(two))183e2 = ZZ(n2).log(two)184e2p = ZZ(n2p).log(two)185rank_lower_bd = e1 + e1p - 2186rank_upper_bd = e2 + e2p - 2187sha_upper_bd = e2 + e2p - e1 - e1p188gens = None # right now, we are not keeping track of them189return rank_lower_bd, rank_upper_bd, 0, sha_upper_bd, gens190191def heegner_index_work(E):192"""193Prepares the input and output for computing the heegner index.194195INPUT:196197- ``E`` - an elliptic curve198199OUTPUT:200201- a Heegner index202203- the discriminant used204205EXAMPLE::206207sage: from sage.schemes.elliptic_curves.BSD import heegner_index_work208sage: heegner_index_work(EllipticCurve('14a'))209(1, -31)210211"""212for D in E.heegner_discriminants_list(10):213I = None214while I is None:215dsl=15216try:217I = E.heegner_index(D, descent_second_limit=dsl)218except RuntimeError as err:219if err.args[0][-33:] == 'Generators not provably computed.':220dsl += 1221else: raise RuntimeError(err)222J = I.is_int()223if J[0] and J[1]>0:224I = J[1]225else:226J = (2*I).is_int()227if J[0] and J[1]>0:228I = J[1]229else:230I = None231if I is not None:232return I, D233234235def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,236return_BSD=False):237r"""238Attempts to prove the Birch and Swinnerton-Dyer conjectural239formula for `E`, returning a list of primes `p` for which this240function fails to prove BSD(E,p). Here, BSD(E,p) is the241statement: "the Birch and Swinnerton-Dyer formula holds up to a242rational number coprime to `p`."243244INPUT:245246- ``E`` - an elliptic curve247248- ``verbosity`` - int, how much information about the proof to print.249250- 0 - print nothing251- 1 - print sketch of proof252- 2 - print information about remaining primes253254- ``two_desc`` - string (default ``'mwrank'``), what to use for the255two-descent. Options are ``'mwrank', 'simon', 'sage'``256257- ``proof`` - bool or None (default: None, see258proof.elliptic_curve or sage.structure.proof). If False, this259function just immediately returns the empty list.260261- ``secs_hi`` - maximum number of seconds to try to compute the262Heegner index before switching over to trying to compute the263Heegner index bound. (Rank 0 only!)264265- ``return_BSD`` - bool (default: False) whether to return an object266which contains information to reconstruct a proof267268NOTE:269270When printing verbose output, phrases such as "by Mazur" are referring271to the following list of papers:272273REFERENCES:274275.. [Cha] B. Cha. Vanishing of some cohomology goups and bounds for the276Shafarevich-Tate groups of elliptic curves. J. Number Theory, 111:154-277178, 2005.278.. [Jetchev] D. Jetchev. Global divisibility of Heegner points and279Tamagawa numbers. Compos. Math. 144 (2008), no. 4, 811--826.280.. [Kato] K. Kato. p-adic Hodge theory and values of zeta functions of281modular forms. Astérisque, (295):ix, 117-290, 2004.282.. [Kolyvagin] V. A. Kolyvagin. On the structure of Shafarevich-Tate283groups. Algebraic geometry, 94--121, Lecture Notes in Math., 1479,284Springer, Berlin, 1991.285.. [LumStein] A. Lum, W. Stein. Verification of the Birch and286Swinnerton-Dyer Conjecture for Elliptic Curves with Complex287Multiplication (unpublished)288.. [Mazur] B. Mazur. Modular curves and the Eisenstein ideal. Inst.289Hautes Études Sci. Publ. Math. No. 47 (1977), 33--186 (1978).290.. [Rubin] K. Rubin. The "main conjectures" of Iwasawa theory for291imaginary quadratic fields. Invent. Math. 103 (1991), no. 1, 25--68.292.. [SteinWuthrich] W. Stein and C. Wuthrich. Computations about293Tate-Shafarevich groups using Iwasawa theory.294http://wstein.org/papers/shark, February 2008.295.. [SteinEtAl] G. Grigorov, A. Jorza, S. Patrikis, W. Stein,296C. Tarniţǎ. Computational verification of the Birch and297Swinnerton-Dyer conjecture for individual elliptic curves.298Math. Comp. 78 (2009), no. 268, 2397--2425.299300301EXAMPLES::302303sage: EllipticCurve('11a').prove_BSD(verbosity=2)304p = 2: True by 2-descent...305True for p not in {2, 5} by Kolyvagin.306True for p=5 by Mazur307[]308309sage: EllipticCurve('14a').prove_BSD(verbosity=2)310p = 2: True by 2-descent311True for p not in {2, 3} by Kolyvagin.312Remaining primes:313p = 3: reducible, not surjective, good ordinary, divides a Tamagawa number314(no bounds found)315ord_p(#Sha_an) = 0316[3]317sage: EllipticCurve('14a').prove_BSD(two_desc='simon')318[3]319320A rank two curve::321322sage: E = EllipticCurve('389a')323324We know nothing with proof=True::325326sage: E.prove_BSD()327Set of all prime numbers: 2, 3, 5, 7, ...328329We (think we) know everything with proof=False::330331sage: E.prove_BSD(proof=False)332[]333334A curve of rank 0 and prime conductor::335336sage: E = EllipticCurve('19a')337sage: E.prove_BSD(verbosity=2)338p = 2: True by 2-descent...339True for p not in {2, 3} by Kolyvagin.340True for p=3 by Mazur341[]342343sage: E = EllipticCurve('37a')344sage: E.rank()3451346sage: E._EllipticCurve_rational_field__rank347{True: 1}348sage: E.analytic_rank = lambda : 0349sage: E.prove_BSD()350Traceback (most recent call last):351...352RuntimeError: It seems that the rank conjecture does not hold for this curve (Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field)! This may be a counterexample to BSD, but is more likely a bug.353354We test the consistency check for the 2-part of Sha::355356sage: E = EllipticCurve('37a')357sage: S = E.sha(); S358Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field359sage: def foo(use_database):360... return 4361sage: S.an = foo362sage: E.prove_BSD()363Traceback (most recent call last):364...365RuntimeError: Apparent contradiction: 0 <= rank(sha[2]) <= 0, but ord_2(sha_an) = 2366367An example with a Tamagawa number at 5::368369sage: E = EllipticCurve('123a1')370sage: E.prove_BSD(verbosity=2)371p = 2: True by 2-descent372True for p not in {2, 5} by Kolyvagin.373Remaining primes:374p = 5: reducible, not surjective, good ordinary, divides a Tamagawa number375(no bounds found)376ord_p(#Sha_an) = 0377[5]378379A curve for which 3 divides the order of the Tate-Shafarevich group::380381sage: E = EllipticCurve('681b')382sage: E.prove_BSD(verbosity=2) # long time383p = 2: True by 2-descent...384True for p not in {2, 3} by Kolyvagin....385Remaining primes:386p = 3: irreducible, surjective, non-split multiplicative387(0 <= ord_p <= 2)388ord_p(#Sha_an) = 2389[3]390391A curve for which we need to use ``heegner_index_bound``::392393sage: E = EllipticCurve('198b')394sage: E.prove_BSD(verbosity=1, secs_hi=1)395p = 2: True by 2-descent396True for p not in {2, 3} by Kolyvagin.397[3]398399The ``return_BSD`` option gives an object with detailed information400about the proof::401402sage: E = EllipticCurve('26b')403sage: B = E.prove_BSD(return_BSD=True)404sage: B.two_tor_rk4050406sage: B.N40726408sage: B.gens409[]410sage: B.primes411[7]412sage: B.heegner_indexes413{-23: 2}414415TESTS:416417This was fixed by trac #8184 and #7575::418419sage: EllipticCurve('438e1').prove_BSD(verbosity=1)420p = 2: True by 2-descent...421True for p not in {2} by Kolyvagin.422[]423424::425426sage: E = EllipticCurve('960d1')427sage: E.prove_BSD(verbosity=1) # long time (4s on sage.math, 2011)428p = 2: True by 2-descent429True for p not in {2} by Kolyvagin.430[]431432"""433if proof is None:434from sage.structure.proof.proof import get_flag435proof = get_flag(proof, "elliptic_curve")436else:437proof = bool(proof)438if not proof:439return []440from copy import copy441BSD = BSD_data()442# We replace this curve by the optimal curve, which we can do since443# truth of BSD(E,p) is invariant under isogeny.444BSD.curve = E.optimal_curve()445if BSD.curve.has_cm():446# ensure that CM is by a maximal order447non_max_j_invs = [-12288000, 54000, 287496, 16581375]448if BSD.curve.j_invariant() in non_max_j_invs: # is this possible for optimal curves?449if verbosity > 0:450print 'CM by non maximal order: switching curves'451for E in BSD.curve.isogeny_class():452if E.j_invariant() not in non_max_j_invs:453BSD.curve = E454break455BSD.update()456galrep = BSD.curve.galois_representation()457458if two_desc=='mwrank':459M = mwrank_two_descent_work(BSD.curve, BSD.two_tor_rk)460elif two_desc=='simon':461M = simon_two_descent_work(BSD.curve, BSD.two_tor_rk)462elif two_desc=='sage':463M = native_two_isogeny_descent_work(BSD.curve, BSD.two_tor_rk)464else:465raise NotImplementedError()466rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens = M467assert sha2_lower_bd <= sha2_upper_bd468if gens is not None: gens = BSD.curve.saturation(gens)[0]469if rank_lower_bd > rank_upper_bd:470raise RuntimeError("Apparent contradiction: %d <= rank <= %d."%(rank_lower_bd, rank_upper_bd))471BSD.two_selmer_rank = rank_upper_bd + sha2_lower_bd + BSD.two_tor_rk472if sha2_upper_bd == sha2_lower_bd:473BSD.rank = rank_lower_bd474BSD.bounds[2] = (sha2_lower_bd, sha2_upper_bd)475else:476BSD.rank = BSD.curve.rank(use_database=True)477sha2_upper_bd -= (BSD.rank - rank_lower_bd)478BSD.bounds[2] = (sha2_lower_bd, sha2_upper_bd)479if verbosity > 0:480print "Unable to compute the rank exactly -- used database."481if rank_lower_bd > 1:482# We do not know BSD(E,p) for even a single p, since it's483# an open problem to show that L^r(E,1)/(Reg*Omega) is484# rational for any curve with r >= 2.485from sage.sets.all import Primes486BSD.primes = Primes()487if return_BSD:488BSD.rank = rank_lower_bd489return BSD490return BSD.primes491if (BSD.sha_an.ord(2) == 0) != (BSD.bounds[2][1] == 0):492raise RuntimeError("Apparent contradiction: %d <= rank(sha[2]) <= %d, but ord_2(sha_an) = %d"%(sha2_lower_bd, sha2_upper_bd, BSD.sha_an.ord(2)))493if BSD.bounds[2][0] == BSD.sha_an.ord(2) and BSD.sha_an.ord(2) == BSD.bounds[2][1]:494if verbosity > 0:495print 'p = 2: True by 2-descent'496BSD.primes = []497BSD.bounds.pop(2)498BSD.proof[2] = ['2-descent']499else:500BSD.primes = [2]501BSD.proof[2] = [('2-descent',)+BSD.bounds[2]]502if len(gens) > rank_lower_bd or \503rank_lower_bd > rank_upper_bd:504raise RuntimeError("Something went wrong with 2-descent.")505if BSD.rank != len(gens):506if BSD.rank != len(BSD.curve._EllipticCurve_rational_field__gens[True]):507raise RuntimeError("Could not get generators")508gens = BSD.curve._EllipticCurve_rational_field__gens[True]509BSD.gens = [BSD.curve.point(x, check=True) for x in gens]510511if BSD.rank != BSD.curve.analytic_rank():512raise RuntimeError("It seems that the rank conjecture does not hold for this curve (%s)! This may be a counterexample to BSD, but is more likely a bug."%(BSD.curve))513514# reduce set of remaining primes to a finite set515import signal516kolyvagin_primes = []517heegner_index = None518if BSD.rank == 0:519for D in BSD.curve.heegner_discriminants_list(10):520max_height = max(13,BSD.curve.quadratic_twist(D).CPS_height_bound())521heegner_primes = -1522while heegner_primes == -1:523if max_height > 21: break524heegner_primes, _, exact = BSD.curve.heegner_index_bound(D, max_height=max_height)525max_height += 1526if isinstance(heegner_primes, list):527break528if not isinstance(heegner_primes, list):529raise RuntimeError("Tried 10 Heegner discriminants, and heegner_index_bound failed each time.")530if exact is not False:531heegner_index = exact532BSD.heegner_indexes[D] = exact533else:534BSD.heegner_index_upper_bound[D] = max(heegner_primes+[1])535if 2 in heegner_primes:536heegner_primes.remove(2)537else: # rank 1538for D in BSD.curve.heegner_discriminants_list(10):539I = BSD.curve.heegner_index(D)540J = I.is_int()541if J[0] and J[1]>0:542I = J[1]543else:544J = (2*I).is_int()545if J[0] and J[1]>0:546I = J[1]547else:548continue549heegner_index = I550BSD.heegner_indexes[D] = I551break552heegner_primes = [p for p in arith.prime_divisors(heegner_index) if p!=2]553554assert BSD.sha_an in ZZ and BSD.sha_an > 0555if BSD.curve.has_cm():556if BSD.curve.analytic_rank() == 0:557if verbosity > 0:558print ' p >= 5: true by Rubin'559BSD.primes.append(3)560else:561K = rings.QuadraticField(BSD.curve.cm_discriminant(), 'a')562D_K = K.disc()563D_E = BSD.curve.discriminant()564if len(K.factor(3)) == 1: # 3 does not split in K565BSD.primes.append(3)566for p in arith.prime_divisors(D_K):567if p >= 5:568BSD.primes.append(p)569for p in arith.prime_divisors(D_E):570if p >= 5 and D_K%p and len(K.factor(p)) == 1: # p is inert in K571BSD.primes.append(p)572for p in heegner_primes:573if p >= 5 and D_E%p != 0 and D_K%p != 0 and len(K.factor(p)) == 1: # p is good for E and inert in K574kolyvagin_primes.append(p)575for p in arith.prime_divisors(BSD.sha_an):576if p >= 5 and D_K%p != 0 and len(K.factor(p)) == 1:577if BSD.curve.is_good(p):578if verbosity > 2 and p in heegner_primes and heegner_index is None:579print 'ALERT: Prime p (%d) >= 5 dividing sha_an, good for E, inert in K, in heegner_primes, should not divide the actual Heegner index'580# Note that the following check is not entirely581# exhaustive, in case there is a p not dividing582# the Heegner index in heegner_primes,583# for which only an outer bound was computed584if p not in heegner_primes:585raise RuntimeError("p = %d divides sha_an, is of good reduction for E, inert in K, and does not divide the Heegner index. This may be a counterexample to BSD, but is more likely a bug. %s"%(p,BSD.curve))586if verbosity > 0:587print 'True for p not in {%s} by Kolyvagin (via Stein & Lum -- unpublished) and Rubin.'%str(list(set(BSD.primes).union(set(kolyvagin_primes))))[1:-1]588BSD.proof['finite'] = copy(BSD.primes)589else: # no CM590# do some tricks to get to a finite set without calling bound_kolyvagin591BSD.primes += [p for p in galrep.non_surjective() if p != 2]592for p in heegner_primes:593if p not in BSD.primes:594BSD.primes.append(p)595for p in arith.prime_divisors(BSD.sha_an):596if p not in BSD.primes and p != 2:597BSD.primes.append(p)598if verbosity > 0:599s = str(BSD.primes)[1:-1]600if 2 not in BSD.primes:601if len(s) == 0: s = '2'602else: s = '2, '+s603print 'True for p not in {' + s + '} by Kolyvagin.'604BSD.proof['finite'] = copy(BSD.primes)605primes_to_remove = []606for p in BSD.primes:607if p == 2: continue608if galrep.is_surjective(p) and not BSD.curve.has_additive_reduction(p):609if BSD.curve.has_nonsplit_multiplicative_reduction(p):610if BSD.rank > 0:611continue612if p==3:613if (not (BSD.curve.is_ordinary(p) and BSD.curve.is_good(p))) and (not BSD.curve.has_split_multiplicative_reduction(p)):614continue615if BSD.rank > 0:616continue617if verbosity > 1:618print ' p = %d: Trying p_primary_bound'%p619p_bound = BSD.Sha.p_primary_bound(p)620if BSD.proof.has_key(p):621BSD.proof[p].append(('Stein-Wuthrich', p_bound))622else:623BSD.proof[p] = [('Stein-Wuthrich', p_bound)]624if BSD.sha_an.ord(p) == 0 and p_bound == 0:625if verbosity > 0:626print 'True for p=%d by Stein-Wuthrich.'%p627primes_to_remove.append(p)628else:629if BSD.bounds.has_key(p):630BSD.bounds[p][1] = min(BSD.bounds[p][1], p_bound)631else:632BSD.bounds[p] = (0, p_bound)633print 'Analytic %d-rank is '%p + str(BSD.sha_an.ord(p)) + ', actual %d-rank is at most %d.'%(p, p_bound)634print ' by Stein-Wuthrich.\n'635for p in primes_to_remove:636BSD.primes.remove(p)637kolyvagin_primes = []638for p in BSD.primes:639if p == 2: continue640if galrep.is_surjective(p):641kolyvagin_primes.append(p)642for p in kolyvagin_primes:643BSD.primes.remove(p)644# apply other hypotheses which imply Kolyvagin's bound holds645bounded_primes = []646D_K = rings.QuadraticField(D, 'a').disc()647648# Cha's hypothesis649for p in BSD.primes:650if p == 2: continue651if D_K%p != 0 and BSD.N%(p**2) != 0 and galrep.is_irreducible(p):652if verbosity > 0:653print 'Kolyvagin\'s bound for p = %d applies by Cha.'%p654if BSD.proof.has_key(p):655BSD.proof[p].append('Cha')656else:657BSD.proof[p] = ['Cha']658kolyvagin_primes.append(p)659# Stein et al.660if not BSD.curve.has_cm():661L = arith.lcm([F.torsion_order() for F in BSD.curve.isogeny_class()])662for p in BSD.primes:663if p in kolyvagin_primes or p == 2: continue664if L%p != 0:665if len(arith.prime_divisors(D_K)) == 1:666if D_K%p == 0: continue667if verbosity > 0:668print 'Kolyvagin\'s bound for p = %d applies by Stein et al.'%p669kolyvagin_primes.append(p)670if BSD.proof.has_key(p):671BSD.proof[p].append('Stein et al.')672else:673BSD.proof[p] = ['Stein et al.']674for p in kolyvagin_primes:675if p in BSD.primes:676BSD.primes.remove(p)677678# apply Kolyvagin's bound679primes_to_remove = []680for p in kolyvagin_primes:681if p == 2: continue682if p not in heegner_primes:683ord_p_bound = 0684elif heegner_index is not None: # p must divide heegner_index685ord_p_bound = 2*heegner_index.ord(p)686# Here Jetchev's results apply.687m_max = max([BSD.curve.tamagawa_number(q).ord(p) for q in BSD.N.prime_divisors()])688if m_max > 0:689if verbosity > 0:690print 'Jetchev\'s results apply (at p = %d) with m_max ='%p, m_max691if BSD.proof.has_key(p):692BSD.proof[p].append(('Jetchev',m_max))693else:694BSD.proof[p] = [('Jetchev',m_max)]695ord_p_bound -= 2*m_max696else: # Heegner index is None697for D in BSD.heegner_index_upper_bound:698M = BSD.heegner_index_upper_bound[D]699ord_p_bound = 0700while p**(ord_p_bound+1) <= M**2:701ord_p_bound += 1702# now ord_p_bound is one on I_K!!!703ord_p_bound *= 2 # by Kolyvagin, now ord_p_bound is one on #Sha704break705if BSD.proof.has_key(p):706BSD.proof[p].append(('Kolyvagin',ord_p_bound))707else:708BSD.proof[p] = [('Kolyvagin',ord_p_bound)]709if BSD.sha_an.ord(p) == 0 and ord_p_bound == 0:710if verbosity > 0:711print 'True for p = %d by Kolyvagin bound'%p712primes_to_remove.append(p)713elif BSD.sha_an.ord(p) > ord_p_bound:714raise RuntimeError("p = %d: ord_p_bound == %d, but sha_an.ord(p) == %d. This appears to be a counterexample to BSD, but is more likely a bug."%(p,ord_p_bound,BSD.sha_an.ord(p)))715else: # BSD.sha_an.ord(p) <= ord_p_bound != 0:716if BSD.bounds.has_key(p):717low = BSD.bounds[p][0]718BSD.bounds[p] = (low, min(BSD.bounds[p][1], ord_p_bound))719else:720BSD.bounds[p] = (0, ord_p_bound)721for p in primes_to_remove:722kolyvagin_primes.remove(p)723BSD.primes = list( set(BSD.primes).union(set(kolyvagin_primes)) )724725# Kato's bound726if BSD.rank == 0 and not BSD.curve.has_cm():727L_over_Omega = BSD.curve.lseries().L_ratio()728kato_primes = BSD.Sha.bound_kato()729primes_to_remove = []730for p in BSD.primes:731if p == 2: continue732if p not in kato_primes:733if verbosity > 0:734print 'Kato further implies that #Sha[%d] is trivial.'%p735primes_to_remove.append(p)736if BSD.proof.has_key(p):737BSD.proof[p].append(('Kato',0))738else:739BSD.proof[p] = [('Kato',0)]740if p not in [2,3] and BSD.N%p != 0:741if galrep.is_surjective(p):742bd = L_over_Omega.valuation(p)743if verbosity > 1:744print 'Kato implies that ord_p(#Sha[%d]) <= %d '%(p,bd)745if BSD.proof.has_key(p):746BSD.proof[p].append(('Kato',bd))747else:748BSD.proof[p] = [('Kato',bd)]749if BSD.bounds.has_key(p):750low = BSD.bounds[p][0]751BSD.bounds[p][1] = (low, min(BSD.bounds[p][1], bd))752else:753BSD.bounds[p] = (0, bd)754for p in primes_to_remove:755BSD.primes.remove(p)756757# Mazur758primes_to_remove = []759if BSD.N.is_prime():760for p in BSD.primes:761if p == 2: continue762if galrep.is_reducible(p):763primes_to_remove.append(p)764if verbosity > 0:765print 'True for p=%s by Mazur'%p766for p in primes_to_remove:767BSD.primes.remove(p)768if BSD.proof.has_key(p):769BSD.proof[p].append('Mazur')770else:771BSD.proof[p] = ['Mazur']772773BSD.primes.sort()774775# Try harder to compute the Heegner index, where it matters776if heegner_index is None:777if max_height < 18:778max_height = 18779for D in BSD.heegner_index_upper_bound:780M = BSD.heegner_index_upper_bound[D]781for p in kolyvagin_primes:782if p not in BSD.primes or p == 3: continue783if verbosity > 0:784print ' p = %d: Trying harder for Heegner index'%p785obt = 0786while p**(BSD.sha_an.ord(p)/2+1) <= M and max_height < 22:787if verbosity > 2:788print ' trying max_height =', max_height789old_bound = M790M, _, exact = BSD.curve.heegner_index_bound(D, max_height=max_height, secs_dc=secs_dc)791if M == -1:792max_height += 1793continue794if exact is not False:795heegner_index = exact796BSD.heegner_indexes[D] = exact797M = exact798if verbosity > 2:799print ' heegner index =', M800else:801M = max(M+[1])802if verbosity > 2:803print ' bound =', M804if old_bound == M:805obt += 1806if obt == 2:807break808max_height += 1809BSD.heegner_index_upper_bound[D] = min(M,BSD.heegner_index_upper_bound[D])810low, upp = BSD.bounds[p]811expn = 0812while p**(expn+1) <= M:813expn += 1814if 2*expn < upp:815upp = 2*expn816BSD.bounds[p] = (low,upp)817if verbosity > 0:818print ' got better bound on ord_p =', upp819if low == upp:820if upp != BSD.sha_an.ord(p):821raise RuntimeError822else:823if verbosity > 0:824print ' proven!'825BSD.primes.remove(p)826break827for p in kolyvagin_primes:828if p not in BSD.primes or p == 3: continue829for D in BSD.curve.heegner_discriminants_list(4):830if D in BSD.heegner_index_upper_bound: continue831print ' discriminant', D832if verbosity > 0:833print 'p = %d: Trying discriminant = %d for Heegner index'%(p,D)834max_height = max(10, BSD.curve.quadratic_twist(D).CPS_height_bound())835obt = 0836while True:837if verbosity > 2:838print ' trying max_height =', max_height839old_bound = M840if p**(BSD.sha_an.ord(p)/2+1) > M or max_height >= 22:841break842M, _, exact = BSD.curve.heegner_index_bound(D, max_height=max_height, secs_dc=secs_dc)843if M == -1:844max_height += 1845continue846if exact is not False:847heegner_index = exact848BSD.heegner_indexes[D] = exact849M = exact850if verbosity > 2:851print ' heegner index =', M852else:853M = max(M+[1])854if verbosity > 2:855print ' bound =', M856if old_bound == M:857obt += 1858if obt == 2:859break860max_height += 1861BSD.heegner_index_upper_bound[D] = M862low, upp = BSD.bounds[p]863expn = 0864while p**(expn+1) <= M:865expn += 1866if 2*expn < upp:867upp = 2*expn868BSD.bounds[p] = (low,upp)869if verbosity > 0:870print ' got better bound =', upp871if low == upp:872if upp != BSD.sha_an.ord(p):873raise RuntimeError874else:875if verbosity > 0:876print ' proven!'877BSD.primes.remove(p)878break879880# print some extra information881if verbosity > 1:882if len(BSD.primes) > 0:883print 'Remaining primes:'884for p in BSD.primes:885s = 'p = ' + str(p) + ': '886if galrep.is_irreducible(p):887s += 'ir'888s += 'reducible, '889if not galrep.is_surjective(p):890s += 'not '891s += 'surjective, '892a_p = BSD.curve.an(p)893if BSD.curve.is_good(p):894if a_p%p != 0:895s += 'good ordinary'896else:897s += 'good, non-ordinary'898else:899assert BSD.curve.is_minimal()900if a_p == 0:901s += 'additive'902elif a_p == 1:903s += 'split multiplicative'904elif a_p == -1:905s += 'non-split multiplicative'906if BSD.curve.tamagawa_product()%p==0:907s += ', divides a Tamagawa number'908if BSD.bounds.has_key(p):909s += '\n (%d <= ord_p <= %d)'%BSD.bounds[p]910else:911s += '\n (no bounds found)'912s += '\n ord_p(#Sha_an) = %d'%BSD.sha_an.ord(p)913if heegner_index is None:914may_divide = True915for D in BSD.heegner_index_upper_bound:916if p > BSD.heegner_index_upper_bound[D] or p not in kolyvagin_primes:917may_divide = False918if may_divide:919s += '\n may divide the Heegner index, for which only a bound was computed'920print s921922if BSD.curve.has_cm():923if BSD.rank == 1:924BSD.proof['reason_finite'] = 'Rubin&Kolyvagin'925else:926BSD.proof['reason_finite'] = 'Rubin'927else:928BSD.proof['reason_finite'] = 'Kolyvagin'929# reduce memory footprint of BSD object:930BSD.curve = BSD.curve.label()931BSD.Sha = None932return BSD if return_BSD else BSD.primes933934935936