passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl

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

Potentially problematic release.


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

Files changed (314) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,1552 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ """
3
+ Elliptic curve constructor
4
+
5
+ AUTHORS:
6
+
7
+ - William Stein (2005): Initial version
8
+
9
+ - John Cremona (2008-01): EllipticCurve(j) fixed for all cases
10
+ """
11
+
12
+ #*****************************************************************************
13
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
14
+ #
15
+ # Distributed under the terms of the GNU General Public License (GPL)
16
+ #
17
+ # This code is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
+ # General Public License for more details.
21
+ #
22
+ # The full text of the GPL is available at:
23
+ #
24
+ # http://www.gnu.org/licenses/
25
+ #*****************************************************************************
26
+
27
+ from sage.rings.integer_ring import ZZ
28
+ from sage.rings.rational_field import QQ
29
+ from sage.rings.rational_field import RationalField
30
+
31
+ import sage.rings.abc
32
+ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
33
+ from sage.rings.number_field.number_field_base import NumberField
34
+ from sage.rings.finite_rings.finite_field_base import FiniteField
35
+ from sage.rings.polynomial.multi_polynomial import MPolynomial
36
+
37
+ from sage.categories.rings import Rings
38
+ from sage.categories.fields import Fields
39
+ _Fields = Fields()
40
+
41
+ from sage.structure.sequence import Sequence
42
+ from sage.structure.element import parent, Expression
43
+ from sage.structure.factory import UniqueFactory
44
+
45
+
46
+ class EllipticCurveFactory(UniqueFactory):
47
+ r"""
48
+ Construct an elliptic curve.
49
+
50
+ In Sage, an elliptic curve is always specified by
51
+ (the coefficients of) a long Weierstrass equation
52
+
53
+ .. MATH::
54
+
55
+ y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6.
56
+
57
+ INPUT:
58
+
59
+ There are several ways to construct an elliptic curve:
60
+
61
+ - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given
62
+ `a`-invariants. The invariants are coerced into a common parent.
63
+ If all are integers, they are coerced into the rational numbers.
64
+
65
+ - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`.
66
+
67
+ - ``EllipticCurve(label)``: Returns the elliptic curve over `\QQ`
68
+ from the Cremona database with the given label. The label is a
69
+ string, such as ``'11a'`` or ``'37b2'``. The letters in the
70
+ label *must* be lower case (Cremona's new labeling).
71
+
72
+ - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic
73
+ curve over `R` with given `a`-invariants. Here `R` can be an
74
+ arbitrary commutative ring, although most functionality is only
75
+ implemented over fields.
76
+
77
+ - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return
78
+ an elliptic curve with `j`-invariant ``j0``.
79
+
80
+ - ``EllipticCurve(polynomial)``: Read off the `a`-invariants from
81
+ the polynomial coefficients, see
82
+ :func:`EllipticCurve_from_Weierstrass_polynomial`.
83
+
84
+ - ``EllipticCurve(cubic, point)``: The elliptic curve defined by a
85
+ plane cubic (homogeneous polynomial in three variables), with a
86
+ rational point.
87
+
88
+ Instead of giving the coefficients as a *list* of length 2 or 5,
89
+ one can also give a *tuple*.
90
+
91
+ EXAMPLES:
92
+
93
+ We illustrate creating elliptic curves::
94
+
95
+ sage: EllipticCurve([0,0,1,-1,0])
96
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
97
+
98
+ We create a curve from a Cremona label::
99
+
100
+ sage: EllipticCurve('37b2')
101
+ Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field
102
+ sage: EllipticCurve('5077a')
103
+ Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
104
+ sage: EllipticCurve('389a')
105
+ Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
106
+
107
+ Old Cremona labels are allowed::
108
+
109
+ sage: EllipticCurve('2400FF')
110
+ Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field
111
+
112
+ Unicode labels are allowed::
113
+
114
+ sage: EllipticCurve(u'389a')
115
+ Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
116
+
117
+ We create curves over a finite field as follows::
118
+
119
+ sage: EllipticCurve([GF(5)(0),0,1,-1,0])
120
+ Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
121
+ sage: EllipticCurve(GF(5), [0, 0,1,-1,0])
122
+ Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
123
+
124
+ Elliptic curves over `\ZZ/N\ZZ` with `N` prime are of type
125
+ "elliptic curve over a finite field"::
126
+
127
+ sage: F = Zmod(101)
128
+ sage: EllipticCurve(F, [2, 3])
129
+ Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101
130
+ sage: E = EllipticCurve([F(2), F(3)])
131
+ sage: type(E)
132
+ <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>
133
+ sage: E.category()
134
+ Category of abelian varieties over Ring of integers modulo 101
135
+
136
+ In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite
137
+ are of type "generic elliptic curve"::
138
+
139
+ sage: F = Zmod(95)
140
+ sage: EllipticCurve(F, [2, 3])
141
+ Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95
142
+ sage: E = EllipticCurve([F(2), F(3)])
143
+ sage: type(E)
144
+ <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'>
145
+ sage: E.category()
146
+ Category of schemes over Ring of integers modulo 95
147
+
148
+ The following is a curve over the complex numbers::
149
+
150
+ sage: E = EllipticCurve(CC, [0,0,1,-1,0])
151
+ sage: E
152
+ Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x
153
+ over Complex Field with 53 bits of precision
154
+ sage: E.j_invariant()
155
+ 2988.97297297297
156
+
157
+ We can also create elliptic curves by giving the Weierstrass equation::
158
+
159
+ sage: R2.<x,y> = PolynomialRing(QQ,2)
160
+ sage: EllipticCurve(y^2 + y - ( x^3 + x - 9 ))
161
+ Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field
162
+
163
+ sage: R.<x,y> = GF(5)[]
164
+ sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x)
165
+ Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5
166
+
167
+ We can also create elliptic curves by giving a smooth plane cubic with a rational point::
168
+
169
+ sage: R3.<x,y,z> = PolynomialRing(QQ,3)
170
+ sage: F = x^3 + y^3 + 30*z^3
171
+ sage: P = [1,-1,0]
172
+ sage: EllipticCurve(F,P)
173
+ Elliptic Curve defined by y^2 - 270*y = x^3 - 24300 over Rational Field
174
+
175
+ We can explicitly specify the `j`-invariant::
176
+
177
+ sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label()
178
+ Elliptic Curve defined by y^2 = x^3 - x over Rational Field
179
+ 1728
180
+ '32a2'
181
+
182
+ sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant()
183
+ Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5
184
+ 2
185
+
186
+ See :issue:`6657` ::
187
+
188
+ sage: EllipticCurve(GF(144169), j=1728) # needs sage.rings.finite_rings
189
+ Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169
190
+
191
+ Elliptic curves over the same ring with the same Weierstrass
192
+ coefficients are identical, even when they are constructed in
193
+ different ways (see :issue:`11474`)::
194
+
195
+ sage: EllipticCurve('11a3') is EllipticCurve(QQ, [0, -1, 1, 0, 0])
196
+ True
197
+
198
+ By default, when a rational value of `j` is given, the constructed
199
+ curve is a minimal twist (minimal conductor for curves with that
200
+ `j`-invariant). This can be changed by setting the optional
201
+ parameter ``minimal_twist``, which is ``True`` by default, to ``False``::
202
+
203
+ sage: EllipticCurve(j=100)
204
+ Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
205
+ sage: E =EllipticCurve(j=100); E
206
+ Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
207
+ sage: E.conductor()
208
+ 33129800
209
+ sage: E.j_invariant()
210
+ 100
211
+ sage: E =EllipticCurve(j=100, minimal_twist=False); E
212
+ Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field
213
+ sage: E.conductor()
214
+ 298168200
215
+ sage: E.j_invariant()
216
+ 100
217
+
218
+ Without this option, constructing the curve could take a long time
219
+ since both `j` and `j-1728` have to be factored to compute the
220
+ minimal twist (see :issue:`13100`)::
221
+
222
+ sage: E = EllipticCurve_from_j(2^256+1, minimal_twist=False)
223
+ sage: E.j_invariant() == 2^256+1
224
+ True
225
+
226
+ TESTS::
227
+
228
+ sage: R = ZZ['u', 'v']
229
+ sage: EllipticCurve(R, [1,1])
230
+ Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v
231
+ over Integer Ring
232
+
233
+ We create a curve and a point over ``QQbar`` (see :issue:`6879`)::
234
+
235
+ sage: E = EllipticCurve(QQbar, [0,1]) # needs sage.rings.number_field
236
+ sage: E(0) # needs sage.rings.number_field
237
+ (0 : 1 : 0)
238
+ sage: E.base_field() # needs sage.rings.number_field
239
+ Algebraic Field
240
+
241
+ sage: E = EllipticCurve(RR, [1,2]); E; E.base_field()
242
+ Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000
243
+ over Real Field with 53 bits of precision
244
+ Real Field with 53 bits of precision
245
+ sage: E = EllipticCurve(CC,[3,4]); E; E.base_field()
246
+ Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000
247
+ over Complex Field with 53 bits of precision
248
+ Complex Field with 53 bits of precision
249
+ sage: E = EllipticCurve(QQbar, [5,6]); E; E.base_field() # needs sage.rings.number_field
250
+ Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field
251
+ Algebraic Field
252
+
253
+ See :issue:`6657` ::
254
+
255
+ sage: EllipticCurve(3, j=1728)
256
+ Traceback (most recent call last):
257
+ ...
258
+ ValueError: First parameter (if present) must be a ring when j is specified
259
+
260
+ sage: EllipticCurve(GF(5), j=3/5)
261
+ Traceback (most recent call last):
262
+ ...
263
+ ValueError: First parameter must be a ring containing 3/5
264
+
265
+ If the universe of the coefficients is a general field, the object
266
+ constructed has type :class:`EllipticCurve_field`. Otherwise it is
267
+ :class:`EllipticCurve_generic`. See :issue:`9816` ::
268
+
269
+ sage: E = EllipticCurve([QQbar(1), 3]); E # needs sage.rings.number_field
270
+ Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field
271
+ sage: type(E) # needs sage.rings.number_field
272
+ <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
273
+
274
+ sage: E = EllipticCurve([RR(1), 3]); E
275
+ Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000
276
+ over Real Field with 53 bits of precision
277
+ sage: type(E)
278
+ <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
279
+
280
+ sage: # needs sage.symbolic
281
+ sage: E = EllipticCurve([SR(i),i]); E
282
+ Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring
283
+ sage: type(E)
284
+ <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
285
+ sage: E.category()
286
+ Category of abelian varieties over Symbolic Ring
287
+ sage: SR in Fields()
288
+ True
289
+
290
+ sage: F = FractionField(PolynomialRing(QQ,'t'))
291
+ sage: t = F.gen()
292
+ sage: E = EllipticCurve([t,0]); E
293
+ Elliptic Curve defined by y^2 = x^3 + t*x
294
+ over Fraction Field of Univariate Polynomial Ring in t over Rational Field
295
+ sage: type(E)
296
+ <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
297
+ sage: E.category()
298
+ Category of abelian varieties over
299
+ Fraction Field of Univariate Polynomial Ring in t over Rational Field
300
+
301
+ See :issue:`12517`::
302
+
303
+ sage: E = EllipticCurve([1..5])
304
+ sage: EllipticCurve(E.a_invariants())
305
+ Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
306
+
307
+ See :issue:`11773`::
308
+
309
+ sage: E = EllipticCurve()
310
+ Traceback (most recent call last):
311
+ ...
312
+ TypeError: invalid input to EllipticCurve constructor
313
+ """
314
+ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, **kwds):
315
+ r"""
316
+ Return a ``UniqueFactory`` key and possibly extra parameters.
317
+
318
+ INPUT: See the documentation for :class:`EllipticCurveFactory`.
319
+
320
+ OUTPUT:
321
+
322
+ A pair ``(key, extra_args)``:
323
+
324
+ - ``key`` has the form `(R, (a_1, a_2, a_3, a_4, a_6))`,
325
+ representing a ring and the Weierstrass coefficients of an
326
+ elliptic curve over that ring;
327
+
328
+ - ``extra_args`` is a dictionary containing additional data to
329
+ be inserted into the elliptic curve structure.
330
+
331
+ EXAMPLES::
332
+
333
+ sage: EllipticCurve.create_key_and_extra_args(j=8000)
334
+ ((Rational Field, (0, 1, 0, -3, 1)), {})
335
+
336
+ When constructing a curve over `\QQ` from a Cremona or LMFDB
337
+ label, the invariants from the database are returned as
338
+ ``extra_args``::
339
+
340
+ sage: key, data = EllipticCurve.create_key_and_extra_args('389.a1')
341
+ sage: key
342
+ (Rational Field, (0, 1, 1, -2, 0))
343
+ sage: data['conductor']
344
+ 389
345
+ sage: data['cremona_label']
346
+ '389a1'
347
+ sage: data['lmfdb_label']
348
+ '389.a1'
349
+ sage: data['rank']
350
+ 2
351
+ sage: data['torsion_order']
352
+ 1
353
+
354
+ User-specified keywords are also included in ``extra_args``::
355
+
356
+ sage: key, data = EllipticCurve.create_key_and_extra_args((0, 0, 1, -23737, 960366), rank=4)
357
+ sage: data['rank']
358
+ 4
359
+
360
+ Furthermore, keywords takes precedence over data from the
361
+ database, which can be used to specify an alternative set of
362
+ generators for the Mordell-Weil group::
363
+
364
+ sage: key, data = EllipticCurve.create_key_and_extra_args('5077a1', gens=[[1, -1], [-2, 3], [4, -7]])
365
+ sage: data['gens']
366
+ [[1, -1], [-2, 3], [4, -7]]
367
+ sage: E = EllipticCurve.create_object(0, key, **data)
368
+ sage: E.gens()
369
+ [(-2 : 3 : 1), (1 : -1 : 1), (4 : -7 : 1)]
370
+
371
+ Note that elliptic curves are equal if and only they have the
372
+ same base ring and Weierstrass equation; the data in
373
+ ``extra_args`` do not influence comparison of elliptic curves.
374
+ A consequence of this is that passing keyword arguments only
375
+ works when constructing an elliptic curve the first time::
376
+
377
+ sage: E = EllipticCurve('433a1', gens=[[-1, 1], [3, 4]])
378
+ sage: E.gens()
379
+ [(-1 : 1 : 1), (3 : 4 : 1)]
380
+ sage: E = EllipticCurve('433a1', gens=[[-1, 0], [0, 1]])
381
+ sage: E.gens()
382
+ [(-1 : 1 : 1), (3 : 4 : 1)]
383
+
384
+ .. WARNING::
385
+
386
+ Manually specifying extra data is almost never necessary
387
+ and is not guaranteed to have any effect, as the above
388
+ example shows. Almost no checking is done, so specifying
389
+ incorrect data may lead to wrong results of computations
390
+ instead of errors or warnings.
391
+
392
+ TESTS::
393
+
394
+ sage: # needs sage.symbolic
395
+ sage: var('x', 'y', 'v', 'w')
396
+ (x, y, v, w)
397
+ sage: EllipticCurve(y^2 + y > x^3 + x - 9)
398
+ Traceback (most recent call last):
399
+ ...
400
+ ValueError: no symbolic relations other than equalities are allowed
401
+ sage: E = EllipticCurve(y^2 + y == x^3 + x - 9)
402
+ sage: E is EllipticCurve(y^2 + y - ( x^3 + x - 9 ))
403
+ True
404
+ sage: R.<x,y> = QQ[]
405
+ sage: E is EllipticCurve(y^2 + y - ( x^3 + x - 9 ))
406
+ True
407
+ """
408
+ R = None
409
+ if x in Rings():
410
+ R, x = (x, y)
411
+
412
+ if j is not None:
413
+ if R is not None:
414
+ try:
415
+ j = R(j)
416
+ except (ZeroDivisionError, ValueError, TypeError):
417
+ raise ValueError("First parameter must be a ring containing %s" % j)
418
+ elif x is not None:
419
+ raise ValueError("First parameter (if present) must be a ring when j is specified")
420
+ x = coefficients_from_j(j, minimal_twist)
421
+
422
+ if isinstance(x, Expression) and x.is_relational():
423
+ import operator
424
+ if x.operator() != operator.eq:
425
+ raise ValueError("no symbolic relations other than equalities are allowed")
426
+ x = x.lhs() - x.rhs()
427
+
428
+ if isinstance(parent(x), sage.rings.abc.SymbolicRing):
429
+ x = x._polynomial_(QQ['x', 'y'])
430
+
431
+ if isinstance(x, MPolynomial):
432
+ if y is None:
433
+ x = coefficients_from_Weierstrass_polynomial(x)
434
+ else:
435
+ # x is a cubic, y a rational point
436
+ x = EllipticCurve_from_cubic(x, y, morphism=False).ainvs()
437
+
438
+ if isinstance(x, str):
439
+ # Interpret x as a Cremona or LMFDB label.
440
+ from sage.databases.cremona import CremonaDatabase
441
+ x, data = CremonaDatabase().coefficients_and_data(x)
442
+ # data is only valid for elliptic curves over QQ.
443
+ if R not in (None, QQ):
444
+ data = {}
445
+ # User-provided keywords may override database entries.
446
+ data.update(kwds)
447
+ kwds = data
448
+
449
+ if not isinstance(x, (list, tuple)):
450
+ raise TypeError("invalid input to EllipticCurve constructor")
451
+
452
+ if len(x) == 2:
453
+ x = (0, 0, 0, x[0], x[1])
454
+ elif len(x) != 5:
455
+ raise ValueError("sequence of coefficients must have length 2 or 5")
456
+
457
+ if R is None:
458
+ R = Sequence(x).universe()
459
+ if R in (ZZ, int):
460
+ R = QQ
461
+
462
+ return (R, tuple(R(a) for a in x)), kwds
463
+
464
+ def create_object(self, version, key, *, names=None, **kwds):
465
+ r"""
466
+ Create an object from a ``UniqueFactory`` key.
467
+
468
+ EXAMPLES::
469
+
470
+ sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2)))
471
+ sage: type(E)
472
+ <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>
473
+
474
+ ``names`` is ignored at the moment, however it is used to support a convenient way to get a generator::
475
+
476
+ sage: # needs eclib
477
+ sage: E.<P> = EllipticCurve(QQ, [1, 3])
478
+ sage: P
479
+ (-1 : 1 : 1)
480
+ sage: E.<P> = EllipticCurve(GF(5), [1, 3])
481
+ sage: P
482
+ (4 : 1 : 1)
483
+
484
+ .. NOTE::
485
+
486
+ Keyword arguments are currently only passed to the
487
+ constructor for elliptic curves over `\QQ`; elliptic
488
+ curves over other fields do not support them.
489
+
490
+ TESTS::
491
+
492
+ sage: E = EllipticCurve.create_object(0, (QQ, (1, 2, 0, 1, 2)), rank=2)
493
+ sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2)), rank=2)
494
+ Traceback (most recent call last):
495
+ ...
496
+ TypeError: unexpected keyword arguments: {'rank': 2}
497
+
498
+ Coverage tests::
499
+
500
+ sage: E = EllipticCurve(QQ, [2, 5], modular_degree=944, regulator=1)
501
+ sage: E.modular_degree()
502
+ 944
503
+ sage: E.regulator()
504
+ 1.00000000000000
505
+ """
506
+ R, x = key
507
+
508
+ if R is QQ:
509
+ from .ell_rational_field import EllipticCurve_rational_field
510
+ return EllipticCurve_rational_field(x, **kwds)
511
+ elif kwds:
512
+ raise TypeError(f"unexpected keyword arguments: {kwds}")
513
+
514
+ if isinstance(R, NumberField):
515
+ from .ell_number_field import EllipticCurve_number_field
516
+ return EllipticCurve_number_field(R, x)
517
+ elif isinstance(R, sage.rings.abc.pAdicField):
518
+ from .ell_padic_field import EllipticCurve_padic_field
519
+ return EllipticCurve_padic_field(R, x)
520
+ elif isinstance(R, FiniteField) or (isinstance(R, sage.rings.abc.IntegerModRing) and R.characteristic().is_prime()):
521
+ from .ell_finite_field import EllipticCurve_finite_field
522
+ return EllipticCurve_finite_field(R, x)
523
+ elif R in _Fields:
524
+ from .ell_field import EllipticCurve_field
525
+ return EllipticCurve_field(R, x)
526
+ from .ell_generic import EllipticCurve_generic
527
+ return EllipticCurve_generic(R, x)
528
+
529
+
530
+ EllipticCurve = EllipticCurveFactory('sage.schemes.elliptic_curves.constructor.EllipticCurve')
531
+
532
+
533
+ def EllipticCurve_from_Weierstrass_polynomial(f):
534
+ r"""
535
+ Return the elliptic curve defined by a cubic in (long) Weierstrass
536
+ form.
537
+
538
+ INPUT:
539
+
540
+ - ``f`` -- a inhomogeneous cubic polynomial in long Weierstrass form
541
+
542
+ OUTPUT: the elliptic curve defined by it
543
+
544
+ EXAMPLES::
545
+
546
+ sage: R.<x,y> = QQ[]
547
+ sage: f = y^2 + 1*x*y + 3*y - (x^3 + 2*x^2 + 4*x + 6)
548
+ sage: EllipticCurve(f)
549
+ Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 6 over Rational Field
550
+ sage: EllipticCurve(f).a_invariants()
551
+ (1, 2, 3, 4, 6)
552
+
553
+ The polynomial ring may have extra variables as long as they
554
+ do not occur in the polynomial itself::
555
+
556
+ sage: R.<x,y,z,w> = QQ[]
557
+ sage: EllipticCurve(-y^2 + x^3 + 1)
558
+ Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
559
+ sage: EllipticCurve(-x^2 + y^3 + 1)
560
+ Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
561
+ sage: EllipticCurve(-w^2 + z^3 + 1)
562
+ Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
563
+
564
+ TESTS::
565
+
566
+ sage: from sage.schemes.elliptic_curves.constructor import EllipticCurve_from_Weierstrass_polynomial
567
+ sage: EllipticCurve_from_Weierstrass_polynomial(-w^2 + z^3 + 1)
568
+ Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
569
+ """
570
+ return EllipticCurve(coefficients_from_Weierstrass_polynomial(f))
571
+
572
+
573
+ def coefficients_from_Weierstrass_polynomial(f):
574
+ r"""
575
+ Return the coefficients `[a_1, a_2, a_3, a_4, a_6]` of a cubic in
576
+ Weierstrass form.
577
+
578
+ EXAMPLES::
579
+
580
+ sage: from sage.schemes.elliptic_curves.constructor import coefficients_from_Weierstrass_polynomial
581
+ sage: R.<w,z> = QQ[]
582
+ sage: coefficients_from_Weierstrass_polynomial(-w^2 + z^3 + 1)
583
+ [0, 0, 0, 0, 1]
584
+ """
585
+ R = f.parent()
586
+ cubic_variables = [ x for x in R.gens() if f.degree(x) == 3 ]
587
+ quadratic_variables = [ y for y in R.gens() if f.degree(y) == 2 ]
588
+ try:
589
+ x = cubic_variables[0]
590
+ y = quadratic_variables[0]
591
+ except IndexError:
592
+ raise ValueError('polynomial is not in long Weierstrass form')
593
+
594
+ a1 = a2 = a3 = a4 = a6 = 0
595
+ x3 = y2 = None
596
+ for coeff, mon in f:
597
+ if mon == x**3:
598
+ x3 = coeff
599
+ elif mon == x**2:
600
+ a2 = coeff
601
+ elif mon == x:
602
+ a4 = coeff
603
+ elif mon == 1:
604
+ a6 = coeff
605
+ elif mon == y**2:
606
+ y2 = -coeff
607
+ elif mon == x*y:
608
+ a1 = -coeff
609
+ elif mon == y:
610
+ a3 = -coeff
611
+ else:
612
+ raise ValueError('polynomial is not in long Weierstrass form')
613
+
614
+ if x3 != y2:
615
+ raise ValueError('the coefficient of x^3 and -y^2 must be the same')
616
+ elif x3 != 1:
617
+ a1, a2, a3, a4, a6 = a1/x3, a2/x3, a3/x3, a4/x3, a6/x3
618
+ return [a1, a2, a3, a4, a6]
619
+
620
+
621
+ def EllipticCurve_from_c4c6(c4, c6):
622
+ r"""
623
+ Return an elliptic curve with given `c_4` and
624
+ `c_6` invariants.
625
+
626
+ EXAMPLES::
627
+
628
+ sage: E = EllipticCurve_from_c4c6(17, -2005)
629
+ sage: E
630
+ Elliptic Curve defined by y^2 = x^3 - 17/48*x + 2005/864 over Rational Field
631
+ sage: E.c_invariants()
632
+ (17, -2005)
633
+ """
634
+ try:
635
+ K = c4.parent()
636
+ except AttributeError:
637
+ K = RationalField()
638
+ if K not in _Fields:
639
+ K = K.fraction_field()
640
+ return EllipticCurve([-K(c4)/K(48), -K(c6)/K(864)])
641
+
642
+
643
+ def EllipticCurve_from_j(j, minimal_twist=True):
644
+ r"""
645
+ Return an elliptic curve with given `j`-invariant.
646
+
647
+ INPUT:
648
+
649
+ - ``j`` -- an element of some field
650
+
651
+ - ``minimal_twist``-- boolean (default: ``True``); if ``True`` and ``j``
652
+ is in `\QQ`, the curve returned is a minimal twist, i.e. has
653
+ minimal conductor; when there is more than one curve with
654
+ minimal conductor, the curve returned is the one whose label
655
+ comes first if the curves are in the CremonaDatabase, otherwise
656
+ the one whose minimal a-invariants are first lexicographically.
657
+ If `j` is not in `\QQ` this parameter is ignored.
658
+
659
+ OUTPUT: an elliptic curve with `j`-invariant `j`
660
+
661
+ EXAMPLES::
662
+
663
+ sage: E = EllipticCurve_from_j(0); E; E.j_invariant(); E.label()
664
+ Elliptic Curve defined by y^2 + y = x^3 over Rational Field
665
+ 0
666
+ '27a3'
667
+
668
+ sage: E = EllipticCurve_from_j(1728); E; E.j_invariant(); E.label()
669
+ Elliptic Curve defined by y^2 = x^3 - x over Rational Field
670
+ 1728
671
+ '32a2'
672
+
673
+ sage: E = EllipticCurve_from_j(1); E; E.j_invariant()
674
+ Elliptic Curve defined by y^2 + x*y = x^3 + 36*x + 3455 over Rational Field
675
+ 1
676
+
677
+ The ``minimal_twist`` parameter (ignored except over `\QQ` and
678
+ ``True`` by default) controls whether or not a minimal twist is
679
+ computed::
680
+
681
+ sage: EllipticCurve_from_j(100)
682
+ Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
683
+ sage: _.conductor()
684
+ 33129800
685
+ sage: EllipticCurve_from_j(100, minimal_twist=False)
686
+ Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field
687
+ sage: _.conductor()
688
+ 298168200
689
+
690
+ Since computing the minimal twist requires factoring both `j` and
691
+ `j-1728` the following example would take a long time without
692
+ setting ``minimal_twist`` to False::
693
+
694
+ sage: E = EllipticCurve_from_j(2^256+1, minimal_twist=False)
695
+ sage: E.j_invariant() == 2^256+1
696
+ True
697
+ """
698
+ return EllipticCurve(coefficients_from_j(j, minimal_twist))
699
+
700
+
701
+ def coefficients_from_j(j, minimal_twist=True):
702
+ r"""
703
+ Return Weierstrass coefficients `(a_1, a_2, a_3, a_4, a_6)` for an
704
+ elliptic curve with given `j`-invariant.
705
+
706
+ INPUT: See :func:`EllipticCurve_from_j`.
707
+
708
+ EXAMPLES::
709
+
710
+ sage: from sage.schemes.elliptic_curves.constructor import coefficients_from_j
711
+ sage: coefficients_from_j(0)
712
+ [0, 0, 1, 0, 0]
713
+ sage: coefficients_from_j(1728)
714
+ [0, 0, 0, -1, 0]
715
+ sage: coefficients_from_j(1)
716
+ [1, 0, 0, 36, 3455]
717
+
718
+ The ``minimal_twist`` parameter (ignored except over `\QQ` and
719
+ ``True`` by default) controls whether or not a minimal twist is
720
+ computed::
721
+
722
+ sage: coefficients_from_j(100)
723
+ [0, 1, 0, 3392, 307888]
724
+ sage: coefficients_from_j(100, minimal_twist=False)
725
+ [0, 0, 0, 488400, -530076800]
726
+ """
727
+ try:
728
+ K = j.parent()
729
+ except AttributeError:
730
+ K = RationalField()
731
+ if K not in _Fields:
732
+ K = K.fraction_field()
733
+
734
+ char = K.characteristic()
735
+ if char == 2:
736
+ if j == 0:
737
+ return Sequence([0, 0, 1, 0, 0], universe=K)
738
+ else:
739
+ return Sequence([1, 0, 0, 0, 1/j], universe=K)
740
+ if char == 3:
741
+ if j == 0:
742
+ return Sequence([0, 0, 0, 1, 0], universe=K)
743
+ else:
744
+ return Sequence([0, j, 0, 0, -j**2], universe=K)
745
+
746
+ if K is RationalField():
747
+ # we construct the minimal twist, i.e. the curve with minimal
748
+ # conductor with this j_invariant:
749
+ if j == 0:
750
+ return Sequence([0, 0, 1, 0, 0], universe=K) # 27a3
751
+ if j == 1728:
752
+ return Sequence([0, 0, 0, -1, 0], universe=K) # 32a2
753
+
754
+ if not minimal_twist:
755
+ k = j-1728
756
+ return Sequence([0, 0, 0, -3*j*k, -2*j*k**2], universe=K)
757
+
758
+ n = j.numerator()
759
+ m = n-1728*j.denominator()
760
+ a4 = -3*n*m
761
+ a6 = -2*n*m**2
762
+
763
+ # Now E=[0,0,0,a4,a6] has j-invariant j=n/d
764
+ from sage.sets.set import Set
765
+ for p in Set(n.prime_divisors()+m.prime_divisors()):
766
+ e = min(a4.valuation(p)//2,a6.valuation(p)//3)
767
+ if e > 0:
768
+ p = p**e
769
+ a4 /= p**2
770
+ a6 /= p**3
771
+
772
+ # Now E=[0,0,0,a4,a6] is minimal at all p != 2,3
773
+ tw = [-1,2,-2,3,-3,6,-6]
774
+ E1 = EllipticCurve([0,0,0,a4,a6])
775
+ Elist = [E1] + [E1.quadratic_twist(t) for t in tw]
776
+ min_cond = min(E.conductor() for E in Elist)
777
+ Elist = [E for E in Elist if E.conductor() == min_cond]
778
+ if len(Elist) > 1:
779
+ from sage.databases.cremona import CremonaDatabase, parse_cremona_label
780
+ if min_cond <= CremonaDatabase().largest_conductor():
781
+ sorter = lambda E: parse_cremona_label(E.label(), numerical_class_code=True)
782
+ else:
783
+ sorter = lambda E: E.ainvs()
784
+ Elist.sort(key=sorter)
785
+ return Sequence(Elist[0].ainvs())
786
+
787
+ # defaults for all other fields:
788
+ if j == 0:
789
+ return Sequence([0, 0, 0, 0, 1], universe=K)
790
+ if j == 1728:
791
+ return Sequence([0, 0, 0, 1, 0], universe=K)
792
+ k = j-1728
793
+ return Sequence([0, 0, 0, -3*j*k, -2*j*k**2], universe=K)
794
+
795
+
796
+ def EllipticCurve_from_cubic(F, P=None, morphism=True):
797
+ r"""
798
+ Construct an elliptic curve from a ternary cubic with a rational point.
799
+
800
+ If you just want the Weierstrass form and are not interested in
801
+ the morphism then it is easier to use the function
802
+ :func:`~sage.schemes.elliptic_curves.jacobian.Jacobian`
803
+ instead. If there is a rational point on the given cubic, this
804
+ function will construct the same elliptic curve but you do not have to
805
+ supply the point ``P``.
806
+
807
+ INPUT:
808
+
809
+ - ``F`` -- a homogeneous cubic in three variables with rational
810
+ coefficients, as a polynomial ring element, defining a smooth
811
+ plane cubic curve `C`
812
+
813
+ - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on `C`,
814
+ or ``None``. If ``None`` then a rational flex will be used as a
815
+ base point if one exists, otherwise an error will be raised.
816
+
817
+ - ``morphism`` -- boolean (default: ``True``); if ``True``
818
+ returns a birational isomorphism from `C` to a Weierstrass
819
+ elliptic curve `E`, otherwise just returns `E`
820
+
821
+ OUTPUT:
822
+
823
+ Either (when ``morphism``=``False``) an elliptic curve `E` in long
824
+ Weierstrass form isomorphic to the plane cubic curve `C` defined
825
+ by the equation `F=0`.
826
+
827
+ Or (when ``morphism=True``), a birational isomorphism from `C` to
828
+ the elliptic curve `E`. If the given point is a flex, this is a
829
+ linear isomorphism.
830
+
831
+ .. NOTE::
832
+
833
+ The function
834
+ :func:`~sage.schemes.elliptic_curves.jacobian.Jacobian` may be
835
+ used instead. It constructs the same elliptic curve (which is in
836
+ all cases the Jacobian of `(F=0)`) and needs no base point to be
837
+ provided, but also returns no isomorphism since in general there
838
+ is none: the plane cubic is only isomorphic to its Jacobian when
839
+ it has a rational point.
840
+
841
+ .. NOTE::
842
+
843
+ When ``morphism=True``, a birational isomorphism between the
844
+ curve `F=0` and the Weierstrass curve is returned. If the point
845
+ happens to be a flex, then this is a linear isomorphism. The
846
+ morphism does not necessarily take the given point `P` to the
847
+ point at infinity on `E`, since we always use a rational flex
848
+ on `C` as base-point when one exists.
849
+
850
+ EXAMPLES:
851
+
852
+ First we find that the Fermat cubic is isomorphic to the curve
853
+ with Cremona label 27a1::
854
+
855
+ sage: R.<x,y,z> = QQ[]
856
+ sage: cubic = x^3 + y^3 + z^3
857
+ sage: P = [1,-1,0]
858
+ sage: E = EllipticCurve_from_cubic(cubic, P, morphism=False); E
859
+ Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field
860
+ sage: E.cremona_label()
861
+ '27a1'
862
+ sage: EllipticCurve_from_cubic(cubic, [0,1,-1], morphism=False).cremona_label()
863
+ '27a1'
864
+ sage: EllipticCurve_from_cubic(cubic, [1,0,-1], morphism=False).cremona_label()
865
+ '27a1'
866
+
867
+ Next we find the minimal model and conductor of the Jacobian of the
868
+ Selmer curve::
869
+
870
+ sage: R.<a,b,c> = QQ[]
871
+ sage: cubic = a^3 + b^3 + 60*c^3
872
+ sage: P = [1,-1,0]
873
+ sage: E = EllipticCurve_from_cubic(cubic, P, morphism=False); E
874
+ Elliptic Curve defined by y^2 - 540*y = x^3 - 97200 over Rational Field
875
+ sage: E.minimal_model()
876
+ Elliptic Curve defined by y^2 = x^3 - 24300 over Rational Field
877
+ sage: E.conductor()
878
+ 24300
879
+
880
+ We can also get the birational isomorphism to and from the
881
+ Weierstrass form. We start with an example where ``P`` is a flex
882
+ and the equivalence is a linear isomorphism::
883
+
884
+ sage: f = EllipticCurve_from_cubic(cubic, P, morphism=True)
885
+ sage: f
886
+ Scheme morphism:
887
+ From: Projective Plane Curve over Rational Field defined by a^3 + b^3 + 60*c^3
888
+ To: Elliptic Curve defined by y^2 - 540*y = x^3 - 97200 over Rational Field
889
+ Defn: Defined on coordinates by sending (a : b : c) to
890
+ (-c : 3*a : 1/180*a + 1/180*b)
891
+
892
+ sage: finv = f.inverse(); finv
893
+ Scheme morphism:
894
+ From: Elliptic Curve defined by y^2 - 540*y = x^3 - 97200 over Rational Field
895
+ To: Projective Plane Curve over Rational Field defined by a^3 + b^3 + 60*c^3
896
+ Defn: Defined on coordinates by sending (x : y : z) to
897
+ (1/3*y : -1/3*y + 180*z : -x)
898
+
899
+ Scheme morphism:
900
+ From: Elliptic Curve defined by y^2 + 2*x*y + 20*y = x^3 - x^2 - 20*x - 400/3
901
+ over Rational Field
902
+ To: Closed subscheme of Projective Space of dimension 2 over Rational Field
903
+ defined by: a^3 + b^3 + 60*c^3
904
+ Defn: Defined on coordinates by sending (x : y : z) to
905
+ (x + y + 20*z : -x - y : -x)
906
+
907
+ We verify that `f` maps the chosen point `P=(1,-1,0)` on the cubic
908
+ to the origin of the elliptic curve::
909
+
910
+ sage: f([1,-1,0])
911
+ (0 : 1 : 0)
912
+ sage: finv([0,1,0])
913
+ (-1 : 1 : 0)
914
+
915
+ To verify the output, we plug in the polynomials to check that
916
+ this indeed transforms the cubic into Weierstrass form::
917
+
918
+ sage: cubic(finv.defining_polynomials()) * finv.post_rescaling()
919
+ -x^3 + y^2*z - 540*y*z^2 + 97200*z^3
920
+
921
+ sage: E.defining_polynomial()(f.defining_polynomials()) * f.post_rescaling()
922
+ a^3 + b^3 + 60*c^3
923
+
924
+ If the given point is not a flex and the cubic has no rational
925
+ flexes, then the cubic can not be transformed to a Weierstrass
926
+ equation by a linear transformation. The general birational
927
+ transformation is still a birational isomorphism, but is
928
+ quadratic::
929
+
930
+ sage: R.<x,y,z> = QQ[]
931
+ sage: cubic = x^2*y + 4*x*y^2 + x^2*z + 8*x*y*z + 4*y^2*z + 9*x*z^2 + 9*y*z^2
932
+ sage: f = EllipticCurve_from_cubic(cubic, [1,-1,1], morphism=True); f
933
+ Scheme morphism:
934
+ From: Projective Plane Curve over Rational Field defined
935
+ by x^2*y + 4*x*y^2 + x^2*z + 8*x*y*z + 4*y^2*z + 9*x*z^2 + 9*y*z^2
936
+ To: Elliptic Curve defined
937
+ by y^2 + 7560/19*x*y + 552960000000/2352637*y = x^3 - 3445200/133*x^2
938
+ over Rational Field
939
+ Defn: Defined on coordinates by sending (x : y : z) to
940
+ (2527/17280*x^2 + 133/2160*x*y + 133/108000*y^2 + 133/2880*x*z
941
+ + 931/18000*y*z - 3857/48000*z^2
942
+ : -6859/288*x^2 + 323/36*x*y + 359/1800*y^2 + 551/48*x*z
943
+ + 2813/300*y*z + 24389/800*z^2
944
+ : -2352637/99532800000*x^2 - 2352637/124416000000*x*y
945
+ - 2352637/622080000000*y^2 + 2352637/82944000000*x*z
946
+ + 2352637/207360000000*y*z - 2352637/276480000000*z^2)
947
+
948
+ Note that the morphism returned cannot be evaluated directly at
949
+ the given point ``P=(1:-1:1)`` since the polynomials defining it
950
+ all vanish there::
951
+
952
+ sage: f([1,-1,1])
953
+ Traceback (most recent call last):
954
+ ...
955
+ ValueError: [0, 0, 0] does not define a valid projective point since all entries are zero
956
+
957
+ Using the group law on the codomain elliptic curve, which has rank
958
+ 1 and full 2-torsion, and the inverse morphism, we can find many
959
+ points on the cubic. First we find the preimages of multiples of
960
+ the generator::
961
+
962
+ sage: # needs eclib
963
+ sage: E = f.codomain()
964
+ sage: E.label()
965
+ '720e2'
966
+ sage: E.rank()
967
+ 1
968
+ sage: R = E.gens()[0]; R
969
+ (-17280000/2527 : 9331200000/6859 : 1)
970
+ sage: finv = f.inverse()
971
+ sage: [finv(k*R) for k in range(1,10)]
972
+ [(-4 : 1 : 0),
973
+ (-1 : 4 : 1),
974
+ (-20 : -55/76 : 1),
975
+ (319/399 : -11339/7539 : 1),
976
+ (159919/14360 : -4078139/1327840 : 1),
977
+ (-27809119/63578639 : 1856146436/3425378659 : 1),
978
+ (-510646582340/56909753439 : 424000923715/30153806197284 : 1),
979
+ (-56686114363679/4050436059492161 : -2433034816977728281/1072927821085503881 : 1),
980
+ (650589589099815846721/72056273157352822480 : -347376189546061993109881/194127383495944026752320 : 1)]
981
+
982
+ The elliptic curve also has torsion, which we can map back::
983
+
984
+ sage: # needs eclib
985
+ sage: E.torsion_points()
986
+ [(0 : 1 : 0),
987
+ (-144000000/17689 : 3533760000000/2352637 : 1),
988
+ (-92160000/17689 : 2162073600000/2352637 : 1),
989
+ (-5760000/17689 : -124070400000/2352637 : 1)]
990
+ sage: [finv(Q) for Q in E.torsion_points() if Q]
991
+ [(9 : -9/4 : 1), (-9 : 0 : 1), (0 : 1 : 0)]
992
+
993
+ In this example, the given point ``P`` is not a flex but the cubic
994
+ does have a rational flex, ``(-4:0:1)``. We return a linear
995
+ isomorphism which maps this flex to the point at infinity on the
996
+ Weierstrass model::
997
+
998
+ sage: R.<a,b,c> = QQ[]
999
+ sage: cubic = a^3 + 7*b^3 + 64*c^3
1000
+ sage: P = [2,2,-1]
1001
+ sage: f = EllipticCurve_from_cubic(cubic, P, morphism=True)
1002
+ sage: E = f.codomain(); E
1003
+ Elliptic Curve defined by y^2 - 258048*y = x^3 - 22196256768 over Rational Field
1004
+ sage: E.minimal_model()
1005
+ Elliptic Curve defined by y^2 + y = x^3 - 331 over Rational Field
1006
+
1007
+ sage: f
1008
+ Scheme morphism:
1009
+ From: Projective Plane Curve over Rational Field defined by a^3 + 7*b^3 + 64*c^3
1010
+ To: Elliptic Curve defined by y^2 - 258048*y = x^3 - 22196256768 over Rational Field
1011
+ Defn: Defined on coordinates by sending (a : b : c) to
1012
+ (b : -48*a : -1/5376*a - 1/1344*c)
1013
+
1014
+ sage: finv = f.inverse(); finv
1015
+ Scheme morphism:
1016
+ From: Elliptic Curve defined by y^2 - 258048*y = x^3 - 22196256768 over Rational Field
1017
+ To: Projective Plane Curve over Rational Field defined by a^3 + 7*b^3 + 64*c^3
1018
+ Defn: Defined on coordinates by sending (x : y : z) to
1019
+ (-1/48*y : x : 1/192*y - 1344*z)
1020
+
1021
+ sage: cubic(finv.defining_polynomials()) * finv.post_rescaling()
1022
+ -x^3 + y^2*z - 258048*y*z^2 + 22196256768*z^3
1023
+
1024
+ sage: E.defining_polynomial()(f.defining_polynomials()) * f.post_rescaling()
1025
+ a^3 + 7*b^3 + 64*c^3
1026
+
1027
+ sage: f(P)
1028
+ (5376 : -258048 : 1)
1029
+ sage: f([-4,0,1])
1030
+ (0 : 1 : 0)
1031
+
1032
+ It is possible to not provide a base point ``P`` provided that the
1033
+ cubic has a rational flex. In this case the flexes will be found
1034
+ and one will be used as a base point::
1035
+
1036
+ sage: R.<x,y,z> = QQ[]
1037
+ sage: cubic = x^3 + y^3 + z^3
1038
+ sage: f = EllipticCurve_from_cubic(cubic, morphism=True)
1039
+ sage: f
1040
+ Scheme morphism:
1041
+ From: Projective Plane Curve over Rational Field defined by x^3 + y^3 + z^3
1042
+ To: Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field
1043
+ Defn: Defined on coordinates by sending (x : y : z) to
1044
+ (y : -3*x : -1/3*x - 1/3*z)
1045
+
1046
+ An error will be raised if no point is given and there are no rational flexes::
1047
+
1048
+ sage: R.<x,y,z> = QQ[]
1049
+ sage: cubic = 3*x^3 + 4*y^3 + 5*z^3
1050
+ sage: EllipticCurve_from_cubic(cubic)
1051
+ Traceback (most recent call last):
1052
+ ...
1053
+ ValueError: A point must be given when the cubic has no rational flexes
1054
+
1055
+ An example over a finite field, using a flex::
1056
+
1057
+ sage: K = GF(17)
1058
+ sage: R.<x,y,z> = K[]
1059
+ sage: cubic = 2*x^3 + 3*y^3 + 4*z^3
1060
+ sage: EllipticCurve_from_cubic(cubic, [0,3,1])
1061
+ Scheme morphism:
1062
+ From: Projective Plane Curve over Finite Field of size 17
1063
+ defined by 2*x^3 + 3*y^3 + 4*z^3
1064
+ To: Elliptic Curve defined by y^2 + 16*y = x^3 + 11 over Finite Field of size 17
1065
+ Defn: Defined on coordinates by sending (x : y : z) to
1066
+ (-x : 4*y : 4*y + 5*z)
1067
+
1068
+ An example in characteristic 3::
1069
+
1070
+ sage: K = GF(3)
1071
+ sage: R.<x,y,z> = K[]
1072
+ sage: cubic = x^3 + y^3 + z^3 + x*y*z
1073
+ sage: EllipticCurve_from_cubic(cubic, [0,1,-1])
1074
+ Scheme morphism:
1075
+ From: Projective Plane Curve over Finite Field of size 3
1076
+ defined by x^3 + y^3 + x*y*z + z^3
1077
+ To: Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Finite Field of size 3
1078
+ Defn: Defined on coordinates by sending (x : y : z) to
1079
+ (y + z : -y : x)
1080
+
1081
+ An example over a number field, using a non-flex and where there are no rational flexes::
1082
+
1083
+ sage: # needs sage.rings.number_field
1084
+ sage: K.<a> = QuadraticField(-3)
1085
+ sage: R.<x,y,z> = K[]
1086
+ sage: cubic = 2*x^3 + 3*y^3 + 5*z^3
1087
+ sage: EllipticCurve_from_cubic(cubic, [1,1,-1])
1088
+ Scheme morphism:
1089
+ From: Projective Plane Curve over Number Field in a
1090
+ with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
1091
+ defined by 2*x^3 + 3*y^3 + 5*z^3
1092
+ To: Elliptic Curve defined by
1093
+ y^2 + 1754460/2053*x*y + 5226454388736000/8653002877*y
1094
+ = x^3 + (-652253285700/4214809)*x^2
1095
+ over Number Field in a with defining polynomial x^2 + 3
1096
+ with a = 1.732050807568878?*I
1097
+ Defn: Defined on coordinates by sending (x : y : z) to
1098
+ (-16424/127575*x^2 - 231989/680400*x*y - 14371/64800*y^2 - 26689/81648*x*z - 10265/27216*y*z - 2053/163296*z^2
1099
+ : 24496/315*x^2 + 119243/840*x*y + 4837/80*y^2 + 67259/504*x*z + 25507/168*y*z + 5135/1008*z^2
1100
+ : 8653002877/2099914709760000*x^2 + 8653002877/699971569920000*x*y + 8653002877/933295426560000*y^2 + 8653002877/419982941952000*x*z + 8653002877/279988627968000*y*z + 8653002877/335986353561600*z^2)
1101
+
1102
+ An example over a function field, using a non-flex::
1103
+
1104
+ sage: K.<t> = FunctionField(QQ)
1105
+ sage: R.<x,y,z> = K[]
1106
+ sage: cubic = x^3 + t*y^3 + (1+t)*z^3
1107
+ sage: EllipticCurve_from_cubic(cubic, [1,1,-1], morphism=False) # needs sage.libs.singular
1108
+ Elliptic Curve defined by y^2 + ((162*t^6+486*t^5+810*t^4+810*t^3+486*t^2+162*t)/(t^6+12*t^5-3*t^4-20*t^3-3*t^2+12*t+1))*x*y + ((314928*t^14+4094064*t^13+23462136*t^12+78102144*t^11+167561379*t^10+243026001*t^9+243026001*t^8+167561379*t^7+78102144*t^6+23462136*t^5+4094064*t^4+314928*t^3)/(t^14+40*t^13+577*t^12+3524*t^11+8075*t^10+5288*t^9-8661*t^8-17688*t^7-8661*t^6+5288*t^5+8075*t^4+3524*t^3+577*t^2+40*t+1))*y = x^3 + ((2187*t^12+13122*t^11-17496*t^10-207765*t^9-516132*t^8-673596*t^7-516132*t^6-207765*t^5-17496*t^4+13122*t^3+2187*t^2)/(t^12+24*t^11+138*t^10-112*t^9-477*t^8+72*t^7+708*t^6+72*t^5-477*t^4-112*t^3+138*t^2+24*t+1))*x^2
1109
+ over Rational function field in t over Rational Field
1110
+
1111
+ TESTS:
1112
+
1113
+ Here is a test for :issue:`21092`::
1114
+
1115
+ sage: R.<x,y,z> = QQ[]
1116
+ sage: cubic = -3*x^2*y + 3*x*y^2 + 4*x^2*z + 4*y^2*z - 3*x*z^2 + 3*y*z^2 - 8*z^3
1117
+ sage: EllipticCurve_from_cubic(cubic, (-4/5, 4/5, 3/5) )
1118
+ Scheme morphism:
1119
+ From: Projective Plane Curve over Rational Field defined
1120
+ by -3*x^2*y + 3*x*y^2 + 4*x^2*z + 4*y^2*z - 3*x*z^2 + 3*y*z^2 - 8*z^3
1121
+ To: Elliptic Curve defined by y^2 + 24*x*y + 3024*y = x^3 + 495*x^2 + 36288*x
1122
+ over Rational Field
1123
+ Defn: Defined on coordinates by sending (x : y : z) to
1124
+ (-1/3*z : 3*x : -1/1008*x + 1/1008*y + 1/378*z)
1125
+ """
1126
+ from sage.schemes.curves.constructor import Curve
1127
+ from sage.matrix.constructor import Matrix
1128
+ from sage.schemes.elliptic_curves.weierstrass_transform import \
1129
+ WeierstrassTransformationWithInverse
1130
+
1131
+ # check the input
1132
+ R = F.parent()
1133
+ K = R.base_ring()
1134
+ if not isinstance(R, MPolynomialRing_base):
1135
+ raise TypeError('equation must be a polynomial')
1136
+ if R.ngens() != 3 or F.nvariables() != 3:
1137
+ raise TypeError('equation must be a polynomial in three variables')
1138
+ if not F.is_homogeneous():
1139
+ raise TypeError('equation must be a homogeneous polynomial')
1140
+
1141
+ C = Curve(F)
1142
+ if P:
1143
+ try:
1144
+ CP = C(P)
1145
+ except (TypeError, ValueError):
1146
+ raise TypeError('{} does not define a point on a projective curve over {} defined by {}'.format(P,K,F))
1147
+
1148
+ x, y, z = R.gens()
1149
+
1150
+ # Test whether P is a flex; if not test whether there are any rational flexes:
1151
+
1152
+ hessian = Matrix([[F.derivative(v1, v2) for v1 in R.gens()] for v2 in R.gens()]).det()
1153
+ if P and hessian(P) == 0:
1154
+ flex_point = P
1155
+ else:
1156
+ flexes = C.intersection(Curve(hessian)).rational_points()
1157
+ if flexes:
1158
+ flex_point = list(flexes[0])
1159
+ if not P:
1160
+ P = flex_point
1161
+ CP = C(P)
1162
+ else:
1163
+ flex_point = None
1164
+
1165
+ if flex_point is not None: # first case: base point is a flex
1166
+ P = flex_point
1167
+ L = tangent_at_smooth_point(C,P)
1168
+ dx, dy, dz = (L.coefficient(v) for v in R.gens())
1169
+
1170
+ # find an invertible matrix M such that (0,1,0)M=P and
1171
+ # ML'=(0,0,1)' where L=[dx,dy,dx]. Then the linear transform
1172
+ # by M takes P to [0,1,0] and L to Z=0:
1173
+
1174
+ if P[0]:
1175
+ Q1 = [0,-dz,dy]
1176
+ Q2 = [0,1,0] if dy else [0,0,1]
1177
+ elif P[1]:
1178
+ Q1 = [dz,0,-dx]
1179
+ Q2 = [1,0,0] if dx else [0,0,1]
1180
+ else:
1181
+ Q1 = [-dy,dx,0]
1182
+ Q2 = [1,0,0] if dx else [0,1,0]
1183
+
1184
+ M = Matrix(K,[Q1,P,Q2])
1185
+ # assert M.is_invertible()
1186
+ # assert list(vector([0,1,0])*M) == P
1187
+ # assert list(M*vector([dx,dy,dz]))[:2] == [0,0]
1188
+
1189
+ M = M.transpose()
1190
+ F2 = R(M.act_on_polynomial(F))
1191
+
1192
+ # scale and dehomogenise
1193
+ a = K(F2.coefficient(x**3))
1194
+ b = K(F2.coefficient(y*y*z))
1195
+
1196
+ F3 = F2([-x, y/b, z*a*b]) / a
1197
+ # assert F3.coefficient(x**3) == -1
1198
+ # assert F3.coefficient(y*y*z) == 1
1199
+ E = EllipticCurve(F3([x,y,1]))
1200
+ if not morphism:
1201
+ return E
1202
+
1203
+ # Construct the (linear) morphism
1204
+ M = M * Matrix(K,[[-1,0,0],[0,1/b,0],[0,0,a*b]])
1205
+ inv_defining_poly = [ M[i,0]*x + M[i,1]*y + M[i,2]*z for i in range(3) ]
1206
+ inv_post = 1/a
1207
+ M = M.inverse()
1208
+ fwd_defining_poly = [ M[i,0]*x + M[i,1]*y + M[i,2]*z for i in range(3) ]
1209
+ fwd_post = a
1210
+
1211
+ else: # Second case: no flexes
1212
+ if not P:
1213
+ raise ValueError('A point must be given when the cubic has no rational flexes')
1214
+ L = tangent_at_smooth_point(C,P)
1215
+ Qlist = [Q for Q in C.intersection(Curve(L)).rational_points() if C(Q) != CP]
1216
+ # assert Qlist
1217
+ P2 = C(Qlist[0])
1218
+ L2 = tangent_at_smooth_point(C,P2)
1219
+ Qlist = [Q for Q in C.intersection(Curve(L2)).rational_points() if C(Q) != P2]
1220
+ # assert Qlist
1221
+ P3 = C(Qlist[0])
1222
+
1223
+ # NB This construction of P3 relies on P2 not being a flex.
1224
+ # If we want to use a non-flex as P when there are rational
1225
+ # flexes this would be a problem. However, the only condition
1226
+ # which P3 must satisfy is that it is on the tangent at P2, it
1227
+ # need not lie on the cubic.
1228
+
1229
+ # send P, P2, P3 to (1:0:0), (0:1:0), (0:0:1) respectively
1230
+ M = Matrix(K, [P, list(P2), list(P3)]).transpose()
1231
+ F2 = M.act_on_polynomial(F)
1232
+ xyzM = [ M[i,0]*x + M[i,1]*y + M[i,2]*z for i in range(3) ]
1233
+ # assert F(xyzM)==F2
1234
+
1235
+ # substitute x = U^2, y = V*W, z = U*W, and rename (x,y,z)=(U,V,W)
1236
+ T1 = [x*x,y*z,x*z]
1237
+ S1 = x**2*z
1238
+ F3 = F2(T1) // S1
1239
+ xyzC = [ t(T1) for t in xyzM ]
1240
+ # assert F3 == F(xyzC) // S1
1241
+
1242
+ # scale and dehomogenise
1243
+ a = K(F3.coefficient(x**3))
1244
+ b = K(F3.coefficient(y*y*z))
1245
+ ab = a*b
1246
+
1247
+ T2 = [-x, y/b, ab*z]
1248
+ F4 = F3(T2) / a
1249
+ # assert F4.coefficient(x**3) == -1
1250
+ # assert F4.coefficient(y*y*z) == 1
1251
+ xyzW = [ t(T2) for t in xyzC ]
1252
+ S2 = a*S1(T2)
1253
+ # assert F4 == F(xyzW) // S2
1254
+
1255
+ E = EllipticCurve(F4([x,y,1]))
1256
+ if not morphism:
1257
+ return E
1258
+
1259
+ inv_defining_poly = xyzW
1260
+ inv_post = 1/S2
1261
+ # assert F4==F(inv_defining_poly)*inv_post
1262
+ MI = M.inverse()
1263
+ xyzI = [ (MI[i,0]*x + MI[i,1]*y + MI[i,2]*z) for i in range(3) ]
1264
+ T1I = [x*z,x*y,z*z] # inverse of T1
1265
+ xyzIC = [ t(xyzI) for t in T1I ]
1266
+ T2I = [-x, b*y, z/ab] # inverse of T2
1267
+ xyzIW = [ t(xyzIC) for t in T2I ]
1268
+ fwd_defining_poly = xyzIW
1269
+ fwd_post = a/(x*z*z)(xyzI)
1270
+ # assert F4(fwd_defining_poly)*fwd_post == F
1271
+
1272
+ # Construct the morphism
1273
+
1274
+ return WeierstrassTransformationWithInverse(
1275
+ C, E, fwd_defining_poly, fwd_post, inv_defining_poly, inv_post)
1276
+
1277
+
1278
+ def tangent_at_smooth_point(C, P):
1279
+ r"""Return the tangent at the smooth point `P` of projective curve `C`.
1280
+
1281
+ INPUT:
1282
+
1283
+ - ``C`` -- a projective plane curve
1284
+
1285
+ - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on `C`
1286
+
1287
+ OUTPUT: the linear form defining the tangent at `P` to `C`
1288
+
1289
+ EXAMPLES::
1290
+
1291
+ sage: R.<x,y,z> = QQ[]
1292
+ sage: from sage.schemes.elliptic_curves.constructor import tangent_at_smooth_point
1293
+ sage: C = Curve(x^3 + y^3 + 60*z^3)
1294
+ sage: tangent_at_smooth_point(C, [1,-1,0])
1295
+ x + y
1296
+
1297
+ sage: K.<t> = FunctionField(QQ)
1298
+ sage: R.<x,y,z> = K[]
1299
+ sage: C = Curve(x^3 + 2*y^3 + 3*z^3)
1300
+ sage: from sage.schemes.elliptic_curves.constructor import tangent_at_smooth_point
1301
+ sage: tangent_at_smooth_point(C,[1,1,-1])
1302
+ 3*x + 6*y + 9*z
1303
+ """
1304
+ # Over function fields such as QQ(t) an error is raised with the
1305
+ # default (factor=True). Note that factor=False returns the
1306
+ # product of the tangents in case of a multiple point, while here
1307
+ # `P` is assumed smooth so factorization is unnecessary, but over
1308
+ # QQ (for example) including the factorization gives better
1309
+ # results, for example returning x+y instead of 3x+3y in the
1310
+ # doctest.
1311
+ try:
1312
+ return C.tangents(P)[0]
1313
+ except NotImplementedError:
1314
+ return C.tangents(P,factor=False)[0]
1315
+
1316
+
1317
+ def chord_and_tangent(F, P):
1318
+ r"""Return the third point of intersection of a cubic with the tangent at one point.
1319
+
1320
+ INPUT:
1321
+
1322
+ - ``F`` -- a homogeneous cubic in three variables with rational
1323
+ coefficients, as a polynomial ring element, defining a smooth
1324
+ plane cubic curve.
1325
+
1326
+ - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on the
1327
+ curve `F=0`
1328
+
1329
+ OUTPUT:
1330
+
1331
+ A point ``Q`` such that ``F(Q)=0``, namely the third point of
1332
+ intersection of the tangent at ``P`` with the curve ``F=0``, so
1333
+ ``Q=P`` if and only if ``P`` is a flex.
1334
+
1335
+ EXAMPLES::
1336
+
1337
+ sage: R.<x,y,z> = QQ[]
1338
+ sage: from sage.schemes.elliptic_curves.constructor import chord_and_tangent
1339
+ sage: F = x^3 + y^3 + 60*z^3
1340
+ sage: chord_and_tangent(F, [1,-1,0])
1341
+ (-1 : 1 : 0)
1342
+
1343
+ sage: F = x^3 + 7*y^3 + 64*z^3
1344
+ sage: p0 = [2,2,-1]
1345
+ sage: p1 = chord_and_tangent(F, p0); p1
1346
+ (5 : -3 : 1)
1347
+ sage: p2 = chord_and_tangent(F, p1); p2
1348
+ (-1265/314 : 183/314 : 1)
1349
+
1350
+ TESTS::
1351
+
1352
+ sage: F(list(p2))
1353
+ 0
1354
+ sage: list(map(type, p2))
1355
+ [<... 'sage.rings.rational.Rational'>,
1356
+ <... 'sage.rings.rational.Rational'>,
1357
+ <... 'sage.rings.rational.Rational'>]
1358
+
1359
+ See :issue:`16068`::
1360
+
1361
+ sage: F = x**3 - 4*x**2*y - 65*x*y**2 + 3*x*y*z - 76*y*z**2
1362
+ sage: chord_and_tangent(F, [0, 1, 0])
1363
+ (0 : 0 : 1)
1364
+ """
1365
+ from sage.schemes.curves.constructor import Curve
1366
+ # check the input
1367
+ R = F.parent()
1368
+ if not isinstance(R, MPolynomialRing_base):
1369
+ raise TypeError('equation must be a polynomial')
1370
+ if R.ngens() != 3:
1371
+ raise TypeError('{} is not a polynomial in three variables'.format(F))
1372
+ if not F.is_homogeneous():
1373
+ raise TypeError('{} is not a homogeneous polynomial'.format(F))
1374
+ x, y, z = R.gens()
1375
+ if len(P) != 3:
1376
+ raise TypeError('{} is not a projective point'.format(P))
1377
+ K = R.base_ring()
1378
+ try:
1379
+ C = Curve(F)
1380
+ P = C(P)
1381
+ except (TypeError, ValueError):
1382
+ raise TypeError('{} does not define a point on a projective curve over {} defined by {}'.format(P,K,F))
1383
+
1384
+ L = Curve(tangent_at_smooth_point(C,P))
1385
+ Qlist = [Q for Q in C.intersection(L).rational_points() if Q != P]
1386
+ if Qlist:
1387
+ return Qlist[0]
1388
+ return P
1389
+
1390
+
1391
+ def projective_point(p):
1392
+ r"""
1393
+ Return equivalent point with denominators removed.
1394
+
1395
+ INPUT:
1396
+
1397
+ - ``P``, ``Q`` -- list/tuple of projective coordinates
1398
+
1399
+ OUTPUT: list of projective coordinates
1400
+
1401
+ EXAMPLES::
1402
+
1403
+ sage: from sage.schemes.elliptic_curves.constructor import projective_point
1404
+ sage: projective_point([4/5, 6/5, 8/5])
1405
+ [2, 3, 4]
1406
+ sage: F = GF(11)
1407
+ sage: projective_point([F(4), F(8), F(2)])
1408
+ [4, 8, 2]
1409
+ """
1410
+ from sage.rings.integer import GCD_list
1411
+ from sage.arith.functions import LCM_list
1412
+ try:
1413
+ p_gcd = GCD_list([x.numerator() for x in p])
1414
+ p_lcm = LCM_list(x.denominator() for x in p)
1415
+ except AttributeError:
1416
+ return p
1417
+ scale = p_lcm / p_gcd
1418
+ return [scale * x for x in p]
1419
+
1420
+
1421
+ def are_projectively_equivalent(P, Q, base_ring):
1422
+ r"""
1423
+ Test whether ``P`` and ``Q`` are projectively equivalent.
1424
+
1425
+ INPUT:
1426
+
1427
+ - ``P``, ``Q`` -- list/tuple of projective coordinates
1428
+
1429
+ - ``base_ring`` -- the base ring
1430
+
1431
+ OUTPUT: boolean
1432
+
1433
+ EXAMPLES::
1434
+
1435
+ sage: from sage.schemes.elliptic_curves.constructor import are_projectively_equivalent
1436
+ sage: are_projectively_equivalent([0,1,2,3], [0,1,2,2], base_ring=QQ)
1437
+ False
1438
+ sage: are_projectively_equivalent([0,1,2,3], [0,2,4,6], base_ring=QQ)
1439
+ True
1440
+ """
1441
+ from sage.matrix.constructor import matrix
1442
+ return matrix(base_ring, [P, Q]).rank() < 2
1443
+
1444
+
1445
+ def EllipticCurves_with_good_reduction_outside_S(S=[], proof=None, verbose=False):
1446
+ r"""
1447
+ Return a sorted list of all elliptic curves defined over `\QQ`
1448
+ with good reduction outside the set `S` of primes.
1449
+
1450
+ INPUT:
1451
+
1452
+ - ``S`` -- list of primes (default: empty list)
1453
+
1454
+ - ``proof`` -- boolean (default: ``True``); the MW basis for
1455
+ auxiliary curves will be computed with this proof flag
1456
+
1457
+ - ``verbose`` -- boolean (default: ``False``); if ``True``, some details
1458
+ of the computation will be output
1459
+
1460
+ .. NOTE::
1461
+
1462
+ Proof flag: The algorithm used requires determining all
1463
+ S-integral points on several auxiliary curves, which in turn
1464
+ requires the computation of their generators. This is not
1465
+ always possible (even in theory) using current knowledge.
1466
+
1467
+ The value of this flag is passed to the function which
1468
+ computes generators of various auxiliary elliptic curves, in
1469
+ order to find their S-integral points. Set to ``False`` if the
1470
+ default (``True``) causes warning messages, but note that you can
1471
+ then not rely on the set of curves returned being
1472
+ complete.
1473
+
1474
+ EXAMPLES::
1475
+
1476
+ sage: # needs eclib sage.symbolic
1477
+ sage: EllipticCurves_with_good_reduction_outside_S([])
1478
+ []
1479
+ sage: elist = EllipticCurves_with_good_reduction_outside_S([2])
1480
+ sage: elist
1481
+ [Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field,
1482
+ Elliptic Curve defined by y^2 = x^3 - x over Rational Field,
1483
+ ...
1484
+ Elliptic Curve defined by y^2 = x^3 - x^2 - 13*x + 21 over Rational Field]
1485
+ sage: len(elist)
1486
+ 24
1487
+ sage: ', '.join(e.label() for e in elist)
1488
+ '32a1, 32a2, 32a3, 32a4, 64a1, 64a2, 64a3, 64a4, 128a1, 128a2, 128b1, 128b2, 128c1, 128c2, 128d1, 128d2, 256a1, 256a2, 256b1, 256b2, 256c1, 256c2, 256d1, 256d2'
1489
+
1490
+ Without ``Proof=False``, this example gives two warnings::
1491
+
1492
+ sage: # needs eclib sage.symbolic
1493
+ sage: elist = EllipticCurves_with_good_reduction_outside_S([11], proof=False) # long time (14s on sage.math, 2011)
1494
+ sage: len(elist) # long time
1495
+ 12
1496
+ sage: ', '.join(e.label() for e in elist) # long time
1497
+ '11a1, 11a2, 11a3, 121a1, 121a2, 121b1, 121b2, 121c1, 121c2, 121d1, 121d2, 121d3'
1498
+
1499
+ sage: # long time, needs eclib sage.symbolic
1500
+ sage: elist = EllipticCurves_with_good_reduction_outside_S([2,3]) # long time (26s on sage.math, 2011)
1501
+ sage: len(elist)
1502
+ 752
1503
+ sage: conds = sorted(set([e.conductor() for e in elist]))
1504
+ sage: max(conds)
1505
+ 62208
1506
+ sage: [N.factor() for N in conds]
1507
+ [2^3 * 3,
1508
+ 3^3,
1509
+ 2^5,
1510
+ 2^2 * 3^2,
1511
+ 2^4 * 3,
1512
+ 2 * 3^3,
1513
+ 2^6,
1514
+ 2^3 * 3^2,
1515
+ 2^5 * 3,
1516
+ 2^2 * 3^3,
1517
+ 2^7,
1518
+ 2^4 * 3^2,
1519
+ 2 * 3^4,
1520
+ 2^6 * 3,
1521
+ 2^3 * 3^3,
1522
+ 3^5,
1523
+ 2^8,
1524
+ 2^5 * 3^2,
1525
+ 2^2 * 3^4,
1526
+ 2^7 * 3,
1527
+ 2^4 * 3^3,
1528
+ 2 * 3^5,
1529
+ 2^6 * 3^2,
1530
+ 2^3 * 3^4,
1531
+ 2^8 * 3,
1532
+ 2^5 * 3^3,
1533
+ 2^2 * 3^5,
1534
+ 2^7 * 3^2,
1535
+ 2^4 * 3^4,
1536
+ 2^6 * 3^3,
1537
+ 2^3 * 3^5,
1538
+ 2^8 * 3^2,
1539
+ 2^5 * 3^4,
1540
+ 2^7 * 3^3,
1541
+ 2^4 * 3^5,
1542
+ 2^6 * 3^4,
1543
+ 2^8 * 3^3,
1544
+ 2^5 * 3^5,
1545
+ 2^7 * 3^4,
1546
+ 2^6 * 3^5,
1547
+ 2^8 * 3^4,
1548
+ 2^7 * 3^5,
1549
+ 2^8 * 3^5]
1550
+ """
1551
+ from .ell_egros import egros_from_jlist, egros_get_j
1552
+ return egros_from_jlist(egros_get_j(S, proof=proof, verbose=verbose), S)