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,1669 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.rings.number_field
3
+ r"""
4
+ Galois representations for elliptic curves over number fields
5
+
6
+ This file contains the code to compute for which primes the Galois
7
+ representation attached to an elliptic curve (over an arbitrary number field)
8
+ is surjective. The functions in this file are called by the ``is_surjective``
9
+ and ``non_surjective`` methods of an elliptic curve over a number field.
10
+
11
+ EXAMPLES::
12
+
13
+ sage: x = polygen(ZZ, 'x')
14
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
15
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
16
+ sage: rho = E.galois_representation()
17
+ sage: rho.is_surjective(29) # Cyclotomic character not surjective.
18
+ False
19
+ sage: rho.is_surjective(31) # See Section 5.10 of [Ser1972].
20
+ True
21
+ sage: rho.non_surjective() # long time (4s on sage.math, 2014)
22
+ [3, 5, 29]
23
+
24
+ sage: E = EllipticCurve_from_j(1728).change_ring(K) # CM
25
+ sage: E.galois_representation().non_surjective() # long time (2s on sage.math, 2014)
26
+ [0]
27
+
28
+ AUTHORS:
29
+
30
+ - Eric Larson (2012-05-28): initial version.
31
+ - Eric Larson (2014-08-13): added isogeny_bound function.
32
+ - John Cremona (2016, 2017): various efficiency improvements to _semistable_reducible_primes
33
+ - John Cremona (2017): implementation of Billerey's algorithm to find all reducible primes
34
+
35
+ REFERENCES:
36
+
37
+ - [Ser1972]_
38
+ - [Sut2012]_
39
+ """
40
+ # ****************************************************************************
41
+ # Copyright (C) 2012 Eric Larson <elarson3@gmail.com>
42
+ #
43
+ # Distributed under the terms of the GNU General Public License (GPL)
44
+ # as published by the Free Software Foundation; either version 2 of
45
+ # the License, or (at your option) any later version.
46
+ # https://www.gnu.org/licenses/
47
+ # ****************************************************************************
48
+
49
+ from sage.arith.misc import legendre_symbol, primes
50
+ from sage.misc.functional import cyclotomic_polynomial
51
+ from sage.misc.lazy_import import lazy_import
52
+ from sage.modules.free_module import VectorSpace
53
+ from sage.rings.finite_rings.finite_field_constructor import GF
54
+ from sage.rings.infinity import Infinity
55
+ from sage.rings.integer import Integer
56
+ from sage.rings.integer_ring import ZZ
57
+ from sage.rings.rational_field import QQ
58
+ from sage.sets.set import Set
59
+ from sage.structure.sage_object import SageObject
60
+
61
+ lazy_import('sage.rings.number_field.number_field', 'NumberField')
62
+
63
+
64
+ class GaloisRepresentation(SageObject):
65
+ r"""
66
+ The compatible family of Galois representation
67
+ attached to an elliptic curve over a number field.
68
+
69
+ Given an elliptic curve `E` over a number field `K`
70
+ and a rational prime number `p`, the `p^n`-torsion
71
+ `E[p^n]` points of `E` is a representation of the
72
+ absolute Galois group `G_K` of `K`. As `n` varies
73
+ we obtain the Tate module `T_p E` which is
74
+ a representation of `G_K` on a free `\ZZ_p`-module
75
+ of rank `2`. As `p` varies the representations
76
+ are compatible.
77
+
78
+ EXAMPLES::
79
+
80
+ sage: x = polygen(ZZ, 'x')
81
+ sage: K = NumberField(x**2 + 1, 'a')
82
+ sage: E = EllipticCurve('11a1').change_ring(K)
83
+ sage: rho = E.galois_representation()
84
+ sage: rho
85
+ Compatible family of Galois representations associated to the Elliptic Curve
86
+ defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20)
87
+ over Number Field in a with defining polynomial x^2 + 1
88
+ """
89
+
90
+ def __init__(self, E):
91
+ r"""
92
+ See ``GaloisRepresentation`` for documentation.
93
+
94
+ EXAMPLES::
95
+
96
+ sage: x = polygen(ZZ, 'x')
97
+ sage: K = NumberField(x**2 + 1, 'a')
98
+ sage: E = EllipticCurve('11a1').change_ring(K)
99
+ sage: rho = E.galois_representation()
100
+ sage: rho
101
+ Compatible family of Galois representations associated to the Elliptic Curve
102
+ defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20)
103
+ over Number Field in a with defining polynomial x^2 + 1
104
+ sage: loads(rho.dumps()) == rho
105
+ True
106
+ """
107
+ self.E = E
108
+
109
+ def __repr__(self):
110
+ r"""
111
+ Return a string representation of the class.
112
+
113
+ EXAMPLES::
114
+
115
+ sage: x = polygen(ZZ, 'x')
116
+ sage: K = NumberField(x**2 + 1, 'a')
117
+ sage: E = EllipticCurve('11a1').change_ring(K)
118
+ sage: rho = E.galois_representation()
119
+ sage: rho
120
+ Compatible family of Galois representations associated to the Elliptic Curve
121
+ defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20)
122
+ over Number Field in a with defining polynomial x^2 + 1
123
+
124
+ sage: K.<a> = NumberField(x^2-x+1)
125
+ sage: E = EllipticCurve([0,0,0,a,0])
126
+ sage: E.galois_representation()
127
+ Compatible family of Galois representations associated to the
128
+ CM Elliptic Curve defined by y^2 = x^3 + a*x
129
+ over Number Field in a with defining polynomial x^2 - x + 1
130
+ """
131
+ if self.E.has_cm():
132
+ return "Compatible family of Galois representations associated to the CM " + repr(self.E)
133
+ else:
134
+ return "Compatible family of Galois representations associated to the " + repr(self.E)
135
+
136
+ def __eq__(self, other):
137
+ r"""
138
+ Compare two Galois representations.
139
+
140
+ We define two compatible families of representations attached
141
+ to elliptic curves to be equal if the curves are isomorphic.
142
+
143
+ EXAMPLES::
144
+
145
+ sage: x = polygen(ZZ, 'x')
146
+ sage: K = NumberField(x**2 + 1, 'a'); a = K.gen()
147
+ sage: rho1 = EllipticCurve_from_j(1 + a).galois_representation()
148
+ sage: rho2 = EllipticCurve_from_j(2 + a).galois_representation()
149
+ sage: rho1 == rho1
150
+ True
151
+ sage: rho1 == rho2
152
+ False
153
+ sage: rho1 == 42
154
+ False
155
+ """
156
+ if type(self) is not type(other):
157
+ return False
158
+ return self.E.is_isomorphic(other.E)
159
+
160
+ def elliptic_curve(self):
161
+ r"""
162
+ Return the elliptic curve associated to this representation.
163
+
164
+ EXAMPLES::
165
+
166
+ sage: x = polygen(ZZ, 'x')
167
+ sage: K = NumberField(x**2 + 1, 'a'); a = K.gen()
168
+ sage: E = EllipticCurve_from_j(a)
169
+ sage: rho = E.galois_representation()
170
+ sage: rho.elliptic_curve() == E
171
+ True
172
+ """
173
+ return self.E
174
+
175
+ def non_surjective(self, A=100):
176
+ r"""
177
+ Return a list of primes `p` including all primes for which the mod-`p`
178
+ representation might not be surjective.
179
+
180
+ INPUT:
181
+
182
+ - ``A`` -- integer; a bound on the number of traces of Frobenius to use
183
+ while trying to prove surjectivity
184
+
185
+ OUTPUT:
186
+
187
+ A list of primes where mod-`p` representation is very likely not
188
+ surjective. At any prime not in this list, the representation is
189
+ definitely surjective. If `E` has CM, the list ``[0]`` is returned.
190
+
191
+ EXAMPLES::
192
+
193
+ sage: x = polygen(ZZ, 'x')
194
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
195
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
196
+ sage: rho = E.galois_representation()
197
+ sage: rho.non_surjective() # See Section 5.10 of [Ser1972]. # long time
198
+ [3, 5, 29]
199
+ sage: K = NumberField(x**2 + 3, 'a'); a = K.gen()
200
+ sage: E = EllipticCurve([0, -1, 1, -10, -20]).change_ring(K) # X_0(11)
201
+ sage: rho = E.galois_representation()
202
+ sage: rho.non_surjective() # long time (4s on sage.math, 2014)
203
+ [3, 5]
204
+ sage: K = NumberField(x**2 + 1, 'a'); a = K.gen()
205
+ sage: E = EllipticCurve_from_j(1728).change_ring(K) # CM
206
+ sage: rho = E.galois_representation()
207
+ sage: rho.non_surjective()
208
+ [0]
209
+ sage: K = NumberField(x**2 - 5, 'a'); a = K.gen()
210
+ sage: E = EllipticCurve_from_j(146329141248*a - 327201914880) # CM
211
+ sage: rho = E.galois_representation()
212
+ sage: rho.non_surjective() # long time (3s on sage.math, 2014)
213
+ [0]
214
+
215
+ TESTS:
216
+
217
+ An example which failed until fixed at :issue:`19229`::
218
+
219
+ sage: K.<a> = NumberField(x^2-x+1)
220
+ sage: E = EllipticCurve([a+1,1,1,0,0])
221
+ sage: rho = E.galois_representation()
222
+ sage: rho.non_surjective()
223
+ [2, 3]
224
+ """
225
+ if self.E.has_cm():
226
+ return [0]
227
+ return _non_surjective(self.E, A)
228
+
229
+ def is_surjective(self, p, A=100):
230
+ r"""
231
+ Return ``True`` if the mod-p representation is (provably)
232
+ surjective onto `Aut(E[p]) = GL_2(\GF{p})`. Return
233
+ ``False`` if it is (probably) not.
234
+
235
+ INPUT:
236
+
237
+ - ``p`` -- prime number
238
+
239
+ - ``A`` -- integer; a bound on the number of traces of Frobenius to use
240
+ while trying to prove surjectivity
241
+
242
+ EXAMPLES::
243
+
244
+ sage: x = polygen(ZZ, 'x')
245
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
246
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
247
+ sage: rho = E.galois_representation()
248
+ sage: rho.is_surjective(29) # Cyclotomic character not surjective.
249
+ False
250
+ sage: rho.is_surjective(7) # See Section 5.10 of [Ser1972].
251
+ True
252
+
253
+ If `E` is defined over `\QQ`, then the exceptional primes for `E_{/K}`
254
+ are the same as the exceptional primes for `E`, except for those primes
255
+ that are ramified in `K/\QQ` or are less than `[K:\QQ]`::
256
+
257
+ sage: K = NumberField(x**2 + 11, 'a')
258
+ sage: E = EllipticCurve([2, 14])
259
+ sage: rhoQQ = E.galois_representation()
260
+ sage: rhoK = E.change_ring(K).galois_representation()
261
+ sage: rhoQQ.is_surjective(2) == rhoK.is_surjective(2)
262
+ False
263
+ sage: rhoQQ.is_surjective(3) == rhoK.is_surjective(3)
264
+ True
265
+ sage: rhoQQ.is_surjective(5) == rhoK.is_surjective(5)
266
+ True
267
+
268
+ For CM curves, the mod-p representation is never surjective::
269
+
270
+ sage: K.<a> = NumberField(x^2 - x + 1)
271
+ sage: E = EllipticCurve([0,0,0,0,a])
272
+ sage: E.has_cm()
273
+ True
274
+ sage: rho = E.galois_representation()
275
+ sage: any(rho.is_surjective(p) for p in [2,3,5,7])
276
+ False
277
+ """
278
+ if self.E.has_cm():
279
+ return False
280
+ return not _exceptionals(self.E, [p], A)
281
+
282
+ def isogeny_bound(self, A=100):
283
+ r"""
284
+ Return a list of primes `p` including all primes for which
285
+ the image of the mod-`p` representation is contained in a
286
+ Borel.
287
+
288
+ .. NOTE::
289
+
290
+ For the actual list of primes `p` at which the
291
+ representation is reducible see :meth:`reducible_primes()`.
292
+
293
+ INPUT:
294
+
295
+ - ``A`` -- integer; a bound on the number of traces of Frobenius to
296
+ use while trying to prove the mod-`p` representation is not contained
297
+ in a Borel
298
+
299
+ OUTPUT:
300
+
301
+ A list of primes which contains (but may not be equal to) all `p` for
302
+ which the image of the mod-`p` representation is contained in a Borel
303
+ subgroup. At any prime not in this list, the image is definitely not
304
+ contained in a Borel. If E has `CM` defined over `K`, the list ``[0]``
305
+ is returned.
306
+
307
+ EXAMPLES::
308
+
309
+ sage: x = polygen(ZZ, 'x')
310
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
311
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
312
+ sage: rho = E.galois_representation()
313
+ sage: rho.isogeny_bound() # See Section 5.10 of [Ser1972]. # long time
314
+ [3, 5]
315
+ sage: K = NumberField(x**2 + 1, 'a')
316
+ sage: E = EllipticCurve_from_j(K(1728)) # CM over K
317
+ sage: E.galois_representation().isogeny_bound()
318
+ [0]
319
+ sage: E = EllipticCurve_from_j(K(0)) # CM NOT over K
320
+ sage: E.galois_representation().isogeny_bound() # long time
321
+ [2, 3]
322
+ sage: E = EllipticCurve_from_j(K(2268945/128)) # c.f. [Sut2012]
323
+ sage: rho = E.galois_representation()
324
+ sage: rho.isogeny_bound() # No 7-isogeny, but... # long time
325
+ [7]
326
+
327
+ For curves with rational CM, there are infinitely many primes
328
+ `p` for which the mod-`p` representation is reducible, and [0]
329
+ is returned::
330
+
331
+ sage: K.<a> = NumberField(x^2 - x + 1)
332
+ sage: E = EllipticCurve([0,0,0,0,a])
333
+ sage: E.has_rational_cm()
334
+ True
335
+ sage: rho = E.galois_representation()
336
+ sage: rho.isogeny_bound()
337
+ [0]
338
+
339
+ An example (an elliptic curve with everywhere good reduction
340
+ over an imaginary quadratic field with quite large
341
+ discriminant), which failed until fixed at :issue:`21776`::
342
+
343
+ sage: K.<a> = NumberField(x^2 - x + 112941801)
344
+ sage: E = EllipticCurve([a+1,a-1,a,-23163076*a + 266044005933275,57560769602038*a - 836483958630700313803])
345
+ sage: E.conductor().norm()
346
+ 1
347
+ sage: GR = E.galois_representation()
348
+ sage: GR.isogeny_bound()
349
+ []
350
+ """
351
+ if self.E.has_rational_cm():
352
+ return [0]
353
+
354
+ E = _over_numberfield(self.E)
355
+ K = E.base_field()
356
+
357
+ char = lambda P: P.smallest_integer() # cheaper than constructing the residue field
358
+
359
+ # semistable reducible primes (we are now not in the CM case)
360
+ bad_primes = _semistable_reducible_primes(E)
361
+
362
+ # primes of additive reduction
363
+ bad_primesK = (K.ideal(E.c4()) + K.ideal(E.discriminant())).prime_factors()
364
+ bad_primes += [char(P) for P in bad_primesK]
365
+
366
+ # ramified primes
367
+ bad_primes += K.absolute_discriminant().prime_factors()
368
+
369
+ # remove repeats:
370
+ bad_primes = list(Set(bad_primes))
371
+
372
+ return Frobenius_filter(E, bad_primes, A)
373
+
374
+ def reducible_primes(self):
375
+ r"""
376
+ Return a list of primes `p` for which the mod-`p`
377
+ representation is reducible, or [0] for CM curves.
378
+
379
+ OUTPUT:
380
+
381
+ A list of those primes `p` for which the mod-`p` representation is
382
+ contained in a Borel subgroup, i.e. is reducible. If E has CM
383
+ *defined over K*, the list ``[0]`` is returned (in this case the
384
+ representation is reducible for infinitely many primes).
385
+
386
+ EXAMPLES::
387
+
388
+ sage: x = polygen(ZZ, 'x')
389
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
390
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
391
+ sage: rho = E.galois_representation()
392
+ sage: rho.reducible_primes() # See Section 5.10 of [Ser1972]. # long time
393
+ [3, 5]
394
+
395
+ sage: K = NumberField(x**2 + 1, 'a')
396
+ sage: E = EllipticCurve_from_j(K(1728)) # CM over K
397
+ sage: E.galois_representation().reducible_primes()
398
+ [0]
399
+ sage: E = EllipticCurve_from_j(K(0)) # CM but NOT over K
400
+ sage: E.galois_representation().reducible_primes() # long time
401
+ [2, 3]
402
+ sage: E = EllipticCurve_from_j(K(2268945/128)) # c.f. [Sut2012]
403
+ sage: rho = E.galois_representation()
404
+ sage: rho.isogeny_bound() # No 7-isogeny, but... # long time
405
+ [7]
406
+ sage: rho.reducible_primes() # long time
407
+ []
408
+
409
+ For curves with rational CM, there are infinitely many primes
410
+ `p` for which the mod-`p` representation is reducible, and [0]
411
+ is returned::
412
+
413
+ sage: K.<a> = NumberField(x^2 - x + 1)
414
+ sage: E = EllipticCurve([0,0,0,0,a])
415
+ sage: E.has_rational_cm()
416
+ True
417
+ sage: rho = E.galois_representation()
418
+ sage: rho.reducible_primes()
419
+ [0]
420
+ """
421
+ if self.E.has_rational_cm():
422
+ return [0]
423
+
424
+ return [l for l in self.isogeny_bound() if self.E.isogenies_prime_degree(l)]
425
+
426
+
427
+ def _non_surjective(E, patience=100):
428
+ r"""
429
+ Return a list of primes `p` including all primes for which the mod-`p`
430
+ representation might not be surjective.
431
+
432
+ INPUT:
433
+
434
+ - ``E`` -- :class:`EllipticCurve` (over a number field)
435
+
436
+ - ``A`` -- integer; a bound on the number of traces of Frobenius to use
437
+ while trying to prove surjectivity
438
+
439
+ OUTPUT:
440
+
441
+ A list of primes where mod-`p` representation is very likely not
442
+ surjective. At any prime not in this list, the representation is
443
+ definitely surjective. If E has CM, a :exc:`ValueError` is raised.
444
+
445
+ EXAMPLES::
446
+
447
+ sage: x = polygen(ZZ, 'x')
448
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
449
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
450
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field._non_surjective(E) # See Section 5.10 of [Ser1972]. # long time
451
+ [3, 5, 29]
452
+ sage: E = EllipticCurve_from_j(1728).change_ring(K) # CM
453
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field._non_surjective(E)
454
+ Traceback (most recent call last):
455
+ ...
456
+ ValueError: The curve E should not have CM.
457
+ """
458
+ if E.has_cm():
459
+ raise ValueError("The curve E should not have CM.")
460
+
461
+ E = _over_numberfield(E)
462
+ K = E.base_field()
463
+
464
+ exceptional_primes = [2, 3, 5, 7, 11, 13, 17, 19]
465
+ # The possible primes l unramified in K/QQ for which the image of the mod l
466
+ # Galois representation could be contained in an exceptional subgroup.
467
+
468
+ # Find the places of additive reduction.
469
+ SA = []
470
+ for P, n in E.conductor().factor():
471
+ if n > 1:
472
+ SA.append(P)
473
+ # TODO: All we really require is a list of primes that include all
474
+ # primes at which E has additive reduction. Perhaps we can speed
475
+ # up things by doing something less time-consuming here that produces
476
+ # a list with some extra terms? (Of course, the longer this list is,
477
+ # the slower the rest of the computation is, so it is not clear that
478
+ # this would help...)
479
+
480
+ char = lambda P: P.smallest_integer() # cheaper than constructing the residue field
481
+
482
+ bad_primes = exceptional_primes
483
+ bad_primes += [char(P) for P in SA]
484
+ bad_primes += K.discriminant().prime_factors()
485
+ bad_primes += _semistable_reducible_primes(E)
486
+ bad_primes += _possible_normalizers(E, SA)
487
+
488
+ bad_primes = list(Set(bad_primes))
489
+
490
+ return _exceptionals(E, bad_primes, patience)
491
+
492
+
493
+ def Frobenius_filter(E, L, patience=100):
494
+ r"""
495
+ Determine which primes in L might have an image contained in a
496
+ Borel subgroup, by checking of traces of Frobenius.
497
+
498
+ .. NOTE::
499
+
500
+ This function will sometimes return primes for which the image
501
+ is not contained in a Borel subgroup. This issue cannot always
502
+ be fixed by increasing patience as it may be a result of a
503
+ failure of a local-global principle for isogenies.
504
+
505
+ INPUT:
506
+
507
+ - ``E`` -- :class:`EllipticCurve` over a number field
508
+
509
+ - ``L`` -- list of prime numbers
510
+
511
+ - ``patience`` -- positive integer (default: 100) bounding the number of
512
+ traces of Frobenius to use while trying to prove irreducibility
513
+
514
+ OUTPUT:
515
+
516
+ The list of all primes `\ell` in L for which the mod `\ell` image might be
517
+ contained in a Borel subgroup of `GL_2(\mathbf{F}_{\ell})`.
518
+
519
+ EXAMPLES::
520
+
521
+ sage: E = EllipticCurve('11a1') # has a 5-isogeny
522
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field.Frobenius_filter(E,primes(40)) # long time
523
+ [5]
524
+
525
+ Example to show that the output may contain primes where the
526
+ representation is in fact reducible. Over `\QQ` the following is
527
+ essentially the unique such example by [Sut2012]_::
528
+
529
+ sage: E = EllipticCurve_from_j(2268945/128)
530
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field.Frobenius_filter(E, [7, 11]) # long time
531
+ [7]
532
+
533
+ This curve does possess a 7-isogeny modulo every prime of good
534
+ reduction, but has no rational 7-isogeny::
535
+
536
+ sage: E.isogenies_prime_degree(7)
537
+ []
538
+
539
+ A number field example::
540
+
541
+ sage: K.<i> = QuadraticField(-1)
542
+ sage: E = EllipticCurve([1+i, -i, i, -399-240*i, 2627+2869*i])
543
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field.Frobenius_filter(E, primes(20)) # long time
544
+ [2, 3]
545
+
546
+ Here the curve really does possess isogenies of degrees 2 and 3::
547
+
548
+ sage: [len(E.isogenies_prime_degree(l)) for l in [2,3]]
549
+ [1, 1]
550
+ """
551
+ E = _over_numberfield(E).global_integral_model()
552
+ K = E.base_field()
553
+
554
+ L = list(set(L)) # Remove duplicates from L and makes a copy for output
555
+ L.sort()
556
+
557
+ include_2 = False
558
+ if 2 in L: # c.f. Section 5.3(a) of [Ser1972].
559
+ L.remove(2)
560
+ include_2 = not E.division_polynomial(2).is_irreducible()
561
+
562
+ K_is_Q = (K == QQ)
563
+ from sage.arith.misc import primes
564
+ from sage.rings.infinity import infinity
565
+
566
+ def primes_iter():
567
+ for p in primes(start=2, stop=infinity):
568
+ if K_is_Q:
569
+ if E.has_good_reduction(p):
570
+ yield ZZ.ideal(p)
571
+ else:
572
+ for P in K.primes_above(p):
573
+ if E.has_good_reduction(P):
574
+ yield P
575
+ numP = 0
576
+ for P in primes_iter():
577
+ if not L or numP == patience: # stop if no primes are left, or patience is exhausted
578
+ break
579
+
580
+ numP += 1
581
+
582
+ # Discard any l for which the Frobenius polynomial at P is
583
+ # irreducible modulo l
584
+
585
+ disc = E.reduction(P).frobenius_polynomial().discriminant()
586
+
587
+ L = [l for l in L if legendre_symbol(disc,l) != -1]
588
+
589
+ #print("After using {} primes P, {} primes l remain".format(numP,len(L)))
590
+
591
+ if include_2:
592
+ L = [2] + L
593
+ return L
594
+
595
+
596
+ def _exceptionals(E, L, patience=1000):
597
+ r"""
598
+ Determine which primes in L are exceptional for E.
599
+
600
+ This is done using Proposition 19 of Section 2.8 of Serre's
601
+ *Propriétés Galoisiennes des Points d'Ordre Fini des Courbes Elliptiques*
602
+ [Ser1972]_.
603
+
604
+ INPUT:
605
+
606
+ - ``E`` -- :class:`EllipticCurve` over a number field
607
+
608
+ - ``L`` -- list of prime numbers
609
+
610
+ - ``patience`` -- integer; a bound on the number of traces of Frobenius to
611
+ use while trying to prove surjectivity
612
+
613
+ OUTPUT:
614
+
615
+ The list of all primes l in L for which the mod l image might fail to be
616
+ surjective.
617
+
618
+ EXAMPLES::
619
+
620
+ sage: x = polygen(ZZ, 'x')
621
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
622
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
623
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field._exceptionals(E, [29, 31])
624
+ [29]
625
+
626
+ For CM curves an error is raised::
627
+
628
+ sage: E = EllipticCurve_from_j(1728).change_ring(K) # CM
629
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field._exceptionals(E,[2,3,5])
630
+ Traceback (most recent call last):
631
+ ...
632
+ ValueError: The curve E should not have CM.
633
+ """
634
+ if E.has_cm():
635
+ raise ValueError("The curve E should not have CM.")
636
+
637
+ E = _over_numberfield(E)
638
+ K = E.base_field()
639
+
640
+ output = []
641
+
642
+ L = list(set(L)) # Remove duplicates from L.
643
+
644
+ for l in L:
645
+ if l == 2: # c.f. Section 5.3(a) of [Ser1972].
646
+ if (E.j_invariant() - 1728).is_square():
647
+ output.append(2)
648
+ elif not E.division_polynomial(2).is_irreducible():
649
+ output.append(2)
650
+
651
+ elif l == 3: # c.f. Section 5.3(b) of [Ser1972].
652
+ if K(-3).is_square():
653
+ output.append(3)
654
+ elif not (K['x'].gen()**3 - E.j_invariant()).is_irreducible():
655
+ output.append(3)
656
+ elif not E.division_polynomial(3).is_irreducible():
657
+ output.append(3)
658
+
659
+ elif (K.discriminant() % l) == 0:
660
+ if not K['x'](cyclotomic_polynomial(l)).is_irreducible():
661
+ # I.E. if the action on lth roots of unity is not surjective
662
+ # (We want this since as a Galois module, \wedge^2 E[l]
663
+ # is isomorphic to the lth roots of unity.)
664
+ output.append(l)
665
+
666
+ for l in output:
667
+ L.remove(l)
668
+ if 2 in L:
669
+ L.remove(2)
670
+ if 3 in L:
671
+ L.remove(3)
672
+
673
+ # If the image is not surjective, then it is contained in one of the
674
+ # maximal subgroups. So, we start by creating a dictionary between primes
675
+ # l in L and possible maximal subgroups in which the mod l image could
676
+ # be contained. This information is stored as a triple whose elements
677
+ # are True/False according to whether the mod l image could be contained
678
+ # in:
679
+ # 0. A Borel or normalizer of split Cartan subgroup.
680
+ # 1. A nonsplit Cartan subgroup or its normalizer.
681
+ # 2. An exceptional subgroup of GL_2.
682
+
683
+ D = {}
684
+ for l in L:
685
+ D[l] = [True, True, True]
686
+
687
+ for P in deg_one_primes_iter(K):
688
+ try:
689
+ trace = E.change_ring(P.residue_field()).trace_of_frobenius()
690
+ except ArithmeticError: # Bad reduction at P.
691
+ continue
692
+
693
+ patience -= 1
694
+
695
+ determinant = P.norm()
696
+ discriminant = trace**2 - 4 * determinant
697
+
698
+ unexc = [] # Primes we discover are unexceptional go here.
699
+
700
+ for l in D:
701
+ tr = GF(l)(trace)
702
+ det = GF(l)(determinant)
703
+ disc = GF(l)(discriminant)
704
+
705
+ if tr == 0:
706
+ # I.E. if Frob_P could be contained in the normalizer of
707
+ # a Cartan subgroup, but not in the Cartan subgroup.
708
+ continue
709
+
710
+ if disc == 0:
711
+ # I.E. If the matrix might be non-diagonalizable over F_{p^2}.
712
+ continue
713
+
714
+ if legendre_symbol(disc, l) == 1:
715
+ # If the matrix is diagonalizable over F_p, it can't be
716
+ # contained in a non-split Cartan subgroup. Since we've
717
+ # gotten rid of the case where it is contained in the
718
+ # of a nonsplit Cartan subgroup but not the Cartan subgroup,
719
+ D[l][1] = False
720
+ else:
721
+ # If the matrix is not diagonalizable over F_p, it can't
722
+ # be contained Borel subgroup.
723
+ D[l][0] = False
724
+
725
+ if det != 0: # c.f. [Ser1972], Section 2.8, Prop. 19
726
+ u = trace**2 / det
727
+ if u not in (1, 2, 4) and u**2 - 3 * u + 1 != 0:
728
+ D[l][2] = False
729
+
730
+ if D[l] == [False, False, False]:
731
+ unexc.append(l)
732
+
733
+ for l in unexc:
734
+ D.pop(l)
735
+ unexc = []
736
+
737
+ if (not D) or (patience == 0):
738
+ break
739
+
740
+ output.extend(D)
741
+ output.sort()
742
+ return output
743
+
744
+
745
+ def _over_numberfield(E):
746
+ r"""
747
+ Return `E`, defined over an absolute ``NumberField``.
748
+
749
+ This is necessary since if `E` is defined over `\QQ`, then we
750
+ cannot use Sage commands available for number fields, and if the
751
+ base field is relative then other problems result.
752
+
753
+ INPUT:
754
+
755
+ - ``E`` -- :class:`EllipticCurve` over a number field
756
+
757
+ OUTPUT:
758
+
759
+ - If `E` is defined over an absolute number field, returns `E`.
760
+
761
+ - If `E` is defined over a relative number field, returns `E` defined over the absolute base field.
762
+
763
+ - If `E` is defined over `\QQ`, returns `E` defined over the number field `\QQ`.
764
+
765
+ EXAMPLES::
766
+
767
+ sage: E = EllipticCurve([1, 2])
768
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field._over_numberfield(E)
769
+ Elliptic Curve defined by y^2 = x^3 + x + 2 over Number Field in a with defining polynomial x
770
+ """
771
+ K = E.base_field()
772
+
773
+ if K == QQ:
774
+ from sage.rings.polynomial.polynomial_ring import polygen
775
+ K = NumberField(polygen(QQ), 'a')
776
+ else:
777
+ K = K.absolute_field('a')
778
+ return E.change_ring(K)
779
+
780
+
781
+ def deg_one_primes_iter(K, principal_only=False):
782
+ r"""
783
+ Return an iterator over degree 1 primes of ``K``.
784
+
785
+ INPUT:
786
+
787
+ - ``K`` -- a number field
788
+ - ``principal_only`` -- boolean; if ``True``, only yield principal primes
789
+
790
+ OUTPUT:
791
+
792
+ An iterator over degree 1 primes of `K` up to the given norm,
793
+ optionally yielding only principal primes.
794
+
795
+ EXAMPLES::
796
+
797
+ sage: K.<a> = QuadraticField(-5)
798
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import deg_one_primes_iter
799
+ sage: it = deg_one_primes_iter(K)
800
+ sage: [next(it) for _ in range(6)]
801
+ [Fractional ideal (2, a + 1),
802
+ Fractional ideal (3, a + 1),
803
+ Fractional ideal (3, a + 2),
804
+ Fractional ideal (-a),
805
+ Fractional ideal (7, a + 3),
806
+ Fractional ideal (7, a + 4)]
807
+ sage: it = deg_one_primes_iter(K, True)
808
+ sage: [next(it) for _ in range(6)]
809
+ [Fractional ideal (-a),
810
+ Fractional ideal (2*a - 3),
811
+ Fractional ideal (-2*a - 3),
812
+ Fractional ideal (a + 6),
813
+ Fractional ideal (a - 6),
814
+ Fractional ideal (3*a - 4)]
815
+ """
816
+ # imaginary quadratic fields have no principal primes of norm < disc / 4
817
+ start = K.discriminant().abs() // 4 if principal_only and K.signature() == (0,1) else 2
818
+
819
+ K_is_Q = (K == QQ)
820
+
821
+ for p in primes(start=start, stop=Infinity):
822
+ if K_is_Q:
823
+ yield ZZ.ideal(p)
824
+ else:
825
+ for P in K.primes_above(p, degree=1):
826
+ if not principal_only or P.is_principal():
827
+ yield P
828
+
829
+
830
+ def _semistable_reducible_primes(E, verbose=False):
831
+ r"""Find a list containing all semistable primes l unramified in K/QQ
832
+ for which the Galois image for E could be reducible.
833
+
834
+ INPUT:
835
+
836
+ - ``E`` -- :class:`EllipticCurve` over a number field
837
+
838
+ OUTPUT:
839
+
840
+ A list of primes, which contains all primes `l` unramified in
841
+ `K/\mathbb{QQ}`, such that `E` is semistable at all primes lying
842
+ over `l`, and the Galois image at `l` is reducible. If `E` has CM
843
+ defined over its ground field, a :exc:`ValueError` is raised.
844
+
845
+ EXAMPLES::
846
+
847
+ sage: E = EllipticCurve([0, -1, 1, -10, -20]) # X_0(11)
848
+ sage: 5 in sage.schemes.elliptic_curves.gal_reps_number_field._semistable_reducible_primes(E)
849
+ True
850
+
851
+ This example, over a quintic field with Galois group `S_5`, took a
852
+ very long time before :issue:`22343`::
853
+
854
+ sage: x = polygen(ZZ, 'x')
855
+ sage: K.<a> = NumberField(x^5 - 6*x^3 + 8*x - 1)
856
+ sage: E = EllipticCurve(K, [a^3 - 2*a, a^4 - 2*a^3 - 4*a^2 + 6*a + 1,
857
+ ....: a + 1, -a^3 + a + 1, -a])
858
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import _semistable_reducible_primes
859
+ sage: _semistable_reducible_primes(E)
860
+ [2, 5, 53, 1117]
861
+ """
862
+ if verbose:
863
+ print("In _semistable_reducible_primes with E={}".format(E.ainvs()))
864
+ K = E.base_field()
865
+ d = K.degree()
866
+
867
+ deg_one_primes = deg_one_primes_iter(K, principal_only=True)
868
+
869
+ bad_primes = set() # This will store the output.
870
+
871
+ # We find two primes (of distinct residue characteristics) which are
872
+ # of degree 1, unramified in K/Q, and at which E has good reduction.
873
+ # Each of these primes will give us a nontrivial divisibility constraint
874
+ # on the exceptional primes l. For both of these primes P, we precompute
875
+ # a generator and the characteristic polynomial of Frob_P^12.
876
+
877
+ precomp = []
878
+ last_p = 0 # The residue characteristic of the most recent prime.
879
+
880
+ while len(precomp) < 2:
881
+ P = next(deg_one_primes)
882
+ p = P.norm()
883
+ if p != last_p and (d == 1 or P.ramification_index() == 1) and E.has_good_reduction(P):
884
+ precomp.append(P)
885
+ last_p = p
886
+
887
+ Px, Py = precomp
888
+ x, y = (PP.gens_reduced()[0] for PP in precomp)
889
+ EmodPx = E.reduction(Px) if d > 1 else E.reduction(x)
890
+ EmodPy = E.reduction(Py) if d > 1 else E.reduction(y)
891
+ fxpol = EmodPx.frobenius_polynomial()
892
+ fypol = EmodPy.frobenius_polynomial()
893
+ fx12pol = fxpol.adams_operator_on_roots(12) # roots are 12th powers of those of fxpol
894
+ fy12pol = fypol.adams_operator_on_roots(12)
895
+ px = x.norm() if d > 1 else x
896
+ py = y.norm() if d > 1 else x
897
+ Zx = fxpol.parent()
898
+ xpol = x.charpoly() if d > 1 else Zx([-x,1])
899
+ ypol = y.charpoly() if d > 1 else Zx([-y,1])
900
+
901
+ if verbose:
902
+ print("Finished precomp, x={} (p={}), y={} (p={})".format(x,px,y,py))
903
+
904
+ for w in range(1 + d // 2):
905
+ if verbose:
906
+ print("w = {}".format(w))
907
+ gx = xpol.symmetric_power(w).adams_operator_on_roots(12).resultant(fx12pol)
908
+ gy = ypol.symmetric_power(w).adams_operator_on_roots(12).resultant(fy12pol)
909
+ if verbose:
910
+ print("computed gx and gy")
911
+
912
+ gxn = Integer(gx.absolute_norm()) if d > 1 else gx
913
+ gyn = Integer(gy.absolute_norm()) if d > 1 else gy
914
+ gxyn = gxn.gcd(gyn)
915
+ if gxyn:
916
+ xprimes = gxyn.prime_factors()
917
+ if verbose:
918
+ print("adding prime factors {} of {} to {}".format(xprimes, gxyn, sorted(bad_primes)))
919
+ bad_primes.update(xprimes)
920
+ if verbose:
921
+ print("...done, bad_primes now {}".format(sorted(bad_primes)))
922
+ continue
923
+ else:
924
+ if verbose:
925
+ print("gx and gy both 0!")
926
+
927
+ ## It is possible that our curve has CM. ##
928
+
929
+ # Our character must be of the form Nm^K_F for an imaginary
930
+ # quadratic subfield F of K (which is the CM field if E has CM).
931
+
932
+ # Note that this can only happen when d is even, w=d/2, and K
933
+ # contains (or the Galois closure of K contains?) the
934
+ # imaginary quadratic field F = Q(sqrt(a)) which is the
935
+ # splitting field of both fx12pol and fy12pol. We compute a
936
+ # and relativise K over F:
937
+
938
+ a = fx12pol.discriminant().squarefree_part()
939
+
940
+ # Construct a field isomorphic to K but a relative extension over QQ(sqrt(a)).
941
+
942
+ # See #19229: the names given here, which are not used, should
943
+ # not be the name of the generator of the base field.
944
+
945
+ rootsa = K(a).sqrt(all=True) # otherwise if a is not a square the
946
+ # returned result is in the symbolic ring!
947
+ try:
948
+ roota = rootsa[0]
949
+ except IndexError:
950
+ raise RuntimeError("error in _semistable_reducible_primes: K={} does not contain sqrt({})".format(K,a))
951
+ K_rel = K.relativize(roota, ['name1','name2'])
952
+ iso = K_rel.structure()[1] # an isomorphism from K to K_rel
953
+
954
+ ## We try again to find a nontrivial divisibility condition. ##
955
+
956
+ div = 0
957
+ patience = 5 * K.absolute_degree()
958
+ # Number of Frobenius elements to check before suspecting that E
959
+ # has CM and computing the set of CM j-invariants of K to check.
960
+ # TODO: Is this the best value for this parameter?
961
+
962
+ while div == 0 and patience > 0:
963
+ P = next(deg_one_primes) # a prime of K not K_rel
964
+ while E.has_bad_reduction(P):
965
+ P = next(deg_one_primes)
966
+
967
+ if verbose:
968
+ print("trying P = {}...".format(P))
969
+ EmodP = E.reduction(P)
970
+ fpol = EmodP.frobenius_polynomial()
971
+ if verbose:
972
+ print("...good reduction, frobenius poly = {}".format(fpol))
973
+ x = iso(P.gens_reduced()[0]).relative_norm()
974
+ xpol = x.charpoly().adams_operator_on_roots(12)
975
+ div2 = Integer(xpol.resultant(fpol.adams_operator_on_roots(12)) // x.norm()**12)
976
+ if div2:
977
+ div = div2.isqrt()
978
+ assert div2 == div**2
979
+ if verbose:
980
+ print("...div = {}".format(div))
981
+ else:
982
+ if verbose:
983
+ print("...div = 0, continuing")
984
+ patience -= 1
985
+
986
+ if patience == 0:
987
+ # We suspect that E has CM, so we check:
988
+ if E.has_cm():
989
+ raise ValueError("In _semistable_reducible_primes, the curve E should not have CM.")
990
+
991
+ assert div != 0
992
+ # We found our divisibility constraint.
993
+
994
+ xprimes = div.prime_factors()
995
+ if verbose:
996
+ print("...adding prime factors {} of {} to {}...".format(xprimes,div, sorted(bad_primes)))
997
+ bad_primes.update(xprimes)
998
+ if verbose:
999
+ print("...done, bad_primes now {}".format(sorted(bad_primes)))
1000
+
1001
+ L = sorted(bad_primes)
1002
+ return L
1003
+
1004
+
1005
+ def _possible_normalizers(E, SA):
1006
+ r"""Find a list containing all primes `l` such that the Galois image at `l`
1007
+ is contained in the normalizer of a Cartan subgroup, such that the
1008
+ corresponding quadratic character is ramified only at the given primes.
1009
+
1010
+ INPUT:
1011
+
1012
+ - ``E`` -- :class:`EllipticCurve` over a number field K
1013
+
1014
+ - ``SA`` -- list of primes of K
1015
+
1016
+ OUTPUT:
1017
+
1018
+ - a list of primes, which contains all primes `l` such that the Galois
1019
+ image at `l` is contained in the normalizer of a Cartan subgroup, such
1020
+ that the corresponding quadratic character is ramified only at primes in SA.
1021
+
1022
+ - if `E` has geometric CM that is not defined over its ground field, a
1023
+ :exc:`ValueError` is raised.
1024
+
1025
+ EXAMPLES::
1026
+
1027
+ sage: E = EllipticCurve([0,0,0,-56,4848])
1028
+ sage: 5 in sage.schemes.elliptic_curves.gal_reps_number_field._possible_normalizers(E, [ZZ.ideal(2)])
1029
+ True
1030
+
1031
+ For CM curves, an error is raised::
1032
+
1033
+ sage: K.<i> = QuadraticField(-1)
1034
+ sage: E = EllipticCurve_from_j(1728).change_ring(K) # CM
1035
+ sage: sage.schemes.elliptic_curves.gal_reps_number_field._possible_normalizers(E, [])
1036
+ Traceback (most recent call last):
1037
+ ...
1038
+ ValueError: The curve E should not have CM.
1039
+ """
1040
+ if E.has_cm():
1041
+ raise ValueError("The curve E should not have CM.")
1042
+
1043
+ E = _over_numberfield(E)
1044
+ K = E.base_field()
1045
+ SA = [K.ideal(I.gens()) for I in SA]
1046
+
1047
+ selmer_gens = K.selmer_generators(SA, 2) # Generators of the selmer group.
1048
+
1049
+ if not selmer_gens:
1050
+ return []
1051
+
1052
+ V = VectorSpace(GF(2), len(selmer_gens))
1053
+ # We think of this as the character group of the selmer group.
1054
+
1055
+ traces_list = []
1056
+ W = V.zero_subspace()
1057
+
1058
+ deg_one_primes = deg_one_primes_iter(K)
1059
+
1060
+ while W.dimension() < V.dimension() - 1:
1061
+ P = next(deg_one_primes)
1062
+
1063
+ k = P.residue_field()
1064
+
1065
+ defines_valid_character = True
1066
+ # A prime P defines a quadratic residue character
1067
+ # on the Selmer group. This variable will be set
1068
+ # to zero if any elements of the selmer group are
1069
+ # zero mod P (i.e. the character is ramified).
1070
+
1071
+ splitting_vector = [] # This will be the values of this
1072
+ # character on the generators of the Selmer group.
1073
+
1074
+ for a in selmer_gens:
1075
+ abar = k(a)
1076
+ if abar == 0:
1077
+ # Ramification.
1078
+ defines_valid_character = False
1079
+ break
1080
+
1081
+ if abar.is_square():
1082
+ splitting_vector.append(GF(2)(0))
1083
+ else:
1084
+ splitting_vector.append(GF(2)(1))
1085
+
1086
+ if not defines_valid_character:
1087
+ continue
1088
+
1089
+ if splitting_vector in W:
1090
+ continue
1091
+
1092
+ try:
1093
+ Etilde = E.change_ring(k)
1094
+ except ArithmeticError: # Bad reduction.
1095
+ continue
1096
+
1097
+ tr = Etilde.trace_of_frobenius()
1098
+
1099
+ if tr == 0:
1100
+ continue
1101
+
1102
+ traces_list.append(tr)
1103
+
1104
+ W = W + V.span([splitting_vector])
1105
+
1106
+ bad_primes = set()
1107
+
1108
+ for i in traces_list:
1109
+ for p in i.prime_factors():
1110
+ bad_primes.add(p)
1111
+
1112
+ # We find the unique vector v in V orthogonal to W:
1113
+ v = W.matrix().transpose().kernel().basis()[0]
1114
+
1115
+ # We find the element a of the selmer group corresponding to v:
1116
+ a = 1
1117
+ for i in range(len(selmer_gens)):
1118
+ if v[i] == 1:
1119
+ a *= selmer_gens[i]
1120
+
1121
+ # Since we've already included the above bad primes, we can assume
1122
+ # that the quadratic character corresponding to the exceptional primes
1123
+ # we're looking for is given by mapping into Gal(K[\sqrt{a}]/K).
1124
+
1125
+ patience = 5 * K.degree()
1126
+ # Number of Frobenius elements to check before suspecting that E
1127
+ # has CM and computing the set of CM j-invariants of K to check.
1128
+ # TODO: Is this the best value for this parameter?
1129
+
1130
+ while True:
1131
+ P = next(deg_one_primes)
1132
+
1133
+ k = P.residue_field()
1134
+
1135
+ if not k(a).is_square():
1136
+ try:
1137
+ tr = E.change_ring(k).trace_of_frobenius()
1138
+ except ArithmeticError: # Bad reduction.
1139
+ continue
1140
+
1141
+ if tr == 0:
1142
+ patience -= 1
1143
+
1144
+ else:
1145
+ for p in tr.prime_factors():
1146
+ bad_primes.add(p)
1147
+
1148
+ bad_primes = sorted(bad_primes)
1149
+ return bad_primes
1150
+
1151
+ #
1152
+ # Code for Billerey's algorithm to find reducible primes
1153
+ #
1154
+ # See "Critères d'irréductibilité pour les représentations des courbes
1155
+ # elliptiques", Nicolas Billerey, https://arxiv.org/abs/0908.1084
1156
+ #
1157
+
1158
+
1159
+ def Billerey_P_l(E, l):
1160
+ r"""
1161
+ Return Billerey's `P_l^*` as defined in [Bil2011]_, equation (9).
1162
+
1163
+ INPUT:
1164
+
1165
+ - ``E`` -- an elliptic curve over a number field `K`, given by a
1166
+ global integral model
1167
+
1168
+ - ``l`` -- a rational prime
1169
+
1170
+ EXAMPLES::
1171
+
1172
+ sage: x = polygen(ZZ, 'x')
1173
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
1174
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
1175
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_P_l
1176
+ sage: [Billerey_P_l(E,l) for l in primes(10)]
1177
+ [x^2 + 8143*x + 16777216,
1178
+ x^2 + 451358*x + 282429536481,
1179
+ x^4 - 664299076*x^3 + 205155493652343750*x^2 - 39595310449600219726562500*x + 3552713678800500929355621337890625,
1180
+ x^4 - 207302404*x^3 - 377423798538689366394*x^2 - 39715249826471656586987520004*x + 36703368217294125441230211032033660188801]
1181
+ """
1182
+ K = E.base_field()
1183
+ qq = K.primes_above(l)
1184
+ # if len(qq) == K.degree():
1185
+ # return None
1186
+ from sage.rings.polynomial.polynomial_ring import polygen
1187
+ from operator import mul
1188
+ P = polygen(ZZ)-1
1189
+ for q in qq:
1190
+ e = K(l).valuation(q)
1191
+ P = P.composed_op(E.reduction(q).frobenius_polynomial().adams_operator_on_roots(12*e), mul, monic=True)
1192
+ return P
1193
+
1194
+
1195
+ def Billerey_B_l(E, l, B=0):
1196
+ r"""
1197
+ Return Billerey's `B_l`, adapted from the definition in [Bil2011]_, after (9).
1198
+
1199
+ INPUT:
1200
+
1201
+ - ``E`` -- an elliptic curve over a number field `K`, given by a
1202
+ global integral model
1203
+
1204
+ - ``l`` -- integer; a rational prime
1205
+
1206
+ - ``B`` -- integer; 0 or LCM of previous `B_l` the prime-to-B part of this
1207
+ `B_l` is ignored
1208
+
1209
+ EXAMPLES::
1210
+
1211
+ sage: x = polygen(ZZ, 'x')
1212
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
1213
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
1214
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_B_l
1215
+ sage: [Billerey_B_l(E,l) for l in primes(15)]
1216
+ [1123077552537600,
1217
+ 227279663773903886745600,
1218
+ 0,
1219
+ 0,
1220
+ 269247154818492941287713746693964214802283882086400,
1221
+ 0]
1222
+ """
1223
+ d = E.base_field().absolute_degree()
1224
+ P = Billerey_P_l(E, l)
1225
+ if P is None:
1226
+ return ZZ.zero()
1227
+ # We compute the factors one at a time since if any is 0 we quit:
1228
+ B_l = ZZ(1)
1229
+ for k in range(1 + d // 2):
1230
+ factor = ZZ(P(l**(12*k)))
1231
+ if factor:
1232
+ B_l *= factor.gcd(B)
1233
+ else:
1234
+ return ZZ(0)
1235
+ return B_l
1236
+
1237
+
1238
+ def Billerey_R_q(E, q, B=0):
1239
+ r"""
1240
+ Return Billerey's `R_q`, adapted from the definition in [Bil2011]_, Theorem 2.8.
1241
+
1242
+ INPUT:
1243
+
1244
+ - ``E`` -- an elliptic curve over a number field `K`, given by a
1245
+ global integral model
1246
+
1247
+ - ``q`` -- a prime ideal of `K`
1248
+
1249
+ - ``B`` -- integer; 0 or LCM of previous `R_q` the prime-to-B part of this
1250
+ `R_q` is ignored
1251
+
1252
+ EXAMPLES::
1253
+
1254
+ sage: x = polygen(ZZ, 'x')
1255
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
1256
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
1257
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_R_q
1258
+ sage: [Billerey_R_q(E,K.prime_above(l)) for l in primes(10)]
1259
+ [1123077552537600,
1260
+ 227279663773903886745600,
1261
+ 51956919562116960000000000000000,
1262
+ 252485933820556361829926400000000]
1263
+ """
1264
+ K = E.base_field()
1265
+ d = K.absolute_degree()
1266
+ h = K.class_number()
1267
+ P = E.reduction(q).frobenius_polynomial().adams_operator_on_roots(12*h)
1268
+ Q = ((q**h).gens_reduced()[0]).absolute_minpoly().adams_operator_on_roots(12)
1269
+
1270
+ # We compute the factors one at a time since if any is 0 we quit:
1271
+ R_q = ZZ(1)
1272
+ for k in range(1 + d // 2):
1273
+ # the following would be in QQ if we did not coerce
1274
+ factor = ZZ(P.resultant(Q.compose_power(k)))
1275
+ if factor:
1276
+ R_q *= factor.gcd(B)
1277
+ else:
1278
+ return ZZ.zero()
1279
+ return R_q
1280
+
1281
+
1282
+ def Billerey_B_bound(E, max_l=200, num_l=8, small_prime_bound=0, debug=False):
1283
+ r"""
1284
+ Compute Billerey's bound `B`.
1285
+
1286
+ We compute `B_l` for `l` up to ``max_l`` (at most) until ``num_l``
1287
+ nonzero values are found (at most). Return the list of primes
1288
+ dividing all `B_l` computed, excluding those dividing 6 or
1289
+ ramified or of bad reduction or less than small_prime_bound. If
1290
+ no nonzero values are found return ``[0]``.
1291
+
1292
+ INPUT:
1293
+
1294
+ - ``E`` -- an elliptic curve over a number field `K`, given by a
1295
+ global integral model
1296
+
1297
+ - ``max_l`` -- integer (default: 200); maximum size of primes l to check
1298
+
1299
+ - ``num_l`` integer (default: 8); maximum number of primes l to check
1300
+
1301
+ - ``small_prime_bound`` -- integer (default: 0); remove primes less
1302
+ than this from the output
1303
+
1304
+ - ``debug`` -- boolean (default: ``False``); if ``True`` prints details
1305
+
1306
+ .. NOTE::
1307
+
1308
+ The purpose of the small_prime_bound is that it is faster to
1309
+ deal with these using the local test; by ignoring them here,
1310
+ we enable the algorithm to terminate sooner when there are no
1311
+ large reducible primes, which is always the case in practice.
1312
+
1313
+ EXAMPLES::
1314
+
1315
+ sage: x = polygen(ZZ, 'x')
1316
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
1317
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
1318
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_B_bound
1319
+ sage: Billerey_B_bound(E)
1320
+ [5]
1321
+
1322
+ If we do not use enough primes `l`, extraneous primes will be
1323
+ included which are not reducible primes::
1324
+
1325
+ sage: Billerey_B_bound(E, num_l=6)
1326
+ [5, 7]
1327
+
1328
+ Similarly if we do not use large enough primes `l`::
1329
+
1330
+ sage: Billerey_B_bound(E, max_l=50, num_l=8)
1331
+ [5, 7]
1332
+ sage: Billerey_B_bound(E, max_l=100, num_l=8)
1333
+ [5]
1334
+
1335
+ This curve does have a rational 5-isogeny::
1336
+
1337
+ sage: len(E.isogenies_prime_degree(5))
1338
+ 1
1339
+ """
1340
+ if debug:
1341
+ print("Computing B-bound for {} with max_l={}, num_l={}".format(E.ainvs(),max_l,num_l) + " (ignoring primes under {})".format(small_prime_bound) if small_prime_bound else "")
1342
+ B = ZZ.zero()
1343
+ ells = []
1344
+ K = E.base_field()
1345
+ DK = K.discriminant()
1346
+ ED = E.discriminant().norm()
1347
+ B0 = ZZ(6*DK*ED)
1348
+
1349
+ def remove_primes(B):
1350
+ B1 = B.prime_to_m_part(B0)
1351
+ for p in primes(small_prime_bound):
1352
+ B1 = B1.prime_to_m_part(p)
1353
+ return B1
1354
+ ll = primes(5,max_l) # iterator
1355
+ while B != 1 and len(ells) < num_l:
1356
+ try:
1357
+ l = next(ll)
1358
+ while B0.valuation(l):
1359
+ l = next(ll)
1360
+ except StopIteration:
1361
+ break
1362
+ if debug:
1363
+ print("..trying l={}".format(l))
1364
+ b = Billerey_B_l(E,l,B)
1365
+ if b:
1366
+ if debug:
1367
+ print("..ok, B_l = {}".format(b))
1368
+ if B:
1369
+ B = B.gcd(b)
1370
+ else:
1371
+ B = remove_primes(b)
1372
+ ells.append(l)
1373
+ if debug:
1374
+ print("..so far, B = {} using l in {}".format(B,ells))
1375
+ else:
1376
+ if debug:
1377
+ print("..B_l=0 for l={}".format(l))
1378
+
1379
+ if B:
1380
+ res = [p for p,e in B.factor()]
1381
+ if debug:
1382
+ print("..returning {}".format(res))
1383
+ return res
1384
+ # or we failed to find any nonzero values...
1385
+ if debug:
1386
+ print("..failed to find a bound")
1387
+ return [0]
1388
+
1389
+
1390
+ def Billerey_R_bound(E, max_l=200, num_l=8, small_prime_bound=None, debug=False):
1391
+ r"""
1392
+ Compute Billerey's bound `R`.
1393
+
1394
+ We compute `R_q` for `q` dividing primes `\ell` up to ``max_l``
1395
+ (at most) until ``num_l`` nonzero values are found (at most).
1396
+ Return the list of primes dividing all ``R_q`` computed, excluding
1397
+ those dividing 6 or ramified or of bad reduction or less than
1398
+ small_prime_bound. If no nonzero values are found return ``[0]``.
1399
+
1400
+ INPUT:
1401
+
1402
+ - ``E`` -- an elliptic curve over a number field `K`, given by a
1403
+ global integral model
1404
+
1405
+ - ``max_l`` -- integer (default: 200); maximum size of rational primes
1406
+ l for which the primes q above l are checked
1407
+
1408
+ - ``num_l`` -- integer (default: 8); maximum number of rational primes
1409
+ l for which the primes q above l are checked
1410
+
1411
+ - ``small_prime_bound`` -- integer (default: 0); remove primes less
1412
+ than this from the output
1413
+
1414
+ - ``debug`` -- boolean (default: ``False``); if ``True`` prints details
1415
+
1416
+ .. NOTE::
1417
+
1418
+ The purpose of the ``small_prime_bound`` is that it is faster to
1419
+ deal with these using the local test; by ignoring them here,
1420
+ we enable the algorithm to terminate sooner when there are no
1421
+ large reducible primes, which is always the case in practice.
1422
+
1423
+ EXAMPLES::
1424
+
1425
+ sage: x = polygen(ZZ, 'x')
1426
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
1427
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
1428
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import Billerey_R_bound
1429
+ sage: Billerey_R_bound(E)
1430
+ [5]
1431
+
1432
+ We may get no bound at all if we do not use enough primes::
1433
+
1434
+ sage: Billerey_R_bound(E, max_l=2, debug=False)
1435
+ [0]
1436
+
1437
+ Or we may get a bound but not a good one if we do not use enough primes::
1438
+
1439
+ sage: Billerey_R_bound(E, num_l=1, debug=False)
1440
+ [5, 17, 67, 157]
1441
+
1442
+ In this case two primes is enough to restrict the set of possible
1443
+ reducible primes to just `\{5\}`. This curve does have a rational 5-isogeny::
1444
+
1445
+ sage: Billerey_R_bound(E, num_l=2, debug=False)
1446
+ [5]
1447
+ sage: len(E.isogenies_prime_degree(5))
1448
+ 1
1449
+ """
1450
+ if debug:
1451
+ print("Computing R-bound for {} with max_l={}, num_l={}".format(E.ainvs(),max_l,num_l) + " (ignoring primes under {})".format(small_prime_bound) if small_prime_bound else "")
1452
+ B = ZZ.zero()
1453
+ ells = []
1454
+ K = E.base_field()
1455
+ DK = K.discriminant()
1456
+ ED = E.discriminant().norm()
1457
+ B0 = ZZ(6*DK*ED)
1458
+
1459
+ def remove_primes(B):
1460
+ B1 = B.prime_to_m_part(B0)
1461
+ for p in primes(small_prime_bound):
1462
+ B1 = B1.prime_to_m_part(p)
1463
+ return B1
1464
+ ll = primes(5, max_l) # iterator
1465
+ while len(ells) < num_l and B != 1:
1466
+ try:
1467
+ l = next(ll)
1468
+ while B0.valuation(l):
1469
+ l = next(ll)
1470
+ except StopIteration:
1471
+ break
1472
+ q = K.prime_above(l)
1473
+ if debug:
1474
+ print("..trying q={} above l={}".format(q,l))
1475
+ b = Billerey_R_q(E,q,B)
1476
+ if b:
1477
+ if debug:
1478
+ print("..ok, R_q = {}, type={}".format(b,type(b)))
1479
+ if B:
1480
+ B = B.gcd(b)
1481
+ else:
1482
+ B = remove_primes(b)
1483
+ ells.append(l)
1484
+ if debug:
1485
+ print("..so far, B = {} using l in {}".format(B,ells))
1486
+
1487
+ if B:
1488
+ res = B.support()
1489
+ if debug:
1490
+ print("..returning {}".format(res))
1491
+ return res
1492
+ # or we failed to find any nonzero values...
1493
+ if debug:
1494
+ print("..failed to find a bound")
1495
+ return [0]
1496
+
1497
+
1498
+ def reducible_primes_Billerey(E, num_l=None, max_l=None, verbose=False):
1499
+ r"""
1500
+ Return a finite set of primes `\ell` containing all those for which
1501
+ `E` has a `K`-rational ell-isogeny, where `K` is the base field of
1502
+ `E`: i.e., the mod-`\ell` representation is irreducible for all
1503
+ `\ell` outside the set returned.
1504
+
1505
+ INPUT:
1506
+
1507
+ - ``E`` -- an elliptic curve defined over a number field `K`
1508
+
1509
+ - ``max_l`` -- integer or ``None`` (default); the maximum prime
1510
+ `\ell` to use for the B-bound and R-bound. If ``None``, a
1511
+ default value will be used.
1512
+
1513
+ - ``num_l`` -- integer or ``None`` (default); the number of primes
1514
+ `\ell` to use for the B-bound and R-bound. If ``None``, a
1515
+ default value will be used.
1516
+
1517
+ .. NOTE::
1518
+
1519
+ If ``E`` has CM then [0] is returned. In this case use the
1520
+ function
1521
+ sage.schemes.elliptic_curves.isogeny_class.possible_isogeny_degrees
1522
+
1523
+ We first compute Billeray's B_bound using at most ``num_l`` primes
1524
+ of size up to ``max_l``. If that fails we compute Billeray's
1525
+ R_bound using at most ``num_q`` primes of size up to ``max_q``.
1526
+
1527
+ Provided that one of these methods succeeds in producing a finite
1528
+ list of primes we check these using a local condition, and finally
1529
+ test that the primes returned actually are reducible. Otherwise
1530
+ we return ``[0]``.
1531
+
1532
+ EXAMPLES::
1533
+
1534
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import reducible_primes_Billerey
1535
+ sage: x = polygen(ZZ, 'x')
1536
+ sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
1537
+ sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
1538
+ sage: reducible_primes_Billerey(E) # long time
1539
+ [3, 5]
1540
+ sage: K = NumberField(x**2 + 1, 'a')
1541
+ sage: E = EllipticCurve_from_j(K(1728)) # CM over K
1542
+ sage: reducible_primes_Billerey(E) # long time
1543
+ [0]
1544
+ sage: E = EllipticCurve_from_j(K(0)) # CM but NOT over K
1545
+ sage: reducible_primes_Billerey(E) # long time
1546
+ [2, 3]
1547
+
1548
+ An example where a prime is not reducible but passes the test::
1549
+
1550
+ sage: E = EllipticCurve_from_j(K(2268945/128)).global_minimal_model() # c.f. [Sut2012]
1551
+ sage: reducible_primes_Billerey(E) # long time
1552
+ [7]
1553
+
1554
+ TESTS:
1555
+
1556
+ Test that this function works with non-integral models (see :issue:`34174`)::
1557
+
1558
+ sage: K.<a> = QuadraticField(4569)
1559
+ sage: j = 46969655/32768
1560
+ sage: E = EllipticCurve(j=K(j))
1561
+ sage: EK = E.change_ring(K)
1562
+ sage: C = EK.isogeny_class(minimal_models=False) # long time
1563
+ sage: len(C) # long time
1564
+ 4
1565
+ """
1566
+ #verbose=True
1567
+ if verbose:
1568
+ print("E = {}, finding reducible primes using Billerey's algorithm".format(E.ainvs()))
1569
+
1570
+ # Set parameters to default values if not given:
1571
+ if max_l is None:
1572
+ max_l = 200
1573
+ if num_l is None:
1574
+ num_l = 8
1575
+
1576
+ K = E.base_field()
1577
+ DK = K.discriminant()
1578
+
1579
+ # We replace E by an integral model if necessary, since this
1580
+ # function and the helper functions need this:
1581
+ E1 = E.global_integral_model()
1582
+ ED = E1.discriminant().norm()
1583
+ B0 = ZZ(6*DK*ED).prime_divisors()
1584
+
1585
+ # Billeray's algorithm will be faster if we tell it to ignore
1586
+ # small primes; these can be tested using the naive algorithm.
1587
+
1588
+ if verbose:
1589
+ print("First doing naive test of primes up to {}...".format(max_l))
1590
+
1591
+ max_small_prime = 200
1592
+ OK_small_primes = reducible_primes_naive(E1, max_l=max_small_prime, num_P=200, verbose=verbose)
1593
+ if verbose:
1594
+ print("Naive test of primes up to {} returns {}.".format(max_small_prime, OK_small_primes))
1595
+
1596
+ B1 = Billerey_B_bound(E1, max_l, num_l, max_small_prime, verbose)
1597
+ if B1 == [0]:
1598
+ if verbose:
1599
+ print("... B_bound ineffective using max_l={}, moving on to R-bound".format(max_l))
1600
+
1601
+ B1 = Billerey_R_bound(E1,max_l, num_l, max_small_prime, verbose)
1602
+ if B1 == [0]:
1603
+ if verbose:
1604
+ print("... R_bound ineffective using max_l={}",format(max_l))
1605
+ return [0]
1606
+ if verbose:
1607
+ print("... R_bound = {}".format(B1))
1608
+ else:
1609
+ if verbose:
1610
+ print("... B_bound = {}".format(B1))
1611
+ B = sorted(set(B0 + B1 + OK_small_primes))
1612
+ if verbose:
1613
+ print("... combined bound = {}".format(B))
1614
+
1615
+ num_p = 100
1616
+ B = Frobenius_filter(E1, B, num_p)
1617
+ if verbose:
1618
+ print("... after Frobenius filter = {}".format(B))
1619
+ return B
1620
+
1621
+
1622
+ def reducible_primes_naive(E, max_l=None, num_P=None, verbose=False):
1623
+ r"""
1624
+ Return locally reducible primes `\ell` up to ``max_l``.
1625
+
1626
+ The list of primes `\ell` returned consists of all those up to
1627
+ ``max_l`` such that `E` mod `P` has an `\ell`-isogeny, where `K`
1628
+ is the base field of `E`, for ``num_P`` primes `P` of `K`. In
1629
+ most cases `E` then has a `K`-rational `\ell`-isogeny, but there
1630
+ are rare exceptions.
1631
+
1632
+ INPUT:
1633
+
1634
+ - ``E`` -- an elliptic curve defined over a number field `K`
1635
+
1636
+ - ``max_l`` -- integer or ``None`` (default); the maximum prime
1637
+ `\ell` to test
1638
+
1639
+ - ``num_P`` -- integer or ``None`` (default); the number of primes
1640
+ `P` of `K` to use in testing each `\ell`
1641
+
1642
+ EXAMPLES::
1643
+
1644
+ sage: from sage.schemes.elliptic_curves.gal_reps_number_field import reducible_primes_naive
1645
+ sage: x = polygen(ZZ, 'x')
1646
+ sage: K.<a> = NumberField(x^4 - 5*x^2 + 3)
1647
+ sage: E = EllipticCurve(K, [a^2 - 2, -a^2 + 3, a^2 - 2, -50*a^2 + 35, 95*a^2 - 67])
1648
+ sage: reducible_primes_naive(E,num_P=10)
1649
+ [2, 5, 53, 173, 197, 241, 293, 317, 409, 557, 601, 653, 677, 769, 773, 797]
1650
+ sage: reducible_primes_naive(E,num_P=15)
1651
+ [2, 5, 197, 557, 653, 769]
1652
+ sage: reducible_primes_naive(E,num_P=20)
1653
+ [2, 5]
1654
+ sage: reducible_primes_naive(E) # long time
1655
+ [2, 5]
1656
+ sage: [phi.degree() for phi in E.isogenies_prime_degree()] # long time
1657
+ [2, 2, 2, 5]
1658
+ """
1659
+ if max_l is None:
1660
+ max_l = 1000
1661
+ if num_P is None:
1662
+ num_P = 100
1663
+ if verbose:
1664
+ print("E = {}, finding reducible primes up to {} using Frobenius filter with {} primes".format(E.ainvs(), max_l, num_P))
1665
+
1666
+ B = Frobenius_filter(E, primes(max_l), num_P)
1667
+ if verbose:
1668
+ print("... returning {}".format(B))
1669
+ return B