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.
- passagemath_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- 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()
|