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,2571 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Projective `n`-space over a ring
|
|
4
|
+
|
|
5
|
+
EXAMPLES:
|
|
6
|
+
|
|
7
|
+
We construct projective space over various rings of various dimensions.
|
|
8
|
+
|
|
9
|
+
The simplest projective space::
|
|
10
|
+
|
|
11
|
+
sage: ProjectiveSpace(0)
|
|
12
|
+
Projective Space of dimension 0 over Integer Ring
|
|
13
|
+
|
|
14
|
+
A slightly bigger projective space over `\QQ`::
|
|
15
|
+
|
|
16
|
+
sage: X = ProjectiveSpace(1000, QQ); X
|
|
17
|
+
Projective Space of dimension 1000 over Rational Field
|
|
18
|
+
sage: X.dimension()
|
|
19
|
+
1000
|
|
20
|
+
|
|
21
|
+
We can use "over" notation to create projective spaces over various
|
|
22
|
+
base rings.
|
|
23
|
+
|
|
24
|
+
::
|
|
25
|
+
|
|
26
|
+
sage: X = ProjectiveSpace(5)/QQ; X
|
|
27
|
+
Projective Space of dimension 5 over Rational Field
|
|
28
|
+
sage: X/CC # needs sage.rings.real_mpfr
|
|
29
|
+
Projective Space of dimension 5 over Complex Field with 53 bits of precision
|
|
30
|
+
|
|
31
|
+
The third argument specifies the printing names of the generators of the
|
|
32
|
+
homogeneous coordinate ring. Using the method :meth:`objgens` you can obtain both
|
|
33
|
+
the space and the generators as ready to use variables. ::
|
|
34
|
+
|
|
35
|
+
sage: P2, vars = ProjectiveSpace(10, QQ, 't').objgens()
|
|
36
|
+
sage: vars
|
|
37
|
+
(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)
|
|
38
|
+
|
|
39
|
+
You can alternatively use the special syntax with ``<`` and ``>``.
|
|
40
|
+
|
|
41
|
+
::
|
|
42
|
+
|
|
43
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, QQ)
|
|
44
|
+
sage: P2
|
|
45
|
+
Projective Space of dimension 2 over Rational Field
|
|
46
|
+
sage: P2.coordinate_ring()
|
|
47
|
+
Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
48
|
+
|
|
49
|
+
The first of the three lines above is just equivalent to the two lines::
|
|
50
|
+
|
|
51
|
+
sage: P2 = ProjectiveSpace(2, QQ, 'xyz')
|
|
52
|
+
sage: x,y,z = P2.gens()
|
|
53
|
+
|
|
54
|
+
For example, we use `x,y,z` to define the intersection of
|
|
55
|
+
two lines.
|
|
56
|
+
|
|
57
|
+
::
|
|
58
|
+
|
|
59
|
+
sage: V = P2.subscheme([x + y + z, x + y - z]); V
|
|
60
|
+
Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
|
|
61
|
+
x + y + z,
|
|
62
|
+
x + y - z
|
|
63
|
+
sage: V.dimension() # needs sage.libs.singular
|
|
64
|
+
0
|
|
65
|
+
|
|
66
|
+
AUTHORS:
|
|
67
|
+
|
|
68
|
+
- Ben Hutz: (June 2012): support for rings
|
|
69
|
+
|
|
70
|
+
- Ben Hutz (9/2014): added support for Cartesian products
|
|
71
|
+
|
|
72
|
+
- Rebecca Lauren Miller (March 2016) : added point_transformation_matrix
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
# ****************************************************************************
|
|
76
|
+
# Copyright (C) 2006 William Stein <wstein@gmail.com>
|
|
77
|
+
#
|
|
78
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
79
|
+
#
|
|
80
|
+
# https://www.gnu.org/licenses/
|
|
81
|
+
# ****************************************************************************
|
|
82
|
+
from itertools import product
|
|
83
|
+
|
|
84
|
+
import sage.rings.abc
|
|
85
|
+
|
|
86
|
+
from sage.arith.misc import gcd, binomial
|
|
87
|
+
from sage.categories.fields import Fields
|
|
88
|
+
from sage.categories.homset import Hom
|
|
89
|
+
from sage.categories.map import Map
|
|
90
|
+
from sage.categories.number_fields import NumberFields
|
|
91
|
+
from sage.categories.rings import Rings
|
|
92
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
93
|
+
from sage.combinat.permutation import Permutation
|
|
94
|
+
from sage.combinat.subset import Subsets
|
|
95
|
+
from sage.misc.latex import latex
|
|
96
|
+
from sage.misc.lazy_import import lazy_import
|
|
97
|
+
from sage.misc.misc_c import prod
|
|
98
|
+
from sage.misc.persist import register_unpickle_override
|
|
99
|
+
from sage.rings.finite_rings.finite_field_base import FiniteField
|
|
100
|
+
from sage.rings.fraction_field import FractionField
|
|
101
|
+
from sage.rings.integer import Integer
|
|
102
|
+
from sage.rings.integer_ring import ZZ
|
|
103
|
+
from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
|
|
104
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
105
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
106
|
+
from sage.rings.rational_field import QQ, RationalField
|
|
107
|
+
from sage.schemes.generic.ambient_space import AmbientSpace
|
|
108
|
+
from sage.schemes.projective.projective_homset import (SchemeHomset_points_projective_ring,
|
|
109
|
+
SchemeHomset_points_projective_field,
|
|
110
|
+
SchemeHomset_polynomial_projective_space)
|
|
111
|
+
from sage.schemes.projective.projective_morphism import (SchemeMorphism_polynomial_projective_space,
|
|
112
|
+
SchemeMorphism_polynomial_projective_space_field,
|
|
113
|
+
SchemeMorphism_polynomial_projective_space_finite_field)
|
|
114
|
+
from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring,
|
|
115
|
+
SchemeMorphism_point_projective_field,
|
|
116
|
+
SchemeMorphism_point_projective_finite_field)
|
|
117
|
+
from sage.structure.category_object import normalize_names
|
|
118
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
119
|
+
|
|
120
|
+
lazy_import('sage.combinat.integer_vector', 'IntegerVectors')
|
|
121
|
+
lazy_import('sage.combinat.permutation', 'Permutation')
|
|
122
|
+
lazy_import('sage.combinat.tuple', ['Tuples', 'UnorderedTuples'])
|
|
123
|
+
lazy_import('sage.combinat.subset', 'Subsets')
|
|
124
|
+
lazy_import('sage.combinat.integer_vector_weighted', 'WeightedIntegerVectors')
|
|
125
|
+
lazy_import('sage.combinat.tuple', ['Tuples', 'UnorderedTuples'])
|
|
126
|
+
lazy_import('sage.dynamics.arithmetic_dynamics.projective_ds', 'DynamicalSystem_projective')
|
|
127
|
+
lazy_import('sage.matrix.constructor', 'matrix')
|
|
128
|
+
lazy_import('sage.modules.free_module', 'FreeModule')
|
|
129
|
+
lazy_import('sage.modules.free_module_element', 'prepare')
|
|
130
|
+
lazy_import('sage.schemes.generic.algebraic_scheme', 'AlgebraicScheme_subscheme')
|
|
131
|
+
lazy_import('sage.schemes.product_projective.space',
|
|
132
|
+
['ProductProjectiveSpaces', 'ProductProjectiveSpaces_ring'])
|
|
133
|
+
lazy_import('sage.schemes.projective.projective_subscheme',
|
|
134
|
+
['AlgebraicScheme_subscheme_projective', 'AlgebraicScheme_subscheme_projective_field'])
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# for better efficiency
|
|
138
|
+
_Fields = Fields()
|
|
139
|
+
_Rings = Rings()
|
|
140
|
+
_CommRings = _Rings.Commutative()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def is_ProjectiveSpace(x):
|
|
144
|
+
r"""
|
|
145
|
+
Return ``True`` if ``x`` is a projective space.
|
|
146
|
+
|
|
147
|
+
In other words, if ``x`` is an ambient space `\mathbb{P}^n_R`,
|
|
148
|
+
where `R` is a ring and `n\geq 0` is an integer.
|
|
149
|
+
|
|
150
|
+
EXAMPLES::
|
|
151
|
+
|
|
152
|
+
sage: from sage.schemes.projective.projective_space import is_ProjectiveSpace
|
|
153
|
+
sage: is_ProjectiveSpace(ProjectiveSpace(5, names='x'))
|
|
154
|
+
doctest:warning...
|
|
155
|
+
DeprecationWarning: The function is_ProjectiveSpace is deprecated; use 'isinstance(..., ProjectiveSpace_ring)' instead.
|
|
156
|
+
See https://github.com/sagemath/sage/issues/38022 for details.
|
|
157
|
+
True
|
|
158
|
+
sage: is_ProjectiveSpace(ProjectiveSpace(5, GF(9, 'alpha'), names='x')) # needs sage.rings.finite_rings
|
|
159
|
+
True
|
|
160
|
+
sage: is_ProjectiveSpace(Spec(ZZ))
|
|
161
|
+
False
|
|
162
|
+
"""
|
|
163
|
+
from sage.misc.superseded import deprecation
|
|
164
|
+
deprecation(38022, "The function is_ProjectiveSpace is deprecated; use 'isinstance(..., ProjectiveSpace_ring)' instead.")
|
|
165
|
+
return isinstance(x, ProjectiveSpace_ring)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def ProjectiveSpace(n, R=None, names=None):
|
|
169
|
+
r"""
|
|
170
|
+
Return projective space of dimension ``n`` over the ring ``R``.
|
|
171
|
+
|
|
172
|
+
EXAMPLES: The dimension and ring can be given in either order.
|
|
173
|
+
|
|
174
|
+
::
|
|
175
|
+
|
|
176
|
+
sage: ProjectiveSpace(3, QQ)
|
|
177
|
+
Projective Space of dimension 3 over Rational Field
|
|
178
|
+
sage: ProjectiveSpace(5, QQ)
|
|
179
|
+
Projective Space of dimension 5 over Rational Field
|
|
180
|
+
sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P
|
|
181
|
+
Projective Space of dimension 2 over Rational Field
|
|
182
|
+
sage: P.coordinate_ring()
|
|
183
|
+
Multivariate Polynomial Ring in X, Y, Z over Rational Field
|
|
184
|
+
|
|
185
|
+
The divide operator does base extension.
|
|
186
|
+
|
|
187
|
+
::
|
|
188
|
+
|
|
189
|
+
sage: ProjectiveSpace(5)/GF(17)
|
|
190
|
+
Projective Space of dimension 5 over Finite Field of size 17
|
|
191
|
+
|
|
192
|
+
The default base ring is `\ZZ`.
|
|
193
|
+
|
|
194
|
+
::
|
|
195
|
+
|
|
196
|
+
sage: ProjectiveSpace(5)
|
|
197
|
+
Projective Space of dimension 5 over Integer Ring
|
|
198
|
+
|
|
199
|
+
There is also a projective space associated each polynomial ring.
|
|
200
|
+
|
|
201
|
+
::
|
|
202
|
+
|
|
203
|
+
sage: R = GF(7)['x,y,z']
|
|
204
|
+
sage: P = ProjectiveSpace(R); P
|
|
205
|
+
Projective Space of dimension 2 over Finite Field of size 7
|
|
206
|
+
sage: P.coordinate_ring()
|
|
207
|
+
Multivariate Polynomial Ring in x, y, z over Finite Field of size 7
|
|
208
|
+
sage: P.coordinate_ring() is R
|
|
209
|
+
True
|
|
210
|
+
|
|
211
|
+
::
|
|
212
|
+
|
|
213
|
+
sage: ProjectiveSpace(3, Zp(5), 'y') # needs sage.rings.padics
|
|
214
|
+
Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20
|
|
215
|
+
|
|
216
|
+
::
|
|
217
|
+
|
|
218
|
+
sage: ProjectiveSpace(2, QQ, 'x,y,z')
|
|
219
|
+
Projective Space of dimension 2 over Rational Field
|
|
220
|
+
|
|
221
|
+
::
|
|
222
|
+
|
|
223
|
+
sage: PS.<x,y> = ProjectiveSpace(1, CC); PS # needs sage.rings.real_mpfr
|
|
224
|
+
Projective Space of dimension 1 over Complex Field with 53 bits of precision
|
|
225
|
+
|
|
226
|
+
::
|
|
227
|
+
|
|
228
|
+
sage: R.<x,y,z> = QQ[]
|
|
229
|
+
sage: ProjectiveSpace(R).variable_names()
|
|
230
|
+
('x', 'y', 'z')
|
|
231
|
+
|
|
232
|
+
Projective spaces are not cached, i.e., there can be several with
|
|
233
|
+
the same base ring and dimension (to facilitate gluing
|
|
234
|
+
constructions).
|
|
235
|
+
|
|
236
|
+
::
|
|
237
|
+
|
|
238
|
+
sage: R.<x> = QQ[]
|
|
239
|
+
sage: ProjectiveSpace(R)
|
|
240
|
+
Projective Space of dimension 0 over Rational Field
|
|
241
|
+
|
|
242
|
+
TESTS::
|
|
243
|
+
|
|
244
|
+
sage: R.<x,y> = QQ[]
|
|
245
|
+
sage: P.<z,w> = ProjectiveSpace(R)
|
|
246
|
+
Traceback (most recent call last):
|
|
247
|
+
...
|
|
248
|
+
NameError: variable names passed to ProjectiveSpace conflict with names in ring
|
|
249
|
+
|
|
250
|
+
::
|
|
251
|
+
|
|
252
|
+
sage: R.<x,y> = QQ[]
|
|
253
|
+
sage: P.<x,y> = ProjectiveSpace(R)
|
|
254
|
+
sage: P.gens() == R.gens()
|
|
255
|
+
True
|
|
256
|
+
"""
|
|
257
|
+
if isinstance(n, (MPolynomialRing_base, PolynomialRing_generic)) and R is None:
|
|
258
|
+
if names is not None:
|
|
259
|
+
# Check for the case that the user provided a variable name
|
|
260
|
+
# That does not match what we wanted to use from R
|
|
261
|
+
names = normalize_names(n.ngens(), names)
|
|
262
|
+
if n.variable_names() != names:
|
|
263
|
+
# The provided name doesn't match the name of R's variables
|
|
264
|
+
raise NameError("variable names passed to ProjectiveSpace conflict with names in ring")
|
|
265
|
+
A = ProjectiveSpace(n.ngens() - 1, n.base_ring(),
|
|
266
|
+
names=n.variable_names())
|
|
267
|
+
A._coordinate_ring = n
|
|
268
|
+
return A
|
|
269
|
+
if names is None:
|
|
270
|
+
names = 'x'
|
|
271
|
+
if isinstance(R, (Integer, int)):
|
|
272
|
+
n, R = R, n
|
|
273
|
+
if R is None:
|
|
274
|
+
R = ZZ # default is the integers
|
|
275
|
+
if R in _Fields:
|
|
276
|
+
if isinstance(R, FiniteField):
|
|
277
|
+
return ProjectiveSpace_finite_field(n, R, names)
|
|
278
|
+
if isinstance(R, RationalField):
|
|
279
|
+
return ProjectiveSpace_rational_field(n, R, names)
|
|
280
|
+
else:
|
|
281
|
+
return ProjectiveSpace_field(n, R, names)
|
|
282
|
+
elif R in _CommRings:
|
|
283
|
+
return ProjectiveSpace_ring(n, R, names)
|
|
284
|
+
raise TypeError("R (=%s) must be a commutative ring" % R)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class ProjectiveSpace_ring(UniqueRepresentation, AmbientSpace):
|
|
288
|
+
"""
|
|
289
|
+
Projective space of dimension `n` over the ring
|
|
290
|
+
`R`.
|
|
291
|
+
|
|
292
|
+
EXAMPLES::
|
|
293
|
+
|
|
294
|
+
sage: X.<x,y,z,w> = ProjectiveSpace(3, QQ)
|
|
295
|
+
sage: X.base_scheme()
|
|
296
|
+
Spectrum of Rational Field
|
|
297
|
+
sage: X.base_ring()
|
|
298
|
+
Rational Field
|
|
299
|
+
sage: X.structure_morphism()
|
|
300
|
+
Scheme morphism:
|
|
301
|
+
From: Projective Space of dimension 3 over Rational Field
|
|
302
|
+
To: Spectrum of Rational Field
|
|
303
|
+
Defn: Structure map
|
|
304
|
+
sage: X.coordinate_ring()
|
|
305
|
+
Multivariate Polynomial Ring in x, y, z, w over Rational Field
|
|
306
|
+
|
|
307
|
+
Loading and saving::
|
|
308
|
+
|
|
309
|
+
sage: loads(X.dumps()) == X
|
|
310
|
+
True
|
|
311
|
+
sage: P = ProjectiveSpace(ZZ, 1, 'x')
|
|
312
|
+
sage: loads(P.dumps()) is P
|
|
313
|
+
True
|
|
314
|
+
|
|
315
|
+
Equality and hashing::
|
|
316
|
+
|
|
317
|
+
sage: ProjectiveSpace(QQ, 3, 'a') == ProjectiveSpace(ZZ, 3, 'a')
|
|
318
|
+
False
|
|
319
|
+
sage: ProjectiveSpace(ZZ, 1, 'a') == ProjectiveSpace(ZZ, 0, 'a')
|
|
320
|
+
False
|
|
321
|
+
sage: ProjectiveSpace(ZZ, 2, 'a') == AffineSpace(ZZ, 2, 'a')
|
|
322
|
+
False
|
|
323
|
+
|
|
324
|
+
sage: ProjectiveSpace(QQ, 3, 'a') != ProjectiveSpace(ZZ, 3, 'a')
|
|
325
|
+
True
|
|
326
|
+
sage: ProjectiveSpace(ZZ, 1, 'a') != ProjectiveSpace(ZZ, 0, 'a')
|
|
327
|
+
True
|
|
328
|
+
sage: ProjectiveSpace(ZZ, 2, 'a') != AffineSpace(ZZ, 2, 'a')
|
|
329
|
+
True
|
|
330
|
+
|
|
331
|
+
sage: hash(ProjectiveSpace(QQ, 3, 'a')) == hash(ProjectiveSpace(ZZ, 3, 'a'))
|
|
332
|
+
False
|
|
333
|
+
sage: hash(ProjectiveSpace(ZZ, 1, 'a')) == hash(ProjectiveSpace(ZZ, 0, 'a'))
|
|
334
|
+
False
|
|
335
|
+
sage: hash(ProjectiveSpace(ZZ, 2, 'a')) == hash(AffineSpace(ZZ, 2, 'a'))
|
|
336
|
+
False
|
|
337
|
+
"""
|
|
338
|
+
@staticmethod
|
|
339
|
+
def __classcall__(cls, n, R=ZZ, names=None):
|
|
340
|
+
"""
|
|
341
|
+
EXAMPLES::
|
|
342
|
+
|
|
343
|
+
sage: ProjectiveSpace(QQ, 2, names='XYZ') is ProjectiveSpace(QQ, 2, names='XYZ')
|
|
344
|
+
True
|
|
345
|
+
"""
|
|
346
|
+
normalized_names = normalize_names(n + 1, names)
|
|
347
|
+
return super().__classcall__(cls, n, R, normalized_names)
|
|
348
|
+
|
|
349
|
+
def __init__(self, n, R=ZZ, names=None):
|
|
350
|
+
"""
|
|
351
|
+
Initialization function.
|
|
352
|
+
|
|
353
|
+
EXAMPLES::
|
|
354
|
+
|
|
355
|
+
sage: ProjectiveSpace(3, Zp(5), 'y') # needs sage.rings.padics
|
|
356
|
+
Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20
|
|
357
|
+
"""
|
|
358
|
+
AmbientSpace.__init__(self, n, R)
|
|
359
|
+
self._assign_names(names)
|
|
360
|
+
|
|
361
|
+
def ngens(self):
|
|
362
|
+
"""
|
|
363
|
+
Return the number of generators of this projective space.
|
|
364
|
+
|
|
365
|
+
This is the number of variables in the coordinate ring of ``self``.
|
|
366
|
+
|
|
367
|
+
EXAMPLES::
|
|
368
|
+
|
|
369
|
+
sage: ProjectiveSpace(3, QQ).ngens()
|
|
370
|
+
4
|
|
371
|
+
sage: ProjectiveSpace(7, ZZ).ngens()
|
|
372
|
+
8
|
|
373
|
+
"""
|
|
374
|
+
return self.dimension_relative() + 1
|
|
375
|
+
|
|
376
|
+
def _check_satisfies_equations(self, v):
|
|
377
|
+
"""
|
|
378
|
+
Return ``True`` if ``v`` defines a point on the scheme; raise a
|
|
379
|
+
:exc:`TypeError` otherwise.
|
|
380
|
+
|
|
381
|
+
EXAMPLES::
|
|
382
|
+
|
|
383
|
+
sage: P = ProjectiveSpace(2, ZZ)
|
|
384
|
+
sage: P._check_satisfies_equations([1, 1, 0])
|
|
385
|
+
True
|
|
386
|
+
|
|
387
|
+
::
|
|
388
|
+
|
|
389
|
+
sage: P = ProjectiveSpace(1, QQ)
|
|
390
|
+
sage: P._check_satisfies_equations((1/2, 0))
|
|
391
|
+
True
|
|
392
|
+
|
|
393
|
+
::
|
|
394
|
+
|
|
395
|
+
sage: P = ProjectiveSpace(2, ZZ)
|
|
396
|
+
sage: P._check_satisfies_equations([0, 0, 0])
|
|
397
|
+
Traceback (most recent call last):
|
|
398
|
+
...
|
|
399
|
+
TypeError: the zero vector is not a point in projective space
|
|
400
|
+
|
|
401
|
+
::
|
|
402
|
+
|
|
403
|
+
sage: P = ProjectiveSpace(2, ZZ)
|
|
404
|
+
sage: P._check_satisfies_equations((1, 0))
|
|
405
|
+
Traceback (most recent call last):
|
|
406
|
+
...
|
|
407
|
+
TypeError: the list v=(1, 0) must have 3 components
|
|
408
|
+
|
|
409
|
+
::
|
|
410
|
+
|
|
411
|
+
sage: P = ProjectiveSpace(2, ZZ)
|
|
412
|
+
sage: P._check_satisfies_equations([1/2, 0, 1])
|
|
413
|
+
Traceback (most recent call last):
|
|
414
|
+
...
|
|
415
|
+
TypeError: the components of v=[1/2, 0, 1] must be elements of Integer Ring
|
|
416
|
+
"""
|
|
417
|
+
if not isinstance(v, (list, tuple)):
|
|
418
|
+
raise TypeError('the argument v=%s must be a list or tuple' % v)
|
|
419
|
+
n = self.ngens()
|
|
420
|
+
if not len(v) == n:
|
|
421
|
+
raise TypeError('the list v=%s must have %s components' % (v, n))
|
|
422
|
+
R = self.base_ring()
|
|
423
|
+
for coord in v:
|
|
424
|
+
if coord not in R:
|
|
425
|
+
raise TypeError('the components of v=%s must be elements of %s' % (v, R))
|
|
426
|
+
zero = [R(0)] * n
|
|
427
|
+
if v == zero:
|
|
428
|
+
raise TypeError('the zero vector is not a point in projective space')
|
|
429
|
+
return True
|
|
430
|
+
|
|
431
|
+
def coordinate_ring(self):
|
|
432
|
+
"""
|
|
433
|
+
Return the coordinate ring of this scheme.
|
|
434
|
+
|
|
435
|
+
EXAMPLES::
|
|
436
|
+
|
|
437
|
+
sage: ProjectiveSpace(3, GF(19^2,'alpha'), 'abcd').coordinate_ring() # needs sage.rings.finite_rings
|
|
438
|
+
Multivariate Polynomial Ring in a, b, c, d over Finite Field in alpha of size 19^2
|
|
439
|
+
|
|
440
|
+
::
|
|
441
|
+
|
|
442
|
+
sage: ProjectiveSpace(3).coordinate_ring()
|
|
443
|
+
Multivariate Polynomial Ring in x0, x1, x2, x3 over Integer Ring
|
|
444
|
+
|
|
445
|
+
::
|
|
446
|
+
|
|
447
|
+
sage: ProjectiveSpace(2, QQ, ['alpha', 'beta', 'gamma']).coordinate_ring()
|
|
448
|
+
Multivariate Polynomial Ring in alpha, beta, gamma over Rational Field
|
|
449
|
+
"""
|
|
450
|
+
try:
|
|
451
|
+
return self._coordinate_ring
|
|
452
|
+
except AttributeError:
|
|
453
|
+
self._coordinate_ring = PolynomialRing(self.base_ring(),
|
|
454
|
+
self.variable_names(),
|
|
455
|
+
self.dimension_relative() + 1)
|
|
456
|
+
return self._coordinate_ring
|
|
457
|
+
|
|
458
|
+
def _validate(self, polynomials):
|
|
459
|
+
"""
|
|
460
|
+
If ``polynomials`` is a tuple of valid polynomial functions on
|
|
461
|
+
``self``, return ``polynomials``, otherwise raise :exc:`TypeError`.
|
|
462
|
+
|
|
463
|
+
Since this is a projective space, polynomials must be homogeneous.
|
|
464
|
+
|
|
465
|
+
INPUT:
|
|
466
|
+
|
|
467
|
+
- ``polynomials`` -- tuple of polynomials in the coordinate ring of
|
|
468
|
+
this space
|
|
469
|
+
|
|
470
|
+
OUTPUT: tuple of polynomials in the coordinate ring of this space
|
|
471
|
+
|
|
472
|
+
EXAMPLES::
|
|
473
|
+
|
|
474
|
+
sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
|
|
475
|
+
sage: P._validate([x*y - z^2, x])
|
|
476
|
+
[x*y - z^2, x]
|
|
477
|
+
|
|
478
|
+
::
|
|
479
|
+
|
|
480
|
+
sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
|
|
481
|
+
sage: P._validate((x*y - z, x))
|
|
482
|
+
Traceback (most recent call last):
|
|
483
|
+
...
|
|
484
|
+
TypeError: x*y - z is not a homogeneous polynomial
|
|
485
|
+
|
|
486
|
+
::
|
|
487
|
+
|
|
488
|
+
sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
|
|
489
|
+
sage: P._validate(x*y - z)
|
|
490
|
+
Traceback (most recent call last):
|
|
491
|
+
...
|
|
492
|
+
TypeError: the argument polynomials=x*y - z must be a list or tuple
|
|
493
|
+
"""
|
|
494
|
+
if not isinstance(polynomials, (list, tuple)):
|
|
495
|
+
raise TypeError('the argument polynomials=%s must be a list or tuple' % polynomials)
|
|
496
|
+
for f in polynomials:
|
|
497
|
+
if not f.is_homogeneous():
|
|
498
|
+
raise TypeError("%s is not a homogeneous polynomial" % f)
|
|
499
|
+
return polynomials
|
|
500
|
+
|
|
501
|
+
def __pow__(self, m):
|
|
502
|
+
"""
|
|
503
|
+
Return the Cartesian power of this space.
|
|
504
|
+
|
|
505
|
+
INPUT:
|
|
506
|
+
|
|
507
|
+
- ``m`` -- integer
|
|
508
|
+
|
|
509
|
+
OUTPUT: product of projective spaces
|
|
510
|
+
|
|
511
|
+
EXAMPLES::
|
|
512
|
+
|
|
513
|
+
sage: P = ProjectiveSpace(1, QQ, 'x')
|
|
514
|
+
sage: P3 = P^3; P3
|
|
515
|
+
Product of projective spaces P^1 x P^1 x P^1 over Rational Field
|
|
516
|
+
sage: P3.variable_names()
|
|
517
|
+
('x0', 'x1', 'x2', 'x3', 'x4', 'x5')
|
|
518
|
+
|
|
519
|
+
As you see, custom variable names are not preserved by power operator,
|
|
520
|
+
since there is no natural way to make new ones in general.
|
|
521
|
+
"""
|
|
522
|
+
mm = int(m)
|
|
523
|
+
if mm != m:
|
|
524
|
+
raise ValueError("m must be an integer")
|
|
525
|
+
return ProductProjectiveSpaces([self.dimension_relative()] * mm, self.base_ring())
|
|
526
|
+
|
|
527
|
+
def __mul__(self, right):
|
|
528
|
+
r"""
|
|
529
|
+
Create the product of projective spaces.
|
|
530
|
+
|
|
531
|
+
INPUT:
|
|
532
|
+
|
|
533
|
+
- ``right`` -- a projective space, product of projective spaces, or subscheme
|
|
534
|
+
|
|
535
|
+
OUTPUT: a product of projective spaces or subscheme
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: P1 = ProjectiveSpace(QQ, 1, 'x')
|
|
540
|
+
sage: P2 = ProjectiveSpace(QQ, 2, 'y')
|
|
541
|
+
sage: P1*P2
|
|
542
|
+
Product of projective spaces P^1 x P^2 over Rational Field
|
|
543
|
+
|
|
544
|
+
::
|
|
545
|
+
|
|
546
|
+
sage: S.<t,x,y,z,u,v,w> = ProductProjectiveSpaces([3, 2], QQ)
|
|
547
|
+
sage: T.<a,b> = ProjectiveSpace(QQ, 1)
|
|
548
|
+
sage: T*S
|
|
549
|
+
Product of projective spaces P^1 x P^3 x P^2 over Rational Field
|
|
550
|
+
|
|
551
|
+
::
|
|
552
|
+
|
|
553
|
+
sage: S = ProjectiveSpace(ZZ, 2, 't')
|
|
554
|
+
sage: T = ProjectiveSpace(ZZ, 3, 'x')
|
|
555
|
+
sage: T.inject_variables()
|
|
556
|
+
Defining x0, x1, x2, x3
|
|
557
|
+
sage: X = T.subscheme([x0*x2 - x1*x3])
|
|
558
|
+
sage: S*X
|
|
559
|
+
Closed subscheme of Product of projective spaces P^2 x P^3 over Integer Ring defined by:
|
|
560
|
+
x0*x2 - x1*x3
|
|
561
|
+
|
|
562
|
+
::
|
|
563
|
+
|
|
564
|
+
sage: S = ProjectiveSpace(QQ, 3, 'x')
|
|
565
|
+
sage: T = AffineSpace(2, QQ, 'y')
|
|
566
|
+
sage: S*T
|
|
567
|
+
Traceback (most recent call last):
|
|
568
|
+
...
|
|
569
|
+
TypeError: Affine Space of dimension 2 over Rational Field must be a
|
|
570
|
+
projective space, product of projective spaces, or subscheme
|
|
571
|
+
"""
|
|
572
|
+
if self.base_ring() != right.base_ring():
|
|
573
|
+
raise ValueError('Must have the same base ring')
|
|
574
|
+
|
|
575
|
+
if isinstance(right, ProductProjectiveSpaces_ring):
|
|
576
|
+
return ProductProjectiveSpaces([self] + right.components())
|
|
577
|
+
elif isinstance(right, ProjectiveSpace_ring):
|
|
578
|
+
if self is right:
|
|
579
|
+
return self.__pow__(2)
|
|
580
|
+
return ProductProjectiveSpaces([self, right])
|
|
581
|
+
elif isinstance(right, AlgebraicScheme_subscheme):
|
|
582
|
+
AS = self * right.ambient_space()
|
|
583
|
+
CR = AS.coordinate_ring()
|
|
584
|
+
n = self.ambient_space().coordinate_ring().ngens()
|
|
585
|
+
|
|
586
|
+
phi = self.ambient_space().coordinate_ring().hom(list(CR.gens()[:n]), CR)
|
|
587
|
+
psi = right.ambient_space().coordinate_ring().hom(list(CR.gens()[n:]), CR)
|
|
588
|
+
return AS.subscheme([phi(t) for t in self.defining_polynomials()] + [psi(t) for t in right.defining_polynomials()])
|
|
589
|
+
else:
|
|
590
|
+
raise TypeError('%s must be a projective space, product of projective spaces, or subscheme' % right)
|
|
591
|
+
|
|
592
|
+
def _latex_(self):
|
|
593
|
+
r"""
|
|
594
|
+
Return a LaTeX representation of this projective space.
|
|
595
|
+
|
|
596
|
+
EXAMPLES::
|
|
597
|
+
|
|
598
|
+
sage: print(latex(ProjectiveSpace(1, ZZ, 'x')))
|
|
599
|
+
{\mathbf P}_{\Bold{Z}}^{1}
|
|
600
|
+
|
|
601
|
+
TESTS::
|
|
602
|
+
|
|
603
|
+
sage: ProjectiveSpace(11, Zp(5), 'y')._latex_() # needs sage.rings.padics
|
|
604
|
+
'{\\mathbf P}_{\\Bold{Z}_{5}}^{11}'
|
|
605
|
+
"""
|
|
606
|
+
return "{\\mathbf P}_{%s}^{%s}" % (latex(self.base_ring()), self.dimension_relative())
|
|
607
|
+
|
|
608
|
+
def _linear_system_as_kernel(self, d, pt, m):
|
|
609
|
+
"""
|
|
610
|
+
Return a matrix whose kernel consists of the coefficient vectors
|
|
611
|
+
of the degree ``d`` hypersurfaces (wrt lexicographic ordering of its
|
|
612
|
+
monomials) with multiplicity at least ``m`` at ``pt``.
|
|
613
|
+
|
|
614
|
+
INPUT:
|
|
615
|
+
|
|
616
|
+
- ``d`` -- nonnegative integer
|
|
617
|
+
|
|
618
|
+
- ``pt`` -- a point of ``self`` (possibly represented by a list with at
|
|
619
|
+
least one component equal to 1)
|
|
620
|
+
|
|
621
|
+
- ``m`` -- nonnegative integer
|
|
622
|
+
|
|
623
|
+
OUTPUT:
|
|
624
|
+
|
|
625
|
+
A matrix of size `\binom{m-1+n}{n}` x `\binom{d+n}{n}` where n is the
|
|
626
|
+
relative dimension of ``self``. The base ring of the matrix is a ring that
|
|
627
|
+
contains the base ring of ``self`` and the coefficients of the given point.
|
|
628
|
+
|
|
629
|
+
EXAMPLES:
|
|
630
|
+
|
|
631
|
+
If the degree `d` is 0, then a matrix consisting of the first unit vector
|
|
632
|
+
is returned::
|
|
633
|
+
|
|
634
|
+
sage: P = ProjectiveSpace(GF(5), 2, names='x')
|
|
635
|
+
sage: pt = P([1, 1, 1])
|
|
636
|
+
sage: P._linear_system_as_kernel(0, pt, 3) # needs sage.modules
|
|
637
|
+
[1]
|
|
638
|
+
[0]
|
|
639
|
+
[0]
|
|
640
|
+
[0]
|
|
641
|
+
[0]
|
|
642
|
+
[0]
|
|
643
|
+
|
|
644
|
+
If the multiplicity `m` is 0, then a matrix with zero rows
|
|
645
|
+
is returned::
|
|
646
|
+
|
|
647
|
+
sage: P = ProjectiveSpace(GF(5), 2, names='x')
|
|
648
|
+
sage: pt = P([1, 1, 1])
|
|
649
|
+
sage: M = P._linear_system_as_kernel(2, pt, 0) # needs sage.modules
|
|
650
|
+
sage: [M.nrows(), M.ncols()] # needs sage.modules
|
|
651
|
+
[0, 6]
|
|
652
|
+
|
|
653
|
+
The base ring does not need to be a field or even an integral domain.
|
|
654
|
+
In this case, the point can be given by a list::
|
|
655
|
+
|
|
656
|
+
sage: R = Zmod(4)
|
|
657
|
+
sage: P = ProjectiveSpace(R, 2, names='x')
|
|
658
|
+
sage: pt = [R(1), R(3), R(0)]
|
|
659
|
+
sage: P._linear_system_as_kernel(3, pt, 2) # needs sage.modules
|
|
660
|
+
[1 3 0 1 0 0 3 0 0 0]
|
|
661
|
+
[0 1 0 2 0 0 3 0 0 0]
|
|
662
|
+
[0 0 1 0 3 0 0 1 0 0]
|
|
663
|
+
|
|
664
|
+
When representing a point by a list at least one component must be 1
|
|
665
|
+
(even when the base ring is a field and the list gives a well-defined
|
|
666
|
+
point in projective space)::
|
|
667
|
+
|
|
668
|
+
sage: R = GF(5)
|
|
669
|
+
sage: P = ProjectiveSpace(R, 2, names='x')
|
|
670
|
+
sage: pt = [R(3), R(3), R(0)]
|
|
671
|
+
sage: P._linear_system_as_kernel(3, pt, 2) # needs sage.modules
|
|
672
|
+
Traceback (most recent call last):
|
|
673
|
+
...
|
|
674
|
+
TypeError: at least one component of pt=[3, 3, 0] must be equal to 1
|
|
675
|
+
|
|
676
|
+
The components of the list do not have to be elements of the base ring
|
|
677
|
+
of the projective space. It suffices if there exists a common parent.
|
|
678
|
+
For example, the kernel of the following matrix corresponds to
|
|
679
|
+
hypersurfaces of degree 2 in 3-space with multiplicity at least 2 at a
|
|
680
|
+
general point in the third affine patch::
|
|
681
|
+
|
|
682
|
+
sage: P = ProjectiveSpace(QQ, 3, names='x')
|
|
683
|
+
sage: RPol.<t0,t1,t2,t3> = PolynomialRing(QQ, 4)
|
|
684
|
+
sage: pt = [t0,t1,1,t3]
|
|
685
|
+
sage: P._linear_system_as_kernel(2, pt, 2) # needs sage.modules
|
|
686
|
+
[ 2*t0 t1 1 t3 0 0 0 0 0 0]
|
|
687
|
+
[ 0 t0 0 0 2*t1 1 t3 0 0 0]
|
|
688
|
+
[ t0^2 t0*t1 t0 t0*t3 t1^2 t1 t1*t3 1 t3 t3^2]
|
|
689
|
+
[ 0 0 0 t0 0 0 t1 0 1 2*t3]
|
|
690
|
+
|
|
691
|
+
.. TODO::
|
|
692
|
+
|
|
693
|
+
Use this method as starting point to implement a class
|
|
694
|
+
LinearSystem for linear systems of hypersurfaces.
|
|
695
|
+
"""
|
|
696
|
+
if not isinstance(d, (int, Integer)):
|
|
697
|
+
raise TypeError('the argument d=%s must be an integer' % d)
|
|
698
|
+
if d < 0:
|
|
699
|
+
raise ValueError('the integer d=%s must be nonnegative' % d)
|
|
700
|
+
if not isinstance(pt, (list, tuple,
|
|
701
|
+
SchemeMorphism_point_projective_ring)):
|
|
702
|
+
raise TypeError('the argument pt=%s must be a list, tuple, or '
|
|
703
|
+
'point on a projective space' % pt)
|
|
704
|
+
pt, R = prepare(pt, None)
|
|
705
|
+
n = self.dimension_relative()
|
|
706
|
+
if not len(pt) == n + 1:
|
|
707
|
+
raise TypeError('the sequence pt=%s must have %s '
|
|
708
|
+
'components' % (pt, n + 1))
|
|
709
|
+
if not R.has_coerce_map_from(self.base_ring()):
|
|
710
|
+
raise TypeError('unable to find a common ring for all elements')
|
|
711
|
+
try:
|
|
712
|
+
i = pt.index(1)
|
|
713
|
+
except Exception:
|
|
714
|
+
raise TypeError('at least one component of pt=%s must be equal '
|
|
715
|
+
'to 1' % pt)
|
|
716
|
+
pt = pt[:i] + pt[i + 1:]
|
|
717
|
+
if not isinstance(m, (int, Integer)):
|
|
718
|
+
raise TypeError('the argument m=%s must be an integer' % m)
|
|
719
|
+
if m < 0:
|
|
720
|
+
raise ValueError('the integer m=%s must be nonnegative' % m)
|
|
721
|
+
# the components of partials correspond to partial derivatives
|
|
722
|
+
# of order at most m-1 with respect to n variables
|
|
723
|
+
partials = IntegerVectors(m - 1, n + 1).list()
|
|
724
|
+
# the components of monoms correspond to monomials of degree
|
|
725
|
+
# at most d in n variables
|
|
726
|
+
monoms = IntegerVectors(d, n + 1).list()
|
|
727
|
+
M = matrix(R, len(partials), len(monoms))
|
|
728
|
+
for row in range(M.nrows()):
|
|
729
|
+
e = partials[row][:i] + partials[row][i + 1:]
|
|
730
|
+
for col in range(M.ncols()):
|
|
731
|
+
f = monoms[col][:i] + monoms[col][i + 1:]
|
|
732
|
+
if all(f[j] >= e[j] for j in range(n)):
|
|
733
|
+
M[row, col] = prod(binomial(fj, ej) * ptj**(fj - ej)
|
|
734
|
+
for ptj, fj, ej in zip(pt, f, e)
|
|
735
|
+
if fj > ej)
|
|
736
|
+
return M
|
|
737
|
+
|
|
738
|
+
def _morphism(self, *args, **kwds):
|
|
739
|
+
"""
|
|
740
|
+
Construct a morphism.
|
|
741
|
+
|
|
742
|
+
For internal use only. See :mod:`morphism` for details.
|
|
743
|
+
|
|
744
|
+
TESTS::
|
|
745
|
+
|
|
746
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
747
|
+
sage: P2._morphism(P2.Hom(P2), [x,y,z])
|
|
748
|
+
Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3
|
|
749
|
+
Defn: Defined on coordinates by sending (x : y : z) to
|
|
750
|
+
(x : y : z)
|
|
751
|
+
"""
|
|
752
|
+
return SchemeMorphism_polynomial_projective_space(*args, **kwds)
|
|
753
|
+
|
|
754
|
+
def _homset(self, *args, **kwds):
|
|
755
|
+
""" ii
|
|
756
|
+
Construct the Hom-set
|
|
757
|
+
|
|
758
|
+
EXAMPLES::
|
|
759
|
+
|
|
760
|
+
sage: P.<x,y,z> = ProjectiveSpace(2, QQ)
|
|
761
|
+
sage: Hom(P, P) # indirect doctest
|
|
762
|
+
Set of morphisms
|
|
763
|
+
From: Projective Space of dimension 2 over Rational Field
|
|
764
|
+
To: Projective Space of dimension 2 over Rational Field
|
|
765
|
+
"""
|
|
766
|
+
return SchemeHomset_polynomial_projective_space(*args, **kwds)
|
|
767
|
+
|
|
768
|
+
def _point_homset(self, *args, **kwds):
|
|
769
|
+
"""
|
|
770
|
+
Construct a point Hom-set.
|
|
771
|
+
|
|
772
|
+
For internal use only. See :mod:`morphism` for details.
|
|
773
|
+
|
|
774
|
+
TESTS::
|
|
775
|
+
|
|
776
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
777
|
+
sage: P2._point_homset(Spec(GF(3)), P2)
|
|
778
|
+
Set of rational points of Projective Space of dimension 2 over Finite Field of size 3
|
|
779
|
+
"""
|
|
780
|
+
return SchemeHomset_points_projective_ring(*args, **kwds)
|
|
781
|
+
|
|
782
|
+
def point(self, v, check=True):
|
|
783
|
+
"""
|
|
784
|
+
Create a point on this projective space.
|
|
785
|
+
|
|
786
|
+
INPUT:
|
|
787
|
+
|
|
788
|
+
- ``v`` -- anything that defines a point
|
|
789
|
+
|
|
790
|
+
- ``check`` -- boolean (default: ``True``); whether
|
|
791
|
+
to check the defining data for consistency
|
|
792
|
+
|
|
793
|
+
OUTPUT: a point of this projective space
|
|
794
|
+
|
|
795
|
+
EXAMPLES::
|
|
796
|
+
|
|
797
|
+
sage: P2 = ProjectiveSpace(QQ, 2)
|
|
798
|
+
sage: P2.point([4,5])
|
|
799
|
+
(4 : 5 : 1)
|
|
800
|
+
|
|
801
|
+
::
|
|
802
|
+
|
|
803
|
+
sage: P = ProjectiveSpace(QQ, 1)
|
|
804
|
+
sage: P.point(infinity)
|
|
805
|
+
(1 : 0)
|
|
806
|
+
|
|
807
|
+
::
|
|
808
|
+
|
|
809
|
+
sage: P = ProjectiveSpace(QQ, 2)
|
|
810
|
+
sage: P.point(infinity)
|
|
811
|
+
Traceback (most recent call last):
|
|
812
|
+
...
|
|
813
|
+
ValueError: +Infinity not well defined in dimension > 1
|
|
814
|
+
|
|
815
|
+
::
|
|
816
|
+
|
|
817
|
+
sage: P = ProjectiveSpace(ZZ, 2)
|
|
818
|
+
sage: P.point([infinity])
|
|
819
|
+
Traceback (most recent call last):
|
|
820
|
+
...
|
|
821
|
+
ValueError: [+Infinity] not well defined in dimension > 1
|
|
822
|
+
"""
|
|
823
|
+
from sage.rings.infinity import infinity
|
|
824
|
+
if v is infinity or (isinstance(v, (list, tuple)) and
|
|
825
|
+
len(v) == 1 and v[0] is infinity):
|
|
826
|
+
if self.dimension_relative() > 1:
|
|
827
|
+
raise ValueError("%s not well defined in dimension > 1" % v)
|
|
828
|
+
v = [1, 0]
|
|
829
|
+
|
|
830
|
+
return self.point_homset()(v, check=check)
|
|
831
|
+
|
|
832
|
+
def _point(self, *args, **kwds):
|
|
833
|
+
"""
|
|
834
|
+
Construct a point.
|
|
835
|
+
|
|
836
|
+
For internal use only. See :mod:`morphism` for details.
|
|
837
|
+
|
|
838
|
+
TESTS::
|
|
839
|
+
|
|
840
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
841
|
+
sage: point_homset = P2._point_homset(Spec(GF(3)), P2)
|
|
842
|
+
sage: P2._point(point_homset, [1,2,3])
|
|
843
|
+
(2 : 1 : 0)
|
|
844
|
+
"""
|
|
845
|
+
return SchemeMorphism_point_projective_ring(*args, **kwds)
|
|
846
|
+
|
|
847
|
+
def _repr_(self):
|
|
848
|
+
"""
|
|
849
|
+
Return a string representation of this projective space.
|
|
850
|
+
|
|
851
|
+
EXAMPLES::
|
|
852
|
+
|
|
853
|
+
sage: ProjectiveSpace(1, ZZ, 'x')
|
|
854
|
+
Projective Space of dimension 1 over Integer Ring
|
|
855
|
+
|
|
856
|
+
TESTS::
|
|
857
|
+
|
|
858
|
+
sage: ProjectiveSpace(3, Zp(5), 'y')._repr_() # needs sage.rings.padics
|
|
859
|
+
'Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20'
|
|
860
|
+
"""
|
|
861
|
+
return "Projective Space of dimension %s over %s" % (self.dimension_relative(), self.base_ring())
|
|
862
|
+
|
|
863
|
+
def _repr_generic_point(self, v=None):
|
|
864
|
+
"""
|
|
865
|
+
Return a string representation of the generic point
|
|
866
|
+
corresponding to the list of polys ``v`` on this projective space.
|
|
867
|
+
|
|
868
|
+
If ``v`` is None, the representation of the generic point of
|
|
869
|
+
the projective space is returned.
|
|
870
|
+
|
|
871
|
+
EXAMPLES::
|
|
872
|
+
|
|
873
|
+
sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
|
|
874
|
+
sage: P._repr_generic_point([z*y - x^2])
|
|
875
|
+
'(-x^2 + y*z)'
|
|
876
|
+
sage: P._repr_generic_point()
|
|
877
|
+
'(x : y : z)'
|
|
878
|
+
"""
|
|
879
|
+
if v is None:
|
|
880
|
+
v = self.gens()
|
|
881
|
+
return '(%s)' % (" : ".join(repr(f) for f in v))
|
|
882
|
+
|
|
883
|
+
def _latex_generic_point(self, v=None):
|
|
884
|
+
"""
|
|
885
|
+
Return a LaTeX representation of the generic point
|
|
886
|
+
corresponding to the list of polys ``v`` on this projective space.
|
|
887
|
+
|
|
888
|
+
If ``v`` is None, the representation of the generic point of
|
|
889
|
+
the projective space is returned.
|
|
890
|
+
|
|
891
|
+
EXAMPLES::
|
|
892
|
+
|
|
893
|
+
sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
|
|
894
|
+
sage: P._latex_generic_point([z*y - x^2])
|
|
895
|
+
'\\left(-x^{2} + y z\\right)'
|
|
896
|
+
sage: P._latex_generic_point()
|
|
897
|
+
'\\left(x : y : z\\right)'
|
|
898
|
+
"""
|
|
899
|
+
if v is None:
|
|
900
|
+
v = self.gens()
|
|
901
|
+
return '\\left(%s\\right)' % (" : ".join(str(latex(f)) for f in v))
|
|
902
|
+
|
|
903
|
+
def change_ring(self, R):
|
|
904
|
+
r"""
|
|
905
|
+
Return a projective space over ring ``R``.
|
|
906
|
+
|
|
907
|
+
INPUT:
|
|
908
|
+
|
|
909
|
+
- ``R`` -- commutative ring or morphism
|
|
910
|
+
|
|
911
|
+
OUTPUT: projective space over ``R``
|
|
912
|
+
|
|
913
|
+
.. NOTE::
|
|
914
|
+
|
|
915
|
+
There is no need to have any relation between ``R`` and the base ring
|
|
916
|
+
of this space, if you want to have such a relation, use
|
|
917
|
+
``self.base_extend(R)`` instead.
|
|
918
|
+
|
|
919
|
+
EXAMPLES::
|
|
920
|
+
|
|
921
|
+
sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
|
|
922
|
+
sage: PQ = P.change_ring(QQ); PQ
|
|
923
|
+
Projective Space of dimension 2 over Rational Field
|
|
924
|
+
sage: PQ.change_ring(GF(5))
|
|
925
|
+
Projective Space of dimension 2 over Finite Field of size 5
|
|
926
|
+
|
|
927
|
+
::
|
|
928
|
+
|
|
929
|
+
sage: K.<w> = QuadraticField(2) # needs sage.rings.number_field
|
|
930
|
+
sage: P = ProjectiveSpace(K, 2, 't') # needs sage.rings.number_field
|
|
931
|
+
sage: P.change_ring(K.embeddings(QQbar)[0]) # needs sage.rings.number_field
|
|
932
|
+
Projective Space of dimension 2 over Algebraic Field
|
|
933
|
+
"""
|
|
934
|
+
if isinstance(R, Map):
|
|
935
|
+
return ProjectiveSpace(self.dimension_relative(), R.codomain(),
|
|
936
|
+
self.variable_names())
|
|
937
|
+
else:
|
|
938
|
+
return ProjectiveSpace(self.dimension_relative(), R,
|
|
939
|
+
self.variable_names())
|
|
940
|
+
|
|
941
|
+
def is_projective(self):
|
|
942
|
+
"""
|
|
943
|
+
Return that this ambient space is projective `n`-space.
|
|
944
|
+
|
|
945
|
+
EXAMPLES::
|
|
946
|
+
|
|
947
|
+
sage: ProjectiveSpace(3,QQ).is_projective()
|
|
948
|
+
True
|
|
949
|
+
"""
|
|
950
|
+
return True
|
|
951
|
+
|
|
952
|
+
def subscheme(self, X):
|
|
953
|
+
"""
|
|
954
|
+
Return the closed subscheme defined by ``X``.
|
|
955
|
+
|
|
956
|
+
INPUT:
|
|
957
|
+
|
|
958
|
+
- ``X`` -- list or tuple of equations
|
|
959
|
+
|
|
960
|
+
EXAMPLES::
|
|
961
|
+
|
|
962
|
+
sage: A.<x,y,z> = ProjectiveSpace(2, QQ)
|
|
963
|
+
sage: X = A.subscheme([x*z^2, y^2*z, x*y^2]); X
|
|
964
|
+
Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
|
|
965
|
+
x*z^2,
|
|
966
|
+
y^2*z,
|
|
967
|
+
x*y^2
|
|
968
|
+
sage: X.defining_polynomials ()
|
|
969
|
+
(x*z^2, y^2*z, x*y^2)
|
|
970
|
+
sage: I = X.defining_ideal(); I
|
|
971
|
+
Ideal (x*z^2, y^2*z, x*y^2) of Multivariate Polynomial Ring in x, y, z
|
|
972
|
+
over Rational Field
|
|
973
|
+
sage: I.groebner_basis() # needs sage.libs.singular
|
|
974
|
+
[x*y^2, y^2*z, x*z^2]
|
|
975
|
+
sage: X.dimension() # needs sage.libs.singular
|
|
976
|
+
0
|
|
977
|
+
sage: X.base_ring()
|
|
978
|
+
Rational Field
|
|
979
|
+
sage: X.base_scheme()
|
|
980
|
+
Spectrum of Rational Field
|
|
981
|
+
sage: X.structure_morphism()
|
|
982
|
+
Scheme morphism:
|
|
983
|
+
From: Closed subscheme of Projective Space of dimension 2
|
|
984
|
+
over Rational Field defined by: x*z^2, y^2*z, x*y^2
|
|
985
|
+
To: Spectrum of Rational Field
|
|
986
|
+
Defn: Structure map
|
|
987
|
+
|
|
988
|
+
TESTS::
|
|
989
|
+
|
|
990
|
+
sage: TestSuite(X).run(skip=["_test_an_element", "_test_elements",\
|
|
991
|
+
....: "_test_elements_eq", "_test_some_elements", "_test_elements_eq_reflexive",\
|
|
992
|
+
....: "_test_elements_eq_symmetric", "_test_elements_eq_transitive",\
|
|
993
|
+
....: "_test_elements_neq"])
|
|
994
|
+
"""
|
|
995
|
+
R = self.base_ring()
|
|
996
|
+
if R.is_field() and R.is_exact():
|
|
997
|
+
return AlgebraicScheme_subscheme_projective_field(self, X)
|
|
998
|
+
|
|
999
|
+
return AlgebraicScheme_subscheme_projective(self, X)
|
|
1000
|
+
|
|
1001
|
+
def points_of_bounded_height(self, **kwds):
|
|
1002
|
+
r"""
|
|
1003
|
+
Return an iterator of the points in ``self`` of absolute multiplicative
|
|
1004
|
+
height of at most the given bound.
|
|
1005
|
+
|
|
1006
|
+
ALGORITHM:
|
|
1007
|
+
|
|
1008
|
+
This is an implementation of Algorithm 6 in [Krumm2016]_.
|
|
1009
|
+
|
|
1010
|
+
INPUT: keyword arguments:
|
|
1011
|
+
|
|
1012
|
+
- ``bound`` -- a real number
|
|
1013
|
+
|
|
1014
|
+
- ``precision`` -- (default: 53) a positive integer
|
|
1015
|
+
|
|
1016
|
+
OUTPUT: an iterator of points of bounded height
|
|
1017
|
+
|
|
1018
|
+
EXAMPLES::
|
|
1019
|
+
|
|
1020
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1021
|
+
sage: sorted(list(P.points_of_bounded_height(bound=2)))
|
|
1022
|
+
[(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1),
|
|
1023
|
+
(1/2 : 1), (1 : 0), (1 : 1), (2 : 1)]
|
|
1024
|
+
|
|
1025
|
+
::
|
|
1026
|
+
|
|
1027
|
+
sage: u = QQ['u'].0
|
|
1028
|
+
sage: P.<x,y,z> = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) # needs sage.rings.number_field
|
|
1029
|
+
sage: len(list(P.points_of_bounded_height(bound=2))) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1030
|
+
265
|
|
1031
|
+
|
|
1032
|
+
::
|
|
1033
|
+
|
|
1034
|
+
sage: # needs sage.rings.number_field
|
|
1035
|
+
sage: CF.<a> = CyclotomicField(3)
|
|
1036
|
+
sage: R.<x> = CF[]
|
|
1037
|
+
sage: L.<l> = CF.extension(x^3 + 2)
|
|
1038
|
+
sage: Q.<x,y> = ProjectiveSpace(L, 1)
|
|
1039
|
+
sage: sorted(list(Q.points_of_bounded_height(bound=1))) # needs sage.geometry.polyhedron
|
|
1040
|
+
[(0 : 1), (1 : 0), (a + 1 : 1), (a : 1),
|
|
1041
|
+
(-1 : 1), (-a - 1 : 1), (-a : 1), (1 : 1)]
|
|
1042
|
+
|
|
1043
|
+
::
|
|
1044
|
+
|
|
1045
|
+
sage: # needs sage.rings.number_field
|
|
1046
|
+
sage: R.<x> = QQ[]
|
|
1047
|
+
sage: F.<a> = NumberField(x^4 - 8*x^2 + 3)
|
|
1048
|
+
sage: P.<x,y,z> = ProjectiveSpace(F, 2)
|
|
1049
|
+
sage: all(exp(p.global_height()) <= 1 # needs sage.geometry.polyhedron sage.symbolic
|
|
1050
|
+
....: for p in P.points_of_bounded_height(bound=1))
|
|
1051
|
+
True
|
|
1052
|
+
|
|
1053
|
+
::
|
|
1054
|
+
|
|
1055
|
+
sage: K.<a> = CyclotomicField(3) # needs sage.rings.number_field
|
|
1056
|
+
sage: P.<x,y,z> = ProjectiveSpace(K, 2) # needs sage.rings.number_field
|
|
1057
|
+
sage: len(list(P.points_of_bounded_height(bound=1))) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1058
|
+
57
|
|
1059
|
+
|
|
1060
|
+
::
|
|
1061
|
+
|
|
1062
|
+
sage: u = QQ['u'].0
|
|
1063
|
+
sage: K.<k> = NumberField(u^2 - 2) # needs sage.rings.number_field
|
|
1064
|
+
sage: P.<x,y> = ProjectiveSpace(K, 1) # needs sage.rings.number_field
|
|
1065
|
+
sage: len(list(P.points_of_bounded_height(bound=2))) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1066
|
+
24
|
|
1067
|
+
|
|
1068
|
+
::
|
|
1069
|
+
|
|
1070
|
+
sage: R.<x> = QQ[]
|
|
1071
|
+
sage: K.<k> = NumberField(x^4 - 8*x^2 + 3) # needs sage.rings.number_field
|
|
1072
|
+
sage: P.<x,y> = ProjectiveSpace(K, 1) # needs sage.rings.number_field
|
|
1073
|
+
sage: len(list(P.points_of_bounded_height(bound=2))) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1074
|
+
108
|
|
1075
|
+
|
|
1076
|
+
::
|
|
1077
|
+
|
|
1078
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1079
|
+
sage: R.<x> = QQ[]
|
|
1080
|
+
sage: K.<v> = NumberField(x^5 + x^3 + 1)
|
|
1081
|
+
sage: P.<x,y,z> = ProjectiveSpace(K, 2)
|
|
1082
|
+
sage: L = P.points_of_bounded_height(bound=1.2)
|
|
1083
|
+
sage: len(list(L))
|
|
1084
|
+
109
|
|
1085
|
+
|
|
1086
|
+
::
|
|
1087
|
+
|
|
1088
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1089
|
+
sage: K.<v> = QuadraticField(2)
|
|
1090
|
+
sage: P.<x,y> = ProjectiveSpace(K, 1)
|
|
1091
|
+
sage: sorted(list(P.points_of_bounded_height(bound=2)))
|
|
1092
|
+
[(-v - 2 : 1), (-v - 1 : 1), (-2 : 1), (-1/2*v - 1 : 1), (-v : 1), (-1 : 1),
|
|
1093
|
+
(-1/2*v : 1), (v - 2 : 1), (-1/2 : 1), (-v + 1 : 1), (1/2*v - 1 : 1), (0 : 1),
|
|
1094
|
+
(-1/2*v + 1 : 1), (v - 1 : 1), (1/2 : 1), (-v + 2 : 1), (1/2*v : 1), (1 : 0),
|
|
1095
|
+
(1 : 1), (v : 1), (1/2*v + 1 : 1), (2 : 1), (v + 1 : 1), (v + 2 : 1)]
|
|
1096
|
+
|
|
1097
|
+
::
|
|
1098
|
+
|
|
1099
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1100
|
+
sage: R.<x> = QQ[]
|
|
1101
|
+
sage: K.<a> = NumberField(3*x^2 + 1)
|
|
1102
|
+
sage: P.<z,w> = ProjectiveSpace(K, 1)
|
|
1103
|
+
sage: sorted(list(P.points_of_bounded_height(bound=1)))
|
|
1104
|
+
[(-1 : 1), (-3/2*a - 1/2 : 1), (3/2*a - 1/2 : 1), (0 : 1),
|
|
1105
|
+
(-3/2*a + 1/2 : 1), (3/2*a + 1/2 : 1), (1 : 0), (1 : 1)]
|
|
1106
|
+
|
|
1107
|
+
::
|
|
1108
|
+
|
|
1109
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1110
|
+
sage: R.<x> = QQ[]
|
|
1111
|
+
sage: K.<a> = NumberField(3*x^2 + 1)
|
|
1112
|
+
sage: O = K.maximal_order()
|
|
1113
|
+
sage: P.<z,w> = ProjectiveSpace(O, 1)
|
|
1114
|
+
sage: len(sorted(list(P.points_of_bounded_height(bound=2))))
|
|
1115
|
+
44
|
|
1116
|
+
|
|
1117
|
+
::
|
|
1118
|
+
|
|
1119
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1120
|
+
sage: R.<x> = QQ[]
|
|
1121
|
+
sage: K.<a> = NumberField(x^3 - 7)
|
|
1122
|
+
sage: O = K.maximal_order()
|
|
1123
|
+
sage: P.<z,w> = ProjectiveSpace(O, 1)
|
|
1124
|
+
sage: len(sorted(list(P.points_of_bounded_height(bound=2))))
|
|
1125
|
+
28
|
|
1126
|
+
|
|
1127
|
+
::
|
|
1128
|
+
|
|
1129
|
+
sage: P.<w,z> = ProjectiveSpace(ZZ, 1)
|
|
1130
|
+
sage: sorted(list(P.points_of_bounded_height(bound=2))) # needs sage.geometry.polyhedron
|
|
1131
|
+
[(-2 : -1), (-2 : 1), (-1 : -2), (-1 : -1),
|
|
1132
|
+
(-1 : 0), (-1 : 1), (-1 : 2), (0 : -1)]
|
|
1133
|
+
|
|
1134
|
+
::
|
|
1135
|
+
|
|
1136
|
+
sage: R.<x> = QQ[]
|
|
1137
|
+
sage: P.<z,w> = ProjectiveSpace(R, 1)
|
|
1138
|
+
sage: P.points_of_bounded_height(bound=2)
|
|
1139
|
+
Traceback (most recent call last):
|
|
1140
|
+
...
|
|
1141
|
+
NotImplementedError: self must be a projective space over
|
|
1142
|
+
a number field or a ring of integers
|
|
1143
|
+
|
|
1144
|
+
::
|
|
1145
|
+
|
|
1146
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
1147
|
+
sage: K.<i> = NumberField(x^2 + 1)
|
|
1148
|
+
sage: PK.<t> = K[]
|
|
1149
|
+
sage: L.<a> = K.extension(t^4 - i)
|
|
1150
|
+
sage: P.<z,w> = ProjectiveSpace(L, 1)
|
|
1151
|
+
sage: sorted(list(P.points_of_bounded_height(bound=1)))
|
|
1152
|
+
[(0 : 1), (1 : 0), (a : 1), (a^2 : 1), (a^3 : 1), (i : 1),
|
|
1153
|
+
(i*a : 1), (i*a^2 : 1), (i*a^3 : 1), (-1 : 1), (-a : 1), (-a^2 : 1),
|
|
1154
|
+
(-a^3 : 1), (-i : 1), (-i*a : 1), (-i*a^2 : 1), (-i*a^3 : 1), (1 : 1)]
|
|
1155
|
+
"""
|
|
1156
|
+
from sage.schemes.projective.proj_bdd_height import (
|
|
1157
|
+
ZZ_points_of_bounded_height,
|
|
1158
|
+
QQ_points_of_bounded_height,
|
|
1159
|
+
IQ_points_of_bounded_height,
|
|
1160
|
+
points_of_bounded_height
|
|
1161
|
+
)
|
|
1162
|
+
|
|
1163
|
+
R = self.base_ring()
|
|
1164
|
+
|
|
1165
|
+
# Check the base ring is the rational field, a number field,
|
|
1166
|
+
# or the ring of integers
|
|
1167
|
+
is_ring_of_ints = False
|
|
1168
|
+
|
|
1169
|
+
if isinstance(R, RationalField):
|
|
1170
|
+
field_type = False
|
|
1171
|
+
elif R in NumberFields():
|
|
1172
|
+
# True for the rational field as well, so check RationalField first
|
|
1173
|
+
field_type = True
|
|
1174
|
+
elif R is ZZ or (isinstance(R, sage.rings.abc.Order) and R.is_integrally_closed()): # Ensure ring of integers / maximal order
|
|
1175
|
+
is_ring_of_ints = True
|
|
1176
|
+
else:
|
|
1177
|
+
raise NotImplementedError("self must be a projective space over a number field or a ring of integers")
|
|
1178
|
+
|
|
1179
|
+
bound = kwds.pop('bound')
|
|
1180
|
+
prec = kwds.pop('precision', 53)
|
|
1181
|
+
|
|
1182
|
+
# Convert between absolute and relative height for calling Krumm's algorithm
|
|
1183
|
+
bound = bound**R.absolute_degree()
|
|
1184
|
+
|
|
1185
|
+
dim = self.dimension_relative()
|
|
1186
|
+
|
|
1187
|
+
# When R is the ring of integers
|
|
1188
|
+
if is_ring_of_ints:
|
|
1189
|
+
fraction_field = FractionField(R)
|
|
1190
|
+
|
|
1191
|
+
# Field of fraction is the rational field
|
|
1192
|
+
if fraction_field == QQ:
|
|
1193
|
+
return ZZ_points_of_bounded_height(self, dim, bound)
|
|
1194
|
+
|
|
1195
|
+
# Field of fraction is a number field
|
|
1196
|
+
r1, r2 = fraction_field.signature()
|
|
1197
|
+
r = r1 + r2 - 1
|
|
1198
|
+
|
|
1199
|
+
if fraction_field.is_relative():
|
|
1200
|
+
deg = fraction_field.relative_degree()
|
|
1201
|
+
else:
|
|
1202
|
+
deg = fraction_field.degree()
|
|
1203
|
+
|
|
1204
|
+
if deg == 2 and r == 0:
|
|
1205
|
+
return IQ_points_of_bounded_height(self, fraction_field, dim, bound)
|
|
1206
|
+
|
|
1207
|
+
return points_of_bounded_height(self, fraction_field, dim, bound, prec)
|
|
1208
|
+
|
|
1209
|
+
# When R is a field
|
|
1210
|
+
if field_type:
|
|
1211
|
+
# For checking whether R is imaginary quadratic field
|
|
1212
|
+
r1, r2 = R.signature()
|
|
1213
|
+
r = r1 + r2 - 1
|
|
1214
|
+
|
|
1215
|
+
if R.is_relative():
|
|
1216
|
+
deg = R.relative_degree()
|
|
1217
|
+
else:
|
|
1218
|
+
deg = R.degree()
|
|
1219
|
+
|
|
1220
|
+
if deg == 2 and r == 0:
|
|
1221
|
+
return IQ_points_of_bounded_height(self, R, dim, bound)
|
|
1222
|
+
|
|
1223
|
+
return points_of_bounded_height(self, R, dim, bound, prec)
|
|
1224
|
+
else:
|
|
1225
|
+
return QQ_points_of_bounded_height(self, dim, bound)
|
|
1226
|
+
|
|
1227
|
+
def affine_patch(self, i, AA=None):
|
|
1228
|
+
r"""
|
|
1229
|
+
Return the `i`-th affine patch of this projective space.
|
|
1230
|
+
|
|
1231
|
+
This is an ambient affine space `\mathbb{A}^n_R,` where
|
|
1232
|
+
`R` is the base ring of ``self``, whose "projective embedding"
|
|
1233
|
+
map is `1` in the `i`-th factor.
|
|
1234
|
+
|
|
1235
|
+
INPUT:
|
|
1236
|
+
|
|
1237
|
+
- ``i`` -- integer between 0 and dimension of ``self``, inclusive
|
|
1238
|
+
|
|
1239
|
+
- ``AA`` -- (default: ``None``) ambient affine space, this is constructed
|
|
1240
|
+
if it is not given
|
|
1241
|
+
|
|
1242
|
+
OUTPUT: an ambient affine space with fixed projective_embedding map
|
|
1243
|
+
|
|
1244
|
+
EXAMPLES::
|
|
1245
|
+
|
|
1246
|
+
sage: PP = ProjectiveSpace(5) / QQ
|
|
1247
|
+
sage: AA = PP.affine_patch(2)
|
|
1248
|
+
sage: AA
|
|
1249
|
+
Affine Space of dimension 5 over Rational Field
|
|
1250
|
+
sage: AA.projective_embedding()
|
|
1251
|
+
Scheme morphism:
|
|
1252
|
+
From: Affine Space of dimension 5 over Rational Field
|
|
1253
|
+
To: Projective Space of dimension 5 over Rational Field
|
|
1254
|
+
Defn: Defined on coordinates by sending (x0, x1, x3, x4, x5) to
|
|
1255
|
+
(x0 : x1 : 1 : x3 : x4 : x5)
|
|
1256
|
+
sage: AA.projective_embedding(0)
|
|
1257
|
+
Scheme morphism:
|
|
1258
|
+
From: Affine Space of dimension 5 over Rational Field
|
|
1259
|
+
To: Projective Space of dimension 5 over Rational Field
|
|
1260
|
+
Defn: Defined on coordinates by sending (x0, x1, x3, x4, x5) to
|
|
1261
|
+
(1 : x0 : x1 : x3 : x4 : x5)
|
|
1262
|
+
|
|
1263
|
+
::
|
|
1264
|
+
|
|
1265
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1266
|
+
sage: P.affine_patch(0).projective_embedding(0).codomain() == P
|
|
1267
|
+
True
|
|
1268
|
+
"""
|
|
1269
|
+
i = int(i) # implicit type checking
|
|
1270
|
+
n = self.dimension_relative()
|
|
1271
|
+
if i < 0 or i > n:
|
|
1272
|
+
raise ValueError("argument i (= %s) must be between 0 and %s" % (i, n))
|
|
1273
|
+
try:
|
|
1274
|
+
A = self.__affine_patches[i]
|
|
1275
|
+
# assume that if you've passed in a new affine space you
|
|
1276
|
+
# want to override the existing patch
|
|
1277
|
+
if AA is None or A == AA:
|
|
1278
|
+
return A
|
|
1279
|
+
except AttributeError:
|
|
1280
|
+
self.__affine_patches = {}
|
|
1281
|
+
except KeyError:
|
|
1282
|
+
pass
|
|
1283
|
+
# if no ith patch exists, we may still be here with AA==None
|
|
1284
|
+
if AA is None:
|
|
1285
|
+
from sage.schemes.affine.affine_space import AffineSpace
|
|
1286
|
+
g = self.gens()
|
|
1287
|
+
gens = g[:i] + g[i + 1:]
|
|
1288
|
+
AA = AffineSpace(n, self.base_ring(), names=gens,
|
|
1289
|
+
ambient_projective_space=self,
|
|
1290
|
+
default_embedding_index=i)
|
|
1291
|
+
elif AA.dimension_relative() != n:
|
|
1292
|
+
raise ValueError("affine space must be of the dimension %s" % (n))
|
|
1293
|
+
self.__affine_patches[i] = AA
|
|
1294
|
+
return AA
|
|
1295
|
+
|
|
1296
|
+
def _an_element_(self):
|
|
1297
|
+
r"""
|
|
1298
|
+
Return a (preferably typical) element of this space.
|
|
1299
|
+
|
|
1300
|
+
This is used both for illustration and testing purposes.
|
|
1301
|
+
|
|
1302
|
+
OUTPUT: a point in this projective space
|
|
1303
|
+
|
|
1304
|
+
EXAMPLES::
|
|
1305
|
+
|
|
1306
|
+
sage: ProjectiveSpace(ZZ, 3, 'x').an_element()
|
|
1307
|
+
(7 : 6 : 5 : 1)
|
|
1308
|
+
|
|
1309
|
+
sage: ProjectiveSpace(PolynomialRing(ZZ,'y'), 3, 'x').an_element()
|
|
1310
|
+
(7*y : 6*y : 5*y : 1)
|
|
1311
|
+
"""
|
|
1312
|
+
n = self.dimension_relative()
|
|
1313
|
+
R = self.base_ring()
|
|
1314
|
+
return self([(7 - i) * R.an_element() for i in range(n)] + [R.one()])
|
|
1315
|
+
|
|
1316
|
+
def Lattes_map(self, E, m):
|
|
1317
|
+
r"""
|
|
1318
|
+
Given an elliptic curve ``E`` and an integer ``m`` return
|
|
1319
|
+
the Lattes map associated to multiplication by `m`.
|
|
1320
|
+
|
|
1321
|
+
In other words, the rational map on the quotient
|
|
1322
|
+
`E/\{\pm 1\} \cong \mathbb{P}^1` associated to `[m]:E \to E`.
|
|
1323
|
+
|
|
1324
|
+
INPUT:
|
|
1325
|
+
|
|
1326
|
+
- ``E`` -- an elliptic curve
|
|
1327
|
+
|
|
1328
|
+
- ``m`` -- integer
|
|
1329
|
+
|
|
1330
|
+
OUTPUT: a dynamical system on this projective space
|
|
1331
|
+
|
|
1332
|
+
EXAMPLES::
|
|
1333
|
+
|
|
1334
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1335
|
+
sage: E = EllipticCurve(QQ,[-1, 0]) # needs sage.schemes
|
|
1336
|
+
sage: P.Lattes_map(E, 2) # needs sage.schemes
|
|
1337
|
+
Dynamical System of Projective Space of dimension 1 over Rational Field
|
|
1338
|
+
Defn: Defined on coordinates by sending (x : y) to
|
|
1339
|
+
(1/4*x^4 + 1/2*x^2*y^2 + 1/4*y^4 : x^3*y - x*y^3)
|
|
1340
|
+
|
|
1341
|
+
TESTS::
|
|
1342
|
+
|
|
1343
|
+
sage: P.<x,y> = ProjectiveSpace(GF(37), 1)
|
|
1344
|
+
sage: E = EllipticCurve([1, 1]) # needs sage.rings.finite_rings sage.schemes
|
|
1345
|
+
sage: f = P.Lattes_map(E, 2); f # needs sage.rings.finite_rings sage.schemes
|
|
1346
|
+
Dynamical System of Projective Space of dimension 1 over Finite Field of size 37
|
|
1347
|
+
Defn: Defined on coordinates by sending (x : y) to
|
|
1348
|
+
(-9*x^4 + 18*x^2*y^2 - 2*x*y^3 - 9*y^4 : x^3*y + x*y^3 + y^4)
|
|
1349
|
+
"""
|
|
1350
|
+
if self.dimension_relative() != 1:
|
|
1351
|
+
raise TypeError("must be dimension 1")
|
|
1352
|
+
if self.base_ring() != E.base_ring():
|
|
1353
|
+
E = E.change_ring(self.base_ring())
|
|
1354
|
+
|
|
1355
|
+
L = E.multiplication_by_m(m, x_only=True)
|
|
1356
|
+
F = [L.numerator(), L.denominator()]
|
|
1357
|
+
R = self.coordinate_ring()
|
|
1358
|
+
x, y = R.gens()
|
|
1359
|
+
phi = F[0].parent().hom([x], R)
|
|
1360
|
+
F = [phi(F[0]).homogenize(y), phi(F[1]).homogenize(y) * y]
|
|
1361
|
+
return DynamicalSystem_projective(F, domain=self)
|
|
1362
|
+
|
|
1363
|
+
def cartesian_product(self, other):
|
|
1364
|
+
r"""
|
|
1365
|
+
Return the Cartesian product of this projective space and
|
|
1366
|
+
``other``.
|
|
1367
|
+
|
|
1368
|
+
INPUT:
|
|
1369
|
+
|
|
1370
|
+
- ``other`` -- a projective space with the same base ring as this space
|
|
1371
|
+
|
|
1372
|
+
OUTPUT: a Cartesian product of projective spaces
|
|
1373
|
+
|
|
1374
|
+
EXAMPLES::
|
|
1375
|
+
|
|
1376
|
+
sage: P1 = ProjectiveSpace(QQ, 1, 'x')
|
|
1377
|
+
sage: P2 = ProjectiveSpace(QQ, 2, 'y')
|
|
1378
|
+
sage: PP = P1.cartesian_product(P2); PP
|
|
1379
|
+
Product of projective spaces P^1 x P^2 over Rational Field
|
|
1380
|
+
sage: PP.gens()
|
|
1381
|
+
(x0, x1, y0, y1, y2)
|
|
1382
|
+
"""
|
|
1383
|
+
return ProductProjectiveSpaces([self, other])
|
|
1384
|
+
|
|
1385
|
+
def chebyshev_polynomial(self, n, kind='first', monic=False):
|
|
1386
|
+
"""
|
|
1387
|
+
Generates an endomorphism of this projective line by a Chebyshev polynomial.
|
|
1388
|
+
|
|
1389
|
+
Chebyshev polynomials are a sequence of recursively defined orthogonal
|
|
1390
|
+
polynomials. Chebyshev of the first kind are defined as `T_0(x) = 1`,
|
|
1391
|
+
`T_1(x) = x`, and `T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x)`. Chebyshev of
|
|
1392
|
+
the second kind are defined as `U_0(x) = 1`,
|
|
1393
|
+
`U_1(x) = 2x`, and `U_{n+1}(x) = 2xU_n(x) - U_{n-1}(x)`.
|
|
1394
|
+
|
|
1395
|
+
INPUT:
|
|
1396
|
+
|
|
1397
|
+
- ``n`` -- nonnegative integer
|
|
1398
|
+
|
|
1399
|
+
- ``kind`` -- ``'first'`` (default) or ``'second'`` specifying which
|
|
1400
|
+
kind of Chebyshev the user would like to generate
|
|
1401
|
+
|
|
1402
|
+
- ``monic`` -- boolean (default: ``False``) specifying if the
|
|
1403
|
+
polynomial defining the system should be monic or not
|
|
1404
|
+
|
|
1405
|
+
OUTPUT: :class:`DynamicalSystem_projective`
|
|
1406
|
+
|
|
1407
|
+
EXAMPLES::
|
|
1408
|
+
|
|
1409
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1410
|
+
sage: P.chebyshev_polynomial(5, 'first') # needs sage.schemes sage.symbolic
|
|
1411
|
+
Dynamical System of Projective Space of dimension 1 over Rational Field
|
|
1412
|
+
Defn: Defined on coordinates by sending (x : y) to
|
|
1413
|
+
(16*x^5 - 20*x^3*y^2 + 5*x*y^4 : y^5)
|
|
1414
|
+
|
|
1415
|
+
::
|
|
1416
|
+
|
|
1417
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1418
|
+
sage: P.chebyshev_polynomial(3, 'second') # needs sage.schemes sage.symbolic
|
|
1419
|
+
Dynamical System of Projective Space of dimension 1 over Rational Field
|
|
1420
|
+
Defn: Defined on coordinates by sending (x : y) to
|
|
1421
|
+
(8*x^3 - 4*x*y^2 : y^3)
|
|
1422
|
+
|
|
1423
|
+
::
|
|
1424
|
+
|
|
1425
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1426
|
+
sage: P.chebyshev_polynomial(3, 2) # needs sage.schemes sage.symbolic
|
|
1427
|
+
Traceback (most recent call last):
|
|
1428
|
+
...
|
|
1429
|
+
ValueError: keyword 'kind' must have a value of either 'first' or 'second'
|
|
1430
|
+
|
|
1431
|
+
::
|
|
1432
|
+
|
|
1433
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1434
|
+
sage: P.chebyshev_polynomial(-4, 'second')
|
|
1435
|
+
Traceback (most recent call last):
|
|
1436
|
+
...
|
|
1437
|
+
ValueError: first parameter 'n' must be a nonnegative integer
|
|
1438
|
+
|
|
1439
|
+
::
|
|
1440
|
+
|
|
1441
|
+
sage: P = ProjectiveSpace(QQ, 2, 'x')
|
|
1442
|
+
sage: P.chebyshev_polynomial(2)
|
|
1443
|
+
Traceback (most recent call last):
|
|
1444
|
+
...
|
|
1445
|
+
TypeError: projective space must be of dimension 1
|
|
1446
|
+
|
|
1447
|
+
::
|
|
1448
|
+
|
|
1449
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1450
|
+
sage: P.chebyshev_polynomial(3, monic=True) # needs sage.schemes sage.symbolic
|
|
1451
|
+
Dynamical System of Projective Space of dimension 1 over Rational Field
|
|
1452
|
+
Defn: Defined on coordinates by sending (x : y) to
|
|
1453
|
+
(x^3 - 3*x*y^2 : y^3)
|
|
1454
|
+
|
|
1455
|
+
::
|
|
1456
|
+
|
|
1457
|
+
sage: F.<t> = FunctionField(QQ)
|
|
1458
|
+
sage: P.<y,z> = ProjectiveSpace(F, 1)
|
|
1459
|
+
sage: P.chebyshev_polynomial(4, monic=True) # needs sage.schemes sage.symbolic
|
|
1460
|
+
Dynamical System of Projective Space of dimension 1
|
|
1461
|
+
over Rational function field in t over Rational Field
|
|
1462
|
+
Defn: Defined on coordinates by sending (y : z) to
|
|
1463
|
+
(y^4 + (-4)*y^2*z^2 + 2*z^4 : z^4)
|
|
1464
|
+
"""
|
|
1465
|
+
if self.dimension_relative() != 1:
|
|
1466
|
+
raise TypeError("projective space must be of dimension 1")
|
|
1467
|
+
n = ZZ(n)
|
|
1468
|
+
if (n < 0):
|
|
1469
|
+
raise ValueError("first parameter 'n' must be a nonnegative integer")
|
|
1470
|
+
# use the affine version and then homogenize.
|
|
1471
|
+
A = self.affine_patch(1)
|
|
1472
|
+
f = A.chebyshev_polynomial(n, kind)
|
|
1473
|
+
if monic and self.base().characteristic() != 2:
|
|
1474
|
+
f = f.homogenize(1)
|
|
1475
|
+
return f.conjugate(matrix([[~ZZ(2), 0], [0, 1]]))
|
|
1476
|
+
return f.homogenize(1)
|
|
1477
|
+
|
|
1478
|
+
def veronese_embedding(self, d, CS=None, order='lex'):
|
|
1479
|
+
r"""
|
|
1480
|
+
Return the degree ``d`` Veronese embedding from this projective space.
|
|
1481
|
+
|
|
1482
|
+
INPUT:
|
|
1483
|
+
|
|
1484
|
+
- ``d`` -- positive integer
|
|
1485
|
+
|
|
1486
|
+
- ``CS`` -- (default: ``None``) a projective ambient space to embed
|
|
1487
|
+
into. If this projective space has dimension `N`, the dimension of
|
|
1488
|
+
``CS`` must be `\binom{N + d}{d} - 1`. This is constructed if not
|
|
1489
|
+
specified.
|
|
1490
|
+
|
|
1491
|
+
- ``order`` -- string (default: ``'lex'``); a monomial order to use to
|
|
1492
|
+
arrange the monomials defining the embedding. The monomials will be
|
|
1493
|
+
arranged from greatest to least with respect to this order.
|
|
1494
|
+
|
|
1495
|
+
OUTPUT: a scheme morphism from this projective space to ``CS``
|
|
1496
|
+
|
|
1497
|
+
EXAMPLES::
|
|
1498
|
+
|
|
1499
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1500
|
+
sage: vd = P.veronese_embedding(4, order='invlex') # needs sage.combinat
|
|
1501
|
+
sage: vd # needs sage.combinat
|
|
1502
|
+
Scheme morphism:
|
|
1503
|
+
From: Projective Space of dimension 1 over Rational Field
|
|
1504
|
+
To: Projective Space of dimension 4 over Rational Field
|
|
1505
|
+
Defn: Defined on coordinates by sending (x : y) to
|
|
1506
|
+
(y^4 : x*y^3 : x^2*y^2 : x^3*y : x^4)
|
|
1507
|
+
|
|
1508
|
+
Veronese surface::
|
|
1509
|
+
|
|
1510
|
+
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
|
|
1511
|
+
sage: Q.<q,r,s,t,u,v> = ProjectiveSpace(QQ, 5)
|
|
1512
|
+
sage: vd = P.veronese_embedding(2, Q) # needs sage.combinat
|
|
1513
|
+
sage: vd # needs sage.combinat
|
|
1514
|
+
Scheme morphism:
|
|
1515
|
+
From: Projective Space of dimension 2 over Rational Field
|
|
1516
|
+
To: Projective Space of dimension 5 over Rational Field
|
|
1517
|
+
Defn: Defined on coordinates by sending (x : y : z) to
|
|
1518
|
+
(x^2 : x*y : x*z : y^2 : y*z : z^2)
|
|
1519
|
+
sage: vd(P.subscheme([])) # needs sage.combinat sage.libs.singular
|
|
1520
|
+
Closed subscheme of Projective Space of dimension 5 over Rational Field
|
|
1521
|
+
defined by:
|
|
1522
|
+
-u^2 + t*v,
|
|
1523
|
+
-s*u + r*v,
|
|
1524
|
+
-s*t + r*u,
|
|
1525
|
+
-s^2 + q*v,
|
|
1526
|
+
-r*s + q*u,
|
|
1527
|
+
-r^2 + q*t
|
|
1528
|
+
"""
|
|
1529
|
+
d = ZZ(d)
|
|
1530
|
+
if d <= 0:
|
|
1531
|
+
raise ValueError("(=%s) must be a positive integer" % d)
|
|
1532
|
+
N = self.dimension()
|
|
1533
|
+
# construct codomain space if not given
|
|
1534
|
+
if CS is None:
|
|
1535
|
+
CS = ProjectiveSpace(self.base_ring(), binomial(N + d, d) - 1)
|
|
1536
|
+
else:
|
|
1537
|
+
if not isinstance(CS, ProjectiveSpace_ring):
|
|
1538
|
+
raise TypeError("(=%s) must be a projective space" % CS)
|
|
1539
|
+
if CS.dimension() != binomial(N + d, d) - 1:
|
|
1540
|
+
raise TypeError("(=%s) has the wrong dimension to serve as the codomain space" % CS)
|
|
1541
|
+
|
|
1542
|
+
R = self.coordinate_ring().change_ring(order=order)
|
|
1543
|
+
monomials = sorted([R({tuple(v): 1}) for v in WeightedIntegerVectors(d, [1] * (N + 1))])
|
|
1544
|
+
monomials.reverse() # order the monomials greatest to least via the given monomial order
|
|
1545
|
+
return Hom(self, CS)(monomials)
|
|
1546
|
+
|
|
1547
|
+
def point_transformation_matrix(self, points_source, points_target, normalize=True):
|
|
1548
|
+
r"""
|
|
1549
|
+
Returns a unique element of PGL that transforms one set of points to another.
|
|
1550
|
+
|
|
1551
|
+
Given a projective space of dimension n and a set of n+2 source points and a set of n+2 target
|
|
1552
|
+
points in the same projective space, such that no n+1 points of each set are linearly dependent
|
|
1553
|
+
find the unique element of PGL that translates the source points to the target points.
|
|
1554
|
+
|
|
1555
|
+
.. warning::
|
|
1556
|
+
over non-exact rings such as the ComplexField, the returned matrix could
|
|
1557
|
+
be very far from correct.
|
|
1558
|
+
|
|
1559
|
+
INPUT:
|
|
1560
|
+
|
|
1561
|
+
- ``points_source`` -- points in source projective space
|
|
1562
|
+
|
|
1563
|
+
- ``points_target`` -- points in target projective space
|
|
1564
|
+
|
|
1565
|
+
- ``normalize`` -- boolean (default: ``True``); if the returned matrix
|
|
1566
|
+
should be normalized. Only works over exact rings. If the base ring
|
|
1567
|
+
is a field, the matrix is normalized so that the last nonzero entry
|
|
1568
|
+
in the last row is 1. If the base ring is a ring, then the matrix is
|
|
1569
|
+
normalized so that the entries are elements of the base ring.
|
|
1570
|
+
|
|
1571
|
+
OUTPUT: transformation matrix - element of PGL
|
|
1572
|
+
|
|
1573
|
+
ALGORITHM:
|
|
1574
|
+
|
|
1575
|
+
See [Hutz2007]_, Proposition 2.16 for details.
|
|
1576
|
+
|
|
1577
|
+
EXAMPLES::
|
|
1578
|
+
|
|
1579
|
+
sage: P1.<a,b,c> = ProjectiveSpace(QQ, 2)
|
|
1580
|
+
sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])]
|
|
1581
|
+
sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])]
|
|
1582
|
+
sage: m = P1.point_transformation_matrix(points_source, points_target); m # needs sage.modules
|
|
1583
|
+
[ -13/59 -128/59 -25/59]
|
|
1584
|
+
[538/177 8/59 26/177]
|
|
1585
|
+
[ -45/59 -196/59 1]
|
|
1586
|
+
sage: [m*points_source[i] == points_target[i] for i in range(4)] # needs sage.modules
|
|
1587
|
+
[True, True, True, True]
|
|
1588
|
+
|
|
1589
|
+
::
|
|
1590
|
+
|
|
1591
|
+
sage: P.<a,b> = ProjectiveSpace(GF(13), 1)
|
|
1592
|
+
sage: points_source = [P([-6, 7]), P([1, 4]), P([3, 2])]
|
|
1593
|
+
sage: points_target = [P([-1, 2]), P([0, 2]), P([-1, 6])]
|
|
1594
|
+
sage: P.point_transformation_matrix(points_source, points_target) # needs sage.modules
|
|
1595
|
+
[10 4]
|
|
1596
|
+
[10 1]
|
|
1597
|
+
|
|
1598
|
+
::
|
|
1599
|
+
|
|
1600
|
+
sage: P.<a,b> = ProjectiveSpace(QQ, 1)
|
|
1601
|
+
sage: points_source = [P([-6, -4]), P([1, 4]), P([3, 2])]
|
|
1602
|
+
sage: points_target = [P([-1, 2]), P([0, 2]), P([-7, -3])]
|
|
1603
|
+
sage: P.point_transformation_matrix(points_source, points_target) # needs sage.modules
|
|
1604
|
+
Traceback (most recent call last):
|
|
1605
|
+
...
|
|
1606
|
+
ValueError: source points not independent
|
|
1607
|
+
|
|
1608
|
+
::
|
|
1609
|
+
|
|
1610
|
+
sage: R.<t> = FunctionField(QQ)
|
|
1611
|
+
sage: P.<a,b> = ProjectiveSpace(R, 1)
|
|
1612
|
+
sage: points_source = [P([-6*t, 7]), P([1, 4]), P([3, 2])]
|
|
1613
|
+
sage: points_target = [P([-1, 2*t]), P([0, 2]), P([-1, 6])]
|
|
1614
|
+
sage: P.point_transformation_matrix(points_source, points_target) # needs sage.modules
|
|
1615
|
+
[ (1/3*t + 7/12)/(t^2 - 53/24*t) (-1/12*t - 7/48)/(t^2 - 53/24*t)]
|
|
1616
|
+
[(-2/3*t^2 - 7/36*t - 35/12)/(t^2 - 53/24*t) 1]
|
|
1617
|
+
|
|
1618
|
+
::
|
|
1619
|
+
|
|
1620
|
+
sage: P1.<a,b,c> = ProjectiveSpace(RR, 2)
|
|
1621
|
+
sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])]
|
|
1622
|
+
sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])]
|
|
1623
|
+
sage: P1.point_transformation_matrix(points_source, # abs tol 1e-13 # needs scipy sage.modules
|
|
1624
|
+
....: points_target)
|
|
1625
|
+
[-0.0619047619047597 -0.609523809523810 -0.119047619047621]
|
|
1626
|
+
[ 0.853968253968253 0.0380952380952380 0.0412698412698421]
|
|
1627
|
+
[ -0.214285714285712 -0.933333333333333 0.280952380952379]
|
|
1628
|
+
|
|
1629
|
+
::
|
|
1630
|
+
|
|
1631
|
+
sage: P1.<a,b,c> = ProjectiveSpace(ZZ, 2)
|
|
1632
|
+
sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])]
|
|
1633
|
+
sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])]
|
|
1634
|
+
sage: P1.point_transformation_matrix(points_source, points_target) # needs sage.modules
|
|
1635
|
+
[ -39 -384 -75]
|
|
1636
|
+
[ 538 24 26]
|
|
1637
|
+
[-135 -588 177]
|
|
1638
|
+
|
|
1639
|
+
::
|
|
1640
|
+
|
|
1641
|
+
sage: P1.<a,b,c> = ProjectiveSpace(ZZ, 2)
|
|
1642
|
+
sage: points_source = [P1([1, 4, 1]), P1([1, 2, 2]), P1([3, 5, 1]), P1([1, -1, 1])]
|
|
1643
|
+
sage: points_target = [P1([5, -2, 7]), P1([3, -2, 3]), P1([6, -5, 9]), P1([3, 6, 7])]
|
|
1644
|
+
sage: P1.point_transformation_matrix(points_source, points_target, # needs sage.modules
|
|
1645
|
+
....: normalize=False)
|
|
1646
|
+
[-13/30 -64/15 -5/6]
|
|
1647
|
+
[269/45 4/15 13/45]
|
|
1648
|
+
[ -3/2 -98/15 59/30]
|
|
1649
|
+
|
|
1650
|
+
::
|
|
1651
|
+
|
|
1652
|
+
sage: R.<t> = ZZ[]
|
|
1653
|
+
sage: P.<a,b> = ProjectiveSpace(R, 1)
|
|
1654
|
+
sage: points_source = [P([-6*t, 7]), P([1, 4]), P([3, 2])]
|
|
1655
|
+
sage: points_target = [P([-1, 2*t]), P([0, 2]), P([-1, 6])]
|
|
1656
|
+
sage: P.point_transformation_matrix(points_source, points_target) # needs sage.modules
|
|
1657
|
+
[ -48*t - 84 12*t + 21]
|
|
1658
|
+
[96*t^2 + 28*t + 420 -144*t^2 + 318*t]
|
|
1659
|
+
|
|
1660
|
+
TESTS::
|
|
1661
|
+
|
|
1662
|
+
sage: P.<a,b> = ProjectiveSpace(QQ, 1)
|
|
1663
|
+
sage: points_source = [P([-6, -1]), P([1, 4]), P([3, 2])]
|
|
1664
|
+
sage: points_target = [P([-1, 2]), P([0, 2]), P([-2, 4])]
|
|
1665
|
+
sage: P.point_transformation_matrix(points_source, points_target) # needs sage.modules
|
|
1666
|
+
Traceback (most recent call last):
|
|
1667
|
+
...
|
|
1668
|
+
ValueError: target points not independent
|
|
1669
|
+
|
|
1670
|
+
::
|
|
1671
|
+
|
|
1672
|
+
sage: P.<a,b,c> = ProjectiveSpace(QQ, 2)
|
|
1673
|
+
sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1])]
|
|
1674
|
+
sage: points_target = [P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1])]
|
|
1675
|
+
sage: P.point_transformation_matrix(points_source, points_target)
|
|
1676
|
+
Traceback (most recent call last):
|
|
1677
|
+
...
|
|
1678
|
+
ValueError: incorrect number of points in source, need 4 points
|
|
1679
|
+
|
|
1680
|
+
::
|
|
1681
|
+
|
|
1682
|
+
sage: P.<a,b,c> = ProjectiveSpace(QQ, 2)
|
|
1683
|
+
sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P([1, -1, 1])]
|
|
1684
|
+
sage: points_target = [P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1]), P([7, 8, -9])]
|
|
1685
|
+
sage: P.point_transformation_matrix(points_source, points_target)
|
|
1686
|
+
Traceback (most recent call last):
|
|
1687
|
+
...
|
|
1688
|
+
ValueError: incorrect number of points in target, need 4 points
|
|
1689
|
+
|
|
1690
|
+
::
|
|
1691
|
+
|
|
1692
|
+
sage: P.<a,b,c> = ProjectiveSpace(QQ, 2)
|
|
1693
|
+
sage: P1.<x,y,z> = ProjectiveSpace(QQ, 2)
|
|
1694
|
+
sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P1([1, -1, 1])]
|
|
1695
|
+
sage: points_target=[P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P([6, -1, 1])]
|
|
1696
|
+
sage: P.point_transformation_matrix(points_source, points_target)
|
|
1697
|
+
Traceback (most recent call last):
|
|
1698
|
+
...
|
|
1699
|
+
ValueError: source points not in self
|
|
1700
|
+
|
|
1701
|
+
::
|
|
1702
|
+
|
|
1703
|
+
sage: P.<a,b,c> = ProjectiveSpace(QQ, 2)
|
|
1704
|
+
sage: P1.<x,y,z> = ProjectiveSpace(QQ, 2)
|
|
1705
|
+
sage: points_source = [P([1, 4, 1]), P([2, -7, 9]), P([3, 5, 1]), P([1, -1, 1])]
|
|
1706
|
+
sage: points_target = [P([5, -2, 7]), P([3, -2, 3]), P([6, -5, 9]), P1([6, -1, 1])]
|
|
1707
|
+
sage: P.point_transformation_matrix(points_source, points_target)
|
|
1708
|
+
Traceback (most recent call last):
|
|
1709
|
+
...
|
|
1710
|
+
ValueError: target points not in self
|
|
1711
|
+
|
|
1712
|
+
::
|
|
1713
|
+
|
|
1714
|
+
sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2)
|
|
1715
|
+
sage: points_source = [P(1, 0, 0), P(0, 1, 0), P(0, 0, 1), P(1, -1, -1)]
|
|
1716
|
+
sage: points_target = [P(0, 1, 0), P(-2, 0, 1), P(0, 0, 1), P(1, -1, -1)]
|
|
1717
|
+
sage: P.point_transformation_matrix(points_source, points_target, # needs sage.modules
|
|
1718
|
+
....: normalize=True)
|
|
1719
|
+
[ 0 -2 0]
|
|
1720
|
+
[-2 0 0]
|
|
1721
|
+
[ 0 1 1]
|
|
1722
|
+
"""
|
|
1723
|
+
r = self.base_ring()
|
|
1724
|
+
n = self.dimension_relative()
|
|
1725
|
+
# makes sure there aren't to few or two many points
|
|
1726
|
+
if len(points_source) != n + 2:
|
|
1727
|
+
raise ValueError("incorrect number of points in source, need %d points" % (n + 2))
|
|
1728
|
+
if len(points_target) != n + 2:
|
|
1729
|
+
raise ValueError("incorrect number of points in target, need %d points" % (n + 2))
|
|
1730
|
+
if any(x.codomain() != self for x in points_source):
|
|
1731
|
+
raise ValueError("source points not in self")
|
|
1732
|
+
if any(x.codomain() != self for x in points_target):
|
|
1733
|
+
raise ValueError("target points not in self")
|
|
1734
|
+
Ms = matrix(r, [list(s) for s in points_source])
|
|
1735
|
+
if any(m == 0 for m in Ms.minors(n + 1)):
|
|
1736
|
+
raise ValueError("source points not independent")
|
|
1737
|
+
Mt = matrix(r, [list(t) for t in points_target])
|
|
1738
|
+
if any(l == 0 for l in Mt.minors(n + 1)):
|
|
1739
|
+
raise ValueError("target points not independent")
|
|
1740
|
+
|
|
1741
|
+
# get_matrix calculates the transform from the list of points
|
|
1742
|
+
# [ [1 : 0 : 0 : ... ]
|
|
1743
|
+
# [0 : 1 : 0 : ... ]
|
|
1744
|
+
# [0 : 0 : 1 : ... ]
|
|
1745
|
+
# ...
|
|
1746
|
+
# [1 : 1 : 1 : ... ] ]
|
|
1747
|
+
# to the list of points S
|
|
1748
|
+
def get_matrix(S, N):
|
|
1749
|
+
a = matrix(N+1, N+1, [S[j][i] for i in range(N+1) for j in range(N+1)])
|
|
1750
|
+
b = matrix(N+1, 1, list(S[N+1]))
|
|
1751
|
+
X = a.solve_right(b)
|
|
1752
|
+
m = matrix(N+1, N+1, [X[i,0]*S[i][j] for i in range(N+1) for j in range(N+1)])
|
|
1753
|
+
m = m.transpose()
|
|
1754
|
+
return m
|
|
1755
|
+
|
|
1756
|
+
m_source = get_matrix(points_source, n)
|
|
1757
|
+
m_target = get_matrix(points_target, n)
|
|
1758
|
+
return_mat = m_target*m_source.inverse()
|
|
1759
|
+
if normalize:
|
|
1760
|
+
R = self.base_ring()
|
|
1761
|
+
if R.is_exact():
|
|
1762
|
+
if R.is_field():
|
|
1763
|
+
last_row = list(return_mat.rows()[-1])[:]
|
|
1764
|
+
last_ele = last_row.pop()
|
|
1765
|
+
while last_ele == 0:
|
|
1766
|
+
last_ele = last_row.pop()
|
|
1767
|
+
return_mat *= ZZ(1)/last_ele
|
|
1768
|
+
else:
|
|
1769
|
+
lcm = return_mat[0][0].denominator()
|
|
1770
|
+
for row in return_mat.rows():
|
|
1771
|
+
for ele in row:
|
|
1772
|
+
lcm = lcm.lcm(ele.denominator())
|
|
1773
|
+
return_mat *= lcm
|
|
1774
|
+
return return_mat
|
|
1775
|
+
|
|
1776
|
+
def hyperplane_transformation_matrix(self, plane_1, plane_2):
|
|
1777
|
+
r"""
|
|
1778
|
+
Return a PGL element sending ``plane_1`` to ``plane_2``.
|
|
1779
|
+
|
|
1780
|
+
``plane_1`` and ``plane_2`` must be hyperplanes (subschemes of
|
|
1781
|
+
codimension 1, each defined by a single linear homogeneous equation).
|
|
1782
|
+
|
|
1783
|
+
INPUT:
|
|
1784
|
+
|
|
1785
|
+
- ``plane_1``, ``plane_2`` -- hyperplanes of this projective space
|
|
1786
|
+
|
|
1787
|
+
OUTPUT: an element of PGL
|
|
1788
|
+
|
|
1789
|
+
EXAMPLES::
|
|
1790
|
+
|
|
1791
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1792
|
+
sage: plane1 = P.subscheme(x)
|
|
1793
|
+
sage: plane2 = P.subscheme(y)
|
|
1794
|
+
sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m # needs sage.modules
|
|
1795
|
+
[0 1]
|
|
1796
|
+
[1 0]
|
|
1797
|
+
sage: plane2(m*P((0,1))) # needs sage.modules
|
|
1798
|
+
(1 : 0)
|
|
1799
|
+
|
|
1800
|
+
::
|
|
1801
|
+
|
|
1802
|
+
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
|
|
1803
|
+
sage: plane1 = P.subscheme(x + 2*y + z)
|
|
1804
|
+
sage: plane2 = P.subscheme(2*x + y + z)
|
|
1805
|
+
sage: P.hyperplane_transformation_matrix(plane1, plane2) # needs sage.modules
|
|
1806
|
+
[1 0 0 0]
|
|
1807
|
+
[0 4 0 0]
|
|
1808
|
+
[0 0 2 0]
|
|
1809
|
+
[0 0 0 1]
|
|
1810
|
+
|
|
1811
|
+
::
|
|
1812
|
+
|
|
1813
|
+
sage: P.<x,y> = ProjectiveSpace(ZZ, 1)
|
|
1814
|
+
sage: plane1 = P.subscheme(x + y)
|
|
1815
|
+
sage: plane2 = P.subscheme(y)
|
|
1816
|
+
sage: P.hyperplane_transformation_matrix(plane1, plane2) # needs sage.modules
|
|
1817
|
+
[-1 0]
|
|
1818
|
+
[ 1 1]
|
|
1819
|
+
|
|
1820
|
+
::
|
|
1821
|
+
|
|
1822
|
+
sage: # needs sage.rings.number_field
|
|
1823
|
+
sage: K.<v> = CyclotomicField(3)
|
|
1824
|
+
sage: P.<x,y,z> = ProjectiveSpace(K, 2)
|
|
1825
|
+
sage: plane1 = P.subscheme(x - 2*v*y + z)
|
|
1826
|
+
sage: plane2 = P.subscheme(x + v*y + v*z)
|
|
1827
|
+
sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m # needs sage.modules
|
|
1828
|
+
[ v 0 0]
|
|
1829
|
+
[ 0 -2*v 0]
|
|
1830
|
+
[ 0 0 1]
|
|
1831
|
+
|
|
1832
|
+
::
|
|
1833
|
+
|
|
1834
|
+
sage: # needs sage.rings.number_field
|
|
1835
|
+
sage: R.<x> = QQ[]
|
|
1836
|
+
sage: K.<k> = NumberField(x^2 + 1)
|
|
1837
|
+
sage: P.<x,y,z,w> = ProjectiveSpace(K, 3)
|
|
1838
|
+
sage: plane1 = P.subscheme(k*x + 2*k*y + z)
|
|
1839
|
+
sage: plane2 = P.subscheme(7*k*x + y + 9*z)
|
|
1840
|
+
sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m # needs sage.modules
|
|
1841
|
+
[ 1 0 0 0]
|
|
1842
|
+
[ 0 14*k 0 0]
|
|
1843
|
+
[ 0 0 7/9 0]
|
|
1844
|
+
[ 0 0 0 1]
|
|
1845
|
+
|
|
1846
|
+
::
|
|
1847
|
+
|
|
1848
|
+
sage: # needs sage.rings.number_field
|
|
1849
|
+
sage: K.<v> = CyclotomicField(3)
|
|
1850
|
+
sage: R.<t> = K[]
|
|
1851
|
+
sage: F.<w> = K.extension(t^5 + 2)
|
|
1852
|
+
sage: G.<u> = F.absolute_field()
|
|
1853
|
+
sage: P.<x,y,z> = ProjectiveSpace(G, 2)
|
|
1854
|
+
sage: plane1 = P.subscheme(x - 2*u*y + z)
|
|
1855
|
+
sage: plane2 = P.subscheme(x + u*y + z)
|
|
1856
|
+
sage: m = P.hyperplane_transformation_matrix(plane1, plane2) # needs sage.modules
|
|
1857
|
+
sage: plane2(m*P((2*u, 1, 0))) # needs sage.modules
|
|
1858
|
+
(-u : 1 : 0)
|
|
1859
|
+
|
|
1860
|
+
::
|
|
1861
|
+
|
|
1862
|
+
sage: P.<x,y,z> = ProjectiveSpace(FiniteField(2), 2)
|
|
1863
|
+
sage: plane1 = P.subscheme(x + y + z)
|
|
1864
|
+
sage: plane2 = P.subscheme(z)
|
|
1865
|
+
sage: P.hyperplane_transformation_matrix(plane1, plane2) # needs sage.modules
|
|
1866
|
+
[1 0 0]
|
|
1867
|
+
[1 1 0]
|
|
1868
|
+
[1 1 1]
|
|
1869
|
+
|
|
1870
|
+
::
|
|
1871
|
+
|
|
1872
|
+
sage: R.<t> = QQ[]
|
|
1873
|
+
sage: P.<x,y,z> = ProjectiveSpace(R, 2)
|
|
1874
|
+
sage: plane1 = P.subscheme(x + 9*t*y + z)
|
|
1875
|
+
sage: plane2 = P.subscheme(x + z)
|
|
1876
|
+
sage: P.hyperplane_transformation_matrix(plane1, plane2) # needs sage.modules
|
|
1877
|
+
[ 1 9*t 0]
|
|
1878
|
+
[ 1 0 0]
|
|
1879
|
+
[ 0 0 1]
|
|
1880
|
+
|
|
1881
|
+
TESTS::
|
|
1882
|
+
|
|
1883
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
1884
|
+
sage: plane1 = P.subscheme(x^2)
|
|
1885
|
+
sage: plane2 = P.subscheme(y)
|
|
1886
|
+
sage: P.hyperplane_transformation_matrix(plane1, plane2)
|
|
1887
|
+
Traceback (most recent call last):
|
|
1888
|
+
...
|
|
1889
|
+
ValueError: plane_1 must be defined by a single degree 1 equation
|
|
1890
|
+
"""
|
|
1891
|
+
if not isinstance(plane_1, AlgebraicScheme_subscheme_projective):
|
|
1892
|
+
raise TypeError('plane_1 must be a subscheme')
|
|
1893
|
+
if not isinstance(plane_2, AlgebraicScheme_subscheme_projective):
|
|
1894
|
+
raise TypeError('plane_2 must be a subscheme')
|
|
1895
|
+
if plane_1.ambient_space() != self:
|
|
1896
|
+
raise ValueError('plane_1 must be a subscheme of this projective space')
|
|
1897
|
+
if plane_2.ambient_space() != self:
|
|
1898
|
+
raise ValueError('plane_2 must be a subscheme of this projective space')
|
|
1899
|
+
if len(plane_1.defining_polynomials()) > 1 or plane_1.defining_polynomials()[0].degree() != 1:
|
|
1900
|
+
raise ValueError('plane_1 must be defined by a single degree 1 equation')
|
|
1901
|
+
if len(plane_2.defining_polynomials()) > 1 or plane_2.defining_polynomials()[0].degree() != 1:
|
|
1902
|
+
raise ValueError('plane_2 must be defined by a single degree 1 equation')
|
|
1903
|
+
N = self.dimension_relative()
|
|
1904
|
+
CR = self.coordinate_ring()
|
|
1905
|
+
points = []
|
|
1906
|
+
from sage.rings.rational_field import QQ
|
|
1907
|
+
P_QQ = ProjectiveSpace(QQ, N)
|
|
1908
|
+
# to determine the PGL transform, we need N+2 points source points and N+2 target points,
|
|
1909
|
+
# of which no N+1 are co-planar. Additionally, in order to map plane_1 to plane_2, N source
|
|
1910
|
+
# points must lie on plane_1, and N target points must lie on plane_2
|
|
1911
|
+
for plane in [plane_1, plane_2]:
|
|
1912
|
+
source_points = []
|
|
1913
|
+
nonzero_places = []
|
|
1914
|
+
height_1 = P_QQ.points_of_bounded_height(bound=1)
|
|
1915
|
+
|
|
1916
|
+
# first we find N planar points
|
|
1917
|
+
# we have a single linear equation with N+1 variables
|
|
1918
|
+
# first we add a point for each variable with coefficient 0
|
|
1919
|
+
# giving us J points added in this loop
|
|
1920
|
+
for i in range(N+1):
|
|
1921
|
+
if plane.defining_polynomials()[0].coefficient(CR.gens()[i]) == 0:
|
|
1922
|
+
L = [0]*(N+1)
|
|
1923
|
+
L[i] = 1
|
|
1924
|
+
source_points.append(self(L))
|
|
1925
|
+
else:
|
|
1926
|
+
nonzero_places.append(i)
|
|
1927
|
+
# next we add a point for each variable with nonzero coefficient, except the last
|
|
1928
|
+
# giving us a total of (N+1) - J - 1 = N - J points added in this loop
|
|
1929
|
+
# resulting in exactly J + (N-J) = N points on the plane
|
|
1930
|
+
for i in range(len(nonzero_places)-1):
|
|
1931
|
+
nonzero_place1 = nonzero_places[i]
|
|
1932
|
+
nonzero_place2 = nonzero_places[i+1]
|
|
1933
|
+
L = [0]*(N+1)
|
|
1934
|
+
L[nonzero_place1] = -1*plane.defining_polynomials()[0].coefficient(CR.gens()[nonzero_place2])
|
|
1935
|
+
L[nonzero_place2] = plane.defining_polynomials()[0].coefficient(CR.gens()[nonzero_place1])
|
|
1936
|
+
source_points.append(self(L))
|
|
1937
|
+
|
|
1938
|
+
# next we add independent points until we have N+2 points total
|
|
1939
|
+
for point in height_1:
|
|
1940
|
+
if len(source_points) == N:
|
|
1941
|
+
try:
|
|
1942
|
+
plane(point)
|
|
1943
|
+
except (ValueError, TypeError):
|
|
1944
|
+
source_points.append(self(point))
|
|
1945
|
+
base_list = [list(s) for s in source_points]
|
|
1946
|
+
elif len(source_points) == N + 1:
|
|
1947
|
+
Ms = matrix(base_list + [point.change_ring(self.base_ring())])
|
|
1948
|
+
if not any(m == 0 for m in Ms.minors(N + 1)):
|
|
1949
|
+
source_points.append(self(point))
|
|
1950
|
+
break
|
|
1951
|
+
if len(source_points) != N+2:
|
|
1952
|
+
raise NotImplementedError('Failed to automatically find sufficient independent points.' +
|
|
1953
|
+
' Please find the necessary independent points manually, then use point transformation matrix.')
|
|
1954
|
+
points.append(source_points)
|
|
1955
|
+
return self.point_transformation_matrix(points[0], points[1])
|
|
1956
|
+
|
|
1957
|
+
def is_linearly_independent(self, points, n=None):
|
|
1958
|
+
r"""
|
|
1959
|
+
Return whether the set of points is linearly independent.
|
|
1960
|
+
|
|
1961
|
+
Alternatively, specify ``n`` to check if every subset of
|
|
1962
|
+
size ``n`` is linearly independent.
|
|
1963
|
+
|
|
1964
|
+
INPUT:
|
|
1965
|
+
|
|
1966
|
+
- ``points`` -- list of points in this projective space
|
|
1967
|
+
|
|
1968
|
+
- ``n`` -- (optional) positive integer less than or equal to the length
|
|
1969
|
+
of ``points``. Specifies the size of the subsets to check for
|
|
1970
|
+
linear independence.
|
|
1971
|
+
|
|
1972
|
+
OUTPUT: ``True`` if ``points`` is linearly independent, ``False`` otherwise
|
|
1973
|
+
|
|
1974
|
+
EXAMPLES::
|
|
1975
|
+
|
|
1976
|
+
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
|
|
1977
|
+
sage: points = [P((1, 0, 1)), P((1, 2, 1)), P((1, 3, 4))]
|
|
1978
|
+
sage: P.is_linearly_independent(points) # needs sage.modules
|
|
1979
|
+
True
|
|
1980
|
+
|
|
1981
|
+
::
|
|
1982
|
+
|
|
1983
|
+
sage: P.<x,y,z> = ProjectiveSpace(GF(5), 2)
|
|
1984
|
+
sage: points = [P((1, 0, 1)), P((1, 2, 1)), P((1, 3, 4)), P((0, 0, 1))]
|
|
1985
|
+
sage: P.is_linearly_independent(points, 2) # needs sage.modules
|
|
1986
|
+
True
|
|
1987
|
+
|
|
1988
|
+
::
|
|
1989
|
+
|
|
1990
|
+
sage: R.<c> = QQ[]
|
|
1991
|
+
sage: P.<x,y,z> = ProjectiveSpace(R, 2)
|
|
1992
|
+
sage: points = [P((c, 0, 1)), P((0, c, 1)), P((1, 0, 4)), P((0, 0, 1))]
|
|
1993
|
+
sage: P.is_linearly_independent(points, 3) # needs sage.modules
|
|
1994
|
+
False
|
|
1995
|
+
|
|
1996
|
+
::
|
|
1997
|
+
|
|
1998
|
+
sage: R.<c> = QQ[]
|
|
1999
|
+
sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2)
|
|
2000
|
+
sage: points = [P((c, 0, 1)), P((0, c, 1)), P((1, 3, 4)), P((0, 0, 1))]
|
|
2001
|
+
sage: P.is_linearly_independent(points, 3) # needs sage.modules
|
|
2002
|
+
True
|
|
2003
|
+
|
|
2004
|
+
::
|
|
2005
|
+
|
|
2006
|
+
sage: # needs sage.rings.number_field
|
|
2007
|
+
sage: K.<k> = CyclotomicField(3)
|
|
2008
|
+
sage: P.<x,y,z> = ProjectiveSpace(K, 2)
|
|
2009
|
+
sage: points = [P((k, k^2, 1)), P((0, k, 1)), P((1, 0, 4)), P((0, 0, 1))]
|
|
2010
|
+
sage: P.is_linearly_independent(points, 3) # needs sage.modules
|
|
2011
|
+
True
|
|
2012
|
+
|
|
2013
|
+
::
|
|
2014
|
+
|
|
2015
|
+
sage: P.<x,y> = ProjectiveSpace(QQ, 1)
|
|
2016
|
+
sage: points = [P((1, 0)), P((1, 1))]
|
|
2017
|
+
sage: P.is_linearly_independent(points) # needs sage.modules
|
|
2018
|
+
True
|
|
2019
|
+
|
|
2020
|
+
TESTS::
|
|
2021
|
+
|
|
2022
|
+
sage: points = [P(1, 0), P(1, 1), P(2, 1)]
|
|
2023
|
+
sage: P.is_linearly_independent(points, 5)
|
|
2024
|
+
Traceback (most recent call last):
|
|
2025
|
+
...
|
|
2026
|
+
ValueError: n must be a nonnegative integer not greater than the length of points
|
|
2027
|
+
"""
|
|
2028
|
+
if not isinstance(points, list):
|
|
2029
|
+
raise TypeError("points must be a list")
|
|
2030
|
+
if any(not isinstance(point, SchemeMorphism_point_projective_ring) for point in points):
|
|
2031
|
+
raise TypeError("points must be a list of projective points")
|
|
2032
|
+
if any(x.codomain() != self for x in points):
|
|
2033
|
+
raise ValueError("points not in this projective space")
|
|
2034
|
+
if n is None:
|
|
2035
|
+
M = matrix([list(t) for t in points])
|
|
2036
|
+
return M.rank() == len(points)
|
|
2037
|
+
n = Integer(n)
|
|
2038
|
+
if n < 1 or n > len(points):
|
|
2039
|
+
raise ValueError('n must be a nonnegative integer not greater than the length of points')
|
|
2040
|
+
all_subsets = Subsets(range(len(points)), n)
|
|
2041
|
+
linearly_independent = True
|
|
2042
|
+
for subset in all_subsets:
|
|
2043
|
+
point_list = []
|
|
2044
|
+
for index in subset:
|
|
2045
|
+
point_list.append(list(points[index]))
|
|
2046
|
+
M = matrix(point_list)
|
|
2047
|
+
if M.rank() != n:
|
|
2048
|
+
linearly_independent = False
|
|
2049
|
+
break
|
|
2050
|
+
return linearly_independent
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
class ProjectiveSpace_field(ProjectiveSpace_ring):
|
|
2054
|
+
def _point_homset(self, *args, **kwds):
|
|
2055
|
+
"""
|
|
2056
|
+
Construct a point Hom-set.
|
|
2057
|
+
|
|
2058
|
+
For internal use only. See :mod:`morphism` for details.
|
|
2059
|
+
|
|
2060
|
+
TESTS::
|
|
2061
|
+
|
|
2062
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
2063
|
+
sage: P2._point_homset(Spec(GF(3)), P2)
|
|
2064
|
+
Set of rational points of Projective Space of dimension 2 over Finite Field of size 3
|
|
2065
|
+
"""
|
|
2066
|
+
return SchemeHomset_points_projective_field(*args, **kwds)
|
|
2067
|
+
|
|
2068
|
+
def _point(self, *args, **kwds):
|
|
2069
|
+
"""
|
|
2070
|
+
Construct a point.
|
|
2071
|
+
|
|
2072
|
+
For internal use only. See :mod:`morphism` for details.
|
|
2073
|
+
|
|
2074
|
+
TESTS::
|
|
2075
|
+
|
|
2076
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
2077
|
+
sage: point_homset = P2._point_homset(Spec(GF(3)), P2)
|
|
2078
|
+
sage: P2._point(point_homset, [1,2,3])
|
|
2079
|
+
(2 : 1 : 0)
|
|
2080
|
+
"""
|
|
2081
|
+
return SchemeMorphism_point_projective_field(*args, **kwds)
|
|
2082
|
+
|
|
2083
|
+
def _morphism(self, *args, **kwds):
|
|
2084
|
+
"""
|
|
2085
|
+
Construct a morphism.
|
|
2086
|
+
|
|
2087
|
+
For internal use only. See :mod:`morphism` for details.
|
|
2088
|
+
|
|
2089
|
+
TESTS::
|
|
2090
|
+
|
|
2091
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
2092
|
+
sage: P2._morphism(P2.Hom(P2), [x,y,z])
|
|
2093
|
+
Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3
|
|
2094
|
+
Defn: Defined on coordinates by sending (x : y : z) to
|
|
2095
|
+
(x : y : z)
|
|
2096
|
+
"""
|
|
2097
|
+
return SchemeMorphism_polynomial_projective_space_field(*args, **kwds)
|
|
2098
|
+
|
|
2099
|
+
def subscheme_from_Chow_form(self, Ch, dim):
|
|
2100
|
+
r"""
|
|
2101
|
+
Return the subscheme defined by the Chow equations associated to the Chow form ``Ch``.
|
|
2102
|
+
|
|
2103
|
+
These equations define the subscheme set-theoretically, but only for smooth
|
|
2104
|
+
subschemes and hypersurfaces do they define the subscheme as a scheme.
|
|
2105
|
+
|
|
2106
|
+
ALGORITHM:
|
|
2107
|
+
|
|
2108
|
+
The Chow form is a polynomial in the Plucker coordinates. The Plucker coordinates
|
|
2109
|
+
are the bracket polynomials. We first re-write the Chow form in terms of the dual
|
|
2110
|
+
Plucker coordinates. Then we expand `Ch(span(p,L)` for a generic point `p` and a
|
|
2111
|
+
generic linear subspace `L`. The coefficients as polynomials in the coordinates
|
|
2112
|
+
of `p` are the equations defining the subscheme. [DalbecSturmfels].
|
|
2113
|
+
|
|
2114
|
+
INPUT:
|
|
2115
|
+
|
|
2116
|
+
- ``Ch`` -- a homogeneous polynomial
|
|
2117
|
+
|
|
2118
|
+
- ``dim`` -- the dimension of the associated scheme
|
|
2119
|
+
|
|
2120
|
+
OUTPUT: a projective subscheme
|
|
2121
|
+
|
|
2122
|
+
EXAMPLES::
|
|
2123
|
+
|
|
2124
|
+
sage: P = ProjectiveSpace(QQ, 4, 'z')
|
|
2125
|
+
sage: R.<x0,x1,x2,x3,x4> = PolynomialRing(QQ)
|
|
2126
|
+
sage: H = x1^2 + x2^2 + 5*x3*x4
|
|
2127
|
+
sage: P.subscheme_from_Chow_form(H, 3) # needs sage.modules
|
|
2128
|
+
Closed subscheme of Projective Space of dimension 4 over Rational Field defined by:
|
|
2129
|
+
-5*z0*z1 + z2^2 + z3^2
|
|
2130
|
+
|
|
2131
|
+
::
|
|
2132
|
+
|
|
2133
|
+
sage: P = ProjectiveSpace(QQ, 3, 'z')
|
|
2134
|
+
sage: R.<x0,x1,x2,x3,x4,x5> = PolynomialRing(QQ)
|
|
2135
|
+
sage: H = x1 - x2 - x3 + x5 + 2*x0
|
|
2136
|
+
sage: P.subscheme_from_Chow_form(H, 1) # needs sage.modules
|
|
2137
|
+
Closed subscheme of Projective Space of dimension 3 over Rational Field
|
|
2138
|
+
defined by:
|
|
2139
|
+
-z1 + z3,
|
|
2140
|
+
z0 + z2 + z3,
|
|
2141
|
+
-z1 - 2*z3,
|
|
2142
|
+
-z0 - z1 + 2*z2
|
|
2143
|
+
|
|
2144
|
+
::
|
|
2145
|
+
|
|
2146
|
+
sage: # needs sage.libs.singular
|
|
2147
|
+
sage: P.<x0,x1,x2,x3> = ProjectiveSpace(GF(7), 3)
|
|
2148
|
+
sage: X = P.subscheme([x3^2 + x1*x2, x2 - x0])
|
|
2149
|
+
sage: Ch = X.Chow_form(); Ch
|
|
2150
|
+
t0^2 - 2*t0*t3 + t3^2 - t2*t4 - t4*t5
|
|
2151
|
+
sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y
|
|
2152
|
+
Closed subscheme of Projective Space of dimension 3
|
|
2153
|
+
over Finite Field of size 7 defined by:
|
|
2154
|
+
x1*x2 + x3^2,
|
|
2155
|
+
-x0*x2 + x2^2,
|
|
2156
|
+
-x0*x1 - x1*x2 - 2*x3^2,
|
|
2157
|
+
x0^2 - x0*x2,
|
|
2158
|
+
x0*x1 + x3^2,
|
|
2159
|
+
-2*x0*x3 + 2*x2*x3,
|
|
2160
|
+
2*x0*x3 - 2*x2*x3,
|
|
2161
|
+
x0^2 - 2*x0*x2 + x2^2
|
|
2162
|
+
sage: I = Y.defining_ideal()
|
|
2163
|
+
sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0]
|
|
2164
|
+
Ideal (x0 - x2, x1*x2 + x3^2) of Multivariate Polynomial Ring
|
|
2165
|
+
in x0, x1, x2, x3 over Finite Field of size 7
|
|
2166
|
+
"""
|
|
2167
|
+
if not Ch.is_homogeneous():
|
|
2168
|
+
raise ValueError("Chow form must be a homogeneous polynomial")
|
|
2169
|
+
n = self.dimension_relative()
|
|
2170
|
+
R = Ch.parent()
|
|
2171
|
+
if binomial(n + 1, n - dim) != R.ngens():
|
|
2172
|
+
raise ValueError("for given dimension, there should be %d variables in the Chow form" % binomial(n + 1, n - dim))
|
|
2173
|
+
# create the brackets associated to variables
|
|
2174
|
+
L1 = []
|
|
2175
|
+
for t in UnorderedTuples(list(range(n + 1)), dim + 1):
|
|
2176
|
+
if all(t[i] < t[i + 1] for i in range(dim)):
|
|
2177
|
+
L1.append(list(t))
|
|
2178
|
+
# create the dual brackets
|
|
2179
|
+
L2 = []
|
|
2180
|
+
signs = []
|
|
2181
|
+
for l in L1:
|
|
2182
|
+
s = []
|
|
2183
|
+
for v in range(n + 1):
|
|
2184
|
+
if v not in l:
|
|
2185
|
+
s.append(v)
|
|
2186
|
+
t1 = [b + 1 for b in l]
|
|
2187
|
+
t2 = [b + 1 for b in s]
|
|
2188
|
+
perm = Permutation(t1 + t2)
|
|
2189
|
+
signs.append(perm.sign())
|
|
2190
|
+
L2.append(s)
|
|
2191
|
+
# create the polys associated to dual brackets
|
|
2192
|
+
if n - dim - 1 > 0:
|
|
2193
|
+
S = PolynomialRing(R.base_ring(), n + 1, 'z')
|
|
2194
|
+
T = PolynomialRing(S, (n + 1) * (n - dim - 1), 's')
|
|
2195
|
+
M = matrix(T, n - dim, n + 1, list(S.gens()) + list(T.gens()))
|
|
2196
|
+
else:
|
|
2197
|
+
T = PolynomialRing(R.base_ring(), n + 1, 'z')
|
|
2198
|
+
M = matrix(T, n - dim, n + 1, list(T.gens()))
|
|
2199
|
+
coords = []
|
|
2200
|
+
for i in range(len(L2)):
|
|
2201
|
+
coords.append(signs[i] * M.matrix_from_columns(L2[i]).det())
|
|
2202
|
+
# substitute in dual brackets to chow form
|
|
2203
|
+
phi = R.hom(coords, T)
|
|
2204
|
+
ch = phi(Ch)
|
|
2205
|
+
# coefficients are polys in zs which are the chow equations for the chow form
|
|
2206
|
+
if n - dim - 1 > 0:
|
|
2207
|
+
return self.subscheme(ch.coefficients())
|
|
2208
|
+
else:
|
|
2209
|
+
return self.subscheme(ch)
|
|
2210
|
+
|
|
2211
|
+
def curve(self, F):
|
|
2212
|
+
r"""
|
|
2213
|
+
Return a curve defined by ``F`` in this projective space.
|
|
2214
|
+
|
|
2215
|
+
INPUT:
|
|
2216
|
+
|
|
2217
|
+
- ``F`` -- a polynomial, or a list or tuple of polynomials in
|
|
2218
|
+
the coordinate ring of this projective space
|
|
2219
|
+
|
|
2220
|
+
EXAMPLES::
|
|
2221
|
+
|
|
2222
|
+
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
|
|
2223
|
+
sage: P.curve([y^2 - x*z]) # needs sage.schemes
|
|
2224
|
+
Projective Plane Curve over Rational Field defined by y^2 - x*z
|
|
2225
|
+
"""
|
|
2226
|
+
from sage.schemes.curves.constructor import Curve
|
|
2227
|
+
return Curve(F, self)
|
|
2228
|
+
|
|
2229
|
+
def line_through(self, p, q):
|
|
2230
|
+
"""
|
|
2231
|
+
Return the line through ``p`` and ``q``.
|
|
2232
|
+
|
|
2233
|
+
INPUT:
|
|
2234
|
+
|
|
2235
|
+
- ``p``, ``q`` -- distinct rational points of the projective space
|
|
2236
|
+
|
|
2237
|
+
EXAMPLES::
|
|
2238
|
+
|
|
2239
|
+
sage: P3.<x0,x1,x2,x3> = ProjectiveSpace(3, QQ)
|
|
2240
|
+
sage: p1 = P3(1, 2, 3, 4)
|
|
2241
|
+
sage: p2 = P3(4, 3, 2, 1)
|
|
2242
|
+
sage: P3.line_through(p1, p2) # needs sage.libs.singular sage.schemes
|
|
2243
|
+
Projective Curve over Rational Field defined by
|
|
2244
|
+
-5/4*x0 + 5/2*x1 - 5/4*x2, -5/2*x0 + 15/4*x1 - 5/4*x3,
|
|
2245
|
+
-5/4*x0 + 15/4*x2 - 5/2*x3, -5/4*x1 + 5/2*x2 - 5/4*x3
|
|
2246
|
+
sage: p3 = P3(2,4,6,8)
|
|
2247
|
+
sage: P3.line_through(p1, p3)
|
|
2248
|
+
Traceback (most recent call last):
|
|
2249
|
+
...
|
|
2250
|
+
ValueError: not distinct points
|
|
2251
|
+
"""
|
|
2252
|
+
if p == q:
|
|
2253
|
+
raise ValueError("not distinct points")
|
|
2254
|
+
|
|
2255
|
+
from sage.schemes.curves.constructor import Curve
|
|
2256
|
+
|
|
2257
|
+
m = matrix(3, list(self.gens()) + list(p) + list(q))
|
|
2258
|
+
return Curve([f for f in m.minors(3) if f])
|
|
2259
|
+
|
|
2260
|
+
def coherent_sheaf(self, module, twist=0):
|
|
2261
|
+
r"""
|
|
2262
|
+
Return the sheaf defined by the graded ``module``.
|
|
2263
|
+
|
|
2264
|
+
If ``twist`` is a non-zero integer `n`, the sheaf twisted by
|
|
2265
|
+
`\OO_{\PP^r}(n)` is returned.
|
|
2266
|
+
|
|
2267
|
+
INPUT:
|
|
2268
|
+
|
|
2269
|
+
- ``module`` -- a free module or a quotient module over the coordinate
|
|
2270
|
+
ring of this space
|
|
2271
|
+
|
|
2272
|
+
- ``twist`` -- (default: `0`) an integer
|
|
2273
|
+
|
|
2274
|
+
EXAMPLES::
|
|
2275
|
+
|
|
2276
|
+
sage: # needs sage.modules
|
|
2277
|
+
sage: P2 = ProjectiveSpace(QQ, 2, 'x')
|
|
2278
|
+
sage: S = P2.coordinate_ring()
|
|
2279
|
+
sage: SS = FreeModule(S, 2)
|
|
2280
|
+
sage: P2.coherent_sheaf(SS, twist=2)
|
|
2281
|
+
Twisted coherent sheaf on Projective Space of dimension 2 over Rational Field
|
|
2282
|
+
"""
|
|
2283
|
+
from sage.schemes.projective.coherent_sheaf import CoherentSheaf_on_projective_space
|
|
2284
|
+
return CoherentSheaf_on_projective_space(self, module, twist=twist)
|
|
2285
|
+
|
|
2286
|
+
def structure_sheaf(self, twist=0):
|
|
2287
|
+
r"""
|
|
2288
|
+
Return the structure sheaf `\OO_{\PP^r}` of this projective space.
|
|
2289
|
+
|
|
2290
|
+
If ``twist`` is a non-zero integer `n`, the sheaf twisted by
|
|
2291
|
+
`\OO_{\PP^r}(n)` is returned.
|
|
2292
|
+
|
|
2293
|
+
INPUT:
|
|
2294
|
+
|
|
2295
|
+
- ``twist`` -- (default: `0`) an integer
|
|
2296
|
+
|
|
2297
|
+
EXAMPLES::
|
|
2298
|
+
|
|
2299
|
+
sage: P3.<x0,x1,x2,x3> = ProjectiveSpace(QQ, 3)
|
|
2300
|
+
sage: P3.structure_sheaf() # needs sage.modules
|
|
2301
|
+
Coherent sheaf on Projective Space of dimension 3 over Rational Field
|
|
2302
|
+
"""
|
|
2303
|
+
M = FreeModule(self.coordinate_ring(), rank=1)
|
|
2304
|
+
return self.coherent_sheaf(M, twist=twist)
|
|
2305
|
+
|
|
2306
|
+
def arithmetic_genus(self):
|
|
2307
|
+
r"""
|
|
2308
|
+
Return the arithmetic genus of this projective space.
|
|
2309
|
+
|
|
2310
|
+
This is known to be 0.
|
|
2311
|
+
|
|
2312
|
+
EXAMPLES::
|
|
2313
|
+
|
|
2314
|
+
sage: P1 = ProjectiveSpace(QQ, 1)
|
|
2315
|
+
sage: P1.arithmetic_genus()
|
|
2316
|
+
0
|
|
2317
|
+
|
|
2318
|
+
We verify that the arithmetic genus of the `2`-dimensional projective space
|
|
2319
|
+
is indeed 0::
|
|
2320
|
+
|
|
2321
|
+
sage: P2 = ProjectiveSpace(QQ, 2)
|
|
2322
|
+
sage: P2.arithmetic_genus()
|
|
2323
|
+
0
|
|
2324
|
+
sage: P2.structure_sheaf().euler_characteristic() - 1 # needs sage.libs.singular sage.modules
|
|
2325
|
+
0
|
|
2326
|
+
"""
|
|
2327
|
+
return 0
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
class ProjectiveSpace_finite_field(ProjectiveSpace_field):
|
|
2331
|
+
def _point(self, *args, **kwds):
|
|
2332
|
+
"""
|
|
2333
|
+
Construct a point.
|
|
2334
|
+
|
|
2335
|
+
For internal use only. See :mod:`morphism` for details.
|
|
2336
|
+
|
|
2337
|
+
TESTS::
|
|
2338
|
+
|
|
2339
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
2340
|
+
sage: point_homset = P2._point_homset(Spec(GF(3)), P2)
|
|
2341
|
+
sage: P2._point(point_homset, [1,2,3])
|
|
2342
|
+
(2 : 1 : 0)
|
|
2343
|
+
"""
|
|
2344
|
+
return SchemeMorphism_point_projective_finite_field(*args, **kwds)
|
|
2345
|
+
|
|
2346
|
+
def _morphism(self, *args, **kwds):
|
|
2347
|
+
"""
|
|
2348
|
+
Construct a morphism.
|
|
2349
|
+
|
|
2350
|
+
For internal use only. See :mod:`morphism` for details.
|
|
2351
|
+
|
|
2352
|
+
TESTS::
|
|
2353
|
+
|
|
2354
|
+
sage: P2.<x,y,z> = ProjectiveSpace(2, GF(3))
|
|
2355
|
+
sage: P2._morphism(P2.Hom(P2), [x,y,z])
|
|
2356
|
+
Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3
|
|
2357
|
+
Defn: Defined on coordinates by sending (x : y : z) to
|
|
2358
|
+
(x : y : z)
|
|
2359
|
+
"""
|
|
2360
|
+
return SchemeMorphism_polynomial_projective_space_finite_field(*args, **kwds)
|
|
2361
|
+
|
|
2362
|
+
def __iter__(self):
|
|
2363
|
+
r"""
|
|
2364
|
+
Return iterator over the elements of this projective space.
|
|
2365
|
+
|
|
2366
|
+
Note that iteration is over the decomposition
|
|
2367
|
+
`\mathbb{P}^n = \mathbb{A}^n \cup \mathbb{P}^n-1`, where
|
|
2368
|
+
`\mathbb{A}^n` is the `n`-th affine patch and
|
|
2369
|
+
`\mathbb{P}^n-1` is the hyperplane at infinity
|
|
2370
|
+
`x_n = 0`.
|
|
2371
|
+
|
|
2372
|
+
EXAMPLES::
|
|
2373
|
+
|
|
2374
|
+
sage: FF = FiniteField(3)
|
|
2375
|
+
sage: PP = ProjectiveSpace(0, FF)
|
|
2376
|
+
sage: [ x for x in PP ]
|
|
2377
|
+
[(1)]
|
|
2378
|
+
sage: PP = ProjectiveSpace(1, FF)
|
|
2379
|
+
sage: [ x for x in PP ]
|
|
2380
|
+
[(0 : 1), (1 : 1), (2 : 1), (1 : 0)]
|
|
2381
|
+
sage: PP = ProjectiveSpace(2, FF)
|
|
2382
|
+
sage: [ x for x in PP ]
|
|
2383
|
+
[(0 : 0 : 1),
|
|
2384
|
+
(0 : 1 : 1),
|
|
2385
|
+
(0 : 2 : 1),
|
|
2386
|
+
(1 : 0 : 1),
|
|
2387
|
+
(1 : 1 : 1),
|
|
2388
|
+
(1 : 2 : 1),
|
|
2389
|
+
(2 : 0 : 1),
|
|
2390
|
+
(2 : 1 : 1),
|
|
2391
|
+
(2 : 2 : 1),
|
|
2392
|
+
(0 : 1 : 0),
|
|
2393
|
+
(1 : 1 : 0),
|
|
2394
|
+
(2 : 1 : 0),
|
|
2395
|
+
(1 : 0 : 0)]
|
|
2396
|
+
|
|
2397
|
+
AUTHORS:
|
|
2398
|
+
|
|
2399
|
+
- David Kohel, John Cremona
|
|
2400
|
+
|
|
2401
|
+
.. TODO::
|
|
2402
|
+
|
|
2403
|
+
Iteration for point sets over finite fields, and return of
|
|
2404
|
+
iter of point set over base field. Note that the point set does not
|
|
2405
|
+
know whether this is a projective space or subscheme.
|
|
2406
|
+
"""
|
|
2407
|
+
n = self.dimension_relative()
|
|
2408
|
+
R = self.base_ring()
|
|
2409
|
+
zero = (R.zero(), )
|
|
2410
|
+
one = (R.one(), )
|
|
2411
|
+
PHom = self.point_homset()
|
|
2412
|
+
C = PHom.codomain()
|
|
2413
|
+
|
|
2414
|
+
for k in range(n + 1): # position of last 1 before the 0's
|
|
2415
|
+
for v in product(*[R for _ in range(n - k)]):
|
|
2416
|
+
yield C._point(PHom, v + one + zero * k, check=False)
|
|
2417
|
+
|
|
2418
|
+
def rational_points(self, F=None):
|
|
2419
|
+
"""
|
|
2420
|
+
Return the list of ``F``-rational points on this projective space,
|
|
2421
|
+
where ``F`` is a given finite field, or the base ring of this space.
|
|
2422
|
+
|
|
2423
|
+
EXAMPLES::
|
|
2424
|
+
|
|
2425
|
+
sage: P = ProjectiveSpace(1, GF(3))
|
|
2426
|
+
sage: P.rational_points()
|
|
2427
|
+
[(0 : 1), (1 : 1), (2 : 1), (1 : 0)]
|
|
2428
|
+
sage: sorted(P.rational_points(GF(3^2, 'b')), key=str) # needs sage.rings.finite_rings
|
|
2429
|
+
[(0 : 1), (1 : 0), (1 : 1), (2 : 1),
|
|
2430
|
+
(2*b + 1 : 1), (2*b + 2 : 1), (2*b : 1),
|
|
2431
|
+
(b + 1 : 1), (b + 2 : 1), (b : 1)]
|
|
2432
|
+
"""
|
|
2433
|
+
if F is None:
|
|
2434
|
+
return list(self)
|
|
2435
|
+
elif not isinstance(F, FiniteField):
|
|
2436
|
+
raise TypeError("second argument (= %s) must be a finite field" % F)
|
|
2437
|
+
return list(self.base_extend(F))
|
|
2438
|
+
|
|
2439
|
+
def rational_points_dictionary(self):
|
|
2440
|
+
r"""
|
|
2441
|
+
Return dictionary of points.
|
|
2442
|
+
|
|
2443
|
+
OUTPUT: dictionary
|
|
2444
|
+
|
|
2445
|
+
EXAMPLES::
|
|
2446
|
+
|
|
2447
|
+
sage: P1 = ProjectiveSpace(GF(7), 1, 'x')
|
|
2448
|
+
sage: P1.rational_points_dictionary()
|
|
2449
|
+
{(0 : 1): 0,
|
|
2450
|
+
(1 : 0): 7,
|
|
2451
|
+
(1 : 1): 1,
|
|
2452
|
+
(2 : 1): 2,
|
|
2453
|
+
(3 : 1): 3,
|
|
2454
|
+
(4 : 1): 4,
|
|
2455
|
+
(5 : 1): 5,
|
|
2456
|
+
(6 : 1): 6}
|
|
2457
|
+
"""
|
|
2458
|
+
n = self.dimension_relative()
|
|
2459
|
+
R = self.base_ring()
|
|
2460
|
+
D = {}
|
|
2461
|
+
zero = R.zero()
|
|
2462
|
+
i = n
|
|
2463
|
+
index = 0
|
|
2464
|
+
while not i < 0:
|
|
2465
|
+
P = [zero for _ in range(i)] + [R.one()]
|
|
2466
|
+
P += [zero for _ in range(n - i)]
|
|
2467
|
+
D.update({self(P): index})
|
|
2468
|
+
index += 1
|
|
2469
|
+
iters = [iter(R) for _ in range(i)]
|
|
2470
|
+
for x in iters:
|
|
2471
|
+
next(x) # put at zero
|
|
2472
|
+
j = 0
|
|
2473
|
+
while j < i:
|
|
2474
|
+
try:
|
|
2475
|
+
P[j] = next(iters[j])
|
|
2476
|
+
D.update({self(P): index})
|
|
2477
|
+
index += 1
|
|
2478
|
+
j = 0
|
|
2479
|
+
except StopIteration:
|
|
2480
|
+
iters[j] = iter(R) # reset
|
|
2481
|
+
next(iters[j]) # put at zero
|
|
2482
|
+
P[j] = zero
|
|
2483
|
+
j += 1
|
|
2484
|
+
i -= 1
|
|
2485
|
+
return D
|
|
2486
|
+
|
|
2487
|
+
|
|
2488
|
+
class ProjectiveSpace_rational_field(ProjectiveSpace_field):
|
|
2489
|
+
def rational_points(self, bound=0):
|
|
2490
|
+
r"""
|
|
2491
|
+
Return the projective points `(x_0:\cdots:x_n)` over
|
|
2492
|
+
`\QQ` with `|x_i| \leq` bound.
|
|
2493
|
+
|
|
2494
|
+
ALGORITHM:
|
|
2495
|
+
|
|
2496
|
+
The very simple algorithm works as follows: every point
|
|
2497
|
+
`(x_0:\cdots:x_n)` in projective space has a unique
|
|
2498
|
+
largest index `i` for which `x_i` is not
|
|
2499
|
+
zero. The algorithm then iterates downward on this
|
|
2500
|
+
index. We normalize by choosing `x_i` positive. Then,
|
|
2501
|
+
the points `x_0,\ldots,x_{i-1}` are the points of
|
|
2502
|
+
affine `i`-space that are relatively prime to
|
|
2503
|
+
`x_i`. We access these by using the Tuples method.
|
|
2504
|
+
|
|
2505
|
+
INPUT:
|
|
2506
|
+
|
|
2507
|
+
- ``bound`` -- integer
|
|
2508
|
+
|
|
2509
|
+
EXAMPLES::
|
|
2510
|
+
|
|
2511
|
+
sage: PP = ProjectiveSpace(0, QQ)
|
|
2512
|
+
sage: PP.rational_points(1)
|
|
2513
|
+
[(1)]
|
|
2514
|
+
sage: PP = ProjectiveSpace(1, QQ)
|
|
2515
|
+
sage: PP.rational_points(2)
|
|
2516
|
+
[(-2 : 1), (-1 : 1), (0 : 1), (1 : 1), (2 : 1), (-1/2 : 1), (1/2 : 1), (1 : 0)]
|
|
2517
|
+
sage: PP = ProjectiveSpace(2, QQ)
|
|
2518
|
+
sage: PP.rational_points(2)
|
|
2519
|
+
[(-2 : -2 : 1), (-1 : -2 : 1), (0 : -2 : 1), (1 : -2 : 1), (2 : -2 : 1),
|
|
2520
|
+
(-2 : -1 : 1), (-1 : -1 : 1), (0 : -1 : 1), (1 : -1 : 1), (2 : -1 : 1),
|
|
2521
|
+
(-2 : 0 : 1), (-1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1), (2 : 0 : 1), (-2 : 1 : 1),
|
|
2522
|
+
(-1 : 1 : 1), (0 : 1 : 1), (1 : 1 : 1), (2 : 1 : 1), (-2 : 2 : 1),
|
|
2523
|
+
(-1 : 2 : 1), (0 : 2 : 1), (1 : 2 : 1), (2 : 2 : 1), (-1/2 : -1 : 1),
|
|
2524
|
+
(1/2 : -1 : 1), (-1 : -1/2 : 1), (-1/2 : -1/2 : 1), (0 : -1/2 : 1),
|
|
2525
|
+
(1/2 : -1/2 : 1), (1 : -1/2 : 1), (-1/2 : 0 : 1), (1/2 : 0 : 1), (-1 : 1/2 : 1),
|
|
2526
|
+
(-1/2 : 1/2 : 1), (0 : 1/2 : 1), (1/2 : 1/2 : 1), (1 : 1/2 : 1), (-1/2 : 1 : 1),
|
|
2527
|
+
(1/2 : 1 : 1), (-2 : 1 : 0), (-1 : 1 : 0), (0 : 1 : 0), (1 : 1 : 0),
|
|
2528
|
+
(2 : 1 : 0), (-1/2 : 1 : 0), (1/2 : 1 : 0), (1 : 0 : 0)]
|
|
2529
|
+
|
|
2530
|
+
AUTHORS:
|
|
2531
|
+
|
|
2532
|
+
- Benjamin Antieau (2008-01-12)
|
|
2533
|
+
"""
|
|
2534
|
+
if not bound > 0:
|
|
2535
|
+
raise ValueError("argument bound (= %s) must be a positive integer")
|
|
2536
|
+
|
|
2537
|
+
n = self.dimension_relative()
|
|
2538
|
+
|
|
2539
|
+
Q = [k - bound for k in range(2 * bound + 1)] # the affine coordinates
|
|
2540
|
+
R = [(k + 1) for k in range(bound)] # the projective coordinate
|
|
2541
|
+
S = [Tuples(Q, (k + 1)) for k in range(n)]
|
|
2542
|
+
pts = []
|
|
2543
|
+
|
|
2544
|
+
i = n
|
|
2545
|
+
while i > 0:
|
|
2546
|
+
P = [0 for _ in range(n + 1)]
|
|
2547
|
+
for ai in R:
|
|
2548
|
+
P[i] = ai
|
|
2549
|
+
for tup in S[i - 1]:
|
|
2550
|
+
if gcd((ai,) + tup) == 1:
|
|
2551
|
+
for j in range(i):
|
|
2552
|
+
P[j] = tup[j]
|
|
2553
|
+
pts.append(self(P))
|
|
2554
|
+
i -= 1
|
|
2555
|
+
|
|
2556
|
+
# now do i=0; this is treated as a special case so that
|
|
2557
|
+
# we don't have all points (1:0),(2,0),(3,0),etc.
|
|
2558
|
+
P = [0 for _ in range(n + 1)]
|
|
2559
|
+
P[0] = 1
|
|
2560
|
+
pts.append(self(P))
|
|
2561
|
+
return pts
|
|
2562
|
+
|
|
2563
|
+
|
|
2564
|
+
# fix the pickles from moving projective_space.py
|
|
2565
|
+
register_unpickle_override('sage.schemes.generic.projective_space',
|
|
2566
|
+
'ProjectiveSpace_field',
|
|
2567
|
+
ProjectiveSpace_field)
|
|
2568
|
+
|
|
2569
|
+
register_unpickle_override('sage.schemes.generic.projective_space',
|
|
2570
|
+
'ProjectiveSpace_rational_field',
|
|
2571
|
+
ProjectiveSpace_rational_field)
|