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