passagemath-schemes 10.6.38__cp314-cp314t-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-schemes might be problematic. Click here for more details.

Files changed (314) hide show
  1. passagemath_schemes/.dylibs/libflint.21.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.38.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.38.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-314t-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-314t-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-314t-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-314t-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-314t-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-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 +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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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,2234 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ r"""
3
+ Period lattices of elliptic curves and related functions
4
+
5
+ Let `E` be an elliptic curve defined over a number field `K`
6
+ (including `\QQ`). We attach a period lattice (a discrete rank 2
7
+ subgroup of `\CC`) to each embedding of `K` into `\CC`.
8
+
9
+ In the case of real embeddings, the lattice is stable under complex
10
+ conjugation and is called a real lattice. These have two types:
11
+ rectangular, (the real curve has two connected components and positive
12
+ discriminant) or non-rectangular (one connected component, negative
13
+ discriminant).
14
+
15
+ The periods are computed to arbitrary precision using the AGM (Gauss's
16
+ Arithmetic-Geometric Mean).
17
+
18
+ EXAMPLES::
19
+
20
+ sage: x = polygen(ZZ, 'x')
21
+ sage: K.<a> = NumberField(x^3 - 2) # needs sage.rings.number_field
22
+ sage: E = EllipticCurve([0,1,0,a,a]) # needs sage.rings.number_field
23
+
24
+ First we try a real embedding::
25
+
26
+ sage: emb = K.embeddings(RealField())[0] # needs sage.rings.number_field
27
+ sage: L = E.period_lattice(emb); L # needs sage.rings.number_field
28
+ Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a
29
+ over Number Field in a with defining polynomial x^3 - 2
30
+ with respect to the embedding Ring morphism:
31
+ From: Number Field in a with defining polynomial x^3 - 2
32
+ To: Algebraic Real Field
33
+ Defn: a |--> 1.259921049894873?
34
+
35
+ The first basis period is real::
36
+
37
+ sage: L.basis() # needs sage.rings.number_field
38
+ (3.81452977217855, 1.90726488608927 + 1.34047785962440*I)
39
+ sage: L.is_real() # needs sage.rings.number_field
40
+ True
41
+
42
+ For a basis `\omega_1,\omega_2` normalised so that `\omega_1/\omega_2`
43
+ is in the fundamental region of the upper half-plane, use the method
44
+ :meth:`~sage.schemes.elliptic_curves.period_lattice.PeriodLattice_ell.normalised_basis`
45
+ instead::
46
+
47
+ sage: L.normalised_basis() # needs sage.rings.number_field
48
+ (1.90726488608927 - 1.34047785962440*I, -1.90726488608927 - 1.34047785962440*I)
49
+
50
+ Next a complex embedding::
51
+
52
+ sage: emb = K.embeddings(ComplexField())[0] # needs sage.rings.number_field
53
+ sage: L = E.period_lattice(emb); L # needs sage.rings.number_field
54
+ Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a
55
+ over Number Field in a with defining polynomial x^3 - 2
56
+ with respect to the embedding Ring morphism:
57
+ From: Number Field in a with defining polynomial x^3 - 2
58
+ To: Algebraic Field
59
+ Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I
60
+
61
+ In this case, the basis `\omega_1`, `\omega_2` is always normalised so
62
+ that `\tau = \omega_1/\omega_2` is in the fundamental region in the
63
+ upper half plane::
64
+
65
+ sage: # needs sage.rings.number_field
66
+ sage: w1, w2 = L.basis(); w1, w2
67
+ (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I)
68
+ sage: L.is_real()
69
+ False
70
+ sage: tau = w1/w2; tau
71
+ 0.387694505032876 + 1.30821088214407*I
72
+ sage: L.normalised_basis()
73
+ (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I)
74
+
75
+ We test that bug :issue:`8415` (caused by a PARI bug fixed in v2.3.5) is OK::
76
+
77
+ sage: # needs database_cremona_mini_ellcurve sage.rings.number_field
78
+ sage: E = EllipticCurve('37a')
79
+ sage: K.<a> = QuadraticField(-7)
80
+ sage: EK = E.change_ring(K)
81
+ sage: EK.period_lattice(K.complex_embeddings()[0])
82
+ Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 + (-1)*x
83
+ over Number Field in a with defining polynomial x^2 + 7
84
+ with a = 2.645751311064591?*I
85
+ with respect to the embedding Ring morphism:
86
+ From: Number Field in a with defining polynomial x^2 + 7
87
+ with a = 2.645751311064591?*I
88
+ To: Algebraic Field
89
+ Defn: a |--> -2.645751311064591?*I
90
+
91
+ REFERENCES:
92
+
93
+ - [CT2013]_
94
+
95
+ AUTHORS:
96
+
97
+ - ?: initial version.
98
+
99
+ - John Cremona:
100
+
101
+ - Adapted to handle real embeddings of number fields, September 2008.
102
+
103
+ - Added basis_matrix function, November 2008
104
+
105
+ - Added support for complex embeddings, May 2009.
106
+
107
+ - Added complex elliptic logs, March 2010; enhanced, October 2010.
108
+ """
109
+
110
+ import sage.rings.abc
111
+
112
+ from sage.categories.morphism import IdentityMorphism
113
+ from sage.misc.cachefunc import cached_method
114
+ from sage.misc.lazy_import import lazy_import
115
+ from sage.modules.free_module import FreeModule_generic_pid
116
+ from sage.rings.complex_mpfr import ComplexField, ComplexNumber
117
+ from sage.rings.infinity import Infinity
118
+ from sage.rings.integer_ring import ZZ
119
+ from sage.rings.qqbar import AA, QQbar
120
+ from sage.rings.rational_field import QQ
121
+ from sage.rings.real_mpfr import RealField, RealNumber
122
+ from sage.schemes.elliptic_curves.constructor import EllipticCurve
123
+ from sage.structure.richcmp import richcmp_method, richcmp, richcmp_not_equal
124
+
125
+ lazy_import('sage.libs.pari', 'pari')
126
+ lazy_import('sage.rings.number_field.number_field', 'refine_embedding')
127
+
128
+
129
+ class PeriodLattice(FreeModule_generic_pid):
130
+ """
131
+ The class for the period lattice of an algebraic variety.
132
+ """
133
+ pass
134
+
135
+
136
+ @richcmp_method
137
+ class PeriodLattice_ell(PeriodLattice):
138
+ r"""
139
+ The class for the period lattice of an elliptic curve.
140
+
141
+ Currently supported are elliptic curves defined over `\QQ`, and
142
+ elliptic curves defined over a number field with a real or complex
143
+ embedding, where the lattice constructed depends on that
144
+ embedding.
145
+ """
146
+
147
+ def __init__(self, E, embedding=None):
148
+ r"""
149
+ Initialises the period lattice by storing the elliptic curve and the embedding.
150
+
151
+ INPUT:
152
+
153
+ - ``E`` -- an elliptic curve
154
+
155
+ - ``embedding`` -- (default: ``None``) an embedding of the base
156
+ field `K` of ``E`` into a real or complex field. If ``None``:
157
+
158
+ - use the built-in coercion to `\RR` for `K=\QQ`;
159
+
160
+ - use the first embedding into `\RR` given by
161
+ ``K.embeddings(RealField())``, if there are any;
162
+
163
+ - use the first embedding into `\CC` given by
164
+ ``K.embeddings(ComplexField())``, if `K` is totally complex.
165
+
166
+ .. NOTE::
167
+
168
+ No periods are computed on creation of the lattice; see the
169
+ methods :meth:`basis`, :meth:`normalised_basis` and
170
+ :meth:`real_period` for precision setting.
171
+
172
+ EXAMPLES:
173
+
174
+ This function is not normally called directly, but will be
175
+ called by the period_lattice() function of classes
176
+ ell_number_field and ell_rational_field::
177
+
178
+ sage: from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell
179
+
180
+ sage: # needs database_cremona_mini_ellcurve
181
+ sage: E = EllipticCurve('37a')
182
+ sage: PeriodLattice_ell(E)
183
+ Period lattice associated to
184
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
185
+
186
+ ::
187
+
188
+ sage: # needs sage.rings.number_field
189
+ sage: x = polygen(ZZ, 'x')
190
+ sage: K.<a> = NumberField(x^3 - 2)
191
+ sage: emb = K.embeddings(RealField())[0]
192
+ sage: E = EllipticCurve([0,1,0,a,a])
193
+ sage: L = PeriodLattice_ell(E, emb); L
194
+ Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a
195
+ over Number Field in a with defining polynomial x^3 - 2
196
+ with respect to the embedding Ring morphism:
197
+ From: Number Field in a with defining polynomial x^3 - 2
198
+ To: Algebraic Real Field
199
+ Defn: a |--> 1.259921049894873?
200
+
201
+ sage: emb = K.embeddings(ComplexField())[0] # needs sage.rings.number_field
202
+ sage: L = PeriodLattice_ell(E, emb); L # needs sage.rings.number_field
203
+ Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a
204
+ over Number Field in a with defining polynomial x^3 - 2
205
+ with respect to the embedding Ring morphism:
206
+ From: Number Field in a with defining polynomial x^3 - 2
207
+ To: Algebraic Field
208
+ Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I
209
+
210
+ TESTS::
211
+
212
+ sage: # needs sage.rings.number_field
213
+ sage: from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell
214
+ sage: K.<a> = NumberField(x^3 - 2)
215
+ sage: emb = K.embeddings(RealField())[0]
216
+ sage: E = EllipticCurve([0,1,0,a,a])
217
+ sage: L = PeriodLattice_ell(E,emb)
218
+ sage: L == loads(dumps(L))
219
+ True
220
+
221
+ Elliptic curve over imaginary number field without ``embedding`` specified::
222
+
223
+ sage: E = EllipticCurve(QQ[I], [5, -3*I])
224
+ sage: L = PeriodLattice_ell(E, embedding=None)
225
+ sage: L.elliptic_logarithm(E(I+1, I+2)) # abs tol 1e-15
226
+ -0.773376784700140 - 0.177736018028666*I
227
+ sage: L.elliptic_exponential(_) # abs tol 1e-15
228
+ (1.00000000000000 - 1.00000000000000*I : 2.00000000000000 - 1.00000000000000*I : 1.00000000000000)
229
+ """
230
+ # First we cache the elliptic curve with this period lattice:
231
+
232
+ self.E = E
233
+
234
+ # Next we cache the embedding into QQbar or AA which extends
235
+ # the given embedding:
236
+
237
+ K = E.base_field()
238
+ self._is_exact = K.is_exact()
239
+ if embedding is None:
240
+ if K in (AA, QQbar):
241
+ embedding = K.hom(QQbar)
242
+ real = K == AA
243
+ elif not self._is_exact:
244
+ embedding = IdentityMorphism(K)
245
+ real = isinstance(K, (sage.rings.abc.RealField, sage.rings.abc.RealDoubleField))
246
+ else:
247
+ embs = K.embeddings(AA)
248
+ real = len(embs) > 0
249
+ if not real:
250
+ embs = K.embeddings(QQbar)
251
+ embedding = embs[0]
252
+ else:
253
+ embedding = refine_embedding(embedding, Infinity)
254
+ real = embedding(K.gen()).imag().is_zero()
255
+
256
+ self.embedding = embedding
257
+
258
+ # Next we compute and cache (in self.real_flag) the type of
259
+ # the lattice: +1 for real rectangular, -1 for real
260
+ # non-rectangular, 0 for non-real:
261
+
262
+ self.real_flag = 0
263
+ if real:
264
+ self.real_flag = +1
265
+ if embedding(E.discriminant()) < 0:
266
+ self.real_flag = -1
267
+
268
+ # The following algebraic data associated to E and the
269
+ # embedding is cached:
270
+ #
271
+ # Ebar: the curve E base-changed to QQbar (or AA)
272
+ # f2: the 2-division polynomial of Ebar
273
+ # ei: the roots e1, e2, e3 of f2, as elements of QQbar (or AA)
274
+ #
275
+ # The ei are used both for period computation and elliptic
276
+ # logarithms.
277
+
278
+ if self._is_exact:
279
+ self.Ebar = self.E.change_ring(self.embedding)
280
+ self.f2 = self.Ebar.two_division_polynomial()
281
+ else:
282
+ self.f2 = self.E.two_division_polynomial()
283
+ if self.real_flag == 1: # positive discriminant
284
+ self._ei = self.f2.roots(AA if self._is_exact else K, multiplicities=False)
285
+ self._ei.sort() # e1 < e2 < e3
286
+ e1, e2, e3 = self._ei
287
+ elif self.real_flag == -1: # negative discriminant
288
+ self._ei = self.f2.roots(QQbar if self._is_exact else ComplexField(K.precision()), multiplicities=False)
289
+ self._ei = sorted(self._ei, key=lambda z: z.imag())
290
+ e1, e3, e2 = self._ei # so e3 is real
291
+ if self._is_exact:
292
+ e3 = AA(e3)
293
+ self._ei = [e1, e2, e3]
294
+ else:
295
+ self._ei = self.f2.roots(QQbar if self._is_exact else ComplexField(K.precision()), multiplicities=False)
296
+ e1, e2, e3 = self._ei
297
+
298
+ # The quantities sqrt(e_i-e_j) are cached (as elements of
299
+ # QQbar) to be used in period computations:
300
+
301
+ self._abc = (e3-e1).sqrt(), (e3-e2).sqrt(), (e2-e1).sqrt()
302
+
303
+ PeriodLattice.__init__(self, base_ring=ZZ, rank=2, degree=1, sparse=False)
304
+
305
+ def __richcmp__(self, other, op):
306
+ r"""
307
+ Comparison function for period lattices.
308
+
309
+ TESTS::
310
+
311
+ sage: # needs sage.rings.number_field
312
+ sage: from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell
313
+ sage: x = polygen(ZZ, 'x')
314
+ sage: K.<a> = NumberField(x^3 - 2)
315
+ sage: E = EllipticCurve([0,1,0,a,a])
316
+ sage: embs = K.embeddings(ComplexField())
317
+ sage: L1, L2, L3 = [PeriodLattice_ell(E, e) for e in embs]
318
+ sage: L1 < L2 < L3
319
+ True
320
+ """
321
+ if not isinstance(other, PeriodLattice_ell):
322
+ return NotImplemented
323
+
324
+ lx = self.E
325
+ rx = other.E
326
+ if lx != rx:
327
+ return richcmp_not_equal(lx, rx, op)
328
+
329
+ a = self.E.base_field().gen()
330
+ return richcmp(self.embedding(a), other.embedding(a), op)
331
+
332
+ def __repr__(self):
333
+ """
334
+ Return the string representation of this period lattice.
335
+
336
+ EXAMPLES::
337
+
338
+ sage: # needs database_cremona_mini_ellcurve
339
+ sage: E = EllipticCurve('37a')
340
+ sage: E.period_lattice()
341
+ Period lattice associated to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
342
+
343
+ ::
344
+
345
+ sage: # needs sage.rings.number_field
346
+ sage: x = polygen(ZZ, 'x')
347
+ sage: K.<a> = NumberField(x^3 - 2)
348
+ sage: emb = K.embeddings(RealField())[0]
349
+ sage: E = EllipticCurve([0,1,0,a,a])
350
+ sage: L = E.period_lattice(emb); L
351
+ Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x^2 + a*x + a over Number Field in a
352
+ with defining polynomial x^3 - 2 with respect to the embedding Ring morphism:
353
+ From: Number Field in a with defining polynomial x^3 - 2
354
+ To: Algebraic Real Field
355
+ Defn: a |--> 1.259921049894873?
356
+ """
357
+ K = self.E.base_field()
358
+ if K in (QQ, AA, QQbar) or isinstance(self.embedding, IdentityMorphism):
359
+ return "Period lattice associated to %s" % (self.E)
360
+ return "Period lattice associated to %s with respect to the embedding %s" % (self.E, self.embedding)
361
+
362
+ def __call__(self, P, prec=None):
363
+ r"""
364
+ Return the elliptic logarithm of a point `P`.
365
+
366
+ INPUT:
367
+
368
+ - ``P`` -- a point on the elliptic curve associated with this period
369
+ lattice
370
+
371
+ - ``prec`` -- (default: ``None``) precision in bits (default
372
+ precision if ``None``)
373
+
374
+ OUTPUT:
375
+
376
+ (complex number) The elliptic logarithm of the point `P` with
377
+ respect to this period lattice. If `E` is the elliptic curve
378
+ and `\sigma:K\to\CC` the embedding, then the returned value `z`
379
+ is such that `z\pmod{L}` maps to `\sigma(P)` under the
380
+ standard Weierstrass isomorphism from `\CC/L` to `\sigma(E)`.
381
+
382
+ EXAMPLES::
383
+
384
+ sage: # needs database_cremona_mini_ellcurve
385
+ sage: E = EllipticCurve('389a')
386
+ sage: L = E.period_lattice()
387
+ sage: E.discriminant() > 0
388
+ True
389
+ sage: L.real_flag
390
+ 1
391
+ sage: P = E([-1,1])
392
+ sage: P.is_on_identity_component ()
393
+ False
394
+ sage: L(P, prec=96) # abs tol 1e-27
395
+ 0.4793482501902193161295330101 + 0.985868850775824102211203849*I
396
+ sage: Q = E([3,5])
397
+ sage: Q.is_on_identity_component()
398
+ True
399
+ sage: L(Q, prec=96)
400
+ 1.931128271542559442488585220
401
+
402
+ Note that this is actually the inverse of the Weierstrass isomorphism::
403
+
404
+ sage: L.elliptic_exponential(L(Q)) # needs database_cremona_mini_ellcurve
405
+ (3.00000000000000 : 5.00000000000000 : 1.00000000000000)
406
+
407
+ An example with negative discriminant, and a torsion point::
408
+
409
+ sage: # needs database_cremona_mini_ellcurve
410
+ sage: E = EllipticCurve('11a1')
411
+ sage: L = E.period_lattice()
412
+ sage: E.discriminant() < 0
413
+ True
414
+ sage: L.real_flag
415
+ -1
416
+ sage: P = E([16,-61])
417
+ sage: L(P)
418
+ 0.253841860855911
419
+ sage: L.real_period() / L(P)
420
+ 5.00000000000000
421
+ """
422
+ return self.elliptic_logarithm(P,prec)
423
+
424
+ @cached_method
425
+ def basis(self, prec=None, algorithm='sage'):
426
+ r"""
427
+ Return a basis for this period lattice as a 2-tuple.
428
+
429
+ INPUT:
430
+
431
+ - ``prec`` -- (default: ``None``) precision in bits (default
432
+ precision if ``None``)
433
+
434
+ - ``algorithm`` -- string (default: ``'sage'``); choice of
435
+ implementation (for real embeddings only) between ``'sage'``
436
+ (native Sage implementation) or ``'pari'`` (use the PARI
437
+ library: only available for real embeddings)
438
+
439
+ OUTPUT:
440
+
441
+ (tuple of Complex) `(\omega_1,\omega_2)` where the lattice is
442
+ `\ZZ\omega_1 + \ZZ\omega_2`. If the lattice is real then
443
+ `\omega_1` is real and positive, `\Im(\omega_2)>0` and
444
+ `\Re(\omega_2/\omega_1)` is either `0` (for rectangular
445
+ lattices) or `\frac{1}{2}` (for non-rectangular lattices).
446
+ Otherwise, `\omega_1/\omega_2` is in the fundamental region of
447
+ the upper half-plane. If the latter normalisation is required
448
+ for real lattices, use the method :meth:`normalised_basis`
449
+ instead.
450
+
451
+ EXAMPLES::
452
+
453
+ sage: # needs database_cremona_mini_ellcurve
454
+ sage: E = EllipticCurve('37a')
455
+ sage: E.period_lattice().basis()
456
+ (2.99345864623196, 2.45138938198679*I)
457
+
458
+ This shows that the issue reported at :issue:`3954` is fixed::
459
+
460
+ sage: # needs database_cremona_mini_ellcurve
461
+ sage: E = EllipticCurve('37a')
462
+ sage: b1 = E.period_lattice().basis(prec=30)
463
+ sage: b2 = E.period_lattice().basis(prec=30)
464
+ sage: b1 == b2
465
+ True
466
+
467
+ This shows that the issue reported at :issue:`4064` is fixed::
468
+
469
+ sage: # needs database_cremona_mini_ellcurve
470
+ sage: E = EllipticCurve('37a')
471
+ sage: E.period_lattice().basis(prec=30)[0].parent()
472
+ Real Field with 30 bits of precision
473
+ sage: E.period_lattice().basis(prec=100)[0].parent()
474
+ Real Field with 100 bits of precision
475
+
476
+ ::
477
+
478
+ sage: # needs sage.rings.number_field
479
+ sage: x = polygen(ZZ, 'x')
480
+ sage: K.<a> = NumberField(x^3 - 2)
481
+ sage: emb = K.embeddings(RealField())[0]
482
+ sage: E = EllipticCurve([0,1,0,a,a])
483
+ sage: L = E.period_lattice(emb)
484
+ sage: L.basis(64)
485
+ (3.81452977217854509, 1.90726488608927255 + 1.34047785962440202*I)
486
+
487
+ sage: # needs sage.rings.number_field
488
+ sage: emb = K.embeddings(ComplexField())[0]
489
+ sage: L = E.period_lattice(emb)
490
+ sage: w1, w2 = L.basis(); w1, w2
491
+ (-1.37588604166076 - 2.58560946624443*I, -2.10339907847356 + 0.428378776460622*I)
492
+ sage: L.is_real()
493
+ False
494
+ sage: tau = w1/w2; tau
495
+ 0.387694505032876 + 1.30821088214407*I
496
+ """
497
+ # We divide into two cases: (1) Q, or a number field with a
498
+ # real embedding; (2) a number field with a complex embedding.
499
+ # In each case the periods are computed by a different
500
+ # internal function.
501
+
502
+ if self.is_real():
503
+ return self._compute_periods_real(prec=prec, algorithm=algorithm)
504
+ else:
505
+ return self._compute_periods_complex(prec=prec)
506
+
507
+ @cached_method
508
+ def gens(self, prec=None, algorithm='sage'):
509
+ r"""
510
+ Return a basis for this period lattice as a 2-tuple.
511
+
512
+ This is an alias for
513
+ :meth:`~sage.schemes.elliptic_curves.period_lattice.PeriodLattice_ell.basis`.
514
+ See the docstring there for a more in-depth explanation and further
515
+ examples.
516
+
517
+ INPUT:
518
+
519
+ - ``prec`` -- (default: ``None``) precision in bits (default
520
+ precision if ``None``)
521
+
522
+ - ``algorithm`` -- string (default: ``'sage'``); choice of
523
+ implementation (for real embeddings only) between ``'sage'``
524
+ (native Sage implementation) or ``'pari'`` (use the PARI
525
+ library: only available for real embeddings)
526
+
527
+ OUTPUT:
528
+
529
+ (tuple of Complex) `(\omega_1,\omega_2)` where the lattice is
530
+ `\ZZ\omega_1 + \ZZ\omega_2`. If the lattice is real then
531
+ `\omega_1` is real and positive, `\Im(\omega_2)>0` and
532
+ `\Re(\omega_2/\omega_1)` is either `0` (for rectangular
533
+ lattices) or `\frac{1}{2}` (for non-rectangular lattices).
534
+ Otherwise, `\omega_1/\omega_2` is in the fundamental region of
535
+ the upper half-plane. If the latter normalisation is required
536
+ for real lattices, use the method :meth:`normalised_basis`
537
+ instead.
538
+
539
+ EXAMPLES::
540
+
541
+ sage: # needs database_cremona_mini_ellcurve
542
+ sage: E = EllipticCurve('37a')
543
+ sage: E.period_lattice().gens()
544
+ (2.99345864623196, 2.45138938198679*I)
545
+ sage: E.period_lattice().gens(prec=100)
546
+ (2.9934586462319596298320099794, 2.4513893819867900608542248319*I)
547
+ """
548
+ return tuple(self.basis(prec=prec, algorithm=algorithm))
549
+
550
+ @cached_method
551
+ def normalised_basis(self, prec=None, algorithm='sage'):
552
+ r"""
553
+ Return a normalised basis for this period lattice as a 2-tuple.
554
+
555
+ INPUT:
556
+
557
+ - ``prec`` -- (default: ``None``) precision in bits (default
558
+ precision if ``None``)
559
+
560
+ - ``algorithm`` -- string (default: ``'sage'``); choice of
561
+ implementation (for real embeddings only) between ``'sage'``
562
+ (native Sage implementation) or ``'pari'`` (use the PARI
563
+ library: only available for real embeddings)
564
+
565
+ OUTPUT:
566
+
567
+ (tuple of Complex) `(\omega_1,\omega_2)` where the lattice has
568
+ the form `\ZZ\omega_1 + \ZZ\omega_2`. The basis is normalised
569
+ so that `\omega_1/\omega_2` is in the fundamental region of
570
+ the upper half-plane. For an alternative normalisation for
571
+ real lattices (with the first period real), use the method
572
+ :meth:`basis` instead.
573
+
574
+ EXAMPLES::
575
+
576
+ sage: # needs database_cremona_mini_ellcurve
577
+ sage: E = EllipticCurve('37a')
578
+ sage: E.period_lattice().normalised_basis()
579
+ (2.99345864623196, -2.45138938198679*I)
580
+
581
+ ::
582
+
583
+ sage: # needs sage.rings.number_field
584
+ sage: x = polygen(ZZ, 'x')
585
+ sage: K.<a> = NumberField(x^3 - 2)
586
+ sage: emb = K.embeddings(RealField())[0]
587
+ sage: E = EllipticCurve([0,1,0,a,a])
588
+ sage: L = E.period_lattice(emb)
589
+ sage: L.normalised_basis(64)
590
+ (1.90726488608927255 - 1.34047785962440202*I,
591
+ -1.90726488608927255 - 1.34047785962440202*I)
592
+
593
+ sage: # needs sage.rings.number_field
594
+ sage: emb = K.embeddings(ComplexField())[0]
595
+ sage: L = E.period_lattice(emb)
596
+ sage: w1, w2 = L.normalised_basis(); w1, w2
597
+ (-1.37588604166076 - 2.58560946624443*I,
598
+ -2.10339907847356 + 0.428378776460622*I)
599
+ sage: L.is_real()
600
+ False
601
+ sage: tau = w1/w2; tau
602
+ 0.387694505032876 + 1.30821088214407*I
603
+ """
604
+ w1, w2 = self.basis(prec=prec, algorithm=algorithm)
605
+ periods, _ = normalise_periods(w1, w2)
606
+ return periods
607
+
608
+ @cached_method
609
+ def tau(self, prec=None, algorithm='sage'):
610
+ r"""
611
+ Return the upper half-plane parameter in the fundamental region.
612
+
613
+ INPUT:
614
+
615
+ - ``prec`` -- (default: ``None``) precision in bits (default
616
+ precision if ``None``)
617
+
618
+ - ``algorithm`` -- string (default: ``'sage'``); choice of
619
+ implementation (for real embeddings only) between 'sage'
620
+ (native Sage implementation) or 'pari' (use the PARI
621
+ library: only available for real embeddings)
622
+
623
+ OUTPUT:
624
+
625
+ (Complex) `\tau = \omega_1/\omega_2` where the lattice has the
626
+ form `\ZZ\omega_1 + \ZZ\omega_2`, normalised so that `\tau =
627
+ \omega_1/\omega_2` is in the fundamental region of the upper
628
+ half-plane.
629
+
630
+ EXAMPLES::
631
+
632
+ sage: # needs database_cremona_mini_ellcurve
633
+ sage: E = EllipticCurve('37a')
634
+ sage: L = E.period_lattice()
635
+ sage: L.tau()
636
+ 1.22112736076463*I
637
+
638
+ ::
639
+
640
+ sage: # needs sage.rings.number_field
641
+ sage: x = polygen(ZZ, 'x')
642
+ sage: K.<a> = NumberField(x^3 - 2)
643
+ sage: emb = K.embeddings(RealField())[0]
644
+ sage: E = EllipticCurve([0,1,0,a,a])
645
+ sage: L = E.period_lattice(emb)
646
+ sage: tau = L.tau(); tau
647
+ -0.338718341018919 + 0.940887817679340*I
648
+ sage: tau.abs()
649
+ 1.00000000000000
650
+ sage: -0.5 <= tau.real() <= 0.5
651
+ True
652
+
653
+ sage: # needs sage.rings.number_field
654
+ sage: emb = K.embeddings(ComplexField())[0]
655
+ sage: L = E.period_lattice(emb)
656
+ sage: tau = L.tau(); tau
657
+ 0.387694505032876 + 1.30821088214407*I
658
+ sage: tau.abs()
659
+ 1.36444961115933
660
+ sage: -0.5 <= tau.real() <= 0.5
661
+ True
662
+ """
663
+ w1, w2 = self.normalised_basis(prec=prec, algorithm=algorithm)
664
+ return w1/w2
665
+
666
+ @cached_method
667
+ def _compute_default_prec(self):
668
+ r"""
669
+ Internal function to compute the default precision to be used if nothing is passed in.
670
+ """
671
+ return RealField().precision() if self._is_exact else self.E.base_field().precision()
672
+
673
+ @cached_method
674
+ def _compute_periods_real(self, prec=None, algorithm='sage'):
675
+ r"""
676
+ Internal function to compute the periods (real embedding case).
677
+
678
+ INPUT:
679
+
680
+ - ``prec`` -- integer or ``None`` (default); floating point
681
+ precision (in bits). If ``None``, use the default precision.
682
+
683
+ - ``algorithm`` string (default: ``'sage'``); choice of implementation between
684
+
685
+ - ``'pari'`` -- use the PARI library
686
+
687
+ - ``'sage'`` -- use a native Sage implementation (with the same underlying algorithm)
688
+
689
+ OUTPUT:
690
+
691
+ (tuple of Complex) `(\omega_1,\omega_2)` where the lattice has
692
+ the form `\ZZ\omega_1 + \ZZ\omega_2`, `\omega_1` is real and
693
+ `\omega_2/\omega_1` has real part either `0` or `frac{1}{2}`.
694
+
695
+ EXAMPLES::
696
+
697
+ sage: # needs sage.rings.number_field
698
+ sage: x = polygen(ZZ, 'x')
699
+ sage: K.<a> = NumberField(x^3 - 2)
700
+ sage: E = EllipticCurve([0,1,0,a,a])
701
+ sage: embs = K.embeddings(CC)
702
+ sage: Ls = [E.period_lattice(e) for e in embs]
703
+ sage: [L.is_real() for L in Ls]
704
+ [False, False, True]
705
+ sage: Ls[2]._compute_periods_real(100)
706
+ (3.8145297721785450936365098936,
707
+ 1.9072648860892725468182549468 + 1.3404778596244020196600112394*I)
708
+ sage: Ls[2]._compute_periods_real(100, algorithm='pari')
709
+ (3.8145297721785450936365098936,
710
+ 1.9072648860892725468182549468 - 1.3404778596244020196600112394*I)
711
+ """
712
+ if prec is None:
713
+ prec = self._compute_default_prec()
714
+ R = RealField(prec)
715
+ C = ComplexField(prec)
716
+
717
+ if algorithm == 'pari':
718
+ ainvs = self.E.a_invariants()
719
+ if self.E.base_field() is not QQ and self._is_exact:
720
+ ainvs = [C(self.embedding(ai)).real() for ai in ainvs]
721
+
722
+ # The precision for omega() is determined by ellinit()
723
+ E_pari = pari.ellinit(ainvs, precision=prec)
724
+ w1, w2 = E_pari.omega()
725
+ return R(w1), C(w2)
726
+
727
+ if algorithm != 'sage':
728
+ raise ValueError("invalid value of 'algorithm' parameter")
729
+
730
+ pi = R.pi()
731
+ # Up to now everything has been exact in AA or QQbar (if self._is_exact),
732
+ # but now we must go transcendental. Only now is the desired precision used!
733
+ if self.real_flag == 1: # positive discriminant
734
+ a, b, c = (R(x) for x in self._abc)
735
+ w1 = R(pi/a.agm(b)) # least real period
736
+ w2 = C(0,pi/a.agm(c)) # least pure imaginary period
737
+ else:
738
+ a = C(self._abc[0])
739
+ x, y, r = a.real().abs(), a.imag().abs(), a.abs()
740
+ w1 = R(pi/r.agm(x)) # least real period
741
+ w2 = R(pi/r.agm(y)) # least pure imaginary period /i
742
+ w2 = C(w1,w2)/2
743
+
744
+ return (w1,w2)
745
+
746
+ @cached_method
747
+ def _compute_periods_complex(self, prec=None, normalise=True):
748
+ r"""
749
+ Internal function to compute the periods (complex embedding case).
750
+
751
+ INPUT:
752
+
753
+ - ``prec`` -- integer or ``None`` (default); floating point precision
754
+ (in bits); if ``None``, use the default precision
755
+
756
+ - ``normalise`` -- boolean (default: ``True``); whether to normalise the
757
+ basis after computation
758
+
759
+ OUTPUT:
760
+
761
+ (tuple of Complex) `(\omega_1,\omega_2)` where the lattice has
762
+ the form `\ZZ\omega_1 + \ZZ\omega_2`. If `normalise` is
763
+ ``True``, the basis is normalised so that `(\omega_1/\omega_2)`
764
+ is in the fundamental region of the upper half plane.
765
+
766
+ EXAMPLES::
767
+
768
+ sage: # needs sage.rings.number_field
769
+ sage: x = polygen(ZZ, 'x')
770
+ sage: K.<a> = NumberField(x^3 - 2)
771
+ sage: E = EllipticCurve([0,1,0,a,a])
772
+ sage: embs = K.embeddings(CC)
773
+ sage: Ls = [E.period_lattice(e) for e in embs]
774
+ sage: [L.is_real() for L in Ls]
775
+ [False, False, True]
776
+ sage: L = Ls[0]
777
+ sage: w1,w2 = L._compute_periods_complex(100); w1,w2
778
+ (-1.3758860416607626645495991458 - 2.5856094662444337042877901304*I,
779
+ -2.1033990784735587243397865076 + 0.42837877646062187766760569686*I)
780
+ sage: tau = w1/w2; tau
781
+ 0.38769450503287609349437509561 + 1.3082108821440725664008561928*I
782
+ sage: tau.real()
783
+ 0.38769450503287609349437509561
784
+ sage: tau.abs()
785
+ 1.3644496111593345713923386773
786
+
787
+ Without normalisation::
788
+
789
+ sage: # needs sage.rings.number_field
790
+ sage: w1,w2 = L._compute_periods_complex(normalise=False); w1,w2
791
+ (2.10339907847356 - 0.428378776460622*I, 0.727513036812796 - 3.01398824270506*I)
792
+ sage: tau = w1/w2; tau
793
+ 0.293483964608883 + 0.627038168678760*I
794
+ sage: tau.real()
795
+ 0.293483964608883
796
+ sage: tau.abs() # > 1
797
+ 0.692321964451917
798
+ """
799
+ if prec is None:
800
+ prec = self._compute_default_prec()
801
+ C = ComplexField(prec)
802
+
803
+ # Up to now everything has been exact in AA or QQbar (if self._is_exact),
804
+ # but now we must go transcendental. Only now is the desired precision used!
805
+ pi = C.pi()
806
+ a, b, c = (C(x) for x in self._abc)
807
+ if (a+b).abs() < (a-b).abs():
808
+ b = -b
809
+ if (a+c).abs() < (a-c).abs():
810
+ c = -c
811
+ w1 = pi/a.agm(b)
812
+ w2 = pi*C.gen()/a.agm(c)
813
+ if (w1/w2).imag() < 0:
814
+ w2 = -w2
815
+ if normalise:
816
+ w1w2, mat = normalise_periods(w1,w2)
817
+ return w1w2
818
+ return (w1,w2)
819
+
820
+ def is_real(self):
821
+ r"""
822
+ Return ``True`` if this period lattice is real.
823
+
824
+ EXAMPLES::
825
+
826
+ sage: # needs database_cremona_mini_ellcurve
827
+ sage: f = EllipticCurve('11a')
828
+ sage: f.period_lattice().is_real()
829
+ True
830
+
831
+ ::
832
+
833
+ sage: # needs sage.rings.number_field
834
+ sage: K.<i> = QuadraticField(-1)
835
+ sage: E = EllipticCurve(K, [0,0,0,i,2*i])
836
+ sage: emb = K.embeddings(ComplexField())[0]
837
+ sage: L = E.period_lattice(emb)
838
+ sage: L.is_real()
839
+ False
840
+
841
+ ::
842
+
843
+ sage: x = polygen(ZZ, 'x')
844
+ sage: K.<a> = NumberField(x^3 - 2) # needs sage.rings.number_field
845
+ sage: E = EllipticCurve([0,1,0,a,a]) # needs sage.rings.number_field
846
+ sage: [E.period_lattice(emb).is_real() for emb in K.embeddings(CC)] # needs sage.rings.number_field
847
+ [False, False, True]
848
+
849
+ ALGORITHM:
850
+
851
+ The lattice is real if it is associated to a real embedding;
852
+ such lattices are stable under conjugation.
853
+ """
854
+ return self.real_flag != 0
855
+
856
+ def is_rectangular(self) -> bool:
857
+ r"""
858
+ Return ``True`` if this period lattice is rectangular.
859
+
860
+ .. NOTE::
861
+
862
+ Only defined for real lattices; a :exc:`RuntimeError`
863
+ is raised for non-real lattices.
864
+
865
+ EXAMPLES::
866
+
867
+ sage: # needs database_cremona_mini_ellcurve
868
+ sage: f = EllipticCurve('11a')
869
+ sage: f.period_lattice().basis()
870
+ (1.26920930427955, 0.634604652139777 + 1.45881661693850*I)
871
+ sage: f.period_lattice().is_rectangular()
872
+ False
873
+
874
+ ::
875
+
876
+ sage: # needs database_cremona_mini_ellcurve
877
+ sage: f = EllipticCurve('37b')
878
+ sage: f.period_lattice().basis()
879
+ (1.08852159290423, 1.76761067023379*I)
880
+ sage: f.period_lattice().is_rectangular()
881
+ True
882
+
883
+ ALGORITHM:
884
+
885
+ The period lattice is rectangular precisely if the
886
+ discriminant of the Weierstrass equation is positive, or
887
+ equivalently if the number of real components is 2.
888
+ """
889
+ if self.is_real():
890
+ return self.real_flag == +1
891
+ raise RuntimeError("Not defined for non-real lattices.")
892
+
893
+ def real_period(self, prec=None, algorithm='sage'):
894
+ """
895
+ Return the real period of this period lattice.
896
+
897
+ INPUT:
898
+
899
+ - ``prec`` -- integer or ``None`` (default); real precision in
900
+ bits (default real precision if ``None``)
901
+
902
+ - ``algorithm`` -- string (default: ``'sage'``); choice of
903
+ implementation (for real embeddings only) between ``'sage'``
904
+ (native Sage implementation) or ``'pari'`` (use the PARI
905
+ library: only available for real embeddings)
906
+
907
+ .. NOTE::
908
+
909
+ Only defined for real lattices; a :exc:`RuntimeError`
910
+ is raised for non-real lattices.
911
+
912
+ EXAMPLES::
913
+
914
+ sage: # needs database_cremona_mini_ellcurve
915
+ sage: E = EllipticCurve('37a')
916
+ sage: E.period_lattice().real_period()
917
+ 2.99345864623196
918
+
919
+ ::
920
+
921
+ sage: # needs sage.rings.number_field
922
+ sage: x = polygen(ZZ, 'x')
923
+ sage: K.<a> = NumberField(x^3 - 2)
924
+ sage: emb = K.embeddings(RealField())[0]
925
+ sage: E = EllipticCurve([0,1,0,a,a])
926
+ sage: L = E.period_lattice(emb)
927
+ sage: L.real_period(64)
928
+ 3.81452977217854509
929
+ """
930
+ if self.is_real():
931
+ return self.basis(prec,algorithm)[0]
932
+ raise RuntimeError("Not defined for non-real lattices.")
933
+
934
+ def omega(self, prec=None, bsd_normalise=False):
935
+ r"""
936
+ Return the real or complex volume of this period lattice.
937
+
938
+ INPUT:
939
+
940
+ - ``prec`` -- integer or ``None`` (default); real precision in
941
+ bits (default real precision if ``None``)
942
+
943
+ - ``bsd_normalise`` -- boolean (default: ``False``); flag to use
944
+ BSD normalisation in the complex case
945
+
946
+ OUTPUT:
947
+
948
+ (real) For real lattices, this is the real period times the
949
+ number of connected components. For non-real lattices it is
950
+ the complex area, or double the area if ``bsd_normalise`` is
951
+ ``True``.
952
+
953
+ .. NOTE::
954
+
955
+ If the curve is given by a *global minimal* Weierstrass
956
+ equation, then with ``bsd_normalise`` = ``True``, this
957
+ gives the correct period in the BSD conjecture: the product
958
+ of this quantity over all embeddings appears in the BSD
959
+ formula. In general a correction factor is required to make
960
+ allowance for the model.
961
+
962
+ EXAMPLES::
963
+
964
+ sage: # needs database_cremona_mini_ellcurve
965
+ sage: E = EllipticCurve('37a')
966
+ sage: E.period_lattice().omega()
967
+ 5.98691729246392
968
+
969
+ This is not a minimal model::
970
+
971
+ sage: E = EllipticCurve([0, -432*6^2])
972
+ sage: E.period_lattice().omega()
973
+ 0.486109385710056
974
+
975
+ If you were to plug the above omega into the BSD conjecture,
976
+ you would get an incorrect value, out by a factor of 2. The
977
+ following works though::
978
+
979
+ sage: F = E.minimal_model()
980
+ sage: F.period_lattice().omega()
981
+ 0.972218771420113
982
+
983
+ ::
984
+
985
+ sage: # needs sage.rings.number_field
986
+ sage: x = polygen(ZZ, 'x')
987
+ sage: K.<a> = NumberField(x^3 - 2)
988
+ sage: emb = K.embeddings(RealField())[0]
989
+ sage: E = EllipticCurve([0,1,0,a,a])
990
+ sage: L = E.period_lattice(emb)
991
+ sage: L.omega(64)
992
+ 3.81452977217854509
993
+
994
+ A complex example (taken from J.E.Cremona and E.Whitley,
995
+ *Periods of cusp forms and elliptic curves over imaginary
996
+ quadratic fields*, Mathematics of Computation 62 No. 205
997
+ (1994), 407-429). See :issue:`29645` and :issue:`29782`::
998
+
999
+ sage: # needs sage.rings.number_field
1000
+ sage: K.<i> = QuadraticField(-1)
1001
+ sage: E = EllipticCurve([0,1-i,i,-i,0])
1002
+ sage: L = E.period_lattice(K.embeddings(CC)[0])
1003
+ sage: L.omega()
1004
+ 8.80694160502647
1005
+ sage: L.omega(prec=200)
1006
+ 8.8069416050264741493250743632295462227858630765392114070032
1007
+ sage: L.omega(bsd_normalise=True)
1008
+ 17.6138832100529
1009
+ """
1010
+ if self.is_real():
1011
+ n_components = 2 if self.real_flag == 1 else 1
1012
+ return self.real_period(prec) * n_components
1013
+ else:
1014
+ bsd_factor = 2 if bsd_normalise else 1
1015
+ return self.complex_area(prec) * bsd_factor
1016
+
1017
+ @cached_method
1018
+ def basis_matrix(self, prec=None, normalised=False):
1019
+ r"""
1020
+ Return the basis matrix of this period lattice.
1021
+
1022
+ INPUT:
1023
+
1024
+ - ``prec`` -- integer or ``None`` (default); real precision in
1025
+ bits (default real precision if ``None``)
1026
+
1027
+ - ``normalised`` -- boolean (default: ``False``); if ``True`` and the
1028
+ embedding is real, use the normalised basis (see
1029
+ :meth:`normalised_basis`) instead of the default
1030
+
1031
+ OUTPUT:
1032
+
1033
+ A `2\times 2` real matrix whose rows are the lattice basis vectors,
1034
+ after identifying `\CC` with `\RR^2`.
1035
+
1036
+ EXAMPLES::
1037
+
1038
+ sage: # needs database_cremona_mini_ellcurve
1039
+ sage: E = EllipticCurve('37a')
1040
+ sage: E.period_lattice().basis_matrix()
1041
+ [ 2.99345864623196 0.000000000000000]
1042
+ [0.000000000000000 2.45138938198679]
1043
+
1044
+ ::
1045
+
1046
+ sage: # needs sage.rings.number_field
1047
+ sage: x = polygen(ZZ, 'x')
1048
+ sage: K.<a> = NumberField(x^3 - 2)
1049
+ sage: emb = K.embeddings(RealField())[0]
1050
+ sage: E = EllipticCurve([0,1,0,a,a])
1051
+ sage: L = E.period_lattice(emb)
1052
+ sage: L.basis_matrix(64)
1053
+ [ 3.81452977217854509 0.000000000000000000]
1054
+ [ 1.90726488608927255 1.34047785962440202]
1055
+
1056
+ See :issue:`4388`::
1057
+
1058
+ sage: # needs database_cremona_mini_ellcurve
1059
+ sage: L = EllipticCurve('11a1').period_lattice()
1060
+ sage: L.basis_matrix()
1061
+ [ 1.26920930427955 0.000000000000000]
1062
+ [0.634604652139777 1.45881661693850]
1063
+ sage: L.basis_matrix(normalised=True)
1064
+ [0.634604652139777 -1.45881661693850]
1065
+ [-1.26920930427955 0.000000000000000]
1066
+
1067
+ ::
1068
+
1069
+ sage: # needs database_cremona_mini_ellcurve
1070
+ sage: L = EllipticCurve('389a1').period_lattice()
1071
+ sage: L.basis_matrix()
1072
+ [ 2.49021256085505 0.000000000000000]
1073
+ [0.000000000000000 1.97173770155165]
1074
+ sage: L.basis_matrix(normalised=True)
1075
+ [ 2.49021256085505 0.000000000000000]
1076
+ [0.000000000000000 -1.97173770155165]
1077
+ """
1078
+ from sage.matrix.constructor import Matrix
1079
+
1080
+ if normalised:
1081
+ return Matrix([list(w) for w in self.normalised_basis(prec)])
1082
+
1083
+ w1,w2 = self.basis(prec)
1084
+ if self.is_real():
1085
+ return Matrix([[w1,0],list(w2)])
1086
+ else:
1087
+ return Matrix([list(w) for w in (w1,w2)])
1088
+
1089
+ def complex_area(self, prec=None):
1090
+ """
1091
+ Return the area of a fundamental domain for the period lattice
1092
+ of the elliptic curve.
1093
+
1094
+ INPUT:
1095
+
1096
+ - ``prec`` -- integer or ``None`` (default); real precision in
1097
+ bits (default real precision if ``None``)
1098
+
1099
+ EXAMPLES::
1100
+
1101
+ sage: # needs database_cremona_mini_ellcurve
1102
+ sage: E = EllipticCurve('37a')
1103
+ sage: E.period_lattice().complex_area()
1104
+ 7.33813274078958
1105
+
1106
+ ::
1107
+
1108
+ sage: # needs sage.rings.number_field
1109
+ sage: x = polygen(ZZ, 'x')
1110
+ sage: K.<a> = NumberField(x^3 - 2)
1111
+ sage: embs = K.embeddings(ComplexField())
1112
+ sage: E = EllipticCurve([0,1,0,a,a])
1113
+ sage: [E.period_lattice(emb).is_real() for emb in K.embeddings(CC)]
1114
+ [False, False, True]
1115
+ sage: [E.period_lattice(emb).complex_area() for emb in embs]
1116
+ [6.02796894766694, 6.02796894766694, 5.11329270448345]
1117
+ """
1118
+ w1,w2 = self.basis(prec)
1119
+ return (w1*w2.conjugate()).imag().abs()
1120
+
1121
+ def sigma(self, z, prec=None, flag=0):
1122
+ r"""
1123
+ Return the value of the Weierstrass sigma function for this elliptic curve period lattice.
1124
+
1125
+ INPUT:
1126
+
1127
+ - ``z`` -- a complex number
1128
+
1129
+ - ``prec`` -- (default: ``None``) real precision in bits
1130
+ (default real precision if ``None``)
1131
+
1132
+ - ``flag`` --
1133
+
1134
+ 0: (default) ???;
1135
+
1136
+ 1: computes an arbitrary determination of log(sigma(z))
1137
+
1138
+ 2, 3: same using the product expansion instead of theta series. ???
1139
+
1140
+ .. NOTE::
1141
+
1142
+ The reason for the ???'s above, is that the PARI
1143
+ documentation for ellsigma is very vague. Also this is
1144
+ only implemented for curves defined over `\QQ`.
1145
+
1146
+ .. TODO::
1147
+
1148
+ This function does not use any of the PeriodLattice functions
1149
+ and so should be moved to ell_rational_field.
1150
+
1151
+ EXAMPLES::
1152
+
1153
+ sage: # needs database_cremona_mini_ellcurve
1154
+ sage: EllipticCurve('389a1').period_lattice().sigma(CC(2,1))
1155
+ 2.60912163570108 - 0.200865080824587*I
1156
+ """
1157
+ if prec is None:
1158
+ prec = self._compute_default_prec()
1159
+ try:
1160
+ return self.E.pari_curve().ellsigma(z, flag, precision=prec)
1161
+ except AttributeError:
1162
+ raise NotImplementedError("sigma function not yet implemented for period lattices of curves not defined over Q")
1163
+
1164
+ def curve(self):
1165
+ r"""
1166
+ Return the elliptic curve associated with this period lattice.
1167
+
1168
+ EXAMPLES::
1169
+
1170
+ sage: # needs database_cremona_mini_ellcurve
1171
+ sage: E = EllipticCurve('37a')
1172
+ sage: L = E.period_lattice()
1173
+ sage: L.curve() is E
1174
+ True
1175
+
1176
+ ::
1177
+
1178
+ sage: # needs sage.rings.number_field
1179
+ sage: x = polygen(ZZ, 'x')
1180
+ sage: K.<a> = NumberField(x^3 - 2)
1181
+ sage: E = EllipticCurve([0,1,0,a,a])
1182
+ sage: L = E.period_lattice(K.embeddings(RealField())[0])
1183
+ sage: L.curve() is E
1184
+ True
1185
+
1186
+ sage: L = E.period_lattice(K.embeddings(ComplexField())[0]) # needs sage.rings.number_field
1187
+ sage: L.curve() is E # needs sage.rings.number_field
1188
+ True
1189
+ """
1190
+ return self.E
1191
+
1192
+ @property
1193
+ def is_approximate(self):
1194
+ """
1195
+ ``self.is_approximate`` is deprecated, use ``not self.curve().is_exact()`` instead.
1196
+
1197
+ TESTS::
1198
+
1199
+ sage: E = EllipticCurve(ComplexField(100), [I, 3*I+4])
1200
+ sage: L = E.period_lattice()
1201
+ sage: L.is_approximate
1202
+ doctest:...: DeprecationWarning: The attribute is_approximate for period lattice is deprecated,
1203
+ use self.curve().is_exact() instead.
1204
+ See https://github.com/sagemath/sage/issues/39212 for details.
1205
+ True
1206
+ sage: L.curve() is E
1207
+ True
1208
+ sage: E.is_exact()
1209
+ False
1210
+ sage: E = EllipticCurve(QQ, [0, 2])
1211
+ sage: L = E.period_lattice()
1212
+ sage: L.is_approximate
1213
+ False
1214
+ sage: L.curve() is E
1215
+ True
1216
+ sage: E.is_exact()
1217
+ True
1218
+ """
1219
+ from sage.misc.superseded import deprecation
1220
+ deprecation(39212, "The attribute is_approximate for period lattice is "
1221
+ "deprecated, use self.curve().is_exact() instead.")
1222
+ return not self._is_exact
1223
+
1224
+ def ei(self):
1225
+ r"""
1226
+ Return the x-coordinates of the 2-division points of the elliptic curve associated
1227
+ with this period lattice, as elements of ``QQbar``.
1228
+
1229
+ EXAMPLES::
1230
+
1231
+ sage: # needs database_cremona_mini_ellcurve
1232
+ sage: E = EllipticCurve('37a')
1233
+ sage: L = E.period_lattice()
1234
+ sage: L.ei()
1235
+ [-1.107159871688768?, 0.2695944364054446?, 0.8375654352833230?]
1236
+
1237
+ In the following example, we should have one purely real 2-division point coordinate,
1238
+ and two conjugate purely imaginary coordinates.
1239
+
1240
+ ::
1241
+
1242
+ sage: # needs sage.rings.number_field
1243
+ sage: x = polygen(ZZ, 'x')
1244
+ sage: K.<a> = NumberField(x^3 - 2)
1245
+ sage: E = EllipticCurve([0,1,0,a,a])
1246
+ sage: L = E.period_lattice(K.embeddings(RealField())[0])
1247
+ sage: x1,x2,x3 = L.ei()
1248
+ sage: abs(x1.real()) + abs(x2.real()) < 1e-14
1249
+ True
1250
+ sage: x1.imag(), x2.imag(), x3
1251
+ (-1.122462048309373?, 1.122462048309373?, -1.000000000000000?)
1252
+
1253
+ ::
1254
+
1255
+ sage: L = E.period_lattice(K.embeddings(ComplexField())[0]) # needs sage.rings.number_field
1256
+ sage: L.ei() # needs sage.rings.number_field
1257
+ [-1.000000000000000? + 0.?e-1...*I,
1258
+ -0.9720806486198328? - 0.561231024154687?*I,
1259
+ 0.9720806486198328? + 0.561231024154687?*I]
1260
+ """
1261
+ return self._ei
1262
+
1263
+ def coordinates(self, z, rounding=None):
1264
+ r"""
1265
+ Return the coordinates of a complex number w.r.t. the lattice basis.
1266
+
1267
+ INPUT:
1268
+
1269
+ - ``z`` -- complex number
1270
+
1271
+ - ``rounding`` -- (default: ``None``) whether and how to round the
1272
+ output (see below)
1273
+
1274
+ OUTPUT:
1275
+
1276
+ When ``rounding`` is ``None`` (the default), returns a tuple
1277
+ of reals `x`, `y` such that `z=xw_1+yw_2` where `w_1`, `w_2`
1278
+ are a basis for the lattice (normalised in the case of complex
1279
+ embeddings).
1280
+
1281
+ When ``rounding`` is ``'round'``, returns a tuple of integers `n_1`,
1282
+ `n_2` which are the closest integers to the `x`, `y` defined
1283
+ above. If `z` is in the lattice these are the coordinates of
1284
+ `z` with respect to the lattice basis.
1285
+
1286
+ When ``rounding`` is ``'floor'``, returns a tuple of integers
1287
+ `n_1`, `n_2` which are the integer parts to the `x`, `y`
1288
+ defined above. These are used in :meth:`.reduce`
1289
+
1290
+ EXAMPLES::
1291
+
1292
+ sage: # needs database_cremona_mini_ellcurve
1293
+ sage: E = EllipticCurve('389a')
1294
+ sage: L = E.period_lattice()
1295
+ sage: w1, w2 = L.basis(prec=100)
1296
+ sage: P = E([-1,1])
1297
+ sage: zP = P.elliptic_logarithm(precision=100); zP # abs tol 1e-28
1298
+ 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I
1299
+ sage: L.coordinates(zP) # abs tol 1e-28
1300
+ (0.19249290511394227352563996419, 0.50000000000000000000000000000)
1301
+ sage: sum([x*w for x, w in zip(L.coordinates(zP), L.basis(prec=100))]) # abs tol 1e-28
1302
+ 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I
1303
+ sage: L.coordinates(12*w1 + 23*w2) # abs tol 1e-28
1304
+ (12.000000000000000000000000000, 23.000000000000000000000000000)
1305
+ sage: L.coordinates(12*w1 + 23*w2, rounding='floor')
1306
+ (11, 22)
1307
+ sage: L.coordinates(12*w1 + 23*w2, rounding='round')
1308
+ (12, 23)
1309
+ """
1310
+ C = z.parent()
1311
+ if isinstance(C, sage.rings.abc.RealField):
1312
+ C = ComplexField(C.precision())
1313
+ z = C(z)
1314
+ else:
1315
+ if isinstance(C, sage.rings.abc.ComplexField):
1316
+ pass
1317
+ else:
1318
+ try:
1319
+ C = ComplexField()
1320
+ z = C(z)
1321
+ except TypeError:
1322
+ raise TypeError("%s is not a complex number" % z)
1323
+ prec = C.precision()
1324
+ from sage.matrix.constructor import Matrix
1325
+ from sage.modules.free_module_element import vector
1326
+ if self.real_flag:
1327
+ w1, w2 = self.basis(prec)
1328
+ M = Matrix([[w1, 0], list(w2)])**(-1)
1329
+ else:
1330
+ w1, w2 = self.normalised_basis(prec)
1331
+ M = Matrix([list(w1), list(w2)])**(-1)
1332
+ u, v = vector(z) * M
1333
+ # Now z = u*w1+v*w2
1334
+ if rounding == 'round':
1335
+ return u.round(), v.round()
1336
+ if rounding == 'floor':
1337
+ return u.floor(), v.floor()
1338
+ return u, v
1339
+
1340
+ def reduce(self, z):
1341
+ r"""
1342
+ Reduce a complex number modulo the lattice.
1343
+
1344
+ INPUT:
1345
+
1346
+ - ``z`` -- complex number
1347
+
1348
+ OUTPUT:
1349
+
1350
+ (complex) the reduction of `z` modulo the lattice, lying in
1351
+ the fundamental period parallelogram with respect to the
1352
+ lattice basis. For curves defined over the reals (i.e. real
1353
+ embeddings) the output will be real when possible.
1354
+
1355
+ EXAMPLES::
1356
+
1357
+ sage: # needs database_cremona_mini_ellcurve
1358
+ sage: E = EllipticCurve('389a')
1359
+ sage: L = E.period_lattice()
1360
+ sage: w1, w2 = L.basis(prec=100)
1361
+ sage: P = E([-1,1])
1362
+ sage: zP = P.elliptic_logarithm(precision=100); zP # abs tol 1e-28
1363
+ 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I
1364
+ sage: z = zP + 10*w1 - 20*w2; z # abs tol 1e-28
1365
+ 25.381473858740770069343110929 - 38.448885180257139986236950114*I
1366
+ sage: L.reduce(z) # abs tol 1e-28
1367
+ 0.47934825019021931612953301006 + 0.98586885077582410221120384908*I
1368
+ sage: L.elliptic_logarithm(2*P) # abs tol 1e-15
1369
+ 0.958696500380439
1370
+ sage: L.reduce(L.elliptic_logarithm(2*P)) # abs tol 1e-15
1371
+ 0.958696500380439
1372
+ sage: L.reduce(L.elliptic_logarithm(2*P) + 10*w1 - 20*w2) # abs tol 1e-15
1373
+ 0.958696500380444
1374
+ """
1375
+ C = z.parent()
1376
+ if isinstance(C, sage.rings.abc.RealField):
1377
+ C = ComplexField(C.precision())
1378
+ z = C(z)
1379
+ elif isinstance(C, sage.rings.abc.ComplexField):
1380
+ pass
1381
+ else:
1382
+ try:
1383
+ C = ComplexField()
1384
+ z = C(z)
1385
+ except TypeError:
1386
+ raise TypeError("%s is not a complex number" % z)
1387
+ prec = C.precision()
1388
+ if self.real_flag:
1389
+ w1, w2 = self.basis(prec) # w1 real
1390
+ else:
1391
+ w1, w2 = self.normalised_basis(prec)
1392
+ u, v = self.coordinates(z, rounding='floor')
1393
+ z = z-u*w1-v*w2
1394
+
1395
+ # Final adjustments for the real case.
1396
+
1397
+ # NB We assume here that when the embedding is real then the
1398
+ # point is also real!
1399
+
1400
+ if self.real_flag == 0:
1401
+ return z
1402
+ if self.real_flag == -1:
1403
+ k = (z.imag() / w2.imag()).round()
1404
+ z = z-k*w2
1405
+ return C(z.real(), 0)
1406
+
1407
+ if ((2*z.imag()/w2.imag()).round()) % 2:
1408
+ return C(z.real(), w2.imag() / 2)
1409
+ else:
1410
+ return C(z.real(), 0)
1411
+
1412
+ def e_log_RC(self, xP, yP, prec=None, reduce=True):
1413
+ r"""
1414
+ Return the elliptic logarithm of a real or complex point.
1415
+
1416
+ INPUT:
1417
+
1418
+ - ``xP``, ``yP`` (real or complex) -- Coordinates of a point on
1419
+ the embedded elliptic curve associated with this period
1420
+ lattice.
1421
+
1422
+ - ``prec`` -- (default: ``None``) real precision in bits
1423
+ (default real precision if ``None``)
1424
+
1425
+ - ``reduce`` -- boolean (default: ``True``); if ``True``, the result
1426
+ is reduced with respect to the period lattice basis
1427
+
1428
+ OUTPUT:
1429
+
1430
+ (complex number) The elliptic logarithm of the point `(xP,yP)`
1431
+ with respect to this period lattice. If `E` is the elliptic
1432
+ curve and `\sigma:K\to\CC` the embedding, the returned
1433
+ value `z` is such that `z\pmod{L}` maps to `(xP,yP)=\sigma(P)`
1434
+ under the standard Weierstrass isomorphism from `\CC/L` to
1435
+ `\sigma(E)`. If ``reduce`` is ``True``, the output is reduced
1436
+ so that it is in the fundamental period parallelogram with
1437
+ respect to the normalised lattice basis.
1438
+
1439
+ ALGORITHM:
1440
+
1441
+ Uses the complex AGM. See [CT2013]_ for details.
1442
+
1443
+ EXAMPLES::
1444
+
1445
+ sage: # needs database_cremona_mini_ellcurve
1446
+ sage: E = EllipticCurve('389a')
1447
+ sage: L = E.period_lattice()
1448
+ sage: P = E([-1,1])
1449
+ sage: xP, yP = [RR(c) for c in P.xy()]
1450
+
1451
+ The elliptic log from the real coordinates::
1452
+
1453
+ sage: L.e_log_RC(xP, yP) # abs tol 1e-15 # needs database_cremona_mini_ellcurve
1454
+ 0.479348250190219 + 0.985868850775824*I
1455
+
1456
+ The same elliptic log from the algebraic point::
1457
+
1458
+ sage: L(P) # abs tol 1e-15 # needs database_cremona_mini_ellcurve
1459
+ 0.479348250190219 + 0.985868850775824*I
1460
+
1461
+ A number field example::
1462
+
1463
+ sage: # needs sage.rings.number_field
1464
+ sage: x = polygen(ZZ, 'x')
1465
+ sage: K.<a> = NumberField(x^3 - 2)
1466
+ sage: E = EllipticCurve([0,0,0,0,a])
1467
+ sage: v = K.real_places()[0]
1468
+ sage: L = E.period_lattice(v)
1469
+ sage: P = E.lift_x(1/3*a^2 + a + 5/3)
1470
+ sage: L(P) # abs tol 1e-15
1471
+ 3.51086196882538
1472
+ sage: xP, yP = [v(c) for c in P.xy()]
1473
+ sage: L.e_log_RC(xP, yP) # abs tol 1e-15
1474
+ 3.51086196882538
1475
+
1476
+ Elliptic logs of real points which do not come from algebraic
1477
+ points::
1478
+
1479
+ sage: # needs sage.rings.number_field
1480
+ sage: ER = EllipticCurve([v(ai) for ai in E.a_invariants()])
1481
+ sage: P = ER.lift_x(12.34)
1482
+ sage: xP, yP = P.xy()
1483
+ sage: xP, yP # abs tol 1e-15
1484
+ (12.3400000000000, -43.3628968710567)
1485
+ sage: L.e_log_RC(xP, yP) # abs tol 1e-15
1486
+ 0.284656841192041
1487
+ sage: xP, yP = ER.lift_x(0).xy() # abs tol 1e-15
1488
+ sage: L.e_log_RC(xP, yP)
1489
+ 1.34921304541057
1490
+
1491
+ Elliptic logs of complex points::
1492
+
1493
+ sage: # needs sage.rings.number_field
1494
+ sage: v = K.complex_embeddings()[0]
1495
+ sage: L = E.period_lattice(v)
1496
+ sage: P = E.lift_x(1/3*a^2 + a + 5/3)
1497
+ sage: L(P) # abs tol 1e-15
1498
+ 1.68207104397706 - 1.87873661686704*I
1499
+ sage: xP, yP = [v(c) for c in P.xy()]
1500
+ sage: L.e_log_RC(xP, yP) # abs tol 1e-15
1501
+ 1.68207104397706 - 1.87873661686704*I
1502
+ sage: EC = EllipticCurve([v(ai) for ai in E.a_invariants()])
1503
+ sage: xP, yP = EC.lift_x(0).xy()
1504
+ sage: L.e_log_RC(xP, yP) # abs tol 1e-15
1505
+ 2.06711431204080 - 1.73451485683471*I
1506
+ """
1507
+ if prec is None:
1508
+ prec = self._compute_default_prec()
1509
+ # Note: using log2(prec) + 3 guard bits is usually enough.
1510
+ # To avoid computing a logarithm, we use 40 guard bits which
1511
+ # should be largely enough in practice.
1512
+ prec2 = prec + 40
1513
+
1514
+ R = RealField(prec2)
1515
+ C = ComplexField(prec2)
1516
+ e1,e2,e3 = self._ei
1517
+ a1,a2,a3 = (self.embedding(a) for a in self.E.ainvs()[:3])
1518
+
1519
+ wP = 2*yP+a1*xP+a3
1520
+
1521
+ # We treat the case of 2-torsion points separately. (Note
1522
+ # that Cohen's algorithm does not handle these properly.)
1523
+
1524
+ if wP.is_zero(): # 2-torsion treated separately
1525
+ w1,w2 = self._compute_periods_complex(prec,normalise=False)
1526
+ if xP == e1:
1527
+ z = w2/2
1528
+ else:
1529
+ if xP == e3:
1530
+ z = w1/2
1531
+ else:
1532
+ z = (w1+w2)/2
1533
+ if reduce:
1534
+ z = self.reduce(z)
1535
+ return z
1536
+
1537
+ # NB The first block of code works fine for real embeddings as
1538
+ # well as complex embeddings. The special code for real
1539
+ # embeddings uses only real arithmetic in the iteration, and is
1540
+ # based on Cremona and Thongjunthug.
1541
+
1542
+ # An older version, based on Cohen's Algorithm 7.4.8 also uses
1543
+ # only real arithmetic, and gives different normalisations,
1544
+ # but also causes problems (see #10026). It is left in but
1545
+ # commented out below.
1546
+
1547
+ if self.real_flag == 0: # complex case
1548
+
1549
+ a = C((e1-e3).sqrt())
1550
+ b = C((e1-e2).sqrt())
1551
+ if (a+b).abs() < (a-b).abs():
1552
+ b = -b
1553
+ r = C(((xP-e3)/(xP-e2)).sqrt())
1554
+ if r.real() < 0:
1555
+ r = -r
1556
+ t = -C(wP)/(2*r*(xP-e2))
1557
+ # eps controls the end of the loop. Since we aim at a target
1558
+ # precision of prec bits, eps = 2^(-prec) is enough.
1559
+ eps = R(1) >> prec
1560
+ while True:
1561
+ s = b*r+a
1562
+ a, b = (a+b)/2, (a*b).sqrt()
1563
+ if (a+b).abs() < (a-b).abs():
1564
+ b = -b
1565
+ r = (a*(r+1)/s).sqrt()
1566
+ if (r.abs()-1).abs() < eps:
1567
+ break
1568
+ if r.real() < 0:
1569
+ r = -r
1570
+ t *= r
1571
+ z = ((a/t).arctan())/a
1572
+ z = ComplexField(prec)(z)
1573
+ if reduce:
1574
+ z = self.reduce(z)
1575
+ return z
1576
+
1577
+ if self.real_flag == -1: # real, connected case
1578
+ z = C(self._abc[0]) # sqrt(e3-e1)
1579
+ a, y, b = z.real(), z.imag(), z.abs()
1580
+ uv = (xP-e1).sqrt()
1581
+ u, v = uv.real().abs(), uv.imag().abs()
1582
+ r = (u*a/(u*a+v*y)).sqrt()
1583
+ t = -r*R(wP)/(2*(u**2+v**2))
1584
+ on_egg = False
1585
+ else: # real, disconnected case
1586
+ a = R(e3-e1).sqrt()
1587
+ b = R(e3-e2).sqrt()
1588
+ if (a+b).abs() < (a-b).abs():
1589
+ b = -b
1590
+ on_egg = (xP < e3)
1591
+ if on_egg:
1592
+ r = a/R(e3-xP).sqrt()
1593
+ t = r*R(wP)/(2*R(xP-e1))
1594
+ else:
1595
+ r = R((xP-e1)/(xP-e2)).sqrt()
1596
+ t = -R(wP)/(2*r*R(xP-e2))
1597
+
1598
+ # eps controls the end of the loop. Since we aim at a target
1599
+ # precision of prec bits, eps = 2^(-prec) is enough.
1600
+ eps = R(1) >> prec
1601
+ while True:
1602
+ s = b*r+a
1603
+ a, b = (a+b)/2, (a*b).sqrt()
1604
+ r = (a*(r+1)/s).sqrt()
1605
+ if (r-1).abs() < eps:
1606
+ break
1607
+ t *= r
1608
+ z = ((a / t).arctan()) / a
1609
+ if on_egg:
1610
+ w1, w2 = self._compute_periods_real(prec)
1611
+ z += w2 / 2
1612
+ z = ComplexField(prec)(z)
1613
+ if reduce:
1614
+ z = self.reduce(z)
1615
+ return z
1616
+
1617
+ def elliptic_logarithm(self, P, prec=None, reduce=True):
1618
+ r"""
1619
+ Return the elliptic logarithm of a point.
1620
+
1621
+ INPUT:
1622
+
1623
+ - ``P`` -- point on the elliptic curve associated with this period
1624
+ lattice
1625
+
1626
+ - ``prec`` -- (default: ``None``) real precision in bits
1627
+ (default real precision if ``None``)
1628
+
1629
+ - ``reduce`` -- boolean (default: ``True``); if ``True``, the result
1630
+ is reduced with respect to the period lattice basis
1631
+
1632
+ OUTPUT:
1633
+
1634
+ (complex number) The elliptic logarithm of the point `P` with
1635
+ respect to this period lattice. If `E` is the elliptic curve
1636
+ and `\sigma:K\to\CC` the embedding, the returned value `z`
1637
+ is such that `z\pmod{L}` maps to `\sigma(P)` under the
1638
+ standard Weierstrass isomorphism from `\CC/L` to `\sigma(E)`.
1639
+ If ``reduce`` is ``True``, the output is reduced so that it is
1640
+ in the fundamental period parallelogram with respect to the
1641
+ normalised lattice basis.
1642
+
1643
+ ALGORITHM:
1644
+
1645
+ Uses the complex AGM. See [CT2013]_ for details.
1646
+
1647
+ EXAMPLES::
1648
+
1649
+ sage: # needs database_cremona_mini_ellcurve
1650
+ sage: E = EllipticCurve('389a')
1651
+ sage: L = E.period_lattice()
1652
+ sage: E.discriminant() > 0
1653
+ True
1654
+ sage: L.real_flag
1655
+ 1
1656
+ sage: P = E([-1,1])
1657
+ sage: P.is_on_identity_component ()
1658
+ False
1659
+ sage: L.elliptic_logarithm(P, prec=96)
1660
+ 0.4793482501902193161295330101 + 0.9858688507758241022112038491*I
1661
+ sage: Q=E([3,5])
1662
+ sage: Q.is_on_identity_component()
1663
+ True
1664
+ sage: L.elliptic_logarithm(Q, prec=96)
1665
+ 1.931128271542559442488585220
1666
+
1667
+ Note that this is actually the inverse of the Weierstrass isomorphism::
1668
+
1669
+ sage: L.elliptic_exponential(_) # abs tol 1e-26 # needs database_cremona_mini_ellcurve
1670
+ (3.000000000000000000000000000 : 5.000000000000000000000000000 : 1.000000000000000000000000000)
1671
+
1672
+ An example with negative discriminant, and a torsion point::
1673
+
1674
+ sage: # needs database_cremona_mini_ellcurve
1675
+ sage: E = EllipticCurve('11a1')
1676
+ sage: L = E.period_lattice()
1677
+ sage: E.discriminant() < 0
1678
+ True
1679
+ sage: L.real_flag
1680
+ -1
1681
+ sage: P = E([16,-61])
1682
+ sage: L.elliptic_logarithm(P)
1683
+ 0.253841860855911
1684
+ sage: L.real_period() / L.elliptic_logarithm(P)
1685
+ 5.00000000000000
1686
+
1687
+ An example where precision is problematic::
1688
+
1689
+ sage: E = EllipticCurve([1, 0, 1, -85357462, 303528987048]) #18074g1
1690
+ sage: P = E([4458713781401/835903744, -64466909836503771/24167649046528, 1])
1691
+ sage: L = E.period_lattice()
1692
+ sage: L.ei()
1693
+ [5334.003952567705? - 1.964393150436?e-6*I,
1694
+ 5334.003952567705? + 1.964393150436?e-6*I,
1695
+ -10668.25790513541?]
1696
+ sage: L.elliptic_logarithm(P,prec=100)
1697
+ 0.27656204014107061464076203097
1698
+
1699
+ Some complex examples, taken from the paper by Cremona and Thongjunthug::
1700
+
1701
+ sage: # needs sage.rings.number_field
1702
+ sage: K.<i> = QuadraticField(-1)
1703
+ sage: a4 = 9*i - 10
1704
+ sage: a6 = 21 - i
1705
+ sage: E = EllipticCurve([0,0,0,a4,a6])
1706
+ sage: e1 = 3 - 2*i; e2 = 1 + i; e3 = -4 + i
1707
+ sage: emb = K.embeddings(CC)[1]
1708
+ sage: L = E.period_lattice(emb)
1709
+ sage: P = E(2 - i, 4 + 2*i)
1710
+
1711
+ By default, the output is reduced with respect to the
1712
+ normalised lattice basis, so that its coordinates with respect
1713
+ to that basis lie in the interval [0,1)::
1714
+
1715
+ sage: z = L.elliptic_logarithm(P, prec=100); z # needs sage.rings.number_field
1716
+ 0.70448375537782208460499649302 - 0.79246725643650979858266018068*I
1717
+ sage: L.coordinates(z) # needs sage.rings.number_field
1718
+ (0.46247636364807931766105406092, 0.79497588726808704200760395829)
1719
+
1720
+ Using ``reduce=False`` this step can be omitted. In this case
1721
+ the coordinates are usually in the interval [-0.5,0.5), but
1722
+ this is not guaranteed. This option is mainly for testing
1723
+ purposes::
1724
+
1725
+ sage: z = L.elliptic_logarithm(P, prec=100, reduce=False); z # needs sage.rings.number_field
1726
+ 0.57002153834710752778063503023 + 0.46476340520469798857457031393*I
1727
+ sage: L.coordinates(z) # needs sage.rings.number_field
1728
+ (0.46247636364807931766105406092, -0.20502411273191295799239604171)
1729
+
1730
+ The elliptic logs of the 2-torsion points are half-periods::
1731
+
1732
+ sage: L.elliptic_logarithm(E(e1, 0), prec=100) # needs sage.rings.number_field
1733
+ 0.64607575874356525952487867052 + 0.22379609053909448304176885364*I
1734
+ sage: L.elliptic_logarithm(E(e2, 0), prec=100) # needs sage.rings.number_field
1735
+ 0.71330686725892253793705940192 - 0.40481924028150941053684639367*I
1736
+ sage: L.elliptic_logarithm(E(e3, 0), prec=100) # needs sage.rings.number_field
1737
+ 0.067231108515357278412180731396 - 0.62861533082060389357861524731*I
1738
+
1739
+ We check this by doubling and seeing that the resulting
1740
+ coordinates are integers::
1741
+
1742
+ sage: L.coordinates(2*L.elliptic_logarithm(E(e1, 0), prec=100)) # needs sage.rings.number_field
1743
+ (1.0000000000000000000000000000, 0.00000000000000000000000000000)
1744
+ sage: L.coordinates(2*L.elliptic_logarithm(E(e2, 0), prec=100)) # needs sage.rings.number_field
1745
+ (1.0000000000000000000000000000, 1.0000000000000000000000000000)
1746
+ sage: L.coordinates(2*L.elliptic_logarithm(E(e3, 0), prec=100)) # needs sage.rings.number_field
1747
+ (0.00000000000000000000000000000, 1.0000000000000000000000000000)
1748
+
1749
+ ::
1750
+
1751
+ sage: # needs sage.rings.number_field
1752
+ sage: a4 = -78*i + 104
1753
+ sage: a6 = -216*i - 312
1754
+ sage: E = EllipticCurve([0,0,0,a4,a6])
1755
+ sage: emb = K.embeddings(CC)[1]
1756
+ sage: L = E.period_lattice(emb)
1757
+ sage: P = E(3 + 2*i, 14 - 7*i)
1758
+ sage: L.elliptic_logarithm(P)
1759
+ 0.297147783912228 - 0.546125549639461*I
1760
+ sage: L.coordinates(L.elliptic_logarithm(P))
1761
+ (0.628653378040238, 0.371417754610223)
1762
+ sage: e1 = 1 + 3*i; e2 = -4 - 12*i; e3 = -e1 - e2
1763
+ sage: L.coordinates(L.elliptic_logarithm(E(e1, 0)))
1764
+ (0.500000000000000, 0.500000000000000)
1765
+ sage: L.coordinates(L.elliptic_logarithm(E(e2, 0)))
1766
+ (1.00000000000000, 0.500000000000000)
1767
+ sage: L.coordinates(L.elliptic_logarithm(E(e3, 0)))
1768
+ (0.500000000000000, 0.000000000000000)
1769
+
1770
+ TESTS:
1771
+
1772
+ See :issue:`10026` and :issue:`11767`::
1773
+
1774
+ sage: # needs sage.rings.number_field
1775
+ sage: K.<w> = QuadraticField(2)
1776
+ sage: E = EllipticCurve([0, -1, 1, -3*w - 4, 3*w + 4])
1777
+ sage: T = E.simon_two_descent(lim1=20, lim3=5, limtriv=20)
1778
+ sage: P, Q = T[2]
1779
+ sage: embs = K.embeddings(CC)
1780
+ sage: Lambda = E.period_lattice(embs[0])
1781
+ sage: Lambda.elliptic_logarithm(P, 100)
1782
+ 4.7100131126199672766973600998
1783
+ sage: R.<x> = QQ[]
1784
+ sage: K.<a> = NumberField(x^2 + x + 5)
1785
+ sage: E = EllipticCurve(K, [0,0,1,-3,-5])
1786
+ sage: P = E([0,a])
1787
+ sage: Lambda = P.curve().period_lattice(K.embeddings(ComplexField(600))[0])
1788
+ sage: Lambda.elliptic_logarithm(P, prec=600)
1789
+ -0.842248166487739393375018008381693990800588864069506187033873183845246233548058477561706400464057832396643843146464236956684557207157300006542470428493573195030603817094900751609464 - 0.571366031453267388121279381354098224265947866751130917440598461117775339240176310729173301979590106474259885638797913383502735083088736326391919063211421189027226502851390118943491*I
1790
+ sage: K.<a> = QuadraticField(-5)
1791
+ sage: E = EllipticCurve([1,1,a,a,0])
1792
+ sage: P = E(0, 0)
1793
+ sage: L = P.curve().period_lattice(K.embeddings(ComplexField())[0])
1794
+ sage: L.elliptic_logarithm(P, prec=500)
1795
+ 1.17058357737548897849026170185581196033579563441850967539191867385734983296504066660506637438866628981886518901958717288150400849746892393771983141354 - 1.13513899565966043682474529757126359416758251309237866586896869548539516543734207347695898664875799307727928332953834601460994992792519799260968053875*I
1796
+ sage: L.elliptic_logarithm(P, prec=1000)
1797
+ 1.17058357737548897849026170185581196033579563441850967539191867385734983296504066660506637438866628981886518901958717288150400849746892393771983141354014895386251320571643977497740116710952913769943240797618468987304985625823413440999754037939123032233879499904283600304184828809773650066658885672885 - 1.13513899565966043682474529757126359416758251309237866586896869548539516543734207347695898664875799307727928332953834601460994992792519799260968053875387282656993476491590607092182964878750169490985439873220720963653658829712494879003124071110818175013453207439440032582917366703476398880865439217473*I
1798
+
1799
+ Elliptic curve over ``QQbar``::
1800
+
1801
+ sage: # needs sage.rings.number_field sage.symbolic
1802
+ sage: E = EllipticCurve(QQbar, [sqrt(2), I])
1803
+ sage: L = E.period_lattice()
1804
+ sage: P = E.lift_x(3)
1805
+ sage: L.elliptic_logarithm(P)
1806
+ -1.97657221097437 - 1.05021415535949*I
1807
+ sage: L.elliptic_exponential(_) # abs tol 1e-15
1808
+ (3.00000000000000 + 9.20856947066460e-16*I : -5.59022723358798 - 0.0894418024719718*I : 1.00000000000000)
1809
+ sage: L.elliptic_logarithm(P, prec=100) # abs tol 1e-15
1810
+ -3.4730631218714889933426781799 + 0.44627675553762761312098773197*I
1811
+ sage: L.elliptic_exponential(_) # abs tol 1e-28
1812
+ (3.0000000000000000000000000000 - 1.4773628579202938936348512161e-30*I : -5.5902272335879800026836302686 - 0.089441802471969391005702381090*I : 1.0000000000000000000000000000)
1813
+
1814
+ Real approximate field, negative discriminant. Note that the output precision uses the precision of the base field::
1815
+
1816
+ sage: E = EllipticCurve(RealField(100), [1, 6])
1817
+ sage: L = E.period_lattice()
1818
+ sage: L.real_flag
1819
+ -1
1820
+ sage: P = E(3, 6)
1821
+ sage: L.elliptic_logarithm(P) # abs tol 1e-26
1822
+ 2.4593388737550379526023682666
1823
+ sage: L.elliptic_exponential(_) # abs tol 1e-26
1824
+ (3.0000000000000000000000000000 : 5.9999999999999999999999999999 : 1.0000000000000000000000000000)
1825
+ sage: E = EllipticCurve(RDF, [1, 6])
1826
+ sage: L = E.period_lattice()
1827
+ sage: L.real_flag
1828
+ -1
1829
+ sage: P = E(3, 6)
1830
+ sage: L.elliptic_logarithm(P) # abs tol 1e-13
1831
+ 2.45933887375504
1832
+ sage: L.elliptic_exponential(_) # abs tol 1e-13
1833
+ (3.00000000000000 : 6.00000000000001 : 1.00000000000000)
1834
+
1835
+ Real approximate field, positive discriminant::
1836
+
1837
+ sage: E = EllipticCurve(RealField(100), [-4, 3])
1838
+ sage: L = E.period_lattice()
1839
+ sage: L.real_flag
1840
+ 1
1841
+ sage: P = E.lift_x(4)
1842
+ sage: L.elliptic_logarithm(P) # abs tol 1e-26
1843
+ 0.51188849089267627141925354967
1844
+ sage: L.elliptic_exponential(_) # abs tol 1e-26
1845
+ (4.0000000000000000000000000000 : -7.1414284285428499979993998114 : 1.0000000000000000000000000000)
1846
+
1847
+ Complex approximate field::
1848
+
1849
+ sage: E = EllipticCurve(ComplexField(100), [I, 3*I+4])
1850
+ sage: L = E.period_lattice()
1851
+ sage: L.real_flag
1852
+ 0
1853
+ sage: P = E.lift_x(4)
1854
+ sage: L.elliptic_logarithm(P) # abs tol 1e-26
1855
+ -1.1447032790074574712147458157 - 0.72429843602171875396186134806*I
1856
+ sage: L.elliptic_exponential(_) # abs tol 1e-26
1857
+ (4.0000000000000000000000000000 + 1.2025589033682610849950210280e-30*I : -8.2570982991257407680322611854 - 0.42387771989714340809597881586*I : 1.0000000000000000000000000000)
1858
+ sage: E = EllipticCurve(CDF, [I, 3*I+4])
1859
+ sage: L = E.period_lattice()
1860
+ sage: L.real_flag
1861
+ 0
1862
+ sage: P = E.lift_x(4)
1863
+ sage: L.elliptic_logarithm(P) # abs tol 1e-13
1864
+ -1.14470327900746 - 0.724298436021719*I
1865
+ sage: L.elliptic_exponential(_) # abs tol 1e-13
1866
+ (4.00000000000000 - 0*I : -8.25709829912574 - 0.423877719897148*I : 1.00000000000000)
1867
+ """
1868
+ if P.curve() is not self.E:
1869
+ raise ValueError("Point is on the wrong curve")
1870
+ if prec is None:
1871
+ prec = self._compute_default_prec()
1872
+ if P.is_zero():
1873
+ return ComplexField(prec)(0)
1874
+
1875
+ # Compute the real or complex coordinates of P:
1876
+
1877
+ xP, yP = (self.embedding(coord) for coord in P.xy())
1878
+
1879
+ # The real work is done over R or C now:
1880
+
1881
+ return self.e_log_RC(xP, yP, prec, reduce=reduce)
1882
+
1883
+ def elliptic_exponential(self, z, to_curve=True):
1884
+ r"""
1885
+ Return the elliptic exponential of a complex number.
1886
+
1887
+ INPUT:
1888
+
1889
+ - ``z`` -- complex number (viewed modulo this period lattice)
1890
+
1891
+ - ``to_curve`` -- boolean (default: ``True``); see below
1892
+
1893
+ OUTPUT:
1894
+
1895
+ - If ``to_curve`` is False, a 2-tuple of real or complex
1896
+ numbers representing the point `(x,y) = (\wp(z),\wp'(z))`
1897
+ where `\wp` denotes the Weierstrass `\wp`-function with
1898
+ respect to this lattice.
1899
+
1900
+ - If ``to_curve`` is True, the point `(X,Y) =
1901
+ (x-b_2/12,y-(a_1(x-b_2/12)-a_3)/2)` as a point in `E(\RR)`
1902
+ or `E(\CC)`, with `(x,y) = (\wp(z),\wp'(z))` as above, where
1903
+ `E` is the elliptic curve over `\RR` or `\CC` whose period
1904
+ lattice this is.
1905
+
1906
+ - If the lattice is real and `z` is also real then the output
1907
+ is a pair of real numbers if ``to_curve`` is ``True``, or a
1908
+ point in `E(\RR)` if ``to_curve`` is ``False``.
1909
+
1910
+ .. NOTE::
1911
+
1912
+ The precision is taken from that of the input ``z``.
1913
+
1914
+ EXAMPLES::
1915
+
1916
+ sage: E = EllipticCurve([1,1,1,-8,6])
1917
+ sage: P = E(1, -2)
1918
+ sage: L = E.period_lattice()
1919
+ sage: z = L(P); z
1920
+ 1.17044757240090
1921
+ sage: L.elliptic_exponential(z)
1922
+ (0.999999999999999 : -2.00000000000000 : 1.00000000000000)
1923
+ sage: _.curve()
1924
+ Elliptic Curve defined by y^2 + 1.00000000000000*x*y + 1.00000000000000*y
1925
+ = x^3 + 1.00000000000000*x^2 - 8.00000000000000*x + 6.00000000000000
1926
+ over Real Field with 53 bits of precision
1927
+ sage: L.elliptic_exponential(z,to_curve=False)
1928
+ (1.41666666666667, -2.00000000000000)
1929
+ sage: z = L(P, prec=201); z
1930
+ 1.17044757240089592298992188482371493504472561677451007994189
1931
+ sage: L.elliptic_exponential(z)
1932
+ (1.00000000000000000000000000000000000000000000000000000000000
1933
+ : -2.00000000000000000000000000000000000000000000000000000000000
1934
+ : 1.00000000000000000000000000000000000000000000000000000000000)
1935
+
1936
+ Examples over number fields::
1937
+
1938
+ sage: # needs sage.rings.number_field
1939
+ sage: x = polygen(QQ)
1940
+ sage: K.<a> = NumberField(x^3 - 2)
1941
+ sage: embs = K.embeddings(CC)
1942
+ sage: E = EllipticCurve('37a')
1943
+ sage: EK = E.change_ring(K)
1944
+ sage: Li = [EK.period_lattice(e) for e in embs]
1945
+ sage: P = EK(-1, -1)
1946
+ sage: Q = EK(a - 1, 1 - a^2)
1947
+ sage: zi = [L.elliptic_logarithm(P) for L in Li]
1948
+ sage: [c.real() for c in Li[0].elliptic_exponential(zi[0])]
1949
+ [-1.00000000000000, -1.00000000000000, 1.00000000000000]
1950
+ sage: [c.real() for c in Li[0].elliptic_exponential(zi[1])]
1951
+ [-1.00000000000000, -1.00000000000000, 1.00000000000000]
1952
+ sage: [c.real() for c in Li[0].elliptic_exponential(zi[2])]
1953
+ [-1.00000000000000, -1.00000000000000, 1.00000000000000]
1954
+
1955
+ sage: # needs sage.rings.number_field
1956
+ sage: zi = [L.elliptic_logarithm(Q) for L in Li]
1957
+ sage: Li[0].elliptic_exponential(zi[0])
1958
+ (-1.62996052494744 - 1.09112363597172*I
1959
+ : 1.79370052598410 - 1.37472963699860*I
1960
+ : 1.00000000000000)
1961
+ sage: [embs[0](c) for c in Q]
1962
+ [-1.62996052494744 - 1.09112363597172*I,
1963
+ 1.79370052598410 - 1.37472963699860*I,
1964
+ 1.00000000000000]
1965
+ sage: Li[1].elliptic_exponential(zi[1])
1966
+ (-1.62996052494744 + 1.09112363597172*I
1967
+ : 1.79370052598410 + 1.37472963699860*I
1968
+ : 1.00000000000000)
1969
+ sage: [embs[1](c) for c in Q]
1970
+ [-1.62996052494744 + 1.09112363597172*I,
1971
+ 1.79370052598410 + 1.37472963699860*I,
1972
+ 1.00000000000000]
1973
+ sage: [c.real() for c in Li[2].elliptic_exponential(zi[2])]
1974
+ [0.259921049894873, -0.587401051968199, 1.00000000000000]
1975
+ sage: [embs[2](c) for c in Q]
1976
+ [0.259921049894873, -0.587401051968200, 1.00000000000000]
1977
+
1978
+ Test to show that :issue:`8820` is fixed::
1979
+
1980
+ sage: # needs database_cremona_mini_ellcurve sage.rings.number_field
1981
+ sage: E = EllipticCurve('37a')
1982
+ sage: K.<a> = QuadraticField(-5)
1983
+ sage: L = E.change_ring(K).period_lattice(K.places()[0])
1984
+ sage: L.elliptic_exponential(CDF(.1,.1)) # abs tol 1e-15
1985
+ (0.0000142854026029 - 49.9960001066650*I
1986
+ : 249.520141250950 + 250.019855549131*I : 1.00000000000000)
1987
+ sage: L.elliptic_exponential(CDF(.1,.1), to_curve=False)
1988
+ (0.0000142854026029447 - 49.9960001066650*I,
1989
+ 500.040282501900 + 500.039711098263*I)
1990
+
1991
+ `z=0` is treated as a special case::
1992
+
1993
+ sage: E = EllipticCurve([1,1,1,-8,6])
1994
+ sage: L = E.period_lattice()
1995
+ sage: L.elliptic_exponential(0)
1996
+ (0.000000000000000 : 1.00000000000000 : 0.000000000000000)
1997
+ sage: L.elliptic_exponential(0, to_curve=False)
1998
+ (+infinity, +infinity)
1999
+
2000
+ ::
2001
+
2002
+ sage: # needs database_cremona_mini_ellcurve sage.rings.number_field
2003
+ sage: E = EllipticCurve('37a')
2004
+ sage: K.<a> = QuadraticField(-5)
2005
+ sage: L = E.change_ring(K).period_lattice(K.places()[0])
2006
+ sage: P = L.elliptic_exponential(0); P
2007
+ (0.000000000000000 : 1.00000000000000 : 0.000000000000000)
2008
+ sage: P.parent()
2009
+ Abelian group of points on Elliptic Curve defined by
2010
+ y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x
2011
+ over Complex Field with 53 bits of precision
2012
+
2013
+ Very small `z` are handled properly (see :issue:`8820`)::
2014
+
2015
+ sage: # needs sage.rings.number_field
2016
+ sage: K.<a> = QuadraticField(-1)
2017
+ sage: E = EllipticCurve([0,0,0,a,0])
2018
+ sage: L = E.period_lattice(K.complex_embeddings()[0])
2019
+ sage: L.elliptic_exponential(1e-100)
2020
+ (0.000000000000000 : 1.00000000000000 : 0.000000000000000)
2021
+
2022
+ The elliptic exponential of `z` is returned as `(0 : 1 : 0)` if
2023
+ the coordinates of `z` with respect to the period lattice are
2024
+ approximately integral::
2025
+
2026
+ sage: (100/log(2.0,10))/0.8
2027
+ 415.241011860920
2028
+ sage: L.elliptic_exponential((RealField(415)(1e-100))).is_zero() # needs sage.rings.number_field
2029
+ True
2030
+ sage: L.elliptic_exponential((RealField(420)(1e-100))).is_zero() # needs sage.rings.number_field
2031
+ False
2032
+ """
2033
+ C = z.parent()
2034
+ z_is_real = False
2035
+ if isinstance(C, sage.rings.abc.RealField):
2036
+ z_is_real = True
2037
+ C = ComplexField(C.precision())
2038
+ z = C(z)
2039
+ else:
2040
+ if isinstance(C, sage.rings.abc.ComplexField):
2041
+ z_is_real = z.is_real()
2042
+ else:
2043
+ try:
2044
+ C = ComplexField()
2045
+ z = C(z)
2046
+ z_is_real = z.is_real()
2047
+ except TypeError:
2048
+ raise TypeError("%s is not a complex number" % z)
2049
+ prec = C.precision()
2050
+
2051
+ # test for the point at infinity:
2052
+
2053
+ eps = (C(2)**(-0.8*prec)).real() ## to test integrality w.r.t. lattice within 20%
2054
+ if all((t.round()-t).abs() < eps for t in self.coordinates(z)):
2055
+ K = z.parent()
2056
+ if to_curve:
2057
+ return self.curve().change_ring(K)(0)
2058
+ else:
2059
+ return K(Infinity), K(Infinity)
2060
+
2061
+ # general number field code (including QQ):
2062
+
2063
+ # We do not use PARI's ellztopoint function since it is only
2064
+ # defined for curves over the reals (note that PARI only
2065
+ # computes the period lattice basis in that case). But Sage
2066
+ # can compute the period lattice basis over CC, and then
2067
+ # PARI's ellwp function works fine.
2068
+
2069
+ # NB converting the PARI values to Sage values might land up
2070
+ # in real/complex fields of spuriously higher precision than
2071
+ # the input, since PARI's precision is in word-size chunks.
2072
+ # So we force the results back into the real/complex fields of
2073
+ # the same precision as the input.
2074
+
2075
+ x, y = pari(self.basis(prec=prec)).ellwp(z, flag=1)
2076
+ x, y = (C(t) for t in (x, y))
2077
+
2078
+ if self.real_flag and z_is_real:
2079
+ x = x.real()
2080
+ y = y.real()
2081
+
2082
+ if to_curve:
2083
+ K = x.parent()
2084
+ if self._is_exact:
2085
+ v = refine_embedding(self.embedding, Infinity)
2086
+ else:
2087
+ v = self.embedding
2088
+ a1, a2, a3, a4, a6 = (K(v(a)) for a in self.E.ainvs())
2089
+ b2 = K(v(self.E.b2()))
2090
+ x = x - b2 / 12
2091
+ y = (y - (a1 * x + a3)) / 2
2092
+ EK = EllipticCurve(K, [a1, a2, a3, a4, a6])
2093
+ return EK.point((x, y, K.one()), check=False)
2094
+ else:
2095
+ return (x, y)
2096
+
2097
+
2098
+ def reduce_tau(tau):
2099
+ r"""
2100
+ Transform a point in the upper half plane to the fundamental region.
2101
+
2102
+ INPUT:
2103
+
2104
+ - ``tau`` -- complex number with positive imaginary part
2105
+
2106
+ OUTPUT:
2107
+
2108
+ (tuple) `(\tau',[a,b,c,d])` where `a,b,c,d` are integers such that
2109
+
2110
+ - `ad-bc=1`;
2111
+ - `\tau'=(a\tau+b)/(c\tau+d)`;
2112
+ - `|\tau'|\ge1`;
2113
+ - `|\Re(\tau')|\le\frac{1}{2}`.
2114
+
2115
+ EXAMPLES::
2116
+
2117
+ sage: # needs sage.rings.real_mpfr sage.symbolic
2118
+ sage: from sage.schemes.elliptic_curves.period_lattice import reduce_tau
2119
+ sage: reduce_tau(CC(1.23,3.45))
2120
+ (0.230000000000000 + 3.45000000000000*I, [1, -1, 0, 1])
2121
+ sage: reduce_tau(CC(1.23,0.0345))
2122
+ (-0.463960069171512 + 1.35591888067914*I, [-5, 6, 4, -5])
2123
+ sage: reduce_tau(CC(1.23,0.0000345))
2124
+ (0.130000000001761 + 2.89855072463768*I, [13, -16, 100, -123])
2125
+ """
2126
+ assert tau.imag() > 0
2127
+ a, b = ZZ(1), ZZ(0)
2128
+ c, d = b, a
2129
+ k = tau.real().round()
2130
+ tau -= k
2131
+ a -= k*c
2132
+ b -= k*d
2133
+ while tau.abs() < 0.999:
2134
+ tau = -1/tau
2135
+ a, b, c, d = c, d, -a, -b
2136
+ k = tau.real().round()
2137
+ tau -= k
2138
+ a -= k*c
2139
+ b -= k*d
2140
+ assert a*d-b*c == 1
2141
+ assert tau.abs() >= 0.999 and tau.real().abs() <= 0.5
2142
+ return tau, [a,b,c,d]
2143
+
2144
+
2145
+ def normalise_periods(w1, w2):
2146
+ r"""
2147
+ Normalise the period basis `(w_1,w_2)` so that `w_1/w_2` is in the fundamental region.
2148
+
2149
+ INPUT:
2150
+
2151
+ - ``w1``, ``w2`` -- two complex numbers with non-real ratio
2152
+
2153
+ OUTPUT:
2154
+
2155
+ (tuple) `((\omega_1',\omega_2'),[a,b,c,d])` where `a,b,c,d` are
2156
+ integers such that
2157
+
2158
+ - `ad-bc=\pm1`;
2159
+ - `(\omega_1',\omega_2') = (a\omega_1+b\omega_2,c\omega_1+d\omega_2)`;
2160
+ - `\tau=\omega_1'/\omega_2'` is in the upper half plane;
2161
+ - `|\tau|\ge1` and `|\Re(\tau)|\le\frac{1}{2}`.
2162
+
2163
+ EXAMPLES::
2164
+
2165
+ sage: # needs sage.rings.real_mpfr sage.symbolic
2166
+ sage: from sage.schemes.elliptic_curves.period_lattice import reduce_tau, normalise_periods
2167
+ sage: w1 = CC(1.234, 3.456)
2168
+ sage: w2 = CC(1.234, 3.456000001)
2169
+ sage: w1/w2 # in lower half plane!
2170
+ 0.999999999743367 - 9.16334785827644e-11*I
2171
+ sage: w1w2, abcd = normalise_periods(w1, w2)
2172
+ sage: a,b,c,d = abcd
2173
+ sage: w1w2 == (a*w1+b*w2, c*w1+d*w2)
2174
+ True
2175
+ sage: w1w2[0]/w1w2[1]
2176
+ 1.23400010389203e9*I
2177
+ sage: a*d-b*c # note change of orientation
2178
+ -1
2179
+ """
2180
+ tau = w1/w2
2181
+ s = +1
2182
+ if tau.imag() < 0:
2183
+ w2 = -w2
2184
+ tau = -tau
2185
+ s = -1
2186
+ tau, abcd = reduce_tau(tau)
2187
+ a, b, c, d = abcd
2188
+ if s < 0:
2189
+ abcd = (a,-b,c,-d)
2190
+ return (a*w1+b*w2,c*w1+d*w2), abcd
2191
+
2192
+
2193
+ def extended_agm_iteration(a, b, c):
2194
+ r"""
2195
+ Internal function for the extended AGM used in elliptic logarithm computation.
2196
+
2197
+ INPUT:
2198
+
2199
+ - ``a``, ``b``, ``c`` -- three real or complex numbers
2200
+
2201
+ OUTPUT:
2202
+
2203
+ (3-tuple) `(a_0,b_0,c_0)`, the limit of the iteration `(a,b,c) \mapsto ((a+b)/2,\sqrt{ab},(c+\sqrt{c^2+b^2-a^2})/2)`.
2204
+
2205
+ EXAMPLES::
2206
+
2207
+ sage: # needs sage.rings.real_mpfr
2208
+ sage: from sage.schemes.elliptic_curves.period_lattice import extended_agm_iteration
2209
+ sage: extended_agm_iteration(RR(1), RR(2), RR(3))
2210
+ (1.45679103104691, 1.45679103104691, 3.21245294970054)
2211
+ sage: extended_agm_iteration(CC(1,2), CC(2,3), CC(3,4))
2212
+ (1.46242448156430 + 2.47791311676267*I,
2213
+ 1.46242448156430 + 2.47791311676267*I,
2214
+ 3.22202144343535 + 4.28383734262540*I)
2215
+
2216
+ TESTS::
2217
+
2218
+ sage: extended_agm_iteration(1,2,3) # needs sage.rings.real_mpfr
2219
+ Traceback (most recent call last):
2220
+ ...
2221
+ ValueError: values must be real or complex numbers
2222
+ """
2223
+ if not isinstance(a, (RealNumber,ComplexNumber)):
2224
+ raise ValueError("values must be real or complex numbers")
2225
+ eps = a.parent().one().real() >> (a.parent().precision() - 10)
2226
+ while True:
2227
+ a1 = (a + b) / 2
2228
+ b1 = (a * b).sqrt()
2229
+ delta = (b**2 - a**2) / c**2
2230
+ f = (1 + (1 + delta).sqrt()) / 2
2231
+ if (f.abs() - 1).abs() < eps:
2232
+ return a, b, c
2233
+ c *= f
2234
+ a, b = a1, b1