passagemath-flint 10.6.1rc10__cp311-cp311-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-311-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-311-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-311-aarch64-linux-gnu.so +0 -0
  25. sage/graphs/chrompoly.pyx +555 -0
  26. sage/graphs/matchpoly.cpython-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-aarch64-linux-gnu.so +0 -0
  220. sage/matrix/change_ring.pyx +43 -0
  221. sage/matrix/matrix_complex_ball_dense.cpython-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-aarch64-linux-gnu.so +0 -0
  285. sage/rings/factorint_flint.pyx +99 -0
  286. sage/rings/fraction_field_FpT.cpython-311-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-311-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-311-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-311-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-311-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-311-aarch64-linux-gnu.so +0 -0
  324. sage/rings/polynomial/hilbert.pyx +602 -0
  325. sage/rings/polynomial/polynomial_complex_arb.cpython-311-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-311-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-311-aarch64-linux-gnu.so +0 -0
  332. sage/rings/polynomial/polynomial_number_field.pyx +345 -0
  333. sage/rings/polynomial/polynomial_rational_flint.cpython-311-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-311-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-311-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-311-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-311-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-311-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-311-aarch64-linux-gnu.so +0 -0
  353. sage/rings/real_interval_absolute.pyx +1073 -0
  354. sage/rings/real_mpfi.cpython-311-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-311-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,2598 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # distutils: libraries = NTL_LIBRARIES gmp
