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
sage/categories/rings.py
ADDED
|
@@ -0,0 +1,1904 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Rings
|
|
4
|
+
"""
|
|
5
|
+
# ****************************************************************************
|
|
6
|
+
# Copyright (C) 2005 David Kohel <kohel@maths.usyd.edu>
|
|
7
|
+
# William Stein <wstein@math.ucsd.edu>
|
|
8
|
+
# 2008 Teresa Gomez-Diaz (CNRS)
|
|
9
|
+
# <Teresa.Gomez-Diaz@univ-mlv.fr>
|
|
10
|
+
# 2008-2011 Nicolas M. Thiery <nthiery at users.sf.net>
|
|
11
|
+
#
|
|
12
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
13
|
+
# https://www.gnu.org/licenses/
|
|
14
|
+
# *****************************************************************************
|
|
15
|
+
import itertools
|
|
16
|
+
|
|
17
|
+
from functools import reduce
|
|
18
|
+
from types import GeneratorType
|
|
19
|
+
|
|
20
|
+
from sage.misc.cachefunc import cached_method
|
|
21
|
+
from sage.misc.lazy_import import LazyImport
|
|
22
|
+
from sage.misc.prandom import randint
|
|
23
|
+
from sage.categories.category_with_axiom import CategoryWithAxiom
|
|
24
|
+
from sage.categories.rngs import Rngs
|
|
25
|
+
from sage.structure.element import Element
|
|
26
|
+
from sage.structure.parent import Parent
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Rings(CategoryWithAxiom):
|
|
30
|
+
"""
|
|
31
|
+
The category of rings.
|
|
32
|
+
|
|
33
|
+
Associative rings with unit, not necessarily commutative
|
|
34
|
+
|
|
35
|
+
EXAMPLES::
|
|
36
|
+
|
|
37
|
+
sage: Rings()
|
|
38
|
+
Category of rings
|
|
39
|
+
sage: sorted(Rings().super_categories(), key=str)
|
|
40
|
+
[Category of rngs, Category of semirings]
|
|
41
|
+
|
|
42
|
+
sage: sorted(Rings().axioms())
|
|
43
|
+
['AdditiveAssociative', 'AdditiveCommutative', 'AdditiveInverse',
|
|
44
|
+
'AdditiveUnital', 'Associative', 'Distributive', 'Unital']
|
|
45
|
+
|
|
46
|
+
sage: Rings() is (CommutativeAdditiveGroups() & Monoids()).Distributive()
|
|
47
|
+
True
|
|
48
|
+
sage: Rings() is Rngs().Unital()
|
|
49
|
+
True
|
|
50
|
+
sage: Rings() is Semirings().AdditiveInverse()
|
|
51
|
+
True
|
|
52
|
+
|
|
53
|
+
TESTS::
|
|
54
|
+
|
|
55
|
+
sage: TestSuite(Rings()).run()
|
|
56
|
+
|
|
57
|
+
.. TODO::
|
|
58
|
+
|
|
59
|
+
(see :issue:`sage_trac/wiki/CategoriesRoadMap`)
|
|
60
|
+
|
|
61
|
+
- Make Rings() into a subcategory or alias of Algebras(ZZ);
|
|
62
|
+
|
|
63
|
+
- A parent P in the category ``Rings()`` should automatically be
|
|
64
|
+
in the category ``Algebras(P)``.
|
|
65
|
+
"""
|
|
66
|
+
_base_category_class_and_axiom = (Rngs, "Unital")
|
|
67
|
+
|
|
68
|
+
def __lean_init__(self):
|
|
69
|
+
return 'ring'
|
|
70
|
+
|
|
71
|
+
class MorphismMethods:
|
|
72
|
+
@cached_method
|
|
73
|
+
def is_injective(self) -> bool:
|
|
74
|
+
"""
|
|
75
|
+
Return whether or not this morphism is injective.
|
|
76
|
+
|
|
77
|
+
EXAMPLES::
|
|
78
|
+
|
|
79
|
+
sage: # needs sage.libs.singular
|
|
80
|
+
sage: R.<x,y> = QQ[]
|
|
81
|
+
sage: R.hom([x, y^2], R).is_injective()
|
|
82
|
+
True
|
|
83
|
+
sage: R.hom([x, x^2], R).is_injective()
|
|
84
|
+
False
|
|
85
|
+
sage: S.<u,v> = R.quotient(x^3*y)
|
|
86
|
+
sage: R.hom([v, u], S).is_injective()
|
|
87
|
+
False
|
|
88
|
+
sage: S.hom([-u, v], S).is_injective()
|
|
89
|
+
True
|
|
90
|
+
sage: S.cover().is_injective()
|
|
91
|
+
False
|
|
92
|
+
|
|
93
|
+
If the domain is a field, the homomorphism is injective::
|
|
94
|
+
|
|
95
|
+
sage: K.<x> = FunctionField(QQ)
|
|
96
|
+
sage: L.<y> = FunctionField(QQ)
|
|
97
|
+
sage: f = K.hom([y]); f
|
|
98
|
+
Function Field morphism:
|
|
99
|
+
From: Rational function field in x over Rational Field
|
|
100
|
+
To: Rational function field in y over Rational Field
|
|
101
|
+
Defn: x |--> y
|
|
102
|
+
sage: f.is_injective()
|
|
103
|
+
True
|
|
104
|
+
|
|
105
|
+
Unless the codomain is the zero ring::
|
|
106
|
+
|
|
107
|
+
sage: codomain = Integers(1)
|
|
108
|
+
sage: f = QQ.hom([Zmod(1)(0)], check=False)
|
|
109
|
+
sage: f.is_injective()
|
|
110
|
+
False
|
|
111
|
+
|
|
112
|
+
Homomorphism from rings of characteristic zero to rings of positive
|
|
113
|
+
characteristic can not be injective::
|
|
114
|
+
|
|
115
|
+
sage: R.<x> = ZZ[]
|
|
116
|
+
sage: f = R.hom([GF(3)(1)]); f
|
|
117
|
+
Ring morphism:
|
|
118
|
+
From: Univariate Polynomial Ring in x over Integer Ring
|
|
119
|
+
To: Finite Field of size 3
|
|
120
|
+
Defn: x |--> 1
|
|
121
|
+
sage: f.is_injective()
|
|
122
|
+
False
|
|
123
|
+
|
|
124
|
+
A morphism whose domain is an order in a number field is injective if
|
|
125
|
+
the codomain has characteristic zero::
|
|
126
|
+
|
|
127
|
+
sage: K.<x> = FunctionField(QQ)
|
|
128
|
+
sage: f = ZZ.hom(K); f
|
|
129
|
+
Composite map:
|
|
130
|
+
From: Integer Ring
|
|
131
|
+
To: Rational function field in x over Rational Field
|
|
132
|
+
Defn: Conversion via FractionFieldElement_1poly_field map:
|
|
133
|
+
From: Integer Ring
|
|
134
|
+
To: Fraction Field of Univariate Polynomial Ring in x
|
|
135
|
+
over Rational Field
|
|
136
|
+
then
|
|
137
|
+
Isomorphism:
|
|
138
|
+
From: Fraction Field of Univariate Polynomial Ring in x
|
|
139
|
+
over Rational Field
|
|
140
|
+
To: Rational function field in x over Rational Field
|
|
141
|
+
sage: f.is_injective()
|
|
142
|
+
True
|
|
143
|
+
|
|
144
|
+
A coercion to the fraction field is injective::
|
|
145
|
+
|
|
146
|
+
sage: R = ZpFM(3) # needs sage.rings.padics
|
|
147
|
+
sage: R.fraction_field().coerce_map_from(R).is_injective()
|
|
148
|
+
True
|
|
149
|
+
"""
|
|
150
|
+
if self.domain().is_zero():
|
|
151
|
+
return True
|
|
152
|
+
if self.codomain().is_zero():
|
|
153
|
+
# the only map to the zero ring that is injective is the map from itself
|
|
154
|
+
return False
|
|
155
|
+
|
|
156
|
+
from sage.categories.fields import Fields
|
|
157
|
+
if self.domain() in Fields():
|
|
158
|
+
# A ring homomorphism from a field to a ring is injective
|
|
159
|
+
# (unless the codomain is the zero ring.) Note that ring
|
|
160
|
+
# homomorphism must send the 1 element to the 1 element
|
|
161
|
+
return True
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
ker = self.kernel()
|
|
165
|
+
except (NotImplementedError, AttributeError):
|
|
166
|
+
pass
|
|
167
|
+
else:
|
|
168
|
+
return ker.is_zero()
|
|
169
|
+
|
|
170
|
+
if self.domain().characteristic() == 0:
|
|
171
|
+
if self.codomain().characteristic() != 0:
|
|
172
|
+
return False
|
|
173
|
+
else:
|
|
174
|
+
from sage.categories.integral_domains import IntegralDomains
|
|
175
|
+
if self.domain() in IntegralDomains():
|
|
176
|
+
# if all elements of the domain are algebraic over ZZ,
|
|
177
|
+
# then the homomorphism must be injective (in
|
|
178
|
+
# particular if the domain is ZZ)
|
|
179
|
+
from sage.categories.number_fields import NumberFields
|
|
180
|
+
if self.domain().fraction_field() in NumberFields():
|
|
181
|
+
return True
|
|
182
|
+
|
|
183
|
+
if self._is_coercion:
|
|
184
|
+
try:
|
|
185
|
+
K = self.domain().fraction_field()
|
|
186
|
+
except (TypeError, AttributeError, ValueError):
|
|
187
|
+
pass
|
|
188
|
+
else:
|
|
189
|
+
if K is self.codomain():
|
|
190
|
+
return True
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
if self.domain().cardinality() > self.codomain().cardinality():
|
|
194
|
+
return False
|
|
195
|
+
except AttributeError:
|
|
196
|
+
pass
|
|
197
|
+
|
|
198
|
+
raise NotImplementedError
|
|
199
|
+
|
|
200
|
+
def _is_nonzero(self) -> bool:
|
|
201
|
+
r"""
|
|
202
|
+
Return whether this is not the zero morphism.
|
|
203
|
+
|
|
204
|
+
.. NOTE::
|
|
205
|
+
|
|
206
|
+
We can not override ``is_zero()`` from the category framework
|
|
207
|
+
and we can not implement ``__bool__`` because it is a
|
|
208
|
+
special method. That this is why this has a cumbersome name.
|
|
209
|
+
|
|
210
|
+
EXAMPLES::
|
|
211
|
+
|
|
212
|
+
sage: ZZ.hom(ZZ)._is_nonzero()
|
|
213
|
+
True
|
|
214
|
+
sage: ZZ.hom(Zmod(1))._is_nonzero()
|
|
215
|
+
False
|
|
216
|
+
"""
|
|
217
|
+
return bool(self.codomain().one())
|
|
218
|
+
|
|
219
|
+
def extend_to_fraction_field(self):
|
|
220
|
+
r"""
|
|
221
|
+
Return the extension of this morphism to fraction fields of
|
|
222
|
+
the domain and the codomain.
|
|
223
|
+
|
|
224
|
+
EXAMPLES::
|
|
225
|
+
|
|
226
|
+
sage: S.<x> = QQ[]
|
|
227
|
+
sage: f = S.hom([x + 1]); f
|
|
228
|
+
Ring endomorphism of Univariate Polynomial Ring in x over Rational Field
|
|
229
|
+
Defn: x |--> x + 1
|
|
230
|
+
|
|
231
|
+
sage: g = f.extend_to_fraction_field(); g # needs sage.libs.singular
|
|
232
|
+
Ring endomorphism of Fraction Field of Univariate Polynomial Ring in x
|
|
233
|
+
over Rational Field
|
|
234
|
+
Defn: x |--> x + 1
|
|
235
|
+
sage: g(x) # needs sage.libs.singular
|
|
236
|
+
x + 1
|
|
237
|
+
sage: g(1/x) # needs sage.libs.singular
|
|
238
|
+
1/(x + 1)
|
|
239
|
+
|
|
240
|
+
If this morphism is not injective, it does not extend to the fraction
|
|
241
|
+
field and an error is raised::
|
|
242
|
+
|
|
243
|
+
sage: f = GF(5).coerce_map_from(ZZ)
|
|
244
|
+
sage: f.extend_to_fraction_field()
|
|
245
|
+
Traceback (most recent call last):
|
|
246
|
+
...
|
|
247
|
+
ValueError: the morphism is not injective
|
|
248
|
+
|
|
249
|
+
TESTS::
|
|
250
|
+
|
|
251
|
+
sage: A.<x> = RR[]
|
|
252
|
+
sage: phi = A.hom([x + 1])
|
|
253
|
+
sage: phi.extend_to_fraction_field() # needs sage.libs.singular
|
|
254
|
+
Ring endomorphism of Fraction Field of
|
|
255
|
+
Univariate Polynomial Ring in x over Real Field with 53 bits of precision
|
|
256
|
+
Defn: x |--> x + 1.00000000000000
|
|
257
|
+
"""
|
|
258
|
+
from sage.rings.morphism import RingHomomorphism_from_fraction_field
|
|
259
|
+
if self.domain().is_field() and self.codomain().is_field():
|
|
260
|
+
return self
|
|
261
|
+
try:
|
|
262
|
+
if not self.is_injective():
|
|
263
|
+
raise ValueError("the morphism is not injective")
|
|
264
|
+
except (NotImplementedError, TypeError): # we trust the user
|
|
265
|
+
pass
|
|
266
|
+
domain = self.domain().fraction_field()
|
|
267
|
+
codomain = self.codomain().fraction_field()
|
|
268
|
+
parent = domain.Hom(codomain) # category = category=self.category_for() ???
|
|
269
|
+
return RingHomomorphism_from_fraction_field(parent, self)
|
|
270
|
+
|
|
271
|
+
class SubcategoryMethods:
|
|
272
|
+
|
|
273
|
+
def NoZeroDivisors(self):
|
|
274
|
+
r"""
|
|
275
|
+
Return the full subcategory of the objects of ``self`` having
|
|
276
|
+
no nonzero zero divisors.
|
|
277
|
+
|
|
278
|
+
A *zero divisor* in a ring `R` is an element `x \in R` such
|
|
279
|
+
that there exists a nonzero element `y \in R` such that
|
|
280
|
+
`x \cdot y = 0` or `y \cdot x = 0`
|
|
281
|
+
(see :wikipedia:`Zero_divisor`).
|
|
282
|
+
|
|
283
|
+
EXAMPLES::
|
|
284
|
+
|
|
285
|
+
sage: Rings().NoZeroDivisors()
|
|
286
|
+
Category of domains
|
|
287
|
+
|
|
288
|
+
TESTS::
|
|
289
|
+
|
|
290
|
+
sage: TestSuite(Rings().NoZeroDivisors()).run()
|
|
291
|
+
sage: Algebras(QQ).NoZeroDivisors.__module__
|
|
292
|
+
'sage.categories.rings'
|
|
293
|
+
"""
|
|
294
|
+
return self._with_axiom('NoZeroDivisors')
|
|
295
|
+
|
|
296
|
+
def Division(self):
|
|
297
|
+
"""
|
|
298
|
+
Return the full subcategory of the division objects of ``self``.
|
|
299
|
+
|
|
300
|
+
A ring satisfies the *division axiom* if all nonzero
|
|
301
|
+
elements have multiplicative inverses.
|
|
302
|
+
|
|
303
|
+
EXAMPLES::
|
|
304
|
+
|
|
305
|
+
sage: Rings().Division()
|
|
306
|
+
Category of division rings
|
|
307
|
+
sage: Rings().Commutative().Division()
|
|
308
|
+
Category of fields
|
|
309
|
+
|
|
310
|
+
TESTS::
|
|
311
|
+
|
|
312
|
+
sage: TestSuite(Rings().Division()).run()
|
|
313
|
+
sage: Algebras(QQ).Division.__module__
|
|
314
|
+
'sage.categories.rings'
|
|
315
|
+
"""
|
|
316
|
+
return self._with_axiom('Division')
|
|
317
|
+
|
|
318
|
+
NoZeroDivisors = LazyImport('sage.categories.domains', 'Domains', at_startup=True)
|
|
319
|
+
Division = LazyImport('sage.categories.division_rings', 'DivisionRings', at_startup=True)
|
|
320
|
+
Commutative = LazyImport('sage.categories.commutative_rings', 'CommutativeRings', at_startup=True)
|
|
321
|
+
|
|
322
|
+
class ParentMethods:
|
|
323
|
+
def is_ring(self) -> bool:
|
|
324
|
+
"""
|
|
325
|
+
Return ``True``, since this in an object of the category of rings.
|
|
326
|
+
|
|
327
|
+
EXAMPLES::
|
|
328
|
+
|
|
329
|
+
sage: Parent(QQ,category=Rings()).is_ring()
|
|
330
|
+
True
|
|
331
|
+
"""
|
|
332
|
+
return True
|
|
333
|
+
|
|
334
|
+
def is_commutative(self) -> bool:
|
|
335
|
+
"""
|
|
336
|
+
Return whether the ring is commutative.
|
|
337
|
+
|
|
338
|
+
The answer is ``True`` only if the category is a sub-category of
|
|
339
|
+
``CommutativeRings``.
|
|
340
|
+
|
|
341
|
+
It is recommended to use instead ``R in Rings().Commutative()``.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: Q.<i,j,k> = QuaternionAlgebra(QQ, -1, -1) # needs sage.combinat sage.libs.singular sage.modules
|
|
346
|
+
sage: Q.is_commutative() # needs sage.combinat sage.libs.singular sage.modules
|
|
347
|
+
False
|
|
348
|
+
"""
|
|
349
|
+
return False
|
|
350
|
+
|
|
351
|
+
def is_integral_domain(self, proof=True) -> bool:
|
|
352
|
+
"""
|
|
353
|
+
Return ``True`` if this ring is an integral domain.
|
|
354
|
+
|
|
355
|
+
INPUT:
|
|
356
|
+
|
|
357
|
+
- ``proof`` -- boolean (default: ``True``); determine what to do
|
|
358
|
+
in unknown cases
|
|
359
|
+
|
|
360
|
+
ALGORITHM:
|
|
361
|
+
|
|
362
|
+
If the parameter ``proof`` is set to ``True``, the returned value is
|
|
363
|
+
correct but the method might throw an error. Otherwise, if it is set
|
|
364
|
+
to ``False``, the method returns ``True`` if it can establish that ``self``
|
|
365
|
+
is an integral domain and ``False`` otherwise.
|
|
366
|
+
|
|
367
|
+
EXAMPLES::
|
|
368
|
+
|
|
369
|
+
sage: QQ.is_integral_domain()
|
|
370
|
+
True
|
|
371
|
+
sage: ZZ.is_integral_domain()
|
|
372
|
+
True
|
|
373
|
+
sage: ZZ['x,y,z'].is_integral_domain()
|
|
374
|
+
True
|
|
375
|
+
sage: Integers(8).is_integral_domain()
|
|
376
|
+
False
|
|
377
|
+
sage: Zp(7).is_integral_domain() # needs sage.rings.padics
|
|
378
|
+
True
|
|
379
|
+
sage: Qp(7).is_integral_domain() # needs sage.rings.padics
|
|
380
|
+
True
|
|
381
|
+
sage: R.<a,b> = QQ[]
|
|
382
|
+
sage: S.<x,y> = R.quo((b^3)) # needs sage.libs.singular
|
|
383
|
+
sage: S.is_integral_domain() # needs sage.libs.singular
|
|
384
|
+
False
|
|
385
|
+
sage: R = ZZ.quotient(ZZ.ideal(10)); R.is_integral_domain()
|
|
386
|
+
False
|
|
387
|
+
|
|
388
|
+
This illustrates the use of the ``proof`` parameter::
|
|
389
|
+
|
|
390
|
+
sage: R.<a,b> = ZZ[]
|
|
391
|
+
sage: S.<x,y> = R.quo((b^3)) # needs sage.libs.singular
|
|
392
|
+
sage: S.is_integral_domain(proof=True) # needs sage.libs.singular
|
|
393
|
+
Traceback (most recent call last):
|
|
394
|
+
...
|
|
395
|
+
NotImplementedError
|
|
396
|
+
sage: S.is_integral_domain(proof=False) # needs sage.libs.singular
|
|
397
|
+
False
|
|
398
|
+
|
|
399
|
+
TESTS:
|
|
400
|
+
|
|
401
|
+
Make sure :issue:`10481` is fixed::
|
|
402
|
+
|
|
403
|
+
sage: x = polygen(ZZ, 'x')
|
|
404
|
+
sage: R.<a> = ZZ['x'].quo(x^2) # needs sage.libs.pari
|
|
405
|
+
sage: R.fraction_field() # needs sage.libs.pari
|
|
406
|
+
Traceback (most recent call last):
|
|
407
|
+
...
|
|
408
|
+
TypeError: self must be an integral domain.
|
|
409
|
+
sage: R.is_integral_domain() # needs sage.libs.pari
|
|
410
|
+
False
|
|
411
|
+
|
|
412
|
+
Forward the proof flag to ``is_field``, see :issue:`22910`::
|
|
413
|
+
|
|
414
|
+
sage: # needs sage.libs.singular
|
|
415
|
+
sage: R1.<x> = GF(5)[]
|
|
416
|
+
sage: F1 = R1.quotient_ring(x^2 + x + 1)
|
|
417
|
+
sage: R2.<x> = F1[]
|
|
418
|
+
sage: F2 = R2.quotient_ring(x^2 + x + 1)
|
|
419
|
+
sage: F2.is_integral_domain(False)
|
|
420
|
+
False
|
|
421
|
+
"""
|
|
422
|
+
if self.is_field(proof):
|
|
423
|
+
return True
|
|
424
|
+
|
|
425
|
+
if self.is_zero():
|
|
426
|
+
return False
|
|
427
|
+
|
|
428
|
+
if proof:
|
|
429
|
+
raise NotImplementedError
|
|
430
|
+
|
|
431
|
+
return False
|
|
432
|
+
|
|
433
|
+
def is_integrally_closed(self) -> bool:
|
|
434
|
+
r"""
|
|
435
|
+
Return whether this ring is integrally closed.
|
|
436
|
+
|
|
437
|
+
This is the default implementation that
|
|
438
|
+
raises a :exc:`NotImplementedError`.
|
|
439
|
+
|
|
440
|
+
EXAMPLES::
|
|
441
|
+
|
|
442
|
+
sage: # needs sage.rings.number_field
|
|
443
|
+
sage: x = polygen(ZZ, 'x')
|
|
444
|
+
sage: K.<a> = NumberField(x^2 + 189*x + 394)
|
|
445
|
+
sage: R = K.order(2*a)
|
|
446
|
+
sage: R.is_integrally_closed()
|
|
447
|
+
False
|
|
448
|
+
sage: R
|
|
449
|
+
Order of conductor 2 generated by 2*a in Number Field in a with defining polynomial x^2 + 189*x + 394
|
|
450
|
+
sage: S = K.maximal_order(); S
|
|
451
|
+
Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 189*x + 394
|
|
452
|
+
sage: S.is_integrally_closed()
|
|
453
|
+
True
|
|
454
|
+
"""
|
|
455
|
+
raise NotImplementedError
|
|
456
|
+
|
|
457
|
+
def is_noetherian(self):
|
|
458
|
+
"""
|
|
459
|
+
Return ``True`` if this ring is Noetherian.
|
|
460
|
+
|
|
461
|
+
EXAMPLES::
|
|
462
|
+
|
|
463
|
+
sage: QQ.is_noetherian()
|
|
464
|
+
True
|
|
465
|
+
sage: ZZ.is_noetherian()
|
|
466
|
+
True
|
|
467
|
+
"""
|
|
468
|
+
return False
|
|
469
|
+
|
|
470
|
+
def is_prime_field(self):
|
|
471
|
+
r"""
|
|
472
|
+
Return ``True`` if this ring is one of the prime fields `\QQ` or
|
|
473
|
+
`\GF{p}`.
|
|
474
|
+
|
|
475
|
+
EXAMPLES::
|
|
476
|
+
|
|
477
|
+
sage: QQ.is_prime_field()
|
|
478
|
+
True
|
|
479
|
+
sage: GF(3).is_prime_field()
|
|
480
|
+
True
|
|
481
|
+
sage: GF(9, 'a').is_prime_field() # needs sage.rings.finite_rings
|
|
482
|
+
False
|
|
483
|
+
sage: ZZ.is_prime_field()
|
|
484
|
+
False
|
|
485
|
+
sage: QQ['x'].is_prime_field()
|
|
486
|
+
False
|
|
487
|
+
sage: Qp(19).is_prime_field() # needs sage.rings.padics
|
|
488
|
+
False
|
|
489
|
+
"""
|
|
490
|
+
# the case of QQ is handled by QQ itself
|
|
491
|
+
from sage.categories.finite_fields import FiniteFields
|
|
492
|
+
return self in FiniteFields() and self.degree() == 1
|
|
493
|
+
|
|
494
|
+
def is_zero(self) -> bool:
|
|
495
|
+
"""
|
|
496
|
+
Return ``True`` if this is the zero ring.
|
|
497
|
+
|
|
498
|
+
EXAMPLES::
|
|
499
|
+
|
|
500
|
+
sage: Integers(1).is_zero()
|
|
501
|
+
True
|
|
502
|
+
sage: Integers(2).is_zero()
|
|
503
|
+
False
|
|
504
|
+
sage: QQ.is_zero()
|
|
505
|
+
False
|
|
506
|
+
sage: R.<x> = ZZ[]
|
|
507
|
+
sage: R.quo(1).is_zero()
|
|
508
|
+
True
|
|
509
|
+
sage: R.<x> = GF(101)[]
|
|
510
|
+
sage: R.quo(77).is_zero()
|
|
511
|
+
True
|
|
512
|
+
sage: R.quo(x^2 + 1).is_zero() # needs sage.libs.pari
|
|
513
|
+
False
|
|
514
|
+
"""
|
|
515
|
+
return self.one() == self.zero()
|
|
516
|
+
|
|
517
|
+
def is_subring(self, other):
|
|
518
|
+
"""
|
|
519
|
+
Return ``True`` if the canonical map from ``self`` to ``other`` is
|
|
520
|
+
injective.
|
|
521
|
+
|
|
522
|
+
This raises a :exc:`NotImplementedError` if not known.
|
|
523
|
+
|
|
524
|
+
EXAMPLES::
|
|
525
|
+
|
|
526
|
+
sage: ZZ.is_subring(QQ)
|
|
527
|
+
True
|
|
528
|
+
sage: ZZ.is_subring(GF(19))
|
|
529
|
+
False
|
|
530
|
+
|
|
531
|
+
TESTS::
|
|
532
|
+
|
|
533
|
+
sage: QQ.is_subring(QQ['x'])
|
|
534
|
+
True
|
|
535
|
+
sage: QQ.is_subring(GF(7))
|
|
536
|
+
False
|
|
537
|
+
sage: QQ.is_subring(CyclotomicField(7)) # needs sage.rings.number_field
|
|
538
|
+
True
|
|
539
|
+
sage: QQ.is_subring(ZZ)
|
|
540
|
+
False
|
|
541
|
+
|
|
542
|
+
Every ring is a subring of itself, :issue:`17287`::
|
|
543
|
+
|
|
544
|
+
sage: QQbar.is_subring(QQbar) # needs sage.rings.number_field
|
|
545
|
+
True
|
|
546
|
+
sage: RR.is_subring(RR)
|
|
547
|
+
True
|
|
548
|
+
sage: CC.is_subring(CC) # needs sage.rings.real_mpfr
|
|
549
|
+
True
|
|
550
|
+
sage: x = polygen(ZZ, 'x')
|
|
551
|
+
sage: K.<a> = NumberField(x^3 - x + 1/10) # needs sage.rings.number_field
|
|
552
|
+
sage: K.is_subring(K) # needs sage.rings.number_field
|
|
553
|
+
True
|
|
554
|
+
sage: R.<x> = RR[]
|
|
555
|
+
sage: R.is_subring(R)
|
|
556
|
+
True
|
|
557
|
+
"""
|
|
558
|
+
if self is other:
|
|
559
|
+
return True
|
|
560
|
+
try:
|
|
561
|
+
return self.Hom(other).natural_map().is_injective()
|
|
562
|
+
except (TypeError, AttributeError):
|
|
563
|
+
return False
|
|
564
|
+
|
|
565
|
+
def is_field(self, proof=True):
|
|
566
|
+
"""
|
|
567
|
+
Return ``True`` if this ring is a field.
|
|
568
|
+
|
|
569
|
+
INPUT:
|
|
570
|
+
|
|
571
|
+
- ``proof`` -- boolean (default: ``True``); determines what to do in
|
|
572
|
+
unknown cases
|
|
573
|
+
|
|
574
|
+
ALGORITHM:
|
|
575
|
+
|
|
576
|
+
If the parameter ``proof`` is set to ``True``, the returned value is
|
|
577
|
+
correct but the method might throw an error. Otherwise, if it is set
|
|
578
|
+
to ``False``, the method returns ``True`` if it can establish that
|
|
579
|
+
``self`` is a field and ``False`` otherwise.
|
|
580
|
+
|
|
581
|
+
EXAMPLES::
|
|
582
|
+
|
|
583
|
+
sage: QQ.is_field()
|
|
584
|
+
True
|
|
585
|
+
sage: GF(9, 'a').is_field() # needs sage.rings.finite_rings
|
|
586
|
+
True
|
|
587
|
+
sage: ZZ.is_field()
|
|
588
|
+
False
|
|
589
|
+
sage: QQ['x'].is_field()
|
|
590
|
+
False
|
|
591
|
+
sage: Frac(QQ['x']).is_field()
|
|
592
|
+
True
|
|
593
|
+
|
|
594
|
+
This illustrates the use of the ``proof`` parameter::
|
|
595
|
+
|
|
596
|
+
sage: R.<a,b> = QQ[]
|
|
597
|
+
sage: S.<x,y> = R.quo((b^3)) # needs sage.libs.singular
|
|
598
|
+
sage: S.is_field(proof=True) # needs sage.libs.singular
|
|
599
|
+
Traceback (most recent call last):
|
|
600
|
+
...
|
|
601
|
+
NotImplementedError
|
|
602
|
+
sage: S.is_field(proof=False) # needs sage.libs.singular
|
|
603
|
+
False
|
|
604
|
+
"""
|
|
605
|
+
if self.is_zero():
|
|
606
|
+
return False
|
|
607
|
+
|
|
608
|
+
if proof:
|
|
609
|
+
raise NotImplementedError("No way to prove that %s is an integral domain!" % self)
|
|
610
|
+
else:
|
|
611
|
+
return False
|
|
612
|
+
|
|
613
|
+
def zeta(self, n=2, all=False):
|
|
614
|
+
"""
|
|
615
|
+
Return a primitive ``n``-th root of unity in ``self`` if there
|
|
616
|
+
is one, or raise a :exc:`ValueError` otherwise.
|
|
617
|
+
|
|
618
|
+
INPUT:
|
|
619
|
+
|
|
620
|
+
- ``n`` -- positive integer
|
|
621
|
+
|
|
622
|
+
- ``all`` -- boolean (default: ``False``); whether to return
|
|
623
|
+
a list of all primitive `n`-th roots of unity. If ``True``, raise a
|
|
624
|
+
:exc:`ValueError` if ``self`` is not an integral domain.
|
|
625
|
+
|
|
626
|
+
OUTPUT: element of ``self`` of finite order
|
|
627
|
+
|
|
628
|
+
EXAMPLES::
|
|
629
|
+
|
|
630
|
+
sage: QQ.zeta()
|
|
631
|
+
-1
|
|
632
|
+
sage: QQ.zeta(1)
|
|
633
|
+
1
|
|
634
|
+
sage: CyclotomicField(6).zeta(6) # needs sage.rings.number_field
|
|
635
|
+
zeta6
|
|
636
|
+
sage: CyclotomicField(3).zeta(3) # needs sage.rings.number_field
|
|
637
|
+
zeta3
|
|
638
|
+
sage: CyclotomicField(3).zeta(3).multiplicative_order() # needs sage.rings.number_field
|
|
639
|
+
3
|
|
640
|
+
|
|
641
|
+
sage: # needs sage.rings.finite_rings
|
|
642
|
+
sage: a = GF(7).zeta(); a
|
|
643
|
+
3
|
|
644
|
+
sage: a.multiplicative_order()
|
|
645
|
+
6
|
|
646
|
+
sage: a = GF(49,'z').zeta(); a
|
|
647
|
+
z
|
|
648
|
+
sage: a.multiplicative_order()
|
|
649
|
+
48
|
|
650
|
+
sage: a = GF(49,'z').zeta(2); a
|
|
651
|
+
6
|
|
652
|
+
sage: a.multiplicative_order()
|
|
653
|
+
2
|
|
654
|
+
|
|
655
|
+
sage: QQ.zeta(3)
|
|
656
|
+
Traceback (most recent call last):
|
|
657
|
+
...
|
|
658
|
+
ValueError: no n-th root of unity in rational field
|
|
659
|
+
sage: Zp(7, prec=8).zeta() # needs sage.rings.padics
|
|
660
|
+
3 + 4*7 + 6*7^2 + 3*7^3 + 2*7^5 + 6*7^6 + 2*7^7 + O(7^8)
|
|
661
|
+
|
|
662
|
+
TESTS::
|
|
663
|
+
|
|
664
|
+
sage: R.<x> = QQ[]
|
|
665
|
+
sage: R.zeta(1)
|
|
666
|
+
1
|
|
667
|
+
sage: R.zeta(2)
|
|
668
|
+
-1
|
|
669
|
+
sage: R.zeta(3) # needs sage.libs.pari
|
|
670
|
+
Traceback (most recent call last):
|
|
671
|
+
...
|
|
672
|
+
ValueError: no 3rd root of unity in Univariate Polynomial Ring in x over Rational Field
|
|
673
|
+
sage: IntegerModRing(8).zeta(2, all = True)
|
|
674
|
+
Traceback (most recent call last):
|
|
675
|
+
...
|
|
676
|
+
ValueError: ring is not an integral domain
|
|
677
|
+
"""
|
|
678
|
+
if all and not self.is_integral_domain():
|
|
679
|
+
raise ValueError("ring is not an integral domain")
|
|
680
|
+
if n == 2:
|
|
681
|
+
if all:
|
|
682
|
+
return [self(-1)]
|
|
683
|
+
else:
|
|
684
|
+
return self(-1)
|
|
685
|
+
elif n == 1:
|
|
686
|
+
if all:
|
|
687
|
+
return [self(1)]
|
|
688
|
+
else:
|
|
689
|
+
return self(1)
|
|
690
|
+
else:
|
|
691
|
+
f = self['x'].cyclotomic_polynomial(n)
|
|
692
|
+
if all:
|
|
693
|
+
return [-P[0] for P, e in f.factor() if P.degree() == 1]
|
|
694
|
+
for P, e in f.factor():
|
|
695
|
+
if P.degree() == 1:
|
|
696
|
+
return -P[0]
|
|
697
|
+
from sage.rings.integer_ring import ZZ
|
|
698
|
+
raise ValueError("no %s root of unity in %r" % (ZZ(n).ordinal_str(), self))
|
|
699
|
+
|
|
700
|
+
def zeta_order(self):
|
|
701
|
+
"""
|
|
702
|
+
Return the order of the distinguished root of unity in ``self``.
|
|
703
|
+
|
|
704
|
+
EXAMPLES::
|
|
705
|
+
|
|
706
|
+
sage: CyclotomicField(19).zeta_order() # needs sage.rings.number_field
|
|
707
|
+
38
|
|
708
|
+
sage: GF(19).zeta_order()
|
|
709
|
+
18
|
|
710
|
+
sage: GF(5^3,'a').zeta_order() # needs sage.rings.finite_rings
|
|
711
|
+
124
|
|
712
|
+
sage: Zp(7, prec=8).zeta_order() # needs sage.rings.padics
|
|
713
|
+
6
|
|
714
|
+
"""
|
|
715
|
+
return self.zeta().multiplicative_order()
|
|
716
|
+
|
|
717
|
+
def localization(self, *args, **kwds):
|
|
718
|
+
"""
|
|
719
|
+
Return the localization of ``self``.
|
|
720
|
+
|
|
721
|
+
This only works for integral domains.
|
|
722
|
+
|
|
723
|
+
EXAMPLES::
|
|
724
|
+
|
|
725
|
+
sage: R = Zmod(6)
|
|
726
|
+
sage: R.localization((4))
|
|
727
|
+
Traceback (most recent call last):
|
|
728
|
+
...
|
|
729
|
+
TypeError: self must be an integral domain
|
|
730
|
+
"""
|
|
731
|
+
raise TypeError("self must be an integral domain")
|
|
732
|
+
|
|
733
|
+
def bracket(self, x, y):
|
|
734
|
+
"""
|
|
735
|
+
Return the Lie bracket `[x, y] = x y - y x` of `x` and `y`.
|
|
736
|
+
|
|
737
|
+
INPUT:
|
|
738
|
+
|
|
739
|
+
- ``x``, ``y`` -- elements of ``self``
|
|
740
|
+
|
|
741
|
+
EXAMPLES::
|
|
742
|
+
|
|
743
|
+
sage: # needs sage.combinat sage.modules
|
|
744
|
+
sage: F = AlgebrasWithBasis(QQ).example()
|
|
745
|
+
sage: F
|
|
746
|
+
An example of an algebra with basis:
|
|
747
|
+
the free algebra on the generators ('a', 'b', 'c') over Rational Field
|
|
748
|
+
sage: a, b, c = F.algebra_generators()
|
|
749
|
+
sage: F.bracket(a, b)
|
|
750
|
+
B[word: ab] - B[word: ba]
|
|
751
|
+
|
|
752
|
+
This measures the default of commutation between `x` and `y`.
|
|
753
|
+
`F` endowed with the bracket operation is a Lie algebra;
|
|
754
|
+
in particular, it satisfies Jacobi's identity::
|
|
755
|
+
|
|
756
|
+
sage: (F.bracket(F.bracket(a,b), c) + F.bracket(F.bracket(b,c), a) # needs sage.combinat sage.modules
|
|
757
|
+
....: + F.bracket(F.bracket(c,a), b))
|
|
758
|
+
0
|
|
759
|
+
"""
|
|
760
|
+
return x * y - y * x
|
|
761
|
+
|
|
762
|
+
def _Hom_(self, Y, category):
|
|
763
|
+
r"""
|
|
764
|
+
Return the homset from ``self`` to ``Y`` in the category ``category``.
|
|
765
|
+
|
|
766
|
+
INPUT:
|
|
767
|
+
|
|
768
|
+
- ``Y`` -- a ring
|
|
769
|
+
- ``category`` -- a subcategory of :class:`Rings()
|
|
770
|
+
<Rings>` or ``None``
|
|
771
|
+
|
|
772
|
+
The sole purpose of this method is to construct the homset
|
|
773
|
+
as a :class:`~sage.rings.homset.RingHomset`. If
|
|
774
|
+
``category`` is specified and is not a subcategory of
|
|
775
|
+
:class:`Rings() <Rings>`, a :exc:`TypeError` is raised instead
|
|
776
|
+
|
|
777
|
+
This method is not meant to be called directly. Please use
|
|
778
|
+
:func:`sage.categories.homset.Hom` instead.
|
|
779
|
+
|
|
780
|
+
EXAMPLES::
|
|
781
|
+
|
|
782
|
+
sage: H = QQ._Hom_(QQ, category=Rings()); H
|
|
783
|
+
Set of Homomorphisms from Rational Field to Rational Field
|
|
784
|
+
sage: H.__class__
|
|
785
|
+
<class 'sage.rings.homset.RingHomset_generic_with_category'>
|
|
786
|
+
|
|
787
|
+
TESTS::
|
|
788
|
+
|
|
789
|
+
sage: Hom(QQ, QQ, category=Rings()).__class__
|
|
790
|
+
<class 'sage.rings.homset.RingHomset_generic_with_category'>
|
|
791
|
+
|
|
792
|
+
sage: Hom(CyclotomicField(3), QQ, category=Rings()).__class__ # needs sage.rings.number_field
|
|
793
|
+
<class 'sage.rings.number_field.homset.CyclotomicFieldHomset_with_category'>
|
|
794
|
+
|
|
795
|
+
sage: TestSuite(Hom(QQ, QQ, category=Rings())).run() # indirect doctest
|
|
796
|
+
"""
|
|
797
|
+
if category is not None and not category.is_subcategory(Rings()):
|
|
798
|
+
raise TypeError(f"{category} is not a subcategory of Rings()")
|
|
799
|
+
if Y not in Rings():
|
|
800
|
+
raise TypeError(f"{Y} is not a ring")
|
|
801
|
+
from sage.rings.homset import RingHomset
|
|
802
|
+
return RingHomset(self, Y, category=category)
|
|
803
|
+
|
|
804
|
+
# this is already in sage.rings.ring.Ring,
|
|
805
|
+
# but not all rings descend from that class,
|
|
806
|
+
# e.g., matrix spaces.
|
|
807
|
+
def _mul_(self, x, switch_sides=False):
|
|
808
|
+
"""
|
|
809
|
+
Multiplication of rings with, e.g., lists.
|
|
810
|
+
|
|
811
|
+
.. NOTE::
|
|
812
|
+
|
|
813
|
+
This method is used to create ideals. It is the same
|
|
814
|
+
as the multiplication method for
|
|
815
|
+
:class:`~sage.rings.ring.Ring`. However, not all
|
|
816
|
+
parents that belong to the category of rings also
|
|
817
|
+
inherits from the base class of rings. Therefore, we
|
|
818
|
+
implemented a ``__mul__`` method for parents, that
|
|
819
|
+
calls a ``_mul_`` method implemented here. See :issue:`7797`.
|
|
820
|
+
|
|
821
|
+
INPUT:
|
|
822
|
+
|
|
823
|
+
- ``x``, an object to multiply with.
|
|
824
|
+
- ``switch_sides`` (optional bool): If ``False``,
|
|
825
|
+
the product is ``self*x``; if ``True``, the
|
|
826
|
+
product is ``x*self``.
|
|
827
|
+
|
|
828
|
+
EXAMPLES:
|
|
829
|
+
|
|
830
|
+
As we mentioned above, this method is called
|
|
831
|
+
when a ring is involved that does not inherit
|
|
832
|
+
from the base class of rings. This is the case,
|
|
833
|
+
e.g., for matrix algebras::
|
|
834
|
+
|
|
835
|
+
sage: # needs sage.modules
|
|
836
|
+
sage: MS = MatrixSpace(QQ, 2, 2)
|
|
837
|
+
sage: isinstance(MS, Ring)
|
|
838
|
+
False
|
|
839
|
+
sage: MS in Rings()
|
|
840
|
+
True
|
|
841
|
+
sage: MS * 2 # indirect doctest
|
|
842
|
+
Left Ideal
|
|
843
|
+
(
|
|
844
|
+
[2 0]
|
|
845
|
+
[0 2]
|
|
846
|
+
)
|
|
847
|
+
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
848
|
+
|
|
849
|
+
In the next example, the ring and the other factor switch sides
|
|
850
|
+
in the product::
|
|
851
|
+
|
|
852
|
+
sage: [MS.2] * MS # needs sage.modules
|
|
853
|
+
Right Ideal
|
|
854
|
+
(
|
|
855
|
+
[0 0]
|
|
856
|
+
[1 0]
|
|
857
|
+
)
|
|
858
|
+
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
859
|
+
|
|
860
|
+
AUTHOR:
|
|
861
|
+
|
|
862
|
+
- Simon King (2011-03-22)
|
|
863
|
+
"""
|
|
864
|
+
try:
|
|
865
|
+
if self.is_commutative():
|
|
866
|
+
return self.ideal(x)
|
|
867
|
+
except (AttributeError, NotImplementedError):
|
|
868
|
+
pass
|
|
869
|
+
try:
|
|
870
|
+
side = x.side()
|
|
871
|
+
except AttributeError:
|
|
872
|
+
return self.ideal(x, side='right' if switch_sides else 'left')
|
|
873
|
+
# presumably x is an ideal...
|
|
874
|
+
try:
|
|
875
|
+
x = x.gens()
|
|
876
|
+
except (AttributeError, NotImplementedError):
|
|
877
|
+
pass # ... not an ideal
|
|
878
|
+
if switch_sides:
|
|
879
|
+
if side in ['right', 'twosided']:
|
|
880
|
+
return self.ideal(x, side=side)
|
|
881
|
+
elif side == 'left':
|
|
882
|
+
return self.ideal(x, side='twosided')
|
|
883
|
+
else:
|
|
884
|
+
if side in ['left', 'twosided']:
|
|
885
|
+
return self.ideal(x, side=side)
|
|
886
|
+
elif side == 'right':
|
|
887
|
+
return self.ideal(x, side='twosided')
|
|
888
|
+
# duck typing failed
|
|
889
|
+
raise TypeError("do not know how to transform %s into an ideal of %s" % (x, self))
|
|
890
|
+
|
|
891
|
+
def __pow__(self, n):
|
|
892
|
+
"""
|
|
893
|
+
Return the free module of rank `n` over this ring. If n is a tuple of
|
|
894
|
+
two elements, creates a matrix space.
|
|
895
|
+
|
|
896
|
+
EXAMPLES::
|
|
897
|
+
|
|
898
|
+
sage: QQ^5 # needs sage.modules
|
|
899
|
+
Vector space of dimension 5 over Rational Field
|
|
900
|
+
sage: Integers(20)^1000 # needs sage.modules
|
|
901
|
+
Ambient free module of rank 1000 over Ring of integers modulo 20
|
|
902
|
+
|
|
903
|
+
sage: QQ^(2, 3) # needs sage.modules
|
|
904
|
+
Full MatrixSpace of 2 by 3 dense matrices over Rational Field
|
|
905
|
+
"""
|
|
906
|
+
if isinstance(n, tuple):
|
|
907
|
+
m, n = n
|
|
908
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
909
|
+
return MatrixSpace(self, m, n)
|
|
910
|
+
else:
|
|
911
|
+
from sage.modules.free_module import FreeModule
|
|
912
|
+
return FreeModule(self, n)
|
|
913
|
+
|
|
914
|
+
def nilradical(self):
|
|
915
|
+
"""
|
|
916
|
+
Return the nilradical of this ring.
|
|
917
|
+
|
|
918
|
+
EXAMPLES::
|
|
919
|
+
|
|
920
|
+
sage: QQ['x,y'].nilradical() # needs sage.libs.singular
|
|
921
|
+
Ideal (0) of Multivariate Polynomial Ring in x, y over Rational Field
|
|
922
|
+
|
|
923
|
+
.. SEEALSO::
|
|
924
|
+
|
|
925
|
+
:meth:`~sage.categories.finite_dimensional_lie_algebras_with_basis.FiniteDimensionalLieAlgebrasWithBasis.ParentMethods.nilradical`
|
|
926
|
+
"""
|
|
927
|
+
return self.zero_ideal().radical()
|
|
928
|
+
|
|
929
|
+
@cached_method
|
|
930
|
+
def unit_ideal(self):
|
|
931
|
+
"""
|
|
932
|
+
Return the unit ideal of this ring.
|
|
933
|
+
|
|
934
|
+
EXAMPLES::
|
|
935
|
+
|
|
936
|
+
sage: Zp(7).unit_ideal() # needs sage.rings.padics
|
|
937
|
+
Principal ideal (1 + O(7^20)) of 7-adic Ring with capped relative precision 20
|
|
938
|
+
"""
|
|
939
|
+
return self._ideal_class_(1)(self, [self.one()])
|
|
940
|
+
|
|
941
|
+
def characteristic(self):
|
|
942
|
+
"""
|
|
943
|
+
Return the characteristic of this ring.
|
|
944
|
+
|
|
945
|
+
EXAMPLES::
|
|
946
|
+
|
|
947
|
+
sage: QQ.characteristic()
|
|
948
|
+
0
|
|
949
|
+
sage: GF(19).characteristic()
|
|
950
|
+
19
|
|
951
|
+
sage: Integers(8).characteristic()
|
|
952
|
+
8
|
|
953
|
+
sage: Zp(5).characteristic() # needs sage.rings.padics
|
|
954
|
+
0
|
|
955
|
+
"""
|
|
956
|
+
from sage.rings.infinity import infinity
|
|
957
|
+
from sage.rings.integer_ring import ZZ
|
|
958
|
+
order_1 = self.one().additive_order()
|
|
959
|
+
return ZZ.zero() if order_1 is infinity else order_1
|
|
960
|
+
|
|
961
|
+
def _test_characteristic(self, **options):
|
|
962
|
+
"""
|
|
963
|
+
Run generic tests on the method :meth:`characteristic`.
|
|
964
|
+
|
|
965
|
+
See also: :class:`TestSuite`.
|
|
966
|
+
|
|
967
|
+
EXAMPLES::
|
|
968
|
+
|
|
969
|
+
sage: ZZ._test_characteristic()
|
|
970
|
+
"""
|
|
971
|
+
tester = self._tester(**options)
|
|
972
|
+
try:
|
|
973
|
+
characteristic = self.characteristic()
|
|
974
|
+
except AttributeError:
|
|
975
|
+
# raised when self.one() does not have a additive_order()
|
|
976
|
+
return
|
|
977
|
+
except NotImplementedError:
|
|
978
|
+
return
|
|
979
|
+
|
|
980
|
+
# test that #12988 is fixed
|
|
981
|
+
from sage.rings.integer import Integer
|
|
982
|
+
tester.assertIsInstance(characteristic, Integer)
|
|
983
|
+
|
|
984
|
+
def ideal(self, *args, **kwds):
|
|
985
|
+
"""
|
|
986
|
+
Create an ideal of this ring.
|
|
987
|
+
|
|
988
|
+
INPUT:
|
|
989
|
+
|
|
990
|
+
- an element or a list/tuple/sequence of elements, the generators
|
|
991
|
+
|
|
992
|
+
- ``coerce`` -- boolean (default: ``True``); whether to first coerce
|
|
993
|
+
the elements into this ring. This must be a keyword
|
|
994
|
+
argument. Only set it to ``False`` if you are certain that each
|
|
995
|
+
generator is already in the ring.
|
|
996
|
+
|
|
997
|
+
- ``ideal_class`` -- callable (default: ``self._ideal_class_()``);
|
|
998
|
+
this must be a keyword argument. A constructor for ideals, taking
|
|
999
|
+
the ring as the first argument and then the generators.
|
|
1000
|
+
Usually a subclass of :class:`~sage.rings.ideal.Ideal_generic` or
|
|
1001
|
+
:class:`~sage.rings.noncommutative_ideals.Ideal_nc`.
|
|
1002
|
+
|
|
1003
|
+
- Further named arguments (such as ``side`` in the case of
|
|
1004
|
+
non-commutative rings) are forwarded to the ideal class.
|
|
1005
|
+
|
|
1006
|
+
The keyword ``side`` can be one of ``'twosided'``,
|
|
1007
|
+
``'left'``, ``'right'``. It determines whether
|
|
1008
|
+
the resulting ideal is twosided, a left ideal or a right ideal.
|
|
1009
|
+
|
|
1010
|
+
EXAMPLES:
|
|
1011
|
+
|
|
1012
|
+
Matrix rings::
|
|
1013
|
+
|
|
1014
|
+
sage: # needs sage.modules
|
|
1015
|
+
sage: MS = MatrixSpace(QQ, 2, 2)
|
|
1016
|
+
sage: MS.ideal(2)
|
|
1017
|
+
Twosided Ideal
|
|
1018
|
+
(
|
|
1019
|
+
[2 0]
|
|
1020
|
+
[0 2]
|
|
1021
|
+
)
|
|
1022
|
+
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
1023
|
+
sage: MS.ideal([MS.0, MS.1], side='right')
|
|
1024
|
+
Right Ideal
|
|
1025
|
+
(
|
|
1026
|
+
[1 0]
|
|
1027
|
+
[0 0],
|
|
1028
|
+
<BLANKLINE>
|
|
1029
|
+
[0 1]
|
|
1030
|
+
[0 0]
|
|
1031
|
+
)
|
|
1032
|
+
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
1033
|
+
|
|
1034
|
+
Polynomial rings::
|
|
1035
|
+
|
|
1036
|
+
sage: R.<x,y> = QQ[]
|
|
1037
|
+
sage: R.ideal(x,y)
|
|
1038
|
+
Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field
|
|
1039
|
+
sage: R.ideal(x+y^2)
|
|
1040
|
+
Ideal (y^2 + x) of Multivariate Polynomial Ring in x, y over Rational Field
|
|
1041
|
+
sage: R.ideal( [x^3,y^3+x^3] )
|
|
1042
|
+
Ideal (x^3, x^3 + y^3) of Multivariate Polynomial Ring in x, y over Rational Field
|
|
1043
|
+
|
|
1044
|
+
Non-commutative rings::
|
|
1045
|
+
|
|
1046
|
+
sage: A = SteenrodAlgebra(2) # needs sage.combinat sage.modules
|
|
1047
|
+
sage: A.ideal(A.1, A.2^2) # needs sage.combinat sage.modules
|
|
1048
|
+
Twosided Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis
|
|
1049
|
+
sage: A.ideal(A.1, A.2^2, side='left') # needs sage.combinat sage.modules
|
|
1050
|
+
Left Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis
|
|
1051
|
+
|
|
1052
|
+
TESTS:
|
|
1053
|
+
|
|
1054
|
+
Make sure that :issue:`11139` is fixed::
|
|
1055
|
+
|
|
1056
|
+
sage: R.<x> = QQ[]
|
|
1057
|
+
sage: R.ideal([])
|
|
1058
|
+
Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field
|
|
1059
|
+
sage: R.ideal(())
|
|
1060
|
+
Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field
|
|
1061
|
+
sage: R.ideal()
|
|
1062
|
+
Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field
|
|
1063
|
+
|
|
1064
|
+
Check ``ideal_class=`` keyword argument when input is empty::
|
|
1065
|
+
|
|
1066
|
+
sage: from sage.rings.ideal import Ideal_pid
|
|
1067
|
+
sage: class CustomIdealClass(Ideal_pid):
|
|
1068
|
+
....: pass
|
|
1069
|
+
sage: type(ZZ.ideal(6))
|
|
1070
|
+
<class 'sage.rings.ideal.Ideal_pid'>
|
|
1071
|
+
sage: type(ZZ.ideal(6, ideal_class=CustomIdealClass))
|
|
1072
|
+
<class '...CustomIdealClass'>
|
|
1073
|
+
sage: type(ZZ.ideal())
|
|
1074
|
+
<class 'sage.rings.ideal.Ideal_pid'>
|
|
1075
|
+
sage: type(ZZ.ideal(ideal_class=CustomIdealClass))
|
|
1076
|
+
<class '...CustomIdealClass'>
|
|
1077
|
+
sage: type(ZZ.ideal((), ideal_class=CustomIdealClass))
|
|
1078
|
+
<class '...CustomIdealClass'>
|
|
1079
|
+
"""
|
|
1080
|
+
if 'coerce' in kwds:
|
|
1081
|
+
coerce = kwds['coerce']
|
|
1082
|
+
del kwds['coerce']
|
|
1083
|
+
else:
|
|
1084
|
+
coerce = True
|
|
1085
|
+
|
|
1086
|
+
from sage.rings.ideal import Ideal_generic
|
|
1087
|
+
if not args:
|
|
1088
|
+
gens = [self(0)]
|
|
1089
|
+
else:
|
|
1090
|
+
gens = args
|
|
1091
|
+
while isinstance(gens, (list, tuple, GeneratorType)) and len(gens) == 1:
|
|
1092
|
+
first = gens[0]
|
|
1093
|
+
if isinstance(first, Ideal_generic):
|
|
1094
|
+
R = first.ring()
|
|
1095
|
+
m = self.convert_map_from(R)
|
|
1096
|
+
if m is not None:
|
|
1097
|
+
gens = [m(g) for g in first.gens()]
|
|
1098
|
+
coerce = False
|
|
1099
|
+
else:
|
|
1100
|
+
m = R.convert_map_from(self)
|
|
1101
|
+
if m is not None:
|
|
1102
|
+
raise NotImplementedError
|
|
1103
|
+
else:
|
|
1104
|
+
raise TypeError
|
|
1105
|
+
break
|
|
1106
|
+
elif isinstance(first, (list, tuple, GeneratorType)):
|
|
1107
|
+
gens = first
|
|
1108
|
+
else:
|
|
1109
|
+
break
|
|
1110
|
+
|
|
1111
|
+
if not gens:
|
|
1112
|
+
gens = [self.zero()]
|
|
1113
|
+
elif coerce:
|
|
1114
|
+
gens = [self(g) for g in gens]
|
|
1115
|
+
|
|
1116
|
+
from sage.categories.principal_ideal_domains import PrincipalIdealDomains
|
|
1117
|
+
if self in PrincipalIdealDomains():
|
|
1118
|
+
# Use GCD algorithm to obtain a principal ideal
|
|
1119
|
+
g = gens[0]
|
|
1120
|
+
if len(gens) == 1:
|
|
1121
|
+
try:
|
|
1122
|
+
# note: we set g = gcd(g, g) to "canonicalize" the generator:
|
|
1123
|
+
# make polynomials monic, etc.
|
|
1124
|
+
g = g.gcd(g)
|
|
1125
|
+
except (AttributeError, NotImplementedError, IndexError):
|
|
1126
|
+
pass
|
|
1127
|
+
else:
|
|
1128
|
+
for h in gens[1:]:
|
|
1129
|
+
g = g.gcd(h)
|
|
1130
|
+
gens = [g]
|
|
1131
|
+
if 'ideal_class' in kwds:
|
|
1132
|
+
C = kwds['ideal_class']
|
|
1133
|
+
del kwds['ideal_class']
|
|
1134
|
+
else:
|
|
1135
|
+
C = self._ideal_class_(len(gens))
|
|
1136
|
+
if len(gens) == 1 and isinstance(gens[0], (list, tuple)):
|
|
1137
|
+
gens = gens[0]
|
|
1138
|
+
return C(self, gens, **kwds)
|
|
1139
|
+
|
|
1140
|
+
# Quotient rings
|
|
1141
|
+
def quotient(self, I, names=None, **kwds):
|
|
1142
|
+
"""
|
|
1143
|
+
Quotient of a ring by a two-sided ideal.
|
|
1144
|
+
|
|
1145
|
+
INPUT:
|
|
1146
|
+
|
|
1147
|
+
- ``I`` -- a twosided ideal of this ring
|
|
1148
|
+
- ``names`` -- (optional) names of the generators of the quotient (if
|
|
1149
|
+
there are multiple generators, you can specify a single character
|
|
1150
|
+
string and the generators are named in sequence starting with 0).
|
|
1151
|
+
- further named arguments that may be passed to the
|
|
1152
|
+
quotient ring constructor.
|
|
1153
|
+
|
|
1154
|
+
EXAMPLES:
|
|
1155
|
+
|
|
1156
|
+
Usually, a ring inherits a method :meth:`sage.rings.ring.Ring.quotient`.
|
|
1157
|
+
So, we need a bit of effort to make the following example work with the
|
|
1158
|
+
category framework::
|
|
1159
|
+
|
|
1160
|
+
sage: # needs sage.combinat sage.modules
|
|
1161
|
+
sage: F.<x,y,z> = FreeAlgebra(QQ)
|
|
1162
|
+
sage: from sage.rings.noncommutative_ideals import Ideal_nc
|
|
1163
|
+
sage: from itertools import product
|
|
1164
|
+
sage: class PowerIdeal(Ideal_nc):
|
|
1165
|
+
....: def __init__(self, R, n):
|
|
1166
|
+
....: self._power = n
|
|
1167
|
+
....: Ideal_nc.__init__(self, R, [R.prod(m)
|
|
1168
|
+
....: for m in product(R.gens(), repeat=n)])
|
|
1169
|
+
....: def reduce(self, x):
|
|
1170
|
+
....: R = self.ring()
|
|
1171
|
+
....: return add([c*R(m) for m, c in x
|
|
1172
|
+
....: if len(m) < self._power], R(0))
|
|
1173
|
+
sage: I = PowerIdeal(F, 3)
|
|
1174
|
+
sage: Q = Rings().parent_class.quotient(F, I); Q
|
|
1175
|
+
Quotient of Free Algebra on 3 generators (x, y, z) over Rational Field
|
|
1176
|
+
by the ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x,
|
|
1177
|
+
x*z*y, x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3,
|
|
1178
|
+
y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y, z*x*z,
|
|
1179
|
+
z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3)
|
|
1180
|
+
sage: Q.0
|
|
1181
|
+
xbar
|
|
1182
|
+
sage: Q.1
|
|
1183
|
+
ybar
|
|
1184
|
+
sage: Q.2
|
|
1185
|
+
zbar
|
|
1186
|
+
sage: Q.0*Q.1
|
|
1187
|
+
xbar*ybar
|
|
1188
|
+
sage: Q.0*Q.1*Q.0
|
|
1189
|
+
0
|
|
1190
|
+
|
|
1191
|
+
An example with polynomial rings::
|
|
1192
|
+
|
|
1193
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
|
1194
|
+
sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2])
|
|
1195
|
+
sage: S = R.quotient(I, 'a')
|
|
1196
|
+
sage: S.gens()
|
|
1197
|
+
(a,)
|
|
1198
|
+
|
|
1199
|
+
sage: # needs sage.libs.singular
|
|
1200
|
+
sage: R.<x,y> = PolynomialRing(QQ, 2)
|
|
1201
|
+
sage: S.<a,b> = R.quotient((x^2, y))
|
|
1202
|
+
sage: S
|
|
1203
|
+
Quotient of Multivariate Polynomial Ring in x, y over Rational Field
|
|
1204
|
+
by the ideal (x^2, y)
|
|
1205
|
+
sage: S.gens()
|
|
1206
|
+
(a, 0)
|
|
1207
|
+
sage: a == b
|
|
1208
|
+
False
|
|
1209
|
+
"""
|
|
1210
|
+
from sage.rings.quotient_ring import QuotientRing
|
|
1211
|
+
return QuotientRing(self, I, names=names, **kwds)
|
|
1212
|
+
|
|
1213
|
+
def quo(self, I, names=None, **kwds):
|
|
1214
|
+
"""
|
|
1215
|
+
Quotient of a ring by a two-sided ideal.
|
|
1216
|
+
|
|
1217
|
+
.. NOTE::
|
|
1218
|
+
|
|
1219
|
+
This is a synonym for :meth:`quotient`.
|
|
1220
|
+
|
|
1221
|
+
EXAMPLES::
|
|
1222
|
+
|
|
1223
|
+
sage: MS = MatrixSpace(QQ, 2) # needs sage.modules
|
|
1224
|
+
sage: I = MS * MS.gens() * MS # needs sage.modules
|
|
1225
|
+
|
|
1226
|
+
``MS`` is not an instance of :class:`~sage.rings.ring.Ring`.
|
|
1227
|
+
|
|
1228
|
+
However it is an instance of the parent class of the
|
|
1229
|
+
category of rings. The quotient method is inherited from
|
|
1230
|
+
there::
|
|
1231
|
+
|
|
1232
|
+
sage: isinstance(MS, sage.rings.ring.Ring) # needs sage.modules
|
|
1233
|
+
False
|
|
1234
|
+
sage: isinstance(MS, Rings().parent_class) # needs sage.modules
|
|
1235
|
+
True
|
|
1236
|
+
sage: MS.quo(I, names=['a','b','c','d']) # needs sage.modules
|
|
1237
|
+
Quotient of Full MatrixSpace of 2 by 2 dense matrices
|
|
1238
|
+
over Rational Field by the ideal
|
|
1239
|
+
(
|
|
1240
|
+
[1 0]
|
|
1241
|
+
[0 0],
|
|
1242
|
+
<BLANKLINE>
|
|
1243
|
+
[0 1]
|
|
1244
|
+
[0 0],
|
|
1245
|
+
<BLANKLINE>
|
|
1246
|
+
[0 0]
|
|
1247
|
+
[1 0],
|
|
1248
|
+
<BLANKLINE>
|
|
1249
|
+
[0 0]
|
|
1250
|
+
[0 1]
|
|
1251
|
+
)
|
|
1252
|
+
|
|
1253
|
+
A test with a subclass of :class:`~sage.rings.ring.Ring`::
|
|
1254
|
+
|
|
1255
|
+
sage: # needs sage.libs.singular
|
|
1256
|
+
sage: R.<x,y> = PolynomialRing(QQ, 2)
|
|
1257
|
+
sage: S.<a,b> = R.quo((x^2, y))
|
|
1258
|
+
sage: S
|
|
1259
|
+
Quotient of Multivariate Polynomial Ring in x, y over Rational Field
|
|
1260
|
+
by the ideal (x^2, y)
|
|
1261
|
+
sage: S.gens()
|
|
1262
|
+
(a, 0)
|
|
1263
|
+
sage: a == b
|
|
1264
|
+
False
|
|
1265
|
+
"""
|
|
1266
|
+
return self.quotient(I, names=names, **kwds)
|
|
1267
|
+
|
|
1268
|
+
def quotient_ring(self, I, names=None, **kwds):
|
|
1269
|
+
"""
|
|
1270
|
+
Quotient of a ring by a two-sided ideal.
|
|
1271
|
+
|
|
1272
|
+
.. NOTE::
|
|
1273
|
+
|
|
1274
|
+
This is a synonym for :meth:`quotient`.
|
|
1275
|
+
|
|
1276
|
+
INPUT:
|
|
1277
|
+
|
|
1278
|
+
- ``I`` -- an ideal of `R`
|
|
1279
|
+
|
|
1280
|
+
- ``names`` -- (optional) names of the generators of the quotient. (If
|
|
1281
|
+
there are multiple generators, you can specify a single character
|
|
1282
|
+
string and the generators are named in sequence starting with 0.)
|
|
1283
|
+
|
|
1284
|
+
- further named arguments that may be passed to the quotient ring
|
|
1285
|
+
constructor.
|
|
1286
|
+
|
|
1287
|
+
OUTPUT: ``R/I`` -- the quotient ring of `R` by the ideal `I`
|
|
1288
|
+
|
|
1289
|
+
EXAMPLES::
|
|
1290
|
+
|
|
1291
|
+
sage: MS = MatrixSpace(QQ, 2) # needs sage.modules
|
|
1292
|
+
sage: I = MS * MS.gens() * MS # needs sage.modules
|
|
1293
|
+
|
|
1294
|
+
``MS`` is not an instance of :class:`~sage.rings.ring.Ring`,
|
|
1295
|
+
but it is an instance of the parent class of the category of
|
|
1296
|
+
rings. The quotient method is inherited from there::
|
|
1297
|
+
|
|
1298
|
+
sage: isinstance(MS, sage.rings.ring.Ring) # needs sage.modules
|
|
1299
|
+
False
|
|
1300
|
+
sage: isinstance(MS, Rings().parent_class) # needs sage.modules
|
|
1301
|
+
True
|
|
1302
|
+
sage: MS.quotient_ring(I, names=['a','b','c','d']) # needs sage.modules
|
|
1303
|
+
Quotient of Full MatrixSpace of 2 by 2 dense matrices
|
|
1304
|
+
over Rational Field by the ideal
|
|
1305
|
+
(
|
|
1306
|
+
[1 0]
|
|
1307
|
+
[0 0],
|
|
1308
|
+
<BLANKLINE>
|
|
1309
|
+
[0 1]
|
|
1310
|
+
[0 0],
|
|
1311
|
+
<BLANKLINE>
|
|
1312
|
+
[0 0]
|
|
1313
|
+
[1 0],
|
|
1314
|
+
<BLANKLINE>
|
|
1315
|
+
[0 0]
|
|
1316
|
+
[0 1]
|
|
1317
|
+
)
|
|
1318
|
+
|
|
1319
|
+
A test with a subclass of :class:`~sage.rings.ring.Ring`::
|
|
1320
|
+
|
|
1321
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
|
1322
|
+
sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2])
|
|
1323
|
+
sage: S = R.quotient_ring(I, 'a')
|
|
1324
|
+
sage: S.gens()
|
|
1325
|
+
(a,)
|
|
1326
|
+
|
|
1327
|
+
sage: # needs sage.libs.singular
|
|
1328
|
+
sage: R.<x,y> = PolynomialRing(QQ,2)
|
|
1329
|
+
sage: S.<a,b> = R.quotient_ring((x^2, y))
|
|
1330
|
+
sage: S
|
|
1331
|
+
Quotient of Multivariate Polynomial Ring in x, y over Rational Field
|
|
1332
|
+
by the ideal (x^2, y)
|
|
1333
|
+
sage: S.gens()
|
|
1334
|
+
(a, 0)
|
|
1335
|
+
sage: a == b
|
|
1336
|
+
False
|
|
1337
|
+
"""
|
|
1338
|
+
return self.quotient(I, names=names, **kwds)
|
|
1339
|
+
|
|
1340
|
+
def __truediv__(self, I):
|
|
1341
|
+
"""
|
|
1342
|
+
Since assigning generator names would not work properly,
|
|
1343
|
+
the construction of a quotient ring using division syntax
|
|
1344
|
+
is not supported.
|
|
1345
|
+
|
|
1346
|
+
EXAMPLES::
|
|
1347
|
+
|
|
1348
|
+
sage: MS = MatrixSpace(QQ, 2) # needs sage.modules
|
|
1349
|
+
sage: I = MS * MS.gens() * MS # needs sage.modules
|
|
1350
|
+
sage: MS/I # needs sage.modules
|
|
1351
|
+
Traceback (most recent call last):
|
|
1352
|
+
...
|
|
1353
|
+
TypeError: use self.quotient(I) to construct the quotient ring
|
|
1354
|
+
|
|
1355
|
+
sage: QQ['x'] / ZZ
|
|
1356
|
+
Traceback (most recent call last):
|
|
1357
|
+
...
|
|
1358
|
+
TypeError: use self.quotient(I) to construct the quotient ring
|
|
1359
|
+
"""
|
|
1360
|
+
raise TypeError("use self.quotient(I) to construct the quotient ring")
|
|
1361
|
+
|
|
1362
|
+
def __getitem__(self, arg):
|
|
1363
|
+
"""
|
|
1364
|
+
Extend this ring by one or several elements to create a polynomial
|
|
1365
|
+
ring, a power series ring, or an algebraic extension.
|
|
1366
|
+
|
|
1367
|
+
This is a convenience method intended primarily for interactive
|
|
1368
|
+
use.
|
|
1369
|
+
|
|
1370
|
+
.. SEEALSO::
|
|
1371
|
+
|
|
1372
|
+
:func:`~sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing`,
|
|
1373
|
+
:func:`~sage.rings.power_series_ring.PowerSeriesRing`,
|
|
1374
|
+
:meth:`~sage.rings.ring.Ring.extension`,
|
|
1375
|
+
:meth:`sage.rings.integer_ring.IntegerRing_class.__getitem__`,
|
|
1376
|
+
:meth:`sage.rings.matrix_space.MatrixSpace.__getitem__`,
|
|
1377
|
+
:meth:`sage.structure.parent.Parent.__getitem__`
|
|
1378
|
+
|
|
1379
|
+
EXAMPLES:
|
|
1380
|
+
|
|
1381
|
+
We create several polynomial rings::
|
|
1382
|
+
|
|
1383
|
+
sage: ZZ['x']
|
|
1384
|
+
Univariate Polynomial Ring in x over Integer Ring
|
|
1385
|
+
sage: QQ['x']
|
|
1386
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
1387
|
+
sage: GF(17)['abc']
|
|
1388
|
+
Univariate Polynomial Ring in abc over Finite Field of size 17
|
|
1389
|
+
sage: GF(17)['a,b,c']
|
|
1390
|
+
Multivariate Polynomial Ring in a, b, c over Finite Field of size 17
|
|
1391
|
+
sage: GF(17)['a']['b']
|
|
1392
|
+
Univariate Polynomial Ring in b over
|
|
1393
|
+
Univariate Polynomial Ring in a over Finite Field of size 17
|
|
1394
|
+
|
|
1395
|
+
We can create Ore polynomial rings::
|
|
1396
|
+
|
|
1397
|
+
sage: k.<t> = GF(5^3) # needs sage.rings.finite_rings
|
|
1398
|
+
sage: Frob = k.frobenius_endomorphism() # needs sage.rings.finite_rings
|
|
1399
|
+
sage: k['x', Frob] # needs sage.modules sage.rings.finite_rings
|
|
1400
|
+
Ore Polynomial Ring in x over Finite Field in t of size 5^3
|
|
1401
|
+
twisted by t |--> t^5
|
|
1402
|
+
|
|
1403
|
+
sage: R.<t> = QQ[]
|
|
1404
|
+
sage: der = R.derivation() # needs sage.modules
|
|
1405
|
+
sage: R['d', der] # needs sage.modules
|
|
1406
|
+
Ore Polynomial Ring in d
|
|
1407
|
+
over Univariate Polynomial Ring in t over Rational Field
|
|
1408
|
+
twisted by d/dt
|
|
1409
|
+
|
|
1410
|
+
We can also create power series rings by using double brackets::
|
|
1411
|
+
|
|
1412
|
+
sage: QQ[['t']]
|
|
1413
|
+
Power Series Ring in t over Rational Field
|
|
1414
|
+
sage: ZZ[['W']]
|
|
1415
|
+
Power Series Ring in W over Integer Ring
|
|
1416
|
+
|
|
1417
|
+
sage: ZZ[['x,y,z']]
|
|
1418
|
+
Multivariate Power Series Ring in x, y, z over Integer Ring
|
|
1419
|
+
sage: ZZ[['x','T']]
|
|
1420
|
+
Multivariate Power Series Ring in x, T over Integer Ring
|
|
1421
|
+
|
|
1422
|
+
Use :func:`~sage.rings.fraction_field.Frac` or
|
|
1423
|
+
:meth:`~sage.rings.ring.CommutativeRing.fraction_field` to obtain
|
|
1424
|
+
the fields of rational functions and Laurent series::
|
|
1425
|
+
|
|
1426
|
+
sage: Frac(QQ['t'])
|
|
1427
|
+
Fraction Field of Univariate Polynomial Ring in t over Rational Field
|
|
1428
|
+
sage: Frac(QQ[['t']])
|
|
1429
|
+
Laurent Series Ring in t over Rational Field
|
|
1430
|
+
sage: QQ[['t']].fraction_field()
|
|
1431
|
+
Laurent Series Ring in t over Rational Field
|
|
1432
|
+
|
|
1433
|
+
Note that the same syntax can be used to create number fields::
|
|
1434
|
+
|
|
1435
|
+
sage: QQ[I] # needs sage.rings.number_field sage.symbolic
|
|
1436
|
+
Number Field in I with defining polynomial x^2 + 1 with I = 1*I
|
|
1437
|
+
sage: QQ[I].coerce_embedding() # needs sage.rings.number_field sage.symbolic
|
|
1438
|
+
Generic morphism:
|
|
1439
|
+
From: Number Field in I with defining polynomial x^2 + 1 with I = 1*I
|
|
1440
|
+
To: Complex Lazy Field
|
|
1441
|
+
Defn: I -> 1*I
|
|
1442
|
+
|
|
1443
|
+
::
|
|
1444
|
+
|
|
1445
|
+
sage: QQ[sqrt(2)] # needs fpylll sage.rings.number_field sage.symbolic
|
|
1446
|
+
Number Field in sqrt2 with defining polynomial x^2 - 2
|
|
1447
|
+
with sqrt2 = 1.414213562373095?
|
|
1448
|
+
sage: QQ[sqrt(2)].coerce_embedding() # needs fpylll sage.rings.number_field sage.symbolic
|
|
1449
|
+
Generic morphism:
|
|
1450
|
+
From: Number Field in sqrt2 with defining polynomial x^2 - 2
|
|
1451
|
+
with sqrt2 = 1.414213562373095?
|
|
1452
|
+
To: Real Lazy Field
|
|
1453
|
+
Defn: sqrt2 -> 1.414213562373095?
|
|
1454
|
+
|
|
1455
|
+
::
|
|
1456
|
+
|
|
1457
|
+
sage: QQ[sqrt(2), sqrt(3)] # needs fpylll sage.rings.number_field sage.symbolic
|
|
1458
|
+
Number Field in sqrt2
|
|
1459
|
+
with defining polynomial x^2 - 2 over its base field
|
|
1460
|
+
|
|
1461
|
+
and orders in number fields::
|
|
1462
|
+
|
|
1463
|
+
sage: ZZ[I] # needs fpylll sage.rings.number_field sage.symbolic
|
|
1464
|
+
Gaussian Integers generated by I0 in Number Field in I0
|
|
1465
|
+
with defining polynomial x^2 + 1 with I0 = 1*I
|
|
1466
|
+
sage: ZZ[sqrt(5)] # needs fpylll sage.rings.number_field sage.symbolic
|
|
1467
|
+
Order of conductor 2 generated by sqrt5 in Number Field in sqrt5
|
|
1468
|
+
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?
|
|
1469
|
+
sage: ZZ[sqrt(2) + sqrt(3)] # needs fpylll sage.rings.number_field sage.symbolic
|
|
1470
|
+
Order generated by a in Number Field in a
|
|
1471
|
+
with defining polynomial x^4 - 10*x^2 + 1 with a = 3.146264369941973?
|
|
1472
|
+
|
|
1473
|
+
Embeddings are found for simple extensions (when that makes sense)::
|
|
1474
|
+
|
|
1475
|
+
sage: QQi.<i> = QuadraticField(-1, 'i') # needs fpylll sage.rings.number_field sage.symbolic
|
|
1476
|
+
sage: QQ[i].coerce_embedding() # needs fpylll sage.rings.number_field sage.symbolic
|
|
1477
|
+
Generic morphism:
|
|
1478
|
+
From: Number Field in i with defining polynomial x^2 + 1 with i = 1*I
|
|
1479
|
+
To: Complex Lazy Field
|
|
1480
|
+
Defn: i -> 1*I
|
|
1481
|
+
|
|
1482
|
+
TESTS:
|
|
1483
|
+
|
|
1484
|
+
A few corner cases::
|
|
1485
|
+
|
|
1486
|
+
sage: QQ[()]
|
|
1487
|
+
Multivariate Polynomial Ring in no variables over Rational Field
|
|
1488
|
+
|
|
1489
|
+
sage: QQ[[]]
|
|
1490
|
+
Traceback (most recent call last):
|
|
1491
|
+
...
|
|
1492
|
+
TypeError: power series rings must have at least one variable
|
|
1493
|
+
|
|
1494
|
+
These kind of expressions do not work::
|
|
1495
|
+
|
|
1496
|
+
sage: QQ['a,b','c']
|
|
1497
|
+
Traceback (most recent call last):
|
|
1498
|
+
...
|
|
1499
|
+
ValueError: variable name 'a,b' is not alphanumeric
|
|
1500
|
+
sage: QQ[['a,b','c']]
|
|
1501
|
+
Traceback (most recent call last):
|
|
1502
|
+
...
|
|
1503
|
+
ValueError: variable name 'a,b' is not alphanumeric
|
|
1504
|
+
|
|
1505
|
+
sage: QQ[[['x']]]
|
|
1506
|
+
Traceback (most recent call last):
|
|
1507
|
+
...
|
|
1508
|
+
TypeError: expected R[...] or R[[...]], not R[[[...]]]
|
|
1509
|
+
|
|
1510
|
+
Extension towers are built as follows and use distinct generator names::
|
|
1511
|
+
|
|
1512
|
+
sage: # needs fpylll sage.rings.number_field sage.symbolic
|
|
1513
|
+
sage: K = QQ[2^(1/3), 2^(1/2), 3^(1/3)]
|
|
1514
|
+
sage: K
|
|
1515
|
+
Number Field in a with defining polynomial x^3 - 2
|
|
1516
|
+
over its base field
|
|
1517
|
+
sage: K.base_field()
|
|
1518
|
+
Number Field in sqrt2 with defining polynomial x^2 - 2
|
|
1519
|
+
over its base field
|
|
1520
|
+
sage: K.base_field().base_field()
|
|
1521
|
+
Number Field in b with defining polynomial x^3 - 3
|
|
1522
|
+
|
|
1523
|
+
Embeddings::
|
|
1524
|
+
|
|
1525
|
+
sage: # needs fpylll sage.rings.number_field sage.symbolic
|
|
1526
|
+
sage: a = 10^100; expr = (2*a + sqrt(2))/(2*a^2-1)
|
|
1527
|
+
sage: QQ[expr].coerce_embedding() is None
|
|
1528
|
+
False
|
|
1529
|
+
sage: QQ[sqrt(5)].gen() > 0
|
|
1530
|
+
True
|
|
1531
|
+
sage: expr = sqrt(2) + I*(cos(pi/4, hold=True) - sqrt(2)/2)
|
|
1532
|
+
sage: QQ[expr].coerce_embedding()
|
|
1533
|
+
Generic morphism:
|
|
1534
|
+
From: Number Field in a with defining polynomial x^2 - 2
|
|
1535
|
+
with a = 1.414213562373095?
|
|
1536
|
+
To: Real Lazy Field
|
|
1537
|
+
Defn: a -> 1.414213562373095?
|
|
1538
|
+
"""
|
|
1539
|
+
def normalize_arg(arg):
|
|
1540
|
+
if isinstance(arg, (tuple, list)):
|
|
1541
|
+
# Allowing arbitrary iterables would create confusion,
|
|
1542
|
+
# but we may want to support a few more.
|
|
1543
|
+
return tuple(arg)
|
|
1544
|
+
if isinstance(arg, str):
|
|
1545
|
+
return tuple(arg.split(','))
|
|
1546
|
+
return (arg,)
|
|
1547
|
+
|
|
1548
|
+
# 1. If arg is a list, try to return a power series ring.
|
|
1549
|
+
|
|
1550
|
+
if isinstance(arg, list):
|
|
1551
|
+
if not arg:
|
|
1552
|
+
raise TypeError("power series rings must have at least one variable")
|
|
1553
|
+
elif len(arg) == 1:
|
|
1554
|
+
# R[["a,b"]], R[[(a,b)]]...
|
|
1555
|
+
if isinstance(arg[0], list):
|
|
1556
|
+
raise TypeError("expected R[...] or R[[...]], not R[[[...]]]")
|
|
1557
|
+
elts = normalize_arg(arg[0])
|
|
1558
|
+
else:
|
|
1559
|
+
elts = normalize_arg(arg)
|
|
1560
|
+
from sage.rings.power_series_ring import PowerSeriesRing
|
|
1561
|
+
return PowerSeriesRing(self, elts)
|
|
1562
|
+
|
|
1563
|
+
if isinstance(arg, tuple):
|
|
1564
|
+
from sage.categories.morphism import Morphism
|
|
1565
|
+
try:
|
|
1566
|
+
from sage.rings.derivation import RingDerivation
|
|
1567
|
+
except ImportError:
|
|
1568
|
+
RingDerivation = ()
|
|
1569
|
+
if len(arg) == 2 and isinstance(arg[1], (Morphism, RingDerivation)):
|
|
1570
|
+
from sage.rings.polynomial.ore_polynomial_ring import OrePolynomialRing
|
|
1571
|
+
return OrePolynomialRing(self, arg[1], names=arg[0])
|
|
1572
|
+
|
|
1573
|
+
# 2. Otherwise, if all specified elements are algebraic, try to
|
|
1574
|
+
# return an algebraic extension
|
|
1575
|
+
|
|
1576
|
+
elts = normalize_arg(arg)
|
|
1577
|
+
|
|
1578
|
+
try:
|
|
1579
|
+
minpolys = [a.minpoly() for a in elts]
|
|
1580
|
+
except (AttributeError, NotImplementedError, ValueError, TypeError):
|
|
1581
|
+
minpolys = None
|
|
1582
|
+
|
|
1583
|
+
if minpolys:
|
|
1584
|
+
# how to pass in names?
|
|
1585
|
+
names = tuple(_gen_names(elts))
|
|
1586
|
+
if len(elts) == 1:
|
|
1587
|
+
from sage.rings.cif import CIF
|
|
1588
|
+
elt = elts[0]
|
|
1589
|
+
try:
|
|
1590
|
+
iv = CIF(elt)
|
|
1591
|
+
except (TypeError, ValueError):
|
|
1592
|
+
emb = None
|
|
1593
|
+
else:
|
|
1594
|
+
# First try creating an ANRoot manually, because
|
|
1595
|
+
# extension(..., embedding=CLF(expr)) (or
|
|
1596
|
+
# ...QQbar(expr)) would normalize the expression in
|
|
1597
|
+
# QQbar, which currently is VERY slow in many cases.
|
|
1598
|
+
# This may fail when minpoly has close roots or elt is
|
|
1599
|
+
# a complicated symbolic expression.
|
|
1600
|
+
# TODO: Rewrite using #19362 and/or #17886 and/or
|
|
1601
|
+
# #15600 once those issues are solved.
|
|
1602
|
+
from sage.rings.qqbar import AlgebraicNumber, ANRoot
|
|
1603
|
+
try:
|
|
1604
|
+
elt = AlgebraicNumber(ANRoot(minpolys[0], iv))
|
|
1605
|
+
except ValueError:
|
|
1606
|
+
pass
|
|
1607
|
+
# Force a real embedding when possible, to get the
|
|
1608
|
+
# right ordered ring structure.
|
|
1609
|
+
from sage.rings.real_lazy import CLF, RLF
|
|
1610
|
+
if (iv.imag().is_zero() or iv.imag().contains_zero()
|
|
1611
|
+
and elt.imag().is_zero()):
|
|
1612
|
+
emb = RLF(elt)
|
|
1613
|
+
else:
|
|
1614
|
+
emb = CLF(elt)
|
|
1615
|
+
return self.extension(minpolys[0], names[0], embedding=emb)
|
|
1616
|
+
try:
|
|
1617
|
+
# Doing the extension all at once is best, if possible...
|
|
1618
|
+
return self.extension(minpolys, names)
|
|
1619
|
+
except (TypeError, ValueError):
|
|
1620
|
+
# ...but we can also construct it iteratively
|
|
1621
|
+
return reduce(lambda R, ext: R.extension(*ext), zip(minpolys, names), self)
|
|
1622
|
+
|
|
1623
|
+
# 2. Otherwise, try to return a polynomial ring
|
|
1624
|
+
|
|
1625
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1626
|
+
return PolynomialRing(self, elts)
|
|
1627
|
+
|
|
1628
|
+
def free_module(self, base=None, basis=None, map=True):
|
|
1629
|
+
"""
|
|
1630
|
+
Return a free module `V` over the specified subring together with maps to and from `V`.
|
|
1631
|
+
|
|
1632
|
+
The default implementation only supports the case that the base ring is the ring itself.
|
|
1633
|
+
|
|
1634
|
+
INPUT:
|
|
1635
|
+
|
|
1636
|
+
- ``base`` -- a subring `R` so that this ring is isomorphic
|
|
1637
|
+
to a finite-rank free `R`-module `V`
|
|
1638
|
+
|
|
1639
|
+
- ``basis`` -- (optional) a basis for this ring over the base
|
|
1640
|
+
|
|
1641
|
+
- ``map`` -- boolean (default: ``True``); whether to return
|
|
1642
|
+
`R`-linear maps to and from `V`
|
|
1643
|
+
|
|
1644
|
+
OUTPUT: a finite-rank free `R`-module `V`
|
|
1645
|
+
|
|
1646
|
+
- An `R`-module isomorphism from `V` to this ring
|
|
1647
|
+
(only included if ``map`` is ``True``)
|
|
1648
|
+
|
|
1649
|
+
- An `R`-module isomorphism from this ring to `V`
|
|
1650
|
+
(only included if ``map`` is ``True``)
|
|
1651
|
+
|
|
1652
|
+
EXAMPLES::
|
|
1653
|
+
|
|
1654
|
+
sage: # needs sage.modules
|
|
1655
|
+
sage: R.<x> = QQ[[]]
|
|
1656
|
+
sage: V, from_V, to_V = R.free_module(R)
|
|
1657
|
+
sage: v = to_V(1 + x); v
|
|
1658
|
+
(1 + x)
|
|
1659
|
+
sage: from_V(v)
|
|
1660
|
+
1 + x
|
|
1661
|
+
sage: W, from_W, to_W = R.free_module(R, basis=(1 - x))
|
|
1662
|
+
sage: W is V
|
|
1663
|
+
True
|
|
1664
|
+
sage: w = to_W(1 + x); w
|
|
1665
|
+
(1 - x^2)
|
|
1666
|
+
sage: from_W(w)
|
|
1667
|
+
1 + x + O(x^20)
|
|
1668
|
+
"""
|
|
1669
|
+
if base is None:
|
|
1670
|
+
base = self.base_ring()
|
|
1671
|
+
if base is self:
|
|
1672
|
+
V = self**1
|
|
1673
|
+
if not map:
|
|
1674
|
+
return V
|
|
1675
|
+
if basis is not None:
|
|
1676
|
+
if isinstance(basis, (list, tuple)):
|
|
1677
|
+
if len(basis) != 1:
|
|
1678
|
+
raise ValueError("basis must have length 1")
|
|
1679
|
+
basis = basis[0]
|
|
1680
|
+
basis = self(basis)
|
|
1681
|
+
if not basis.is_unit():
|
|
1682
|
+
raise ValueError("basis element must be a unit")
|
|
1683
|
+
from sage.modules.free_module_morphism import BaseIsomorphism1D_from_FM, BaseIsomorphism1D_to_FM
|
|
1684
|
+
Hfrom = V.Hom(self)
|
|
1685
|
+
Hto = self.Hom(V)
|
|
1686
|
+
from_V = Hfrom.__make_element_class__(BaseIsomorphism1D_from_FM)(Hfrom, basis=basis)
|
|
1687
|
+
to_V = Hto.__make_element_class__(BaseIsomorphism1D_to_FM)(Hto, basis=basis)
|
|
1688
|
+
return V, from_V, to_V
|
|
1689
|
+
else:
|
|
1690
|
+
if not self.has_coerce_map_from(base):
|
|
1691
|
+
raise ValueError("base must be a subring of this ring")
|
|
1692
|
+
raise NotImplementedError
|
|
1693
|
+
|
|
1694
|
+
def _random_nonzero_element(self, *args, **kwds):
|
|
1695
|
+
"""
|
|
1696
|
+
Return a random nonzero element in this ring.
|
|
1697
|
+
|
|
1698
|
+
The default behaviour of this method is to repeatedly call the
|
|
1699
|
+
``random_element`` method until a nonzero element is obtained.
|
|
1700
|
+
|
|
1701
|
+
In this implementation, all parameters are simply pushed forward
|
|
1702
|
+
to the ``random_element`` method.
|
|
1703
|
+
|
|
1704
|
+
INPUT:
|
|
1705
|
+
|
|
1706
|
+
- ``*args``, ``**kwds`` -- parameters that can be forwarded to
|
|
1707
|
+
the ``random_element`` method
|
|
1708
|
+
|
|
1709
|
+
EXAMPLES::
|
|
1710
|
+
|
|
1711
|
+
sage: ZZ._random_nonzero_element() != 0
|
|
1712
|
+
True
|
|
1713
|
+
sage: A = GF((5, 3)) # needs sage.rings.finite_rings
|
|
1714
|
+
sage: A._random_nonzero_element() != 0 # needs sage.rings.finite_rings sage.modules
|
|
1715
|
+
True
|
|
1716
|
+
"""
|
|
1717
|
+
while True:
|
|
1718
|
+
x = self.random_element(*args, **kwds)
|
|
1719
|
+
if not x.is_zero():
|
|
1720
|
+
return x
|
|
1721
|
+
|
|
1722
|
+
def random_element(self, *args):
|
|
1723
|
+
"""
|
|
1724
|
+
Return a random integer coerced into this ring.
|
|
1725
|
+
|
|
1726
|
+
INPUT:
|
|
1727
|
+
|
|
1728
|
+
- either no integer, one integer or two integers
|
|
1729
|
+
|
|
1730
|
+
The integer is chosen uniformly from the closed interval
|
|
1731
|
+
``[-2,2]``, ``[-a,a]`` or ``[a,b]`` according to the
|
|
1732
|
+
length of the input.
|
|
1733
|
+
|
|
1734
|
+
ALGORITHM:
|
|
1735
|
+
|
|
1736
|
+
This uses Python's ``randint``.
|
|
1737
|
+
|
|
1738
|
+
EXAMPLES::
|
|
1739
|
+
|
|
1740
|
+
sage: -8 <= ZZ.random_element(8) <= 8
|
|
1741
|
+
True
|
|
1742
|
+
sage: -8 <= QQ.random_element(8) <= 8
|
|
1743
|
+
True
|
|
1744
|
+
sage: 4 <= ZZ.random_element(4,12) <= 12
|
|
1745
|
+
True
|
|
1746
|
+
"""
|
|
1747
|
+
if not args:
|
|
1748
|
+
a, b = -2, 2
|
|
1749
|
+
elif len(args) == 1:
|
|
1750
|
+
bound = args[0]
|
|
1751
|
+
a, b = -bound, bound
|
|
1752
|
+
else:
|
|
1753
|
+
a, b = args[0], args[1]
|
|
1754
|
+
return randint(a, b) * self.one()
|
|
1755
|
+
|
|
1756
|
+
class ElementMethods:
|
|
1757
|
+
def is_unit(self) -> bool:
|
|
1758
|
+
r"""
|
|
1759
|
+
Return whether this element is a unit in the ring.
|
|
1760
|
+
|
|
1761
|
+
.. NOTE::
|
|
1762
|
+
|
|
1763
|
+
This is a generic implementation for (non-commutative) rings
|
|
1764
|
+
which only works for the one element, its additive inverse, and
|
|
1765
|
+
the zero element. Most rings should provide a more specialized
|
|
1766
|
+
implementation.
|
|
1767
|
+
|
|
1768
|
+
EXAMPLES::
|
|
1769
|
+
|
|
1770
|
+
sage: # needs sage.modules
|
|
1771
|
+
sage: MS = MatrixSpace(ZZ, 2)
|
|
1772
|
+
sage: MS.one().is_unit()
|
|
1773
|
+
True
|
|
1774
|
+
sage: MS.zero().is_unit()
|
|
1775
|
+
False
|
|
1776
|
+
sage: MS([1,2,3,4]).is_unit()
|
|
1777
|
+
False
|
|
1778
|
+
"""
|
|
1779
|
+
if self.is_one() or (-self).is_one():
|
|
1780
|
+
return True
|
|
1781
|
+
if self.is_zero(): # now 0 != 1
|
|
1782
|
+
return False
|
|
1783
|
+
raise NotImplementedError
|
|
1784
|
+
|
|
1785
|
+
def inverse_of_unit(self):
|
|
1786
|
+
r"""
|
|
1787
|
+
Return the inverse of this element if it is a unit.
|
|
1788
|
+
|
|
1789
|
+
OUTPUT: an element in the same ring as this element
|
|
1790
|
+
|
|
1791
|
+
EXAMPLES::
|
|
1792
|
+
|
|
1793
|
+
sage: R.<x> = ZZ[]
|
|
1794
|
+
sage: S = R.quo(x^2 + x + 1) # needs sage.libs.pari
|
|
1795
|
+
sage: S(1).inverse_of_unit() # needs sage.libs.pari
|
|
1796
|
+
1
|
|
1797
|
+
|
|
1798
|
+
This method fails when the element is not a unit::
|
|
1799
|
+
|
|
1800
|
+
sage: 2.inverse_of_unit()
|
|
1801
|
+
Traceback (most recent call last):
|
|
1802
|
+
...
|
|
1803
|
+
ArithmeticError: inverse does not exist
|
|
1804
|
+
|
|
1805
|
+
The inverse returned is in the same ring as this element::
|
|
1806
|
+
|
|
1807
|
+
sage: a = -1
|
|
1808
|
+
sage: a.parent()
|
|
1809
|
+
Integer Ring
|
|
1810
|
+
sage: a.inverse_of_unit().parent()
|
|
1811
|
+
Integer Ring
|
|
1812
|
+
|
|
1813
|
+
Note that this is often not the case when computing inverses in other ways::
|
|
1814
|
+
|
|
1815
|
+
sage: (~a).parent()
|
|
1816
|
+
Rational Field
|
|
1817
|
+
sage: (1/a).parent()
|
|
1818
|
+
Rational Field
|
|
1819
|
+
"""
|
|
1820
|
+
try:
|
|
1821
|
+
if not self.is_unit():
|
|
1822
|
+
raise ArithmeticError("element is not a unit")
|
|
1823
|
+
except NotImplementedError:
|
|
1824
|
+
# if an element does not implement is_unit, we just try to
|
|
1825
|
+
# invert it anyway; if the result is in the ring again, it was
|
|
1826
|
+
# a unit
|
|
1827
|
+
pass
|
|
1828
|
+
|
|
1829
|
+
inverse = ~self
|
|
1830
|
+
if inverse not in self.parent():
|
|
1831
|
+
raise ArithmeticError("element is not a unit")
|
|
1832
|
+
|
|
1833
|
+
# return the inverse (with the correct parent)
|
|
1834
|
+
return self.parent()(inverse)
|
|
1835
|
+
|
|
1836
|
+
def _divide_if_possible(self, y):
|
|
1837
|
+
"""
|
|
1838
|
+
Divide ``self`` by ``y`` if possible and raise a
|
|
1839
|
+
:exc:`ValueError` otherwise.
|
|
1840
|
+
|
|
1841
|
+
EXAMPLES::
|
|
1842
|
+
|
|
1843
|
+
sage: 4._divide_if_possible(2)
|
|
1844
|
+
2
|
|
1845
|
+
sage: _.parent()
|
|
1846
|
+
Integer Ring
|
|
1847
|
+
|
|
1848
|
+
sage: 4._divide_if_possible(3)
|
|
1849
|
+
Traceback (most recent call last):
|
|
1850
|
+
...
|
|
1851
|
+
ValueError: 4 is not divisible by 3
|
|
1852
|
+
"""
|
|
1853
|
+
q, r = self.quo_rem(y)
|
|
1854
|
+
if r != 0:
|
|
1855
|
+
raise ValueError("%s is not divisible by %s" % (self, y))
|
|
1856
|
+
return q
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
def _gen_words():
|
|
1860
|
+
r"""
|
|
1861
|
+
Generate words.
|
|
1862
|
+
|
|
1863
|
+
EXAMPLES::
|
|
1864
|
+
|
|
1865
|
+
sage: from sage.categories.rings import _gen_words
|
|
1866
|
+
sage: import itertools
|
|
1867
|
+
sage: list(itertools.islice(_gen_words(), 30))[20:]
|
|
1868
|
+
['u', 'v', 'w', 'x', 'y', 'z', 'aa', 'ab', 'ac', 'ad']
|
|
1869
|
+
"""
|
|
1870
|
+
repeat = 1
|
|
1871
|
+
while True:
|
|
1872
|
+
for w in itertools.product("abcdefghijklmnopqrstuvwxyz", repeat=repeat):
|
|
1873
|
+
yield ''.join(w)
|
|
1874
|
+
repeat += 1
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
def _gen_names(elts):
|
|
1878
|
+
r"""
|
|
1879
|
+
Used to find a name for a generator when rings are created using the
|
|
1880
|
+
``__getitem__`` syntax, e.g. ``ZZ['x']``, ``ZZ[sqrt(2)]``.
|
|
1881
|
+
|
|
1882
|
+
EXAMPLES::
|
|
1883
|
+
|
|
1884
|
+
sage: from sage.categories.rings import _gen_names
|
|
1885
|
+
sage: list(_gen_names([sqrt(5)])) # needs sage.symbolic
|
|
1886
|
+
['sqrt5']
|
|
1887
|
+
sage: list(_gen_names([sqrt(-17), 2^(1/3)])) # needs sage.symbolic
|
|
1888
|
+
['a', 'b']
|
|
1889
|
+
sage: list(_gen_names((1..27)))[-1]
|
|
1890
|
+
'aa'
|
|
1891
|
+
"""
|
|
1892
|
+
import re
|
|
1893
|
+
from sage.structure.category_object import certify_names
|
|
1894
|
+
it = _gen_words()
|
|
1895
|
+
for x in elts:
|
|
1896
|
+
name = str(x)
|
|
1897
|
+
m = re.match(r'^sqrt\((\d+)\)$', name)
|
|
1898
|
+
if m:
|
|
1899
|
+
name = "sqrt%s" % m.groups()[0]
|
|
1900
|
+
try:
|
|
1901
|
+
certify_names([name])
|
|
1902
|
+
except ValueError:
|
|
1903
|
+
name = next(it)
|
|
1904
|
+
yield name
|