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,2044 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Ring `\ZZ/n\ZZ` of integers modulo `n`
4
+
5
+ EXAMPLES::
6
+
7
+ sage: R = Integers(97)
8
+ sage: a = R(5)
9
+ sage: a**100000000000000000000000000000000000000000000000000000000000000
10
+ 61
11
+
12
+ This example illustrates the relation between
13
+ `\ZZ/p\ZZ` and `\GF{p}`. In
14
+ particular, there is a canonical map to `\GF{p}`, but not in
15
+ the other direction.
16
+
17
+ ::
18
+
19
+ sage: r = Integers(7)
20
+ sage: s = GF(7)
21
+ sage: r.has_coerce_map_from(s)
22
+ False
23
+ sage: s.has_coerce_map_from(r)
24
+ True
25
+ sage: s(1) + r(1)
26
+ 2
27
+ sage: parent(s(1) + r(1))
28
+ Finite Field of size 7
29
+ sage: parent(r(1) + s(1))
30
+ Finite Field of size 7
31
+
32
+ We list the elements of `\ZZ/3\ZZ`::
33
+
34
+ sage: R = Integers(3)
35
+ sage: list(R)
36
+ [0, 1, 2]
37
+
38
+ AUTHORS:
39
+
40
+ - William Stein (initial code)
41
+
42
+ - David Joyner (2005-12-22): most examples
43
+
44
+ - Robert Bradshaw (2006-08-24): convert to SageX (Cython)
45
+
46
+ - William Stein (2007-04-29): square_roots_of_one
47
+
48
+ - Simon King (2011-04-21): allow to prescribe a category
49
+
50
+ - Simon King (2013-09): Only allow to prescribe the category of fields
51
+
52
+ - Kyle Hofmann (2024-02): New implementation of root-finding
53
+ """
54
+
55
+ # ****************************************************************************
56
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
57
+ #
58
+ # This program is free software: you can redistribute it and/or modify
59
+ # it under the terms of the GNU General Public License as published by
60
+ # the Free Software Foundation, either version 2 of the License, or
61
+ # (at your option) any later version.
62
+ # https://www.gnu.org/licenses/
63
+ # ****************************************************************************
64
+
65
+
66
+ import sage.misc.prandom as random
67
+
68
+ from sage.arith.misc import factor
69
+ from sage.arith.misc import primitive_root
70
+ from sage.arith.misc import CRT_basis
71
+ from sage.rings.ring import Field
72
+ from sage.misc.mrange import cartesian_product_iterator
73
+ import sage.rings.abc
74
+ from sage.rings.finite_rings import integer_mod
75
+ import sage.rings.integer as integer
76
+ import sage.rings.integer_ring as integer_ring
77
+ import sage.rings.quotient_ring as quotient_ring
78
+
79
+ try:
80
+ from sage.libs.pari import pari
81
+ from cypari2.handle_error import PariError
82
+ except ImportError:
83
+ class PariError(Exception):
84
+ pass
85
+
86
+ from sage.misc.cachefunc import cached_method
87
+
88
+ from sage.structure.factory import UniqueFactory
89
+ from sage.structure.richcmp import richcmp, richcmp_method
90
+
91
+ from sage.interfaces.abc import GapElement
92
+
93
+
94
+ class IntegerModFactory(UniqueFactory):
95
+ r"""
96
+ Return the quotient ring `\ZZ / n\ZZ`.
97
+
98
+ INPUT:
99
+
100
+ - ``order`` -- integer (default: 0); positive or negative
101
+ - ``is_field`` -- boolean (default: ``False``); assert that the order is
102
+ prime and hence the quotient ring belongs to the category of fields
103
+ - ``category`` -- (optional) the category that the quotient ring belongs to
104
+
105
+ .. NOTE::
106
+
107
+ The optional argument ``is_field`` is not part of the cache key.
108
+ Hence, this factory will create precisely one instance of `\ZZ /
109
+ n\ZZ`. However, if ``is_field`` is true, then a previously created
110
+ instance of the quotient ring will be updated to be in the category of
111
+ fields.
112
+
113
+ **Use with care!** Erroneously putting `\ZZ / n\ZZ` into the category
114
+ of fields may have consequences that can compromise a whole Sage
115
+ session, so that a restart will be needed.
116
+
117
+ EXAMPLES::
118
+
119
+ sage: IntegerModRing(15)
120
+ Ring of integers modulo 15
121
+ sage: IntegerModRing(7)
122
+ Ring of integers modulo 7
123
+ sage: IntegerModRing(-100)
124
+ Ring of integers modulo 100
125
+
126
+ Note that you can also use ``Integers``, which is a
127
+ synonym for ``IntegerModRing``.
128
+
129
+ ::
130
+
131
+ sage: Integers(18)
132
+ Ring of integers modulo 18
133
+ sage: Integers() is Integers(0) is ZZ
134
+ True
135
+
136
+ .. NOTE::
137
+
138
+ Testing whether a quotient ring `\ZZ / n\ZZ` is a field can of
139
+ course be very costly. By default, it is not tested whether `n`
140
+ is prime or not, in contrast to
141
+ :func:`~sage.rings.finite_rings.finite_field_constructor.GF`. If the user
142
+ is sure that the modulus is prime and wants to avoid a primality
143
+ test, (s)he can provide ``category=Fields()`` when constructing
144
+ the quotient ring, and then the result will behave like a field.
145
+ If the category is not provided during initialisation, and it is
146
+ found out later that the ring is in fact a field, then the category
147
+ will be changed at runtime, having the same effect as providing
148
+ ``Fields()`` during initialisation.
149
+
150
+ EXAMPLES::
151
+
152
+ sage: R = IntegerModRing(5)
153
+ sage: R.category()
154
+ Join of Category of finite commutative rings
155
+ and Category of subquotients of monoids
156
+ and Category of quotients of semigroups
157
+ and Category of finite enumerated sets
158
+ sage: R in Fields()
159
+ True
160
+ sage: R.category()
161
+ Join of Category of finite enumerated fields
162
+ and Category of subquotients of monoids
163
+ and Category of quotients of semigroups
164
+ sage: S = IntegerModRing(5, is_field=True)
165
+ sage: S is R
166
+ True
167
+
168
+ .. WARNING::
169
+
170
+ If the optional argument ``is_field`` was used by mistake, there is
171
+ currently no way to revert its impact, even though
172
+ :meth:`IntegerModRing_generic.is_field` with the optional argument
173
+ ``proof=True`` would return the correct answer. So, prescribe
174
+ ``is_field=True`` only if you know what your are doing!
175
+
176
+ EXAMPLES::
177
+
178
+ sage: R = IntegerModRing(33, is_field=True)
179
+ sage: R in Fields()
180
+ True
181
+ sage: R.is_field()
182
+ True
183
+
184
+ If the optional argument `proof=True` is provided, primality is tested and
185
+ the mistaken category assignment is reported::
186
+
187
+ sage: R.is_field(proof=True)
188
+ Traceback (most recent call last):
189
+ ...
190
+ ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED!
191
+ The order 33 is not prime, but this ring has been put
192
+ into the category of fields. This may already have consequences
193
+ in other parts of Sage. Either it was a mistake of the user,
194
+ or a probabilistic primality test has failed.
195
+ In the latter case, please inform the developers.
196
+
197
+ However, the mistaken assignment is not automatically corrected::
198
+
199
+ sage: R in Fields()
200
+ True
201
+
202
+ To avoid side-effects of this test on other tests, we clear the cache of
203
+ the ring factory::
204
+
205
+ sage: IntegerModRing._cache.clear()
206
+ """
207
+ def get_object(self, version, key, extra_args):
208
+ out = super().get_object(version, key, extra_args)
209
+ category = extra_args.get('category', None)
210
+ if category is not None:
211
+ out._refine_category_(category)
212
+ out._factory_data[3]['category'] = category
213
+ return out
214
+
215
+ def create_key_and_extra_args(self, order=0, is_field=False, category=None):
216
+ """
217
+ An integer mod ring is specified uniquely by its order.
218
+
219
+ EXAMPLES::
220
+
221
+ sage: Zmod.create_key_and_extra_args(7)
222
+ (7, {})
223
+ sage: Zmod.create_key_and_extra_args(7, True)
224
+ (7, {'category': Category of fields})
225
+ """
226
+ if is_field:
227
+ from sage.categories.fields import Fields
228
+ return order, {'category': Fields()}
229
+ return order, {}
230
+
231
+ def create_object(self, version, order, **kwds):
232
+ """
233
+ EXAMPLES::
234
+
235
+ sage: R = Integers(10)
236
+ sage: TestSuite(R).run() # indirect doctest
237
+ """
238
+ if isinstance(order, tuple):
239
+ # this is for unpickling old data
240
+ order, category = order
241
+ kwds.setdefault('category', category)
242
+ if order < 0:
243
+ order = -order
244
+ if order == 0:
245
+ return integer_ring.IntegerRing(**kwds)
246
+ else:
247
+ return IntegerModRing_generic(order, **kwds)
248
+
249
+
250
+ Zmod = Integers = IntegerModRing = IntegerModFactory("IntegerModRing")
251
+
252
+
253
+ from sage.categories.noetherian_rings import NoetherianRings
254
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
255
+ from sage.categories.category import JoinCategory
256
+ default_category = JoinCategory((NoetherianRings(), FiniteEnumeratedSets()))
257
+ ZZ = integer_ring.IntegerRing()
258
+
259
+
260
+ def _unit_gens_primepowercase(p, r):
261
+ r"""
262
+ Return a list of generators for `(\ZZ/p^r\ZZ)^*` and their orders.
263
+
264
+ EXAMPLES::
265
+
266
+ sage: from sage.rings.finite_rings.integer_mod_ring import _unit_gens_primepowercase
267
+ sage: _unit_gens_primepowercase(2, 3)
268
+ [(7, 2), (5, 2)]
269
+ sage: _unit_gens_primepowercase(17, 1) # needs sage.libs.pari
270
+ [(3, 16)]
271
+ sage: _unit_gens_primepowercase(3, 3) # needs sage.libs.pari
272
+ [(2, 18)]
273
+ """
274
+ pr = p**r
275
+ if p == 2:
276
+ if r == 1:
277
+ return []
278
+ if r == 2:
279
+ return [(integer_mod.Mod(3, 4), integer.Integer(2))]
280
+ return [(integer_mod.Mod(-1, pr), integer.Integer(2)),
281
+ (integer_mod.Mod(5, pr), integer.Integer(2**(r - 2)))]
282
+
283
+ # odd prime
284
+ return [(integer_mod.Mod(primitive_root(pr, check=False), pr),
285
+ integer.Integer(p**(r - 1) * (p - 1)))]
286
+
287
+
288
+ @richcmp_method
289
+ class IntegerModRing_generic(quotient_ring.QuotientRing_generic, sage.rings.abc.IntegerModRing):
290
+ """
291
+ The ring of integers modulo `N`.
292
+
293
+ INPUT:
294
+
295
+ - ``order`` -- integer
296
+
297
+ - ``category`` -- a subcategory of ``CommutativeRings()`` (the default)
298
+
299
+ OUTPUT: the ring of integers modulo `N`
300
+
301
+ EXAMPLES:
302
+
303
+ First we compute with integers modulo `29`.
304
+
305
+ ::
306
+
307
+ sage: FF = IntegerModRing(29)
308
+ sage: FF
309
+ Ring of integers modulo 29
310
+ sage: FF.category()
311
+ Join of Category of finite commutative rings
312
+ and Category of subquotients of monoids
313
+ and Category of quotients of semigroups
314
+ and Category of finite enumerated sets
315
+ sage: FF.is_field()
316
+ True
317
+ sage: FF.characteristic()
318
+ 29
319
+ sage: FF.order()
320
+ 29
321
+
322
+ sage: # needs sage.groups sage.libs.pari sage.modules
323
+ sage: gens = FF.unit_gens()
324
+ sage: a = gens[0]
325
+ sage: a
326
+ 2
327
+ sage: a.is_square()
328
+ False
329
+ sage: def pow(i): return a**i
330
+ sage: [pow(i) for i in range(16)]
331
+ [1, 2, 4, 8, 16, 3, 6, 12, 24, 19, 9, 18, 7, 14, 28, 27]
332
+ sage: TestSuite(FF).run()
333
+
334
+ We have seen above that an integer mod ring is, by default, not
335
+ initialised as an object in the category of fields. However, one
336
+ can force it to be. Moreover, testing containment in the category
337
+ of fields my re-initialise the category of the integer mod ring::
338
+
339
+ sage: F19 = IntegerModRing(19, is_field=True)
340
+ sage: F19.category().is_subcategory(Fields())
341
+ True
342
+ sage: F23 = IntegerModRing(23)
343
+ sage: F23.category().is_subcategory(Fields())
344
+ False
345
+ sage: F23 in Fields()
346
+ True
347
+ sage: F23.category().is_subcategory(Fields())
348
+ True
349
+ sage: TestSuite(F19).run()
350
+ sage: TestSuite(F23).run()
351
+
352
+ By :issue:`15229`, there is a unique instance of the
353
+ integral quotient ring of a given order. Using the
354
+ :func:`IntegerModRing` factory twice, and using
355
+ ``is_field=True`` the second time, will update the
356
+ category of the unique instance::
357
+
358
+ sage: F31a = IntegerModRing(31)
359
+ sage: F31a.category().is_subcategory(Fields())
360
+ False
361
+ sage: F31b = IntegerModRing(31, is_field=True)
362
+ sage: F31a is F31b
363
+ True
364
+ sage: F31a.category().is_subcategory(Fields())
365
+ True
366
+
367
+ Next we compute with the integers modulo `16`.
368
+
369
+ ::
370
+
371
+ sage: Z16 = IntegerModRing(16)
372
+ sage: Z16.category()
373
+ Join of Category of finite commutative rings
374
+ and Category of subquotients of monoids
375
+ and Category of quotients of semigroups
376
+ and Category of finite enumerated sets
377
+ sage: Z16.is_field()
378
+ False
379
+ sage: Z16.order()
380
+ 16
381
+ sage: Z16.characteristic()
382
+ 16
383
+
384
+ sage: # needs sage.groups sage.modules
385
+ sage: gens = Z16.unit_gens()
386
+ sage: gens
387
+ (15, 5)
388
+ sage: a = gens[0]
389
+ sage: b = gens[1]
390
+ sage: def powa(i): return a**i
391
+ sage: def powb(i): return b**i
392
+ sage: gp_exp = FF.unit_group_exponent()
393
+ sage: gp_exp
394
+ 28
395
+ sage: [powa(i) for i in range(15)]
396
+ [1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1]
397
+ sage: [powb(i) for i in range(15)]
398
+ [1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9]
399
+ sage: a.multiplicative_order()
400
+ 2
401
+ sage: b.multiplicative_order()
402
+ 4
403
+
404
+ sage: TestSuite(Z16).run()
405
+
406
+ Saving and loading::
407
+
408
+ sage: R = Integers(100000)
409
+ sage: TestSuite(R).run() # long time (17s on sage.math, 2011)
410
+
411
+ Testing ideals and quotients::
412
+
413
+ sage: Z10 = Integers(10)
414
+ sage: I = Z10.principal_ideal(0)
415
+ sage: Z10.quotient(I) == Z10
416
+ True
417
+ sage: I = Z10.principal_ideal(2)
418
+ sage: Z10.quotient(I) == Z10
419
+ False
420
+ sage: I.is_prime()
421
+ True
422
+
423
+ ::
424
+
425
+ sage: R = IntegerModRing(97)
426
+ sage: a = R(5)
427
+ sage: a**(10^62)
428
+ 61
429
+ """
430
+ def __init__(self, order, cache=None, category=None):
431
+ """
432
+ Create with the command ``IntegerModRing(order)``.
433
+
434
+ TESTS::
435
+
436
+ sage: FF = IntegerModRing(29)
437
+ sage: TestSuite(FF).run()
438
+ sage: F19 = IntegerModRing(19, is_field=True)
439
+ sage: TestSuite(F19).run()
440
+ sage: F23 = IntegerModRing(23)
441
+ sage: F23 in Fields()
442
+ True
443
+ sage: TestSuite(F23).run()
444
+ sage: Z16 = IntegerModRing(16)
445
+ sage: TestSuite(Z16).run()
446
+ sage: R = Integers(100000)
447
+ sage: TestSuite(R).run() # long time (17s on sage.math, 2011)
448
+
449
+ sage: R = IntegerModRing(18)
450
+ sage: R.is_finite()
451
+ True
452
+
453
+ TESTS::
454
+
455
+ sage: Integers(8).is_noetherian()
456
+ True
457
+ """
458
+ order = ZZ(order)
459
+ if order <= 0:
460
+ raise ZeroDivisionError("order must be positive")
461
+ self.__order = order
462
+ self._pyx_order = integer_mod.NativeIntStruct(order)
463
+ global default_category
464
+ if category is None:
465
+ category = default_category
466
+ else:
467
+ # If the category is given, e.g., as Fields(), then we still
468
+ # know that the result will also live in default_category.
469
+ # Hence, we use the join of the default and the given category.
470
+ category = category.join([category, default_category])
471
+ # Give the generator a 'name' to make quotients work. The
472
+ # name 'x' is used because it's also used for the ring of
473
+ # integers: see the __init__ method for IntegerRing_class in
474
+ # sage/rings/integer_ring.pyx.
475
+ quotient_ring.QuotientRing_generic.__init__(self, ZZ, ZZ.ideal(order),
476
+ names=('x',),
477
+ category=category)
478
+ # We want that the ring is its own base ring.
479
+ self._base = self
480
+ if cache is None:
481
+ cache = order < 500
482
+ if cache:
483
+ self._precompute_table()
484
+ self._zero_element = integer_mod.IntegerMod(self, 0)
485
+ self._one_element = integer_mod.IntegerMod(self, 1)
486
+
487
+ def _macaulay2_init_(self, macaulay2=None) -> str:
488
+ """
489
+ EXAMPLES::
490
+
491
+ sage: macaulay2(Integers(7)) # optional - macaulay2
492
+ ZZ
493
+ --
494
+ 7
495
+
496
+ ::
497
+
498
+ sage: macaulay2(Integers(10)) # optional - macaulay2
499
+ ZZ[]
500
+ ----
501
+ 10
502
+ """
503
+ return "ZZ/{}".format(self.order())
504
+
505
+ def _axiom_init_(self) -> str:
506
+ """
507
+ Return a string representation of ``self`` in (Pan)Axiom.
508
+
509
+ EXAMPLES::
510
+
511
+ sage: Z7 = Integers(7)
512
+ sage: Z7._axiom_init_()
513
+ 'IntegerMod(7)'
514
+
515
+ sage: axiom(Z7) #optional - axiom
516
+ IntegerMod 7
517
+
518
+ sage: fricas(Z7) #optional - fricas
519
+ IntegerMod(7)
520
+ """
521
+ return 'IntegerMod({})'.format(self.order())
522
+
523
+ _fricas_init_ = _axiom_init_
524
+
525
+ def krull_dimension(self):
526
+ """
527
+ Return the Krull dimension of ``self``.
528
+
529
+ EXAMPLES::
530
+
531
+ sage: Integers(18).krull_dimension()
532
+ 0
533
+ """
534
+ return integer.Integer(0)
535
+
536
+ def extension(self, poly, name=None, names=None, **kwds):
537
+ """
538
+ Return an algebraic extension of ``self``. See
539
+ :meth:`sage.rings.ring.CommutativeRing.extension()` for more
540
+ information.
541
+
542
+ EXAMPLES::
543
+
544
+ sage: R.<t> = QQ[]
545
+ sage: Integers(8).extension(t^2 - 3)
546
+ Univariate Quotient Polynomial Ring in t
547
+ over Ring of integers modulo 8 with modulus t^2 + 5
548
+ """
549
+ if self.modulus() == 1:
550
+ return self
551
+
552
+ from sage.rings.ring import CommutativeRing
553
+ return CommutativeRing.extension(self, poly, name, names, **kwds)
554
+
555
+ @cached_method
556
+ def is_prime_field(self) -> bool:
557
+ """
558
+ Return ``True`` if the order is prime.
559
+
560
+ EXAMPLES::
561
+
562
+ sage: Zmod(7).is_prime_field()
563
+ True
564
+ sage: Zmod(8).is_prime_field()
565
+ False
566
+ """
567
+ return self.__order.is_prime()
568
+
569
+ def _precompute_table(self) -> None:
570
+ """
571
+ Compute a table of elements so that elements are unique.
572
+
573
+ EXAMPLES::
574
+
575
+ sage: R = Zmod(500); R._precompute_table()
576
+ sage: R(7) + R(13) is R(3) + R(17)
577
+ True
578
+ """
579
+ self._pyx_order.precompute_table(self)
580
+
581
+ def list_of_elements_of_multiplicative_group(self) -> list:
582
+ """
583
+ Return a list of all invertible elements, as python ints.
584
+
585
+ EXAMPLES::
586
+
587
+ sage: R = Zmod(12)
588
+ sage: L = R.list_of_elements_of_multiplicative_group(); L
589
+ [1, 5, 7, 11]
590
+ sage: type(L[0])
591
+ <... 'int'>
592
+ sage: Zmod(1).list_of_elements_of_multiplicative_group()
593
+ [0]
594
+ """
595
+ import sage.rings.fast_arith as a
596
+ if self.__order <= 46340: # todo: don't hard code
597
+ gcd = a.arith_int().gcd_int
598
+ elif self.__order <= 2147483647: # todo: don't hard code
599
+ gcd = a.arith_llong().gcd_longlong
600
+ else:
601
+ raise NotImplementedError("list_of_elements_of_multiplicative_group() is not implemented for large moduli")
602
+ N = self.__order
603
+ # Don't use N.coprime_integers() here because we want Python ints
604
+ return [i for i in range(N) if gcd(i, N) == 1]
605
+
606
+ @cached_method
607
+ def multiplicative_subgroups(self):
608
+ r"""
609
+ Return generators for each subgroup of `(\ZZ/N\ZZ)^*`.
610
+
611
+ EXAMPLES::
612
+
613
+ sage: # optional - gap_package_polycyclic, needs sage.groups sage.libs.pari sage.modules
614
+ sage: Integers(5).multiplicative_subgroups()
615
+ ((2,), (4,), ())
616
+ sage: Integers(15).multiplicative_subgroups()
617
+ ((11, 7), (11, 4), (2,), (11,), (14,), (7,), (4,), ())
618
+ sage: Integers(2).multiplicative_subgroups()
619
+ ((),)
620
+ sage: len(Integers(341).multiplicative_subgroups())
621
+ 80
622
+
623
+ TESTS::
624
+
625
+ sage: # needs sage.groups sage.modules
626
+ sage: IntegerModRing(1).multiplicative_subgroups()
627
+ ((),)
628
+ sage: IntegerModRing(2).multiplicative_subgroups()
629
+ ((),)
630
+ sage: IntegerModRing(3).multiplicative_subgroups() # optional - gap_package_polycyclic
631
+ ((2,), ())
632
+ """
633
+ return tuple(tuple(g.value() for g in H.gens())
634
+ for H in self.unit_group().subgroups())
635
+
636
+ def is_integral_domain(self, proof=None):
637
+ """
638
+ Return ``True`` if and only if the order of ``self`` is prime.
639
+
640
+ EXAMPLES::
641
+
642
+ sage: Integers(389).is_integral_domain()
643
+ True
644
+ sage: Integers(389^2).is_integral_domain() # needs sage.libs.pari
645
+ False
646
+
647
+ TESTS:
648
+
649
+ Check that :issue:`17453` is fixed::
650
+
651
+ sage: R = Zmod(5)
652
+ sage: R in IntegralDomains()
653
+ True
654
+ """
655
+ return self.is_field(proof)
656
+
657
+ def is_unique_factorization_domain(self, proof=None):
658
+ """
659
+ Return ``True`` if and only if the order of ``self`` is prime.
660
+
661
+ EXAMPLES::
662
+
663
+ sage: Integers(389).is_unique_factorization_domain()
664
+ True
665
+ sage: Integers(389^2).is_unique_factorization_domain() # needs sage.libs.pari
666
+ False
667
+ """
668
+ return self.is_field(proof)
669
+
670
+ @cached_method
671
+ def is_field(self, proof=None):
672
+ r"""
673
+ Return ``True`` precisely if the order is prime.
674
+
675
+ INPUT:
676
+
677
+ - ``proof`` -- boolean or ``None`` (default). If ``False``, then test
678
+ whether the category of the quotient is a subcategory of
679
+ ``Fields()``, or do a probabilistic primality test. If ``None``, then
680
+ test the category and then do a primality test according to the
681
+ global arithmetic proof settings. If ``True``, do a deterministic
682
+ primality test.
683
+
684
+ If it is found (perhaps probabilistically) that the ring is a field,
685
+ then the category of the ring is refined to include the category
686
+ of fields. This may change the Python class of the ring!
687
+
688
+ EXAMPLES::
689
+
690
+ sage: R = IntegerModRing(18)
691
+ sage: R.is_field()
692
+ False
693
+ sage: FF = IntegerModRing(17)
694
+ sage: FF.is_field()
695
+ True
696
+
697
+ By :issue:`15229`, the category of the ring is refined,
698
+ if it is found that the ring is in fact a field::
699
+
700
+ sage: R = IntegerModRing(127)
701
+ sage: R.category()
702
+ Join of Category of finite commutative rings
703
+ and Category of subquotients of monoids
704
+ and Category of quotients of semigroups
705
+ and Category of finite enumerated sets
706
+ sage: R.is_field()
707
+ True
708
+ sage: R.category()
709
+ Join of Category of finite enumerated fields
710
+ and Category of subquotients of monoids
711
+ and Category of quotients of semigroups
712
+
713
+ It is possible to mistakenly put `\ZZ/n\ZZ` into the category of fields.
714
+ In this case, :meth:`is_field` will return ``True`` without performing a
715
+ primality check. However, if the optional argument ``proof=True`` is
716
+ provided, primality is tested and the mistake is uncovered in a warning
717
+ message::
718
+
719
+ sage: R = IntegerModRing(21, is_field=True)
720
+ sage: R.is_field()
721
+ True
722
+ sage: R.is_field(proof=True)
723
+ Traceback (most recent call last):
724
+ ...
725
+ ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED!
726
+ The order 21 is not prime, but this ring has been put
727
+ into the category of fields. This may already have consequences
728
+ in other parts of Sage. Either it was a mistake of the user,
729
+ or a probabilistic primality test has failed.
730
+ In the latter case, please inform the developers.
731
+
732
+ To avoid side-effects of this test on other tests, we clear the cache
733
+ of the ring factory::
734
+
735
+ sage: IntegerModRing._cache.clear()
736
+ """
737
+ from sage.categories.fields import Fields
738
+ if not proof:
739
+ if self.category().is_subcategory(Fields()):
740
+ return True
741
+ is_prime = self.order().is_prime(proof=proof)
742
+ if is_prime:
743
+ self._refine_category_(Fields())
744
+ self._factory_data[3]['category'] = Fields()
745
+ else:
746
+ if self.category().is_subcategory(Fields()):
747
+ raise ValueError(("THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED!\n"
748
+ "The order {} is not prime, but this ring has been put\n"
749
+ "into the category of fields. This may already have consequences\n"
750
+ "in other parts of Sage. Either it was a mistake of the user,\n"
751
+ "or a probabilistic primality test has failed.\n"
752
+ "In the latter case, please inform the developers.").format(self.order()))
753
+ return is_prime
754
+
755
+ @cached_method
756
+ def field(self):
757
+ """
758
+ If this ring is a field, return the corresponding field as a finite
759
+ field, which may have extra functionality and structure. Otherwise,
760
+ raise a :exc:`ValueError`.
761
+
762
+ EXAMPLES::
763
+
764
+ sage: R = Integers(7); R
765
+ Ring of integers modulo 7
766
+ sage: R.field()
767
+ Finite Field of size 7
768
+ sage: R = Integers(9)
769
+ sage: R.field()
770
+ Traceback (most recent call last):
771
+ ...
772
+ ValueError: self must be a field
773
+ """
774
+ try:
775
+ return self.__field
776
+ except AttributeError:
777
+ if not self.is_field():
778
+ raise ValueError("self must be a field")
779
+ from . import finite_field_constructor
780
+ k = finite_field_constructor.FiniteField(self.order())
781
+ self.__field = k
782
+ return k
783
+
784
+ def _pseudo_fraction_field(self):
785
+ """
786
+ If ``self`` is composite, we may still want to do division by elements
787
+ of ``self``.
788
+
789
+ EXAMPLES::
790
+
791
+ sage: Integers(15).fraction_field()
792
+ Traceback (most recent call last):
793
+ ...
794
+ TypeError: self must be an integral domain.
795
+ sage: Integers(15)._pseudo_fraction_field()
796
+ Ring of integers modulo 15
797
+ sage: R.<x> = Integers(15)[]
798
+ sage: (x+5)/2
799
+ 8*x + 10
800
+
801
+ This should be very fast::
802
+
803
+ sage: R.<x> = Integers(next_prime(10^101)*next_prime(10^100))[] # needs sage.libs.pari
804
+ sage: x / R.base_ring()(2) # needs sage.libs.pari
805
+ 500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000401*x
806
+ """
807
+ return self
808
+
809
+ @cached_method
810
+ def multiplicative_group_is_cyclic(self):
811
+ """
812
+ Return ``True`` if the multiplicative group of this field is cyclic.
813
+ This is the case exactly when the order is less than 8, a power
814
+ of an odd prime, or twice a power of an odd prime.
815
+
816
+ EXAMPLES::
817
+
818
+ sage: R = Integers(7); R
819
+ Ring of integers modulo 7
820
+ sage: R.multiplicative_group_is_cyclic()
821
+ True
822
+ sage: R = Integers(9)
823
+ sage: R.multiplicative_group_is_cyclic() # needs sage.libs.pari
824
+ True
825
+ sage: Integers(8).multiplicative_group_is_cyclic()
826
+ False
827
+ sage: Integers(4).multiplicative_group_is_cyclic()
828
+ True
829
+ sage: Integers(25*3).multiplicative_group_is_cyclic() # needs sage.libs.pari
830
+ False
831
+
832
+ We test that :issue:`5250` is fixed::
833
+
834
+ sage: Integers(162).multiplicative_group_is_cyclic() # needs sage.libs.pari
835
+ True
836
+ """
837
+ n = self.order()
838
+ if n < 8:
839
+ return True
840
+
841
+ if n % 4 == 0:
842
+ return False # know n > 7, so n=4 case not a problem
843
+ if n % 4 == 2:
844
+ n = n // 2
845
+
846
+ return n.is_prime_power()
847
+
848
+ @cached_method
849
+ def multiplicative_generator(self):
850
+ """
851
+ Return a generator for the multiplicative group of this ring,
852
+ assuming the multiplicative group is cyclic.
853
+
854
+ Use the unit_gens function to obtain generators even in the
855
+ non-cyclic case.
856
+
857
+ EXAMPLES::
858
+
859
+ sage: # needs sage.groups sage.libs.pari
860
+ sage: R = Integers(7); R
861
+ Ring of integers modulo 7
862
+ sage: R.multiplicative_generator()
863
+ 3
864
+ sage: R = Integers(9)
865
+ sage: R.multiplicative_generator()
866
+ 2
867
+ sage: Integers(8).multiplicative_generator()
868
+ Traceback (most recent call last):
869
+ ...
870
+ ValueError: multiplicative group of this ring is not cyclic
871
+ sage: Integers(4).multiplicative_generator()
872
+ 3
873
+ sage: Integers(25*3).multiplicative_generator()
874
+ Traceback (most recent call last):
875
+ ...
876
+ ValueError: multiplicative group of this ring is not cyclic
877
+ sage: Integers(25*3).unit_gens()
878
+ (26, 52)
879
+ sage: Integers(162).unit_gens()
880
+ (83,)
881
+ """
882
+ try:
883
+ return self.__mult_gen
884
+ except AttributeError:
885
+ if self.is_field():
886
+ a = self(self.field().multiplicative_generator())
887
+ self.__mult_gen = a
888
+ return a
889
+ if self.multiplicative_group_is_cyclic():
890
+ v = self.unit_gens()
891
+ if len(v) != 1:
892
+ raise ArithmeticError
893
+ return v[0]
894
+
895
+ raise ValueError("multiplicative group of this ring is not cyclic")
896
+
897
+ def quadratic_nonresidue(self):
898
+ """
899
+ Return a quadratic non-residue in ``self``.
900
+
901
+ EXAMPLES::
902
+
903
+ sage: R = Integers(17)
904
+ sage: R.quadratic_nonresidue() # needs sage.libs.pari
905
+ 3
906
+ sage: R(3).is_square()
907
+ False
908
+ """
909
+ try:
910
+ return self._nonresidue
911
+ except AttributeError:
912
+ for a in self:
913
+ if not a.is_square():
914
+ self._nonresidue = a
915
+ return a
916
+
917
+ def square_roots_of_one(self):
918
+ """
919
+ Return all square roots of 1 in self, i.e., all solutions to
920
+ `x^2 - 1 = 0`.
921
+
922
+ OUTPUT: the square roots of 1 in ``self`` as a tuple
923
+
924
+ EXAMPLES::
925
+
926
+ sage: R = Integers(2^10)
927
+ sage: [x for x in R if x^2 == 1]
928
+ [1, 511, 513, 1023]
929
+ sage: R.square_roots_of_one()
930
+ (1, 511, 513, 1023)
931
+
932
+ ::
933
+
934
+ sage: # needs sage.libs.pari
935
+ sage: v = Integers(9*5).square_roots_of_one(); v
936
+ (1, 19, 26, 44)
937
+ sage: [x^2 for x in v]
938
+ [1, 1, 1, 1]
939
+ sage: v = Integers(9*5*8).square_roots_of_one(); v
940
+ (1, 19, 71, 89, 91, 109, 161, 179, 181, 199, 251, 269, 271, 289, 341, 359)
941
+ sage: [x^2 for x in v]
942
+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
943
+ """
944
+ try:
945
+ return self.__square_roots_of_one
946
+ except AttributeError:
947
+ pass
948
+ n = self.__order
949
+ if n.is_prime_power():
950
+ if n % 2 == 0:
951
+ # power of 2
952
+ if n == 2:
953
+ v = [self(1)]
954
+ elif n == 4:
955
+ v = [self(1), self(3)]
956
+ else: # n >= 8
957
+ half_ord = n // 2
958
+ v = [self(1), self(-1),
959
+ self(half_ord - 1), self(half_ord + 1)]
960
+ else:
961
+ v = [self(1), self(-1)]
962
+ else:
963
+ # Reduce to the prime power case.
964
+ F = self.factored_order()
965
+ vmod = []
966
+ moduli = []
967
+ for p, e in F:
968
+ k = p**e
969
+ R = IntegerModRing(p**e)
970
+ w = [self(x) for x in R.square_roots_of_one()]
971
+ vmod.append(w)
972
+ moduli.append(k)
973
+ # Now combine in all possible ways using the CRT
974
+ basis = CRT_basis(moduli)
975
+ from sage.misc.mrange import cartesian_product_iterator
976
+ v = []
977
+ for x in cartesian_product_iterator(vmod):
978
+ # x is a specific choice of roots modulo each prime power divisor
979
+ a = sum([basis[i] * x[i] for i in range(len(x))])
980
+ v.append(a)
981
+
982
+ v.sort()
983
+ v = tuple(v)
984
+ self.__square_roots_of_one = v
985
+ return v
986
+
987
+ @cached_method
988
+ def factored_order(self):
989
+ """
990
+ EXAMPLES::
991
+
992
+ sage: R = IntegerModRing(18)
993
+ sage: FF = IntegerModRing(17)
994
+ sage: R.factored_order()
995
+ 2 * 3^2
996
+ sage: FF.factored_order()
997
+ 17
998
+ """
999
+ return factor(self.__order, int_=(self.__order < 2**31))
1000
+
1001
+ def factored_unit_order(self):
1002
+ r"""
1003
+ Return a list of :class:`Factorization` objects, each the factorization
1004
+ of the order of the units in a `\ZZ / p^n \ZZ` component of this group
1005
+ (using the Chinese Remainder Theorem).
1006
+
1007
+ EXAMPLES::
1008
+
1009
+ sage: R = Integers(8*9*25*17*29)
1010
+ sage: R.factored_unit_order()
1011
+ [2^2, 2 * 3, 2^2 * 5, 2^4, 2^2 * 7]
1012
+ """
1013
+ ans = []
1014
+ from sage.structure.factorization import Factorization
1015
+ for p, e in self.factored_order():
1016
+ ans.append(Factorization([(p, e - 1)]) *
1017
+ factor(p - 1, int_=(self.__order < 2**31)))
1018
+ return ans
1019
+
1020
+ def characteristic(self):
1021
+ """
1022
+ EXAMPLES::
1023
+
1024
+ sage: R = IntegerModRing(18)
1025
+ sage: FF = IntegerModRing(17)
1026
+ sage: FF.characteristic()
1027
+ 17
1028
+ sage: R.characteristic()
1029
+ 18
1030
+ """
1031
+ return self.__order
1032
+
1033
+ def _repr_(self):
1034
+ """
1035
+ String representation.
1036
+
1037
+ EXAMPLES::
1038
+
1039
+ sage: Zmod(87)
1040
+ Ring of integers modulo 87
1041
+ """
1042
+ return "Ring of integers modulo {}".format(self.__order)
1043
+
1044
+ def _latex_(self):
1045
+ r"""
1046
+ Latex representation.
1047
+
1048
+ EXAMPLES::
1049
+
1050
+ sage: latex(Zmod(87))
1051
+ \ZZ/87\ZZ
1052
+ """
1053
+ return "\\ZZ/{}\\ZZ".format(self.__order)
1054
+
1055
+ def modulus(self):
1056
+ r"""
1057
+ Return the polynomial `x - 1` over this ring.
1058
+
1059
+ .. NOTE::
1060
+
1061
+ This function exists for consistency with the finite-field
1062
+ modulus function.
1063
+
1064
+ EXAMPLES::
1065
+
1066
+ sage: R = IntegerModRing(18)
1067
+ sage: R.modulus()
1068
+ x + 17
1069
+ sage: R = IntegerModRing(17)
1070
+ sage: R.modulus()
1071
+ x + 16
1072
+ """
1073
+ try:
1074
+ return self.__modulus
1075
+ except AttributeError:
1076
+ x = self['x'].gen()
1077
+ self.__modulus = x - 1
1078
+ return self.__modulus
1079
+
1080
+ def order(self):
1081
+ """
1082
+ Return the order of this ring.
1083
+
1084
+ EXAMPLES::
1085
+
1086
+ sage: Zmod(87).order()
1087
+ 87
1088
+ """
1089
+ return self.__order
1090
+
1091
+ def cardinality(self):
1092
+ """
1093
+ Return the cardinality of this ring.
1094
+
1095
+ EXAMPLES::
1096
+
1097
+ sage: Zmod(87).cardinality()
1098
+ 87
1099
+ """
1100
+ return self.order()
1101
+
1102
+ def _pari_order(self):
1103
+ """
1104
+ Return the pari integer representing the order of this ring.
1105
+
1106
+ EXAMPLES::
1107
+
1108
+ sage: Zmod(87)._pari_order() # needs sage.libs.pari
1109
+ 87
1110
+ """
1111
+ try:
1112
+ return self.__pari_order
1113
+ except AttributeError:
1114
+ self.__pari_order = pari(self.order())
1115
+ return self.__pari_order
1116
+
1117
+ def _element_constructor_(self, x):
1118
+ """
1119
+ TESTS::
1120
+
1121
+ sage: # needs sage.rings.finite_rings
1122
+ sage: K2 = GF(2)
1123
+ sage: K3 = GF(3)
1124
+ sage: K8 = GF(8, 'a')
1125
+ sage: K8(5) # indirect doctest
1126
+ 1
1127
+ sage: K8('a+1')
1128
+ a + 1
1129
+ sage: K8(K2(1))
1130
+ 1
1131
+
1132
+ The following test refers to :issue:`6468`::
1133
+
1134
+ sage: class foo_parent(Parent):
1135
+ ....: pass
1136
+ sage: class foo(RingElement):
1137
+ ....: def lift(self):
1138
+ ....: raise PariError
1139
+ sage: P = foo_parent()
1140
+ sage: F = foo(P)
1141
+ sage: GF(2)(F)
1142
+ Traceback (most recent call last):
1143
+ ...
1144
+ TypeError: error coercing to finite field
1145
+
1146
+ The following test refers to :issue:`8970`::
1147
+
1148
+ sage: R = Zmod(13); a = R(2)
1149
+ sage: a == R(gap(a)) # needs sage.libs.gap
1150
+ True
1151
+
1152
+ libgap interface (:issue:`23714`)::
1153
+
1154
+ sage: a = libgap.eval("Z(13)^2") # needs sage.libs.gap
1155
+ sage: a.sage() # needs sage.libs.gap
1156
+ 4
1157
+ sage: libgap(a.sage()) == a # needs sage.libs.gap
1158
+ True
1159
+
1160
+ better syntax for libgap interface::
1161
+
1162
+ sage: a = libgap.Z(13)^2 # needs sage.libs.gap
1163
+ sage: libgap(a.sage()) == a # needs sage.libs.gap
1164
+ True
1165
+ """
1166
+ try:
1167
+ return integer_mod.IntegerMod(self, x)
1168
+ except (NotImplementedError, PariError):
1169
+ raise TypeError("error coercing to finite field")
1170
+ except TypeError:
1171
+ if isinstance(x, GapElement):
1172
+ from sage.libs.gap.libgap import libgap
1173
+ return libgap(x).sage()
1174
+ raise # Continue up with the original TypeError
1175
+
1176
+ def __iter__(self):
1177
+ """
1178
+ EXAMPLES::
1179
+
1180
+ sage: R = IntegerModRing(3)
1181
+ sage: for i in R:
1182
+ ....: print(i)
1183
+ 0
1184
+ 1
1185
+ 2
1186
+ sage: L = [i for i in R]
1187
+ sage: L[0].parent()
1188
+ Ring of integers modulo 3
1189
+ """
1190
+ i = 0
1191
+ order = int(self.__order)
1192
+ while i < order:
1193
+ yield self(i)
1194
+ i = i + 1
1195
+
1196
+ def _coerce_map_from_(self, S):
1197
+ r"""
1198
+ EXAMPLES::
1199
+
1200
+ sage: R = Integers(15)
1201
+ sage: f = R.coerce_map_from(Integers(450)); f # indirect doctest
1202
+ Natural morphism:
1203
+ From: Ring of integers modulo 450
1204
+ To: Ring of integers modulo 15
1205
+ sage: f(-1)
1206
+ 14
1207
+ sage: f = R.coerce_map_from(int); f
1208
+ Native morphism:
1209
+ From: Set of Python objects of class 'int'
1210
+ To: Ring of integers modulo 15
1211
+ sage: f(-1r)
1212
+ 14
1213
+ sage: f = R.coerce_map_from(ZZ); f
1214
+ Natural morphism:
1215
+ From: Integer Ring
1216
+ To: Ring of integers modulo 15
1217
+ sage: f(-1)
1218
+ 14
1219
+ sage: f = R.coerce_map_from(Integers(10)); print(f)
1220
+ None
1221
+ sage: f = R.coerce_map_from(QQ); print(f)
1222
+ None
1223
+
1224
+ sage: R = IntegerModRing(17)
1225
+ sage: a = R(3)
1226
+ sage: b = R.coerce(3)
1227
+ sage: b
1228
+ 3
1229
+ sage: a==b
1230
+ True
1231
+
1232
+ This is allowed::
1233
+
1234
+ sage: R(2/3)
1235
+ 12
1236
+
1237
+ But this is not, since there is no (canonical or not!) ring
1238
+ homomorphism from `\QQ` to `\GF{17}`.
1239
+
1240
+ ::
1241
+
1242
+ sage: R.coerce(2/3)
1243
+ Traceback (most recent call last):
1244
+ ...
1245
+ TypeError: no canonical coercion from Rational Field to Ring of integers modulo 17
1246
+
1247
+ We do not allow the coercion ``GF(p) -> Z/pZ``, because in case of a
1248
+ canonical isomorphism, there is a coercion map in only one
1249
+ direction, i.e., to the object in the smaller category.
1250
+ """
1251
+ if S is int:
1252
+ return integer_mod.Int_to_IntegerMod(self)
1253
+ elif S is integer_ring.ZZ:
1254
+ return integer_mod.Integer_to_IntegerMod(self)
1255
+ elif isinstance(S, IntegerModRing_generic):
1256
+ if isinstance(S, Field):
1257
+ return None
1258
+ try:
1259
+ return integer_mod.IntegerMod_to_IntegerMod(S, self)
1260
+ except TypeError:
1261
+ pass
1262
+ to_ZZ = integer_ring.ZZ._internal_coerce_map_from(S)
1263
+ if to_ZZ is not None:
1264
+ return integer_mod.Integer_to_IntegerMod(self) * to_ZZ
1265
+
1266
+ def _convert_map_from_(self, other):
1267
+ """
1268
+ Conversion from `p`-adic fields.
1269
+
1270
+ EXAMPLES::
1271
+
1272
+ sage: Zmod(81).convert_map_from(Qp(3)) # needs sage.rings.padics
1273
+ Reduction morphism:
1274
+ From: 3-adic Field with capped relative precision 20
1275
+ To: Ring of integers modulo 81
1276
+ """
1277
+ from sage.rings.padics.padic_generic import pAdicGeneric, ResidueReductionMap
1278
+ if isinstance(other, pAdicGeneric) and other.degree() == 1:
1279
+ p = other.prime()
1280
+ N = self.cardinality()
1281
+ n = N.exact_log(p)
1282
+ if p**n == N:
1283
+ return ResidueReductionMap._create_(other, self)
1284
+
1285
+ def __richcmp__(self, other, op):
1286
+ """
1287
+ EXAMPLES::
1288
+
1289
+ sage: Z11 = IntegerModRing(11); Z11
1290
+ Ring of integers modulo 11
1291
+ sage: Z12 = IntegerModRing(12); Z12
1292
+ Ring of integers modulo 12
1293
+ sage: Z13 = IntegerModRing(13); Z13
1294
+ Ring of integers modulo 13
1295
+ sage: Z11 == Z11, Z11 == Z12, Z11 == Z13
1296
+ (True, False, False)
1297
+ sage: F = GF(11); F
1298
+ Finite Field of size 11
1299
+ sage: Z11 == F
1300
+ False
1301
+
1302
+ In :issue:`15229`, the following was implemented::
1303
+
1304
+ sage: R1 = IntegerModRing(5)
1305
+ sage: R2 = IntegerModRing(5, is_field=True)
1306
+ sage: R1 is R2 # used to return False
1307
+ True
1308
+ sage: R2 == GF(5)
1309
+ False
1310
+ """
1311
+ # We want that GF(p) and IntegerModRing(p) evaluate unequal.
1312
+ # However, we cannot just compare the types, since the
1313
+ # choice of a different category also changes the type.
1314
+ # But if we go to the base class, we avoid the influence
1315
+ # of the category.
1316
+ try:
1317
+ c = bool(other.__class__.__base__ != self.__class__.__base__)
1318
+ except AttributeError: # __base__ does not always exists
1319
+ c = bool(type(other) is not type(self))
1320
+ if c:
1321
+ return NotImplemented
1322
+ return richcmp(self.__order, other.__order, op)
1323
+
1324
+ def unit_gens(self, **kwds):
1325
+ r"""
1326
+ Return generators for the unit group `(\ZZ/N\ZZ)^*`.
1327
+
1328
+ We compute the list of generators using a deterministic algorithm, so
1329
+ the generators list will always be the same. For each odd prime divisor
1330
+ of `N` there will be exactly one corresponding generator; if `N` is
1331
+ even there will be 0, 1 or 2 generators according to whether 2 divides
1332
+ `N` to order 1, 2 or `\geq 3`.
1333
+
1334
+ OUTPUT: a tuple containing the units of ``self``
1335
+
1336
+ EXAMPLES::
1337
+
1338
+ sage: # needs sage.groups sage.libs.pari sage.modules
1339
+ sage: R = IntegerModRing(18)
1340
+ sage: R.unit_gens()
1341
+ (11,)
1342
+ sage: R = IntegerModRing(17)
1343
+ sage: R.unit_gens()
1344
+ (3,)
1345
+ sage: IntegerModRing(next_prime(10^30)).unit_gens()
1346
+ (5,)
1347
+
1348
+ The choice of generators is affected by the optional keyword
1349
+ ``algorithm``; this can be ``'sage'`` (default) or ``'pari'``.
1350
+ See :meth:`unit_group` for details. ::
1351
+
1352
+ sage: # needs sage.groups sage.modules
1353
+ sage: A = Zmod(55)
1354
+ sage: A.unit_gens(algorithm='sage')
1355
+ (12, 46)
1356
+ sage: A.unit_gens(algorithm='pari') # needs sage.libs.pari
1357
+ (2, 21)
1358
+
1359
+ TESTS::
1360
+
1361
+ sage: # needs sage.groups sage.modules
1362
+ sage: IntegerModRing(2).unit_gens()
1363
+ ()
1364
+ sage: IntegerModRing(4).unit_gens()
1365
+ (3,)
1366
+ sage: IntegerModRing(8).unit_gens()
1367
+ (7, 5)
1368
+ """
1369
+ return self.unit_group(**kwds).gens_values()
1370
+
1371
+ def unit_group_exponent(self):
1372
+ """
1373
+ EXAMPLES::
1374
+
1375
+ sage: # needs sage.groups sage.libs.pari sage.modules
1376
+ sage: R = IntegerModRing(17)
1377
+ sage: R.unit_group_exponent()
1378
+ 16
1379
+ sage: R = IntegerModRing(18)
1380
+ sage: R.unit_group_exponent()
1381
+ 6
1382
+ """
1383
+ return self.unit_group().exponent()
1384
+
1385
+ def unit_group_order(self):
1386
+ """
1387
+ Return the order of the unit group of this residue class ring.
1388
+
1389
+ EXAMPLES::
1390
+
1391
+ sage: R = Integers(500)
1392
+ sage: R.unit_group_order() # needs sage.groups sage.libs.pari sage.modules
1393
+ 200
1394
+ """
1395
+ return self.unit_group().order()
1396
+
1397
+ @cached_method
1398
+ def unit_group(self, algorithm='sage'):
1399
+ r"""
1400
+ Return the unit group of ``self``.
1401
+
1402
+ INPUT:
1403
+
1404
+ - ``self`` -- the ring `\ZZ/n\ZZ` for a positive integer `n`
1405
+
1406
+ - ``algorithm`` -- either ``'sage'`` (default) or ``'pari'``
1407
+
1408
+ OUTPUT:
1409
+
1410
+ The unit group of ``self``. This is a finite Abelian group
1411
+ equipped with a distinguished set of generators, which is
1412
+ computed using a deterministic algorithm depending on the
1413
+ ``algorithm`` parameter.
1414
+
1415
+ - If ``algorithm == 'sage'``, the generators correspond to the
1416
+ prime factors `p \mid n` (one generator for each odd `p`;
1417
+ the number of generators for `p = 2` is 0, 1 or 2 depending
1418
+ on the order to which 2 divides `n`).
1419
+
1420
+ - If ``algorithm == 'pari'``, the generators are chosen such
1421
+ that their orders form a decreasing sequence with respect to
1422
+ divisibility.
1423
+
1424
+ EXAMPLES:
1425
+
1426
+ The output of the algorithms ``'sage'`` and ``'pari'`` can
1427
+ differ in various ways. In the following example, the same
1428
+ cyclic factors are computed, but in a different order::
1429
+
1430
+ sage: # needs sage.groups sage.libs.pari sage.modules
1431
+ sage: A = Zmod(15)
1432
+ sage: G = A.unit_group(); G
1433
+ Multiplicative Abelian group isomorphic to C2 x C4
1434
+ sage: G.gens_values()
1435
+ (11, 7)
1436
+ sage: H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari
1437
+ Multiplicative Abelian group isomorphic to C4 x C2
1438
+ sage: H.gens_values() # needs sage.libs.pari
1439
+ (7, 11)
1440
+
1441
+ Here are two examples where the cyclic factors are isomorphic,
1442
+ but are ordered differently and have different generators::
1443
+
1444
+ sage: # needs sage.groups sage.libs.pari sage.modules
1445
+ sage: A = Zmod(40)
1446
+ sage: G = A.unit_group(); G
1447
+ Multiplicative Abelian group isomorphic to C2 x C2 x C4
1448
+ sage: G.gens_values()
1449
+ (31, 21, 17)
1450
+ sage: H = A.unit_group(algorithm='pari'); H
1451
+ Multiplicative Abelian group isomorphic to C4 x C2 x C2
1452
+ sage: H.gens_values()
1453
+ (17, 31, 21)
1454
+
1455
+ sage: # needs sage.groups sage.libs.pari sage.modules
1456
+ sage: A = Zmod(192)
1457
+ sage: G = A.unit_group(); G
1458
+ Multiplicative Abelian group isomorphic to C2 x C16 x C2
1459
+ sage: G.gens_values()
1460
+ (127, 133, 65)
1461
+ sage: H = A.unit_group(algorithm='pari'); H
1462
+ Multiplicative Abelian group isomorphic to C16 x C2 x C2
1463
+ sage: H.gens_values()
1464
+ (133, 127, 65)
1465
+
1466
+ In the following examples, the cyclic factors are not even
1467
+ isomorphic::
1468
+
1469
+ sage: # needs sage.groups sage.libs.pari sage.modules
1470
+ sage: A = Zmod(319)
1471
+ sage: A.unit_group()
1472
+ Multiplicative Abelian group isomorphic to C10 x C28
1473
+ sage: A.unit_group(algorithm='pari')
1474
+ Multiplicative Abelian group isomorphic to C140 x C2
1475
+ sage: A = Zmod(30.factorial())
1476
+ sage: A.unit_group()
1477
+ Multiplicative Abelian group isomorphic to
1478
+ C2 x C16777216 x C3188646 x C62500 x C2058 x C110 x C156 x C16 x C18 x C22 x C28
1479
+ sage: A.unit_group(algorithm='pari')
1480
+ Multiplicative Abelian group isomorphic to
1481
+ C20499647385305088000000 x C55440 x C12 x C12 x C4 x C2 x C2 x C2 x C2 x C2 x C2
1482
+
1483
+ TESTS:
1484
+
1485
+ We test the cases where the unit group is trivial::
1486
+
1487
+ sage: # needs sage.groups sage.libs.pari sage.modules
1488
+ sage: A = Zmod(1)
1489
+ sage: A.unit_group()
1490
+ Trivial Abelian group
1491
+ sage: A.unit_group(algorithm='pari')
1492
+ Trivial Abelian group
1493
+ sage: A = Zmod(2)
1494
+ sage: A.unit_group()
1495
+ Trivial Abelian group
1496
+ sage: A.unit_group(algorithm='pari')
1497
+ Trivial Abelian group
1498
+ sage: Zmod(3).unit_group(algorithm='bogus')
1499
+ Traceback (most recent call last):
1500
+ ...
1501
+ ValueError: unknown algorithm 'bogus' for computing the unit group
1502
+ """
1503
+ from sage.groups.abelian_gps.values import AbelianGroupWithValues
1504
+ if algorithm == 'sage':
1505
+ n = self.order()
1506
+ gens = []
1507
+ orders = []
1508
+ for p, r in self.factored_order():
1509
+ m = n // (p**r)
1510
+ for g, o in _unit_gens_primepowercase(p, r):
1511
+ x = g.crt(integer_mod.Mod(1, m))
1512
+ gens.append(x)
1513
+ orders.append(o)
1514
+ elif algorithm == 'pari':
1515
+ _, orders, gens = self.order().__pari__().znstar()
1516
+ gens = [self(g) for g in gens]
1517
+ orders = [integer.Integer(o) for o in orders]
1518
+ else:
1519
+ raise ValueError('unknown algorithm %r for computing the unit group' % algorithm)
1520
+ return AbelianGroupWithValues(gens, orders, values_group=self)
1521
+
1522
+ def random_element(self, bound=None):
1523
+ """
1524
+ Return a random element of this ring.
1525
+
1526
+ INPUT:
1527
+
1528
+ - ``bound`` -- positive integer or ``None`` (the default); if given,
1529
+ return the coercion of an integer in the interval
1530
+ ``[-bound, bound]`` into this ring
1531
+
1532
+ EXAMPLES::
1533
+
1534
+ sage: R = IntegerModRing(18)
1535
+ sage: R.random_element().parent() is R
1536
+ True
1537
+ sage: found = [False]*18
1538
+ sage: while not all(found):
1539
+ ....: found[R.random_element()] = True
1540
+
1541
+ We test the ``bound`` option::
1542
+
1543
+ sage: R.random_element(2) in [R(-2), R(-1), R(0), R(1), R(2)]
1544
+ True
1545
+ """
1546
+ if bound is not None:
1547
+ a = random.randint(-bound, bound)
1548
+ else:
1549
+ a = random.randint(0, self.order() - 1)
1550
+ return self(a)
1551
+
1552
+ @staticmethod
1553
+ def _lift_residue_field_root(p, e, f, fprime, root):
1554
+ """Lifts a root of f
1555
+
1556
+ INPUT:
1557
+
1558
+ - ``p`` -- integer, a prime number
1559
+ - ``e`` -- positive integer
1560
+ - ``f`` -- polynomial with coefficients in ``IntegerModRing(p**e)``
1561
+ - ``fprime`` -- derivative of ``f``
1562
+ - ``root`` -- Element of ``IntegerModRing(p)`` with ``f(root) = 0``
1563
+
1564
+ OUTPUT: iterable of roots of ``f`` modulo ``p**e``. Each root is an
1565
+ ``IntegerModRing(p**e)`` element.
1566
+
1567
+ TESTS::
1568
+
1569
+ sage: R = Zmod(2)
1570
+ sage: S.<x> = R[]
1571
+ sage: R._lift_residue_field_root(2, 1, S.zero(), S.zero(), R(0))
1572
+ (0,)
1573
+
1574
+ Lifting roots of the zero polynomial::
1575
+
1576
+ sage: R = Zmod(41)
1577
+ sage: S.<x> = R[]
1578
+ sage: R._lift_residue_field_root(41, 1, S.zero(), S.zero(), R(12))
1579
+ (12,)
1580
+ sage: R = Zmod(5**2)
1581
+ sage: S.<x> = R[]
1582
+ sage: R._lift_residue_field_root(5, 2, S.zero(), S.zero(), R(2))
1583
+ [2, 7, 12, 17, 22]
1584
+ sage: R = Zmod(2**3)
1585
+ sage: S.<x> = R[]
1586
+ sage: R._lift_residue_field_root(2, 3, S.zero(), S.zero(), R(1))
1587
+ [1, 5, 3, 7]
1588
+
1589
+ Trivial case where ``e == 1``::
1590
+
1591
+ sage: R = Zmod(41)
1592
+ sage: S.<x> = R[]
1593
+ sage: f = x^2 - 2
1594
+ sage: R._lift_residue_field_root(41, 1, f, f.derivative(), R(17))
1595
+ (17,)
1596
+
1597
+ sage: R = Zmod(43)
1598
+ sage: S.<x> = R[]
1599
+ sage: f = x^43 - 3
1600
+ sage: R._lift_residue_field_root(43, 1, f, f.derivative(), R(3))
1601
+ (3,)
1602
+
1603
+ Non-singular cases with one step of lifting::
1604
+
1605
+ sage: R = Zmod(2**2)
1606
+ sage: S.<x> = R[]
1607
+ sage: f = x - 1
1608
+ sage: R._lift_residue_field_root(2, 2, f, f.derivative(), R(1))
1609
+ (1,)
1610
+ sage: f = x - 3
1611
+ sage: R._lift_residue_field_root(2, 2, f, f.derivative(), R(1))
1612
+ (3,)
1613
+
1614
+ sage: # needs sage.libs.pari
1615
+ sage: R = Zmod(4001**2)
1616
+ sage: S.<x> = R[]
1617
+ sage: f = x^3 - 2
1618
+ sage: R._lift_residue_field_root(4001, 2, f, f.derivative(), R(3981))
1619
+ (5309307,)
1620
+ sage: f = x^3 - 3
1621
+ sage: R._lift_residue_field_root(4001, 2, f, f.derivative(), R(1091))
1622
+ (11035849,)
1623
+
1624
+ Non-singular cases with multiple steps of lifting::
1625
+
1626
+ sage: R = Zmod(2**10)
1627
+ sage: S.<x> = R[]
1628
+ sage: f = x + 1
1629
+ sage: R._lift_residue_field_root(2, 10, f, f.derivative(), Zmod(2)(1))
1630
+ (1023,)
1631
+
1632
+ sage: R = Zmod(2**16)
1633
+ sage: S.<x> = R[]
1634
+ sage: f = x + 1
1635
+ sage: R._lift_residue_field_root(2, 16, f, f.derivative(), Zmod(2)(1))
1636
+ (65535,)
1637
+
1638
+ sage: # needs sage.libs.pari
1639
+ sage: R = Zmod(7**4)
1640
+ sage: S.<x> = R[]
1641
+ sage: f = x^4 - 2
1642
+ sage: R._lift_residue_field_root(7, 4, f, f.derivative(), Zmod(7)(2))
1643
+ (121,)
1644
+
1645
+ Singular cases::
1646
+
1647
+ sage: R = Zmod(2**3)
1648
+ sage: S.<x> = R[]
1649
+ sage: f = x^2 - 1
1650
+ sage: R._lift_residue_field_root(2, 3, f, f.derivative(), Zmod(2)(1))
1651
+ [1, 5, 3, 7]
1652
+ sage: f = 2*x
1653
+ sage: R._lift_residue_field_root(2, 3, f, f.derivative(), Zmod(2)(0))
1654
+ [0, 4]
1655
+
1656
+ sage: R = Zmod(11**2)
1657
+ sage: S.<x> = R[]
1658
+ sage: f = x^2 + 13*x + 1
1659
+ sage: R._lift_residue_field_root(11, 2, f, f.derivative(), Zmod(11)(10))
1660
+ []
1661
+
1662
+ sage: # needs sage.libs.pari
1663
+ sage: R = Zmod(11**3)
1664
+ sage: S.<x> = R[]
1665
+ sage: f = x^2 + 123*x + 1
1666
+ sage: R._lift_residue_field_root(11, 3, f, f.derivative(), Zmod(11)(10))
1667
+ [10, 131, 252, 373, 494, 615, 736, 857, 978, 1099, 1220, 109, 230, 351, 472, 593, 714, 835, 956, 1077, 1198, 1319]
1668
+ """
1669
+ if e == 1:
1670
+ # Nothing to do
1671
+ return (root,)
1672
+ deriv = fprime(root)
1673
+ if deriv:
1674
+ # Unique lift, use Newton iteration
1675
+ prec = 1
1676
+ while True:
1677
+ prec = min(2*prec, e)
1678
+ Zp_prec = Zmod(p**prec)
1679
+ root = Zp_prec(root.lift())
1680
+ deriv = fprime(root)
1681
+ step = f(root) / deriv
1682
+ root -= step
1683
+ if prec >= e:
1684
+ return (root,)
1685
+ else:
1686
+ # Non-unique lift, go one power at a time
1687
+ prec = 1
1688
+ new_power = 1
1689
+ new_mod = p
1690
+ current_roots = (root,)
1691
+ for _ in range(e - 1):
1692
+ prec += 1
1693
+ new_power = new_mod
1694
+ new_mod *= p
1695
+ new_roots = []
1696
+ Zp_prec = Zmod(new_mod)
1697
+ for rt in current_roots:
1698
+ rt = Zp_prec(rt.lift())
1699
+ if f(rt):
1700
+ continue
1701
+ new_roots.append(rt)
1702
+ for _ in range(p - 1):
1703
+ rt += new_power
1704
+ new_roots.append(rt)
1705
+ current_roots = new_roots
1706
+
1707
+ return current_roots
1708
+
1709
+ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algorithm=None):
1710
+ r"""
1711
+ Return the roots of ``f`` in the ring ``ring``.
1712
+
1713
+ INPUT:
1714
+
1715
+ - ``f`` - a polynomial defined over this ring
1716
+
1717
+ - ``ring`` - the ring to find roots in. Control flow elsewhere
1718
+ ensures that the only cases we need to handle are ``self`` and
1719
+ ``None``. Otherwise we raise ``NotImplementedError``.
1720
+
1721
+ - ``multiplicities`` - bool (default: ``True``). If ``True``, return
1722
+ list of pairs `(r, n)`, where `r` is a root and `n` is its
1723
+ multiplicity. If ``False``, just return the unique roots, with no
1724
+ information about multiplicities. Multiplicities are only defined
1725
+ over fields, and this method raises ``NotImplementedError`` if this
1726
+ is ``True`` but the ring is not a field.
1727
+
1728
+ - ``algorithm`` - ignored
1729
+
1730
+ ALGORITHM:
1731
+
1732
+ The algorithm is adapted from [Gou2020]_, section 4.5, and [Coh1993]_,
1733
+ section 3.5.3. It is a combination of the Chinese Remainder Theorem
1734
+ and Hensel's lemma. As a base case, if `N` is prime, then we find
1735
+ roots by factoring `f`. If `N` is a prime power `p^e`, then we find
1736
+ roots modulo `p` and lift them. Finally, for general `N`, we first
1737
+ factor the modulus `N` into prime powers, list all roots modulo those
1738
+ prime powers, and combine the roots using the Chinese Remainder
1739
+ Theorem.
1740
+
1741
+ Suppose that we are trying to find roots modulo `p^e` and that `r` is
1742
+ a root of `f(x)` modulo `p`. The easy case is when `f'(r) \not\equiv
1743
+ 0 \pmod{p}`, for then Hensel's lemma implies that there is a unique
1744
+ `r_e \in \Zmod{p^e}` with `r_e \equiv r \pmod{p}`.
1745
+ Moreover, this `r_e` can be found by applying Newton's method for
1746
+ numerically approximating roots. Each iteration of Newton's method
1747
+ doubles the precision to which the root is known.
1748
+
1749
+ But if `f'(r) \equiv 0 \pmod{p}`, then this is no longer true. In
1750
+ fact, in this case roots modulo `p^e` are not the same as `p`-adic
1751
+ roots, and finding all the latter does not guarantee that we have
1752
+ found all the former. For example, if `f(x) = 2x` and `p = 2`, then
1753
+ there is only one `p`-adic root, namely zero. But the solutions of
1754
+ `2x \equiv 0 \pmod{2^k}` are `0` and `2^{k-1}`; the former lifts to
1755
+ two roots modulo `2^{k+1}`, namely `0` and `2^k`, while the latter
1756
+ does not lift at all. We handle this case by lifting one power at a
1757
+ time. While we can no longer use Newton's method to solve for a lift,
1758
+ the Taylor series it is based on still yields constraints on the roots
1759
+ modulo `p^{k+1}`: If `r_k` is a root of `f` modulo `p^k`, then either
1760
+ every lift of `r_k` to `\Zmod{p^{k + 1}}` is a root of `f`
1761
+ modulo `p^{k+1}` or none of them are. Consequently we may find roots
1762
+ modulo `p^e` by lifting one power at a time.
1763
+
1764
+ When `f'(r) \equiv 0 \pmod{p}`, an alternative approach is to change
1765
+ variables, factor out the root, and then factor out powers of `p`.
1766
+ This has the advantage that it will eventually reach a situation where
1767
+ the lift converges quadratically, but it is not presently implemented.
1768
+ A different form of Hensel's lemma applies once we are close enough to
1769
+ a `p`-adic root (see [Gou2020]_, problem 120), but it seems delicate
1770
+ to use it directly to find all roots modulo `p^e` (consider our
1771
+ earlier example of `f(x) = 2x`), so we do not presently attempt to
1772
+ apply Hensel's lemma in this way.
1773
+
1774
+ EXAMPLES::
1775
+
1776
+ sage: # needs sage.libs.pari
1777
+ sage: R.<x> = Zmod(41)[]
1778
+ sage: (x^3 + x).roots()
1779
+ [(0, 1), (32, 1), (9, 1)]
1780
+ sage: (x^3 + x).roots(multiplicities=False)
1781
+ [0, 32, 9]
1782
+ sage: (x^6 + x^5 + 9*x^4 + 20*x^3 + 3*x^2 + 18*x + 7).roots()
1783
+ [(19, 1), (20, 2), (21, 3)]
1784
+ sage: (x^6 + x^5 + 9*x^4 + 20*x^3 + 3*x^2 + 18*x + 7).roots(multiplicities=False)
1785
+ [19, 20, 21]
1786
+
1787
+ We can find roots without multiplicities over a ring whose modulus is
1788
+ a prime power, even a big power:
1789
+
1790
+ sage: # needs sage.libs.pari
1791
+ sage: R.<x> = Zmod(7^3)[]
1792
+ sage: (x^2 + x + 1).roots(multiplicities=False)
1793
+ [18, 324]
1794
+ sage: R.<x> = Zmod(2^50)[]
1795
+ sage: (x + 1).roots(multiplicities=False)
1796
+ [1125899906842623]
1797
+
1798
+ We can also find roots without multiplicities over a ring whose modulus
1799
+ is a product of primes or prime powers:
1800
+
1801
+ sage: R.<x> = Zmod(60)[]
1802
+ sage: (x^2 - 1).roots(multiplicities=False) # needs sage.libs.pari
1803
+ [29, 41, 49, 1, 59, 11, 19, 31]
1804
+
1805
+ We may also ask for roots modulo a quotient of the ring over which the
1806
+ polynomial is defined:
1807
+
1808
+ sage: R.<x> = Zmod(120)[]
1809
+ sage: (x^2 - 1).roots(multiplicities=False) # needs sage.libs.pari
1810
+ [89, 41, 49, 1, 29, 101, 109, 61, 59, 11, 19, 91, 119, 71, 79, 31]
1811
+ sage: (x^2 - 1).roots(Zmod(60), multiplicities=False) # needs sage.libs.pari
1812
+ [29, 41, 49, 1, 59, 11, 19, 31]
1813
+
1814
+ TESTS::
1815
+
1816
+ sage: R.<x> = Zmod(2)[]
1817
+ sage: x.roots() # needs sage.libs.pari
1818
+ [(0, 1)]
1819
+
1820
+ Test polynomials with content:
1821
+
1822
+ sage: R.<x> = Zmod(4)[]
1823
+ sage: (2*x).roots(multiplicities=False) # needs sage.libs.pari
1824
+ [0, 2]
1825
+
1826
+ sage: R.<x> = Zmod(6)[]
1827
+ sage: (3*x).roots(multiplicities=False) # needs sage.libs.pari
1828
+ [0, 4, 2]
1829
+
1830
+ Test polynomial with many roots:
1831
+
1832
+ sage: R.<x> = Zmod(6)[]
1833
+ sage: f = x * (x - 1) * (x - 2) * (x - 3) * (x - 4) * (x - 5)
1834
+ sage: len(f.roots(multiplicities=False)) # needs sage.libs.pari
1835
+ 6
1836
+
1837
+ Test finding roots over large prime powers:
1838
+
1839
+ sage: R.<x> = Zmod(2**16)[]
1840
+ sage: (x^3 + 5).roots(multiplicities=False) # needs sage.libs.pari
1841
+ [45475]
1842
+ sage: (x^2 + 46*x + 1).roots(multiplicities=False) # needs sage.libs.pari
1843
+ [421, 33189, 16805, 49573, 8613, 41381, 24997, 57765, 7725, 40493, 24109, 56877, 15917, 48685, 32301, 65069]
1844
+
1845
+ sage: # needs sage.libs.pari
1846
+ sage: R.<x> = Zmod(3**16)[]
1847
+ sage: (x^2 + 2).roots(multiplicities=False)
1848
+ [24620738, 18425983]
1849
+ sage: (x^2 + 11*x + 1).roots(multiplicities=False)
1850
+ [633836, 14982743, 29331650, 13715060, 28063967, 42412874]
1851
+ sage: (x^3 + 8).roots(multiplicities=False)
1852
+ [14348905, 28697812, 43046719]
1853
+
1854
+ Test some larger primes:
1855
+
1856
+ sage: # needs sage.libs.pari
1857
+ sage: R.<x> = Zmod(41**4)[]
1858
+ sage: (x^2 + 2).roots(multiplicities=False)
1859
+ [2208905, 616856]
1860
+ sage: R.<x> = Zmod(43**4)[]
1861
+ sage: (x^2 + 3).roots(multiplicities=False)
1862
+ [3269879, 148922]
1863
+
1864
+ We can't find roots with multiplicities in non-fields:
1865
+
1866
+ sage: # needs sage.libs.pari
1867
+ sage: R.<x> = Zmod(6)[]
1868
+ sage: (x + 1).roots()
1869
+ Traceback (most recent call last):
1870
+ ...
1871
+ NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)
1872
+ sage: R.<x> = Zmod(8)[]
1873
+ sage: (x + 1).roots()
1874
+ Traceback (most recent call last):
1875
+ ...
1876
+ NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)
1877
+ sage: R.<x> = Zmod(12)[]
1878
+ sage: (x + 1).roots()
1879
+ Traceback (most recent call last):
1880
+ ...
1881
+ NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)
1882
+
1883
+ The zero polynomial has every residue class as a root, but we don't
1884
+ support multiplicities even over fields (they would all be infinite).
1885
+
1886
+ sage: R.<x> = Zmod(6)[]
1887
+ sage: R.zero().roots()
1888
+ Traceback (most recent call last):
1889
+ ...
1890
+ NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)
1891
+ sage: R.zero().roots(multiplicities=False)
1892
+ [0, 1, 2, 3, 4, 5]
1893
+
1894
+ sage: R.<x> = Zmod(7)[]
1895
+ sage: R.zero().roots()
1896
+ Traceback (most recent call last):
1897
+ ...
1898
+ NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)
1899
+ sage: R.zero().roots(multiplicities=False)
1900
+ [0, 1, 2, 3, 4, 5, 6]
1901
+
1902
+ sage: R.<x> = Zmod(8)[]
1903
+ sage: R.zero().roots()
1904
+ Traceback (most recent call last):
1905
+ ...
1906
+ NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)
1907
+ sage: R.zero().roots(multiplicities=False)
1908
+ [0, 1, 2, 3, 4, 5, 6, 7]
1909
+
1910
+ This method doesn't support root-finding over rings that aren't Z/nZ:
1911
+
1912
+ sage: R.<x> = Zmod(120)[]
1913
+ sage: f = x^2 - 1
1914
+ sage: f.base_ring()._roots_univariate_polynomial(f, ring=RR, multiplicities=False)
1915
+ Traceback (most recent call last):
1916
+ ...
1917
+ NotImplementedError
1918
+
1919
+ Sage allows us to coerce polynomials from one modulus to another,
1920
+ and that makes the following defined:
1921
+
1922
+ sage: # needs sage.libs.pari
1923
+ sage: R.<x> = Zmod(100)[]
1924
+ sage: (x^2 - 1).roots(Zmod(99), multiplicities=False) == (x^2 - 1).change_ring(Zmod(99)).roots(multiplicities=False)
1925
+ True
1926
+ """
1927
+
1928
+ # This function only supports roots in an IntegerModRing
1929
+ if ring is not self and ring is not None:
1930
+ raise NotImplementedError
1931
+
1932
+ deg = f.degree()
1933
+
1934
+ if multiplicities:
1935
+ if deg < 0 or not self.is_field():
1936
+ raise NotImplementedError(
1937
+ "root finding with multiplicities for this polynomial not"
1938
+ " implemented (try the multiplicities=False option)"
1939
+ )
1940
+ # Roots of non-zero polynomial over finite fields by factorization
1941
+ return f._roots_from_factorization(f.factor(), multiplicities)
1942
+
1943
+ # Zero polynomial is a base case
1944
+ if deg < 0:
1945
+ # All residue classes are roots of the zero polynomial
1946
+ return [*map(self, range(self.cardinality()))]
1947
+
1948
+ # Finite fields are a base case
1949
+ if self.is_field():
1950
+ return f._roots_from_factorization(f.factor(), False)
1951
+
1952
+ # Otherwise, find roots modulo each prime power
1953
+ fac = self.factored_order()
1954
+ prime_power_roots = []
1955
+ for p, e in fac:
1956
+ Zpe = Zmod(p**e)
1957
+ fpe = f.change_ring(Zpe)
1958
+ fpe_prime = fpe.derivative()
1959
+ fp = fpe.change_ring(Zmod(p))
1960
+
1961
+ mod_p_roots = fp.roots(multiplicities=False)
1962
+
1963
+ this_prime_power = []
1964
+ for root in mod_p_roots:
1965
+ this_prime_power.extend(
1966
+ self._lift_residue_field_root(p, e, fpe, fpe_prime, root)
1967
+ )
1968
+ prime_power_roots.append(this_prime_power)
1969
+
1970
+ # Combine using Chinese Remainder Theorem
1971
+ ppwr_basis = CRT_basis([p**e for p, e in fac])
1972
+ result = []
1973
+ for res in cartesian_product_iterator(prime_power_roots):
1974
+ root = self.zero()
1975
+ for c, x in zip(ppwr_basis, res):
1976
+ root += c*x.lift()
1977
+ result.append(root)
1978
+ return result
1979
+
1980
+ #######################################################
1981
+ # Suppose for interfaces
1982
+ #######################################################
1983
+ def _gap_init_(self):
1984
+ """
1985
+ EXAMPLES::
1986
+
1987
+ sage: R = Integers(12345678900)
1988
+ sage: R
1989
+ Ring of integers modulo 12345678900
1990
+ sage: gap(R) # indirect doctest # needs sage.libs.gap
1991
+ (Integers mod 12345678900)
1992
+ """
1993
+ return 'ZmodnZ({})'.format(self.order())
1994
+
1995
+ def _magma_init_(self, magma):
1996
+ """
1997
+ EXAMPLES::
1998
+
1999
+ sage: R = Integers(12345678900)
2000
+ sage: R
2001
+ Ring of integers modulo 12345678900
2002
+ sage: magma(R) # indirect doctest, optional - magma
2003
+ Residue class ring of integers modulo 12345678900
2004
+ """
2005
+ return 'Integers({})'.format(self.order())
2006
+
2007
+ def degree(self):
2008
+ """
2009
+ Return 1.
2010
+
2011
+ EXAMPLES::
2012
+
2013
+ sage: R = Integers(12345678900)
2014
+ sage: R.degree()
2015
+ 1
2016
+ """
2017
+ return integer.Integer(1)
2018
+
2019
+
2020
+ # Register unpickling methods for backward compatibility.
2021
+
2022
+ from sage.misc.persist import register_unpickle_override
2023
+ register_unpickle_override('sage.rings.integer_mod_ring', 'IntegerModRing_generic', IntegerModRing_generic)
2024
+
2025
+
2026
+ def crt(v):
2027
+ """
2028
+ INPUT:
2029
+
2030
+ - ``v`` -- (list) a lift of elements of ``rings.IntegerMod(n)``, for
2031
+ various coprime moduli ``n``
2032
+
2033
+ EXAMPLES::
2034
+
2035
+ sage: from sage.rings.finite_rings.integer_mod_ring import crt
2036
+ sage: crt([mod(3, 8), mod(1,19), mod(7, 15)])
2037
+ 1027
2038
+ """
2039
+ if len(v) == 0:
2040
+ return IntegerModRing(1).one()
2041
+ x = v[0]
2042
+ for i in range(1, len(v)):
2043
+ x = x.crt(v[i])
2044
+ return x