passagemath-flint 10.6.1rc10__cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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 (360) hide show
  1. passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
  2. passagemath_flint-10.6.1rc10.dist-info/RECORD +360 -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-3701249d.so.21.0.0 +0 -0
  6. passagemath_flint.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
  7. passagemath_flint.libs/libgfortran-8a9a71bc.so.5.0.0 +0 -0
  8. passagemath_flint.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
  9. passagemath_flint.libs/libgsl-e3525837.so.28.0.0 +0 -0
  10. passagemath_flint.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
  11. passagemath_flint.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
  12. passagemath_flint.libs/libntl-1004113e.so.44.0.1 +0 -0
  13. passagemath_flint.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  14. sage/all__sagemath_flint.py +29 -0
  15. sage/combinat/all__sagemath_flint.py +1 -0
  16. sage/combinat/posets/all__sagemath_flint.py +1 -0
  17. sage/combinat/posets/hasse_cython_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  18. sage/combinat/posets/hasse_cython_flint.pyx +194 -0
  19. sage/data_structures/all__sagemath_flint.py +1 -0
  20. sage/data_structures/bounded_integer_sequences.cpython-310-aarch64-linux-gnu.so +0 -0
  21. sage/data_structures/bounded_integer_sequences.pxd +62 -0
  22. sage/data_structures/bounded_integer_sequences.pyx +1418 -0
  23. sage/graphs/all__sagemath_flint.py +1 -0
  24. sage/graphs/chrompoly.cpython-310-aarch64-linux-gnu.so +0 -0
  25. sage/graphs/chrompoly.pyx +555 -0
  26. sage/graphs/matchpoly.cpython-310-aarch64-linux-gnu.so +0 -0
  27. sage/graphs/matchpoly.pyx +412 -0
  28. sage/libs/all__sagemath_flint.py +17 -0
  29. sage/libs/arb/__init__.py +1 -0
  30. sage/libs/arb/acb.pxd +154 -0
  31. sage/libs/arb/acb_calc.pxd +9 -0
  32. sage/libs/arb/acb_elliptic.pxd +25 -0
  33. sage/libs/arb/acb_hypgeom.pxd +74 -0
  34. sage/libs/arb/acb_mat.pxd +62 -0
  35. sage/libs/arb/acb_modular.pxd +17 -0
  36. sage/libs/arb/acb_poly.pxd +216 -0
  37. sage/libs/arb/arb.pxd +240 -0
  38. sage/libs/arb/arb_fmpz_poly.pxd +21 -0
  39. sage/libs/arb/arb_hypgeom.pxd +83 -0
  40. sage/libs/arb/arb_wrap.h +34 -0
  41. sage/libs/arb/arf.pxd +131 -0
  42. sage/libs/arb/arith.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/libs/arb/arith.pyx +87 -0
  44. sage/libs/arb/bernoulli.pxd +6 -0
  45. sage/libs/arb/mag.pxd +77 -0
  46. sage/libs/arb/types.pxd +37 -0
  47. sage/libs/flint/__init__.py +1 -0
  48. sage/libs/flint/acb.pxd +270 -0
  49. sage/libs/flint/acb_calc.pxd +22 -0
  50. sage/libs/flint/acb_dft.pxd +51 -0
  51. sage/libs/flint/acb_dirichlet.pxd +112 -0
  52. sage/libs/flint/acb_elliptic.pxd +42 -0
  53. sage/libs/flint/acb_hypgeom.pxd +169 -0
  54. sage/libs/flint/acb_macros.pxd +9 -0
  55. sage/libs/flint/acb_mat.pxd +136 -0
  56. sage/libs/flint/acb_mat_macros.pxd +10 -0
  57. sage/libs/flint/acb_modular.pxd +62 -0
  58. sage/libs/flint/acb_poly.pxd +251 -0
  59. sage/libs/flint/acb_poly_macros.pxd +8 -0
  60. sage/libs/flint/acb_theta.pxd +124 -0
  61. sage/libs/flint/acf.pxd +32 -0
  62. sage/libs/flint/aprcl.pxd +84 -0
  63. sage/libs/flint/arb.pxd +382 -0
  64. sage/libs/flint/arb_calc.pxd +31 -0
  65. sage/libs/flint/arb_fmpz_poly.pxd +34 -0
  66. sage/libs/flint/arb_fpwrap.pxd +215 -0
  67. sage/libs/flint/arb_hypgeom.pxd +147 -0
  68. sage/libs/flint/arb_macros.pxd +9 -0
  69. sage/libs/flint/arb_mat.pxd +140 -0
  70. sage/libs/flint/arb_mat_macros.pxd +10 -0
  71. sage/libs/flint/arb_poly.pxd +237 -0
  72. sage/libs/flint/arf.pxd +167 -0
  73. sage/libs/flint/arith.cpython-310-aarch64-linux-gnu.so +0 -0
  74. sage/libs/flint/arith.pxd +76 -0
  75. sage/libs/flint/arith.pyx +77 -0
  76. sage/libs/flint/arith_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  77. sage/libs/flint/arith_sage.pyx +308 -0
  78. sage/libs/flint/bernoulli.pxd +28 -0
  79. sage/libs/flint/bool_mat.pxd +52 -0
  80. sage/libs/flint/ca.pxd +203 -0
  81. sage/libs/flint/ca_ext.pxd +34 -0
  82. sage/libs/flint/ca_field.pxd +32 -0
  83. sage/libs/flint/ca_mat.pxd +117 -0
  84. sage/libs/flint/ca_poly.pxd +104 -0
  85. sage/libs/flint/ca_vec.pxd +46 -0
  86. sage/libs/flint/calcium.pxd +27 -0
  87. sage/libs/flint/d_mat.pxd +39 -0
  88. sage/libs/flint/d_vec.pxd +32 -0
  89. sage/libs/flint/dirichlet.pxd +57 -0
  90. sage/libs/flint/dlog.pxd +53 -0
  91. sage/libs/flint/double_extras.pxd +24 -0
  92. sage/libs/flint/double_interval.pxd +36 -0
  93. sage/libs/flint/fexpr.pxd +104 -0
  94. sage/libs/flint/fexpr_builtin.pxd +20 -0
  95. sage/libs/flint/fft.pxd +66 -0
  96. sage/libs/flint/flint.pxd +36 -0
  97. sage/libs/flint/flint_ntl_wrap.h +35 -0
  98. sage/libs/flint/flint_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  99. sage/libs/flint/flint_sage.pyx +163 -0
  100. sage/libs/flint/flint_wrap.h +190 -0
  101. sage/libs/flint/fmpq.pxd +137 -0
  102. sage/libs/flint/fmpq_mat.pxd +105 -0
  103. sage/libs/flint/fmpq_mat_macros.pxd +10 -0
  104. sage/libs/flint/fmpq_mpoly.pxd +165 -0
  105. sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
  106. sage/libs/flint/fmpq_poly.pxd +241 -0
  107. sage/libs/flint/fmpq_poly_macros.pxd +9 -0
  108. sage/libs/flint/fmpq_poly_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  109. sage/libs/flint/fmpq_poly_sage.pxd +31 -0
  110. sage/libs/flint/fmpq_poly_sage.pyx +48 -0
  111. sage/libs/flint/fmpq_vec.pxd +27 -0
  112. sage/libs/flint/fmpz.pxd +256 -0
  113. sage/libs/flint/fmpz_extras.pxd +32 -0
  114. sage/libs/flint/fmpz_factor.pxd +42 -0
  115. sage/libs/flint/fmpz_factor_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  116. sage/libs/flint/fmpz_factor_sage.pxd +4 -0
  117. sage/libs/flint/fmpz_factor_sage.pyx +29 -0
  118. sage/libs/flint/fmpz_lll.pxd +49 -0
  119. sage/libs/flint/fmpz_macros.pxd +8 -0
  120. sage/libs/flint/fmpz_mat.pxd +184 -0
  121. sage/libs/flint/fmpz_mat_macros.pxd +10 -0
  122. sage/libs/flint/fmpz_mod.pxd +46 -0
  123. sage/libs/flint/fmpz_mod_mat.pxd +71 -0
  124. sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
  125. sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
  126. sage/libs/flint/fmpz_mod_poly.pxd +249 -0
  127. sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
  128. sage/libs/flint/fmpz_mod_vec.pxd +27 -0
  129. sage/libs/flint/fmpz_mpoly.pxd +224 -0
  130. sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
  131. sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
  132. sage/libs/flint/fmpz_poly.cpython-310-aarch64-linux-gnu.so +0 -0
  133. sage/libs/flint/fmpz_poly.pxd +407 -0
  134. sage/libs/flint/fmpz_poly.pyx +19 -0
  135. sage/libs/flint/fmpz_poly_factor.pxd +33 -0
  136. sage/libs/flint/fmpz_poly_macros.pxd +8 -0
  137. sage/libs/flint/fmpz_poly_mat.pxd +71 -0
  138. sage/libs/flint/fmpz_poly_q.pxd +55 -0
  139. sage/libs/flint/fmpz_poly_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  140. sage/libs/flint/fmpz_poly_sage.pxd +20 -0
  141. sage/libs/flint/fmpz_poly_sage.pyx +500 -0
  142. sage/libs/flint/fmpz_vec.pxd +80 -0
  143. sage/libs/flint/fmpzi.pxd +52 -0
  144. sage/libs/flint/fq.pxd +97 -0
  145. sage/libs/flint/fq_default.pxd +84 -0
  146. sage/libs/flint/fq_default_mat.pxd +70 -0
  147. sage/libs/flint/fq_default_poly.pxd +97 -0
  148. sage/libs/flint/fq_default_poly_factor.pxd +39 -0
  149. sage/libs/flint/fq_embed.pxd +28 -0
  150. sage/libs/flint/fq_mat.pxd +83 -0
  151. sage/libs/flint/fq_nmod.pxd +95 -0
  152. sage/libs/flint/fq_nmod_embed.pxd +28 -0
  153. sage/libs/flint/fq_nmod_mat.pxd +83 -0
  154. sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
  155. sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
  156. sage/libs/flint/fq_nmod_poly.pxd +202 -0
  157. sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
  158. sage/libs/flint/fq_nmod_vec.pxd +33 -0
  159. sage/libs/flint/fq_poly.pxd +204 -0
  160. sage/libs/flint/fq_poly_factor.pxd +47 -0
  161. sage/libs/flint/fq_vec.pxd +33 -0
  162. sage/libs/flint/fq_zech.pxd +99 -0
  163. sage/libs/flint/fq_zech_embed.pxd +28 -0
  164. sage/libs/flint/fq_zech_mat.pxd +78 -0
  165. sage/libs/flint/fq_zech_poly.pxd +198 -0
  166. sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
  167. sage/libs/flint/fq_zech_vec.pxd +33 -0
  168. sage/libs/flint/gr.pxd +174 -0
  169. sage/libs/flint/gr_generic.pxd +215 -0
  170. sage/libs/flint/gr_mat.pxd +161 -0
  171. sage/libs/flint/gr_mpoly.pxd +68 -0
  172. sage/libs/flint/gr_poly.pxd +276 -0
  173. sage/libs/flint/gr_special.pxd +237 -0
  174. sage/libs/flint/gr_vec.pxd +120 -0
  175. sage/libs/flint/hypgeom.pxd +24 -0
  176. sage/libs/flint/long_extras.pxd +23 -0
  177. sage/libs/flint/mag.pxd +131 -0
  178. sage/libs/flint/mag_macros.pxd +8 -0
  179. sage/libs/flint/mpf_mat.pxd +36 -0
  180. sage/libs/flint/mpf_vec.pxd +34 -0
  181. sage/libs/flint/mpfr_mat.pxd +27 -0
  182. sage/libs/flint/mpfr_vec.pxd +25 -0
  183. sage/libs/flint/mpn_extras.pxd +41 -0
  184. sage/libs/flint/mpoly.pxd +72 -0
  185. sage/libs/flint/nf.pxd +19 -0
  186. sage/libs/flint/nf_elem.pxd +74 -0
  187. sage/libs/flint/nmod.pxd +35 -0
  188. sage/libs/flint/nmod_mat.pxd +104 -0
  189. sage/libs/flint/nmod_mpoly.pxd +144 -0
  190. sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
  191. sage/libs/flint/nmod_poly.pxd +339 -0
  192. sage/libs/flint/nmod_poly_factor.pxd +44 -0
  193. sage/libs/flint/nmod_poly_linkage.pxi +710 -0
  194. sage/libs/flint/nmod_poly_mat.pxd +76 -0
  195. sage/libs/flint/nmod_vec.pxd +40 -0
  196. sage/libs/flint/ntl_interface.pxd +17 -0
  197. sage/libs/flint/padic.pxd +93 -0
  198. sage/libs/flint/padic_mat.pxd +64 -0
  199. sage/libs/flint/padic_poly.pxd +88 -0
  200. sage/libs/flint/partitions.pxd +23 -0
  201. sage/libs/flint/perm.pxd +26 -0
  202. sage/libs/flint/profiler.pxd +24 -0
  203. sage/libs/flint/qadic.pxd +77 -0
  204. sage/libs/flint/qfb.pxd +44 -0
  205. sage/libs/flint/qqbar.pxd +172 -0
  206. sage/libs/flint/qsieve.cpython-310-aarch64-linux-gnu.so +0 -0
  207. sage/libs/flint/qsieve.pxd +41 -0
  208. sage/libs/flint/qsieve.pyx +21 -0
  209. sage/libs/flint/qsieve_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/libs/flint/qsieve_sage.pyx +67 -0
  211. sage/libs/flint/thread_pool.pxd +25 -0
  212. sage/libs/flint/types.pxd +2076 -0
  213. sage/libs/flint/ulong_extras.cpython-310-aarch64-linux-gnu.so +0 -0
  214. sage/libs/flint/ulong_extras.pxd +141 -0
  215. sage/libs/flint/ulong_extras.pyx +21 -0
  216. sage/libs/flint/ulong_extras_sage.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/libs/flint/ulong_extras_sage.pyx +21 -0
  218. sage/matrix/all__sagemath_flint.py +1 -0
  219. sage/matrix/change_ring.cpython-310-aarch64-linux-gnu.so +0 -0
  220. sage/matrix/change_ring.pyx +43 -0
  221. sage/matrix/matrix_complex_ball_dense.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/matrix/matrix_complex_ball_dense.pxd +14 -0
  223. sage/matrix/matrix_complex_ball_dense.pyx +973 -0
  224. sage/matrix/matrix_cyclo_dense.cpython-310-aarch64-linux-gnu.so +0 -0
  225. sage/matrix/matrix_cyclo_dense.pxd +16 -0
  226. sage/matrix/matrix_cyclo_dense.pyx +1761 -0
  227. sage/matrix/matrix_integer_dense.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/matrix/matrix_integer_dense.pxd +32 -0
  229. sage/matrix/matrix_integer_dense.pyx +5801 -0
  230. sage/matrix/matrix_integer_dense_hnf.py +1294 -0
  231. sage/matrix/matrix_integer_dense_saturation.py +346 -0
  232. sage/matrix/matrix_integer_sparse.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/matrix/matrix_integer_sparse.pxd +9 -0
  234. sage/matrix/matrix_integer_sparse.pyx +1090 -0
  235. sage/matrix/matrix_rational_dense.cpython-310-aarch64-linux-gnu.so +0 -0
  236. sage/matrix/matrix_rational_dense.pxd +23 -0
  237. sage/matrix/matrix_rational_dense.pyx +2995 -0
  238. sage/matrix/matrix_rational_sparse.cpython-310-aarch64-linux-gnu.so +0 -0
  239. sage/matrix/matrix_rational_sparse.pxd +11 -0
  240. sage/matrix/matrix_rational_sparse.pyx +789 -0
  241. sage/matrix/misc_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  242. sage/matrix/misc_flint.pyx +109 -0
  243. sage/modular/all__sagemath_flint.py +1 -0
  244. sage/modular/modform/all__sagemath_flint.py +1 -0
  245. sage/modular/modform/eis_series_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  246. sage/modular/modform/eis_series_cython.pyx +226 -0
  247. sage/modular/modsym/all__sagemath_flint.py +1 -0
  248. sage/modular/modsym/apply.cpython-310-aarch64-linux-gnu.so +0 -0
  249. sage/modular/modsym/apply.pxd +6 -0
  250. sage/modular/modsym/apply.pyx +113 -0
  251. sage/modular/modsym/heilbronn.cpython-310-aarch64-linux-gnu.so +0 -0
  252. sage/modular/modsym/heilbronn.pyx +966 -0
  253. sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
  254. sage/modular/pollack_stevens/dist.cpython-310-aarch64-linux-gnu.so +0 -0
  255. sage/modular/pollack_stevens/dist.pxd +38 -0
  256. sage/modular/pollack_stevens/dist.pyx +1439 -0
  257. sage/quivers/algebra.py +691 -0
  258. sage/quivers/algebra_elements.cpython-310-aarch64-linux-gnu.so +0 -0
  259. sage/quivers/algebra_elements.pxd +97 -0
  260. sage/quivers/algebra_elements.pxi +1324 -0
  261. sage/quivers/algebra_elements.pyx +1424 -0
  262. sage/quivers/all.py +1 -0
  263. sage/quivers/ar_quiver.py +917 -0
  264. sage/quivers/homspace.py +640 -0
  265. sage/quivers/morphism.py +1282 -0
  266. sage/quivers/path_semigroup.py +1155 -0
  267. sage/quivers/paths.cpython-310-aarch64-linux-gnu.so +0 -0
  268. sage/quivers/paths.pxd +13 -0
  269. sage/quivers/paths.pyx +809 -0
  270. sage/quivers/representation.py +2975 -0
  271. sage/rings/all__sagemath_flint.py +37 -0
  272. sage/rings/cif.py +4 -0
  273. sage/rings/complex_arb.cpython-310-aarch64-linux-gnu.so +0 -0
  274. sage/rings/complex_arb.pxd +29 -0
  275. sage/rings/complex_arb.pyx +5176 -0
  276. sage/rings/complex_interval.cpython-310-aarch64-linux-gnu.so +0 -0
  277. sage/rings/complex_interval.pxd +30 -0
  278. sage/rings/complex_interval.pyx +2475 -0
  279. sage/rings/complex_interval_field.py +711 -0
  280. sage/rings/convert/all.py +1 -0
  281. sage/rings/convert/mpfi.cpython-310-aarch64-linux-gnu.so +0 -0
  282. sage/rings/convert/mpfi.pxd +6 -0
  283. sage/rings/convert/mpfi.pyx +576 -0
  284. sage/rings/factorint_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  285. sage/rings/factorint_flint.pyx +99 -0
  286. sage/rings/fraction_field_FpT.cpython-310-aarch64-linux-gnu.so +0 -0
  287. sage/rings/fraction_field_FpT.pxd +28 -0
  288. sage/rings/fraction_field_FpT.pyx +2043 -0
  289. sage/rings/imaginary_unit.py +5 -0
  290. sage/rings/monomials.py +73 -0
  291. sage/rings/number_field/S_unit_solver.py +2870 -0
  292. sage/rings/number_field/all__sagemath_flint.py +7 -0
  293. sage/rings/number_field/bdd_height.py +664 -0
  294. sage/rings/number_field/class_group.py +762 -0
  295. sage/rings/number_field/galois_group.py +1307 -0
  296. sage/rings/number_field/homset.py +612 -0
  297. sage/rings/number_field/maps.py +687 -0
  298. sage/rings/number_field/morphism.py +272 -0
  299. sage/rings/number_field/number_field.py +12820 -0
  300. sage/rings/number_field/number_field_element.cpython-310-aarch64-linux-gnu.so +0 -0
  301. sage/rings/number_field/number_field_element.pxd +59 -0
  302. sage/rings/number_field/number_field_element.pyx +5735 -0
  303. sage/rings/number_field/number_field_element_quadratic.cpython-310-aarch64-linux-gnu.so +0 -0
  304. sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
  305. sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
  306. sage/rings/number_field/number_field_ideal_rel.py +925 -0
  307. sage/rings/number_field/number_field_morphisms.cpython-310-aarch64-linux-gnu.so +0 -0
  308. sage/rings/number_field/number_field_morphisms.pyx +781 -0
  309. sage/rings/number_field/number_field_rel.py +2734 -0
  310. sage/rings/number_field/order.py +2981 -0
  311. sage/rings/number_field/order_ideal.py +804 -0
  312. sage/rings/number_field/selmer_group.py +715 -0
  313. sage/rings/number_field/small_primes_of_degree_one.py +242 -0
  314. sage/rings/number_field/splitting_field.py +606 -0
  315. sage/rings/number_field/structure.py +380 -0
  316. sage/rings/number_field/unit_group.py +721 -0
  317. sage/rings/padics/all__sagemath_flint.py +3 -0
  318. sage/rings/polynomial/all__sagemath_flint.py +1 -0
  319. sage/rings/polynomial/complex_roots.py +312 -0
  320. sage/rings/polynomial/evaluation_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  321. sage/rings/polynomial/evaluation_flint.pxd +7 -0
  322. sage/rings/polynomial/evaluation_flint.pyx +68 -0
  323. sage/rings/polynomial/hilbert.cpython-310-aarch64-linux-gnu.so +0 -0
  324. sage/rings/polynomial/hilbert.pyx +602 -0
  325. sage/rings/polynomial/polynomial_complex_arb.cpython-310-aarch64-linux-gnu.so +0 -0
  326. sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
  327. sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
  328. sage/rings/polynomial/polynomial_integer_dense_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  329. sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
  330. sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
  331. sage/rings/polynomial/polynomial_number_field.cpython-310-aarch64-linux-gnu.so +0 -0
  332. sage/rings/polynomial/polynomial_number_field.pyx +345 -0
  333. sage/rings/polynomial/polynomial_rational_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  334. sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
  335. sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
  336. sage/rings/polynomial/polynomial_zmod_flint.cpython-310-aarch64-linux-gnu.so +0 -0
  337. sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
  338. sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
  339. sage/rings/polynomial/real_roots.cpython-310-aarch64-linux-gnu.so +0 -0
  340. sage/rings/polynomial/real_roots.pxd +81 -0
  341. sage/rings/polynomial/real_roots.pyx +4704 -0
  342. sage/rings/polynomial/refine_root.cpython-310-aarch64-linux-gnu.so +0 -0
  343. sage/rings/polynomial/refine_root.pyx +142 -0
  344. sage/rings/polynomial/weil/all.py +4 -0
  345. sage/rings/polynomial/weil/power_sums.h +46 -0
  346. sage/rings/polynomial/weil/weil_polynomials.cpython-310-aarch64-linux-gnu.so +0 -0
  347. sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
  348. sage/rings/qqbar.py +9025 -0
  349. sage/rings/real_arb.cpython-310-aarch64-linux-gnu.so +0 -0
  350. sage/rings/real_arb.pxd +21 -0
  351. sage/rings/real_arb.pyx +4065 -0
  352. sage/rings/real_interval_absolute.cpython-310-aarch64-linux-gnu.so +0 -0
  353. sage/rings/real_interval_absolute.pyx +1073 -0
  354. sage/rings/real_mpfi.cpython-310-aarch64-linux-gnu.so +0 -0
  355. sage/rings/real_mpfi.pyx +5428 -0
  356. sage/schemes/all__sagemath_flint.py +1 -0
  357. sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
  358. sage/schemes/elliptic_curves/descent_two_isogeny.cpython-310-aarch64-linux-gnu.so +0 -0
  359. sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
  360. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,606 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.libs.pari
