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,2570 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ """
3
+ Generic Multivariate Polynomials
4
+
5
+ AUTHORS:
6
+
7
+ - David Joyner: first version
8
+
9
+ - William Stein: use dict's instead of lists
10
+
11
+ - Martin Albrecht malb@informatik.uni-bremen.de: some functions added
12
+
13
+ - William Stein (2006-02-11): added better __div__ behavior.
14
+
15
+ - Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some
16
+ Singular features
17
+
18
+ - William Stein (2006-04-19): added e.g.,
19
+ ``f[1,3]`` to get coeff of `xy^3`; added examples of the new
20
+ ``R.x,y = PolynomialRing(QQ,2)`` notation.
21
+
22
+ - Martin Albrecht: improved singular coercions (restructured class
23
+ hierarchy) and added ETuples
24
+
25
+ - Robert Bradshaw (2007-08-14): added support for coercion of
26
+ polynomials in a subset of variables (including multi-level
27
+ univariate rings)
28
+
29
+ - Joel B. Mohler (2008-03): Refactored interactions with ETuples.
30
+
31
+ EXAMPLES:
32
+
33
+ We verify Lagrange's four squares identity::
34
+
35
+ sage: R.<a0,a1,a2,a3,b0,b1,b2,b3> = QQbar[] # needs sage.rings.number_field
36
+ sage: ((a0^2 + a1^2 + a2^2 + a3^2) * (b0^2 + b1^2 + b2^2 + b3^2) == # needs sage.rings.number_field
37
+ ....: (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2
38
+ ....: + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2)
39
+ True
40
+ """
41
+ # ****************************************************************************
42
+ #
43
+ # Sage: Open Source Mathematical Software
44
+ #
45
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
46
+ # 2022 Vincent Delecroix <20100.delecroix@gmail.com>
47
+ #
48
+ # Distributed under the terms of the GNU General Public License (GPL)
49
+ #
50
+ # This code is distributed in the hope that it will be useful,
51
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
52
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53
+ # General Public License for more details.
54
+ #
55
+ # The full text of the GPL is available at:
56
+ #
57
+ # https://www.gnu.org/licenses/
58
+ # ****************************************************************************
59
+
60
+ import operator
61
+
62
+ from sage.structure.element import CommutativeRingElement, coerce_binop, get_coercion_model, parent
63
+ from sage.misc.misc_c import prod
64
+ from sage.rings.integer import Integer
65
+ import sage.rings.integer_ring
66
+ from sage.rings.qqbar_decorators import handle_AA_and_QQbar
67
+ from . import polydict
68
+ from sage.structure.factorization import Factorization
69
+ from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr
70
+ from sage.structure.sequence import Sequence
71
+ from .multi_polynomial import MPolynomial, is_MPolynomial
72
+ from sage.misc.lazy_attribute import lazy_attribute
73
+ from sage.misc.superseded import deprecated_function_alias
74
+ from sage.rings.rational_field import QQ
75
+ from sage.rings.fraction_field import FractionField
76
+
77
+
78
+ class MPolynomial_element(MPolynomial):
79
+ r"""
80
+ Generic multivariate polynomial.
81
+
82
+ This implementation is based on the :class:`~sage.rings.polynomial.polydict.PolyDict`.
83
+
84
+ .. TODO::
85
+
86
+ As mentioned in their docstring,
87
+ :class:`~sage.rings.polynomial.polydict.PolyDict` objects never clear
88
+ zeros. In all arithmetic operations on :class:`MPolynomial_element`
89
+ there is an additional call to the method ``remove_zeros`` to clear
90
+ them. This is not ideal because of the presence of inexact zeros, see
91
+ :issue:`35174`.
92
+ """
93
+ def __init__(self, parent, x):
94
+ """
95
+ EXAMPLES::
96
+
97
+ sage: # needs sage.rings.number_field
98
+ sage: x = polygen(ZZ, 'x')
99
+ sage: K.<cuberoot2> = NumberField(x^3 - 2)
100
+ sage: L.<cuberoot3> = K.extension(x^3 - 3)
101
+ sage: S.<sqrt2> = L.extension(x^2 - 2)
102
+ sage: S
103
+ Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
104
+ sage: P.<x,y,z> = PolynomialRing(S) # indirect doctest
105
+ """
106
+ CommutativeRingElement.__init__(self, parent)
107
+ self.__element = x
108
+
109
+ def _repr_(self):
110
+ """
111
+ EXAMPLES::
112
+
113
+ sage: P.<x,y,z> = PolynomialRing(QQbar) # needs sage.rings.number_field
114
+ sage: x + QQbar(sqrt(2) - 1/2*I) # indirect doctest # needs sage.rings.number_field sage.symbolic
115
+ x + 1.414213562373095? - 0.50000000000000000?*I
116
+ """
117
+ return "%s" % self.__element
118
+
119
+ ####################
120
+
121
+ def __call__(self, *x, **kwds):
122
+ r"""
123
+ Evaluate this multi-variate polynomial at `x`, where
124
+ `x` is either the tuple of values to substitute in, or one
125
+ can use functional notation `f(a_0,a_1,a_2, \ldots)` to
126
+ evaluate `f` with the `i`-th variable replaced by `a_i`.
127
+
128
+ EXAMPLES::
129
+
130
+ sage: # needs sage.rings.real_mpfr
131
+ sage: R.<x,y> = CC[]
132
+ sage: f = x^2 + y^2
133
+ sage: f(1,2)
134
+ 5.00000000000000
135
+ sage: f((1,2))
136
+ 5.00000000000000
137
+
138
+ ::
139
+
140
+ sage: # needs sage.rings.real_mpfr
141
+ sage: x = PolynomialRing(CC, 3, 'x').gens()
142
+ sage: f = x[0] + x[1] - 2*x[1]*x[2]; f
143
+ (-2.00000000000000)*x1*x2 + x0 + x1
144
+ sage: f(1,2,0)
145
+ 3.00000000000000
146
+ sage: f(1,2,5)
147
+ -17.0000000000000
148
+
149
+ TESTS:
150
+
151
+ Check :issue:`27446`::
152
+
153
+ sage: P = PolynomialRing(QQ, 't', 0)
154
+ sage: a = P(1)
155
+ sage: a(()).parent()
156
+ Rational Field
157
+
158
+ AUTHORS:
159
+
160
+ - David Kohel (2005-09-27)
161
+ """
162
+ if len(kwds) > 0:
163
+ f = self.subs(**kwds)
164
+ if len(x) > 0:
165
+ return f(*x)
166
+ else:
167
+ return f
168
+ if len(x) == 1 and isinstance(x[0], (list, tuple)):
169
+ x = x[0]
170
+ n = self.parent().ngens()
171
+ if len(x) != n:
172
+ raise TypeError("x must be of correct length")
173
+ if n == 0:
174
+ return self.constant_coefficient()
175
+ try:
176
+ K = x[0].parent()
177
+ except AttributeError:
178
+ K = self.parent().base_ring()
179
+ try:
180
+ y = K.zero()
181
+ one = K.one()
182
+ except (AttributeError, RuntimeError):
183
+ y = K(0)
184
+ one = K(1)
185
+ for m, c in self.element().dict().items():
186
+ y += c * prod((v ** e for v, e in zip(x, m) if e), one)
187
+ return y
188
+
189
+ def _richcmp_(self, right, op):
190
+ """
191
+ Compare ``self`` to ``right`` with respect to the term order of
192
+ self.parent().
193
+
194
+ EXAMPLES::
195
+
196
+ sage: R.<x,y,z> = PolynomialRing(QQbar, 3, order='lex') # needs sage.rings.number_field
197
+ sage: x^1*y^2 > y^3*z^4 # needs sage.rings.number_field
198
+ True
199
+ sage: x^3*y^2*z^4 < x^3*y^2*z^1 # needs sage.rings.number_field
200
+ False
201
+
202
+ ::
203
+
204
+ sage: R.<x,y,z> = PolynomialRing(CC, 3, order='deglex') # needs sage.rings.real_mpfr
205
+ sage: x^1*y^2*z^3 > x^3*y^2*z^0 # needs sage.rings.real_mpfr
206
+ True
207
+ sage: x^1*y^2*z^4 < x^1*y^1*z^5 # needs sage.rings.real_mpfr
208
+ False
209
+
210
+ ::
211
+
212
+ sage: R.<x,y,z> = PolynomialRing(QQbar, 3, order='degrevlex') # needs sage.rings.number_field
213
+ sage: x^1*y^5*z^2 > x^4*y^1*z^3 # needs sage.rings.number_field
214
+ True
215
+ sage: x^4*y^7*z^1 < x^4*y^2*z^3 # needs sage.rings.number_field
216
+ False
217
+ """
218
+ return self.__element.rich_compare(right.__element, op,
219
+ self.parent().term_order().sortkey)
220
+
221
+ def _im_gens_(self, codomain, im_gens, base_map=None):
222
+ """
223
+ EXAMPLES::
224
+
225
+ sage: R.<x,y> = PolynomialRing(QQbar, 2) # needs sage.rings.number_field
226
+ sage: f = R.hom([y, x], R) # needs sage.rings.number_field
227
+ sage: f(x^2 + 3*y^5) # indirect doctest # needs sage.rings.number_field
228
+ 3*x^5 + y^2
229
+
230
+ You can specify a map on the base ring::
231
+
232
+ sage: # needs sage.libs.singular
233
+ sage: F.<x,y> = ZZ[]
234
+ sage: F = F.fraction_field(); x,y = F(x),F(y)
235
+ sage: cc = F.hom([y,x])
236
+ sage: R.<z,w> = F[]
237
+ sage: phi = R.hom([w,z], base_map=cc)
238
+ sage: phi(w/x)
239
+ 1/y*z
240
+ """
241
+ n = self.parent().ngens()
242
+ if n == 0:
243
+ return codomain.coerce(self)
244
+ y = codomain(0)
245
+ if base_map is None:
246
+ # Just use conversion
247
+ base_map = codomain
248
+ for (m,c) in self.element().dict().items():
249
+ y += base_map(c)*prod([ im_gens[i]**m[i] for i in range(n) if m[i] ])
250
+ return y
251
+
252
+ def number_of_terms(self):
253
+ """
254
+ Return the number of nonzero coefficients of this polynomial.
255
+
256
+ This is also called weight, :meth:`hamming_weight` or sparsity.
257
+
258
+ EXAMPLES::
259
+
260
+ sage: # needs sage.rings.real_mpfr
261
+ sage: R.<x, y> = CC[]
262
+ sage: f = x^3 - y
263
+ sage: f.number_of_terms()
264
+ 2
265
+ sage: R(0).number_of_terms()
266
+ 0
267
+ sage: f = (x+y)^100
268
+ sage: f.number_of_terms()
269
+ 101
270
+
271
+ The method :meth:`hamming_weight` is an alias::
272
+
273
+ sage: f.hamming_weight() # needs sage.rings.real_mpfr
274
+ 101
275
+ """
276
+ return len(self.element().dict())
277
+
278
+ hamming_weight = number_of_terms
279
+
280
+ def __neg__(self):
281
+ """
282
+ Return the negative of ``self``.
283
+
284
+ EXAMPLES::
285
+
286
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
287
+ sage: -x # needs sage.rings.number_field
288
+ -x
289
+ sage: -(y-1) # needs sage.rings.number_field
290
+ -y + 1
291
+ """
292
+ return self.__class__(self.parent(), -self.__element)
293
+
294
+ def _add_(self, right):
295
+ """
296
+ Return the sum of ``self`` and ``right``.
297
+
298
+ EXAMPLES::
299
+
300
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
301
+ sage: x + y # needs sage.rings.number_field
302
+ x + y
303
+ """
304
+ elt = self.__element + right.__element
305
+ elt.remove_zeros()
306
+ return self.__class__(self.parent(), elt)
307
+
308
+ def _sub_(self, right):
309
+ """
310
+ Return the difference between ``self`` and ``right``.
311
+
312
+ EXAMPLES::
313
+
314
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
315
+ sage: x - y # needs sage.rings.number_field
316
+ x - y
317
+ """
318
+ elt = self.__element - right.__element
319
+ elt.remove_zeros()
320
+ return self.__class__(self.parent(), elt)
321
+
322
+ def _mul_(self, right):
323
+ """
324
+ Return the product between ``self`` and ``right``.
325
+
326
+ EXAMPLES::
327
+
328
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
329
+ sage: x * y # needs sage.rings.number_field
330
+ x*y
331
+ """
332
+ elt = self.__element * right.__element
333
+ elt.remove_zeros()
334
+ return self.__class__(self.parent(), elt)
335
+
336
+ def _lmul_(self, a):
337
+ """
338
+ Left Scalar Multiplication.
339
+
340
+ EXAMPLES:
341
+
342
+ Note that it is not really possible to do a meaningful
343
+ example since sage mpoly rings refuse to have non-commutative
344
+ bases.
345
+
346
+ ::
347
+
348
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
349
+ sage: f = (x + y) # needs sage.rings.number_field
350
+ sage: 3 * f # needs sage.rings.number_field
351
+ 3*x + 3*y
352
+ """
353
+ elt = self.__element.scalar_lmult(a)
354
+ elt.remove_zeros()
355
+ return self.__class__(self.parent(), elt)
356
+
357
+ def _rmul_(self, a):
358
+ """
359
+ Right Scalar Multiplication.
360
+
361
+ EXAMPLES:
362
+
363
+ Note that it is not really possible to do a meaningful
364
+ example since sage mpoly rings refuse to have non-commutative
365
+ bases.
366
+
367
+ ::
368
+
369
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
370
+ sage: f = (x + y) # needs sage.rings.number_field
371
+ sage: f * 3 # needs sage.rings.number_field
372
+ 3*x + 3*y
373
+ """
374
+ elt = self.__element.scalar_rmult(a)
375
+ elt.remove_zeros()
376
+ return self.__class__(self.parent(), elt)
377
+
378
+ def _div_(self, right):
379
+ r"""
380
+ EXAMPLES::
381
+
382
+ sage: R.<x,y> = CC['x,y'] # needs sage.rings.real_mpfr
383
+ sage: f = (x + y)/x; f # needs sage.rings.real_mpfr
384
+ (x + y)/x
385
+ sage: f.parent() # needs sage.rings.real_mpfr
386
+ Fraction Field of Multivariate Polynomial Ring in x, y over
387
+ Complex Field with 53 bits of precision
388
+
389
+ If dividing by a scalar, there is no need to go to the fraction
390
+ field of the polynomial ring::
391
+
392
+ sage: f = (x + y)/2; f # needs sage.rings.real_mpfr
393
+ 0.500000000000000*x + 0.500000000000000*y
394
+ sage: f.parent() # needs sage.rings.real_mpfr
395
+ Multivariate Polynomial Ring in x, y over Complex Field with
396
+ 53 bits of precision
397
+
398
+ TESTS:
399
+
400
+ Ensure that :issue:`13704` is fixed.::
401
+
402
+ sage: R.<t> = PolynomialRing(QQ)
403
+ sage: S.<x,y> = PolynomialRing(R)
404
+ sage: x/S(2)
405
+ 1/2*x
406
+ """
407
+ if right.is_constant():
408
+ inv = self.base_ring().one() / right.constant_coefficient()
409
+ return inv * self
410
+ return self.parent().fraction_field()(self, right, coerce=False)
411
+
412
+ def __rpow__(self, n):
413
+ if not isinstance(n, (int, Integer)):
414
+ raise TypeError("The exponent must be an integer.")
415
+ return self.parent()(self.__element**n)
416
+
417
+ def element(self):
418
+ return self.__element
419
+
420
+
421
+ class MPolynomial_polydict(Polynomial_singular_repr, MPolynomial_element):
422
+ r"""
423
+ Multivariate polynomials implemented in pure python using
424
+ polydicts.
425
+ """
426
+ def __init__(self, parent, x):
427
+ """
428
+ EXAMPLES::
429
+
430
+ sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() # needs sage.rings.number_field
431
+ sage: x # needs sage.rings.number_field
432
+ (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9)
433
+ sage: loads(dumps(x)) == x # needs sage.rings.number_field
434
+ True
435
+ """
436
+ if not isinstance(x, polydict.PolyDict):
437
+ x = polydict.PolyDict(x)
438
+ x.remove_zeros()
439
+ MPolynomial_element.__init__(self, parent, x)
440
+
441
+ def _new_constant_poly(self, x, P):
442
+ """
443
+ Quickly create a new constant polynomial with value x in parent P.
444
+
445
+ ASSUMPTION:
446
+
447
+ x must be an element of the base ring of P. That assumption is
448
+ not verified.
449
+
450
+ EXAMPLES::
451
+
452
+ sage: R.<x,y> = QQ['t'][]
453
+ sage: x._new_constant_poly(R.base_ring()(2),R)
454
+ 2
455
+ """
456
+ return MPolynomial_polydict(P, {P._zero_tuple:x})
457
+
458
+ def _repr_(self):
459
+ """
460
+ EXAMPLES::
461
+
462
+ sage: # needs sage.rings.number_field
463
+ sage: R.<x,y> = QQbar[]
464
+ sage: repr(-x^2 - y + 1) # indirect doctest
465
+ '-x^2 - y + 1'
466
+ sage: K.<I> = QuadraticField(-1)
467
+ sage: R.<x,y> = K[]
468
+ sage: repr(-I*y - x^2) # indirect doctest
469
+ '-x^2 + (-I)*y'
470
+ """
471
+ if self.is_gen():
472
+ return self.parent().variable_names()[self.degrees().nonzero_positions()[0]]
473
+ try:
474
+ key = self.parent().term_order().sortkey
475
+ except AttributeError:
476
+ key = None
477
+ atomic = self.parent().base_ring()._repr_option('element_is_atomic')
478
+ return self.element().poly_repr(self.parent().variable_names(),
479
+ atomic_coefficients=atomic,
480
+ sortkey=key)
481
+
482
+ def _latex_(self):
483
+ r"""
484
+ EXAMPLES::
485
+
486
+ sage: # needs sage.rings.number_field
487
+ sage: R.<x,y> = QQbar[]
488
+ sage: latex(-x^2 - y + 1)
489
+ -x^{2} - y + 1
490
+ sage: K.<I> = QuadraticField(-1)
491
+ sage: R.<x,y> = K[]
492
+ sage: latex(-I*y + I*x^2)
493
+ \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) y
494
+ """
495
+ try:
496
+ key = self.parent().term_order().sortkey
497
+ except AttributeError:
498
+ key = None
499
+ atomic = self.parent().base_ring()._repr_option('element_is_atomic')
500
+ return self.element().latex(self.parent().latex_variable_names(),
501
+ atomic_coefficients=atomic, sortkey=key)
502
+
503
+ def _repr_with_changed_varnames(self, varnames):
504
+ """
505
+ EXAMPLES::
506
+
507
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
508
+ sage: f = -x^2 - y + 1 # needs sage.rings.number_field
509
+ sage: f._repr_with_changed_varnames(['jack', 'jill']) # needs sage.rings.number_field
510
+ '-jack^2 - jill + 1'
511
+ """
512
+ try:
513
+ key = self.parent().term_order().sortkey
514
+ except AttributeError:
515
+ key = None
516
+ atomic = self.parent().base_ring()._repr_option('element_is_atomic')
517
+ return self.element().poly_repr(varnames,
518
+ atomic_coefficients=atomic, sortkey=key)
519
+
520
+ def _macaulay2_(self, macaulay2=None):
521
+ """
522
+ EXAMPLES::
523
+
524
+ sage: R = GF(13)['a,b']['c,d']
525
+ sage: macaulay2(R('a^2 + c')) # optional - macaulay2
526
+ 2
527
+ c + a
528
+
529
+ TESTS:
530
+
531
+ Elements of the base ring are coerced to the polynomial ring
532
+ correctly::
533
+
534
+ sage: macaulay2(R('a^2')).ring()._operator('===', R) # optional - macaulay2
535
+ true
536
+ """
537
+ if macaulay2 is None:
538
+ from sage.interfaces.macaulay2 import macaulay2 as m2_default
539
+ macaulay2 = m2_default
540
+ m2_parent = macaulay2(self.parent())
541
+ macaulay2.use(m2_parent)
542
+ return macaulay2('substitute(%s,%s)' % (repr(self), m2_parent._name))
543
+
544
+ def degrees(self):
545
+ r"""
546
+ Return a tuple (precisely - an ``ETuple``) with the
547
+ degree of each variable in this polynomial. The list of degrees is,
548
+ of course, ordered by the order of the generators.
549
+
550
+ EXAMPLES::
551
+
552
+ sage: # needs sage.rings.number_field
553
+ sage: R.<x,y,z> = PolynomialRing(QQbar)
554
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
555
+ sage: f.degrees()
556
+ (2, 2, 0)
557
+ sage: f = x^2 + z^2
558
+ sage: f.degrees()
559
+ (2, 0, 2)
560
+ sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees
561
+ 2
562
+ sage: R.<x,y,z,u> = PolynomialRing(QQbar)
563
+ sage: f = (1-x) * (1+y+z+x^3)^5
564
+ sage: f.degrees()
565
+ (16, 5, 5, 0)
566
+ sage: R(0).degrees()
567
+ (0, 0, 0, 0)
568
+ """
569
+ if not self:
570
+ return polydict.ETuple({}, self.parent().ngens())
571
+ else:
572
+ return self._MPolynomial_element__element.max_exp()
573
+
574
+ def degree(self, x=None, std_grading=False):
575
+ """
576
+ Return the degree of ``self`` in ``x``, where ``x`` must be one of the
577
+ generators for the parent of ``self``.
578
+
579
+ INPUT:
580
+
581
+ - ``x`` -- multivariate polynomial (a generator of the parent
582
+ of ``self``). If ``x`` is not specified (or is None), return
583
+ the total degree, which is the maximum degree of any
584
+ monomial. Note that a weighted term ordering alters the
585
+ grading of the generators of the ring; see the tests below.
586
+ To avoid this behavior, set the optional argument ``std_grading=True``.
587
+
588
+ OUTPUT: integer
589
+
590
+ EXAMPLES::
591
+
592
+ sage: R.<x,y> = RR[]
593
+ sage: f = y^2 - x^9 - x
594
+ sage: f.degree(x)
595
+ 9
596
+ sage: f.degree(y)
597
+ 2
598
+ sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x)
599
+ 3
600
+ sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y)
601
+ 10
602
+
603
+ Note that total degree takes into account if we are working in a polynomial
604
+ ring with a weighted term order.
605
+
606
+ ::
607
+
608
+ sage: R = PolynomialRing(QQ, 'x,y', order=TermOrder('wdeglex',(2,3)))
609
+ sage: x,y = R.gens()
610
+ sage: x.degree()
611
+ 2
612
+ sage: y.degree()
613
+ 3
614
+ sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y)
615
+ (0, 1, 0, 1)
616
+ sage: f = x^2*y + x*y^2
617
+ sage: f.degree(x)
618
+ 2
619
+ sage: f.degree(y)
620
+ 2
621
+ sage: f.degree()
622
+ 8
623
+ sage: f.degree(std_grading=True)
624
+ 3
625
+
626
+ Note that if ``x`` is not a generator of the parent of ``self``,
627
+ for example if it is a generator of a polynomial algebra which
628
+ maps naturally to this one, then it is converted to an element
629
+ of this algebra. (This fixes the problem reported in
630
+ :issue:`17366`.)
631
+
632
+ ::
633
+
634
+ sage: x, y = ZZ['x','y'].gens()
635
+ sage: GF(3037000453)['x','y'].gen(0).degree(x) # needs sage.rings.finite_rings
636
+ 1
637
+
638
+ sage: x0, y0 = QQ['x','y'].gens()
639
+ sage: GF(3037000453)['x','y'].gen(0).degree(x0) # needs sage.rings.finite_rings
640
+ Traceback (most recent call last):
641
+ ...
642
+ TypeError: argument is not coercible to the parent
643
+
644
+ sage: GF(3037000453)['x','y'].gen(0).degree(x^2) # needs sage.rings.finite_rings
645
+ Traceback (most recent call last):
646
+ ...
647
+ TypeError: argument is not a generator
648
+
649
+ TESTS::
650
+
651
+ sage: R = PolynomialRing(GF(2)['t'], 'x,y',
652
+ ....: order=TermOrder('wdeglex', (2,3)))
653
+ sage: x, y = R.gens()
654
+ sage: x.degree()
655
+ 2
656
+ sage: y.degree()
657
+ 3
658
+ sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y)
659
+ (0, 1, 0, 1)
660
+ sage: f = (x^2*y + x*y^2)
661
+ sage: f.degree(x)
662
+ 2
663
+ sage: f.degree(y)
664
+ 2
665
+ sage: f.degree()
666
+ 8
667
+ sage: f.degree(std_grading=True)
668
+ 3
669
+ sage: R(0).degree()
670
+ -1
671
+
672
+ Degree of zero polynomial for other implementation :issue:`20048` ::
673
+
674
+ sage: R.<x,y> = GF(3037000453)[] # needs sage.rings.finite_rings
675
+ sage: R.zero().degree(x)
676
+ -1
677
+
678
+ Ensure that :issue:`37603` is fixed::
679
+
680
+ sage: # needs sage.rings.number_field
681
+ sage: R.<x,y,z> = PolynomialRing(QQbar)
682
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
683
+ sage: type(f.degree())
684
+ <class 'sage.rings.integer.Integer'>
685
+ sage: type(f.degree(x))
686
+ <class 'sage.rings.integer.Integer'>
687
+ sage: type(f.degree(x)) == type(f.degree(y)) == type(f.degree(z))
688
+ True
689
+ """
690
+ if x is None:
691
+ if std_grading or not self.parent().term_order().is_weighted_degree_order():
692
+ return Integer(self.element().degree(None))
693
+ return self.weighted_degree(self.parent().term_order().weights())
694
+ if isinstance(x, MPolynomial):
695
+ if x.parent() is not self.parent():
696
+ try:
697
+ x = self.parent().coerce(x)
698
+ except TypeError:
699
+ raise TypeError("x must canonically coerce to parent")
700
+ if not x.is_gen():
701
+ raise TypeError("x must be one of the generators of the parent")
702
+ else:
703
+ raise TypeError("x must be one of the generators of the parent")
704
+ return Integer(self.element().degree(x.element()))
705
+
706
+ def total_degree(self):
707
+ """
708
+ Return the total degree of ``self``, which is the maximum degree of any
709
+ monomial in ``self``.
710
+
711
+ EXAMPLES::
712
+
713
+ sage: # needs sage.rings.number_field
714
+ sage: R.<x,y,z> = QQbar[]
715
+ sage: f = 2*x*y^3*z^2
716
+ sage: f.total_degree()
717
+ 6
718
+ sage: f = 4*x^2*y^2*z^3
719
+ sage: f.total_degree()
720
+ 7
721
+ sage: f = 99*x^6*y^3*z^9
722
+ sage: f.total_degree()
723
+ 18
724
+ sage: f = x*y^3*z^6 + 3*x^2
725
+ sage: f.total_degree()
726
+ 10
727
+ sage: f = z^3 + 8*x^4*y^5*z
728
+ sage: f.total_degree()
729
+ 10
730
+ sage: f = z^9 + 10*x^4 + y^8*x^2
731
+ sage: f.total_degree()
732
+ 10
733
+
734
+ TESTS:
735
+
736
+ Ensure that :issue:`37603` is fixed::
737
+
738
+ sage: # needs sage.rings.number_field
739
+ sage: R.<x,y,z> = QQbar[]
740
+ sage: f = 2*x*y^3*z^2
741
+ sage: f.total_degree()
742
+ 6
743
+ sage: type(f.total_degree())
744
+ <class 'sage.rings.integer.Integer'>
745
+ """
746
+ return self.degree()
747
+
748
+ def monomial_coefficient(self, mon):
749
+ """
750
+ Return the coefficient in the base ring of the monomial ``mon`` in
751
+ ``self``, where ``mon`` must have the same parent as ``self``.
752
+
753
+ This function contrasts with the function
754
+ ``coefficient`` which returns the coefficient of a
755
+ monomial viewing this polynomial in a polynomial ring over a base
756
+ ring having fewer variables.
757
+
758
+ INPUT:
759
+
760
+ - ``mon`` -- a monomial
761
+
762
+ OUTPUT: coefficient in base ring
763
+
764
+ .. SEEALSO::
765
+
766
+ For coefficients in a base ring of fewer variables, look
767
+ at :meth:`coefficient`.
768
+
769
+ EXAMPLES:
770
+
771
+ ::
772
+
773
+ sage: # needs sage.rings.number_field
774
+ sage: R.<x,y> = QQbar[]
775
+ sage: f = 2 * x * y
776
+ sage: c = f.monomial_coefficient(x*y); c
777
+ 2
778
+ sage: c.parent()
779
+ Algebraic Field
780
+
781
+ ::
782
+
783
+ sage: # needs sage.rings.number_field
784
+ sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y
785
+ sage: f.monomial_coefficient(y^2)
786
+ 1
787
+ sage: f.monomial_coefficient(x*y)
788
+ 5
789
+ sage: f.monomial_coefficient(x^9)
790
+ -1
791
+ sage: f.monomial_coefficient(x^10)
792
+ 0
793
+
794
+ ::
795
+
796
+ sage: # needs sage.rings.number_field
797
+ sage: a = polygen(ZZ, 'a')
798
+ sage: K.<a> = NumberField(a^2 + a + 1)
799
+ sage: P.<x,y> = K[]
800
+ sage: f = (a*x - 1) * ((a+1)*y - 1); f
801
+ -x*y + (-a)*x + (-a - 1)*y + 1
802
+ sage: f.monomial_coefficient(x)
803
+ -a
804
+ """
805
+ if parent(mon) is not self.parent():
806
+ raise TypeError("mon must be a monomial in the parent of self")
807
+ exp = polydict.monomial_exponent(mon.element())
808
+ zero = self.parent().base_ring().zero()
809
+ return self.element().get(exp, zero)
810
+
811
+ def monomial_coefficients(self, copy=None):
812
+ """
813
+ Return underlying dictionary with keys the exponents and values
814
+ the coefficients of this polynomial.
815
+
816
+ EXAMPLES::
817
+
818
+ sage: # needs sage.rings.number_field
819
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='lex')
820
+ sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3)
821
+ sage: f.monomial_coefficients()
822
+ {(1, 5, 2): 1, (2, 0, 1): 1, (4, 1, 3): 1}
823
+
824
+ ``dict`` is an alias::
825
+
826
+ sage: f.dict() # needs sage.rings.number_field
827
+ {(1, 5, 2): 1, (2, 0, 1): 1, (4, 1, 3): 1}
828
+ """
829
+ return self.element().dict()
830
+
831
+ dict = monomial_coefficients
832
+
833
+ def __iter__(self):
834
+ """
835
+ Iterate over ``self`` respecting the term order.
836
+
837
+ EXAMPLES::
838
+
839
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='lex') # needs sage.rings.number_field
840
+ sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field
841
+ sage: list(f) # needs sage.rings.number_field
842
+ [(1, x^4*y*z^3), (1, x^2*z), (1, x*y^5*z^2)]
843
+
844
+ ::
845
+
846
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='deglex') # needs sage.rings.number_field
847
+ sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field
848
+ sage: list(f) # needs sage.rings.number_field
849
+ [(1, x^4*y*z^3), (1, x*y^5*z^2), (1, x^2*z)]
850
+
851
+ ::
852
+
853
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='degrevlex') # needs sage.rings.number_field
854
+ sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field
855
+ sage: list(f) # needs sage.rings.number_field
856
+ [(1, x*y^5*z^2), (1, x^4*y*z^3), (1, x^2*z)]
857
+
858
+ ::
859
+
860
+ sage: R = ZZ['t']
861
+ sage: P.<x,y,z> = PolynomialRing(R,3)
862
+ sage: f = 3*x^3*y + 16*x + 7
863
+ sage: [(c,m) for c,m in f]
864
+ [(3, x^3*y), (16, x), (7, 1)]
865
+ sage: f = P.random_element(10,10)
866
+ sage: sum(c*m for c,m in f) == f
867
+ True
868
+ """
869
+ elt = self.element()
870
+ ring = self.parent()
871
+ one = ring.base_ring().one()
872
+ for exp in self._exponents:
873
+ yield (elt[exp], MPolynomial_polydict(ring, polydict.PolyDict({exp: one}, check=False)))
874
+
875
+ def __getitem__(self, x):
876
+ """
877
+ Return the coefficient corresponding to ``x``.
878
+
879
+ INPUT:
880
+
881
+ - ``x`` -- tuple or, in case of a single-variable
882
+ MPolynomial ring, ``x`` can also be an integer
883
+
884
+ EXAMPLES::
885
+
886
+ sage: # needs sage.rings.number_field
887
+ sage: R.<x, y> = PolynomialRing(QQbar, 2)
888
+ sage: f = -10*x^3*y + 17*x*y
889
+ sage: f[3,1]
890
+ -10
891
+ sage: f[1,1]
892
+ 17
893
+ sage: f[0,1]
894
+ 0
895
+
896
+ ::
897
+
898
+ sage: R.<x> = PolynomialRing(QQbar, 1); R # needs sage.rings.number_field
899
+ Multivariate Polynomial Ring in x over Algebraic Field
900
+ sage: f = 5*x^2 + 3; f # needs sage.rings.number_field
901
+ 5*x^2 + 3
902
+ sage: f[2] # needs sage.rings.number_field
903
+ 5
904
+ """
905
+ if isinstance(x, MPolynomial):
906
+ return self.monomial_coefficient(x)
907
+ if not isinstance(x, tuple):
908
+ try:
909
+ x = tuple(x)
910
+ except TypeError:
911
+ x = (x, )
912
+ try:
913
+ return self.element()[x]
914
+ except KeyError:
915
+ return self.parent().base_ring().zero()
916
+
917
+ def iterator_exp_coeff(self, as_ETuples=True):
918
+ """
919
+ Iterate over ``self`` as pairs of ((E)Tuple, coefficient).
920
+
921
+ INPUT:
922
+
923
+ - ``as_ETuples`` -- boolean (default: ``True``); if ``True`` iterate
924
+ over pairs whose first element is an ETuple, otherwise as a tuples
925
+
926
+ EXAMPLES::
927
+
928
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='lex') # needs sage.rings.number_field
929
+ sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field
930
+ sage: list(f.iterator_exp_coeff()) # needs sage.rings.number_field
931
+ [((4, 1, 3), 1), ((2, 0, 1), 1), ((1, 5, 2), 1)]
932
+
933
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='deglex') # needs sage.rings.number_field
934
+ sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field
935
+ sage: list(f.iterator_exp_coeff(as_ETuples=False)) # needs sage.rings.number_field
936
+ [((4, 1, 3), 1), ((1, 5, 2), 1), ((2, 0, 1), 1)]
937
+ """
938
+ elt = self.element()
939
+ if as_ETuples:
940
+ for exp in self._exponents:
941
+ yield (exp, elt[exp])
942
+ else:
943
+ for exp in self._exponents:
944
+ yield (tuple(exp), elt[exp])
945
+
946
+ def coefficient(self, degrees):
947
+ """
948
+ Return the coefficient of the variables with the degrees specified
949
+ in the python dictionary ``degrees``. Mathematically,
950
+ this is the coefficient in the base ring adjoined by the variables
951
+ of this ring not listed in ``degrees``. However, the
952
+ result has the same parent as this polynomial.
953
+
954
+ This function contrasts with the function
955
+ ``monomial_coefficient`` which returns the coefficient
956
+ in the base ring of a monomial.
957
+
958
+ INPUT:
959
+
960
+ - ``degrees`` -- can be any of:
961
+
962
+ - a dictionary of degree restrictions
963
+
964
+ - a list of degree restrictions (with ``None`` in
965
+ the unrestricted variables)
966
+
967
+ - a monomial (very fast, but not as flexible)
968
+
969
+ OUTPUT: element of the parent of ``self``
970
+
971
+ .. SEEALSO::
972
+
973
+ For coefficients of specific monomials, look at
974
+ :meth:`monomial_coefficient`.
975
+
976
+ EXAMPLES::
977
+
978
+ sage: # needs sage.rings.number_field
979
+ sage: R.<x, y> = QQbar[]
980
+ sage: f = 2 * x * y
981
+ sage: c = f.coefficient({x: 1, y: 1}); c
982
+ 2
983
+ sage: c.parent()
984
+ Multivariate Polynomial Ring in x, y over Algebraic Field
985
+ sage: c in PolynomialRing(QQbar, 2, names=['x', 'y'])
986
+ True
987
+ sage: f = y^2 - x^9 - 7*x + 5*x*y
988
+ sage: f.coefficient({y: 1})
989
+ 5*x
990
+ sage: f.coefficient({y: 0})
991
+ -x^9 + (-7)*x
992
+ sage: f.coefficient({x: 0, y: 0})
993
+ 0
994
+ sage: f = (1+y+y^2) * (1+x+x^2)
995
+ sage: f.coefficient({x: 0})
996
+ y^2 + y + 1
997
+ sage: f.coefficient([0, None])
998
+ y^2 + y + 1
999
+ sage: f.coefficient(x)
1000
+ y^2 + y + 1
1001
+ sage: # Be aware that this may not be what you think!
1002
+ sage: # The physical appearance of the variable x is deceiving -- particularly if the exponent would be a variable.
1003
+ sage: f.coefficient(x^0) # outputs the full polynomial
1004
+ x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1
1005
+
1006
+ ::
1007
+
1008
+ sage: # needs sage.rings.real_mpfr
1009
+ sage: R.<x,y> = RR[]
1010
+ sage: f = x*y + 5
1011
+ sage: c = f.coefficient({x: 0, y: 0}); c
1012
+ 5.00000000000000
1013
+ sage: parent(c)
1014
+ Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision
1015
+
1016
+ AUTHORS:
1017
+
1018
+ - Joel B. Mohler (2007-10-31)
1019
+ """
1020
+ looking_for = None
1021
+ if isinstance(degrees, MPolynomial) and degrees.parent() == self.parent() and degrees.is_monomial():
1022
+ looking_for = [e if e > 0 else None for e in degrees._exponents[0]]
1023
+ elif isinstance(degrees, list):
1024
+ looking_for = degrees
1025
+ elif isinstance(degrees, dict):
1026
+ poly_vars = self.parent().gens()
1027
+ looking_for = [None] * len(poly_vars)
1028
+ for d, exp in degrees.items():
1029
+ for i in range(len(poly_vars)):
1030
+ if d == poly_vars[i]:
1031
+ looking_for[i] = exp
1032
+ if not looking_for:
1033
+ raise ValueError("You must pass a dictionary list or monomial.")
1034
+ return self.parent()(self.element().polynomial_coefficient(looking_for))
1035
+
1036
+ def global_height(self, prec=None):
1037
+ """
1038
+ Return the (projective) global height of the polynomial.
1039
+
1040
+ This returns the absolute logarithmic height of the coefficients
1041
+ thought of as a projective point.
1042
+
1043
+ INPUT:
1044
+
1045
+ - ``prec`` -- desired floating point precision (default:
1046
+ default :class:`RealField` precision)
1047
+
1048
+ OUTPUT: a real number
1049
+
1050
+ EXAMPLES::
1051
+
1052
+ sage: R.<x,y> = PolynomialRing(QQbar, 2) # needs sage.rings.number_field
1053
+ sage: f = QQbar(i)*x^2 + 3*x*y # needs sage.rings.number_field
1054
+ sage: f.global_height() # needs sage.rings.number_field
1055
+ 1.09861228866811
1056
+
1057
+ Scaling should not change the result::
1058
+
1059
+ sage: # needs sage.rings.number_field sage.symbolic
1060
+ sage: R.<x, y> = PolynomialRing(QQbar, 2)
1061
+ sage: f = 1/25*x^2 + 25/3*x + 1 + QQbar(sqrt(2))*y^2
1062
+ sage: f.global_height()
1063
+ 6.43775164973640
1064
+ sage: g = 100 * f
1065
+ sage: g.global_height()
1066
+ 6.43775164973640
1067
+
1068
+ ::
1069
+
1070
+ sage: # needs sage.rings.number_field
1071
+ sage: R.<x> = QQ[]
1072
+ sage: K.<k> = NumberField(x^2 + 1)
1073
+ sage: Q.<q,r> = PolynomialRing(K, implementation='generic')
1074
+ sage: f = 12 * q
1075
+ sage: f.global_height()
1076
+ 0.000000000000000
1077
+
1078
+ ::
1079
+
1080
+ sage: R.<x,y> = PolynomialRing(QQ, implementation='generic')
1081
+ sage: f = 1/123*x*y + 12
1082
+ sage: f.global_height(prec=2) # needs sage.symbolic
1083
+ 8.0
1084
+
1085
+ ::
1086
+
1087
+ sage: R.<x,y> = PolynomialRing(QQ, implementation='generic')
1088
+ sage: f = 0*x*y
1089
+ sage: f.global_height() # needs sage.rings.real_mpfr
1090
+ 0.000000000000000
1091
+ """
1092
+ if prec is None:
1093
+ prec = 53
1094
+
1095
+ if self.is_zero():
1096
+ from sage.rings.real_mpfr import RealField
1097
+ return RealField(prec).zero()
1098
+
1099
+ from sage.categories.number_fields import NumberFields
1100
+
1101
+ K = self.base_ring()
1102
+ if K in NumberFields() or isinstance(K, (sage.rings.abc.Order, sage.rings.integer_ring.IntegerRing_class)):
1103
+ from sage.schemes.projective.projective_space import ProjectiveSpace
1104
+ Pr = ProjectiveSpace(K, self.number_of_terms()-1)
1105
+ return Pr.point(self.coefficients()).global_height(prec=prec)
1106
+ if isinstance(K, sage.rings.abc.AlgebraicField):
1107
+ from sage.rings.qqbar import number_field_elements_from_algebraics
1108
+
1109
+ K_pre, P, phi = number_field_elements_from_algebraics(list(self.coefficients()))
1110
+ from sage.schemes.projective.projective_space import ProjectiveSpace
1111
+ Pr = ProjectiveSpace(K_pre, len(P)-1)
1112
+ return Pr.point(P).global_height(prec=prec)
1113
+
1114
+ raise TypeError("Must be over a Numberfield or a Numberfield Order.")
1115
+
1116
+ def local_height(self, v, prec=None):
1117
+ """
1118
+ Return the maximum of the local height of the coefficients of
1119
+ this polynomial.
1120
+
1121
+ INPUT:
1122
+
1123
+ - ``v`` -- a prime or prime ideal of the base ring
1124
+
1125
+ - ``prec`` -- desired floating point precision (default:
1126
+ default RealField precision)
1127
+
1128
+ OUTPUT: a real number
1129
+
1130
+ EXAMPLES::
1131
+
1132
+ sage: R.<x,y> = PolynomialRing(QQ, implementation='generic')
1133
+ sage: f = 1/1331*x^2 + 1/4000*y
1134
+ sage: f.local_height(1331) # needs sage.rings.real_mpfr
1135
+ 7.19368581839511
1136
+
1137
+ ::
1138
+
1139
+ sage: # needs sage.rings.number_field
1140
+ sage: R.<x> = QQ[]
1141
+ sage: K.<k> = NumberField(x^2 - 5)
1142
+ sage: T.<t,w> = PolynomialRing(K, implementation='generic')
1143
+ sage: I = K.ideal(3)
1144
+ sage: f = 1/3*t*w + 3
1145
+ sage: f.local_height(I) # needs sage.symbolic
1146
+ 1.09861228866811
1147
+
1148
+ ::
1149
+
1150
+ sage: R.<x,y> = PolynomialRing(QQ, implementation='generic')
1151
+ sage: f = 1/2*x*y + 2
1152
+ sage: f.local_height(2, prec=2) # needs sage.rings.real_mpfr
1153
+ 0.75
1154
+ """
1155
+ from sage.categories.number_fields import NumberFields
1156
+
1157
+ if prec is None:
1158
+ prec = 53
1159
+
1160
+ K = FractionField(self.base_ring())
1161
+ if K not in NumberFields():
1162
+ raise TypeError("must be over a Numberfield or a Numberfield order")
1163
+
1164
+ return max([K(c).local_height(v, prec=prec) for c in self.coefficients()])
1165
+
1166
+ def local_height_arch(self, i, prec=None):
1167
+ """
1168
+ Return the maximum of the local height at the ``i``-th infinite place
1169
+ of the coefficients of this polynomial.
1170
+
1171
+ INPUT:
1172
+
1173
+ - ``i`` -- integer
1174
+
1175
+ - ``prec`` -- desired floating point precision (default:
1176
+ default :class:`RealField` precision)
1177
+
1178
+ OUTPUT: a real number
1179
+
1180
+ EXAMPLES::
1181
+
1182
+ sage: R.<x,y> = PolynomialRing(QQ, implementation='generic')
1183
+ sage: f = 210*x*y
1184
+ sage: f.local_height_arch(0) # needs sage.rings.real_mpfr
1185
+ 5.34710753071747
1186
+
1187
+ ::
1188
+
1189
+ sage: # needs sage.rings.number_field
1190
+ sage: R.<x> = QQ[]
1191
+ sage: K.<k> = NumberField(x^2 - 5)
1192
+ sage: T.<t,w> = PolynomialRing(K, implementation='generic')
1193
+ sage: f = 1/2*t*w + 3
1194
+ sage: f.local_height_arch(1, prec=52)
1195
+ 1.09861228866811
1196
+
1197
+ ::
1198
+
1199
+ sage: R.<x,y> = PolynomialRing(QQ, implementation='generic')
1200
+ sage: f = 1/2*x*y + 3
1201
+ sage: f.local_height_arch(0, prec=2) # needs sage.rings.real_mpfr
1202
+ 1.0
1203
+ """
1204
+ from sage.categories.number_fields import NumberFields
1205
+
1206
+ if prec is None:
1207
+ prec = 53
1208
+
1209
+ K = FractionField(self.base_ring())
1210
+ if K not in NumberFields():
1211
+ return TypeError("must be over a Numberfield or a Numberfield Order")
1212
+
1213
+ if K == QQ:
1214
+ return max([K(c).local_height_arch(prec=prec) for c in self.coefficients()])
1215
+ return max([K(c).local_height_arch(i, prec=prec) for c in self.coefficients()])
1216
+
1217
+ @lazy_attribute
1218
+ def _exponents(self):
1219
+ """
1220
+ Return the exponents of the monomials appearing in ``self`` for
1221
+ internal use only.
1222
+
1223
+ EXAMPLES::
1224
+
1225
+ sage: R.<a,b,c> = PolynomialRing(QQbar, 3) # needs sage.rings.number_field
1226
+ sage: f = a^3 + b + 2*b^2 # needs sage.rings.number_field
1227
+ sage: f._exponents # needs sage.rings.number_field
1228
+ [(3, 0, 0), (0, 2, 0), (0, 1, 0)]
1229
+ """
1230
+ return sorted(self.element().dict(), key=self.parent().term_order().sortkey, reverse=True)
1231
+
1232
+ def exponents(self, as_ETuples=True):
1233
+ r"""
1234
+ Return the exponents of the monomials appearing in ``self``.
1235
+
1236
+ INPUT:
1237
+
1238
+ - ``as_ETuples`` -- (default: ``True``) return the list of
1239
+ exponents as a list of ETuples
1240
+
1241
+ OUTPUT: the list of exponents as a list of ETuples or tuples
1242
+
1243
+ EXAMPLES::
1244
+
1245
+ sage: R.<a,b,c> = PolynomialRing(QQbar, 3) # needs sage.rings.number_field
1246
+ sage: f = a^3 + b + 2*b^2 # needs sage.rings.number_field
1247
+ sage: f.exponents() # needs sage.rings.number_field
1248
+ [(3, 0, 0), (0, 2, 0), (0, 1, 0)]
1249
+
1250
+ By default the list of exponents is a list of ETuples::
1251
+
1252
+ sage: type(f.exponents()[0]) # needs sage.rings.number_field
1253
+ <class 'sage.rings.polynomial.polydict.ETuple'>
1254
+ sage: type(f.exponents(as_ETuples=False)[0]) # needs sage.rings.number_field
1255
+ <... 'tuple'>
1256
+
1257
+ TESTS:
1258
+
1259
+ Check that we can mutate the list and not change the result::
1260
+
1261
+ sage: # needs sage.rings.number_field
1262
+ sage: R.<a,b,c> = PolynomialRing(QQbar, 3)
1263
+ sage: f = a^3 + b + 2*b^2
1264
+ sage: E = f.exponents(); E
1265
+ [(3, 0, 0), (0, 2, 0), (0, 1, 0)]
1266
+ sage: E.pop()
1267
+ (0, 1, 0)
1268
+ sage: E != f.exponents()
1269
+ True
1270
+ """
1271
+ if as_ETuples:
1272
+ return list(self._exponents) # Make a shallow copy
1273
+ else:
1274
+ return [tuple(e) for e in self._exponents]
1275
+
1276
+ def inverse_of_unit(self):
1277
+ """
1278
+ Return the inverse of a unit in a ring.
1279
+
1280
+ TESTS::
1281
+
1282
+ sage: R.<c> = QQ[]
1283
+ sage: l = R(2)
1284
+ sage: l.inverse_of_unit().parent()
1285
+ Univariate Polynomial Ring in c over Rational Field
1286
+ """
1287
+ if self.is_unit():
1288
+ d = self.element().dict()
1289
+ if len(d) != 1:
1290
+ raise NotImplementedError
1291
+ return list(d.values())[0].inverse_of_unit()
1292
+ raise ArithmeticError("is not a unit")
1293
+
1294
+ def is_homogeneous(self):
1295
+ """
1296
+ Return ``True`` if ``self`` is a homogeneous polynomial.
1297
+
1298
+ EXAMPLES::
1299
+
1300
+ sage: # needs sage.rings.number_field
1301
+ sage: R.<x,y> = QQbar[]
1302
+ sage: (x + y).is_homogeneous()
1303
+ True
1304
+ sage: (x.parent()(0)).is_homogeneous()
1305
+ True
1306
+ sage: (x + y^2).is_homogeneous()
1307
+ False
1308
+ sage: (x^2 + y^2).is_homogeneous()
1309
+ True
1310
+ sage: (x^2 + y^2*x).is_homogeneous()
1311
+ False
1312
+ sage: (x^2*y + y^2*x).is_homogeneous()
1313
+ True
1314
+
1315
+ The weight of the parent ring is respected::
1316
+
1317
+ sage: # needs sage.rings.finite_rings
1318
+ sage: term_order = TermOrder("wdegrevlex", [1, 3])
1319
+ sage: R.<x, y> = PolynomialRing(Qp(5), order=term_order)
1320
+ sage: (x + y).is_homogeneous()
1321
+ False
1322
+ sage: (x^3 + y).is_homogeneous()
1323
+ True
1324
+ """
1325
+ return self.element().is_homogeneous(self.parent().term_order().weights())
1326
+
1327
+ def _homogenize(self, var):
1328
+ r"""
1329
+ Return ``self`` if ``self`` is homogeneous.
1330
+ Otherwise return a homogenized polynomial constructed by modifying
1331
+ the degree of the variable with index ``var``.
1332
+
1333
+ INPUT:
1334
+
1335
+ - ``var`` -- integer indicating which variable to
1336
+ use to homogenize (``0 <= var < parent(self).ngens()``)
1337
+
1338
+ OUTPUT: a multivariate polynomial
1339
+
1340
+ EXAMPLES::
1341
+
1342
+ sage: # needs sage.rings.number_field
1343
+ sage: P.<x,y> = QQbar[]
1344
+ sage: f = x^2 + y + 1 + 5*x*y^1
1345
+ sage: g = f.homogenize('z'); g # indirect doctest
1346
+ x^2 + 5*x*y + y*z + z^2
1347
+ sage: g.parent()
1348
+ Multivariate Polynomial Ring in x, y, z over Algebraic Field
1349
+
1350
+ SEE: ``self.homogenize``
1351
+ """
1352
+ if self.is_homogeneous():
1353
+ return self
1354
+ X = self.element().homogenize(var)
1355
+ X.remove_zeros()
1356
+ R = self.parent()
1357
+ return R(X)
1358
+
1359
+ def is_gen(self) -> bool:
1360
+ """
1361
+ Return ``True`` if ``self`` is a generator of its parent.
1362
+
1363
+ EXAMPLES::
1364
+
1365
+ sage: # needs sage.rings.number_field
1366
+ sage: R.<x,y> = QQbar[]
1367
+ sage: x.is_gen()
1368
+ True
1369
+ sage: (x + y - y).is_gen()
1370
+ True
1371
+ sage: (x*y).is_gen()
1372
+ False
1373
+
1374
+ TESTS::
1375
+
1376
+ sage: # needs sage.rings.number_field
1377
+ sage: R.<x,y> = QQbar[]
1378
+ sage: x.is_generator()
1379
+ doctest:warning...:
1380
+ DeprecationWarning: is_generator is deprecated. Please use is_gen instead.
1381
+ See https://github.com/sagemath/sage/issues/38942 for details.
1382
+ True
1383
+ """
1384
+ elt = self.element()
1385
+ if len(elt) == 1:
1386
+ (e, c), = elt.dict().items()
1387
+ return e.nonzero_values() == [1] and c.is_one()
1388
+ return False
1389
+
1390
+ is_generator = deprecated_function_alias(38942, is_gen)
1391
+
1392
+ def is_monomial(self):
1393
+ """
1394
+ Return ``True`` if ``self`` is a monomial, which we define to be a
1395
+ product of generators with coefficient 1.
1396
+
1397
+ Use :meth:`is_term` to allow the coefficient to not be 1.
1398
+
1399
+ EXAMPLES::
1400
+
1401
+ sage: # needs sage.rings.number_field
1402
+ sage: R.<x,y> = QQbar[]
1403
+ sage: x.is_monomial()
1404
+ True
1405
+ sage: (x + 2*y).is_monomial()
1406
+ False
1407
+ sage: (2*x).is_monomial()
1408
+ False
1409
+ sage: (x*y).is_monomial()
1410
+ True
1411
+
1412
+ To allow a non-1 leading coefficient, use :meth:`is_term`::
1413
+
1414
+ sage: (2*x*y).is_term() # needs sage.rings.number_field
1415
+ True
1416
+ sage: (2*x*y).is_monomial() # needs sage.rings.number_field
1417
+ False
1418
+ """
1419
+ return len(self.element()) == 1 and self.element().coefficients()[0] == 1
1420
+
1421
+ def is_term(self):
1422
+ """
1423
+ Return ``True`` if ``self`` is a term, which we define to be a
1424
+ product of generators times some coefficient, which need
1425
+ not be 1.
1426
+
1427
+ Use :meth:`is_monomial` to require that the coefficient be 1.
1428
+
1429
+ EXAMPLES::
1430
+
1431
+ sage: # needs sage.rings.number_field
1432
+ sage: R.<x,y> = QQbar[]
1433
+ sage: x.is_term()
1434
+ True
1435
+ sage: (x + 2*y).is_term()
1436
+ False
1437
+ sage: (2*x).is_term()
1438
+ True
1439
+ sage: (7*x^5*y).is_term()
1440
+ True
1441
+
1442
+ To require leading coefficient 1, use :meth:`is_monomial`::
1443
+
1444
+ sage: (2*x*y).is_monomial() # needs sage.rings.number_field
1445
+ False
1446
+ sage: (2*x*y).is_term() # needs sage.rings.number_field
1447
+ True
1448
+ """
1449
+ return len(self.element()) == 1
1450
+
1451
+ def subs(self, fixed=None, **kwds):
1452
+ """
1453
+ Fix some given variables in a given multivariate polynomial and
1454
+ return the changed multivariate polynomials. The polynomial itself
1455
+ is not affected. The variable, value pairs for fixing are to be
1456
+ provided as a dictionary of the form ``{variable: value}``.
1457
+
1458
+ This is a special case of evaluating the polynomial with some of
1459
+ the variables constants and the others the original variables.
1460
+
1461
+ INPUT:
1462
+
1463
+ - ``fixed`` -- (optional) dictionary of inputs
1464
+
1465
+ - ``**kwds`` -- named parameters
1466
+
1467
+ OUTPUT: new :class:`MPolynomial`
1468
+
1469
+ EXAMPLES::
1470
+
1471
+ sage: # needs sage.rings.number_field
1472
+ sage: R.<x,y> = QQbar[]
1473
+ sage: f = x^2 + y + x^2*y^2 + 5
1474
+ sage: f((5, y))
1475
+ 25*y^2 + y + 30
1476
+ sage: f.subs({x: 5})
1477
+ 25*y^2 + y + 30
1478
+ """
1479
+ variables = list(self.parent().gens())
1480
+ for i in range(len(variables)):
1481
+ if str(variables[i]) in kwds:
1482
+ variables[i] = kwds[str(variables[i])]
1483
+ elif fixed:
1484
+ if variables[i] in fixed:
1485
+ variables[i] = fixed[variables[i]]
1486
+ elif i in fixed:
1487
+ variables[i] = fixed[i]
1488
+ return self(tuple(variables))
1489
+
1490
+ def monomials(self):
1491
+ """
1492
+ Return the list of monomials in ``self``. The returned list is
1493
+ decreasingly ordered by the term ordering of ``self.parent()``.
1494
+
1495
+ OUTPUT: list of :class:`MPolynomial` instances, representing monomials
1496
+
1497
+ EXAMPLES::
1498
+
1499
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
1500
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # needs sage.rings.number_field
1501
+ sage: f.monomials() # needs sage.rings.number_field
1502
+ [x^2*y^2, x^2, y, 1]
1503
+
1504
+ ::
1505
+
1506
+ sage: # needs sage.rings.number_field
1507
+ sage: R.<fx,fy,gx,gy> = QQbar[]
1508
+ sage: F = (fx*gy - fy*gx)^3; F
1509
+ -fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3
1510
+ sage: F.monomials()
1511
+ [fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3]
1512
+ sage: F.coefficients()
1513
+ [-1, 3, -3, 1]
1514
+ sage: sum(map(mul, zip(F.coefficients(), F.monomials()))) == F
1515
+ True
1516
+ """
1517
+ ring = self.parent()
1518
+ one = ring.base_ring().one()
1519
+ return [MPolynomial_polydict(ring, polydict.PolyDict({m: one}, check=False))
1520
+ for m in self._exponents]
1521
+
1522
+ def constant_coefficient(self):
1523
+ """
1524
+ Return the constant coefficient of this multivariate polynomial.
1525
+
1526
+ EXAMPLES::
1527
+
1528
+ sage: # needs sage.rings.number_field
1529
+ sage: R.<x,y> = QQbar[]
1530
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1531
+ sage: f.constant_coefficient()
1532
+ 5
1533
+ sage: f = 3*x^2
1534
+ sage: f.constant_coefficient()
1535
+ 0
1536
+ """
1537
+ #v = (0,)*int(self.parent().ngens())
1538
+ d = self.element().dict()
1539
+ try:
1540
+ return d[polydict.ETuple({},self.parent().ngens())]
1541
+ except KeyError:
1542
+ return self.parent().base_ring().zero()
1543
+
1544
+ def is_univariate(self):
1545
+ """
1546
+ Return ``True`` if this multivariate polynomial is univariate and
1547
+ ``False`` otherwise.
1548
+
1549
+ EXAMPLES::
1550
+
1551
+ sage: # needs sage.rings.number_field
1552
+ sage: R.<x,y> = QQbar[]
1553
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1554
+ sage: f.is_univariate()
1555
+ False
1556
+ sage: g = f.subs({x: 10}); g
1557
+ 700*y^2 + (-2)*y + 305
1558
+ sage: g.is_univariate()
1559
+ True
1560
+ sage: f = x^0
1561
+ sage: f.is_univariate()
1562
+ True
1563
+ """
1564
+ mons = self.element().dict()
1565
+
1566
+ found = -1
1567
+ for mon in mons:
1568
+ for i in mon.nonzero_positions():
1569
+ if found != i:
1570
+ if found != -1:
1571
+ return False
1572
+ else:
1573
+ found = i
1574
+ return True
1575
+
1576
+ def univariate_polynomial(self, R=None):
1577
+ """
1578
+ Return a univariate polynomial associated to this multivariate
1579
+ polynomial.
1580
+
1581
+ INPUT:
1582
+
1583
+ - ``R`` -- (default: ``None``) :class:`PolynomialRing`
1584
+
1585
+
1586
+ If this polynomial is not in at most one variable, then a
1587
+ :exc:`ValueError` exception is raised. This is checked using the
1588
+ method :meth:`is_univariate`. The new :class:`Polynomial` is over the same base
1589
+ ring as the given :class:`MPolynomial`.
1590
+
1591
+ EXAMPLES::
1592
+
1593
+ sage: # needs sage.rings.number_field
1594
+ sage: R.<x,y> = QQbar[]
1595
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1596
+ sage: f.univariate_polynomial()
1597
+ Traceback (most recent call last):
1598
+ ...
1599
+ TypeError: polynomial must involve at most one variable
1600
+ sage: g = f.subs({x: 10}); g
1601
+ 700*y^2 + (-2)*y + 305
1602
+ sage: g.univariate_polynomial()
1603
+ 700*y^2 - 2*y + 305
1604
+ sage: g.univariate_polynomial(PolynomialRing(QQ, 'z'))
1605
+ 700*z^2 - 2*z + 305
1606
+
1607
+ TESTS::
1608
+
1609
+ sage: P = PolynomialRing(QQ, 0, '')
1610
+ sage: P(5).univariate_polynomial()
1611
+ 5
1612
+ """
1613
+ if self.parent().ngens() == 0:
1614
+ if R is None:
1615
+ return self.base_ring()(self)
1616
+ else:
1617
+ return R(self)
1618
+
1619
+ if not self.is_univariate():
1620
+ raise TypeError("polynomial must involve at most one variable")
1621
+
1622
+ #construct ring if None
1623
+ if R is None:
1624
+ # constant, we just pick first variable from parent
1625
+ if self.is_constant():
1626
+ R = self.base_ring()[self.parent().variable_names()[0]]
1627
+ else:
1628
+ R = self.base_ring()[str(self.variables()[0])]
1629
+
1630
+ monomial_coefficients = self._MPolynomial_element__element.dict()
1631
+
1632
+ if not self.is_constant():
1633
+ var_idx = self.degrees().nonzero_positions()[0] #variable
1634
+ else:
1635
+ var_idx = 0 #constant
1636
+ if len(monomial_coefficients) == 0:
1637
+ return R(0)
1638
+
1639
+ #construct list
1640
+ lookup = [0,] * len(next(iter(monomial_coefficients)))
1641
+ coefficients = []
1642
+ for degree in range(max(m[var_idx]
1643
+ for m in monomial_coefficients.keys()) + 1):
1644
+ lookup[var_idx] = int(degree)
1645
+ try:
1646
+ coefficients.append( monomial_coefficients[ polydict.ETuple(lookup) ] ) #if we find something, add the coefficient
1647
+ except KeyError:
1648
+ coefficients.append( 0 ) #else add zero
1649
+
1650
+ #construct polynomial
1651
+ return R(coefficients)
1652
+
1653
+ def variables(self):
1654
+ """
1655
+ Return the tuple of variables occurring in this polynomial.
1656
+
1657
+ EXAMPLES::
1658
+
1659
+ sage: # needs sage.rings.number_field
1660
+ sage: R.<x,y> = QQbar[]
1661
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1662
+ sage: f.variables()
1663
+ (x, y)
1664
+ sage: g = f.subs({x: 10}); g
1665
+ 700*y^2 + (-2)*y + 305
1666
+ sage: g.variables()
1667
+ (y,)
1668
+
1669
+ TESTS:
1670
+
1671
+ This shows that the issue at :issue:`7077` is fixed::
1672
+
1673
+ sage: x,y,z=polygens(QQ,'x,y,z')
1674
+ sage: (x^2).variables()
1675
+ (x,)
1676
+ """
1677
+ return tuple([self.parent().gen(index) for index in self.degrees().nonzero_positions()])
1678
+
1679
+ def variable(self, i):
1680
+ """
1681
+ Return the `i`-th variable occurring in this polynomial.
1682
+
1683
+ EXAMPLES::
1684
+
1685
+ sage: # needs sage.rings.number_field
1686
+ sage: R.<x,y> = QQbar[]
1687
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1688
+ sage: f.variable(0)
1689
+ x
1690
+ sage: f.variable(1)
1691
+ y
1692
+ """
1693
+ return self.variables()[int(i)]
1694
+
1695
+ def nvariables(self):
1696
+ """
1697
+ Return the number of variables in this polynomial.
1698
+
1699
+ EXAMPLES::
1700
+
1701
+ sage: # needs sage.rings.number_field
1702
+ sage: R.<x,y> = QQbar[]
1703
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1704
+ sage: f.nvariables()
1705
+ 2
1706
+ sage: g = f.subs({x: 10}); g
1707
+ 700*y^2 + (-2)*y + 305
1708
+ sage: g.nvariables()
1709
+ 1
1710
+ """
1711
+ return len(self.degrees().nonzero_positions())
1712
+
1713
+ def is_constant(self):
1714
+ """
1715
+ Return ``True`` if ``self`` is a constant and ``False`` otherwise.
1716
+
1717
+ EXAMPLES::
1718
+
1719
+ sage: # needs sage.rings.number_field
1720
+ sage: R.<x,y> = QQbar[]
1721
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
1722
+ sage: f.is_constant()
1723
+ False
1724
+ sage: g = 10*x^0
1725
+ sage: g.is_constant()
1726
+ True
1727
+ """
1728
+ return self.element().is_constant()
1729
+
1730
+ def lm(self):
1731
+ """
1732
+ Return the lead monomial of ``self`` with respect to the term order of
1733
+ ``self.parent()``.
1734
+
1735
+ EXAMPLES::
1736
+
1737
+ sage: R.<x,y,z> = PolynomialRing(GF(7), 3, order='lex')
1738
+ sage: (x^1*y^2 + y^3*z^4).lm()
1739
+ x*y^2
1740
+ sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm()
1741
+ x^3*y^2*z^4
1742
+
1743
+ ::
1744
+
1745
+ sage: # needs sage.rings.real_mpfr
1746
+ sage: R.<x,y,z> = PolynomialRing(CC, 3, order='deglex')
1747
+ sage: (x^1*y^2*z^3 + x^3*y^2*z^0).lm()
1748
+ x*y^2*z^3
1749
+ sage: (x^1*y^2*z^4 + x^1*y^1*z^5).lm()
1750
+ x*y^2*z^4
1751
+
1752
+ ::
1753
+
1754
+ sage: # needs sage.rings.number_field
1755
+ sage: R.<x,y,z> = PolynomialRing(QQbar, 3, order='degrevlex')
1756
+ sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm()
1757
+ x*y^5*z^2
1758
+ sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm()
1759
+ x^4*y^7*z
1760
+
1761
+ TESTS::
1762
+
1763
+ sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict
1764
+ sage: R.<x,y> = MPolynomialRing_polydict(GF(2), 2, order='lex')
1765
+ sage: f = x + y
1766
+ sage: f.lm()
1767
+ x
1768
+ """
1769
+ try:
1770
+ return self.__lm
1771
+ except AttributeError:
1772
+ if self.is_zero():
1773
+ return self
1774
+ R = self.parent()
1775
+ f = self._MPolynomial_element__element.lcmt(R.term_order().greater_tuple)
1776
+ one = R.base_ring().one()
1777
+ self.__lm = MPolynomial_polydict(R,polydict.PolyDict({f: one}, check=False))
1778
+ return self.__lm
1779
+
1780
+ def lc(self):
1781
+ """
1782
+ Return the leading coefficient of ``self``, i.e.,
1783
+ ``self.coefficient(self.lm())``.
1784
+
1785
+ EXAMPLES::
1786
+
1787
+ sage: R.<x,y,z> = QQbar[] # needs sage.rings.number_field
1788
+ sage: f = 3*x^2 - y^2 - x*y # needs sage.rings.number_field
1789
+ sage: f.lc() # needs sage.rings.number_field
1790
+ 3
1791
+ """
1792
+ try:
1793
+ return self.__lc
1794
+ except AttributeError:
1795
+ if self.is_zero():
1796
+ return self.base_ring()._zero_element
1797
+ R = self.parent()
1798
+ f = self._MPolynomial_element__element.dict()
1799
+ self.__lc = f[self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple )]
1800
+ return self.__lc
1801
+
1802
+ def lt(self):
1803
+ r"""
1804
+ Return the leading term of ``self`` i.e., ``self.lc()*self.lm()``. The
1805
+ notion of "leading term" depends on the ordering defined in the
1806
+ parent ring.
1807
+
1808
+ EXAMPLES::
1809
+
1810
+ sage: # needs sage.rings.number_field
1811
+ sage: R.<x,y,z> = PolynomialRing(QQbar)
1812
+ sage: f = 3*x^2 - y^2 - x*y
1813
+ sage: f.lt()
1814
+ 3*x^2
1815
+ sage: R.<x,y,z> = PolynomialRing(QQbar, order='invlex')
1816
+ sage: f = 3*x^2 - y^2 - x*y
1817
+ sage: f.lt()
1818
+ -y^2
1819
+
1820
+ TESTS::
1821
+
1822
+ sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict
1823
+ sage: R.<x,y> = MPolynomialRing_polydict(GF(2), 2, order='lex')
1824
+ sage: f = x + y
1825
+ sage: f.lt()
1826
+ x
1827
+ """
1828
+ try:
1829
+ return self.__lt
1830
+ except AttributeError:
1831
+ if self.is_zero():
1832
+ return self
1833
+ R = self.parent()
1834
+ f = self._MPolynomial_element__element.dict()
1835
+ res = self._MPolynomial_element__element.lcmt(R.term_order().greater_tuple)
1836
+ self.__lt = MPolynomial_polydict(R, polydict.PolyDict({res: f[res]}, check=False))
1837
+ return self.__lt
1838
+
1839
+ def __eq__(self, right):
1840
+ if not isinstance(right, MPolynomial_polydict):
1841
+ # we want comparison with zero to be fast
1842
+ if not right:
1843
+ return not self._MPolynomial_element__element.dict()
1844
+ return CommutativeRingElement.__eq__(self, right)
1845
+ return self._MPolynomial_element__element == right._MPolynomial_element__element
1846
+
1847
+ def __ne__(self, right):
1848
+ if not isinstance(right, MPolynomial_polydict):
1849
+ # we want comparison with zero to be fast
1850
+ if not right:
1851
+ return not not self._MPolynomial_element__element.dict()
1852
+ return CommutativeRingElement.__ne__(self, right)
1853
+ return self._MPolynomial_element__element != right._MPolynomial_element__element
1854
+
1855
+ # required by Python 3
1856
+ __hash__ = MPolynomial_element.__hash__
1857
+
1858
+ def __bool__(self):
1859
+ """
1860
+ Return ``True`` if ``self != 0``.
1861
+
1862
+ .. NOTE::
1863
+
1864
+ This is much faster than actually writing ``self == 0``.
1865
+ """
1866
+ return bool(self._MPolynomial_element__element)
1867
+
1868
+ def _floordiv_(self, right):
1869
+ r"""
1870
+ Quotient of division of ``self`` by ``other``. This is denoted ``//``.
1871
+
1872
+ .. NOTE::
1873
+
1874
+ It's not clear to me that this is well-defined if
1875
+ ``self`` is not exactly divisible by other.
1876
+
1877
+ EXAMPLES::
1878
+
1879
+ sage: # needs sage.rings.number_field
1880
+ sage: R.<x,y> = QQbar[]
1881
+ sage: 2*x*y//y
1882
+ 2*x
1883
+ sage: 2*x//y
1884
+ 0
1885
+ sage: 2*x//4
1886
+ 1/2*x
1887
+ sage: type(0//y)
1888
+ <class 'sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict'>
1889
+ """
1890
+ # handle division by monomials without using Singular
1891
+ if len(right.monomial_coefficients()) == 1:
1892
+ P = self.parent()
1893
+ ret = P(0)
1894
+ denC, denM = next(iter(right))
1895
+ for c, m in self:
1896
+ t = c * m
1897
+ if denC.divides(c) and P.monomial_divides(denM, m):
1898
+ ret += P.monomial_quotient(t, right, coeff=True)
1899
+ return ret
1900
+
1901
+ Q, _ = self.quo_rem(right)
1902
+ return Q
1903
+
1904
+ def _derivative(self, var=None):
1905
+ r"""
1906
+ Differentiates ``self`` with respect to variable ``var``.
1907
+
1908
+ If ``var`` is not one of the generators of this ring, ``_derivative(var)``
1909
+ is called recursively on each coefficient of this polynomial.
1910
+
1911
+ .. SEEALSO::
1912
+
1913
+ :meth:`derivative`
1914
+
1915
+ EXAMPLES::
1916
+
1917
+ sage: # needs sage.rings.number_field
1918
+ sage: R.<t> = PowerSeriesRing(QQbar)
1919
+ sage: S.<x, y> = PolynomialRing(R)
1920
+ sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3
1921
+ sage: f.parent()
1922
+ Multivariate Polynomial Ring in x, y
1923
+ over Power Series Ring in t over Algebraic Field
1924
+ sage: f._derivative(x) # with respect to x
1925
+ (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2
1926
+ sage: f._derivative(x).parent()
1927
+ Multivariate Polynomial Ring in x, y
1928
+ over Power Series Ring in t over Algebraic Field
1929
+ sage: f._derivative(y) # with respect to y
1930
+ (3*t^2 + O(t^3))*x^2*y^2
1931
+ sage: f._derivative(t) # with respect to t (recurses into base ring)
1932
+ (2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3
1933
+ sage: f._derivative(x)._derivative(y) # with respect to x and then y
1934
+ (6*t^2 + O(t^3))*x*y^2
1935
+ sage: f.derivative(y, 3) # with respect to y three times
1936
+ (6*t^2 + O(t^3))*x^2
1937
+ sage: f._derivative() # can't figure out the variable
1938
+ Traceback (most recent call last):
1939
+ ...
1940
+ ValueError: must specify which variable to differentiate with respect to
1941
+ """
1942
+ if var is None:
1943
+ raise ValueError("must specify which variable to differentiate with respect to")
1944
+
1945
+ P = self.parent()
1946
+
1947
+ # check if var is one of the generators
1948
+ index = polydict.gen_index(P(var).element())
1949
+ if index == -1:
1950
+ # var is not a generator; do term-by-term differentiation recursively
1951
+ # var may be, for example, a generator of the base ring
1952
+ d = {e: x._derivative(var)
1953
+ for e, x in self.monomial_coefficients().items()}
1954
+ d = polydict.PolyDict(d, check=False)
1955
+ d.remove_zeros()
1956
+ return MPolynomial_polydict(P, d)
1957
+
1958
+ # differentiate w.r.t. indicated variable
1959
+ elt = self.element().derivative_i(index)
1960
+ elt.remove_zeros()
1961
+ return MPolynomial_polydict(P, elt)
1962
+
1963
+ def integral(self, var=None):
1964
+ r"""
1965
+ Integrate ``self`` with respect to variable ``var``.
1966
+
1967
+ .. NOTE::
1968
+
1969
+ The integral is always chosen so the constant term is 0.
1970
+
1971
+ If ``var`` is not one of the generators of this ring, ``integral(var)``
1972
+ is called recursively on each coefficient of this polynomial.
1973
+
1974
+ EXAMPLES:
1975
+
1976
+ On polynomials with rational coefficients::
1977
+
1978
+ sage: x, y = PolynomialRing(QQ, 'x, y').gens()
1979
+ sage: ex = x*y + x - y
1980
+ sage: it = ex.integral(x); it
1981
+ 1/2*x^2*y + 1/2*x^2 - x*y
1982
+ sage: it.parent() == x.parent()
1983
+ True
1984
+
1985
+ sage: R = ZZ['x']['y, z']
1986
+ sage: y, z = R.gens()
1987
+ sage: R.an_element().integral(y).parent()
1988
+ Multivariate Polynomial Ring in y, z
1989
+ over Univariate Polynomial Ring in x over Rational Field
1990
+
1991
+ On polynomials with coefficients in power series::
1992
+
1993
+ sage: # needs sage.rings.number_field
1994
+ sage: R.<t> = PowerSeriesRing(QQbar)
1995
+ sage: S.<x, y> = PolynomialRing(R)
1996
+ sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3
1997
+ sage: f.parent()
1998
+ Multivariate Polynomial Ring in x, y
1999
+ over Power Series Ring in t over Algebraic Field
2000
+ sage: f.integral(x) # with respect to x
2001
+ (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4
2002
+ sage: f.integral(x).parent()
2003
+ Multivariate Polynomial Ring in x, y
2004
+ over Power Series Ring in t over Algebraic Field
2005
+ sage: f.integral(y) # with respect to y
2006
+ (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y
2007
+ sage: f.integral(t) # with respect to t (recurses into base ring)
2008
+ (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3
2009
+
2010
+ TESTS::
2011
+
2012
+ sage: f.integral() # can't figure out the variable # needs sage.rings.number_field
2013
+ Traceback (most recent call last):
2014
+ ...
2015
+ ValueError: must specify which variable to integrate with respect to
2016
+
2017
+ :issue:`34000`::
2018
+
2019
+ sage: R = ZZ['x']['y,z']
2020
+ sage: y, z = R.gens()
2021
+ sage: parent(y.integral(y))
2022
+ Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in x over Rational Field
2023
+ """
2024
+ if var is None:
2025
+ raise ValueError("must specify which variable to integrate "
2026
+ "with respect to")
2027
+
2028
+ # TODO:
2029
+ # calling the coercion model bin_op is much more accurate than using the
2030
+ # true division (which is bypassed by polynomials). But it does not work
2031
+ # in all cases!!
2032
+ # See similar in polynomial_element.pyx
2033
+ P = self.parent()
2034
+ cm = get_coercion_model()
2035
+ try:
2036
+ S = cm.bin_op(P.one(), sage.rings.integer_ring.ZZ.one(), operator.truediv).parent()
2037
+ except TypeError:
2038
+ Q = (P.base_ring().one() / sage.rings.integer_ring.ZZ.one()).parent()
2039
+ S = P.change_ring(Q)
2040
+
2041
+ if P is not S:
2042
+ return S.coerce(self).integral(var)
2043
+
2044
+ # check if var is one of the generators
2045
+ index = polydict.gen_index(P(var).element())
2046
+ if index == -1:
2047
+ # var is not a generator; do term-by-term integration recursively
2048
+ # var may be, for example, a generator of the base ring
2049
+ d = {e: x.integral(var)
2050
+ for e, x in self.monomial_coefficients().items()}
2051
+ d = polydict.PolyDict(d, check=False)
2052
+ d.remove_zeros()
2053
+ else:
2054
+ # integrate w.r.t. indicated variable
2055
+ d = self.element().integral_i(index)
2056
+ return MPolynomial_polydict(P, d)
2057
+
2058
+ def factor(self, proof=None):
2059
+ r"""
2060
+ Compute the irreducible factorization of this polynomial.
2061
+
2062
+ INPUT:
2063
+
2064
+ - ``proof`` -- insist on provably correct results (default: ``True``
2065
+ unless explicitly disabled for the ``'polynomial'`` subsystem with
2066
+ :class:`sage.structure.proof.proof.WithProof`.)
2067
+
2068
+ TESTS:
2069
+
2070
+ Check if we can handle polynomials with no variables, see :issue:`7950`::
2071
+
2072
+ sage: P = PolynomialRing(ZZ,0,'')
2073
+ sage: res = P(10).factor(); res
2074
+ 2 * 5
2075
+ sage: res[0][0].parent()
2076
+ Multivariate Polynomial Ring in no variables over Integer Ring
2077
+ sage: R = PolynomialRing(QQ,0,'')
2078
+ sage: res = R(10).factor(); res
2079
+ 10
2080
+ sage: res.unit().parent()
2081
+ Rational Field
2082
+ sage: P(0).factor()
2083
+ Traceback (most recent call last):
2084
+ ...
2085
+ ArithmeticError: factorization of 0 is not defined
2086
+
2087
+ Check if we can factor a constant polynomial, see :issue:`8207`::
2088
+
2089
+ sage: R.<x,y> = CC[] # needs sage.rings.real_mpfr
2090
+ sage: R(1).factor() # needs sage.rings.real_mpfr
2091
+ 1.00000000000000
2092
+
2093
+ Check that we prohibit too large moduli, :issue:`11829`::
2094
+
2095
+ sage: R.<x,y> = GF(previous_prime(2^31))[] # needs sage.rings.finite_rings
2096
+ sage: factor(x + y + 1) # needs sage.rings.finite_rings
2097
+ Traceback (most recent call last):
2098
+ ...
2099
+ NotImplementedError: Factorization of multivariate polynomials
2100
+ over prime fields with characteristic > 2^29 is not implemented.
2101
+
2102
+ Check that we can factor over the algebraic field (:issue:`25390`)::
2103
+
2104
+ sage: # needs sage.libs.singular sage.rings.number_field
2105
+ sage: R.<x,y> = PolynomialRing(QQbar)
2106
+ sage: factor(x^2 + y^2)
2107
+ (x + (-1*I)*y) * (x + 1*I*y)
2108
+
2109
+ Check that the global proof flag for polynomials is honored::
2110
+
2111
+ sage: # needs sage.libs.singular
2112
+ sage: R.<x,y> = PolynomialRing(QQ['z'])
2113
+ sage: f = x^2 + y^2
2114
+ sage: with proof.WithProof('polynomial', True):
2115
+ ....: f.factor()
2116
+ Traceback (most recent call last):
2117
+ ...
2118
+ NotImplementedError: Provably correct factorization not implemented.
2119
+ Disable this error by wrapping your code in a
2120
+ `with proof.WithProof('polynomial', False):` block.
2121
+ sage: with proof.WithProof('polynomial', False):
2122
+ ....: f.factor()
2123
+ Traceback (most recent call last):
2124
+ ...
2125
+ TypeError: no conversion of this ring to a Singular ring defined
2126
+
2127
+ We check that the original issue in :issue:`7554` is fixed::
2128
+
2129
+ sage: K.<a> = PolynomialRing(QQ)
2130
+ sage: R.<x,y> = PolynomialRing(FractionField(K))
2131
+ sage: factor(x) # needs sage.libs.pari
2132
+ x
2133
+
2134
+ In the example below, we set the special method
2135
+ ``_factor_multivariate_polynomial()`` in the base ring which is called to
2136
+ factor multivariate polynomials. This facility can be used to easily
2137
+ extend polynomial factorization to work over new rings you introduce::
2138
+
2139
+ sage: R.<x, y> = PolynomialRing(QQ['z'])
2140
+ sage: (x*y).factor()
2141
+ Traceback (most recent call last):
2142
+ ...
2143
+ NotImplementedError: ...
2144
+ sage: R.base_ring()._factor_multivariate_polynomial = lambda f, **kwargs: f.change_ring(QQ).factor()
2145
+ sage: (x*y).factor() # needs sage.libs.pari
2146
+ y * x
2147
+ sage: del R.base_ring()._factor_multivariate_polynomial # clean up
2148
+
2149
+ Check that a "multivariate" polynomial in one variable is factored
2150
+ correctly::
2151
+
2152
+ sage: R.<z> = PolynomialRing(CC,1) # needs sage.rings.real_mpfr
2153
+ sage: f = z^4 - 6*z + 3 # needs sage.rings.real_mpfr
2154
+ sage: f.factor() # needs sage.libs.pari sage.rings.real_mpfr
2155
+ (z - 1.60443920904349) * (z - 0.511399619393097)
2156
+ * (z + 1.05791941421830 - 1.59281852704435*I)
2157
+ * (z + 1.05791941421830 + 1.59281852704435*I)
2158
+
2159
+ We check a case that failed with an exception at some point::
2160
+
2161
+ sage: # needs sage.rings.finite_rings
2162
+ sage: k.<u> = GF(4)
2163
+ sage: R.<v> = k[]
2164
+ sage: l.<v> = R.quo(v^3 + v + 1)
2165
+ sage: R.<x,y> = l[]
2166
+ sage: f = y^3 + x^3 + (u + 1)*x
2167
+ sage: f.factor()
2168
+ x^3 + y^3 + (u + 1)*x
2169
+ """
2170
+ R = self.parent()
2171
+
2172
+ # raise error if trying to factor zero
2173
+ if not self:
2174
+ raise ArithmeticError("factorization of {!r} is not defined".format(self))
2175
+
2176
+ # if number of variables is zero ...
2177
+ if R.ngens() == 0:
2178
+ base_ring = self.base_ring()
2179
+ if base_ring.is_field():
2180
+ return Factorization([],unit=self.base_ring()(self))
2181
+ else:
2182
+ F = base_ring(self).factor()
2183
+ return Factorization([(R(f),m) for f,m in F], unit=F.unit())
2184
+
2185
+ base_ring = self.base_ring()
2186
+ if hasattr(base_ring, '_factor_multivariate_polynomial'):
2187
+ return base_ring._factor_multivariate_polynomial(self, proof=proof)
2188
+
2189
+ # try to use univariate factoring
2190
+ try:
2191
+ F = self.univariate_polynomial().factor()
2192
+ return Factorization([(R(f), m) for f, m in F], unit=F.unit())
2193
+ except TypeError:
2194
+ pass
2195
+
2196
+ base_ring = self.base_ring()
2197
+ if base_ring.is_finite():
2198
+ if base_ring.characteristic() > 1 << 29:
2199
+ raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.")
2200
+
2201
+ if proof is None:
2202
+ from sage.structure.proof.proof import get_flag
2203
+ proof = get_flag(subsystem='polynomial')
2204
+ if proof:
2205
+ raise NotImplementedError("Provably correct factorization not implemented. Disable this error by wrapping your code in a `with proof.WithProof('polynomial', False):` block.")
2206
+
2207
+ R._singular_().set_ring()
2208
+ S = self._singular_().factorize()
2209
+ factors = S[1]
2210
+ exponents = S[2]
2211
+ v = sorted([(R(factors[i + 1]), Integer(exponents[i + 1]))
2212
+ for i in range(len(factors))])
2213
+ unit = R(1)
2214
+ for i in range(len(v)):
2215
+ if v[i][0].is_unit():
2216
+ unit = unit * v[i][0]
2217
+ del v[i]
2218
+ break
2219
+ F = sorted(Factorization(v, unit=unit))
2220
+ return F
2221
+
2222
+ @handle_AA_and_QQbar
2223
+ def lift(self, I):
2224
+ """
2225
+ Given an ideal `I = (f_1,...,f_r)` and some `g` (= ``self``) in `I`, find
2226
+ `s_1,...,s_r` such that `g = s_1 f_1 + ... + s_r f_r`.
2227
+
2228
+ ALGORITHM: Use Singular.
2229
+
2230
+ EXAMPLES::
2231
+
2232
+ sage: # needs sage.rings.real_mpfr
2233
+ sage: A.<x,y> = PolynomialRing(CC, 2, order='degrevlex')
2234
+ sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7])
2235
+ sage: f = x*y^13 + y^12
2236
+ sage: M = f.lift(I); M # needs sage.libs.singular
2237
+ [y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 + y^4]
2238
+ sage: sum(map(mul, zip(M, I.gens()))) == f # needs sage.libs.singular
2239
+ True
2240
+
2241
+ TESTS:
2242
+
2243
+ Check that this method works over ``QQbar`` (:issue:`25351`)::
2244
+
2245
+ sage: # needs sage.rings.number_field
2246
+ sage: A.<x,y> = QQbar[]
2247
+ sage: I = A.ideal([x^2 + y^2 - 1, x^2 - y^2])
2248
+ sage: f = 2*x^2 - 1
2249
+ sage: M = f.lift(I) # needs sage.libs.singular
2250
+ sage: sum(map(mul, zip(M, I.gens()))) == f # needs sage.libs.singular
2251
+ True
2252
+ """
2253
+ fs = self._singular_()
2254
+ Is = I._singular_()
2255
+ P = I.ring()
2256
+ try:
2257
+ M = Is.lift(fs)._sage_(P)
2258
+ except TypeError:
2259
+ raise ArithmeticError("f is not in I")
2260
+ return Sequence(M.list(), P, check=False, immutable=True)
2261
+
2262
+ @coerce_binop
2263
+ @handle_AA_and_QQbar
2264
+ def quo_rem(self, right):
2265
+ """
2266
+ Return quotient and remainder of ``self`` and ``right``.
2267
+
2268
+ EXAMPLES::
2269
+
2270
+ sage: R.<x,y> = CC[] # needs sage.rings.real_mpfr
2271
+ sage: f = y*x^2 + x + 1 # needs sage.rings.real_mpfr
2272
+ sage: f.quo_rem(x) # needs sage.libs.singular sage.rings.real_mpfr
2273
+ (x*y + 1.00000000000000, 1.00000000000000)
2274
+
2275
+ sage: R = QQ['a','b']['x','y','z']
2276
+ sage: p1 = R('a + (1+2*b)*x*y + (3-a^2)*z')
2277
+ sage: p2 = R('x-1')
2278
+ sage: p1.quo_rem(p2) # needs sage.libs.singular
2279
+ ((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a)
2280
+
2281
+ sage: R.<x,y> = Qp(5)[] # needs sage.rings.padics
2282
+ sage: x.quo_rem(y) # needs sage.libs.singular sage.rings.padics
2283
+ Traceback (most recent call last):
2284
+ ...
2285
+ TypeError: no conversion of this ring to a Singular ring defined
2286
+
2287
+ ALGORITHM: Use Singular.
2288
+
2289
+ TESTS:
2290
+
2291
+ Check that this method works over ``QQbar`` (:issue:`25351`)::
2292
+
2293
+ sage: R.<x,y> = QQbar[] # needs sage.rings.number_field
2294
+ sage: f = y*x^2 + x + 1 # needs sage.rings.number_field
2295
+ sage: f.quo_rem(x) # needs sage.libs.singular sage.rings.number_field
2296
+ (x*y + 1, 1)
2297
+ """
2298
+ R = self.parent()
2299
+ try:
2300
+ R._singular_().set_ring()
2301
+ except (TypeError, ImportError):
2302
+ f = self.parent().flattening_morphism()
2303
+ if f.domain() != f.codomain():
2304
+ g = f.section()
2305
+ q,r = f(self).quo_rem(f(right))
2306
+ return g(q), g(r)
2307
+ else:
2308
+ raise TypeError
2309
+ else:
2310
+ X = self._singular_().division(right._singular_())
2311
+ return R(X[1][1,1]), R(X[2][1])
2312
+
2313
+ @handle_AA_and_QQbar
2314
+ def resultant(self, other, variable=None):
2315
+ """
2316
+ Compute the resultant of ``self`` and ``other`` with respect
2317
+ to ``variable``.
2318
+
2319
+ If a second argument is not provided, the first variable of
2320
+ ``self.parent()`` is chosen.
2321
+
2322
+ For inexact rings or rings not available in Singular,
2323
+ this computes the determinant of the Sylvester matrix.
2324
+
2325
+ INPUT:
2326
+
2327
+ - ``other`` -- polynomial in ``self.parent()``
2328
+
2329
+ - ``variable`` -- (optional) variable (of type polynomial) in
2330
+ ``self.parent()``
2331
+
2332
+ EXAMPLES::
2333
+
2334
+ sage: P.<x,y> = PolynomialRing(QQ, 2)
2335
+ sage: a = x + y
2336
+ sage: b = x^3 - y^3
2337
+ sage: a.resultant(b) # needs sage.libs.singular
2338
+ -2*y^3
2339
+ sage: a.resultant(b, y) # needs sage.libs.singular
2340
+ 2*x^3
2341
+
2342
+ TESTS::
2343
+
2344
+ sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
2345
+ sage: P.<x,y> = MPolynomialRing_polydict_domain(QQ, 2, order='degrevlex')
2346
+ sage: a = x + y
2347
+ sage: b = x^3 - y^3
2348
+ sage: a.resultant(b) # needs sage.libs.singular
2349
+ -2*y^3
2350
+ sage: a.resultant(b, y) # needs sage.libs.singular
2351
+ 2*x^3
2352
+
2353
+ Check that :issue:`15061` is fixed::
2354
+
2355
+ sage: R.<x, y> = AA[] # needs sage.rings.number_field
2356
+ sage: (x^2 + 1).resultant(x^2 - y) # needs sage.libs.singular sage.rings.number_field
2357
+ y^2 + 2*y + 1
2358
+
2359
+ Test for :issue:`2693`::
2360
+
2361
+ sage: R.<x,y> = RR[]
2362
+ sage: p = x + y
2363
+ sage: q = x*y
2364
+ sage: p.resultant(q) # needs sage.libs.singular sage.modules
2365
+ -y^2
2366
+
2367
+ Check that this method works over QQbar (:issue:`25351`)::
2368
+
2369
+ sage: # needs sage.rings.number_field
2370
+ sage: P.<x,y> = QQbar[]
2371
+ sage: a = x + y
2372
+ sage: b = x^3 - y^3
2373
+ sage: a.resultant(b) # needs sage.libs.singular sage.modules
2374
+ (-2)*y^3
2375
+ sage: a.resultant(b, y) # needs sage.libs.singular sage.modules
2376
+ 2*x^3
2377
+ """
2378
+ R = self.parent()
2379
+ if variable is None:
2380
+ variable = R.gen(0)
2381
+ if R._has_singular and R.is_exact():
2382
+ rt = self._singular_().resultant(other._singular_(), variable._singular_())
2383
+ r = rt.sage_poly(R)
2384
+ else:
2385
+ r = self.sylvester_matrix(other, variable).det()
2386
+ if R.ngens() <= 1 and r.degree() <= 0:
2387
+ return R.base_ring()(r[0])
2388
+ else:
2389
+ return r
2390
+
2391
+ @coerce_binop
2392
+ @handle_AA_and_QQbar
2393
+ def subresultants(self, other, variable=None):
2394
+ r"""
2395
+ Return the nonzero subresultant polynomials of ``self`` and ``other``.
2396
+
2397
+ INPUT:
2398
+
2399
+ - ``other`` -- a polynomial
2400
+
2401
+ OUTPUT: list of polynomials in the same ring as ``self``
2402
+
2403
+ EXAMPLES::
2404
+
2405
+ sage: # needs sage.libs.singular sage.rings.number_field
2406
+ sage: R.<x,y> = QQbar[]
2407
+ sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1)
2408
+ sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1)
2409
+ sage: p.subresultants(q, y)
2410
+ [2*x^6 + (-22)*x^5 + 102*x^4 + (-274)*x^3 + 488*x^2 + (-552)*x + 288,
2411
+ -x^3 - x^2*y + 6*x^2 + 5*x*y + (-11)*x + (-6)*y + 6]
2412
+ sage: p.subresultants(q, x)
2413
+ [2*y^6 + (-22)*y^5 + 102*y^4 + (-274)*y^3 + 488*y^2 + (-552)*y + 288,
2414
+ x*y^2 + y^3 + (-5)*x*y + (-6)*y^2 + 6*x + 11*y - 6]
2415
+ """
2416
+ R = self.parent()
2417
+ if variable is None:
2418
+ x = R.gen(0)
2419
+ else:
2420
+ x = variable
2421
+ p = self.polynomial(x)
2422
+ q = other.polynomial(x)
2423
+ return [R(f) for f in p.subresultants(q)]
2424
+
2425
+ def reduce(self, I):
2426
+ """
2427
+ Reduce this polynomial by the polynomials in `I`.
2428
+
2429
+ INPUT:
2430
+
2431
+ - ``I`` -- list of polynomials or an ideal
2432
+
2433
+ EXAMPLES::
2434
+
2435
+ sage: # needs sage.rings.number_field
2436
+ sage: P.<x,y,z> = QQbar[]
2437
+ sage: f1 = -2 * x^2 + x^3
2438
+ sage: f2 = -2 * y + x * y
2439
+ sage: f3 = -x^2 + y^2
2440
+ sage: F = Ideal([f1, f2, f3])
2441
+ sage: g = x*y - 3*x*y^2
2442
+ sage: g.reduce(F) # needs sage.libs.singular
2443
+ (-6)*y^2 + 2*y
2444
+ sage: g.reduce(F.gens()) # needs sage.libs.singular
2445
+ (-6)*y^2 + 2*y
2446
+
2447
+ ::
2448
+
2449
+ sage: f = 3*x # needs sage.rings.number_field
2450
+ sage: f.reduce([2*x, y]) # needs sage.libs.singular sage.rings.number_field
2451
+ 0
2452
+
2453
+ ::
2454
+
2455
+ sage: # needs sage.libs.singular sage.rings.number_field
2456
+ sage: k.<w> = CyclotomicField(3)
2457
+ sage: A.<y9,y12,y13,y15> = PolynomialRing(k)
2458
+ sage: J = [y9 + y12]
2459
+ sage: f = y9 - y12; f.reduce(J)
2460
+ -2*y12
2461
+ sage: f = y13*y15; f.reduce(J)
2462
+ y13*y15
2463
+ sage: f = y13*y15 + y9 - y12; f.reduce(J)
2464
+ y13*y15 - 2*y12
2465
+
2466
+ Make sure the remainder returns the correct type, fixing :issue:`13903`::
2467
+
2468
+ sage: R.<y1,y2> = PolynomialRing(Qp(5), 2, order='lex') # needs sage.rings.padics
2469
+ sage: G = [y1^2 + y2^2, y1*y2 + y2^2, y2^3] # needs sage.rings.padics
2470
+ sage: type((y2^3).reduce(G)) # needs sage.libs.singular sage.rings.padics
2471
+ <class 'sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict'>
2472
+
2473
+ TESTS:
2474
+
2475
+ Verify that :issue:`34105` is fixed::
2476
+
2477
+ sage: R.<x,y> = AA[] # needs sage.rings.number_field
2478
+ sage: x.reduce(R.zero_ideal()) # needs sage.libs.singular sage.rings.number_field
2479
+ x
2480
+ """
2481
+ from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
2482
+
2483
+ k = self.base_ring()
2484
+ P = self.parent()
2485
+
2486
+ if isinstance(I, MPolynomialIdeal):
2487
+ I = I.gens()
2488
+
2489
+ if not k.is_field():
2490
+ raise TypeError("Can only reduce polynomials over fields.")
2491
+
2492
+ try:
2493
+ fs = self._singular_()
2494
+ Is = fs.parent().ideal(I)
2495
+ return P(fs.reduce(Is))
2496
+ except (NotImplementedError, TypeError):
2497
+ pass
2498
+
2499
+ I = [g for g in I if g]
2500
+ lI = len(I)
2501
+ r = P.zero()
2502
+ p = self
2503
+
2504
+ while p != 0:
2505
+ for i in range(lI):
2506
+ gi = I[i]
2507
+ plm = p.lm()
2508
+ gilm = gi.lm()
2509
+ if P.monomial_divides(gilm, plm):
2510
+ quot = p.lc()/gi.lc() * P.monomial_quotient(plm, gilm)
2511
+ p -= quot * gi
2512
+ break
2513
+ else:
2514
+ plt = p.lt()
2515
+ r += plt
2516
+ p -= plt
2517
+ return r
2518
+
2519
+
2520
+ ###############################################################
2521
+ # Useful for some geometry code.
2522
+ ###############################################################
2523
+
2524
+ def degree_lowest_rational_function(r, x):
2525
+ r"""
2526
+ Return the difference of valuations of ``r`` with respect to variable ``x``.
2527
+
2528
+ INPUT:
2529
+
2530
+ - ``r`` -- a multivariate rational function
2531
+
2532
+ - ``x`` -- a multivariate polynomial ring generator
2533
+
2534
+ OUTPUT: integer; the difference `val_x(p) - val_x(q)` where `r = p/q`
2535
+
2536
+ .. NOTE::
2537
+
2538
+ This function should be made a method of the
2539
+ :class:`FractionFieldElement` class.
2540
+
2541
+ EXAMPLES::
2542
+
2543
+ sage: R1 = PolynomialRing(FiniteField(5), 3, names=["a", "b", "c"])
2544
+ sage: F = FractionField(R1)
2545
+ sage: a,b,c = R1.gens()
2546
+ sage: f = 3*a*b^2*c^3 + 4*a*b*c
2547
+ sage: g = a^2*b*c^2 + 2*a^2*b^4*c^7
2548
+
2549
+ Consider the quotient
2550
+ `f/g = \frac{4 + 3 bc^{2}}{ac + 2 ab^{3}c^{6}}` (note the
2551
+ cancellation).
2552
+
2553
+ ::
2554
+
2555
+ sage: # needs sage.rings.finite_rings
2556
+ sage: r = f/g; r
2557
+ (-2*b*c^2 - 1)/(2*a*b^3*c^6 + a*c)
2558
+ sage: degree_lowest_rational_function(r, a)
2559
+ -1
2560
+ sage: degree_lowest_rational_function(r, b)
2561
+ 0
2562
+ sage: degree_lowest_rational_function(r, c)
2563
+ -1
2564
+ """
2565
+ from sage.rings.fraction_field import FractionField
2566
+ F = FractionField(r.parent())
2567
+ r = F(r)
2568
+ f = r.numerator().polynomial(x)
2569
+ g = r.denominator().polynomial(x)
2570
+ return f.valuation() - g.valuation()