passagemath-schemes 10.6.40__cp314-cp314-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.

Files changed (314) 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.6.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.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 +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -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 +720 -0
  40. sage/modular/abvar/homspace.py +998 -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 +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -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 +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -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 +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-314-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 +2017 -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 +1071 -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 +815 -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 +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -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 +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. 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