3
+ """
4
+ Splitting fields of polynomials over number fields
5
+
6
+ AUTHORS:
7
+
8
+ - Jeroen Demeyer (2014-01-02): initial version for :issue:`2217`
9
+ - Jeroen Demeyer (2014-01-03): added ``abort_degree`` argument, :issue:`15626`
10
+ """
11
+
12
+ #*****************************************************************************
13
+ # Copyright (C) 2014 Jeroen Demeyer <jdemeyer@cage.ugent.be>
14
+ #
15
+ # This program is free software: you can redistribute it and/or modify
16
+ # it under the terms of the GNU General Public License as published by
17
+ # the Free Software Foundation, either version 2 of the License, or
18
+ # (at your option) any later version.
19
+ # http://www.gnu.org/licenses/
20
+ #*****************************************************************************
21
+
22
+ from sage.rings.integer import Integer
23
+ from sage.arith.misc import factorial
24
+ from sage.rings.number_field.number_field import NumberField
25
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
26
+ from sage.rings.rational_field import RationalField
27
+ from sage.libs.pari import pari
28
+ from cypari2.handle_error import PariError
29
+
30
+
31
+ class SplittingFieldAbort(Exception):
32
+ """
33
+ Special exception class to indicate an early abort of :func:`splitting_field`.
34
+
35
+ EXAMPLES::
36
+
37
+ sage: from sage.rings.number_field.splitting_field import SplittingFieldAbort
38
+ sage: raise SplittingFieldAbort(20, 60)
39
+ Traceback (most recent call last):
40
+ ...
41
+ SplittingFieldAbort: degree of splitting field is a multiple of 20
42
+ sage: raise SplittingFieldAbort(12, 12)
43
+ Traceback (most recent call last):
44
+ ...
45
+ SplittingFieldAbort: degree of splitting field equals 12
46
+ """
47
+ def __init__(self, div, mult):
48
+ self.degree_divisor = div
49
+ self.degree_multiple = mult
50
+ if div == mult:
51
+ msg = "degree of splitting field equals %s" % div
52
+ else:
53
+ msg = "degree of splitting field is a multiple of %s" % div
54
+ super().__init__(msg)
55
+
56
+
57
+ class SplittingData:
58
+ """
59
+ A class to store data for internal use in :func:`splitting_field`.
60
+ It contains two attributes :attr:`pol` (polynomial), :attr:`dm`
61
+ (degree multiple), where ``pol`` is a PARI polynomial and
62
+ ``dm`` a Sage :class:`Integer`.
63
+
64
+ ``dm`` is a multiple of the degree of the splitting field of
65
+ ``pol`` over some field `E`. In :func:`splitting_field`, `E` is the
66
+ field containing the current field `K` and all roots of other
67
+ polynomials inside the list `L` with ``dm`` less than this ``dm``.
68
+ """
69
+ def __init__(self, _pol, _dm):
70
+ self.pol = _pol
71
+ self.dm = Integer(_dm)
72
+
73
+ def key(self):
74
+ """
75
+ Return a sorting key. Compare first by degree bound, then by
76
+ polynomial degree, then by discriminant.
77
+
78
+ EXAMPLES::
79
+
80
+ sage: from sage.rings.number_field.splitting_field import SplittingData
81
+ sage: L = []
82
+ sage: L.append(SplittingData(pari("x^2 + 1"), 1))
83
+ sage: L.append(SplittingData(pari("x^3 + 1"), 1))
84
+ sage: L.append(SplittingData(pari("x^2 + 7"), 2))
85
+ sage: L.append(SplittingData(pari("x^3 + 1"), 2))
86
+ sage: L.append(SplittingData(pari("x^3 + x^2 + x + 1"), 2))
87
+ sage: L.sort(key=lambda x: x.key()); L
88
+ [SplittingData(x^2 + 1, 1), SplittingData(x^3 + 1, 1), SplittingData(x^2 + 7, 2), SplittingData(x^3 + x^2 + x + 1, 2), SplittingData(x^3 + 1, 2)]
89
+ sage: [x.key() for x in L]
90
+ [(1, 2, 16), (1, 3, 729), (2, 2, 784), (2, 3, 256), (2, 3, 729)]
91
+ """
92
+ return (self.dm, self.poldegree(), self.pol.poldisc().norm().abs())
93
+
94
+ def poldegree(self):
95
+ """
96
+ Return the degree of ``self.pol``.
97
+
98
+ EXAMPLES::
99
+
100
+ sage: from sage.rings.number_field.splitting_field import SplittingData
101
+ sage: SplittingData(pari("x^123 + x + 1"), 2).poldegree()
102
+ 123
103
+ """
104
+ return self.pol.poldegree()
105
+
106
+ def __repr__(self):
107
+ """
108
+ TESTS::
109
+
110
+ sage: from sage.rings.number_field.splitting_field import SplittingData
111
+ sage: print(SplittingData(pari("polcyclo(24)"), 2))
112
+ SplittingData(x^8 - x^4 + 1, 2)
113
+ """
114
+ return "SplittingData(%s, %s)" % (self.pol, self.dm)
115
+
116
+ def _repr_tuple(self):
117
+ """
118
+ TESTS::
119
+
120
+ sage: from sage.rings.number_field.splitting_field import SplittingData
121
+ sage: SplittingData(pari("polcyclo(24)"), 2)._repr_tuple()
122
+ (8, 2)
123
+ """
124
+ return (self.poldegree(), self.dm)
125
+
126
+
127
+ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=None, simplify=True, simplify_all=False):
128
+ r"""
129
+ Compute the splitting field of a given polynomial, defined over a
130
+ number field.
131
+
132
+ INPUT:
133
+
134
+ - ``poly`` -- a monic polynomial over a number field
135
+
136
+ - ``name`` -- a variable name for the number field
137
+
138
+ - ``map`` -- boolean (default: ``False``); also return an embedding of
139
+ ``poly`` into the resulting field. Note that computing this
140
+ embedding might be expensive.
141
+
142
+ - ``degree_multiple`` -- a multiple of the absolute degree of
143
+ the splitting field. If ``degree_multiple`` equals the actual
144
+ degree, this can enormously speed up the computation.
145
+
146
+ - ``abort_degree`` -- abort by raising a :class:`SplittingFieldAbort`
147
+ if it can be determined that the absolute degree of the splitting
148
+ field is strictly larger than ``abort_degree``.
149
+
150
+ - ``simplify`` -- boolean (default: ``True``); during the algorithm, try
151
+ to find a simpler defining polynomial for the intermediate
152
+ number fields using PARI's ``polredbest()``. This usually speeds
153
+ up the computation but can also considerably slow it down.
154
+ Try and see what works best in the given situation.
155
+
156
+ - ``simplify_all`` -- boolean (default: ``False``); if ``True``, simplify
157
+ intermediate fields and also the resulting number field
158
+
159
+ OUTPUT:
160
+
161
+ If ``map`` is ``False``, the splitting field as an absolute number
162
+ field. If ``map`` is ``True``, a tuple ``(K, phi)`` where ``phi``
163
+ is an embedding of the base field in ``K``.
164
+
165
+ EXAMPLES::
166
+
167
+ sage: R.<x> = PolynomialRing(QQ)
168
+ sage: K.<a> = (x^3 + 2).splitting_field(); K
169
+ Number Field in a with defining polynomial
170
+ x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1
171
+ sage: K.<a> = (x^3 - 3*x + 1).splitting_field(); K
172
+ Number Field in a with defining polynomial x^3 - 3*x + 1
173
+
174
+ The ``simplify`` and ``simplify_all`` flags usually yield
175
+ fields defined by polynomials with smaller coefficients.
176
+ By default, ``simplify`` is ``True`` and ``simplify_all`` is ``False``.
177
+
178
+ ::
179
+
180
+ sage: (x^4 - x + 1).splitting_field('a', simplify=False)
181
+ Number Field in a with defining polynomial
182
+ x^24 - 2780*x^22 + 2*x^21 + 3527512*x^20 - 2876*x^19 - 2701391985*x^18 + 945948*x^17
183
+ + 1390511639677*x^16 + 736757420*x^15 - 506816498313560*x^14 - 822702898220*x^13
184
+ + 134120588299548463*x^12 + 362240696528256*x^11 - 25964582366880639486*x^10
185
+ - 91743672243419990*x^9 + 3649429473447308439427*x^8 + 14310332927134072336*x^7
186
+ - 363192569823568746892571*x^6 - 1353403793640477725898*x^5
187
+ + 24293393281774560140427565*x^4 + 70673814899934142357628*x^3
188
+ - 980621447508959243128437933*x^2 - 1539841440617805445432660*x
189
+ + 18065914012013502602456565991
190
+ sage: (x^4 - x + 1).splitting_field('a', simplify=True)
191
+ Number Field in a with defining polynomial
192
+ x^24 + 8*x^23 - 32*x^22 - 310*x^21 + 540*x^20 + 4688*x^19 - 6813*x^18 - 32380*x^17
193
+ + 49525*x^16 + 102460*x^15 - 129944*x^14 - 287884*x^13 + 372727*x^12 + 150624*x^11
194
+ - 110530*x^10 - 566926*x^9 + 1062759*x^8 - 779940*x^7 + 863493*x^6 - 1623578*x^5
195
+ + 1759513*x^4 - 955624*x^3 + 459975*x^2 - 141948*x + 53919
196
+ sage: (x^4 - x + 1).splitting_field('a', simplify_all=True)
197
+ Number Field in a with defining polynomial x^24 - 3*x^23 + 2*x^22 - x^20 + 4*x^19
198
+ + 32*x^18 - 35*x^17 - 92*x^16 + 49*x^15 + 163*x^14 - 15*x^13 - 194*x^12 - 15*x^11
199
+ + 163*x^10 + 49*x^9 - 92*x^8 - 35*x^7 + 32*x^6 + 4*x^5 - x^4 + 2*x^2 - 3*x + 1
200
+
201
+ Reducible polynomials also work::
202
+
203
+ sage: pol = (x^4 - 1)*(x^2 + 1/2)*(x^2 + 1/3)
204
+ sage: pol.splitting_field('a', simplify_all=True)
205
+ Number Field in a with defining polynomial x^8 - x^4 + 1
206
+
207
+ Relative situation::
208
+
209
+ sage: R.<x> = PolynomialRing(QQ)
210
+ sage: K.<a> = NumberField(x^3 + 2)
211
+ sage: S.<t> = PolynomialRing(K)
212
+ sage: L.<b> = (t^2 - a).splitting_field()
213
+ sage: L
214
+ Number Field in b with defining polynomial t^6 + 2
215
+
216
+ With ``map=True``, we also get the embedding of the base field
217
+ into the splitting field::
218
+
219
+ sage: L.<b>, phi = (t^2 - a).splitting_field(map=True)
220
+ sage: phi
221
+ Ring morphism:
222
+ From: Number Field in a with defining polynomial x^3 + 2
223
+ To: Number Field in b with defining polynomial t^6 + 2
224
+ Defn: a |--> b^2
225
+ sage: (x^4 - x + 1).splitting_field('a', simplify_all=True, map=True)[1]
226
+ Ring morphism:
227
+ From: Rational Field
228
+ To: Number Field in a with defining polynomial
229
+ x^24 - 3*x^23 + 2*x^22 - x^20 + 4*x^19 + 32*x^18 - 35*x^17 - 92*x^16
230
+ + 49*x^15 + 163*x^14 - 15*x^13 - 194*x^12 - 15*x^11 + 163*x^10 + 49*x^9
231
+ - 92*x^8 - 35*x^7 + 32*x^6 + 4*x^5 - x^4 + 2*x^2 - 3*x + 1
232
+ Defn: 1 |--> 1
233
+
234
+ We can enable verbose messages::
235
+
236
+ sage: from sage.misc.verbose import set_verbose
237
+ sage: set_verbose(2)
238
+ sage: K.<a> = (x^3 - x + 1).splitting_field()
239
+ verbose 1 (...: splitting_field.py, splitting_field) Starting field: y
240
+ verbose 1 (...: splitting_field.py, splitting_field) SplittingData to factor: [(3, 0)]
241
+ verbose 2 (...: splitting_field.py, splitting_field) Done factoring (time = ...)
242
+ verbose 1 (...: splitting_field.py, splitting_field) SplittingData to handle: [(2, 2), (3, 3)]
243
+ verbose 1 (...: splitting_field.py, splitting_field) Bounds for absolute degree: [6, 6]
244
+ verbose 2 (...: splitting_field.py, splitting_field) Handling polynomial x^2 + 23
245
+ verbose 1 (...: splitting_field.py, splitting_field) New field before simplifying: x^2 + 23 (time = ...)
246
+ verbose 1 (...: splitting_field.py, splitting_field) New field: y^2 - y + 6 (time = ...)
247
+ verbose 2 (...: splitting_field.py, splitting_field) Converted polynomials to new field (time = ...)
248
+ verbose 1 (...: splitting_field.py, splitting_field) SplittingData to factor: []
249
+ verbose 2 (...: splitting_field.py, splitting_field) Done factoring (time = ...)
250
+ verbose 1 (...: splitting_field.py, splitting_field) SplittingData to handle: [(3, 3)]
251
+ verbose 1 (...: splitting_field.py, splitting_field) Bounds for absolute degree: [6, 6]
252
+ verbose 2 (...: splitting_field.py, splitting_field) Handling polynomial x^3 - x + 1
253
+ verbose 1 (...: splitting_field.py, splitting_field) New field: y^6 + 3*y^5 + 19*y^4 + 35*y^3 + 127*y^2 + 73*y + 271 (time = ...)
254
+ sage: set_verbose(0)
255
+
256
+ Try all Galois groups in degree 4. We use a quadratic base field
257
+ such that ``polgalois()`` cannot be used::
258
+
259
+ sage: R.<x> = PolynomialRing(QuadraticField(-11))
260
+ sage: C2C2pol = x^4 - 10*x^2 + 1
261
+ sage: C2C2pol.splitting_field('x')
262
+ Number Field in x with defining polynomial x^8 + 24*x^6 + 608*x^4 + 9792*x^2 + 53824
263
+ sage: C4pol = x^4 + x^3 + x^2 + x + 1
264
+ sage: C4pol.splitting_field('x')
265
+ Number Field in x with defining polynomial
266
+ x^8 - x^7 - 2*x^6 + 5*x^5 + x^4 + 15*x^3 - 18*x^2 - 27*x + 81
267
+ sage: D8pol = x^4 - 2
268
+ sage: D8pol.splitting_field('x')
269
+ Number Field in x with defining polynomial
270
+ x^16 + 8*x^15 + 68*x^14 + 336*x^13 + 1514*x^12 + 5080*x^11 + 14912*x^10
271
+ + 35048*x^9 + 64959*x^8 + 93416*x^7 + 88216*x^6 + 41608*x^5 - 25586*x^4
272
+ - 60048*x^3 - 16628*x^2 + 12008*x + 34961
273
+ sage: A4pol = x^4 - 4*x^3 + 14*x^2 - 28*x + 21
274
+ sage: A4pol.splitting_field('x')
275
+ Number Field in x with defining polynomial
276
+ x^24 - 20*x^23 + 290*x^22 - 3048*x^21 + 26147*x^20 - 186132*x^19 + 1130626*x^18
277
+ - 5913784*x^17 + 26899345*x^16 - 106792132*x^15 + 371066538*x^14 - 1127792656*x^13
278
+ + 2991524876*x^12 - 6888328132*x^11 + 13655960064*x^10 - 23000783036*x^9
279
+ + 32244796382*x^8 - 36347834476*x^7 + 30850889884*x^6 - 16707053128*x^5
280
+ + 1896946429*x^4 + 4832907884*x^3 - 3038258802*x^2 - 200383596*x + 593179173
281
+ sage: S4pol = x^4 + x + 1
282
+ sage: S4pol.splitting_field('x')
283
+ Number Field in x with defining polynomial x^48 ...
284
+
285
+ Some bigger examples::
286
+
287
+ sage: R.<x> = PolynomialRing(QQ)
288
+ sage: pol15 = chebyshev_T(31, x) - 1 # 2^30*(x-1)*minpoly(cos(2*pi/31))^2
289
+ sage: pol15.splitting_field('a')
290
+ Number Field in a with defining polynomial
291
+ x^15 - x^14 - 14*x^13 + 13*x^12 + 78*x^11 - 66*x^10 - 220*x^9 + 165*x^8
292
+ + 330*x^7 - 210*x^6 - 252*x^5 + 126*x^4 + 84*x^3 - 28*x^2 - 8*x + 1
293
+ sage: pol48 = x^6 - 4*x^4 + 12*x^2 - 12
294
+ sage: pol48.splitting_field('a')
295
+ Number Field in a with defining polynomial x^48 ...
296
+
297
+ If you somehow know the degree of the field in advance, you
298
+ should add a ``degree_multiple`` argument. This can speed up the
299
+ computation, in particular for polynomials of degree >= 12 or
300
+ for relative extensions::
301
+
302
+ sage: pol15.splitting_field('a', degree_multiple=15)
303
+ Number Field in a with defining polynomial
304
+ x^15 + x^14 - 14*x^13 - 13*x^12 + 78*x^11 + 66*x^10 - 220*x^9 - 165*x^8
305
+ + 330*x^7 + 210*x^6 - 252*x^5 - 126*x^4 + 84*x^3 + 28*x^2 - 8*x - 1
306
+
307
+ A value for ``degree_multiple`` which isn't actually a
308
+ multiple of the absolute degree of the splitting field can
309
+ either result in a wrong answer or the following exception::
310
+
311
+ sage: pol48.splitting_field('a', degree_multiple=20)
312
+ Traceback (most recent call last):
313
+ ...
314
+ ValueError: inconsistent degree_multiple in splitting_field()
315
+
316
+ Compute the Galois closure as the splitting field of the defining polynomial::
317
+
318
+ sage: R.<x> = PolynomialRing(QQ)
319
+ sage: pol48 = x^6 - 4*x^4 + 12*x^2 - 12
320
+ sage: K.<a> = NumberField(pol48)
321
+ sage: L.<b> = pol48.change_ring(K).splitting_field()
322
+ sage: L
323
+ Number Field in b with defining polynomial x^48 ...
324
+
325
+ Try all Galois groups over `\QQ` in degree 5 except for `S_5`
326
+ (the latter is infeasible with the current implementation)::
327
+
328
+ sage: C5pol = x^5 + x^4 - 4*x^3 - 3*x^2 + 3*x + 1
329
+ sage: C5pol.splitting_field('x')
330
+ Number Field in x with defining polynomial x^5 + x^4 - 4*x^3 - 3*x^2 + 3*x + 1
331
+ sage: D10pol = x^5 - x^4 - 5*x^3 + 4*x^2 + 3*x - 1
332
+ sage: D10pol.splitting_field('x')
333
+ Number Field in x with defining polynomial
334
+ x^10 - 28*x^8 + 216*x^6 - 681*x^4 + 902*x^2 - 401
335
+ sage: AGL_1_5pol = x^5 - 2
336
+ sage: AGL_1_5pol.splitting_field('x')
337
+ Number Field in x with defining polynomial
338
+ x^20 + 10*x^19 + 55*x^18 + 210*x^17 + 595*x^16 + 1300*x^15 + 2250*x^14
339
+ + 3130*x^13 + 3585*x^12 + 3500*x^11 + 2965*x^10 + 2250*x^9 + 1625*x^8
340
+ + 1150*x^7 + 750*x^6 + 400*x^5 + 275*x^4 + 100*x^3 + 75*x^2 + 25
341
+ sage: A5pol = x^5 - x^4 + 2*x^2 - 2*x + 2
342
+ sage: A5pol.splitting_field('x')
343
+ Number Field in x with defining polynomial x^60 ...
344
+
345
+ We can use the ``abort_degree`` option if we don't want to compute
346
+ fields of too large degree (this can be used to check whether the
347
+ splitting field has small degree)::
348
+
349
+ sage: (x^5 + x + 3).splitting_field('b', abort_degree=119)
350
+ Traceback (most recent call last):
351
+ ...
352
+ SplittingFieldAbort: degree of splitting field equals 120
353
+ sage: (x^10 + x + 3).splitting_field('b', abort_degree=60) # long time (10s on sage.math, 2014)
354
+ Traceback (most recent call last):
355
+ ...
356
+ SplittingFieldAbort: degree of splitting field is a multiple of 180
357
+
358
+ Use the ``degree_divisor`` attribute to recover the divisor of the
359
+ degree of the splitting field or ``degree_multiple`` to recover a
360
+ multiple::
361
+
362
+ sage: from sage.rings.number_field.splitting_field import SplittingFieldAbort
363
+ sage: try: # long time (4s on sage.math, 2014)
364
+ ....: (x^8 + x + 1).splitting_field('b', abort_degree=60, simplify=False)
365
+ ....: except SplittingFieldAbort as e:
366
+ ....: print(e.degree_divisor)
367
+ ....: print(e.degree_multiple)
368
+ 120
369
+ 1440
370
+
371
+ TESTS::
372
+
373
+ sage: from sage.rings.number_field.splitting_field import splitting_field
374
+ sage: splitting_field(polygen(QQ), name='x', map=True, simplify_all=True)
375
+ (Number Field in x with defining polynomial x, Ring morphism:
376
+ From: Rational Field
377
+ To: Number Field in x with defining polynomial x
378
+ Defn: 1 |--> 1)
379
+ """
380
+ from sage.misc.timing import cputime
381
+ from sage.misc.verbose import verbose
382
+
383
+ degree_multiple = Integer(degree_multiple or 0)
384
+ abort_degree = Integer(abort_degree or 0)
385
+
386
+ # Kpol = PARI polynomial in y defining the extension found so far
387
+ F = poly.base_ring()
388
+ if isinstance(F, RationalField):
389
+ Kpol = pari("'y")
390
+ else:
391
+ Kpol = F.pari_polynomial("y")
392
+ # Fgen = the generator of F as element of Q[y]/Kpol
393
+ # (only needed if map=True)
394
+ if map:
395
+ Fgen = F.gen().__pari__()
396
+ verbose("Starting field: %s" % Kpol)
397
+
398
+ # L and Lred are lists of SplittingData.
399
+ # L contains polynomials which are irreducible over K,
400
+ # Lred contains polynomials which need to be factored.
401
+ L = []
402
+ Lred = [SplittingData(poly._pari_with_name(), degree_multiple)]
403
+
404
+ # Main loop, handle polynomials one by one
405
+ while True:
406
+ # Absolute degree of current field K
407
+ absolute_degree = Integer(Kpol.poldegree())
408
+
409
+ # Compute minimum relative degree of splitting field
410
+ rel_degree_divisor = Integer(1)
411
+ for splitting in L:
412
+ rel_degree_divisor = rel_degree_divisor.lcm(splitting.poldegree())
413
+
414
+ # Check for early aborts
415
+ abort_rel_degree = abort_degree//absolute_degree
416
+ if abort_rel_degree and rel_degree_divisor > abort_rel_degree:
417
+ raise SplittingFieldAbort(absolute_degree * rel_degree_divisor, degree_multiple)
418
+
419
+ # First, factor polynomials in Lred and store the result in L
420
+ verbose("SplittingData to factor: %s" % [s._repr_tuple() for s in Lred])
421
+ t = cputime()
422
+ for splitting in Lred:
423
+ m = splitting.dm.gcd(degree_multiple).gcd(factorial(splitting.poldegree()))
424
+ if m == 1:
425
+ continue
426
+ factors = Kpol.nffactor(splitting.pol)[0]
427
+ for q in factors:
428
+ d = q.poldegree()
429
+ fac = factorial(d)
430
+ # Multiple of the degree of the splitting field of q,
431
+ # note that the degree equals fac iff the Galois group is S_n.
432
+ mq = m.gcd(fac)
433
+ if mq == 1:
434
+ continue
435
+ # Multiple of the degree of the splitting field of q
436
+ # over the field defined by adding square root of the
437
+ # discriminant.
438
+ # If the Galois group is contained in A_n, then mq_alt is
439
+ # also the degree multiple over the current field K.
440
+ # Here, we have equality if the Galois group is A_n.
441
+ mq_alt = mq.gcd(fac//2)
442
+
443
+ # If we are over Q, then use PARI's polgalois() to compute
444
+ # these degrees exactly.
445
+ if absolute_degree == 1:
446
+ try:
447
+ G = q.polgalois()
448
+ except PariError:
449
+ pass
450
+ else:
451
+ mq = Integer(G[0])
452
+ mq_alt = mq//2 if (G[1] == -1) else mq
453
+
454
+ # In degree 4, use the cubic resolvent to refine the
455
+ # degree bounds.
456
+ if d == 4 and mq >= 12: # mq equals 12 or 24
457
+ # Compute cubic resolvent
458
+ a0, a1, a2, a3, a4 = (q/q.pollead()).Vecrev()
459
+ assert a4 == 1
460
+ cubicpol = pari([4*a0*a2 - a1*a1 - a0*a3*a3, a1*a3 - 4*a0, -a2, 1]).Polrev()
461
+ cubicfactors = Kpol.nffactor(cubicpol)[0]
462
+ if len(cubicfactors) == 1: # A4 or S4
463
+ # After adding a root of the cubic resolvent,
464
+ # the degree of the extension defined by q
465
+ # is a factor 3 smaller.
466
+ L.append(SplittingData(cubicpol, 3))
467
+ rel_degree_divisor = rel_degree_divisor.lcm(3)
468
+ mq = mq//3 # 4 or 8
469
+ mq_alt = 4
470
+ elif len(cubicfactors) == 2: # C4 or D8
471
+ # The irreducible degree 2 factor is
472
+ # equivalent to x^2 - q.poldisc().
473
+ discpol = cubicfactors[1]
474
+ L.append(SplittingData(discpol, 2))
475
+ mq = mq_alt = 4
476
+ else: # C2 x C2
477
+ mq = mq_alt = 4
478
+
479
+ if mq > mq_alt >= 3:
480
+ # Add quadratic resolvent x^2 - D to decrease
481
+ # the degree multiple by a factor 2.
482
+ discpol = pari([-q.poldisc(), 0, 1]).Polrev()
483
+ discfactors = Kpol.nffactor(discpol)[0]
484
+ if len(discfactors) == 1:
485
+ # Discriminant is not a square
486
+ L.append(SplittingData(discpol, 2))
487
+ rel_degree_divisor = rel_degree_divisor.lcm(2)
488
+ mq = mq_alt
489
+
490
+ L.append(SplittingData(q, mq))
491
+ rel_degree_divisor = rel_degree_divisor.lcm(q.poldegree())
492
+ if abort_rel_degree and rel_degree_divisor > abort_rel_degree:
493
+ raise SplittingFieldAbort(absolute_degree * rel_degree_divisor, degree_multiple)
494
+ verbose("Done factoring", t, level=2)
495
+
496
+ if len(L) == 0: # Nothing left to do
497
+ break
498
+
499
+ # Recompute absolute degree multiple
500
+ new_degree_multiple = absolute_degree
501
+ for splitting in L:
502
+ new_degree_multiple *= splitting.dm
503
+ degree_multiple = new_degree_multiple.gcd(degree_multiple)
504
+
505
+ # Absolute degree divisor
506
+ degree_divisor = rel_degree_divisor * absolute_degree
507
+
508
+ # Sort according to degree to handle low degrees first
509
+ L.sort(key=lambda x: x.key())
510
+ verbose("SplittingData to handle: %s" % [s._repr_tuple() for s in L])
511
+ verbose("Bounds for absolute degree: [%s, %s]" % (degree_divisor,degree_multiple))
512
+
513
+ # Check consistency
514
+ if degree_multiple % degree_divisor != 0:
515
+ raise ValueError("inconsistent degree_multiple in splitting_field()")
516
+ for splitting in L:
517
+ # The degree of the splitting field must be a multiple of
518
+ # the degree of the polynomial. Only do this check for
519
+ # SplittingData with minimal dm, because the higher dm are
520
+ # defined as relative degree over the splitting field of
521
+ # the polynomials with lesser dm.
522
+ if splitting.dm > L[0].dm:
523
+ break
524
+ if splitting.dm % splitting.poldegree() != 0:
525
+ raise ValueError("inconsistent degree_multiple in splitting_field()")
526
+
527
+ # Add a root of f = L[0] to construct the field N = K[x]/f(x)
528
+ splitting = L[0]
529
+ f = splitting.pol
530
+ verbose("Handling polynomial %s" % (f.lift()), level=2)
531
+ t = cputime()
532
+ Npol, KtoN, k = Kpol.rnfequation(f, flag=1)
533
+
534
+ # Make Npol monic integral primitive, store in Mpol
535
+ # (after this, we don't need Npol anymore, only Mpol)
536
+ Mdiv = pari(1)
537
+ Mpol = Npol
538
+ while True:
539
+ denom = Integer(Mpol.pollead())
540
+ if denom == 1:
541
+ break
542
+ denom = pari(denom.factor().radical_value())
543
+ Mpol = (Mpol*(denom**Mpol.poldegree())).subst("x", pari([0,1/denom]).Polrev("x"))
544
+ Mpol /= Mpol.content()
545
+ Mdiv *= denom
546
+
547
+ # We are finished for sure if we hit the degree bound
548
+ finished = (Mpol.poldegree() >= degree_multiple)
549
+
550
+ if simplify_all or (simplify and not finished):
551
+ # Find a simpler defining polynomial Lpol for Mpol
552
+ verbose("New field before simplifying: %s" % Mpol, t)
553
+ t = cputime()
554
+ M = Mpol.polredbest(1)
555
+ Lpol = M[0].change_variable_name("y")
556
+ MtoL = M[1].lift().change_variable_name("y").Mod(Lpol)
557
+ else:
558
+ # Lpol = Mpol
559
+ Lpol = Mpol.change_variable_name("y")
560
+ MtoL = pari("'y")
561
+
562
+ NtoL = MtoL/Mdiv
563
+ KtoL = KtoN.lift().subst("x", NtoL).Mod(Lpol)
564
+ Kpol = Lpol # New Kpol (for next iteration)
565
+ verbose("New field: %s" % Kpol, t)
566
+ if map:
567
+ t = cputime()
568
+ Fgen = Fgen.lift().subst("y", KtoL)
569
+ verbose("Computed generator of F in K", t, level=2)
570
+ if finished:
571
+ break
572
+
573
+ t = cputime()
574
+
575
+ # Convert f and elements of L from K to L and store in L
576
+ # (if the polynomial is certain to remain irreducible) or Lred.
577
+ Lold = L[1:]
578
+ L = []
579
+ Lred = []
580
+
581
+ # First add f divided by the linear factor we obtained,
582
+ # mg is the new degree multiple.
583
+ mg = splitting.dm//f.poldegree()
584
+ if mg > 1:
585
+ g = [c.subst("y", KtoL).Mod(Lpol) for c in f.Vecrev().lift()]
586
+ g = pari(g).Polrev()
587
+ g /= pari([k*KtoL - NtoL, 1]).Polrev() # divide linear factor
588
+ Lred.append(SplittingData(g, mg))
589
+
590
+ for splitting in Lold:
591
+ g = [c.subst("y", KtoL) for c in splitting.pol.Vecrev().lift()]
592
+ g = pari(g).Polrev()
593
+ mg = splitting.dm
594
+ if Integer(g.poldegree()).gcd(f.poldegree()) == 1: # linearly disjoint fields
595
+ L.append(SplittingData(g, mg))
596
+ else:
597
+ Lred.append(SplittingData(g, mg))
598
+ verbose("Converted polynomials to new field", t, level=2)
599
+
600
+ # Convert Kpol to Sage and construct the absolute number field
601
+ Kpol = PolynomialRing(RationalField(), name=poly.variable_name())(Kpol/Kpol.pollead())
602
+ K = NumberField(Kpol, name)
603
+ if map:
604
+ return K, F.hom(Fgen, K)
605
+ else:
606
+ return K