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,2792 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Morphisms on projective schemes
4
+
5
+ This module defines morphisms from projective schemes. A morphism from a
6
+ projective scheme to a projective scheme is defined by homogeneous polynomials
7
+ of the same degree that define what the morphism does on points in the ambient
8
+ projective space. A morphism from a projective scheme to an affine scheme is
9
+ determined by rational function, that is, quotients of homogeneous polynomials
10
+ of the same degree.
11
+
12
+ EXAMPLES::
13
+
14
+ sage: P2.<x0,x1,x2> = ProjectiveSpace(QQ, 2)
15
+ sage: A2.<x,y> = AffineSpace(QQ, 2)
16
+ sage: P2.hom([x0, x1, x1 + x2], P2)
17
+ Scheme endomorphism of Projective Space of dimension 2 over Rational Field
18
+ Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x0 : x1 : x1 + x2)
19
+ sage: P2.hom([x1/x0, (x1 + x2)/x0], A2)
20
+ Scheme morphism:
21
+ From: Projective Space of dimension 2 over Rational Field
22
+ To: Affine Space of dimension 2 over Rational Field
23
+ Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x1/x0, (x1 + x2)/x0)
24
+
25
+ AUTHORS:
26
+
27
+ - David Kohel, William Stein: initial version
28
+
29
+ - William Stein (2006-02-11): fixed bug where P(0,0,0) was allowed as
30
+ a projective point
31
+
32
+ - Volker Braun (2011-08-08): renamed classes, more documentation, misc
33
+ cleanups
34
+
35
+ - Ben Hutz (2013-03): iteration functionality and new directory structure
36
+ for affine/projective, height functionality
37
+
38
+ - Brian Stout, Ben Hutz (2013-11): added minimal model functionality
39
+
40
+ - Dillon Rose (2014-01): speed enhancements
41
+
42
+ - Ben Hutz (2015-11): iteration of subschemes
43
+
44
+ - Kwankyu Lee (2020-02): added indeterminacy_locus() and image()
45
+
46
+ - Kwankyu Lee (2022-05): added graph(), projective_degrees(), and degree()
47
+ """
48
+
49
+ # ****************************************************************************
50
+ # Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
51
+ # Copyright (C) 2006 David Kohel <kohel@maths.usyd.edu.au>
52
+ # Copyright (C) 2006 William Stein <wstein@gmail.com>
53
+ #
54
+ # This program is free software: you can redistribute it and/or modify
55
+ # it under the terms of the GNU General Public License as published by
56
+ # the Free Software Foundation, either version 2 of the License, or
57
+ # (at your option) any later version.
58
+ # http://www.gnu.org/licenses/
59
+ # ****************************************************************************
60
+
61
+ import sys
62
+
63
+ import sage.rings.abc
64
+
65
+ from sage.arith.functions import lcm
66
+ from sage.arith.misc import GCD as gcd
67
+ from sage.categories.fields import Fields
68
+ from sage.categories.finite_fields import FiniteFields
69
+ from sage.categories.homset import Hom, End
70
+ from sage.categories.number_fields import NumberFields
71
+ from sage.misc.cachefunc import cached_method
72
+ from sage.misc.lazy_attribute import lazy_attribute
73
+ from sage.misc.lazy_import import lazy_import
74
+ from sage.misc.misc_c import prod
75
+ from sage.rings.finite_rings.finite_field_base import FiniteField
76
+ from sage.rings.fraction_field import FractionField
77
+ from sage.rings.integer import Integer
78
+ from sage.rings.integer_ring import ZZ
79
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
80
+ from sage.rings.quotient_ring import QuotientRing_generic
81
+ from sage.rings.rational_field import QQ
82
+ from sage.schemes.generic.morphism import SchemeMorphism_polynomial
83
+
84
+ lazy_import('sage.dynamics.arithmetic_dynamics.generic_ds', 'DynamicalSystem')
85
+ lazy_import('sage.dynamics.arithmetic_dynamics.projective_ds',
86
+ ['DynamicalSystem_projective', 'DynamicalSystem_projective_field',
87
+ 'DynamicalSystem_projective_finite_field'])
88
+ lazy_import('sage.rings.algebraic_closure_finite_field', 'AlgebraicClosureFiniteField_generic')
89
+ lazy_import('sage.rings.number_field.number_field_ideal', 'NumberFieldFractionalIdeal')
90
+ lazy_import('sage.rings.padics.padic_base_generic', 'pAdicGeneric')
91
+ lazy_import('sage.rings.padics.padic_valuation', 'pAdicValuation_base')
92
+
93
+
94
+ _NumberFields = NumberFields()
95
+ _FiniteFields = FiniteFields()
96
+ _Fields = Fields()
97
+
98
+
99
+ class SchemeMorphism_polynomial_projective_space(SchemeMorphism_polynomial):
100
+ r"""
101
+ A morphism of schemes determined by rational functions that define
102
+ what the morphism does on points in the ambient projective space.
103
+
104
+ EXAMPLES::
105
+
106
+ sage: R.<x,y> = QQ[]
107
+ sage: P1 = ProjectiveSpace(R)
108
+ sage: H = P1.Hom(P1)
109
+ sage: H([y,2*x])
110
+ Scheme endomorphism of Projective Space of dimension 1 over Rational Field
111
+ Defn: Defined on coordinates by sending (x : y) to
112
+ (y : 2*x)
113
+
114
+ An example of a morphism between projective plane curves (see :issue:`10297`)::
115
+
116
+ sage: # needs sage.schemes
117
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
118
+ sage: f = x^3 + y^3 + 60*z^3
119
+ sage: g = y^2*z - (x^3 - 6400*z^3/3)
120
+ sage: C = Curve(f)
121
+ sage: E = Curve(g)
122
+ sage: xbar,ybar,zbar = C.coordinate_ring().gens()
123
+ sage: H = C.Hom(E)
124
+ sage: H([zbar, xbar - ybar, -(xbar+ybar)/80])
125
+ Scheme morphism:
126
+ From: Projective Plane Curve over Rational Field defined by x^3 + y^3 + 60*z^3
127
+ To: Projective Plane Curve over Rational Field defined by -x^3 + y^2*z + 6400/3*z^3
128
+ Defn: Defined on coordinates by sending (x : y : z) to
129
+ (z : x - y : -1/80*x - 1/80*y)
130
+
131
+ A more complicated example::
132
+
133
+ sage: P2.<x,y,z> = ProjectiveSpace(2, QQ)
134
+ sage: P1 = P2.subscheme(x - y)
135
+ sage: H12 = P1.Hom(P2)
136
+ sage: H12([x^2, x*z, z^2])
137
+ Scheme morphism:
138
+ From: Closed subscheme of Projective Space of dimension 2 over Rational Field
139
+ defined by: x - y
140
+ To: Projective Space of dimension 2 over Rational Field
141
+ Defn: Defined on coordinates by sending (x : y : z) to (x^2 : x*z : z^2)
142
+
143
+ We illustrate some error checking::
144
+
145
+ sage: R.<x,y> = QQ[]
146
+ sage: P1 = ProjectiveSpace(R)
147
+ sage: H = P1.Hom(P1)
148
+ sage: f = H([x - y, x*y])
149
+ Traceback (most recent call last):
150
+ ...
151
+ ValueError: polys (=[x - y, x*y]) must be of the same degree
152
+
153
+ sage: H([x - 1, x*y + x])
154
+ Traceback (most recent call last):
155
+ ...
156
+ ValueError: polys (=[x - 1, x*y + x]) must be homogeneous
157
+
158
+ sage: H([exp(x), exp(y)]) # needs sage.symbolic
159
+ Traceback (most recent call last):
160
+ ...
161
+ TypeError: polys (=[e^x, e^y]) must be elements of
162
+ Multivariate Polynomial Ring in x, y over Rational Field
163
+
164
+ We can also compute the forward image of subschemes through
165
+ elimination. In particular, let `X = V(h_1,\ldots, h_t)` and define the ideal
166
+ `I = (h_1,\ldots,h_t,y_0-f_0(\bar{x}), \ldots, y_n-f_n(\bar{x}))`.
167
+ Then the elimination ideal `I_{n+1} = I \cap K[y_0,\ldots,y_n]` is a homogeneous
168
+ ideal and `f(X) = V(I_{n+1})`::
169
+
170
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
171
+ sage: H = End(P)
172
+ sage: f = H([(x-2*y)^2, (x-2*z)^2, x^2])
173
+ sage: X = P.subscheme(y-z)
174
+ sage: f(f(f(X))) # needs sage.libs.singular
175
+ Closed subscheme of Projective Space of dimension 2 over Rational Field
176
+ defined by:
177
+ y - z
178
+
179
+ ::
180
+
181
+ sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
182
+ sage: H = End(P)
183
+ sage: f = H([(x-2*y)^2, (x-2*z)^2, (x-2*w)^2, x^2])
184
+ sage: f(P.subscheme([x,y,z])) # needs sage.libs.singular
185
+ Closed subscheme of Projective Space of dimension 3 over Rational Field
186
+ defined by:
187
+ w,
188
+ y,
189
+ x
190
+ """
191
+ def __init__(self, parent, polys, check=True):
192
+ """
193
+ Initialize.
194
+
195
+ EXAMPLES::
196
+
197
+ sage: P1.<x,y> = ProjectiveSpace(QQ,1)
198
+ sage: H = P1.Hom(P1)
199
+ sage: H([y,2*x])
200
+ Scheme endomorphism of Projective Space of dimension 1 over Rational Field
201
+ Defn: Defined on coordinates by sending (x : y) to
202
+ (y : 2*x)
203
+
204
+ ::
205
+
206
+ sage: R.<t> = PolynomialRing(QQ)
207
+ sage: P.<x,y,z> = ProjectiveSpace(R, 2)
208
+ sage: X = P.subscheme([x])
209
+ sage: H = End(X)
210
+ sage: H([x^2, t*y^2, x*z])
211
+ Scheme endomorphism of Closed subscheme of Projective Space of dimension 2
212
+ over Univariate Polynomial Ring in t over Rational Field defined by: x
213
+ Defn: Defined on coordinates by sending (x : y : z) to
214
+ (x^2 : t*y^2 : x*z)
215
+
216
+ When elements of the quotient ring is used, they are reduced::
217
+
218
+ sage: # needs sage.rings.real_mpfr
219
+ sage: P.<x,y,z> = ProjectiveSpace(CC, 2)
220
+ sage: X = P.subscheme([x - y])
221
+ sage: u,v,w = X.coordinate_ring().gens() # needs sage.libs.singular
222
+ sage: H = End(X)
223
+ sage: H([u^2, v^2, w*u]) # needs sage.libs.singular
224
+ Scheme endomorphism of Closed subscheme of Projective Space of dimension 2
225
+ over Complex Field with 53 bits of precision defined by: x - y
226
+ Defn: Defined on coordinates by sending (x : y : z) to
227
+ (y^2 : y^2 : y*z)
228
+ """
229
+ if check:
230
+ try: # polys might be in a quotient ring
231
+ polys = [f.lift() for f in polys]
232
+ except (TypeError, AttributeError):
233
+ pass
234
+
235
+ try:
236
+ source_ring = parent.domain().ambient_space().coordinate_ring()
237
+ K = FractionField(source_ring)
238
+
239
+ try:
240
+ polys = [K(f) for f in polys]
241
+ except TypeError:
242
+ raise TypeError("polys (=%s) must be elements of %s" % (polys, source_ring))
243
+
244
+ if parent.codomain().is_projective():
245
+ degs = []
246
+ l = 1
247
+ for f in polys:
248
+ num = f.numerator()
249
+ den = f.denominator()
250
+ if not num.is_homogeneous() or not den.is_homogeneous():
251
+ raise ValueError("polys (={}) must be homogeneous".format(polys))
252
+
253
+ if not num.is_zero():
254
+ l *= den
255
+ degs.append(num.degree() - den.degree())
256
+
257
+ d = degs[0]
258
+ if not all(d == deg for deg in degs[1:]):
259
+ raise ValueError("polys (={}) must be of the same degree".format(polys))
260
+
261
+ polys = [(l * f).numerator() for f in polys]
262
+ elif parent.codomain().is_affine():
263
+ for f in polys:
264
+ num = f.numerator()
265
+ den = f.denominator()
266
+ if not (num.is_homogeneous() and
267
+ den.is_homogeneous() and
268
+ num.degree() == den.degree()):
269
+ raise ValueError("polys (={}) must be quotients of "
270
+ "homogeneous polynomials of the same degree".format(polys))
271
+ check = False
272
+ except (NotImplementedError, TypeError, AttributeError):
273
+ pass
274
+
275
+ SchemeMorphism_polynomial.__init__(self, parent, polys, check)
276
+
277
+ R = polys[0].base_ring()
278
+ self._is_prime_finite_field = isinstance(R, FiniteField) and R.is_prime_field()
279
+
280
+ def __call__(self, x, check=True):
281
+ r"""
282
+ Compute the forward image of the point or subscheme ``x`` by this map.
283
+
284
+ For subschemes, the forward image is computed through elimination.
285
+ In particular, let `X = V(h_1,\ldots, h_t)` and define the ideal
286
+ `I = (h_1,\ldots,h_t,y_0-f_0(\bar{x}), \ldots, y_n-f_n(\bar{x}))`.
287
+ Then the elimination ideal `I_{n+1} = I \cap K[y_0,\ldots,y_n]` is a homogeneous
288
+ ideal and `self(X) = V(I_{n+1})`.
289
+
290
+ The input boolean ``check`` can be set to false when fast iteration of
291
+ points is desired. It bypasses all input checking and passes ``x`` straight
292
+ to the fast evaluation of points function.
293
+
294
+ INPUT:
295
+
296
+ - ``x`` -- a point or subscheme in domain of this map
297
+
298
+ - ``check`` -- boolean; if ``False`` assume that ``x`` is a point
299
+
300
+ EXAMPLES::
301
+
302
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
303
+ sage: H = End(P)
304
+ sage: f = H([x^2 + y^2, y^2, z^2 + y*z])
305
+ sage: f(P([1,1,1]))
306
+ (1 : 1/2 : 1)
307
+
308
+ ::
309
+
310
+ sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2)
311
+ sage: P1.<u,v> = ProjectiveSpace(QQ, 1)
312
+ sage: H = End(P1)
313
+ sage: f = H([u^2, v^2])
314
+ sage: f(PS([0,1,1]))
315
+ Traceback (most recent call last):
316
+ ...
317
+ TypeError: (0 : 1 : 1) fails to convert into the map's domain Projective Space of
318
+ dimension 1 over Rational Field, but a `pushforward` method is not properly implemented
319
+
320
+ ::
321
+
322
+ sage: PS.<x,y> = ProjectiveSpace(QQ, 1)
323
+ sage: P1.<u,v> = ProjectiveSpace(QQ, 1)
324
+ sage: H = End(P1)
325
+ sage: f = H([u^2, v^2])
326
+ sage: f([0,1])
327
+ (0 : 1)
328
+ sage: f(PS([0,1]))
329
+ (0 : 1)
330
+
331
+ ::
332
+
333
+ sage: PS.<x,y,z,w> = ProjectiveSpace(QQ, 3)
334
+ sage: H = End(PS)
335
+ sage: f = H([y^2, x^2, w^2, z^2])
336
+ sage: X = PS.subscheme([z^2 + y*w])
337
+ sage: f(X) # needs sage.libs.singular
338
+ Closed subscheme of Projective Space of dimension 3 over Rational Field
339
+ defined by:
340
+ x*z - w^2
341
+
342
+ ::
343
+
344
+ sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2)
345
+ sage: P1.<u,v> = ProjectiveSpace(ZZ, 1)
346
+ sage: H = End(PS)
347
+ sage: f = H([x^2, y^2, z^2])
348
+ sage: X = P1.subscheme([u - v])
349
+ sage: f(X) # needs sage.libs.singular
350
+ Traceback (most recent call last):
351
+ ...
352
+ TypeError: subscheme must be in ambient space of domain of map
353
+
354
+ ::
355
+
356
+ sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2)
357
+ sage: P1.<u,v> = ProjectiveSpace(ZZ, 1)
358
+ sage: H = End(P1)
359
+ sage: f = H([u^2, v^2])
360
+ sage: f([u - v]) # needs sage.libs.singular
361
+ Closed subscheme of Projective Space of dimension 1 over Integer Ring defined by:
362
+ u - v
363
+ sage: X = PS.subscheme([x - z])
364
+ sage: f([x - z])
365
+ Traceback (most recent call last):
366
+ ...
367
+ TypeError: [x - z] fails to convert into the map's domain Projective Space of
368
+ dimension 1 over Integer Ring, but a `pushforward` method is not properly implemented
369
+
370
+ TESTS:
371
+
372
+ Check that :issue:`32209` is fixed::
373
+
374
+ sage: S.<x,y> = ProjectiveSpace(ZZ, 1)
375
+ sage: T.<u,v> = ProjectiveSpace(ZZ, 1)
376
+ sage: h = T.hom([u^2 + v^2, u*v], S); h
377
+ Scheme morphism:
378
+ From: Projective Space of dimension 1 over Integer Ring
379
+ To: Projective Space of dimension 1 over Integer Ring
380
+ Defn: Defined on coordinates by sending (u : v) to
381
+ (u^2 + v^2 : u*v)
382
+
383
+ sage: # needs sage.rings.finite_rings
384
+ sage: F.<a> = GF(4)
385
+ sage: P = T(F)(1, a)
386
+ sage: h(P) # needs sage.libs.singular
387
+ (1 : 1)
388
+ sage: h(P).domain()
389
+ Spectrum of Finite Field in a of size 2^2
390
+ sage: h.change_ring(F)(P)
391
+ (1 : 1)
392
+ """
393
+ from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_ring
394
+ if check:
395
+ from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective
396
+ if isinstance(x, SchemeMorphism_point_projective_ring):
397
+ if self.domain() != x.codomain():
398
+ try:
399
+ x = self.domain()(x)
400
+ except (TypeError, NotImplementedError):
401
+ raise TypeError("%s fails to convert into the map's domain %s, but a `pushforward` method is not properly implemented" % (x, self.domain()))
402
+ # else pass it onto the eval below
403
+ elif isinstance(x, AlgebraicScheme_subscheme_projective):
404
+ return x._forward_image(self) # call subscheme eval
405
+ else: # not a projective point or subscheme
406
+ try:
407
+ x = self.domain()(x)
408
+ except (TypeError, NotImplementedError):
409
+ try:
410
+ x = self.domain().subscheme(x)
411
+ return x._forward_image(self) # call subscheme eval
412
+ except (TypeError, NotImplementedError):
413
+ raise TypeError("%s fails to convert into the map's domain %s, but a `pushforward` method is not properly implemented" % (x, self.domain()))
414
+
415
+ R = x.domain().coordinate_ring()
416
+ if R is self.base_ring():
417
+ P = self._fast_eval(x._coords)
418
+ else:
419
+ P = [f(x._coords) for f in self._polys]
420
+ return self.codomain().point_homset(R)(P, check=check)
421
+
422
+ @lazy_attribute
423
+ def _fastpolys(self):
424
+ """
425
+ Lazy attribute for fast_callable polynomials for this map.
426
+
427
+ EXAMPLES::
428
+
429
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
430
+ sage: H = Hom(P,P)
431
+ sage: f = H([x^2 + y^2, y^2])
432
+ sage: [g.op_list() for g in f._fastpolys]
433
+ [[('load_const', 0), ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', ('load_const', 1), ('load_arg', ...), ('ipow', 2), 'mul', 'add', 'return'],
434
+ [('load_const', 0), ('load_const', 1), ('load_arg', 1), ('ipow', 2), 'mul', 'add', 'return']]
435
+ """
436
+ from sage.ext.fast_callable import fast_callable
437
+
438
+ polys = self._polys
439
+
440
+ fastpolys = []
441
+ for poly in polys:
442
+ # These tests are in place because the float and integer domain evaluate
443
+ # faster than using the base_ring
444
+ if self._is_prime_finite_field:
445
+ prime = polys[0].base_ring().characteristic()
446
+ degree = polys[0].degree()
447
+ coefficients = poly.coefficients()
448
+ height = max(abs(c.lift()) for c in coefficients)
449
+ num_terms = len(coefficients)
450
+ largest_value = num_terms * height * (prime - 1) ** degree
451
+ # If the calculations will not overflow the float data type use domain float
452
+ # Else use domain integer
453
+ if largest_value < (2 ** sys.float_info.mant_dig):
454
+ fastpolys.append(fast_callable(poly, domain=float))
455
+ else:
456
+ fastpolys.append(fast_callable(poly, domain=ZZ))
457
+ else:
458
+ fastpolys.append(fast_callable(poly, domain=poly.base_ring()))
459
+ return fastpolys
460
+
461
+ def _fast_eval(self, x):
462
+ """
463
+ Evaluate projective morphism at point described by ``x``.
464
+
465
+ EXAMPLES::
466
+
467
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
468
+ sage: H = Hom(P, P)
469
+ sage: f = H([x^2 + y^2, y^2, z^2 + y*z])
470
+ sage: f._fast_eval([1,1,1])
471
+ [2, 1, 2]
472
+
473
+ ::
474
+
475
+ sage: T.<z> = LaurentSeriesRing(ZZ)
476
+ sage: P.<x,y> = ProjectiveSpace(T, 1)
477
+ sage: H = End(P)
478
+ sage: f = H([x^2 + x*y, y^2])
479
+ sage: Q = P(z,1)
480
+ sage: f._fast_eval(list(Q))
481
+ [z + z^2, 1]
482
+
483
+ ::
484
+
485
+ sage: # needs sage.libs.pari sage.rings.real_mpfr
486
+ sage: T.<z> = PolynomialRing(CC)
487
+ sage: I = T.ideal(z^3)
488
+ sage: P.<x,y> = ProjectiveSpace(T.quotient_ring(I), 1)
489
+ sage: H = End(P)
490
+ sage: f = H([x^2 + x*y, y^2])
491
+ sage: Q = P(z^2, 1)
492
+ sage: f._fast_eval(list(Q))
493
+ [zbar^2, 1.00000000000000]
494
+
495
+ ::
496
+
497
+ sage: # needs sage.rings.real_mpfr
498
+ sage: T.<z> = LaurentSeriesRing(CC)
499
+ sage: R.<t> = PolynomialRing(T)
500
+ sage: P.<x,y> = ProjectiveSpace(R,1)
501
+ sage: H = End(P)
502
+ sage: f = H([x^2 + x*y, y^2])
503
+ sage: Q = P(t^2, z)
504
+ sage: f._fast_eval(list(Q))
505
+ [t^4 + z*t^2, z^2]
506
+ """
507
+ P = [f(*x) for f in self._fastpolys]
508
+ return P
509
+
510
+ def __eq__(self, right):
511
+ """
512
+ Test the equality of two projective morphisms.
513
+
514
+ INPUT:
515
+
516
+ - ``right`` -- a map on projective space
517
+
518
+ OUTPUT:
519
+
520
+ ``True`` if ``self`` and ``right`` define the same projective map.
521
+ ``False`` otherwise.
522
+
523
+ EXAMPLES::
524
+
525
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
526
+ sage: H = Hom(P, P)
527
+ sage: f = H([x^2 - 2*x*y + z*x, z^2 - y^2, 5*z*y])
528
+ sage: g = H([x^2, y^2, z^2])
529
+ sage: f == g
530
+ False
531
+
532
+ ::
533
+
534
+ sage: # needs sage.rings.real_mpfr
535
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
536
+ sage: P2.<u,v> = ProjectiveSpace(CC, 1)
537
+ sage: H = End(P)
538
+ sage: H2 = End(P2)
539
+ sage: f = H([x^2 - 2*x*y, y^2])
540
+ sage: g = H2([u^2 - 2*u*v, v^2])
541
+ sage: f == g
542
+ False
543
+
544
+ ::
545
+
546
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
547
+ sage: H = End(P)
548
+ sage: f = H([x^2 - 2*x*y, y^2])
549
+ sage: g = H([x^2*y - 2*x*y^2, y^3])
550
+ sage: f == g
551
+ True
552
+ """
553
+ if not isinstance(right, SchemeMorphism_polynomial):
554
+ return False
555
+ if self.parent() != right.parent():
556
+ return False
557
+ n = len(self._polys)
558
+ return all(self._polys[i] * right._polys[j] == self._polys[j] * right._polys[i]
559
+ for i in range(n) for j in range(i + 1, n))
560
+
561
+ def __ne__(self, right):
562
+ """
563
+ Test the inequality of two projective morphisms.
564
+
565
+ INPUT:
566
+
567
+ - ``right`` -- a map on projective space
568
+
569
+ OUTPUT:
570
+
571
+ ``True`` if ``self`` and ``right`` define different projective maps.
572
+ ``False`` otherwise.
573
+
574
+ EXAMPLES::
575
+
576
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
577
+ sage: H = Hom(P, P)
578
+ sage: f = H([x^3 - 2*x^2*y, 5*x*y^2])
579
+ sage: g = f.change_ring(GF(7))
580
+ sage: f != g
581
+ True
582
+
583
+ ::
584
+
585
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
586
+ sage: H = Hom(P, P)
587
+ sage: f = H([x^2 - 2*x*y + z*x, z^2 - y^2, 5*z*y])
588
+ sage: f != f
589
+ False
590
+ """
591
+ if not isinstance(right, SchemeMorphism_polynomial):
592
+ return True
593
+ if self.parent() != right.parent():
594
+ return True
595
+ n = len(self._polys)
596
+ return any(self._polys[i] * right._polys[j] != self._polys[j] * right._polys[i]
597
+ for i in range(n) for j in range(i + 1, n))
598
+
599
+ def _matrix_times_polymap_(self, mat, h):
600
+ """
601
+ Multiply the morphism on the left by a matrix ``mat``.
602
+
603
+ INPUT:
604
+
605
+ - ``mat`` -- a matrix
606
+
607
+ OUTPUT: a scheme morphism given by ``self*mat``
608
+
609
+ EXAMPLES::
610
+
611
+ sage: P.<x,y> = ProjectiveSpace(ZZ, 1)
612
+ sage: H = Hom(P,P)
613
+ sage: f = H([x^2 + y^2, y^2])
614
+ sage: matrix([[1,2], [0,1]]) * f # needs sage.modules
615
+ Scheme endomorphism of Projective Space of dimension 1 over Integer Ring
616
+ Defn: Defined on coordinates by sending (x : y) to
617
+ (x^2 + 3*y^2 : y^2)
618
+
619
+ ::
620
+
621
+ sage: # needs sage.rings.number_field
622
+ sage: R.<x> = PolynomialRing(QQ)
623
+ sage: K.<i> = NumberField(x^2 + 1)
624
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
625
+ sage: H = Hom(P, P)
626
+ sage: f = H([1/3*x^2 + 1/2*y^2, y^2])
627
+ sage: matrix([[i,0], [0,i]]) * f # needs sage.modules
628
+ Scheme endomorphism of Projective Space of dimension 1 over
629
+ Number Field in i with defining polynomial x^2 + 1
630
+ Defn: Defined on coordinates by sending (x : y) to
631
+ ((1/3*i)*x^2 + (1/2*i)*y^2 : i*y^2)
632
+ """
633
+ from sage.modules.free_module_element import vector
634
+
635
+ if not mat.is_square():
636
+ raise ValueError("matrix must be square")
637
+ if mat.ncols() != self.codomain().ngens():
638
+ raise ValueError("matrix size is incompatible")
639
+ F = mat * vector(list(self))
640
+ if isinstance(self, DynamicalSystem):
641
+ return h(list(F)).as_dynamical_system()
642
+ return h(list(F))
643
+
644
+ def _polymap_times_matrix_(self, mat, h):
645
+ """
646
+ Multiply the morphism on the right by a matrix ``mat``.
647
+
648
+ INPUT:
649
+
650
+ - ``mat`` -- a matrix
651
+
652
+ OUTPUT: a scheme morphism given by ``mat*self``
653
+
654
+ EXAMPLES::
655
+
656
+ sage: P.<x,y> = ProjectiveSpace(ZZ, 1)
657
+ sage: H = Hom(P, P)
658
+ sage: f = H([x^2 + y^2, y^2])
659
+ sage: f * matrix([[1,2], [0,1]]) # needs sage.modules
660
+ Scheme endomorphism of Projective Space of dimension 1 over Integer Ring
661
+ Defn: Defined on coordinates by sending (x : y) to
662
+ (x^2 + 4*x*y + 5*y^2 : y^2)
663
+
664
+ ::
665
+
666
+ sage: # needs sage.rings.number_field
667
+ sage: R.<x> = PolynomialRing(QQ)
668
+ sage: K.<i> = NumberField(x^2 + 1)
669
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
670
+ sage: H = Hom(P, P)
671
+ sage: f = H([1/3*x^2 + 1/2*y^2, y^2])
672
+ sage: f * matrix([[i,0], [0,i]]) # needs sage.modules
673
+ Scheme endomorphism of Projective Space of dimension 1 over
674
+ Number Field in i with defining polynomial x^2 + 1
675
+ Defn: Defined on coordinates by sending (x : y) to
676
+ (-1/3*x^2 - 1/2*y^2 : -y^2)
677
+ """
678
+ from sage.modules.free_module_element import vector
679
+ if not mat.is_square():
680
+ raise ValueError("matrix must be square")
681
+ if mat.nrows() != self.domain().ngens():
682
+ raise ValueError("matrix size is incompatible")
683
+ X = mat * vector(self[0].parent().gens())
684
+ F = vector(self._polys)
685
+ F = F(list(X))
686
+ if isinstance(self, DynamicalSystem):
687
+ return h(list(F)).as_dynamical_system()
688
+ return h(list(F))
689
+
690
+ def as_dynamical_system(self):
691
+ """
692
+ Return this endomorphism as a :class:`DynamicalSystem_projective`.
693
+
694
+ OUTPUT: :class:`DynamicalSystem_projective`
695
+
696
+ EXAMPLES::
697
+
698
+ sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2)
699
+ sage: H = End(P)
700
+ sage: f = H([x^2, y^2, z^2])
701
+ sage: type(f.as_dynamical_system()) # needs sage.schemes
702
+ <class 'sage.dynamics.arithmetic_dynamics.projective_ds.DynamicalSystem_projective'>
703
+
704
+ ::
705
+
706
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
707
+ sage: H = End(P)
708
+ sage: f = H([x^2 - y^2, y^2])
709
+ sage: type(f.as_dynamical_system()) # needs sage.schemes
710
+ <class 'sage.dynamics.arithmetic_dynamics.projective_ds.DynamicalSystem_projective_field'>
711
+
712
+ ::
713
+
714
+ sage: P.<x,y> = ProjectiveSpace(GF(5), 1)
715
+ sage: H = End(P)
716
+ sage: f = H([x^2, y^2])
717
+ sage: type(f.as_dynamical_system()) # needs sage.schemes
718
+ <class 'sage.dynamics.arithmetic_dynamics.projective_ds.DynamicalSystem_projective_finite_field'>
719
+
720
+ ::
721
+
722
+ sage: P.<x,y> = ProjectiveSpace(RR, 1)
723
+ sage: f = DynamicalSystem([x^2 + y^2, y^2], P) # needs sage.schemes
724
+ sage: g = f.as_dynamical_system() # needs sage.schemes
725
+ sage: g is f # needs sage.schemes
726
+ True
727
+ """
728
+ if isinstance(self, DynamicalSystem):
729
+ return self
730
+ if not self.is_endomorphism():
731
+ raise TypeError("must be an endomorphism")
732
+ R = self.base_ring()
733
+ if R not in _Fields:
734
+ return DynamicalSystem_projective(list(self), self.domain())
735
+ if isinstance(R, FiniteField):
736
+ return DynamicalSystem_projective_finite_field(list(self), self.domain())
737
+ return DynamicalSystem_projective_field(list(self), self.domain())
738
+
739
+ def scale_by(self, t):
740
+ """
741
+ Scale each coordinate by a factor of ``t``.
742
+
743
+ A :exc:`TypeError` occurs if the point is not in the coordinate ring
744
+ of the parent after scaling.
745
+
746
+ INPUT:
747
+
748
+ - ``t`` -- a ring element
749
+
750
+ OUTPUT: none
751
+
752
+ EXAMPLES::
753
+
754
+ sage: A.<x,y> = ProjectiveSpace(QQ, 1)
755
+ sage: H = Hom(A, A)
756
+ sage: f = H([x^3 - 2*x*y^2, x^2*y])
757
+ sage: f.scale_by(1/x)
758
+ sage: f
759
+ Scheme endomorphism of Projective Space of dimension 1 over Rational Field
760
+ Defn: Defined on coordinates by sending (x : y) to (x^2 - 2*y^2 : x*y)
761
+
762
+ ::
763
+
764
+ sage: R.<t> = PolynomialRing(QQ)
765
+ sage: P.<x,y> = ProjectiveSpace(R, 1)
766
+ sage: H = Hom(P,P)
767
+ sage: f = H([3/5*x^2, 6*y^2])
768
+ sage: f.scale_by(5/3*t); f
769
+ Scheme endomorphism of Projective Space of dimension 1 over
770
+ Univariate Polynomial Ring in t over Rational Field
771
+ Defn: Defined on coordinates by sending (x : y) to (t*x^2 : 10*t*y^2)
772
+
773
+ ::
774
+
775
+ sage: P.<x,y,z> = ProjectiveSpace(GF(7), 2)
776
+ sage: X = P.subscheme(x^2 - y^2)
777
+ sage: H = Hom(X, X)
778
+ sage: f = H([x^2, y^2, z^2])
779
+ sage: f.scale_by(x - y); f # needs sage.libs.singular
780
+ Scheme endomorphism of Closed subscheme of Projective Space of dimension 2
781
+ over Finite Field of size 7 defined by: x^2 - y^2
782
+ Defn: Defined on coordinates by sending (x : y : z) to
783
+ (x*y^2 - y^3 : x*y^2 - y^3 : x*z^2 - y*z^2)
784
+ """
785
+ if t == 0:
786
+ raise ValueError("Cannot scale by 0")
787
+ R = self.domain().coordinate_ring()
788
+ if isinstance(R, QuotientRing_generic):
789
+ phi = R._internal_coerce_map_from(self.domain().ambient_space().coordinate_ring())
790
+ for i in range(self.codomain().ambient_space().dimension_relative() + 1):
791
+ new_polys = [phi(u * t).lift() for u in self]
792
+ else:
793
+ for i in range(self.codomain().ambient_space().dimension_relative() + 1):
794
+ new_polys = [R(u * t) for u in self]
795
+ self._polys = tuple(new_polys)
796
+
797
+ def normalize_coordinates(self, **kwds):
798
+ """
799
+ Ensures that this morphism has integral coefficients.
800
+ If the coordinate ring has a GCD, then it ensures that the
801
+ coefficients have no common factor.
802
+
803
+ It also makes the leading coefficients of the first polynomial
804
+ positive (if positive has meaning in the coordinate ring).
805
+ This is done in place.
806
+
807
+ When ``ideal`` or ``valuation`` is specified, normalization occurs
808
+ with respect to the absolute value defined by the ``ideal`` or
809
+ ``valuation``. That is, the coefficients are scaled such that
810
+ one coefficient has absolute value 1 while the others have
811
+ absolute value less than or equal to 1.
812
+ Only supported when the base ring is a number field.
813
+
814
+ INPUT: keyword arguments:
815
+
816
+ - ``ideal`` -- (optional) a prime ideal of the base ring of this
817
+ morphism
818
+
819
+ - ``valuation`` -- (optional) a valuation of the base ring of this
820
+ morphism
821
+
822
+ OUTPUT: none
823
+
824
+ EXAMPLES::
825
+
826
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
827
+ sage: H = Hom(P, P)
828
+ sage: f = H([5/4*x^3, 5*x*y^2])
829
+ sage: f.normalize_coordinates(); f
830
+ Scheme endomorphism of Projective Space of dimension 1 over Rational Field
831
+ Defn: Defined on coordinates by sending (x : y) to (x^2 : 4*y^2)
832
+
833
+ ::
834
+
835
+ sage: P.<x,y,z> = ProjectiveSpace(GF(7), 2)
836
+ sage: X = P.subscheme(x^2 - y^2)
837
+ sage: H = Hom(X, X)
838
+ sage: f = H([x^3 + x*y^2, x*y^2, x*z^2])
839
+ sage: f.normalize_coordinates(); f # needs sage.libs.singular
840
+ Scheme endomorphism of Closed subscheme of Projective Space of dimension 2
841
+ over Finite Field of size 7 defined by: x^2 - y^2
842
+ Defn: Defined on coordinates by sending (x : y : z) to (2*y^2 : y^2 : z^2)
843
+
844
+ ::
845
+
846
+ sage: R.<a,b> = QQ[]
847
+ sage: P.<x,y,z> = ProjectiveSpace(R, 2)
848
+ sage: H = End(P)
849
+ sage: f = H([a*(x*z + y^2)*x^2, a*b*(x*z + y^2)*y^2, a*(x*z + y^2)*z^2])
850
+ sage: f.normalize_coordinates(); f
851
+ Scheme endomorphism of Projective Space of dimension 2 over
852
+ Multivariate Polynomial Ring in a, b over Rational Field
853
+ Defn: Defined on coordinates by sending (x : y : z) to (x^2 : b*y^2 : z^2)
854
+
855
+ ::
856
+
857
+ sage: # needs sage.rings.number_field sage.schemes
858
+ sage: K.<w> = QuadraticField(5)
859
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
860
+ sage: f = DynamicalSystem([w*x^2 + (1/5*w)*y^2, w*y^2])
861
+ sage: f.normalize_coordinates(); f
862
+ Dynamical System of Projective Space of dimension 1 over Number Field in w
863
+ with defining polynomial x^2 - 5 with w = 2.236067977499790?
864
+ Defn: Defined on coordinates by sending (x : y) to (5*x^2 + y^2 : 5*y^2)
865
+
866
+ ::
867
+
868
+ sage: # needs sage.rings.number_field sage.schemes
869
+ sage: R.<t> = PolynomialRing(ZZ)
870
+ sage: K.<b> = NumberField(t^3 - 11)
871
+ sage: a = 7/(b - 1)
872
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
873
+ sage: f = DynamicalSystem_projective([a*y^2 - (a*y - x)^2, y^2])
874
+ sage: f.normalize_coordinates(); f
875
+ Dynamical System of Projective Space of dimension 1 over
876
+ Number Field in b with defining polynomial t^3 - 11
877
+ Defn: Defined on coordinates by sending (x : y) to
878
+ (-100*x^2 + (140*b^2 + 140*b + 140)*x*y + (-77*b^2 - 567*b - 1057)*y^2
879
+ : 100*y^2)
880
+
881
+ We can used ``ideal`` to scale with respect to a norm defined by an ideal::
882
+
883
+ sage: # needs sage.schemes
884
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
885
+ sage: f = DynamicalSystem_projective([2*x^3, 2*x^2*y + 4*x*y^2])
886
+ sage: f.normalize_coordinates(ideal=2); f
887
+ Dynamical System of Projective Space of dimension 1 over Rational Field
888
+ Defn: Defined on coordinates by sending (x : y) to (x^3 : x^2*y + 2*x*y^2)
889
+
890
+ ::
891
+
892
+ sage: # needs sage.rings.number_field
893
+ sage: R.<w> = QQ[]
894
+ sage: A.<a> = NumberField(w^2 + 1)
895
+ sage: P.<x,y,z> = ProjectiveSpace(A, 2)
896
+ sage: X = P.subscheme(x^2 - y^2)
897
+ sage: H = Hom(X, X)
898
+ sage: f = H([(a+1)*x^3 + 2*x*y^2, 4*x*y^2, 8*x*z^2])
899
+ sage: f.normalize_coordinates(ideal=A.prime_above(2)); f
900
+ Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over
901
+ Number Field in a with defining polynomial w^2 + 1 defined by: x^2 - y^2
902
+ Defn: Defined on coordinates by sending (x : y : z) to
903
+ ((-a + 2)*x*y^2 : (-2*a + 2)*x*y^2 : (-4*a + 4)*x*z^2)
904
+
905
+ We can pass in a valuation to ``valuation``::
906
+
907
+ sage: g = H([(a+1)*x^3 + 2*x*y^2, 4*x*y^2, 8*x*z^2]) # needs sage.rings.number_field
908
+ sage: g.normalize_coordinates(valuation=A.valuation(A.prime_above(2))) # needs sage.geometry.polyhedron sage.rings.number_field
909
+ sage: g == f # needs sage.geometry.polyhedron sage.rings.number_field
910
+ True
911
+
912
+ ::
913
+
914
+ sage: # needs sage.rings.padics sage.schemes
915
+ sage: P.<x,y> = ProjectiveSpace(Qp(3), 1)
916
+ sage: f = DynamicalSystem_projective([3*x^2 + 6*y^2, 9*x*y])
917
+ sage: f.normalize_coordinates(); f
918
+ Dynamical System of Projective Space of dimension 1 over
919
+ 3-adic Field with capped relative precision 20
920
+ Defn: Defined on coordinates by sending (x : y) to
921
+ (x^2 + (2 + O(3^20))*y^2 : (3 + O(3^21))*x*y)
922
+
923
+ Check that #35797 is fixed::
924
+
925
+ sage: # needs sage.rings.number_field sage.schemes
926
+ sage: R.<x> = QQ[]
927
+ sage: K.<a> = NumberField(3*x^2 + 1)
928
+ sage: P.<z,w> = ProjectiveSpace(K, 1)
929
+ sage: f = DynamicalSystem_projective([a*(z^2 + w^2), z*w])
930
+ sage: f.normalize_coordinates(); f
931
+ Dynamical System of Projective Space of dimension 1 over
932
+ Number Field in a with defining polynomial 3*x^2 + 1
933
+ Defn: Defined on coordinates by sending (z : w) to
934
+ ((3/2*a + 1/2)*z^2 + (3/2*a + 1/2)*w^2 : (-3/2*a + 3/2)*z*w)
935
+
936
+ ::
937
+
938
+ sage: R.<a,b> = QQ[]
939
+ sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2)
940
+ sage: H = End(P)
941
+ sage: f = H([a/b*(x*z + y^2)*x^2, a*b*(x*z + y^2)*y^2, a*(x*z + y^2)*z^2])
942
+ sage: f.normalize_coordinates(); f
943
+ Scheme endomorphism of Projective Space of dimension 2 over Fraction
944
+ Field of Multivariate Polynomial Ring in a, b over Rational Field
945
+ Defn: Defined on coordinates by sending (x : y : z) to
946
+ (x^2 : (b^2)*y^2 : b*z^2)
947
+ """
948
+ # If ideal or valuation is specified, we scale according the norm
949
+ # defined by the ideal/valuation
950
+ ideal = kwds.pop('ideal', None)
951
+ if ideal is not None:
952
+ if not (ideal in ZZ or isinstance(ideal, NumberFieldFractionalIdeal)):
953
+ raise TypeError('ideal must be an ideal of a number field, not %s' % ideal)
954
+ if isinstance(ideal, NumberFieldFractionalIdeal):
955
+ if ideal.number_field() != self.base_ring():
956
+ raise ValueError('ideal must be an ideal of the base ring of this morphism ' +
957
+ ', not an ideal of %s' % ideal.number_field())
958
+ if not ideal.is_prime():
959
+ raise ValueError('ideal was %s, not a prime ideal' % ideal)
960
+ for generator in ideal.gens():
961
+ if generator.valuation(ideal) == 1:
962
+ uniformizer = generator
963
+ break
964
+ else:
965
+ ideal = ZZ(ideal)
966
+ if self.base_ring() != QQ:
967
+ raise ValueError('ideal was an integer, but the base ring of this ' +
968
+ 'morphism is %s' % self.base_ring())
969
+ if not ideal.is_prime():
970
+ raise ValueError('ideal must be a prime, not %s' % ideal)
971
+ uniformizer = ideal
972
+ valuations = []
973
+ for poly in self:
974
+ for coefficient, monomial in poly:
975
+ if coefficient != 0:
976
+ valuations.append(coefficient.valuation(ideal))
977
+ min_val = min(valuations)
978
+ self.scale_by(uniformizer**(-1 * min_val))
979
+ return
980
+
981
+ valuation = kwds.pop('valuation', None)
982
+ if valuation is not None:
983
+ if not isinstance(valuation, pAdicValuation_base):
984
+ raise TypeError('valuation must be a valuation on a number field, not %s' % valuation)
985
+ if valuation.domain() != self.base_ring():
986
+ raise ValueError('the domain of valuation must be the base ring of this morphism ' +
987
+ 'not %s' % valuation.domain())
988
+ uniformizer = valuation.uniformizer()
989
+ ramification_index = 1 / valuation(uniformizer)
990
+ valuations = []
991
+ for poly in self:
992
+ for coefficient, monomial in poly:
993
+ if coefficient != 0:
994
+ valuations.append(valuation(coefficient) * ramification_index)
995
+ min_val = min(valuations)
996
+ self.scale_by(uniformizer**(-1 * min_val))
997
+ return
998
+
999
+ N = self.codomain().ambient_space().dimension_relative() + 1
1000
+
1001
+ R = self.domain().base_ring()
1002
+
1003
+ # Clear any denominators from the coefficients
1004
+ if R in NumberFields():
1005
+ if R.maximal_order() is ZZ:
1006
+ denom = lcm([self[i].denominator() for i in range(N)])
1007
+ else:
1008
+ denom = R.ideal([c for poly in self for c in poly.coefficients()]).norm().denominator()
1009
+
1010
+ self.scale_by(denom)
1011
+ else:
1012
+ self.scale_by(lcm([self[i].denominator() for i in range(N)]))
1013
+
1014
+ # There are cases, such as the example above over GF(7),
1015
+ # where we want to compute GCDs, but NOT in the case
1016
+ # where R is a NumberField of class number > 1.
1017
+ if R in NumberFields():
1018
+ if R.class_number() > 1:
1019
+ return
1020
+
1021
+ # R is a Number Field with class number 1 (i.e., a UFD) then
1022
+ # we can compute GCDs, so we attempt to remove any common factors.
1023
+
1024
+ GCD = gcd(self[0], self[1])
1025
+ index = 2
1026
+
1027
+ while GCD != 1 and index < N:
1028
+ GCD = gcd(GCD, self[index])
1029
+ index += +1
1030
+ if GCD != 1:
1031
+ self.scale_by(R(1) / GCD)
1032
+
1033
+ # Scale by 1/GCD of the coefficients.
1034
+ if R in _NumberFields:
1035
+ O = R.maximal_order()
1036
+ elif isinstance(R, FiniteField):
1037
+ O = R
1038
+ elif isinstance(R, QuotientRing_generic):
1039
+ O = R.ring()
1040
+ elif isinstance(R, sage.rings.abc.pAdicField):
1041
+ O = R.integer_ring()
1042
+ else:
1043
+ O = R
1044
+ GCD = gcd([O(c) for poly in self for c in poly.coefficients()])
1045
+
1046
+ if GCD != 1:
1047
+ self.scale_by(1 / GCD)
1048
+
1049
+ # If R is not p-adic, we make the first coordinate positive
1050
+ if not isinstance(R, pAdicGeneric):
1051
+ if self[0].lc() < 0:
1052
+ self.scale_by(-1)
1053
+
1054
+ def degree(self):
1055
+ r"""
1056
+ Return the degree of this map.
1057
+
1058
+ The degree is defined as the degree of the homogeneous
1059
+ polynomials that are the coordinates of this map.
1060
+
1061
+ OUTPUT: positive integer
1062
+
1063
+ EXAMPLES::
1064
+
1065
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1066
+ sage: H = Hom(P, P)
1067
+ sage: f = H([x^2 + y^2, y^2])
1068
+ sage: f.degree()
1069
+ 2
1070
+
1071
+ ::
1072
+
1073
+ sage: # needs sage.rings.real_mpfr
1074
+ sage: P.<x,y,z> = ProjectiveSpace(CC, 2)
1075
+ sage: H = Hom(P, P)
1076
+ sage: f = H([x^3 + y^3, y^2*z, z*x*y])
1077
+ sage: f.degree()
1078
+ 3
1079
+
1080
+ ::
1081
+
1082
+ sage: R.<t> = PolynomialRing(QQ)
1083
+ sage: P.<x,y,z> = ProjectiveSpace(R, 2)
1084
+ sage: H = Hom(P, P)
1085
+ sage: f = H([x^2 + t*y^2, (2-t)*y^2, z^2])
1086
+ sage: f.degree()
1087
+ 2
1088
+
1089
+ ::
1090
+
1091
+ sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2)
1092
+ sage: X = P.subscheme(x^2 - y^2)
1093
+ sage: H = Hom(X, X)
1094
+ sage: f = H([x^2, y^2, z^2])
1095
+ sage: f.degree()
1096
+ 2
1097
+ """
1098
+ return self._polys[0].degree()
1099
+
1100
+ def dehomogenize(self, n):
1101
+ r"""
1102
+ Return the standard dehomogenization at the ``n[0]`` coordinate for the domain
1103
+ and the ``n[1]`` coordinate for the codomain.
1104
+
1105
+ Note that the new function is defined over the fraction field
1106
+ of the base ring of this map.
1107
+
1108
+ INPUT:
1109
+
1110
+ - ``n`` -- tuple of nonnegative integers; if ``n`` is an integer, then
1111
+ the two values of the tuple are assumed to be the same
1112
+
1113
+ OUTPUT: :class:`SchemeMorphism_polynomial_affine_space`
1114
+
1115
+ EXAMPLES::
1116
+
1117
+ sage: P.<x,y> = ProjectiveSpace(ZZ, 1)
1118
+ sage: H = Hom(P, P)
1119
+ sage: f = H([x^2 + y^2, y^2])
1120
+ sage: f.dehomogenize(0)
1121
+ Scheme endomorphism of Affine Space of dimension 1 over Integer Ring
1122
+ Defn: Defined on coordinates by sending (y) to (y^2/(y^2 + 1))
1123
+
1124
+ ::
1125
+
1126
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1127
+ sage: H = Hom(P, P)
1128
+ sage: f = H([x^2 - y^2, y^2])
1129
+ sage: f.dehomogenize((0,1))
1130
+ Scheme morphism:
1131
+ From: Affine Space of dimension 1 over Rational Field
1132
+ To: Affine Space of dimension 1 over Rational Field
1133
+ Defn: Defined on coordinates by sending (y) to ((-y^2 + 1)/y^2)
1134
+
1135
+ ::
1136
+
1137
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1138
+ sage: H = Hom(P, P)
1139
+ sage: f = H([x^2 + y^2, y^2 - z^2, 2*z^2])
1140
+ sage: f.dehomogenize(2)
1141
+ Scheme endomorphism of Affine Space of dimension 2 over Rational Field
1142
+ Defn: Defined on coordinates by sending (x, y) to
1143
+ (1/2*x^2 + 1/2*y^2, 1/2*y^2 - 1/2)
1144
+
1145
+ ::
1146
+
1147
+ sage: R.<t> = PolynomialRing(QQ)
1148
+ sage: P.<x,y,z> = ProjectiveSpace(FractionField(R),2)
1149
+ sage: H = Hom(P,P)
1150
+ sage: f = H([x^2 + t*y^2, t*y^2 - z^2, t*z^2])
1151
+ sage: f.dehomogenize(2)
1152
+ Scheme endomorphism of Affine Space of dimension 2 over Fraction Field
1153
+ of Univariate Polynomial Ring in t over Rational Field
1154
+ Defn: Defined on coordinates by sending (x, y) to
1155
+ (1/t*x^2 + y^2, y^2 - 1/t)
1156
+
1157
+ ::
1158
+
1159
+ sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2)
1160
+ sage: X = P.subscheme(x^2 - y^2)
1161
+ sage: H = Hom(X, X)
1162
+ sage: f = H([x^2, y^2, x*z])
1163
+ sage: f.dehomogenize(2) # needs sage.libs.singular
1164
+ Scheme endomorphism of Closed subscheme of Affine Space of dimension 2
1165
+ over Integer Ring defined by: x^2 - y^2
1166
+ Defn: Defined on coordinates by sending (x, y) to (x, y^2/x)
1167
+
1168
+ ::
1169
+
1170
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1171
+ sage: H = End(P)
1172
+ sage: f = H([x^2 - 2*x*y, y^2])
1173
+ sage: f.dehomogenize(0).homogenize(0) == f
1174
+ True
1175
+
1176
+ ::
1177
+
1178
+ sage: # needs sage.rings.number_field
1179
+ sage: K.<w> = QuadraticField(3)
1180
+ sage: O = K.ring_of_integers()
1181
+ sage: P.<x,y> = ProjectiveSpace(O, 1)
1182
+ sage: H = End(P)
1183
+ sage: f = H([x^2 - O(w)*y^2, y^2])
1184
+ sage: f.dehomogenize(1)
1185
+ Scheme endomorphism of Affine Space of dimension 1 over
1186
+ Maximal Order generated by w in Number Field in w with defining polynomial x^2 - 3
1187
+ with w = 1.732050807568878?
1188
+ Defn: Defined on coordinates by sending (x) to (x^2 - w)
1189
+
1190
+ ::
1191
+
1192
+ sage: P1.<x,y> = ProjectiveSpace(QQ, 1)
1193
+ sage: P2.<u,v,w> = ProjectiveSpace(QQ, 2)
1194
+ sage: H = Hom(P2, P1)
1195
+ sage: f = H([u*w, v^2 + w^2])
1196
+ sage: f.dehomogenize((2,1))
1197
+ Scheme morphism:
1198
+ From: Affine Space of dimension 2 over Rational Field
1199
+ To: Affine Space of dimension 1 over Rational Field
1200
+ Defn: Defined on coordinates by sending (u, v) to (u/(v^2 + 1))
1201
+ """
1202
+ # the dehomogenizations are stored for future use
1203
+ try:
1204
+ return self.__dehomogenization[n]
1205
+ except AttributeError:
1206
+ self.__dehomogenization = {}
1207
+ except KeyError:
1208
+ pass
1209
+ # it is possible to dehomogenize the domain and codomain at different coordinates
1210
+ if isinstance(n, (tuple, list)):
1211
+ ind = tuple(n)
1212
+ else:
1213
+ ind = (n, n)
1214
+ PS_domain = self.domain()
1215
+ A_domain = PS_domain.ambient_space()
1216
+ if self._polys[ind[1]].substitute({A_domain.gen(ind[0]): 1}) == 0:
1217
+ raise ValueError("can't dehomogenize at 0 coordinate")
1218
+ else:
1219
+ Aff_domain = PS_domain.affine_patch(ind[0])
1220
+ S = Aff_domain.ambient_space().coordinate_ring()
1221
+ FS = FractionField(S)
1222
+ N = A_domain.dimension_relative()
1223
+ R = A_domain.coordinate_ring()
1224
+ phi = R.hom([S.gen(j) for j in range(0, ind[0])] + [1] + [S.gen(j) for j in range(ind[0], N)], FS)
1225
+ F = []
1226
+ G = phi(self._polys[ind[1]])
1227
+ # ind[1] is relative to codomain
1228
+ M = self.codomain().ambient_space().dimension_relative()
1229
+ F.extend(phi(self._polys[i]) / G
1230
+ for i in range(M + 1) if i != ind[1])
1231
+ H = Hom(Aff_domain, self.codomain().affine_patch(ind[1]))
1232
+ # since often you dehomogenize at the same coordinate in domain
1233
+ # and codomain it should be stored appropriately.
1234
+ if ind == (n, n):
1235
+ self.__dehomogenization[ind] = H(F)
1236
+ return self.__dehomogenization[ind]
1237
+ else:
1238
+ self.__dehomogenization[n] = H(F)
1239
+ return self.__dehomogenization[n]
1240
+
1241
+ @cached_method
1242
+ def is_morphism(self):
1243
+ r"""
1244
+ Return ``True`` if this map is a morphism.
1245
+
1246
+ The map is a morphism if and only if the ideal generated by
1247
+ the defining polynomials is the unit ideal
1248
+ (no common zeros of the defining polynomials).
1249
+
1250
+ OUTPUT: boolean
1251
+
1252
+ EXAMPLES::
1253
+
1254
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1255
+ sage: H = Hom(P, P)
1256
+ sage: f = H([x^2 + y^2, y^2])
1257
+ sage: f.is_morphism() # needs sage.libs.singular
1258
+ True
1259
+
1260
+ ::
1261
+
1262
+ sage: P.<x,y,z> = ProjectiveSpace(RR, 2)
1263
+ sage: H = Hom(P, P)
1264
+ sage: f = H([x*z - y*z, x^2 - y^2, z^2])
1265
+ sage: f.is_morphism() # needs sage.libs.singular
1266
+ False
1267
+
1268
+ ::
1269
+
1270
+ sage: R.<t> = PolynomialRing(GF(5))
1271
+ sage: P.<x,y,z> = ProjectiveSpace(R, 2)
1272
+ sage: H = Hom(P, P)
1273
+ sage: f = H([x*z - t*y^2, x^2 - y^2, t*z^2])
1274
+ sage: f.is_morphism() # needs sage.libs.singular
1275
+ True
1276
+
1277
+ Map that is not morphism on projective space, but is over a subscheme::
1278
+
1279
+ sage: P.<x,y,z> = ProjectiveSpace(RR, 2)
1280
+ sage: X = P.subscheme([x*y + y*z])
1281
+ sage: H = Hom(X, X)
1282
+ sage: f = H([x*z - y*z, x^2 - y^2, z^2])
1283
+ sage: f.is_morphism() # needs sage.libs.singular
1284
+ True
1285
+ """
1286
+
1287
+ R = self.coordinate_ring()
1288
+ F = list(self._polys)
1289
+ defpolys = list(self.domain().defining_polynomials())
1290
+ if R.base_ring().is_field():
1291
+ F.extend(defpolys)
1292
+ J = R.ideal(F)
1293
+ else:
1294
+ S = PolynomialRing(R.base_ring().fraction_field(), R.gens(), R.ngens())
1295
+ L = [S(f) for f in F] + [S(f) for f in defpolys]
1296
+ J = S.ideal(L)
1297
+ if J.dimension() > 0:
1298
+ return False
1299
+ else:
1300
+ return True
1301
+
1302
+ def global_height(self, prec=None):
1303
+ r"""
1304
+ Return the global height of the coefficients as a projective point.
1305
+
1306
+ INPUT:
1307
+
1308
+ - ``prec`` -- desired floating point precision (default:
1309
+ default RealField precision)
1310
+
1311
+ OUTPUT: a real number
1312
+
1313
+ EXAMPLES::
1314
+
1315
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1316
+ sage: H = Hom(P, P)
1317
+ sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]);
1318
+ sage: f.global_height() # needs sage.symbolic
1319
+ 20.8348429892146
1320
+
1321
+ ::
1322
+
1323
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1324
+ sage: H = Hom(P, P)
1325
+ sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y]);
1326
+ sage: f.global_height(prec=11) # needs sage.symbolic
1327
+ 20.8
1328
+
1329
+ ::
1330
+
1331
+ sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2)
1332
+ sage: H = Hom(P, P)
1333
+ sage: f = H([4*x^2 + 100*y^2, 210*x*y, 10000*z^2]);
1334
+ sage: f.global_height() # needs sage.symbolic
1335
+ 8.51719319141624
1336
+
1337
+ ::
1338
+
1339
+ sage: # needs sage.rings.number_field
1340
+ sage: R.<z> = PolynomialRing(QQ)
1341
+ sage: K.<w> = NumberField(z^2 - 2)
1342
+ sage: O = K.maximal_order()
1343
+ sage: P.<x,y> = ProjectiveSpace(O, 1)
1344
+ sage: H = Hom(P, P)
1345
+ sage: f = H([2*x^2 + 3*O(w)*y^2, O(w)*y^2])
1346
+ sage: f.global_height()
1347
+ 1.09861228866811
1348
+
1349
+ ::
1350
+
1351
+ sage: # needs sage.rings.number_field sage.symbolic
1352
+ sage: P.<x,y> = ProjectiveSpace(QQbar, 1)
1353
+ sage: P2.<u,v,w> = ProjectiveSpace(QQbar, 2)
1354
+ sage: H = Hom(P, P2)
1355
+ sage: f = H([x^2 + QQbar(I)*x*y + 3*y^2, y^2, QQbar(sqrt(5))*x*y])
1356
+ sage: f.global_height()
1357
+ 1.09861228866811
1358
+
1359
+ ::
1360
+
1361
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1362
+ sage: A.<z,w> = ProjectiveSpace(QQ, 1)
1363
+ sage: H = Hom(P, A)
1364
+ sage: f = H([1/1331*x^2 + 4000*y*z, y^2])
1365
+ sage: f.global_height() # needs sage.symbolic
1366
+ 15.4877354584971
1367
+
1368
+ ::
1369
+
1370
+ sage: # needs sage.schemes
1371
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1372
+ sage: f = DynamicalSystem([1/25*x^2 + 25/3*x*y + y^2, 1*y^2])
1373
+ sage: exp(f.global_height()) # needs sage.symbolic
1374
+ 625.000000000000
1375
+
1376
+ Scaling should not change the result::
1377
+
1378
+ sage: # needs sage.schemes
1379
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1380
+ sage: f = DynamicalSystem([1/25*x^2 + 25/3*x*y + y^2, 1*y^2])
1381
+ sage: f.global_height() # needs sage.symbolic
1382
+ 6.43775164973640
1383
+ sage: c = 10000
1384
+ sage: f.scale_by(c)
1385
+ sage: f.global_height() # needs sage.symbolic
1386
+ 6.43775164973640
1387
+ """
1388
+ K = self.domain().base_ring()
1389
+ if K in _NumberFields or K == ZZ or isinstance(K, sage.rings.abc.Order):
1390
+ f = self
1391
+ elif isinstance(K, sage.rings.abc.AlgebraicField):
1392
+ f = self._number_field_from_algebraics()
1393
+ else:
1394
+ raise TypeError("Must be over a Numberfield or a Numberfield Order or QQbar")
1395
+
1396
+ # Get the coefficients from all of the polynomials in the dynamical system
1397
+ coeffs = [x for k in f for x in k.coefficients()]
1398
+
1399
+ from sage.schemes.projective.projective_space import ProjectiveSpace
1400
+
1401
+ P = ProjectiveSpace(K, len(coeffs) - 1)
1402
+ return P.point(coeffs).global_height(prec=prec)
1403
+
1404
+ def local_height(self, v, prec=None):
1405
+ r"""
1406
+ Return the maximum of the local height of the coefficients in any
1407
+ of the coordinate functions of this map.
1408
+
1409
+ INPUT:
1410
+
1411
+ - ``v`` -- a prime or prime ideal of the base ring
1412
+
1413
+ - ``prec`` -- desired floating point precision (default:
1414
+ default RealField precision)
1415
+
1416
+ OUTPUT: a real number
1417
+
1418
+ EXAMPLES::
1419
+
1420
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1421
+ sage: H = Hom(P, P)
1422
+ sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y])
1423
+ sage: f.local_height(1331) # needs sage.rings.real_mpfr
1424
+ 7.19368581839511
1425
+
1426
+ ::
1427
+
1428
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1429
+ sage: H = Hom(P, P)
1430
+ sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y])
1431
+ sage: f.local_height(1331, prec=2) # needs sage.rings.real_mpfr
1432
+ 8.0
1433
+
1434
+ This function does not automatically normalize::
1435
+
1436
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1437
+ sage: H = Hom(P, P)
1438
+ sage: f = H([4*x^2 + 3/100*y^2, 8/210*x*y, 1/10000*z^2])
1439
+ sage: f.local_height(2) # needs sage.rings.real_mpfr
1440
+ 2.77258872223978
1441
+ sage: f.normalize_coordinates() # needs sage.libs.singular
1442
+ sage: f.local_height(2) # needs sage.libs.singular
1443
+ 0.000000000000000
1444
+
1445
+ ::
1446
+
1447
+ sage: # needs sage.rings.number_field
1448
+ sage: R.<z> = PolynomialRing(QQ)
1449
+ sage: K.<w> = NumberField(z^2 - 2)
1450
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
1451
+ sage: H = Hom(P, P)
1452
+ sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2])
1453
+ sage: f.local_height(K.ideal(3))
1454
+ 1.09861228866811
1455
+ """
1456
+ K = FractionField(self.domain().base_ring())
1457
+ if K not in _NumberFields:
1458
+ raise TypeError("must be over a number field or a number field order")
1459
+ return max([K(c).local_height(v, prec=prec) for f in self for c in f.coefficients()])
1460
+
1461
+ def local_height_arch(self, i, prec=None):
1462
+ r"""
1463
+ Return the maximum of the local height at the ``i``-th infinite place of the coefficients in any
1464
+ of the coordinate functions of this map.
1465
+
1466
+ INPUT:
1467
+
1468
+ - ``i`` -- integer
1469
+
1470
+ - ``prec`` -- desired floating point precision (default:
1471
+ default RealField precision)
1472
+
1473
+ OUTPUT: a real number
1474
+
1475
+ EXAMPLES::
1476
+
1477
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1478
+ sage: H = Hom(P, P)
1479
+ sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y])
1480
+ sage: f.local_height_arch(0) # needs sage.rings.real_mpfr
1481
+ 5.34710753071747
1482
+
1483
+ ::
1484
+
1485
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1486
+ sage: H = Hom(P, P)
1487
+ sage: f = H([1/1331*x^2 + 1/4000*y^2, 210*x*y])
1488
+ sage: f.local_height_arch(0, prec=5) # needs sage.rings.real_mpfr
1489
+ 5.2
1490
+
1491
+ ::
1492
+
1493
+ sage: # needs sage.rings.number_field
1494
+ sage: R.<z> = PolynomialRing(QQ)
1495
+ sage: K.<w> = NumberField(z^2 - 2)
1496
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
1497
+ sage: H = Hom(P, P)
1498
+ sage: f = H([2*x^2 + w/3*y^2, 1/w*y^2])
1499
+ sage: f.local_height_arch(1)
1500
+ 0.6931471805599453094172321214582
1501
+ """
1502
+ K = FractionField(self.domain().base_ring())
1503
+ if K not in _NumberFields:
1504
+ raise TypeError("must be over a number field or a number field order")
1505
+ if K == QQ:
1506
+ return max([K(c).local_height_arch(prec=prec) for f in self for c in f.coefficients()])
1507
+ else:
1508
+ return max([K(c).local_height_arch(i, prec=prec) for f in self for c in f.coefficients()])
1509
+
1510
+ def wronskian_ideal(self):
1511
+ r"""
1512
+ Return the ideal generated by the critical point locus.
1513
+
1514
+ This is the vanishing of the maximal minors of the Jacobian matrix.
1515
+ Not implemented for subvarieties.
1516
+
1517
+ OUTPUT: an ideal in the coordinate ring of the domain of this map
1518
+
1519
+ EXAMPLES::
1520
+
1521
+ sage: # needs sage.rings.number_field
1522
+ sage: R.<x> = PolynomialRing(QQ)
1523
+ sage: K.<w> = NumberField(x^2 + 11)
1524
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
1525
+ sage: H = End(P)
1526
+ sage: f = H([x^2 - w*y^2, w*y^2])
1527
+ sage: f.wronskian_ideal()
1528
+ Ideal ((4*w)*x*y) of Multivariate Polynomial Ring in x, y
1529
+ over Number Field in w with defining polynomial x^2 + 11
1530
+
1531
+ ::
1532
+
1533
+ sage: # needs sage.rings.number_field
1534
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1535
+ sage: P2.<u,v,t> = ProjectiveSpace(K, 2)
1536
+ sage: H = Hom(P, P2)
1537
+ sage: f = H([x^2 - 2*y^2, y^2, x*y])
1538
+ sage: f.wronskian_ideal()
1539
+ Ideal (4*x*y, 2*x^2 + 4*y^2, -2*y^2) of
1540
+ Multivariate Polynomial Ring in x, y over Rational Field
1541
+ """
1542
+ from sage.calculus.functions import jacobian
1543
+
1544
+ dom = self.domain()
1545
+ from sage.schemes.projective.projective_space import ProjectiveSpace_ring
1546
+ if not (isinstance(dom, ProjectiveSpace_ring) and isinstance(self.codomain(), ProjectiveSpace_ring)):
1547
+ raise NotImplementedError("not implemented for subschemes")
1548
+ N = dom.dimension_relative() + 1
1549
+ R = dom.coordinate_ring()
1550
+ J = jacobian(self.defining_polynomials(), dom.gens())
1551
+ return R.ideal(J.minors(N))
1552
+
1553
+
1554
+ class SchemeMorphism_polynomial_projective_space_field(SchemeMorphism_polynomial_projective_space):
1555
+
1556
+ def rational_preimages(self, Q, k=1):
1557
+ r"""
1558
+ Determine all of the rational `k`-th preimages of ``Q`` by this map.
1559
+
1560
+ Given a rational point ``Q`` in the domain of this map, return all the rational points ``P``
1561
+ in the domain with `f^k(P)==Q`. In other words, the set of `k`-th preimages of ``Q``.
1562
+ The map must be defined over a number field and be an endomorphism for `k > 1`.
1563
+
1564
+ If ``Q`` is a subscheme, then return the subscheme that maps to ``Q`` by this map.
1565
+ In particular, `f^{-k}(V(h_1,\ldots,h_t)) = V(h_1 \circ f^k, \ldots, h_t \circ f^k)`.
1566
+
1567
+ INPUT:
1568
+
1569
+ - ``Q`` -- a rational point or subscheme in the domain of this map
1570
+
1571
+ - ``k`` -- positive integer
1572
+
1573
+ OUTPUT: a list of rational points or a subscheme in the domain of this map
1574
+
1575
+ EXAMPLES::
1576
+
1577
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1578
+ sage: H = End(P)
1579
+ sage: f = H([16*x^2 - 29*y^2, 16*y^2])
1580
+ sage: f.rational_preimages(P(-1, 4)) # needs sage.libs.singular
1581
+ [(-5/4 : 1), (5/4 : 1)]
1582
+
1583
+ ::
1584
+
1585
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1586
+ sage: H = End(P)
1587
+ sage: f = H([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2,
1588
+ ....: 67*x^2 - 180*x*y - 157*x*z + 90*y*z,
1589
+ ....: -90*z^2])
1590
+ sage: f.rational_preimages(P(-9, -4, 1)) # needs sage.libs.singular
1591
+ [(0 : 4 : 1)]
1592
+
1593
+ A non-periodic example ::
1594
+
1595
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1596
+ sage: H = End(P)
1597
+ sage: f = H([x^2 + y^2, 2*x*y])
1598
+ sage: f.rational_preimages(P(17, 15)) # needs sage.libs.singular
1599
+ [(3/5 : 1), (5/3 : 1)]
1600
+
1601
+ ::
1602
+
1603
+ sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
1604
+ sage: H = End(P)
1605
+ sage: f = H([x^2 - 2*y*w - 3*w^2, -2*x^2 + y^2 - 2*x*z + 4*y*w + 3*w^2,
1606
+ ....: x^2 - y^2 + 2*x*z + z^2 - 2*y*w - w^2,
1607
+ ....: w^2])
1608
+ sage: f.rational_preimages(P(0, -1, 0, 1)) # needs sage.libs.singular
1609
+ []
1610
+
1611
+ ::
1612
+
1613
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1614
+ sage: H = End(P)
1615
+ sage: f = H([x^2 + y^2, 2*x*y])
1616
+ sage: f.rational_preimages([CC.0, 1]) # needs sage.libs.singular
1617
+ Traceback (most recent call last):
1618
+ ...
1619
+ TypeError: point must be in codomain of self
1620
+
1621
+ A number field example ::
1622
+
1623
+ sage: # needs sage.rings.number_field
1624
+ sage: z = QQ['z'].0
1625
+ sage: K.<a> = NumberField(z^2 - 2)
1626
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
1627
+ sage: H = End(P)
1628
+ sage: f = H([x^2 + y^2, y^2])
1629
+ sage: f.rational_preimages(P(3, 1)) # needs sage.libs.singular
1630
+ [(-a : 1), (a : 1)]
1631
+
1632
+ ::
1633
+
1634
+ sage: # needs sage.rings.number_field
1635
+ sage: z = QQ['z'].0
1636
+ sage: K.<a> = NumberField(z^2 - 2)
1637
+ sage: P.<x,y,z> = ProjectiveSpace(K, 2)
1638
+ sage: X = P.subscheme([x^2 - z^2])
1639
+ sage: H = End(X)
1640
+ sage: f= H([x^2 - z^2, a*y^2, z^2 - x^2])
1641
+ sage: f.rational_preimages(X([1, 2, -1])) # needs sage.libs.singular
1642
+ []
1643
+
1644
+ ::
1645
+
1646
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1647
+ sage: X = P.subscheme([x^2 - z^2])
1648
+ sage: H = End(X)
1649
+ sage: f = H([x^2-z^2, y^2, z^2-x^2])
1650
+ sage: f.rational_preimages(X([0, 1, 0])) # needs sage.libs.singular
1651
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
1652
+ x^2 - z^2,
1653
+ -x^2 + z^2,
1654
+ 0,
1655
+ -x^2 + z^2
1656
+
1657
+ ::
1658
+
1659
+ sage: P.<x, y> = ProjectiveSpace(QQ, 1)
1660
+ sage: H = End(P)
1661
+ sage: f = H([x^2 - y^2, y^2])
1662
+ sage: f.rational_preimages(P.subscheme([x])) # needs sage.libs.singular
1663
+ Closed subscheme of Projective Space of dimension 1 over Rational Field
1664
+ defined by: x^2 - y^2
1665
+
1666
+ ::
1667
+
1668
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1669
+ sage: H = End(P)
1670
+ sage: f = H([x^2 - 29/16*y^2, y^2])
1671
+ sage: f.rational_preimages(P(5/4, 1), k=4) # needs sage.libs.singular
1672
+ [(-3/4 : 1), (3/4 : 1), (-7/4 : 1), (7/4 : 1)]
1673
+
1674
+ ::
1675
+
1676
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
1677
+ sage: P2.<u,v,w> = ProjectiveSpace(QQ, 2)
1678
+ sage: H = Hom(P, P2)
1679
+ sage: f = H([x^2, y^2, x^2-y^2])
1680
+ sage: f.rational_preimages(P2(1, 1, 0)) # needs sage.libs.singular
1681
+ [(-1 : 1), (1 : 1)]
1682
+ """
1683
+ k = ZZ(k)
1684
+ if k <= 0:
1685
+ raise ValueError("k (=%s) must be a positive integer" % k)
1686
+ # first check if subscheme
1687
+ from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective
1688
+ if isinstance(Q, AlgebraicScheme_subscheme_projective):
1689
+ return Q.preimage(self, k)
1690
+
1691
+ # else assume a point
1692
+ BR = self.base_ring()
1693
+ if k > 1 and not self.is_endomorphism():
1694
+ raise TypeError("must be an endomorphism of projective space")
1695
+ if Q not in self.codomain():
1696
+ raise TypeError("point must be in codomain of self")
1697
+ if isinstance(BR.base_ring(), (sage.rings.abc.ComplexField, sage.rings.abc.RealField,
1698
+ sage.rings.abc.RealIntervalField, sage.rings.abc.ComplexIntervalField)):
1699
+ raise NotImplementedError("not implemented over precision fields")
1700
+ PS = self.domain().ambient_space()
1701
+ N = PS.dimension_relative()
1702
+ L = [Q]
1703
+ for n in range(k):
1704
+ L2 = []
1705
+ for P in L:
1706
+ I = list(self.domain().defining_polynomials())
1707
+ I.extend(P[i] * self[j] - P[j] * self[i]
1708
+ for i in range(N + 1) for j in range(i + 1, N + 1))
1709
+ X = PS.subscheme(I)
1710
+ if X.dimension() > 0:
1711
+ return X
1712
+ L2.extend(PS(T) for T in X.rational_points()
1713
+ if not all(g(tuple(T)) == 0 for g in self))
1714
+ L = L2
1715
+ return L
1716
+
1717
+ def _number_field_from_algebraics(self):
1718
+ r"""
1719
+ Given a projective map defined over `\QQbar`, return the same map, but defined
1720
+ over a number field.
1721
+
1722
+ This is only implemented for maps of projective space.
1723
+
1724
+ OUTPUT: scheme morphism
1725
+
1726
+ EXAMPLES::
1727
+
1728
+ sage: # needs sage.rings.number_field
1729
+ sage: R.<x> = PolynomialRing(QQ)
1730
+ sage: P.<x,y> = ProjectiveSpace(QQbar, 1)
1731
+ sage: H = End(P)
1732
+ sage: f = H([QQbar(3^(1/3))*x^2 + QQbar(sqrt(-2))*y^2, y^2]) # needs sage.symbolic
1733
+ sage: f._number_field_from_algebraics() # needs sage.symbolic
1734
+ Scheme endomorphism of Projective Space of dimension 1 over Number
1735
+ Field in a with defining polynomial y^6 + 6*y^4 - 6*y^3 + 12*y^2 + 36*y + 17
1736
+ with a = 1.442249570307409? - 1.414213562373095?*I
1737
+ Defn: Defined on coordinates by sending (x : y) to
1738
+ ((-48/269*a^5 + 27/269*a^4 - 320/269*a^3 + 468/269*a^2 - 772/269*a
1739
+ - 1092/269)*x^2 + (-48/269*a^5 + 27/269*a^4 - 320/269*a^3 + 468/269*a^2
1740
+ - 1041/269*a - 1092/269)*y^2 : y^2)
1741
+
1742
+ ::
1743
+
1744
+ sage: # needs sage.rings.number_field
1745
+ sage: P.<x,y> = ProjectiveSpace(QQbar, 1)
1746
+ sage: P2.<u,v,w> = ProjectiveSpace(QQbar, 2)
1747
+ sage: H = Hom(P, P2)
1748
+ sage: f = H([x^2 + QQbar(I)*x*y + 3*y^2, y^2, QQbar(sqrt(5))*x*y]) # needs sage.symbolic
1749
+ sage: f._number_field_from_algebraics() # needs sage.symbolic
1750
+ Scheme morphism:
1751
+ From: Projective Space of dimension 1 over Number Field in a
1752
+ with defining polynomial y^4 + 3*y^2 + 1
1753
+ with a = 0.?e-166 + 1.618033988749895?*I
1754
+ To: Projective Space of dimension 2 over Number Field in a
1755
+ with defining polynomial y^4 + 3*y^2 + 1
1756
+ with a = 0.?e-166 + 1.618033988749895?*I
1757
+ Defn: Defined on coordinates by sending (x : y) to
1758
+ (x^2 + (-a^3 - 2*a)*x*y + 3*y^2 : y^2 : (-2*a^2 - 3)*x*y)
1759
+
1760
+ The following was fixed in :issue:`23808`::
1761
+
1762
+ sage: # needs sage.rings.number_field
1763
+ sage: R.<t> = PolynomialRing(QQ)
1764
+ sage: s = (t^3 + t + 1).roots(QQbar)[0][0]
1765
+ sage: P.<x,y> = ProjectiveSpace(QQbar, 1)
1766
+ sage: H = Hom(P, P)
1767
+ sage: f = H([s*x^3 - 13*y^3, y^3 - 15*y^3])
1768
+ sage: f
1769
+ Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field
1770
+ Defn: Defined on coordinates by sending (x : y) to
1771
+ ((-0.6823278038280193?)*x^3 + (-13)*y^3 : (-14)*y^3)
1772
+ sage: f_alg = f._number_field_from_algebraics()
1773
+ sage: f_alg.change_ring(QQbar) # Used to fail
1774
+ Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field
1775
+ Defn: Defined on coordinates by sending (x : y) to
1776
+ ((-0.6823278038280193?)*x^3 + (-13)*y^3 : (-14)*y^3)
1777
+ """
1778
+ from sage.rings.qqbar import number_field_elements_from_algebraics
1779
+ from sage.schemes.projective.projective_space import ProjectiveSpace_ring
1780
+
1781
+ if not (isinstance(self.domain(), ProjectiveSpace_ring) and isinstance(self.domain(), ProjectiveSpace_ring)):
1782
+ raise NotImplementedError("not implemented for subschemes")
1783
+
1784
+ K_pre, C, phi = number_field_elements_from_algebraics([c for f in self
1785
+ for c in f.coefficients()], minimal=True)
1786
+ # check if the same field
1787
+ if K_pre is QQ:
1788
+ if K_pre is self.base_ring():
1789
+ return self
1790
+ elif not isinstance(self.base_ring(), sage.rings.abc.AlgebraicField) and K_pre.is_isomorphic(self.base_ring()):
1791
+ return self
1792
+ # Issue 23808: The field K_pre returned above does not have its embedding set to be phi
1793
+ # and phi is forgotten, so we redefine K_pre to be a field K with phi as the specified
1794
+ # embedding:
1795
+ if K_pre is QQ:
1796
+ K = QQ
1797
+ else:
1798
+ from sage.rings.number_field.number_field import NumberField
1799
+ K = NumberField(K_pre.polynomial(), embedding=phi(K_pre.gen()), name='a')
1800
+ psi = K_pre.hom([K.gen()], K) # Identification of K_pre with K
1801
+ C = [psi(c) for c in C] # The elements of C were in K_pre, move them to K
1802
+ from sage.schemes.projective.projective_space import ProjectiveSpace
1803
+ N = self.domain().dimension_relative()
1804
+ PS = ProjectiveSpace(K, N, self.domain().variable_names())
1805
+ if self.is_endomorphism():
1806
+ H = End(PS)
1807
+ else:
1808
+ PS2 = ProjectiveSpace(K, self.codomain().dimension_relative(),
1809
+ self.codomain().variable_names())
1810
+ H = Hom(PS, PS2)
1811
+ R = PS.coordinate_ring()
1812
+ exps = [f.exponents() for f in self]
1813
+ F = []
1814
+ j = 0
1815
+ for t in exps:
1816
+ G = 0
1817
+ for e in t:
1818
+ G += C[j]*prod([R.gen(i)**e[i] for i in range(N+1)])
1819
+ j += 1
1820
+ F.append(G)
1821
+ return H(F)
1822
+
1823
+ def base_indeterminacy_locus(self):
1824
+ r"""
1825
+ Return the base indeterminacy locus of this map.
1826
+
1827
+ The base indeterminacy locus is the set of points in projective space
1828
+ at which all of the defining polynomials of the rational map
1829
+ simultaneously vanish.
1830
+
1831
+ OUTPUT: a subscheme of the domain of the map
1832
+
1833
+ EXAMPLES::
1834
+
1835
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1836
+ sage: H = End(P)
1837
+ sage: f = H([x*z - y*z, x^2 - y^2, z^2])
1838
+ sage: f.base_indeterminacy_locus()
1839
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
1840
+ x*z - y*z,
1841
+ x^2 - y^2,
1842
+ z^2
1843
+
1844
+ ::
1845
+
1846
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1847
+ sage: H = End(P)
1848
+ sage: f = H([x^2, y^2, z^2])
1849
+ sage: f.base_indeterminacy_locus()
1850
+ Closed subscheme of Projective Space of dimension 2 over Rational Field
1851
+ defined by:
1852
+ x^2,
1853
+ y^2,
1854
+ z^2
1855
+
1856
+ ::
1857
+
1858
+ sage: P1.<x,y,z> = ProjectiveSpace(RR, 2)
1859
+ sage: P2.<t,u,v,w> = ProjectiveSpace(RR, 3)
1860
+ sage: H = Hom(P1, P2)
1861
+ sage: h = H([y^3*z^3, x^3*z^3, y^3*z^3, x^2*y^2*z^2])
1862
+ sage: h.base_indeterminacy_locus() # needs sage.rings.real_mpfr
1863
+ Closed subscheme of Projective Space of dimension 2 over
1864
+ Real Field with 53 bits of precision defined by:
1865
+ y^3*z^3,
1866
+ x^3*z^3,
1867
+ y^3*z^3,
1868
+ x^2*y^2*z^2
1869
+
1870
+ If defining polynomials are not normalized, output scheme will not be normalized::
1871
+
1872
+ sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
1873
+ sage: H = End(P)
1874
+ sage: f = H([x*x^2,x*y^2,x*z^2])
1875
+ sage: f.base_indeterminacy_locus()
1876
+ Closed subscheme of Projective Space of dimension 2 over Rational Field
1877
+ defined by:
1878
+ x^3,
1879
+ x*y^2,
1880
+ x*z^2
1881
+ """
1882
+ dom = self.domain()
1883
+ AS = dom.ambient_space()
1884
+ return AS.subscheme(list(dom.defining_polynomials()) + list(self.defining_polynomials()))
1885
+
1886
+ def indeterminacy_locus(self):
1887
+ r"""
1888
+ Return the indeterminacy locus of this map as a rational map on the domain.
1889
+
1890
+ The indeterminacy locus is the intersection of all the base indeterminacy
1891
+ locuses of maps that define the same rational map as by this map.
1892
+
1893
+ OUTPUT: a subscheme of the domain of the map
1894
+
1895
+ EXAMPLES::
1896
+
1897
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1898
+ sage: H = End(P)
1899
+ sage: f = H([x^2, y^2, z^2])
1900
+ sage: f.indeterminacy_locus() # needs sage.libs.singular
1901
+ ... DeprecationWarning: The meaning of indeterminacy_locus() has changed.
1902
+ Read the docstring. See https://github.com/sagemath/sage/issues/29145 for details.
1903
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
1904
+ z,
1905
+ y,
1906
+ x
1907
+
1908
+ ::
1909
+
1910
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1911
+ sage: H = End(P)
1912
+ sage: f = H([x*z - y*z, x^2 - y^2, z^2])
1913
+ sage: f.indeterminacy_locus() # needs sage.libs.singular
1914
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
1915
+ z,
1916
+ x^2 - y^2
1917
+
1918
+ There is related :meth:`base_indeterminacy_locus()` method. This
1919
+ computes the indeterminacy locus only from the defining polynomials of
1920
+ the map::
1921
+
1922
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1923
+ sage: H = End(P)
1924
+ sage: f = H([x*z - y*z, x^2 - y^2, z^2])
1925
+ sage: f.base_indeterminacy_locus()
1926
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
1927
+ x*z - y*z,
1928
+ x^2 - y^2,
1929
+ z^2
1930
+ """
1931
+ from sage.misc.superseded import deprecation
1932
+ deprecation(29145, "The meaning of indeterminacy_locus() has changed. Read the docstring.")
1933
+ P = self.domain()
1934
+ X = P.subscheme(0) # projective space as a subscheme
1935
+ return (self*X.hom(P.gens(), P)).indeterminacy_locus()
1936
+
1937
+ def indeterminacy_points(self, F=None, base=False):
1938
+ r"""
1939
+ Return the points in the indeterminacy locus of this map.
1940
+
1941
+ If the dimension of the indeterminacy locus is not zero, an error is raised.
1942
+
1943
+ INPUT:
1944
+
1945
+ - ``F`` -- a field; if not given, the base ring of the domain is assumed
1946
+
1947
+ - ``base`` -- if ``True``, the base indeterminacy locus is used
1948
+
1949
+ OUTPUT: indeterminacy points of the map defined over ``F``
1950
+
1951
+ EXAMPLES::
1952
+
1953
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1954
+ sage: H = End(P)
1955
+ sage: f = H([x*z - y*z, x^2 - y^2, z^2])
1956
+ sage: f.indeterminacy_points() # needs sage.libs.singular
1957
+ ... DeprecationWarning: The meaning of indeterminacy_locus() has changed.
1958
+ Read the docstring. See https://github.com/sagemath/sage/issues/29145 for details.
1959
+ [(-1 : 1 : 0), (1 : 1 : 0)]
1960
+
1961
+ ::
1962
+
1963
+ sage: P1.<x,y,z> = ProjectiveSpace(RR, 2)
1964
+ sage: P2.<t,u,v,w> = ProjectiveSpace(RR, 3)
1965
+ sage: H = Hom(P1, P2)
1966
+ sage: h = H([x + y, y, z + y, y])
1967
+ sage: set_verbose(None)
1968
+ sage: h.indeterminacy_points(base=True) # needs sage.libs.singular
1969
+ []
1970
+ sage: g = H([y^3*z^3, x^3*z^3, y^3*z^3, x^2*y^2*z^2])
1971
+ sage: g.indeterminacy_points(base=True) # needs sage.libs.singular
1972
+ Traceback (most recent call last):
1973
+ ...
1974
+ ValueError: indeterminacy scheme is not dimension 0
1975
+
1976
+ ::
1977
+
1978
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
1979
+ sage: H = End(P)
1980
+ sage: f = H([x^2 + y^2, x*z, x^2 + y^2])
1981
+ sage: f.indeterminacy_points() # needs sage.libs.singular
1982
+ [(0 : 0 : 1)]
1983
+
1984
+ sage: R.<t> = QQ[]
1985
+ sage: K.<a> = NumberField(t^2 + 1) # needs sage.rings.number_field
1986
+ sage: f.indeterminacy_points(F=K) # needs sage.libs.singular sage.rings.number_field
1987
+ [(-a : 1 : 0), (0 : 0 : 1), (a : 1 : 0)]
1988
+ sage: set_verbose(None)
1989
+ sage: f.indeterminacy_points(F=QQbar, base=True) # needs sage.libs.singular sage.rings.number_field
1990
+ [(-1*I : 1 : 0), (0 : 0 : 1), (1*I : 1 : 0)]
1991
+
1992
+ ::
1993
+
1994
+ sage: set_verbose(None)
1995
+ sage: K.<t> = FunctionField(QQ)
1996
+ sage: P.<x,y,z> = ProjectiveSpace(K, 2)
1997
+ sage: H = End(P)
1998
+ sage: f = H([x^2 - t^2*y^2, y^2 - z^2, x^2 - t^2*z^2])
1999
+ sage: f.indeterminacy_points(base=True) # needs sage.libs.singular
2000
+ [(-t : -1 : 1), (-t : 1 : 1), (t : -1 : 1), (t : 1 : 1)]
2001
+
2002
+ ::
2003
+
2004
+ sage: # needs sage.rings.padics
2005
+ sage: set_verbose(None)
2006
+ sage: P.<x,y,z> = ProjectiveSpace(Qp(3), 2)
2007
+ sage: H = End(P)
2008
+ sage: f = H([x^2 - 7*y^2, y^2 - z^2, x^2 - 7*z^2])
2009
+ sage: f.indeterminacy_points(base=True) # needs sage.libs.singular
2010
+ [(2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 2*3^6 + 3^8
2011
+ + 3^9 + 2*3^11 + 3^15 + 2*3^16 + 3^18 + O(3^20) : 1 + O(3^20) : 1 + O(3^20)),
2012
+ (2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 2*3^6 + 3^8 + 3^9 + 2*3^11 + 3^15
2013
+ + 2*3^16 + 3^18 + O(3^20) : 2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5
2014
+ + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13
2015
+ + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 + O(3^20) : 1 + O(3^20)),
2016
+ (1 + 3 + 3^2 + 2*3^4 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 2*3^12 + 2*3^13
2017
+ + 2*3^14 + 3^15 + 2*3^17 + 3^18 + 2*3^19 + O(3^20) : 1 + O(3^20) : 1 + O(3^20)),
2018
+ (1 + 3 + 3^2 + 2*3^4 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 2*3^12 + 2*3^13
2019
+ + 2*3^14 + 3^15 + 2*3^17 + 3^18 + 2*3^19 + O(3^20) : 2 + 2*3 + 2*3^2
2020
+ + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11
2021
+ + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19
2022
+ + O(3^20) : 1 + O(3^20))]
2023
+ """
2024
+ if F is None:
2025
+ fcn = self
2026
+ else:
2027
+ if not F.is_field():
2028
+ raise NotImplementedError("indeterminacy points only implemented for fields")
2029
+ fcn = self.change_ring(F)
2030
+ if base:
2031
+ indScheme = fcn.base_indeterminacy_locus()
2032
+ else:
2033
+ indScheme = fcn.indeterminacy_locus()
2034
+ if indScheme.dimension() > 0:
2035
+ raise ValueError("indeterminacy scheme is not dimension 0")
2036
+ # Other error checking is in indeterminacy_locus
2037
+ indPoints = indScheme.rational_points()
2038
+ return indPoints
2039
+
2040
+ def reduce_base_field(self):
2041
+ """
2042
+ Return this map defined over the field of definition of the coefficients.
2043
+
2044
+ The base field of the map could be strictly larger than
2045
+ the field where all of the coefficients are defined. This function
2046
+ reduces the base field to the minimal possible. This can be done when
2047
+ the base ring is a number field, QQbar, a finite field, or algebraic
2048
+ closure of a finite field.
2049
+
2050
+ OUTPUT: a scheme morphism
2051
+
2052
+ EXAMPLES::
2053
+
2054
+ sage: # needs sage.rings.finite_rings
2055
+ sage: K.<t> = GF(3^4)
2056
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
2057
+ sage: P2.<a,b,c> = ProjectiveSpace(K, 2)
2058
+ sage: H = End(P)
2059
+ sage: H2 = Hom(P, P2)
2060
+ sage: H3 = Hom(P2, P)
2061
+ sage: f = H([x^2 + (2*t^3 + 2*t^2 + 1)*y^2, y^2])
2062
+ sage: f.reduce_base_field() # needs sage.libs.singular sage.modules
2063
+ Scheme endomorphism of Projective Space of dimension 1
2064
+ over Finite Field in t2 of size 3^2
2065
+ Defn: Defined on coordinates by sending (x : y) to (x^2 + t2*y^2 : y^2)
2066
+ sage: f2 = H2([x^2 + 5*y^2, y^2, 2*x*y])
2067
+ sage: f2.reduce_base_field() # needs sage.libs.singular sage.modules
2068
+ Scheme morphism:
2069
+ From: Projective Space of dimension 1 over Finite Field of size 3
2070
+ To: Projective Space of dimension 2 over Finite Field of size 3
2071
+ Defn: Defined on coordinates by sending (x : y) to (x^2 - y^2 : y^2 : -x*y)
2072
+ sage: f3 = H3([a^2 + t*b^2, c^2])
2073
+ sage: f3.reduce_base_field() # needs sage.libs.singular sage.modules
2074
+ Scheme morphism:
2075
+ From: Projective Space of dimension 2 over Finite Field in t of size 3^4
2076
+ To: Projective Space of dimension 1 over Finite Field in t of size 3^4
2077
+ Defn: Defined on coordinates by sending (a : b : c) to (a^2 + t*b^2 : c^2)
2078
+
2079
+ ::
2080
+
2081
+ sage: # needs sage.rings.number_field
2082
+ sage: K.<v> = CyclotomicField(4)
2083
+ sage: P.<x,y> = ProjectiveSpace(K, 1)
2084
+ sage: H = End(P)
2085
+ sage: f = H([x^2 + 2*y^2, y^2])
2086
+ sage: f.reduce_base_field() # needs sage.libs.singular
2087
+ Scheme endomorphism of Projective Space of dimension 1 over Rational Field
2088
+ Defn: Defined on coordinates by sending (x : y) to (x^2 + 2*y^2 : y^2)
2089
+
2090
+ ::
2091
+
2092
+ sage: # needs sage.rings.finite_rings
2093
+ sage: K.<v> = GF(5)
2094
+ sage: L = K.algebraic_closure()
2095
+ sage: P.<x,y> = ProjectiveSpace(L, 1)
2096
+ sage: H = End(P)
2097
+ sage: f = H([(L.gen(2))*x^2 + L.gen(4)*y^2, x*y])
2098
+ sage: f.reduce_base_field() # needs sage.libs.singular
2099
+ Scheme endomorphism of Projective Space of dimension 1
2100
+ over Finite Field in z4 of size 5^4
2101
+ Defn: Defined on coordinates by sending (x : y) to
2102
+ ((z4^3 + z4^2 + z4 - 2)*x^2 + z4*y^2 : x*y)
2103
+ sage: f = DynamicalSystem_projective([L.gen(3)*x^2 + L.gen(2)*y^2, x*y]) # needs sage.schemes
2104
+ sage: f.reduce_base_field() # needs sage.libs.singular sage.schemes
2105
+ Dynamical System of Projective Space of dimension 1
2106
+ over Finite Field in z6 of size 5^6
2107
+ Defn: Defined on coordinates by sending (x : y) to
2108
+ ((-z6^5 + z6^4 - z6^3 - z6^2 - 2*z6 - 2)*x^2
2109
+ + (z6^5 - 2*z6^4 + z6^2 - z6 + 1)*y^2 : x*y)
2110
+
2111
+ TESTS::
2112
+
2113
+ sage: # needs sage.rings.finite_rings
2114
+ sage: F = GF(3).algebraic_closure()
2115
+ sage: P.<x,y> = ProjectiveSpace(F, 1)
2116
+ sage: H = Hom(P, P)
2117
+ sage: f = H([x^2 + y^2, y^2])
2118
+ sage: f.reduce_base_field() # needs sage.libs.singular
2119
+ Scheme endomorphism of Projective Space of dimension 1 over Finite Field of size 3
2120
+ Defn: Defined on coordinates by sending (x : y) to
2121
+ (x^2 + y^2 : y^2)
2122
+ """
2123
+ K = self.base_ring()
2124
+ if K in NumberFields() or isinstance(K, sage.rings.abc.AlgebraicField):
2125
+ return self._number_field_from_algebraics()
2126
+ if K in FiniteFields():
2127
+ #find the degree of the extension containing the coefficients
2128
+ c = [v for g in self for v in g.coefficients()]
2129
+ d = lcm([a.minpoly().degree() for a in c])
2130
+ if d == 1:
2131
+ from sage.rings.finite_rings.finite_field_constructor import GF
2132
+
2133
+ return self.change_ring(GF(K.characteristic()))
2134
+ if d == K.degree():
2135
+ return self
2136
+ # otherwise we are not in the prime subfield so coercion
2137
+ # to it does not work
2138
+ for L, phi in K.subfields():
2139
+ # find the right subfield and its embedding
2140
+ if L.degree() == d:
2141
+ break
2142
+ # we need to rewrite each of the coefficients in terms of the generator
2143
+ # of L. To do this, we'll set-up an ideal and use elimination
2144
+ R = PolynomialRing(K.prime_subfield(), 2, 'a')
2145
+ a, b = R.gens()
2146
+ from sage.schemes.projective.projective_space import ProjectiveSpace
2147
+ new_domain = ProjectiveSpace(L, self.domain().dimension_relative(),
2148
+ self.domain().variable_names())
2149
+ new_R = new_domain.coordinate_ring()
2150
+ u = phi(L.gen()) # gen of L in terms of gen of K
2151
+ g = R(str(u).replace(K.variable_name(), R.variable_names()[0])) #converted to R
2152
+ new_f = []
2153
+ for fi in self:
2154
+ mon = fi.monomials()
2155
+ mon_deg = [m.degrees() for m in mon]
2156
+ coef = fi.coefficients()
2157
+ new_c = []
2158
+ for c in coef:
2159
+ # for each coefficient do the elimination
2160
+ w = R(str(c).replace(K.variable_name(), R.variable_names()[0]))
2161
+ I = R.ideal([b-g, w])
2162
+ v = I.elimination_ideal([a]).gen(0)
2163
+ # elimination can change scale the result, so correct the leading coefficient
2164
+ # and convert back to L
2165
+ if v.subs({b:g}).lc() == w.lc():
2166
+ new_c.append(L(str(v).replace(R.variable_names()[1], L.variable_name())))
2167
+ else:
2168
+ new_c.append(L(str(w.lc()*v).replace(R.variable_names()[1], L.variable_name())))
2169
+ # reconstruct as a poly in the new domain
2170
+ new_f.append(sum(new_c[i]*prod(new_R.gen(j)**mon_deg[i][j]
2171
+ for j in range(new_R.ngens()))
2172
+ for i in range(len(mon))))
2173
+ # return the correct type of map
2174
+ if self.is_endomorphism():
2175
+ H = Hom(new_domain, new_domain)
2176
+ else:
2177
+ new_codomain = ProjectiveSpace(L, self.codomain().dimension_relative(), self.codomain().variable_names())
2178
+ H = Hom(new_domain, new_codomain)
2179
+ return H(new_f)
2180
+ elif isinstance(K, AlgebraicClosureFiniteField_generic):
2181
+ self.domain().coordinate_ring()
2182
+ # find the degree of the extension containing the coefficients
2183
+ c = [v for g in self for v in g.coefficients()]
2184
+ d = lcm([a.minpoly().degree() for a in c])
2185
+ # get the appropriate subfield
2186
+ L, L_to_K = K.subfield(d)
2187
+ from sage.schemes.projective.projective_space import ProjectiveSpace
2188
+ new_domain = ProjectiveSpace(L, self.domain().dimension_relative(),
2189
+ self.domain().variable_names())
2190
+ new_R = new_domain.coordinate_ring()
2191
+ # we need to rewrite each of the coefficients in terms of the generator
2192
+ # of L. To do this, we'll set-up an ideal and use elimination
2193
+ new_f = []
2194
+ for fi in self:
2195
+ mon = fi.monomials()
2196
+ mon_deg = [m.degrees() for m in mon]
2197
+ coef = fi.coefficients()
2198
+ new_c = []
2199
+ for c in coef:
2200
+ # for each coefficient move to the correct base field
2201
+ da = c.minpoly().degree()
2202
+ for M, M_to_L in L.subfields():
2203
+ # find the right subfield and it's embedding
2204
+ if M.degree() == da:
2205
+ break
2206
+ c = M(str(c).replace(c.as_finite_field_element()[0].variable_name(),
2207
+ M.variable_name()))
2208
+ new_c.append(M_to_L(c))
2209
+ # reconstruct as a poly in the new domain
2210
+ new_f.append(sum([new_c[i] * prod(new_R.gen(j)**mon_deg[i][j]
2211
+ for j in range(new_R.ngens()))
2212
+ for i in range(len(mon))]))
2213
+ # return the correct type of map
2214
+ if self.is_endomorphism():
2215
+ H = Hom(new_domain, new_domain)
2216
+ else:
2217
+ new_codomain = ProjectiveSpace(L, self.codomain().dimension_relative(), self.codomain().variable_names())
2218
+ H = Hom(new_domain, new_codomain)
2219
+ return H(new_f)
2220
+ raise NotImplementedError("only implemented for number fields and finite fields")
2221
+
2222
+ def image(self):
2223
+ """
2224
+ Return the scheme-theoretic image of the morphism.
2225
+
2226
+ OUTPUT: a subscheme of the ambient space of the codomain
2227
+
2228
+ EXAMPLES::
2229
+
2230
+ sage: P2.<x0,x1,x2> = ProjectiveSpace(QQ, 2)
2231
+ sage: f = P2.hom([x0^3, x0^2*x1, x0*x1^2], P2)
2232
+ sage: f.image() # needs sage.libs.singular
2233
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
2234
+ x1^2 - x0*x2
2235
+ sage: f = P2.hom([x0 - x1, x0 - x2, x1 - x2], P2)
2236
+ sage: f.image() # needs sage.libs.singular
2237
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
2238
+ x0 - x1 + x2
2239
+
2240
+ ::
2241
+
2242
+ sage: P2.<x0,x1,x2> = ProjectiveSpace(QQ, 2)
2243
+ sage: A2.<x,y> = AffineSpace(QQ, 2)
2244
+ sage: f = P2.hom([1, x0/x1], A2)
2245
+ sage: f.image() # needs sage.libs.singular
2246
+ Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
2247
+ -x + 1
2248
+ """
2249
+ X = self.domain().subscheme(0)
2250
+ e = X.embedding_morphism()
2251
+ return (self*e).image()
2252
+
2253
+
2254
+ class SchemeMorphism_polynomial_projective_space_finite_field(SchemeMorphism_polynomial_projective_space_field):
2255
+
2256
+ def _fast_eval(self, x):
2257
+ """
2258
+ Evaluate projective morphism at point described by x.
2259
+
2260
+ EXAMPLES::
2261
+
2262
+ sage: P.<x,y,z> = ProjectiveSpace(GF(7), 2)
2263
+ sage: H = Hom(P, P)
2264
+ sage: f = H([x^2 + y^2, y^2, z^2 + y*z])
2265
+ sage: f._fast_eval([1,1,1])
2266
+ [2, 1, 2]
2267
+ """
2268
+ if self._is_prime_finite_field:
2269
+ p = self.base_ring().characteristic()
2270
+ P = [Integer(f(*x)) % p for f in self._fastpolys]
2271
+ else:
2272
+ P = [f(*x) for f in self._fastpolys]
2273
+ return P
2274
+
2275
+
2276
+ class SchemeMorphism_polynomial_projective_subscheme_field(SchemeMorphism_polynomial_projective_space_field):
2277
+ """
2278
+ Morphisms from subschemes of projective spaces defined over fields.
2279
+ """
2280
+ def __call__(self, x):
2281
+ """
2282
+ Apply this morphism to the point ``x``.
2283
+
2284
+ INPUT:
2285
+
2286
+ - ``x`` -- a point in the domain of definition
2287
+
2288
+ OUTPUT: the image of the point ``x`` under the morphism
2289
+
2290
+ TESTS::
2291
+
2292
+ sage: # needs sage.libs.pari sage.schemes
2293
+ sage: R.<x,y,z> = QQ[]
2294
+ sage: C = Curve(7*x^2 + 2*y*z + z^2)
2295
+ sage: f, g = C.parametrization()
2296
+ sage: g([0, -1, 2])
2297
+ (1 : 0)
2298
+ sage: f([1, 0])
2299
+ (0 : -1/2 : 1)
2300
+ sage: _ == C([0, -1, 2])
2301
+ True
2302
+ """
2303
+ try:
2304
+ reprs = self.representatives()
2305
+ except NotImplementedError: # Singular does not support the base field
2306
+ try:
2307
+ return super().__call__(x)
2308
+ except ValueError:
2309
+ raise ValueError('cannot apply the morphism to this point')
2310
+
2311
+ for m in reprs:
2312
+ try:
2313
+ return super(SchemeMorphism_polynomial_projective_subscheme_field, m).__call__(x)
2314
+ except ValueError:
2315
+ pass
2316
+ raise ValueError('the morphism is not defined at this point')
2317
+
2318
+ def __eq__(self, other):
2319
+ """
2320
+ EXAMPLES::
2321
+
2322
+ sage: R.<x,y,z> = QQ[]
2323
+
2324
+ sage: # needs sage.libs.pari sage.schemes
2325
+ sage: C = Curve(7*x^2 + 2*y*z + z^2) # conic
2326
+ sage: f, g = C.parametrization()
2327
+ sage: f*g == C.identity_morphism()
2328
+ True
2329
+
2330
+ sage: # needs sage.schemes
2331
+ sage: C = Curve(x^2 + y^2 - z^2)
2332
+ sage: P.<u, v> = ProjectiveSpace(QQ, 1)
2333
+ sage: f = C.hom([x + z, y], P)
2334
+ sage: g = C.hom([y, z - x], P)
2335
+ sage: f == g
2336
+ True
2337
+ sage: h = C.hom([z, x - y], P)
2338
+ sage: f == h
2339
+ False
2340
+ """
2341
+ Y = self.codomain()
2342
+
2343
+ if not isinstance(other, SchemeMorphism_polynomial):
2344
+ return False
2345
+ if self.domain() != other.domain() or Y != other.codomain():
2346
+ return False
2347
+
2348
+ if not Y.is_projective(): # codomain is affine
2349
+ e = Y.projective_embedding(0)
2350
+ return (e * self) == (e * other)
2351
+
2352
+ from sage.matrix.constructor import matrix
2353
+
2354
+ R = self.domain().coordinate_ring()
2355
+ mat = matrix([self.defining_polynomials(), other.defining_polynomials()])
2356
+ return all(R(minor).is_zero() for minor in mat.minors(2))
2357
+
2358
+ @cached_method
2359
+ def representatives(self):
2360
+ """
2361
+ Return all maps representing the same rational map as by this map.
2362
+
2363
+ EXAMPLES::
2364
+
2365
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
2366
+ sage: X = P2.subscheme(0)
2367
+ sage: f = X.hom([x^2*y, x^2*z, x*y*z], P2)
2368
+ sage: f.representatives() # needs sage.libs.singular
2369
+ [Scheme morphism:
2370
+ From: Closed subscheme of Projective Space of dimension 2
2371
+ over Rational Field defined by: 0
2372
+ To: Projective Space of dimension 2 over Rational Field
2373
+ Defn: Defined on coordinates by sending (x : y : z) to (x*y : x*z : y*z)]
2374
+
2375
+ ::
2376
+
2377
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
2378
+ sage: P1.<a,b> = ProjectiveSpace(QQ, 1)
2379
+ sage: X = P2.subscheme([x^2 - y^2 - y*z])
2380
+ sage: f = X.hom([x, y], P1)
2381
+ sage: f.representatives() # needs sage.libs.singular
2382
+ [Scheme morphism:
2383
+ From: Closed subscheme of Projective Space of dimension 2
2384
+ over Rational Field defined by: x^2 - y^2 - y*z
2385
+ To: Projective Space of dimension 1 over Rational Field
2386
+ Defn: Defined on coordinates by sending (x : y : z) to (y + z : x),
2387
+ Scheme morphism:
2388
+ From: Closed subscheme of Projective Space of dimension 2
2389
+ over Rational Field defined by: x^2 - y^2 - y*z
2390
+ To: Projective Space of dimension 1 over Rational Field
2391
+ Defn: Defined on coordinates by sending (x : y : z) to (x : y)]
2392
+ sage: g = _[0] # needs sage.libs.singular
2393
+ sage: g.representatives() # needs sage.libs.singular
2394
+ [Scheme morphism:
2395
+ From: Closed subscheme of Projective Space of dimension 2
2396
+ over Rational Field defined by: x^2 - y^2 - y*z
2397
+ To: Projective Space of dimension 1 over Rational Field
2398
+ Defn: Defined on coordinates by sending (x : y : z) to (y + z : x),
2399
+ Scheme morphism:
2400
+ From: Closed subscheme of Projective Space of dimension 2
2401
+ over Rational Field defined by: x^2 - y^2 - y*z
2402
+ To: Projective Space of dimension 1 over Rational Field
2403
+ Defn: Defined on coordinates by sending (x : y : z) to (x : y)]
2404
+
2405
+ ::
2406
+
2407
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
2408
+ sage: X = P2.subscheme([x^2 - y^2 - y*z])
2409
+ sage: A1.<a> = AffineSpace(QQ, 1)
2410
+ sage: g = X.hom([y/x], A1)
2411
+ sage: g.representatives() # needs sage.libs.singular
2412
+ [Scheme morphism:
2413
+ From: Closed subscheme of Projective Space of dimension 2
2414
+ over Rational Field defined by: x^2 - y^2 - y*z
2415
+ To: Affine Space of dimension 1 over Rational Field
2416
+ Defn: Defined on coordinates by sending (x : y : z) to (x/(y + z)),
2417
+ Scheme morphism:
2418
+ From: Closed subscheme of Projective Space of dimension 2
2419
+ over Rational Field defined by: x^2 - y^2 - y*z
2420
+ To: Affine Space of dimension 1 over Rational Field
2421
+ Defn: Defined on coordinates by sending (x : y : z) to (y/x)]
2422
+ sage: g0, g1 = _ # needs sage.libs.singular
2423
+ sage: emb = A1.projective_embedding(0)
2424
+ sage: emb*g0 # needs sage.libs.singular
2425
+ Scheme morphism:
2426
+ From: Closed subscheme of Projective Space of dimension 2
2427
+ over Rational Field defined by: x^2 - y^2 - y*z
2428
+ To: Projective Space of dimension 1 over Rational Field
2429
+ Defn: Defined on coordinates by sending (x : y : z) to (y + z : x)
2430
+ sage: emb*g1 # needs sage.libs.singular
2431
+ Scheme morphism:
2432
+ From: Closed subscheme of Projective Space of dimension 2
2433
+ over Rational Field defined by: x^2 - y^2 - y*z
2434
+ To: Projective Space of dimension 1 over Rational Field
2435
+ Defn: Defined on coordinates by sending (x : y : z) to (x : y)
2436
+
2437
+ ALGORITHM:
2438
+
2439
+ The algorithm is from Proposition 1.1 in [Sim2004]_.
2440
+ """
2441
+ X = self.domain()
2442
+ Y = self.codomain()
2443
+
2444
+ if not Y.is_projective(): # Y is affine
2445
+ emb = Y.projective_embedding(0)
2446
+ hom = self.parent()
2447
+ reprs = []
2448
+ for r in (emb*self).representatives():
2449
+ f0 = r[0]
2450
+ reprs.append(hom([f / f0 for f in r[1:]]))
2451
+ return reprs
2452
+
2453
+ if not (X.base_ring() in _NumberFields or
2454
+ X.base_ring() in _FiniteFields):
2455
+ raise NotImplementedError("base ring {} is not supported by Singular".format(X.base_ring()))
2456
+
2457
+ if not X.is_irreducible():
2458
+ raise ValueError("domain is not an irreducible scheme")
2459
+
2460
+ # prepare homogeneous coordinate ring of X in Singular
2461
+ from sage.interfaces.singular import singular
2462
+ from sage.rings.polynomial.term_order import TermOrder
2463
+ T = TermOrder('degrevlex')
2464
+ T._singular_ringorder_column = 1 # (c,dp) in Singular
2465
+ S = X.ambient_space().coordinate_ring().change_ring(order=T)
2466
+ R = S.quotient_ring(X.defining_ideal().change_ring(S))
2467
+
2468
+ if R is S: # true when the defining ideal is zero
2469
+ def lift(x):
2470
+ return x.numerator()
2471
+ else: # R is an ordinary quotient ring
2472
+ def lift(x):
2473
+ return x.lift()
2474
+
2475
+ F = [R(f) for f in self.defining_polynomials()]
2476
+ n = len(F)
2477
+ I = R.ideal(F)
2478
+
2479
+ # find r with nonzero F[r]
2480
+ r = 0
2481
+ while not F[r]:
2482
+ r = r + 1
2483
+
2484
+ # This is a minimal free presentation of the ideal I:
2485
+ #
2486
+ # phi F
2487
+ # R^m ------> R^n -----> I
2488
+ #
2489
+ # where n is the number of defining polynomials and m is the number of
2490
+ # syzygy relations of I.
2491
+
2492
+ # compute the kernel of the transpose of phi in Singular
2493
+ phi = I._singular_().syz()
2494
+ phi_trans = phi.matrix().transpose()
2495
+ kernel = singular.modulo(phi_trans, singular.module())
2496
+
2497
+ M = kernel.sage_matrix(R) # m * n matrix over R
2498
+ reprs = []
2499
+ for i in range(M.ncols()):
2500
+ lifts = [lift(F[j] * M[r][i] / F[r]) for j in range(n)]
2501
+ reprs.append(X.hom(lifts, Y))
2502
+
2503
+ return reprs
2504
+
2505
+ def indeterminacy_locus(self):
2506
+ """
2507
+ Return the indeterminacy locus of this map.
2508
+
2509
+ The map defines a rational map on the domain. The output is the
2510
+ subscheme of the domain on which the rational map is not defined by any
2511
+ representative of the rational map. See :meth:`representatives()`.
2512
+
2513
+ EXAMPLES::
2514
+
2515
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
2516
+ sage: P2.<x0,x1,x2> = ProjectiveSpace(QQ, 2)
2517
+ sage: X = P2.subscheme(0)
2518
+ sage: f = X.hom([x1,x0], P)
2519
+ sage: L = f.indeterminacy_locus() # needs sage.libs.singular
2520
+ sage: L.rational_points() # needs sage.libs.singular
2521
+ [(0 : 0 : 1)]
2522
+
2523
+ ::
2524
+
2525
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
2526
+ sage: P1.<a,b> = ProjectiveSpace(QQ, 1)
2527
+ sage: X = P2.subscheme([x^2 - y^2 - y*z])
2528
+ sage: f = X.hom([x,y], P1)
2529
+ sage: f.indeterminacy_locus() # needs sage.libs.singular
2530
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
2531
+ z,
2532
+ y,
2533
+ x
2534
+
2535
+ ::
2536
+
2537
+ sage: P3.<x,y,z,w> = ProjectiveSpace(QQ, 3)
2538
+ sage: P2.<a,b,c> = ProjectiveSpace(QQ, 2)
2539
+ sage: X = P3.subscheme(x^2 - w*y - x*z)
2540
+ sage: f = X.hom([x*y, y*z, z*x], P2)
2541
+ sage: L = f.indeterminacy_locus() # needs sage.libs.singular
2542
+ sage: L.dimension() # needs sage.libs.singular
2543
+ 0
2544
+ sage: L.degree() # needs sage.libs.singular
2545
+ 2
2546
+ sage: L.rational_points() # needs sage.libs.singular
2547
+ [(0 : 0 : 0 : 1), (0 : 1 : 0 : 0)]
2548
+
2549
+ ::
2550
+
2551
+ sage: P3.<x,y,z,w> = ProjectiveSpace(QQ, 3)
2552
+ sage: A2.<a,b> = AffineSpace(QQ, 2)
2553
+ sage: X = P3.subscheme(x^2 - w*y - x*z)
2554
+ sage: f = X.hom([x/z, y/x], A2)
2555
+ sage: L = f.indeterminacy_locus() # needs sage.libs.singular
2556
+ sage: L.rational_points() # needs sage.libs.singular
2557
+ [(0 : 0 : 0 : 1), (0 : 1 : 0 : 0)]
2558
+
2559
+ ::
2560
+
2561
+ sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
2562
+ sage: X = P.subscheme(x - y)
2563
+ sage: H = End(X)
2564
+ sage: f = H([x^2 - 4*y^2, y^2 - z^2, 4*z^2 - x^2])
2565
+ sage: Z = f.indeterminacy_locus(); Z # needs sage.libs.singular
2566
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
2567
+ z,
2568
+ y,
2569
+ x
2570
+ """
2571
+ X = self.domain()
2572
+ Y = self.codomain()
2573
+ Amb = X.ambient_space()
2574
+
2575
+ if not X.is_irreducible():
2576
+ components = X.irreducible_components()
2577
+
2578
+ def self_with_domain(C):
2579
+ return self*C.hom(Amb.gens(), X)
2580
+
2581
+ locus = self_with_domain(components[0]).indeterminacy_locus()
2582
+ for C in components[1:]:
2583
+ locus = locus.union(self_with_domain(C).indeterminacy_locus())
2584
+
2585
+ return locus
2586
+
2587
+ if not Y.is_projective(): # Y is affine
2588
+ emb = Y.projective_embedding(0)
2589
+ else:
2590
+ emb = None
2591
+
2592
+ polys = list(X.defining_polynomials())
2593
+
2594
+ for r in self.representatives():
2595
+ r_proj = r if emb is None else emb * r
2596
+ polys.extend(r_proj)
2597
+
2598
+ return Amb.subscheme(polys).reduce()
2599
+
2600
+ def is_morphism(self):
2601
+ """
2602
+ Return ``True`` if the map is defined everywhere on the domain.
2603
+
2604
+ EXAMPLES::
2605
+
2606
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ,2)
2607
+ sage: P1.<a,b> = ProjectiveSpace(QQ, 1)
2608
+ sage: X = P2.subscheme([x^2 - y^2 - y*z])
2609
+ sage: f = X.hom([x,y], P1)
2610
+ sage: f.is_morphism() # needs sage.libs.singular
2611
+ True
2612
+ """
2613
+ return self.indeterminacy_locus().dimension() < 0
2614
+
2615
+ def image(self):
2616
+ """
2617
+ Return the scheme-theoretic image of the morphism.
2618
+
2619
+ EXAMPLES::
2620
+
2621
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
2622
+ sage: P2.<x0,x1,x2> = ProjectiveSpace(QQ, 2)
2623
+ sage: X = P2.subscheme(0)
2624
+ sage: f = X.hom([x1,x0], P)
2625
+ sage: f.image() # needs sage.libs.singular
2626
+ Closed subscheme of Projective Space of dimension 1 over Rational Field defined by:
2627
+ (no polynomials)
2628
+
2629
+ ::
2630
+
2631
+ sage: P2.<x,y,z> = ProjectiveSpace(QQ,2)
2632
+ sage: X = P2.subscheme([z^3 - x*y^2 + y^3])
2633
+ sage: f = X.hom([x*z, x*y, x^2 + y*z], P2)
2634
+ sage: f.image() # needs sage.libs.singular
2635
+ Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
2636
+ x^6 + 2*x^3*y^3 + x*y^5 + y^6 - x^3*y^2*z - y^5*z
2637
+ """
2638
+ X = self.domain()
2639
+ Y = self.codomain()
2640
+
2641
+ if not Y.is_projective():
2642
+ e = Y.projective_embedding(0)
2643
+ return (e * self).image().affine_patch(0, Y.ambient_space())
2644
+
2645
+ k = self.base_ring()
2646
+
2647
+ AX = X.ambient_space()
2648
+ AY = Y.ambient_space()
2649
+
2650
+ S = AX.coordinate_ring()
2651
+ T = AY.coordinate_ring()
2652
+
2653
+ n = S.ngens()
2654
+ m = T.ngens()
2655
+
2656
+ dummy_names = ['d{}__'.format(i) for i in range(m)]
2657
+ D = PolynomialRing(k, names=dummy_names)
2658
+
2659
+ names = list(S.variable_names()) + dummy_names # this order of variables is important
2660
+ R = PolynomialRing(k, names=names, order='degrevlex({}),degrevlex({})'.format(m,n))
2661
+
2662
+ # compute the ideal of the image by elimination
2663
+ i = R.ideal(list(X.defining_ideal().gens()) + [self._polys[i] - R.gen(n + i) for i in range(m)])
2664
+ j = [g for g in i.groebner_basis() if g in D]
2665
+
2666
+ gens = [g.subs(dict(zip(R.gens()[n:],T.gens()))) for g in j]
2667
+ return AY.subscheme(gens)
2668
+
2669
+ @cached_method
2670
+ def graph(self):
2671
+ """
2672
+ Return the graph of this morphism.
2673
+
2674
+ The graph is a subscheme of the product of the ambient spaces of the
2675
+ domain and the codomain. If the ambient space of the codomain is an
2676
+ affine space, it is first embedded into a projective space.
2677
+
2678
+ EXAMPLES:
2679
+
2680
+ We get the standard quadratic curve as the graph of a quadratic function
2681
+ of an affine line. ::
2682
+
2683
+ sage: A1.<x> = AffineSpace(1, QQ)
2684
+ sage: X = A1.subscheme(0) # affine line
2685
+ sage: phi = X.hom([x^2], A1)
2686
+ sage: mor = phi.homogenize(0) # needs sage.libs.singular
2687
+ sage: G = mor.graph(); G # needs sage.libs.singular
2688
+ Closed subscheme of Product of projective spaces P^1 x P^1
2689
+ over Rational Field defined by: x1^2*x2 - x0^2*x3
2690
+ sage: G.affine_patch([0, 0]) # needs sage.libs.singular
2691
+ Closed subscheme of Affine Space of dimension 2
2692
+ over Rational Field defined by: x0^2 - x1
2693
+ """
2694
+ X = self.domain()
2695
+ Y = self.codomain()
2696
+
2697
+ if not Y.is_projective():
2698
+ e = Y.projective_embedding(0)
2699
+ return (e * self).graph()
2700
+
2701
+ AX = X.ambient_space()
2702
+ AY = Y.ambient_space()
2703
+
2704
+ n = AX.dimension()
2705
+ m = AY.dimension()
2706
+
2707
+ if any(v in AX.variable_names() for v in AY.variable_names()):
2708
+ from sage.schemes.product_projective.space import ProductProjectiveSpaces
2709
+ AXY = ProductProjectiveSpaces([n, m], self.base_ring())
2710
+ else:
2711
+ AXY = AX * AY # product of projective spaces
2712
+
2713
+ R = AXY.coordinate_ring()
2714
+ F = [R(f) for f in self.defining_polynomials()]
2715
+ g = R.gens()
2716
+
2717
+ # Suppose R = k[x_0, ..., x_n, y_0, ..., y_m]. Then the bihomogeneous
2718
+ # ideal of the graph is
2719
+ #
2720
+ # I + (y_iF_j - y_jF_i : 0 <= i, j <= m)
2721
+ #
2722
+ # saturated with respect to (F_0, F_1, ..., F_m).
2723
+ n1 = n + 1
2724
+ m1 = m + 1
2725
+ I = X.defining_ideal().change_ring(R)
2726
+ h = [g[n1 + i] * F[j] - g[n1 + j] * F[i] for i in range(m1) for j in range(i + 1, m1)]
2727
+ J, _ = (I + R.ideal(h)).saturation(R.ideal(F))
2728
+
2729
+ return AXY.subscheme(J)
2730
+
2731
+ @cached_method
2732
+ def projective_degrees(self):
2733
+ """
2734
+ Return the projective degrees of this rational map.
2735
+
2736
+ EXAMPLES::
2737
+
2738
+ sage: # needs sage.schemes
2739
+ sage: k = GF(11)
2740
+ sage: E = EllipticCurve(k, [1,1])
2741
+ sage: Q = E(6, 5)
2742
+ sage: phi = E.scalar_multiplication(2)
2743
+ sage: mor = phi.as_morphism()
2744
+ sage: mor.projective_degrees()
2745
+ (12, 3)
2746
+ """
2747
+ X = self.domain()
2748
+ Y = self.codomain()
2749
+
2750
+ if not Y.is_projective(): # Y is affine
2751
+ e = Y.projective_embedding(0)
2752
+ return (e * self).projective_degrees()
2753
+
2754
+ AX = X.ambient_space()
2755
+ AY = Y.ambient_space()
2756
+ xn = AX.ngens()
2757
+ yn = AY.ngens()
2758
+
2759
+ G = self.graph()
2760
+ I = G.defining_ideal() # a bihomogeneous ideal
2761
+
2762
+ from sage.modules.free_module_element import vector
2763
+
2764
+ degrees = xn * [vector([1, 0])] + yn * [vector([0, 1])]
2765
+ res = I.graded_free_resolution(degrees=degrees, algorithm='shreyer')
2766
+ kpoly = res.K_polynomial()
2767
+
2768
+ L = kpoly.parent()
2769
+ t1, t2 = L.gens()
2770
+ poly = kpoly.substitute({t1: 1 - t1, t2: 1 - t2})
2771
+
2772
+ n = AX.dimension()
2773
+ m = AY.dimension()
2774
+ k = X.dimension()
2775
+ return tuple(poly.monomial_coefficient(L.monomial(n - i, m - k + i)) for i in range(k + 1))
2776
+
2777
+ def degree(self):
2778
+ """
2779
+ Return the degree of this rational map.
2780
+
2781
+ EXAMPLES::
2782
+
2783
+ sage: # needs sage.schemes
2784
+ sage: k = GF(11)
2785
+ sage: E = EllipticCurve(k, [1,1])
2786
+ sage: Q = E(6, 5)
2787
+ sage: phi = E.scalar_multiplication(2)
2788
+ sage: mor = phi.as_morphism()
2789
+ sage: mor.degree()
2790
+ 4
2791
+ """
2792
+ return self.projective_degrees()[0] // self.image().degree()