passagemath-schemes 10.6.38__cp314-cp314t-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-schemes might be problematic. Click here for more details.
- passagemath_schemes/.dylibs/libflint.21.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.38.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.38.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314t-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-314t-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314t-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,1036 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
"Birch and Swinnerton-Dyer formulas"
|
|
3
|
+
|
|
4
|
+
from sage.arith.misc import prime_divisors
|
|
5
|
+
from sage.misc.lazy_import import lazy_import
|
|
6
|
+
from sage.rings.infinity import Infinity
|
|
7
|
+
from sage.rings.integer_ring import ZZ
|
|
8
|
+
from sage.rings.rational_field import QQ
|
|
9
|
+
|
|
10
|
+
lazy_import("sage.functions.other", "ceil")
|
|
11
|
+
lazy_import("sage.rings.number_field.number_field", "QuadraticField")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BSD_data:
|
|
15
|
+
"""
|
|
16
|
+
Helper class used to keep track of information in proving BSD.
|
|
17
|
+
|
|
18
|
+
EXAMPLES::
|
|
19
|
+
|
|
20
|
+
sage: from sage.schemes.elliptic_curves.BSD import BSD_data
|
|
21
|
+
sage: D = BSD_data()
|
|
22
|
+
sage: D.Sha is None
|
|
23
|
+
True
|
|
24
|
+
sage: D.curve = EllipticCurve('11a')
|
|
25
|
+
sage: D.update() # needs sage.graphs
|
|
26
|
+
sage: D.Sha # needs sage.graphs
|
|
27
|
+
Tate-Shafarevich group for the Elliptic Curve
|
|
28
|
+
defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
|
|
29
|
+
"""
|
|
30
|
+
def __init__(self):
|
|
31
|
+
self.curve = None
|
|
32
|
+
self.two_tor_rk = None
|
|
33
|
+
self.Sha = None
|
|
34
|
+
self.sha_an = None
|
|
35
|
+
self.N = None
|
|
36
|
+
|
|
37
|
+
self.rank = None
|
|
38
|
+
self.gens = None
|
|
39
|
+
self.bounds = {} # p : (low_bd, up_bd) bounds on ord_p(#sha)
|
|
40
|
+
self.primes = None # BSD(E,p) holds for odd primes p outside this set
|
|
41
|
+
self.heegner_indexes = {} # D : I_K, K = QQ(\sqrt(D))
|
|
42
|
+
self.heegner_index_upper_bound = {} # D : M, I_K <= M
|
|
43
|
+
self.N_factorization = None
|
|
44
|
+
self.proof = {}
|
|
45
|
+
|
|
46
|
+
def update(self):
|
|
47
|
+
"""
|
|
48
|
+
Update some properties from ``curve``.
|
|
49
|
+
|
|
50
|
+
EXAMPLES::
|
|
51
|
+
|
|
52
|
+
sage: from sage.schemes.elliptic_curves.BSD import BSD_data
|
|
53
|
+
sage: D = BSD_data()
|
|
54
|
+
sage: D.Sha is None
|
|
55
|
+
True
|
|
56
|
+
sage: D.curve = EllipticCurve('11a')
|
|
57
|
+
sage: D.update() # needs sage.graphs
|
|
58
|
+
sage: D.Sha # needs sage.graphs
|
|
59
|
+
Tate-Shafarevich group for the Elliptic Curve
|
|
60
|
+
defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
|
|
61
|
+
"""
|
|
62
|
+
self.two_tor_rk = self.curve.two_torsion_rank()
|
|
63
|
+
self.Sha = self.curve.sha()
|
|
64
|
+
self.sha_an = self.Sha.an(use_database=True)
|
|
65
|
+
self.N = self.curve.conductor()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def simon_two_descent_work(E, two_tor_rk):
|
|
69
|
+
"""
|
|
70
|
+
Prepare the output from Simon two-descent.
|
|
71
|
+
|
|
72
|
+
INPUT:
|
|
73
|
+
|
|
74
|
+
- ``E`` -- an elliptic curve
|
|
75
|
+
|
|
76
|
+
- ``two_tor_rk`` -- its two-torsion rank
|
|
77
|
+
|
|
78
|
+
OUTPUT:
|
|
79
|
+
|
|
80
|
+
- a lower bound on the rank
|
|
81
|
+
|
|
82
|
+
- an upper bound on the rank
|
|
83
|
+
|
|
84
|
+
- a lower bound on the rank of Sha[2]
|
|
85
|
+
|
|
86
|
+
- an upper bound on the rank of Sha[2]
|
|
87
|
+
|
|
88
|
+
- a list of the generators found
|
|
89
|
+
|
|
90
|
+
EXAMPLES::
|
|
91
|
+
|
|
92
|
+
sage: from sage.schemes.elliptic_curves.BSD import simon_two_descent_work
|
|
93
|
+
sage: E = EllipticCurve('14a')
|
|
94
|
+
sage: simon_two_descent_work(E, E.two_torsion_rank())
|
|
95
|
+
doctest:warning
|
|
96
|
+
...
|
|
97
|
+
DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari.
|
|
98
|
+
See https://github.com/sagemath/sage/issues/35621 for details.
|
|
99
|
+
...
|
|
100
|
+
(0, 0, 0, 0, [])
|
|
101
|
+
sage: E = EllipticCurve('37a')
|
|
102
|
+
sage: simon_two_descent_work(E, E.two_torsion_rank()) # needs eclib
|
|
103
|
+
(1, 1, 0, 0, [(0 : 0 : 1)])
|
|
104
|
+
"""
|
|
105
|
+
from sage.misc.superseded import deprecation
|
|
106
|
+
deprecation(35621, 'Use the two-descent in pari instead, as this script has been ported over to pari.')
|
|
107
|
+
rank_lower_bd, two_sel_rk, gens = E.simon_two_descent()
|
|
108
|
+
rank_upper_bd = two_sel_rk - two_tor_rk
|
|
109
|
+
gens = [P for P in gens if P.additive_order() == Infinity]
|
|
110
|
+
return rank_lower_bd, rank_upper_bd, 0, rank_upper_bd - rank_lower_bd, gens
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def mwrank_two_descent_work(E, two_tor_rk):
|
|
114
|
+
"""
|
|
115
|
+
Prepare the output from mwrank two-descent.
|
|
116
|
+
|
|
117
|
+
INPUT:
|
|
118
|
+
|
|
119
|
+
- ``E`` -- an elliptic curve
|
|
120
|
+
|
|
121
|
+
- ``two_tor_rk`` -- its two-torsion rank
|
|
122
|
+
|
|
123
|
+
OUTPUT:
|
|
124
|
+
|
|
125
|
+
- a lower bound on the rank
|
|
126
|
+
|
|
127
|
+
- an upper bound on the rank
|
|
128
|
+
|
|
129
|
+
- a lower bound on the rank of Sha[2]
|
|
130
|
+
|
|
131
|
+
- an upper bound on the rank of Sha[2]
|
|
132
|
+
|
|
133
|
+
- a list of the generators found
|
|
134
|
+
|
|
135
|
+
EXAMPLES::
|
|
136
|
+
|
|
137
|
+
sage: from sage.schemes.elliptic_curves.BSD import mwrank_two_descent_work
|
|
138
|
+
sage: E = EllipticCurve('14a')
|
|
139
|
+
sage: mwrank_two_descent_work(E, E.two_torsion_rank()) # needs eclib
|
|
140
|
+
(0, 0, 0, 0, [])
|
|
141
|
+
sage: E = EllipticCurve('37a')
|
|
142
|
+
sage: mwrank_two_descent_work(E, E.two_torsion_rank()) # needs eclib
|
|
143
|
+
(1, 1, 0, 0, [(0 : -1 : 1)])
|
|
144
|
+
"""
|
|
145
|
+
MWRC = E.mwrank_curve()
|
|
146
|
+
rank_upper_bd = MWRC.rank_bound()
|
|
147
|
+
rank_lower_bd = MWRC.rank()
|
|
148
|
+
gens = [E(P) for P in MWRC.gens()]
|
|
149
|
+
sha2_lower_bd = MWRC.selmer_rank() - two_tor_rk - rank_upper_bd
|
|
150
|
+
sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd
|
|
151
|
+
return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def pari_two_descent_work(E):
|
|
155
|
+
r"""
|
|
156
|
+
Prepare the output from pari by two-isogeny.
|
|
157
|
+
|
|
158
|
+
INPUT:
|
|
159
|
+
|
|
160
|
+
- ``E`` -- an elliptic curve
|
|
161
|
+
|
|
162
|
+
OUTPUT: a tuple of 5 elements with the first 4 being integers
|
|
163
|
+
|
|
164
|
+
- a lower bound on the rank
|
|
165
|
+
|
|
166
|
+
- an upper bound on the rank
|
|
167
|
+
|
|
168
|
+
- a lower bound on the rank of Sha[2]
|
|
169
|
+
|
|
170
|
+
- an upper bound on the rank of Sha[2]
|
|
171
|
+
|
|
172
|
+
- a list of the generators found
|
|
173
|
+
|
|
174
|
+
EXAMPLES::
|
|
175
|
+
|
|
176
|
+
sage: from sage.schemes.elliptic_curves.BSD import pari_two_descent_work
|
|
177
|
+
sage: E = EllipticCurve('14a')
|
|
178
|
+
sage: pari_two_descent_work(E)
|
|
179
|
+
(0, 0, 0, 0, [])
|
|
180
|
+
sage: E = EllipticCurve('37a')
|
|
181
|
+
sage: pari_two_descent_work(E) # random, up to sign # needs eclib
|
|
182
|
+
(1, 1, 0, 0, [(0 : -1 : 1)])
|
|
183
|
+
sage: E = EllipticCurve('210e7')
|
|
184
|
+
sage: pari_two_descent_work(E) # needs eclib
|
|
185
|
+
(0, 2, 0, 2, [])
|
|
186
|
+
sage: E = EllipticCurve('66b3')
|
|
187
|
+
sage: pari_two_descent_work(E) # needs eclib
|
|
188
|
+
(0, 0, 2, 2, [])
|
|
189
|
+
"""
|
|
190
|
+
ep = E.pari_curve()
|
|
191
|
+
lower, rank_upper_bd, s, pts = ep.ellrank()
|
|
192
|
+
gens = sorted([E.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts])
|
|
193
|
+
gens = E.saturation(gens)[0]
|
|
194
|
+
# this is explained in the pari-gp documentation:
|
|
195
|
+
# s is the dimension of Sha[2]/2Sha[4],
|
|
196
|
+
# which is a lower bound for dim Sha[2]
|
|
197
|
+
# dim Sha[2] = dim Sel2 - rank E(Q) - dim tors
|
|
198
|
+
# rank_upper_bd = dim Sel_2 - dim tors - s
|
|
199
|
+
sha_upper_bd = rank_upper_bd - len(gens) + s
|
|
200
|
+
return len(gens), rank_upper_bd, s, sha_upper_bd, gens
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def native_two_isogeny_descent_work(E, two_tor_rk):
|
|
204
|
+
"""
|
|
205
|
+
Prepare the output from two-descent by two-isogeny.
|
|
206
|
+
|
|
207
|
+
INPUT:
|
|
208
|
+
|
|
209
|
+
- ``E`` -- an elliptic curve
|
|
210
|
+
|
|
211
|
+
- ``two_tor_rk`` -- its two-torsion rank
|
|
212
|
+
|
|
213
|
+
OUTPUT:
|
|
214
|
+
|
|
215
|
+
- a lower bound on the rank
|
|
216
|
+
|
|
217
|
+
- an upper bound on the rank
|
|
218
|
+
|
|
219
|
+
- a lower bound on the rank of Sha[2]
|
|
220
|
+
|
|
221
|
+
- an upper bound on the rank of Sha[2]
|
|
222
|
+
|
|
223
|
+
- a list of the generators found (currently None, since we don't store them)
|
|
224
|
+
|
|
225
|
+
EXAMPLES::
|
|
226
|
+
|
|
227
|
+
sage: from sage.schemes.elliptic_curves.BSD import native_two_isogeny_descent_work
|
|
228
|
+
sage: E = EllipticCurve('14a')
|
|
229
|
+
sage: native_two_isogeny_descent_work(E, E.two_torsion_rank())
|
|
230
|
+
(0, 0, 0, 0, None)
|
|
231
|
+
sage: E = EllipticCurve('65a')
|
|
232
|
+
sage: native_two_isogeny_descent_work(E, E.two_torsion_rank())
|
|
233
|
+
(1, 1, 0, 0, None)
|
|
234
|
+
"""
|
|
235
|
+
from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny
|
|
236
|
+
n1, n2, n1p, n2p = two_descent_by_two_isogeny(E)
|
|
237
|
+
# bring n1 and n1p up to the nearest power of two
|
|
238
|
+
two = ZZ(2) # otherwise "log" is symbolic >.<
|
|
239
|
+
e1 = ceil(ZZ(n1).log(two))
|
|
240
|
+
e1p = ceil(ZZ(n1p).log(two))
|
|
241
|
+
e2 = ZZ(n2).log(two)
|
|
242
|
+
e2p = ZZ(n2p).log(two)
|
|
243
|
+
rank_lower_bd = e1 + e1p - 2
|
|
244
|
+
rank_upper_bd = e2 + e2p - 2
|
|
245
|
+
sha_upper_bd = e2 + e2p - e1 - e1p
|
|
246
|
+
gens = None # right now, we are not keeping track of them
|
|
247
|
+
return rank_lower_bd, rank_upper_bd, 0, sha_upper_bd, gens
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def heegner_index_work(E):
|
|
251
|
+
"""
|
|
252
|
+
Prepare the input and output for computing the heegner index.
|
|
253
|
+
|
|
254
|
+
INPUT:
|
|
255
|
+
|
|
256
|
+
- ``E`` -- an elliptic curve
|
|
257
|
+
|
|
258
|
+
OUTPUT:
|
|
259
|
+
|
|
260
|
+
- a Heegner index
|
|
261
|
+
|
|
262
|
+
- the discriminant used
|
|
263
|
+
|
|
264
|
+
EXAMPLES::
|
|
265
|
+
|
|
266
|
+
sage: from sage.schemes.elliptic_curves.BSD import heegner_index_work
|
|
267
|
+
sage: heegner_index_work(EllipticCurve('14a')) # needs sage.graphs
|
|
268
|
+
(1, -31)
|
|
269
|
+
"""
|
|
270
|
+
for D in E.heegner_discriminants_list(10):
|
|
271
|
+
I = None
|
|
272
|
+
while I is None:
|
|
273
|
+
dsl = 15
|
|
274
|
+
try:
|
|
275
|
+
I = E.heegner_index(D, descent_second_limit=dsl)
|
|
276
|
+
except RuntimeError as err:
|
|
277
|
+
if err.args[0][-33:] == 'Generators not provably computed.':
|
|
278
|
+
dsl += 1
|
|
279
|
+
else:
|
|
280
|
+
raise RuntimeError(err)
|
|
281
|
+
J = I.is_int()
|
|
282
|
+
if J[0] and J[1] > 0:
|
|
283
|
+
I = J[1]
|
|
284
|
+
else:
|
|
285
|
+
J = (2 * I).is_int()
|
|
286
|
+
if J[0] and J[1] > 0:
|
|
287
|
+
I = J[1]
|
|
288
|
+
else:
|
|
289
|
+
I = None
|
|
290
|
+
if I is not None:
|
|
291
|
+
return I, D
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
|
|
295
|
+
return_BSD=False):
|
|
296
|
+
r"""
|
|
297
|
+
Attempt to prove the Birch and Swinnerton-Dyer conjectural
|
|
298
|
+
formula for `E`, returning a list of primes `p` for which this
|
|
299
|
+
function fails to prove BSD(E,p).
|
|
300
|
+
|
|
301
|
+
Here, BSD(E,p) is the
|
|
302
|
+
statement: "the Birch and Swinnerton-Dyer formula holds up to a
|
|
303
|
+
rational number coprime to `p`."
|
|
304
|
+
|
|
305
|
+
INPUT:
|
|
306
|
+
|
|
307
|
+
- ``E`` -- an elliptic curve
|
|
308
|
+
|
|
309
|
+
- ``verbosity`` -- integer; how much information about the proof to print
|
|
310
|
+
|
|
311
|
+
- 0: print nothing
|
|
312
|
+
- 1: print sketch of proof
|
|
313
|
+
- 2: print information about remaining primes
|
|
314
|
+
|
|
315
|
+
- ``two_desc`` -- string (default: ``'mwrank'``); what to use for the
|
|
316
|
+
two-descent. Options are ``'mwrank', 'pari', 'sage'``.
|
|
317
|
+
|
|
318
|
+
- ``proof`` -- boolean or ``None`` (default: None, see
|
|
319
|
+
proof.elliptic_curve or sage.structure.proof). If ``False``, this
|
|
320
|
+
function just immediately returns the empty list.
|
|
321
|
+
|
|
322
|
+
- ``secs_hi`` -- maximum number of seconds to try to compute the
|
|
323
|
+
Heegner index before switching over to trying to compute the
|
|
324
|
+
Heegner index bound. (Rank 0 only!)
|
|
325
|
+
|
|
326
|
+
- ``return_BSD`` -- boolean (default: ``False``); whether to return an object
|
|
327
|
+
which contains information to reconstruct a proof
|
|
328
|
+
|
|
329
|
+
.. NOTE::
|
|
330
|
+
|
|
331
|
+
When printing verbose output, phrases such as "by Mazur" are referring
|
|
332
|
+
to the following list of papers:
|
|
333
|
+
|
|
334
|
+
REFERENCES:
|
|
335
|
+
|
|
336
|
+
- [Cha2005]_
|
|
337
|
+
- [Jet2008]_
|
|
338
|
+
- [Kat2004]_
|
|
339
|
+
- [Kol1991]_
|
|
340
|
+
- [LW2015]_
|
|
341
|
+
- [LS]_
|
|
342
|
+
- [Maz1978]_
|
|
343
|
+
- [Rub1991]_
|
|
344
|
+
- [SW2013]_
|
|
345
|
+
- [GJPST2009]_
|
|
346
|
+
|
|
347
|
+
EXAMPLES::
|
|
348
|
+
|
|
349
|
+
sage: EllipticCurve('11a').prove_BSD(verbosity=2) # needs sage.graphs
|
|
350
|
+
p = 2: True by 2-descent
|
|
351
|
+
True for p not in {2, 5} by Kolyvagin.
|
|
352
|
+
Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
|
|
353
|
+
True for p = 5 by Kolyvagin bound
|
|
354
|
+
[]
|
|
355
|
+
|
|
356
|
+
sage: EllipticCurve('14a').prove_BSD(verbosity=2) # needs sage.graphs
|
|
357
|
+
p = 2: True by 2-descent
|
|
358
|
+
True for p not in {2, 3} by Kolyvagin.
|
|
359
|
+
Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
|
|
360
|
+
True for p = 3 by Kolyvagin bound
|
|
361
|
+
[]
|
|
362
|
+
|
|
363
|
+
sage: E = EllipticCurve("20a1")
|
|
364
|
+
sage: E.prove_BSD(verbosity=2) # needs sage.graphs
|
|
365
|
+
p = 2: True by 2-descent
|
|
366
|
+
True for p not in {2, 3} by Kolyvagin.
|
|
367
|
+
Kato further implies that #Sha[3] is trivial.
|
|
368
|
+
[]
|
|
369
|
+
|
|
370
|
+
sage: E = EllipticCurve("50b1")
|
|
371
|
+
sage: E.prove_BSD(verbosity=2) # needs sage.graphs
|
|
372
|
+
p = 2: True by 2-descent
|
|
373
|
+
True for p not in {2, 3, 5} by Kolyvagin.
|
|
374
|
+
Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
|
|
375
|
+
Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
|
|
376
|
+
True for p = 3 by Kolyvagin bound
|
|
377
|
+
True for p = 5 by Kolyvagin bound
|
|
378
|
+
[]
|
|
379
|
+
sage: E.prove_BSD(two_desc='pari') # needs sage.graphs
|
|
380
|
+
[]
|
|
381
|
+
|
|
382
|
+
A rank two curve::
|
|
383
|
+
|
|
384
|
+
sage: E = EllipticCurve('389a')
|
|
385
|
+
|
|
386
|
+
We know nothing with proof=True::
|
|
387
|
+
|
|
388
|
+
sage: E.prove_BSD() # needs sage.graphs
|
|
389
|
+
Set of all prime numbers: 2, 3, 5, 7, ...
|
|
390
|
+
|
|
391
|
+
We (think we) know everything with proof=False::
|
|
392
|
+
|
|
393
|
+
sage: E.prove_BSD(proof=False) # needs sage.graphs
|
|
394
|
+
[]
|
|
395
|
+
|
|
396
|
+
A curve of rank 0 and prime conductor::
|
|
397
|
+
|
|
398
|
+
sage: E = EllipticCurve('19a')
|
|
399
|
+
sage: E.prove_BSD(verbosity=2) # needs sage.graphs
|
|
400
|
+
p = 2: True by 2-descent
|
|
401
|
+
True for p not in {2, 3} by Kolyvagin.
|
|
402
|
+
Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
|
|
403
|
+
True for p = 3 by Kolyvagin bound
|
|
404
|
+
[]
|
|
405
|
+
|
|
406
|
+
sage: E = EllipticCurve('37a')
|
|
407
|
+
sage: E.rank()
|
|
408
|
+
1
|
|
409
|
+
sage: E._EllipticCurve_rational_field__rank
|
|
410
|
+
(1, True)
|
|
411
|
+
sage: E.analytic_rank = lambda : 0
|
|
412
|
+
sage: E.prove_BSD() # needs sage.graphs
|
|
413
|
+
Traceback (most recent call last):
|
|
414
|
+
...
|
|
415
|
+
RuntimeError: It seems that the rank conjecture does not hold for this curve
|
|
416
|
+
(Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field)!
|
|
417
|
+
This may be a counterexample to BSD, but is more likely a bug.
|
|
418
|
+
|
|
419
|
+
We test the consistency check for the 2-part of Sha::
|
|
420
|
+
|
|
421
|
+
sage: E = EllipticCurve('37a')
|
|
422
|
+
sage: S = E.sha(); S
|
|
423
|
+
Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x
|
|
424
|
+
over Rational Field
|
|
425
|
+
sage: def foo(use_database):
|
|
426
|
+
....: return 4
|
|
427
|
+
sage: S.an = foo
|
|
428
|
+
sage: E.prove_BSD() # needs sage.graphs
|
|
429
|
+
Traceback (most recent call last):
|
|
430
|
+
...
|
|
431
|
+
RuntimeError: Apparent contradiction: 0 <= rank(sha[2]) <= 0, but ord_2(sha_an) = 2
|
|
432
|
+
|
|
433
|
+
An example with a Tamagawa number at 5::
|
|
434
|
+
|
|
435
|
+
sage: E = EllipticCurve('123a1')
|
|
436
|
+
sage: E.prove_BSD(verbosity=2) # needs sage.graphs
|
|
437
|
+
p = 2: True by 2-descent
|
|
438
|
+
True for p not in {2, 5} by Kolyvagin.
|
|
439
|
+
Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
|
|
440
|
+
True for p = 5 by Kolyvagin bound
|
|
441
|
+
[]
|
|
442
|
+
|
|
443
|
+
A curve for which 3 divides the order of the Tate-Shafarevich group::
|
|
444
|
+
|
|
445
|
+
sage: E = EllipticCurve('681b')
|
|
446
|
+
sage: E.prove_BSD(verbosity=2) # long time # needs sage.graphs
|
|
447
|
+
p = 2: True by 2-descent...
|
|
448
|
+
True for p not in {2, 3} by Kolyvagin....
|
|
449
|
+
Remaining primes:
|
|
450
|
+
p = 3: irreducible, surjective, non-split multiplicative
|
|
451
|
+
(0 <= ord_p <= 2)
|
|
452
|
+
ord_p(#Sha_an) = 2
|
|
453
|
+
[3]
|
|
454
|
+
|
|
455
|
+
A curve for which we need to use ``heegner_index_bound``::
|
|
456
|
+
|
|
457
|
+
sage: E = EllipticCurve('198b')
|
|
458
|
+
sage: E.prove_BSD(verbosity=1, secs_hi=1) # needs sage.graphs
|
|
459
|
+
p = 2: True by 2-descent
|
|
460
|
+
True for p not in {2, 3} by Kolyvagin.
|
|
461
|
+
[3]
|
|
462
|
+
|
|
463
|
+
The ``return_BSD`` option gives an object with detailed information
|
|
464
|
+
about the proof::
|
|
465
|
+
|
|
466
|
+
sage: # needs sage.graphs
|
|
467
|
+
sage: E = EllipticCurve('26b')
|
|
468
|
+
sage: B = E.prove_BSD(return_BSD=True)
|
|
469
|
+
sage: B.two_tor_rk
|
|
470
|
+
0
|
|
471
|
+
sage: B.N
|
|
472
|
+
26
|
|
473
|
+
sage: B.gens
|
|
474
|
+
[]
|
|
475
|
+
sage: B.primes
|
|
476
|
+
[]
|
|
477
|
+
sage: B.heegner_indexes
|
|
478
|
+
{-23: 2}
|
|
479
|
+
|
|
480
|
+
TESTS:
|
|
481
|
+
|
|
482
|
+
This was fixed by :issue:`8184` and :issue:`7575`::
|
|
483
|
+
|
|
484
|
+
sage: EllipticCurve('438e1').prove_BSD(verbosity=1) # needs sage.graphs
|
|
485
|
+
p = 2: True by 2-descent...
|
|
486
|
+
True for p not in {2} by Kolyvagin.
|
|
487
|
+
[]
|
|
488
|
+
|
|
489
|
+
::
|
|
490
|
+
|
|
491
|
+
sage: E = EllipticCurve('960d1')
|
|
492
|
+
sage: E.prove_BSD(verbosity=1) # long time (4s on sage.math, 2011) # needs sage.graphs
|
|
493
|
+
p = 2: True by 2-descent
|
|
494
|
+
True for p not in {2} by Kolyvagin.
|
|
495
|
+
[]
|
|
496
|
+
|
|
497
|
+
::
|
|
498
|
+
|
|
499
|
+
sage: E = EllipticCurve('66b3')
|
|
500
|
+
sage: E.prove_BSD(two_desc="pari",verbosity=1) # needs sage.graphs
|
|
501
|
+
p = 2: True by 2-descent
|
|
502
|
+
True for p not in {2} by Kolyvagin.
|
|
503
|
+
[]
|
|
504
|
+
"""
|
|
505
|
+
if proof is None:
|
|
506
|
+
from sage.structure.proof.proof import get_flag
|
|
507
|
+
proof = get_flag(proof, "elliptic_curve")
|
|
508
|
+
else:
|
|
509
|
+
proof = bool(proof)
|
|
510
|
+
if not proof:
|
|
511
|
+
return []
|
|
512
|
+
from copy import copy
|
|
513
|
+
BSD = BSD_data()
|
|
514
|
+
# We replace this curve by the optimal curve, which we can do since
|
|
515
|
+
# truth of BSD(E,p) is invariant under isogeny.
|
|
516
|
+
BSD.curve = E.optimal_curve()
|
|
517
|
+
if BSD.curve.has_cm():
|
|
518
|
+
# ensure that CM is by a maximal order
|
|
519
|
+
non_max_j_invs = [-12288000, 54000, 287496, 16581375]
|
|
520
|
+
if BSD.curve.j_invariant() in non_max_j_invs: # is this possible for optimal curves?
|
|
521
|
+
if verbosity > 0:
|
|
522
|
+
print('CM by non maximal order: switching curves')
|
|
523
|
+
for E in BSD.curve.isogeny_class():
|
|
524
|
+
if E.j_invariant() not in non_max_j_invs:
|
|
525
|
+
BSD.curve = E
|
|
526
|
+
break
|
|
527
|
+
BSD.update()
|
|
528
|
+
galrep = BSD.curve.galois_representation()
|
|
529
|
+
|
|
530
|
+
if two_desc == 'mwrank':
|
|
531
|
+
M = mwrank_two_descent_work(BSD.curve, BSD.two_tor_rk)
|
|
532
|
+
elif two_desc == 'pari':
|
|
533
|
+
M = pari_two_descent_work(BSD.curve)
|
|
534
|
+
elif two_desc == 'sage':
|
|
535
|
+
M = native_two_isogeny_descent_work(BSD.curve, BSD.two_tor_rk)
|
|
536
|
+
else:
|
|
537
|
+
raise NotImplementedError()
|
|
538
|
+
rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens = M
|
|
539
|
+
assert sha2_lower_bd <= sha2_upper_bd
|
|
540
|
+
if gens is not None:
|
|
541
|
+
gens = BSD.curve.saturation(gens)[0]
|
|
542
|
+
if rank_lower_bd > rank_upper_bd:
|
|
543
|
+
raise RuntimeError("Apparent contradiction: %d <= rank <= %d." % (rank_lower_bd, rank_upper_bd))
|
|
544
|
+
BSD.two_selmer_rank = rank_upper_bd + sha2_lower_bd + BSD.two_tor_rk
|
|
545
|
+
if sha2_upper_bd == sha2_lower_bd:
|
|
546
|
+
BSD.rank = rank_lower_bd
|
|
547
|
+
BSD.bounds[2] = (sha2_lower_bd, sha2_upper_bd)
|
|
548
|
+
else:
|
|
549
|
+
BSD.rank = BSD.curve.rank(use_database=True)
|
|
550
|
+
sha2_upper_bd -= (BSD.rank - rank_lower_bd)
|
|
551
|
+
BSD.bounds[2] = (sha2_lower_bd, sha2_upper_bd)
|
|
552
|
+
if verbosity > 0:
|
|
553
|
+
print("Unable to compute the rank exactly -- used database.")
|
|
554
|
+
if rank_lower_bd > 1:
|
|
555
|
+
# We do not know BSD(E,p) for even a single p, since it's
|
|
556
|
+
# an open problem to show that L^r(E,1)/(Reg*Omega) is
|
|
557
|
+
# rational for any curve with r >= 2.
|
|
558
|
+
from sage.sets.primes import Primes
|
|
559
|
+
BSD.primes = Primes()
|
|
560
|
+
if return_BSD:
|
|
561
|
+
BSD.rank = rank_lower_bd
|
|
562
|
+
return BSD
|
|
563
|
+
return BSD.primes
|
|
564
|
+
if (BSD.sha_an.ord(2) == 0) != (BSD.bounds[2][1] == 0):
|
|
565
|
+
raise 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)))
|
|
566
|
+
if BSD.bounds[2][0] == BSD.sha_an.ord(2) and BSD.sha_an.ord(2) == BSD.bounds[2][1]:
|
|
567
|
+
if verbosity > 0:
|
|
568
|
+
print('p = 2: True by 2-descent')
|
|
569
|
+
BSD.primes = []
|
|
570
|
+
BSD.bounds.pop(2)
|
|
571
|
+
BSD.proof[2] = ['2-descent']
|
|
572
|
+
else:
|
|
573
|
+
BSD.primes = [2]
|
|
574
|
+
BSD.proof[2] = [('2-descent',) + BSD.bounds[2]]
|
|
575
|
+
if len(gens) > rank_lower_bd or rank_lower_bd > rank_upper_bd:
|
|
576
|
+
raise RuntimeError("Something went wrong with 2-descent.")
|
|
577
|
+
if BSD.rank != len(gens):
|
|
578
|
+
gens = BSD.curve.gens(proof=True)
|
|
579
|
+
if BSD.rank != len(gens):
|
|
580
|
+
raise RuntimeError("Could not get generators")
|
|
581
|
+
BSD.gens = [BSD.curve.point(x, check=True) for x in gens]
|
|
582
|
+
|
|
583
|
+
if BSD.rank != BSD.curve.analytic_rank():
|
|
584
|
+
raise 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)
|
|
585
|
+
|
|
586
|
+
# reduce set of remaining primes to a finite set
|
|
587
|
+
kolyvagin_primes = []
|
|
588
|
+
heegner_index = None
|
|
589
|
+
if BSD.rank == 0:
|
|
590
|
+
for D in BSD.curve.heegner_discriminants_list(10):
|
|
591
|
+
max_height = max(13, BSD.curve.quadratic_twist(D).CPS_height_bound())
|
|
592
|
+
heegner_primes = -1
|
|
593
|
+
while heegner_primes == -1:
|
|
594
|
+
if max_height > 21:
|
|
595
|
+
break
|
|
596
|
+
heegner_primes, _, exact = BSD.curve.heegner_index_bound(D, max_height=max_height)
|
|
597
|
+
max_height += 1
|
|
598
|
+
if isinstance(heegner_primes, list):
|
|
599
|
+
break
|
|
600
|
+
if not isinstance(heegner_primes, list):
|
|
601
|
+
raise RuntimeError("Tried 10 Heegner discriminants, and heegner_index_bound failed each time.")
|
|
602
|
+
if exact is not False:
|
|
603
|
+
heegner_index = exact
|
|
604
|
+
BSD.heegner_indexes[D] = exact
|
|
605
|
+
else:
|
|
606
|
+
BSD.heegner_index_upper_bound[D] = max(heegner_primes + [1])
|
|
607
|
+
if 2 in heegner_primes:
|
|
608
|
+
heegner_primes.remove(2)
|
|
609
|
+
else: # rank 1
|
|
610
|
+
for D in BSD.curve.heegner_discriminants_list(10):
|
|
611
|
+
I = BSD.curve.heegner_index(D)
|
|
612
|
+
J = I.is_int()
|
|
613
|
+
if J[0] and J[1] > 0:
|
|
614
|
+
I = J[1]
|
|
615
|
+
else:
|
|
616
|
+
J = (2 * I).is_int()
|
|
617
|
+
if J[0] and J[1] > 0:
|
|
618
|
+
I = J[1]
|
|
619
|
+
else:
|
|
620
|
+
continue
|
|
621
|
+
heegner_index = I
|
|
622
|
+
BSD.heegner_indexes[D] = I
|
|
623
|
+
break
|
|
624
|
+
heegner_primes = [p for p in prime_divisors(heegner_index) if p != 2]
|
|
625
|
+
|
|
626
|
+
assert BSD.sha_an in ZZ and BSD.sha_an > 0
|
|
627
|
+
if BSD.curve.has_cm():
|
|
628
|
+
if BSD.curve.analytic_rank() == 0:
|
|
629
|
+
if verbosity > 0:
|
|
630
|
+
print(' p >= 5: true by Rubin')
|
|
631
|
+
BSD.primes.append(3)
|
|
632
|
+
else:
|
|
633
|
+
K = QuadraticField(BSD.curve.cm_discriminant(), 'a')
|
|
634
|
+
D_K = K.disc()
|
|
635
|
+
D_E = BSD.curve.discriminant()
|
|
636
|
+
if len(K.factor(3)) == 1: # 3 does not split in K
|
|
637
|
+
BSD.primes.append(3)
|
|
638
|
+
for p in prime_divisors(D_K):
|
|
639
|
+
if p >= 5:
|
|
640
|
+
BSD.primes.append(p)
|
|
641
|
+
for p in prime_divisors(D_E):
|
|
642
|
+
if p >= 5 and D_K % p and len(K.factor(p)) == 1:
|
|
643
|
+
# p is inert in K
|
|
644
|
+
BSD.primes.append(p)
|
|
645
|
+
for p in heegner_primes:
|
|
646
|
+
if p >= 5 and D_E % p and D_K % p and len(K.factor(p)) == 1:
|
|
647
|
+
# p is good for E and inert in K
|
|
648
|
+
kolyvagin_primes.append(p)
|
|
649
|
+
for p in prime_divisors(BSD.sha_an):
|
|
650
|
+
if p >= 5 and D_K % p and len(K.factor(p)) == 1:
|
|
651
|
+
if BSD.curve.is_good(p):
|
|
652
|
+
if verbosity > 2 and p in heegner_primes and heegner_index is None:
|
|
653
|
+
print('ALERT: Prime p (%d) >= 5 dividing sha_an, good for E, inert in K, in heegner_primes, should not divide the actual Heegner index')
|
|
654
|
+
# Note that the following check is not entirely
|
|
655
|
+
# exhaustive, in case there is a p not dividing
|
|
656
|
+
# the Heegner index in heegner_primes,
|
|
657
|
+
# for which only an outer bound was computed
|
|
658
|
+
if p not in heegner_primes:
|
|
659
|
+
raise 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))
|
|
660
|
+
if verbosity > 0:
|
|
661
|
+
print('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])
|
|
662
|
+
BSD.proof['finite'] = copy(BSD.primes)
|
|
663
|
+
else: # no CM
|
|
664
|
+
# do some tricks to get to a finite set without calling bound_kolyvagin
|
|
665
|
+
BSD.primes += [p for p in galrep.non_surjective() if p != 2]
|
|
666
|
+
for p in heegner_primes:
|
|
667
|
+
if p not in BSD.primes:
|
|
668
|
+
BSD.primes.append(p)
|
|
669
|
+
for p in prime_divisors(BSD.sha_an):
|
|
670
|
+
if p not in BSD.primes and p != 2:
|
|
671
|
+
BSD.primes.append(p)
|
|
672
|
+
if verbosity > 0:
|
|
673
|
+
s = str(BSD.primes)[1:-1]
|
|
674
|
+
if 2 not in BSD.primes:
|
|
675
|
+
if not s:
|
|
676
|
+
s = '2'
|
|
677
|
+
else:
|
|
678
|
+
s = '2, ' + s
|
|
679
|
+
print('True for p not in {' + s + '} by Kolyvagin.')
|
|
680
|
+
BSD.proof['finite'] = copy(BSD.primes)
|
|
681
|
+
primes_to_remove = []
|
|
682
|
+
for p in BSD.primes:
|
|
683
|
+
if p == 2:
|
|
684
|
+
continue
|
|
685
|
+
if galrep.is_surjective(p) and not BSD.curve.has_additive_reduction(p):
|
|
686
|
+
if BSD.curve.has_nonsplit_multiplicative_reduction(p):
|
|
687
|
+
if BSD.rank > 0:
|
|
688
|
+
continue
|
|
689
|
+
if p == 3:
|
|
690
|
+
if (not (BSD.curve.is_ordinary(p) and BSD.curve.is_good(p))) and (not BSD.curve.has_split_multiplicative_reduction(p)):
|
|
691
|
+
continue
|
|
692
|
+
if BSD.rank > 0:
|
|
693
|
+
continue
|
|
694
|
+
if verbosity > 1:
|
|
695
|
+
print(' p = %d: Trying p_primary_bound' % p)
|
|
696
|
+
p_bound = BSD.Sha.p_primary_bound(p)
|
|
697
|
+
if p in BSD.proof:
|
|
698
|
+
BSD.proof[p].append(('Stein-Wuthrich', p_bound))
|
|
699
|
+
else:
|
|
700
|
+
BSD.proof[p] = [('Stein-Wuthrich', p_bound)]
|
|
701
|
+
if BSD.sha_an.ord(p) == 0 and p_bound == 0:
|
|
702
|
+
if verbosity > 0:
|
|
703
|
+
print('True for p=%d by Stein-Wuthrich.' % p)
|
|
704
|
+
primes_to_remove.append(p)
|
|
705
|
+
else:
|
|
706
|
+
if p in BSD.bounds:
|
|
707
|
+
BSD.bounds[p][1] = min(BSD.bounds[p][1], p_bound)
|
|
708
|
+
else:
|
|
709
|
+
BSD.bounds[p] = (0, p_bound)
|
|
710
|
+
print('Analytic %d-rank is ' % p + str(BSD.sha_an.ord(p)) + ', actual %d-rank is at most %d.' % (p, p_bound))
|
|
711
|
+
print(' by Stein-Wuthrich.\n')
|
|
712
|
+
for p in primes_to_remove:
|
|
713
|
+
BSD.primes.remove(p)
|
|
714
|
+
kolyvagin_primes = []
|
|
715
|
+
for p in BSD.primes:
|
|
716
|
+
if p == 2:
|
|
717
|
+
continue
|
|
718
|
+
if galrep.is_surjective(p):
|
|
719
|
+
kolyvagin_primes.append(p)
|
|
720
|
+
for p in kolyvagin_primes:
|
|
721
|
+
BSD.primes.remove(p)
|
|
722
|
+
# apply other hypotheses which imply Kolyvagin's bound holds
|
|
723
|
+
D_K = QuadraticField(D, 'a').disc()
|
|
724
|
+
|
|
725
|
+
# Cha's hypothesis
|
|
726
|
+
for p in BSD.primes:
|
|
727
|
+
if p == 2:
|
|
728
|
+
continue
|
|
729
|
+
if D_K % p != 0 and BSD.N % (p**2) != 0 and galrep.is_irreducible(p):
|
|
730
|
+
if verbosity > 0:
|
|
731
|
+
print('Kolyvagin\'s bound for p = %d applies by Cha.' % p)
|
|
732
|
+
if p in BSD.proof:
|
|
733
|
+
BSD.proof[p].append('Cha')
|
|
734
|
+
else:
|
|
735
|
+
BSD.proof[p] = ['Cha']
|
|
736
|
+
kolyvagin_primes.append(p)
|
|
737
|
+
# Stein et al replaced
|
|
738
|
+
for p in BSD.primes:
|
|
739
|
+
# the lemma about the vanishing of H^1 is false in Stein et al for p=5 and 11
|
|
740
|
+
# here is the correction from Lawson-Wuthrich. Especially Theorem 14 in
|
|
741
|
+
# [LW2015] above.
|
|
742
|
+
if p in kolyvagin_primes or p == 2 or D_K % p == 0:
|
|
743
|
+
continue
|
|
744
|
+
crit_lw = False
|
|
745
|
+
if p > 11 or p == 7:
|
|
746
|
+
crit_lw = True
|
|
747
|
+
elif p == 11:
|
|
748
|
+
if BSD.N != 121 or BSD.curve.label() != "121c2":
|
|
749
|
+
crit_lw = True
|
|
750
|
+
elif galrep.is_irreducible(p):
|
|
751
|
+
crit_lw = True
|
|
752
|
+
else:
|
|
753
|
+
phis = BSD.curve.isogenies_prime_degree(p)
|
|
754
|
+
if len(phis) != 1:
|
|
755
|
+
crit_lw = True
|
|
756
|
+
else:
|
|
757
|
+
C = phis[0].codomain()
|
|
758
|
+
if p == 3:
|
|
759
|
+
if BSD.curve.torsion_order() % p != 0 and C.torsion_order() % p != 0:
|
|
760
|
+
crit_lw = True
|
|
761
|
+
else: # p == 5
|
|
762
|
+
Et = BSD.curve.quadratic_twist(5)
|
|
763
|
+
if Et.torsion_order() % p != 0 and C.torsion_order() % p != 0:
|
|
764
|
+
crit_lw = True
|
|
765
|
+
if crit_lw:
|
|
766
|
+
if verbosity > 0:
|
|
767
|
+
print('Kolyvagin\'s bound for p = %d applies by Lawson-Wuthrich' % p)
|
|
768
|
+
kolyvagin_primes.append(p)
|
|
769
|
+
if p in BSD.proof:
|
|
770
|
+
BSD.proof[p].append('Lawson-Wuthrich')
|
|
771
|
+
else:
|
|
772
|
+
BSD.proof[p] = ['Lawson-Wuthrich']
|
|
773
|
+
for p in kolyvagin_primes:
|
|
774
|
+
if p in BSD.primes:
|
|
775
|
+
BSD.primes.remove(p)
|
|
776
|
+
|
|
777
|
+
# apply Kolyvagin's bound
|
|
778
|
+
primes_to_remove = []
|
|
779
|
+
for p in kolyvagin_primes:
|
|
780
|
+
if p == 2:
|
|
781
|
+
continue
|
|
782
|
+
if p not in heegner_primes:
|
|
783
|
+
ord_p_bound = 0
|
|
784
|
+
elif heegner_index is not None: # p must divide heegner_index
|
|
785
|
+
ord_p_bound = 2 * heegner_index.ord(p)
|
|
786
|
+
# Here Jetchev's results apply.
|
|
787
|
+
m_max = max([BSD.curve.tamagawa_number(q).ord(p) for q in BSD.N.prime_divisors()])
|
|
788
|
+
if m_max > 0:
|
|
789
|
+
if verbosity > 0:
|
|
790
|
+
print('Jetchev\'s results apply (at p = %d) with m_max =' % p, m_max)
|
|
791
|
+
if p in BSD.proof:
|
|
792
|
+
BSD.proof[p].append(('Jetchev', m_max))
|
|
793
|
+
else:
|
|
794
|
+
BSD.proof[p] = [('Jetchev', m_max)]
|
|
795
|
+
ord_p_bound -= 2 * m_max
|
|
796
|
+
else: # Heegner index is None
|
|
797
|
+
for D in BSD.heegner_index_upper_bound:
|
|
798
|
+
M = BSD.heegner_index_upper_bound[D]
|
|
799
|
+
ord_p_bound = 0
|
|
800
|
+
while p**(ord_p_bound + 1) <= M**2:
|
|
801
|
+
ord_p_bound += 1
|
|
802
|
+
# now ord_p_bound is one on I_K!!!
|
|
803
|
+
ord_p_bound *= 2 # by Kolyvagin, now ord_p_bound is one on #Sha
|
|
804
|
+
break
|
|
805
|
+
if p in BSD.proof:
|
|
806
|
+
BSD.proof[p].append(('Kolyvagin', ord_p_bound))
|
|
807
|
+
else:
|
|
808
|
+
BSD.proof[p] = [('Kolyvagin', ord_p_bound)]
|
|
809
|
+
if BSD.sha_an.ord(p) == 0 and ord_p_bound == 0:
|
|
810
|
+
if verbosity > 0:
|
|
811
|
+
print('True for p = %d by Kolyvagin bound' % p)
|
|
812
|
+
primes_to_remove.append(p)
|
|
813
|
+
elif BSD.sha_an.ord(p) > ord_p_bound:
|
|
814
|
+
raise 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)))
|
|
815
|
+
else: # BSD.sha_an.ord(p) <= ord_p_bound != 0:
|
|
816
|
+
if p in BSD.bounds:
|
|
817
|
+
low = BSD.bounds[p][0]
|
|
818
|
+
BSD.bounds[p] = (low, min(BSD.bounds[p][1], ord_p_bound))
|
|
819
|
+
else:
|
|
820
|
+
BSD.bounds[p] = (0, ord_p_bound)
|
|
821
|
+
for p in primes_to_remove:
|
|
822
|
+
kolyvagin_primes.remove(p)
|
|
823
|
+
BSD.primes = list(set(BSD.primes).union(set(kolyvagin_primes)))
|
|
824
|
+
|
|
825
|
+
# Kato's bound
|
|
826
|
+
if BSD.rank == 0 and not BSD.curve.has_cm():
|
|
827
|
+
L_over_Omega = BSD.curve.lseries().L_ratio()
|
|
828
|
+
kato_primes = BSD.Sha.bound_kato()
|
|
829
|
+
primes_to_remove = []
|
|
830
|
+
for p in BSD.primes:
|
|
831
|
+
if p == 2:
|
|
832
|
+
continue
|
|
833
|
+
if p not in kato_primes:
|
|
834
|
+
if verbosity > 0:
|
|
835
|
+
print('Kato further implies that #Sha[%d] is trivial.' % p)
|
|
836
|
+
primes_to_remove.append(p)
|
|
837
|
+
if p in BSD.proof:
|
|
838
|
+
BSD.proof[p].append(('Kato', 0))
|
|
839
|
+
else:
|
|
840
|
+
BSD.proof[p] = [('Kato', 0)]
|
|
841
|
+
if p not in [2, 3] and BSD.N % p != 0:
|
|
842
|
+
if galrep.is_surjective(p):
|
|
843
|
+
bd = L_over_Omega.valuation(p)
|
|
844
|
+
if verbosity > 1:
|
|
845
|
+
print('Kato implies that ord_p(#Sha[%d]) <= %d ' % (p, bd))
|
|
846
|
+
if p in BSD.proof:
|
|
847
|
+
BSD.proof[p].append(('Kato', bd))
|
|
848
|
+
else:
|
|
849
|
+
BSD.proof[p] = [('Kato', bd)]
|
|
850
|
+
if p in BSD.bounds:
|
|
851
|
+
low = BSD.bounds[p][0]
|
|
852
|
+
BSD.bounds[p][1] = (low, min(BSD.bounds[p][1], bd))
|
|
853
|
+
else:
|
|
854
|
+
BSD.bounds[p] = (0, bd)
|
|
855
|
+
for p in primes_to_remove:
|
|
856
|
+
BSD.primes.remove(p)
|
|
857
|
+
|
|
858
|
+
# Mazur
|
|
859
|
+
primes_to_remove = []
|
|
860
|
+
if BSD.N.is_prime():
|
|
861
|
+
for p in BSD.primes:
|
|
862
|
+
if p == 2:
|
|
863
|
+
continue
|
|
864
|
+
if galrep.is_reducible(p):
|
|
865
|
+
primes_to_remove.append(p)
|
|
866
|
+
if verbosity > 0:
|
|
867
|
+
print('True for p=%s by Mazur' % p)
|
|
868
|
+
for p in primes_to_remove:
|
|
869
|
+
BSD.primes.remove(p)
|
|
870
|
+
if p in BSD.proof:
|
|
871
|
+
BSD.proof[p].append('Mazur')
|
|
872
|
+
else:
|
|
873
|
+
BSD.proof[p] = ['Mazur']
|
|
874
|
+
|
|
875
|
+
BSD.primes.sort()
|
|
876
|
+
|
|
877
|
+
# Try harder to compute the Heegner index, where it matters
|
|
878
|
+
if heegner_index is None:
|
|
879
|
+
max_height = max(max_height, 18)
|
|
880
|
+
for D in BSD.heegner_index_upper_bound:
|
|
881
|
+
M = BSD.heegner_index_upper_bound[D]
|
|
882
|
+
for p in kolyvagin_primes:
|
|
883
|
+
if p not in BSD.primes or p == 3:
|
|
884
|
+
continue
|
|
885
|
+
if verbosity > 0:
|
|
886
|
+
print(' p = %d: Trying harder for Heegner index' % p)
|
|
887
|
+
obt = 0
|
|
888
|
+
while p**(BSD.sha_an.ord(p) / 2 + 1) <= M and max_height < 22:
|
|
889
|
+
if verbosity > 2:
|
|
890
|
+
print(' trying max_height =', max_height)
|
|
891
|
+
old_bound = M
|
|
892
|
+
M, _, exact = BSD.curve.heegner_index_bound(D, max_height=max_height, secs_dc=secs_hi)
|
|
893
|
+
if M == -1:
|
|
894
|
+
max_height += 1
|
|
895
|
+
continue
|
|
896
|
+
if exact is not False:
|
|
897
|
+
heegner_index = exact
|
|
898
|
+
BSD.heegner_indexes[D] = exact
|
|
899
|
+
M = exact
|
|
900
|
+
if verbosity > 2:
|
|
901
|
+
print(' heegner index =', M)
|
|
902
|
+
else:
|
|
903
|
+
M = max(M + [1])
|
|
904
|
+
if verbosity > 2:
|
|
905
|
+
print(' bound =', M)
|
|
906
|
+
if old_bound == M:
|
|
907
|
+
obt += 1
|
|
908
|
+
if obt == 2:
|
|
909
|
+
break
|
|
910
|
+
max_height += 1
|
|
911
|
+
BSD.heegner_index_upper_bound[D] = min(M, BSD.heegner_index_upper_bound[D])
|
|
912
|
+
low, upp = BSD.bounds[p]
|
|
913
|
+
expn = 0
|
|
914
|
+
while p**(expn + 1) <= M:
|
|
915
|
+
expn += 1
|
|
916
|
+
if 2 * expn < upp:
|
|
917
|
+
upp = 2 * expn
|
|
918
|
+
BSD.bounds[p] = (low, upp)
|
|
919
|
+
if verbosity > 0:
|
|
920
|
+
print(' got better bound on ord_p =', upp)
|
|
921
|
+
if low == upp:
|
|
922
|
+
if upp != BSD.sha_an.ord(p):
|
|
923
|
+
raise RuntimeError
|
|
924
|
+
else:
|
|
925
|
+
if verbosity > 0:
|
|
926
|
+
print(' proven!')
|
|
927
|
+
BSD.primes.remove(p)
|
|
928
|
+
break
|
|
929
|
+
for p in kolyvagin_primes:
|
|
930
|
+
if p not in BSD.primes or p == 3:
|
|
931
|
+
continue
|
|
932
|
+
for D in BSD.curve.heegner_discriminants_list(4):
|
|
933
|
+
if D in BSD.heegner_index_upper_bound:
|
|
934
|
+
continue
|
|
935
|
+
print(' discriminant', D)
|
|
936
|
+
if verbosity > 0:
|
|
937
|
+
print('p = %d: Trying discriminant = %d for Heegner index' % (p, D))
|
|
938
|
+
max_height = max(10, BSD.curve.quadratic_twist(D).CPS_height_bound())
|
|
939
|
+
obt = 0
|
|
940
|
+
while True:
|
|
941
|
+
if verbosity > 2:
|
|
942
|
+
print(' trying max_height =', max_height)
|
|
943
|
+
old_bound = M
|
|
944
|
+
if p**(BSD.sha_an.ord(p) / 2 + 1) > M or max_height >= 22:
|
|
945
|
+
break
|
|
946
|
+
M, _, exact = BSD.curve.heegner_index_bound(D, max_height=max_height, secs_dc=secs_hi)
|
|
947
|
+
if M == -1:
|
|
948
|
+
max_height += 1
|
|
949
|
+
continue
|
|
950
|
+
if exact is not False:
|
|
951
|
+
heegner_index = exact
|
|
952
|
+
BSD.heegner_indexes[D] = exact
|
|
953
|
+
M = exact
|
|
954
|
+
if verbosity > 2:
|
|
955
|
+
print(' heegner index =', M)
|
|
956
|
+
else:
|
|
957
|
+
M = max(M + [1])
|
|
958
|
+
if verbosity > 2:
|
|
959
|
+
print(' bound =', M)
|
|
960
|
+
if old_bound == M:
|
|
961
|
+
obt += 1
|
|
962
|
+
if obt == 2:
|
|
963
|
+
break
|
|
964
|
+
max_height += 1
|
|
965
|
+
BSD.heegner_index_upper_bound[D] = M
|
|
966
|
+
low, upp = BSD.bounds[p]
|
|
967
|
+
expn = 0
|
|
968
|
+
while p**(expn + 1) <= M:
|
|
969
|
+
expn += 1
|
|
970
|
+
if 2 * expn < upp:
|
|
971
|
+
upp = 2 * expn
|
|
972
|
+
BSD.bounds[p] = (low, upp)
|
|
973
|
+
if verbosity > 0:
|
|
974
|
+
print(' got better bound =', upp)
|
|
975
|
+
if low == upp:
|
|
976
|
+
if upp != BSD.sha_an.ord(p):
|
|
977
|
+
raise RuntimeError
|
|
978
|
+
else:
|
|
979
|
+
if verbosity > 0:
|
|
980
|
+
print(' proven!')
|
|
981
|
+
BSD.primes.remove(p)
|
|
982
|
+
break
|
|
983
|
+
|
|
984
|
+
# some extra information
|
|
985
|
+
if verbosity > 1:
|
|
986
|
+
if BSD.primes:
|
|
987
|
+
print('Remaining primes:')
|
|
988
|
+
for p in BSD.primes:
|
|
989
|
+
s = 'p = ' + str(p) + ': '
|
|
990
|
+
if galrep.is_irreducible(p):
|
|
991
|
+
s += 'ir'
|
|
992
|
+
s += 'reducible, '
|
|
993
|
+
if not galrep.is_surjective(p):
|
|
994
|
+
s += 'not '
|
|
995
|
+
s += 'surjective, '
|
|
996
|
+
a_p = BSD.curve.an(p)
|
|
997
|
+
if BSD.curve.is_good(p):
|
|
998
|
+
if a_p % p != 0:
|
|
999
|
+
s += 'good ordinary'
|
|
1000
|
+
else:
|
|
1001
|
+
s += 'good, non-ordinary'
|
|
1002
|
+
else:
|
|
1003
|
+
assert BSD.curve.is_minimal()
|
|
1004
|
+
if a_p == 0:
|
|
1005
|
+
s += 'additive'
|
|
1006
|
+
elif a_p == 1:
|
|
1007
|
+
s += 'split multiplicative'
|
|
1008
|
+
elif a_p == -1:
|
|
1009
|
+
s += 'non-split multiplicative'
|
|
1010
|
+
if BSD.curve.tamagawa_product() % p == 0:
|
|
1011
|
+
s += ', divides a Tamagawa number'
|
|
1012
|
+
if p in BSD.bounds:
|
|
1013
|
+
s += '\n (%d <= ord_p <= %d)' % BSD.bounds[p]
|
|
1014
|
+
else:
|
|
1015
|
+
s += '\n (no bounds found)'
|
|
1016
|
+
s += '\n ord_p(#Sha_an) = %d' % BSD.sha_an.ord(p)
|
|
1017
|
+
if heegner_index is None:
|
|
1018
|
+
may_divide = True
|
|
1019
|
+
for D in BSD.heegner_index_upper_bound:
|
|
1020
|
+
if p > BSD.heegner_index_upper_bound[D] or p not in kolyvagin_primes:
|
|
1021
|
+
may_divide = False
|
|
1022
|
+
if may_divide:
|
|
1023
|
+
s += '\n may divide the Heegner index, for which only a bound was computed'
|
|
1024
|
+
print(s)
|
|
1025
|
+
|
|
1026
|
+
if BSD.curve.has_cm():
|
|
1027
|
+
if BSD.rank == 1:
|
|
1028
|
+
BSD.proof['reason_finite'] = 'Rubin&Kolyvagin'
|
|
1029
|
+
else:
|
|
1030
|
+
BSD.proof['reason_finite'] = 'Rubin'
|
|
1031
|
+
else:
|
|
1032
|
+
BSD.proof['reason_finite'] = 'Kolyvagin'
|
|
1033
|
+
# reduce memory footprint of BSD object:
|
|
1034
|
+
BSD.curve = BSD.curve.label()
|
|
1035
|
+
BSD.Sha = None
|
|
1036
|
+
return BSD if return_BSD else BSD.primes
|