passagemath-flint 10.6.1rc10__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
  2. passagemath_flint-10.6.1rc10.dist-info/RECORD +361 -0
  3. passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
  4. passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
  5. passagemath_flint.libs/libflint-aecb9cc5.so.21.0.0 +0 -0
  6. passagemath_flint.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  7. passagemath_flint.libs/libgfortran-8f1e9814.so.5.0.0 +0 -0
  8. passagemath_flint.libs/libgmp-6e109695.so.10.5.0 +0 -0
  9. passagemath_flint.libs/libgsl-cda90e79.so.28.0.0 +0 -0
  10. passagemath_flint.libs/libmpfi-e3c25853.so.0.0.0 +0 -0
  11. passagemath_flint.libs/libmpfr-82690d50.so.6.2.1 +0 -0
  12. passagemath_flint.libs/libntl-74e7d9a3.so.44.0.1 +0 -0
  13. passagemath_flint.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
  14. passagemath_flint.libs/libquadmath-828275a7.so.0.0.0 +0 -0
  15. sage/all__sagemath_flint.py +29 -0
  16. sage/combinat/all__sagemath_flint.py +1 -0
  17. sage/combinat/posets/all__sagemath_flint.py +1 -0
  18. sage/combinat/posets/hasse_cython_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  19. sage/combinat/posets/hasse_cython_flint.pyx +194 -0
  20. sage/data_structures/all__sagemath_flint.py +1 -0
  21. sage/data_structures/bounded_integer_sequences.cpython-313-x86_64-linux-gnu.so +0 -0
  22. sage/data_structures/bounded_integer_sequences.pxd +62 -0
  23. sage/data_structures/bounded_integer_sequences.pyx +1418 -0
  24. sage/graphs/all__sagemath_flint.py +1 -0
  25. sage/graphs/chrompoly.cpython-313-x86_64-linux-gnu.so +0 -0
  26. sage/graphs/chrompoly.pyx +555 -0
  27. sage/graphs/matchpoly.cpython-313-x86_64-linux-gnu.so +0 -0
  28. sage/graphs/matchpoly.pyx +412 -0
  29. sage/libs/all__sagemath_flint.py +17 -0
  30. sage/libs/arb/__init__.py +1 -0
  31. sage/libs/arb/acb.pxd +154 -0
  32. sage/libs/arb/acb_calc.pxd +9 -0
  33. sage/libs/arb/acb_elliptic.pxd +25 -0
  34. sage/libs/arb/acb_hypgeom.pxd +74 -0
  35. sage/libs/arb/acb_mat.pxd +62 -0
  36. sage/libs/arb/acb_modular.pxd +17 -0
  37. sage/libs/arb/acb_poly.pxd +216 -0
  38. sage/libs/arb/arb.pxd +240 -0
  39. sage/libs/arb/arb_fmpz_poly.pxd +21 -0
  40. sage/libs/arb/arb_hypgeom.pxd +83 -0
  41. sage/libs/arb/arb_wrap.h +34 -0
  42. sage/libs/arb/arf.pxd +131 -0
  43. sage/libs/arb/arith.cpython-313-x86_64-linux-gnu.so +0 -0
  44. sage/libs/arb/arith.pyx +87 -0
  45. sage/libs/arb/bernoulli.pxd +6 -0
  46. sage/libs/arb/mag.pxd +77 -0
  47. sage/libs/arb/types.pxd +37 -0
  48. sage/libs/flint/__init__.py +1 -0
  49. sage/libs/flint/acb.pxd +270 -0
  50. sage/libs/flint/acb_calc.pxd +22 -0
  51. sage/libs/flint/acb_dft.pxd +51 -0
  52. sage/libs/flint/acb_dirichlet.pxd +112 -0
  53. sage/libs/flint/acb_elliptic.pxd +42 -0
  54. sage/libs/flint/acb_hypgeom.pxd +169 -0
  55. sage/libs/flint/acb_macros.pxd +9 -0
  56. sage/libs/flint/acb_mat.pxd +136 -0
  57. sage/libs/flint/acb_mat_macros.pxd +10 -0
  58. sage/libs/flint/acb_modular.pxd +62 -0
  59. sage/libs/flint/acb_poly.pxd +251 -0
  60. sage/libs/flint/acb_poly_macros.pxd +8 -0
  61. sage/libs/flint/acb_theta.pxd +124 -0
  62. sage/libs/flint/acf.pxd +32 -0
  63. sage/libs/flint/aprcl.pxd +84 -0
  64. sage/libs/flint/arb.pxd +382 -0
  65. sage/libs/flint/arb_calc.pxd +31 -0
  66. sage/libs/flint/arb_fmpz_poly.pxd +34 -0
  67. sage/libs/flint/arb_fpwrap.pxd +215 -0
  68. sage/libs/flint/arb_hypgeom.pxd +147 -0
  69. sage/libs/flint/arb_macros.pxd +9 -0
  70. sage/libs/flint/arb_mat.pxd +140 -0
  71. sage/libs/flint/arb_mat_macros.pxd +10 -0
  72. sage/libs/flint/arb_poly.pxd +237 -0
  73. sage/libs/flint/arf.pxd +167 -0
  74. sage/libs/flint/arith.cpython-313-x86_64-linux-gnu.so +0 -0
  75. sage/libs/flint/arith.pxd +76 -0
  76. sage/libs/flint/arith.pyx +77 -0
  77. sage/libs/flint/arith_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  78. sage/libs/flint/arith_sage.pyx +308 -0
  79. sage/libs/flint/bernoulli.pxd +28 -0
  80. sage/libs/flint/bool_mat.pxd +52 -0
  81. sage/libs/flint/ca.pxd +203 -0
  82. sage/libs/flint/ca_ext.pxd +34 -0
  83. sage/libs/flint/ca_field.pxd +32 -0
  84. sage/libs/flint/ca_mat.pxd +117 -0
  85. sage/libs/flint/ca_poly.pxd +104 -0
  86. sage/libs/flint/ca_vec.pxd +46 -0
  87. sage/libs/flint/calcium.pxd +27 -0
  88. sage/libs/flint/d_mat.pxd +39 -0
  89. sage/libs/flint/d_vec.pxd +32 -0
  90. sage/libs/flint/dirichlet.pxd +57 -0
  91. sage/libs/flint/dlog.pxd +53 -0
  92. sage/libs/flint/double_extras.pxd +24 -0
  93. sage/libs/flint/double_interval.pxd +36 -0
  94. sage/libs/flint/fexpr.pxd +104 -0
  95. sage/libs/flint/fexpr_builtin.pxd +20 -0
  96. sage/libs/flint/fft.pxd +66 -0
  97. sage/libs/flint/flint.pxd +36 -0
  98. sage/libs/flint/flint_ntl_wrap.h +35 -0
  99. sage/libs/flint/flint_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  100. sage/libs/flint/flint_sage.pyx +163 -0
  101. sage/libs/flint/flint_wrap.h +190 -0
  102. sage/libs/flint/fmpq.pxd +137 -0
  103. sage/libs/flint/fmpq_mat.pxd +105 -0
  104. sage/libs/flint/fmpq_mat_macros.pxd +10 -0
  105. sage/libs/flint/fmpq_mpoly.pxd +165 -0
  106. sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
  107. sage/libs/flint/fmpq_poly.pxd +241 -0
  108. sage/libs/flint/fmpq_poly_macros.pxd +9 -0
  109. sage/libs/flint/fmpq_poly_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  110. sage/libs/flint/fmpq_poly_sage.pxd +31 -0
  111. sage/libs/flint/fmpq_poly_sage.pyx +48 -0
  112. sage/libs/flint/fmpq_vec.pxd +27 -0
  113. sage/libs/flint/fmpz.pxd +256 -0
  114. sage/libs/flint/fmpz_extras.pxd +32 -0
  115. sage/libs/flint/fmpz_factor.pxd +42 -0
  116. sage/libs/flint/fmpz_factor_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  117. sage/libs/flint/fmpz_factor_sage.pxd +4 -0
  118. sage/libs/flint/fmpz_factor_sage.pyx +29 -0
  119. sage/libs/flint/fmpz_lll.pxd +49 -0
  120. sage/libs/flint/fmpz_macros.pxd +8 -0
  121. sage/libs/flint/fmpz_mat.pxd +184 -0
  122. sage/libs/flint/fmpz_mat_macros.pxd +10 -0
  123. sage/libs/flint/fmpz_mod.pxd +46 -0
  124. sage/libs/flint/fmpz_mod_mat.pxd +71 -0
  125. sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
  126. sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
  127. sage/libs/flint/fmpz_mod_poly.pxd +249 -0
  128. sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
  129. sage/libs/flint/fmpz_mod_vec.pxd +27 -0
  130. sage/libs/flint/fmpz_mpoly.pxd +224 -0
  131. sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
  132. sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
  133. sage/libs/flint/fmpz_poly.cpython-313-x86_64-linux-gnu.so +0 -0
  134. sage/libs/flint/fmpz_poly.pxd +407 -0
  135. sage/libs/flint/fmpz_poly.pyx +19 -0
  136. sage/libs/flint/fmpz_poly_factor.pxd +33 -0
  137. sage/libs/flint/fmpz_poly_macros.pxd +8 -0
  138. sage/libs/flint/fmpz_poly_mat.pxd +71 -0
  139. sage/libs/flint/fmpz_poly_q.pxd +55 -0
  140. sage/libs/flint/fmpz_poly_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  141. sage/libs/flint/fmpz_poly_sage.pxd +20 -0
  142. sage/libs/flint/fmpz_poly_sage.pyx +500 -0
  143. sage/libs/flint/fmpz_vec.pxd +80 -0
  144. sage/libs/flint/fmpzi.pxd +52 -0
  145. sage/libs/flint/fq.pxd +97 -0
  146. sage/libs/flint/fq_default.pxd +84 -0
  147. sage/libs/flint/fq_default_mat.pxd +70 -0
  148. sage/libs/flint/fq_default_poly.pxd +97 -0
  149. sage/libs/flint/fq_default_poly_factor.pxd +39 -0
  150. sage/libs/flint/fq_embed.pxd +28 -0
  151. sage/libs/flint/fq_mat.pxd +83 -0
  152. sage/libs/flint/fq_nmod.pxd +95 -0
  153. sage/libs/flint/fq_nmod_embed.pxd +28 -0
  154. sage/libs/flint/fq_nmod_mat.pxd +83 -0
  155. sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
  156. sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
  157. sage/libs/flint/fq_nmod_poly.pxd +202 -0
  158. sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
  159. sage/libs/flint/fq_nmod_vec.pxd +33 -0
  160. sage/libs/flint/fq_poly.pxd +204 -0
  161. sage/libs/flint/fq_poly_factor.pxd +47 -0
  162. sage/libs/flint/fq_vec.pxd +33 -0
  163. sage/libs/flint/fq_zech.pxd +99 -0
  164. sage/libs/flint/fq_zech_embed.pxd +28 -0
  165. sage/libs/flint/fq_zech_mat.pxd +78 -0
  166. sage/libs/flint/fq_zech_poly.pxd +198 -0
  167. sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
  168. sage/libs/flint/fq_zech_vec.pxd +33 -0
  169. sage/libs/flint/gr.pxd +174 -0
  170. sage/libs/flint/gr_generic.pxd +215 -0
  171. sage/libs/flint/gr_mat.pxd +161 -0
  172. sage/libs/flint/gr_mpoly.pxd +68 -0
  173. sage/libs/flint/gr_poly.pxd +276 -0
  174. sage/libs/flint/gr_special.pxd +237 -0
  175. sage/libs/flint/gr_vec.pxd +120 -0
  176. sage/libs/flint/hypgeom.pxd +24 -0
  177. sage/libs/flint/long_extras.pxd +23 -0
  178. sage/libs/flint/mag.pxd +131 -0
  179. sage/libs/flint/mag_macros.pxd +8 -0
  180. sage/libs/flint/mpf_mat.pxd +36 -0
  181. sage/libs/flint/mpf_vec.pxd +34 -0
  182. sage/libs/flint/mpfr_mat.pxd +27 -0
  183. sage/libs/flint/mpfr_vec.pxd +25 -0
  184. sage/libs/flint/mpn_extras.pxd +41 -0
  185. sage/libs/flint/mpoly.pxd +72 -0
  186. sage/libs/flint/nf.pxd +19 -0
  187. sage/libs/flint/nf_elem.pxd +74 -0
  188. sage/libs/flint/nmod.pxd +35 -0
  189. sage/libs/flint/nmod_mat.pxd +104 -0
  190. sage/libs/flint/nmod_mpoly.pxd +144 -0
  191. sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
  192. sage/libs/flint/nmod_poly.pxd +339 -0
  193. sage/libs/flint/nmod_poly_factor.pxd +44 -0
  194. sage/libs/flint/nmod_poly_linkage.pxi +710 -0
  195. sage/libs/flint/nmod_poly_mat.pxd +76 -0
  196. sage/libs/flint/nmod_vec.pxd +40 -0
  197. sage/libs/flint/ntl_interface.pxd +17 -0
  198. sage/libs/flint/padic.pxd +93 -0
  199. sage/libs/flint/padic_mat.pxd +64 -0
  200. sage/libs/flint/padic_poly.pxd +88 -0
  201. sage/libs/flint/partitions.pxd +23 -0
  202. sage/libs/flint/perm.pxd +26 -0
  203. sage/libs/flint/profiler.pxd +24 -0
  204. sage/libs/flint/qadic.pxd +77 -0
  205. sage/libs/flint/qfb.pxd +44 -0
  206. sage/libs/flint/qqbar.pxd +172 -0
  207. sage/libs/flint/qsieve.cpython-313-x86_64-linux-gnu.so +0 -0
  208. sage/libs/flint/qsieve.pxd +41 -0
  209. sage/libs/flint/qsieve.pyx +21 -0
  210. sage/libs/flint/qsieve_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  211. sage/libs/flint/qsieve_sage.pyx +67 -0
  212. sage/libs/flint/thread_pool.pxd +25 -0
  213. sage/libs/flint/types.pxd +2076 -0
  214. sage/libs/flint/ulong_extras.cpython-313-x86_64-linux-gnu.so +0 -0
  215. sage/libs/flint/ulong_extras.pxd +141 -0
  216. sage/libs/flint/ulong_extras.pyx +21 -0
  217. sage/libs/flint/ulong_extras_sage.cpython-313-x86_64-linux-gnu.so +0 -0
  218. sage/libs/flint/ulong_extras_sage.pyx +21 -0
  219. sage/matrix/all__sagemath_flint.py +1 -0
  220. sage/matrix/change_ring.cpython-313-x86_64-linux-gnu.so +0 -0
  221. sage/matrix/change_ring.pyx +43 -0
  222. sage/matrix/matrix_complex_ball_dense.cpython-313-x86_64-linux-gnu.so +0 -0
  223. sage/matrix/matrix_complex_ball_dense.pxd +14 -0
  224. sage/matrix/matrix_complex_ball_dense.pyx +973 -0
  225. sage/matrix/matrix_cyclo_dense.cpython-313-x86_64-linux-gnu.so +0 -0
  226. sage/matrix/matrix_cyclo_dense.pxd +16 -0
  227. sage/matrix/matrix_cyclo_dense.pyx +1761 -0
  228. sage/matrix/matrix_integer_dense.cpython-313-x86_64-linux-gnu.so +0 -0
  229. sage/matrix/matrix_integer_dense.pxd +32 -0
  230. sage/matrix/matrix_integer_dense.pyx +5801 -0
  231. sage/matrix/matrix_integer_dense_hnf.py +1294 -0
  232. sage/matrix/matrix_integer_dense_saturation.py +346 -0
  233. sage/matrix/matrix_integer_sparse.cpython-313-x86_64-linux-gnu.so +0 -0
  234. sage/matrix/matrix_integer_sparse.pxd +9 -0
  235. sage/matrix/matrix_integer_sparse.pyx +1090 -0
  236. sage/matrix/matrix_rational_dense.cpython-313-x86_64-linux-gnu.so +0 -0
  237. sage/matrix/matrix_rational_dense.pxd +23 -0
  238. sage/matrix/matrix_rational_dense.pyx +2995 -0
  239. sage/matrix/matrix_rational_sparse.cpython-313-x86_64-linux-gnu.so +0 -0
  240. sage/matrix/matrix_rational_sparse.pxd +11 -0
  241. sage/matrix/matrix_rational_sparse.pyx +789 -0
  242. sage/matrix/misc_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  243. sage/matrix/misc_flint.pyx +109 -0
  244. sage/modular/all__sagemath_flint.py +1 -0
  245. sage/modular/modform/all__sagemath_flint.py +1 -0
  246. sage/modular/modform/eis_series_cython.cpython-313-x86_64-linux-gnu.so +0 -0
  247. sage/modular/modform/eis_series_cython.pyx +226 -0
  248. sage/modular/modsym/all__sagemath_flint.py +1 -0
  249. sage/modular/modsym/apply.cpython-313-x86_64-linux-gnu.so +0 -0
  250. sage/modular/modsym/apply.pxd +6 -0
  251. sage/modular/modsym/apply.pyx +113 -0
  252. sage/modular/modsym/heilbronn.cpython-313-x86_64-linux-gnu.so +0 -0
  253. sage/modular/modsym/heilbronn.pyx +966 -0
  254. sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
  255. sage/modular/pollack_stevens/dist.cpython-313-x86_64-linux-gnu.so +0 -0
  256. sage/modular/pollack_stevens/dist.pxd +38 -0
  257. sage/modular/pollack_stevens/dist.pyx +1439 -0
  258. sage/quivers/algebra.py +691 -0
  259. sage/quivers/algebra_elements.cpython-313-x86_64-linux-gnu.so +0 -0
  260. sage/quivers/algebra_elements.pxd +97 -0
  261. sage/quivers/algebra_elements.pxi +1324 -0
  262. sage/quivers/algebra_elements.pyx +1424 -0
  263. sage/quivers/all.py +1 -0
  264. sage/quivers/ar_quiver.py +917 -0
  265. sage/quivers/homspace.py +640 -0
  266. sage/quivers/morphism.py +1282 -0
  267. sage/quivers/path_semigroup.py +1155 -0
  268. sage/quivers/paths.cpython-313-x86_64-linux-gnu.so +0 -0
  269. sage/quivers/paths.pxd +13 -0
  270. sage/quivers/paths.pyx +809 -0
  271. sage/quivers/representation.py +2975 -0
  272. sage/rings/all__sagemath_flint.py +37 -0
  273. sage/rings/cif.py +4 -0
  274. sage/rings/complex_arb.cpython-313-x86_64-linux-gnu.so +0 -0
  275. sage/rings/complex_arb.pxd +29 -0
  276. sage/rings/complex_arb.pyx +5176 -0
  277. sage/rings/complex_interval.cpython-313-x86_64-linux-gnu.so +0 -0
  278. sage/rings/complex_interval.pxd +30 -0
  279. sage/rings/complex_interval.pyx +2475 -0
  280. sage/rings/complex_interval_field.py +711 -0
  281. sage/rings/convert/all.py +1 -0
  282. sage/rings/convert/mpfi.cpython-313-x86_64-linux-gnu.so +0 -0
  283. sage/rings/convert/mpfi.pxd +6 -0
  284. sage/rings/convert/mpfi.pyx +576 -0
  285. sage/rings/factorint_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  286. sage/rings/factorint_flint.pyx +99 -0
  287. sage/rings/fraction_field_FpT.cpython-313-x86_64-linux-gnu.so +0 -0
  288. sage/rings/fraction_field_FpT.pxd +28 -0
  289. sage/rings/fraction_field_FpT.pyx +2043 -0
  290. sage/rings/imaginary_unit.py +5 -0
  291. sage/rings/monomials.py +73 -0
  292. sage/rings/number_field/S_unit_solver.py +2870 -0
  293. sage/rings/number_field/all__sagemath_flint.py +7 -0
  294. sage/rings/number_field/bdd_height.py +664 -0
  295. sage/rings/number_field/class_group.py +762 -0
  296. sage/rings/number_field/galois_group.py +1307 -0
  297. sage/rings/number_field/homset.py +612 -0
  298. sage/rings/number_field/maps.py +687 -0
  299. sage/rings/number_field/morphism.py +272 -0
  300. sage/rings/number_field/number_field.py +12820 -0
  301. sage/rings/number_field/number_field_element.cpython-313-x86_64-linux-gnu.so +0 -0
  302. sage/rings/number_field/number_field_element.pxd +59 -0
  303. sage/rings/number_field/number_field_element.pyx +5735 -0
  304. sage/rings/number_field/number_field_element_quadratic.cpython-313-x86_64-linux-gnu.so +0 -0
  305. sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
  306. sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
  307. sage/rings/number_field/number_field_ideal_rel.py +925 -0
  308. sage/rings/number_field/number_field_morphisms.cpython-313-x86_64-linux-gnu.so +0 -0
  309. sage/rings/number_field/number_field_morphisms.pyx +781 -0
  310. sage/rings/number_field/number_field_rel.py +2734 -0
  311. sage/rings/number_field/order.py +2981 -0
  312. sage/rings/number_field/order_ideal.py +804 -0
  313. sage/rings/number_field/selmer_group.py +715 -0
  314. sage/rings/number_field/small_primes_of_degree_one.py +242 -0
  315. sage/rings/number_field/splitting_field.py +606 -0
  316. sage/rings/number_field/structure.py +380 -0
  317. sage/rings/number_field/unit_group.py +721 -0
  318. sage/rings/padics/all__sagemath_flint.py +3 -0
  319. sage/rings/polynomial/all__sagemath_flint.py +1 -0
  320. sage/rings/polynomial/complex_roots.py +312 -0
  321. sage/rings/polynomial/evaluation_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  322. sage/rings/polynomial/evaluation_flint.pxd +7 -0
  323. sage/rings/polynomial/evaluation_flint.pyx +68 -0
  324. sage/rings/polynomial/hilbert.cpython-313-x86_64-linux-gnu.so +0 -0
  325. sage/rings/polynomial/hilbert.pyx +602 -0
  326. sage/rings/polynomial/polynomial_complex_arb.cpython-313-x86_64-linux-gnu.so +0 -0
  327. sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
  328. sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
  329. sage/rings/polynomial/polynomial_integer_dense_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  330. sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
  331. sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
  332. sage/rings/polynomial/polynomial_number_field.cpython-313-x86_64-linux-gnu.so +0 -0
  333. sage/rings/polynomial/polynomial_number_field.pyx +345 -0
  334. sage/rings/polynomial/polynomial_rational_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  335. sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
  336. sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
  337. sage/rings/polynomial/polynomial_zmod_flint.cpython-313-x86_64-linux-gnu.so +0 -0
  338. sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
  339. sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
  340. sage/rings/polynomial/real_roots.cpython-313-x86_64-linux-gnu.so +0 -0
  341. sage/rings/polynomial/real_roots.pxd +81 -0
  342. sage/rings/polynomial/real_roots.pyx +4704 -0
  343. sage/rings/polynomial/refine_root.cpython-313-x86_64-linux-gnu.so +0 -0
  344. sage/rings/polynomial/refine_root.pyx +142 -0
  345. sage/rings/polynomial/weil/all.py +4 -0
  346. sage/rings/polynomial/weil/power_sums.h +46 -0
  347. sage/rings/polynomial/weil/weil_polynomials.cpython-313-x86_64-linux-gnu.so +0 -0
  348. sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
  349. sage/rings/qqbar.py +9025 -0
  350. sage/rings/real_arb.cpython-313-x86_64-linux-gnu.so +0 -0
  351. sage/rings/real_arb.pxd +21 -0
  352. sage/rings/real_arb.pyx +4065 -0
  353. sage/rings/real_interval_absolute.cpython-313-x86_64-linux-gnu.so +0 -0
  354. sage/rings/real_interval_absolute.pyx +1073 -0
  355. sage/rings/real_mpfi.cpython-313-x86_64-linux-gnu.so +0 -0
  356. sage/rings/real_mpfi.pyx +5428 -0
  357. sage/schemes/all__sagemath_flint.py +1 -0
  358. sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
  359. sage/schemes/elliptic_curves/descent_two_isogeny.cpython-313-x86_64-linux-gnu.so +0 -0
  360. sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
  361. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,715 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.libs.pari
