passagemath-schemes 10.8.1a4__cp314-cp314t-macosx_13_0_arm64.whl

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