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,1911 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# sage.doctest: needs sage.rings.padics
|
|
3
|
+
r"""
|
|
4
|
+
`p`-adic Generic
|
|
5
|
+
|
|
6
|
+
A generic superclass for all `p`-adic parents.
|
|
7
|
+
|
|
8
|
+
AUTHORS:
|
|
9
|
+
|
|
10
|
+
- David Roe
|
|
11
|
+
- Genya Zaytman: documentation
|
|
12
|
+
- David Harvey: doctests
|
|
13
|
+
- Julian Rueth (2013-03-16): test methods for basic arithmetic
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# ****************************************************************************
|
|
17
|
+
# Copyright (C) 2007-2013 David Roe <roed.math@gmail.com>
|
|
18
|
+
# William Stein <wstein@gmail.com>
|
|
19
|
+
# Julian Rueth <julian.rueth@fsfe.org>
|
|
20
|
+
#
|
|
21
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
22
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
23
|
+
# the License, or (at your option) any later version.
|
|
24
|
+
#
|
|
25
|
+
# https://www.gnu.org/licenses/
|
|
26
|
+
# ****************************************************************************
|
|
27
|
+
|
|
28
|
+
from copy import copy
|
|
29
|
+
|
|
30
|
+
from sage.structure.richcmp import richcmp
|
|
31
|
+
from sage.categories.principal_ideal_domains import PrincipalIdealDomains
|
|
32
|
+
from sage.categories.morphism import Morphism
|
|
33
|
+
from sage.categories.fields import Fields
|
|
34
|
+
from sage.rings.infinity import infinity
|
|
35
|
+
from .local_generic import LocalGeneric
|
|
36
|
+
from sage.rings.integer import Integer
|
|
37
|
+
from sage.rings.infinity import Infinity
|
|
38
|
+
from sage.rings.padics.precision_error import PrecisionError
|
|
39
|
+
from sage.misc.cachefunc import cached_method
|
|
40
|
+
from sage.structure.richcmp import richcmp_not_equal
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class pAdicGeneric(LocalGeneric):
|
|
44
|
+
def __init__(self, base, p, prec, print_mode, names, element_class, category=None):
|
|
45
|
+
r"""
|
|
46
|
+
Initialize ``self``.
|
|
47
|
+
|
|
48
|
+
INPUT:
|
|
49
|
+
|
|
50
|
+
- ``base`` -- base ring
|
|
51
|
+
- ``p`` -- prime
|
|
52
|
+
- ``print_mode`` -- dictionary of print options
|
|
53
|
+
- ``names`` -- how to print the uniformizer
|
|
54
|
+
- ``element_class`` -- the class for elements of this ring
|
|
55
|
+
|
|
56
|
+
EXAMPLES::
|
|
57
|
+
|
|
58
|
+
sage: R = Zp(17) # indirect doctest
|
|
59
|
+
"""
|
|
60
|
+
from sage.rings.padics.padic_printing import pAdicPrinter
|
|
61
|
+
|
|
62
|
+
if category is None:
|
|
63
|
+
if self.is_field():
|
|
64
|
+
category = Fields()
|
|
65
|
+
else:
|
|
66
|
+
category = PrincipalIdealDomains()
|
|
67
|
+
category = category.Metric().Complete()
|
|
68
|
+
LocalGeneric.__init__(self, base, prec, names, element_class, category)
|
|
69
|
+
self._printer = pAdicPrinter(self, print_mode)
|
|
70
|
+
self._qth_roots_of_unity = [(1, Infinity)]
|
|
71
|
+
|
|
72
|
+
def some_elements(self):
|
|
73
|
+
r"""
|
|
74
|
+
Return a list of elements in this ring.
|
|
75
|
+
|
|
76
|
+
This is typically used for running generic tests (see :class:`TestSuite`).
|
|
77
|
+
|
|
78
|
+
EXAMPLES::
|
|
79
|
+
|
|
80
|
+
sage: Zp(2,4).some_elements()
|
|
81
|
+
[0, 1 + O(2^4), 2 + O(2^5), 1 + 2^2 + 2^3 + O(2^4), 2 + 2^2 + 2^3 + 2^4 + O(2^5)]
|
|
82
|
+
"""
|
|
83
|
+
p = self(self.prime())
|
|
84
|
+
a = self.gen()
|
|
85
|
+
one = self.one()
|
|
86
|
+
L = [self.zero(), one, p, (one+p+p).inverse_of_unit(), p-p**2]
|
|
87
|
+
if a != p:
|
|
88
|
+
L.extend([a, (one + a + p).inverse_of_unit()])
|
|
89
|
+
if self.is_field():
|
|
90
|
+
L.extend([~(p-p-a),p**(-20)])
|
|
91
|
+
return L
|
|
92
|
+
|
|
93
|
+
def _modified_print_mode(self, print_mode):
|
|
94
|
+
r"""
|
|
95
|
+
Return a dictionary of print options, starting with ``self``'s
|
|
96
|
+
print options but modified by the options in the dictionary
|
|
97
|
+
``print_mode``.
|
|
98
|
+
|
|
99
|
+
INPUT:
|
|
100
|
+
|
|
101
|
+
- ``print_mode`` -- dictionary with keys in
|
|
102
|
+
|
|
103
|
+
* ``mode``
|
|
104
|
+
* ``pos``
|
|
105
|
+
* ``ram_name``
|
|
106
|
+
* ``unram_name``
|
|
107
|
+
* ``var_name``
|
|
108
|
+
* ``max_ram_terms``
|
|
109
|
+
* ``max_unram_terms``
|
|
110
|
+
* ``max_terse_terms``
|
|
111
|
+
* ``sep``
|
|
112
|
+
* ``alphabet``
|
|
113
|
+
|
|
114
|
+
EXAMPLES::
|
|
115
|
+
|
|
116
|
+
sage: R = Zp(5)
|
|
117
|
+
sage: R._modified_print_mode({'mode': 'bars'})['ram_name']
|
|
118
|
+
'5'
|
|
119
|
+
"""
|
|
120
|
+
if print_mode is None:
|
|
121
|
+
print_mode = {}
|
|
122
|
+
elif isinstance(print_mode, str):
|
|
123
|
+
print_mode = {'mode': print_mode}
|
|
124
|
+
for option in ['mode', 'pos', 'ram_name', 'unram_name', 'var_name',
|
|
125
|
+
'max_ram_terms', 'max_unram_terms', 'max_terse_terms',
|
|
126
|
+
'sep', 'alphabet', 'show_prec']:
|
|
127
|
+
if option not in print_mode:
|
|
128
|
+
print_mode[option] = self._printer.dict()[option]
|
|
129
|
+
return print_mode
|
|
130
|
+
|
|
131
|
+
def ngens(self):
|
|
132
|
+
r"""
|
|
133
|
+
Return the number of generators of ``self``.
|
|
134
|
+
|
|
135
|
+
We conventionally define this as 1: for base rings, we take a
|
|
136
|
+
uniformizer as the generator; for extension rings, we take a
|
|
137
|
+
root of the minimal polynomial defining the extension.
|
|
138
|
+
|
|
139
|
+
EXAMPLES::
|
|
140
|
+
|
|
141
|
+
sage: Zp(5).ngens()
|
|
142
|
+
1
|
|
143
|
+
sage: Zq(25,names='a').ngens() # needs sage.libs.ntl
|
|
144
|
+
1
|
|
145
|
+
"""
|
|
146
|
+
return 1
|
|
147
|
+
|
|
148
|
+
def gens(self) -> tuple:
|
|
149
|
+
r"""
|
|
150
|
+
Return a tuple of generators.
|
|
151
|
+
|
|
152
|
+
EXAMPLES::
|
|
153
|
+
|
|
154
|
+
sage: R = Zp(5); R.gens()
|
|
155
|
+
(5 + O(5^21),)
|
|
156
|
+
sage: Zq(25,names='a').gens() # needs sage.libs.ntl
|
|
157
|
+
(a + O(5^20),)
|
|
158
|
+
sage: S.<x> = ZZ[]; f = x^5 + 25*x -5; W.<w> = R.ext(f); W.gens() # needs sage.libs.ntl
|
|
159
|
+
(w + O(w^101),)
|
|
160
|
+
"""
|
|
161
|
+
return (self.gen(),)
|
|
162
|
+
|
|
163
|
+
def __richcmp__(self, other, op):
|
|
164
|
+
r"""
|
|
165
|
+
Rich comparison of ``self`` with ``other``.
|
|
166
|
+
|
|
167
|
+
We consider two `p`-adic rings or fields to be equal if they are
|
|
168
|
+
equal mathematically, and also have the same precision cap and
|
|
169
|
+
printing parameters.
|
|
170
|
+
|
|
171
|
+
EXAMPLES::
|
|
172
|
+
|
|
173
|
+
sage: R = Qp(7)
|
|
174
|
+
sage: S = Qp(7,print_mode='val-unit')
|
|
175
|
+
sage: R == S
|
|
176
|
+
False
|
|
177
|
+
sage: S = Qp(7,type='capped-rel')
|
|
178
|
+
sage: R == S
|
|
179
|
+
True
|
|
180
|
+
sage: R is S
|
|
181
|
+
True
|
|
182
|
+
"""
|
|
183
|
+
if not isinstance(other, pAdicGeneric):
|
|
184
|
+
return NotImplemented
|
|
185
|
+
|
|
186
|
+
lx = self.prime()
|
|
187
|
+
rx = other.prime()
|
|
188
|
+
if lx != rx:
|
|
189
|
+
return richcmp_not_equal(lx, rx, op)
|
|
190
|
+
|
|
191
|
+
lx = self.precision_cap()
|
|
192
|
+
rx = other.precision_cap()
|
|
193
|
+
if lx != rx:
|
|
194
|
+
return richcmp_not_equal(lx, rx, op)
|
|
195
|
+
|
|
196
|
+
return self._printer.richcmp_modes(other._printer, op)
|
|
197
|
+
|
|
198
|
+
def print_mode(self) -> str:
|
|
199
|
+
r"""
|
|
200
|
+
Return the current print mode as a string.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: R = Qp(7,5, 'capped-rel')
|
|
205
|
+
sage: R.print_mode()
|
|
206
|
+
'series'
|
|
207
|
+
"""
|
|
208
|
+
return self._printer._print_mode()
|
|
209
|
+
|
|
210
|
+
def characteristic(self):
|
|
211
|
+
r"""
|
|
212
|
+
Return the characteristic of ``self``, which is always 0.
|
|
213
|
+
|
|
214
|
+
EXAMPLES::
|
|
215
|
+
|
|
216
|
+
sage: R = Zp(3, 10,'fixed-mod'); R.characteristic()
|
|
217
|
+
0
|
|
218
|
+
"""
|
|
219
|
+
return Integer(0)
|
|
220
|
+
|
|
221
|
+
def prime(self):
|
|
222
|
+
r"""
|
|
223
|
+
Return the prime, ie the characteristic of the residue field.
|
|
224
|
+
|
|
225
|
+
OUTPUT: the characteristic of the residue field
|
|
226
|
+
|
|
227
|
+
EXAMPLES::
|
|
228
|
+
|
|
229
|
+
sage: R = Zp(3,5,'fixed-mod')
|
|
230
|
+
sage: R.prime()
|
|
231
|
+
3
|
|
232
|
+
"""
|
|
233
|
+
return self.prime_pow._prime()
|
|
234
|
+
|
|
235
|
+
def uniformizer_pow(self, n):
|
|
236
|
+
r"""
|
|
237
|
+
Return `p^n`, as an element of ``self``.
|
|
238
|
+
|
|
239
|
+
If ``n`` is infinity, returns 0.
|
|
240
|
+
|
|
241
|
+
EXAMPLES::
|
|
242
|
+
|
|
243
|
+
sage: R = Zp(3, 5, 'fixed-mod')
|
|
244
|
+
sage: R.uniformizer_pow(3)
|
|
245
|
+
3^3
|
|
246
|
+
sage: R.uniformizer_pow(infinity)
|
|
247
|
+
0
|
|
248
|
+
"""
|
|
249
|
+
if n is infinity:
|
|
250
|
+
return self(0)
|
|
251
|
+
return self(self.prime_pow.pow_Integer_Integer(n))
|
|
252
|
+
|
|
253
|
+
def _unram_print(self):
|
|
254
|
+
r"""
|
|
255
|
+
For printing. Will be ``None`` if the unramified subextension
|
|
256
|
+
of ``self`` is of degree 1 over `\ZZ_p` or `\QQ_p`.
|
|
257
|
+
|
|
258
|
+
EXAMPLES::
|
|
259
|
+
|
|
260
|
+
sage: Zp(5)._unram_print()
|
|
261
|
+
"""
|
|
262
|
+
return None
|
|
263
|
+
|
|
264
|
+
def residue_characteristic(self):
|
|
265
|
+
r"""
|
|
266
|
+
Return the prime, i.e., the characteristic of the residue field.
|
|
267
|
+
|
|
268
|
+
OUTPUT: the characteristic of the residue field
|
|
269
|
+
|
|
270
|
+
EXAMPLES::
|
|
271
|
+
|
|
272
|
+
sage: R = Zp(3,5,'fixed-mod')
|
|
273
|
+
sage: R.residue_characteristic()
|
|
274
|
+
3
|
|
275
|
+
"""
|
|
276
|
+
return self.prime()
|
|
277
|
+
|
|
278
|
+
def residue_class_field(self):
|
|
279
|
+
r"""
|
|
280
|
+
Return the residue class field.
|
|
281
|
+
|
|
282
|
+
EXAMPLES::
|
|
283
|
+
|
|
284
|
+
sage: R = Zp(3,5,'fixed-mod')
|
|
285
|
+
sage: k = R.residue_class_field()
|
|
286
|
+
sage: k
|
|
287
|
+
Finite Field of size 3
|
|
288
|
+
"""
|
|
289
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
290
|
+
return GF(self.prime())
|
|
291
|
+
|
|
292
|
+
def residue_field(self):
|
|
293
|
+
r"""
|
|
294
|
+
Return the residue class field.
|
|
295
|
+
|
|
296
|
+
EXAMPLES::
|
|
297
|
+
|
|
298
|
+
sage: R = Zp(3,5,'fixed-mod')
|
|
299
|
+
sage: k = R.residue_field()
|
|
300
|
+
sage: k
|
|
301
|
+
Finite Field of size 3
|
|
302
|
+
"""
|
|
303
|
+
return self.residue_class_field()
|
|
304
|
+
|
|
305
|
+
def residue_ring(self, n):
|
|
306
|
+
r"""
|
|
307
|
+
Return the quotient of the ring of integers by the ``n``-th
|
|
308
|
+
power of the maximal ideal.
|
|
309
|
+
|
|
310
|
+
EXAMPLES::
|
|
311
|
+
|
|
312
|
+
sage: R = Zp(11)
|
|
313
|
+
sage: R.residue_ring(3)
|
|
314
|
+
Ring of integers modulo 1331
|
|
315
|
+
"""
|
|
316
|
+
from sage.rings.finite_rings.integer_mod_ring import Zmod
|
|
317
|
+
return Zmod(self.prime()**n)
|
|
318
|
+
|
|
319
|
+
def residue_system(self):
|
|
320
|
+
r"""
|
|
321
|
+
Return a list of elements representing all the residue classes.
|
|
322
|
+
|
|
323
|
+
EXAMPLES::
|
|
324
|
+
|
|
325
|
+
sage: R = Zp(3, 5,'fixed-mod')
|
|
326
|
+
sage: R.residue_system()
|
|
327
|
+
[0, 1, 2]
|
|
328
|
+
"""
|
|
329
|
+
return [self(i) for i in self.residue_class_field()]
|
|
330
|
+
|
|
331
|
+
def _fraction_field_key(self, print_mode=None):
|
|
332
|
+
r"""
|
|
333
|
+
Change ``print_mode`` from a dictionary to a tuple, raising
|
|
334
|
+
a deprecation warning if it is present.
|
|
335
|
+
|
|
336
|
+
EXAMPLES::
|
|
337
|
+
|
|
338
|
+
sage: Zp(5)._fraction_field_key()
|
|
339
|
+
sage: Zp(5)._fraction_field_key({"pos":False})
|
|
340
|
+
doctest:warning
|
|
341
|
+
...
|
|
342
|
+
DeprecationWarning: Use the change method if you want to change print options in fraction_field()
|
|
343
|
+
See https://github.com/sagemath/sage/issues/23227 for details.
|
|
344
|
+
(('pos', False),)
|
|
345
|
+
"""
|
|
346
|
+
if print_mode is not None:
|
|
347
|
+
from sage.misc.superseded import deprecation
|
|
348
|
+
deprecation(23227, "Use the change method if you want to change print options in fraction_field()")
|
|
349
|
+
return tuple(sorted(print_mode.items()))
|
|
350
|
+
|
|
351
|
+
@cached_method(key=_fraction_field_key)
|
|
352
|
+
def fraction_field(self, print_mode=None):
|
|
353
|
+
r"""
|
|
354
|
+
Return the fraction field of this ring or field.
|
|
355
|
+
|
|
356
|
+
For `\ZZ_p`, this is the `p`-adic field with the same options,
|
|
357
|
+
and for extensions, it is just the extension of the fraction
|
|
358
|
+
field of the base determined by the same polynomial.
|
|
359
|
+
|
|
360
|
+
The fraction field of a capped absolute ring is capped relative,
|
|
361
|
+
and that of a fixed modulus ring is floating point.
|
|
362
|
+
|
|
363
|
+
INPUT:
|
|
364
|
+
|
|
365
|
+
- ``print_mode`` -- (optional) a dictionary containing print options;
|
|
366
|
+
defaults to the same options as this ring
|
|
367
|
+
|
|
368
|
+
OUTPUT: the fraction field of this ring
|
|
369
|
+
|
|
370
|
+
EXAMPLES::
|
|
371
|
+
|
|
372
|
+
sage: R = Zp(5, print_mode='digits', show_prec=False)
|
|
373
|
+
sage: K = R.fraction_field(); K(1/3)
|
|
374
|
+
31313131313131313132
|
|
375
|
+
sage: L = R.fraction_field({'max_ram_terms':4}); L(1/3)
|
|
376
|
+
doctest:warning
|
|
377
|
+
...
|
|
378
|
+
DeprecationWarning: Use the change method if you want to change print options in fraction_field()
|
|
379
|
+
See https://github.com/sagemath/sage/issues/23227 for details.
|
|
380
|
+
3132
|
|
381
|
+
sage: U.<a> = Zq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3) # needs sage.libs.ntl
|
|
382
|
+
sage: U.fraction_field() # needs sage.libs.ntl
|
|
383
|
+
17-adic Unramified Extension Field in a defined by x^4 + 7*x^2 + 10*x + 3
|
|
384
|
+
sage: U.fraction_field({"pos":False}) == U.fraction_field() # needs sage.libs.ntl
|
|
385
|
+
False
|
|
386
|
+
|
|
387
|
+
TESTS::
|
|
388
|
+
|
|
389
|
+
sage: R = ZpLC(2); R
|
|
390
|
+
doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation.
|
|
391
|
+
See https://github.com/sagemath/sage/issues/23505 for details.
|
|
392
|
+
2-adic Ring with lattice-cap precision
|
|
393
|
+
sage: K = R.fraction_field(); K
|
|
394
|
+
2-adic Field with lattice-cap precision
|
|
395
|
+
|
|
396
|
+
sage: K = QpLC(2); K2 = K.fraction_field({'mode':'terse'})
|
|
397
|
+
sage: K2 is K
|
|
398
|
+
False
|
|
399
|
+
sage: K = QpLC(2, label='test'); K
|
|
400
|
+
2-adic Field with lattice-cap precision (label: test)
|
|
401
|
+
sage: K.fraction_field()
|
|
402
|
+
2-adic Field with lattice-cap precision (label: test)
|
|
403
|
+
sage: K.fraction_field({'mode':'series'}) is K
|
|
404
|
+
True
|
|
405
|
+
"""
|
|
406
|
+
if self.is_field() and print_mode is None:
|
|
407
|
+
return self
|
|
408
|
+
if print_mode is None:
|
|
409
|
+
return self.change(field=True)
|
|
410
|
+
else:
|
|
411
|
+
return self.change(field=True, **print_mode)
|
|
412
|
+
|
|
413
|
+
def integer_ring(self, print_mode=None):
|
|
414
|
+
r"""
|
|
415
|
+
Return the ring of integers of this ring or field.
|
|
416
|
+
|
|
417
|
+
For `\QQ_p`, this is the `p`-adic ring with the same options,
|
|
418
|
+
and for extensions, it is just the extension of the ring
|
|
419
|
+
of integers of the base determined by the same polynomial.
|
|
420
|
+
|
|
421
|
+
INPUT:
|
|
422
|
+
|
|
423
|
+
- ``print_mode`` -- (optional) a dictionary containing print options;
|
|
424
|
+
defaults to the same options as this ring
|
|
425
|
+
|
|
426
|
+
OUTPUT: the ring of elements of this field with nonnegative valuation
|
|
427
|
+
|
|
428
|
+
EXAMPLES::
|
|
429
|
+
|
|
430
|
+
sage: K = Qp(5, print_mode='digits', show_prec=False)
|
|
431
|
+
sage: R = K.integer_ring(); R(1/3)
|
|
432
|
+
31313131313131313132
|
|
433
|
+
sage: S = K.integer_ring({'max_ram_terms':4}); S(1/3)
|
|
434
|
+
doctest:warning
|
|
435
|
+
...
|
|
436
|
+
DeprecationWarning: Use the change method if you want to change print options in integer_ring()
|
|
437
|
+
See https://github.com/sagemath/sage/issues/23227 for details.
|
|
438
|
+
3132
|
|
439
|
+
sage: U.<a> = Qq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3) # needs sage.libs.ntl
|
|
440
|
+
sage: U.integer_ring() # needs sage.libs.ntl
|
|
441
|
+
17-adic Unramified Extension Ring in a defined by x^4 + 7*x^2 + 10*x + 3
|
|
442
|
+
sage: U.fraction_field({"print_mode":"terse"}) == U.fraction_field() # needs sage.libs.ntl
|
|
443
|
+
doctest:warning
|
|
444
|
+
...
|
|
445
|
+
DeprecationWarning: Use the change method if you want to change print options in fraction_field()
|
|
446
|
+
See https://github.com/sagemath/sage/issues/23227 for details.
|
|
447
|
+
False
|
|
448
|
+
|
|
449
|
+
TESTS::
|
|
450
|
+
|
|
451
|
+
sage: K = QpLC(2); K
|
|
452
|
+
2-adic Field with lattice-cap precision
|
|
453
|
+
sage: R = K.integer_ring(); R
|
|
454
|
+
2-adic Ring with lattice-cap precision
|
|
455
|
+
|
|
456
|
+
sage: R = ZpLC(2); R2 = R.integer_ring({'mode':'terse'})
|
|
457
|
+
sage: R2 is R
|
|
458
|
+
False
|
|
459
|
+
sage: R = ZpLC(2, label='test'); R
|
|
460
|
+
2-adic Ring with lattice-cap precision (label: test)
|
|
461
|
+
sage: R.integer_ring()
|
|
462
|
+
2-adic Ring with lattice-cap precision (label: test)
|
|
463
|
+
sage: R.integer_ring({'mode':'series'}) is R
|
|
464
|
+
True
|
|
465
|
+
|
|
466
|
+
The `secure` attribute for relaxed type is preserved::
|
|
467
|
+
|
|
468
|
+
sage: K = QpER(5, secure=True) # needs sage.libs.flint
|
|
469
|
+
sage: K.integer_ring().is_secure()
|
|
470
|
+
True
|
|
471
|
+
"""
|
|
472
|
+
# Currently does not support fields with non integral defining
|
|
473
|
+
# polynomials. This should change when the padic_general_extension
|
|
474
|
+
# framework gets worked out.
|
|
475
|
+
if not self.is_field() and print_mode is None:
|
|
476
|
+
return self
|
|
477
|
+
if print_mode is None:
|
|
478
|
+
return self.change(field=False, check=False)
|
|
479
|
+
else:
|
|
480
|
+
from sage.misc.superseded import deprecation
|
|
481
|
+
deprecation(23227, "Use the change method if you want to change print options in integer_ring()")
|
|
482
|
+
return self.change(field=False, **print_mode)
|
|
483
|
+
|
|
484
|
+
def teichmuller(self, x, prec=None):
|
|
485
|
+
r"""
|
|
486
|
+
Return the Teichmüller representative of ``x``.
|
|
487
|
+
|
|
488
|
+
- ``x`` -- something that can be cast into ``self``
|
|
489
|
+
|
|
490
|
+
OUTPUT: the Teichmüller lift of ``x``
|
|
491
|
+
|
|
492
|
+
EXAMPLES::
|
|
493
|
+
|
|
494
|
+
sage: R = Zp(5, 10, 'capped-rel', 'series')
|
|
495
|
+
sage: R.teichmuller(2)
|
|
496
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
|
|
497
|
+
sage: R = Qp(5, 10,'capped-rel','series')
|
|
498
|
+
sage: R.teichmuller(2)
|
|
499
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
|
|
500
|
+
sage: R = Zp(5, 10, 'capped-abs', 'series')
|
|
501
|
+
sage: R.teichmuller(2)
|
|
502
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
|
|
503
|
+
sage: R = Zp(5, 10, 'fixed-mod', 'series')
|
|
504
|
+
sage: R.teichmuller(2)
|
|
505
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9
|
|
506
|
+
|
|
507
|
+
sage: # needs sage.libs.ntl
|
|
508
|
+
sage: R = Zp(5,5)
|
|
509
|
+
sage: S.<x> = R[]
|
|
510
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5
|
|
511
|
+
sage: W.<w> = R.ext(f)
|
|
512
|
+
sage: y = W.teichmuller(3); y
|
|
513
|
+
3 + 3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + 3*w^15
|
|
514
|
+
+ 2*w^16 + 3*w^17 + w^18 + 3*w^19 + 3*w^20 + 2*w^21 + 2*w^22
|
|
515
|
+
+ 3*w^23 + 4*w^24 + O(w^25)
|
|
516
|
+
sage: y^5 == y
|
|
517
|
+
True
|
|
518
|
+
sage: g = x^3 + 3*x + 3
|
|
519
|
+
sage: A.<a> = R.ext(g)
|
|
520
|
+
sage: b = A.teichmuller(1 + 2*a - a^2); b
|
|
521
|
+
(4*a^2 + 2*a + 1) + 2*a*5 + (3*a^2 + 1)*5^2 + (a + 4)*5^3
|
|
522
|
+
+ (a^2 + a + 1)*5^4 + O(5^5)
|
|
523
|
+
sage: b^125 == b
|
|
524
|
+
True
|
|
525
|
+
|
|
526
|
+
We check that :issue:`23736` is resolved::
|
|
527
|
+
|
|
528
|
+
sage: # needs sage.libs.ntl
|
|
529
|
+
sage: R.teichmuller(GF(5)(2))
|
|
530
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + O(5^5)
|
|
531
|
+
|
|
532
|
+
AUTHORS:
|
|
533
|
+
|
|
534
|
+
- Initial version: David Roe
|
|
535
|
+
- Quadratic time version: Kiran Kedlaya <kedlaya@math.mit.edu> (2007-03-27)
|
|
536
|
+
"""
|
|
537
|
+
ans = self(x) if prec is None else self(x, prec)
|
|
538
|
+
# Since Teichmüller representatives are defined at infinite precision,
|
|
539
|
+
# we can lift to precision prec, as long as the absolute precision of ans is positive.
|
|
540
|
+
if ans.precision_absolute() <= 0:
|
|
541
|
+
raise ValueError("not enough precision to determine Teichmuller representative")
|
|
542
|
+
if ans.valuation() > 0:
|
|
543
|
+
return self(0) if prec is None else self(0, prec)
|
|
544
|
+
ans = ans.lift_to_precision(prec)
|
|
545
|
+
if ans is x:
|
|
546
|
+
ans = copy(ans)
|
|
547
|
+
ans._teichmuller_set_unsafe()
|
|
548
|
+
return ans
|
|
549
|
+
|
|
550
|
+
def teichmuller_system(self):
|
|
551
|
+
r"""
|
|
552
|
+
Return a set of Teichmüller representatives for the invertible
|
|
553
|
+
elements of `\ZZ / p\ZZ`.
|
|
554
|
+
|
|
555
|
+
OUTPUT:
|
|
556
|
+
|
|
557
|
+
A list of Teichmüller representatives for the invertible elements
|
|
558
|
+
of `\ZZ / p\ZZ`.
|
|
559
|
+
|
|
560
|
+
EXAMPLES::
|
|
561
|
+
|
|
562
|
+
sage: R = Zp(3, 5,'fixed-mod', 'terse')
|
|
563
|
+
sage: R.teichmuller_system()
|
|
564
|
+
[1, 242]
|
|
565
|
+
|
|
566
|
+
Check that :issue:`20457` is fixed::
|
|
567
|
+
|
|
568
|
+
sage: F.<a> = Qq(5^2,6) # needs sage.libs.ntl
|
|
569
|
+
sage: F.teichmuller_system()[3] # needs sage.libs.ntl
|
|
570
|
+
(2*a + 2) + (4*a + 1)*5 + 4*5^2 + (2*a + 1)*5^3 + (4*a + 1)*5^4 + (2*a + 3)*5^5 + O(5^6)
|
|
571
|
+
|
|
572
|
+
.. NOTE::
|
|
573
|
+
|
|
574
|
+
Should this return 0 as well?
|
|
575
|
+
"""
|
|
576
|
+
R = self.residue_class_field()
|
|
577
|
+
prec = self.precision_cap()
|
|
578
|
+
return [self.teichmuller(self(i).lift_to_precision(prec))
|
|
579
|
+
for i in R if i != 0]
|
|
580
|
+
|
|
581
|
+
# def different(self):
|
|
582
|
+
# raise NotImplementedError
|
|
583
|
+
|
|
584
|
+
# def automorphisms(self):
|
|
585
|
+
# r"""
|
|
586
|
+
# Returns the group of automorphisms of `\ZZ_p`, i.e. the trivial group.
|
|
587
|
+
# """
|
|
588
|
+
# raise NotImplementedError
|
|
589
|
+
|
|
590
|
+
# def galois_group(self):
|
|
591
|
+
# r"""
|
|
592
|
+
# Returns the Galois group of `\ZZ_p`, i.e. the trivial group.
|
|
593
|
+
# """
|
|
594
|
+
# raise NotImplementedError
|
|
595
|
+
|
|
596
|
+
# def hasGNB(self):
|
|
597
|
+
# r"""
|
|
598
|
+
# Returns whether or not `\ZZ_p` has a Gauss Normal Basis.
|
|
599
|
+
# """
|
|
600
|
+
# raise NotImplementedError
|
|
601
|
+
|
|
602
|
+
def extension(self, modulus, prec=None, names=None, print_mode=None, implementation='FLINT', **kwds):
|
|
603
|
+
r"""
|
|
604
|
+
Create an extension of this `p`-adic ring.
|
|
605
|
+
|
|
606
|
+
EXAMPLES::
|
|
607
|
+
|
|
608
|
+
sage: # needs sage.libs.ntl
|
|
609
|
+
sage: k = Qp(5)
|
|
610
|
+
sage: R.<x> = k[]
|
|
611
|
+
sage: l.<w> = k.extension(x^2 - 5); l
|
|
612
|
+
5-adic Eisenstein Extension Field in w defined by x^2 - 5
|
|
613
|
+
sage: F = list(Qp(19)['x'](cyclotomic_polynomial(5)).factor())[0][0]
|
|
614
|
+
sage: L = Qp(19).extension(F, names='a'); L
|
|
615
|
+
19-adic Unramified Extension Field in a defined by x^2 + 8751674996211859573806383*x + 1
|
|
616
|
+
"""
|
|
617
|
+
if isinstance(modulus, list):
|
|
618
|
+
if len(modulus) == 0:
|
|
619
|
+
return self
|
|
620
|
+
else:
|
|
621
|
+
return self.extension(modulus[-1], prec=prec[-1],
|
|
622
|
+
names=names[-1],
|
|
623
|
+
implementation=implementation[-1],
|
|
624
|
+
print_mode=print_mode, **kwds).extension(
|
|
625
|
+
modulus[:-1], prec=prec[:-1],
|
|
626
|
+
names=names[:-1],
|
|
627
|
+
implementation=implementation[:-1],
|
|
628
|
+
print_mode=print_mode, **kwds)
|
|
629
|
+
from sage.rings.padics.factory import ExtensionFactory
|
|
630
|
+
if print_mode is None:
|
|
631
|
+
print_mode = {}
|
|
632
|
+
elif isinstance(print_mode, str):
|
|
633
|
+
print_mode = {'print_mode': print_mode}
|
|
634
|
+
else:
|
|
635
|
+
if not isinstance(print_mode, dict):
|
|
636
|
+
print_mode = dict(print_mode)
|
|
637
|
+
for option in ['mode', 'pos', 'max_ram_terms', 'max_unram_terms', 'max_terse_terms', 'sep', 'alphabet']:
|
|
638
|
+
if option in print_mode:
|
|
639
|
+
print_mode["print_" + option] = print_mode[option]
|
|
640
|
+
del print_mode[option]
|
|
641
|
+
elif "print_" + option not in print_mode:
|
|
642
|
+
if "print_" + option in kwds:
|
|
643
|
+
print_mode["print_" + option] = kwds["print_" + option]
|
|
644
|
+
else:
|
|
645
|
+
print_mode["print_" + option] = self._printer.dict()[option]
|
|
646
|
+
for option in ['ram_name', 'unram_name', 'var_name']:
|
|
647
|
+
if option not in print_mode:
|
|
648
|
+
if option in kwds:
|
|
649
|
+
print_mode[option] = kwds[option]
|
|
650
|
+
else:
|
|
651
|
+
print_mode[option] = self._printer.dict()[option]
|
|
652
|
+
return ExtensionFactory(base=self, modulus=modulus, prec=prec, names=names, check=True, implementation=implementation, **print_mode)
|
|
653
|
+
|
|
654
|
+
def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None):
|
|
655
|
+
r"""
|
|
656
|
+
Check whether the given images and map on the base ring determine a
|
|
657
|
+
valid homomorphism to the codomain.
|
|
658
|
+
|
|
659
|
+
EXAMPLES::
|
|
660
|
+
|
|
661
|
+
sage: # needs sage.libs.ntl
|
|
662
|
+
sage: R.<x> = ZZ[]
|
|
663
|
+
sage: K.<a> = Qq(25, modulus=x^2-2)
|
|
664
|
+
sage: L.<b> = Qq(625, modulus=x^4-2)
|
|
665
|
+
sage: K._is_valid_homomorphism_(L, [b^2])
|
|
666
|
+
True
|
|
667
|
+
sage: L._is_valid_homomorphism_(L, [b^3])
|
|
668
|
+
False
|
|
669
|
+
sage: z = L(-1).sqrt()
|
|
670
|
+
sage: L._is_valid_homomorphism_(L, [z*b])
|
|
671
|
+
True
|
|
672
|
+
sage: L._is_valid_homomorphism_(L, [-b])
|
|
673
|
+
True
|
|
674
|
+
sage: W.<w> = K.extension(x^2 - 5)
|
|
675
|
+
sage: cc = K.hom([-a])
|
|
676
|
+
sage: W._is_valid_homomorphism_(W, [w], base_map=cc)
|
|
677
|
+
True
|
|
678
|
+
sage: W._is_valid_homomorphism_(W, [-w], base_map=cc)
|
|
679
|
+
True
|
|
680
|
+
sage: W._is_valid_homomorphism_(W, [w+1])
|
|
681
|
+
False
|
|
682
|
+
"""
|
|
683
|
+
K = self.base_ring()
|
|
684
|
+
if base_map is None and not codomain.has_coerce_map_from(K):
|
|
685
|
+
return False
|
|
686
|
+
if len(im_gens) != 1:
|
|
687
|
+
raise ValueError("Wrong number of generators")
|
|
688
|
+
if self is K:
|
|
689
|
+
# Qp or Zp, so either base_map is not None or there's a coercion to the codomain
|
|
690
|
+
# We check that the im_gens has the right length and value
|
|
691
|
+
return im_gens[0] == codomain(self.prime())
|
|
692
|
+
# Now we're an extension. We check that the defining polynomial maps to zero
|
|
693
|
+
f = self.modulus()
|
|
694
|
+
if base_map is not None:
|
|
695
|
+
f = f.change_ring(base_map)
|
|
696
|
+
return f(im_gens[0]) == 0
|
|
697
|
+
|
|
698
|
+
def _test_add(self, **options):
|
|
699
|
+
r"""
|
|
700
|
+
Test addition of elements of this ring.
|
|
701
|
+
|
|
702
|
+
INPUT:
|
|
703
|
+
|
|
704
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
705
|
+
|
|
706
|
+
EXAMPLES::
|
|
707
|
+
|
|
708
|
+
sage: Zp(3)._test_add()
|
|
709
|
+
|
|
710
|
+
.. SEEALSO::
|
|
711
|
+
|
|
712
|
+
:class:`TestSuite`
|
|
713
|
+
"""
|
|
714
|
+
from sage.misc.misc import some_tuples
|
|
715
|
+
|
|
716
|
+
tester = self._tester(**options)
|
|
717
|
+
elements = tester.some_elements()
|
|
718
|
+
|
|
719
|
+
for x in elements:
|
|
720
|
+
y = x + self.zero()
|
|
721
|
+
tester.assertEqual(y,x)
|
|
722
|
+
tester.assertEqual(y.precision_absolute(),x.precision_absolute())
|
|
723
|
+
tester.assertEqual(y.precision_relative(),x.precision_relative())
|
|
724
|
+
|
|
725
|
+
for x,y in some_tuples(elements, 2, tester._max_runs):
|
|
726
|
+
z = x + y
|
|
727
|
+
tester.assertIs(z.parent(), self)
|
|
728
|
+
zprec = min(x.precision_absolute(), y.precision_absolute())
|
|
729
|
+
if self.is_lattice_prec():
|
|
730
|
+
tester.assertGreaterEqual(z.precision_absolute(), zprec)
|
|
731
|
+
elif not self.is_floating_point():
|
|
732
|
+
tester.assertEqual(z.precision_absolute(), zprec)
|
|
733
|
+
tester.assertGreaterEqual(z.valuation(), min(x.valuation(),y.valuation()))
|
|
734
|
+
if x.valuation() != y.valuation():
|
|
735
|
+
tester.assertEqual(z.valuation(), min(x.valuation(),y.valuation()))
|
|
736
|
+
tester.assertTrue(y.is_equal_to(z-x,zprec))
|
|
737
|
+
tester.assertTrue(x.is_equal_to(z-y,zprec))
|
|
738
|
+
|
|
739
|
+
def _test_sub(self, **options):
|
|
740
|
+
r"""
|
|
741
|
+
Test subtraction on elements of this ring.
|
|
742
|
+
|
|
743
|
+
INPUT:
|
|
744
|
+
|
|
745
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
746
|
+
|
|
747
|
+
EXAMPLES::
|
|
748
|
+
|
|
749
|
+
sage: Zp(3)._test_sub()
|
|
750
|
+
|
|
751
|
+
.. SEEALSO::
|
|
752
|
+
|
|
753
|
+
:class:`TestSuite`
|
|
754
|
+
"""
|
|
755
|
+
from sage.misc.misc import some_tuples
|
|
756
|
+
|
|
757
|
+
tester = self._tester(**options)
|
|
758
|
+
|
|
759
|
+
elements = list(tester.some_elements())
|
|
760
|
+
for x in elements:
|
|
761
|
+
y = x - self.zero()
|
|
762
|
+
tester.assertEqual(y, x)
|
|
763
|
+
tester.assertEqual(y.precision_absolute(), x.precision_absolute())
|
|
764
|
+
tester.assertEqual(y.precision_relative(), x.precision_relative())
|
|
765
|
+
|
|
766
|
+
for x,y in some_tuples(elements, 2, tester._max_runs):
|
|
767
|
+
z = x - y
|
|
768
|
+
tester.assertIs(z.parent(), self)
|
|
769
|
+
zprec = min(x.precision_absolute(), y.precision_absolute())
|
|
770
|
+
if self.is_lattice_prec():
|
|
771
|
+
tester.assertGreaterEqual(z.precision_absolute(), zprec)
|
|
772
|
+
elif not self.is_floating_point():
|
|
773
|
+
tester.assertEqual(z.precision_absolute(), zprec)
|
|
774
|
+
tester.assertGreaterEqual(z.valuation(), min(x.valuation(),y.valuation()))
|
|
775
|
+
if x.valuation() != y.valuation():
|
|
776
|
+
tester.assertEqual(z.valuation(), min(x.valuation(),y.valuation()))
|
|
777
|
+
tester.assertTrue((-y).is_equal_to(z - x,zprec))
|
|
778
|
+
tester.assertTrue(x.is_equal_to(z + y,zprec))
|
|
779
|
+
|
|
780
|
+
def _test_invert(self, **options):
|
|
781
|
+
"""
|
|
782
|
+
Test multiplicative inversion of elements of this ring.
|
|
783
|
+
|
|
784
|
+
INPUT:
|
|
785
|
+
|
|
786
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
787
|
+
|
|
788
|
+
EXAMPLES::
|
|
789
|
+
|
|
790
|
+
sage: Zp(3)._test_invert()
|
|
791
|
+
|
|
792
|
+
.. SEEALSO::
|
|
793
|
+
|
|
794
|
+
:class:`TestSuite`
|
|
795
|
+
"""
|
|
796
|
+
tester = self._tester(**options)
|
|
797
|
+
|
|
798
|
+
elements = tester.some_elements()
|
|
799
|
+
for x in elements:
|
|
800
|
+
try:
|
|
801
|
+
y = ~x
|
|
802
|
+
except (ZeroDivisionError, PrecisionError, ValueError):
|
|
803
|
+
tester.assertFalse(x.is_unit())
|
|
804
|
+
if not self.is_fixed_mod():
|
|
805
|
+
tester.assertTrue(x.is_zero())
|
|
806
|
+
else:
|
|
807
|
+
try:
|
|
808
|
+
e = y * x
|
|
809
|
+
except ZeroDivisionError:
|
|
810
|
+
tester.assertTrue(self.is_floating_point() and (x.is_zero() or y.is_zero()))
|
|
811
|
+
else:
|
|
812
|
+
tester.assertFalse(x.is_zero())
|
|
813
|
+
tester.assertIs(y.parent(), self if self.is_fixed_mod() else self.fraction_field())
|
|
814
|
+
tester.assertTrue(e.is_one())
|
|
815
|
+
tester.assertEqual(e.precision_relative(), x.precision_relative())
|
|
816
|
+
tester.assertEqual(y.valuation(), -x.valuation())
|
|
817
|
+
|
|
818
|
+
def _test_mul(self, **options):
|
|
819
|
+
r"""
|
|
820
|
+
Test multiplication of elements of this ring.
|
|
821
|
+
|
|
822
|
+
INPUT:
|
|
823
|
+
|
|
824
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
825
|
+
|
|
826
|
+
EXAMPLES::
|
|
827
|
+
|
|
828
|
+
sage: Zp(3)._test_mul()
|
|
829
|
+
|
|
830
|
+
.. SEEALSO::
|
|
831
|
+
|
|
832
|
+
:class:`TestSuite`
|
|
833
|
+
"""
|
|
834
|
+
from sage.misc.misc import some_tuples
|
|
835
|
+
|
|
836
|
+
tester = self._tester(**options)
|
|
837
|
+
|
|
838
|
+
elements = list(tester.some_elements())
|
|
839
|
+
for x,y in some_tuples(elements, 2, tester._max_runs):
|
|
840
|
+
z = x * y
|
|
841
|
+
tester.assertIs(z.parent(), self)
|
|
842
|
+
if self.is_capped_relative() or self.is_floating_point():
|
|
843
|
+
tester.assertEqual(z.precision_relative(), min(x.precision_relative(), y.precision_relative()))
|
|
844
|
+
else:
|
|
845
|
+
tester.assertLessEqual(z.precision_relative(), min(x.precision_relative(), y.precision_relative()))
|
|
846
|
+
if not z.is_zero():
|
|
847
|
+
tester.assertEqual(z.valuation(), x.valuation() + y.valuation())
|
|
848
|
+
|
|
849
|
+
def _test_div(self, **options):
|
|
850
|
+
r"""
|
|
851
|
+
Test division of elements of this ring.
|
|
852
|
+
|
|
853
|
+
INPUT:
|
|
854
|
+
|
|
855
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
856
|
+
|
|
857
|
+
EXAMPLES::
|
|
858
|
+
|
|
859
|
+
sage: Zp(3)._test_div()
|
|
860
|
+
|
|
861
|
+
.. SEEALSO::
|
|
862
|
+
|
|
863
|
+
:class:`TestSuite`
|
|
864
|
+
"""
|
|
865
|
+
from sage.misc.misc import some_tuples
|
|
866
|
+
|
|
867
|
+
tester = self._tester(**options)
|
|
868
|
+
|
|
869
|
+
elements = list(tester.some_elements())
|
|
870
|
+
for x,y in some_tuples(elements, 2, tester._max_runs):
|
|
871
|
+
try:
|
|
872
|
+
z = x / y
|
|
873
|
+
except (ZeroDivisionError, PrecisionError, ValueError):
|
|
874
|
+
if self.is_fixed_mod():
|
|
875
|
+
tester.assertFalse(y.is_unit())
|
|
876
|
+
else:
|
|
877
|
+
tester.assertTrue(y.is_zero())
|
|
878
|
+
else:
|
|
879
|
+
try:
|
|
880
|
+
xx = z*y
|
|
881
|
+
except ZeroDivisionError:
|
|
882
|
+
tester.assertTrue(self.is_floating_point() and (z.is_zero() or y.is_zero()))
|
|
883
|
+
else:
|
|
884
|
+
tester.assertFalse(y.is_zero())
|
|
885
|
+
tester.assertIs(z.parent(), self if self.is_fixed_mod() else self.fraction_field())
|
|
886
|
+
# The following might be false if there is an absolute cap
|
|
887
|
+
# tester.assertEqual(z.precision_relative(), min(x.precision_relative(), y.precision_relative()))
|
|
888
|
+
if not x.is_zero():
|
|
889
|
+
tester.assertEqual(z.valuation(), x.valuation() - y.valuation())
|
|
890
|
+
tester.assertEqual(xx, x)
|
|
891
|
+
|
|
892
|
+
def _test_neg(self, **options):
|
|
893
|
+
r"""
|
|
894
|
+
Test the negation operator on elements of this ring.
|
|
895
|
+
|
|
896
|
+
INPUT:
|
|
897
|
+
|
|
898
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
899
|
+
|
|
900
|
+
EXAMPLES::
|
|
901
|
+
|
|
902
|
+
sage: Zp(3)._test_neg()
|
|
903
|
+
|
|
904
|
+
.. SEEALSO::
|
|
905
|
+
|
|
906
|
+
:class:`TestSuite`
|
|
907
|
+
"""
|
|
908
|
+
tester = self._tester(**options)
|
|
909
|
+
for x in tester.some_elements():
|
|
910
|
+
y = -x
|
|
911
|
+
tester.assertIs(y.parent(), self)
|
|
912
|
+
tester.assertTrue((x+y).is_zero())
|
|
913
|
+
tester.assertEqual(y.valuation(),x.valuation())
|
|
914
|
+
tester.assertEqual(x.precision_absolute(),y.precision_absolute())
|
|
915
|
+
tester.assertEqual(x.precision_relative(),y.precision_relative())
|
|
916
|
+
tester.assertEqual(x.is_zero(),y.is_zero())
|
|
917
|
+
tester.assertEqual(x.is_unit(),y.is_unit())
|
|
918
|
+
|
|
919
|
+
def _test_shift(self, **options):
|
|
920
|
+
"""
|
|
921
|
+
Test the shift operator on elements of this ring.
|
|
922
|
+
|
|
923
|
+
INPUT:
|
|
924
|
+
|
|
925
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
926
|
+
|
|
927
|
+
EXAMPLES::
|
|
928
|
+
|
|
929
|
+
sage: Zp(3)._test_shift()
|
|
930
|
+
|
|
931
|
+
.. SEEALSO::
|
|
932
|
+
|
|
933
|
+
:class:`TestSuite`
|
|
934
|
+
"""
|
|
935
|
+
tester = self._tester(**options)
|
|
936
|
+
if self.is_relaxed():
|
|
937
|
+
cap = self.default_prec()
|
|
938
|
+
else:
|
|
939
|
+
cap = self.precision_cap()
|
|
940
|
+
k = self.residue_field()
|
|
941
|
+
for v in range(min(cap,10)):
|
|
942
|
+
if self.is_capped_absolute() or self.is_fixed_mod():
|
|
943
|
+
prec = cap - v
|
|
944
|
+
else:
|
|
945
|
+
prec = cap
|
|
946
|
+
b = self.uniformizer_pow(v)
|
|
947
|
+
for x in tester.some_elements():
|
|
948
|
+
y = (x << v) >> v
|
|
949
|
+
if x._is_exact_zero() or self.is_field():
|
|
950
|
+
tester.assertEqual(x, y)
|
|
951
|
+
else:
|
|
952
|
+
tester.assertTrue(x.is_equal_to(y, prec))
|
|
953
|
+
y = (x >> v) << v
|
|
954
|
+
if x._is_exact_zero() or self.is_field():
|
|
955
|
+
tester.assertEqual(x, y)
|
|
956
|
+
else:
|
|
957
|
+
for i in range(min(v,prec)):
|
|
958
|
+
tester.assertEqual(k(y.expansion(i)), 0)
|
|
959
|
+
for i in range(v,prec):
|
|
960
|
+
tester.assertEqual(y.expansion(i), x.expansion(i))
|
|
961
|
+
xx = y + (x % b)
|
|
962
|
+
tester.assertTrue(xx.is_equal_to(x,prec))
|
|
963
|
+
|
|
964
|
+
def _test_log(self, **options):
|
|
965
|
+
r"""
|
|
966
|
+
Test the log operator on elements of this ring.
|
|
967
|
+
|
|
968
|
+
INPUT:
|
|
969
|
+
|
|
970
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
971
|
+
|
|
972
|
+
EXAMPLES::
|
|
973
|
+
|
|
974
|
+
sage: Zp(3)._test_log()
|
|
975
|
+
|
|
976
|
+
.. SEEALSO::
|
|
977
|
+
|
|
978
|
+
:class:`TestSuite`
|
|
979
|
+
"""
|
|
980
|
+
tester = self._tester(**options)
|
|
981
|
+
for x in tester.some_elements():
|
|
982
|
+
if x.is_zero():
|
|
983
|
+
continue
|
|
984
|
+
try:
|
|
985
|
+
l = x.log(p_branch=0)
|
|
986
|
+
tester.assertIs(l.parent(), self)
|
|
987
|
+
except ValueError:
|
|
988
|
+
l = x.log(p_branch=0, change_frac=True)
|
|
989
|
+
if self.is_capped_absolute() or self.is_capped_relative():
|
|
990
|
+
if self.absolute_e() == 1:
|
|
991
|
+
tester.assertEqual(l.precision_absolute(), x.precision_relative())
|
|
992
|
+
else:
|
|
993
|
+
tester.assertLessEqual(l.precision_absolute(), x.precision_relative())
|
|
994
|
+
|
|
995
|
+
if self.is_capped_absolute() or self.is_capped_relative():
|
|
996
|
+
# In the fixed modulus setting, rounding errors may occur
|
|
997
|
+
for x, y, b in tester.some_elements(repeat=3):
|
|
998
|
+
if (x*y).is_zero():
|
|
999
|
+
continue
|
|
1000
|
+
r1 = x.log(pi_branch=b) + y.log(pi_branch=b)
|
|
1001
|
+
r2 = (x*y).log(pi_branch=b)
|
|
1002
|
+
tester.assertEqual(r1, r2)
|
|
1003
|
+
|
|
1004
|
+
p = self.prime()
|
|
1005
|
+
for x in tester.some_elements():
|
|
1006
|
+
if x.is_zero():
|
|
1007
|
+
continue
|
|
1008
|
+
if p == 2:
|
|
1009
|
+
a = 4 * x.unit_part()
|
|
1010
|
+
else:
|
|
1011
|
+
a = p * x.unit_part()
|
|
1012
|
+
b = a.exp().log()
|
|
1013
|
+
c = (1+a).log().exp()
|
|
1014
|
+
tester.assertEqual(a, b)
|
|
1015
|
+
tester.assertEqual(1+a, c)
|
|
1016
|
+
|
|
1017
|
+
def _test_teichmuller(self, **options):
|
|
1018
|
+
r"""
|
|
1019
|
+
Test Teichmüller lifts.
|
|
1020
|
+
|
|
1021
|
+
INPUT:
|
|
1022
|
+
|
|
1023
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
1024
|
+
|
|
1025
|
+
EXAMPLES::
|
|
1026
|
+
|
|
1027
|
+
sage: Zp(3)._test_teichmuller()
|
|
1028
|
+
|
|
1029
|
+
.. SEEALSO::
|
|
1030
|
+
|
|
1031
|
+
:class:`TestSuite`
|
|
1032
|
+
"""
|
|
1033
|
+
tester = self._tester(**options)
|
|
1034
|
+
|
|
1035
|
+
for x in tester.some_elements():
|
|
1036
|
+
try:
|
|
1037
|
+
y = self.teichmuller(x)
|
|
1038
|
+
except ValueError:
|
|
1039
|
+
tester.assertTrue(x.valuation() < 0 or x.precision_absolute() == 0)
|
|
1040
|
+
else:
|
|
1041
|
+
try:
|
|
1042
|
+
tester.assertEqual(x.residue(), y.residue())
|
|
1043
|
+
except (NotImplementedError, AttributeError):
|
|
1044
|
+
pass
|
|
1045
|
+
if self.is_relaxed():
|
|
1046
|
+
tester.assertTrue(y.is_equal_at_precision(y**self.residue_field().order(), self.default_prec()))
|
|
1047
|
+
else:
|
|
1048
|
+
tester.assertEqual(y**self.residue_field().order(), y)
|
|
1049
|
+
|
|
1050
|
+
def _test_convert_residue_field(self, **options):
|
|
1051
|
+
r"""
|
|
1052
|
+
Test that conversion of residue field elements back to this ring works.
|
|
1053
|
+
|
|
1054
|
+
INPUT:
|
|
1055
|
+
|
|
1056
|
+
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
|
|
1057
|
+
|
|
1058
|
+
EXAMPLES::
|
|
1059
|
+
|
|
1060
|
+
sage: Zp(3)._test_convert_residue_field()
|
|
1061
|
+
|
|
1062
|
+
.. SEEALSO::
|
|
1063
|
+
|
|
1064
|
+
:class:`TestSuite`
|
|
1065
|
+
"""
|
|
1066
|
+
tester = self._tester(**options)
|
|
1067
|
+
|
|
1068
|
+
for x in tester.some_elements():
|
|
1069
|
+
if x.valuation() < 0:
|
|
1070
|
+
continue
|
|
1071
|
+
if x.precision_absolute() <= 0:
|
|
1072
|
+
continue
|
|
1073
|
+
y = x.residue()
|
|
1074
|
+
z = self(y)
|
|
1075
|
+
tester.assertEqual(z.residue(), y)
|
|
1076
|
+
|
|
1077
|
+
@cached_method
|
|
1078
|
+
def _log_unit_part_p(self):
|
|
1079
|
+
r"""
|
|
1080
|
+
Compute the logarithm of the unit-part of `p`.
|
|
1081
|
+
|
|
1082
|
+
If `\pi` is the uniformizer in this ring, then we can uniquely write
|
|
1083
|
+
`p=\pi^e u` where `u` is a `\pi`-adic unit. This method computes the
|
|
1084
|
+
logarithm of `u`.
|
|
1085
|
+
|
|
1086
|
+
This is a helper method for
|
|
1087
|
+
:meth:`sage.rings.padics.padic_generic_element.pAdicGenericElement.log`.
|
|
1088
|
+
|
|
1089
|
+
TESTS::
|
|
1090
|
+
|
|
1091
|
+
sage: R = Qp(3,5)
|
|
1092
|
+
sage: R._log_unit_part_p()
|
|
1093
|
+
O(3^5)
|
|
1094
|
+
|
|
1095
|
+
sage: S.<x> = ZZ[]
|
|
1096
|
+
sage: W.<pi> = R.extension(x^3-3) # needs sage.libs.ntl
|
|
1097
|
+
sage: W._log_unit_part_p() # needs sage.libs.ntl
|
|
1098
|
+
O(pi^15)
|
|
1099
|
+
|
|
1100
|
+
sage: W.<pi> = R.extension(x^3-3*x-3) # needs sage.libs.ntl
|
|
1101
|
+
sage: W._log_unit_part_p() # needs sage.libs.ntl
|
|
1102
|
+
2 + pi + 2*pi^2 + pi^4 + pi^5 + 2*pi^7 + 2*pi^8 + pi^9 + 2*pi^10 + pi^11 + pi^12 + 2*pi^14 + O(pi^15)
|
|
1103
|
+
"""
|
|
1104
|
+
return self(self.prime()).unit_part().log()
|
|
1105
|
+
|
|
1106
|
+
def frobenius_endomorphism(self, n=1):
|
|
1107
|
+
r"""
|
|
1108
|
+
Return the `n`-th power of the absolute arithmetic Frobeninus
|
|
1109
|
+
endomorphism on this field.
|
|
1110
|
+
|
|
1111
|
+
INPUT:
|
|
1112
|
+
|
|
1113
|
+
- ``n`` -- integer (default: 1)
|
|
1114
|
+
|
|
1115
|
+
EXAMPLES::
|
|
1116
|
+
|
|
1117
|
+
sage: K.<a> = Qq(3^5) # needs sage.libs.ntl
|
|
1118
|
+
sage: Frob = K.frobenius_endomorphism(); Frob # needs sage.libs.ntl
|
|
1119
|
+
Frobenius endomorphism on 3-adic Unramified Extension
|
|
1120
|
+
... lifting a |--> a^3 on the residue field
|
|
1121
|
+
sage: Frob(a) == a.frobenius() # needs sage.libs.ntl
|
|
1122
|
+
True
|
|
1123
|
+
|
|
1124
|
+
We can specify a power::
|
|
1125
|
+
|
|
1126
|
+
sage: K.frobenius_endomorphism(2) # needs sage.libs.ntl
|
|
1127
|
+
Frobenius endomorphism on 3-adic Unramified Extension
|
|
1128
|
+
... lifting a |--> a^(3^2) on the residue field
|
|
1129
|
+
|
|
1130
|
+
The result is simplified if possible::
|
|
1131
|
+
|
|
1132
|
+
sage: K.frobenius_endomorphism(6) # needs sage.libs.ntl
|
|
1133
|
+
Frobenius endomorphism on 3-adic Unramified Extension
|
|
1134
|
+
... lifting a |--> a^3 on the residue field
|
|
1135
|
+
sage: K.frobenius_endomorphism(5) # needs sage.libs.ntl
|
|
1136
|
+
Identity endomorphism of 3-adic Unramified Extension ...
|
|
1137
|
+
|
|
1138
|
+
Comparisons work::
|
|
1139
|
+
|
|
1140
|
+
sage: K.frobenius_endomorphism(6) == Frob # needs sage.libs.ntl
|
|
1141
|
+
True
|
|
1142
|
+
"""
|
|
1143
|
+
from .morphism import FrobeniusEndomorphism_padics
|
|
1144
|
+
return FrobeniusEndomorphism_padics(self, n)
|
|
1145
|
+
|
|
1146
|
+
def _test_elements_eq_transitive(self, **options):
|
|
1147
|
+
r"""
|
|
1148
|
+
The operator ``==`` is not transitive for `p`-adic numbers.
|
|
1149
|
+
|
|
1150
|
+
We disable the check of the category framework by overriding
|
|
1151
|
+
this method.
|
|
1152
|
+
|
|
1153
|
+
EXAMPLES::
|
|
1154
|
+
|
|
1155
|
+
sage: R = Zp(3)
|
|
1156
|
+
sage: R(3) == R(0,1)
|
|
1157
|
+
True
|
|
1158
|
+
sage: R(0,1) == R(6)
|
|
1159
|
+
True
|
|
1160
|
+
sage: R(3) == R(6)
|
|
1161
|
+
False
|
|
1162
|
+
sage: R._test_elements_eq_transitive()
|
|
1163
|
+
"""
|
|
1164
|
+
pass
|
|
1165
|
+
|
|
1166
|
+
def valuation(self):
|
|
1167
|
+
r"""
|
|
1168
|
+
Return the `p`-adic valuation on this ring.
|
|
1169
|
+
|
|
1170
|
+
OUTPUT:
|
|
1171
|
+
|
|
1172
|
+
A valuation that is normalized such that the rational prime `p` has
|
|
1173
|
+
valuation 1.
|
|
1174
|
+
|
|
1175
|
+
EXAMPLES::
|
|
1176
|
+
|
|
1177
|
+
sage: # needs sage.libs.ntl
|
|
1178
|
+
sage: K = Qp(3)
|
|
1179
|
+
sage: R.<a> = K[]
|
|
1180
|
+
sage: L.<a> = K.extension(a^3 - 3)
|
|
1181
|
+
sage: v = L.valuation(); v
|
|
1182
|
+
3-adic valuation
|
|
1183
|
+
sage: v(3)
|
|
1184
|
+
1
|
|
1185
|
+
sage: L(3).valuation()
|
|
1186
|
+
3
|
|
1187
|
+
|
|
1188
|
+
The normalization is chosen such that the valuation restricts to the
|
|
1189
|
+
valuation on the base ring::
|
|
1190
|
+
|
|
1191
|
+
sage: v(3) == K.valuation()(3) # needs sage.libs.ntl
|
|
1192
|
+
True
|
|
1193
|
+
sage: v.restriction(K) == K.valuation() # needs sage.libs.ntl
|
|
1194
|
+
True
|
|
1195
|
+
|
|
1196
|
+
.. SEEALSO::
|
|
1197
|
+
|
|
1198
|
+
:meth:`NumberField_generic.valuation() <sage.rings.number_field.number_field.NumberField_generic.valuation>`,
|
|
1199
|
+
:meth:`Order.valuation() <sage.rings.number_field.order.Order.valuation>`
|
|
1200
|
+
"""
|
|
1201
|
+
from sage.rings.padics.padic_valuation import pAdicValuation
|
|
1202
|
+
return pAdicValuation(self)
|
|
1203
|
+
|
|
1204
|
+
def _primitive_qth_root_of_unity(self, exponent):
|
|
1205
|
+
r"""
|
|
1206
|
+
Compute the ``p^exponent``-th roots of unity in this ring.
|
|
1207
|
+
|
|
1208
|
+
INPUT:
|
|
1209
|
+
|
|
1210
|
+
- ``exponent`` -- integer or ``Infinity``
|
|
1211
|
+
|
|
1212
|
+
OUTPUT:
|
|
1213
|
+
|
|
1214
|
+
A triple ``(zeta, n, nextzeta)`` where
|
|
1215
|
+
|
|
1216
|
+
- ``zeta`` is a generator of the group of ``p^exponent``-th
|
|
1217
|
+
roots of unity in this ring, and
|
|
1218
|
+
- ``p^n`` is the order of ``zeta``.
|
|
1219
|
+
- ``nextzeta`` is the result of ``zeta._inverse_pth_root()``
|
|
1220
|
+
if ``n`` is positive and ``None`` otherwise
|
|
1221
|
+
|
|
1222
|
+
TESTS::
|
|
1223
|
+
|
|
1224
|
+
sage: # needs sage.libs.ntl
|
|
1225
|
+
sage: K.<a> = Qq(2^3, 5)
|
|
1226
|
+
sage: S.<x> = K[]
|
|
1227
|
+
sage: L.<pi> = K.extension(x^2 + 2*x + 2)
|
|
1228
|
+
sage: zeta = L.primitive_root_of_unity(); zeta # indirect doctest
|
|
1229
|
+
a + a*pi + pi^2 + a*pi^4 + a*pi^5 + a^2*pi^8 + a^2*pi^9 + O(pi^10)
|
|
1230
|
+
sage: zeta.parent() is L
|
|
1231
|
+
True
|
|
1232
|
+
"""
|
|
1233
|
+
n = len(self._qth_roots_of_unity)
|
|
1234
|
+
|
|
1235
|
+
# We check if the result is cached
|
|
1236
|
+
if exponent < n-1:
|
|
1237
|
+
return self._qth_roots_of_unity[exponent][0], exponent, self._qth_roots_of_unity[exponent+1]
|
|
1238
|
+
zeta, accuracy = self._qth_roots_of_unity[-1]
|
|
1239
|
+
if accuracy is not Infinity:
|
|
1240
|
+
return self._qth_roots_of_unity[-2][0], n-2, (zeta, accuracy)
|
|
1241
|
+
|
|
1242
|
+
# It is not, so we compute it
|
|
1243
|
+
while accuracy is Infinity and n <= exponent + 1:
|
|
1244
|
+
self._qth_roots_of_unity[-1] = (self(zeta), Infinity) # to avoid multiple conversions
|
|
1245
|
+
if n == 1: # case of pth root of unity
|
|
1246
|
+
p = self.prime()
|
|
1247
|
+
e = self.absolute_e()
|
|
1248
|
+
k = self.residue_field()
|
|
1249
|
+
if e % (p-1) != 0:
|
|
1250
|
+
# No pth root of unity in this ring
|
|
1251
|
+
zeta = accuracy = None
|
|
1252
|
+
else:
|
|
1253
|
+
rho = -k(self(p).expansion(e))
|
|
1254
|
+
try:
|
|
1255
|
+
r = rho.nth_root(p-1)
|
|
1256
|
+
except ValueError:
|
|
1257
|
+
# No pth root of unity in this ring
|
|
1258
|
+
zeta = accuracy = None
|
|
1259
|
+
else:
|
|
1260
|
+
# We compute a primitive pth root of unity
|
|
1261
|
+
m = e // (p-1)
|
|
1262
|
+
prec = self.precision_cap() + e * (1 + m.valuation(p))
|
|
1263
|
+
ring = self.change(prec=prec)
|
|
1264
|
+
zeta = 1 + (ring(r).lift_to_precision() << m)
|
|
1265
|
+
curprec = m*p + 1
|
|
1266
|
+
while curprec < prec:
|
|
1267
|
+
curprec -= e
|
|
1268
|
+
curprec = min(2*curprec + e, p*curprec)
|
|
1269
|
+
zeta = zeta.lift_to_precision(min(prec,curprec))
|
|
1270
|
+
zeta += zeta * (1 - zeta**p) // p
|
|
1271
|
+
else:
|
|
1272
|
+
zeta, accuracy = zeta._inverse_pth_root()
|
|
1273
|
+
assert accuracy is not None
|
|
1274
|
+
self._qth_roots_of_unity.append((zeta, accuracy))
|
|
1275
|
+
n += 1
|
|
1276
|
+
return self._qth_roots_of_unity[-2][0], n-2, self._qth_roots_of_unity[-1]
|
|
1277
|
+
|
|
1278
|
+
def primitive_root_of_unity(self, n=None, order=False):
|
|
1279
|
+
r"""
|
|
1280
|
+
Return a generator of the group of ``n``-th roots of unity
|
|
1281
|
+
in this ring.
|
|
1282
|
+
|
|
1283
|
+
INPUT:
|
|
1284
|
+
|
|
1285
|
+
- ``n`` -- integer or ``None`` (default: ``None``)
|
|
1286
|
+
|
|
1287
|
+
- ``order`` -- boolean (default: ``False``)
|
|
1288
|
+
|
|
1289
|
+
OUTPUT:
|
|
1290
|
+
|
|
1291
|
+
A generator of the group of ``n``-th roots of unity.
|
|
1292
|
+
If ``n`` is ``None``, a generator of the full group of roots
|
|
1293
|
+
of unity is returned.
|
|
1294
|
+
|
|
1295
|
+
If ``order`` is ``True``, the order of the above group is
|
|
1296
|
+
returned as well.
|
|
1297
|
+
|
|
1298
|
+
EXAMPLES::
|
|
1299
|
+
|
|
1300
|
+
sage: R = Zp(5, 10)
|
|
1301
|
+
sage: zeta = R.primitive_root_of_unity(); zeta
|
|
1302
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
|
|
1303
|
+
sage: zeta == R.teichmuller(2)
|
|
1304
|
+
True
|
|
1305
|
+
|
|
1306
|
+
Now we consider an example with non trivial ``p``-th roots of unity::
|
|
1307
|
+
|
|
1308
|
+
sage: # needs sage.libs.ntl
|
|
1309
|
+
sage: W = Zp(3, 2)
|
|
1310
|
+
sage: S.<x> = W[]
|
|
1311
|
+
sage: R.<pi> = W.extension((x+1)^6 + (x+1)^3 + 1)
|
|
1312
|
+
sage: zeta, order = R.primitive_root_of_unity(order=True)
|
|
1313
|
+
sage: zeta
|
|
1314
|
+
2 + 2*pi + 2*pi^3 + 2*pi^7 + 2*pi^8 + 2*pi^9 + pi^11 + O(pi^12)
|
|
1315
|
+
sage: order
|
|
1316
|
+
18
|
|
1317
|
+
sage: zeta.multiplicative_order()
|
|
1318
|
+
18
|
|
1319
|
+
sage: zeta, order = R.primitive_root_of_unity(24, order=True)
|
|
1320
|
+
sage: zeta
|
|
1321
|
+
2 + pi^3 + 2*pi^7 + 2*pi^8 + 2*pi^10 + 2*pi^11 + O(pi^12)
|
|
1322
|
+
sage: order # equal to gcd(18,24)
|
|
1323
|
+
6
|
|
1324
|
+
sage: zeta.multiplicative_order()
|
|
1325
|
+
6
|
|
1326
|
+
"""
|
|
1327
|
+
p = self.prime()
|
|
1328
|
+
k = self.residue_field()
|
|
1329
|
+
prec = self.precision_cap()
|
|
1330
|
+
c = k.cardinality()
|
|
1331
|
+
|
|
1332
|
+
# We compute a primitive qth root of unity
|
|
1333
|
+
# where q is the highest power of p dividing exponent
|
|
1334
|
+
if n is None:
|
|
1335
|
+
qthzeta, s, _ = self._primitive_qth_root_of_unity(Infinity)
|
|
1336
|
+
m = c - 1
|
|
1337
|
+
else:
|
|
1338
|
+
qthzeta, s, _ = self._primitive_qth_root_of_unity(n.valuation(p))
|
|
1339
|
+
m = n.gcd(c - 1)
|
|
1340
|
+
qthzeta = self(qthzeta)
|
|
1341
|
+
|
|
1342
|
+
# We now compute a primitive mth root of qthzeta
|
|
1343
|
+
if m == 1:
|
|
1344
|
+
zeta = qthzeta
|
|
1345
|
+
else:
|
|
1346
|
+
zeta = self(k.multiplicative_generator() ** ((c-1) // m))
|
|
1347
|
+
invm = self(1/m)
|
|
1348
|
+
curprec = 1
|
|
1349
|
+
while curprec < prec:
|
|
1350
|
+
curprec *= 2
|
|
1351
|
+
zeta = zeta.lift_to_precision(min(prec,curprec))
|
|
1352
|
+
zeta += invm * zeta * (1 - qthzeta*zeta**m)
|
|
1353
|
+
|
|
1354
|
+
if order:
|
|
1355
|
+
return zeta, m * p**s
|
|
1356
|
+
else:
|
|
1357
|
+
return zeta
|
|
1358
|
+
|
|
1359
|
+
def roots_of_unity(self, n=None):
|
|
1360
|
+
r"""
|
|
1361
|
+
Return all the ``n``-th roots of unity in this ring.
|
|
1362
|
+
|
|
1363
|
+
INPUT:
|
|
1364
|
+
|
|
1365
|
+
- ``n`` -- integer or ``None`` (default: ``None``); if
|
|
1366
|
+
``None``, the full group of roots of unity is returned
|
|
1367
|
+
|
|
1368
|
+
EXAMPLES::
|
|
1369
|
+
|
|
1370
|
+
sage: R = Zp(5, 10)
|
|
1371
|
+
sage: roots = R.roots_of_unity(); roots
|
|
1372
|
+
[1 + O(5^10),
|
|
1373
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10),
|
|
1374
|
+
4 + 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),
|
|
1375
|
+
3 + 3*5 + 2*5^2 + 3*5^3 + 5^4 + 2*5^6 + 5^7 + 4*5^8 + 5^9 + O(5^10)]
|
|
1376
|
+
|
|
1377
|
+
sage: R.roots_of_unity(10)
|
|
1378
|
+
[1 + O(5^10),
|
|
1379
|
+
4 + 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)]
|
|
1380
|
+
|
|
1381
|
+
In this case, the roots of unity are the Teichmüller representatives::
|
|
1382
|
+
|
|
1383
|
+
sage: R.teichmuller_system()
|
|
1384
|
+
[1 + O(5^10),
|
|
1385
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10),
|
|
1386
|
+
3 + 3*5 + 2*5^2 + 3*5^3 + 5^4 + 2*5^6 + 5^7 + 4*5^8 + 5^9 + O(5^10),
|
|
1387
|
+
4 + 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)]
|
|
1388
|
+
|
|
1389
|
+
In general, there might be more roots of unity (it happens when the ring has non
|
|
1390
|
+
trivial ``p``-th roots of unity)::
|
|
1391
|
+
|
|
1392
|
+
sage: # needs sage.libs.ntl
|
|
1393
|
+
sage: W.<a> = Zq(3^2, 2)
|
|
1394
|
+
sage: S.<x> = W[]
|
|
1395
|
+
sage: R.<pi> = W.extension((x+1)^2 + (x+1) + 1)
|
|
1396
|
+
sage: roots = R.roots_of_unity(); roots
|
|
1397
|
+
[1 + O(pi^4),
|
|
1398
|
+
a + 2*a*pi + 2*a*pi^2 + a*pi^3 + O(pi^4),
|
|
1399
|
+
...
|
|
1400
|
+
1 + pi + O(pi^4),
|
|
1401
|
+
a + a*pi^2 + 2*a*pi^3 + O(pi^4),
|
|
1402
|
+
...
|
|
1403
|
+
1 + 2*pi + pi^2 + O(pi^4),
|
|
1404
|
+
a + a*pi + a*pi^2 + O(pi^4),
|
|
1405
|
+
...]
|
|
1406
|
+
sage: len(roots)
|
|
1407
|
+
24
|
|
1408
|
+
|
|
1409
|
+
We check that the logarithm of each root of unity vanishes::
|
|
1410
|
+
|
|
1411
|
+
sage: # needs sage.libs.ntl
|
|
1412
|
+
sage: for root in roots:
|
|
1413
|
+
....: if root.log() != 0:
|
|
1414
|
+
....: raise ValueError
|
|
1415
|
+
"""
|
|
1416
|
+
zeta, order = self.primitive_root_of_unity(n, order=True)
|
|
1417
|
+
return [ zeta**i for i in range(order) ]
|
|
1418
|
+
|
|
1419
|
+
def _roots_univariate_polynomial(self, P, ring, multiplicities, algorithm, secure=False):
|
|
1420
|
+
r"""
|
|
1421
|
+
Return the roots of ``P`` in the ring ``ring``.
|
|
1422
|
+
|
|
1423
|
+
INPUT:
|
|
1424
|
+
|
|
1425
|
+
- ``P`` -- a polynomial defined over this ring
|
|
1426
|
+
|
|
1427
|
+
- ``ring`` -- a ring into which this ring coerces
|
|
1428
|
+
|
|
1429
|
+
- ``multiplicities`` -- boolean (default: ``True``);
|
|
1430
|
+
whether we have to return the multiplicities of each
|
|
1431
|
+
root or not
|
|
1432
|
+
|
|
1433
|
+
- ``algorithm`` -- ``'pari'``, ``'sage'`` or ``None`` (default:
|
|
1434
|
+
``None``); Sage provides an implementation for any extension of
|
|
1435
|
+
`\QQ_p` whereas only roots of polynomials over `\QQ_p` is implemented
|
|
1436
|
+
in Pari; the default is ``'pari'`` if ``ring`` is `\ZZ_p` or `\QQ_p`,
|
|
1437
|
+
``'sage'`` otherwise.
|
|
1438
|
+
|
|
1439
|
+
- ``secure`` -- boolean (default: ``False``)
|
|
1440
|
+
|
|
1441
|
+
.. NOTE::
|
|
1442
|
+
|
|
1443
|
+
When ``secure`` is ``True``, this method raises an error when
|
|
1444
|
+
the precision on the input polynomial is not enough to determine
|
|
1445
|
+
the number of roots in the ground field. This happens when two
|
|
1446
|
+
roots cannot be separated.
|
|
1447
|
+
A typical example is the polynomial
|
|
1448
|
+
|
|
1449
|
+
.. MATH::
|
|
1450
|
+
|
|
1451
|
+
(1 + O(p^10))*X^2 + O(p^10)*X + O(p^10).
|
|
1452
|
+
|
|
1453
|
+
Indeed its discriminant might be any `p`-adic integer divisible
|
|
1454
|
+
by `p^{10}` (resp. `p^{11}` when `p=2`) and so can be as well
|
|
1455
|
+
zero, a square and a non-square.
|
|
1456
|
+
In the first case, the polynomial has one double root; in the
|
|
1457
|
+
second case, it has two roots; in the third case, it has no
|
|
1458
|
+
root in `\QQ_p`.
|
|
1459
|
+
|
|
1460
|
+
When ``secure`` is ``False``, this method assumes that two
|
|
1461
|
+
inseparable roots actually collapse. In the above example,
|
|
1462
|
+
it then answers that the given polynomial has a double root
|
|
1463
|
+
`O(p^5)`.
|
|
1464
|
+
|
|
1465
|
+
This keyword is ignored when using the ``pari`` algorithm.
|
|
1466
|
+
|
|
1467
|
+
EXAMPLES::
|
|
1468
|
+
|
|
1469
|
+
sage: # needs sage.libs.ntl
|
|
1470
|
+
sage: A = Zp(3, prec=10, print_mode='terse')
|
|
1471
|
+
sage: S.<x> = A[]
|
|
1472
|
+
sage: P = x^2 - 7
|
|
1473
|
+
sage: P.roots()
|
|
1474
|
+
[(30793 + O(3^10), 1), (28256 + O(3^10), 1)]
|
|
1475
|
+
sage: P.roots(multiplicities=False)
|
|
1476
|
+
[30793 + O(3^10), 28256 + O(3^10)]
|
|
1477
|
+
|
|
1478
|
+
We compare with the result given by the method
|
|
1479
|
+
:meth:`sage.rings.padics.padic_generic_element.square_root`::
|
|
1480
|
+
|
|
1481
|
+
sage: A(7).square_root(all=True) # needs sage.libs.ntl
|
|
1482
|
+
[30793 + O(3^10), 28256 + O(3^10)]
|
|
1483
|
+
|
|
1484
|
+
Here is another example::
|
|
1485
|
+
|
|
1486
|
+
sage: P = x * (x-1) * (x-2) * (x-3) * (x-4) # needs sage.libs.ntl
|
|
1487
|
+
sage: P.roots(multiplicities=False) # needs sage.libs.ntl
|
|
1488
|
+
[39370 + O(3^10),
|
|
1489
|
+
19684 + O(3^10),
|
|
1490
|
+
2 + O(3^10),
|
|
1491
|
+
3 + O(3^10),
|
|
1492
|
+
O(3^10)]
|
|
1493
|
+
|
|
1494
|
+
The result is not quite what we expected.
|
|
1495
|
+
In fact, the roots are correct but the precision is not::
|
|
1496
|
+
|
|
1497
|
+
sage: [ root.add_bigoh(9) for root in P.roots(multiplicities=False) ] # needs sage.libs.ntl
|
|
1498
|
+
[4 + O(3^9),
|
|
1499
|
+
1 + O(3^9),
|
|
1500
|
+
2 + O(3^9),
|
|
1501
|
+
3 + O(3^9),
|
|
1502
|
+
O(3^9)]
|
|
1503
|
+
|
|
1504
|
+
This is due to the fact that we are using ``'pari'`` which does not
|
|
1505
|
+
track precision (it can only compute `p`-adic roots of exact polynomials).
|
|
1506
|
+
If we are switching to ``'sage'`` then the precision on the result
|
|
1507
|
+
becomes correct (but the computation is much slower)::
|
|
1508
|
+
|
|
1509
|
+
sage: P.roots(multiplicities=False, algorithm='sage') # needs sage.geometry.polyhedron sage.libs.ntl
|
|
1510
|
+
[0,
|
|
1511
|
+
3 + O(3^11),
|
|
1512
|
+
1 + O(3^9),
|
|
1513
|
+
4 + O(3^9),
|
|
1514
|
+
2 + O(3^9)]
|
|
1515
|
+
|
|
1516
|
+
We check that the keyword ``secure`` works as explained above::
|
|
1517
|
+
|
|
1518
|
+
sage: P = x^2 + O(3^10)*x + O(3^10) # needs sage.libs.ntl
|
|
1519
|
+
sage: P.roots(algorithm='sage') # needs sage.geometry.polyhedron sage.libs.ntl
|
|
1520
|
+
[(O(3^5), 2)]
|
|
1521
|
+
sage: P.roots(algorithm='sage', secure=True) # needs sage.libs.ntl
|
|
1522
|
+
Traceback (most recent call last):
|
|
1523
|
+
...
|
|
1524
|
+
PrecisionError: not enough precision to determine the number of roots
|
|
1525
|
+
|
|
1526
|
+
An example over an extension::
|
|
1527
|
+
|
|
1528
|
+
sage: B.<b> = Zq(3^3, prec=10, print_mode='terse') # needs sage.libs.ntl
|
|
1529
|
+
sage: P = B.modulus() # needs sage.libs.ntl
|
|
1530
|
+
|
|
1531
|
+
We check that `P` has no root in `A`::
|
|
1532
|
+
|
|
1533
|
+
sage: P.roots() # needs sage.libs.ntl
|
|
1534
|
+
[]
|
|
1535
|
+
|
|
1536
|
+
but that it has roots in `B`::
|
|
1537
|
+
|
|
1538
|
+
sage: P.roots(B) # needs sage.geometry.polyhedron sage.libs.ntl sage.libs.singular
|
|
1539
|
+
[(35149 + 57730*b + 41124*b^2 + O(3^10), 1),
|
|
1540
|
+
(23900 + 1318*b + 17925*b^2 + O(3^10), 1),
|
|
1541
|
+
(b + O(3^10), 1)]
|
|
1542
|
+
|
|
1543
|
+
We check further that the other roots are the conjugates
|
|
1544
|
+
of ``b`` under Frobenius::
|
|
1545
|
+
|
|
1546
|
+
sage: b.frobenius() # needs sage.libs.ntl
|
|
1547
|
+
23900 + 1318*b + 17925*b^2 + O(3^10)
|
|
1548
|
+
sage: b.frobenius().frobenius() # needs sage.libs.ntl
|
|
1549
|
+
35149 + 57730*b + 41124*b^2 + O(3^10)
|
|
1550
|
+
|
|
1551
|
+
Root finding works over ramified extensions also::
|
|
1552
|
+
|
|
1553
|
+
sage: # needs sage.libs.ntl
|
|
1554
|
+
sage: E = x^3 - 3*x + 3*b
|
|
1555
|
+
sage: C.<pi> = B.extension(E)
|
|
1556
|
+
sage: E.roots(C) # needs sage.geometry.polyhedron sage.libs.singular
|
|
1557
|
+
[(pi + O(pi^30), 1)]
|
|
1558
|
+
sage: S.<x> = C[]
|
|
1559
|
+
sage: P = prod(x - (pi+i) for i in range(5))
|
|
1560
|
+
sage: P.roots() # needs sage.geometry.polyhedron sage.libs.singular
|
|
1561
|
+
[(pi + O(pi^29), 1),
|
|
1562
|
+
(3 + pi + O(pi^29), 1),
|
|
1563
|
+
(1 + pi + O(pi^27), 1),
|
|
1564
|
+
(4 + pi + O(pi^27), 1),
|
|
1565
|
+
(2 + pi + O(pi^30), 1)]
|
|
1566
|
+
|
|
1567
|
+
TESTS::
|
|
1568
|
+
|
|
1569
|
+
sage: S(0).roots() # needs sage.libs.ntl
|
|
1570
|
+
Traceback (most recent call last):
|
|
1571
|
+
...
|
|
1572
|
+
ArithmeticError: factorization of 0 is not defined
|
|
1573
|
+
"""
|
|
1574
|
+
if P.is_zero():
|
|
1575
|
+
raise ArithmeticError("factorization of 0 is not defined")
|
|
1576
|
+
if ring is None:
|
|
1577
|
+
ring = self
|
|
1578
|
+
if algorithm is None:
|
|
1579
|
+
try:
|
|
1580
|
+
return self._roots_univariate_polynomial(P, ring, multiplicities, "pari", secure)
|
|
1581
|
+
except (NotImplementedError, PrecisionError):
|
|
1582
|
+
return self._roots_univariate_polynomial(P, ring, multiplicities, "sage", secure)
|
|
1583
|
+
elif algorithm == "pari":
|
|
1584
|
+
P = P.change_ring(ring)
|
|
1585
|
+
try:
|
|
1586
|
+
# note that P.factor() calls pari
|
|
1587
|
+
return P._roots_from_factorization(P.factor(), multiplicities)
|
|
1588
|
+
except (AttributeError, TypeError):
|
|
1589
|
+
raise NotImplementedError("root finding for this polynomial is not implemented in pari")
|
|
1590
|
+
elif algorithm == "sage":
|
|
1591
|
+
if ring.is_field():
|
|
1592
|
+
roots = P.change_ring(ring)._roots(secure, -Infinity, None)
|
|
1593
|
+
else:
|
|
1594
|
+
K = ring.fraction_field()
|
|
1595
|
+
roots = P.change_ring(K)._roots(secure, 0, None)
|
|
1596
|
+
if multiplicities:
|
|
1597
|
+
return [ (ring(root), m) for (root, m) in roots ]
|
|
1598
|
+
else:
|
|
1599
|
+
return [ ring(root) for (root, m) in roots ]
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
class ResidueReductionMap(Morphism):
|
|
1603
|
+
r"""
|
|
1604
|
+
Reduction map from a `p`-adic ring or field to its residue field or ring.
|
|
1605
|
+
|
|
1606
|
+
These maps must be created using the :meth:`_create_` method in order
|
|
1607
|
+
to support categories correctly.
|
|
1608
|
+
|
|
1609
|
+
EXAMPLES::
|
|
1610
|
+
|
|
1611
|
+
sage: from sage.rings.padics.padic_generic import ResidueReductionMap
|
|
1612
|
+
sage: R.<a> = Zq(125); k = R.residue_field() # needs sage.libs.ntl
|
|
1613
|
+
sage: f = ResidueReductionMap._create_(R, k); f # needs sage.libs.ntl
|
|
1614
|
+
Reduction morphism:
|
|
1615
|
+
From: 5-adic Unramified Extension Ring in a defined by x^3 + 3*x + 3
|
|
1616
|
+
To: Finite Field in a0 of size 5^3
|
|
1617
|
+
"""
|
|
1618
|
+
@staticmethod
|
|
1619
|
+
def _create_(R, k):
|
|
1620
|
+
r"""
|
|
1621
|
+
Initialization. We have to implement this as a static method
|
|
1622
|
+
in order to call ``__make_element_class__``.
|
|
1623
|
+
|
|
1624
|
+
INPUT:
|
|
1625
|
+
|
|
1626
|
+
- ``R`` -- a `p`-adic ring or field
|
|
1627
|
+
- ``k`` -- the residue field of ``R``, or a residue ring of ``R``
|
|
1628
|
+
|
|
1629
|
+
EXAMPLES::
|
|
1630
|
+
|
|
1631
|
+
sage: f = Zmod(49).convert_map_from(Zp(7)) # needs sage.rings.finite_rings
|
|
1632
|
+
sage: TestSuite(f).run() # needs sage.rings.finite_rings
|
|
1633
|
+
sage: K.<a> = Qq(125); k = K.residue_field(); f = k.convert_map_from(K) # needs sage.libs.ntl
|
|
1634
|
+
sage: TestSuite(f).run() # needs sage.rings.finite_rings
|
|
1635
|
+
"""
|
|
1636
|
+
if R.is_field():
|
|
1637
|
+
from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
|
|
1638
|
+
cat = SetsWithPartialMaps()
|
|
1639
|
+
else:
|
|
1640
|
+
from sage.categories.rings import Rings
|
|
1641
|
+
cat = Rings()
|
|
1642
|
+
from sage.categories.homset import Hom
|
|
1643
|
+
kfield = R.residue_field()
|
|
1644
|
+
N = k.cardinality()
|
|
1645
|
+
q = kfield.cardinality()
|
|
1646
|
+
n = N.exact_log(q)
|
|
1647
|
+
if N != q**n:
|
|
1648
|
+
raise RuntimeError("N must be a power of q")
|
|
1649
|
+
H = Hom(R, k, cat)
|
|
1650
|
+
f = H.__make_element_class__(ResidueReductionMap)(H)
|
|
1651
|
+
f._n = n
|
|
1652
|
+
if kfield is k:
|
|
1653
|
+
f._field = True
|
|
1654
|
+
else:
|
|
1655
|
+
f._field = False
|
|
1656
|
+
return f
|
|
1657
|
+
|
|
1658
|
+
def is_surjective(self):
|
|
1659
|
+
r"""
|
|
1660
|
+
The reduction map is surjective.
|
|
1661
|
+
|
|
1662
|
+
EXAMPLES::
|
|
1663
|
+
|
|
1664
|
+
sage: GF(7).convert_map_from(Qp(7)).is_surjective() # needs sage.rings.finite_rings
|
|
1665
|
+
True
|
|
1666
|
+
"""
|
|
1667
|
+
return True
|
|
1668
|
+
|
|
1669
|
+
def is_injective(self):
|
|
1670
|
+
r"""
|
|
1671
|
+
The reduction map is far from injective.
|
|
1672
|
+
|
|
1673
|
+
EXAMPLES::
|
|
1674
|
+
|
|
1675
|
+
sage: GF(5).convert_map_from(ZpCA(5)).is_injective() # needs sage.rings.finite_rings
|
|
1676
|
+
False
|
|
1677
|
+
"""
|
|
1678
|
+
return False
|
|
1679
|
+
|
|
1680
|
+
def _call_(self, x):
|
|
1681
|
+
r"""
|
|
1682
|
+
Evaluate this morphism.
|
|
1683
|
+
|
|
1684
|
+
EXAMPLES::
|
|
1685
|
+
|
|
1686
|
+
sage: # needs sage.libs.ntl
|
|
1687
|
+
sage: R.<a> = Zq(125); k = R.residue_field()
|
|
1688
|
+
sage: f = k.convert_map_from(R)
|
|
1689
|
+
sage: f(15)
|
|
1690
|
+
0
|
|
1691
|
+
sage: f(1/(1+a))
|
|
1692
|
+
a0^2 + 4*a0 + 4
|
|
1693
|
+
|
|
1694
|
+
sage: Zmod(121).convert_map_from(Qp(11))(3/11) # needs sage.rings.finite_rings
|
|
1695
|
+
Traceback (most recent call last):
|
|
1696
|
+
...
|
|
1697
|
+
ValueError: element must have nonnegative valuation in order to compute residue
|
|
1698
|
+
"""
|
|
1699
|
+
return x.residue(self._n, field=self._field, check_prec=self._field)
|
|
1700
|
+
|
|
1701
|
+
def section(self):
|
|
1702
|
+
r"""
|
|
1703
|
+
Return the section from the residue ring or field
|
|
1704
|
+
back to the `p`-adic ring or field.
|
|
1705
|
+
|
|
1706
|
+
EXAMPLES::
|
|
1707
|
+
|
|
1708
|
+
sage: GF(3).convert_map_from(Zp(3)).section() # needs sage.rings.finite_rings
|
|
1709
|
+
Lifting morphism:
|
|
1710
|
+
From: Finite Field of size 3
|
|
1711
|
+
To: 3-adic Ring with capped relative precision 20
|
|
1712
|
+
"""
|
|
1713
|
+
return ResidueLiftingMap._create_(self.codomain(), self.domain())
|
|
1714
|
+
|
|
1715
|
+
def _repr_type(self):
|
|
1716
|
+
r"""
|
|
1717
|
+
Type of morphism, for printing.
|
|
1718
|
+
|
|
1719
|
+
EXAMPLES::
|
|
1720
|
+
|
|
1721
|
+
sage: GF(3).convert_map_from(Zp(3))._repr_type() # needs sage.rings.finite_rings
|
|
1722
|
+
'Reduction'
|
|
1723
|
+
"""
|
|
1724
|
+
return "Reduction"
|
|
1725
|
+
|
|
1726
|
+
def _richcmp_(self, other, op):
|
|
1727
|
+
r"""
|
|
1728
|
+
Compare this element to ``other`` with respect to ``op``.
|
|
1729
|
+
|
|
1730
|
+
EXAMPLES::
|
|
1731
|
+
|
|
1732
|
+
sage: from sage.rings.padics.padic_generic import ResidueReductionMap
|
|
1733
|
+
sage: f = ResidueReductionMap._create_(Zp(3), GF(3))
|
|
1734
|
+
sage: g = ResidueReductionMap._create_(Zp(3), GF(3))
|
|
1735
|
+
sage: f is g
|
|
1736
|
+
False
|
|
1737
|
+
sage: f == g
|
|
1738
|
+
True
|
|
1739
|
+
"""
|
|
1740
|
+
if type(self) is not type(other):
|
|
1741
|
+
return NotImplemented
|
|
1742
|
+
return richcmp((self.domain(), self.codomain()), (other.domain(), other.codomain()), op)
|
|
1743
|
+
|
|
1744
|
+
# A class for the Teichmüller lift would also be reasonable....
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
class ResidueLiftingMap(Morphism):
|
|
1748
|
+
r"""
|
|
1749
|
+
Lifting map to a `p`-adic ring or field from its residue field or ring.
|
|
1750
|
+
|
|
1751
|
+
These maps must be created using the :meth:`_create_` method in order
|
|
1752
|
+
to support categories correctly.
|
|
1753
|
+
|
|
1754
|
+
EXAMPLES::
|
|
1755
|
+
|
|
1756
|
+
sage: from sage.rings.padics.padic_generic import ResidueLiftingMap
|
|
1757
|
+
sage: R.<a> = Zq(125); k = R.residue_field() # needs sage.libs.ntl
|
|
1758
|
+
sage: f = ResidueLiftingMap._create_(k, R); f # needs sage.libs.ntl
|
|
1759
|
+
Lifting morphism:
|
|
1760
|
+
From: Finite Field in a0 of size 5^3
|
|
1761
|
+
To: 5-adic Unramified Extension Ring in a defined by x^3 + 3*x + 3
|
|
1762
|
+
"""
|
|
1763
|
+
@staticmethod
|
|
1764
|
+
def _create_(k, R):
|
|
1765
|
+
r"""
|
|
1766
|
+
Initialization. We have to implement this as a static method
|
|
1767
|
+
in order to call ``__make_element_class__``.
|
|
1768
|
+
|
|
1769
|
+
INPUT:
|
|
1770
|
+
|
|
1771
|
+
- ``k`` -- the residue field of ``R``, or a residue ring of ``R``
|
|
1772
|
+
- ``R`` -- a `p`-adic ring or field
|
|
1773
|
+
|
|
1774
|
+
EXAMPLES::
|
|
1775
|
+
|
|
1776
|
+
sage: f = Zp(3).convert_map_from(Zmod(81))
|
|
1777
|
+
sage: TestSuite(f).run()
|
|
1778
|
+
"""
|
|
1779
|
+
from sage.categories.sets_cat import Sets
|
|
1780
|
+
from sage.categories.homset import Hom
|
|
1781
|
+
kfield = R.residue_field()
|
|
1782
|
+
N = k.cardinality()
|
|
1783
|
+
q = kfield.cardinality()
|
|
1784
|
+
n = N.exact_log(q)
|
|
1785
|
+
if N != q**n:
|
|
1786
|
+
raise RuntimeError("N must be a power of q")
|
|
1787
|
+
H = Hom(k, R, Sets())
|
|
1788
|
+
f = H.__make_element_class__(ResidueLiftingMap)(H)
|
|
1789
|
+
f._n = n
|
|
1790
|
+
return f
|
|
1791
|
+
|
|
1792
|
+
def _call_(self, x):
|
|
1793
|
+
r"""
|
|
1794
|
+
Evaluate this morphism.
|
|
1795
|
+
|
|
1796
|
+
EXAMPLES::
|
|
1797
|
+
|
|
1798
|
+
sage: R.<a> = Zq(27); k = R.residue_field(); a0 = k.gen() # needs sage.libs.ntl
|
|
1799
|
+
sage: f = R.convert_map_from(k); f # needs sage.libs.ntl
|
|
1800
|
+
Lifting morphism:
|
|
1801
|
+
From: Finite Field in a0 of size 3^3
|
|
1802
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1803
|
+
sage: f(a0 + 1) # needs sage.libs.ntl
|
|
1804
|
+
(a + 1) + O(3)
|
|
1805
|
+
|
|
1806
|
+
sage: Zp(3)(Zmod(81)(0))
|
|
1807
|
+
O(3^4)
|
|
1808
|
+
"""
|
|
1809
|
+
R = self.codomain()
|
|
1810
|
+
K = R.maximal_unramified_subextension()
|
|
1811
|
+
if self._n == 1 or K is R:
|
|
1812
|
+
unram_n = self._n
|
|
1813
|
+
if K.absolute_degree() == 1:
|
|
1814
|
+
lift = K._element_constructor_(x, unram_n)
|
|
1815
|
+
else:
|
|
1816
|
+
lift = K(x.polynomial().list(), unram_n)
|
|
1817
|
+
return R(lift, self._n)
|
|
1818
|
+
else:
|
|
1819
|
+
#unram_n = (self._n - 1) // R.absolute_e() + 1
|
|
1820
|
+
raise NotImplementedError
|
|
1821
|
+
|
|
1822
|
+
def _call_with_args(self, x, args=(), kwds={}):
|
|
1823
|
+
r"""
|
|
1824
|
+
Evaluate this morphism with extra arguments.
|
|
1825
|
+
|
|
1826
|
+
EXAMPLES::
|
|
1827
|
+
|
|
1828
|
+
sage: f = Zp(2).convert_map_from(Zmod(128))
|
|
1829
|
+
sage: f(7, 5) # indirect doctest
|
|
1830
|
+
1 + 2 + 2^2 + O(2^5)
|
|
1831
|
+
"""
|
|
1832
|
+
R = self.codomain()
|
|
1833
|
+
kwds = dict(kwds) # we're changing it
|
|
1834
|
+
if args:
|
|
1835
|
+
args = (min(args[0], self._n),) + args[1:]
|
|
1836
|
+
absprec = args[0]
|
|
1837
|
+
else:
|
|
1838
|
+
absprec = kwds['absprec'] = min(kwds.get('absprec', self._n), self._n)
|
|
1839
|
+
K = R.maximal_unramified_subextension()
|
|
1840
|
+
if absprec == 1 or K is R:
|
|
1841
|
+
if K.absolute_degree() == 1:
|
|
1842
|
+
lift = K._element_constructor_(x, *args, **kwds)
|
|
1843
|
+
else:
|
|
1844
|
+
lift = K(x.polynomial().list(), *args, **kwds)
|
|
1845
|
+
return R(lift, *args, **kwds)
|
|
1846
|
+
else:
|
|
1847
|
+
raise NotImplementedError
|
|
1848
|
+
|
|
1849
|
+
def _repr_type(self):
|
|
1850
|
+
r"""
|
|
1851
|
+
Type of morphism, for printing.
|
|
1852
|
+
|
|
1853
|
+
EXAMPLES::
|
|
1854
|
+
|
|
1855
|
+
sage: Zp(3).convert_map_from(GF(3))._repr_type()
|
|
1856
|
+
'Lifting'
|
|
1857
|
+
"""
|
|
1858
|
+
return "Lifting"
|
|
1859
|
+
|
|
1860
|
+
def _richcmp_(self, other, op):
|
|
1861
|
+
r"""
|
|
1862
|
+
Compare this element to ``other`` with respect to ``op``.
|
|
1863
|
+
|
|
1864
|
+
EXAMPLES::
|
|
1865
|
+
|
|
1866
|
+
sage: # needs sage.rings.finite_rings
|
|
1867
|
+
sage: from sage.rings.padics.padic_generic import ResidueLiftingMap
|
|
1868
|
+
sage: f = ResidueLiftingMap._create_(GF(3), Zp(3))
|
|
1869
|
+
sage: g = ResidueLiftingMap._create_(GF(3), Zp(3))
|
|
1870
|
+
sage: f is g
|
|
1871
|
+
False
|
|
1872
|
+
sage: f == g
|
|
1873
|
+
True
|
|
1874
|
+
"""
|
|
1875
|
+
if type(self) is not type(other):
|
|
1876
|
+
return NotImplemented
|
|
1877
|
+
return richcmp((self.domain(), self.codomain()), (other.domain(), other.codomain()), op)
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
def local_print_mode(obj, print_options, pos=None, ram_name=None):
|
|
1881
|
+
r"""
|
|
1882
|
+
Context manager for safely temporarily changing the print_mode
|
|
1883
|
+
of a `p`-adic ring/field.
|
|
1884
|
+
|
|
1885
|
+
EXAMPLES::
|
|
1886
|
+
|
|
1887
|
+
sage: R = Zp(5)
|
|
1888
|
+
sage: R(45)
|
|
1889
|
+
4*5 + 5^2 + O(5^21)
|
|
1890
|
+
sage: with local_print_mode(R, 'val-unit'):
|
|
1891
|
+
....: print(R(45))
|
|
1892
|
+
5 * 9 + O(5^21)
|
|
1893
|
+
|
|
1894
|
+
.. NOTE::
|
|
1895
|
+
|
|
1896
|
+
For more documentation see :class:`sage.structure.parent_gens.localvars`.
|
|
1897
|
+
"""
|
|
1898
|
+
from sage.rings.padics.padic_printing import pAdicPrinter
|
|
1899
|
+
|
|
1900
|
+
if isinstance(print_options, str):
|
|
1901
|
+
print_options = {'mode': print_options}
|
|
1902
|
+
elif not isinstance(print_options, dict):
|
|
1903
|
+
raise TypeError("print_options must be a dictionary or a string")
|
|
1904
|
+
if pos is not None:
|
|
1905
|
+
print_options['pos'] = pos
|
|
1906
|
+
if ram_name is not None:
|
|
1907
|
+
print_options['ram_name'] = ram_name
|
|
1908
|
+
for option in ['mode', 'pos', 'ram_name', 'unram_name', 'var_name', 'max_ram_terms', 'max_unram_terms', 'max_terse_terms', 'sep', 'alphabet']:
|
|
1909
|
+
if option not in print_options:
|
|
1910
|
+
print_options[option] = obj._printer.dict()[option]
|
|
1911
|
+
return pAdicPrinter(obj, print_options)
|