passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_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 (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,3784 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ """
3
+ Univariate Polynomial Rings
4
+
5
+ Sage implements sparse and dense polynomials over commutative and
6
+ non-commutative rings. In the non-commutative case, the polynomial
7
+ variable commutes with the elements of the base ring.
8
+
9
+ AUTHOR:
10
+
11
+ - William Stein
12
+
13
+ - Kiran Kedlaya (2006-02-13): added macaulay2 option
14
+
15
+ - Martin Albrecht (2006-08-25): removed it again as it isn't needed anymore
16
+
17
+ - Simon King (2011-05): Dense and sparse polynomial rings must not be equal.
18
+
19
+ - Simon King (2011-10): Choice of categories for polynomial rings.
20
+
21
+ EXAMPLES::
22
+
23
+ sage: z = QQ['z'].0
24
+ sage: (z^3 + z - 1)^3
25
+ z^9 + 3*z^7 - 3*z^6 + 3*z^5 - 6*z^4 + 4*z^3 - 3*z^2 + 3*z - 1
26
+
27
+ Saving and loading of polynomial rings works::
28
+
29
+ sage: loads(dumps(QQ['x'])) == QQ['x']
30
+ True
31
+ sage: k = PolynomialRing(QQ['x'],'y'); loads(dumps(k))==k
32
+ True
33
+ sage: k = PolynomialRing(ZZ,'y'); loads(dumps(k)) == k
34
+ True
35
+ sage: k = PolynomialRing(ZZ,'y', sparse=True); loads(dumps(k))
36
+ Sparse Univariate Polynomial Ring in y over Integer Ring
37
+
38
+ Rings with different variable names are not equal; in fact,
39
+ by :issue:`9944`, polynomial rings are equal if and only
40
+ if they are identical (which should be the case for all parent
41
+ structures in Sage)::
42
+
43
+ sage: QQ['y'] != QQ['x']
44
+ True
45
+ sage: QQ['y'] != QQ['z']
46
+ True
47
+
48
+ We create a polynomial ring over a quaternion algebra::
49
+
50
+ sage: # needs sage.combinat sage.libs.singular sage.modules
51
+ sage: A.<i,j,k> = QuaternionAlgebra(QQ, -1,-1)
52
+ sage: R.<w> = PolynomialRing(A, sparse=True)
53
+ sage: f = w^3 + (i+j)*w + 1
54
+ sage: f
55
+ w^3 + (i + j)*w + 1
56
+ sage: f^2
57
+ w^6 + (2*i + 2*j)*w^4 + 2*w^3 - 2*w^2 + (2*i + 2*j)*w + 1
58
+ sage: f = w + i ; g = w + j
59
+ sage: f * g
60
+ w^2 + (i + j)*w + k
61
+ sage: g * f
62
+ w^2 + (i + j)*w - k
63
+
64
+ :issue:`9944` introduced some changes related with
65
+ coercion. Previously, a dense and a sparse polynomial ring with the
66
+ same variable name over the same base ring evaluated equal, but of
67
+ course they were not identical. Coercion maps are cached - but if a
68
+ coercion to a dense ring is requested and a coercion to a sparse ring
69
+ is returned instead (since the cache keys are equal!), all hell breaks
70
+ loose.
71
+
72
+ Therefore, the coercion between rings of sparse and dense polynomials
73
+ works as follows::
74
+
75
+ sage: R.<x> = PolynomialRing(QQ, sparse=True)
76
+ sage: S.<x> = QQ[]
77
+ sage: S == R
78
+ False
79
+ sage: S.has_coerce_map_from(R)
80
+ True
81
+ sage: R.has_coerce_map_from(S)
82
+ False
83
+ sage: (R.0 + S.0).parent()
84
+ Univariate Polynomial Ring in x over Rational Field
85
+ sage: (S.0 + R.0).parent()
86
+ Univariate Polynomial Ring in x over Rational Field
87
+
88
+ It may be that one has rings of dense or sparse polynomials over
89
+ different base rings. In that situation, coercion works by means of
90
+ the :func:`~sage.categories.pushout.pushout` formalism::
91
+
92
+ sage: R.<x> = PolynomialRing(GF(5), sparse=True)
93
+ sage: S.<x> = PolynomialRing(ZZ)
94
+ sage: R.has_coerce_map_from(S)
95
+ False
96
+ sage: S.has_coerce_map_from(R)
97
+ False
98
+ sage: S.0 + R.0
99
+ 2*x
100
+ sage: (S.0 + R.0).parent()
101
+ Univariate Polynomial Ring in x over Finite Field of size 5
102
+ sage: (S.0 + R.0).parent().is_sparse()
103
+ False
104
+
105
+ Similarly, there is a coercion from the (non-default) NTL
106
+ implementation for univariate polynomials over the integers
107
+ to the default FLINT implementation, but not vice versa::
108
+
109
+ sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') # needs sage.libs.ntl
110
+ sage: S.<x> = PolynomialRing(ZZ, implementation='FLINT')
111
+ sage: (S.0 + R.0).parent() is S # needs sage.libs.flint sage.libs.ntl
112
+ True
113
+ sage: (R.0 + S.0).parent() is S # needs sage.libs.flint sage.libs.ntl
114
+ True
115
+
116
+ TESTS::
117
+
118
+ sage: K.<x> = FractionField(QQ['x'])
119
+ sage: V.<z> = K[]
120
+ sage: x+z
121
+ z + x
122
+
123
+ Check that :issue:`5562` has been fixed::
124
+
125
+ sage: R.<u> = PolynomialRing(RDF, 1)
126
+ sage: v1 = vector([u]) # needs sage.modules
127
+ sage: v2 = vector([CDF(2)]) # needs sage.modules
128
+ sage: v1 * v2 # needs sage.modules
129
+ 2.0*u
130
+ """
131
+
132
+ # ****************************************************************************
133
+ # Copyright (C) 2006 William Stein <wstein@gmail.com>
134
+ #
135
+ # This program is free software: you can redistribute it and/or modify
136
+ # it under the terms of the GNU General Public License as published by
137
+ # the Free Software Foundation, either version 2 of the License, or
138
+ # (at your option) any later version.
139
+ # https://www.gnu.org/licenses/
140
+ # ****************************************************************************
141
+
142
+
143
+ import sys
144
+
145
+ from sage.misc.superseded import deprecation
146
+ from sage.structure.element import Element
147
+ from sage.structure.category_object import check_default_category
148
+
149
+ import sage.categories as categories
150
+ from sage.categories.morphism import IdentityMorphism
151
+ from sage.categories.principal_ideal_domains import PrincipalIdealDomains
152
+ from sage.categories.rings import Rings
153
+
154
+ from sage.rings.ring import Ring, CommutativeRing
155
+ from sage.structure.element import RingElement
156
+ import sage.rings.rational_field as rational_field
157
+ from sage.rings.rational_field import QQ
158
+ from sage.rings.integer_ring import ZZ
159
+ from sage.rings.integer import Integer
160
+ from sage.rings.number_field.number_field_base import NumberField
161
+
162
+ try:
163
+ from cypari2.gen import Gen as pari_gen
164
+ except ImportError:
165
+ pari_gen = ()
166
+
167
+ from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category
168
+
169
+ import sage.misc.latex as latex
170
+ from sage.misc.cachefunc import cached_method
171
+ from sage.misc.lazy_attribute import lazy_attribute
172
+
173
+ import sage.rings.abc
174
+ from sage.rings.fraction_field_element import FractionFieldElement
175
+ from sage.rings.finite_rings.element_base import FiniteRingElement
176
+ from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr
177
+ from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
178
+ from sage.rings.power_series_ring_element import PowerSeries
179
+
180
+ _CommutativeRings = categories.commutative_rings.CommutativeRings()
181
+
182
+ import sage.interfaces.abc
183
+
184
+
185
+ def is_PolynomialRing(x):
186
+ """
187
+ Return ``True`` if ``x`` is a *univariate* polynomial ring (and not a
188
+ sparse multivariate polynomial ring in one variable).
189
+
190
+ EXAMPLES::
191
+
192
+ sage: from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
193
+ sage: from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
194
+ sage: is_PolynomialRing(2)
195
+ doctest:warning...
196
+ DeprecationWarning: The function is_PolynomialRing is deprecated;
197
+ use 'isinstance(..., PolynomialRing_generic)' instead.
198
+ See https://github.com/sagemath/sage/issues/38266 for details.
199
+ False
200
+
201
+ This polynomial ring is not univariate.
202
+
203
+ ::
204
+
205
+ sage: is_PolynomialRing(ZZ['x,y,z'])
206
+ False
207
+ sage: is_MPolynomialRing(ZZ['x,y,z'])
208
+ doctest:warning...
209
+ DeprecationWarning: The function is_MPolynomialRing is deprecated;
210
+ use 'isinstance(..., MPolynomialRing_base)' instead.
211
+ See https://github.com/sagemath/sage/issues/38266 for details.
212
+ True
213
+
214
+ ::
215
+
216
+ sage: is_PolynomialRing(ZZ['w'])
217
+ True
218
+
219
+ Univariate means not only in one variable, but is a specific data
220
+ type. There is a multivariate (sparse) polynomial ring data type,
221
+ which supports a single variable as a special case.
222
+
223
+ ::
224
+
225
+ sage: # needs sage.libs.singular
226
+ sage: R.<w> = PolynomialRing(ZZ, implementation='singular'); R
227
+ Multivariate Polynomial Ring in w over Integer Ring
228
+ sage: is_PolynomialRing(R)
229
+ False
230
+ sage: type(R)
231
+ <class 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
232
+ """
233
+ deprecation(38266,
234
+ "The function is_PolynomialRing is deprecated; "
235
+ "use 'isinstance(..., PolynomialRing_generic)' instead.")
236
+ return isinstance(x, PolynomialRing_generic)
237
+
238
+
239
+ #########################################################################################
240
+
241
+ class PolynomialRing_generic(Ring):
242
+ """
243
+ Univariate polynomial ring over a ring.
244
+ """
245
+
246
+ def __init__(self, base_ring, name=None, sparse=False, implementation=None,
247
+ element_class=None, category=None):
248
+ """
249
+ EXAMPLES::
250
+
251
+ sage: R.<x> = QQ['x']
252
+ sage: R(-1) + R(1)
253
+ 0
254
+ sage: (x - 2/3)*(x^2 - 8*x + 16)
255
+ x^3 - 26/3*x^2 + 64/3*x - 32/3
256
+
257
+ sage: category(ZZ['x'])
258
+ Join of Category of unique factorization domains
259
+ and Category of algebras with basis over
260
+ (Dedekind domains and euclidean domains
261
+ and noetherian rings and infinite enumerated sets
262
+ and metric spaces)
263
+ and Category of commutative algebras over
264
+ (Dedekind domains and euclidean domains
265
+ and noetherian rings and infinite enumerated sets
266
+ and metric spaces)
267
+ and Category of infinite sets
268
+
269
+ sage: category(GF(7)['x'])
270
+ Join of Category of euclidean domains
271
+ and Category of algebras with basis over
272
+ (finite enumerated fields and subquotients of monoids
273
+ and quotients of semigroups)
274
+ and Category of commutative algebras over
275
+ (finite enumerated fields and subquotients of monoids
276
+ and quotients of semigroups)
277
+ and Category of infinite sets
278
+
279
+ TESTS:
280
+
281
+ Verify that :issue:`15232` has been resolved::
282
+
283
+ sage: K.<x> = FunctionField(QQ)
284
+ sage: R.<y> = K[]
285
+ sage: TestSuite(R).run()
286
+
287
+ Check that category for zero ring::
288
+
289
+ sage: PolynomialRing(Zmod(1), 'x').category()
290
+ Category of finite commutative rings
291
+
292
+ Check ``is_finite`` inherited from category (:issue:`24432`)::
293
+
294
+ sage: Zmod(1)['x'].is_finite()
295
+ True
296
+
297
+ sage: GF(7)['x'].is_finite()
298
+ False
299
+
300
+ sage: Zmod(1)['x']['y'].is_finite()
301
+ True
302
+
303
+ sage: GF(7)['x']['y'].is_finite()
304
+ False
305
+ """
306
+ # We trust that, if category is given, it is useful and does not need to be joined
307
+ # with the default category
308
+ if base_ring.is_zero():
309
+ category = categories.rings.Rings().Commutative().Finite()
310
+ else:
311
+ defaultcat = polynomial_default_category(base_ring.category(), 1)
312
+ category = check_default_category(defaultcat, category)
313
+ self.__is_sparse = sparse
314
+ if element_class:
315
+ self._polynomial_class = element_class
316
+ else:
317
+ if sparse:
318
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse
319
+ self._polynomial_class = Polynomial_generic_sparse
320
+ else:
321
+ from sage.rings.polynomial.polynomial_element import Polynomial_generic_dense
322
+ self._polynomial_class = Polynomial_generic_dense
323
+ self.Element = self._polynomial_class
324
+ self.__cyclopoly_cache = {}
325
+ self._has_singular = False
326
+ Ring.__init__(self, base_ring, names=name, normalize=True, category=category)
327
+ from sage.rings.semirings.non_negative_integer_semiring import NonNegativeIntegerSemiring
328
+ self._indices = NonNegativeIntegerSemiring()
329
+ self._populate_coercion_lists_(convert_method_name='_polynomial_')
330
+
331
+ def __reduce__(self):
332
+ from sage.rings.polynomial.polynomial_ring_constructor import unpickle_PolynomialRing
333
+ args = (self.base_ring(), self.variable_names(), None, self.is_sparse())
334
+ return unpickle_PolynomialRing, args
335
+
336
+ def _element_constructor_(self, x=None, check=True, is_gen=False,
337
+ construct=False, **kwds):
338
+ r"""
339
+ Convert ``x`` into this univariate polynomial ring,
340
+ possibly non-canonically.
341
+
342
+ Conversion from power series::
343
+
344
+ sage: R.<x> = QQ[]
345
+ sage: R(1 + x + x^2 + O(x^3))
346
+ x^2 + x + 1
347
+
348
+ Stacked polynomial rings coerce into constants if possible. First,
349
+ the univariate case::
350
+
351
+ sage: R.<x> = QQ[]
352
+ sage: S.<u> = R[]
353
+ sage: S(u + 2)
354
+ u + 2
355
+ sage: S(x + 3)
356
+ x + 3
357
+ sage: S(x + 3).degree()
358
+ 0
359
+
360
+ Second, the multivariate case::
361
+
362
+ sage: R.<x,y> = QQ[]
363
+ sage: S.<u> = R[]
364
+ sage: S(x + 2*y)
365
+ x + 2*y
366
+ sage: S(x + 2*y).degree()
367
+ 0
368
+ sage: S(u + 2*x)
369
+ u + 2*x
370
+ sage: S(u + 2*x).degree()
371
+ 1
372
+
373
+ Foreign polynomial rings coerce into the highest ring; the point
374
+ here is that an element of T could coerce to an element of R or an
375
+ element of S; it is anticipated that an element of T is more likely
376
+ to be "the right thing" and is historically consistent.
377
+
378
+ ::
379
+
380
+ sage: R.<x> = QQ[]
381
+ sage: S.<u> = R[]
382
+ sage: T.<a> = QQ[]
383
+ sage: S(a)
384
+ u
385
+
386
+ Coercing in pari elements::
387
+
388
+ sage: QQ['x'](pari('[1,2,3/5]')) # needs sage.libs.pari
389
+ 3/5*x^2 + 2*x + 1
390
+ sage: QQ['x'](pari('(-1/3)*x^10 + (2/3)*x - 1/5')) # needs sage.libs.pari
391
+ -1/3*x^10 + 2/3*x - 1/5
392
+
393
+ Coercing strings::
394
+
395
+ sage: QQ['y']('-y')
396
+ -y
397
+
398
+ TESTS:
399
+
400
+ Python 3 range is allowed::
401
+
402
+ sage: R = PolynomialRing(ZZ,'x')
403
+ sage: R(range(4))
404
+ 3*x^3 + 2*x^2 + x
405
+
406
+ This shows that the issue at :issue:`4106` is fixed::
407
+
408
+ sage: # needs sage.symbolic
409
+ sage: x = var('x')
410
+ sage: R = IntegerModRing(4)
411
+ sage: S = R['x']
412
+ sage: S(x)
413
+ x
414
+
415
+ Throw a :exc:`TypeError` if any of the coefficients cannot be coerced
416
+ into the base ring (:issue:`6777`)::
417
+
418
+ sage: RealField(300)['x']( [ 1, ComplexField(300).gen(), 0 ]) # needs sage.rings.real_mpfr
419
+ Traceback (most recent call last):
420
+ ...
421
+ TypeError: unable to convert '1.00...00*I' to a real number
422
+
423
+ Check that the bug in :issue:`11239` is fixed::
424
+
425
+ sage: # needs sage.rings.finite_rings
426
+ sage: K.<a> = GF(5^2, prefix='z')
427
+ sage: L.<b> = GF(5^4, prefix='z')
428
+ sage: f = K['x'].gen() + a
429
+ sage: L['x'](f)
430
+ x + b^3 + b^2 + b + 3
431
+
432
+ A test from :issue:`14485` ::
433
+
434
+ sage: x = SR.var('x') # needs sage.symbolic
435
+ sage: QQbar[x](x^6 + x^5 + x^4 - x^3 + x^2 - x + 2/5) # needs sage.rings.number_field sage.symbolic
436
+ x^6 + x^5 + x^4 - x^3 + x^2 - x + 2/5
437
+
438
+ Check support for unicode characters (:issue:`29280`)::
439
+
440
+ sage: QQ['λ']('λ^2')
441
+ λ^2
442
+ """
443
+ C = self.element_class
444
+ if isinstance(x, (list, tuple)):
445
+ return C(self, x, check=check, is_gen=False, construct=construct)
446
+ if isinstance(x, range):
447
+ return C(self, list(x), check=check, is_gen=False,
448
+ construct=construct)
449
+ if isinstance(x, Element):
450
+ P = x.parent()
451
+ if P is self:
452
+ return x
453
+ elif P is self.base_ring():
454
+ # It *is* the base ring, hence, we should not need to check.
455
+ # Moreover, if x is equal to zero then we usually need to
456
+ # provide [] to the polynomial class, not [x], if we don't want
457
+ # to check (normally, polynomials like to strip trailing zeroes).
458
+ # However, in the padic case, we WANT that trailing
459
+ # zeroes are not stripped, because O(5)==0, but still it must
460
+ # not be forgotten. It should be the job of the __init__ method
461
+ # to decide whether to strip or not to strip.
462
+ return C(self, [x], check=False, is_gen=False,
463
+ construct=construct)
464
+ elif P == self.base_ring():
465
+ return C(self, [x], check=True, is_gen=False,
466
+ construct=construct)
467
+ if isinstance(x, sage.interfaces.abc.SingularElement) and self._has_singular:
468
+ self._singular_().set_ring()
469
+ try:
470
+ return x.sage_poly(self)
471
+ except Exception:
472
+ raise TypeError("Unable to coerce singular object")
473
+ elif isinstance(x, str):
474
+ try:
475
+ from sage.misc.parser import Parser, LookupNameMaker
476
+ R = self.base_ring()
477
+ p = Parser(Integer, R, LookupNameMaker({self.variable_name(): self.gen()}, R))
478
+ return self(p.parse(x))
479
+ except NameError:
480
+ raise TypeError("Unable to coerce string")
481
+ elif isinstance(x, FractionFieldElement):
482
+ if x.denominator().is_unit():
483
+ x = x.numerator() * x.denominator().inverse_of_unit()
484
+ else:
485
+ raise TypeError("denominator must be a unit")
486
+ elif isinstance(x, pari_gen):
487
+ if x.type() == 't_RFRAC':
488
+ raise TypeError("denominator must be a unit")
489
+ if x.type() != 't_POL':
490
+ x = x.Polrev()
491
+ elif isinstance(x, FiniteRingElement):
492
+ try:
493
+ return self(x.polynomial())
494
+ except AttributeError:
495
+ pass
496
+ elif isinstance(x, PowerSeries):
497
+ x = x.truncate()
498
+ return C(self, x, check, is_gen, construct=construct, **kwds)
499
+
500
+ @classmethod
501
+ def _implementation_names(cls, implementation, base_ring, sparse=False):
502
+ """
503
+ Check whether this class can handle the implementation
504
+ ``implementation`` over the given base ring and sparseness.
505
+
506
+ This is a simple wrapper around :meth:`_implementation_names_impl`
507
+ which does the real work.
508
+
509
+ .. NOTE::
510
+
511
+ It is assumed that the ``base_ring`` argument is a base ring
512
+ which the class can handle.
513
+
514
+ INPUT:
515
+
516
+ - ``implementation`` -- either a string denoting a specific
517
+ implementation or ``None`` for the default
518
+
519
+ - ``base_ring`` -- the base ring for the polynomial ring
520
+
521
+ - ``sparse`` -- boolean; whether the implementation is sparse
522
+
523
+ OUTPUT:
524
+
525
+ - if the implementation is supported, the output is a list of
526
+ all names (possibly including ``None``) which refer to the
527
+ given implementation. The first element of the list is the
528
+ canonical name. If the ``__init__`` method does not take an
529
+ ``implementation`` keyword, then the first element must be
530
+ ``None``.
531
+
532
+ - if the implementation is not supported, raise a
533
+ :exc:`ValueError`.
534
+
535
+ EXAMPLES::
536
+
537
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
538
+ sage: PolynomialRing_generic._implementation_names(None, ZZ, True)
539
+ [None, 'generic']
540
+ sage: PolynomialRing_generic._implementation_names("generic", ZZ, True)
541
+ [None, 'generic']
542
+ sage: PolynomialRing_generic._implementation_names("xyzzy", ZZ, True)
543
+ Traceback (most recent call last):
544
+ ...
545
+ ValueError: unknown implementation 'xyzzy' for sparse polynomial rings over Integer Ring
546
+ """
547
+ names = cls._implementation_names_impl(implementation, base_ring, sparse)
548
+ if names is NotImplemented:
549
+ raise ValueError("unknown implementation %r for %s polynomial rings over %r" %
550
+ (implementation, "sparse" if sparse else "dense", base_ring))
551
+ assert isinstance(names, list)
552
+ assert implementation in names
553
+ return names
554
+
555
+ @staticmethod
556
+ def _implementation_names_impl(implementation, base_ring, sparse):
557
+ """
558
+ The underlying implementation of :meth:`_implementation_names`.
559
+
560
+ The behaviour is exactly the same, except that an unknown
561
+ implementation returns ``NotImplemented`` instead of raising
562
+ :exc:`ValueError`.
563
+
564
+ EXAMPLES::
565
+
566
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
567
+ sage: PolynomialRing_generic._implementation_names_impl("xyzzy", ZZ, True)
568
+ NotImplemented
569
+ """
570
+ if implementation is None or implementation == "generic":
571
+ return [None, "generic"]
572
+ return NotImplemented
573
+
574
+ def is_integral_domain(self, proof=True):
575
+ """
576
+ EXAMPLES::
577
+
578
+ sage: ZZ['x'].is_integral_domain()
579
+ True
580
+ sage: Integers(8)['x'].is_integral_domain()
581
+ False
582
+ """
583
+ return self.base_ring().is_integral_domain(proof)
584
+
585
+ def is_unique_factorization_domain(self, proof=True):
586
+ """
587
+ EXAMPLES::
588
+
589
+ sage: ZZ['x'].is_unique_factorization_domain()
590
+ True
591
+ sage: Integers(8)['x'].is_unique_factorization_domain()
592
+ False
593
+ """
594
+ return self.base_ring().is_unique_factorization_domain(proof)
595
+
596
+ def is_noetherian(self):
597
+ return self.base_ring().is_noetherian()
598
+
599
+ def some_elements(self):
600
+ r"""
601
+ Return a list of polynomials.
602
+
603
+ This is typically used for running generic tests.
604
+
605
+ EXAMPLES::
606
+
607
+ sage: R.<x> = QQ[]
608
+ sage: R.some_elements()
609
+ [x, 0, 1, 1/2, x^2 + 2*x + 1, x^3, x^2 - 1, x^2 + 1, 2*x^2 + 2]
610
+ """
611
+ # the comments in the following lines describe the motivation for
612
+ # adding these elements, they are not accurate over all rings and in
613
+ # all contexts
614
+ R = self.base_ring()
615
+ # Doing things this way is a little robust against rings where
616
+ # 2 might not convert in
617
+ one = R.one()
618
+ return [self.gen(),
619
+ self.zero(), self(one), self(R.an_element()), # elements of the base ring
620
+ self([one,2*one,one]), # a square
621
+ self([0,0,0,one]), # a power but not a square
622
+ self([-one,0,one]), # a reducible element
623
+ self([one,0,one]), # an irreducible element
624
+ self([2*one,0,2*one]), # an element with non-trivial content
625
+ ]
626
+
627
+ def monomials_of_degree(self, degree):
628
+ r"""
629
+ Return the list of all monomials of the given total
630
+ degree in this univariate polynomial ring, which is simply the list with one element ``[self.gen()**degree]``.
631
+
632
+ .. SEEALSO::
633
+
634
+ :meth:`sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base.monomials_of_degree`
635
+
636
+ EXAMPLES::
637
+
638
+ sage: R.<x> = ZZ[]
639
+ sage: mons = R.monomials_of_degree(2)
640
+ sage: mons
641
+ [x^2]
642
+ """
643
+ return [self.gen()**degree]
644
+
645
+ @cached_method
646
+ def flattening_morphism(self):
647
+ r"""
648
+ Return the flattening morphism of this polynomial ring.
649
+
650
+ EXAMPLES::
651
+
652
+ sage: QQ['a','b']['x'].flattening_morphism()
653
+ Flattening morphism:
654
+ From: Univariate Polynomial Ring in x over
655
+ Multivariate Polynomial Ring in a, b over Rational Field
656
+ To: Multivariate Polynomial Ring in a, b, x over Rational Field
657
+
658
+ sage: QQ['x'].flattening_morphism()
659
+ Identity endomorphism of Univariate Polynomial Ring in x over Rational Field
660
+ """
661
+ from .multi_polynomial_ring import MPolynomialRing_base
662
+ base = self.base_ring()
663
+ if isinstance(base, (PolynomialRing_generic, MPolynomialRing_base)):
664
+ from .flatten import FlatteningMorphism
665
+ return FlatteningMorphism(self)
666
+ else:
667
+ return IdentityMorphism(self)
668
+
669
+ def construction(self):
670
+ """
671
+ Return the construction functor.
672
+ """
673
+ return categories.pushout.PolynomialFunctor(self.variable_name(), sparse=self.__is_sparse), self.base_ring()
674
+
675
+ def completion(self, p=None, prec=20, extras=None):
676
+ r"""
677
+ Return the completion of ``self`` with respect to the irreducible
678
+ polynomial ``p``.
679
+
680
+ Currently only implemented for ``p=self.gen()`` (the default), i.e. you
681
+ can only complete `R[x]` with respect to `x`, the result being a ring
682
+ of power series in `x`. The ``prec`` variable controls the precision
683
+ used in the power series ring. If ``prec`` is `\infty`, then this
684
+ returns a :class:`LazyPowerSeriesRing`.
685
+
686
+ EXAMPLES::
687
+
688
+ sage: P.<x> = PolynomialRing(QQ)
689
+ sage: P
690
+ Univariate Polynomial Ring in x over Rational Field
691
+ sage: PP = P.completion(x)
692
+ sage: PP
693
+ Power Series Ring in x over Rational Field
694
+ sage: f = 1 - x
695
+ sage: PP(f)
696
+ 1 - x
697
+ sage: 1 / f
698
+ -1/(x - 1)
699
+ sage: g = 1 / PP(f); g
700
+ 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11
701
+ + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + O(x^20)
702
+ sage: 1 / g
703
+ 1 - x + O(x^20)
704
+
705
+ sage: # needs sage.combinat
706
+ sage: PP = P.completion(x, prec=oo); PP
707
+ Lazy Taylor Series Ring in x over Rational Field
708
+ sage: g = 1 / PP(f); g
709
+ 1 + x + x^2 + O(x^3)
710
+ sage: 1 / g == f
711
+ True
712
+ """
713
+ if p is None or str(p) == self._names[0]:
714
+ if prec == float('inf'):
715
+ from sage.rings.lazy_series_ring import LazyPowerSeriesRing
716
+ return LazyPowerSeriesRing(self.base_ring(), names=(self._names[0],),
717
+ sparse=self.is_sparse())
718
+ from sage.rings.power_series_ring import PowerSeriesRing
719
+ return PowerSeriesRing(self.base_ring(), name=self._names[0],
720
+ default_prec=prec, sparse=self.is_sparse())
721
+
722
+ raise NotImplementedError("cannot complete %s with respect to %s" % (self, p))
723
+
724
+ def _coerce_map_from_base_ring(self):
725
+ """
726
+ Return a coercion map from the base ring of ``self``.
727
+
728
+ EXAMPLES::
729
+
730
+ sage: R.<x> = QQ[]
731
+ sage: R.coerce_map_from(QQ)
732
+ Polynomial base injection morphism:
733
+ From: Rational Field
734
+ To: Univariate Polynomial Ring in x over Rational Field
735
+ sage: R.coerce_map_from(ZZ)
736
+ Composite map:
737
+ From: Integer Ring
738
+ To: Univariate Polynomial Ring in x over Rational Field
739
+ Defn: Natural morphism:
740
+ From: Integer Ring
741
+ To: Rational Field
742
+ then
743
+ Polynomial base injection morphism:
744
+ From: Rational Field
745
+ To: Univariate Polynomial Ring in x over Rational Field
746
+ sage: R.coerce_map_from(GF(7))
747
+ """
748
+ from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection
749
+
750
+ return PolynomialBaseringInjection(self.base_ring(), self)
751
+
752
+ def _coerce_map_from_(self, P):
753
+ """
754
+ The rings that canonically coerce to this polynomial ring are:
755
+
756
+ - this ring itself
757
+
758
+ - any ring that canonically coerces to the base ring of this ring.
759
+
760
+ - polynomial rings in the same variable over any base ring that
761
+ canonically coerces to the base ring of this ring.
762
+
763
+ - a multivariate polynomial ring P such that ``self``'s variable name
764
+ is among the variable names of P, and the ring obtained by
765
+ removing that variable is different from the base ring of ``self``,
766
+ but coerces into it. (see :issue:`813` for a discussion of this)
767
+
768
+ Caveat: There is no coercion from a dense into a sparse
769
+ polynomial ring. So, when adding a dense and a sparse
770
+ polynomial, the result will be dense. See :issue:`9944`.
771
+
772
+ EXAMPLES::
773
+
774
+ sage: R = QQ['x']
775
+ sage: R.has_coerce_map_from(ZZ['x'])
776
+ True
777
+ sage: R.has_coerce_map_from(ZZ['y'])
778
+ False
779
+
780
+ Here we test against the change in the coercions introduced
781
+ in :issue:`9944`::
782
+
783
+ sage: R.<x> = PolynomialRing(QQ, sparse=True)
784
+ sage: S.<x> = QQ[]
785
+ sage: (R.0 + S.0).parent()
786
+ Univariate Polynomial Ring in x over Rational Field
787
+ sage: (S.0 + R.0).parent()
788
+ Univariate Polynomial Ring in x over Rational Field
789
+
790
+ Here we test a feature that was implemented in :issue:`813`::
791
+
792
+ sage: P = QQ['x','y']
793
+ sage: Q = Frac(QQ['x'])['y']
794
+ sage: Q.has_coerce_map_from(P)
795
+ True
796
+ sage: P.0 + Q.0
797
+ y + x
798
+
799
+ In order to avoid bidirectional coercions (which are generally
800
+ problematic), we only have a coercion from P to Q if the base
801
+ ring of Q is more complicated than "P minus one variable"::
802
+
803
+ sage: Q = QQ['x']['y']
804
+ sage: P.has_coerce_map_from(Q)
805
+ True
806
+ sage: Q.has_coerce_map_from(P)
807
+ False
808
+ sage: Q.base_ring() is P.remove_var(Q.variable_name())
809
+ True
810
+
811
+ Over the integers, there is a coercion from the NTL and generic
812
+ implementation to the default FLINT implementation::
813
+
814
+ sage: del R, S # clear values from doctests above
815
+ sage: R = PolynomialRing(ZZ, 't', implementation='NTL') # needs sage.libs.ntl
816
+ sage: S = PolynomialRing(ZZ, 't', implementation='FLINT') # needs sage.libs.flint
817
+ sage: T = PolynomialRing(ZZ, 't', implementation='generic')
818
+ sage: R.has_coerce_map_from(S) # needs sage.libs.flint sage.libs.ntl
819
+ False
820
+ sage: R.has_coerce_map_from(T) # needs sage.libs.ntl
821
+ False
822
+ sage: S.has_coerce_map_from(T) # needs sage.libs.flint
823
+ True
824
+ sage: S.has_coerce_map_from(R) # needs sage.libs.flint sage.libs.ntl
825
+ True
826
+ sage: T.has_coerce_map_from(R) # needs sage.libs.ntl
827
+ False
828
+ sage: T.has_coerce_map_from(S) # needs sage.libs.flint
829
+ False
830
+ """
831
+ base_ring = self.base_ring()
832
+
833
+ # workaround, useful for the zero ring
834
+ if P == base_ring:
835
+ return self._coerce_map_from_base_ring()
836
+
837
+ # handle constants that canonically coerce into self.base_ring()
838
+ # first, if possible
839
+ try:
840
+ connecting = base_ring.coerce_map_from(P)
841
+ if connecting is not None:
842
+ return self.coerce_map_from(base_ring) * connecting
843
+ except TypeError:
844
+ pass
845
+
846
+ # polynomial rings in the same variable over a base that canonically
847
+ # coerces into self.base_ring()
848
+ if isinstance(P, PolynomialRing_generic):
849
+ if self.construction()[0] != P.construction()[0]:
850
+ # Construction (including variable names) must be the
851
+ # same to allow coercion
852
+ return False
853
+ self_sparse = self.is_sparse()
854
+ P_sparse = P.is_sparse()
855
+ if self_sparse and not P_sparse:
856
+ # Coerce only sparse -> dense
857
+ return False
858
+
859
+ if P.base_ring() is base_ring:
860
+ # Same base ring but different implementations.
861
+ # Ideally, we should avoid cyclic coercions (a coercion
862
+ # from A to B and also from B to A), but this is
863
+ # currently hard to do:
864
+ # see https://github.com/sagemath/sage/issues/24319
865
+ if not self_sparse and P_sparse:
866
+ # Always allow coercion sparse -> dense
867
+ pass
868
+ elif base_ring is ZZ:
869
+ # Over ZZ, only allow coercion from any ZZ['x']
870
+ # implementation to the default FLINT implementation
871
+ try:
872
+ from .polynomial_integer_dense_flint import Polynomial_integer_dense_flint
873
+ except ImportError:
874
+ return None
875
+ if self.element_class is not Polynomial_integer_dense_flint:
876
+ return None
877
+ # Other rings: always allow coercion
878
+ # To be fixed in Issue #24319
879
+ f = base_ring.coerce_map_from(P.base_ring())
880
+ if f is None:
881
+ return None
882
+ from sage.rings.homset import RingHomset
883
+ from sage.rings.polynomial.polynomial_ring_homomorphism import PolynomialRingHomomorphism_from_base
884
+ return PolynomialRingHomomorphism_from_base(RingHomset(P, self), f)
885
+
886
+ # Last, we consider multivariate polynomial rings:
887
+ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
888
+ if isinstance(P, MPolynomialRing_base) and self.variable_name() in P.variable_names():
889
+ P_ = P.remove_var(self.variable_name())
890
+ return self.base_ring() != P_ and self.base_ring().has_coerce_map_from(P_)
891
+
892
+ def _lean_init_(self):
893
+ """
894
+
895
+ EXAMPLES::
896
+
897
+ sage: ZZ['x']._lean_init_()
898
+ 'polynomial int'
899
+
900
+ """
901
+ # data.polynomial.basic
902
+ return 'polynomial ' + self.base_ring()._lean_init_()
903
+
904
+ def _magma_init_(self, magma):
905
+ """
906
+ Used in converting this ring to the corresponding ring in MAGMA.
907
+
908
+ EXAMPLES::
909
+
910
+ sage: # optional - magma
911
+ sage: R = QQ['y']
912
+ sage: R._magma_init_(magma)
913
+ 'SageCreateWithNames(PolynomialRing(_sage_ref...),["y"])'
914
+ sage: S = magma(R)
915
+ sage: S
916
+ Univariate Polynomial Ring in y over Rational Field
917
+ sage: S.1
918
+ y
919
+ sage: magma(PolynomialRing(GF(7), 'x')) # needs sage.rings.finite_rings
920
+ Univariate Polynomial Ring in x over GF(7)
921
+ sage: magma(PolynomialRing(GF(49,'a'), 'x')) # needs sage.rings.finite_rings
922
+ Univariate Polynomial Ring in x over GF(7^2)
923
+ sage: magma(PolynomialRing(PolynomialRing(ZZ,'w'), 'x'))
924
+ Univariate Polynomial Ring in x over Univariate Polynomial Ring in w over Integer Ring
925
+
926
+ Watch out, Magma has different semantics from Sage, i.e., in Magma
927
+ there is a unique univariate polynomial ring, and the variable name
928
+ has no intrinsic meaning (it only impacts printing), so can't be
929
+ reliably set because of caching.
930
+
931
+ ::
932
+
933
+ sage: # optional - magma
934
+ sage: m = Magma()
935
+ sage: m(QQ['w'])
936
+ Univariate Polynomial Ring in w over Rational Field
937
+ sage: m(QQ['x'])
938
+ Univariate Polynomial Ring in x over Rational Field
939
+ sage: m(QQ['w'])
940
+ Univariate Polynomial Ring in x over Rational Field
941
+
942
+ A nested example over a Givaro finite field::
943
+
944
+ sage: k.<a> = GF(9) # needs sage.rings.finite_rings
945
+ sage: R.<x> = k[] # needs sage.rings.finite_rings
946
+ sage: magma(a^2*x^3 + (a+1)*x + a) # optional - magma # needs sage.rings.finite_rings
947
+ a^2*x^3 + a^2*x + a
948
+ """
949
+ B = magma(self.base_ring())
950
+ Bref = B._ref()
951
+ s = 'PolynomialRing(%s)' % (Bref)
952
+ return magma._with_names(s, self.variable_names())
953
+
954
+ def _gap_init_(self, gap=None):
955
+ """
956
+ String for representing this polynomial ring in GAP.
957
+
958
+ INPUT:
959
+
960
+ - ``gap`` -- (optional GAP instance) used for representing the base ring
961
+
962
+ EXAMPLES::
963
+
964
+ sage: R.<z> = ZZ[]
965
+ sage: gap(R) # needs sage.libs.gap
966
+ PolynomialRing( Integers, ["z"] )
967
+ sage: gap(R) is gap(R) # needs sage.libs.gap
968
+ True
969
+ sage: gap(z^2 + z) # needs sage.libs.gap
970
+ z^2+z
971
+
972
+ A univariate polynomial ring over a multivariate polynomial
973
+ ring over a number field::
974
+
975
+ sage: # needs sage.rings.number_field
976
+ sage: Q.<t> = QQ[]
977
+ sage: K.<tau> = NumberField(t^2 + t + 1)
978
+ sage: P.<x,y> = K[]
979
+ sage: S.<z> = P[]
980
+ sage: gap(S) # needs sage.libs.gap
981
+ PolynomialRing( PolynomialRing( <algebraic extension over the Rationals of degree 2>, ["x", "y"] ), ["z"] )
982
+ sage: gap(S) is gap(S) # needs sage.libs.gap
983
+ True
984
+ """
985
+ if gap is not None:
986
+ base_ring = gap(self.base_ring()).name()
987
+ else:
988
+ base_ring = self.base_ring()._gap_init_()
989
+ return 'PolynomialRing(%s, ["%s"])' % (base_ring, self.variable_name())
990
+
991
+ def _sage_input_(self, sib, coerced):
992
+ r"""
993
+ Produce an expression which will reproduce this value when
994
+ evaluated.
995
+
996
+ EXAMPLES::
997
+
998
+ sage: sage_input(GF(5)['x']['y'], verify=True)
999
+ # Verified
1000
+ GF(5)['x']['y']
1001
+ sage: from sage.misc.sage_input import SageInputBuilder
1002
+ sage: ZZ['z']._sage_input_(SageInputBuilder(), False)
1003
+ {constr_parent: {subscr: {atomic:ZZ}[{atomic:'z'}]} with gens: ('z',)}
1004
+ """
1005
+ base = sib(self.base_ring())
1006
+ sie = base[self.variable_name()]
1007
+ gens_syntax = sib.empty_subscript(base)
1008
+ return sib.parent_with_gens(self, sie, self.variable_names(), 'R',
1009
+ gens_syntax=gens_syntax)
1010
+
1011
+ def _macaulay2_init_(self, macaulay2=None):
1012
+ """
1013
+ EXAMPLES::
1014
+
1015
+ sage: R = QQ['x']
1016
+ sage: macaulay2(R).describe() # optional - macaulay2
1017
+ QQ[x, Degrees => {1}, Heft => {1}, MonomialOrder => {MonomialSize => 16}]
1018
+ {GRevLex => {1} }
1019
+ {Position => Up }
1020
+
1021
+ TESTS:
1022
+
1023
+ Check that results are cached (:issue:`28074`)::
1024
+
1025
+ sage: R = ZZ['t']
1026
+ sage: macaulay2(R) is macaulay2(R) # optional - macaulay2
1027
+ True
1028
+ """
1029
+ if macaulay2 is None:
1030
+ from sage.interfaces.macaulay2 import macaulay2 as m2_default
1031
+ macaulay2 = m2_default
1032
+ return macaulay2._macaulay2_input_ring(self.base_ring(), self.gens())
1033
+
1034
+ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None):
1035
+ """
1036
+ EXAMPLES::
1037
+
1038
+ sage: R.<x> = QQ[]
1039
+ sage: R._is_valid_homomorphism_(GF(7), [5])
1040
+ False
1041
+ sage: R._is_valid_homomorphism_(Qp(7), [5]) # needs sage.rings.padics
1042
+ True
1043
+ """
1044
+ # Since poly rings are free, any image of the gen
1045
+ # determines a homomorphism
1046
+ if base_map is None:
1047
+ # If no base map is given, the only requirement is that the
1048
+ # base ring coerces into the codomain
1049
+ return codomain.has_coerce_map_from(self.base_ring())
1050
+ return True
1051
+
1052
+ # Polynomial rings should be unique parents. Hence,
1053
+ # no need for any comparison method
1054
+
1055
+ def __hash__(self):
1056
+ # should be faster than just relying on the string representation
1057
+ try:
1058
+ return self._cached_hash
1059
+ except AttributeError:
1060
+ pass
1061
+ h = self._cached_hash = hash((self.base_ring(),self.variable_name()))
1062
+ return h
1063
+
1064
+ def _repr_(self):
1065
+ try:
1066
+ return self._cached_repr
1067
+ except AttributeError:
1068
+ pass
1069
+ s = "Univariate Polynomial Ring in %s over %s" % (
1070
+ self.variable_name(), self.base_ring())
1071
+ if self.is_sparse():
1072
+ s = "Sparse " + s
1073
+ self._cached_repr = s
1074
+ return s
1075
+
1076
+ def _latex_(self):
1077
+ r"""
1078
+ EXAMPLES::
1079
+
1080
+ sage: S.<alpha12> = ZZ[]
1081
+ sage: latex(S)
1082
+ \Bold{Z}[\alpha_{12}]
1083
+ """
1084
+ return "%s[%s]" % (latex.latex(self.base_ring()), self.latex_variable_names()[0])
1085
+
1086
+ def base_extend(self, R):
1087
+ """
1088
+ Return the base extension of this polynomial ring to `R`.
1089
+
1090
+ EXAMPLES::
1091
+
1092
+ sage: # needs sage.rings.real_mpfr
1093
+ sage: R.<x> = RR[]; R
1094
+ Univariate Polynomial Ring in x over Real Field with 53 bits of precision
1095
+ sage: R.base_extend(CC)
1096
+ Univariate Polynomial Ring in x over Complex Field with 53 bits of precision
1097
+ sage: R.base_extend(QQ)
1098
+ Traceback (most recent call last):
1099
+ ...
1100
+ TypeError: no such base extension
1101
+ sage: R.change_ring(QQ)
1102
+ Univariate Polynomial Ring in x over Rational Field
1103
+ """
1104
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1105
+
1106
+ if R.has_coerce_map_from(self.base_ring()):
1107
+ return PolynomialRing(R, names=self.variable_name(), sparse=self.is_sparse())
1108
+ else:
1109
+ raise TypeError("no such base extension")
1110
+
1111
+ def change_ring(self, R):
1112
+ """
1113
+ Return the polynomial ring in the same variable as ``self`` over `R`.
1114
+
1115
+ EXAMPLES::
1116
+
1117
+ sage: # needs sage.rings.finite_rings sage.rings.real_interval_field
1118
+ sage: R.<ZZZ> = RealIntervalField()[]; R
1119
+ Univariate Polynomial Ring in ZZZ over
1120
+ Real Interval Field with 53 bits of precision
1121
+ sage: R.change_ring(GF(19^2, 'b'))
1122
+ Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2
1123
+ """
1124
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1125
+
1126
+ return PolynomialRing(R, names=self.variable_name(), sparse=self.is_sparse())
1127
+
1128
+ def change_var(self, var):
1129
+ r"""
1130
+ Return the polynomial ring in variable ``var`` over the same base
1131
+ ring.
1132
+
1133
+ EXAMPLES::
1134
+
1135
+ sage: R.<x> = ZZ[]; R
1136
+ Univariate Polynomial Ring in x over Integer Ring
1137
+ sage: R.change_var('y')
1138
+ Univariate Polynomial Ring in y over Integer Ring
1139
+ """
1140
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1141
+
1142
+ return PolynomialRing(self.base_ring(), names=var, sparse=self.is_sparse())
1143
+
1144
+ def extend_variables(self, added_names, order='degrevlex'):
1145
+ r"""
1146
+ Return a multivariate polynomial ring with the same base ring but
1147
+ with ``added_names`` as additional variables.
1148
+
1149
+ EXAMPLES::
1150
+
1151
+ sage: R.<x> = ZZ[]; R
1152
+ Univariate Polynomial Ring in x over Integer Ring
1153
+ sage: R.extend_variables('y, z')
1154
+ Multivariate Polynomial Ring in x, y, z over Integer Ring
1155
+ sage: R.extend_variables(('y', 'z'))
1156
+ Multivariate Polynomial Ring in x, y, z over Integer Ring
1157
+ """
1158
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1159
+
1160
+ if isinstance(added_names, str):
1161
+ added_names = added_names.split(',')
1162
+ return PolynomialRing(self.base_ring(), names=self.variable_names() + tuple(added_names), order=order)
1163
+
1164
+ def variable_names_recursive(self, depth=sage.rings.infinity.infinity):
1165
+ r"""
1166
+ Return the list of variable names of this ring and its base rings,
1167
+ as if it were a single multi-variate polynomial.
1168
+
1169
+ INPUT:
1170
+
1171
+ - ``depth`` -- integer or :mod:`Infinity <sage.rings.infinity>`
1172
+
1173
+ OUTPUT: a tuple of strings
1174
+
1175
+ EXAMPLES::
1176
+
1177
+ sage: R = QQ['x']['y']['z']
1178
+ sage: R.variable_names_recursive()
1179
+ ('x', 'y', 'z')
1180
+ sage: R.variable_names_recursive(2)
1181
+ ('y', 'z')
1182
+ """
1183
+ if depth <= 0:
1184
+ return ()
1185
+ elif depth == 1:
1186
+ return self.variable_names()
1187
+ else:
1188
+ my_vars = self.variable_names()
1189
+ try:
1190
+ return self.base_ring().variable_names_recursive(depth - len(my_vars)) + my_vars
1191
+ except AttributeError:
1192
+ return my_vars
1193
+
1194
+ def _mpoly_base_ring(self, variables=None):
1195
+ r"""
1196
+ Return the base ring if this is viewed as a polynomial ring over
1197
+ ``variables``. See also ``Polynomial._mpoly_dict_recursive``.
1198
+ """
1199
+ if variables is None:
1200
+ variables = self.variable_names_recursive()
1201
+ variables = list(variables)
1202
+ var = self.variable_name()
1203
+ if var not in variables:
1204
+ return self
1205
+ else:
1206
+ try:
1207
+ return self.base_ring()._mpoly_base_ring(variables[:variables.index(var)])
1208
+ except AttributeError:
1209
+ return self.base_ring()
1210
+
1211
+ def characteristic(self):
1212
+ """
1213
+ Return the characteristic of this polynomial ring, which is the
1214
+ same as that of its base ring.
1215
+
1216
+ EXAMPLES::
1217
+
1218
+ sage: # needs sage.rings.real_interval_field
1219
+ sage: R.<ZZZ> = RealIntervalField()[]; R
1220
+ Univariate Polynomial Ring in ZZZ over Real Interval Field with 53 bits of precision
1221
+ sage: R.characteristic()
1222
+ 0
1223
+ sage: S = R.change_ring(GF(19^2, 'b')); S # needs sage.rings.finite_rings
1224
+ Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2
1225
+ sage: S.characteristic() # needs sage.rings.finite_rings
1226
+ 19
1227
+ """
1228
+ return self.base_ring().characteristic()
1229
+
1230
+ def cyclotomic_polynomial(self, n):
1231
+ """
1232
+ Return the `n`-th cyclotomic polynomial as a polynomial in this
1233
+ polynomial ring. For details of the implementation, see the
1234
+ documentation for
1235
+ :func:`sage.rings.polynomial.cyclotomic.cyclotomic_coeffs`.
1236
+
1237
+ EXAMPLES::
1238
+
1239
+ sage: R = ZZ['x']
1240
+ sage: R.cyclotomic_polynomial(8)
1241
+ x^4 + 1
1242
+ sage: R.cyclotomic_polynomial(12)
1243
+ x^4 - x^2 + 1
1244
+
1245
+ sage: S = PolynomialRing(FiniteField(7), 'x')
1246
+ sage: S.cyclotomic_polynomial(12)
1247
+ x^4 + 6*x^2 + 1
1248
+ sage: S.cyclotomic_polynomial(1)
1249
+ x + 6
1250
+
1251
+ TESTS:
1252
+
1253
+ Make sure it agrees with other systems for the trivial case::
1254
+
1255
+ sage: ZZ['x'].cyclotomic_polynomial(1)
1256
+ x - 1
1257
+ sage: gp('polcyclo(1)') # needs sage.libs.pari
1258
+ x - 1
1259
+ """
1260
+ if n <= 0:
1261
+ raise ArithmeticError("n=%s must be positive" % n)
1262
+ elif n == 1:
1263
+ return self.gen() - 1
1264
+ else:
1265
+ from .cyclotomic import cyclotomic_coeffs
1266
+ return self(cyclotomic_coeffs(n), check=True)
1267
+
1268
+ @cached_method
1269
+ def gen(self, n=0):
1270
+ """
1271
+ Return the indeterminate generator of this polynomial ring.
1272
+
1273
+ EXAMPLES::
1274
+
1275
+ sage: R.<abc> = Integers(8)[]; R
1276
+ Univariate Polynomial Ring in abc over Ring of integers modulo 8
1277
+ sage: t = R.gen(); t
1278
+ abc
1279
+ sage: t.is_gen()
1280
+ True
1281
+
1282
+ An identical generator is always returned.
1283
+
1284
+ ::
1285
+
1286
+ sage: t is R.gen()
1287
+ True
1288
+ """
1289
+ if n != 0:
1290
+ raise IndexError("generator n not defined")
1291
+ return self.element_class(self, [0,1], is_gen=True)
1292
+
1293
+ def gens_dict(self) -> dict:
1294
+ """
1295
+ Return a dictionary whose entries are ``{name:variable,...}``,
1296
+ where ``name`` stands for the variable names of this
1297
+ object (as strings) and ``variable`` stands for the corresponding
1298
+ generators (as elements of this object).
1299
+
1300
+ EXAMPLES::
1301
+
1302
+ sage: R.<y,x,a42> = RR[]
1303
+ sage: R.gens_dict()
1304
+ {'a42': a42, 'x': x, 'y': y}
1305
+ """
1306
+ gens = self.gens()
1307
+ names = self.variable_names()
1308
+ assert len(gens) == len(names)
1309
+ return dict(zip(names, gens))
1310
+
1311
+ def parameter(self):
1312
+ """
1313
+ Return the generator of this polynomial ring.
1314
+
1315
+ This is the same as ``self.gen()``.
1316
+ """
1317
+ return self.gen()
1318
+
1319
+ @cached_method
1320
+ def is_exact(self):
1321
+ return self.base_ring().is_exact()
1322
+
1323
+ def is_field(self, proof=True):
1324
+ """
1325
+ Return ``False``, since polynomial rings are never fields.
1326
+
1327
+ EXAMPLES::
1328
+
1329
+ sage: # needs sage.libs.ntl
1330
+ sage: R.<z> = Integers(2)[]; R
1331
+ Univariate Polynomial Ring in z over Ring of integers modulo 2 (using GF2X)
1332
+ sage: R.is_field()
1333
+ False
1334
+ """
1335
+ return False
1336
+
1337
+ def is_sparse(self):
1338
+ """
1339
+ Return ``True`` if elements of this polynomial ring have a sparse
1340
+ representation.
1341
+
1342
+ EXAMPLES::
1343
+
1344
+ sage: R.<z> = Integers(8)[]; R
1345
+ Univariate Polynomial Ring in z over Ring of integers modulo 8
1346
+ sage: R.is_sparse()
1347
+ False
1348
+ sage: R.<W> = PolynomialRing(QQ, sparse=True); R
1349
+ Sparse Univariate Polynomial Ring in W over Rational Field
1350
+ sage: R.is_sparse()
1351
+ True
1352
+ """
1353
+ return self.__is_sparse
1354
+
1355
+ def monomial(self, exponent):
1356
+ """
1357
+ Return the monomial with the ``exponent``.
1358
+
1359
+ INPUT:
1360
+
1361
+ - ``exponent`` -- nonnegative integer
1362
+
1363
+ EXAMPLES::
1364
+
1365
+ sage: R.<x> = PolynomialRing(ZZ)
1366
+ sage: R.monomial(5)
1367
+ x^5
1368
+ sage: e=(10,)
1369
+ sage: R.monomial(*e)
1370
+ x^10
1371
+ sage: m = R.monomial(100)
1372
+ sage: R.monomial(m.degree()) == m
1373
+ True
1374
+ """
1375
+ return self({exponent: self.base_ring().one()})
1376
+
1377
+ def krull_dimension(self):
1378
+ """
1379
+ Return the Krull dimension of this polynomial ring, which is one
1380
+ more than the Krull dimension of the base ring.
1381
+
1382
+ EXAMPLES::
1383
+
1384
+ sage: R.<x> = QQ[]
1385
+ sage: R.krull_dimension()
1386
+ 1
1387
+
1388
+ sage: # needs sage.rings.finite_rings
1389
+ sage: R.<z> = GF(9, 'a')[]; R
1390
+ Univariate Polynomial Ring in z over Finite Field in a of size 3^2
1391
+ sage: R.krull_dimension()
1392
+ 1
1393
+ sage: S.<t> = R[]
1394
+ sage: S.krull_dimension()
1395
+ 2
1396
+ sage: for n in range(10):
1397
+ ....: S = PolynomialRing(S, 'w')
1398
+ sage: S.krull_dimension()
1399
+ 12
1400
+ """
1401
+ return self.base_ring().krull_dimension() + 1
1402
+
1403
+ def ngens(self):
1404
+ """
1405
+ Return the number of generators of this polynomial ring, which is 1
1406
+ since it is a univariate polynomial ring.
1407
+
1408
+ EXAMPLES::
1409
+
1410
+ sage: R.<z> = Integers(8)[]; R
1411
+ Univariate Polynomial Ring in z over Ring of integers modulo 8
1412
+ sage: R.ngens()
1413
+ 1
1414
+ """
1415
+ return 1
1416
+
1417
+ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds):
1418
+ r"""
1419
+ Return a random polynomial of given degree (bounds).
1420
+
1421
+ INPUT:
1422
+
1423
+ - ``degree`` -- (default: ``(-1, 2)``) integer for fixing the degree or
1424
+ a tuple of minimum and maximum degrees
1425
+
1426
+ - ``monic`` -- boolean (default: ``False``); indicate whether the sampled
1427
+ polynomial should be monic
1428
+
1429
+ - ``*args, **kwds`` -- additional keyword parameters passed on to the
1430
+ ``random_element`` method for the base ring
1431
+
1432
+ EXAMPLES::
1433
+
1434
+ sage: R.<x> = ZZ[]
1435
+ sage: f = R.random_element(10, x=5, y=10)
1436
+ sage: f.degree()
1437
+ 10
1438
+ sage: f.parent() is R
1439
+ True
1440
+ sage: all(a in range(5, 10) for a in f.coefficients())
1441
+ True
1442
+ sage: R.random_element(6).degree()
1443
+ 6
1444
+
1445
+ If a tuple of two integers is given for the ``degree`` argument, a
1446
+ polynomial is chosen among all polynomials with degree between them. If
1447
+ the base ring can be sampled uniformly, then this method also samples
1448
+ uniformly::
1449
+
1450
+ sage: R.random_element(degree=(0, 4)).degree() in range(0, 5)
1451
+ True
1452
+ sage: found = [False]*5
1453
+ sage: while not all(found):
1454
+ ....: found[R.random_element(degree=(0, 4)).degree()] = True
1455
+
1456
+ Note that the zero polynomial has degree `-1`, so if you want to
1457
+ consider it set the minimum degree to `-1`::
1458
+
1459
+ sage: while R.random_element(degree=(-1,2), x=-1, y=1) != R.zero():
1460
+ ....: pass
1461
+
1462
+ Monic polynomials are chosen among all monic polynomials with degree
1463
+ between the given ``degree`` argument::
1464
+
1465
+ sage: all(R.random_element(degree=(-1, 1), monic=True).is_monic() for _ in range(10^3))
1466
+ True
1467
+ sage: all(R.random_element(degree=(0, 1), monic=True).is_monic() for _ in range(10^3))
1468
+ True
1469
+
1470
+ TESTS::
1471
+
1472
+ sage: R.random_element(degree=[5])
1473
+ Traceback (most recent call last):
1474
+ ...
1475
+ ValueError: degree argument must be an integer or a tuple of 2 integers (min_degree, max_degree)
1476
+
1477
+ sage: R.random_element(degree=(5,4))
1478
+ Traceback (most recent call last):
1479
+ ...
1480
+ ValueError: minimum degree must be less or equal than maximum degree
1481
+
1482
+ Check that :issue:`16682` is fixed::
1483
+
1484
+ sage: R = PolynomialRing(GF(2), 'z')
1485
+ sage: for _ in range(100):
1486
+ ....: d = randint(-1, 20)
1487
+ ....: P = R.random_element(degree=d)
1488
+ ....: assert P.degree() == d
1489
+
1490
+ In :issue:`37118`, ranges including integers below `-1` no longer raise
1491
+ an error::
1492
+
1493
+ sage: R.random_element(degree=(-2, 3)) # random
1494
+ z^3 + z^2 + 1
1495
+
1496
+ ::
1497
+
1498
+ sage: 0 in [R.random_element(degree=(-1, 2), monic=True) for _ in range(500)]
1499
+ False
1500
+
1501
+ Testing error handling::
1502
+
1503
+ sage: R.random_element(degree=-5)
1504
+ Traceback (most recent call last):
1505
+ ...
1506
+ ValueError: degree (=-5) must be at least -1
1507
+
1508
+ sage: R.random_element(degree=(-3, -2))
1509
+ Traceback (most recent call last):
1510
+ ...
1511
+ ValueError: maximum degree (=-2) must be at least -1
1512
+
1513
+ Testing uniformity::
1514
+
1515
+ sage: from collections import Counter
1516
+ sage: R = GF(3)["x"]
1517
+ sage: samples = [R.random_element(degree=(-1, 2)) for _ in range(27000)] # long time
1518
+ sage: assert all(750 <= f <= 1250 for f in Counter(samples).values()) # long time
1519
+
1520
+ sage: samples = [R.random_element(degree=(-1, 2), monic=True) for _ in range(13000)] # long time
1521
+ sage: assert all(750 <= f <= 1250 for f in Counter(samples).values()) # long time
1522
+ """
1523
+ R = self.base_ring()
1524
+
1525
+ if isinstance(degree, (list, tuple)):
1526
+ if len(degree) != 2:
1527
+ raise ValueError("degree argument must be an integer or a tuple of 2 integers (min_degree, max_degree)")
1528
+ if degree[0] > degree[1]:
1529
+ raise ValueError("minimum degree must be less or equal than maximum degree")
1530
+ if degree[1] < -1:
1531
+ raise ValueError(f"maximum degree (={degree[1]}) must be at least -1")
1532
+ else:
1533
+ if degree < -1:
1534
+ raise ValueError(f"degree (={degree}) must be at least -1")
1535
+ degree = (degree, degree)
1536
+
1537
+ if degree[0] <= -2:
1538
+ degree = (-1, degree[1])
1539
+
1540
+ # If the coefficient range only contains 0, then
1541
+ # * if the degree range includes -1, return the zero polynomial,
1542
+ # * otherwise raise a value error
1543
+ if args == (0, 1):
1544
+ if degree[0] == -1:
1545
+ return self.zero()
1546
+ else:
1547
+ raise ValueError("No polynomial of degree >= 0 has all coefficients zero")
1548
+
1549
+ if degree == (-1, -1):
1550
+ return self.zero()
1551
+
1552
+ # If `monic` is set, zero should be ignored
1553
+ if degree[0] == -1 and monic:
1554
+ if degree[1] == -1:
1555
+ raise ValueError("the maximum degree of monic polynomials needs to be at least 0")
1556
+ if degree[1] == 0:
1557
+ return self.one()
1558
+ degree = (0, degree[1])
1559
+
1560
+ # Pick random coefficients
1561
+ end = degree[1]
1562
+ if degree[0] == -1:
1563
+ return self([R.random_element(*args, **kwds) for _ in range(end + 1)])
1564
+
1565
+ nonzero = False
1566
+ coefs = [None] * (end + 1)
1567
+
1568
+ while not nonzero:
1569
+ # Pick leading coefficients, if `monic` is set it's handle here.
1570
+ if monic:
1571
+ for i in range(degree[1] - degree[0] + 1):
1572
+ coefs[end - i] = R.random_element(*args, **kwds)
1573
+ if not nonzero and not coefs[end - i].is_zero():
1574
+ coefs[end - i] = R.one()
1575
+ nonzero = True
1576
+ else:
1577
+ # Fast path
1578
+ for i in range(degree[1] - degree[0] + 1):
1579
+ coefs[end - i] = R.random_element(*args, **kwds)
1580
+ nonzero |= not coefs[end - i].is_zero()
1581
+
1582
+ # Now we pick the remaining coefficients.
1583
+ for i in range(degree[1] - degree[0] + 1, degree[1] + 1):
1584
+ coefs[end - i] = R.random_element(*args, **kwds)
1585
+
1586
+ return self(coefs)
1587
+
1588
+ def _monics_degree(self, of_degree):
1589
+ """
1590
+ Refer to monics() for full documentation.
1591
+ """
1592
+ base = self.base_ring()
1593
+ for coeffs in sage.misc.mrange.xmrange_iter([[base.one()]]+[base]*of_degree):
1594
+ # Each iteration returns a *new* list!
1595
+ # safe to mutate the return
1596
+ coeffs.reverse()
1597
+ yield self(coeffs)
1598
+
1599
+ def _monics_max(self, max_degree):
1600
+ """
1601
+ Refer to monics() for full documentation.
1602
+ """
1603
+ for degree in range(max_degree + 1):
1604
+ yield from self._monics_degree(degree)
1605
+
1606
+ def _polys_degree(self, of_degree):
1607
+ """
1608
+ Refer to polynomials() for full documentation.
1609
+ """
1610
+ base = self.base_ring()
1611
+ base0 = base.zero()
1612
+ for leading_coeff in base:
1613
+ if leading_coeff != base0:
1614
+ for lt1 in sage.misc.mrange.xmrange_iter([base]*(of_degree)):
1615
+ # Each iteration returns a *new* list!
1616
+ # safe to mutate the return
1617
+ coeffs = [leading_coeff] + lt1
1618
+ coeffs.reverse()
1619
+ yield self(coeffs)
1620
+
1621
+ def _polys_max(self, max_degree):
1622
+ """
1623
+ Refer to polynomials() for full documentation.
1624
+ """
1625
+ base = self.base_ring()
1626
+ for coeffs in sage.misc.mrange.xmrange_iter([base]*(max_degree+1)):
1627
+ # Each iteration returns a *new* list!
1628
+ # safe to mutate the return
1629
+ coeffs.reverse()
1630
+ yield self(coeffs)
1631
+
1632
+ @lazy_attribute
1633
+ def _Karatsuba_threshold(self):
1634
+ """
1635
+ Return the default Karatsuba threshold.
1636
+
1637
+ EXAMPLES::
1638
+
1639
+ sage: R.<x> = QQbar[] # needs sage.rings.number_field
1640
+ sage: R._Karatsuba_threshold # needs sage.rings.number_field
1641
+ 8
1642
+ sage: MS = MatrixSpace(ZZ, 2, 2) # needs sage.modules
1643
+ sage: R.<x> = MS[] # needs sage.modules
1644
+ sage: R._Karatsuba_threshold # needs sage.modules
1645
+ 0
1646
+ """
1647
+ base_ring = self.base_ring()
1648
+ if isinstance(base_ring, PolynomialRing_generic):
1649
+ return 0
1650
+ try:
1651
+ from sage.matrix.matrix_space import MatrixSpace
1652
+ except ImportError:
1653
+ pass
1654
+ else:
1655
+ if isinstance(base_ring, MatrixSpace):
1656
+ return 0
1657
+ from sage.rings.fraction_field import FractionField_generic
1658
+ if isinstance(base_ring, FractionField_generic):
1659
+ return 1 << 60
1660
+ # Generic default value
1661
+ return 8
1662
+
1663
+ def karatsuba_threshold(self):
1664
+ """
1665
+ Return the Karatsuba threshold used for this ring by the method
1666
+ :meth:`_mul_karatsuba` to fall back to the schoolbook algorithm.
1667
+
1668
+ EXAMPLES::
1669
+
1670
+ sage: K = QQ['x']
1671
+ sage: K.karatsuba_threshold()
1672
+ 8
1673
+ sage: K = QQ['x']['y']
1674
+ sage: K.karatsuba_threshold()
1675
+ 0
1676
+ """
1677
+ return self._Karatsuba_threshold
1678
+
1679
+ def set_karatsuba_threshold(self, Karatsuba_threshold):
1680
+ """
1681
+ Changes the default threshold for this ring in the method
1682
+ :meth:`_mul_karatsuba` to fall back to the schoolbook algorithm.
1683
+
1684
+ .. warning::
1685
+
1686
+ This method may have a negative performance impact in polynomial
1687
+ arithmetic. So use it at your own risk.
1688
+
1689
+ EXAMPLES::
1690
+
1691
+ sage: K = QQ['x']
1692
+ sage: K.karatsuba_threshold()
1693
+ 8
1694
+ sage: K.set_karatsuba_threshold(0)
1695
+ sage: K.karatsuba_threshold()
1696
+ 0
1697
+ """
1698
+ self._Karatsuba_threshold = int(Karatsuba_threshold)
1699
+
1700
+ def polynomials(self, of_degree=None, max_degree=None):
1701
+ """
1702
+ Return an iterator over the polynomials of specified degree.
1703
+
1704
+ INPUT: Pass exactly one of:
1705
+
1706
+ - ``max_degree`` -- an int; the iterator will generate all polynomials
1707
+ which have degree less than or equal to ``max_degree``
1708
+
1709
+ - ``of_degree`` -- an int; the iterator will generate
1710
+ all polynomials which have degree ``of_degree``
1711
+
1712
+ OUTPUT: an iterator
1713
+
1714
+ EXAMPLES::
1715
+
1716
+ sage: P = PolynomialRing(GF(3), 'y')
1717
+ sage: for p in P.polynomials(of_degree=2): print(p)
1718
+ y^2
1719
+ y^2 + 1
1720
+ y^2 + 2
1721
+ y^2 + y
1722
+ y^2 + y + 1
1723
+ y^2 + y + 2
1724
+ y^2 + 2*y
1725
+ y^2 + 2*y + 1
1726
+ y^2 + 2*y + 2
1727
+ 2*y^2
1728
+ 2*y^2 + 1
1729
+ 2*y^2 + 2
1730
+ 2*y^2 + y
1731
+ 2*y^2 + y + 1
1732
+ 2*y^2 + y + 2
1733
+ 2*y^2 + 2*y
1734
+ 2*y^2 + 2*y + 1
1735
+ 2*y^2 + 2*y + 2
1736
+ sage: for p in P.polynomials(max_degree=1): print(p)
1737
+ 0
1738
+ 1
1739
+ 2
1740
+ y
1741
+ y + 1
1742
+ y + 2
1743
+ 2*y
1744
+ 2*y + 1
1745
+ 2*y + 2
1746
+ sage: for p in P.polynomials(max_degree=1, of_degree=3): print(p)
1747
+ Traceback (most recent call last):
1748
+ ...
1749
+ ValueError: you should pass exactly one of of_degree and max_degree
1750
+
1751
+ AUTHORS:
1752
+
1753
+ - Joel B. Mohler
1754
+ """
1755
+
1756
+ if self.base_ring().order() is sage.rings.infinity.infinity:
1757
+ raise NotImplementedError
1758
+ if of_degree is not None and max_degree is None:
1759
+ return self._polys_degree( of_degree )
1760
+ if max_degree is not None and of_degree is None:
1761
+ return self._polys_max( max_degree )
1762
+ raise ValueError("you should pass exactly one of of_degree and max_degree")
1763
+
1764
+ def monics(self, of_degree=None, max_degree=None):
1765
+ """
1766
+ Return an iterator over the monic polynomials of specified degree.
1767
+
1768
+ INPUT: Pass exactly one of:
1769
+
1770
+
1771
+ - ``max_degree`` -- an int; the iterator will generate all monic
1772
+ polynomials which have degree less than or equal to ``max_degree``
1773
+
1774
+ - ``of_degree`` -- an int; the iterator will generate
1775
+ all monic polynomials which have degree ``of_degree``
1776
+
1777
+ OUTPUT: an iterator
1778
+
1779
+ EXAMPLES::
1780
+
1781
+ sage: # needs sage.rings.finite_rings
1782
+ sage: P = PolynomialRing(GF(4, 'a'), 'y')
1783
+ sage: for p in P.monics(of_degree=2): print(p)
1784
+ y^2
1785
+ y^2 + a
1786
+ y^2 + a + 1
1787
+ y^2 + 1
1788
+ y^2 + a*y
1789
+ y^2 + a*y + a
1790
+ y^2 + a*y + a + 1
1791
+ y^2 + a*y + 1
1792
+ y^2 + (a + 1)*y
1793
+ y^2 + (a + 1)*y + a
1794
+ y^2 + (a + 1)*y + a + 1
1795
+ y^2 + (a + 1)*y + 1
1796
+ y^2 + y
1797
+ y^2 + y + a
1798
+ y^2 + y + a + 1
1799
+ y^2 + y + 1
1800
+ sage: for p in P.monics(max_degree=1): print(p)
1801
+ 1
1802
+ y
1803
+ y + a
1804
+ y + a + 1
1805
+ y + 1
1806
+ sage: for p in P.monics(max_degree=1, of_degree=3): print(p)
1807
+ Traceback (most recent call last):
1808
+ ...
1809
+ ValueError: you should pass exactly one of of_degree and max_degree
1810
+
1811
+ AUTHORS:
1812
+
1813
+ - Joel B. Mohler
1814
+ """
1815
+
1816
+ if self.base_ring().order() is sage.rings.infinity.infinity:
1817
+ raise NotImplementedError
1818
+ if of_degree is not None and max_degree is None:
1819
+ return self._monics_degree( of_degree )
1820
+ if max_degree is not None and of_degree is None:
1821
+ return self._monics_max( max_degree )
1822
+ raise ValueError("you should pass exactly one of of_degree and max_degree")
1823
+
1824
+
1825
+ # PolynomialRing_general is deprecated since 2024-12-03. See Issue #38207.
1826
+ PolynomialRing_general = PolynomialRing_generic
1827
+
1828
+
1829
+ class PolynomialRing_commutative(PolynomialRing_generic):
1830
+ """
1831
+ Univariate polynomial ring over a commutative ring.
1832
+ """
1833
+ def __init__(self, base_ring, name=None, sparse=False, implementation=None,
1834
+ element_class=None, category=None):
1835
+ if base_ring not in _CommutativeRings:
1836
+ raise TypeError("Base ring %s must be a commutative ring." % repr(base_ring))
1837
+ # We trust that, if a category is given, that it is useful.
1838
+ if base_ring.is_zero():
1839
+ category = categories.algebras.Algebras(base_ring.category()).Commutative().Finite()
1840
+ else:
1841
+ defaultcat = polynomial_default_category(base_ring.category(), 1)
1842
+ category = check_default_category(defaultcat, category)
1843
+ PolynomialRing_generic.__init__(self, base_ring, name=name,
1844
+ sparse=sparse, implementation=implementation,
1845
+ element_class=element_class, category=category)
1846
+
1847
+ def quotient_by_principal_ideal(self, f, names=None, **kwds):
1848
+ """
1849
+ Return the quotient of this polynomial ring by the principal
1850
+ ideal (generated by) `f`.
1851
+
1852
+ INPUT:
1853
+
1854
+ - ``f`` -- either a polynomial in ``self``, or a principal
1855
+ ideal of ``self``
1856
+ - further named arguments that are passed to the quotient constructor
1857
+
1858
+ EXAMPLES::
1859
+
1860
+ sage: R.<x> = QQ[]
1861
+ sage: I = (x^2 - 1) * R
1862
+ sage: R.quotient_by_principal_ideal(I) # needs sage.libs.pari
1863
+ Univariate Quotient Polynomial Ring in xbar
1864
+ over Rational Field with modulus x^2 - 1
1865
+
1866
+ The same example, using the polynomial instead of the ideal,
1867
+ and customizing the variable name::
1868
+
1869
+ sage: R.<x> = QQ[]
1870
+ sage: R.quotient_by_principal_ideal(x^2 - 1, names=('foo',)) # needs sage.libs.pari
1871
+ Univariate Quotient Polynomial Ring in foo
1872
+ over Rational Field with modulus x^2 - 1
1873
+
1874
+ TESTS:
1875
+
1876
+ Quotienting by the zero ideal returns ``self`` (:issue:`5978`)::
1877
+
1878
+ sage: R = QQ['x']
1879
+ sage: R.quotient_by_principal_ideal(R.zero_ideal()) is R
1880
+ True
1881
+ sage: R.quotient_by_principal_ideal(0) is R
1882
+ True
1883
+ """
1884
+ from sage.rings.ideal import Ideal
1885
+ I = Ideal(f)
1886
+ if I.is_zero():
1887
+ return self
1888
+ f = I.gen()
1889
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing
1890
+ return PolynomialQuotientRing(self, f, names, **kwds)
1891
+
1892
+ def weyl_algebra(self):
1893
+ """
1894
+ Return the Weyl algebra generated from ``self``.
1895
+
1896
+ EXAMPLES::
1897
+
1898
+ sage: R = QQ['x']
1899
+ sage: W = R.weyl_algebra(); W # needs sage.modules
1900
+ Differential Weyl algebra of polynomials in x over Rational Field
1901
+ sage: W.polynomial_ring() == R # needs sage.modules
1902
+ True
1903
+ """
1904
+ from sage.algebras.weyl_algebra import DifferentialWeylAlgebra
1905
+ return DifferentialWeylAlgebra(self)
1906
+
1907
+ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=True, algorithm=None, degree_bound=None):
1908
+ """
1909
+ Return the list of roots of ``p``.
1910
+
1911
+ INPUT:
1912
+
1913
+ - ``p`` -- the polynomial whose roots are computed
1914
+ - ``ring`` -- the ring to find roots (default: the base ring of ``p``)
1915
+ - ``multiplicities`` -- boolean (default: ``True``); if ``True``,
1916
+ return a list of pairs ``(root, multiplicity)``; if ``False`` return
1917
+ a list of roots
1918
+ - ``algorithm`` -- ignored (TODO: remove)
1919
+ - ``degree_bound`` -- if not ``None``, return only roots of degree at
1920
+ most ``degree_bound``
1921
+
1922
+ EXAMPLES::
1923
+
1924
+ sage: # needs sage.libs.singular
1925
+ sage: R.<x> = QQ[]
1926
+ sage: S.<y> = R[]
1927
+ sage: p = y^3 + (-x^2 - 3)*y^2 + (2*x^3 - x^2 + 3)*y - x^4 + 2*x^2 - 1
1928
+ sage: p.roots()
1929
+ [(x^2 - 2*x + 1, 1), (x + 1, 2)]
1930
+ sage: p.roots(multiplicities=False)
1931
+ [x^2 - 2*x + 1, x + 1]
1932
+ sage: p.roots(degree_bound=1)
1933
+ [(x + 1, 2)]
1934
+
1935
+ TESTS:
1936
+
1937
+ Check that :issue:`23639` is fixed::
1938
+
1939
+ sage: foo = QQ['x']['y'].one()
1940
+ sage: foo.roots(QQ)
1941
+ []
1942
+ """
1943
+ if ring is not None and ring is not self:
1944
+ p = p.change_ring(ring)
1945
+ if degree_bound is None:
1946
+ return p.roots(multiplicities=multiplicities, algorithm=algorithm)
1947
+ return p.roots(multiplicities=multiplicities, algorithm=algorithm, degree_bound=degree_bound)
1948
+
1949
+ roots = p._roots_from_factorization(p.factor(), multiplicities)
1950
+ if degree_bound is not None:
1951
+ if multiplicities:
1952
+ roots = [(r,m) for (r,m) in roots if r.degree() <= degree_bound]
1953
+ else:
1954
+ roots = [r for r in roots if r.degree() <= degree_bound]
1955
+ return roots
1956
+
1957
+
1958
+ class PolynomialRing_integral_domain(PolynomialRing_commutative, PolynomialRing_singular_repr, CommutativeRing):
1959
+ def __init__(self, base_ring, name='x', sparse=False, implementation=None,
1960
+ element_class=None, category=None):
1961
+ """
1962
+ TESTS::
1963
+
1964
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing
1965
+ sage: R = PRing(ZZ, 'x'); R
1966
+ Univariate Polynomial Ring in x over Integer Ring
1967
+ sage: type(R.gen()) # needs sage.libs.flint
1968
+ <class 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint'>
1969
+
1970
+ sage: R = PRing(ZZ, 'x', implementation='NTL'); R # needs sage.libs.ntl
1971
+ Univariate Polynomial Ring in x over Integer Ring (using NTL)
1972
+ sage: type(R.gen()) # needs sage.libs.ntl
1973
+ <class 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
1974
+ """
1975
+ self._implementation_repr = ''
1976
+ if element_class is None:
1977
+ given_implementation = implementation
1978
+ for implementation in self._implementation_names(implementation, base_ring, sparse):
1979
+ if base_ring is ZZ:
1980
+ if implementation == 'NTL':
1981
+ try:
1982
+ from sage.rings.polynomial.polynomial_integer_dense_ntl \
1983
+ import Polynomial_integer_dense_ntl as element_class
1984
+ except ImportError:
1985
+ if given_implementation:
1986
+ raise
1987
+ continue
1988
+ self._implementation_repr = ' (using NTL)'
1989
+ elif implementation == 'FLINT':
1990
+ try:
1991
+ from .polynomial_integer_dense_flint \
1992
+ import Polynomial_integer_dense_flint as element_class
1993
+ except ImportError:
1994
+ if given_implementation:
1995
+ raise
1996
+ continue
1997
+ break
1998
+ PolynomialRing_commutative.__init__(self, base_ring, name=name,
1999
+ sparse=sparse, implementation=implementation,
2000
+ element_class=element_class, category=category)
2001
+ self._has_singular = can_convert_to_singular(self)
2002
+
2003
+ @cached_method(key=lambda self, d, q, sign, lead: (d, q, sign, tuple([x if isinstance(x, (tuple, list)) else (x, 0) for x in lead]) if isinstance(lead, (tuple, list)) else ((lead, 0))))
2004
+ def weil_polynomials(self, d, q, sign=1, lead=1):
2005
+ r"""
2006
+ Return all integer polynomials whose complex roots all have a specified
2007
+ absolute value.
2008
+
2009
+ Such polynomials `f` satisfy a functional equation
2010
+
2011
+ .. MATH::
2012
+
2013
+ T^d f(q/T) = s q^{d/2} f(T)
2014
+
2015
+ where `d` is the degree of `f`, `s` is a sign and `q^{1/2}` is the
2016
+ absolute value of the roots of `f`.
2017
+
2018
+ INPUT:
2019
+
2020
+ - ``d`` -- integer; the degree of the polynomials
2021
+
2022
+ - ``q`` -- integer; the square of the complex absolute value of the
2023
+ roots
2024
+
2025
+ - ``sign`` -- integer (default: `1`); the sign `s` of the functional
2026
+ equation
2027
+
2028
+ - ``lead`` -- integer; list of integers or list of pairs of integers
2029
+ (default: `1`), constraints on the leading few coefficients of the
2030
+ generated polynomials. If pairs `(a, b)` of integers are given, they
2031
+ are treated as a constraint of the form `\equiv a \pmod{b}`; the
2032
+ moduli must be in decreasing order by divisibility, and the modulus
2033
+ of the leading coefficient must be 0.
2034
+
2035
+ .. SEEALSO::
2036
+
2037
+ More documentation and additional options are available using the
2038
+ iterator
2039
+ :class:`sage.rings.polynomial.weil.weil_polynomials.WeilPolynomials`
2040
+ directly. In addition, polynomials have a method
2041
+ :meth:`is_weil_polynomial` to test whether or not the given
2042
+ polynomial is a Weil polynomial.
2043
+
2044
+ EXAMPLES::
2045
+
2046
+ sage: # needs sage.libs.flint
2047
+ sage: R.<T> = ZZ[]
2048
+ sage: L = R.weil_polynomials(4, 2)
2049
+ sage: len(L)
2050
+ 35
2051
+ sage: L[9]
2052
+ T^4 + T^3 + 2*T^2 + 2*T + 4
2053
+ sage: all(p.is_weil_polynomial() for p in L)
2054
+ True
2055
+
2056
+ Setting multiple leading coefficients::
2057
+
2058
+ sage: R.<T> = QQ[]
2059
+ sage: l = R.weil_polynomials(4, 2, lead=((1,0), (2,4), (1,2))); l # needs sage.libs.flint
2060
+ [T^4 + 2*T^3 + 5*T^2 + 4*T + 4,
2061
+ T^4 + 2*T^3 + 3*T^2 + 4*T + 4,
2062
+ T^4 - 2*T^3 + 5*T^2 - 4*T + 4,
2063
+ T^4 - 2*T^3 + 3*T^2 - 4*T + 4]
2064
+
2065
+ We do not require Weil polynomials to be monic. This example generates Weil
2066
+ polynomials associated to K3 surfaces over `\GF{2}` of Picard number at least 12::
2067
+
2068
+ sage: R.<T> = QQ[]
2069
+ sage: l = R.weil_polynomials(10, 1, lead=2) # needs sage.libs.flint
2070
+ sage: len(l) # needs sage.libs.flint
2071
+ 4865
2072
+ sage: l[len(l)//2] # needs sage.libs.flint
2073
+ 2*T^10 + T^8 + T^6 + T^4 + T^2 + 2
2074
+
2075
+ TESTS:
2076
+
2077
+ We check that products of Weil polynomials are also listed as Weil
2078
+ polynomials::
2079
+
2080
+ sage: all((f * g) in R.weil_polynomials(6, q) for q in [3, 4] # needs sage.libs.flint
2081
+ ....: for f in R.weil_polynomials(2, q) for g in R.weil_polynomials(4, q))
2082
+ True
2083
+
2084
+ We check that irreducible Weil polynomials of degree 6 are CM::
2085
+
2086
+ sage: simples = [f for f in R.weil_polynomials(6, 3) if f.is_irreducible()] # needs sage.libs.flint
2087
+ sage: len(simples) # needs sage.libs.flint
2088
+ 348
2089
+ sage: reals = [R([f[3+i] + sum((-3)^j * (i+2*j)/(i+j) * binomial(i+j,j) * f[3+i+2*j] # needs sage.libs.flint
2090
+ ....: for j in range(1, (3+i)//2 + 1))
2091
+ ....: for i in range(4)]) for f in simples]
2092
+
2093
+ Check that every polynomial in this list has 3 real roots between `-2
2094
+ \sqrt{3}` and `2 \sqrt{3}`::
2095
+
2096
+ sage: roots = [f.roots(RR, multiplicities=False) for f in reals] # needs sage.libs.flint
2097
+ sage: all(len(L) == 3 and all(x^2 <= 12 for x in L) for L in roots) # needs sage.libs.flint
2098
+ True
2099
+
2100
+ Finally, check that the original polynomials are reconstructed as CM
2101
+ polynomials::
2102
+
2103
+ sage: all(f == T^3*r(T + 3/T) for (f, r) in zip(simples, reals)) # needs sage.libs.flint
2104
+ True
2105
+
2106
+ A simple check (not sufficient)::
2107
+
2108
+ sage: all(f.number_of_real_roots() == 0 for f in simples) # needs sage.libs.flint
2109
+ True
2110
+ """
2111
+ R = self.base_ring()
2112
+ if not (R is ZZ or R is QQ):
2113
+ raise ValueError("Weil polynomials have integer coefficients")
2114
+ from sage.rings.polynomial.weil.weil_polynomials import WeilPolynomials
2115
+ return list(WeilPolynomials(d, q, sign, lead, polring=self))
2116
+
2117
+ @staticmethod
2118
+ def _implementation_names_impl(implementation, base_ring, sparse):
2119
+ """
2120
+ TESTS::
2121
+
2122
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain
2123
+ sage: PolynomialRing_integral_domain._implementation_names_impl(None, ZZ, False)
2124
+ ['FLINT', None]
2125
+ sage: PolynomialRing_integral_domain._implementation_names_impl(None, ZZ, True)
2126
+ [None, 'generic']
2127
+ sage: PolynomialRing_integral_domain._implementation_names_impl(None, QQ, False)
2128
+ [None, 'generic']
2129
+ sage: PolynomialRing_integral_domain._implementation_names_impl(None, QQ, True)
2130
+ [None, 'generic']
2131
+ """
2132
+ if base_ring is ZZ and not sparse:
2133
+ defaults = ["FLINT", None]
2134
+ if implementation in defaults:
2135
+ return defaults
2136
+ elif implementation in ["NTL", "generic"]:
2137
+ return [implementation]
2138
+ elif implementation is None or implementation == "generic":
2139
+ return [None, "generic"]
2140
+ return NotImplemented
2141
+
2142
+ def _repr_(self):
2143
+ """
2144
+ TESTS::
2145
+
2146
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing
2147
+ sage: R = PRing(ZZ, 'x', implementation='NTL'); R # needs sage.libs.ntl
2148
+ Univariate Polynomial Ring in x over Integer Ring (using NTL)
2149
+ """
2150
+ s = PolynomialRing_commutative._repr_(self)
2151
+ return s + self._implementation_repr
2152
+
2153
+ def construction(self):
2154
+ """
2155
+ Return the construction functor.
2156
+
2157
+ EXAMPLES::
2158
+
2159
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing
2160
+ sage: R = PRing(ZZ, 'x'); R
2161
+ Univariate Polynomial Ring in x over Integer Ring
2162
+ sage: functor, arg = R.construction(); functor, arg
2163
+ (Poly[x], Integer Ring)
2164
+ sage: functor.implementation is None
2165
+ True
2166
+
2167
+ sage: # needs sage.libs.ntl
2168
+ sage: R = PRing(ZZ, 'x', implementation='NTL'); R
2169
+ Univariate Polynomial Ring in x over Integer Ring (using NTL)
2170
+ sage: functor, arg = R.construction(); functor, arg
2171
+ (Poly[x], Integer Ring)
2172
+ sage: functor.implementation
2173
+ 'NTL'
2174
+ """
2175
+ implementation = None
2176
+ # NOTE: This is obviously not a complete solution. The parents
2177
+ # don't keep track in a clean way what the implementation is.
2178
+ # Issue #31852 is the task of finding a general solution for
2179
+ # construction functors of parents with multiple
2180
+ # implementations, such as MatrixSpace, Polyhedron, and
2181
+ # PolynomialRing.
2182
+ if 'NTL' in self._implementation_repr:
2183
+ implementation = 'NTL'
2184
+ return categories.pushout.PolynomialFunctor(self.variable_name(), sparse=self.is_sparse(),
2185
+ implementation=implementation), self.base_ring()
2186
+
2187
+
2188
+ class PolynomialRing_field(PolynomialRing_integral_domain):
2189
+ def __init__(self, base_ring, name='x', sparse=False, implementation=None,
2190
+ element_class=None, category=None):
2191
+ """
2192
+ TESTS::
2193
+
2194
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_field as PRing
2195
+ sage: R = PRing(QQ, 'x'); R
2196
+ Univariate Polynomial Ring in x over Rational Field
2197
+ sage: type(R.gen()) # needs sage.libs.flint
2198
+ <class 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
2199
+ sage: R = PRing(QQ, 'x', sparse=True); R
2200
+ Sparse Univariate Polynomial Ring in x over Rational Field
2201
+ sage: type(R.gen())
2202
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'>
2203
+
2204
+ sage: # needs sage.rings.real_mpfr
2205
+ sage: R = PRing(CC, 'x'); R
2206
+ Univariate Polynomial Ring in x over Complex Field with 53 bits of precision
2207
+ sage: type(R.gen())
2208
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'>
2209
+
2210
+ Demonstrate that :issue:`8762` is fixed::
2211
+
2212
+ sage: R.<x> = PolynomialRing(GF(next_prime(10^20)), sparse=True) # needs sage.rings.finite_rings
2213
+ sage: x^(10^20) # this should be fast # needs sage.rings.finite_rings
2214
+ x^100000000000000000000
2215
+ """
2216
+ def _element_class():
2217
+ if element_class:
2218
+ return element_class
2219
+ if sparse:
2220
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse_field
2221
+ return Polynomial_generic_sparse_field
2222
+ if isinstance(base_ring, rational_field.RationalField):
2223
+ try:
2224
+ from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
2225
+ return Polynomial_rational_flint
2226
+ except ImportError:
2227
+ pass
2228
+ elif isinstance(base_ring, NumberField):
2229
+ if base_ring.is_absolute():
2230
+ from sage.rings.polynomial.polynomial_number_field import Polynomial_absolute_number_field_dense
2231
+ return Polynomial_absolute_number_field_dense
2232
+ else:
2233
+ from sage.rings.polynomial.polynomial_number_field import Polynomial_relative_number_field_dense
2234
+ return Polynomial_relative_number_field_dense
2235
+ elif isinstance(base_ring, sage.rings.abc.RealField):
2236
+ try:
2237
+ from .polynomial_real_mpfr_dense import PolynomialRealDense
2238
+ return PolynomialRealDense
2239
+ except ImportError:
2240
+ pass
2241
+ elif isinstance(base_ring, sage.rings.abc.ComplexBallField):
2242
+ try:
2243
+ from sage.rings.polynomial.polynomial_complex_arb import Polynomial_complex_arb
2244
+ return Polynomial_complex_arb
2245
+ except ImportError:
2246
+ pass
2247
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_dense_field
2248
+ return Polynomial_generic_dense_field
2249
+
2250
+ if category is None:
2251
+ cat = PrincipalIdealDomains()
2252
+ else:
2253
+ cat = category & PrincipalIdealDomains()
2254
+
2255
+ PolynomialRing_integral_domain.__init__(self, base_ring, name=name,
2256
+ sparse=sparse, implementation=implementation,
2257
+ element_class=_element_class(), category=cat)
2258
+
2259
+ def _ideal_class_(self, n=0):
2260
+ """
2261
+ Return the class representing ideals in univariate polynomial rings
2262
+ over fields.
2263
+
2264
+ EXAMPLES::
2265
+
2266
+ sage: R.<t> = GF(5)[]
2267
+ sage: R._ideal_class_()
2268
+ <class 'sage.rings.polynomial.ideal.Ideal_1poly_field'>
2269
+ """
2270
+ from sage.rings.polynomial.ideal import Ideal_1poly_field
2271
+ return Ideal_1poly_field
2272
+
2273
+ def divided_difference(self, points, full_table=False):
2274
+ r"""
2275
+ Return the Newton divided-difference coefficients of the
2276
+ Lagrange interpolation polynomial through ``points``.
2277
+
2278
+ INPUT:
2279
+
2280
+ - ``points`` -- list of pairs `(x_0, y_0), (x_1, y_1),
2281
+ \dots, (x_n, y_n)` of elements of the base ring of ``self``,
2282
+ where `x_i - x_j` is invertible for `i \neq j`. This method
2283
+ converts the `x_i` and `y_i` into the base ring of ``self``.
2284
+
2285
+ - ``full_table`` -- boolean (default: ``False``); if ``True``,
2286
+ return the full divided-difference table. If ``False``,
2287
+ only return entries along the main diagonal; these are the
2288
+ Newton divided-difference coefficients `F_{i,i}`.
2289
+
2290
+ OUTPUT:
2291
+
2292
+ The Newton divided-difference coefficients of the `n`-th
2293
+ Lagrange interpolation polynomial `P_n(x)` that passes through
2294
+ the points in ``points`` (see :meth:`lagrange_polynomial`).
2295
+ These are the coefficients `F_{0,0}, F_{1,1}, \dots, F_{n,n}`
2296
+ in the base ring of ``self`` such that
2297
+
2298
+ .. MATH::
2299
+
2300
+ P_n(x) = \sum_{i=0}^n F_{i,i} \prod_{j=0}^{i-1} (x - x_j)
2301
+
2302
+ EXAMPLES:
2303
+
2304
+ Only return the divided-difference coefficients `F_{i,i}`.
2305
+ This example is taken from Example 1, page 121 of [BF2005]_::
2306
+
2307
+ sage: # needs sage.rings.real_mpfr
2308
+ sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022),
2309
+ ....: (1.9, 0.2818186), (2.2, 0.1103623)]
2310
+ sage: R = PolynomialRing(RR, "x")
2311
+ sage: R.divided_difference(points)
2312
+ [0.765197700000000,
2313
+ -0.483705666666666,
2314
+ -0.108733888888889,
2315
+ 0.0658783950617283,
2316
+ 0.00182510288066044]
2317
+
2318
+ Now return the full divided-difference table::
2319
+
2320
+ sage: # needs sage.rings.real_mpfr
2321
+ sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022),
2322
+ ....: (1.9, 0.2818186), (2.2, 0.1103623)]
2323
+ sage: R = PolynomialRing(RR, "x")
2324
+ sage: R.divided_difference(points, full_table=True)
2325
+ [[0.765197700000000],
2326
+ [0.620086000000000, -0.483705666666666],
2327
+ [0.455402200000000, -0.548946000000000, -0.108733888888889],
2328
+ [0.281818600000000, -0.578612000000000,
2329
+ -0.0494433333333339, 0.0658783950617283],
2330
+ [0.110362300000000, -0.571520999999999, 0.0118183333333349,
2331
+ 0.0680685185185209, 0.00182510288066044]]
2332
+
2333
+ The following example is taken from Example 4.12, page 225 of
2334
+ [MF1999]_::
2335
+
2336
+ sage: points = [(1, -3), (2, 0), (3, 15), (4, 48), (5, 105), (6, 192)]
2337
+ sage: R = PolynomialRing(QQ, "x")
2338
+ sage: R.divided_difference(points)
2339
+ [-3, 3, 6, 1, 0, 0]
2340
+ sage: R.divided_difference(points, full_table=True)
2341
+ [[-3],
2342
+ [0, 3],
2343
+ [15, 15, 6],
2344
+ [48, 33, 9, 1],
2345
+ [105, 57, 12, 1, 0],
2346
+ [192, 87, 15, 1, 0, 0]]
2347
+ """
2348
+ to_base_ring = self.base_ring()
2349
+ points = [tuple(to_base_ring(c) for c in p) for p in points]
2350
+ n = len(points)
2351
+ F = [[points[i][1]] for i in range(n)]
2352
+ for i in range(1, n):
2353
+ for j in range(1, i+1):
2354
+ numer = F[i][j-1] - F[i-1][j-1]
2355
+ denom = points[i][0] - points[i-j][0]
2356
+ F[i].append(numer / denom)
2357
+ if full_table:
2358
+ return F
2359
+ else:
2360
+ return [F[i][i] for i in range(n)]
2361
+
2362
+ def lagrange_polynomial(self, points, algorithm='divided_difference',
2363
+ previous_row=None):
2364
+ r"""
2365
+ Return the Lagrange interpolation polynomial through the
2366
+ given points.
2367
+
2368
+ INPUT:
2369
+
2370
+ - ``points`` -- list of pairs `(x_0, y_0), (x_1, y_1),
2371
+ \dots, (x_n, y_n)` of elements of the base ring of ``self``,
2372
+ where `x_i - x_j` is invertible for `i \neq j`. This method
2373
+ converts the `x_i` and `y_i` into the base ring of ``self``.
2374
+
2375
+ - ``algorithm`` -- (default: ``'divided_difference'``) one of
2376
+ the following:
2377
+
2378
+ - ``'divided_difference'``: use the method of divided
2379
+ differences.
2380
+
2381
+ - ``'neville'``: adapt Neville's method as
2382
+ described on page 144 of [BF2005]_ to recursively generate
2383
+ the Lagrange interpolation polynomial. Neville's method
2384
+ generates a table of approximating polynomials, where the
2385
+ last row of that table contains the `n`-th Lagrange
2386
+ interpolation polynomial. The adaptation implemented by
2387
+ this method is to only generate the last row of this
2388
+ table, instead of the full table itself. Generating the
2389
+ full table can be memory inefficient.
2390
+
2391
+ - ``'pari'``: use Pari's function :pari:`polinterpolate`
2392
+
2393
+ - ``previous_row`` -- (default: ``None``) this option is only
2394
+ relevant if used with ``algorithm='neville'``. If provided,
2395
+ this should be the last row of the table resulting from a
2396
+ previous use of Neville's method. If such a row is passed,
2397
+ then ``points`` should consist of both previous and new
2398
+ interpolating points. Neville's method will then use that
2399
+ last row and the interpolating points to generate a new row
2400
+ containing an interpolation polynomial for the new points.
2401
+
2402
+ OUTPUT:
2403
+
2404
+ The Lagrange interpolation polynomial through the points
2405
+ `(x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)`. This is the
2406
+ unique polynomial `P_n` of degree at most `n` in ``self``
2407
+ satisfying `P_n(x_i) = y_i` for `0 \le i \le n`.
2408
+
2409
+ EXAMPLES:
2410
+
2411
+ By default, we use the method of divided differences::
2412
+
2413
+ sage: R = PolynomialRing(QQ, 'x')
2414
+ sage: f = R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)]); f
2415
+ -23/84*x^3 - 11/84*x^2 + 13/7*x + 1
2416
+ sage: f(0)
2417
+ 1
2418
+ sage: f(2)
2419
+ 2
2420
+ sage: f(3)
2421
+ -2
2422
+ sage: f(-4)
2423
+ 9
2424
+
2425
+ sage: # needs sage.rings.finite_rings
2426
+ sage: R = PolynomialRing(GF(2**3, 'a'), 'x')
2427
+ sage: a = R.base_ring().gen()
2428
+ sage: f = R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)]); f
2429
+ a^2*x^2 + a^2*x + a^2
2430
+ sage: f(a^2 + a)
2431
+ a
2432
+ sage: f(a)
2433
+ 1
2434
+ sage: f(a^2)
2435
+ a^2 + a + 1
2436
+
2437
+ Now use a memory efficient version of Neville's method::
2438
+
2439
+ sage: R = PolynomialRing(QQ, 'x')
2440
+ sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)],
2441
+ ....: algorithm='neville')
2442
+ [9,
2443
+ -11/7*x + 19/7,
2444
+ -17/42*x^2 - 83/42*x + 53/7,
2445
+ -23/84*x^3 - 11/84*x^2 + 13/7*x + 1]
2446
+
2447
+ sage: # needs sage.rings.finite_rings
2448
+ sage: R = PolynomialRing(GF(2**3, 'a'), 'x')
2449
+ sage: a = R.base_ring().gen()
2450
+ sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)],
2451
+ ....: algorithm='neville')
2452
+ [a^2 + a + 1, x + a + 1, a^2*x^2 + a^2*x + a^2]
2453
+
2454
+ Repeated use of Neville's method to get better Lagrange
2455
+ interpolation polynomials::
2456
+
2457
+ sage: R = PolynomialRing(QQ, 'x')
2458
+ sage: p = R.lagrange_polynomial([(0,1), (2,2)], algorithm='neville')
2459
+ sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)],
2460
+ ....: algorithm='neville', previous_row=p)[-1]
2461
+ -23/84*x^3 - 11/84*x^2 + 13/7*x + 1
2462
+
2463
+ sage: # needs sage.rings.finite_rings
2464
+ sage: R = PolynomialRing(GF(2**3, 'a'), 'x')
2465
+ sage: a = R.base_ring().gen()
2466
+ sage: p = R.lagrange_polynomial([(a^2+a, a), (a, 1)], algorithm='neville')
2467
+ sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)],
2468
+ ....: algorithm='neville', previous_row=p)[-1]
2469
+ a^2*x^2 + a^2*x + a^2
2470
+
2471
+ One can also use ``Pari``'s implementation::
2472
+
2473
+ sage: R = PolynomialRing(QQ, 'x')
2474
+ sage: data = [(0,1), (2,5), (3,10)]
2475
+ sage: p = R.lagrange_polynomial(data, algorithm='pari'); p # needs sage.libs.pari
2476
+ x^2 + 1
2477
+
2478
+ TESTS:
2479
+
2480
+ The value for ``algorithm`` must be either
2481
+ ``'divided_difference'`` (default), ``'neville'`` or ``'pari'``::
2482
+
2483
+ sage: R = PolynomialRing(QQ, 'x')
2484
+ sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm='abc')
2485
+ Traceback (most recent call last):
2486
+ ...
2487
+ ValueError: algorithm can be 'divided_difference', 'neville' or 'pari'
2488
+
2489
+ Make sure that :issue:`10304` is fixed. The return value
2490
+ should always be an element of ``self`` in the case of
2491
+ ``divided_difference``, or a list of elements of ``self`` in
2492
+ the case of ``neville``::
2493
+
2494
+ sage: R = PolynomialRing(QQ, 'x')
2495
+ sage: R.lagrange_polynomial([]).parent() == R
2496
+ True
2497
+ sage: R.lagrange_polynomial([(2, 3)]).parent() == R
2498
+ True
2499
+ sage: row = R.lagrange_polynomial([], algorithm='neville')
2500
+ sage: all(poly.parent() == R for poly in row)
2501
+ True
2502
+ sage: row = R.lagrange_polynomial([(2, 3)], algorithm='neville')
2503
+ sage: all(poly.parent() == R for poly in row)
2504
+ True
2505
+
2506
+ Check that base fields of positive characteristic are treated
2507
+ correctly (see :issue:`9787`)::
2508
+
2509
+ sage: R.<x> = GF(101)[]
2510
+ sage: R.lagrange_polynomial([[1, 0], [2, 0]])
2511
+ 0
2512
+ sage: R.lagrange_polynomial([[1, 0], [2, 0], [3, 0]])
2513
+ 0
2514
+ """
2515
+ # Perhaps we should be slightly stricter on the input and use
2516
+ # self.base_ring().coerce here and in the divided_difference()
2517
+ # method above. However, this breaks an example in
2518
+ # sage.tests.french_book.nonlinear_doctest where the base ring
2519
+ # is CC, but the function values lie in the symbolic ring.
2520
+ to_base_ring = self.base_ring()
2521
+ points = [[to_base_ring(u) for u in x] for x in points]
2522
+ var = self.gen()
2523
+
2524
+ # use the method of divided-difference
2525
+ if algorithm == "divided_difference":
2526
+ # Evaluate in nested form, similar to Horner's method. This is
2527
+ # more efficient than evaluation using the definition of
2528
+ # Lagrange interpolation polynomial by means of divided
2529
+ # difference.
2530
+ n = len(points)
2531
+ if n == 0:
2532
+ return self.zero()
2533
+
2534
+ F = self.divided_difference(points)
2535
+ P = self.coerce(F[n-1])
2536
+ for i in range(n-2, -1, -1):
2537
+ P *= (var - points[i][0])
2538
+ P += F[i]
2539
+ return P
2540
+
2541
+ # Evaluate using the definition of Lagrange interpolation
2542
+ # polynomial by means of divided difference. This is slow
2543
+ # compared to that above, which is in nested form.
2544
+ # P = 0
2545
+ # for i in range(n):
2546
+ # prod = 1
2547
+ # for j in range(i):
2548
+ # prod *= (var - points[j][0])
2549
+ # P += (F[i] * prod)
2550
+ # return P
2551
+
2552
+ # using Neville's method for recursively generating the
2553
+ # Lagrange interpolation polynomial
2554
+ elif algorithm == "neville":
2555
+ if previous_row is None:
2556
+ previous_row = []
2557
+ N = len(points)
2558
+ M = len(previous_row)
2559
+ # During the computation, P keeps track of the previous row,
2560
+ # and Q keeps track of the current row
2561
+ P = previous_row + [None] * (N - M) # use results of previous computation if available
2562
+ Q = [None] * N
2563
+ for i in range(M, N):
2564
+ Q[0] = self.coerce(points[i][1]) # start populating the current row
2565
+ for j in range(1, 1 + i):
2566
+ numer = (var - points[i - j][0]) * Q[j - 1] - (var - points[i][0]) * P[j - 1]
2567
+ denom = points[i][0] - points[i - j][0]
2568
+ Q[j] = numer / denom
2569
+ P, Q = Q, P # the current row is complete, reuse the old P to hold the next row
2570
+ return P # return the last row in the Neville table
2571
+
2572
+ elif algorithm == "pari":
2573
+ from sage.libs.pari import pari
2574
+ positions = pari([a for a, b in points])
2575
+ values = pari([b for a, b in points])
2576
+ return self(pari.polinterpolate(positions, values))
2577
+
2578
+ raise ValueError("algorithm can be 'divided_difference', 'neville' or 'pari'")
2579
+
2580
+ @cached_method
2581
+ def fraction_field(self):
2582
+ """
2583
+ Return the fraction field of ``self``.
2584
+
2585
+ EXAMPLES::
2586
+
2587
+ sage: QQbar['x'].fraction_field() # needs sage.rings.number_field
2588
+ Fraction Field of Univariate Polynomial Ring in x over Algebraic
2589
+ Field
2590
+
2591
+ TESTS:
2592
+
2593
+ Check that :issue:`25449` has been resolved::
2594
+
2595
+ sage: # needs sage.rings.finite_rings
2596
+ sage: k = GF(25453)
2597
+ sage: F.<x> = FunctionField(k)
2598
+ sage: R.<t> = k[]
2599
+ sage: t(x)
2600
+ x
2601
+
2602
+ sage: # needs sage.rings.finite_rings
2603
+ sage: k = GF(55667)
2604
+ sage: F.<x> = FunctionField(k)
2605
+ sage: R.<t> = k[]
2606
+ sage: t(x)
2607
+ x
2608
+
2609
+ Fixed :issue:`37374`::
2610
+
2611
+ sage: x = PolynomialRing(GF(37), ['x'], sparse=True).fraction_field().gen()
2612
+ sage: type(x.numerator())
2613
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'>
2614
+ sage: (x^8 + 16*x^6 + 4*x^4 + x^2 + 12).numerator() - 1
2615
+ x^8 + 16*x^6 + 4*x^4 + x^2 + 11
2616
+ """
2617
+ from sage.rings.fraction_field import FractionField_1poly_field
2618
+ return FractionField_1poly_field(self)
2619
+
2620
+
2621
+ class PolynomialRing_dense_finite_field(PolynomialRing_field):
2622
+ """
2623
+ Univariate polynomial ring over a finite field.
2624
+
2625
+ EXAMPLES::
2626
+
2627
+ sage: R = PolynomialRing(GF(27, 'a'), 'x') # needs sage.rings.finite_rings
2628
+ sage: type(R) # needs sage.rings.finite_rings
2629
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_finite_field_with_category'>
2630
+ """
2631
+ def __init__(self, base_ring, name='x', element_class=None, implementation=None):
2632
+ """
2633
+ TESTS::
2634
+
2635
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_finite_field
2636
+ sage: R = PolynomialRing_dense_finite_field(GF(5), implementation='generic')
2637
+ sage: type(R(0))
2638
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_finite_field_with_category.element_class'>
2639
+
2640
+ sage: S = PolynomialRing_dense_finite_field(GF(25, 'a'), implementation='NTL') # needs sage.libs.ntl sage.rings.finite_rings
2641
+ sage: type(S(0)) # needs sage.libs.ntl sage.rings.finite_rings
2642
+ <class 'sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX'>
2643
+
2644
+ sage: S = PolynomialRing_dense_finite_field(GF(64), implementation='superfast') # needs sage.rings.finite_rings
2645
+ Traceback (most recent call last):
2646
+ ...
2647
+ ValueError: unknown implementation 'superfast' for dense polynomial rings over Finite Field in z6 of size 2^6
2648
+ """
2649
+ if element_class is None:
2650
+ given_implementation = implementation
2651
+ for implementation in self._implementation_names(implementation, base_ring):
2652
+ if implementation == "NTL":
2653
+ try:
2654
+ from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext
2655
+ from sage.libs.ntl.ntl_ZZ_pX import ntl_ZZ_pX
2656
+ from sage.rings.polynomial.polynomial_zz_pex import Polynomial_ZZ_pEX
2657
+ except ImportError:
2658
+ if given_implementation:
2659
+ raise
2660
+ continue
2661
+ p = base_ring.characteristic()
2662
+ self._modulus = ntl_ZZ_pEContext(ntl_ZZ_pX(list(base_ring.modulus()), p))
2663
+ element_class = Polynomial_ZZ_pEX
2664
+ break
2665
+ PolynomialRing_field.__init__(self, base_ring, sparse=False, name=name,
2666
+ implementation=implementation, element_class=element_class)
2667
+
2668
+ @staticmethod
2669
+ def _implementation_names_impl(implementation, base_ring, sparse):
2670
+ """
2671
+ TESTS::
2672
+
2673
+ sage: # needs sage.rings.finite_rings
2674
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_finite_field
2675
+ sage: PolynomialRing_dense_finite_field._implementation_names_impl("NTL", GF(4), False)
2676
+ ['NTL', None]
2677
+ sage: PolynomialRing_dense_finite_field._implementation_names_impl(None, GF(4), False)
2678
+ ['NTL', None]
2679
+ sage: PolynomialRing_dense_finite_field._implementation_names_impl("generic", GF(4), False)
2680
+ ['generic']
2681
+ sage: PolynomialRing_dense_finite_field._implementation_names_impl("FLINT", GF(4), False)
2682
+ NotImplemented
2683
+ sage: PolynomialRing_dense_finite_field._implementation_names_impl(None, GF(4), True)
2684
+ NotImplemented
2685
+ """
2686
+ if sparse:
2687
+ return NotImplemented
2688
+ defaults = ["NTL", None]
2689
+ if implementation in defaults:
2690
+ return defaults
2691
+ elif implementation == "generic":
2692
+ return [implementation]
2693
+ return NotImplemented
2694
+
2695
+ def irreducible_element(self, n, algorithm=None):
2696
+ """
2697
+ Construct a monic irreducible polynomial of degree `n`.
2698
+
2699
+ INPUT:
2700
+
2701
+ - ``n`` -- integer; degree of the polynomial to construct
2702
+
2703
+ - ``algorithm`` -- string (algorithm to use) or ``None``:
2704
+
2705
+ - ``'random'`` or ``None``:
2706
+ try random polynomials until an irreducible one is found
2707
+
2708
+ - ``'first_lexicographic'``: try polynomials in
2709
+ lexicographic order until an irreducible one is found
2710
+
2711
+ OUTPUT: a monic irreducible polynomial of degree `n` in ``self``
2712
+
2713
+ EXAMPLES::
2714
+
2715
+ sage: # needs sage.modules sage.rings.finite_rings
2716
+ sage: f = GF(5^3, 'a')['x'].irreducible_element(2)
2717
+ sage: f.degree()
2718
+ 2
2719
+ sage: f.is_irreducible()
2720
+ True
2721
+ sage: R = GF(19)['x']
2722
+ sage: R.irreducible_element(21, algorithm='first_lexicographic')
2723
+ x^21 + x + 5
2724
+ sage: R = GF(5**2, 'a')['x']
2725
+ sage: R.irreducible_element(17, algorithm='first_lexicographic')
2726
+ x^17 + a*x + 4*a + 3
2727
+
2728
+ AUTHORS:
2729
+
2730
+ - Peter Bruin (June 2013)
2731
+ - Jean-Pierre Flori (May 2014)
2732
+ """
2733
+ if n < 1:
2734
+ raise ValueError("degree must be at least 1")
2735
+
2736
+ if algorithm is None:
2737
+ algorithm = "random"
2738
+
2739
+ if algorithm == "random":
2740
+ while True:
2741
+ f = self.gen()**n + self.random_element(degree=(0, n - 1))
2742
+ if f.is_irreducible():
2743
+ return f
2744
+ elif algorithm == "first_lexicographic":
2745
+ for g in self.polynomials(max_degree=n-1):
2746
+ f = self.gen()**n + g
2747
+ if f.is_irreducible():
2748
+ return f
2749
+ else:
2750
+ raise ValueError("no such algorithm for finding an irreducible polynomial: %s" % algorithm)
2751
+
2752
+ def _roth_ruckenstein(self, p, degree_bound, precision):
2753
+ r"""
2754
+ Return all polynomials which are a solution to the, possibly modular,
2755
+ root-finding problem.
2756
+
2757
+ This is the core of Roth-Ruckenstein's algorithm where all conversions,
2758
+ checks and parent-extraction have been done.
2759
+
2760
+ INPUT:
2761
+
2762
+ - ``p`` -- a nonzero polynomial over ``F[x][y]``. The polynomial ``p``
2763
+ should be first truncated to ``precision``
2764
+
2765
+ - ``degree_bound`` -- a bound on the degree of the roots of ``p`` that
2766
+ the algorithm computes
2767
+
2768
+ - ``precision`` -- if given, roots are computed modulo `x^d` where `d` is
2769
+ ``precision`` (see below)
2770
+
2771
+ OUTPUT: the list of roots of ``p`` of degree at most ``degree_bound``:
2772
+
2773
+ - If `precision = None` actual roots are computed, i.e. all `f \in F[x]`
2774
+ such that `p(f) = 0`.
2775
+
2776
+ - If ``precision = k`` for some integer ``k``, then all `f \in \F[x]` such
2777
+ that `Q(f) \equiv 0 \mod x^k` are computed. This set is infinite, thus it
2778
+ represented as a list of pairs in `F[x] \times \ZZ_+`, where
2779
+ `(f, d)` denotes that `Q(f + x^d h) \equiv 0 \mod x^k` for any `h \in
2780
+ F[[x]]`.
2781
+
2782
+ EXAMPLES::
2783
+
2784
+ sage: # needs sage.rings.finite_rings
2785
+ sage: F = GF(17)
2786
+ sage: Px.<x> = F[]
2787
+ sage: Pxy.<y> = Px[]
2788
+ sage: p = (y - (x**2 + x + 1)) * (y**2 - x + 1) * (y - (x**3 + 4*x + 16))
2789
+ sage: Px._roth_ruckenstein(p, 3, None)
2790
+ [x^3 + 4*x + 16, x^2 + x + 1]
2791
+ sage: Px._roth_ruckenstein(p, 2, None)
2792
+ [x^2 + x + 1]
2793
+ sage: Px._roth_ruckenstein(p, 1, 2)
2794
+ [(4*x + 16, 2), (2*x + 13, 2), (15*x + 4, 2), (x + 1, 2)]
2795
+ """
2796
+ def roth_rec(p, lam, k, g):
2797
+ r"""
2798
+ Recursive core method for Roth-Ruckenstein algorithm.
2799
+
2800
+ INPUT:
2801
+
2802
+ - ``p`` -- the current value of the polynomial
2803
+ - ``lam`` -- is the power of x whose coefficient is being computed
2804
+ - ``k`` -- the remaining precision to handle (if ``precision`` is given)
2805
+ - ``g`` -- the root being computed
2806
+ """
2807
+ if precision and k <= 0:
2808
+ solutions.append((g, lam))
2809
+ return
2810
+ val = min(c.valuation() for c in p)
2811
+ if precision:
2812
+ k = k - val
2813
+ T = p.map_coefficients(lambda c:c.shift(-val))
2814
+ Ty = T.map_coefficients(lambda c:c[0]).change_ring(F)
2815
+ if Ty.is_zero() or (precision and k <= 0):
2816
+ if precision:
2817
+ solutions.append((g, lam))
2818
+ else:
2819
+ solutions.append(g)
2820
+ return
2821
+ roots = Ty.roots(multiplicities=False)
2822
+ for gamma in roots:
2823
+ g_new = g + gamma*x**lam
2824
+ if lam < degree_bound:
2825
+ Tg = T(x*y + gamma)
2826
+ roth_rec(Tg , lam+1, k, g_new)
2827
+ else:
2828
+ if precision:
2829
+ solutions.append((g_new, lam+1))
2830
+ elif p(gamma).is_zero():
2831
+ solutions.append(g_new)
2832
+ return
2833
+
2834
+ x = self.gen()
2835
+ y = p.parent().gen()
2836
+ F = self.base_ring()
2837
+ solutions = []
2838
+ g = self.zero()
2839
+
2840
+ roth_rec(p, 0, precision, g)
2841
+ return solutions
2842
+
2843
+ def _alekhnovich(self, p, degree_bound, precision=None, dc_threshold=None):
2844
+ r"""
2845
+ Use Alekhnovich's Divide & Conquer variant of Roth-Ruckenstein's
2846
+ rootfinding algorithm to find roots modulo-up-to-some-precision of a `Q \in
2847
+ F[x][y]` where `F` is a finite field. Supports a mixed strategy with
2848
+ Roth-Ruckenstein applied at lowest precision.
2849
+
2850
+ INPUT:
2851
+
2852
+ - ``p`` -- a nonzero polynomial over ``F[x][y]``. The polynomial ``p``
2853
+ should be first truncated to ``precision``
2854
+
2855
+ - ``degree_bound`` -- a bound on the degree of the roots of ``p`` that
2856
+ the algorithm computes
2857
+
2858
+ - ``precision`` -- if given, roots are computed modulo `x^d` where `d` is
2859
+ ``precision`` (see below)
2860
+
2861
+ - ``dc_threshold`` -- if given, the algorithm calls :meth:`_roth_ruckenetein`
2862
+ to compute roots of degree at most ``dc_threshold``
2863
+
2864
+ OUTPUT: the list of roots of ``p`` of degree at most ``degree_bound``:
2865
+
2866
+ - If `precision = None` actual roots are computed, i.e. all `f \in F[x]`
2867
+ such that `p(f) = 0`.
2868
+
2869
+ - If ``precision = k`` for some integer ``k``, then all `f \in \F[x]` such
2870
+ that `Q(f) \equiv 0 \mod x^k` are computed. This set is infinite, thus it
2871
+ represented as a list of pairs in `F[x] \times \ZZ_+`, where
2872
+ `(f, d)` denotes that `Q(f + x^d h) \equiv 0 \mod x^k` for any `h \in
2873
+ F[[x]]`.
2874
+
2875
+ .. NOTE::
2876
+
2877
+ Non-exhaustive testing tends to indicate that ``dc_threhold = None`` is,
2878
+ surprisingly, the best strategy. (See the example section.)
2879
+
2880
+ EXAMPLES::
2881
+
2882
+ sage: # needs sage.rings.finite_rings
2883
+ sage: R.<x> = GF(17)[]
2884
+ sage: S.<y> = R[]
2885
+ sage: p = (y - 2*x^2 - 3*x - 14) * (y - 3*x + 2) * (y - 1)
2886
+ sage: R._alekhnovich(p, 2)
2887
+ [3*x + 15, 2*x^2 + 3*x + 14, 1]
2888
+ sage: R._alekhnovich(p, 1)
2889
+ [3*x + 15, 1]
2890
+ sage: R._alekhnovich(p, 1, precision=2)
2891
+ [(3*x + 15, 2), (3*x + 14, 2), (1, 2)]
2892
+
2893
+ Example of benchmark to check that `dc_threshold = None` is better::
2894
+
2895
+ sage: # not tested, needs sage.rings.finite_rings
2896
+ sage: p = prod(y - R.random_element(20)
2897
+ ....: for _ in range(10)) * S.random_element(10,10)
2898
+ sage: %timeit _alekhnovich(R, p, 20, dc_threshold = None)
2899
+ 1 loop, best of 3: 418 ms per loop
2900
+ sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 1)
2901
+ 1 loop, best of 3: 416 ms per loop
2902
+ sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 2)
2903
+ 1 loop, best of 3: 418 ms per loop
2904
+ sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 3)
2905
+ 1 loop, best of 3: 454 ms per loop
2906
+ sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 4)
2907
+ 1 loop, best of 3: 519 ms per loop
2908
+
2909
+ AUTHORS:
2910
+
2911
+ - Johan Rosenkilde (2015) -- Original implementation
2912
+ - Bruno Grenet (August 2016) -- Incorporation into SageMath and polishing
2913
+ """
2914
+ def alekh_rec(p, k, degree_bound, lvl):
2915
+ r"""
2916
+ Recursive core method for Alekhnovich algorithm.
2917
+
2918
+ INPUT:
2919
+
2920
+ - ``p`` -- the current value of the polynomial
2921
+ - ``k`` -- the number of coefficients left to be computed
2922
+ - ``degree_bound`` -- the current degree bound
2923
+ - ``lvl`` -- the level in the recursion tree
2924
+ """
2925
+ if k <= 0:
2926
+ return [ (self.zero(),0) ]
2927
+ elif degree_bound < 0:
2928
+ # The only possible root of (current) p, if any, is y = 0
2929
+ if p(0).is_zero() or p(0).valuation() >= k:
2930
+ return [ (self.zero(),0) ]
2931
+ else:
2932
+ return []
2933
+ elif k == 1 or degree_bound == 0:
2934
+ #Either one coefficient left to be computed, or p has only one coefficient
2935
+ py = self([c[0] for c in p.list()]) # py = p(x=0, y)
2936
+ if py.is_zero():
2937
+ return [ (self.zero(), 0) ]
2938
+ roots = py.roots(multiplicities=False)
2939
+ return [ (self(r),1) for r in roots ]
2940
+ elif k < dc_threshold:
2941
+ # Run Roth-Ruckenstein
2942
+ return self._roth_ruckenstein(p, degree_bound=degree_bound, precision=k)
2943
+ else:
2944
+ p = p.map_coefficients(lambda c:c.truncate(k))
2945
+ half_roots = alekh_rec(p, k//2, degree_bound, lvl+1)
2946
+ whole_roots = []
2947
+ for (hi, di) in half_roots:
2948
+ QhatT = p(hi + y*x**di)
2949
+ if not QhatT:
2950
+ whole_roots.append((hi,di))
2951
+ else:
2952
+ val = min(c.valuation() for c in QhatT)
2953
+ Qhat = QhatT.map_coefficients(lambda c:c.shift(-val))
2954
+ sec_half = alekh_rec(Qhat, k-val, degree_bound - di, lvl+1)
2955
+ whole_roots.extend([ (hi + hij.shift(di), di+dij) for (hij, dij) in sec_half ])
2956
+ return whole_roots
2957
+
2958
+ x = self.gen()
2959
+ y = p.parent().gen()
2960
+
2961
+ # If precision is not given, find actual roots. To be sure, precision then
2962
+ # needs to be more than wdeg{1,degree_bound}(Q) since a root might have degree degree_bound.
2963
+ if precision is None:
2964
+ k = 1 + max( p[i].degree() + degree_bound*i for i in range(1+p.degree()))
2965
+ else:
2966
+ k = precision
2967
+
2968
+ mod_roots = alekh_rec(p, k, degree_bound, 0)
2969
+
2970
+ if precision is None:
2971
+ roots = []
2972
+ for hi,_ in mod_roots:
2973
+ if p(hi).is_zero():
2974
+ roots.append(hi)
2975
+ return roots
2976
+ else:
2977
+ return mod_roots
2978
+
2979
+ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=False, algorithm=None, degree_bound=None):
2980
+ """
2981
+ Return the list of roots of ``p``.
2982
+
2983
+ INPUT:
2984
+
2985
+ - ``p`` -- the polynomial whose roots are computed
2986
+ - ``ring`` -- the ring to find roots (default: the base ring of ``p``)
2987
+ - ``multiplicities`` -- boolean (default: ``True``); currently, roots are only
2988
+ computed without their multiplicities
2989
+ - ``algorithm`` -- the algorithm to use: either ``'Alekhnovich'`` (default)
2990
+ or ``'Roth-Ruckenstein'``
2991
+ - ``degree_bound`` -- if not ``None``, return only roots of degree at
2992
+ most ``degree_bound``
2993
+
2994
+ EXAMPLES::
2995
+
2996
+ sage: # needs sage.rings.finite_rings
2997
+ sage: R.<x> = GF(13)[]
2998
+ sage: S.<y> = R[]
2999
+ sage: p = y^2 + (12*x^2 + x + 11)*y + x^3 + 12*x^2 + 12*x + 1
3000
+ sage: p.roots(multiplicities=False)
3001
+ [x^2 + 11*x + 1, x + 1]
3002
+ sage: p.roots(multiplicities=False, degree_bound=1)
3003
+ [x + 1]
3004
+ sage: p.roots(multiplicities=False, algorithm='Roth-Ruckenstein')
3005
+ [x^2 + 11*x + 1, x + 1]
3006
+
3007
+ TESTS:
3008
+
3009
+ Check that :issue:`23639` is fixed::
3010
+
3011
+ sage: R = GF(3)['x']['y']
3012
+ sage: R.one().roots(multiplicities=False)
3013
+ []
3014
+ sage: R.zero().roots(multiplicities=False)
3015
+ Traceback (most recent call last):
3016
+ ...
3017
+ ArithmeticError: roots of 0 are not defined
3018
+ """
3019
+ if multiplicities:
3020
+ raise NotImplementedError("Use multiplicities=False")
3021
+
3022
+ if degree_bound is None:
3023
+ l = p.degree()
3024
+ if l < 0:
3025
+ raise ArithmeticError("roots of 0 are not defined")
3026
+ if l == 0:
3027
+ return []
3028
+ dl = p[l].degree()
3029
+ degree_bound = max((p[i].degree() - dl)//(l - i) for i in range(l) if p[i])
3030
+
3031
+ if algorithm is None:
3032
+ algorithm = "Alekhnovich"
3033
+
3034
+ if algorithm == "Roth-Ruckenstein":
3035
+ return self._roth_ruckenstein(p, degree_bound, None)
3036
+
3037
+ elif algorithm == "Alekhnovich":
3038
+ return self._alekhnovich(p, degree_bound)
3039
+
3040
+ else:
3041
+ raise ValueError("unknown algorithm '{}'".format(algorithm))
3042
+
3043
+
3044
+ class PolynomialRing_cdvr(PolynomialRing_integral_domain):
3045
+ r"""
3046
+ A class for polynomial ring over complete discrete valuation rings
3047
+ """
3048
+ def __init__(self, base_ring, name=None, sparse=False, implementation=None,
3049
+ element_class=None, category=None):
3050
+ r"""
3051
+ TESTS::
3052
+
3053
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_cdvr
3054
+
3055
+ sage: S.<x> = ZZ[]
3056
+ sage: isinstance(S, PolynomialRing_cdvr)
3057
+ False
3058
+
3059
+ sage: # needs sage.rings.padics
3060
+ sage: S.<x> = Zp(5)[]
3061
+ sage: isinstance(S, PolynomialRing_cdvr)
3062
+ True
3063
+ """
3064
+ if element_class is None:
3065
+ if sparse:
3066
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse_cdvr
3067
+ element_class = Polynomial_generic_sparse_cdvr
3068
+ else:
3069
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_dense_cdvr
3070
+ element_class = Polynomial_generic_dense_cdvr
3071
+ PolynomialRing_integral_domain.__init__(self, base_ring, name, sparse,
3072
+ implementation=implementation,
3073
+ element_class=element_class, category=category)
3074
+
3075
+
3076
+ class PolynomialRing_cdvf(PolynomialRing_cdvr, PolynomialRing_field):
3077
+ """
3078
+ A class for polynomial ring over complete discrete valuation fields
3079
+ """
3080
+ def __init__(self, base_ring, name=None, sparse=False, implementation=None,
3081
+ element_class=None, category=None):
3082
+ r"""
3083
+ TESTS::
3084
+
3085
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_cdvf
3086
+
3087
+ sage: S.<x> = QQ[]
3088
+ sage: isinstance(S, PolynomialRing_cdvf)
3089
+ False
3090
+
3091
+ sage: S.<x> = Qp(5)[] # needs sage.rings.padics
3092
+ sage: isinstance(S, PolynomialRing_cdvf) # needs sage.rings.padics
3093
+ True
3094
+ """
3095
+ if element_class is None:
3096
+ if sparse:
3097
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse_cdvf
3098
+ element_class = Polynomial_generic_sparse_cdvf
3099
+ else:
3100
+ from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_dense_cdvf
3101
+ element_class = Polynomial_generic_dense_cdvf
3102
+ PolynomialRing_field.__init__(self, base_ring, name, sparse,
3103
+ implementation=implementation, element_class=element_class,
3104
+ category=category)
3105
+
3106
+
3107
+ class PolynomialRing_dense_padic_ring_generic(PolynomialRing_cdvr):
3108
+ r"""
3109
+ A class for dense polynomial ring over `p`-adic rings
3110
+ """
3111
+ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None):
3112
+ PolynomialRing_cdvr.__init__(self, base_ring, sparse=False, name=name,
3113
+ implementation=implementation, element_class=element_class,
3114
+ category=category)
3115
+
3116
+ @staticmethod
3117
+ def _implementation_names_impl(implementation, base_ring, sparse):
3118
+ """
3119
+ Only support ``implementation=None`` and ``sparse=False``.
3120
+
3121
+ TESTS::
3122
+
3123
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_generic
3124
+ sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl(None, Zp(2), False) # needs sage.rings.padics
3125
+ [None]
3126
+ sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl(None, Zp(2), True) # needs sage.rings.padics
3127
+ NotImplemented
3128
+ sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl("generic", Zp(2), False) # needs sage.rings.padics
3129
+ NotImplemented
3130
+ """
3131
+ if implementation is None and not sparse:
3132
+ return [None] # Not a "generic" implementation
3133
+ return NotImplemented
3134
+
3135
+
3136
+ class PolynomialRing_dense_padic_field_generic(PolynomialRing_cdvf):
3137
+ r"""
3138
+ A class for dense polynomial ring over `p`-adic fields
3139
+ """
3140
+ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None):
3141
+ PolynomialRing_cdvf.__init__(self, base_ring, sparse=False, name=name,
3142
+ implementation=implementation, element_class=element_class,
3143
+ category=category)
3144
+
3145
+ @staticmethod
3146
+ def _implementation_names_impl(implementation, base_ring, sparse):
3147
+ """
3148
+ Only support ``implementation=None`` and ``sparse=False``.
3149
+
3150
+ TESTS::
3151
+
3152
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_field_generic
3153
+ sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl(None, Qp(2), False) # needs sage.rings.padics
3154
+ [None]
3155
+ sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl(None, Qp(2), True) # needs sage.rings.padics
3156
+ NotImplemented
3157
+ sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl("generic", Qp(2), False) # needs sage.rings.padics
3158
+ NotImplemented
3159
+ """
3160
+ if implementation is None and not sparse:
3161
+ return [None] # Not a "generic" implementation
3162
+ return NotImplemented
3163
+
3164
+
3165
+ class PolynomialRing_dense_padic_ring_capped_relative(PolynomialRing_dense_padic_ring_generic):
3166
+ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None):
3167
+ """
3168
+ TESTS::
3169
+
3170
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_capped_relative as PRing
3171
+ sage: R = PRing(Zp(13), name='t'); R # needs sage.rings.padics
3172
+ Univariate Polynomial Ring in t over 13-adic Ring with capped relative precision 20
3173
+ sage: type(R.gen()) # needs sage.rings.padics
3174
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_capped_relative_with_category.element_class'>
3175
+ """
3176
+ if element_class is None:
3177
+ from sage.rings.polynomial.padics.\
3178
+ polynomial_padic_capped_relative_dense import \
3179
+ Polynomial_padic_capped_relative_dense
3180
+ element_class = Polynomial_padic_capped_relative_dense
3181
+ PolynomialRing_dense_padic_ring_generic.__init__(self, base_ring, name=name,
3182
+ implementation=implementation,
3183
+ element_class=element_class, category=category)
3184
+
3185
+
3186
+ class PolynomialRing_dense_padic_ring_capped_absolute(PolynomialRing_dense_padic_ring_generic):
3187
+ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None):
3188
+ """
3189
+ TESTS::
3190
+
3191
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_capped_absolute as PRing
3192
+ sage: R = PRing(Zp(13, type='capped-abs'), name='t'); R # needs sage.rings.padics
3193
+ Univariate Polynomial Ring in t over 13-adic Ring with capped absolute precision 20
3194
+ sage: type(R.gen()) # needs sage.rings.padics
3195
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_capped_absolute_with_category.element_class'>
3196
+ """
3197
+ if element_class is None:
3198
+ from sage.rings.polynomial.padics.polynomial_padic_flat import \
3199
+ Polynomial_padic_flat
3200
+ element_class = Polynomial_padic_flat
3201
+ PolynomialRing_dense_padic_ring_generic.__init__(self, base_ring, name=name,
3202
+ implementation=implementation,
3203
+ element_class=element_class, category=category)
3204
+
3205
+
3206
+ class PolynomialRing_dense_padic_ring_fixed_mod(PolynomialRing_dense_padic_ring_generic):
3207
+ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None):
3208
+ """
3209
+ TESTS::
3210
+
3211
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_fixed_mod as PRing
3212
+ sage: R = PRing(Zp(13, type='fixed-mod'), name='t'); R # needs sage.rings.padics
3213
+ Univariate Polynomial Ring in t over 13-adic Ring of fixed modulus 13^20
3214
+
3215
+ sage: type(R.gen()) # needs sage.rings.padics
3216
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_fixed_mod_with_category.element_class'>
3217
+ """
3218
+ if element_class is None:
3219
+ from sage.rings.polynomial.padics.polynomial_padic_flat import \
3220
+ Polynomial_padic_flat
3221
+ element_class = Polynomial_padic_flat
3222
+ PolynomialRing_dense_padic_ring_generic.__init__(self, base_ring, name=name,
3223
+ implementation=implementation,
3224
+ element_class=element_class, category=category)
3225
+
3226
+
3227
+ class PolynomialRing_dense_padic_field_capped_relative(PolynomialRing_dense_padic_field_generic):
3228
+ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None):
3229
+ """
3230
+ TESTS::
3231
+
3232
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_field_capped_relative as PRing
3233
+ sage: R = PRing(Qp(13), name='t'); R # needs sage.rings.padics
3234
+ Univariate Polynomial Ring in t over 13-adic Field with capped relative precision 20
3235
+ sage: type(R.gen()) # needs sage.rings.padics
3236
+ <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_field_capped_relative_with_category.element_class'>
3237
+ """
3238
+ if element_class is None:
3239
+ from sage.rings.polynomial.padics.\
3240
+ polynomial_padic_capped_relative_dense import \
3241
+ Polynomial_padic_capped_relative_dense
3242
+ element_class = Polynomial_padic_capped_relative_dense
3243
+ PolynomialRing_dense_padic_field_generic.__init__(self, base_ring, name=name,
3244
+ implementation=implementation,
3245
+ element_class=element_class, category=category)
3246
+
3247
+
3248
+ class PolynomialRing_dense_mod_n(PolynomialRing_commutative):
3249
+ def __init__(self, base_ring, name=None, element_class=None,
3250
+ implementation=None, category=None):
3251
+ """
3252
+ TESTS::
3253
+
3254
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_n as PRing
3255
+ sage: R = PRing(Zmod(15), 'x'); R
3256
+ Univariate Polynomial Ring in x over Ring of integers modulo 15
3257
+ sage: type(R.gen()) # needs sage.libs.flint
3258
+ <class 'sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint'>
3259
+
3260
+ sage: R = PRing(Zmod(15), 'x', implementation='NTL'); R # needs sage.libs.ntl
3261
+ Univariate Polynomial Ring in x over Ring of integers modulo 15 (using NTL)
3262
+ sage: type(R.gen()) # needs sage.libs.ntl
3263
+ <class 'sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz'>
3264
+
3265
+ sage: R = PRing(Zmod(2**63*3), 'x', implementation='NTL'); R # needs sage.libs.ntl
3266
+ Univariate Polynomial Ring in x over Ring of integers modulo 27670116110564327424 (using NTL)
3267
+ sage: type(R.gen()) # needs sage.libs.ntl
3268
+ <class 'sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ'>
3269
+
3270
+ sage: R = PRing(Zmod(2**63*3), 'x', implementation='FLINT')
3271
+ Traceback (most recent call last):
3272
+ ...
3273
+ ValueError: FLINT does not support modulus 27670116110564327424
3274
+
3275
+ sage: R = PRing(Zmod(2**63*3), 'x'); R # needs sage.libs.ntl
3276
+ Univariate Polynomial Ring in x over Ring of integers modulo 27670116110564327424 (using NTL)
3277
+ sage: type(R.gen()) # needs sage.libs.ntl
3278
+ <class 'sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ'>
3279
+ """
3280
+ if element_class is None:
3281
+ self._implementation_repr = ''
3282
+ given_implementation = implementation
3283
+ for implementation in self._implementation_names(implementation, base_ring):
3284
+ if implementation == "FLINT":
3285
+ try:
3286
+ from .polynomial_zmod_flint import Polynomial_zmod_flint as element_class
3287
+ except ImportError:
3288
+ if given_implementation:
3289
+ raise
3290
+ continue
3291
+ self._implementation_repr = ''
3292
+ elif implementation == "NTL":
3293
+ modulus = base_ring.order()
3294
+ try:
3295
+ from . import polynomial_modn_dense_ntl as modn_dense_ntl
3296
+ except ImportError:
3297
+ if given_implementation:
3298
+ raise
3299
+ continue
3300
+ if modulus < ZZ(modn_dense_ntl.zz_p_max):
3301
+ element_class = modn_dense_ntl.Polynomial_dense_modn_ntl_zz
3302
+ else:
3303
+ element_class = modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ
3304
+ self._implementation_repr = ' (using NTL)'
3305
+ break
3306
+
3307
+ PolynomialRing_commutative.__init__(self, base_ring, name=name, implementation=implementation,
3308
+ element_class=element_class, category=category)
3309
+
3310
+ @staticmethod
3311
+ def _implementation_names_impl(implementation, base_ring, sparse):
3312
+ """
3313
+ TESTS::
3314
+
3315
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_n
3316
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl("FLINT", IntegerModRing(10), False)
3317
+ ['FLINT', None]
3318
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl("NTL", IntegerModRing(10), False)
3319
+ ['NTL']
3320
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl(None, IntegerModRing(10), False)
3321
+ ['FLINT', None]
3322
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl("generic", IntegerModRing(10), False)
3323
+ NotImplemented
3324
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl("FLINT", IntegerModRing(10^30), False)
3325
+ Traceback (most recent call last):
3326
+ ...
3327
+ ValueError: FLINT does not support modulus 1000000000000000000000000000000
3328
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl("NTL", IntegerModRing(10^30), False)
3329
+ ['NTL', None]
3330
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl(None, IntegerModRing(10^30), False)
3331
+ ['NTL', None]
3332
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl("generic", IntegerModRing(10^30), False)
3333
+ NotImplemented
3334
+ sage: PolynomialRing_dense_mod_n._implementation_names_impl(None, IntegerModRing(10^30), True)
3335
+ NotImplemented
3336
+ """
3337
+ if sparse:
3338
+ return NotImplemented
3339
+ modulus = base_ring.order()
3340
+ if modulus <= sys.maxsize:
3341
+ defaults = ["FLINT", None]
3342
+ elif implementation == "FLINT":
3343
+ raise ValueError("FLINT does not support modulus %s" % modulus)
3344
+ else:
3345
+ defaults = ["NTL", None]
3346
+ if implementation in defaults:
3347
+ return defaults
3348
+ elif implementation == "NTL":
3349
+ return [implementation]
3350
+ return NotImplemented
3351
+
3352
+ @cached_method
3353
+ def modulus(self):
3354
+ """
3355
+ EXAMPLES::
3356
+
3357
+ sage: R.<x> = Zmod(15)[]
3358
+ sage: R.modulus()
3359
+ 15
3360
+ """
3361
+ return self.base_ring().characteristic()
3362
+
3363
+ def _repr_(self):
3364
+ """
3365
+ TESTS::
3366
+
3367
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing
3368
+ sage: R = PRing(ZZ, 'x', implementation='NTL'); R # needs sage.libs.ntl
3369
+ Univariate Polynomial Ring in x over Integer Ring (using NTL)
3370
+ """
3371
+ s = PolynomialRing_commutative._repr_(self)
3372
+ return s + self._implementation_repr
3373
+
3374
+ def residue_field(self, ideal, names=None):
3375
+ """
3376
+ Return the residue finite field at the given ideal.
3377
+
3378
+ EXAMPLES::
3379
+
3380
+ sage: # needs sage.libs.ntl sage.libs.pari
3381
+ sage: R.<t> = GF(2)[]
3382
+ sage: k.<a> = R.residue_field(t^3 + t + 1); k
3383
+ Residue field in a
3384
+ of Principal ideal (t^3 + t + 1) of Univariate Polynomial Ring in t
3385
+ over Finite Field of size 2 (using GF2X)
3386
+ sage: k.list()
3387
+ [0, a, a^2, a + 1, a^2 + a, a^2 + a + 1, a^2 + 1, 1]
3388
+ sage: R.residue_field(t)
3389
+ Residue field of Principal ideal (t) of Univariate Polynomial Ring in t
3390
+ over Finite Field of size 2 (using GF2X)
3391
+ sage: P = R.irreducible_element(8) * R
3392
+ sage: P
3393
+ Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t
3394
+ over Finite Field of size 2 (using GF2X)
3395
+ sage: k.<a> = R.residue_field(P); k
3396
+ Residue field in a
3397
+ of Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t
3398
+ over Finite Field of size 2 (using GF2X)
3399
+ sage: k.cardinality()
3400
+ 256
3401
+
3402
+ Non-maximal ideals are not accepted::
3403
+
3404
+ sage: # needs sage.libs.ntl sage.libs.pari
3405
+ sage: R.residue_field(t^2 + 1)
3406
+ Traceback (most recent call last):
3407
+ ...
3408
+ ArithmeticError: ideal is not maximal
3409
+ sage: R.residue_field(0)
3410
+ Traceback (most recent call last):
3411
+ ...
3412
+ ArithmeticError: ideal is not maximal
3413
+ sage: R.residue_field(1)
3414
+ Traceback (most recent call last):
3415
+ ...
3416
+ ArithmeticError: ideal is not maximal
3417
+ """
3418
+ ideal = self.ideal(ideal)
3419
+ if not ideal.is_maximal():
3420
+ raise ArithmeticError("ideal is not maximal")
3421
+ return ideal.residue_field(names)
3422
+
3423
+
3424
+ class PolynomialRing_dense_mod_p(PolynomialRing_dense_finite_field,
3425
+ PolynomialRing_dense_mod_n,
3426
+ PolynomialRing_singular_repr):
3427
+ def __init__(self, base_ring, name='x', implementation=None, element_class=None, category=None):
3428
+ """
3429
+ TESTS::
3430
+
3431
+ sage: P = GF(2)['x']; P # needs sage.libs.ntl
3432
+ Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)
3433
+ sage: type(P.gen()) # needs sage.libs.ntl
3434
+ <class 'sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X'>
3435
+
3436
+ sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_p
3437
+ sage: P = PolynomialRing_dense_mod_p(GF(5), 'x'); P
3438
+ Univariate Polynomial Ring in x over Finite Field of size 5
3439
+ sage: type(P.gen()) # needs sage.libs.flint
3440
+ <class 'sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint'>
3441
+
3442
+ sage: # needs sage.libs.ntl
3443
+ sage: P = PolynomialRing_dense_mod_p(GF(5), 'x', implementation='NTL'); P
3444
+ Univariate Polynomial Ring in x over Finite Field of size 5 (using NTL)
3445
+ sage: type(P.gen())
3446
+ <class 'sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p'>
3447
+
3448
+ sage: P = PolynomialRing_dense_mod_p(GF(9223372036854775837), 'x'); P # needs sage.libs.ntl sage.rings.finite_rings
3449
+ Univariate Polynomial Ring in x over Finite Field of size 9223372036854775837 (using NTL)
3450
+ sage: type(P.gen()) # needs sage.libs.ntl sage.rings.finite_rings
3451
+ <class 'sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p'>
3452
+
3453
+ This caching bug was fixed in :issue:`24264`::
3454
+
3455
+ sage: # needs sage.rings.finite_rings
3456
+ sage: p = 2^64 + 13
3457
+ sage: A = GF(p^2)
3458
+ sage: B = GF(p^3)
3459
+ sage: R = A.modulus().parent()
3460
+ sage: S = B.modulus().parent()
3461
+ sage: R is S
3462
+ True
3463
+ """
3464
+ if element_class is None:
3465
+ given_implementation = implementation
3466
+ for implementation in self._implementation_names(implementation, base_ring):
3467
+ if implementation == "FLINT":
3468
+ try:
3469
+ from .polynomial_zmod_flint import Polynomial_zmod_flint as element_class
3470
+ except ImportError:
3471
+ if given_implementation:
3472
+ raise
3473
+ continue
3474
+ self._implementation_repr = ''
3475
+ elif implementation == "NTL":
3476
+ try:
3477
+ from .polynomial_modn_dense_ntl import Polynomial_dense_mod_p as element_class
3478
+ except ImportError:
3479
+ if given_implementation:
3480
+ raise
3481
+ continue
3482
+ self._implementation_repr = ' (using NTL)'
3483
+ elif implementation == "GF2X":
3484
+ try:
3485
+ from .polynomial_gf2x import Polynomial_GF2X as element_class
3486
+ except ImportError:
3487
+ if given_implementation:
3488
+ raise
3489
+ continue
3490
+ self._implementation_repr = ' (using GF2X)'
3491
+ break
3492
+
3493
+ category = check_default_category(PrincipalIdealDomains(),
3494
+ category)
3495
+
3496
+ PolynomialRing_dense_mod_n.__init__(self, base_ring, name=name, implementation=implementation,
3497
+ element_class=element_class, category=category)
3498
+
3499
+ self._has_singular = can_convert_to_singular(self)
3500
+
3501
+ @staticmethod
3502
+ def _implementation_names_impl(implementation, base_ring, sparse):
3503
+ """
3504
+ TESTS::
3505
+
3506
+ sage: # needs sage.libs.ntl
3507
+ sage: PolynomialRing(GF(2), 'x', implementation='GF2X')
3508
+ Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)
3509
+ sage: PolynomialRing(GF(2), 'x', implementation='NTL')
3510
+ Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)
3511
+ sage: PolynomialRing(GF(2), 'x', implementation=None)
3512
+ Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)
3513
+ sage: PolynomialRing(GF(3), 'x', implementation='GF2X')
3514
+ Traceback (most recent call last):
3515
+ ...
3516
+ ValueError: GF2X only supports modulus 2
3517
+ sage: A = PolynomialRing(Zmod(2), 'x'); A
3518
+ Univariate Polynomial Ring in x over Ring of integers modulo 2 (using GF2X)
3519
+ sage: A in PrincipalIdealDomains()
3520
+ True
3521
+
3522
+ sage: PolynomialRing(GF(2), 'x', implementation="FLINT") # needs sage.libs.flint
3523
+ Univariate Polynomial Ring in x over Finite Field of size 2
3524
+ """
3525
+ if sparse:
3526
+ return NotImplemented
3527
+ modulus = base_ring.characteristic()
3528
+ if modulus == 2:
3529
+ defaults = ["GF2X", "NTL", None]
3530
+ elif implementation == "GF2X":
3531
+ raise ValueError("GF2X only supports modulus 2")
3532
+ elif modulus <= sys.maxsize:
3533
+ defaults = ["FLINT", None]
3534
+ elif implementation == "FLINT":
3535
+ raise ValueError("FLINT does not support modulus %s" % modulus)
3536
+ else:
3537
+ defaults = ["NTL", None]
3538
+ if implementation in defaults:
3539
+ return defaults
3540
+ elif implementation in ["NTL", "FLINT"]:
3541
+ return [implementation]
3542
+ return NotImplemented
3543
+
3544
+ def irreducible_element(self, n, algorithm=None):
3545
+ """
3546
+ Construct a monic irreducible polynomial of degree `n`.
3547
+
3548
+ INPUT:
3549
+
3550
+ - ``n`` -- integer; the degree of the polynomial to construct
3551
+
3552
+ - ``algorithm`` -- string (algorithm to use) or ``None``;
3553
+ currently available options are:
3554
+
3555
+ - ``'adleman-lenstra'``: a variant of the Adleman--Lenstra
3556
+ algorithm as implemented in PARI.
3557
+
3558
+ - ``'conway'``: look up the Conway polynomial of degree `n`
3559
+ over the field of `p` elements in the database; raise a
3560
+ :exc:`RuntimeError` if it is not found.
3561
+
3562
+ - ``'ffprimroot'``: use the :pari:`ffprimroot` function from
3563
+ PARI.
3564
+
3565
+ - ``'first_lexicographic'``: return the lexicographically
3566
+ smallest irreducible polynomial of degree `n`.
3567
+
3568
+ - ``'minimal_weight'``: return an irreducible polynomial of
3569
+ degree `n` with minimal number of non-zero coefficients.
3570
+ Only implemented for `p = 2`.
3571
+
3572
+ - ``'primitive'``: return a polynomial `f` such that a root of
3573
+ `f` generates the multiplicative group of the finite field
3574
+ extension defined by `f`. This uses the Conway polynomial if
3575
+ possible, otherwise it uses ``'ffprimroot'``.
3576
+
3577
+ - ``'random'``: try random polynomials until an irreducible
3578
+ one is found.
3579
+
3580
+ If ``algorithm`` is ``None``, use `x - 1` in degree 1. In
3581
+ degree > 1, the Conway polynomial is used if it is found in
3582
+ the database. Otherwise, the algorithm ``minimal_weight``
3583
+ is used if `p = 2`, and the algorithm ``'adleman-lenstra'`` if
3584
+ `p > 2`.
3585
+
3586
+ OUTPUT: a monic irreducible polynomial of degree `n` in ``self``
3587
+
3588
+ EXAMPLES::
3589
+
3590
+ sage: # needs sage.rings.finite_rings
3591
+ sage: GF(5)['x'].irreducible_element(2)
3592
+ x^2 + 4*x + 2
3593
+ sage: GF(5)['x'].irreducible_element(2, algorithm='adleman-lenstra')
3594
+ x^2 + x + 1
3595
+ sage: GF(5)['x'].irreducible_element(2, algorithm='primitive')
3596
+ x^2 + 4*x + 2
3597
+ sage: GF(5)['x'].irreducible_element(32, algorithm='first_lexicographic')
3598
+ x^32 + 2
3599
+ sage: GF(5)['x'].irreducible_element(32, algorithm='conway')
3600
+ Traceback (most recent call last):
3601
+ ...
3602
+ RuntimeError: requested Conway polynomial not in database.
3603
+ sage: GF(5)['x'].irreducible_element(32, algorithm='primitive')
3604
+ x^32 + ...
3605
+
3606
+ In characteristic 2::
3607
+
3608
+ sage: GF(2)['x'].irreducible_element(33) # needs sage.rings.finite_rings
3609
+ x^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1
3610
+ sage: GF(2)['x'].irreducible_element(33, algorithm='minimal_weight') # needs sage.libs.ntl sage.rings.finite_rings
3611
+ x^33 + x^10 + 1
3612
+
3613
+ In degree 1::
3614
+
3615
+ sage: GF(97)['x'].irreducible_element(1) # needs sage.rings.finite_rings
3616
+ x + 96
3617
+ sage: GF(97)['x'].irreducible_element(1, algorithm='conway') # needs sage.rings.finite_rings
3618
+ x + 92
3619
+ sage: GF(97)['x'].irreducible_element(1, algorithm='adleman-lenstra') # needs sage.rings.finite_rings
3620
+ x
3621
+
3622
+ AUTHORS:
3623
+
3624
+ - Peter Bruin (June 2013)
3625
+
3626
+ - Jeroen Demeyer (September 2014): add "ffprimroot" algorithm,
3627
+ see :issue:`8373`.
3628
+ """
3629
+ from sage.libs.pari import pari
3630
+ from sage.rings.finite_rings.conway_polynomials import (conway_polynomial,
3631
+ exists_conway_polynomial)
3632
+
3633
+ p = self.characteristic()
3634
+ n = int(n)
3635
+ if n < 1:
3636
+ raise ValueError("degree must be at least 1")
3637
+
3638
+ if algorithm is None:
3639
+ if n == 1:
3640
+ return self((-1,1)) # Polynomial x - 1
3641
+ elif exists_conway_polynomial(p, n):
3642
+ algorithm = "conway"
3643
+ elif p == 2:
3644
+ try:
3645
+ from .polynomial_gf2x import GF2X_BuildSparseIrred_list
3646
+ except ImportError:
3647
+ algorithm = "adleman-lenstra"
3648
+ else:
3649
+ algorithm = "minimal_weight"
3650
+ else:
3651
+ algorithm = "adleman-lenstra"
3652
+ elif algorithm == "primitive":
3653
+ if exists_conway_polynomial(p, n):
3654
+ algorithm = "conway"
3655
+ else:
3656
+ algorithm = "ffprimroot"
3657
+
3658
+ if algorithm == "adleman-lenstra":
3659
+ return self(pari(p).ffinit(n))
3660
+ elif algorithm == "conway":
3661
+ return self(conway_polynomial(p, n))
3662
+ elif algorithm == "first_lexicographic":
3663
+ if p == 2:
3664
+ try:
3665
+ from .polynomial_gf2x import GF2X_BuildIrred_list
3666
+ except ImportError:
3667
+ pass
3668
+ else:
3669
+ return self(GF2X_BuildIrred_list(n))
3670
+ else:
3671
+ # Fallback to PolynomialRing_dense_finite_field.irreducible_element
3672
+ pass
3673
+ elif algorithm == "ffprimroot":
3674
+ return self(pari(p).ffinit(n).ffgen().ffprimroot().charpoly())
3675
+ elif algorithm == "minimal_weight":
3676
+ if p == 2:
3677
+ from .polynomial_gf2x import GF2X_BuildSparseIrred_list
3678
+ return self(GF2X_BuildSparseIrred_list(n))
3679
+ else:
3680
+ raise NotImplementedError("'minimal_weight' option only implemented for p = 2")
3681
+ elif algorithm == "random":
3682
+ if p == 2:
3683
+ try:
3684
+ from .polynomial_gf2x import GF2X_BuildRandomIrred_list
3685
+ except ImportError:
3686
+ pass
3687
+ else:
3688
+ return self(GF2X_BuildRandomIrred_list(n))
3689
+ else:
3690
+ pass
3691
+
3692
+ # No suitable algorithm found, try algorithms from the base class.
3693
+ return PolynomialRing_dense_finite_field.irreducible_element(self, n, algorithm)
3694
+
3695
+ @cached_method
3696
+ def fraction_field(self):
3697
+ """
3698
+ Return the fraction field of ``self``.
3699
+
3700
+ EXAMPLES::
3701
+
3702
+ sage: R.<t> = GF(5)[]
3703
+ sage: R.fraction_field()
3704
+ Fraction Field of Univariate Polynomial Ring in t
3705
+ over Finite Field of size 5
3706
+ """
3707
+ try:
3708
+ from sage.rings.fraction_field_FpT import FpT
3709
+ from sage.rings.polynomial.polynomial_zmod_flint import Polynomial_zmod_flint
3710
+ except ImportError:
3711
+ pass
3712
+ else:
3713
+ p = self.base_ring().characteristic()
3714
+ if (issubclass(self.element_class, Polynomial_zmod_flint)
3715
+ and 2 < p < FpT.INTEGER_LIMIT):
3716
+ return FpT(self)
3717
+ return super().fraction_field()
3718
+
3719
+
3720
+ def polygen(ring_or_element, name='x'):
3721
+ """
3722
+ Return a polynomial indeterminate.
3723
+
3724
+ INPUT:
3725
+
3726
+ - ``polygen(base_ring, name='x')``
3727
+
3728
+ - ``polygen(ring_element, name='x')``
3729
+
3730
+ If the first input is a ring, return a polynomial generator over
3731
+ that ring. If it is a ring element, return a polynomial generator
3732
+ over the parent of the element.
3733
+
3734
+ EXAMPLES::
3735
+
3736
+ sage: z = polygen(QQ, 'z')
3737
+ sage: z^3 + z +1
3738
+ z^3 + z + 1
3739
+ sage: parent(z)
3740
+ Univariate Polynomial Ring in z over Rational Field
3741
+
3742
+ .. NOTE::
3743
+
3744
+ If you give a list or comma-separated string to :func:`polygen`, you'll
3745
+ get a tuple of indeterminates, exactly as if you called
3746
+ :func:`polygens`.
3747
+ """
3748
+ if isinstance(ring_or_element, RingElement):
3749
+ base_ring = ring_or_element.parent()
3750
+ elif ring_or_element in Rings():
3751
+ base_ring = ring_or_element
3752
+ else:
3753
+ raise TypeError("input must be a ring or ring element")
3754
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
3755
+
3756
+ t = PolynomialRing(base_ring, name)
3757
+ if t.ngens() > 1:
3758
+ return t.gens()
3759
+ return t.gen()
3760
+
3761
+
3762
+ def polygens(base_ring, names='x', *args):
3763
+ """
3764
+ Return indeterminates over the given base ring with the given
3765
+ names.
3766
+
3767
+ EXAMPLES::
3768
+
3769
+ sage: x,y,z = polygens(QQ,'x,y,z')
3770
+ sage: (x+y+z)^2
3771
+ x^2 + 2*x*y + y^2 + 2*x*z + 2*y*z + z^2
3772
+ sage: parent(x)
3773
+ Multivariate Polynomial Ring in x, y, z over Rational Field
3774
+ sage: t = polygens(QQ, ['x','yz','abc'])
3775
+ sage: t
3776
+ (x, yz, abc)
3777
+
3778
+ The number of generators can be passed as a third argument::
3779
+
3780
+ sage: polygens(QQ, 'x', 4)
3781
+ (x0, x1, x2, x3)
3782
+ """
3783
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
3784
+ return PolynomialRing(base_ring, names, *args).gens()