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,1816 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.rings.padics
3
+ #
4
+ # All these methods are imported in EllipticCurve_rational_field,
5
+ # so there is no reason to add this module to the documentation.
6
+ r"""
7
+ Miscellaneous `p`-adic methods
8
+ """
9
+
10
+ ######################################################################
11
+ # Copyright (C) 2007 William Stein <wstein@gmail.com>
12
+ #
13
+ # Distributed under the terms of the GNU General Public License (GPL)
14
+ #
15
+ # This code is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
+ # General Public License for more details.
19
+ #
20
+ # The full text of the GPL is available at:
21
+ #
22
+ # https://www.gnu.org/licenses/
23
+ ######################################################################
24
+
25
+ import math
26
+
27
+ from sage.arith.functions import lcm as LCM
28
+ from sage.arith.misc import valuation
29
+ from sage.matrix.constructor import Matrix as matrix
30
+ from sage.misc.cachefunc import cached_method
31
+ from sage.misc.lazy_import import lazy_import
32
+ from sage.rings.big_oh import O
33
+ from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
34
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers
35
+ from sage.rings.integer import Integer
36
+ from sage.rings.laurent_series_ring import LaurentSeriesRing
37
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
38
+ from sage.rings.power_series_ring import PowerSeriesRing
39
+ from sage.rings.rational_field import RationalField
40
+ import sage.schemes.hyperelliptic_curves.hypellfrob
41
+ import sage.schemes.hyperelliptic_curves.monsky_washnitzer
42
+
43
+ lazy_import('sage.rings.padics.factory', ['Qp', 'Zp'])
44
+
45
+
46
+ from . import padic_lseries as plseries
47
+
48
+ sqrt = math.sqrt
49
+
50
+
51
+ def __check_padic_hypotheses(self, p):
52
+ r"""
53
+ Helper function that determines if `p`
54
+ is an odd prime of good ordinary reduction.
55
+
56
+ EXAMPLES::
57
+
58
+ sage: # needs database_cremona_mini_ellcurve
59
+ sage: E = EllipticCurve('11a1')
60
+ sage: from sage.schemes.elliptic_curves.padics import __check_padic_hypotheses
61
+ sage: __check_padic_hypotheses(E,5)
62
+ 5
63
+ sage: __check_padic_hypotheses(E,29)
64
+ Traceback (most recent call last):
65
+ ...
66
+ ArithmeticError: p must be a good ordinary prime
67
+ """
68
+ p = Integer(p)
69
+ if not p.is_prime():
70
+ raise ValueError("p = (%s) must be prime" % p)
71
+ if p == 2:
72
+ raise ValueError("p must be odd")
73
+ if self.conductor() % p == 0 or self.ap(p) % p == 0:
74
+ raise ArithmeticError("p must be a good ordinary prime")
75
+ return p
76
+
77
+
78
+ def _normalize_padic_lseries(self, p, normalize, implementation, precision):
79
+ r"""
80
+ Normalize parameters for :meth:`padic_lseries`.
81
+
82
+ TESTS::
83
+
84
+ sage: from sage.schemes.elliptic_curves.padics import _normalize_padic_lseries
85
+ sage: u = _normalize_padic_lseries(None, 5, None, 'sage', 10)
86
+ sage: v = _normalize_padic_lseries(None, 5, "L_ratio", 'sage', 10)
87
+ sage: u == v
88
+ True
89
+ """
90
+ if implementation == 'eclib':
91
+ if normalize is None:
92
+ normalize = "L_ratio"
93
+ elif implementation == 'sage':
94
+ if normalize is None:
95
+ normalize = "L_ratio"
96
+ elif implementation == 'pollackstevens':
97
+ if precision is None:
98
+ raise ValueError("Must specify precision when using 'pollackstevens'")
99
+ if normalize is not None:
100
+ raise ValueError("The 'normalize' parameter is not used for Pollack-Stevens' overconvergent modular symbols")
101
+ elif implementation == "num":
102
+ if normalize is not None:
103
+ raise ValueError("The 'normalize' parameter is not used for numerical modular symbols")
104
+ else:
105
+ raise ValueError("Implementation should be one of 'sage', 'eclib', 'num' or 'pollackstevens'")
106
+ return (p, normalize, implementation, precision)
107
+
108
+
109
+ @cached_method(key=_normalize_padic_lseries)
110
+ def padic_lseries(self, p, normalize=None, implementation='eclib',
111
+ precision=None):
112
+ r"""
113
+ Return the `p`-adic `L`-series of ``self`` at
114
+ `p`, which is an object whose approx method computes
115
+ approximation to the true `p`-adic `L`-series to
116
+ any desired precision.
117
+
118
+ INPUT:
119
+
120
+ - ``p`` -- prime
121
+
122
+ - ``normalize`` -- 'L_ratio' (default), 'period' or 'none';
123
+ this is describes the way the modular symbols
124
+ are normalized. See modular_symbol for
125
+ more details.
126
+
127
+ - ``implementation`` -- 'eclib' (default), 'sage', 'num' or 'pollackstevens';
128
+ Whether to use John Cremona's eclib, the Sage implementation,
129
+ numerical modular symbols
130
+ or Pollack-Stevens' implementation of overconvergent
131
+ modular symbols.
132
+
133
+ EXAMPLES::
134
+
135
+ sage: # needs database_cremona_mini_ellcurve eclib
136
+ sage: E = EllipticCurve('37a')
137
+ sage: L = E.padic_lseries(5); L
138
+ 5-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
139
+ sage: type(L)
140
+ <class 'sage.schemes.elliptic_curves.padic_lseries.pAdicLseriesOrdinary'>
141
+
142
+ We compute the `3`-adic `L`-series of two curves of
143
+ rank `0` and in each case verify the interpolation property
144
+ for their leading coefficient (i.e., value at 0)::
145
+
146
+ sage: # needs database_cremona_mini_ellcurve
147
+ sage: e = EllipticCurve('11a')
148
+ sage: ms = e.modular_symbol()
149
+ sage: [ms(1/11), ms(1/3), ms(0), ms(oo)]
150
+ [0, -3/10, 1/5, 0]
151
+ sage: ms(0)
152
+ 1/5
153
+ sage: L = e.padic_lseries(3)
154
+ sage: P = L.series(5)
155
+ sage: P(0)
156
+ 2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)
157
+ sage: alpha = L.alpha(9); alpha
158
+ 2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + O(3^9)
159
+ sage: R.<x> = QQ[]
160
+ sage: f = x^2 - e.ap(3)*x + 3
161
+ sage: f(alpha)
162
+ O(3^9)
163
+ sage: r = e.lseries().L_ratio(); r # needs sage.graphs
164
+ 1/5
165
+ sage: (1 - alpha^(-1))^2 * r # needs sage.graphs
166
+ 2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + O(3^9)
167
+ sage: P(0)
168
+ 2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)
169
+
170
+ Next consider the curve 37b::
171
+
172
+ sage: # needs database_cremona_mini_ellcurve sage.graphs
173
+ sage: e = EllipticCurve('37b')
174
+ sage: L = e.padic_lseries(3)
175
+ sage: P = L.series(5)
176
+ sage: alpha = L.alpha(9); alpha
177
+ 1 + 2*3 + 3^2 + 2*3^5 + 2*3^7 + 3^8 + O(3^9)
178
+ sage: r = e.lseries().L_ratio(); r
179
+ 1/3
180
+ sage: (1 - alpha^(-1))^2 * r
181
+ 3 + 3^2 + 2*3^4 + 2*3^5 + 2*3^6 + 3^7 + O(3^9)
182
+ sage: P(0)
183
+ 3 + 3^2 + 2*3^4 + 2*3^5 + O(3^6)
184
+
185
+ We can use Sage modular symbols instead to compute the `L`-series::
186
+
187
+ sage: # needs database_cremona_mini_ellcurve sage.graphs
188
+ sage: e = EllipticCurve('11a')
189
+ sage: L = e.padic_lseries(3, implementation='sage')
190
+ sage: L.series(5, prec=10)
191
+ 2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7) + (1 + 3 + 2*3^2 + 3^3 + O(3^4))*T
192
+ + (1 + 2*3 + O(3^4))*T^2 + (3 + 2*3^2 + O(3^3))*T^3 + (2*3 + 3^2 + O(3^3))*T^4
193
+ + (2 + 2*3 + 2*3^2 + O(3^3))*T^5 + (1 + 3^2 + O(3^3))*T^6 + (2 + 3^2 + O(3^3))*T^7
194
+ + (2 + 2*3 + 2*3^2 + O(3^3))*T^8 + (2 + O(3^2))*T^9 + O(T^10)
195
+
196
+ Also the numerical modular symbols can be used.
197
+ This may allow for much larger conductor in some instances::
198
+
199
+ sage: E = EllipticCurve([101,103])
200
+ sage: L = E.padic_lseries(5, implementation='num')
201
+ sage: L.series(2) # needs sage.graphs
202
+ O(5^4) + (3 + O(5))*T + (1 + O(5))*T^2 + (3 + O(5))*T^3 + O(5)*T^4 + O(T^5)
203
+
204
+ Finally, we can use the overconvergent method of Pollack-Stevens.::
205
+
206
+ sage: # needs database_cremona_mini_ellcurve sage.graphs
207
+ sage: e = EllipticCurve('11a')
208
+ sage: L = e.padic_lseries(3, implementation='pollackstevens', precision=6)
209
+ sage: L.series(5)
210
+ 2 + 3 + 3^2 + 2*3^3 + 2*3^5 + O(3^6) + (1 + 3 + 2*3^2 + 3^3 + O(3^4))*T + (1 + 2*3 + O(3^2))*T^2 + (3 + O(3^2))*T^3 + O(3^0)*T^4 + O(T^5)
211
+ sage: L[3]
212
+ 3 + O(3^2)
213
+
214
+ Another example with a semistable prime.::
215
+
216
+ sage: # needs database_cremona_mini_ellcurve
217
+ sage: E = EllipticCurve("11a1")
218
+ sage: L = E.padic_lseries(11, implementation='pollackstevens', precision=3)
219
+ sage: L[1]
220
+ 10 + 3*11 + O(11^2)
221
+ sage: L[3]
222
+ O(11^0)
223
+ """
224
+ p, normalize, implementation, precision = self._normalize_padic_lseries(p,
225
+ normalize, implementation, precision)
226
+
227
+ if implementation in ['sage', 'eclib', 'num']:
228
+ if self.ap(p) % p != 0:
229
+ Lp = plseries.pAdicLseriesOrdinary(self, p,
230
+ normalize=normalize, implementation=implementation)
231
+ else:
232
+ Lp = plseries.pAdicLseriesSupersingular(self, p,
233
+ normalize=normalize, implementation=implementation)
234
+ else:
235
+ phi = self.pollack_stevens_modular_symbol(sign=0)
236
+ if phi.parent().level() % p == 0:
237
+ Phi = phi.lift(p, precision, eigensymbol=True)
238
+ else:
239
+ Phi = phi.p_stabilize_and_lift(p, precision, eigensymbol=True)
240
+ Lp = Phi.padic_lseries() #mm TODO should this pass precision on too ?
241
+ Lp._cinf = self.real_components()
242
+ return Lp
243
+
244
+
245
+ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True):
246
+ r"""
247
+ Compute the cyclotomic `p`-adic regulator of this curve.
248
+ The model of the curve needs to be integral and minimal at `p`.
249
+ Moreover the reduction at `p` should not be additive.
250
+
251
+ INPUT:
252
+
253
+ - ``p`` -- prime >= 5
254
+
255
+ - ``prec`` -- answer will be returned modulo `p^{\mathrm{prec}}`
256
+
257
+ - ``height`` -- precomputed height function; if not supplied, this function
258
+ will call ``padic_height`` to compute it
259
+
260
+ - ``check_hypotheses`` -- boolean; whether to check
261
+ that this is a curve for which the `p`-adic height makes sense
262
+
263
+ OUTPUT: the `p`-adic cyclotomic regulator of this curve, to the
264
+ requested precision
265
+
266
+ If the rank is 0, we output 1.
267
+
268
+ AUTHORS:
269
+
270
+ - Liang Xiao: original implementation at the 2006 MSRI
271
+ graduate workshop on modular forms
272
+
273
+ - David Harvey (2006-09-13): cleaned up and integrated into Sage,
274
+ removed some redundant height computations
275
+
276
+ - Chris Wuthrich (2007-05-22): added multiplicative and
277
+ supersingular cases
278
+
279
+ - David Harvey (2007-09-20): fixed some precision loss that was
280
+ occurring
281
+
282
+ EXAMPLES::
283
+
284
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
285
+ sage: E = EllipticCurve("37a")
286
+ sage: E.padic_regulator(5, 10)
287
+ 5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)
288
+
289
+ An anomalous case::
290
+
291
+ sage: E.padic_regulator(53, 10) # needs database_cremona_mini_ellcurve sage.symbolic
292
+ 26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + O(53^9)
293
+
294
+ An anomalous case where the precision drops some::
295
+
296
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
297
+ sage: E = EllipticCurve("5077a")
298
+ sage: E.padic_regulator(5, 10)
299
+ 5 + 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 4*5^7 + 2*5^8 + 5^9 + O(5^10)
300
+
301
+ Check that answers agree over a range of precisions::
302
+
303
+ sage: # long time, needs database_cremona_mini_ellcurve sage.symbolic
304
+ sage: max_prec = 30 # make sure we get past p^2
305
+ sage: full = E.padic_regulator(5, max_prec)
306
+ sage: for prec in range(1, max_prec):
307
+ ....: assert E.padic_regulator(5, prec) == full
308
+
309
+ A case where the generator belongs to the formal group already
310
+ (:issue:`3632`)::
311
+
312
+ sage: E = EllipticCurve([37,0])
313
+ sage: E.padic_regulator(5,10) # needs sage.symbolic
314
+ 2*5^2 + 2*5^3 + 5^4 + 5^5 + 4*5^6 + 3*5^8 + 4*5^9 + O(5^10)
315
+
316
+ The result is not dependent on the model for the curve::
317
+
318
+ sage: E = EllipticCurve([0,0,0,0,2^12*17])
319
+ sage: Em = E.minimal_model()
320
+ sage: E.padic_regulator(7) == Em.padic_regulator(7) # needs sage.symbolic
321
+ True
322
+
323
+ Allow a python int as input::
324
+
325
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
326
+ sage: E = EllipticCurve('37a')
327
+ sage: E.padic_regulator(int(5))
328
+ 5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + 5^10 + 3*5^11 + 3*5^12 + 5^13 + 4*5^14 + 5^15 + 2*5^16 + 5^17 + 2*5^18 + 4*5^19 + O(5^20)
329
+ """
330
+ p = Integer(p) # this is assumed in code below
331
+ if check_hypotheses:
332
+ if not p.is_prime():
333
+ raise ValueError("p = (%s) must be prime" % p)
334
+ if p == 2:
335
+ raise ValueError("p must be odd") # todo
336
+ if self.conductor() % (p**2) == 0:
337
+ raise ArithmeticError("p must be a semi-stable prime")
338
+
339
+ if self.conductor() % p == 0:
340
+ Eq = self.tate_curve(p)
341
+ reg = Eq.padic_regulator(prec=prec)
342
+ return reg
343
+ elif self.ap(p) % p == 0:
344
+ lp = self.padic_lseries(p)
345
+ reg = lp.Dp_valued_regulator(prec=prec)
346
+ return reg
347
+ else:
348
+ if self.rank() == 0:
349
+ return Qp(p,prec)(1)
350
+ if height is None:
351
+ height = self.padic_height(p, prec, check_hypotheses=False)
352
+ d = self.padic_height_pairing_matrix(p=p, prec=prec, height=height, check_hypotheses=False)
353
+ return d.determinant()
354
+
355
+
356
+ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses=True):
357
+ r"""
358
+ Compute the cyclotomic `p`-adic height pairing matrix of
359
+ this curve with respect to the basis ``self.gens()`` for the
360
+ Mordell-Weil group for a given odd prime `p` of good ordinary
361
+ reduction.
362
+ The model needs to be integral and minimal at `p`.
363
+
364
+ INPUT:
365
+
366
+ - ``p`` -- prime >= 5
367
+
368
+ - ``prec`` -- answer will be returned modulo `p^{\mathrm{prec}}`
369
+
370
+ - ``height`` -- precomputed height function; if not supplied, this function
371
+ will call ``padic_height`` to compute it
372
+
373
+ - ``check_hypotheses`` -- boolean; whether to check that this is a curve
374
+ for which the `p`-adic height makes sense
375
+
376
+ OUTPUT: the `p`-adic cyclotomic height pairing matrix of this curve
377
+ to the given precision
378
+
379
+ AUTHORS:
380
+
381
+ - David Harvey, Liang Xiao, Robert Bradshaw, Jennifer
382
+ Balakrishnan: original implementation at the 2006 MSRI graduate
383
+ workshop on modular forms
384
+
385
+ - David Harvey (2006-09-13): cleaned up and integrated into Sage,
386
+ removed some redundant height computations
387
+
388
+ EXAMPLES::
389
+
390
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
391
+ sage: E = EllipticCurve("37a")
392
+ sage: E.padic_height_pairing_matrix(5, 10)
393
+ [5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)]
394
+
395
+ A rank two example::
396
+
397
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
398
+ sage: e = EllipticCurve('389a')
399
+ sage: e._set_gens([e(-1, 1), e(1,0)]) # avoid platform dependent gens
400
+ sage: e.padic_height_pairing_matrix(5,10)
401
+ [ 3*5 + 2*5^2 + 5^4 + 5^5 + 5^7 + 4*5^9 + O(5^10) 5 + 4*5^2 + 5^3 + 2*5^4 + 3*5^5 + 4*5^6 + 5^7 + 5^8 + 2*5^9 + O(5^10)]
402
+ [5 + 4*5^2 + 5^3 + 2*5^4 + 3*5^5 + 4*5^6 + 5^7 + 5^8 + 2*5^9 + O(5^10) 4*5 + 2*5^4 + 3*5^6 + 4*5^7 + 4*5^8 + O(5^10)]
403
+
404
+ An anomalous rank 3 example::
405
+
406
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
407
+ sage: e = EllipticCurve("5077a")
408
+ sage: e._set_gens([e(-1,3), e(2,0), e(4,6)])
409
+ sage: e.padic_height_pairing_matrix(5,4)
410
+ [4 + 3*5 + 4*5^2 + 4*5^3 + O(5^4) 4 + 4*5^2 + 2*5^3 + O(5^4) 3*5 + 4*5^2 + 5^3 + O(5^4)]
411
+ [ 4 + 4*5^2 + 2*5^3 + O(5^4) 3 + 4*5 + 3*5^2 + 5^3 + O(5^4) 2 + 4*5 + O(5^4)]
412
+ [ 3*5 + 4*5^2 + 5^3 + O(5^4) 2 + 4*5 + O(5^4) 1 + 3*5 + 5^2 + 5^3 + O(5^4)]
413
+ """
414
+ if check_hypotheses:
415
+ p = __check_padic_hypotheses(self, p)
416
+
417
+ K = Qp(p, prec=prec)
418
+
419
+ rank = self.rank()
420
+ M = matrix(K, rank, rank, 0)
421
+ if rank == 0:
422
+ return M
423
+
424
+ basis = self.gens()
425
+
426
+ if height is None:
427
+ height = self.padic_height(p, prec, check_hypotheses=False)
428
+
429
+ # Use <P, Q> =1/2*( h(P + Q) - h(P) - h(Q) )
430
+
431
+ for i in range(rank):
432
+ M[i,i] = height(basis[i])
433
+ for i in range(rank):
434
+ for j in range(i+1, rank):
435
+ M[i, j] = ( height(basis[i] + basis[j]) - M[i,i] - M[j,j] ) / 2
436
+ M[j, i] = M[i, j]
437
+
438
+ return M
439
+
440
+
441
+ def _multiply_point(E, R, P, m):
442
+ r"""
443
+ Compute coordinates of a multiple of `P` with entries in a ring.
444
+
445
+ INPUT:
446
+
447
+ - ``E`` -- elliptic curve over `\QQ` with integer
448
+ coefficients
449
+
450
+ - ``P`` -- a rational point on `P` that reduces to a
451
+ non-singular point at all primes
452
+
453
+ - ``R`` -- a ring in which 2 is invertible (typically
454
+ `\ZZ/L\ZZ` for some positive odd integer `L`)
455
+
456
+ - ``m`` -- integer (default: 1)
457
+
458
+ OUTPUT:
459
+
460
+ A triple `(a', b', d')` such that if the point
461
+ `mP` has coordinates `(a/d^2, b/d^3)`, then we have
462
+ `a' \equiv a`, `b' \equiv \pm b`,
463
+ `d' \equiv \pm d` all in `R` (i.e. modulo
464
+ `L`).
465
+
466
+ Note the ambiguity of signs for `b'` and `d'`.
467
+ There's not much one can do about this, but at least one can say
468
+ that the sign for `b'` will match the sign for
469
+ `d'`.
470
+
471
+ ALGORITHM: Proposition 9 in [Har2009]_.
472
+
473
+ Complexity is soft-`O(\log L \log m + \log^2 m)`.
474
+
475
+ AUTHORS:
476
+
477
+ - David Harvey (2008-01): replaced _DivPolyContext with
478
+ _multiply_point
479
+
480
+ EXAMPLES:
481
+
482
+ 37a has trivial Tamagawa numbers so all points have nonsingular
483
+ reduction at all primes::
484
+
485
+ sage: # needs database_cremona_mini_ellcurve
486
+ sage: E = EllipticCurve("37a")
487
+ sage: P = E([0, -1]); P
488
+ (0 : -1 : 1)
489
+ sage: 19*P
490
+ (-59997896/67387681 : 88075171080/553185473329 : 1)
491
+ sage: R = Integers(625)
492
+ sage: from sage.schemes.elliptic_curves.padics import _multiply_point
493
+ sage: _multiply_point(E, R, P, 19)
494
+ (229, 170, 541)
495
+ sage: -59997896 % 625
496
+ 229
497
+ sage: -88075171080 % 625 # note sign is flipped
498
+ 170
499
+ sage: -67387681.sqrt() % 625 # sign is flipped here too
500
+ 541
501
+
502
+ Trivial cases (:issue:`3632`)::
503
+
504
+ sage: # needs database_cremona_mini_ellcurve
505
+ sage: _multiply_point(E, R, P, 1)
506
+ (0, 624, 1)
507
+ sage: _multiply_point(E, R, 19*P, 1)
508
+ (229, 455, 84)
509
+ sage: (170 + 455) % 625 # note the sign did not flip here
510
+ 0
511
+ sage: (541 + 84) % 625
512
+ 0
513
+
514
+ Test over a range of `n` for a single curve with fairly
515
+ random coefficients::
516
+
517
+ sage: R = Integers(625)
518
+ sage: E = EllipticCurve([4, -11, 17, -8, -10])
519
+ sage: P = E.gens()[0] * LCM(E.tamagawa_numbers())
520
+ sage: from sage.schemes.elliptic_curves.padics import _multiply_point
521
+ sage: Q = P
522
+ sage: for n in range(1, 25):
523
+ ....: naive = R(Q[0].numerator()), \
524
+ ....: R(Q[1].numerator()), \
525
+ ....: R(Q[0].denominator().sqrt())
526
+ ....: triple = _multiply_point(E, R, P, n)
527
+ ....: assert (triple[0] == naive[0]) and ( \
528
+ ....: (triple[1] == naive[1] and triple[2] == naive[2]) or \
529
+ ....: (triple[1] == -naive[1] and triple[2] == -naive[2])), \
530
+ ....: "_multiply_point() gave an incorrect answer"
531
+ ....: Q = Q + P
532
+ """
533
+ assert m >= 1
534
+
535
+ alpha = R(P[0].numerator())
536
+ beta = R(P[1].numerator())
537
+ d = R(P[0].denominator().sqrt())
538
+ if m == 1:
539
+ return alpha, beta, d
540
+
541
+ a1 = R(E.a1()) * d
542
+ a3 = R(E.a3()) * d**3
543
+
544
+ b2 = R(E.b2()) * d**2
545
+ b4 = R(E.b4()) * d**4
546
+ b6 = R(E.b6()) * d**6
547
+ b8 = R(E.b8()) * d**8
548
+
549
+ B4 = 6*alpha**2 + b2*alpha + b4
550
+ B6 = 4*alpha**3 + b2*alpha**2 + 2*b4*alpha + b6
551
+ B6_sqr = B6*B6
552
+ B8 = 3*alpha**4 + b2*alpha**3 + 3*b4*alpha**2 + 3*b6*alpha + b8
553
+
554
+ T = 2*beta + a1*alpha + a3
555
+
556
+ # make a list of disjoint intervals [a[i], b[i]) such that we need to
557
+ # compute g(k) for all a[i] <= k <= b[i] for each i
558
+ intervals = []
559
+ interval = (m - 2, m + 3)
560
+ while interval[0] < interval[1]:
561
+ intervals.append(interval)
562
+ interval = max((interval[0] - 3) >> 1, 0), \
563
+ min((interval[1] + 5) >> 1, interval[0])
564
+
565
+ # now walk through list and compute g(k)
566
+ g = {0 : R(0), 1 : R(1), 2 : R(-1), 3 : B8, 4 : B6**2 - B4*B8}
567
+ for i in reversed(intervals):
568
+ k = i[0]
569
+ while k < i[1]:
570
+ if k > 4:
571
+ j = k >> 1
572
+ if k & 1:
573
+ t1 = g[j]
574
+ t2 = g[j+1]
575
+ prod1 = g[j+2] * t1*t1*t1
576
+ prod2 = g[j-1] * t2*t2*t2
577
+ g[k] = prod1 - B6_sqr * prod2 if j & 1 else B6_sqr * prod1 - prod2
578
+ else:
579
+ t1 = g[j-1]
580
+ t2 = g[j+1]
581
+ g[k] = g[j] * (g[j-2] * t2*t2 - g[j+2] * t1*t1)
582
+ k = k + 1
583
+
584
+ if m & 1:
585
+ psi_m = g[m]
586
+ psi_m_m1 = g[m-1] * T
587
+ psi_m_p1 = g[m+1] * T
588
+ else:
589
+ psi_m = g[m] * T
590
+ psi_m_m1 = g[m-1]
591
+ psi_m_p1 = g[m+1]
592
+
593
+ theta = alpha * psi_m * psi_m - psi_m_m1 * psi_m_p1
594
+ t1 = g[m-2] * g[m+1] * g[m+1] - g[m+2] * g[m-1] * g[m-1]
595
+ if m & 1:
596
+ t1 = t1 * T
597
+ omega = (t1 + (a1 * theta + a3 * psi_m * psi_m) * psi_m) / -2
598
+
599
+ return theta, omega, psi_m * d
600
+
601
+
602
+ def _multiple_to_make_good_reduction(E):
603
+ r"""
604
+ Return the integer `n_2` such that for all points `P` in `E(\QQ)`
605
+ `n_2*P` has good reduction at all primes.
606
+ If the model is globally minimal the lcm of the
607
+ Tamagawa numbers will do, otherwise we have to take into
608
+ account the change of the model.
609
+
610
+ INPUT:
611
+
612
+ - ``E`` -- an elliptic curve over `\QQ`
613
+
614
+ OUTPUT: a positive integer ``n2``
615
+
616
+ EXAMPLE (:issue:`34790`)::
617
+
618
+ sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction
619
+ sage: E = EllipticCurve([-1728,-100656])
620
+ sage: _multiple_to_make_good_reduction(E)
621
+ 30
622
+
623
+ The number ``n_2`` is not always optimal but it is in this example.
624
+ The first multiple of the generator `P` with good reduction in this
625
+ non-minimal model is `30 P`.
626
+
627
+ TESTS::
628
+
629
+ sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction
630
+ sage: E = EllipticCurve([1/2,1/3])
631
+ sage: _multiple_to_make_good_reduction(E)
632
+ Traceback (most recent call last):
633
+ ...
634
+ NotImplementedError: This only implemented for integral models. Please change the model first.
635
+ sage: E = EllipticCurve([0,3])
636
+ sage: _multiple_to_make_good_reduction(E)
637
+ 1
638
+ sage: E = EllipticCurve([0,5^7]) # min eq is additive
639
+ sage: _multiple_to_make_good_reduction(E)
640
+ 5
641
+ sage: E = EllipticCurve([7,0,0,0,7^7]) # min eq is split mult
642
+ sage: _multiple_to_make_good_reduction(E)
643
+ 6
644
+ sage: E = EllipticCurve([0,-3^2,0,0,3^7]) # min eq is non-split mult
645
+ sage: _multiple_to_make_good_reduction(E)
646
+ 4
647
+ """
648
+ if not E.is_integral():
649
+ st = ("This only implemented for integral models. "
650
+ "Please change the model first.")
651
+ raise NotImplementedError(st)
652
+ if E.is_minimal():
653
+ n2 = LCM(E.tamagawa_numbers())
654
+ else:
655
+ # generalising to number fields one can get the u from local_data
656
+ Emin = E.global_minimal_model()
657
+ iota = E.isomorphism_to(Emin)
658
+ u = Integer(iota.u)
659
+ ps = u.prime_divisors()
660
+ li = []
661
+ for p in ps:
662
+ np = u.valuation(p)
663
+ if Emin.discriminant() % p != 0:
664
+ li.append(Emin.Np(p) * p**(np-1))
665
+ elif Emin.has_additive_reduction(p):
666
+ li.append(E.tamagawa_number(p) * p**np)
667
+ elif E.has_split_multiplicative_reduction(p):
668
+ li.append(E.tamagawa_number(p) * (p-1) * p**(np-1))
669
+ else: # non split
670
+ li.append(E.tamagawa_number(p) * (p+1) * p**(np-1))
671
+ otherbad = Integer(Emin.discriminant()).prime_divisors()
672
+ otherbad = [p for p in otherbad if u % p != 0 ]
673
+ li += [E.tamagawa_number(p) for p in otherbad]
674
+ n2 = LCM(li)
675
+ return n2
676
+
677
+
678
+ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True):
679
+ r"""
680
+ Compute the cyclotomic `p`-adic height.
681
+
682
+ The equation of the curve must be integral and minimal at `p`.
683
+
684
+ INPUT:
685
+
686
+ - ``p`` -- prime >= 5 for which the curve has semi-stable reduction
687
+
688
+ - ``prec`` -- integer >= 1 (default: 20); desired precision of result
689
+
690
+ - ``sigma`` -- precomputed value of sigma; if not supplied, this function
691
+ will call ``padic_sigma`` to compute it
692
+
693
+ - ``check_hypotheses`` -- boolean; whether to check that this is a curve
694
+ for which the `p`-adic height makes sense
695
+
696
+ OUTPUT:
697
+
698
+ A function that accepts two parameters:
699
+
700
+ - a `\QQ`-rational point on the curve whose height should be computed
701
+
702
+ - optional boolean flag 'check': if ``False``, it skips some input
703
+ checking, and returns the `p`-adic height of that point to the
704
+ desired precision.
705
+
706
+ - The normalization (sign and a factor 1/2 with respect to some other
707
+ normalizations that appear in the literature) is chosen in such a way
708
+ as to make the `p`-adic Birch Swinnerton-Dyer conjecture hold as stated
709
+ in [MTT1986]_.
710
+
711
+ AUTHORS:
712
+
713
+ - Jennifer Balakrishnan: original code developed at the 2006 MSRI
714
+ graduate workshop on modular forms
715
+
716
+ - David Harvey (2006-09-13): integrated into Sage, optimised to
717
+ speed up repeated evaluations of the returned height function,
718
+ addressed some thorny precision questions
719
+
720
+ - David Harvey (2006-09-30): rewrote to use division polynomials
721
+ for computing denominator of `nP`.
722
+
723
+ - David Harvey (2007-02): cleaned up according to algorithms in
724
+ "Efficient Computation of p-adic Heights"
725
+
726
+ - Chris Wuthrich (2007-05): added supersingular and multiplicative heights
727
+
728
+ EXAMPLES::
729
+
730
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
731
+ sage: E = EllipticCurve("37a")
732
+ sage: P = E.gens()[0]
733
+ sage: h = E.padic_height(5, 10)
734
+ sage: h(P)
735
+ 5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)
736
+
737
+ An anomalous case::
738
+
739
+ sage: h = E.padic_height(53, 10) # needs database_cremona_mini_ellcurve sage.symbolic
740
+ sage: h(P) # needs database_cremona_mini_ellcurve sage.symbolic
741
+ 26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + 17*53^9 + O(53^10)
742
+
743
+ Boundary case::
744
+
745
+ sage: E.padic_height(5, 3)(P) # needs database_cremona_mini_ellcurve sage.symbolic
746
+ 5 + 5^2 + O(5^3)
747
+
748
+ A case that works the division polynomial code a little harder::
749
+
750
+ sage: E.padic_height(5, 10)(5*P) # needs database_cremona_mini_ellcurve sage.symbolic
751
+ 5^3 + 5^4 + 5^5 + 3*5^8 + 4*5^9 + O(5^10)
752
+
753
+ Check that answers agree over a range of precisions::
754
+
755
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
756
+ sage: max_prec = 30 # make sure we get past p^2 # long time
757
+ sage: full = E.padic_height(5, max_prec)(P) # long time
758
+ sage: for prec in range(1, max_prec): # long time
759
+ ....: assert E.padic_height(5, prec)(P) == full
760
+
761
+ A supersingular prime for a curve::
762
+
763
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
764
+ sage: E = EllipticCurve('37a')
765
+ sage: E.is_supersingular(3)
766
+ True
767
+ sage: h = E.padic_height(3, 5)
768
+ sage: h(E.gens()[0])
769
+ (3 + 3^3 + O(3^6), 2*3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + O(3^7))
770
+ sage: E.padic_regulator(5)
771
+ 5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + 5^10 + 3*5^11 + 3*5^12 + 5^13 + 4*5^14 + 5^15 + 2*5^16 + 5^17 + 2*5^18 + 4*5^19 + O(5^20)
772
+ sage: E.padic_regulator(3, 5)
773
+ (3 + 2*3^2 + 3^3 + O(3^4), 3^2 + 2*3^3 + 3^4 + O(3^5))
774
+
775
+ A torsion point in both the good and supersingular cases::
776
+
777
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
778
+ sage: E = EllipticCurve('11a')
779
+ sage: P = E.torsion_subgroup().gen(0).element(); P
780
+ (5 : 5 : 1)
781
+ sage: h = E.padic_height(19, 5)
782
+ sage: h(P)
783
+ 0
784
+ sage: h = E.padic_height(5, 5)
785
+ sage: h(P)
786
+ 0
787
+
788
+ The result is not dependent on the model for the curve::
789
+
790
+ sage: # needs sage.symbolic
791
+ sage: E = EllipticCurve([0,0,0,0,2^12*17])
792
+ sage: Em = E.minimal_model()
793
+ sage: P = E.gens()[0]
794
+ sage: Pm = Em.gens()[0]
795
+ sage: h = E.padic_height(7)
796
+ sage: hm = Em.padic_height(7)
797
+ sage: h(P) == hm(Pm)
798
+ True
799
+
800
+ TESTS:
801
+
802
+ Check that issue :issue:`20798` is solved::
803
+
804
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
805
+ sage: E = EllipticCurve("91b")
806
+ sage: h = E.padic_height(7,10)
807
+ sage: P = E.gen(0)
808
+ sage: h(P)
809
+ 2*7 + 7^2 + 5*7^3 + 6*7^4 + 2*7^5 + 3*7^6 + 7^7 + 4*7^9 + 5*7^10 + O(7^11)
810
+ sage: h(P+P)
811
+ 7 + 5*7^2 + 6*7^3 + 5*7^4 + 4*7^5 + 6*7^6 + 5*7^7 + 2*7^9 + 7^10 + O(7^11)
812
+ """
813
+ if check_hypotheses:
814
+ if not p.is_prime():
815
+ raise ValueError("p = (%s) must be prime" % p)
816
+ if p == 2:
817
+ raise ValueError("p must be odd") # todo
818
+ if self.conductor() % (p**2) == 0:
819
+ raise ArithmeticError("p must be a semi-stable prime")
820
+
821
+ prec = int(prec)
822
+ if prec < 1:
823
+ raise ValueError("prec (=%s) must be at least 1" % prec)
824
+
825
+ if self.conductor() % p == 0:
826
+ Eq = self.tate_curve(p)
827
+ return Eq.padic_height(prec=prec)
828
+ elif self.ap(p) % p == 0:
829
+ lp = self.padic_lseries(p)
830
+ return lp.Dp_valued_height(prec=prec)
831
+
832
+ # else good ordinary case
833
+
834
+ # For notation and definitions, see [Har2009]_.
835
+
836
+ n1 = self.change_ring(GF(p)).cardinality()
837
+ n2 = _multiple_to_make_good_reduction(self)
838
+ n = LCM(n1, n2)
839
+ m = int(n / n2)
840
+
841
+ adjusted_prec = prec + 2 * valuation(n, p) # this is M'
842
+ R = Integers(p ** adjusted_prec)
843
+
844
+ if sigma is None:
845
+ sigma = self.padic_sigma(p, adjusted_prec, check_hypotheses=False)
846
+
847
+ # K is the field for the final result
848
+ K = Qp(p, prec=adjusted_prec-1)
849
+ E = self
850
+
851
+ def height(P, check=True):
852
+ if P.is_finite_order():
853
+ return K(0)
854
+
855
+ if check:
856
+ assert P.curve() == E, "the point P must lie on the curve " \
857
+ "from which the height function was created"
858
+
859
+ Q = n2 * P
860
+ alpha, beta, d = _multiply_point(E, R, Q, m)
861
+
862
+ assert beta.lift() % p != 0, "beta should be a unit!"
863
+ assert d.lift() % p == 0, "d should not be a unit!"
864
+
865
+ t = -d * alpha / beta
866
+
867
+ total = R(1)
868
+ t_power = t
869
+ for k in range(2, adjusted_prec + 1):
870
+ total = total + t_power * sigma[k].lift()
871
+ t_power = t_power * t
872
+ total = (-alpha / beta) * total
873
+
874
+ L = Qp(p, prec=adjusted_prec)
875
+ total = L(total.lift(), adjusted_prec) # yuck... get rid of this lift!
876
+
877
+ # changed sign to make it correct for p-adic bsd
878
+ answer = -total.log() * 2 / n**2
879
+
880
+ if check:
881
+ assert answer.precision_absolute() >= prec, "we should have got an " \
882
+ "answer with precision at least prec, but we didn't."
883
+ return K(answer)
884
+
885
+ # (man... I love python's local function definitions...)
886
+ return height
887
+
888
+
889
+ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True):
890
+ r"""
891
+ Compute the cyclotomic `p`-adic height.
892
+
893
+ The equation of the curve must be minimal at `p`.
894
+
895
+ INPUT:
896
+
897
+ - ``p`` -- prime >= 5 for which the curve has good ordinary reduction
898
+
899
+ - ``prec`` -- integer >= 2 (default: 20); desired precision of result
900
+
901
+ - ``E2`` -- precomputed value of E2. If not supplied,
902
+ this function will call padic_E2 to compute it. The value supplied
903
+ must be correct mod `p^{prec-2}` (or slightly higher in the
904
+ anomalous case; see the code for details).
905
+
906
+ - ``check_hypotheses`` -- boolean; whether to check
907
+ that this is a curve for which the `p`-adic height makes sense
908
+
909
+ OUTPUT:
910
+
911
+ A function that accepts two parameters:
912
+
913
+ - a `\QQ`-rational point on the curve whose height should be computed
914
+
915
+ - optional boolean flag 'check': if ``False``, it skips some input
916
+ checking, and returns the `p`-adic height of that point to the
917
+ desired precision.
918
+
919
+ - The normalization (sign and a factor 1/2 with respect to some other
920
+ normalizations that appear in the literature) is chosen in such a way
921
+ as to make the `p`-adic Birch Swinnerton-Dyer conjecture hold as stated
922
+ in [MTT1986]_.
923
+
924
+ AUTHORS:
925
+
926
+ - David Harvey (2008-01): based on the padic_height() function,
927
+ using the algorithm of [Har2009]_.
928
+
929
+ EXAMPLES::
930
+
931
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
932
+ sage: E = EllipticCurve("37a")
933
+ sage: P = E.gens()[0]
934
+ sage: h = E.padic_height_via_multiply(5, 10)
935
+ sage: h(P)
936
+ 5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)
937
+
938
+ An anomalous case::
939
+
940
+ sage: h = E.padic_height_via_multiply(53, 10) # needs database_cremona_mini_ellcurve sage.symbolic
941
+ sage: h(P) # needs database_cremona_mini_ellcurve sage.symbolic
942
+ 26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + 17*53^9 + O(53^10)
943
+
944
+ Supply the value of E2 manually::
945
+
946
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
947
+ sage: E2 = E.padic_E2(5, 8)
948
+ sage: E2
949
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + O(5^8)
950
+ sage: h = E.padic_height_via_multiply(5, 10, E2=E2)
951
+ sage: h(P)
952
+ 5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)
953
+
954
+ Boundary case::
955
+
956
+ sage: E.padic_height_via_multiply(5, 3)(P) # needs database_cremona_mini_ellcurve sage.symbolic
957
+ 5 + 5^2 + O(5^3)
958
+
959
+ Check that answers agree over a range of precisions::
960
+
961
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
962
+ sage: max_prec = 30 # make sure we get past p^2 # long time
963
+ sage: full = E.padic_height(5, max_prec)(P) # long time
964
+ sage: for prec in range(2, max_prec): # long time
965
+ ....: assert E.padic_height_via_multiply(5, prec)(P) == full
966
+ """
967
+ if check_hypotheses:
968
+ if not p.is_prime():
969
+ raise ValueError("p = (%s) must be prime" % p)
970
+ if p == 2:
971
+ raise ValueError("p must be odd") # todo
972
+ if self.conductor() % p == 0:
973
+ raise ArithmeticError("must have good reduction at p")
974
+ if self.ap(p) % p == 0:
975
+ raise ArithmeticError("must be ordinary at p")
976
+
977
+ prec = int(prec)
978
+ if prec < 1:
979
+ raise ValueError("prec (=%s) must be at least 1" % prec)
980
+
981
+ # For notation and definitions, [Har2009]_
982
+
983
+ n1 = self.change_ring(GF(p)).cardinality()
984
+ n2 = _multiple_to_make_good_reduction(self)
985
+ n = LCM(n1, n2)
986
+ m = int(n / n2)
987
+
988
+ lamb = int(math.floor(math.sqrt(prec)))
989
+
990
+ adjusted_prec = prec + 2 * valuation(n, p) # this is M'
991
+ R = Integers(p ** (adjusted_prec + 2*lamb))
992
+
993
+ sigma = self.padic_sigma_truncated(p, N=adjusted_prec, E2=E2, lamb=lamb)
994
+
995
+ # K is the field for the final result
996
+ K = Qp(p, prec=adjusted_prec-1)
997
+ E = self
998
+
999
+ def height(P, check=True):
1000
+ if P.is_finite_order():
1001
+ return K(0)
1002
+
1003
+ if check:
1004
+ assert P.curve() == E, "the point P must lie on the curve " \
1005
+ "from which the height function was created"
1006
+
1007
+ Q = n2 * P
1008
+ alpha, beta, d = _multiply_point(E, R, Q, m * p**lamb)
1009
+
1010
+ assert beta.lift() % p != 0, "beta should be a unit!"
1011
+ assert d.lift() % p == 0, "d should not be a unit!"
1012
+
1013
+ t = -d * alpha / beta
1014
+
1015
+ total = R(1)
1016
+ t_power = t
1017
+ for k in range(2, sigma.prec()):
1018
+ total = total + t_power * sigma[k].lift()
1019
+ t_power = t_power * t
1020
+ total = (-alpha / beta) * total
1021
+
1022
+ L = Qp(p, prec=adjusted_prec + 2*lamb)
1023
+ total = L(total.lift(), adjusted_prec + 2*lamb)
1024
+
1025
+ # changed sign to make it correct for p-adic bsd
1026
+ answer = -total.log() * 2 / (n * p**lamb)**2
1027
+
1028
+ if check:
1029
+ assert answer.precision_absolute() >= prec, "we should have got an " \
1030
+ "answer with precision at least prec, but we didn't."
1031
+ return K(answer)
1032
+
1033
+ # (man... I love python's local function definitions...)
1034
+ return height
1035
+
1036
+
1037
+ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True):
1038
+ r"""
1039
+ Compute the `p`-adic sigma function with respect to the standard
1040
+ invariant differential `dx/(2y + a_1 x + a_3)`, as
1041
+ defined by Mazur and Tate in [MT1991]_, as a power series in the usual
1042
+ uniformiser `t` at the origin.
1043
+
1044
+ The equation of the curve must be minimal at `p`.
1045
+
1046
+ INPUT:
1047
+
1048
+ - ``p`` -- prime >= 5 for which the curve has good ordinary reduction
1049
+
1050
+ - ``N`` -- integer >= 1 (default: 20); precision of result,
1051
+ see OUTPUT section for description
1052
+
1053
+ - ``E2`` -- precomputed value of E2. If not supplied,
1054
+ this function will call padic_E2 to compute it. The value supplied
1055
+ must be correct mod `p^{N-2}`.
1056
+
1057
+ - ``check`` -- boolean; whether to perform a
1058
+ consistency check (i.e. verify that the computed sigma satisfies
1059
+ the defining
1060
+
1061
+ - ``differential equation`` -- note that this does NOT guarantee
1062
+ correctness of all the returned digits, but it comes pretty close
1063
+
1064
+ - ``check_hypotheses`` -- boolean; whether to check that this is a curve
1065
+ for which the `p`-adic sigma function makes sense
1066
+
1067
+ OUTPUT: a power series `t + \cdots` with coefficients in `\ZZ_p`
1068
+
1069
+ The output series will be truncated at `O(t^{N+1})`, and
1070
+ the coefficient of `t^n` for `n \geq 1` will be
1071
+ correct to precision `O(p^{N-n+1})`.
1072
+
1073
+ In practice this means the following. If `t_0 = p^k u`,
1074
+ where `u` is a `p`-adic unit with at least
1075
+ `N` digits of precision, and `k \geq 1`, then the
1076
+ returned series may be used to compute `\sigma(t_0)`
1077
+ correctly modulo `p^{N+k}` (i.e. with `N` correct
1078
+ `p`-adic digits).
1079
+
1080
+ ALGORITHM: Described in "Efficient Computation of p-adic Heights"
1081
+ (David Harvey) [Har2009]_ which is basically an optimised version of the
1082
+ algorithm from "p-adic Heights and Log Convergence" (Mazur, Stein,
1083
+ Tate) [MST2006]_.
1084
+
1085
+ Running time is soft-`O(N^2 \log p)`, plus whatever time is
1086
+ necessary to compute `E_2`.
1087
+
1088
+ AUTHORS:
1089
+
1090
+ - David Harvey (2006-09-12)
1091
+
1092
+ - David Harvey (2007-02): rewrote
1093
+
1094
+ EXAMPLES::
1095
+
1096
+ sage: EllipticCurve([-1, 1/4]).padic_sigma(5, 10) # needs sage.symbolic
1097
+ O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (2 + 2*5 + 5^2 + 4*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (1 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
1098
+
1099
+ Run it with a consistency check::
1100
+
1101
+ sage: EllipticCurve("37a").padic_sigma(5, 10, check=True) # needs sage.symbolic
1102
+ O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + (3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7))*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + (2 + 3*5 + 5^4 + O(5^5))*t^6 + (4 + 3*5 + 2*5^2 + O(5^4))*t^7 + (2 + 3*5 + 2*5^2 + O(5^3))*t^8 + (4*5 + O(5^2))*t^9 + (1 + O(5))*t^10 + O(t^11)
1103
+
1104
+ Boundary cases::
1105
+
1106
+ sage: EllipticCurve([1, 1, 1, 1, 1]).padic_sigma(5, 1) # needs sage.symbolic
1107
+ (1 + O(5))*t + O(t^2)
1108
+ sage: EllipticCurve([1, 1, 1, 1, 1]).padic_sigma(5, 2) # needs sage.symbolic
1109
+ (1 + O(5^2))*t + (3 + O(5))*t^2 + O(t^3)
1110
+
1111
+ Supply your very own value of E2::
1112
+
1113
+ sage: # needs sage.symbolic
1114
+ sage: X = EllipticCurve("37a")
1115
+ sage: my_E2 = X.padic_E2(5, 8)
1116
+ sage: my_E2 = my_E2 + 5**5 # oops!!!
1117
+ sage: X.padic_sigma(5, 10, E2=my_E2)
1118
+ O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 4*5^5 + 2*5^6 + 3*5^7 + O(5^8))*t^3 + (3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7))*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 3*5^5 + O(5^6))*t^5 + (2 + 3*5 + 5^4 + O(5^5))*t^6 + (4 + 3*5 + 2*5^2 + O(5^4))*t^7 + (2 + 3*5 + 2*5^2 + O(5^3))*t^8 + (4*5 + O(5^2))*t^9 + (1 + O(5))*t^10 + O(t^11)
1119
+
1120
+ Check that sigma is "weight 1".
1121
+
1122
+ ::
1123
+
1124
+ sage: # needs sage.symbolic
1125
+ sage: f = EllipticCurve([-1, 3]).padic_sigma(5, 10)
1126
+ sage: g = EllipticCurve([-1*(2**4), 3*(2**6)]).padic_sigma(5, 10)
1127
+ sage: t = f.parent().gen()
1128
+ sage: f(2*t)/2
1129
+ (1 + O(5^10))*t + (4 + 3*5 + 3*5^2 + 3*5^3 + 4*5^4 + 4*5^5 + 3*5^6 + 5^7 + O(5^8))*t^3 + (3 + 3*5^2 + 5^4 + 2*5^5 + O(5^6))*t^5 + (4 + 5 + 3*5^3 + O(5^4))*t^7 + (4 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
1130
+ sage: g
1131
+ O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (4 + 3*5 + 3*5^2 + 3*5^3 + 4*5^4 + 4*5^5 + 3*5^6 + 5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (3 + 3*5^2 + 5^4 + 2*5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (4 + 5 + 3*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (4 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
1132
+ sage: f(2*t)/2 -g
1133
+ O(t^11)
1134
+
1135
+ Test that it returns consistent results over a range of precision::
1136
+
1137
+ sage: # long time, needs sage.symbolic
1138
+ sage: max_N = 30 # get up to at least p^2
1139
+ sage: E = EllipticCurve([1, 1, 1, 1, 1])
1140
+ sage: p = 5
1141
+ sage: E2 = E.padic_E2(5, max_N)
1142
+ sage: max_sigma = E.padic_sigma(p, max_N, E2=E2)
1143
+ sage: for N in range(3, max_N):
1144
+ ....: sigma = E.padic_sigma(p, N, E2=E2)
1145
+ ....: assert sigma == max_sigma
1146
+ """
1147
+ if check_hypotheses:
1148
+ p = __check_padic_hypotheses(self, p)
1149
+
1150
+ # todo: implement the p == 3 case
1151
+ # NOTE: If we ever implement p == 3, it's necessary to check over
1152
+ # the precision loss estimates (below) very carefully; I think it
1153
+ # may become necessary to compute E2 to an even higher precision.
1154
+ if p < 5:
1155
+ raise NotImplementedError("p (=%s) must be at least 5" % p)
1156
+
1157
+ N = int(N)
1158
+
1159
+ # a few special cases for small N
1160
+ if N < 1:
1161
+ raise ValueError("N (=%s) must be at least 1" % N)
1162
+
1163
+ if N == 1:
1164
+ # return simply t + O(t^2)
1165
+ K = Qp(p, 2)
1166
+ return PowerSeriesRing(K, "t")([K(0), K(1, 1)], prec=2)
1167
+
1168
+ if N == 2:
1169
+ # return t + a_1/2 t^2 + O(t^3)
1170
+ K = Qp(p, 3)
1171
+ return PowerSeriesRing(K, "t")([K(0), K(1, 2),
1172
+ K(self.a1()/2, 1)], prec=3)
1173
+
1174
+ if self.discriminant().valuation(p) != 0:
1175
+ raise NotImplementedError("equation of curve must be minimal at p")
1176
+
1177
+ if E2 is None:
1178
+ E2 = self.padic_E2(p, N-2, check_hypotheses=False)
1179
+ elif E2.precision_absolute() < N-2:
1180
+ raise ValueError("supplied E2 has insufficient precision")
1181
+
1182
+ QQt = LaurentSeriesRing(RationalField(), "x")
1183
+
1184
+ R = Integers(p**(N-2))
1185
+ X = self.change_ring(R)
1186
+ c = (X.a1()**2 + 4*X.a2() - R(E2)) / 12
1187
+
1188
+ f = X.formal_group().differential(N+2) # f = 1 + ... + O(t^{N+2})
1189
+ x = X.formal_group().x(N) # x = t^{-2} + ... + O(t^N)
1190
+
1191
+ Rt = x.parent()
1192
+
1193
+ A = (x + c) * f
1194
+ # do integral over QQ, to avoid divisions by p
1195
+ A = Rt(QQt(A).integral())
1196
+ A = (-X.a1()/2 - A) * f
1197
+
1198
+ # Convert to a power series and remove the -1/x term.
1199
+ # Also we artificially bump up the accuracy from N-2 to N-1 digits;
1200
+ # the constant term needs to be known to N-1 digits, so we compute
1201
+ # it directly
1202
+ assert A.valuation() == -1 and A[-1] == 1
1203
+ A = A - A.parent().gen() ** (-1)
1204
+ A = A.power_series().list()
1205
+ R = Integers(p**(N-1))
1206
+ A = [R(u) for u in A]
1207
+ A[0] = self.change_ring(R).a1()/2 # fix constant term
1208
+ A = PowerSeriesRing(R, "x")(A, len(A))
1209
+
1210
+ theta = _brent(A, p, N)
1211
+ sigma = theta * theta.parent().gen()
1212
+
1213
+ # Convert the answer to power series over p-adics; drop the precision
1214
+ # of the t^k coefficient to p^(N-k+1).
1215
+ # [Note: there are actually more digits available, but it's a bit
1216
+ # tricky to figure out exactly how many, and we only need p^(N-k+1)
1217
+ # for p-adic height purposes anyway]
1218
+ K = Qp(p, N + 1)
1219
+
1220
+ sigma = sigma.padded_list(N+1)
1221
+
1222
+ sigma[0] = K(0, N + 1)
1223
+ sigma[1] = K(1, N)
1224
+ for n in range(2, N+1):
1225
+ sigma[n] = K(sigma[n].lift(), N - n + 1)
1226
+
1227
+ S = PowerSeriesRing(K, "t", N+1)
1228
+ sigma = S(sigma, N+1)
1229
+
1230
+ # if requested, check that sigma satisfies the appropriate
1231
+ # differential equation
1232
+ if check:
1233
+ R = Integers(p**N)
1234
+ X = self.change_ring(R)
1235
+ x = X.formal_group().x(N+5) # few extra terms for safety
1236
+ f = X.formal_group().differential(N+5)
1237
+ c = (X.a1()**2 + 4*X.a2() - R(E2)) / 12
1238
+
1239
+ # convert sigma to be over Z/p^N
1240
+ s = f.parent()(sigma)
1241
+ sinv = s**(-1)
1242
+ finv = f**(-1)
1243
+
1244
+ # apply differential equation
1245
+ temp = (s.derivative() * sinv * finv).derivative() * finv + c + x
1246
+
1247
+ # coefficient of t^k in the result should be zero mod p^(N-k-2)
1248
+ for k in range(N-2):
1249
+ assert temp[k].lift().valuation(p) >= N - k - 2, \
1250
+ "sigma correctness check failed!"
1251
+
1252
+ return sigma
1253
+
1254
+
1255
+ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True):
1256
+ r"""
1257
+ Compute the `p`-adic sigma function with respect to the standard
1258
+ invariant differential `dx/(2y + a_1 x + a_3)`, as
1259
+ defined by Mazur and Tate in [MT1991]_, as a power series in the usual
1260
+ uniformiser `t` at the origin.
1261
+
1262
+ The equation of the curve must be minimal at `p`.
1263
+
1264
+ This function differs from :func:`padic_sigma` in the precision profile
1265
+ of the returned power series; see OUTPUT below.
1266
+
1267
+ INPUT:
1268
+
1269
+ - ``p`` -- prime >= 5 for which the curve has good ordinary reduction
1270
+
1271
+ - ``N`` -- integer >= 2 (default: 20); precision of result,
1272
+ see OUTPUT section for description
1273
+
1274
+ - ``lamb`` -- integer >= 0; see OUTPUT section for description
1275
+
1276
+ - ``E2`` -- precomputed value of E2. If not supplied,
1277
+ this function will call padic_E2 to compute it. The value supplied
1278
+ must be correct mod `p^{N-2}`.
1279
+
1280
+ - ``check_hypotheses`` -- boolean; whether to check that this is a curve
1281
+ for which the `p`-adic sigma function makes sense
1282
+
1283
+ OUTPUT: a power series `t + \cdots` with coefficients in `\ZZ_p`
1284
+
1285
+ The coefficient of `t^j` for `j \geq 1` will be
1286
+ correct to precision `O(p^{N - 2 + (3 - j)(lamb + 1)})`.
1287
+
1288
+ ALGORITHM: Described in "Efficient Computation of p-adic Heights"
1289
+ [Har2009]_, which is basically an
1290
+ optimised version of the algorithm from "p-adic Heights and Log
1291
+ Convergence" (Mazur, Stein, Tate) [MST2006]_.
1292
+
1293
+ Running time is soft-`O(N^2 \lambda^{-1} \log p)`, plus
1294
+ whatever time is necessary to compute `E_2`.
1295
+
1296
+ AUTHORS:
1297
+
1298
+ - David Harvey (2008-01): wrote based on previous
1299
+ :func:`padic_sigma` function
1300
+
1301
+ EXAMPLES::
1302
+
1303
+ sage: E = EllipticCurve([-1, 1/4])
1304
+ sage: E.padic_sigma_truncated(5, 10) # needs sage.symbolic
1305
+ O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (2 + 2*5 + 5^2 + 4*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (1 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
1306
+
1307
+ Note the precision of the `t^3` coefficient depends only on
1308
+ `N`, not on lamb::
1309
+
1310
+ sage: E.padic_sigma_truncated(5, 10, lamb=2) # needs sage.symbolic
1311
+ O(5^17) + (1 + O(5^14))*t + O(5^11)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^5)*t^4 + (2 + O(5^2))*t^5 + O(t^6)
1312
+
1313
+ Compare against plain padic_sigma() function over a dense range of
1314
+ N and lamb
1315
+
1316
+ ::
1317
+
1318
+ sage: # long time, needs sage.symbolic
1319
+ sage: E = EllipticCurve([1, 2, 3, 4, 7])
1320
+ sage: E2 = E.padic_E2(5, 50)
1321
+ sage: for N in range(2, 10):
1322
+ ....: for lamb in range(10):
1323
+ ....: correct = E.padic_sigma(5, N + 3*lamb, E2=E2)
1324
+ ....: compare = E.padic_sigma_truncated(5, N=N, lamb=lamb, E2=E2)
1325
+ ....: assert compare == correct
1326
+ """
1327
+ if check_hypotheses:
1328
+ p = __check_padic_hypotheses(self, p)
1329
+
1330
+ # todo: implement the p == 3 case
1331
+ # NOTE: If we ever implement p == 3, it's necessary to check over
1332
+ # the precision loss estimates (below) very carefully; I think it
1333
+ # may become necessary to compute E2 to an even higher precision.
1334
+ if p < 5:
1335
+ raise NotImplementedError("p (=%s) must be at least 5" % p)
1336
+
1337
+ N = int(N)
1338
+ lamb = int(lamb)
1339
+
1340
+ if lamb < 0:
1341
+ raise ValueError("lamb (=%s) must be at least 0" % lamb)
1342
+
1343
+ # a few special cases for small N
1344
+ if N <= 1:
1345
+ raise ValueError("N (=%s) must be at least 2" % N)
1346
+
1347
+ if N == 2:
1348
+ # return t + a_1/2 t^2 + O(t^3)
1349
+ K = Qp(p, 3*(lamb+1))
1350
+ return PowerSeriesRing(K, "t")([K(0), K(1, 2*(lamb+1)),
1351
+ K(self.a1()/2, lamb+1)], prec=3)
1352
+
1353
+ if self.discriminant().valuation(p) != 0:
1354
+ raise NotImplementedError("equation of curve must be minimal at p")
1355
+
1356
+ if E2 is None:
1357
+ E2 = self.padic_E2(p, N-2, check_hypotheses=False)
1358
+ elif E2.precision_absolute() < N-2:
1359
+ raise ValueError("supplied E2 has insufficient precision")
1360
+
1361
+ # The main part of the algorithm is exactly the same as
1362
+ # for padic_sigma(), but we truncate all the series earlier.
1363
+ # Want the answer O(t^(trunc+1)) instead of O(t^(N+1)) like in padic_sigma().
1364
+ trunc = (Integer(N-2) / (lamb + 1)).ceil() + 2
1365
+
1366
+ QQt = LaurentSeriesRing(RationalField(), "x")
1367
+
1368
+ R = Integers(p**(N-2))
1369
+ X = self.change_ring(R)
1370
+ c = (X.a1()**2 + 4*X.a2() - R(E2)) / 12
1371
+
1372
+ f = X.formal_group().differential(trunc+2) # f = 1 + ... + O(t^{trunc+2})
1373
+ x = X.formal_group().x(trunc) # x = t^{-2} + ... + O(t^trunc)
1374
+
1375
+ Rt = x.parent()
1376
+
1377
+ A = (x + c) * f
1378
+ # do integral over QQ, to avoid divisions by p
1379
+ A = Rt(QQt(A).integral())
1380
+ A = (-X.a1()/2 - A) * f
1381
+
1382
+ # Convert to a power series and remove the -1/x term.
1383
+ # Also we artificially bump up the accuracy from N-2 to N-1+lamb digits;
1384
+ # the constant term needs to be known to N-1+lamb digits, so we compute
1385
+ # it directly
1386
+ assert A.valuation() == -1 and A[-1] == 1
1387
+ A = A - A.parent().gen() ** (-1)
1388
+ A = A.power_series().list()
1389
+ R = Integers(p**(N-1+lamb))
1390
+ A = [R(u) for u in A]
1391
+ A[0] = self.change_ring(R).a1()/2 # fix constant term
1392
+ A = PowerSeriesRing(R, "x")(A, len(A))
1393
+
1394
+ theta = _brent(A, p, trunc)
1395
+ sigma = theta * theta.parent().gen()
1396
+
1397
+ # Convert the answer to power series over p-adics; drop the precision
1398
+ # of the t^j coefficient to p^{N - 2 + (3 - j)(lamb + 1)}).
1399
+ K = Qp(p, N - 2 + 3*(lamb+1))
1400
+
1401
+ sigma = sigma.padded_list(trunc+1)
1402
+
1403
+ sigma[0] = K(0, N - 2 + 3*(lamb+1))
1404
+ sigma[1] = K(1, N - 2 + 2*(lamb+1))
1405
+ for j in range(2, trunc+1):
1406
+ sigma[j] = K(sigma[j].lift(), N - 2 + (3 - j)*(lamb+1))
1407
+
1408
+ S = PowerSeriesRing(K, "t", trunc + 1)
1409
+ sigma = S(sigma, trunc+1)
1410
+
1411
+ return sigma
1412
+
1413
+
1414
+ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm='auto'):
1415
+ r"""
1416
+ Return the value of the `p`-adic modular form `E2`
1417
+ for `(E, \omega)` where `\omega` is the usual
1418
+ invariant differential `dx/(2y + a_1 x + a_3)`.
1419
+
1420
+ INPUT:
1421
+
1422
+ - ``p`` -- prime (= 5) for which `E` is good and ordinary
1423
+
1424
+ - ``prec`` -- (relative) `p`-adic precision (= 1) for result
1425
+
1426
+ - ``check`` -- boolean; whether to perform a consistency check. This will
1427
+ slow down the computation by a constant factor 2. (The consistency check
1428
+ is to compute the whole matrix of frobenius on Monsky-Washnitzer
1429
+ cohomology, and verify that its trace is correct to the specified
1430
+ precision. Otherwise, the trace is used to compute one column from the
1431
+ other one (possibly after a change of basis).)
1432
+
1433
+ - ``check_hypotheses`` -- boolean; whether to check that this is a curve
1434
+ for which the `p`-adic sigma function makes sense
1435
+
1436
+ - ``algorithm`` -- one of ``'standard'``, ``'sqrtp'``, or
1437
+ ``'auto'``. This selects which version of Kedlaya's algorithm is used.
1438
+ The ``'standard'`` one is the one described in Kedlaya's paper. The
1439
+ ``'sqrtp'`` one has better performance for large `p`, but only
1440
+ works when `p > 6N` (`N=` ``prec``). The ``'auto'`` option
1441
+ selects ``'sqrtp'`` whenever possible.
1442
+
1443
+ Note that if the ``'sqrtp'`` algorithm is used, a consistency check
1444
+ will automatically be applied, regardless of the setting of the
1445
+ ``check`` flag.
1446
+
1447
+ OUTPUT: `p`-adic number to precision ``prec``
1448
+
1449
+ .. NOTE::
1450
+
1451
+ If the discriminant of the curve has nonzero valuation at p,
1452
+ then the result will not be returned mod `p^\text{prec}`,
1453
+ but it still *will* have ``prec`` *digits* of precision.
1454
+
1455
+ .. TODO::
1456
+
1457
+ Once we have a better implementation of the "standard"
1458
+ algorithm, the algorithm selection strategy for "auto" needs to be
1459
+ revisited.
1460
+
1461
+ AUTHORS:
1462
+
1463
+ - David Harvey (2006-09-01): partly based on code written
1464
+ by Robert Bradshaw at the MSRI 2006 modular forms workshop
1465
+
1466
+ ACKNOWLEDGMENT: - discussion with Eyal Goren that led to the trace
1467
+ trick.
1468
+
1469
+ EXAMPLES: Here is the example discussed in the paper "Computation
1470
+ of p-adic Heights and Log Convergence" (Mazur, Stein, Tate) [MST2006]_::
1471
+
1472
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5) # needs sage.symbolic
1473
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + O(5^20)
1474
+
1475
+ Let's try to higher precision (this is the same answer the MAGMA
1476
+ implementation gives)::
1477
+
1478
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 100) # needs sage.symbolic
1479
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + 2*5^30 + 5^31 + 4*5^33 + 3*5^34 + 4*5^35 + 5^36 + 4*5^37 + 4*5^38 + 3*5^39 + 4*5^41 + 2*5^42 + 3*5^43 + 2*5^44 + 2*5^48 + 3*5^49 + 4*5^50 + 2*5^51 + 5^52 + 4*5^53 + 4*5^54 + 3*5^55 + 2*5^56 + 3*5^57 + 4*5^58 + 4*5^59 + 5^60 + 3*5^61 + 5^62 + 4*5^63 + 5^65 + 3*5^66 + 2*5^67 + 5^69 + 2*5^70 + 3*5^71 + 3*5^72 + 5^74 + 5^75 + 5^76 + 3*5^77 + 4*5^78 + 4*5^79 + 2*5^80 + 3*5^81 + 5^82 + 5^83 + 4*5^84 + 3*5^85 + 2*5^86 + 3*5^87 + 5^88 + 2*5^89 + 4*5^90 + 4*5^92 + 3*5^93 + 4*5^94 + 3*5^95 + 2*5^96 + 4*5^97 + 4*5^98 + 2*5^99 + O(5^100)
1480
+
1481
+ Check it works at low precision too::
1482
+
1483
+ sage: # needs sage.symbolic
1484
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 1)
1485
+ 2 + O(5)
1486
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 2)
1487
+ 2 + 4*5 + O(5^2)
1488
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 3)
1489
+ 2 + 4*5 + O(5^3)
1490
+
1491
+ TODO: With the old(-er), i.e., = sage-2.4 `p`-adics we got
1492
+ `5 + O(5^2)` as output, i.e., relative precision 1, but
1493
+ with the newer `p`-adics we get relative precision 0 and absolute
1494
+ precision 1.
1495
+
1496
+ ::
1497
+
1498
+ sage: EllipticCurve([1, 1, 1, 1, 1]).padic_E2(5, 1) # needs sage.symbolic
1499
+ O(5)
1500
+
1501
+ Check it works for different models of the same curve (37a), even
1502
+ when the discriminant changes by a power of p (note that E2 depends
1503
+ on the differential too, which is why it gets scaled in some of the
1504
+ examples below)::
1505
+
1506
+ sage: X1 = EllipticCurve([-1, 1/4])
1507
+ sage: X1.j_invariant(), X1.discriminant()
1508
+ (110592/37, 37)
1509
+ sage: X1.padic_E2(5, 10) # needs sage.symbolic
1510
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)
1511
+
1512
+ ::
1513
+
1514
+ sage: X2 = EllipticCurve([0, 0, 1, -1, 0])
1515
+ sage: X2.j_invariant(), X2.discriminant()
1516
+ (110592/37, 37)
1517
+ sage: X2.padic_E2(5, 10) # needs sage.symbolic
1518
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)
1519
+
1520
+ ::
1521
+
1522
+ sage: X3 = EllipticCurve([-1*(2**4), 1/4*(2**6)])
1523
+ sage: X3.j_invariant(), X3.discriminant() / 2**12
1524
+ (110592/37, 37)
1525
+ sage: 2**(-2) * X3.padic_E2(5, 10) # needs sage.symbolic
1526
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)
1527
+
1528
+ ::
1529
+
1530
+ sage: X4 = EllipticCurve([-1*(7**4), 1/4*(7**6)])
1531
+ sage: X4.j_invariant(), X4.discriminant() / 7**12
1532
+ (110592/37, 37)
1533
+ sage: 7**(-2) * X4.padic_E2(5, 10) # needs sage.symbolic
1534
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)
1535
+
1536
+ ::
1537
+
1538
+ sage: X5 = EllipticCurve([-1*(5**4), 1/4*(5**6)])
1539
+ sage: X5.j_invariant(), X5.discriminant() / 5**12
1540
+ (110592/37, 37)
1541
+ sage: 5**(-2) * X5.padic_E2(5, 10) # needs sage.symbolic
1542
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)
1543
+
1544
+ ::
1545
+
1546
+ sage: X6 = EllipticCurve([-1/(5**4), 1/4/(5**6)])
1547
+ sage: X6.j_invariant(), X6.discriminant() * 5**12
1548
+ (110592/37, 37)
1549
+ sage: 5**2 * X6.padic_E2(5, 10) # needs sage.symbolic
1550
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)
1551
+
1552
+ Test check=True vs check=False::
1553
+
1554
+ sage: # needs sage.symbolic
1555
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 1, check=False)
1556
+ 2 + O(5)
1557
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 1, check=True)
1558
+ 2 + O(5)
1559
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 30, check=False)
1560
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + O(5^30)
1561
+ sage: EllipticCurve([-1, 1/4]).padic_E2(5, 30, check=True)
1562
+ 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + O(5^30)
1563
+
1564
+ Here's one using the `p^{1/2}` algorithm::
1565
+
1566
+ sage: EllipticCurve([-1, 1/4]).padic_E2(3001, 3, algorithm='sqrtp') # needs sage.symbolic
1567
+ 1907 + 2819*3001 + 1124*3001^2 + O(3001^3)
1568
+ """
1569
+ if self.conductor() % p == 0:
1570
+ if not self.conductor() % (p**2) == 0:
1571
+ eq = self.tate_curve(p)
1572
+ return eq.E2(prec=prec)
1573
+
1574
+ X = self.minimal_model().short_weierstrass_model()
1575
+ frob_p = X.matrix_of_frobenius(p, prec, check, check_hypotheses, algorithm).change_ring(Integers(p**prec))
1576
+
1577
+ frob_p_n = frob_p**prec
1578
+
1579
+ # todo: think about the sign of this. Is it correct?
1580
+ output_ring = Qp(p, prec)
1581
+
1582
+ E2_of_X = output_ring( (-12 * frob_p_n[0,1] / frob_p_n[1,1]).lift() ) \
1583
+ + O(p**prec)
1584
+
1585
+ # Take into account the coordinate change.
1586
+ fudge_factor = (X.discriminant() / self.discriminant()).nth_root(6)
1587
+ # todo: here I should be able to write:
1588
+ # return E2_of_X / fudge_factor
1589
+ # However, there is a bug in Sage (#51 on trac) which makes this
1590
+ # crash sometimes when prec == 1. For example,
1591
+ # EllipticCurve([1, 1, 1, 1, 1]).padic_E2(5, 1)
1592
+ # makes it crash. I haven't figured out exactly what the bug
1593
+ # is yet, but for now I use the following workaround:
1594
+ fudge_factor_inverse = Qp(p, prec=(E2_of_X.precision_absolute() + 1))(1 / fudge_factor)
1595
+ return output_ring(E2_of_X * fudge_factor_inverse)
1596
+
1597
+
1598
+ def matrix_of_frobenius(self, p, prec=20, check=False, check_hypotheses=True, algorithm='auto'):
1599
+ r"""
1600
+ Return the matrix of Frobenius on the Monsky Washnitzer cohomology of
1601
+ the short Weierstrass model of the minimal model of the elliptic curve.
1602
+
1603
+ INPUT:
1604
+
1605
+ - ``p`` -- prime (>= 3) for which `E` is good and ordinary
1606
+
1607
+ - ``prec`` -- (relative) `p`-adic precision for result (default: 20)
1608
+
1609
+ - ``check`` -- boolean (default: ``False``); whether to perform a
1610
+ consistency check. This will slow down the computation by a
1611
+ constant factor 2. (The consistency check is to verify
1612
+ that its trace is correct to the specified precision. Otherwise,
1613
+ the trace is used to compute one column from the other one
1614
+ (possibly after a change of basis).)
1615
+
1616
+ - ``check_hypotheses`` -- boolean; whether to check that this is a curve
1617
+ for which the `p`-adic sigma function makes sense
1618
+
1619
+ - ``algorithm`` -- one of ``'standard'``, ``'sqrtp'``, or
1620
+ ``'auto'``. This selects which version of Kedlaya's algorithm is used.
1621
+ The ``'standard'`` one is the one described in Kedlaya's paper. The
1622
+ ``'sqrtp'`` one has better performance for large `p`, but only
1623
+ works when `p > 6N` (`N=` prec). The ``'auto'`` option
1624
+ selects ``'sqrtp'`` whenever possible.
1625
+
1626
+ Note that if the ``'sqrtp'`` algorithm is used, a consistency check
1627
+ will automatically be applied, regardless of the setting of the
1628
+ ``check`` flag.
1629
+
1630
+ OUTPUT: a matrix of `p`-adic number to precision ``prec``
1631
+
1632
+ See also the documentation of padic_E2.
1633
+
1634
+ EXAMPLES::
1635
+
1636
+ sage: # needs database_cremona_mini_ellcurve sage.symbolic
1637
+ sage: E = EllipticCurve('37a1')
1638
+ sage: E.matrix_of_frobenius(7)
1639
+ [ 2*7 + 4*7^2 + 5*7^4 + 6*7^5 + 6*7^6 + 7^8 + 4*7^9 + 3*7^10 + 2*7^11 + 5*7^12 + 4*7^14 + 7^16 + 2*7^17 + 3*7^18 + 4*7^19 + 3*7^20 + O(7^21) 2 + 3*7 + 6*7^2 + 7^3 + 3*7^4 + 5*7^5 + 3*7^7 + 7^8 + 3*7^9 + 6*7^13 + 7^14 + 7^16 + 5*7^17 + 4*7^18 + 7^19 + O(7^20)]
1640
+ [ 2*7 + 3*7^2 + 7^3 + 3*7^4 + 6*7^5 + 2*7^6 + 3*7^7 + 5*7^8 + 3*7^9 + 2*7^11 + 6*7^12 + 5*7^13 + 4*7^16 + 4*7^17 + 6*7^18 + 6*7^19 + 4*7^20 + O(7^21) 6 + 4*7 + 2*7^2 + 6*7^3 + 7^4 + 6*7^7 + 5*7^8 + 2*7^9 + 3*7^10 + 4*7^11 + 7^12 + 6*7^13 + 2*7^14 + 6*7^15 + 5*7^16 + 4*7^17 + 3*7^18 + 2*7^19 + O(7^20)]
1641
+ sage: M = E.matrix_of_frobenius(11,prec=3); M
1642
+ [ 9*11 + 9*11^3 + O(11^4) 10 + 11 + O(11^3)]
1643
+ [ 2*11 + 11^2 + O(11^4) 6 + 11 + 10*11^2 + O(11^3)]
1644
+ sage: M.det()
1645
+ 11 + O(11^4)
1646
+ sage: M.trace()
1647
+ 6 + 10*11 + 10*11^2 + O(11^3)
1648
+ sage: E.ap(11)
1649
+ -5
1650
+ sage: E = EllipticCurve('83a1')
1651
+ sage: E.matrix_of_frobenius(3,6)
1652
+ [ 2*3 + 3^5 + O(3^6) 2*3 + 2*3^2 + 2*3^3 + O(3^6)]
1653
+ [ 2*3 + 3^2 + 2*3^5 + O(3^6) 2 + 2*3^2 + 2*3^3 + 2*3^4 + 3^5 + O(3^6)]
1654
+ """
1655
+ p = Integer(p)
1656
+ prec = int(prec)
1657
+
1658
+ if p < 3:
1659
+ raise NotImplementedError("p (=%s) must be at least 3" % p)
1660
+ if prec < 1:
1661
+ raise ValueError("prec (=%s) must be at least 1" % prec)
1662
+
1663
+ if check_hypotheses:
1664
+ p = __check_padic_hypotheses(self, p)
1665
+
1666
+ if algorithm == "auto":
1667
+ algorithm = "standard" if p < 6*prec else "sqrtp"
1668
+ elif algorithm == "sqrtp" and p < 6*prec:
1669
+ raise ValueError("sqrtp algorithm is only available when p > 6*prec")
1670
+
1671
+ if algorithm not in ["standard", "sqrtp"]:
1672
+ raise ValueError("unknown algorithm '%s'" % algorithm)
1673
+
1674
+ # for p = 3, we create the corresponding hyperelliptic curve
1675
+ # and call matrix of frobenius on it
1676
+ if p == 3:
1677
+ from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve
1678
+ f,g = self.hyperelliptic_polynomials()
1679
+ return HyperellipticCurve(f + (g/2)**2).matrix_of_frobenius(p,prec)
1680
+
1681
+ # To run matrix_of_frobenius(), we need to have the equation in the
1682
+ # form y^2 = x^3 + ax + b, whose discriminant is invertible mod p.
1683
+ # When we change coordinates like this, we might scale the invariant
1684
+ # differential, so we need to account for this. We do this by
1685
+ # comparing discriminants: if the discriminants differ by u^12,
1686
+ # then the differentials differ by u. There's a sign ambiguity here,
1687
+ # but it doesn't matter because E2 changes by u^2 :-)
1688
+
1689
+ # todo: In fact, there should be available a function that returns
1690
+ # exactly *which* coordinate change was used. If I had that I could
1691
+ # avoid the discriminant circus at the end.
1692
+
1693
+ # todo: The following strategy won't work at all for p = 2, 3.
1694
+
1695
+ # TODO change the basis back to the original equation.
1696
+ X = self.minimal_model().short_weierstrass_model()
1697
+
1698
+ assert X.discriminant().valuation(p) == 0, "Something's gone wrong. " \
1699
+ "The discriminant of the Weierstrass model should be a unit " \
1700
+ " at p."
1701
+
1702
+ if algorithm == "standard":
1703
+ # Need to increase precision a little to compensate for precision
1704
+ # losses during the computation. (See monsky_washnitzer.py
1705
+ # for more details.)
1706
+ adjusted_prec = sage.schemes.hyperelliptic_curves.monsky_washnitzer.adjusted_prec(p, prec)
1707
+
1708
+ if check:
1709
+ trace = None
1710
+ else:
1711
+ trace = self.ap(p)
1712
+
1713
+ base_ring = Integers(p**adjusted_prec)
1714
+
1715
+ R, x = PolynomialRing(base_ring, 'x').objgen()
1716
+ Q = x**3 + base_ring(X.a4()) * x + base_ring(X.a6())
1717
+ frob_p = sage.schemes.hyperelliptic_curves.monsky_washnitzer.matrix_of_frobenius(
1718
+ Q, p, adjusted_prec, trace)
1719
+
1720
+ else: # algorithm == "sqrtp"
1721
+ p_to_prec = p**prec
1722
+ R = PolynomialRing(Integers(), "x")
1723
+ Q = R([X.a6() % p_to_prec, X.a4() % p_to_prec, 0, 1])
1724
+ frob_p = sage.schemes.hyperelliptic_curves.hypellfrob.hypellfrob(p, prec, Q)
1725
+
1726
+ # let's force a trace-check since this algorithm is fairly new
1727
+ # and we don't want to get caught with our pants down...
1728
+ trace = self.ap(p)
1729
+ check = True
1730
+
1731
+ if check:
1732
+ trace_of_frobenius = frob_p.trace().lift() % p**prec
1733
+ correct_trace = self.ap(p) % p**prec
1734
+ assert trace_of_frobenius == correct_trace, \
1735
+ "Consistency check failed! (correct = %s, actual = %s)" % \
1736
+ (correct_trace, trace_of_frobenius)
1737
+
1738
+ return frob_p.change_ring(Zp(p, prec))
1739
+
1740
+
1741
+ def _brent(F, p, N):
1742
+ r"""
1743
+ This is an internal function; it is used by padic_sigma().
1744
+
1745
+ `F` is a assumed to be a power series over `R = \ZZ/p^{N-1}\ZZ`.
1746
+
1747
+ It solves the differential equation `G'(t)/G(t) = F(t)`
1748
+ using Brent's algorithm, with initial condition `G(0) = 1`.
1749
+ It is assumed that the solution `G` has `p`-integral coefficients.
1750
+
1751
+ More precisely, suppose that `f(t)` is a power series with
1752
+ genuine `p`-adic coefficients, and suppose that
1753
+ `g(t)` is an exact solution to `g'(t)/g(t) = f(t)`.
1754
+ Let `I` be the ideal
1755
+ `(p^N, p^{N-1} t, \ldots, p t^{N-1}, t^N)`. The input
1756
+ `F(t)` should be a finite-precision approximation to
1757
+ `f(t)`, in the sense that `\int (F - f) dt` should
1758
+ lie in `I`. Then the function returns a series
1759
+ `G(t)` such that `(G - g)(t)` lies in `I`.
1760
+
1761
+ Complexity should be about `O(N^2 \log^2 N \log p)`, plus
1762
+ some log-log factors.
1763
+
1764
+ For more information, and a proof of the precision guarantees, see
1765
+ Lemma 4 in [Har2009]_.
1766
+
1767
+ AUTHORS:
1768
+
1769
+ - David Harvey (2007-02)
1770
+
1771
+ EXAMPLES: Carefully test the precision guarantees::
1772
+
1773
+ sage: brent = sage.schemes.elliptic_curves.padics._brent
1774
+ sage: for p in [2, 3, 5]:
1775
+ ....: for N in [2, 3, 10, 50]:
1776
+ ....: R = Integers(p**(N-1))
1777
+ ....: Rx.<x> = PowerSeriesRing(R, "x")
1778
+ ....: for _ in range(5):
1779
+ ....: g = [R.random_element() for i in range(N)]
1780
+ ....: g[0] = R(1)
1781
+ ....: g = Rx(g, len(g))
1782
+ ....: f = g.derivative() / g
1783
+ ....: # perturb f by something whose integral is in I
1784
+ ....: err = [R.random_element() * p**(N-i) for i in range(N+1)]
1785
+ ....: err = Rx(err, len(err))
1786
+ ....: err = err.derivative()
1787
+ ....: F = f + err
1788
+ ....: # run brent() and compare output modulo I
1789
+ ....: G = brent(F, p, N)
1790
+ ....: assert G.prec() >= N, "not enough output terms"
1791
+ ....: err = (G - g).list()
1792
+ ....: for i in range(len(err)):
1793
+ ....: assert err[i].lift().valuation(p) >= (N - i), \
1794
+ ....: "incorrect precision output"
1795
+ """
1796
+ Rx = F.parent() # Rx = power series ring over Z/p^{N-1} Z
1797
+ Qx = PowerSeriesRing(RationalField(), "x")
1798
+
1799
+ # initial approximation:
1800
+ G = Rx.one()
1801
+
1802
+ from sage.misc.misc import newton_method_sizes
1803
+
1804
+ # loop over an appropriate increasing sequence of lengths s
1805
+ for s in newton_method_sizes(N):
1806
+ # zero-extend to s terms
1807
+ # todo: there has to be a better way in Sage to do this...
1808
+ G = Rx(G.list(), s)
1809
+
1810
+ # extend current approximation to be correct to s terms
1811
+ H = G.derivative() / G - F
1812
+ # Do the integral of H over QQ[x] to avoid division by p problems
1813
+ H = Rx(Qx(H).integral())
1814
+ G = G * (1 - H)
1815
+
1816
+ return G