passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- sage/typeset/unicode_characters.py +101 -0
|
@@ -0,0 +1,1670 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# sage.doctest: needs sage.rings.padics
|
|
3
|
+
r"""
|
|
4
|
+
Local Generic
|
|
5
|
+
|
|
6
|
+
Superclass for `p`-adic and power series rings.
|
|
7
|
+
|
|
8
|
+
AUTHORS:
|
|
9
|
+
|
|
10
|
+
- David Roe
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# *****************************************************************************
|
|
14
|
+
# Copyright (C) 2007-2013 David Roe <roed.math@gmail.com>
|
|
15
|
+
# William Stein <wstein@gmail.com>
|
|
16
|
+
#
|
|
17
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
18
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
19
|
+
# the License, or (at your option) any later version.
|
|
20
|
+
#
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# *****************************************************************************
|
|
23
|
+
|
|
24
|
+
from copy import copy
|
|
25
|
+
|
|
26
|
+
from sage.categories.complete_discrete_valuation import CompleteDiscreteValuationRings, CompleteDiscreteValuationFields
|
|
27
|
+
from sage.structure.category_object import check_default_category
|
|
28
|
+
from sage.rings.integer import Integer
|
|
29
|
+
from sage.rings.integer_ring import ZZ
|
|
30
|
+
from sage.rings.infinity import Infinity
|
|
31
|
+
from sage.structure.parent import Parent
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class LocalGeneric(Parent):
|
|
35
|
+
def __init__(self, base, prec, names, element_class, category=None):
|
|
36
|
+
r"""
|
|
37
|
+
Initialize ``self``.
|
|
38
|
+
|
|
39
|
+
EXAMPLES::
|
|
40
|
+
|
|
41
|
+
sage: R = Zp(5) # indirect doctest
|
|
42
|
+
sage: R.precision_cap()
|
|
43
|
+
20
|
|
44
|
+
|
|
45
|
+
In :issue:`14084`, the category framework has been implemented for `p`-adic rings::
|
|
46
|
+
|
|
47
|
+
sage: TestSuite(R).run() # needs sage.geometry.polyhedron
|
|
48
|
+
sage: K = Qp(7)
|
|
49
|
+
sage: TestSuite(K).run() # needs sage.geometry.polyhedron
|
|
50
|
+
|
|
51
|
+
TESTS::
|
|
52
|
+
|
|
53
|
+
sage: R = Zp(5, 5, 'fixed-mod')
|
|
54
|
+
sage: R._repr_option('element_is_atomic')
|
|
55
|
+
False
|
|
56
|
+
|
|
57
|
+
sage: R = Zp(3, 10,'fixed-mod')
|
|
58
|
+
sage: R.is_finite()
|
|
59
|
+
False
|
|
60
|
+
sage: R.cardinality()
|
|
61
|
+
+Infinity
|
|
62
|
+
|
|
63
|
+
sage: Qp(11).is_finite()
|
|
64
|
+
False
|
|
65
|
+
sage: Qp(11).cardinality()
|
|
66
|
+
+Infinity
|
|
67
|
+
"""
|
|
68
|
+
self._prec = prec
|
|
69
|
+
self.Element = element_class
|
|
70
|
+
default_category = getattr(self, '_default_category', None)
|
|
71
|
+
if self.is_field():
|
|
72
|
+
category = CompleteDiscreteValuationFields()
|
|
73
|
+
else:
|
|
74
|
+
category = CompleteDiscreteValuationRings()
|
|
75
|
+
category = category.Metric().Complete().Infinite()
|
|
76
|
+
if default_category is not None:
|
|
77
|
+
category = check_default_category(default_category, category)
|
|
78
|
+
Parent.__init__(self, base=base, names=(names,),
|
|
79
|
+
normalize=False, category=category)
|
|
80
|
+
|
|
81
|
+
def is_capped_relative(self) -> bool:
|
|
82
|
+
r"""
|
|
83
|
+
Return whether this `p`-adic ring bounds precision in a capped
|
|
84
|
+
relative fashion.
|
|
85
|
+
|
|
86
|
+
The relative precision of an element is the power of `p`
|
|
87
|
+
modulo which the unit part of that element is defined. In a
|
|
88
|
+
capped relative ring, the relative precision of elements are
|
|
89
|
+
bounded by a constant depending on the ring.
|
|
90
|
+
|
|
91
|
+
EXAMPLES::
|
|
92
|
+
|
|
93
|
+
sage: R = ZpCA(5, 15)
|
|
94
|
+
sage: R.is_capped_relative()
|
|
95
|
+
False
|
|
96
|
+
sage: R(5^7)
|
|
97
|
+
5^7 + O(5^15)
|
|
98
|
+
sage: S = Zp(5, 15)
|
|
99
|
+
sage: S.is_capped_relative()
|
|
100
|
+
True
|
|
101
|
+
sage: S(5^7)
|
|
102
|
+
5^7 + O(5^22)
|
|
103
|
+
"""
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
def is_capped_absolute(self) -> bool:
|
|
107
|
+
r"""
|
|
108
|
+
Return whether this `p`-adic ring bounds precision in a
|
|
109
|
+
capped absolute fashion.
|
|
110
|
+
|
|
111
|
+
The absolute precision of an element is the power of `p`
|
|
112
|
+
modulo which that element is defined. In a capped absolute
|
|
113
|
+
ring, the absolute precision of elements are bounded by a
|
|
114
|
+
constant depending on the ring.
|
|
115
|
+
|
|
116
|
+
EXAMPLES::
|
|
117
|
+
|
|
118
|
+
sage: R = ZpCA(5, 15)
|
|
119
|
+
sage: R.is_capped_absolute()
|
|
120
|
+
True
|
|
121
|
+
sage: R(5^7)
|
|
122
|
+
5^7 + O(5^15)
|
|
123
|
+
sage: S = Zp(5, 15)
|
|
124
|
+
sage: S.is_capped_absolute()
|
|
125
|
+
False
|
|
126
|
+
sage: S(5^7)
|
|
127
|
+
5^7 + O(5^22)
|
|
128
|
+
"""
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
def is_fixed_mod(self) -> bool:
|
|
132
|
+
r"""
|
|
133
|
+
Return whether this `p`-adic ring bounds precision in a fixed
|
|
134
|
+
modulus fashion.
|
|
135
|
+
|
|
136
|
+
The absolute precision of an element is the power of `p`
|
|
137
|
+
modulo which that element is defined. In a fixed modulus
|
|
138
|
+
ring, the absolute precision of every element is defined to be
|
|
139
|
+
the precision cap of the parent. This means that some
|
|
140
|
+
operations, such as division by `p`, don't return a well defined
|
|
141
|
+
answer.
|
|
142
|
+
|
|
143
|
+
EXAMPLES::
|
|
144
|
+
|
|
145
|
+
sage: R = ZpFM(5,15)
|
|
146
|
+
sage: R.is_fixed_mod()
|
|
147
|
+
True
|
|
148
|
+
sage: R(5^7,absprec=9)
|
|
149
|
+
5^7
|
|
150
|
+
sage: S = ZpCA(5, 15)
|
|
151
|
+
sage: S.is_fixed_mod()
|
|
152
|
+
False
|
|
153
|
+
sage: S(5^7,absprec=9)
|
|
154
|
+
5^7 + O(5^9)
|
|
155
|
+
"""
|
|
156
|
+
return False
|
|
157
|
+
|
|
158
|
+
def is_floating_point(self) -> bool:
|
|
159
|
+
r"""
|
|
160
|
+
Return whether this `p`-adic ring bounds precision in a floating
|
|
161
|
+
point fashion.
|
|
162
|
+
|
|
163
|
+
The relative precision of an element is the power of `p`
|
|
164
|
+
modulo which the unit part of that element is defined. In a
|
|
165
|
+
floating point ring, elements do not store precision, but arithmetic
|
|
166
|
+
operations truncate to a relative precision depending on the ring.
|
|
167
|
+
|
|
168
|
+
EXAMPLES::
|
|
169
|
+
|
|
170
|
+
sage: R = ZpCR(5, 15)
|
|
171
|
+
sage: R.is_floating_point()
|
|
172
|
+
False
|
|
173
|
+
sage: R(5^7)
|
|
174
|
+
5^7 + O(5^22)
|
|
175
|
+
sage: S = ZpFP(5, 15)
|
|
176
|
+
sage: S.is_floating_point()
|
|
177
|
+
True
|
|
178
|
+
sage: S(5^7)
|
|
179
|
+
5^7
|
|
180
|
+
"""
|
|
181
|
+
return False
|
|
182
|
+
|
|
183
|
+
def is_lattice_prec(self) -> bool:
|
|
184
|
+
r"""
|
|
185
|
+
Return whether this `p`-adic ring bounds precision using
|
|
186
|
+
a lattice model.
|
|
187
|
+
|
|
188
|
+
In lattice precision, relationships between elements
|
|
189
|
+
are stored in a precision object of the parent, which
|
|
190
|
+
allows for optimal precision tracking at the cost of
|
|
191
|
+
increased memory usage and runtime.
|
|
192
|
+
|
|
193
|
+
EXAMPLES::
|
|
194
|
+
|
|
195
|
+
sage: R = ZpCR(5, 15)
|
|
196
|
+
sage: R.is_lattice_prec()
|
|
197
|
+
False
|
|
198
|
+
sage: x = R(25, 8)
|
|
199
|
+
sage: x - x
|
|
200
|
+
O(5^8)
|
|
201
|
+
sage: S = ZpLC(5, 15)
|
|
202
|
+
doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation.
|
|
203
|
+
See https://github.com/sagemath/sage/issues/23505 for details.
|
|
204
|
+
sage: S.is_lattice_prec()
|
|
205
|
+
True
|
|
206
|
+
sage: x = S(25, 8)
|
|
207
|
+
sage: x - x
|
|
208
|
+
O(5^30)
|
|
209
|
+
"""
|
|
210
|
+
return False
|
|
211
|
+
|
|
212
|
+
def is_relaxed(self) -> bool:
|
|
213
|
+
r"""
|
|
214
|
+
Return whether this `p`-adic ring bounds precision in a relaxed
|
|
215
|
+
fashion.
|
|
216
|
+
|
|
217
|
+
In a relaxed ring, elements have mechanisms for computing
|
|
218
|
+
themselves to greater precision.
|
|
219
|
+
|
|
220
|
+
EXAMPLES::
|
|
221
|
+
|
|
222
|
+
sage: R = Zp(5)
|
|
223
|
+
sage: R.is_relaxed()
|
|
224
|
+
False
|
|
225
|
+
"""
|
|
226
|
+
return False
|
|
227
|
+
|
|
228
|
+
def _latex_(self) -> str:
|
|
229
|
+
r"""
|
|
230
|
+
Latex.
|
|
231
|
+
|
|
232
|
+
EXAMPLES::
|
|
233
|
+
|
|
234
|
+
sage: latex(Zq(27,names='a')) # indirect doctest # needs sage.libs.ntl
|
|
235
|
+
\Bold{Z}_{3^{3}}
|
|
236
|
+
"""
|
|
237
|
+
return self._repr_(do_latex=True)
|
|
238
|
+
|
|
239
|
+
def change(self, **kwds):
|
|
240
|
+
r"""
|
|
241
|
+
Return a new ring with changed attributes.
|
|
242
|
+
|
|
243
|
+
INPUT:
|
|
244
|
+
|
|
245
|
+
The following arguments are applied to every ring in the tower:
|
|
246
|
+
|
|
247
|
+
- ``type`` -- string, the precision type
|
|
248
|
+
- ``p`` -- the prime of the ground ring; defining polynomials
|
|
249
|
+
will be converted to the new base rings
|
|
250
|
+
- ``print_mode`` -- string
|
|
251
|
+
- ``print_pos`` -- boolean
|
|
252
|
+
- ``print_sep`` -- string
|
|
253
|
+
- ``print_alphabet`` -- dictionary
|
|
254
|
+
- ``show_prec`` -- boolean
|
|
255
|
+
- ``check`` -- boolean
|
|
256
|
+
- ``label`` -- string (only for lattice precision)
|
|
257
|
+
|
|
258
|
+
The following arguments are only applied to the top ring in the tower:
|
|
259
|
+
|
|
260
|
+
- ``var_name`` -- string
|
|
261
|
+
- ``res_name`` -- string
|
|
262
|
+
- ``unram_name`` -- string
|
|
263
|
+
- ``ram_name`` -- string
|
|
264
|
+
- ``names`` -- string
|
|
265
|
+
- ``modulus`` -- polynomial
|
|
266
|
+
|
|
267
|
+
The following arguments have special behavior:
|
|
268
|
+
|
|
269
|
+
- ``prec`` -- integer; if the precision is increased on an extension ring,
|
|
270
|
+
the precision on the base is increased as necessary (respecting ramification).
|
|
271
|
+
If the precision is decreased, the precision of the base is unchanged.
|
|
272
|
+
|
|
273
|
+
- ``field`` -- boolean; if ``True``, switch to a tower of fields via the fraction field
|
|
274
|
+
If ``False``, switch to a tower of rings of integers
|
|
275
|
+
|
|
276
|
+
- ``q`` -- prime power; replace the initial unramified extension of `\QQ_p` or `\ZZ_p`
|
|
277
|
+
with an unramified extension of residue cardinality `q`.
|
|
278
|
+
If the initial extension is ramified, add in an unramified extension.
|
|
279
|
+
|
|
280
|
+
- ``base`` -- ring or field; use a specific base ring instead of recursively
|
|
281
|
+
calling :meth:`change` down the tower
|
|
282
|
+
|
|
283
|
+
See the :mod:`constructors <sage.rings.padics.factory>` for more details on the
|
|
284
|
+
meaning of these arguments.
|
|
285
|
+
|
|
286
|
+
EXAMPLES:
|
|
287
|
+
|
|
288
|
+
We can use this method to change the precision::
|
|
289
|
+
|
|
290
|
+
sage: Zp(5).change(prec=40)
|
|
291
|
+
5-adic Ring with capped relative precision 40
|
|
292
|
+
|
|
293
|
+
or the precision type::
|
|
294
|
+
|
|
295
|
+
sage: Zp(5).change(type='capped-abs')
|
|
296
|
+
5-adic Ring with capped absolute precision 20
|
|
297
|
+
|
|
298
|
+
or even the prime::
|
|
299
|
+
|
|
300
|
+
sage: ZpCA(3).change(p=17)
|
|
301
|
+
17-adic Ring with capped absolute precision 20
|
|
302
|
+
|
|
303
|
+
You can switch between the ring of integers and its fraction field::
|
|
304
|
+
|
|
305
|
+
sage: ZpCA(3).change(field=True)
|
|
306
|
+
3-adic Field with capped relative precision 20
|
|
307
|
+
|
|
308
|
+
You can also change print modes::
|
|
309
|
+
|
|
310
|
+
sage: R = Zp(5).change(prec=5, print_mode='digits')
|
|
311
|
+
sage: repr(~R(17))
|
|
312
|
+
'...13403'
|
|
313
|
+
|
|
314
|
+
Changing print mode to 'digits' works for Eisenstein extensions::
|
|
315
|
+
|
|
316
|
+
sage: # needs sage.libs.ntl
|
|
317
|
+
sage: S.<x> = ZZ[]
|
|
318
|
+
sage: W.<w> = Zp(3).extension(x^4 + 9*x^2 + 3*x - 3)
|
|
319
|
+
sage: W.print_mode()
|
|
320
|
+
'series'
|
|
321
|
+
sage: W.change(print_mode='digits').print_mode()
|
|
322
|
+
'digits'
|
|
323
|
+
|
|
324
|
+
You can change extensions::
|
|
325
|
+
|
|
326
|
+
sage: # needs sage.libs.flint
|
|
327
|
+
sage: K.<a> = QqFP(125, prec=4)
|
|
328
|
+
sage: K.change(q=64)
|
|
329
|
+
2-adic Unramified Extension Field in a defined by x^6 + x^4 + x^3 + x + 1
|
|
330
|
+
sage: R.<x> = QQ[]
|
|
331
|
+
sage: K.change(modulus = x^2 - x + 2, print_pos=False)
|
|
332
|
+
5-adic Unramified Extension Field in a defined by x^2 - x + 2
|
|
333
|
+
|
|
334
|
+
and variable names::
|
|
335
|
+
|
|
336
|
+
sage: K.change(names='b') # needs sage.libs.flint
|
|
337
|
+
5-adic Unramified Extension Field in b defined by x^3 + 3*x + 3
|
|
338
|
+
|
|
339
|
+
and precision::
|
|
340
|
+
|
|
341
|
+
sage: # needs sage.libs.flint
|
|
342
|
+
sage: Kup = K.change(prec=8); Kup
|
|
343
|
+
5-adic Unramified Extension Field in a defined by x^3 + 3*x + 3
|
|
344
|
+
sage: Kup.precision_cap()
|
|
345
|
+
8
|
|
346
|
+
sage: Kup.base_ring()
|
|
347
|
+
5-adic Field with floating precision 8
|
|
348
|
+
|
|
349
|
+
If you decrease the precision, the precision of the base stays the same::
|
|
350
|
+
|
|
351
|
+
sage: # needs sage.libs.flint
|
|
352
|
+
sage: Kdown = K.change(prec=2); Kdown
|
|
353
|
+
5-adic Unramified Extension Field in a defined by x^3 + 3*x + 3
|
|
354
|
+
sage: Kdown.precision_cap()
|
|
355
|
+
2
|
|
356
|
+
sage: Kdown.base_ring()
|
|
357
|
+
5-adic Field with floating precision 4
|
|
358
|
+
|
|
359
|
+
Changing the prime works for extensions::
|
|
360
|
+
|
|
361
|
+
sage: # needs sage.libs.ntl
|
|
362
|
+
sage: x = polygen(ZZ)
|
|
363
|
+
sage: R.<a> = Zp(5).extension(x^2 + 2)
|
|
364
|
+
sage: S = R.change(p=7)
|
|
365
|
+
sage: S.defining_polynomial(exact=True)
|
|
366
|
+
x^2 + 2
|
|
367
|
+
sage: A.<y> = Zp(5)[]
|
|
368
|
+
sage: R.<a> = Zp(5).extension(y^2 + 2)
|
|
369
|
+
sage: S = R.change(p=7)
|
|
370
|
+
sage: S.defining_polynomial(exact=True)
|
|
371
|
+
y^2 + 2
|
|
372
|
+
|
|
373
|
+
::
|
|
374
|
+
|
|
375
|
+
sage: # needs sage.libs.ntl
|
|
376
|
+
sage: R.<a> = Zq(5^3)
|
|
377
|
+
sage: S = R.change(prec=50)
|
|
378
|
+
sage: S.defining_polynomial(exact=True)
|
|
379
|
+
x^3 + 3*x + 3
|
|
380
|
+
|
|
381
|
+
Changing label for lattice precision (the precision lattice is not copied)::
|
|
382
|
+
|
|
383
|
+
sage: R = ZpLC(37, (8,11))
|
|
384
|
+
sage: S = R.change(label = "change"); S
|
|
385
|
+
37-adic Ring with lattice-cap precision (label: change)
|
|
386
|
+
sage: S.change(label = "new")
|
|
387
|
+
37-adic Ring with lattice-cap precision (label: new)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
TESTS:
|
|
391
|
+
|
|
392
|
+
The `secure` attribute for relaxed type is copied::
|
|
393
|
+
|
|
394
|
+
sage: # needs sage.libs.flint
|
|
395
|
+
sage: R = ZpER(5, secure=True); R
|
|
396
|
+
5-adic Ring handled with relaxed arithmetics
|
|
397
|
+
sage: K = R.change(field=True); K
|
|
398
|
+
5-adic Field handled with relaxed arithmetics
|
|
399
|
+
sage: K.is_secure()
|
|
400
|
+
True
|
|
401
|
+
|
|
402
|
+
The `check=False` option works for relaxed type::
|
|
403
|
+
|
|
404
|
+
sage: # needs sage.libs.flint
|
|
405
|
+
sage: R = ZpER(5) ; R
|
|
406
|
+
5-adic Ring handled with relaxed arithmetics
|
|
407
|
+
sage: K = R.change(field=True, check=False) ; K
|
|
408
|
+
5-adic Field handled with relaxed arithmetics
|
|
409
|
+
"""
|
|
410
|
+
# We support both print_* and * for *=mode, pos, sep, alphabet
|
|
411
|
+
for atr in ('print_mode', 'print_pos', 'print_sep', 'print_alphabet'):
|
|
412
|
+
if atr in kwds:
|
|
413
|
+
kwds[atr[6:]] = kwds.pop(atr)
|
|
414
|
+
|
|
415
|
+
def get_unramified_modulus(q, res_name):
|
|
416
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
|
|
417
|
+
return GF(q, res_name).modulus().change_ring(ZZ)
|
|
418
|
+
n = None
|
|
419
|
+
q = None
|
|
420
|
+
from .padic_base_generic import pAdicBaseGeneric
|
|
421
|
+
if 'q' in kwds and isinstance(self.base_ring(), pAdicBaseGeneric):
|
|
422
|
+
q = kwds.pop('q')
|
|
423
|
+
if not isinstance(q, Integer):
|
|
424
|
+
raise TypeError("q must be an integer")
|
|
425
|
+
p, n = q.is_prime_power(get_data=True)
|
|
426
|
+
if n == 0:
|
|
427
|
+
raise ValueError("q must be a prime power")
|
|
428
|
+
if 'p' in kwds and kwds['p'] != p:
|
|
429
|
+
raise ValueError("q does not match p")
|
|
430
|
+
kwds['p'] = p
|
|
431
|
+
functor, ring = self.construction(forbid_frac_field=True)
|
|
432
|
+
functor = copy(functor)
|
|
433
|
+
if 'mode' in kwds and 'show_prec' not in kwds:
|
|
434
|
+
new_type = kwds.get('type', self._prec_type())
|
|
435
|
+
cur_type = self._prec_type()
|
|
436
|
+
cur_mode = self._printer._print_mode()
|
|
437
|
+
cur_show_prec = self._printer._show_prec()
|
|
438
|
+
from .factory import _canonicalize_show_prec
|
|
439
|
+
if cur_show_prec == _canonicalize_show_prec(cur_type, cur_mode):
|
|
440
|
+
kwds['show_prec'] = _canonicalize_show_prec(new_type, kwds['mode'])
|
|
441
|
+
else:
|
|
442
|
+
raise RuntimeError
|
|
443
|
+
p = kwds.get('p', functor.p if hasattr(functor, 'p') else self.prime())
|
|
444
|
+
curpstr = str(self.prime())
|
|
445
|
+
functor_dict = getattr(functor, "extras", getattr(functor, "kwds", None))
|
|
446
|
+
# If we are switching to 'digits', or changing p, need to ensure a large enough alphabet.
|
|
447
|
+
if 'alphabet' not in kwds and (kwds.get('mode') == 'digits' or
|
|
448
|
+
(functor_dict['print_mode'].get('mode') == 'digits' and p > getattr(functor, "p", p))):
|
|
449
|
+
from .padic_printing import _printer_defaults
|
|
450
|
+
kwds['alphabet'] = _printer_defaults.alphabet()[:p]
|
|
451
|
+
# For fraction fields of fixed-mod rings, we need to explicitly set show_prec = False
|
|
452
|
+
if 'field' in kwds and 'type' not in kwds:
|
|
453
|
+
if self._prec_type() == 'capped-abs':
|
|
454
|
+
kwds['type'] = 'capped-rel'
|
|
455
|
+
elif self._prec_type() == 'fixed-mod':
|
|
456
|
+
kwds['type'] = 'floating-point'
|
|
457
|
+
kwds['show_prec'] = False # This can be removed once printing of fixed mod elements is changed.
|
|
458
|
+
|
|
459
|
+
# There are two kinds of functors possible:
|
|
460
|
+
# CompletionFunctor and AlgebraicExtensionFunctor
|
|
461
|
+
# We distinguish them by the presence of ``prec``,
|
|
462
|
+
if hasattr(functor, "prec"):
|
|
463
|
+
functor.extras = copy(functor.extras)
|
|
464
|
+
functor.extras['print_mode'] = copy(functor.extras['print_mode'])
|
|
465
|
+
if 'type' in kwds and kwds['type'] not in functor._dvr_types:
|
|
466
|
+
raise ValueError("completion type must be one of %s" % (", ".join(functor._dvr_types[1:])))
|
|
467
|
+
if 'field' in kwds:
|
|
468
|
+
field = kwds.pop('field')
|
|
469
|
+
if field:
|
|
470
|
+
ring = ring.fraction_field()
|
|
471
|
+
elif ring.is_field():
|
|
472
|
+
ring = ring.ring_of_integers()
|
|
473
|
+
for atr in ('p', 'prec', 'type'):
|
|
474
|
+
if atr in kwds:
|
|
475
|
+
setattr(functor, atr, kwds.pop(atr))
|
|
476
|
+
if q is not None:
|
|
477
|
+
if 'names' in kwds:
|
|
478
|
+
names = kwds.pop('names')
|
|
479
|
+
elif 'unram_name' in kwds:
|
|
480
|
+
names = kwds.pop('unram_name')
|
|
481
|
+
else:
|
|
482
|
+
raise TypeError("You must specify the name of the generator")
|
|
483
|
+
res_name = kwds.pop('res_name', names + '0')
|
|
484
|
+
modulus = kwds.pop('modulus', get_unramified_modulus(q, res_name))
|
|
485
|
+
implementation = kwds.pop('implementation', 'FLINT')
|
|
486
|
+
# We have to change the way p prints in the default case
|
|
487
|
+
if 'names' in kwds:
|
|
488
|
+
functor.extras['names'] = kwds.pop('names')
|
|
489
|
+
elif functor.extras['names'][0] == curpstr:
|
|
490
|
+
functor.extras['names'] = (str(p),)
|
|
491
|
+
# Labels for lattice precision
|
|
492
|
+
if 'label' in kwds:
|
|
493
|
+
functor.extras['label'] = kwds.pop('label')
|
|
494
|
+
elif 'label' in functor.extras and functor.type not in ['lattice-cap', 'lattice-float']:
|
|
495
|
+
del functor.extras['label']
|
|
496
|
+
for atr in ('ram_name', 'var_name'):
|
|
497
|
+
if atr in kwds:
|
|
498
|
+
functor.extras['print_mode'][atr] = kwds.pop(atr)
|
|
499
|
+
elif functor.extras['print_mode'].get(atr) == curpstr:
|
|
500
|
+
functor.extras['print_mode'][atr] = str(p)
|
|
501
|
+
if 'check' in kwds:
|
|
502
|
+
functor.extras['check'] = kwds.pop('check')
|
|
503
|
+
for atr in ('mode', 'pos', 'unram_name', 'max_ram_terms', 'max_unram_terms', 'max_terse_terms', 'sep', 'alphabet', 'show_prec'):
|
|
504
|
+
if atr in kwds:
|
|
505
|
+
functor.extras['print_mode'][atr] = kwds.pop(atr)
|
|
506
|
+
if kwds:
|
|
507
|
+
raise ValueError("Extra arguments received: %s" % (", ".join(kwds.keys())))
|
|
508
|
+
if q is not None:
|
|
509
|
+
# Create an unramified extension
|
|
510
|
+
base = functor(ring)
|
|
511
|
+
from .factory import ExtensionFactory
|
|
512
|
+
modulus = modulus.change_ring(base)
|
|
513
|
+
return ExtensionFactory(base=base, premodulus=modulus, names=names, res_name=res_name, unram=True, implementation=implementation)
|
|
514
|
+
else:
|
|
515
|
+
functor.kwds = copy(functor.kwds)
|
|
516
|
+
functor.kwds['print_mode'] = copy(functor.kwds['print_mode'])
|
|
517
|
+
if 'prec' in kwds:
|
|
518
|
+
# This will need to be modified once lattice precision supports extensions
|
|
519
|
+
prec = kwds.pop('prec')
|
|
520
|
+
baseprec = (prec - 1) // self.relative_e() + 1
|
|
521
|
+
if baseprec > self.base_ring().precision_cap():
|
|
522
|
+
kwds['prec'] = baseprec
|
|
523
|
+
functor.precs = [prec]
|
|
524
|
+
from sage.rings.padics.padic_base_generic import pAdicBaseGeneric
|
|
525
|
+
if 'names' in kwds:
|
|
526
|
+
functor.names = [kwds.pop('names')]
|
|
527
|
+
modulus = None
|
|
528
|
+
if 'modulus' in kwds:
|
|
529
|
+
modulus = kwds.pop('modulus')
|
|
530
|
+
if n is not None and modulus.degree() != n:
|
|
531
|
+
raise ValueError("modulus must have degree matching q")
|
|
532
|
+
elif q is not None:
|
|
533
|
+
if self.relative_e() == 1:
|
|
534
|
+
# If q is specified, replace the modulus with one from q.
|
|
535
|
+
modulus = get_unramified_modulus(q, functor.kwds.get('res_name', functor.names[0] + '0'))
|
|
536
|
+
elif self.relative_f() != 1:
|
|
537
|
+
raise ValueError("Cannot change q in mixed extensions")
|
|
538
|
+
for atr in ('var_name', 'res_name', 'unram_name', 'ram_name'):
|
|
539
|
+
if atr in kwds:
|
|
540
|
+
functor.kwds[atr] = kwds.pop(atr)
|
|
541
|
+
if 'check' in kwds:
|
|
542
|
+
functor.kwds['check'] = kwds['check']
|
|
543
|
+
for atr in ('mode', 'pos', 'max_ram_terms', 'max_unram_terms', 'max_terse_terms', 'sep', 'alphabet', 'show_prec'):
|
|
544
|
+
if atr in kwds:
|
|
545
|
+
functor.kwds['print_mode'][atr] = kwds[atr]
|
|
546
|
+
if 'base' in kwds:
|
|
547
|
+
ring = kwds['base']
|
|
548
|
+
else:
|
|
549
|
+
if q is not None and self.relative_f() == 1:
|
|
550
|
+
kwds['q'] = q
|
|
551
|
+
ring = ring.change(**kwds)
|
|
552
|
+
if modulus is None:
|
|
553
|
+
if len(functor.polys) != 1:
|
|
554
|
+
raise RuntimeError("Unexpected number of defining polynomials")
|
|
555
|
+
modulus = functor.polys[0]
|
|
556
|
+
if isinstance(modulus.base_ring(), pAdicBaseGeneric):
|
|
557
|
+
modulus.change_ring(ring)
|
|
558
|
+
functor.polys = [modulus]
|
|
559
|
+
return functor(ring)
|
|
560
|
+
|
|
561
|
+
def precision_cap(self):
|
|
562
|
+
r"""
|
|
563
|
+
Return the precision cap for this ring.
|
|
564
|
+
|
|
565
|
+
EXAMPLES::
|
|
566
|
+
|
|
567
|
+
sage: R = Zp(3, 10,'fixed-mod'); R.precision_cap()
|
|
568
|
+
10
|
|
569
|
+
sage: R = Zp(3, 10,'capped-rel'); R.precision_cap()
|
|
570
|
+
10
|
|
571
|
+
sage: R = Zp(3, 10,'capped-abs'); R.precision_cap()
|
|
572
|
+
10
|
|
573
|
+
|
|
574
|
+
.. NOTE::
|
|
575
|
+
|
|
576
|
+
This will have different meanings depending on the type of
|
|
577
|
+
local ring. For fixed modulus rings, all elements are
|
|
578
|
+
considered modulo ``self.prime()^self.precision_cap()``.
|
|
579
|
+
For rings with an absolute cap (i.e. the class
|
|
580
|
+
``pAdicRingCappedAbsolute``), each element has a precision
|
|
581
|
+
that is tracked and is bounded above by
|
|
582
|
+
``self.precision_cap()``. Rings with relative caps
|
|
583
|
+
(e.g. the class ``pAdicRingCappedRelative``) are the same
|
|
584
|
+
except that the precision is the precision of the unit
|
|
585
|
+
part of each element.
|
|
586
|
+
"""
|
|
587
|
+
return self._prec
|
|
588
|
+
|
|
589
|
+
def _precision_cap(self):
|
|
590
|
+
r"""
|
|
591
|
+
Return the precision cap for this ring, in the format
|
|
592
|
+
used by the factory methods to create the ring.
|
|
593
|
+
|
|
594
|
+
For most `p`-adic types, this is the same as :meth:`precision_cap`,
|
|
595
|
+
but there is a difference for lattice precision.
|
|
596
|
+
|
|
597
|
+
EXAMPLES::
|
|
598
|
+
|
|
599
|
+
sage: Zp(17,34)._precision_cap()
|
|
600
|
+
34
|
|
601
|
+
"""
|
|
602
|
+
return self._prec
|
|
603
|
+
|
|
604
|
+
def is_exact(self):
|
|
605
|
+
r"""
|
|
606
|
+
Return whether this `p`-adic ring is exact, i.e. ``False``.
|
|
607
|
+
|
|
608
|
+
EXAMPLES::
|
|
609
|
+
|
|
610
|
+
sage: R = Zp(5, 3, 'fixed-mod'); R.is_exact()
|
|
611
|
+
False
|
|
612
|
+
"""
|
|
613
|
+
return False
|
|
614
|
+
|
|
615
|
+
def residue_characteristic(self):
|
|
616
|
+
r"""
|
|
617
|
+
Return the characteristic of ``self``'s residue field.
|
|
618
|
+
|
|
619
|
+
INPUT:
|
|
620
|
+
|
|
621
|
+
- ``self`` -- a `p`-adic ring
|
|
622
|
+
|
|
623
|
+
OUTPUT: the characteristic of the residue field
|
|
624
|
+
|
|
625
|
+
EXAMPLES::
|
|
626
|
+
|
|
627
|
+
sage: R = Zp(3, 5, 'capped-rel'); R.residue_characteristic()
|
|
628
|
+
3
|
|
629
|
+
"""
|
|
630
|
+
return self.residue_class_field().characteristic()
|
|
631
|
+
|
|
632
|
+
def defining_polynomial(self, var='x', exact=False):
|
|
633
|
+
r"""
|
|
634
|
+
Return the defining polynomial of this local ring.
|
|
635
|
+
|
|
636
|
+
INPUT:
|
|
637
|
+
|
|
638
|
+
- ``var`` -- string (default: ``'x'``); the name of the variable
|
|
639
|
+
|
|
640
|
+
- ``exact`` -- boolean (default: ``False``); whether to return the
|
|
641
|
+
underlying exact defining polynomial rather than the one with coefficients
|
|
642
|
+
in the base ring
|
|
643
|
+
|
|
644
|
+
OUTPUT: the defining polynomial of this ring as an extension over its ground ring
|
|
645
|
+
|
|
646
|
+
EXAMPLES::
|
|
647
|
+
|
|
648
|
+
sage: R = Zp(3, 3, 'fixed-mod')
|
|
649
|
+
|
|
650
|
+
sage: R.defining_polynomial().parent()
|
|
651
|
+
Univariate Polynomial Ring in x over 3-adic Ring of fixed modulus 3^3
|
|
652
|
+
sage: R.defining_polynomial('foo')
|
|
653
|
+
foo
|
|
654
|
+
|
|
655
|
+
sage: R.defining_polynomial(exact=True).parent()
|
|
656
|
+
Univariate Polynomial Ring in x over Integer Ring
|
|
657
|
+
"""
|
|
658
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
659
|
+
if exact:
|
|
660
|
+
from sage.rings.integer_ring import ZZ
|
|
661
|
+
return PolynomialRing(ZZ, var).gen()
|
|
662
|
+
else:
|
|
663
|
+
return PolynomialRing(self, var).gen()
|
|
664
|
+
|
|
665
|
+
def ground_ring(self):
|
|
666
|
+
r"""
|
|
667
|
+
Return ``self``.
|
|
668
|
+
|
|
669
|
+
Will be overridden by extensions.
|
|
670
|
+
|
|
671
|
+
INPUT:
|
|
672
|
+
|
|
673
|
+
- ``self`` -- a local ring
|
|
674
|
+
|
|
675
|
+
OUTPUT: the ground ring of ``self``, i.e., itself
|
|
676
|
+
|
|
677
|
+
EXAMPLES::
|
|
678
|
+
|
|
679
|
+
sage: R = Zp(3, 5, 'fixed-mod')
|
|
680
|
+
sage: S = Zp(3, 4, 'fixed-mod')
|
|
681
|
+
sage: R.ground_ring() is R
|
|
682
|
+
True
|
|
683
|
+
sage: S.ground_ring() is R
|
|
684
|
+
False
|
|
685
|
+
"""
|
|
686
|
+
return self
|
|
687
|
+
|
|
688
|
+
def ground_ring_of_tower(self):
|
|
689
|
+
r"""
|
|
690
|
+
Return ``self``.
|
|
691
|
+
|
|
692
|
+
Will be overridden by extensions.
|
|
693
|
+
|
|
694
|
+
INPUT:
|
|
695
|
+
|
|
696
|
+
- ``self`` -- a `p`-adic ring
|
|
697
|
+
|
|
698
|
+
OUTPUT: the ground ring of the tower for ``self``, i.e., itself
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: R = Zp(5)
|
|
703
|
+
sage: R.ground_ring_of_tower()
|
|
704
|
+
5-adic Ring with capped relative precision 20
|
|
705
|
+
"""
|
|
706
|
+
return self
|
|
707
|
+
|
|
708
|
+
def absolute_degree(self):
|
|
709
|
+
r"""
|
|
710
|
+
Return the degree of this extension over the prime `p`-adic field/ring.
|
|
711
|
+
|
|
712
|
+
EXAMPLES::
|
|
713
|
+
|
|
714
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
715
|
+
sage: K.absolute_degree() # needs sage.libs.ntl
|
|
716
|
+
5
|
|
717
|
+
|
|
718
|
+
sage: R.<x> = QQ[]
|
|
719
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
720
|
+
sage: L.absolute_degree() # needs sage.libs.ntl
|
|
721
|
+
2
|
|
722
|
+
"""
|
|
723
|
+
return self.absolute_e() * self.absolute_f()
|
|
724
|
+
|
|
725
|
+
def relative_degree(self):
|
|
726
|
+
r"""
|
|
727
|
+
Return the degree of this extension over its base field/ring.
|
|
728
|
+
|
|
729
|
+
EXAMPLES::
|
|
730
|
+
|
|
731
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
732
|
+
sage: K.relative_degree() # needs sage.libs.ntl
|
|
733
|
+
5
|
|
734
|
+
|
|
735
|
+
sage: R.<x> = QQ[]
|
|
736
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
737
|
+
sage: L.relative_degree() # needs sage.libs.ntl
|
|
738
|
+
2
|
|
739
|
+
"""
|
|
740
|
+
return self.absolute_degree() // self.base_ring().absolute_degree()
|
|
741
|
+
|
|
742
|
+
def degree(self):
|
|
743
|
+
r"""
|
|
744
|
+
Return the degree of this extension.
|
|
745
|
+
|
|
746
|
+
Raise an error if the base ring/field is itself an extension.
|
|
747
|
+
|
|
748
|
+
EXAMPLES::
|
|
749
|
+
|
|
750
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
751
|
+
sage: K.degree() # needs sage.libs.ntl
|
|
752
|
+
5
|
|
753
|
+
|
|
754
|
+
sage: R.<x> = QQ[]
|
|
755
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
756
|
+
sage: L.degree() # needs sage.libs.ntl
|
|
757
|
+
2
|
|
758
|
+
"""
|
|
759
|
+
if self.base_ring().absolute_degree() == 1:
|
|
760
|
+
return self.absolute_degree()
|
|
761
|
+
else:
|
|
762
|
+
raise NotImplementedError("For a relative p-adic ring or field you must use relative_degree or absolute_degree as appropriate")
|
|
763
|
+
|
|
764
|
+
def absolute_e(self):
|
|
765
|
+
r"""
|
|
766
|
+
Return the absolute ramification index of this ring/field.
|
|
767
|
+
|
|
768
|
+
EXAMPLES::
|
|
769
|
+
|
|
770
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
771
|
+
sage: K.absolute_e() # needs sage.libs.ntl
|
|
772
|
+
1
|
|
773
|
+
|
|
774
|
+
sage: R.<x> = QQ[]
|
|
775
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
776
|
+
sage: L.absolute_e() # needs sage.libs.ntl
|
|
777
|
+
2
|
|
778
|
+
"""
|
|
779
|
+
# Override this in subclasses (if appropriate)
|
|
780
|
+
if self is self.base_ring():
|
|
781
|
+
return ZZ(1)
|
|
782
|
+
else:
|
|
783
|
+
return self.base_ring().absolute_e()
|
|
784
|
+
|
|
785
|
+
def absolute_ramification_index(self):
|
|
786
|
+
r"""
|
|
787
|
+
Return the absolute ramification index of this ring/field.
|
|
788
|
+
|
|
789
|
+
EXAMPLES::
|
|
790
|
+
|
|
791
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
792
|
+
sage: K.absolute_ramification_index() # needs sage.libs.ntl
|
|
793
|
+
1
|
|
794
|
+
|
|
795
|
+
sage: R.<x> = QQ[]
|
|
796
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
797
|
+
sage: L.absolute_ramification_index() # needs sage.libs.ntl
|
|
798
|
+
2
|
|
799
|
+
"""
|
|
800
|
+
return self.absolute_e()
|
|
801
|
+
|
|
802
|
+
def relative_e(self):
|
|
803
|
+
r"""
|
|
804
|
+
Return the ramification index of this extension over its base ring/field.
|
|
805
|
+
|
|
806
|
+
EXAMPLES::
|
|
807
|
+
|
|
808
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
809
|
+
sage: K.relative_e() # needs sage.libs.ntl
|
|
810
|
+
1
|
|
811
|
+
|
|
812
|
+
sage: R.<x> = QQ[]
|
|
813
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
814
|
+
sage: L.relative_e() # needs sage.libs.ntl
|
|
815
|
+
2
|
|
816
|
+
"""
|
|
817
|
+
return self.absolute_e() // self.base_ring().absolute_e()
|
|
818
|
+
|
|
819
|
+
def relative_ramification_index(self):
|
|
820
|
+
r"""
|
|
821
|
+
Return the ramification index of this extension over its base ring/field.
|
|
822
|
+
|
|
823
|
+
EXAMPLES::
|
|
824
|
+
|
|
825
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
826
|
+
sage: K.relative_ramification_index() # needs sage.libs.ntl
|
|
827
|
+
1
|
|
828
|
+
|
|
829
|
+
sage: R.<x> = QQ[]
|
|
830
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
831
|
+
sage: L.relative_ramification_index() # needs sage.libs.ntl
|
|
832
|
+
2
|
|
833
|
+
"""
|
|
834
|
+
return self.relative_e()
|
|
835
|
+
|
|
836
|
+
def e(self):
|
|
837
|
+
r"""
|
|
838
|
+
Return the ramification index of this extension.
|
|
839
|
+
|
|
840
|
+
Raise an error if the base ring/field is itself an extension.
|
|
841
|
+
|
|
842
|
+
EXAMPLES::
|
|
843
|
+
|
|
844
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
845
|
+
sage: K.e() # needs sage.libs.ntl
|
|
846
|
+
1
|
|
847
|
+
|
|
848
|
+
sage: R.<x> = QQ[]
|
|
849
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
850
|
+
sage: L.e() # needs sage.libs.ntl
|
|
851
|
+
2
|
|
852
|
+
"""
|
|
853
|
+
if self.base_ring().absolute_degree() == 1:
|
|
854
|
+
return self.absolute_e()
|
|
855
|
+
else:
|
|
856
|
+
raise NotImplementedError("For a relative p-adic ring or field you must use relative_e or absolute_e as appropriate")
|
|
857
|
+
|
|
858
|
+
def ramification_index(self):
|
|
859
|
+
r"""
|
|
860
|
+
Return the ramification index of this extension.
|
|
861
|
+
|
|
862
|
+
Raise an error if the base ring/field is itself an extension.
|
|
863
|
+
|
|
864
|
+
EXAMPLES::
|
|
865
|
+
|
|
866
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
867
|
+
sage: K.ramification_index() # needs sage.libs.ntl
|
|
868
|
+
1
|
|
869
|
+
|
|
870
|
+
sage: R.<x> = QQ[]
|
|
871
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
872
|
+
sage: L.ramification_index() # needs sage.libs.ntl
|
|
873
|
+
2
|
|
874
|
+
"""
|
|
875
|
+
return self.e()
|
|
876
|
+
|
|
877
|
+
def absolute_f(self):
|
|
878
|
+
r"""
|
|
879
|
+
Return the degree of the residue field of this ring/field
|
|
880
|
+
over its prime subfield.
|
|
881
|
+
|
|
882
|
+
EXAMPLES::
|
|
883
|
+
|
|
884
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
885
|
+
sage: K.absolute_f() # needs sage.libs.ntl
|
|
886
|
+
5
|
|
887
|
+
|
|
888
|
+
sage: R.<x> = QQ[]
|
|
889
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
890
|
+
sage: L.absolute_f() # needs sage.libs.ntl
|
|
891
|
+
1
|
|
892
|
+
"""
|
|
893
|
+
# Override this in subclasses (if appropriate)
|
|
894
|
+
if self is self.base_ring():
|
|
895
|
+
return ZZ(1)
|
|
896
|
+
else:
|
|
897
|
+
return self.base_ring().absolute_f()
|
|
898
|
+
|
|
899
|
+
def absolute_inertia_degree(self):
|
|
900
|
+
r"""
|
|
901
|
+
Return the degree of the residue field of this ring/field
|
|
902
|
+
over its prime subfield.
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
907
|
+
sage: K.absolute_inertia_degree() # needs sage.libs.ntl
|
|
908
|
+
5
|
|
909
|
+
|
|
910
|
+
sage: R.<x> = QQ[]
|
|
911
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
912
|
+
sage: L.absolute_inertia_degree() # needs sage.libs.ntl
|
|
913
|
+
1
|
|
914
|
+
"""
|
|
915
|
+
return self.absolute_f()
|
|
916
|
+
|
|
917
|
+
def relative_f(self):
|
|
918
|
+
r"""
|
|
919
|
+
Return the degree of the residual extension over its base ring/field.
|
|
920
|
+
|
|
921
|
+
EXAMPLES::
|
|
922
|
+
|
|
923
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
924
|
+
sage: K.relative_f() # needs sage.libs.ntl
|
|
925
|
+
5
|
|
926
|
+
|
|
927
|
+
sage: R.<x> = QQ[]
|
|
928
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
929
|
+
sage: L.relative_f() # needs sage.libs.ntl
|
|
930
|
+
1
|
|
931
|
+
"""
|
|
932
|
+
return self.absolute_f() // self.base_ring().absolute_f()
|
|
933
|
+
|
|
934
|
+
def relative_inertia_degree(self):
|
|
935
|
+
r"""
|
|
936
|
+
Return the degree of the residual extension over its base ring/field.
|
|
937
|
+
|
|
938
|
+
EXAMPLES::
|
|
939
|
+
|
|
940
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
941
|
+
sage: K.relative_inertia_degree() # needs sage.libs.ntl
|
|
942
|
+
5
|
|
943
|
+
|
|
944
|
+
sage: R.<x> = QQ[]
|
|
945
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
946
|
+
sage: L.relative_inertia_degree() # needs sage.libs.ntl
|
|
947
|
+
1
|
|
948
|
+
"""
|
|
949
|
+
return self.relative_f()
|
|
950
|
+
|
|
951
|
+
def f(self):
|
|
952
|
+
r"""
|
|
953
|
+
Return the degree of the residual extension.
|
|
954
|
+
|
|
955
|
+
Raise an error if the base ring/field is itself an extension.
|
|
956
|
+
|
|
957
|
+
EXAMPLES::
|
|
958
|
+
|
|
959
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
960
|
+
sage: K.f() # needs sage.libs.ntl
|
|
961
|
+
5
|
|
962
|
+
|
|
963
|
+
sage: R.<x> = QQ[]
|
|
964
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
965
|
+
sage: L.f() # needs sage.libs.ntl
|
|
966
|
+
1
|
|
967
|
+
"""
|
|
968
|
+
if self.base_ring().absolute_degree() == 1:
|
|
969
|
+
return self.absolute_f()
|
|
970
|
+
else:
|
|
971
|
+
raise NotImplementedError("For a relative p-adic ring or field you must use relative_f or absolute_f as appropriate")
|
|
972
|
+
|
|
973
|
+
def inertia_degree(self):
|
|
974
|
+
r"""
|
|
975
|
+
Return the degree of the residual extension.
|
|
976
|
+
|
|
977
|
+
Raise an error if the base ring/field is itself an extension.
|
|
978
|
+
|
|
979
|
+
EXAMPLES::
|
|
980
|
+
|
|
981
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
982
|
+
sage: K.inertia_degree() # needs sage.libs.ntl
|
|
983
|
+
5
|
|
984
|
+
|
|
985
|
+
sage: R.<x> = QQ[]
|
|
986
|
+
sage: L.<pi> = Qp(3).extension(x^2 - 3) # needs sage.libs.ntl
|
|
987
|
+
sage: L.inertia_degree() # needs sage.libs.ntl
|
|
988
|
+
1
|
|
989
|
+
"""
|
|
990
|
+
return self.f()
|
|
991
|
+
|
|
992
|
+
def inertia_subring(self):
|
|
993
|
+
r"""
|
|
994
|
+
Return the inertia subring, i.e. ``self``.
|
|
995
|
+
|
|
996
|
+
INPUT:
|
|
997
|
+
|
|
998
|
+
- ``self`` -- a local ring
|
|
999
|
+
|
|
1000
|
+
OUTPUT: the inertia subring of ``self``, i.e., itself
|
|
1001
|
+
|
|
1002
|
+
EXAMPLES::
|
|
1003
|
+
|
|
1004
|
+
sage: R = Zp(5)
|
|
1005
|
+
sage: R.inertia_subring()
|
|
1006
|
+
5-adic Ring with capped relative precision 20
|
|
1007
|
+
"""
|
|
1008
|
+
return self
|
|
1009
|
+
|
|
1010
|
+
def maximal_unramified_subextension(self):
|
|
1011
|
+
r"""
|
|
1012
|
+
Return the maximal unramified subextension.
|
|
1013
|
+
|
|
1014
|
+
INPUT:
|
|
1015
|
+
|
|
1016
|
+
- ``self`` -- a local ring
|
|
1017
|
+
|
|
1018
|
+
OUTPUT: the maximal unramified subextension of ``self``
|
|
1019
|
+
|
|
1020
|
+
EXAMPLES::
|
|
1021
|
+
|
|
1022
|
+
sage: R = Zp(5)
|
|
1023
|
+
sage: R.maximal_unramified_subextension()
|
|
1024
|
+
5-adic Ring with capped relative precision 20
|
|
1025
|
+
"""
|
|
1026
|
+
return self.inertia_subring()
|
|
1027
|
+
|
|
1028
|
+
# def get_extension(self):
|
|
1029
|
+
# r"""
|
|
1030
|
+
# Return the trivial extension of self.
|
|
1031
|
+
# """
|
|
1032
|
+
# raise NotImplementedError
|
|
1033
|
+
|
|
1034
|
+
def uniformiser(self):
|
|
1035
|
+
r"""
|
|
1036
|
+
Return a uniformiser for ``self``, ie a generator for the unique maximal ideal.
|
|
1037
|
+
|
|
1038
|
+
EXAMPLES::
|
|
1039
|
+
|
|
1040
|
+
sage: R = Zp(5)
|
|
1041
|
+
sage: R.uniformiser()
|
|
1042
|
+
5 + O(5^21)
|
|
1043
|
+
sage: A = Zp(7,10)
|
|
1044
|
+
sage: S.<x> = A[] # needs sage.libs.ntl
|
|
1045
|
+
sage: B.<t> = A.ext(x^2+7) # needs sage.libs.ntl
|
|
1046
|
+
sage: B.uniformiser() # needs sage.libs.ntl
|
|
1047
|
+
t + O(t^21)
|
|
1048
|
+
"""
|
|
1049
|
+
return self.uniformizer()
|
|
1050
|
+
|
|
1051
|
+
def uniformiser_pow(self, n):
|
|
1052
|
+
r"""
|
|
1053
|
+
Return the `n`-th power of the uniformiser of ``self`` (as an element
|
|
1054
|
+
of ``self``).
|
|
1055
|
+
|
|
1056
|
+
EXAMPLES::
|
|
1057
|
+
|
|
1058
|
+
sage: R = Zp(5)
|
|
1059
|
+
sage: R.uniformiser_pow(5)
|
|
1060
|
+
5^5 + O(5^25)
|
|
1061
|
+
"""
|
|
1062
|
+
return self.uniformizer_pow(n)
|
|
1063
|
+
|
|
1064
|
+
def ext(self, *args, **kwds):
|
|
1065
|
+
r"""
|
|
1066
|
+
Construct an extension of ``self``. See :meth:`extension` for more details.
|
|
1067
|
+
|
|
1068
|
+
EXAMPLES::
|
|
1069
|
+
|
|
1070
|
+
sage: A = Zp(7,10)
|
|
1071
|
+
sage: S.<x> = A[] # needs sage.libs.ntl
|
|
1072
|
+
sage: B.<t> = A.ext(x^2 + 7) # needs sage.libs.ntl
|
|
1073
|
+
sage: B.uniformiser() # needs sage.libs.ntl
|
|
1074
|
+
t + O(t^21)
|
|
1075
|
+
"""
|
|
1076
|
+
return self.extension(*args, **kwds)
|
|
1077
|
+
|
|
1078
|
+
def _test_add_bigoh(self, **options):
|
|
1079
|
+
r"""
|
|
1080
|
+
Perform tests on ``add_bigoh``.
|
|
1081
|
+
|
|
1082
|
+
EXAMPLES::
|
|
1083
|
+
|
|
1084
|
+
sage: K = Qp(3)
|
|
1085
|
+
sage: K._test_add_bigoh()
|
|
1086
|
+
"""
|
|
1087
|
+
tester = self._tester(**options)
|
|
1088
|
+
for x in tester.some_elements():
|
|
1089
|
+
tester.assertEqual(x.add_bigoh(x.precision_absolute()), x)
|
|
1090
|
+
from sage.rings.infinity import infinity
|
|
1091
|
+
tester.assertEqual(x.add_bigoh(infinity), x)
|
|
1092
|
+
tester.assertEqual(x.add_bigoh(x.precision_absolute()+1), x)
|
|
1093
|
+
|
|
1094
|
+
y = x.add_bigoh(0)
|
|
1095
|
+
tester.assertIs(y.parent(), self)
|
|
1096
|
+
if self.is_capped_absolute():
|
|
1097
|
+
tester.assertEqual(y.precision_absolute(), 0)
|
|
1098
|
+
tester.assertEqual(y, self.zero())
|
|
1099
|
+
elif self.is_capped_relative() or self.is_lattice_prec():
|
|
1100
|
+
tester.assertLessEqual(y.precision_absolute(), 0)
|
|
1101
|
+
elif self.is_fixed_mod() or self.is_floating_point():
|
|
1102
|
+
tester.assertGreaterEqual((x-y).valuation(), 0)
|
|
1103
|
+
|
|
1104
|
+
# if absprec < 0, then the result is in the fraction field (see #13591)
|
|
1105
|
+
y = x.add_bigoh(-1)
|
|
1106
|
+
tester.assertIs(y.parent(), self.fraction_field())
|
|
1107
|
+
if not self.is_floating_point() and not self.is_fixed_mod():
|
|
1108
|
+
tester.assertLessEqual(y.precision_absolute(), -1)
|
|
1109
|
+
|
|
1110
|
+
# make sure that we handle very large values correctly
|
|
1111
|
+
if self._prec_type() not in ['lattice-float', 'relaxed']: # no cap in these models
|
|
1112
|
+
absprec = Integer(2)**1000
|
|
1113
|
+
tester.assertEqual(x.add_bigoh(absprec), x)
|
|
1114
|
+
|
|
1115
|
+
def _test_residue(self, **options):
|
|
1116
|
+
r"""
|
|
1117
|
+
Perform some tests on the residue field of this ring.
|
|
1118
|
+
|
|
1119
|
+
EXAMPLES::
|
|
1120
|
+
|
|
1121
|
+
sage: R = Zp(2)
|
|
1122
|
+
sage: R._test_residue()
|
|
1123
|
+
"""
|
|
1124
|
+
tester = self._tester(**options)
|
|
1125
|
+
tester.assertEqual(self.residue_field().characteristic(), self.residue_characteristic())
|
|
1126
|
+
|
|
1127
|
+
for x in tester.some_elements():
|
|
1128
|
+
errors = []
|
|
1129
|
+
if x.precision_absolute() <= 0:
|
|
1130
|
+
from .precision_error import PrecisionError
|
|
1131
|
+
errors.append(PrecisionError)
|
|
1132
|
+
if x.valuation() < 0:
|
|
1133
|
+
errors.append(ValueError)
|
|
1134
|
+
if errors:
|
|
1135
|
+
with tester.assertRaises(tuple(errors)):
|
|
1136
|
+
x.residue()
|
|
1137
|
+
continue
|
|
1138
|
+
y = x.residue()
|
|
1139
|
+
# residue() is in `Z/pZ` which is not identical to the residue field `F_p`
|
|
1140
|
+
tester.assertEqual(y.parent().cardinality(), self.residue_field().cardinality())
|
|
1141
|
+
z = self(y)
|
|
1142
|
+
tester.assertGreater((x-z).valuation(), 0)
|
|
1143
|
+
|
|
1144
|
+
for x in self.residue_field().some_elements():
|
|
1145
|
+
y = self(x)
|
|
1146
|
+
if x.is_zero():
|
|
1147
|
+
tester.assertGreater(y.valuation(), 0)
|
|
1148
|
+
else:
|
|
1149
|
+
tester.assertEqual(y.valuation(), 0)
|
|
1150
|
+
z = y.residue()
|
|
1151
|
+
tester.assertEqual(x, z)
|
|
1152
|
+
|
|
1153
|
+
def _matrix_flatten_precision(self, M):
|
|
1154
|
+
r"""
|
|
1155
|
+
Rescale rows and columns of ``M`` so that the minimal
|
|
1156
|
+
absolute precision of each row and column is equal to
|
|
1157
|
+
the cap.
|
|
1158
|
+
|
|
1159
|
+
This method is useful for increasing the numerical
|
|
1160
|
+
stability. It is called by :meth:`_matrix_smith_form`
|
|
1161
|
+
and :meth:`_matrix_determinant`
|
|
1162
|
+
|
|
1163
|
+
Only for internal use.
|
|
1164
|
+
|
|
1165
|
+
OUTPUT:
|
|
1166
|
+
|
|
1167
|
+
The lists of valuations by which rows and columns,
|
|
1168
|
+
respectively, have been shifted.
|
|
1169
|
+
|
|
1170
|
+
EXAMPLES::
|
|
1171
|
+
|
|
1172
|
+
sage: # needs sage.modules
|
|
1173
|
+
sage: K = Qp(2, print_mode='digits', prec=10)
|
|
1174
|
+
sage: M = matrix(K, 2, 2, [K(1,5),K(2,7),K(3,3),K(5,8)])
|
|
1175
|
+
sage: M
|
|
1176
|
+
[ ...00001 ...0000010]
|
|
1177
|
+
[ ...011 ...00000101]
|
|
1178
|
+
sage: K._matrix_flatten_precision(M)
|
|
1179
|
+
([5, 7], [0, -2])
|
|
1180
|
+
sage: M
|
|
1181
|
+
[ ...0000100000 ...0000010000]
|
|
1182
|
+
[ ...0110000000 ...0000010100000]
|
|
1183
|
+
"""
|
|
1184
|
+
parent = M.base_ring()
|
|
1185
|
+
cap = parent.precision_cap()
|
|
1186
|
+
n = M.nrows()
|
|
1187
|
+
m = M.ncols()
|
|
1188
|
+
shift_rows = n * [ZZ.zero()]
|
|
1189
|
+
shift_cols = m * [ZZ.zero()]
|
|
1190
|
+
for i in range(n):
|
|
1191
|
+
prec = min(M[i, j].precision_absolute() for j in range(m))
|
|
1192
|
+
if prec is Infinity or prec == cap:
|
|
1193
|
+
continue
|
|
1194
|
+
shift_rows[i] = s = cap - prec
|
|
1195
|
+
for j in range(m):
|
|
1196
|
+
M[i, j] <<= s
|
|
1197
|
+
for j in range(m):
|
|
1198
|
+
prec = min(M[i,j].precision_absolute() for i in range(n))
|
|
1199
|
+
if prec is Infinity or prec == cap:
|
|
1200
|
+
continue
|
|
1201
|
+
shift_cols[j] = s = cap - prec
|
|
1202
|
+
for i in range(n):
|
|
1203
|
+
M[i,j] <<= s
|
|
1204
|
+
return shift_rows, shift_cols
|
|
1205
|
+
|
|
1206
|
+
def _matrix_smith_form(self, M, transformation, integral, exact):
|
|
1207
|
+
r"""
|
|
1208
|
+
Return the Smith normal form of the matrix `M`.
|
|
1209
|
+
|
|
1210
|
+
This method gets called by
|
|
1211
|
+
:meth:`sage.matrix.matrix2.Matrix.smith_form` to compute the Smith
|
|
1212
|
+
normal form over local rings and fields.
|
|
1213
|
+
|
|
1214
|
+
The entries of the Smith normal form are normalized such that nonzero
|
|
1215
|
+
entries of the diagonal are powers of the distinguished uniformizer.
|
|
1216
|
+
|
|
1217
|
+
INPUT:
|
|
1218
|
+
|
|
1219
|
+
- ``M`` -- a matrix over this ring
|
|
1220
|
+
|
|
1221
|
+
- ``transformation`` -- boolean; whether the transformation matrices
|
|
1222
|
+
are returned
|
|
1223
|
+
|
|
1224
|
+
- ``integral`` -- a subring of the base ring or ``True``; the entries
|
|
1225
|
+
of the transformation matrices are in this ring. If ``True``, the
|
|
1226
|
+
entries are in the ring of integers of the base ring.
|
|
1227
|
+
|
|
1228
|
+
- ``exact`` -- boolean. If ``True``, the diagonal smith form will
|
|
1229
|
+
be exact, or raise a :exc:`PrecisionError` if this is not possible
|
|
1230
|
+
If ``False``, the diagonal entries will be inexact, but the
|
|
1231
|
+
transformation matrices will be exact.
|
|
1232
|
+
|
|
1233
|
+
EXAMPLES::
|
|
1234
|
+
|
|
1235
|
+
sage: # needs sage.modules
|
|
1236
|
+
sage: A = Zp(5, prec=10, print_mode='digits')
|
|
1237
|
+
sage: M = matrix(A, 2, 2, [2, 7, 1, 6])
|
|
1238
|
+
sage: S, L, R = M.smith_form() # indirect doctest
|
|
1239
|
+
sage: S
|
|
1240
|
+
[ ...1 0]
|
|
1241
|
+
[ 0 ...10]
|
|
1242
|
+
sage: L
|
|
1243
|
+
[...222222223 ...]
|
|
1244
|
+
[...444444444 ...2]
|
|
1245
|
+
sage: R
|
|
1246
|
+
[...0000000001 ...2222222214]
|
|
1247
|
+
[ 0 ...0000000001]
|
|
1248
|
+
|
|
1249
|
+
If not needed, it is possible to avoid the computation of
|
|
1250
|
+
the transformations matrices `L` and `R`::
|
|
1251
|
+
|
|
1252
|
+
sage: # needs sage.modules
|
|
1253
|
+
sage: M.smith_form(transformation=False) # indirect doctest
|
|
1254
|
+
[ ...1 0]
|
|
1255
|
+
[ 0 ...10]
|
|
1256
|
+
|
|
1257
|
+
This method works for rectangular matrices as well::
|
|
1258
|
+
|
|
1259
|
+
sage: # needs sage.modules
|
|
1260
|
+
sage: M = matrix(A, 3, 2, [2, 7, 1, 6, 3, 8])
|
|
1261
|
+
sage: S, L, R = M.smith_form() # indirect doctest
|
|
1262
|
+
sage: S
|
|
1263
|
+
[ ...1 0]
|
|
1264
|
+
[ 0 ...10]
|
|
1265
|
+
[ 0 0]
|
|
1266
|
+
sage: L
|
|
1267
|
+
[...222222223 ... ...]
|
|
1268
|
+
[...444444444 ...2 ...]
|
|
1269
|
+
[...444444443 ...1 ...1]
|
|
1270
|
+
sage: R
|
|
1271
|
+
[...0000000001 ...2222222214]
|
|
1272
|
+
[ 0 ...0000000001]
|
|
1273
|
+
|
|
1274
|
+
If some of the elementary divisors have valuation larger than the
|
|
1275
|
+
minimum precision of any entry in the matrix, then they are
|
|
1276
|
+
reported as an inexact zero::
|
|
1277
|
+
|
|
1278
|
+
sage: # needs sage.modules
|
|
1279
|
+
sage: A = ZpCA(5, prec=10)
|
|
1280
|
+
sage: M = matrix(A, 2, 2, [5, 5, 5, 5])
|
|
1281
|
+
sage: M.smith_form(transformation=False, exact=False) # indirect doctest
|
|
1282
|
+
[5 + O(5^10) O(5^10)]
|
|
1283
|
+
[ O(5^10) O(5^10)]
|
|
1284
|
+
|
|
1285
|
+
However, an error is raised if the precision on the entries is
|
|
1286
|
+
not enough to determine which column to use as a pivot at some point::
|
|
1287
|
+
|
|
1288
|
+
sage: # needs sage.modules
|
|
1289
|
+
sage: M = matrix(A, 2, 2, [A(0,5), A(5^6,10), A(0,8), A(5^7,10)]); M
|
|
1290
|
+
[ O(5^5) 5^6 + O(5^10)]
|
|
1291
|
+
[ O(5^8) 5^7 + O(5^10)]
|
|
1292
|
+
sage: M.smith_form(transformation=False, exact=False) # indirect doctest
|
|
1293
|
+
Traceback (most recent call last):
|
|
1294
|
+
...
|
|
1295
|
+
PrecisionError: not enough precision to compute Smith normal form
|
|
1296
|
+
|
|
1297
|
+
TESTS::
|
|
1298
|
+
|
|
1299
|
+
sage: # needs sage.modules
|
|
1300
|
+
sage: A = ZpCR(5, prec=10)
|
|
1301
|
+
sage: M = zero_matrix(A, 2) # needs sage.geometry.polyhedron
|
|
1302
|
+
sage: M.smith_form(transformation=False) # indirect doctest # needs sage.geometry.polyhedron
|
|
1303
|
+
[0 0]
|
|
1304
|
+
[0 0]
|
|
1305
|
+
|
|
1306
|
+
sage: # needs sage.modules
|
|
1307
|
+
sage: M = matrix(2, 2, [ A(0,10), 0, 0, 0] )
|
|
1308
|
+
sage: M.smith_form(transformation=False) # indirect doctest
|
|
1309
|
+
Traceback (most recent call last):
|
|
1310
|
+
...
|
|
1311
|
+
PrecisionError: some elementary divisors indistinguishable from zero (try exact=False)
|
|
1312
|
+
sage: M.smith_form(transformation=False, exact=False) # indirect doctest
|
|
1313
|
+
[O(5^10) O(5^10)]
|
|
1314
|
+
[O(5^10) O(5^10)]
|
|
1315
|
+
"""
|
|
1316
|
+
from sage.rings.infinity import infinity
|
|
1317
|
+
from .precision_error import PrecisionError
|
|
1318
|
+
from copy import copy
|
|
1319
|
+
n = M.nrows()
|
|
1320
|
+
m = M.ncols()
|
|
1321
|
+
if m > n:
|
|
1322
|
+
## It's easier below if we can always deal with precision on left.
|
|
1323
|
+
if transformation:
|
|
1324
|
+
d, u, v = self._matrix_smith_form(M.transpose(), True, integral, exact)
|
|
1325
|
+
return d.transpose(), v.transpose(), u.transpose()
|
|
1326
|
+
else:
|
|
1327
|
+
return self._matrix_smith_form(M.transpose(), False, integral, exact).transpose()
|
|
1328
|
+
smith = M.parent()(0)
|
|
1329
|
+
S = copy(M)
|
|
1330
|
+
Z = self.integer_ring()
|
|
1331
|
+
if integral is None or integral is self or integral is (not self.is_field()):
|
|
1332
|
+
integral = not self.is_field()
|
|
1333
|
+
R = self
|
|
1334
|
+
elif integral is True or integral is Z:
|
|
1335
|
+
# This is a field, but we want the integral smith form
|
|
1336
|
+
# The diagonal matrix may not be integral, but the transformations should be
|
|
1337
|
+
R = Z
|
|
1338
|
+
integral = True
|
|
1339
|
+
elif integral is False or integral is self.fraction_field():
|
|
1340
|
+
# This is a ring, but we want the field smith form
|
|
1341
|
+
# The diagonal matrix should be over this ring, but the transformations should not
|
|
1342
|
+
R = self.fraction_field()
|
|
1343
|
+
integral = False
|
|
1344
|
+
else:
|
|
1345
|
+
raise NotImplementedError("Smith normal form over this subring")
|
|
1346
|
+
## the difference between ball_prec and inexact_ring is just for lattice precision.
|
|
1347
|
+
ball_prec = R._prec_type() in ['capped-rel','capped-abs']
|
|
1348
|
+
inexact_ring = R._prec_type() not in ['fixed-mod','floating-point']
|
|
1349
|
+
|
|
1350
|
+
if not integral:
|
|
1351
|
+
shift_rows, shift_cols = self._matrix_flatten_precision(S)
|
|
1352
|
+
|
|
1353
|
+
precS = min(x.precision_absolute() for x in S.list())
|
|
1354
|
+
if transformation:
|
|
1355
|
+
from sage.matrix.special import identity_matrix
|
|
1356
|
+
left = identity_matrix(R,n)
|
|
1357
|
+
right = identity_matrix(R,m)
|
|
1358
|
+
|
|
1359
|
+
if ball_prec and precS is infinity: # capped-rel and M = 0 exactly
|
|
1360
|
+
return (smith, left, right) if transformation else smith
|
|
1361
|
+
|
|
1362
|
+
val = -infinity
|
|
1363
|
+
for piv in range(m): # m <= n
|
|
1364
|
+
curval = infinity
|
|
1365
|
+
pivi = pivj = piv
|
|
1366
|
+
# allzero tracks whether every possible pivot is zero.
|
|
1367
|
+
# if so, we can stop. allzero is also used in detecting some
|
|
1368
|
+
# precision problems: if we can't determine what pivot has
|
|
1369
|
+
# the smallest valuation, or if exact=True and some elementary
|
|
1370
|
+
# divisor is zero modulo the working precision
|
|
1371
|
+
allzero = True
|
|
1372
|
+
# allexact is tracked because there is one case where we can correctly
|
|
1373
|
+
# deduce the exact smith form even with some elementary divisors zero:
|
|
1374
|
+
# if the bottom right block consists entirely of exact zeros.
|
|
1375
|
+
allexact = True
|
|
1376
|
+
for i in range(piv,n):
|
|
1377
|
+
for j in range(piv,m):
|
|
1378
|
+
Sij = S[i,j]
|
|
1379
|
+
v = Sij.valuation()
|
|
1380
|
+
allzero = allzero and Sij.is_zero()
|
|
1381
|
+
if exact: # we only care in this case
|
|
1382
|
+
allexact = allexact and Sij.precision_absolute() is infinity
|
|
1383
|
+
if v < curval:
|
|
1384
|
+
pivi = i
|
|
1385
|
+
pivj = j
|
|
1386
|
+
curval = v
|
|
1387
|
+
if v == val:
|
|
1388
|
+
break
|
|
1389
|
+
else:
|
|
1390
|
+
continue
|
|
1391
|
+
break
|
|
1392
|
+
val = curval
|
|
1393
|
+
|
|
1394
|
+
if inexact_ring and not allzero and val >= precS:
|
|
1395
|
+
if ball_prec:
|
|
1396
|
+
raise PrecisionError("not enough precision to compute Smith normal form")
|
|
1397
|
+
precS = min([ S[i,j].precision_absolute() for i in range(piv,n) for j in range(piv,m) ])
|
|
1398
|
+
if val >= precS:
|
|
1399
|
+
raise PrecisionError("not enough precision to compute Smith normal form")
|
|
1400
|
+
|
|
1401
|
+
if allzero:
|
|
1402
|
+
if exact:
|
|
1403
|
+
if allexact:
|
|
1404
|
+
# We need to finish checking allexact since we broke out of the loop early
|
|
1405
|
+
for i in range(i,n):
|
|
1406
|
+
for j in range(piv,m):
|
|
1407
|
+
allexact = allexact and S[i,j].precision_absolute() is infinity
|
|
1408
|
+
if not allexact:
|
|
1409
|
+
break
|
|
1410
|
+
else:
|
|
1411
|
+
continue
|
|
1412
|
+
break
|
|
1413
|
+
if not allexact:
|
|
1414
|
+
raise PrecisionError("some elementary divisors indistinguishable from zero (try exact=False)")
|
|
1415
|
+
break
|
|
1416
|
+
|
|
1417
|
+
# We swap the lowest valuation pivot into position
|
|
1418
|
+
S.swap_rows(pivi,piv)
|
|
1419
|
+
S.swap_columns(pivj,piv)
|
|
1420
|
+
if transformation:
|
|
1421
|
+
left.swap_rows(pivi,piv)
|
|
1422
|
+
right.swap_columns(pivj,piv)
|
|
1423
|
+
|
|
1424
|
+
# ... and clear out this row and column. Note that we
|
|
1425
|
+
# will deal with precision later, thus the call to lift_to_precision
|
|
1426
|
+
smith[piv,piv] = self(1) << val
|
|
1427
|
+
inv = (S[piv,piv] >> val).inverse_of_unit()
|
|
1428
|
+
if ball_prec:
|
|
1429
|
+
inv = inv.lift_to_precision()
|
|
1430
|
+
for i in range(piv+1,n):
|
|
1431
|
+
scalar = -inv * Z(S[i,piv] >> val)
|
|
1432
|
+
if ball_prec:
|
|
1433
|
+
scalar = scalar.lift_to_precision()
|
|
1434
|
+
S.add_multiple_of_row(i,piv,scalar,piv+1)
|
|
1435
|
+
if transformation:
|
|
1436
|
+
left.add_multiple_of_row(i,piv,scalar)
|
|
1437
|
+
if transformation:
|
|
1438
|
+
left.rescale_row(piv,inv)
|
|
1439
|
+
for j in range(piv+1,m):
|
|
1440
|
+
scalar = -inv * Z(S[piv,j] >> val)
|
|
1441
|
+
if ball_prec:
|
|
1442
|
+
scalar = scalar.lift_to_precision()
|
|
1443
|
+
right.add_multiple_of_column(j,piv,scalar)
|
|
1444
|
+
else:
|
|
1445
|
+
# We use piv as an upper bound on a range below, and need to set it correctly
|
|
1446
|
+
# in the case that we didn't break out of the loop
|
|
1447
|
+
piv = m
|
|
1448
|
+
# We update the precision on left
|
|
1449
|
+
# The bigoh measures the effect of multiplying by row operations
|
|
1450
|
+
# on the left in order to clear out the digits in the smith form
|
|
1451
|
+
# with valuation at least precS
|
|
1452
|
+
if ball_prec and exact and transformation:
|
|
1453
|
+
for j in range(n):
|
|
1454
|
+
delta = min(left[i,j].valuation() - smith[i,i].valuation() for i in range(piv))
|
|
1455
|
+
if delta is not infinity:
|
|
1456
|
+
for i in range(n):
|
|
1457
|
+
left[i,j] = left[i,j].add_bigoh(precS + delta)
|
|
1458
|
+
## Otherwise, we update the precision on smith
|
|
1459
|
+
if ball_prec and not exact:
|
|
1460
|
+
smith = smith.apply_map(lambda x: x.add_bigoh(precS))
|
|
1461
|
+
## We now have to adjust the elementary divisors (and precision) in the non-integral case
|
|
1462
|
+
if not integral:
|
|
1463
|
+
for i in range(piv):
|
|
1464
|
+
v = smith[i,i].valuation()
|
|
1465
|
+
if transformation:
|
|
1466
|
+
for j in range(n):
|
|
1467
|
+
left[i,j] >>= v
|
|
1468
|
+
if exact:
|
|
1469
|
+
smith[i,i] = self(1)
|
|
1470
|
+
else:
|
|
1471
|
+
for j in range(n):
|
|
1472
|
+
smith[i,j] = smith[i,j] >> v
|
|
1473
|
+
if transformation:
|
|
1474
|
+
for i in range(n):
|
|
1475
|
+
for j in range(n):
|
|
1476
|
+
left[i,j] <<= shift_rows[j]
|
|
1477
|
+
for i in range(m):
|
|
1478
|
+
for j in range(m):
|
|
1479
|
+
right[i,j] <<= shift_cols[i]
|
|
1480
|
+
if transformation:
|
|
1481
|
+
return smith, left, right
|
|
1482
|
+
else:
|
|
1483
|
+
return smith
|
|
1484
|
+
|
|
1485
|
+
def _test_matrix_smith(self, **options):
|
|
1486
|
+
r"""
|
|
1487
|
+
Test that :meth:`_matrix_smith_form` works correctly.
|
|
1488
|
+
|
|
1489
|
+
EXAMPLES::
|
|
1490
|
+
|
|
1491
|
+
sage: ZpCA(5, 15)._test_matrix_smith() # needs sage.geometry.polyhedron
|
|
1492
|
+
"""
|
|
1493
|
+
tester = self._tester(**options)
|
|
1494
|
+
tester.assertEqual(self.residue_field().characteristic(), self.residue_characteristic())
|
|
1495
|
+
|
|
1496
|
+
from itertools import chain
|
|
1497
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
1498
|
+
from .precision_error import PrecisionError
|
|
1499
|
+
matrices = chain(*[MatrixSpace(self, n, m).some_elements() for n in (1,3,7) for m in (1,4,7)])
|
|
1500
|
+
for M in tester.some_elements(matrices):
|
|
1501
|
+
bases = [self]
|
|
1502
|
+
if self is not self.integer_ring():
|
|
1503
|
+
bases.append(self.integer_ring())
|
|
1504
|
+
for base in bases:
|
|
1505
|
+
try:
|
|
1506
|
+
S,U,V = M.smith_form(integral=base)
|
|
1507
|
+
except PrecisionError:
|
|
1508
|
+
continue
|
|
1509
|
+
|
|
1510
|
+
if self.is_exact() or self._prec_type() not in ['fixed-mod','floating-point']:
|
|
1511
|
+
tester.assertEqual(U*M*V, S)
|
|
1512
|
+
|
|
1513
|
+
tester.assertEqual(U.nrows(), U.ncols())
|
|
1514
|
+
tester.assertEqual(U.base_ring(), base)
|
|
1515
|
+
|
|
1516
|
+
tester.assertEqual(V.nrows(), V.ncols())
|
|
1517
|
+
tester.assertEqual(V.base_ring(), base)
|
|
1518
|
+
|
|
1519
|
+
for d in S.diagonal():
|
|
1520
|
+
if not d.is_zero():
|
|
1521
|
+
tester.assertTrue(d.unit_part().is_one())
|
|
1522
|
+
|
|
1523
|
+
for (d,dd) in zip(S.diagonal(), S.diagonal()[1:]):
|
|
1524
|
+
tester.assertTrue(d.divides(dd))
|
|
1525
|
+
|
|
1526
|
+
def _matrix_determinant(self, M):
|
|
1527
|
+
r"""
|
|
1528
|
+
Return the determinant of the matrix `M`.
|
|
1529
|
+
|
|
1530
|
+
This method gets called by
|
|
1531
|
+
:meth:`sage.matrix.matrix2.Matrix.determinant`.
|
|
1532
|
+
|
|
1533
|
+
INPUT:
|
|
1534
|
+
|
|
1535
|
+
- ``M`` -- a matrix over this ring
|
|
1536
|
+
|
|
1537
|
+
ALGORITHM:
|
|
1538
|
+
|
|
1539
|
+
We flatten the absolute precision in order to increase
|
|
1540
|
+
the numerical stability.
|
|
1541
|
+
|
|
1542
|
+
We row-echelonize the matrix by always choosing the
|
|
1543
|
+
pivot of smallest valuation and allowing permutations
|
|
1544
|
+
of columns.
|
|
1545
|
+
|
|
1546
|
+
Then we compute separately the value of the determinant
|
|
1547
|
+
(as the product of the diagonal entries of the row-echelon
|
|
1548
|
+
form) and a bound on the precision on it.
|
|
1549
|
+
|
|
1550
|
+
EXAMPLES::
|
|
1551
|
+
|
|
1552
|
+
sage: # needs sage.modules
|
|
1553
|
+
sage: R = Qp(5,10)
|
|
1554
|
+
sage: M = matrix(R, 2, 2, [1, 6, 2, 7])
|
|
1555
|
+
sage: M.determinant() # indirect doctest
|
|
1556
|
+
4*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5^9 + O(5^10)
|
|
1557
|
+
sage: (5*M).determinant() # indirect doctest
|
|
1558
|
+
4*5^3 + 4*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + O(5^12)
|
|
1559
|
+
|
|
1560
|
+
Sometimes, we gain precision on the determinant::
|
|
1561
|
+
|
|
1562
|
+
sage: # needs sage.modules
|
|
1563
|
+
sage: M = matrix(R, 3, 3,
|
|
1564
|
+
....: [R(16820,7), R(73642,7), R( 3281,7),
|
|
1565
|
+
....: R(67830,7), R(63768,7), R(76424,7),
|
|
1566
|
+
....: R(37790,7), R(38784,7), R(69287,7)])
|
|
1567
|
+
sage: M.determinant() # indirect doctest
|
|
1568
|
+
4*5^5 + 4*5^6 + 3*5^7 + 2*5^8 + O(5^9)
|
|
1569
|
+
|
|
1570
|
+
TESTS:
|
|
1571
|
+
|
|
1572
|
+
We check the stability of our algorithm::
|
|
1573
|
+
|
|
1574
|
+
sage: # needs sage.modules
|
|
1575
|
+
sage: for dim in range(3,10):
|
|
1576
|
+
....: M = matrix(dim, dim, [ R(1) for _ in range(dim^2) ])
|
|
1577
|
+
....: print(M.determinant())
|
|
1578
|
+
O(5^20)
|
|
1579
|
+
O(5^30)
|
|
1580
|
+
O(5^40)
|
|
1581
|
+
O(5^50)
|
|
1582
|
+
O(5^60)
|
|
1583
|
+
O(5^70)
|
|
1584
|
+
O(5^80)
|
|
1585
|
+
|
|
1586
|
+
sage: # needs sage.geometry.polyhedron
|
|
1587
|
+
sage: A = random_matrix(Qp(5),4)
|
|
1588
|
+
sage: B = random_matrix(Qp(5),4)
|
|
1589
|
+
sage: (A*B).det() == A.det()*B.det()
|
|
1590
|
+
True
|
|
1591
|
+
sage: A.change_ring(QQ).det() == A.det()
|
|
1592
|
+
True
|
|
1593
|
+
|
|
1594
|
+
sage: matrix(Qp(37),[0]).determinant()
|
|
1595
|
+
0
|
|
1596
|
+
sage: matrix(Qp(37),[O(37)]).determinant()
|
|
1597
|
+
O(37)
|
|
1598
|
+
"""
|
|
1599
|
+
n = M.nrows()
|
|
1600
|
+
|
|
1601
|
+
# For 2x2 matrices, we use the formula
|
|
1602
|
+
if n == 2:
|
|
1603
|
+
return M[0,0]*M[1,1] - M[0,1]*M[1,0]
|
|
1604
|
+
|
|
1605
|
+
R = M.base_ring()
|
|
1606
|
+
track_precision = R._prec_type() in ['capped-rel','capped-abs']
|
|
1607
|
+
|
|
1608
|
+
S = copy(M)
|
|
1609
|
+
shift_rows, shift_cols = self._matrix_flatten_precision(S)
|
|
1610
|
+
shift = sum(shift_rows) + sum(shift_cols)
|
|
1611
|
+
det = R(1)
|
|
1612
|
+
|
|
1613
|
+
sign = 1
|
|
1614
|
+
valdet = 0
|
|
1615
|
+
val = -Infinity
|
|
1616
|
+
for piv in range(n):
|
|
1617
|
+
pivi = pivj = piv
|
|
1618
|
+
curval = S[pivi, pivj].valuation()
|
|
1619
|
+
for i in range(piv,n):
|
|
1620
|
+
for j in range(piv,n):
|
|
1621
|
+
v = S[i,j].valuation()
|
|
1622
|
+
if v < curval:
|
|
1623
|
+
pivi = i
|
|
1624
|
+
pivj = j
|
|
1625
|
+
curval = v
|
|
1626
|
+
if v == val:
|
|
1627
|
+
break
|
|
1628
|
+
else:
|
|
1629
|
+
continue
|
|
1630
|
+
break
|
|
1631
|
+
val = curval
|
|
1632
|
+
if S[pivi,pivj] == 0:
|
|
1633
|
+
if track_precision:
|
|
1634
|
+
return R(0, valdet + (n-piv)*val - shift)
|
|
1635
|
+
else:
|
|
1636
|
+
return R(0)
|
|
1637
|
+
|
|
1638
|
+
valdet += val
|
|
1639
|
+
S.swap_rows(pivi,piv)
|
|
1640
|
+
if pivi > piv:
|
|
1641
|
+
sign = -sign
|
|
1642
|
+
S.swap_columns(pivj,piv)
|
|
1643
|
+
if pivj > piv:
|
|
1644
|
+
sign = -sign
|
|
1645
|
+
|
|
1646
|
+
det *= S[piv,piv]
|
|
1647
|
+
inv = ~(S[piv,piv] >> val)
|
|
1648
|
+
for i in range(piv+1,n):
|
|
1649
|
+
scalar = -inv * (S[i,piv] >> val)
|
|
1650
|
+
if track_precision:
|
|
1651
|
+
scalar = scalar.lift_to_precision()
|
|
1652
|
+
S.add_multiple_of_row(i,piv,scalar)
|
|
1653
|
+
|
|
1654
|
+
if track_precision:
|
|
1655
|
+
relprec = +Infinity
|
|
1656
|
+
relprec_neg = 0
|
|
1657
|
+
for i in range(n):
|
|
1658
|
+
prec = Infinity
|
|
1659
|
+
for j in range(n):
|
|
1660
|
+
prec = min(prec, S[i,j].precision_absolute())
|
|
1661
|
+
prec -= S[i,i].valuation()
|
|
1662
|
+
relprec = min(prec, relprec)
|
|
1663
|
+
if prec < 0:
|
|
1664
|
+
relprec_neg += prec
|
|
1665
|
+
if relprec_neg < 0:
|
|
1666
|
+
relprec = relprec_neg
|
|
1667
|
+
det = (sign*det).add_bigoh(valdet+relprec)
|
|
1668
|
+
else:
|
|
1669
|
+
det = sign*det
|
|
1670
|
+
return det >> shift
|