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,1014 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ r"""
3
+ Global and semi-global minimal models for elliptic curves over number fields
4
+
5
+ When `E` is an elliptic curve defined over a number field `K` of class
6
+ number 1, then it has a global minimal model, and we have a method to
7
+ compute it, namely ``E.global_minimal_model()``. Until Sage-6.7 this was
8
+ done using Tate's algorithm to minimise one prime at a time without
9
+ affecting the other primes. When the class number is not 1, a
10
+ different approach is used.
11
+
12
+ In the general case global minimal models may or may not exist. This
13
+ module includes functions to determine this, and to find a global
14
+ minimal model when it does exist. The obstruction to the existence of
15
+ a global minimal model is encoded in an ideal class, which is trivial
16
+ if and only if a global minimal model exists: we provide a function
17
+ which returns this class. When the obstruction is not trivial, there
18
+ exist models which are minimal at all primes except at a single prime
19
+ in the obstruction class, where the discriminant valuation is 12 more
20
+ than the minimal valuation at that prime; we provide a function to
21
+ return such a model.
22
+
23
+ The implementation of this functionality is based on work of Kraus
24
+ [Kra1989]_ which gives a local condition for when a pair of number field
25
+ elements `c_4`, `c_6` belong to a Weierstrass model which is
26
+ integral at a prime `P`, together with a global version. Only primes
27
+ dividing 2 or 3 are hard to deal with. In order to compute the
28
+ corresponding integral model one then needs to combine together the
29
+ local transformations implicit in [Kra1989]_ into a single global one.
30
+
31
+ Various utility functions relating to the testing and use of Kraus's
32
+ conditions are included here.
33
+
34
+ AUTHORS:
35
+
36
+ - John Cremona (2015)
37
+ """
38
+
39
+ ##############################################################################
40
+ # Copyright (C) 2012-2014 John Cremona <john.cremona@gmail.com>
41
+ # William Stein <wstein@gmail.com>
42
+ #
43
+ # Distributed under the terms of the GNU General Public License (GPL)
44
+ #
45
+ # This code is distributed in the hope that it will be useful,
46
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48
+ # General Public License for more details.
49
+ #
50
+ # The full text of the GPL is available at:
51
+ #
52
+ # https://www.gnu.org/licenses/
53
+ ##############################################################################
54
+
55
+ from sage.schemes.elliptic_curves.constructor import EllipticCurve
56
+
57
+
58
+ def c4c6_nonsingular(c4, c6):
59
+ r"""
60
+ Check if `c_4`, `c_6` are integral with valid associated discriminant.
61
+
62
+ INPUT:
63
+
64
+ - ``c4``, ``c6`` -- elements of a number field
65
+
66
+ OUTPUT:
67
+
68
+ Boolean, ``True`` if `c_4`, `c_6` are both integral and `c_4^3-c_6^2` is a
69
+ nonzero multiple of 1728.
70
+
71
+ EXAMPLES:
72
+
73
+ Over `\QQ`::
74
+
75
+ sage: from sage.schemes.elliptic_curves.kraus import c4c6_nonsingular
76
+ sage: c4c6_nonsingular(0,0)
77
+ False
78
+ sage: c4c6_nonsingular(0,1/2)
79
+ False
80
+ sage: c4c6_nonsingular(2,3)
81
+ False
82
+ sage: c4c6_nonsingular(4,8)
83
+ False
84
+ sage: all(c4c6_nonsingular(*E.c_invariants()) for E in cremona_curves([ 11..100]))
85
+ True
86
+
87
+ Over number fields::
88
+
89
+ sage: # needs sage.rings.number_field
90
+ sage: x = polygen(ZZ, 'x')
91
+ sage: K.<a> = NumberField(x^2 - 10)
92
+ sage: c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
93
+ True
94
+ sage: K.<a> = NumberField(x^3 - 10)
95
+ sage: c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
96
+ True
97
+ """
98
+ if not (c4.is_integral() and c6.is_integral()):
99
+ return False
100
+ D = (c4**3-c6**2)/1728
101
+ return not D.is_zero() and D.is_integral()
102
+
103
+
104
+ def c4c6_model(c4, c6, assume_nonsingular=False):
105
+ r"""
106
+ Return the elliptic curve [0,0,0,-c4/48,-c6/864] with given c-invariants.
107
+
108
+ INPUT:
109
+
110
+ - ``c4``, ``c6`` -- elements of a number field
111
+
112
+ - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
113
+ check for integrality and nosingularity
114
+
115
+ OUTPUT:
116
+
117
+ The elliptic curve with a-invariants `[0,0,0,-c_4/48,-c_6/864]`, whose
118
+ c-invariants are the given `c_4`, `c_6`. If the supplied invariants are
119
+ singular, returns ``None`` when ``assume_nonsingular`` is ``False`` and
120
+ raises an :exc:`ArithmeticError` otherwise.
121
+
122
+ EXAMPLES::
123
+
124
+ sage: from sage.schemes.elliptic_curves.kraus import c4c6_model
125
+ sage: x = polygen(ZZ, 'x')
126
+ sage: K.<a> = NumberField(x^3 - 10) # needs sage.rings.number_field
127
+ sage: c4c6_model(-217728*a - 679104, 141460992*a + 409826304) # needs sage.rings.number_field
128
+ Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
129
+ over Number Field in a with defining polynomial x^3 - 10
130
+
131
+ sage: c4, c6 = EllipticCurve('389a1').c_invariants()
132
+ sage: c4c6_model(c4,c6)
133
+ Elliptic Curve defined by y^2 = x^3 - 7/3*x + 107/108 over Rational Field
134
+ """
135
+ if not assume_nonsingular:
136
+ if not c4c6_nonsingular(c4,c6):
137
+ return None
138
+ return EllipticCurve([0,0,0,-c4/48,-c6/864])
139
+
140
+ # Arithmetic utility functions
141
+
142
+
143
+ def make_integral(a, P, e):
144
+ r"""
145
+ Return `b` in `O_K` with `P^e|(a-b)`, given `a` in `O_{K,P}`.
146
+
147
+ INPUT:
148
+
149
+ - ``a`` -- a number field element integral at `P`
150
+
151
+ - ``P`` -- a prime ideal of the number field
152
+
153
+ - ``e`` -- positive integer
154
+
155
+ OUTPUT:
156
+
157
+ A globally integral number field element `b` which is congruent to
158
+ `a` modulo `P^e`.
159
+
160
+ ALGORITHM:
161
+
162
+ Totally naive, we simply test residues modulo `P^e` until one
163
+ works. We will only use this when `P` is a prime dividing 2 and `e`
164
+ is the ramification degree, so the number of residues to check is
165
+ at worst `2^d` where `d` is the degree of the field.
166
+
167
+ EXAMPLES::
168
+
169
+ sage: from sage.schemes.elliptic_curves.kraus import make_integral
170
+
171
+ sage: # needs sage.rings.number_field
172
+ sage: x = polygen(ZZ, 'x')
173
+ sage: K.<a> = NumberField(x^2 - 10)
174
+ sage: P = K.primes_above(2)[0]
175
+ sage: e = P.ramification_index(); e
176
+ 2
177
+ sage: x = 1/5
178
+ sage: b = make_integral(x, P, e); b
179
+ 1
180
+ sage: (b-x).valuation(P) >= e
181
+ True
182
+ sage: make_integral(1/a, P, e)
183
+ Traceback (most recent call last):
184
+ ...
185
+ ArithmeticError: Cannot lift 1/10*a to O_K mod (Fractional ideal (2, a))^2
186
+ """
187
+ for b in (P**e).residues():
188
+ if (a-b).valuation(P) >= e:
189
+ return b
190
+ raise ArithmeticError("Cannot lift %s to O_K mod (%s)^%s" % (a, P, e))
191
+
192
+
193
+ def sqrt_mod_4(x, P):
194
+ r"""
195
+ Return a local square root mod 4, if it exists.
196
+
197
+ INPUT:
198
+
199
+ - ``x`` -- an integral number field element
200
+
201
+ - ``P`` -- a prime ideal of the number field dividing 2
202
+
203
+ OUTPUT:
204
+
205
+ A pair ``(True, r)`` where that `r^2-x` has valuation at least `2e`,
206
+ or ``(False, 0)`` if there is no such `r`. Note that
207
+ `r^2\mod{P^{2e}}` only depends on `r\mod{P^e}`.
208
+
209
+ EXAMPLES::
210
+
211
+ sage: # needs sage.rings.number_field
212
+ sage: from sage.schemes.elliptic_curves.kraus import sqrt_mod_4
213
+ sage: x = polygen(ZZ, 'x')
214
+ sage: K.<a> = NumberField(x^2 - 10)
215
+ sage: P = K.primes_above(2)[0]
216
+ sage: sqrt_mod_4(1 + 2*a, P)
217
+ (False, 0)
218
+ sage: sqrt_mod_4(-1 + 2*a, P)
219
+ (True, a + 1)
220
+ sage: (1+a)^2 - (-1 + 2*a)
221
+ 12
222
+ sage: e = P.ramification_index()
223
+ sage: ((1+a)^2 - (-1+2*a)).mod(P**e)
224
+ 0
225
+ """
226
+ e = P.ramification_index()
227
+ P2 = P**e
228
+ for r in P2.residues():
229
+ if (r*r-x).valuation(P) >= 2*e:
230
+ return True, r
231
+ return False, 0
232
+
233
+ # Kraus test and check for primes dividing 3:
234
+
235
+
236
+ def test_b2_local(c4, c6, P, b2, debug=False):
237
+ r"""
238
+ Test if `b_2` gives a valid model at a prime dividing 3.
239
+
240
+ INPUT:
241
+
242
+ - ``c4``, ``c6`` -- elements of a number field
243
+
244
+ - ``P`` -- a prime ideal of the number field which divides 3
245
+
246
+ - ``b2`` -- an element of the number field
247
+
248
+ OUTPUT:
249
+
250
+ The elliptic curve which is the `(b_2/12,0,0)`-transform of
251
+ `[0,0,0,-c_4/48,-c_6/864]` if this is integral at `P`, else ``False``.
252
+
253
+ EXAMPLES::
254
+
255
+ sage: # needs sage.rings.number_field
256
+ sage: x = polygen(ZZ, 'x')
257
+ sage: K.<a> = NumberField(x^2 - 10)
258
+ sage: c4 = -60544*a + 385796
259
+ sage: c6 = -55799680*a + 262126328
260
+ sage: P3a, P3b = K.primes_above(3)
261
+ sage: from sage.schemes.elliptic_curves.kraus import test_b2_local
262
+
263
+ `b_2=0` works at the first prime but not the second::
264
+
265
+ sage: b2 = 0
266
+ sage: test_b2_local(c4,c6,P3a,b2) # needs sage.rings.number_field
267
+ Elliptic Curve defined by
268
+ y^2 = x^3 + (3784/3*a-96449/12)*x + (1743740/27*a-32765791/108)
269
+ over Number Field in a with defining polynomial x^2 - 10
270
+ sage: test_b2_local(c4,c6,P3b,b2) # needs sage.rings.number_field
271
+ False
272
+
273
+ `b_2=-a` works at the second prime but not the first::
274
+
275
+ sage: b2 = -a # needs sage.rings.number_field
276
+ sage: test_b2_local(c4,c6,P3a,b2,debug=True) # needs sage.rings.number_field
277
+ test_b2_local: not integral at Fractional ideal (3, a + 1)
278
+ False
279
+ sage: test_b2_local(c4,c6,P3b,b2) # needs sage.rings.number_field
280
+ Elliptic Curve defined by
281
+ y^2 = x^3 + (-1/4*a)*x^2 + (3784/3*a-192893/24)*x + (56378369/864*a-32879311/108)
282
+ over Number Field in a with defining polynomial x^2 - 10
283
+
284
+ Using CRT we can do both with the same `b_2`::
285
+
286
+ sage: b2 = K.solve_CRT([0,-a],[P3a,P3b]); b2 # needs sage.rings.number_field
287
+ a + 1
288
+ sage: test_b2_local(c4,c6,P3a,b2) # needs sage.rings.number_field
289
+ Elliptic Curve defined by
290
+ y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
291
+ over Number Field in a with defining polynomial x^2 - 10
292
+ sage: test_b2_local(c4,c6,P3b,b2) # needs sage.rings.number_field
293
+ Elliptic Curve defined
294
+ by y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
295
+ over Number Field in a with defining polynomial x^2 - 10
296
+ """
297
+ E = c4c6_model(c4,c6).rst_transform(b2/12,0,0)
298
+ if not (c4,c6) == E.c_invariants():
299
+ if debug:
300
+ print("test_b2_local: wrong c-invariants at P=%s" % P)
301
+ return False
302
+ if not E.is_local_integral_model(P):
303
+ if debug:
304
+ print("test_b2_local: not integral at %s" % P)
305
+ return False
306
+ return E
307
+
308
+
309
+ def test_b2_global(c4, c6, b2, debug=False):
310
+ r"""
311
+ Test if `b_2` gives a valid model at all primes dividing 3.
312
+
313
+ INPUT:
314
+
315
+ - ``c4``, ``c6`` -- elements of a number field
316
+
317
+ - ``b2`` -- an element of the number field
318
+
319
+ OUTPUT:
320
+
321
+ The elliptic curve which is the `(b_2/12,0,0)`-transform of
322
+ `[0,0,0,-c_4/48,-c_6/864]` if this is integral at all primes `P`
323
+ dividing 3, else ``False``.
324
+
325
+ EXAMPLES::
326
+
327
+ sage: # needs sage.rings.number_field
328
+ sage: x = polygen(ZZ, 'x')
329
+ sage: K.<a> = NumberField(x^2 - 10)
330
+ sage: c4 = -60544*a + 385796
331
+ sage: c6 = -55799680*a + 262126328
332
+ sage: b2 = a+1
333
+ sage: from sage.schemes.elliptic_curves.kraus import test_b2_global
334
+ sage: test_b2_global(c4,c6,b2)
335
+ Elliptic Curve defined by
336
+ y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
337
+ over Number Field in a with defining polynomial x^2 - 10
338
+ sage: test_b2_global(c4,c6,0,debug=True)
339
+ test_b2_global: not integral at all primes dividing 3
340
+ False
341
+ sage: test_b2_global(c4,c6,-a,debug=True)
342
+ test_b2_global: not integral at all primes dividing 3
343
+ False
344
+ """
345
+ E = c4c6_model(c4,c6).rst_transform(b2/12,0,0)
346
+ if not (c4,c6) == E.c_invariants():
347
+ if debug:
348
+ print("test_b2_global: wrong c-invariants")
349
+ return False
350
+ if not all(E.is_local_integral_model(P)
351
+ for P in c4.parent().primes_above(3)):
352
+ if debug:
353
+ print("test_b2_global: not integral at all primes dividing 3")
354
+ return False
355
+ return E
356
+
357
+
358
+ def check_Kraus_local_3(c4, c6, P, assume_nonsingular=False, debug=False):
359
+ r"""
360
+ Test if `c_4`, `c_6` satisfy Kraus's conditions at a prime `P` dividing 3.
361
+
362
+ INPUT:
363
+
364
+ - ``c4``, ``c6`` -- elements of a number field
365
+
366
+ - ``P`` -- a prime ideal of the number field which divides 3
367
+
368
+ - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
369
+ check for integrality and nosingularity
370
+
371
+ OUTPUT:
372
+
373
+ Either ``(False, 0)`` if Kraus's conditions fail, or ``(True, b2)`` if
374
+ they pass, in which case the elliptic curve which is the
375
+ `(b_2/12,0,0)`-transform of `[0,0,0,-c_4/48,-c_6/864]` is integral at `P`.
376
+
377
+ EXAMPLES::
378
+
379
+ sage: # needs sage.rings.number_field
380
+ sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local_3
381
+ sage: x = polygen(ZZ, 'x')
382
+ sage: K.<a> = NumberField(x^2 - 10)
383
+ sage: c4 = -60544*a + 385796
384
+ sage: c6 = -55799680*a + 262126328
385
+ sage: P3a, P3b = K.primes_above(3)
386
+ sage: check_Kraus_local_3(c4,c6,P3a)
387
+ (True, 0)
388
+ sage: check_Kraus_local_3(c4,c6,P3b)
389
+ (True, -a)
390
+
391
+ An example in a field where 3 is ramified::
392
+
393
+ sage: # needs sage.rings.number_field
394
+ sage: K.<a> = NumberField(x^2 - 15)
395
+ sage: c4 = -60504*a + 386001
396
+ sage: c6 = -55346820*a + 261045153
397
+ sage: P3 = K.primes_above(3)[0]
398
+ sage: check_Kraus_local_3(c4,c6,P3)
399
+ (True, a)
400
+ """
401
+ if not assume_nonsingular:
402
+ if not c4c6_nonsingular(c4,c6):
403
+ return False, 0
404
+ e = P.ramification_index()
405
+ P3 = P**e
406
+ if c4.valuation(P) == 0:
407
+ b2 = (-c6*c4.inverse_mod(P3)).mod(P3)
408
+ if debug:
409
+ assert test_b2_local(c4,c6,P,b2)
410
+ return True, b2
411
+ if c6.valuation(P) >= 3*e:
412
+ b2 = c6.parent().zero()
413
+ if debug:
414
+ assert test_b2_local(c4,c6,P,b2)
415
+ return True, b2
416
+ # check for a solution x to x^3-3*x*c4-26=0 (27), such an x must
417
+ # also satisfy x*c4+c6=0 (3) and x^2=c4 (3) and x^3=-c6 (9), and
418
+ # if x is a solution then so is any x'=x (3) so it is enough to
419
+ # check residues mod 3.
420
+ for x in P3.residues():
421
+ if (x*c4+c6).valuation(P) >= e:
422
+ if (x*(x*x-3*c4)-2*c6).valuation(P) >= 3*e:
423
+ if debug:
424
+ assert test_b2_local(c4,c6,P,x)
425
+ return True, x
426
+ return False, 0
427
+
428
+ # Kraus test and check for primes dividing 2:
429
+
430
+
431
+ def test_a1a3_local(c4, c6, P, a1, a3, debug=False):
432
+ r"""
433
+ Test if `a_1`, `a_3` are valid at a prime `P` dividing `2`.
434
+
435
+ INPUT:
436
+
437
+ - ``c4``, ``c6`` -- elements of a number field
438
+
439
+ - ``P`` -- a prime ideal of the number field which divides 2
440
+
441
+ - ``a1``, ``a3`` -- elements of the number field
442
+
443
+ OUTPUT:
444
+
445
+ The elliptic curve which is the `(a_1^2/12,a_1/2,a_3/2)`-transform of
446
+ `[0,0,0,-c_4/48,-c_6/864]` if this is integral at `P`, else ``False``.
447
+
448
+ EXAMPLES::
449
+
450
+ sage: # needs sage.rings.number_field
451
+ sage: from sage.schemes.elliptic_curves.kraus import test_a1a3_local
452
+ sage: x = polygen(ZZ, 'x')
453
+ sage: K.<a> = NumberField(x^2 - 10)
454
+ sage: c4 = -60544*a + 385796
455
+ sage: c6 = -55799680*a + 262126328
456
+ sage: P = K.primes_above(2)[0]
457
+ sage: test_a1a3_local(c4,c6,P,a,0)
458
+ Elliptic Curve defined by
459
+ y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
460
+ over Number Field in a with defining polynomial x^2 - 10
461
+ sage: test_a1a3_local(c4,c6,P,a,a,debug=True)
462
+ test_a1a3_local: not integral at Fractional ideal (2, a)
463
+ False
464
+ """
465
+ E = c4c6_model(c4,c6).rst_transform(a1**2/12,a1/2,a3/2)
466
+ if not (c4,c6) == E.c_invariants():
467
+ if debug:
468
+ print("test_a1a3_local: wrong c-invariants at P=%s" % P)
469
+ return False
470
+ if not E.is_local_integral_model(P):
471
+ if debug:
472
+ print("test_a1a3_local: not integral at %s" % P)
473
+ return False
474
+ return E
475
+
476
+
477
+ def test_a1a3_global(c4, c6, a1, a3, debug=False):
478
+ r"""
479
+ Test if `a_1`, `a_3` are valid at all primes `P` dividing 2.
480
+
481
+ INPUT:
482
+
483
+ - ``c4``, ``c6`` -- elements of a number field
484
+
485
+ - ``a1``, ``a3`` -- elements of the number field
486
+
487
+ OUTPUT:
488
+
489
+ The elliptic curve which is the `(a_1^2/12,a_1/2,a_3/2)`-transform of
490
+ `[0,0,0,-c_4/48,-c_6/864]` if this is integral at all primes `P`
491
+ dividing 2, else ``False``.
492
+
493
+ EXAMPLES::
494
+
495
+ sage: # needs sage.rings.number_field
496
+ sage: from sage.schemes.elliptic_curves.kraus import test_a1a3_global
497
+ sage: x = polygen(ZZ, 'x')
498
+ sage: K.<a> = NumberField(x^2 - 10)
499
+ sage: c4 = -60544*a + 385796
500
+ sage: c6 = -55799680*a + 262126328
501
+ sage: test_a1a3_global(c4,c6,a,a,debug=False)
502
+ False
503
+ sage: test_a1a3_global(c4,c6,a,0)
504
+ Elliptic Curve defined by
505
+ y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
506
+ over Number Field in a with defining polynomial x^2 - 10
507
+ """
508
+ E = c4c6_model(c4,c6).rst_transform(a1**2/12,a1/2,a3/2)
509
+ if not (c4, c6) == E.c_invariants():
510
+ if debug:
511
+ print("wrong c-invariants")
512
+ return False
513
+ if not all(E.is_local_integral_model(P)
514
+ for P in c4.parent().primes_above(2)):
515
+ if debug:
516
+ print("not integral at all primes above 2")
517
+ return False
518
+ return E
519
+
520
+
521
+ def test_rst_global(c4, c6, r, s, t, debug=False):
522
+ r"""
523
+ Test if the `(r,s,t)`-transform of the standard `c_4,c_6`-model is integral.
524
+
525
+ INPUT:
526
+
527
+ - ``c4``, ``c6`` -- elements of a number field
528
+
529
+ - ``r``, ``s``, ``t`` -- elements of the number field
530
+
531
+ OUTPUT:
532
+
533
+ The elliptic curve which is the `(r,s,t)`-transform of
534
+ `[0,0,0,-c_4/48,-c_6/864]` if this is integral at all primes `P`, else
535
+ ``False``.
536
+
537
+ EXAMPLES::
538
+
539
+ sage: # needs sage.rings.number_field
540
+ sage: from sage.schemes.elliptic_curves.kraus import test_rst_global
541
+ sage: x = polygen(ZZ, 'x')
542
+ sage: K.<a> = NumberField(x^2-10)
543
+ sage: c4 = -60544*a + 385796
544
+ sage: c6 = -55799680*a + 262126328
545
+ sage: test_rst_global(c4,c6,1/3*a - 133/6, 3/2*a, -89/2*a + 5)
546
+ Elliptic Curve defined by
547
+ y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
548
+ over Number Field in a with defining polynomial x^2 - 10
549
+ sage: test_rst_global(c4,c6,a, 3, -89*a, debug=False)
550
+ False
551
+ """
552
+ E = c4c6_model(c4,c6).rst_transform(r,s,t)
553
+ if not (c4,c6) == E.c_invariants():
554
+ if debug:
555
+ print("test_rst_global: wrong c-invariants")
556
+ return False
557
+ if not E.is_global_integral_model():
558
+ if debug:
559
+ print("test_rst_global: not integral at some prime")
560
+ print(E.ainvs())
561
+ K = E.base_field()
562
+ for P in K.primes_above(2)+K.primes_above(3):
563
+ if not E.is_local_integral_model(P):
564
+ print(" -- not integral at P=%s" % P)
565
+ return False
566
+ return E
567
+
568
+ # When a1 is None this function finds a pair a1, a3 such that there is
569
+ # a model with these invariants and a2=0 with the given c4, c6,
570
+ # integral at P. The value of a1 is unique modulo 2 (i.e. mod P^e
571
+ # where e is the ramification degree of 2); the value of a3 is unique
572
+ # mod 2 once a1 is fixed, but not otherwise: when a1 is replaced by
573
+ # a1+2s we must replace a3 by a3 + a1*s*(a1+s).
574
+
575
+ # Because of the latter point, and to fix the bug at #19665, we allow
576
+ # the user to specify a1, in which case a3 is computed from it. This
577
+ # is important in the global application where we need to put together
578
+ # the transforms for all the primes above 2: we must first get the
579
+ # local a1's, then CRT these to get a global a1, then go back to get
580
+ # the local a3's and finally CRT these.
581
+
582
+
583
+ def check_Kraus_local_2(c4, c6, P, a1=None, assume_nonsingular=False):
584
+ r"""
585
+ Test if `c_4`, `c_6` satisfy Kraus's conditions at a prime `P` dividing 2.
586
+
587
+ INPUT:
588
+
589
+ - ``c4``, ``c6`` -- integral elements of a number field
590
+
591
+ - ``P`` -- a prime ideal of the number field which divides 2
592
+
593
+ - ``a1`` -- an integral elements of a number field, or ``None`` (default)
594
+
595
+ - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
596
+ check for integrality and nonsingularity
597
+
598
+ OUTPUT:
599
+
600
+ Either ``(False, 0, 0)`` if Kraus's conditions fail, or ``(True, a1,
601
+ a3)`` if they pass, in which case the elliptic curve which is the
602
+ `(a_1^2/12,a_1/2,a_3/2)`-transform of `[0,0,0,-c_4/48,-c_6/864]` is
603
+ integral at `P`. If `a_1` is provided and valid then the output will
604
+ be ``(True, a1, a3)`` for suitable `a_3`.
605
+
606
+ EXAMPLES::
607
+
608
+ sage: # needs sage.rings.number_field
609
+ sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local_2
610
+ sage: x = polygen(ZZ, 'x')
611
+ sage: K.<a> = NumberField(x^2 - 10)
612
+ sage: c4 = -60544*a + 385796 # EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
613
+ sage: c6 = -55799680*a + 262126328
614
+ sage: P = K.primes_above(2)[0]
615
+ sage: check_Kraus_local_2(c4,c6,P)
616
+ (True, a, 0)
617
+ """
618
+ if not assume_nonsingular:
619
+ if not c4c6_nonsingular(c4,c6):
620
+ return False,0,0
621
+ e = P.ramification_index()
622
+ P2 = P**e
623
+ c4val = c4.valuation(P)
624
+
625
+ if c4val == 0:
626
+ if a1 is None:
627
+ flag, t = sqrt_mod_4(-c6,P)
628
+ if not flag:
629
+ return False,0,0
630
+ # In the assignment to a1, a3 we divide by units at P,
631
+ # (note that c6+a1**6 = 0 mod P**e so dividing by 4 is OK)
632
+ # but the results, which are well-defined modulo P^e, may
633
+ # not be globally integral
634
+ a1 = make_integral(c4/t,P,e)
635
+ a13 = a1**3
636
+ a3 = make_integral((c6+a13**2)/(4*a13),P,2*e)
637
+ if test_a1a3_local(c4,c6,P,a1,a3):
638
+ return True, a1,a3
639
+ else:
640
+ raise RuntimeError("check_Kraus_local_2 fails")
641
+
642
+ if c4val >= 4*e:
643
+ if a1 is None:
644
+ a1 = c4.parent().zero() # 0
645
+ flag, a3 = sqrt_mod_4(c6/8,P)
646
+ if flag:
647
+ if test_a1a3_local(c4,c6,P,a1,a3):
648
+ return True, a1,a3
649
+ else:
650
+ raise RuntimeError("check_Kraus_local_2 fails")
651
+ else:
652
+ return False,0,0
653
+
654
+ # val(c4) strictly between 0 and 4e; a1 unique mod 2, with 3 conditions to be satisfied:
655
+
656
+ P2res = [a1] if a1 else P2.residues()
657
+ for a1 in P2res:
658
+ Px = -a1**6+3*a1**2*c4+2*c6
659
+ if Px.valuation(P) >= 4*e: # (i)
660
+ flag, a3 = sqrt_mod_4(Px/16,P) # (ii)
661
+ if flag:
662
+ a1sq = a1*a1
663
+ if (4*a1sq*Px-(a1sq**2-c4)**2).valuation(P) >= 8*e: # (iii)
664
+ if test_a1a3_local(c4,c6,P,a1,a3):
665
+ return True, a1, a3
666
+ else:
667
+ raise RuntimeError("check_Kraus_local_2 fails")
668
+ # end of loop, but no a1 found
669
+ return False, 0, 0
670
+
671
+ # Wrapper function for local Kraus check, outsources the real work to
672
+ # other functions for primes dividing 2 or 3:
673
+
674
+
675
+ def check_Kraus_local(c4, c6, P, assume_nonsingular=False):
676
+ r"""
677
+ Check Kraus's conditions locally at a prime `P`.
678
+
679
+ INPUT:
680
+
681
+ - ``c4``, ``c6`` -- elements of a number field
682
+
683
+ - ``P`` -- a prime ideal of the number field
684
+
685
+ - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
686
+ check for integrality and nonsingularity
687
+
688
+ OUTPUT:
689
+
690
+ Tuple: either ``(True, E)`` if there is a Weierstrass model `E` integral
691
+ at `P` and with invariants `c_4`, `c_6`, or ``(False, None)`` if there is
692
+ none.
693
+
694
+ EXAMPLES::
695
+
696
+ sage: # needs sage.rings.number_field
697
+ sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local
698
+ sage: x = polygen(ZZ, 'x')
699
+ sage: K.<a> = NumberField(x^2 - 15)
700
+ sage: P2 = K.primes_above(2)[0]
701
+ sage: P3 = K.primes_above(3)[0]
702
+ sage: P5 = K.primes_above(5)[0]
703
+ sage: E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
704
+ sage: c4, c6 = E.c_invariants()
705
+ sage: flag, E = check_Kraus_local(c4,c6,P2); flag
706
+ True
707
+ sage: E.is_local_integral_model(P2) and (c4,c6)==E.c_invariants()
708
+ True
709
+ sage: flag, E = check_Kraus_local(c4,c6,P3); flag
710
+ True
711
+ sage: E.is_local_integral_model(P3) and (c4,c6)==E.c_invariants()
712
+ True
713
+ sage: flag, E = check_Kraus_local(c4,c6,P5); flag
714
+ True
715
+ sage: E.is_local_integral_model(P5) and (c4,c6)==E.c_invariants()
716
+ True
717
+
718
+ sage: # needs sage.rings.number_field
719
+ sage: c4 = 123+456*a
720
+ sage: c6 = 789+101112*a
721
+ sage: check_Kraus_local(c4,c6,P2)
722
+ (False, None)
723
+ sage: check_Kraus_local(c4,c6,P3)
724
+ (False, None)
725
+ sage: check_Kraus_local(c4,c6,P5)
726
+ (False, None)
727
+ """
728
+ if not assume_nonsingular:
729
+ if not c4c6_nonsingular(c4,c6):
730
+ return False, None
731
+ K = c4.parent()
732
+ if K(2).valuation(P) > 0:
733
+ flag, a1, a3 = check_Kraus_local_2(c4,c6,P,None,True)
734
+ if flag:
735
+ E = test_a1a3_local(c4,c6,P,a1,a3)
736
+ if E:
737
+ return (True, E)
738
+ return (False, None)
739
+ if K(3).valuation(P) > 0:
740
+ flag, b2 = check_Kraus_local_3(c4,c6,P,True)
741
+ if flag:
742
+ E = test_b2_local(c4,c6,P,b2)
743
+ if E:
744
+ return (True, E)
745
+ return (False, None)
746
+ return (True, c4c6_model(c4,c6))
747
+
748
+
749
+ def check_Kraus_global(c4, c6, assume_nonsingular=False, debug=False):
750
+ r"""
751
+ Test if `c_4`, `c_6` satisfy Kraus's conditions at all primes.
752
+
753
+ INPUT:
754
+
755
+ - ``c4``, ``c6`` -- elements of a number field
756
+
757
+ - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
758
+ check for integrality and nonsingularity
759
+
760
+ OUTPUT:
761
+
762
+ Either ``False`` if Kraus's conditions fail, or, if they pass, an
763
+ elliptic curve `E` which is integral and has c-invariants `c_4`, `c_6`.
764
+
765
+ EXAMPLES::
766
+
767
+ sage: # needs sage.rings.number_field
768
+ sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_global
769
+ sage: x = polygen(ZZ, 'x')
770
+ sage: K.<a> = NumberField(x^2 - 10)
771
+ sage: E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
772
+ sage: c4, c6 = E.c_invariants()
773
+ sage: check_Kraus_global(c4,c6,debug=True)
774
+ Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 3
775
+ Using b2=a + 1 gives a model integral at 3:
776
+ (0, 1/4*a + 1/4, 0, 10091/8*a - 128595/16, 4097171/64*a - 19392359/64)
777
+ Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 2
778
+ Using (a1,a3)=(3*a,0) gives a model integral at 2:
779
+ (3*a, 0, 0, 3784/3*a - 23606/3, 1999160/27*a - 9807634/27)
780
+ (a1, b2, a3) = (3*a, a + 1, 0)
781
+ Using (r, s, t)=(1/3*a - 133/6, 3/2*a, -89/2*a + 5) should give a global integral model...
782
+ ...and it does!
783
+ Elliptic Curve defined by
784
+ y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
785
+ over Number Field in a with defining polynomial x^2 - 10
786
+
787
+ sage: # needs sage.rings.number_field
788
+ sage: K.<a> = NumberField(x^2 - 15)
789
+ sage: E = EllipticCurve([0, 0, 0, 4536*a + 14148, -163728*a - 474336])
790
+ sage: c4, c6 = E.c_invariants()
791
+ sage: check_Kraus_global(c4,c6)
792
+ Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
793
+ over Number Field in a with defining polynomial x^2 - 15
794
+
795
+ TESTS (see :issue:`17295`)::
796
+
797
+ sage: # needs sage.groups sage.rings.number_field
798
+ sage: K.<a> = NumberField(x^3 - 7*x - 5)
799
+ sage: E = EllipticCurve([a, 0, 1, 2*a^2 + 5*a + 3, -a^2 - 3*a - 2])
800
+ sage: assert E.conductor().norm() == 8
801
+ sage: G = K.galois_group(names='b')
802
+ sage: def conj_curve(E, sigma): return EllipticCurve([sigma(a) for a in E.ainvs()])
803
+ sage: EL = conj_curve(E,G[0])
804
+ sage: L = EL.base_field()
805
+ sage: assert L.class_number() == 2
806
+ sage: EL.isogeny_class() # long time (~10s)
807
+ Isogeny class of Elliptic Curve defined by
808
+ y^2 + (-1/90*b^4+7/18*b^2-1/2*b-98/45)*x*y + y = x^3 + (1/45*b^5-1/18*b^4-7/9*b^3+41/18*b^2+167/90*b-29/9)*x + (-1/90*b^5+1/30*b^4+7/18*b^3-4/3*b^2-61/90*b+11/5)
809
+ over Number Field in b with defining polynomial x^6 - 42*x^4 + 441*x^2 - 697
810
+ """
811
+ if not assume_nonsingular:
812
+ if not c4c6_nonsingular(c4,c6):
813
+ return False
814
+
815
+ # Check all primes dividing 3; for each get the value of b2
816
+ K = c4.parent()
817
+ three = K.ideal(3)
818
+ Plist3 = K.primes_above(3)
819
+ dat = [check_Kraus_local_3(c4,c6,P,True) for P in Plist3]
820
+ if not all(d[0] for d in dat):
821
+ if debug:
822
+ print("Local Kraus condition for (c4,c6)=(%s,%s) fails at some prime dividing 3" % (c4,c6))
823
+ return False
824
+ if debug:
825
+ print("Local Kraus conditions for (c4,c6)=(%s,%s) pass at all primes dividing 3" % (c4,c6))
826
+
827
+ # OK at all primes dividing 3; now use CRT to combine the b2
828
+ # values to get a single residue class for b2 mod 3:
829
+
830
+ b2list = [d[1] for d in dat]
831
+ P3list = [P**three.valuation(P) for P in Plist3]
832
+ b2 = K.solve_CRT(b2list,P3list, check=True).mod(three)
833
+
834
+ # test that this b2 value works at all P|3:
835
+ if debug:
836
+ E = test_b2_global(c4,c6,b2)
837
+ if E:
838
+ print("Using b2=%s gives a model integral at 3:\n%s" % (b2,E.ainvs()))
839
+ else:
840
+ raise RuntimeError("Error in check_Kraus_global at some prime dividing 3")
841
+
842
+ # Check all primes dividing 2; for each get the value of a1, then
843
+ # CRT these to get a single a1 (mod 2) and use these to obtain
844
+ # local a3; finally CRT these
845
+ two = K.ideal(2)
846
+ Plist2 = K.primes_above(2)
847
+ dat = [check_Kraus_local_2(c4, c6, P, None, True) for P in Plist2]
848
+ if not all(d[0] for d in dat):
849
+ if debug:
850
+ print("Local Kraus condition for (c4,c6)=(%s,%s) fails at some prime dividing 2" % (c4, c6))
851
+ return False
852
+ if debug:
853
+ print("Local Kraus conditions for (c4,c6)=(%s,%s) pass at all primes dividing 2" % (c4,c6))
854
+
855
+ # OK at all primes dividing 2; now use CRT to combine the a1
856
+ # values to get the residue classes of a1 mod 2:
857
+ P2list = [P**(two.valuation(P)) for P in Plist2]
858
+ a1list = [d[1] for d in dat]
859
+ a1 = K.solve_CRT(a1list,P2list, check=True)
860
+ # See comment below: this is needed for when we combine with the primes above 3.
861
+ if a1 not in three: # three.divides(a1) causes a segfault
862
+ a1 = 3*a1
863
+
864
+ # Using this a1, recompute the local a3's:
865
+ dat = [check_Kraus_local_2(c4,c6,P,a1,True) for P in Plist2]
866
+ # Use CRT to combine these:
867
+ a3list = [d[2] for d in dat]
868
+ a3 = K.solve_CRT(a3list,P2list, check=True)
869
+
870
+ # test that these a1,a3 values work at all P|2:
871
+ if debug:
872
+ E = test_a1a3_global(c4,c6,a1,a3,debug)
873
+ if E:
874
+ print("Using (a1,a3)=(%s,%s) gives a model integral at 2:\n%s" % (a1,a3,E.ainvs()))
875
+ else:
876
+ raise RuntimeError("Error in check_Kraus_global at some prime dividing 2")
877
+
878
+ # Now we put together the 2-adic and 3-adic transforms to get a
879
+ # global (r,s,t)-transform from [0,0,0,-c4/48,-c6/864] to a global
880
+ # integral model.
881
+
882
+ # We need the combined transform (r,s,t) to have both the forms
883
+ # (r,s,t) = (a1^2/12,a1/2,a3/2)*(r2,0,0) with 2-integral r2, and
884
+ # (r,s,t) = (b2/12,0,0,0)*(r3,s3,t3) with 3-integral r3,s3,t3.
885
+
886
+ # A solution (assuming that a1,a3,b2 are globally integral) is
887
+ # r2=(b2-a1^2)/3, r3=(b2-a1^2)/4, s3=a1/2, t3=(a1*r2+a3)/2,
888
+ # provided that a1 =0 (mod 3), to make t3 3-integral. Since a1
889
+ # was only determined mod 2 this can be fixed first, simply by
890
+ # multiplying a1 by 3 if necessary. We did this above.
891
+
892
+ if debug:
893
+ print("(a1, b2, a3) = (%s, %s, %s)" % (a1,b2,a3))
894
+ assert a1.is_integral()
895
+ assert a3.is_integral()
896
+ assert b2.is_integral()
897
+ s = a1/2
898
+ r = b2/3 - s**2
899
+ t = s*(b2-a1**2)/3 + a3/2
900
+ if debug:
901
+ print("Using (r, s, t)=(%s, %s, %s) should give a global integral model..." % (r,s,t))
902
+
903
+ # Final computation of the curve E:
904
+ E = test_rst_global(c4,c6,r,s,t,debug)
905
+ if not E:
906
+ if debug:
907
+ print("Error in check_Kraus_global with combining mod-2 and mod-3 transforms")
908
+ E = c4c6_model(c4,c6).rst_transform(r,s,t)
909
+ print("Transformed model is %a" % (E.ainvs(),))
910
+ for P in Plist2+Plist3:
911
+ if not E.is_local_integral_model(P):
912
+ print("Not integral at P=%s" % P)
913
+ raise RuntimeError("Error in check_Kraus_global combining transforms at 2 and 3")
914
+
915
+ # Success!
916
+ if debug:
917
+ print("...and it does!")
918
+ return E
919
+
920
+
921
+ def semi_global_minimal_model(E, debug=False):
922
+ r"""
923
+ Return a global minimal model for this elliptic curve if it
924
+ exists, or a model minimal at all but one prime otherwise.
925
+
926
+ INPUT:
927
+
928
+ - ``E`` -- an elliptic curve over a number field
929
+
930
+ - ``debug`` -- boolean (default: ``False``); if ``True``, prints some
931
+ messages about the progress of the computation
932
+
933
+ OUTPUT:
934
+
935
+ A tuple ``(Emin, I)`` where ``Emin`` is an elliptic curve which is either a
936
+ global minimal model of `E` if one exists (i.e., an integral model
937
+ which is minimal at every prime), or a semi-global minimal model
938
+ (i.e., an integral model which is minimal at every prime except
939
+ one). `I` is the unit ideal of ``Emin`` is a global minimal model, else
940
+ is the unique prime at which ``Emin`` is not minimal. Thus in all
941
+ cases,
942
+ ``Emin.minimal_discriminant_ideal() * I**12 == (E.discriminant())``.
943
+
944
+ .. NOTE::
945
+
946
+ This function is normally not called directly by users, who
947
+ will use the elliptic curve method :meth:`global_minimal_model`
948
+ instead; that method also applied various reductions after
949
+ minimising the model.
950
+
951
+ EXAMPLES::
952
+
953
+ sage: # needs sage.rings.number_field
954
+ sage: x = polygen(ZZ, 'x')
955
+ sage: K.<a> = NumberField(x^2 - 10)
956
+ sage: K.class_number()
957
+ 2
958
+ sage: E = EllipticCurve([0,0,0,-186408*a - 589491, 78055704*a + 246833838])
959
+ sage: from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
960
+ sage: Emin, P = semi_global_minimal_model(E)
961
+ sage: Emin
962
+ Elliptic Curve defined by
963
+ y^2 + 3*x*y + (2*a-11)*y = x^3 + (a-10)*x^2 + (-152*a-415)*x + (1911*a+5920)
964
+ over Number Field in a with defining polynomial x^2 - 10
965
+ sage: E.minimal_discriminant_ideal()*P**12 == K.ideal(Emin.discriminant())
966
+ True
967
+
968
+ TESTS:
969
+
970
+ Consider (see :issue:`20737`) a curve with no global minimal model
971
+ whose non-minimality class has order 3 in the class group, which
972
+ has order 3315. The smallest prime in that ideal class has norm
973
+ 23567::
974
+
975
+ sage: # long time, needs sage.rings.number_field
976
+ sage: K.<a> = NumberField(x^2 - x + 31821453)
977
+ sage: ainvs = (0, 0, 0, -382586771000351226384*a - 2498023791133552294513515,
978
+ ....: 358777608829102441023422458989744*a + 1110881475104109582383304709231832166)
979
+ sage: E = EllipticCurve(ainvs)
980
+ sage: from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
981
+ sage: Emin, p = semi_global_minimal_model(E) # 25s
982
+ sage: p
983
+ Fractional ideal (23567, a + 2270)
984
+ sage: p.norm()
985
+ 23567
986
+ sage: Emin.discriminant().norm().factor()
987
+ 23567^12
988
+ """
989
+ c = E.global_minimality_class()
990
+ I = c.ideal()
991
+ c4, c6 = E.c_invariants()
992
+ if c.is_one():
993
+ P = E.base_field().ideal(1)
994
+ else:
995
+ if debug:
996
+ print("No global minimal model, obstruction class = %s of order %s" % (c, c.order()))
997
+ bound = E.base_field().minkowski_bound().round() * 5
998
+ have_prime = False
999
+ while not have_prime:
1000
+ try:
1001
+ P = c.representative_prime(norm_bound=bound)
1002
+ have_prime = True
1003
+ except RuntimeError:
1004
+ bound *= 2
1005
+ if debug:
1006
+ print("Using prime {} of norm {} in that class".format(P, P.norm()))
1007
+ I = I / P
1008
+ u = I.gens_reduced()[0]
1009
+ rc4 = c4 / u**4
1010
+ rc6 = c6 / u**6
1011
+ Emin = check_Kraus_global(rc4, rc6, assume_nonsingular=True, debug=debug)
1012
+ if Emin:
1013
+ return Emin, P
1014
+ raise RuntimeError("failed to compute global minimal model")