3
+ # distutils: extra_compile_args = NTL_CFLAGS
4
+ # distutils: include_dirs = NTL_INCDIR
5
+ # distutils: library_dirs = NTL_LIBDIR
6
+ # distutils: extra_link_args = NTL_LIBEXTRA
7
+ # distutils: language = c++
8
+ r"""
9
+ Univariate polynomials over `\QQ` implemented via FLINT
10
+
11
+ AUTHOR:
12
+
13
+ - Sebastian Pancratz
14
+ """
15
+
16
+ # ****************************************************************************
17
+ # Copyright (C) 2010 Sebastian Pancratz <sfp@pancratz.org>
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ # https://www.gnu.org/licenses/
24
+ # ****************************************************************************
25
+
26
+ from cysignals.signals cimport sig_on, sig_str, sig_off
27
+
28
+ from libc.limits cimport LONG_MIN
29
+ from cpython.long cimport PyLong_AsLong
30
+ from sage.arith.long cimport pyobject_to_long
31
+
32
+ from sage.libs.flint.acb cimport acb_div_fmpz
33
+ from sage.libs.flint.arb cimport arb_div_fmpz
34
+ from sage.libs.flint.arb_fmpz_poly cimport _arb_fmpz_poly_evaluate_arb, _arb_fmpz_poly_evaluate_acb
35
+ from sage.libs.flint.fmpz cimport *
36
+ from sage.libs.flint.fmpq cimport *
37
+ from sage.libs.flint.fmpz_poly cimport *
38
+ from sage.libs.flint.fmpq_poly cimport *
39
+ from sage.libs.flint.fmpq_poly_sage cimport *
40
+ from sage.libs.gmp.mpz cimport *
41
+ from sage.libs.gmp.mpq cimport *
42
+
43
+ from sage.rings.complex_arb cimport ComplexBall
44
+ from sage.rings.integer cimport Integer, smallInteger
45
+ from sage.rings.integer_ring import ZZ
46
+ from sage.rings.fraction_field_element import FractionFieldElement
47
+ from sage.rings.rational cimport Rational
48
+ from sage.rings.rational_field import QQ
49
+ from sage.rings.real_arb cimport RealBall
50
+ from sage.rings.polynomial.polynomial_element cimport Polynomial
51
+ from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint
52
+
53
+ from sage.structure.parent cimport Parent
54
+ from sage.structure.element cimport Element
55
+ from sage.structure.element import coerce_binop
56
+
57
+ from sage.misc.cachefunc import cached_method
58
+
59
+ try:
60
+ from cypari2.gen import Gen as pari_gen
61
+ except ImportError:
62
+ pari_gen = ()
63
+
64
+
65
+ cdef inline bint _do_sig(fmpq_poly_t op) noexcept:
66
+ """
67
+ Return 1 when signal handling should be carried out for an operation
68
+ on this polynomial and 0 otherwise.
69
+
70
+ Strictly speaking, whether or not signal handling should be carried
71
+ ought to depend on the operation as well as the operands in question.
72
+ For simplicity we carry out signal handling for all but the simplest
73
+ of operands regardless of the operation.
74
+
75
+ TESTS::
76
+
77
+ sage: R.<t> = QQ[]
78
+ sage: f = 1 + t/2
79
+ sage: g = 2/3 + t^2
80
+ sage: _ = f * g # indirect doctest
81
+ """
82
+ # Issue #12173: check that the degree is greater than 1000 before computing
83
+ # the max limb size
84
+ return (fmpq_poly_length(op) > 0 and
85
+ (fmpq_poly_degree(op) > 1000 or
86
+ sage_fmpq_poly_max_limbs(op) > 1))
87
+
88
+ cdef class Polynomial_rational_flint(Polynomial):
89
+ """
90
+ Univariate polynomials over the rationals, implemented via FLINT.
91
+
92
+ Internally, we represent rational polynomial as the quotient of an integer
93
+ polynomial and a positive denominator which is coprime to the content of
94
+ the numerator.
95
+
96
+ TESTS::
97
+
98
+ sage: f = QQ['x'].random_element()
99
+ sage: from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
100
+ sage: isinstance(f, Polynomial_rational_flint)
101
+ True
102
+
103
+ .. automethod:: _add_
104
+ .. automethod:: _sub_
105
+ .. automethod:: _lmul_
106
+ .. automethod:: _rmul_
107
+ .. automethod:: _mul_
108
+ .. automethod:: _mul_trunc_
109
+ """
110
+
111
+ ###########################################################################
112
+ # Allocation & initialisation #
113
+ ###########################################################################
114
+
115
+ cdef Polynomial_rational_flint _new(self):
116
+ """
117
+ Quickly create a new polynomial object in this class.
118
+
119
+ OUTPUT: polynomial of type ``Polynomial_rational_flint``
120
+
121
+ TESTS::
122
+
123
+ sage: R.<t> = QQ[]
124
+ sage: f = 2/3*t^2
125
+ sage: g = -1/2*t + 2
126
+ sage: f + g # indirect doctest
127
+ 2/3*t^2 - 1/2*t + 2
128
+ """
129
+ cdef Polynomial_rational_flint res = Polynomial_rational_flint.__new__(Polynomial_rational_flint)
130
+ res._parent = self._parent
131
+ res._is_gen = 0
132
+ return res
133
+
134
+ cpdef Polynomial _new_constant_poly(self, x, Parent P):
135
+ r"""
136
+ Quickly create a new constant polynomial with value x in parent P.
137
+
138
+ ASSUMPTION:
139
+
140
+ x must be a rational or convertible to an int.
141
+
142
+ EXAMPLES::
143
+
144
+ sage: R.<x> = QQ[]
145
+ sage: x._new_constant_poly(2/1,R)
146
+ 2
147
+ sage: x._new_constant_poly(2,R)
148
+ 2
149
+ sage: x._new_constant_poly("2",R)
150
+ 2
151
+ sage: x._new_constant_poly("2.1",R)
152
+ Traceback (most recent call last):
153
+ ...
154
+ ValueError: invalid literal for int() with base 10: '2.1'
155
+ """
156
+ cdef Polynomial_rational_flint res = Polynomial_rational_flint.__new__(Polynomial_rational_flint)
157
+ res._parent = P
158
+ res._is_gen = <char>0
159
+ if isinstance(x, int):
160
+ fmpq_poly_set_si(res._poly, <int> x)
161
+
162
+ elif isinstance(x, Integer):
163
+ fmpq_poly_set_mpz(res._poly, (<Integer> x).value)
164
+
165
+ elif isinstance(x, Rational):
166
+ fmpq_poly_set_mpq(res._poly, (<Rational> x).value)
167
+
168
+ else:
169
+ fmpq_poly_set_si(res._poly, int(x))
170
+ return res
171
+
172
+ def __cinit__(self):
173
+ """
174
+ Initialises the underlying data structure.
175
+
176
+ TESTS::
177
+
178
+ sage: R.<t> = QQ[]
179
+ sage: f = 2/3 * t - 7 #indirect doctest
180
+ """
181
+ fmpq_poly_init(self._poly)
182
+
183
+ def __dealloc__(self):
184
+ """
185
+ Deallocate the underlying data structure.
186
+
187
+ TESTS::
188
+
189
+ sage: R.<t> = QQ[]
190
+ sage: f = 1/3 * t
191
+ sage: del f
192
+ """
193
+ fmpq_poly_clear(self._poly)
194
+
195
+ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
196
+ """
197
+ Initialises the associated data for the polynomial ``self``.
198
+
199
+ INPUT:
200
+
201
+ - ``parent`` -- polynomial ring, the parent of ``self``
202
+ - ``x`` -- data for the new polynomial ``self``, e.g. a polynomial, an
203
+ integer, a rational, a list of rationals, a dictionary with keys
204
+ the degrees and the rational coefficients, etc (default: ``None``)
205
+ - ``check`` -- whether the integrity of the data needs to be verified,
206
+ largely ignored by this method (default: ``True``)
207
+ - ``is_gen`` -- whether ``self`` shall be initialised as the generator of
208
+ the parent polynomial ring
209
+ - ``construct`` -- whether the element shall always be constructed
210
+ as an independent copy of any input data (default: ``False``)
211
+
212
+ TESTS::
213
+
214
+ sage: R.<t> = QQ[]
215
+ sage: f = -4 * t^2 + 1/3 * t - 1/7 # indirect doctest
216
+
217
+ sage: f = ZZ['x']([1..10^6])
218
+ sage: g = f.change_ring(QQ)
219
+ sage: g[:10]
220
+ 10*x^9 + 9*x^8 + 8*x^7 + 7*x^6 + 6*x^5 + 5*x^4 + 4*x^3 + 3*x^2 + 2*x + 1
221
+ """
222
+ cdef long deg
223
+ cdef unsigned long n
224
+ cdef Rational c
225
+ cdef list L1
226
+ cdef fmpq_t q
227
+
228
+ Polynomial.__init__(self, parent, is_gen=is_gen)
229
+
230
+ if is_gen:
231
+ fmpq_poly_set_coeff_si(self._poly, 1, 1)
232
+
233
+ elif isinstance(x, Polynomial_rational_flint):
234
+ fmpq_poly_set(self._poly, (<Polynomial_rational_flint> x)._poly)
235
+
236
+ elif isinstance(x, int):
237
+ fmpq_poly_set_si(self._poly, <int> x)
238
+
239
+ elif isinstance(x, Integer):
240
+ fmpq_poly_set_mpz(self._poly, (<Integer> x).value)
241
+
242
+ elif isinstance(x, Rational):
243
+ fmpq_poly_set_mpq(self._poly, (<Rational> x).value)
244
+
245
+ elif isinstance(x, (list, tuple)):
246
+
247
+ if len(x) == 0:
248
+ return
249
+ elif len(x) == 1:
250
+ Polynomial_rational_flint.__init__(self, parent, x[0],
251
+ check=check, is_gen=False, construct=construct)
252
+ return
253
+
254
+ L1 = [e if isinstance(e, Rational) else Rational(e) for e in x]
255
+ n = <unsigned long> len(x)
256
+ sig_on()
257
+ fmpq_poly_fit_length(self._poly, n)
258
+ for deg from 0 <= deg < n:
259
+ fmpq_init_set_readonly(q, (<Rational> L1[deg]).value)
260
+ fmpq_poly_set_coeff_fmpq(self._poly, deg, q)
261
+ fmpq_clear_readonly(q)
262
+ sig_off()
263
+
264
+ # deg = 0
265
+ # for e in x:
266
+ # c = Rational(e)
267
+ # fmpq_poly_set_coeff_mpq(self._poly, deg, c.value)
268
+ # deg += 1
269
+
270
+ elif isinstance(x, dict):
271
+ for deg, e in x.iteritems():
272
+ c = Rational(e)
273
+ fmpq_poly_set_coeff_mpq(self._poly, deg, c.value)
274
+
275
+ elif isinstance(x, pari_gen):
276
+ k = self._parent.base_ring()
277
+ x = [k(w) for w in x.list()]
278
+ Polynomial_rational_flint.__init__(self, parent, x, check=True,
279
+ is_gen=False, construct=construct)
280
+
281
+ elif isinstance(x, Polynomial_integer_dense_flint):
282
+ fmpq_poly_set_fmpz_poly(self._poly, (<Polynomial_integer_dense_flint>x)._poly)
283
+
284
+ elif isinstance(x, Polynomial):
285
+ k = self._parent.base_ring()
286
+ x = [k(w) for w in list(x)]
287
+ Polynomial_rational_flint.__init__(self, parent, x, check=True,
288
+ is_gen=False, construct=construct)
289
+
290
+ elif isinstance(x, FractionFieldElement) and (x.parent().base() is parent or x.parent().base() == parent) and x.denominator() == 1:
291
+ x = x.numerator()
292
+ Polynomial_rational_flint.__init__(self, parent, x, check=check,
293
+ is_gen=is_gen, construct=construct)
294
+
295
+ else:
296
+ x = parent.base_ring()(x)
297
+ Polynomial_rational_flint.__init__(self, parent, x, check=check,
298
+ is_gen=is_gen, construct=construct)
299
+
300
+ def __reduce__(self):
301
+ """
302
+ This is used when pickling polynomials.
303
+
304
+ TESTS::
305
+
306
+ sage: R.<t> = QQ[]
307
+ sage: f = 2/3 * t^2 + 1
308
+ sage: r = f.__reduce__(); r
309
+ (<class 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>, (Univariate Polynomial Ring in t over Rational Field, [1, 0, 2/3], False, False))
310
+ sage: r[0](*r[1])
311
+ 2/3*t^2 + 1
312
+ sage: loads(dumps(f)) == f
313
+ True
314
+ """
315
+ return (Polynomial_rational_flint,
316
+ (self.parent(), self.list(), False, self.is_gen()))
317
+
318
+ def __copy__(self):
319
+ """
320
+ Return a copy of ``self``.
321
+
322
+ TESTS::
323
+
324
+ sage: R.<t> = QQ[]
325
+ sage: f = 4/5 * t^3 - 1/17
326
+ sage: copy(f) == f
327
+ True
328
+ """
329
+ cdef Polynomial_rational_flint res = self._new()
330
+ fmpq_poly_set(res._poly, self._poly)
331
+ return res
332
+
333
+ def _singular_(self, singular=None):
334
+ """
335
+ Return a Singular representation of ``self``.
336
+
337
+ INPUT:
338
+
339
+ - ``singular`` -- Singular interpreter (default: default interpreter)
340
+
341
+ EXAMPLES::
342
+
343
+ sage: P.<x> = PolynomialRing(QQ)
344
+ sage: f = 3*x^2 + 2*x + 5
345
+ sage: singular(f) # needs sage.libs.singular
346
+ 3*x^2+2*x+5
347
+ """
348
+ if singular is None:
349
+ from sage.interfaces.singular import singular
350
+ self._parent._singular_(singular).set_ring() # Expensive!
351
+ return singular(self._singular_init_())
352
+
353
+ cpdef list list(self, bint copy=True):
354
+ """
355
+ Return a list with the coefficients of ``self``.
356
+
357
+ EXAMPLES::
358
+
359
+ sage: R.<t> = QQ[]
360
+ sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
361
+ sage: f.list()
362
+ [1, 1, 1/2, 1/3, 1/4]
363
+ sage: g = R(0)
364
+ sage: g.list()
365
+ []
366
+ """
367
+ cdef unsigned long length = fmpq_poly_length(self._poly)
368
+ return [self.get_unsafe(n) for n in range(length)]
369
+
370
+ ###########################################################################
371
+ # Basis access #
372
+ ###########################################################################
373
+
374
+ def degree(self):
375
+ """
376
+ Return the degree of ``self``.
377
+
378
+ By convention, the degree of the zero polynomial is `-1`.
379
+
380
+ EXAMPLES::
381
+
382
+ sage: R.<t> = QQ[]
383
+ sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
384
+ sage: f.degree()
385
+ 4
386
+ sage: g = R(0)
387
+ sage: g.degree()
388
+ -1
389
+
390
+ TESTS::
391
+
392
+ sage: type(f.degree())
393
+ <class 'sage.rings.integer.Integer'>
394
+ """
395
+ return smallInteger(fmpq_poly_degree(self._poly))
396
+
397
+ cdef get_unsafe(self, Py_ssize_t n):
398
+ """
399
+ Return the `n`-th coefficient of ``self``.
400
+
401
+ INPUT:
402
+
403
+ - ``n`` -- degree of the monomial whose coefficient is to be
404
+ returned
405
+
406
+ EXAMPLES::
407
+
408
+ sage: R.<t> = QQ[]
409
+ sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
410
+ sage: f[-1], f[0], f[3], f[5] # indirect doctest
411
+ (0, 1, 1/3, 0)
412
+ sage: f[:3] # indirect doctest
413
+ 1/2*t^2 + t + 1
414
+ """
415
+ cdef Rational z = Rational.__new__(Rational)
416
+ fmpq_poly_get_coeff_mpq(z.value, self._poly, n)
417
+ return z
418
+
419
+ cpdef _unsafe_mutate(self, unsigned long n, value):
420
+ """
421
+ Set the `n`-th coefficient of ``self`` to ``value``.
422
+
423
+ TESTS::
424
+
425
+ sage: R.<t> = QQ[]
426
+ sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
427
+ sage: f._unsafe_mutate(4, 1/5)
428
+ sage: f
429
+ 1/5*t^4 + 1/3*t^3 + 1/2*t^2 + t + 1
430
+
431
+ WARNING:
432
+
433
+ Polynomials in Sage are meant to be immutable, and some methods may
434
+ rely on this convention. This method should be used only with the
435
+ utmost care.
436
+ """
437
+ cdef bint do_sig = _do_sig(self._poly)
438
+ cdef fmpz_t tmpfz
439
+
440
+ if isinstance(value, int):
441
+ if do_sig: sig_str("FLINT exception")
442
+ fmpq_poly_set_coeff_si(self._poly, n, value)
443
+ if do_sig: sig_off()
444
+ elif isinstance(value, Integer):
445
+ if do_sig: sig_str("FLINT exception")
446
+ fmpz_init_set_readonly(tmpfz, (<Integer> value).value)
447
+ fmpq_poly_set_coeff_fmpz(self._poly, n, tmpfz)
448
+ fmpz_clear_readonly(tmpfz)
449
+ if do_sig: sig_off()
450
+ elif isinstance(value, Rational):
451
+ if do_sig: sig_str("FLINT exception")
452
+ fmpq_poly_set_coeff_mpq(self._poly, n, (<Rational> value).value)
453
+ if do_sig: sig_off()
454
+ else:
455
+ value = Rational(value)
456
+ if do_sig: sig_str("FLINT exception")
457
+ fmpq_poly_set_coeff_mpq(self._poly, n, (<Rational> value).value)
458
+ if do_sig: sig_off()
459
+
460
+ def __call__(self, *x, **kwds):
461
+ """
462
+ Call this polynomial with the given parameters, which can be
463
+ interpreted as polynomial composition or evaluation by this
464
+ method.
465
+
466
+ If the argument is not simply an integer, a rational, or a
467
+ polynomial, the call is passed on to the generic implementation
468
+ in the Polynomial class.
469
+
470
+ EXAMPLES:
471
+
472
+ The first example illustrates polynomial composition::
473
+
474
+ sage: R.<t> = QQ[]
475
+ sage: f = t^2 - 1
476
+ sage: g = t + 1
477
+ sage: f(g) # indirect doctest
478
+ t^2 + 2*t
479
+
480
+ Now we illustrate how a polynomial can be evaluated at a rational
481
+ number::
482
+
483
+ sage: f(-2/3) # indirect doctest
484
+ -5/9
485
+
486
+ TESTS:
487
+
488
+ sage: t(-sys.maxsize-1r) == t(-sys.maxsize-1)
489
+ True
490
+ sage: (t/3)(RealBallField(100)(1))
491
+ [0.33333333333333333333333333333...]
492
+ sage: (t/3)(ComplexBallField(10)(1+i)) # needs sage.symbolic
493
+ [0.33...] + [0.33...]*I
494
+ """
495
+ cdef Polynomial_rational_flint f
496
+ cdef Rational r
497
+ cdef fmpz_t tmpfz
498
+ cdef fmpq_t tmpfq, tmpfq1
499
+ cdef RealBall arb_a, arb_z
500
+ cdef ComplexBall acb_a, acb_z
501
+
502
+ if len(x) == 1:
503
+ a = x[0]
504
+ if isinstance(a, Polynomial_rational_flint):
505
+ f = (<Polynomial_rational_flint> a)._new()
506
+ sig_str("FLINT exception")
507
+ fmpq_poly_compose(f._poly, self._poly,
508
+ (<Polynomial_rational_flint> a)._poly)
509
+ sig_off()
510
+ return f
511
+ elif isinstance(a, Rational):
512
+ r = Rational.__new__(Rational)
513
+ sig_str("FLINT exception")
514
+ fmpq_init_set_readonly(tmpfq, (<Rational> a).value)
515
+ fmpq_init(tmpfq1)
516
+ fmpq_poly_evaluate_fmpq(tmpfq1, self._poly, tmpfq)
517
+ fmpq_get_mpq(r.value, tmpfq1)
518
+ fmpq_clear(tmpfq1)
519
+ fmpq_clear_readonly(tmpfq)
520
+ sig_off()
521
+ return r
522
+ elif isinstance(a, Integer):
523
+ r = Rational.__new__(Rational)
524
+ sig_str("FLINT exception")
525
+ fmpz_init_set_readonly(tmpfz, (<Integer> a).value)
526
+ fmpq_init(tmpfq)
527
+ fmpq_poly_evaluate_fmpz(tmpfq, self._poly, tmpfz)
528
+ fmpq_get_mpq(r.value, tmpfq)
529
+ fmpq_clear(tmpfq)
530
+ fmpz_clear_readonly(tmpfz)
531
+ sig_off()
532
+ return r
533
+ elif isinstance(a, int):
534
+ r = Rational.__new__(Rational)
535
+ sig_str("FLINT exception")
536
+ fmpz_init(tmpfz)
537
+ fmpq_init(tmpfq)
538
+ fmpz_set_si(tmpfz, PyLong_AsLong(a))
539
+ fmpq_poly_evaluate_fmpz(tmpfq, self._poly, tmpfz)
540
+ fmpq_get_mpq(r.value, tmpfq)
541
+ fmpq_clear(tmpfq)
542
+ fmpz_clear(tmpfz)
543
+ sig_off()
544
+ return r
545
+ if isinstance(a, RealBall):
546
+ arb_a = <RealBall> a
547
+ arb_z = arb_a._new()
548
+ sig_on()
549
+ _arb_fmpz_poly_evaluate_arb(arb_z.value, fmpq_poly_numref(self._poly),
550
+ fmpq_poly_length(self._poly), arb_a.value, arb_a._parent._prec)
551
+ arb_div_fmpz(arb_z.value, arb_z.value, fmpq_poly_denref(self._poly), arb_a._parent._prec)
552
+ sig_off()
553
+ return arb_z
554
+ if isinstance(a, ComplexBall):
555
+ acb_a = <ComplexBall> a
556
+ acb_z = acb_a._new()
557
+ sig_on()
558
+ _arb_fmpz_poly_evaluate_acb(acb_z.value, fmpq_poly_numref(self._poly),
559
+ fmpq_poly_length(self._poly), acb_a.value, acb_a._parent._prec)
560
+ acb_div_fmpz(acb_z.value, acb_z.value, fmpq_poly_denref(self._poly), acb_a._parent._prec)
561
+ sig_off()
562
+ return acb_z
563
+
564
+ return Polynomial.__call__(self, *x, **kwds)
565
+
566
+ cpdef Polynomial truncate(self, long n):
567
+ """
568
+ Return ``self`` truncated modulo `t^n`.
569
+
570
+ INPUT:
571
+
572
+ - ``n`` -- the power of `t` modulo which ``self`` is truncated
573
+
574
+ EXAMPLES::
575
+
576
+ sage: R.<t> = QQ[]
577
+ sage: f = 1 - t + 1/2*t^2 - 1/3*t^3
578
+ sage: f.truncate(0)
579
+ 0
580
+ sage: f.truncate(2)
581
+ -t + 1
582
+ """
583
+ cdef Polynomial_rational_flint res
584
+ cdef bint do_sig
585
+
586
+ if (n >= fmpq_poly_length(self._poly)):
587
+ return self
588
+ else:
589
+ res = self._new()
590
+ if n > 0:
591
+ do_sig = _do_sig(self._poly)
592
+ if do_sig: sig_str("FLINT exception")
593
+ fmpq_poly_get_slice(res._poly, self._poly, 0, n)
594
+ if do_sig: sig_off()
595
+ return res
596
+
597
+ def reverse(self, degree=None):
598
+ """
599
+ Reverse the coefficients of this polynomial (thought of as a polynomial
600
+ of degree ``degree``).
601
+
602
+ INPUT:
603
+
604
+ - ``degree`` -- ``None`` or integral value that fits in an ``unsigned
605
+ long`` (default: degree of ``self``); if specified, truncate or zero
606
+ pad the list of coefficients to this degree before reversing it
607
+
608
+ EXAMPLES:
609
+
610
+ We first consider the simplest case, where we reverse all coefficients
611
+ of a polynomial and obtain a polynomial of the same degree::
612
+
613
+ sage: R.<t> = QQ[]
614
+ sage: f = 1 + t + t^2 / 2 + t^3 / 3 + t^4 / 4
615
+ sage: f.reverse()
616
+ t^4 + t^3 + 1/2*t^2 + 1/3*t + 1/4
617
+
618
+ Next, an example where the returned polynomial has lower degree because
619
+ the original polynomial has low coefficients equal to zero::
620
+
621
+ sage: R.<t> = QQ[]
622
+ sage: f = 3/4*t^2 + 6*t^7
623
+ sage: f.reverse()
624
+ 3/4*t^5 + 6
625
+
626
+ The next example illustrates the passing of a value for ``degree`` less
627
+ than the length of ``self``, notationally resulting in truncation prior to
628
+ reversing::
629
+
630
+ sage: R.<t> = QQ[]
631
+ sage: f = 1 + t + t^2 / 2 + t^3 / 3 + t^4 / 4
632
+ sage: f.reverse(2)
633
+ t^2 + t + 1/2
634
+
635
+ Now we illustrate the passing of a value for ``degree`` greater than
636
+ the length of ``self``, notationally resulting in zero padding at the top
637
+ end prior to reversing::
638
+
639
+ sage: R.<t> = QQ[]
640
+ sage: f = 1 + t + t^2 / 2 + t^3 / 3
641
+ sage: f.reverse(4)
642
+ t^4 + t^3 + 1/2*t^2 + 1/3*t
643
+
644
+ TESTS:
645
+
646
+ We illustrate two ways in which the interpretation of ``degree`` as an
647
+ unsigned long int may fail. Firstly, an integral value which is
648
+ too large, yielding an :exc:`OverflowError`::
649
+
650
+ sage: R.<t> = QQ[]
651
+ sage: f = 1 + t/2
652
+ sage: f.reverse(2**64 - 1)
653
+ Traceback (most recent call last):
654
+ ...
655
+ OverflowError:... int too large to convert...
656
+
657
+ Secondly, a value which cannot be converted to an integral value,
658
+ resulting in a ValueError::
659
+
660
+ sage: R.<t> = QQ[]
661
+ sage: f = 1 + t/2
662
+ sage: f.reverse(I)
663
+ Traceback (most recent call last):
664
+ ...
665
+ ValueError: degree must be convertible to long
666
+
667
+ We check that this specialized implementation is compatible with the
668
+ generic one::
669
+
670
+ sage: all((t + 2*t^2).reverse(degree=d)
671
+ ....: == Polynomial.reverse(t + 2*t^2, degree=d)
672
+ ....: for d in [None, 0, 1, 2, 3, 4, 5])
673
+ True
674
+ """
675
+ cdef unsigned long len
676
+ cdef Polynomial_rational_flint res
677
+ cdef bint do_sig
678
+
679
+ if degree is None:
680
+ len = fmpq_poly_length(self._poly)
681
+ else:
682
+ try:
683
+ len = <unsigned long> (degree + 1)
684
+ except (TypeError, ValueError):
685
+ raise ValueError('degree must be convertible to long')
686
+
687
+ res = self._new()
688
+ do_sig = _do_sig(self._poly)
689
+ if do_sig: sig_str("FLINT exception")
690
+ fmpq_poly_reverse(res._poly, self._poly, len)
691
+ if do_sig: sig_off()
692
+ return res
693
+
694
+ def revert_series(self, n):
695
+ r"""
696
+ Return a polynomial `f` such that ``f(self(x)) = self(f(x)) = x mod x^n``.
697
+
698
+ EXAMPLES::
699
+
700
+ sage: R.<t> = QQ[]
701
+ sage: f = t - t^3/6 + t^5/120
702
+ sage: f.revert_series(6)
703
+ 3/40*t^5 + 1/6*t^3 + t
704
+
705
+ sage: f.revert_series(-1)
706
+ Traceback (most recent call last):
707
+ ValueError: argument n must be a nonnegative integer, got -1
708
+
709
+ sage: g = - t^3/3 + t^5/5
710
+ sage: g.revert_series(6)
711
+ Traceback (most recent call last):
712
+ ...
713
+ ValueError: self must have constant coefficient 0 and a unit for coefficient t^1
714
+ """
715
+
716
+ cdef Polynomial_rational_flint res = self._new()
717
+ cdef unsigned long m
718
+ if n < 0:
719
+ raise ValueError("argument n must be a nonnegative integer, got {}".format(n))
720
+ m = n
721
+ if not self[0].is_zero() or not self[1].is_unit():
722
+ raise ValueError("self must have constant coefficient 0 and a unit for coefficient {}^1".format(self.parent().gen()))
723
+
724
+ sig_str("FLINT exception")
725
+ fmpq_poly_revert_series(res._poly, self._poly, m)
726
+ sig_off()
727
+
728
+ return res
729
+
730
+ ###########################################################################
731
+ # Comparisons #
732
+ ###########################################################################
733
+
734
+ cpdef bint is_zero(self) except -1:
735
+ """
736
+ Return whether or not ``self`` is the zero polynomial.
737
+
738
+ EXAMPLES::
739
+
740
+ sage: R.<t> = QQ[]
741
+ sage: f = 1 - t + 1/2*t^2 - 1/3*t^3
742
+ sage: f.is_zero()
743
+ False
744
+ sage: R(0).is_zero()
745
+ True
746
+ """
747
+ return fmpq_poly_is_zero(self._poly)
748
+
749
+ cpdef bint is_one(self) except -1:
750
+ r"""
751
+ Return whether or not this polynomial is one.
752
+
753
+ EXAMPLES::
754
+
755
+ sage: R.<x> = QQ[]
756
+ sage: R([0,1]).is_one()
757
+ False
758
+ sage: R([1]).is_one()
759
+ True
760
+ sage: R([0]).is_one()
761
+ False
762
+ sage: R([-1]).is_one()
763
+ False
764
+ sage: R([1,1]).is_one()
765
+ False
766
+ """
767
+ return fmpq_poly_is_one(self._poly)
768
+
769
+ def __bool__(self):
770
+ """
771
+ Return whether or not ``self`` is nonzero.
772
+
773
+ EXAMPLES::
774
+
775
+ sage: R.<t> = QQ[]
776
+ sage: f = 1 - t + 1/2*t^2 - 1/3*t^3
777
+ sage: bool(f)
778
+ True
779
+ sage: bool(R(0))
780
+ False
781
+ """
782
+ return not fmpq_poly_is_zero(self._poly)
783
+
784
+ ###########################################################################
785
+ # Shifting #
786
+ ###########################################################################
787
+
788
+ def __lshift__(self, long n):
789
+ """
790
+ Notationally multiply ``self`` by `t^n`.
791
+
792
+ EXAMPLES::
793
+
794
+ sage: R.<t> = QQ[]
795
+ sage: t << 10 # indirect doctest
796
+ t^11
797
+
798
+ TESTS::
799
+
800
+ sage: R.<t> = QQ[]
801
+ sage: t << (-1)
802
+ 1
803
+ sage: t << (-10)
804
+ 0
805
+ sage: f = R.random_element(1000)
806
+ sage: (f << 23) >> 23 == f # indirect doctest
807
+ True
808
+ """
809
+ if n < 0:
810
+ assert n != LONG_MIN
811
+ return self >> (-n)
812
+
813
+ cdef Polynomial_rational_flint f = <Polynomial_rational_flint> self
814
+ cdef Polynomial_rational_flint res
815
+ cdef bint do_sig
816
+
817
+ if n == 0 or fmpq_poly_is_zero(f._poly):
818
+ return self
819
+ else:
820
+ res = f._new()
821
+ do_sig = fmpq_poly_length(f._poly) > 5000 or n > 5000
822
+
823
+ if do_sig: sig_str("FLINT exception")
824
+ fmpq_poly_shift_left(res._poly, f._poly, n)
825
+ if do_sig: sig_off()
826
+ return res
827
+
828
+ def __rshift__(self, long n):
829
+ """
830
+ Notationally return the quotient of Euclidean division of ``self``
831
+ by `t^n`.
832
+
833
+ EXAMPLES::
834
+
835
+ sage: R.<t> = QQ[]
836
+ sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
837
+ sage: f >> 2
838
+ 1/4*t^2 + 1/3*t + 1/2
839
+ sage: f >> (-2)
840
+ 1/4*t^6 + 1/3*t^5 + 1/2*t^4 + t^3 + t^2
841
+ """
842
+ if n < 0:
843
+ assert n != LONG_MIN
844
+ return self << (-n)
845
+
846
+ cdef Polynomial_rational_flint f = <Polynomial_rational_flint> self
847
+ cdef Polynomial_rational_flint res
848
+ cdef bint do_sig
849
+
850
+ if n == 0 or fmpq_poly_is_zero(f._poly):
851
+ return self
852
+ else:
853
+ res = f._new()
854
+ do_sig = _do_sig(f._poly)
855
+
856
+ if do_sig: sig_str("FLINT exception")
857
+ fmpq_poly_shift_right(res._poly, f._poly, n)
858
+ if do_sig: sig_off()
859
+ return res
860
+
861
+ ###########################################################################
862
+ # Arithmetic #
863
+ ###########################################################################
864
+
865
+ cpdef _add_(self, right):
866
+ """
867
+ Return the sum of two rational polynomials.
868
+
869
+ EXAMPLES::
870
+
871
+ sage: R.<t> = QQ[]
872
+ sage: f = 2/3 + t + 2*t^3
873
+ sage: g = -1 + t/3 - 10/11*t^4
874
+ sage: f + g
875
+ -10/11*t^4 + 2*t^3 + 4/3*t - 1/3
876
+
877
+ TESTS::
878
+
879
+ sage: R.<t> = QQ[]
880
+ sage: f = R.random_element(2000)
881
+ sage: f + f == 2 * f # indirect doctest
882
+ True
883
+ """
884
+ cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
885
+ cdef Polynomial_rational_flint res = self._new()
886
+ cdef bint do_sig = _do_sig(self._poly) or _do_sig(op2._poly)
887
+
888
+ if do_sig: sig_str("FLINT exception")
889
+ fmpq_poly_add(res._poly, self._poly, op2._poly)
890
+ if do_sig: sig_off()
891
+ return res
892
+
893
+ cpdef _sub_(self, right):
894
+ """
895
+ Return the difference of two rational polynomials.
896
+
897
+ EXAMPLES::
898
+
899
+ sage: R.<t> = QQ[]
900
+ sage: f = -10/11*t^4 + 2*t^3 + 4/3*t - 1/3
901
+ sage: g = 2*t^3
902
+ sage: f - g # indirect doctest
903
+ -10/11*t^4 + 4/3*t - 1/3
904
+
905
+ TESTS::
906
+
907
+ sage: R.<t> = QQ[]
908
+ sage: f = R.random_element(2000)
909
+ sage: f - f/2 == 1/2 * f # indirect doctest
910
+ True
911
+ """
912
+ cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
913
+ cdef Polynomial_rational_flint res = self._new()
914
+ cdef bint do_sig = _do_sig(self._poly) or _do_sig(op2._poly)
915
+
916
+ if do_sig: sig_str("FLINT exception")
917
+ fmpq_poly_sub(res._poly, self._poly, op2._poly)
918
+ if do_sig: sig_off()
919
+ return res
920
+
921
+ cpdef _neg_(self):
922
+ """
923
+ Return the difference of two rational polynomials.
924
+
925
+ EXAMPLES::
926
+
927
+ sage: R.<t> = QQ[]
928
+ sage: f = 3*t/2
929
+ sage: -f # indirect doctest
930
+ -3/2*t
931
+
932
+ TESTS::
933
+
934
+ sage: R.<t> = QQ[]
935
+ sage: f = R.random_element(2000)
936
+ sage: f + (-f) == 0 # indirect doctest
937
+ True
938
+ """
939
+ cdef Polynomial_rational_flint res = self._new()
940
+ cdef bint do_sig = _do_sig(self._poly)
941
+
942
+ if do_sig: sig_str("FLINT exception")
943
+ fmpq_poly_neg(res._poly, self._poly)
944
+ if do_sig: sig_off()
945
+ return res
946
+
947
+ @coerce_binop
948
+ def quo_rem(self, right):
949
+ r"""
950
+ Return the quotient and remainder of the Euclidean division of
951
+ ``self`` and ``right``.
952
+
953
+ Raises a :exc:`ZeroDivisionError` if ``right`` is zero.
954
+
955
+ EXAMPLES::
956
+
957
+ sage: R.<t> = QQ[]
958
+ sage: f = R.random_element(2000)
959
+ sage: g = R.random_element(1000)
960
+ sage: q, r = f.quo_rem(g)
961
+ sage: f == q*g + r
962
+ True
963
+ """
964
+ if right.is_zero():
965
+ raise ZeroDivisionError("division by zero polynomial")
966
+ if self.is_zero():
967
+ return self, self
968
+
969
+ cdef Polynomial_rational_flint qq = self._new()
970
+ cdef Polynomial_rational_flint rr = self._new()
971
+
972
+ sig_str("FLINT exception")
973
+ fmpq_poly_divrem(qq._poly, rr._poly, self._poly,
974
+ (<Polynomial_rational_flint> right)._poly)
975
+ sig_off()
976
+ return qq, rr
977
+
978
+ @coerce_binop
979
+ def gcd(self, right):
980
+ r"""
981
+ Return the (monic) greatest common divisor of ``self`` and ``right``.
982
+
983
+ Corner cases: if ``self`` and ``right`` are both zero, returns zero. If
984
+ only one of them is zero, returns the other polynomial, up to
985
+ normalisation.
986
+
987
+ EXAMPLES::
988
+
989
+ sage: R.<t> = QQ[]
990
+ sage: f = -2 + 3*t/2 + 4*t^2/7 - t^3
991
+ sage: g = 1/2 + 4*t + 2*t^4/3
992
+ sage: f.gcd(g)
993
+ 1
994
+ sage: f = (-3*t + 1/2) * f
995
+ sage: g = (-3*t + 1/2) * (4*t^2/3 - 1) * g
996
+ sage: f.gcd(g)
997
+ t - 1/6
998
+ """
999
+ cdef Polynomial_rational_flint res = self._new()
1000
+
1001
+ sig_str("FLINT exception")
1002
+ fmpq_poly_gcd(res._poly, self._poly,
1003
+ (<Polynomial_rational_flint> right)._poly)
1004
+ sig_off()
1005
+ return res
1006
+
1007
+ @coerce_binop
1008
+ def lcm(self, right):
1009
+ r"""
1010
+ Return the monic (or zero) least common multiple of ``self`` and ``right``.
1011
+
1012
+ Corner cases: if either of ``self`` and ``right`` are zero, returns zero.
1013
+ This behaviour is ensures that the relation `\lcm(a,b)\cdot \gcd(a,b) = a\cdot b`
1014
+ holds up to multiplication by rationals.
1015
+
1016
+ EXAMPLES::
1017
+
1018
+ sage: R.<t> = QQ[]
1019
+ sage: f = -2 + 3*t/2 + 4*t^2/7 - t^3
1020
+ sage: g = 1/2 + 4*t + 2*t^4/3
1021
+ sage: f.lcm(g)
1022
+ t^7 - 4/7*t^6 - 3/2*t^5 + 8*t^4 - 75/28*t^3 - 66/7*t^2 + 87/8*t + 3/2
1023
+ sage: f.lcm(g) * f.gcd(g) // (f * g)
1024
+ -3/2
1025
+ """
1026
+ cdef Polynomial_rational_flint res = self._new()
1027
+
1028
+ sig_str("FLINT exception")
1029
+ fmpq_poly_lcm(res._poly, self._poly,
1030
+ (<Polynomial_rational_flint> right)._poly)
1031
+ sig_off()
1032
+ return res
1033
+
1034
+ @coerce_binop
1035
+ def xgcd(self, right):
1036
+ r"""
1037
+ Return polynomials `d`, `s`, and `t` such that ``d == s * self + t * right``,
1038
+ where `d` is the (monic) greatest common divisor of ``self`` and ``right``.
1039
+ The choice of `s` and `t` is not specified any further.
1040
+
1041
+ Corner cases: if ``self`` and ``right`` are zero, returns zero polynomials.
1042
+ Otherwise, if only ``self`` is zero, returns ``(d, s, t) = (right, 0, 1)`` up
1043
+ to normalisation, and similarly if only ``right`` is zero.
1044
+
1045
+ EXAMPLES::
1046
+
1047
+ sage: R.<t> = QQ[]
1048
+ sage: f = 2/3 + 3/4 * t - t^2
1049
+ sage: g = -3 + 1/7 * t
1050
+ sage: f.xgcd(g)
1051
+ (1, -12/5095, -84/5095*t - 1701/5095)
1052
+
1053
+ TESTS:
1054
+
1055
+ The following example used to crash (cf. :issue:`11771`)::
1056
+
1057
+ sage: R.<t> = QQ[]
1058
+ sage: f = 10**383 * (t+1)
1059
+ sage: g = 10**445 * t^2 + 1
1060
+ sage: r = f.xgcd(g)
1061
+ sage: r[0] == f.gcd(g)
1062
+ True
1063
+ sage: r[1]*f + r[2]*g == r[0]
1064
+ True
1065
+ """
1066
+ cdef Polynomial_rational_flint d = self._new()
1067
+ cdef Polynomial_rational_flint s = self._new()
1068
+ cdef Polynomial_rational_flint t = self._new()
1069
+
1070
+ sig_str("FLINT exception")
1071
+ fmpq_poly_xgcd(d._poly, s._poly, t._poly, self._poly, (<Polynomial_rational_flint>right)._poly)
1072
+ sig_off()
1073
+ return d, s, t
1074
+
1075
+ cpdef _mul_(self, right):
1076
+ """
1077
+ Return the product of ``self`` and ``right``.
1078
+
1079
+ EXAMPLES::
1080
+
1081
+ sage: R.<t> = QQ[]
1082
+ sage: f = -1 + 3*t/2 - t^3
1083
+ sage: g = 2/3 + 7/3*t + 3*t^2
1084
+ sage: f * g # indirect doctest
1085
+ -3*t^5 - 7/3*t^4 + 23/6*t^3 + 1/2*t^2 - 4/3*t - 2/3
1086
+
1087
+ TESTS::
1088
+
1089
+ sage: R.<t> = QQ[]
1090
+ sage: f = R.random_element(2000)
1091
+ sage: g = R.random_element(2000)
1092
+ sage: (f + g) * (f - g) == f^2 - g^2 # indirect doctest
1093
+ True
1094
+ """
1095
+ cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
1096
+ cdef Polynomial_rational_flint res = self._new()
1097
+ cdef bint do_sig = _do_sig(self._poly) or _do_sig(op2._poly)
1098
+
1099
+ if do_sig: sig_str("FLINT exception")
1100
+ fmpq_poly_mul(res._poly, self._poly, op2._poly)
1101
+ if do_sig: sig_off()
1102
+ return res
1103
+
1104
+ cpdef Polynomial _mul_trunc_(self, Polynomial right, long n):
1105
+ r"""
1106
+ Truncated multiplication.
1107
+
1108
+ EXAMPLES::
1109
+
1110
+ sage: x = polygen(QQ)
1111
+ sage: p1 = 1/2 - 3*x + 2/7*x**3
1112
+ sage: p2 = x + 2/5*x**5 + x**7
1113
+ sage: p1._mul_trunc_(p2, 5)
1114
+ 2/7*x^4 - 3*x^2 + 1/2*x
1115
+ sage: (p1*p2).truncate(5)
1116
+ 2/7*x^4 - 3*x^2 + 1/2*x
1117
+
1118
+ sage: p1._mul_trunc_(p2, 1)
1119
+ 0
1120
+ sage: p1._mul_trunc_(p2, 0)
1121
+ Traceback (most recent call last):
1122
+ ...
1123
+ ValueError: n must be > 0
1124
+
1125
+ ALGORITHM:
1126
+
1127
+ Call the FLINT method ``fmpq_poly_mullow``.
1128
+ """
1129
+ cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
1130
+ cdef Polynomial_rational_flint res = self._new()
1131
+ cdef bint do_sig = _do_sig(self._poly) or _do_sig(op2._poly)
1132
+
1133
+ if n <= 0:
1134
+ raise ValueError("n must be > 0")
1135
+
1136
+ if do_sig: sig_str("FLINT exception")
1137
+ fmpq_poly_mullow(res._poly, self._poly, op2._poly, n)
1138
+ if do_sig: sig_off()
1139
+ return res
1140
+
1141
+ cpdef _rmul_(self, Element left):
1142
+ r"""
1143
+ Return ``left * self``, where ``left`` is a rational number.
1144
+
1145
+ EXAMPLES::
1146
+
1147
+ sage: R.<t> = QQ[]
1148
+ sage: f = 3/2*t^3 - t + 1/3
1149
+ sage: 6 * f # indirect doctest
1150
+ 9*t^3 - 6*t + 2
1151
+ """
1152
+ cdef Polynomial_rational_flint res = self._new()
1153
+ cdef bint do_sig = _do_sig(self._poly)
1154
+
1155
+ if do_sig: sig_str("FLINT exception")
1156
+ fmpq_poly_scalar_mul_mpq(res._poly, self._poly,
1157
+ (<Rational> left).value)
1158
+ if do_sig: sig_off()
1159
+ return res
1160
+
1161
+ cpdef _lmul_(self, Element right):
1162
+ r"""
1163
+ Return ``self * right``, where ``right`` is a rational number.
1164
+
1165
+ EXAMPLES::
1166
+
1167
+ sage: R.<t> = QQ[]
1168
+ sage: f = 3/2*t^3 - t + 1/3
1169
+ sage: f * 6 # indirect doctest
1170
+ 9*t^3 - 6*t + 2
1171
+ """
1172
+ cdef Polynomial_rational_flint res = self._new()
1173
+ cdef bint do_sig = _do_sig(self._poly)
1174
+
1175
+ if do_sig: sig_str("FLINT exception")
1176
+ fmpq_poly_scalar_mul_mpq(res._poly, self._poly,
1177
+ (<Rational> right).value)
1178
+ if do_sig: sig_off()
1179
+ return res
1180
+
1181
+ def __pow__(Polynomial_rational_flint self, exp, mod):
1182
+ """
1183
+ Return ``self`` raised to the power of ``exp``.
1184
+
1185
+ The corner case of ``exp == 0`` is handled by returning the constant
1186
+ polynomial 1. Note that this includes the case ``0^0 == 1``.
1187
+
1188
+ This method only supports integral values for ``exp`` that fit into
1189
+ a signed long int (except when this is a constant polynomial).
1190
+
1191
+ INPUT:
1192
+
1193
+ - ``exp`` -- exponent
1194
+
1195
+ OUTPUT: polynomial; this polynomial raised to the power of ``exp``
1196
+
1197
+ EXAMPLES::
1198
+
1199
+ sage: R.<t> = QQ[]
1200
+ sage: f = 1/2 + 2*t - t^2/3
1201
+ sage: f^0
1202
+ 1
1203
+ sage: f^3
1204
+ -1/27*t^6 + 2/3*t^5 - 23/6*t^4 + 6*t^3 + 23/4*t^2 + 3/2*t + 1/8
1205
+ sage: f^(-3)
1206
+ -27/(t^6 - 18*t^5 + 207/2*t^4 - 162*t^3 - 621/4*t^2 - 81/2*t - 27/8)
1207
+
1208
+ TESTS::
1209
+
1210
+ sage: R.<t> = QQ[]
1211
+ sage: t^0
1212
+ 1
1213
+ sage: R(0)^0
1214
+ 1
1215
+ sage: R(0)^(-1)
1216
+ Traceback (most recent call last):
1217
+ ...
1218
+ ZeroDivisionError: negative exponent in power of zero
1219
+
1220
+ We verify the checking of the exponent::
1221
+
1222
+ sage: R.<t> = QQ[]
1223
+ sage: (1 + t)^(2/3)
1224
+ Traceback (most recent call last):
1225
+ ...
1226
+ ValueError: not a 3rd power
1227
+ sage: (1 + t)^(2^63)
1228
+ Traceback (most recent call last):
1229
+ ...
1230
+ OverflowError: Sage Integer too large to convert to C long
1231
+
1232
+ FLINT memory errors do not crash Sage (:issue:`17629`)::
1233
+
1234
+ sage: t^(sys.maxsize//2)
1235
+ Traceback (most recent call last):
1236
+ ...
1237
+ RuntimeError: FLINT exception
1238
+
1239
+ Flush the output buffer to get rid of stray output -- see
1240
+ :issue:`28649`::
1241
+
1242
+ sage: from sage.misc.misc_c import cyflush
1243
+ sage: cyflush()
1244
+ ...
1245
+
1246
+ Test fractional powers (:issue:`20086`)::
1247
+
1248
+ sage: P.<R> = QQ[]
1249
+ sage: (1/27*R^3 + 2/3*R^2 + 4*R + 8)^(2/3)
1250
+ 1/9*R^2 + 4/3*R + 4
1251
+ sage: _.parent()
1252
+ Univariate Polynomial Ring in R over Rational Field
1253
+ sage: P(1/4)^(1/2)
1254
+ 1/2
1255
+ sage: _.parent()
1256
+ Univariate Polynomial Ring in R over Rational Field
1257
+
1258
+ sage: (R+2)^(2/5)
1259
+ Traceback (most recent call last):
1260
+ ...
1261
+ ValueError: not a 5th power
1262
+
1263
+ sage: P(1/3)^(1/2)
1264
+ Traceback (most recent call last):
1265
+ ...
1266
+ ValueError: not a perfect 2nd power
1267
+ sage: P(4)^P(1/2)
1268
+ Traceback (most recent call last):
1269
+ ...
1270
+ TypeError: no canonical coercion from Univariate Polynomial
1271
+ Ring in R over Rational Field to Rational Field
1272
+ sage: (R + 1)^P(2)
1273
+ Traceback (most recent call last):
1274
+ ...
1275
+ TypeError: no canonical coercion from Univariate Polynomial
1276
+ Ring in R over Rational Field to Rational Field
1277
+ sage: (R + 1)^R
1278
+ Traceback (most recent call last):
1279
+ ...
1280
+ TypeError: no canonical coercion from Univariate Polynomial
1281
+ Ring in R over Rational Field to Rational Field
1282
+ sage: 2^R
1283
+ Traceback (most recent call last):
1284
+ ...
1285
+ TypeError: no canonical coercion from Univariate Polynomial
1286
+ Ring in R over Rational Field to Rational Field
1287
+
1288
+ Check that using third argument raises an error::
1289
+
1290
+ sage: R.<x> = PolynomialRing(QQ)
1291
+ sage: pow(x, 2, x)
1292
+ Traceback (most recent call last):
1293
+ ...
1294
+ NotImplementedError: pow() with a modulus is not implemented for this ring
1295
+ """
1296
+ cdef Polynomial_rational_flint res
1297
+ cdef long n
1298
+
1299
+ if mod is not None:
1300
+ raise NotImplementedError(
1301
+ "pow() with a modulus is not implemented for this ring"
1302
+ )
1303
+
1304
+ try:
1305
+ n = pyobject_to_long(exp)
1306
+ except TypeError:
1307
+ r = QQ.coerce(exp)
1308
+ num = r.numerator()
1309
+ den = r.denominator()
1310
+
1311
+ if fmpq_poly_degree(self._poly) == 0:
1312
+ return self.parent()(self[0].nth_root(den) ** num)
1313
+
1314
+ return self.nth_root(den) ** num
1315
+
1316
+ else:
1317
+ if n < 0:
1318
+ if fmpq_poly_is_zero(self._poly):
1319
+ raise ZeroDivisionError("negative exponent in power of zero")
1320
+ res = self._new()
1321
+ sig_str("FLINT exception")
1322
+ fmpq_poly_pow(res._poly, self._poly, -n)
1323
+ sig_off()
1324
+ return ~res
1325
+ else:
1326
+ res = self._new()
1327
+ sig_str("FLINT exception")
1328
+ if self._is_gen:
1329
+ fmpq_poly_set_coeff_si(res._poly, n, 1)
1330
+ else:
1331
+ fmpq_poly_pow(res._poly, self._poly, n)
1332
+ sig_off()
1333
+ return res
1334
+
1335
+ def __floordiv__(Polynomial_rational_flint self, right):
1336
+ """
1337
+ Return the quotient of ``self`` and ``right`` obtained by Euclidean division.
1338
+
1339
+ EXAMPLES::
1340
+
1341
+ sage: R.<t> = QQ[]
1342
+ sage: f = t^3 - t/2 + 1/5
1343
+ sage: g = 2/3*t - 1
1344
+ sage: f // g # indirect doctest
1345
+ 3/2*t^2 + 9/4*t + 21/8
1346
+
1347
+ TESTS::
1348
+
1349
+ sage: R.<t> = QQ[]
1350
+ sage: f = R.random_element(1000)
1351
+ sage: g = R.random_element(500)
1352
+ sage: if g == 0: g = R(1)
1353
+ sage: qr = f.quo_rem(g)
1354
+ sage: q = f // g # indirect doctest
1355
+ sage: qr[0] == q
1356
+ True
1357
+ """
1358
+ cdef Polynomial_rational_flint res
1359
+ cdef bint do_sig
1360
+ cdef fmpq_t tmpfq
1361
+
1362
+ if right == 0:
1363
+ raise ZeroDivisionError("division by zero polynomial")
1364
+
1365
+ if not isinstance(right, Polynomial_rational_flint):
1366
+ if right in QQ:
1367
+ res = self._new()
1368
+ do_sig = _do_sig(self._poly)
1369
+
1370
+ if do_sig: sig_str("FLINT exception")
1371
+ fmpq_init_set_readonly(tmpfq, (<Rational> QQ(right)).value)
1372
+ fmpq_poly_scalar_div_fmpq(res._poly, self._poly, tmpfq)
1373
+ fmpq_clear_readonly(tmpfq)
1374
+ if do_sig: sig_off()
1375
+ return res
1376
+
1377
+ right = self._parent(right)
1378
+
1379
+ res = self._new()
1380
+ sig_str("FLINT exception")
1381
+ fmpq_poly_div(res._poly, self._poly,
1382
+ (<Polynomial_rational_flint>right)._poly)
1383
+ sig_off()
1384
+ return res
1385
+
1386
+ cpdef Polynomial inverse_series_trunc(self, long prec):
1387
+ r"""
1388
+ Return a polynomial approximation of precision ``prec`` of the inverse
1389
+ series of this polynomial.
1390
+
1391
+ EXAMPLES::
1392
+
1393
+ sage: x = polygen(QQ)
1394
+ sage: p = 2 + x - 3/5*x**2
1395
+ sage: q5 = p.inverse_series_trunc(5)
1396
+ sage: q5
1397
+ 151/800*x^4 - 17/80*x^3 + 11/40*x^2 - 1/4*x + 1/2
1398
+ sage: q5 * p
1399
+ -453/4000*x^6 + 253/800*x^5 + 1
1400
+
1401
+ sage: q100 = p.inverse_series_trunc(100)
1402
+ sage: (q100 * p).truncate(100)
1403
+ 1
1404
+
1405
+ TESTS::
1406
+
1407
+ sage: (0*x).inverse_series_trunc(4)
1408
+ Traceback (most recent call last):
1409
+ ...
1410
+ ValueError: constant term is zero
1411
+ sage: x.inverse_series_trunc(4)
1412
+ Traceback (most recent call last):
1413
+ ...
1414
+ ValueError: constant term is zero
1415
+ sage: (x+1).inverse_series_trunc(0)
1416
+ Traceback (most recent call last):
1417
+ ...
1418
+ ValueError: the precision must be positive, got 0
1419
+ """
1420
+ if prec <= 0:
1421
+ raise ValueError("the precision must be positive, got {}".format(prec))
1422
+ if fmpq_poly_degree(self._poly) == -1 or \
1423
+ fmpz_is_zero(fmpq_poly_numref(self._poly)):
1424
+ raise ValueError("constant term is zero")
1425
+
1426
+ cdef Polynomial_rational_flint res = self._new()
1427
+ if prec <= 0:
1428
+ return res
1429
+ sig_on()
1430
+ fmpq_poly_inv_series(res._poly, self._poly, prec)
1431
+ sig_off()
1432
+ return res
1433
+
1434
+ cpdef _mod_(self, right):
1435
+ """
1436
+ Return the remainder of ``self`` and ``right`` obtain by Euclidean division.
1437
+
1438
+ EXAMPLES::
1439
+
1440
+ sage: R.<t> = QQ[]
1441
+ sage: f = t^3 - t/2 + 1/5
1442
+ sage: g = 2/3*t - 1
1443
+ sage: f % g # indirect doctest
1444
+ 113/40
1445
+
1446
+ TESTS::
1447
+
1448
+ sage: R.<t> = QQ[]
1449
+ sage: f = R.random_element(1000)
1450
+ sage: g = R.random_element(500)
1451
+ sage: if g == 0: g = R(1)
1452
+ sage: qr = f.quo_rem(g)
1453
+ sage: r = f % g # indirect doctest
1454
+ sage: qr[1] == r
1455
+ True
1456
+ """
1457
+ cdef Polynomial_rational_flint res
1458
+
1459
+ if right == 0:
1460
+ raise ZeroDivisionError("division by zero polynomial")
1461
+
1462
+ res = self._new()
1463
+ sig_str("FLINT exception")
1464
+ fmpq_poly_rem(res._poly, self._poly,
1465
+ (<Polynomial_rational_flint>right)._poly)
1466
+ sig_off()
1467
+ return res
1468
+
1469
+ ###########################################################################
1470
+ # Further methods #
1471
+ ###########################################################################
1472
+
1473
+ def numerator(self):
1474
+ """
1475
+ Return the numerator of ``self``.
1476
+
1477
+ Representing ``self`` as the quotient of an integer polynomial and
1478
+ a positive integer denominator (coprime to the content of the
1479
+ polynomial), returns the integer polynomial.
1480
+
1481
+ EXAMPLES::
1482
+
1483
+ sage: R.<t> = QQ[]
1484
+ sage: f = (3 * t^3 + 1) / -3
1485
+ sage: f.numerator()
1486
+ -3*t^3 - 1
1487
+ """
1488
+ cdef Polynomial_integer_dense_flint num
1489
+ num = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint)
1490
+ parent = ZZ[self.variable_name()]
1491
+ Polynomial_integer_dense_flint.__init__(num, parent, x=None,
1492
+ check=False, is_gen=False, construct=False)
1493
+ sig_str("FLINT exception")
1494
+ fmpq_poly_get_numerator(num._poly, self._poly)
1495
+ sig_off()
1496
+ return num
1497
+
1498
+ def denominator(self):
1499
+ """
1500
+ Return the denominator of ``self``.
1501
+
1502
+ EXAMPLES::
1503
+
1504
+ sage: R.<t> = QQ[]
1505
+ sage: f = (3 * t^3 + 1) / -3
1506
+ sage: f.denominator()
1507
+ 3
1508
+ """
1509
+ cdef Integer den = Integer.__new__(Integer)
1510
+ if fmpq_poly_denref(self._poly) is NULL:
1511
+ mpz_set_ui(den.value, 1)
1512
+ else:
1513
+ fmpz_get_mpz(den.value, <fmpz *> fmpq_poly_denref(self._poly))
1514
+ return den
1515
+
1516
+ def _derivative(self, var=None):
1517
+ """
1518
+ Return the derivative of this polynomial with respect to ``var``.
1519
+
1520
+ INPUT:
1521
+
1522
+ - ``var`` -- must be either (equal to) the generator of the polynomial
1523
+ ring to which this polynomial belongs, or ``None``; either way the
1524
+ behaviour is the same
1525
+
1526
+ OUTPUT: derivative as a ``Polynomial_rational_flint``
1527
+
1528
+ .. SEEALSO:: :meth:`~Polynomial.derivative`
1529
+
1530
+ EXAMPLES::
1531
+
1532
+ sage: R.<x> = QQ[]
1533
+ sage: f = x^4 - x - 1
1534
+ sage: f._derivative()
1535
+ 4*x^3 - 1
1536
+ sage: f._derivative(None)
1537
+ 4*x^3 - 1
1538
+ sage: f._derivative(2*x)
1539
+ Traceback (most recent call last):
1540
+ ...
1541
+ ValueError: cannot differentiate with respect to 2*x
1542
+
1543
+ Check that :issue:`28187` is fixed::
1544
+
1545
+ sage: x = var("x") # needs sage.symbolic
1546
+ sage: f._derivative(x) # needs sage.symbolic
1547
+ 4*x^3 - 1
1548
+ """
1549
+ cdef Polynomial_rational_flint der
1550
+ cdef bint do_sig
1551
+
1552
+ if var is not None and var != self._parent.gen():
1553
+ raise ValueError("cannot differentiate with respect to {}".format(var))
1554
+
1555
+ der = self._new()
1556
+ do_sig = _do_sig(self._poly)
1557
+
1558
+ if do_sig: sig_str("FLINT exception")
1559
+ fmpq_poly_derivative(der._poly, self._poly)
1560
+ if do_sig: sig_off()
1561
+ return der
1562
+
1563
+ def real_root_intervals(self):
1564
+ """
1565
+ Return isolating intervals for the real roots of ``self``.
1566
+
1567
+ EXAMPLES:
1568
+
1569
+ We compute the roots of the characteristic polynomial of some
1570
+ Salem numbers::
1571
+
1572
+ sage: R.<t> = QQ[]
1573
+ sage: f = 1 - t^2 - t^3 - t^4 + t^6
1574
+ sage: f.real_root_intervals()
1575
+ [((1/2, 3/4), 1), ((1, 3/2), 1)]
1576
+ """
1577
+ from sage.rings.polynomial.real_roots import real_roots
1578
+ return real_roots(self)
1579
+
1580
+ @coerce_binop
1581
+ def resultant(Polynomial_rational_flint self, right):
1582
+ r"""
1583
+ Return the resultant of ``self`` and ``right``.
1584
+
1585
+ Enumerating the roots over `\QQ` as `r_1, \dots, r_m` and
1586
+ `s_1, \dots, s_n` and letting `x` and `y` denote the leading
1587
+ coefficients of `f` and `g`, the resultant of the two polynomials
1588
+ is defined by
1589
+
1590
+ .. MATH::
1591
+
1592
+ x^{\deg g} y^{\deg f} \prod_{i,j} (r_i - s_j).
1593
+
1594
+ Corner cases: if one of the polynomials is zero, the resultant
1595
+ is zero. Note that otherwise if one of the polynomials is constant,
1596
+ the last term in the above is the empty product.
1597
+
1598
+ EXAMPLES::
1599
+
1600
+ sage: R.<t> = QQ[]
1601
+ sage: f = (t - 2/3) * (t + 4/5) * (t - 1)
1602
+ sage: g = (t - 1/3) * (t + 1/2) * (t + 1)
1603
+ sage: f.resultant(g)
1604
+ 119/1350
1605
+ sage: h = (t - 1/3) * (t + 1/2) * (t - 1)
1606
+ sage: f.resultant(h)
1607
+ 0
1608
+ """
1609
+ cdef Rational res = Rational.__new__(Rational)
1610
+ cdef fmpq_t t
1611
+ fmpq_init(t)
1612
+ sig_str("FLINT exception")
1613
+ fmpq_poly_resultant(t, self._poly,
1614
+ (<Polynomial_rational_flint>right)._poly)
1615
+ fmpq_get_mpq(res.value, t)
1616
+ sig_off()
1617
+ fmpq_clear(t)
1618
+ return res
1619
+
1620
+ @cached_method
1621
+ def is_irreducible(self):
1622
+ r"""
1623
+ Return whether this polynomial is irreducible.
1624
+
1625
+ This method computes the primitive part as an element of `\ZZ[t]` and
1626
+ calls the method ``is_irreducible`` for elements of that polynomial
1627
+ ring.
1628
+
1629
+ By definition, over any integral domain, an element `r` is irreducible
1630
+ if and only if it is nonzero, not a unit and whenever `r = ab` then
1631
+ `a` or `b` is a unit.
1632
+
1633
+ EXAMPLES::
1634
+
1635
+ sage: R.<t> = QQ[]
1636
+ sage: (t^2 + 2).is_irreducible()
1637
+ True
1638
+ sage: (t^2 - 1).is_irreducible()
1639
+ False
1640
+
1641
+ TESTS::
1642
+
1643
+ sage: R.<t> = QQ[]
1644
+ sage: R(0).is_irreducible()
1645
+ False
1646
+ sage: R(-1/2).is_irreducible()
1647
+ False
1648
+ sage: (t + 1).is_irreducible()
1649
+ True
1650
+
1651
+ Test that caching works::
1652
+
1653
+ sage: R.<t> = QQ[]
1654
+ sage: f = t + 1
1655
+ sage: f.is_irreducible()
1656
+ True
1657
+ sage: f.is_irreducible.cache
1658
+ True
1659
+ """
1660
+ cdef Polynomial_integer_dense_flint primitive
1661
+ cdef unsigned long length = fmpq_poly_length(self._poly)
1662
+
1663
+ if length < 2:
1664
+ return False
1665
+ elif length == 2:
1666
+ return True
1667
+ else:
1668
+ primitive = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint)
1669
+ parent = ZZ[self.variable_name()]
1670
+ Polynomial_integer_dense_flint.__init__(primitive, parent,
1671
+ x=None, check=True, is_gen=False, construct=False)
1672
+
1673
+ sig_str("FLINT exception")
1674
+ fmpq_poly_get_numerator(primitive._poly, self._poly)
1675
+ fmpz_poly_primitive_part(primitive._poly, primitive._poly)
1676
+ sig_off()
1677
+ return primitive.is_irreducible()
1678
+
1679
+ #######################################################
1680
+ # Transcendental functions (return truncated series) #
1681
+ #######################################################
1682
+
1683
+ def _log_series(self, long prec):
1684
+ r"""
1685
+ Return the logarithm of this polynomial up to precision ``prec``.
1686
+
1687
+ EXAMPLES::
1688
+
1689
+ sage: x = polygen(QQ)
1690
+ sage: (1+x)._log_series(5)
1691
+ -1/4*x^4 + 1/3*x^3 - 1/2*x^2 + x
1692
+
1693
+ sage: (1/3*x^3 - 2*x^2 + x + 1)._log_series(10)._exp_series(10)
1694
+ 1/3*x^3 - 2*x^2 + x + 1
1695
+
1696
+ TESTS::
1697
+
1698
+ sage: x._log_series(5)
1699
+ Traceback (most recent call last):
1700
+ ...
1701
+ ValueError: constant term should be 1 in order to take logarithm
1702
+ sage: (0*x)._log_series(5)
1703
+ Traceback (most recent call last):
1704
+ ...
1705
+ ValueError: constant term should be 1 in order to take logarithm
1706
+ """
1707
+ if fmpq_poly_degree(self._poly) == -1 or \
1708
+ fmpz_cmp(fmpq_poly_numref(self._poly),
1709
+ fmpq_poly_denref(self._poly)):
1710
+ raise ValueError("constant term should be 1 in order to take logarithm")
1711
+
1712
+ cdef Polynomial_rational_flint res = self._new()
1713
+ sig_on()
1714
+ fmpq_poly_log_series(res._poly, self._poly, prec)
1715
+ sig_off()
1716
+ return res
1717
+
1718
+ def _exp_series(self, long prec):
1719
+ r"""
1720
+ Return the exponential of this polynomial up to precision ``prec``.
1721
+
1722
+ EXAMPLES::
1723
+
1724
+ sage: x = polygen(QQ)
1725
+ sage: x._exp_series(5)
1726
+ 1/24*x^4 + 1/6*x^3 + 1/2*x^2 + x + 1
1727
+ sage: (1/3*x^4 - 3*x^2 - 1/2*x)._exp_series(5)._log_series(5)
1728
+ 1/3*x^4 - 3*x^2 - 1/2*x
1729
+
1730
+ TESTS::
1731
+
1732
+ sage: (x+1)._exp_series(5)
1733
+ Traceback (most recent call last):
1734
+ ...
1735
+ ValueError: constant term should be 0 in order to take exponential
1736
+ sage: (0*x)._exp_series(5)
1737
+ 1
1738
+ sage: _.parent()
1739
+ Univariate Polynomial Ring in x over Rational Field
1740
+ """
1741
+ if fmpq_poly_degree(self._poly) == -1:
1742
+ return self._parent.one()
1743
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1744
+ raise ValueError("constant term should be 0 in order to take exponential")
1745
+
1746
+ cdef Polynomial_rational_flint res = self._new()
1747
+ sig_on()
1748
+ fmpq_poly_exp_series(res._poly, self._poly, prec)
1749
+ sig_off()
1750
+ return res
1751
+
1752
+ def _atan_series(self, long prec):
1753
+ r"""
1754
+ Return the arctangent of this polynomial up to precision ``prec``.
1755
+
1756
+ EXAMPLES::
1757
+
1758
+ sage: x = polygen(QQ)
1759
+ sage: x._atan_series(7)
1760
+ 1/5*x^5 - 1/3*x^3 + x
1761
+ sage: (1/5*x^3 + 2*x^2 - x)._atan_series(10)._tan_series(10)
1762
+ 1/5*x^3 + 2*x^2 - x
1763
+
1764
+ TESTS::
1765
+
1766
+ sage: (1+x)._atan_series(3)
1767
+ Traceback (most recent call last):
1768
+ ...
1769
+ ValueError: constant term should be 0 in order to take arctangent
1770
+ sage: (0*x)._atan_series(10)
1771
+ 0
1772
+ sage: _.parent()
1773
+ Univariate Polynomial Ring in x over Rational Field
1774
+ """
1775
+ if fmpq_poly_degree(self._poly) == -1:
1776
+ return self._parent.zero()
1777
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1778
+ raise ValueError("constant term should be 0 in order to take arctangent")
1779
+
1780
+ cdef Polynomial_rational_flint res = self._new()
1781
+ sig_on()
1782
+ fmpq_poly_atan_series(res._poly, self._poly, prec)
1783
+ sig_off()
1784
+ return res
1785
+
1786
+ def _atanh_series(self, long prec):
1787
+ r"""
1788
+ Return the hyperbolic arctangent of this polynomial up to precision
1789
+ ``prec``.
1790
+
1791
+ EXAMPLES::
1792
+
1793
+ sage: x = polygen(QQ)
1794
+ sage: x._atanh_series(7)
1795
+ 1/5*x^5 + 1/3*x^3 + x
1796
+ sage: (1/5*x^3 + 2*x^2 - x)._atanh_series(10)._tanh_series(10)
1797
+ 1/5*x^3 + 2*x^2 - x
1798
+
1799
+ TESTS::
1800
+
1801
+ sage: (0*x)._atanh_series(10)
1802
+ 0
1803
+ sage: _.parent()
1804
+ Univariate Polynomial Ring in x over Rational Field
1805
+ """
1806
+ if fmpq_poly_degree(self._poly) == -1:
1807
+ return self._parent.zero()
1808
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1809
+ raise ValueError("constant term should be 0 in order to take hyperbolic arctangent")
1810
+
1811
+ cdef Polynomial_rational_flint res = self._new()
1812
+ sig_on()
1813
+ fmpq_poly_atanh_series(res._poly, self._poly, prec)
1814
+ sig_off()
1815
+ return res
1816
+
1817
+ def _asin_series(self, long prec):
1818
+ r"""
1819
+ Return the arcsine of this polynomial up to precision ``prec``.
1820
+
1821
+ EXAMPLES::
1822
+
1823
+ sage: x = polygen(QQ)
1824
+ sage: x._asin_series(7)
1825
+ 3/40*x^5 + 1/6*x^3 + x
1826
+ sage: (1/5*x^3 + 2*x^2 - x)._asin_series(10)._sin_series(10)
1827
+ 1/5*x^3 + 2*x^2 - x
1828
+
1829
+ TESTS::
1830
+
1831
+ sage: (x+1)._asin_series(5)
1832
+ Traceback (most recent call last):
1833
+ ...
1834
+ ValueError: constant term should be 0 in order to take arcsine
1835
+ sage: (0*x)._asin_series(5)
1836
+ 0
1837
+ sage: _.parent()
1838
+ Univariate Polynomial Ring in x over Rational Field
1839
+ """
1840
+ if fmpq_poly_degree(self._poly) == -1:
1841
+ return self._parent.zero()
1842
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1843
+ raise ValueError("constant term should be 0 in order to take arcsine")
1844
+
1845
+ cdef Polynomial_rational_flint res = self._new()
1846
+ sig_on()
1847
+ fmpq_poly_asin_series(res._poly, self._poly, prec)
1848
+ sig_off()
1849
+ return res
1850
+
1851
+ def _asinh_series(self, long prec):
1852
+ r"""
1853
+ Return the hyperbolic arcsine of this polynomial up to precision
1854
+ ``prec``.
1855
+
1856
+ EXAMPLES::
1857
+
1858
+ sage: x = polygen(QQ)
1859
+ sage: x._asinh_series(7)
1860
+ 3/40*x^5 - 1/6*x^3 + x
1861
+ sage: (1/5*x^3 + 2*x^2 - x)._asinh_series(10)._sinh_series(10)
1862
+ 1/5*x^3 + 2*x^2 - x
1863
+
1864
+ TESTS::
1865
+
1866
+ sage: (x+1)._asinh_series(5)
1867
+ Traceback (most recent call last):
1868
+ ...
1869
+ ValueError: constant term should be 0 in order to take hyperbolic arcsine
1870
+ sage: (0*x)._asinh_series(5)
1871
+ 0
1872
+ sage: _.parent()
1873
+ Univariate Polynomial Ring in x over Rational Field
1874
+ """
1875
+ if fmpq_poly_degree(self._poly) == -1:
1876
+ return self._parent.zero()
1877
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1878
+ raise ValueError("constant term should be 0 in order to take hyperbolic arcsine")
1879
+
1880
+ cdef Polynomial_rational_flint res = self._new()
1881
+ sig_on()
1882
+ fmpq_poly_asinh_series(res._poly, self._poly, prec)
1883
+ sig_off()
1884
+ return res
1885
+
1886
+ def _tan_series(self, long prec):
1887
+ r"""
1888
+ Return the tangent of this polynomial up to precision ``prec``.
1889
+
1890
+ EXAMPLES::
1891
+
1892
+ sage: x = polygen(QQ)
1893
+ sage: x._tan_series(8)
1894
+ 17/315*x^7 + 2/15*x^5 + 1/3*x^3 + x
1895
+ sage: (1/5*x^3 + 2*x^2 - x)._tan_series(10)._atan_series(10)
1896
+ 1/5*x^3 + 2*x^2 - x
1897
+
1898
+ TESTS::
1899
+
1900
+ sage: (x+1)._tan_series(10)
1901
+ Traceback (most recent call last):
1902
+ ...
1903
+ ValueError: constant term should be 0 in order to take tangent
1904
+ sage: (0*x)._tan_series(5)
1905
+ 0
1906
+ sage: _.parent()
1907
+ Univariate Polynomial Ring in x over Rational Field
1908
+ """
1909
+ if fmpq_poly_degree(self._poly) == -1:
1910
+ return self._parent.zero()
1911
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1912
+ raise ValueError("constant term should be 0 in order to take tangent")
1913
+
1914
+ cdef Polynomial_rational_flint res = self._new()
1915
+ sig_on()
1916
+ fmpq_poly_tan_series(res._poly, self._poly, prec)
1917
+ sig_off()
1918
+ return res
1919
+
1920
+ def _sin_series(self, long prec):
1921
+ r"""
1922
+ Return the sine of this polynomial up to precision ``prec``.
1923
+
1924
+ EXAMPLES::
1925
+
1926
+ sage: x = polygen(QQ)
1927
+ sage: x._sin_series(8)
1928
+ -1/5040*x^7 + 1/120*x^5 - 1/6*x^3 + x
1929
+ sage: (1/5*x^3 - 2*x^2 + 1/2*x)._sin_series(10)._asin_series(10)
1930
+ 1/5*x^3 - 2*x^2 + 1/2*x
1931
+
1932
+ TESTS::
1933
+
1934
+ sage: (x+1)._sin_series(10)
1935
+ Traceback (most recent call last):
1936
+ ...
1937
+ ValueError: constant term should be 0 in order to take sine
1938
+ sage: (0*x)._sin_series(5)
1939
+ 0
1940
+ sage: _.parent()
1941
+ Univariate Polynomial Ring in x over Rational Field
1942
+ """
1943
+ if fmpq_poly_degree(self._poly) == -1:
1944
+ return self._parent.zero()
1945
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1946
+ raise ValueError("constant term should be 0 in order to take sine")
1947
+
1948
+ cdef Polynomial_rational_flint res = self._new()
1949
+ sig_on()
1950
+ fmpq_poly_sin_series(res._poly, self._poly, prec)
1951
+ sig_off()
1952
+ return res
1953
+
1954
+ def _cos_series(self, long prec):
1955
+ r"""
1956
+ Return the cosine of this polynomial up to precision ``prec``.
1957
+
1958
+ EXAMPLES::
1959
+
1960
+ sage: x = polygen(QQ)
1961
+ sage: x._cos_series(10)
1962
+ 1/40320*x^8 - 1/720*x^6 + 1/24*x^4 - 1/2*x^2 + 1
1963
+
1964
+ TESTS::
1965
+
1966
+ sage: (x+1)._cos_series(5)
1967
+ Traceback (most recent call last):
1968
+ ...
1969
+ ValueError: constant term should be 0 in order to take cosine
1970
+ sage: (0*x)._cos_series(5)
1971
+ 0
1972
+ sage: _.parent()
1973
+ Univariate Polynomial Ring in x over Rational Field
1974
+ """
1975
+ if fmpq_poly_degree(self._poly) == -1:
1976
+ return self._parent.zero()
1977
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
1978
+ raise ValueError("constant term should be 0 in order to take cosine")
1979
+
1980
+ cdef Polynomial_rational_flint res = self._new()
1981
+ sig_on()
1982
+ fmpq_poly_cos_series(res._poly, self._poly, prec)
1983
+ sig_off()
1984
+ return res
1985
+
1986
+ def _sinh_series(self, long prec):
1987
+ r"""
1988
+ Return the hyperbolic sine of this polynomial up to precision ``prec``.
1989
+
1990
+ EXAMPLES::
1991
+
1992
+ sage: x = polygen(QQ)
1993
+ sage: x._sinh_series(8)
1994
+ 1/5040*x^7 + 1/120*x^5 + 1/6*x^3 + x
1995
+
1996
+ TESTS::
1997
+
1998
+ sage: (x+1)._sinh_series(5)
1999
+ Traceback (most recent call last):
2000
+ ...
2001
+ ValueError: constant term should be 0 in order to take hyperbolic sine
2002
+ sage: (0*x)._sinh_series(5)
2003
+ 0
2004
+ sage: _.parent()
2005
+ Univariate Polynomial Ring in x over Rational Field
2006
+ """
2007
+ if fmpq_poly_degree(self._poly) == -1:
2008
+ return self._parent.zero()
2009
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
2010
+ raise ValueError("constant term should be 0 in order to take hyperbolic sine")
2011
+
2012
+ cdef Polynomial_rational_flint res = self._new()
2013
+ sig_on()
2014
+ fmpq_poly_sinh_series(res._poly, self._poly, prec)
2015
+ sig_off()
2016
+ return res
2017
+
2018
+ def _cosh_series(self, long prec):
2019
+ r"""
2020
+ Return the hyperbolic cosine of this polynomial up to precision
2021
+ ``prec``.
2022
+
2023
+ EXAMPLES::
2024
+
2025
+ sage: x = polygen(QQ)
2026
+ sage: x._cosh_series(8)
2027
+ 1/720*x^6 + 1/24*x^4 + 1/2*x^2 + 1
2028
+
2029
+ A trigonometric identity::
2030
+
2031
+ sage: x._cosh_series(8) + x._sinh_series(8) == x._exp_series(8)
2032
+ True
2033
+
2034
+ TESTS::
2035
+
2036
+ sage: (x+1)._cosh_series(5)
2037
+ Traceback (most recent call last):
2038
+ ...
2039
+ ValueError: constant term should be 0 in order to take hyperbolic cosine
2040
+ sage: (0*x)._cosh_series(5)
2041
+ 1
2042
+ sage: _.parent()
2043
+ Univariate Polynomial Ring in x over Rational Field
2044
+ """
2045
+ if fmpq_poly_degree(self._poly) == -1:
2046
+ return self._parent.one()
2047
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
2048
+ raise ValueError("constant term should be 0 in order to take hyperbolic cosine")
2049
+
2050
+ cdef Polynomial_rational_flint res = self._new()
2051
+ sig_on()
2052
+ fmpq_poly_cosh_series(res._poly, self._poly, prec)
2053
+ sig_off()
2054
+ return res
2055
+
2056
+ def _tanh_series(self, long prec):
2057
+ r"""
2058
+ Return the hyperbolic tangent of this polynomial up to precision
2059
+ ``prec``.
2060
+
2061
+ EXAMPLES::
2062
+
2063
+ sage: x = polygen(QQ)
2064
+ sage: x._tanh_series(8)
2065
+ -17/315*x^7 + 2/15*x^5 - 1/3*x^3 + x
2066
+
2067
+ TESTS::
2068
+
2069
+ sage: (x+1)._tanh_series(5)
2070
+ Traceback (most recent call last):
2071
+ ...
2072
+ ValueError: constant term should be 0 in order to take hyperbolic tangent
2073
+ sage: (0*x)._tanh_series(5)
2074
+ 0
2075
+ sage: _.parent()
2076
+ Univariate Polynomial Ring in x over Rational Field
2077
+ """
2078
+ if fmpq_poly_degree(self._poly) == -1:
2079
+ return self._parent.zero()
2080
+ elif not fmpz_is_zero(fmpq_poly_numref(self._poly)):
2081
+ raise ValueError("constant term should be 0 in order to take hyperbolic tangent")
2082
+
2083
+ cdef Polynomial_rational_flint res = self._new()
2084
+ sig_on()
2085
+ fmpq_poly_tanh_series(res._poly, self._poly, prec)
2086
+ sig_off()
2087
+ return res
2088
+
2089
+ ###########################################################################
2090
+ # Methods using PARI #
2091
+ ###########################################################################
2092
+
2093
+ def galois_group(self, pari_group=False, algorithm='pari'):
2094
+ """
2095
+ Return the Galois group of this polynomial as a permutation group.
2096
+
2097
+ INPUT:
2098
+
2099
+ - ``self`` -- irreducible polynomial
2100
+
2101
+ - ``pari_group`` -- boolean (default: ``False``); if ``True`` instead
2102
+ return the Galois group as a PARI group. This has a useful label
2103
+ in it, and may be slightly faster since it doesn't require looking
2104
+ up a group in GAP. To get a permutation group from a PARI
2105
+ group ``P``, type ``PermutationGroup(P)``.
2106
+
2107
+ - ``algorithm`` -- ``'pari'``, ``'gap'``, ``'kash'``, ``'magma'`` (default:
2108
+ ``'pari'``, for degrees is at most 11;
2109
+ ``'gap'``, for degrees from 12 to 15;
2110
+ ``'kash'``, for degrees from 16 or more).
2111
+
2112
+ OUTPUT: Galois group
2113
+
2114
+ ALGORITHM:
2115
+
2116
+ The Galois group is computed using PARI in C library mode, or possibly
2117
+ GAP, KASH, or MAGMA.
2118
+
2119
+ .. NOTE::
2120
+
2121
+ The PARI documentation contains the following warning: The method
2122
+ used is that of resolvent polynomials and is sensitive to the
2123
+ current precision. The precision is updated internally but, in very
2124
+ rare cases, a wrong result may be returned if the initial precision
2125
+ was not sufficient.
2126
+
2127
+ GAP uses the "Transitive Groups Libraries" from the "TransGrp"
2128
+ GAP package which comes installed with the "gap" Sage package.
2129
+
2130
+ MAGMA does not return a provably correct result. Please see the
2131
+ MAGMA documentation for how to obtain a provably correct result.
2132
+
2133
+ EXAMPLES::
2134
+
2135
+ sage: # needs sage.groups sage.libs.pari
2136
+ sage: R.<x> = QQ[]
2137
+ sage: f = x^4 - 17*x^3 - 2*x + 1
2138
+ sage: G = f.galois_group(); G
2139
+ Transitive group number 5 of degree 4
2140
+ sage: G.gens()
2141
+ ((1,2,3,4), (1,2))
2142
+ sage: G.order()
2143
+ 24
2144
+
2145
+ It is potentially useful to instead obtain the corresponding PARI
2146
+ group, which is little more than a 4-tuple. See the PARI manual for
2147
+ the exact details. (Note that the third entry in the tuple is in the
2148
+ new standard ordering.)
2149
+
2150
+ ::
2151
+
2152
+ sage: # needs sage.groups sage.libs.pari
2153
+ sage: f = x^4 - 17*x^3 - 2*x + 1
2154
+ sage: G = f.galois_group(pari_group=True); G
2155
+ PARI group [24, -1, 5, "S4"] of degree 4
2156
+ sage: PermutationGroup(G)
2157
+ Transitive group number 5 of degree 4
2158
+
2159
+ You can use KASH or GAP to compute Galois groups as well. The advantage is
2160
+ that KASH (resp. GAP) can compute Galois groups of fields up to
2161
+ degree 23 (resp. 15), whereas PARI only goes to degree 11.
2162
+ (In my not-so-thorough experiments PARI is faster than KASH.)
2163
+
2164
+ ::
2165
+
2166
+ sage: R.<x> = QQ[]
2167
+ sage: f = x^4 - 17*x^3 - 2*x + 1
2168
+ sage: f.galois_group(algorithm='kash') # optional - kash
2169
+ Transitive group number 5 of degree 4
2170
+
2171
+ sage: # needs sage.libs.gap
2172
+ sage: f = x^4 - 17*x^3 - 2*x + 1
2173
+ sage: f.galois_group(algorithm='gap')
2174
+ Transitive group number 5 of degree 4
2175
+ sage: f = x^13 - 17*x^3 - 2*x + 1
2176
+ sage: f.galois_group(algorithm='gap')
2177
+ Transitive group number 9 of degree 13
2178
+ sage: f = x^12 - 2*x^8 - x^7 + 2*x^6 + 4*x^4 - 2*x^3 - x^2 - x + 1
2179
+ sage: f.galois_group(algorithm='gap')
2180
+ Transitive group number 183 of degree 12
2181
+
2182
+ sage: f.galois_group(algorithm='magma') # optional - magma
2183
+ Transitive group number 183 of degree 12
2184
+
2185
+ TESTS:
2186
+
2187
+ We illustrate the behaviour in the case of reducible polynomials::
2188
+
2189
+ sage: R.<t> = QQ[]
2190
+ sage: f = (1 + t)^2
2191
+ sage: f.galois_group()
2192
+ Traceback (most recent call last):
2193
+ ...
2194
+ ValueError: The polynomial must be irreducible
2195
+
2196
+ Variable names that are reserved in PARI, such as ``zeta``,
2197
+ are supported (see :issue:`20631`)::
2198
+
2199
+ sage: R.<zeta> = QQ[]
2200
+ sage: (zeta^2 + zeta + 1).galois_group(pari_group=True) # needs sage.libs.pari
2201
+ PARI group [2, -1, 1, "S2"] of degree 2
2202
+ """
2203
+ if not self.is_irreducible():
2204
+ raise ValueError("The polynomial must be irreducible")
2205
+
2206
+ if self.degree() > 11 and algorithm == 'pari':
2207
+ if self.degree() < 16:
2208
+ algorithm = 'gap'
2209
+ else:
2210
+ algorithm = 'kash'
2211
+
2212
+ if self.degree() > 21 and algorithm == 'kash':
2213
+ raise NotImplementedError("Galois group computation is "
2214
+ "supported for degrees up to 11 using PARI, or up to 21 "
2215
+ "if KASH is installed. Try "
2216
+ "algorithm='magma' if you have magma.")
2217
+
2218
+ if algorithm == 'pari':
2219
+ from sage.groups.pari_group import PariGroup
2220
+ G = self._pari_with_name().Polrev().polgalois()
2221
+ H = PariGroup(G, self.degree())
2222
+ if pari_group:
2223
+ return H
2224
+ else:
2225
+ from sage.groups.perm_gps.permgroup import PermutationGroup
2226
+ return PermutationGroup(H)
2227
+
2228
+ elif algorithm == 'kash':
2229
+ try:
2230
+ from sage.interfaces.kash import kash
2231
+ from sage.groups.perm_gps.permgroup_named import TransitiveGroup
2232
+ kash.eval('X := PolynomialRing(RationalField()).1')
2233
+ s = self._repr(name='X')
2234
+ G = kash('Galois(%s)' % s)
2235
+ d = int(kash.eval('%s.ext1' % G.name()))
2236
+ n = int(kash.eval('%s.ext2' % G.name()))
2237
+ return TransitiveGroup(d, n)
2238
+ except RuntimeError as msg:
2239
+ raise NotImplementedError(str(msg) + "\nSorry, " +
2240
+ "computation of Galois groups of fields of degree " +
2241
+ "bigger than 11 is not yet implemented. Try installing " +
2242
+ "the optional free (closed source) KASH software, which " +
2243
+ "supports degrees up to 21, or use algorithm='magma' if " +
2244
+ "you have magma.")
2245
+
2246
+ elif algorithm == 'gap':
2247
+ if self.degree() > 15:
2248
+ raise NotImplementedError("Galois group computation is " +
2249
+ "supported for degrees up to 15 using GAP. Try " +
2250
+ "algorithm='kash'.")
2251
+ from sage.libs.gap.libgap import libgap
2252
+ from sage.groups.perm_gps.permgroup_named import TransitiveGroup
2253
+ fgap = libgap(self)
2254
+ return TransitiveGroup(self.degree(), fgap.GaloisType())
2255
+
2256
+ elif algorithm == 'magma':
2257
+ from sage.interfaces.magma import magma
2258
+ from sage.groups.perm_gps.permgroup_named import TransitiveGroup
2259
+ X = magma(self).GaloisGroup()
2260
+ try:
2261
+ n, d = X.TransitiveGroupIdentification(nvals=2)
2262
+ d = int(d)
2263
+ n = int(n)
2264
+ except RuntimeError as msg:
2265
+ raise RuntimeError(str(msg) + "\nUnable to lookup " +
2266
+ "description of Galois group as a transitive " +
2267
+ "group.\n%s" % X)
2268
+ return TransitiveGroup(d, n)
2269
+
2270
+ else:
2271
+ raise ValueError("Algorithm %s not supported." % algorithm)
2272
+
2273
+ def factor_mod(self, p):
2274
+ """
2275
+ Return the factorization of ``self`` modulo the prime `p`.
2276
+
2277
+ Assumes that the degree of this polynomial is at least one, and raises
2278
+ a :exc:`ValueError` otherwise.
2279
+
2280
+ INPUT:
2281
+
2282
+ - ``p`` -- prime number
2283
+
2284
+ OUTPUT: factorization of this polynomial modulo `p`
2285
+
2286
+ EXAMPLES::
2287
+
2288
+ sage: # needs sage.libs.pari
2289
+ sage: R.<x> = QQ[]
2290
+ sage: (x^5 + 17*x^3 + x + 3).factor_mod(3)
2291
+ x * (x^2 + 1)^2
2292
+ sage: (x^5 + 2).factor_mod(5)
2293
+ (x + 2)^5
2294
+
2295
+ Variable names that are reserved in PARI, such as ``zeta``,
2296
+ are supported (see :issue:`20631`)::
2297
+
2298
+ sage: R.<zeta> = QQ[]
2299
+ sage: (zeta^2 + zeta + 1).factor_mod(7) # needs sage.libs.pari
2300
+ (zeta + 3) * (zeta + 5)
2301
+ """
2302
+ from sage.rings.finite_rings.finite_field_constructor import FiniteField
2303
+
2304
+ p = Integer(p)
2305
+ if not p.is_prime():
2306
+ raise ValueError("p must be prime")
2307
+
2308
+ if self.degree() < 1:
2309
+ raise ValueError("The polynomial must have degree at least 1")
2310
+
2311
+ G = self._pari_with_name().factormod(p)
2312
+ K = FiniteField(p)
2313
+ R = K[self.parent().variable_name()]
2314
+ return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient())
2315
+
2316
+ def factor_padic(self, p, prec=10):
2317
+ r"""
2318
+ Return the `p`-adic factorization of this polynomial to the given
2319
+ precision.
2320
+
2321
+ INPUT:
2322
+
2323
+ - ``p`` -- prime number
2324
+
2325
+ - ``prec`` -- integer; the precision
2326
+
2327
+ OUTPUT: factorization of ``self`` viewed as a `p`-adic polynomial
2328
+
2329
+ EXAMPLES::
2330
+
2331
+ sage: # needs sage.rings.padic
2332
+ sage: R.<x> = QQ[]
2333
+ sage: f = x^3 - 2
2334
+ sage: f.factor_padic(2)
2335
+ (1 + O(2^10))*x^3 + O(2^10)*x^2 + O(2^10)*x
2336
+ + 2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10)
2337
+ sage: f.factor_padic(3)
2338
+ (1 + O(3^10))*x^3 + O(3^10)*x^2 + O(3^10)*x
2339
+ + 1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10)
2340
+ sage: f.factor_padic(5)
2341
+ ((1 + O(5^10))*x
2342
+ + 2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10))
2343
+ * ((1 + O(5^10))*x^2
2344
+ + (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x
2345
+ + 4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10))
2346
+
2347
+ The input polynomial is considered to have "infinite" precision,
2348
+ therefore the `p`-adic factorization of the polynomial is not
2349
+ the same as first coercing to `\QQ_p` and then factoring
2350
+ (see also :issue:`15422`)::
2351
+
2352
+ sage: # needs sage.rings.padic
2353
+ sage: f = x^2 - 3^6
2354
+ sage: f.factor_padic(3, 5)
2355
+ ((1 + O(3^5))*x + 3^3 + O(3^5)) * ((1 + O(3^5))*x + 2*3^3 + 2*3^4 + O(3^5))
2356
+ sage: f.change_ring(Qp(3,5)).factor()
2357
+ Traceback (most recent call last):
2358
+ ...
2359
+ PrecisionError: p-adic factorization not well-defined since
2360
+ the discriminant is zero up to the requestion p-adic precision
2361
+
2362
+ A more difficult example::
2363
+
2364
+ sage: R.<x> = QQ[]
2365
+ sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
2366
+ sage: f.factor_padic(5, 10) # needs sage.rings.padic
2367
+ (4*5^4 + O(5^14)) * ((1 + O(5^9))*x + 5^-1 + O(5^9))^2
2368
+ * ((1 + O(5^10))*x + 5 + O(5^10))^2
2369
+
2370
+ Try some bogus inputs::
2371
+
2372
+ sage: # needs sage.rings.padic
2373
+ sage: f.factor_padic(3, -1)
2374
+ Traceback (most recent call last):
2375
+ ...
2376
+ ValueError: prec_cap must be nonnegative
2377
+ sage: f.factor_padic(6, 10)
2378
+ Traceback (most recent call last):
2379
+ ...
2380
+ ValueError: p must be prime
2381
+ sage: f.factor_padic('hello', 'world')
2382
+ Traceback (most recent call last):
2383
+ ...
2384
+ TypeError: unable to convert 'hello' to an integer
2385
+ """
2386
+ from sage.rings.padics.factory import Qp
2387
+
2388
+ p = Integer(p)
2389
+ prec = Integer(prec)
2390
+
2391
+ # Parent field for coefficients and polynomial
2392
+ K = Qp(p, prec, type='capped-rel')
2393
+ R = K[self.parent().variable_name()]
2394
+
2395
+ # Factor the *exact* polynomial using factorpadic()
2396
+ G = self._pari_with_name().factorpadic(p, prec)
2397
+
2398
+ from sage.rings.polynomial.padics.polynomial_padic import _pari_padic_factorization_to_sage
2399
+ return _pari_padic_factorization_to_sage(G, R, self.leading_coefficient())
2400
+
2401
+ def hensel_lift(self, p, e):
2402
+ r"""
2403
+ Assuming that this polynomial factors modulo `p` into distinct
2404
+ monic factors, computes the Hensel lifts of these factors modulo
2405
+ `p^e`. We assume that ``self`` has integer coefficients.
2406
+
2407
+ Return an empty list if this polynomial has degree less than one.
2408
+
2409
+ INPUT:
2410
+
2411
+ - ``p`` -- prime number; coerceable to :class:`Integer`
2412
+ - ``e`` -- exponent; coerceable to :class:`Integer`
2413
+
2414
+ OUTPUT: Hensel lifts; list of polynomials over `\ZZ / p^e \ZZ`
2415
+
2416
+ EXAMPLES::
2417
+
2418
+ sage: R.<x> = QQ[]
2419
+ sage: R((x-1)*(x+1)).hensel_lift(7, 2) # needs sage.libs.pari
2420
+ [x + 1, x + 48]
2421
+
2422
+ If the input polynomial `f` is not monic, we get a factorization of
2423
+ `f / lc(f)`::
2424
+
2425
+ sage: R(2*x^2 - 2).hensel_lift(7, 2) # needs sage.libs.pari
2426
+ [x + 1, x + 48]
2427
+
2428
+ TESTS::
2429
+
2430
+ sage: # needs sage.libs.pari
2431
+ sage: R.<x> = QQ[]
2432
+ sage: R(0).hensel_lift(7, 2)
2433
+ []
2434
+ sage: R(x).hensel_lift(7, 2)
2435
+ [x]
2436
+ sage: R(x - 1).hensel_lift(7, 2)
2437
+ [x + 48]
2438
+
2439
+ Variable names that are reserved in PARI, such as ``I``, are
2440
+ supported (see :issue:`20631`)::
2441
+
2442
+ sage: # needs sage.libs.pari
2443
+ sage: R.<I> = QQ[]
2444
+ sage: (I^2 + 1).hensel_lift(5, 3)
2445
+ [I + 57, I + 68]
2446
+ sage: (I^2 + 1).hensel_lift(2, 3)
2447
+ Traceback (most recent call last):
2448
+ ...
2449
+ ValueError: I^2 + 1 is not square-free modulo 2
2450
+ """
2451
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
2452
+
2453
+ p = Integer(p)
2454
+ if not p.is_prime():
2455
+ raise ValueError("p must be prime")
2456
+ e = Integer(e)
2457
+ if e < 1:
2458
+ raise ValueError("e must be at least 1")
2459
+
2460
+ # The relevant PARI method doesn't seem to play well with constant and
2461
+ # linear polynomials, so we handle these separately.
2462
+ #
2463
+ if self.degree() < 1:
2464
+ return [ ]
2465
+ elif self.degree() == 1:
2466
+ R = IntegerModRing(p**e)
2467
+ S = R[self.parent().variable_name()]
2468
+ return [S(self)]
2469
+
2470
+ f = self._pari_with_name()
2471
+ F = f.factormod(p)
2472
+ if any(n > 1 for n in F[1]):
2473
+ raise ValueError("{} is not square-free modulo {}".format(self, p))
2474
+ H = f.polhensellift(F[0].liftint(), p, e)
2475
+ R = IntegerModRing(p**e)
2476
+ S = R[self.parent().variable_name()]
2477
+ return [S(m) for m in H]
2478
+
2479
+ def discriminant(self):
2480
+ r"""
2481
+ Return the discriminant of this polynomial.
2482
+
2483
+ The discriminant `R_n` is defined as
2484
+
2485
+ .. MATH::
2486
+
2487
+ R_n = a_n^{2 n-2} \prod_{1 \le i < j \le n} (r_i - r_j)^2,
2488
+
2489
+ where `n` is the degree of this polynomial, `a_n` is the leading
2490
+ coefficient and the roots over `\QQbar` are `r_1, \ldots, r_n`.
2491
+
2492
+ The discriminant of constant polynomials is defined to be 0.
2493
+
2494
+ OUTPUT: discriminant, an element of the base ring of the polynomial ring
2495
+
2496
+ .. NOTE::
2497
+
2498
+ Note the identity `R_n(f) := (-1)^{(n (n-1)/2)} R(f,f') a_n^{(n-k-2)}`,
2499
+ where `n` is the degree of this polynomial, `a_n` is the leading
2500
+ coefficient, `f'` is the derivative of `f`, and `k` is the degree
2501
+ of `f'`. Calls :meth:`resultant`.
2502
+
2503
+ ALGORITHM:
2504
+
2505
+ Use PARI.
2506
+
2507
+ EXAMPLES:
2508
+
2509
+ In the case of elliptic curves in special form, the discriminant is
2510
+ easy to calculate::
2511
+
2512
+ sage: R.<t> = QQ[]
2513
+ sage: f = t^3 + t + 1
2514
+ sage: d = f.discriminant(); d # needs sage.libs.pari
2515
+ -31
2516
+ sage: d.parent() is QQ # needs sage.libs.pari
2517
+ True
2518
+ sage: EllipticCurve([1, 1]).discriminant() / 16 # needs sage.schemes
2519
+ -31
2520
+
2521
+ ::
2522
+
2523
+ sage: R.<t> = QQ[]
2524
+ sage: f = 2*t^3 + t + 1
2525
+ sage: d = f.discriminant(); d # needs sage.libs.pari
2526
+ -116
2527
+
2528
+ ::
2529
+
2530
+ sage: R.<t> = QQ[]
2531
+ sage: f = t^3 + 3*t - 17
2532
+ sage: f.discriminant() # needs sage.libs.pari
2533
+ -7911
2534
+
2535
+ TESTS::
2536
+
2537
+ sage: # needs sage.libs.pari
2538
+ sage: R.<t> = QQ[]
2539
+ sage: R(0).discriminant()
2540
+ 0
2541
+ sage: R(2/3).discriminant()
2542
+ 0
2543
+ sage: (t + 1/2).discriminant()
2544
+ 1
2545
+
2546
+ Variable names that are reserved in PARI, such as ``I``, are
2547
+ supported (see :issue:`20631`)::
2548
+
2549
+ sage: R.<I> = QQ[]
2550
+ sage: (I^2 + 1).discriminant() # needs sage.libs.pari
2551
+ -4
2552
+ """
2553
+ return QQ(self._pari_with_name().poldisc())
2554
+
2555
+ # Alias for discriminant
2556
+ disc = discriminant
2557
+
2558
+ def galois_group_davenport_smith_test(self, num_trials=50, assume_irreducible=False):
2559
+ """
2560
+ Use the Davenport-Smith test to attempt to certify that `f` has Galois group `A_n` or `S_n`.
2561
+
2562
+ Return 1 if the Galois group is certified as `S_n`, 2 if `A_n`, or 0 if no conclusion is reached.
2563
+
2564
+ By default, we first check that `f` is irreducible. For extra efficiency, one can override this
2565
+ by specifying ``assume_irreducible=True``; this yields undefined results if `f` is not irreducible.
2566
+
2567
+ A corresponding function in Magma is ``IsEasySnAn``.
2568
+
2569
+ EXAMPLES::
2570
+
2571
+ sage: # needs sage.libs.pari
2572
+ sage: P.<x> = QQ[]
2573
+ sage: u = x^7 + x + 1
2574
+ sage: u.galois_group_davenport_smith_test()
2575
+ 1
2576
+ sage: u = x^7 - x^4 - x^3 + 3*x^2 - 1
2577
+ sage: u.galois_group_davenport_smith_test()
2578
+ 2
2579
+ sage: u = x^7 - 2
2580
+ sage: u.galois_group_davenport_smith_test()
2581
+ 0
2582
+ """
2583
+ from sage.arith.misc import primes_first_n
2584
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
2585
+
2586
+ if not assume_irreducible and not self.is_irreducible():
2587
+ return 0
2588
+ d = self.degree()
2589
+ for p in primes_first_n(num_trials):
2590
+ fp = self.change_ring(IntegerModRing(p))
2591
+ g = fp.factor()[-1][0]
2592
+ d1 = g.degree()
2593
+ # Here we use the fact that a transitive permutation representation with a long prime cycle
2594
+ # must have image at least as big as A_n.
2595
+ if (d1 <= 7 and (d,d1) in ((1,1),(2,2),(3,2),(3,3),(4,3),(5,3),(5,4),(6,5),(7,5))) or\
2596
+ (d1 > d/2 and d1 < d-2 and d1.is_prime()):
2597
+ return (2 if self.disc().is_square() else 1)
2598
+ return 0