3
+ r"""
4
+ `p`-Selmer groups of number fields
5
+
6
+ This file contains code to compute `K(S,p)` where
7
+
8
+ - `K` is a number field
9
+ - `S` is a finite set of primes of `K`
10
+ - `p` is a prime number
11
+
12
+ For `m\ge2`, `K(S,m)` is defined to be the finite subgroup of
13
+ `K^*/(K^*)^m` consisting of elements represented by `a\in K^*` whose
14
+ valuation at all primes not in `S` is a multiple of `m`. It fits in
15
+ the short exact sequence
16
+
17
+ .. MATH::
18
+
19
+ 1 \rightarrow O^*_{K,S}/(O^*_{K,S})^m \rightarrow K(S,m) \rightarrow Cl_{K,S}[m] \rightarrow 1
20
+
21
+ where `O^*_{K,S}` is the group of `S`-units of `K` and `Cl_{K,S}` the
22
+ `S`-class group. When `m=p` is prime, `K(S,p)` is a
23
+ finite-dimensional vector space over `GF(p)`. Its generators come
24
+ from three sources: units (modulo `p`-th powers); generators of the
25
+ `p`-th powers of ideals which are not principal but whose `p`-th
26
+ powers are principal; and generators coming from the prime ideals in
27
+ `S`.
28
+
29
+ The main function here is :meth:`pSelmerGroup`. This will not
30
+ normally be used by users, who instead will access it through a method
31
+ of the NumberField class.
32
+
33
+
34
+ AUTHORS:
35
+
36
+ - John Cremona (2005-2021)
37
+ """
38
+
39
+ # ****************************************************************************
40
+ # Copyright (C) 2021 John Cremona <john.cremona@gmail.com>
41
+ #
42
+ # Distributed under the terms of the GNU General Public License (GPL)
43
+ # as published by the Free Software Foundation; either version 2 of
44
+ # the License, or (at your option) any later version.
45
+ # https://www.gnu.org/licenses/
46
+ # ****************************************************************************
47
+
48
+
49
+ from sage.rings.finite_rings.finite_field_constructor import GF
50
+ from sage.rings.rational_field import QQ
51
+ from sage.misc.misc_c import prod
52
+
53
+ # A utility function to allow the same code to be used over QQ and
54
+ # over number fields:
55
+
56
+
57
+ def _ideal_generator(I):
58
+ r"""
59
+ Return the generator of a principal ideal.
60
+
61
+ INPUT:
62
+
63
+ - ``I`` -- either a fractional ideal of a number field, which must be
64
+ principal, or a rational integer
65
+
66
+ OUTPUT: a generator of `I` when `I` is a principal ideal, else `I` itself
67
+
68
+ EXAMPLES::
69
+
70
+ sage: from sage.rings.number_field.selmer_group import _ideal_generator
71
+ sage: _ideal_generator(5)
72
+ 5
73
+
74
+ sage: K.<a> = QuadraticField(-11)
75
+ sage: [_ideal_generator(K.prime_above(p)) for p in primes(25)]
76
+ [2, 1/2*a - 1/2, -1/2*a - 3/2, 7, a, 13, 17, 19, 1/2*a + 9/2]
77
+ """
78
+ try:
79
+ return I.gens_reduced()[0]
80
+ except AttributeError:
81
+ return I.abs()
82
+
83
+
84
+ def _coords_in_C_p(I, C, p):
85
+ r"""
86
+ Return coordinates of the ideal ``I`` with respect to a basis of
87
+ the `p`-torsion of the ideal class group ``C``.
88
+
89
+ INPUT:
90
+
91
+ - ``I`` -- ideal; a fractional ideal of a number field ``K``, whose
92
+ `p`-th power is principal
93
+
94
+ - ``C`` -- (class group) the ideal class group of ``K``
95
+
96
+ - ``p`` -- prime number
97
+
98
+ OUTPUT:
99
+
100
+ The coordinates of the ideal class `[I]` in the `p`-torsion
101
+ subgroup `C[p]`. An error is raised if `I^p` is not principal.
102
+
103
+ ALGORITHM:
104
+
105
+ Find the coordinates of `[I]` with respect to generators of `C` as
106
+ an abelian group, check that coordinates are 0 in cyclic factors
107
+ of order prime to `p`, and return the list of `c/(n/p)` (mod `p`)
108
+ for coordinates `c` for each cyclic factor of order `n` which is a
109
+ multiple of `p`.
110
+
111
+ EXAMPLES::
112
+
113
+ sage: from sage.rings.number_field.selmer_group import _coords_in_C_p
114
+ sage: K.<a> = QuadraticField(-5)
115
+ sage: C = K.class_group()
116
+ sage: C.order()
117
+ 2
118
+ sage: P = K.prime_above(2)
119
+ sage: C(P).order()
120
+ 2
121
+ sage: _coords_in_C_p(P,C,2)
122
+ [1]
123
+ sage: _coords_in_C_p(P,C,3)
124
+ Traceback (most recent call last):
125
+ ...
126
+ ValueError: The 3rd power of Fractional ideal (2, a + 1) is not principal
127
+ """
128
+ cyclic_orders = C.gens_orders()
129
+ non_p_indices = [i for i,n in enumerate(cyclic_orders) if not p.divides(n)]
130
+ p_indices = [(i, n // p) for i,n in enumerate(cyclic_orders) if p.divides(n)]
131
+
132
+ coords = C(I).exponents()
133
+ if all(coords[i] == 0 for i in non_p_indices) and all(coords[i] % n == 0 for i, n in p_indices):
134
+ return [(coords[i] // n) % p for i, n in p_indices]
135
+ raise ValueError("The {} power of {} is not principal".format(p.ordinal_str(),I))
136
+
137
+
138
+ def _coords_in_C_mod_p(I, C, p):
139
+ r"""
140
+ Return coordinates of the ideal ``I`` with respect to a basis of
141
+ the `p`-cotorsion of the ideal class group ``C``.
142
+
143
+ INPUT:
144
+
145
+ - ``I`` -- ideal; a fractional ideal of a number field ``K``
146
+
147
+ - ``C`` -- (class group) the ideal class group of ``K``
148
+
149
+ - ``p`` -- prime number
150
+
151
+ OUTPUT:
152
+
153
+ The coordinates of the ideal class `[I]` in the `p`-cotorsion group `C/C^p`.
154
+
155
+ ALGORITHM:
156
+
157
+ Find the coordinates of `[I]` with respect to generators of `C` as
158
+ an abelian group, and return the list of `c` (mod `p`)
159
+ for coordinates `c` for each cyclic factor of order `n` which is a
160
+ multiple of `p`.
161
+
162
+ EXAMPLES::
163
+
164
+ sage: from sage.rings.number_field.selmer_group import _coords_in_C_mod_p
165
+ sage: K.<a> = QuadraticField(-5)
166
+ sage: C = K.class_group()
167
+ sage: [_coords_in_C_mod_p(K.prime_above(p), C, 2) for p in primes(25)]
168
+ [[1], [1], [0], [1], [0], [0], [0], [0], [1]]
169
+
170
+ An example where the class group has two primary components, one
171
+ of which is not cyclic::
172
+
173
+ sage: from sage.rings.number_field.selmer_group import _coords_in_C_mod_p
174
+ sage: x = polygen(ZZ, 'x')
175
+ sage: K.<a> = NumberField(x^2 - x + 58)
176
+ sage: C = K.class_group()
177
+ sage: C.gens_orders()
178
+ (6, 2)
179
+ sage: [_coords_in_C_mod_p(K.prime_above(p), C, 2) for p in primes(25)]
180
+ [[1, 0], [1, 1], [1, 1], [0, 1], [1, 0], [0, 1], [0, 0], [0, 1], [0, 0]]
181
+ sage: [_coords_in_C_mod_p(K.prime_above(p), C, 3) for p in primes(25)]
182
+ [[2], [0], [1], [0], [0], [1], [0], [2], [0]]
183
+ """
184
+ cyclic_orders = C.gens_orders()
185
+ p_indices = [i for i, n in enumerate(cyclic_orders) if p.divides(n)]
186
+ coords = C(I).exponents()
187
+ return [coords[i] % p for i in p_indices]
188
+
189
+
190
+ def _root_ideal(I, C, p):
191
+ r"""
192
+ Return a `p`-th root of an ideal with respect to the class group.
193
+
194
+ INPUT:
195
+
196
+ - ``I`` -- ideal; a fractional ideal of a number field ``K``,
197
+ whose ideal class is a `p`-th power
198
+
199
+ - ``C`` -- (class group) the ideal class group of ``K``
200
+
201
+ - ``p`` -- prime number
202
+
203
+ OUTPUT: an ideal `J` such that `J^p` is in the same ideal class as `I`
204
+
205
+ EXAMPLES::
206
+
207
+ sage: from sage.rings.number_field.selmer_group import _root_ideal
208
+ sage: x = polygen(ZZ, 'x')
209
+ sage: K.<a> = NumberField(x^2 - x + 58)
210
+ sage: C = K.class_group()
211
+ sage: cyclic_gens = C.gens_ideals()
212
+ sage: [C(I).order() for I in cyclic_gens]
213
+ [6, 2]
214
+ sage: C.gens_orders()
215
+ (6, 2)
216
+ sage: I = cyclic_gens[0]^2
217
+ sage: J = _root_ideal(I, C, 2)
218
+ sage: C(J^2) == C(I)
219
+ True
220
+ sage: I = cyclic_gens[0]^3
221
+ sage: J = _root_ideal(I, C, 3)
222
+ sage: C(J^3) == C(I)
223
+ True
224
+ """
225
+ cyclic_orders = C.gens_orders()
226
+ cyclic_gens = C.gens_ideals()
227
+ coords = C(I).exponents()
228
+
229
+ # In the next line, e=(ci/p)%n should satisfy p*e=ci (mod n): we
230
+ # are dividing the coordinate vector by p in the appropriate sense
231
+
232
+ if not all(p.divides(ci) for ci, n in zip(coords, cyclic_orders) if p.divides(n)):
233
+ raise ValueError("The ideal class of {} is not a {} power".format(I,p.ordinal_str()))
234
+
235
+ w = [ci // p if p.divides(n) else (ci / p) % n for ci, n in zip(coords, cyclic_orders)]
236
+
237
+ return prod([gen ** wi for wi, gen in zip(w, cyclic_gens)], C.number_field().ideal(1))
238
+
239
+
240
+ def coords_in_U_mod_p(u, U, p):
241
+ r"""
242
+ Return coordinates of a unit ``u`` with respect to a basis of the
243
+ `p`-cotorsion `U/U^p` of the unit group ``U``.
244
+
245
+ INPUT:
246
+
247
+ - ``u`` -- (algebraic unit) a unit in a number field ``K``
248
+
249
+ - ``U`` -- (unit group) the unit group of ``K``
250
+
251
+ - ``p`` -- prime number
252
+
253
+ OUTPUT:
254
+
255
+ The coordinates of the unit `u` in the `p`-cotorsion group `U/U^p`.
256
+
257
+ ALGORITHM:
258
+
259
+ Take the coordinate vector of `u` with respect to the generators
260
+ of the unit group, drop the coordinate of the roots of unity
261
+ factor if it is prime to `p`, and reduce the vector mod `p`.
262
+
263
+ EXAMPLES::
264
+
265
+ sage: from sage.rings.number_field.selmer_group import coords_in_U_mod_p
266
+ sage: x = polygen(ZZ, 'x')
267
+ sage: K.<a> = NumberField(x^4 - 5*x^2 + 1)
268
+ sage: U = K.unit_group()
269
+ sage: U
270
+ Unit group with structure C2 x Z x Z x Z of Number Field in a with defining polynomial x^4 - 5*x^2 + 1
271
+ sage: u0, u1, u2, u3 = U.gens_values()
272
+ sage: u = u1*u2^2*u3^3
273
+ sage: coords_in_U_mod_p(u,U,2)
274
+ [0, 1, 0, 1]
275
+ sage: coords_in_U_mod_p(u,U,3)
276
+ [1, 2, 0]
277
+ sage: u*=u0
278
+ sage: coords_in_U_mod_p(u,U,2)
279
+ [1, 1, 0, 1]
280
+ sage: coords_in_U_mod_p(u,U,3)
281
+ [1, 2, 0]
282
+ """
283
+ coords = U.log(u)
284
+ start = 1 - int(p.divides(U.zeta_order())) # 0 or 1
285
+ return [c % p for c in coords[start:]]
286
+
287
+
288
+ def basis_for_p_cokernel(S, C, p):
289
+ r"""
290
+ Return a basis for the group of ideals supported on ``S`` (mod
291
+ `p`-th-powers) whose class in the class group ``C`` is a `p`-th power,
292
+ together with a function which takes the ``S``-exponents of such an
293
+ ideal and returns its coordinates on this basis.
294
+
295
+ INPUT:
296
+
297
+ - ``S`` -- list of prime ideals in a number field ``K``
298
+
299
+ - ``C`` -- (class group) the ideal class group of ``K``
300
+
301
+ - ``p`` -- prime number
302
+
303
+ OUTPUT:
304
+
305
+ (tuple) (``b``, ``f``) where
306
+
307
+ - ``b`` is a list of ideals which is a basis for the group of
308
+ ideals supported on ``S`` (modulo `p`-th powers) whose ideal
309
+ class is a `p`-th power;
310
+
311
+ - ``f`` is a function which takes such an ideal and returns its
312
+ coordinates with respect to this basis.
313
+
314
+ EXAMPLES::
315
+
316
+ sage: from sage.rings.number_field.selmer_group import basis_for_p_cokernel
317
+ sage: x = polygen(ZZ, 'x')
318
+ sage: K.<a> = NumberField(x^2 - x + 58)
319
+ sage: S = K.ideal(30).support(); S
320
+ [Fractional ideal (2, a),
321
+ Fractional ideal (2, a + 1),
322
+ Fractional ideal (3, a + 1),
323
+ Fractional ideal (5, a + 1),
324
+ Fractional ideal (5, a + 3)]
325
+ sage: C = K.class_group()
326
+ sage: C.gens_orders()
327
+ (6, 2)
328
+ sage: [C(P).exponents() for P in S]
329
+ [(5, 0), (1, 0), (3, 1), (1, 1), (5, 1)]
330
+ sage: b, f = basis_for_p_cokernel(S, C, 2); b
331
+ [Fractional ideal (2), Fractional ideal (15, a + 13), Fractional ideal (5)]
332
+ sage: b, f = basis_for_p_cokernel(S, C, 3); b
333
+ [Fractional ideal (50, a + 18),
334
+ Fractional ideal (10, a + 3),
335
+ Fractional ideal (3, a + 1),
336
+ Fractional ideal (5)]
337
+ sage: b, f = basis_for_p_cokernel(S, C, 5); b
338
+ [Fractional ideal (2, a),
339
+ Fractional ideal (2, a + 1),
340
+ Fractional ideal (3, a + 1),
341
+ Fractional ideal (5, a + 1),
342
+ Fractional ideal (5, a + 3)]
343
+ """
344
+ from sage.matrix.constructor import Matrix
345
+ M = Matrix(GF(p), [_coords_in_C_mod_p(P, C, p) for P in S])
346
+ k = M.left_kernel()
347
+ bas = [prod([P ** bj.lift() for P, bj in zip(S, b.list())],
348
+ C.number_field().ideal(1)) for b in k.basis()]
349
+ return bas, k.coordinate_vector
350
+
351
+ # The main function
352
+
353
+
354
+ def pSelmerGroup(K, S, p, proof=None, debug=False):
355
+ r"""
356
+ Return the `p`-Selmer group `K(S,p)` of the number field `K`
357
+ with respect to the prime ideals in ``S``.
358
+
359
+ INPUT:
360
+
361
+ - ``K`` -- a number field or `\QQ`
362
+
363
+ - ``S`` -- list of prime ideals in `K`, or prime
364
+ numbers when `K` is `\QQ`
365
+
366
+ - ``p`` -- a prime number
367
+
368
+ - ``proof`` -- if ``True``, compute the class group provably
369
+ correctly. Default is ``True``. Call :meth:`proof.number_field` to
370
+ change this default globally.
371
+
372
+ - ``debug`` -- boolean (default: ``False``); debug flag
373
+
374
+ OUTPUT:
375
+
376
+ (tuple) ``KSp``, ``KSp_gens``, ``from_KSp``, ``to_KSp`` where
377
+
378
+ - ``KSp`` is an abstract vector space over `GF(p)` isomorphic to `K(S,p)`;
379
+
380
+ - ``KSp_gens`` is a list of elements of `K^*` generating `K(S,p)`;
381
+
382
+ - ``from_KSp`` is a function from ``KSp`` to `K^*` implementing
383
+ the isomorphism from the abstract `K(S,p)` to `K(S,p)` as a
384
+ subgroup of `K^*/(K^*)^p`;
385
+
386
+ - ``to_KSP`` is a partial function from `K^*` to ``KSp``, defined
387
+ on elements `a` whose image in `K^*/(K^*)^p` lies in `K(S,p)`,
388
+ mapping them via the inverse isomorphism to the abstract vector
389
+ space ``KSp``.
390
+
391
+ ALGORITHM:
392
+
393
+ The list of generators of `K(S,p)` is the concatenation of three
394
+ sublists, called ``alphalist``, ``betalist`` and ``ulist`` in the
395
+ code. Only ``alphalist`` depends on the primes in `S`.
396
+
397
+ - ``ulist`` is a basis for `U/U^p` where `U` is the unit group.
398
+ This is the list of fundamental units, including the generator
399
+ of the group of roots of unity if its order is divisible by `p`.
400
+ These have valuation `0` at all primes.
401
+
402
+ - ``betalist`` is a list of the generators of the `p`-th powers of
403
+ ideals which generate the `p`-torsion in the class group (so is
404
+ empty if the class number is prime to `p`). These have
405
+ valuation divisible by `p` at all primes.
406
+
407
+ - ``alphalist`` is a list of generators for each ideal `A` in a
408
+ basis of those ideals supported on `S` (modulo `p`-th powers of
409
+ ideals) which are `p`-th powers in the class group. We find `B`
410
+ such that `A/B^p` is principal and take a generator of it, for
411
+ each `A` in a generating set. As a special case, if all the
412
+ ideals in `S` are principal then ``alphalist`` is a list of
413
+ their generators.
414
+
415
+ The map from the abstract space to `K^*` is easy: we just take the
416
+ product of the generators to powers given by the coefficient
417
+ vector. No attempt is made to reduce the resulting product modulo
418
+ `p`-th powers.
419
+
420
+ The reverse map is more complicated. Given `a\in K^*`:
421
+
422
+ - write the principal ideal `(a)` in the form `AB^p` with `A`
423
+ supported by `S` and `p`-th power free. If this fails, then `a`
424
+ does not represent an element of `K(S,p)` and an error is
425
+ raised.
426
+
427
+ - set `I_S` to be the group of ideals spanned by `S` mod `p`-th
428
+ powers, and `I_{S,p}` the subgroup of `I_S` which maps to `0` in
429
+ `C/C^p`.
430
+
431
+ - Convert `A` to an element of `I_{S,p}`, hence find the
432
+ coordinates of `a` with respect to the generators in
433
+ ``alphalist``.
434
+
435
+ - after dividing out by `A`, now `(a)=B^p` (with a different `a`
436
+ and `B`). Write the ideal class `[B]`, whose `p`-th power is
437
+ trivial, in terms of the generators of `C[p]`; then `B=(b)B_1`,
438
+ where the coefficients of `B_1` with respect to generators of
439
+ `C[p]` give the coordinates of the result with respect to the
440
+ generators in ``betalist``.
441
+
442
+ - after dividing out by `B`, and by `b^p`, we now have `(a)=(1)`,
443
+ so `a` is a unit, which can be expressed in terms of the unit
444
+ generators.
445
+
446
+ EXAMPLES:
447
+
448
+ Over `\QQ` the unit contribution is trivial unless `p=2` and
449
+ the class group is trivial::
450
+
451
+ sage: from sage.rings.number_field.selmer_group import pSelmerGroup
452
+ sage: QS2, gens, fromQS2, toQS2 = pSelmerGroup(QQ, [2,3], 2)
453
+ sage: QS2
454
+ Vector space of dimension 3 over Finite Field of size 2
455
+ sage: gens
456
+ [2, 3, -1]
457
+ sage: a = fromQS2([1,1,1]); a.factor()
458
+ -1 * 2 * 3
459
+ sage: toQS2(-6)
460
+ (1, 1, 1)
461
+
462
+ sage: QS3, gens, fromQS3, toQS3 = pSelmerGroup(QQ, [2,13], 3)
463
+ sage: QS3
464
+ Vector space of dimension 2 over Finite Field of size 3
465
+ sage: gens
466
+ [2, 13]
467
+ sage: a = fromQS3([5,4]); a.factor()
468
+ 2^5 * 13^4
469
+ sage: toQS3(a)
470
+ (2, 1)
471
+ sage: toQS3(a) == QS3([5,4])
472
+ True
473
+
474
+ A real quadratic field with class number 2, where the fundamental
475
+ unit is a generator, and the class group provides another
476
+ generator when `p=2`::
477
+
478
+ sage: K.<a> = QuadraticField(-5)
479
+ sage: K.class_number()
480
+ 2
481
+ sage: P2 = K.ideal(2, -a+1)
482
+ sage: P3 = K.ideal(3, a+1)
483
+ sage: P5 = K.ideal(a)
484
+ sage: KS2, gens, fromKS2, toKS2 = pSelmerGroup(K, [P2, P3, P5], 2)
485
+ sage: KS2
486
+ Vector space of dimension 4 over Finite Field of size 2
487
+ sage: gens
488
+ [a + 1, a, 2, -1]
489
+
490
+ Each generator must have even valuation at primes not in `S`::
491
+
492
+ sage: [K.ideal(g).factor() for g in gens]
493
+ [(Fractional ideal (2, a + 1)) * (Fractional ideal (3, a + 1)),
494
+ Fractional ideal (-a),
495
+ (Fractional ideal (2, a + 1))^2,
496
+ 1]
497
+
498
+ sage: toKS2(10)
499
+ (0, 0, 1, 1)
500
+ sage: fromKS2([0,0,1,1])
501
+ -2
502
+ sage: K(10/(-2)).is_square()
503
+ True
504
+
505
+ sage: KS3, gens, fromKS3, toKS3 = pSelmerGroup(K, [P2, P3, P5], 3)
506
+ sage: KS3
507
+ Vector space of dimension 3 over Finite Field of size 3
508
+ sage: gens
509
+ [1/2, 1/4*a + 1/4, a]
510
+
511
+ The ``to`` and ``from`` maps are inverses of each other::
512
+
513
+ sage: K.<a> = QuadraticField(-5)
514
+ sage: S = K.ideal(30).support()
515
+ sage: KS2, gens, fromKS2, toKS2 = pSelmerGroup(K, S, 2)
516
+ sage: KS2
517
+ Vector space of dimension 5 over Finite Field of size 2
518
+ sage: assert all(toKS2(fromKS2(v))==v for v in KS2)
519
+ sage: KS3, gens, fromKS3, toKS3 = pSelmerGroup(K, S, 3)
520
+ sage: KS3
521
+ Vector space of dimension 4 over Finite Field of size 3
522
+ sage: assert all(toKS3(fromKS3(v))==v for v in KS3)
523
+ """
524
+ from sage.rings.number_field.number_field import proof_flag
525
+ from sage.modules.free_module import VectorSpace
526
+ from sage.sets.set import Set
527
+
528
+ proof = proof_flag(proof)
529
+
530
+ # Input check: p and all P in S must be prime. Remove any repeats in S.
531
+
532
+ S = list(Set(S))
533
+ if not all(P.is_prime() for P in S):
534
+ raise ValueError("elements of S must all be prime")
535
+ if not p.is_prime():
536
+ raise ValueError("p must be prime")
537
+
538
+ F = GF(p)
539
+
540
+ # Step 1. The unit contribution: all fundamental units, and also the
541
+ # generating root of unity if its order is a multiple of p; we just
542
+ # take generators of U/U^p. These have valuation 0 everywhere.
543
+
544
+ hK = 1 if K == QQ else K.class_number(proof=proof)
545
+ C = K.class_group() if K == QQ else K.class_group(proof=proof)
546
+
547
+ hKp = (hK % p == 0) # flag whether the class number is divisible by p
548
+
549
+ if K == QQ:
550
+ if p == 2:
551
+ ulist = [QQ(-1)]
552
+ else:
553
+ ulist = []
554
+ else:
555
+ U = K.unit_group(proof=proof)
556
+ ulist = U.gens_values()
557
+ if U.zeta_order() % p:
558
+ ulist = ulist[1:]
559
+
560
+ if debug:
561
+ print("{} generators in ulist = {}".format(len(ulist),ulist))
562
+
563
+ # Step 2. The class group contribution: generators of the p'th
564
+ # powers of ideals generating the p-torsion in the class group.
565
+ # These have valuation divisible by p everywhere.
566
+
567
+ if hKp:
568
+ betalist = [_ideal_generator(c ** n)
569
+ for c, n in zip(C.gens_ideals(), C.gens_orders())
570
+ if n % p == 0]
571
+ else:
572
+ betalist = []
573
+
574
+ if debug:
575
+ print("{} generators in betalist = {}".format(len(betalist),betalist))
576
+
577
+ # Step 3. The part depending on S: one generator for each ideal A
578
+ # in a basis of those ideals supported on S (modulo p'th powers of
579
+ # ideals) which is a p'th power in the class group. We find B
580
+ # such that A/B^p is principal and take a generator of that, for
581
+ # each A in a generating set.
582
+
583
+ # As a special case, when the class number is 1 we just take
584
+ # generators of the primes in S.
585
+
586
+ if hK > 1:
587
+ T, f = basis_for_p_cokernel(S, C, p)
588
+ alphalist = [_ideal_generator(I / _root_ideal(I, C, p) ** p) for I in T]
589
+ else:
590
+ f = lambda x:x
591
+ alphalist = [_ideal_generator(P) for P in S]
592
+
593
+ if debug:
594
+ print("{} generators in alphalist = {}".format(len(alphalist), alphalist))
595
+
596
+ # Now we have the generators of K(S,p), and define K(S,p) as an
597
+ # abstract vector space:
598
+
599
+ KSp_gens = alphalist + betalist + ulist
600
+ KSp = VectorSpace(GF(p), len(KSp_gens))
601
+
602
+ if debug:
603
+ print("Generators of K(S,p) = {} (dimension {})".format(KSp_gens, len(KSp_gens)))
604
+
605
+ # Now we define maps in each direction between the abstract space and K^*.
606
+
607
+ # Define the easy map from KSp into K^*:
608
+
609
+ def from_KSp(v):
610
+ return prod([g ** vi for g, vi in zip(KSp_gens, v)], K(1))
611
+
612
+ # Define the hard map from (a subgroup of) K^* to KSp:
613
+
614
+ def to_KSp(a):
615
+ # Check that a is in K(S,p):
616
+
617
+ if not a:
618
+ raise ValueError("argument {} should be nonzero".format(a))
619
+ try:
620
+ a = K(a)
621
+ except ValueError:
622
+ raise ValueError("argument {} should be in {}".format(a, K))
623
+
624
+ if not all(P in S or a.valuation(P) % p == 0 for P in a.support()):
625
+ raise ValueError("argument {} should have valuations divisible by {} at all primes in {}".format(a, p, S))
626
+
627
+ # 1. (a) is a p'th power mod ideals in S, say (a)=AB^p, where
628
+ # A is supported on S and is a linear combination of the
629
+ # ideals T above. Find the exponents of the P_i in S in A:
630
+
631
+ S_vals = [F(a.valuation(P)) for P in S]
632
+ avec = list(f(S_vals)) # coordinates of A w.r.t ideals in T (mod p'th powers)
633
+ a1 = prod((alpha ** e for alpha, e in zip(alphalist,avec)), K(1))
634
+ a /= a1
635
+ if debug:
636
+ print("alpha component is {} with coords {}".format(a1,avec))
637
+ if K == QQ:
638
+ print("continuing with quotient {} whose ideal should be a {}'th power: {}".format(a,p,a.factor()))
639
+ else:
640
+ print("continuing with quotient {} whose ideal should be a {}'th power: {}".format(a,p,K.ideal(a).factor()))
641
+
642
+ # 2. Now (a) is a p'th power, say (a)=B^p.
643
+ # Find B and the exponents of [B] w.r.t. basis of C[p]:
644
+
645
+ supp = a.support()
646
+ vals = [a.valuation(P) for P in supp]
647
+ if debug:
648
+ assert all(v % p == 0 for v in vals)
649
+ one = K(1) if K == QQ else K.ideal(1)
650
+ aa = a.abs() if K == QQ else K.ideal(a)
651
+ B = prod((P ** (v // p) for P, v in zip(supp,vals)), one)
652
+ if debug:
653
+ assert B ** p == aa
654
+ print("B={}".format(B))
655
+ print("a={}".format(a))
656
+
657
+ if hKp:
658
+ bvec = _coords_in_C_p(B, C, p)
659
+ a2 = prod((beta ** e for beta, e in zip(betalist, bvec)), K(1))
660
+ a /= a2
661
+ supp = a.support()
662
+ vals = [a.valuation(P) for P in supp]
663
+ if debug:
664
+ assert all(v % p == 0 for v in vals)
665
+ B = prod((P ** (v // p) for P, v in zip(supp, vals)), one)
666
+ if debug:
667
+ assert B ** p == aa
668
+ else:
669
+ bvec = []
670
+ a2 = 1
671
+
672
+ if debug:
673
+ print("beta component is {} with coords {}".format(a2,bvec))
674
+ print("continuing with quotient {} which should be a p'th power times a unit".format(a))
675
+
676
+ # 3. Now (a) = (c)^p for some c, so a/c^p is a unit
677
+
678
+ if K != QQ:
679
+ assert B.is_principal()
680
+
681
+ if debug:
682
+ print("B={}".format(B))
683
+ a3 = B if K == QQ else _ideal_generator(B)
684
+ if debug:
685
+ print("a3={}".format(a3))
686
+ a /= a3 ** p
687
+ if debug:
688
+ print("dividing by {}th power of {}".format(p,a3))
689
+ print("continuing with quotient {} which should be a unit".format(a))
690
+
691
+ #4. Now a is a unit
692
+
693
+ # NB not a.is_unit which is true for all a in K^*. One could
694
+ # also test K.ring_of_integers()(a).is_unit().
695
+
696
+ if debug:
697
+ if K == QQ:
698
+ assert a.abs() == 1
699
+ else:
700
+ assert K.ideal(a).is_one()
701
+
702
+ if K == QQ:
703
+ if p == 2:
704
+ cvec = [1] if a == -1 else [0]
705
+ else:
706
+ cvec = []
707
+ else:
708
+ cvec = coords_in_U_mod_p(a,U,p)
709
+
710
+ if debug:
711
+ print("gamma component has coords {}".format(cvec))
712
+
713
+ return KSp(avec + bvec + cvec)
714
+
715
+ return KSp, KSp_gens, from_KSp, to_KSp