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,1154 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
Algebraic closures of finite fields
|
|
5
|
+
|
|
6
|
+
Let `\Bold{F}` be a finite field, and let `\overline{\Bold{F}}` be an
|
|
7
|
+
algebraic closure of `\Bold{F}`; this is unique up to (non-canonical)
|
|
8
|
+
isomorphism. For every `n\ge 1`, there is a unique subfield
|
|
9
|
+
`\Bold{F}_n` of `\overline{\Bold{F}}` such that
|
|
10
|
+
`\Bold{F}\subset\Bold{F}_n` and `[\Bold{F}_n:\Bold{F}]=n`.
|
|
11
|
+
|
|
12
|
+
In Sage, algebraic closures of finite fields are implemented using
|
|
13
|
+
compatible systems of finite fields. The resulting Sage object keeps
|
|
14
|
+
track of a finite lattice of the subfields `\Bold{F}_n` and the
|
|
15
|
+
embeddings between them. This lattice is extended as necessary.
|
|
16
|
+
|
|
17
|
+
The Sage class corresponding to `\overline{\Bold{F}}` can be
|
|
18
|
+
constructed from the finite field `\Bold{F}` by using the
|
|
19
|
+
:meth:`~sage.rings.finite_rings.finite_field_base.FiniteField.algebraic_closure`
|
|
20
|
+
method.
|
|
21
|
+
|
|
22
|
+
The Sage class for elements of `\overline{\Bold{F}}` is
|
|
23
|
+
:class:`AlgebraicClosureFiniteFieldElement`. Such an element is
|
|
24
|
+
represented as an element of one of the `\Bold{F}_n`. This means that
|
|
25
|
+
each element `x\in\Bold{F}` has infinitely many different
|
|
26
|
+
representations, one for each `n` such that `x` is in `\Bold{F}_n`.
|
|
27
|
+
|
|
28
|
+
.. NOTE::
|
|
29
|
+
|
|
30
|
+
Only prime finite fields are currently accepted as base fields for
|
|
31
|
+
algebraic closures. To obtain an algebraic closure of a non-prime
|
|
32
|
+
finite field `\Bold{F}`, take an algebraic closure of the prime
|
|
33
|
+
field of `\Bold{F}` and embed `\Bold{F}` into this.
|
|
34
|
+
|
|
35
|
+
Algebraic closures of finite fields are currently implemented
|
|
36
|
+
using (pseudo-)Conway polynomials; see
|
|
37
|
+
:class:`AlgebraicClosureFiniteField_pseudo_conway` and the module
|
|
38
|
+
:mod:`~sage.rings.finite_rings.conway_polynomials`. Other
|
|
39
|
+
implementations may be added by creating appropriate subclasses of
|
|
40
|
+
:class:`AlgebraicClosureFiniteField_generic`.
|
|
41
|
+
|
|
42
|
+
In the current implementation, algebraic closures do not satisfy
|
|
43
|
+
the unique parent condition. Moreover, there is no coercion map
|
|
44
|
+
between different algebraic closures of the same finite field.
|
|
45
|
+
There is a conceptual reason for this, namely that the definition
|
|
46
|
+
of pseudo-Conway polynomials only determines an algebraic closure
|
|
47
|
+
up to *non-unique* isomorphism. This means in particular that
|
|
48
|
+
different algebraic closures, and their respective elements, never
|
|
49
|
+
compare equal.
|
|
50
|
+
|
|
51
|
+
AUTHORS:
|
|
52
|
+
|
|
53
|
+
- Peter Bruin (August 2013): initial version
|
|
54
|
+
|
|
55
|
+
- Vincent Delecroix (November 2013): additional methods
|
|
56
|
+
"""
|
|
57
|
+
from sage.misc.abstract_method import abstract_method
|
|
58
|
+
from sage.misc.fast_methods import WithEqualityById
|
|
59
|
+
from sage.rings.finite_rings.finite_field_base import FiniteField
|
|
60
|
+
from sage.rings.ring import Field
|
|
61
|
+
from sage.sets.family import AbstractFamily
|
|
62
|
+
from sage.structure.element import Element, FieldElement
|
|
63
|
+
from sage.structure.richcmp import richcmp
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class AlgebraicClosureFiniteFieldElement(FieldElement):
|
|
67
|
+
"""
|
|
68
|
+
Element of an algebraic closure of a finite field.
|
|
69
|
+
|
|
70
|
+
EXAMPLES::
|
|
71
|
+
|
|
72
|
+
sage: F = GF(3).algebraic_closure()
|
|
73
|
+
sage: F.gen(2)
|
|
74
|
+
z2
|
|
75
|
+
sage: type(F.gen(2))
|
|
76
|
+
<class 'sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField_pseudo_conway_with_category.element_class'>
|
|
77
|
+
"""
|
|
78
|
+
def __init__(self, parent, value):
|
|
79
|
+
"""
|
|
80
|
+
TESTS::
|
|
81
|
+
|
|
82
|
+
sage: F = GF(3).algebraic_closure()
|
|
83
|
+
sage: TestSuite(F.gen(2)).run(skip=['_test_pickling'])
|
|
84
|
+
|
|
85
|
+
.. NOTE::
|
|
86
|
+
|
|
87
|
+
The ``_test_pickling`` test has to be skipped because
|
|
88
|
+
there is no coercion map between the parents of ``x``
|
|
89
|
+
and ``loads(dumps(x))``.
|
|
90
|
+
"""
|
|
91
|
+
if isinstance(value, Element) and isinstance(value.parent(), FiniteField):
|
|
92
|
+
n = value.parent().degree()
|
|
93
|
+
else:
|
|
94
|
+
from sage.rings.integer import Integer
|
|
95
|
+
n = Integer(1)
|
|
96
|
+
self._value = parent._subfield(n).coerce(value)
|
|
97
|
+
self._level = n
|
|
98
|
+
FieldElement.__init__(self, parent)
|
|
99
|
+
|
|
100
|
+
def __hash__(self):
|
|
101
|
+
r"""
|
|
102
|
+
TESTS::
|
|
103
|
+
|
|
104
|
+
sage: F = GF(2).algebraic_closure()
|
|
105
|
+
sage: hash(F.zero())
|
|
106
|
+
0
|
|
107
|
+
sage: hash(F.one())
|
|
108
|
+
1
|
|
109
|
+
sage: z1 = F.gen(1)
|
|
110
|
+
sage: z2 = F.gen(2)
|
|
111
|
+
sage: z3 = F.gen(3)
|
|
112
|
+
sage: z4 = F.gen(4)
|
|
113
|
+
|
|
114
|
+
sage: hash(z2) == hash(z3+z2-z3)
|
|
115
|
+
True
|
|
116
|
+
sage: hash(F.zero()) == hash(z3+z2-z3-z2)
|
|
117
|
+
True
|
|
118
|
+
|
|
119
|
+
sage: X = [z4**i for i in range(2**4-1)]
|
|
120
|
+
sage: X.append(F.zero())
|
|
121
|
+
sage: X.extend([z3, z3**2, z3*z4])
|
|
122
|
+
sage: assert len(X) == len(set(hash(x) for x in X))
|
|
123
|
+
|
|
124
|
+
sage: F = GF(3).algebraic_closure()
|
|
125
|
+
sage: z1 = F.gen(1)
|
|
126
|
+
sage: z2 = F.gen(2)
|
|
127
|
+
sage: z3 = F.gen(3)
|
|
128
|
+
sage: z4 = F.gen(4)
|
|
129
|
+
|
|
130
|
+
sage: hash(z2) == hash(z3+z2-z3)
|
|
131
|
+
True
|
|
132
|
+
|
|
133
|
+
sage: X = [z4**i for i in range(3**4-1)]
|
|
134
|
+
sage: X.append(F.zero())
|
|
135
|
+
sage: X.extend([z3, z3**2, z3*z4])
|
|
136
|
+
sage: assert len(X) == len(set(hash(x) for x in X))
|
|
137
|
+
|
|
138
|
+
Check that :issue:`19956` is fixed::
|
|
139
|
+
|
|
140
|
+
sage: R.<x,y> = GF(2).algebraic_closure()[]
|
|
141
|
+
sage: x.resultant(y) # needs sage.modules
|
|
142
|
+
y
|
|
143
|
+
"""
|
|
144
|
+
# TODO: this is *very* slow
|
|
145
|
+
# NOTE: the hash of a generator (e.g. z2, z3, ...) is always the
|
|
146
|
+
# characteristic! In particular its hash value is not compatible with
|
|
147
|
+
# sections.
|
|
148
|
+
F, x, _ = self.as_finite_field_element(minimal=True)
|
|
149
|
+
if F.degree() == 1:
|
|
150
|
+
return hash(x)
|
|
151
|
+
else:
|
|
152
|
+
return hash((x, F.degree()))
|
|
153
|
+
|
|
154
|
+
def _repr_(self):
|
|
155
|
+
"""
|
|
156
|
+
Return a string representation of ``self``.
|
|
157
|
+
|
|
158
|
+
EXAMPLES::
|
|
159
|
+
|
|
160
|
+
sage: F = GF(3).algebraic_closure()
|
|
161
|
+
sage: F._repr_()
|
|
162
|
+
'Algebraic closure of Finite Field of size 3'
|
|
163
|
+
"""
|
|
164
|
+
return self._value._repr_()
|
|
165
|
+
|
|
166
|
+
def _richcmp_(self, right, op):
|
|
167
|
+
"""
|
|
168
|
+
Compare ``self`` with ``right``.
|
|
169
|
+
|
|
170
|
+
EXAMPLES::
|
|
171
|
+
|
|
172
|
+
sage: F = GF(3).algebraic_closure()
|
|
173
|
+
sage: F.gen(2) == F.gen(3)
|
|
174
|
+
False
|
|
175
|
+
"""
|
|
176
|
+
x, y = self.parent()._to_common_subfield(self, right)
|
|
177
|
+
return richcmp(x, y, op)
|
|
178
|
+
|
|
179
|
+
def __pow__(self, exp):
|
|
180
|
+
r"""
|
|
181
|
+
TESTS::
|
|
182
|
+
|
|
183
|
+
sage: F2 = GF(2).algebraic_closure()
|
|
184
|
+
sage: z12 = F2.gen(3*4)
|
|
185
|
+
sage: z12**3
|
|
186
|
+
z12^3
|
|
187
|
+
sage: z12**13
|
|
188
|
+
z12^8 + z12^7 + z12^6 + z12^4 + z12^2 + z12
|
|
189
|
+
"""
|
|
190
|
+
return self.__class__(self.parent(), self._value ** exp)
|
|
191
|
+
|
|
192
|
+
def _add_(self, right):
|
|
193
|
+
"""
|
|
194
|
+
Return ``self`` + ``right``.
|
|
195
|
+
|
|
196
|
+
EXAMPLES::
|
|
197
|
+
|
|
198
|
+
sage: F = GF(3).algebraic_closure()
|
|
199
|
+
sage: F.gen(2) + F.gen(3)
|
|
200
|
+
z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 1
|
|
201
|
+
"""
|
|
202
|
+
F = self.parent()
|
|
203
|
+
x, y = F._to_common_subfield(self, right)
|
|
204
|
+
return self.__class__(F, x + y)
|
|
205
|
+
|
|
206
|
+
def _sub_(self, right):
|
|
207
|
+
"""
|
|
208
|
+
Return ``self`` - ``right``.
|
|
209
|
+
|
|
210
|
+
EXAMPLES::
|
|
211
|
+
|
|
212
|
+
sage: F = GF(3).algebraic_closure()
|
|
213
|
+
sage: F.gen(2) - F.gen(3)
|
|
214
|
+
z6^4 + 2*z6^3 + z6^2 + 2*z6
|
|
215
|
+
"""
|
|
216
|
+
F = self.parent()
|
|
217
|
+
x, y = F._to_common_subfield(self, right)
|
|
218
|
+
return self.__class__(F, x - y)
|
|
219
|
+
|
|
220
|
+
def _mul_(self, right):
|
|
221
|
+
"""
|
|
222
|
+
Return ``self`` * ``right``.
|
|
223
|
+
|
|
224
|
+
EXAMPLES::
|
|
225
|
+
|
|
226
|
+
sage: F = GF(3).algebraic_closure()
|
|
227
|
+
sage: F.gen(2) * F.gen(3)
|
|
228
|
+
z6^5 + 2*z6^4 + z6^2 + 2
|
|
229
|
+
"""
|
|
230
|
+
F = self.parent()
|
|
231
|
+
x, y = F._to_common_subfield(self, right)
|
|
232
|
+
return self.__class__(F, x * y)
|
|
233
|
+
|
|
234
|
+
def _div_(self, right):
|
|
235
|
+
"""
|
|
236
|
+
Return ``self`` / ``right``.
|
|
237
|
+
|
|
238
|
+
EXAMPLES::
|
|
239
|
+
|
|
240
|
+
sage: F = GF(3).algebraic_closure()
|
|
241
|
+
sage: F.gen(2) / F.gen(3)
|
|
242
|
+
z6^5 + 2*z6^4 + z6^3 + 1
|
|
243
|
+
"""
|
|
244
|
+
F = self.parent()
|
|
245
|
+
x, y = F._to_common_subfield(self, right)
|
|
246
|
+
return self.__class__(F, x / y)
|
|
247
|
+
|
|
248
|
+
def change_level(self, n):
|
|
249
|
+
"""
|
|
250
|
+
Return a representation of ``self`` as an element of the
|
|
251
|
+
subfield of degree `n` of the parent, if possible.
|
|
252
|
+
|
|
253
|
+
EXAMPLES::
|
|
254
|
+
|
|
255
|
+
sage: F = GF(3).algebraic_closure()
|
|
256
|
+
sage: z = F.gen(4)
|
|
257
|
+
sage: (z^10).change_level(6)
|
|
258
|
+
2*z6^5 + 2*z6^3 + z6^2 + 2*z6 + 2
|
|
259
|
+
sage: z.change_level(6)
|
|
260
|
+
Traceback (most recent call last):
|
|
261
|
+
...
|
|
262
|
+
ValueError: z4 is not in the image of Ring morphism:
|
|
263
|
+
From: Finite Field in z2 of size 3^2
|
|
264
|
+
To: Finite Field in z4 of size 3^4
|
|
265
|
+
Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1
|
|
266
|
+
|
|
267
|
+
sage: a = F(1).change_level(3); a
|
|
268
|
+
1
|
|
269
|
+
sage: a.change_level(2)
|
|
270
|
+
1
|
|
271
|
+
sage: F.gen(3).change_level(1)
|
|
272
|
+
Traceback (most recent call last):
|
|
273
|
+
...
|
|
274
|
+
ValueError: z3 is not in the image of Ring morphism:
|
|
275
|
+
From: Finite Field of size 3
|
|
276
|
+
To: Finite Field in z3 of size 3^3
|
|
277
|
+
Defn: 1 |--> 1
|
|
278
|
+
"""
|
|
279
|
+
F = self.parent()
|
|
280
|
+
l = self._level
|
|
281
|
+
m = l.gcd(n)
|
|
282
|
+
xl = self._value
|
|
283
|
+
xm = F.inclusion(m, l).section()(xl)
|
|
284
|
+
xn = F.inclusion(m, n)(xm)
|
|
285
|
+
return self.__class__(F, xn)
|
|
286
|
+
|
|
287
|
+
def _latex_(self):
|
|
288
|
+
"""
|
|
289
|
+
Return a LaTeX representation of ``self``.
|
|
290
|
+
|
|
291
|
+
EXAMPLES::
|
|
292
|
+
|
|
293
|
+
sage: F = GF(3).algebraic_closure()
|
|
294
|
+
sage: s = F.gen(1) + F.gen(2) + F.gen(3)
|
|
295
|
+
sage: s
|
|
296
|
+
z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 2
|
|
297
|
+
sage: latex(s)
|
|
298
|
+
z_{6}^{5} + 2 z_{6}^{4} + 2 z_{6}^{3} + z_{6}^{2} + 2 z_{6} + 2
|
|
299
|
+
"""
|
|
300
|
+
return self._value._latex_()
|
|
301
|
+
|
|
302
|
+
def minpoly(self):
|
|
303
|
+
"""
|
|
304
|
+
Return the minimal polynomial of ``self`` over the prime
|
|
305
|
+
field.
|
|
306
|
+
|
|
307
|
+
EXAMPLES::
|
|
308
|
+
|
|
309
|
+
sage: F = GF(11).algebraic_closure()
|
|
310
|
+
sage: F.gen(3).minpoly()
|
|
311
|
+
x^3 + 2*x + 9
|
|
312
|
+
"""
|
|
313
|
+
return self._value.minpoly()
|
|
314
|
+
|
|
315
|
+
minimal_polynomial = minpoly
|
|
316
|
+
|
|
317
|
+
def is_square(self):
|
|
318
|
+
"""
|
|
319
|
+
Return ``True`` if ``self`` is a square.
|
|
320
|
+
|
|
321
|
+
This always returns ``True``.
|
|
322
|
+
|
|
323
|
+
EXAMPLES::
|
|
324
|
+
|
|
325
|
+
sage: F = GF(3).algebraic_closure()
|
|
326
|
+
sage: F.gen(2).is_square()
|
|
327
|
+
True
|
|
328
|
+
"""
|
|
329
|
+
return True
|
|
330
|
+
|
|
331
|
+
def sqrt(self, all=False):
|
|
332
|
+
"""
|
|
333
|
+
Return a square root of ``self``.
|
|
334
|
+
|
|
335
|
+
If the optional keyword argument ``all`` is set to ``True``,
|
|
336
|
+
return a list of all square roots of ``self`` instead.
|
|
337
|
+
|
|
338
|
+
EXAMPLES::
|
|
339
|
+
|
|
340
|
+
sage: F = GF(3).algebraic_closure()
|
|
341
|
+
sage: F.gen(2).sqrt()
|
|
342
|
+
z4^3 + z4 + 1
|
|
343
|
+
sage: F.gen(2).sqrt(all=True)
|
|
344
|
+
[z4^3 + z4 + 1, 2*z4^3 + 2*z4 + 2]
|
|
345
|
+
sage: (F.gen(2)^2).sqrt()
|
|
346
|
+
z2
|
|
347
|
+
sage: (F.gen(2)^2).sqrt(all=True)
|
|
348
|
+
[z2, 2*z2]
|
|
349
|
+
"""
|
|
350
|
+
F = self.parent()
|
|
351
|
+
x = self._value
|
|
352
|
+
if not x.is_square():
|
|
353
|
+
l = self._level
|
|
354
|
+
x = F.inclusion(l, 2*l)(x)
|
|
355
|
+
sqrt = x.sqrt(extend=False, all=all)
|
|
356
|
+
if all:
|
|
357
|
+
return [self.__class__(F, y) for y in sqrt]
|
|
358
|
+
return self.__class__(F, sqrt)
|
|
359
|
+
|
|
360
|
+
def nth_root(self, n):
|
|
361
|
+
"""
|
|
362
|
+
Return an `n`-th root of ``self``.
|
|
363
|
+
|
|
364
|
+
EXAMPLES::
|
|
365
|
+
|
|
366
|
+
sage: F = GF(5).algebraic_closure()
|
|
367
|
+
sage: t = F.gen(2) + 1
|
|
368
|
+
sage: s = t.nth_root(15); s
|
|
369
|
+
4*z6^5 + 3*z6^4 + 2*z6^3 + 2*z6^2 + 4
|
|
370
|
+
sage: s**15 == t
|
|
371
|
+
True
|
|
372
|
+
|
|
373
|
+
.. TODO::
|
|
374
|
+
|
|
375
|
+
This function could probably be made faster.
|
|
376
|
+
"""
|
|
377
|
+
from sage.rings.integer import Integer
|
|
378
|
+
F = self.parent()
|
|
379
|
+
x = self._value
|
|
380
|
+
n = Integer(n)
|
|
381
|
+
l = self._level
|
|
382
|
+
# In order to be smart we look for the smallest subfield that
|
|
383
|
+
# actually contains the root.
|
|
384
|
+
for d in n.divisors():
|
|
385
|
+
xx = F.inclusion(l, d*l)(x)
|
|
386
|
+
try:
|
|
387
|
+
y = xx.nth_root(n, extend=False)
|
|
388
|
+
except ValueError:
|
|
389
|
+
continue
|
|
390
|
+
return self.__class__(F, y)
|
|
391
|
+
|
|
392
|
+
raise AssertionError('cannot find n-th root in algebraic closure of finite field')
|
|
393
|
+
|
|
394
|
+
def multiplicative_order(self):
|
|
395
|
+
"""
|
|
396
|
+
Return the multiplicative order of ``self``.
|
|
397
|
+
|
|
398
|
+
EXAMPLES::
|
|
399
|
+
|
|
400
|
+
sage: K = GF(7).algebraic_closure()
|
|
401
|
+
sage: K.gen(5).multiplicative_order()
|
|
402
|
+
16806
|
|
403
|
+
sage: (K.gen(1) + K.gen(2) + K.gen(3)).multiplicative_order()
|
|
404
|
+
7353
|
|
405
|
+
"""
|
|
406
|
+
return self._value.multiplicative_order()
|
|
407
|
+
|
|
408
|
+
def pth_power(self, k=1):
|
|
409
|
+
"""
|
|
410
|
+
Return the `p^k`-th power of ``self``, where `p` is the
|
|
411
|
+
characteristic of ``self.parent()``.
|
|
412
|
+
|
|
413
|
+
EXAMPLES::
|
|
414
|
+
|
|
415
|
+
sage: K = GF(13).algebraic_closure('t')
|
|
416
|
+
sage: t3 = K.gen(3)
|
|
417
|
+
sage: s = 1 + t3 + t3**2
|
|
418
|
+
sage: s.pth_power()
|
|
419
|
+
10*t3^2 + 6*t3
|
|
420
|
+
sage: s.pth_power(2)
|
|
421
|
+
2*t3^2 + 6*t3 + 11
|
|
422
|
+
sage: s.pth_power(3)
|
|
423
|
+
t3^2 + t3 + 1
|
|
424
|
+
sage: s.pth_power(3).parent() is K
|
|
425
|
+
True
|
|
426
|
+
"""
|
|
427
|
+
return self.__class__(self.parent(), self._value.pth_power(k))
|
|
428
|
+
|
|
429
|
+
def pth_root(self, k=1):
|
|
430
|
+
"""
|
|
431
|
+
Return the unique `p^k`-th root of ``self``, where `p` is the
|
|
432
|
+
characteristic of ``self.parent()``.
|
|
433
|
+
|
|
434
|
+
EXAMPLES::
|
|
435
|
+
|
|
436
|
+
sage: K = GF(13).algebraic_closure('t')
|
|
437
|
+
sage: t3 = K.gen(3)
|
|
438
|
+
sage: s = 1 + t3 + t3**2
|
|
439
|
+
sage: s.pth_root()
|
|
440
|
+
2*t3^2 + 6*t3 + 11
|
|
441
|
+
sage: s.pth_root(2)
|
|
442
|
+
10*t3^2 + 6*t3
|
|
443
|
+
sage: s.pth_root(3)
|
|
444
|
+
t3^2 + t3 + 1
|
|
445
|
+
sage: s.pth_root(2).parent() is K
|
|
446
|
+
True
|
|
447
|
+
"""
|
|
448
|
+
return self.__class__(self.parent(), self._value.pth_root(k))
|
|
449
|
+
|
|
450
|
+
def as_finite_field_element(self, minimal=False):
|
|
451
|
+
"""
|
|
452
|
+
Return ``self`` as a finite field element.
|
|
453
|
+
|
|
454
|
+
INPUT:
|
|
455
|
+
|
|
456
|
+
- ``minimal`` -- boolean (default: ``False``); if ``True``,
|
|
457
|
+
always return the smallest subfield containing ``self``
|
|
458
|
+
|
|
459
|
+
OUTPUT:
|
|
460
|
+
|
|
461
|
+
- a triple (``field``, ``element``, ``morphism``) where
|
|
462
|
+
``field`` is a finite field, ``element`` an element of
|
|
463
|
+
``field`` and ``morphism`` a morphism from ``field`` to
|
|
464
|
+
``self.parent()``.
|
|
465
|
+
|
|
466
|
+
EXAMPLES::
|
|
467
|
+
|
|
468
|
+
sage: F = GF(3).algebraic_closure('t')
|
|
469
|
+
sage: t = F.gen(5)
|
|
470
|
+
sage: t.as_finite_field_element()
|
|
471
|
+
(Finite Field in t5 of size 3^5,
|
|
472
|
+
t5,
|
|
473
|
+
Ring morphism:
|
|
474
|
+
From: Finite Field in t5 of size 3^5
|
|
475
|
+
To: Algebraic closure of Finite Field of size 3
|
|
476
|
+
Defn: t5 |--> t5)
|
|
477
|
+
|
|
478
|
+
By default, ``field`` is not necessarily minimal. We can
|
|
479
|
+
force it to be minimal using the ``minimal`` option::
|
|
480
|
+
|
|
481
|
+
sage: s = t + 1 - t
|
|
482
|
+
sage: s.as_finite_field_element()[0]
|
|
483
|
+
Finite Field in t5 of size 3^5
|
|
484
|
+
sage: s.as_finite_field_element(minimal=True)[0]
|
|
485
|
+
Finite Field of size 3
|
|
486
|
+
|
|
487
|
+
This also works when the element has to be converted between
|
|
488
|
+
two non-trivial finite subfields (see :issue:`16509`)::
|
|
489
|
+
|
|
490
|
+
sage: K = GF(5).algebraic_closure()
|
|
491
|
+
sage: z = K.gen(5) - K.gen(5) + K.gen(2)
|
|
492
|
+
sage: z.as_finite_field_element(minimal=True)
|
|
493
|
+
(Finite Field in z2 of size 5^2, z2, Ring morphism:
|
|
494
|
+
From: Finite Field in z2 of size 5^2
|
|
495
|
+
To: Algebraic closure of Finite Field of size 5
|
|
496
|
+
Defn: z2 |--> z2)
|
|
497
|
+
|
|
498
|
+
There are automatic coercions between the various
|
|
499
|
+
subfields::
|
|
500
|
+
|
|
501
|
+
sage: a = K.gen(2) + 1
|
|
502
|
+
sage: _,b,_ = a.as_finite_field_element()
|
|
503
|
+
sage: K4 = K.subfield(4)[0]
|
|
504
|
+
sage: K4(b)
|
|
505
|
+
z4^3 + z4^2 + z4 + 4
|
|
506
|
+
sage: b.minimal_polynomial() == K4(b).minimal_polynomial()
|
|
507
|
+
True
|
|
508
|
+
sage: K(K4(b)) == K(b)
|
|
509
|
+
True
|
|
510
|
+
|
|
511
|
+
You can also use the inclusions that are implemented at
|
|
512
|
+
the level of the algebraic closure::
|
|
513
|
+
|
|
514
|
+
sage: f = K.inclusion(2,4); f
|
|
515
|
+
Ring morphism:
|
|
516
|
+
From: Finite Field in z2 of size 5^2
|
|
517
|
+
To: Finite Field in z4 of size 5^4
|
|
518
|
+
Defn: z2 |--> z4^3 + z4^2 + z4 + 3
|
|
519
|
+
sage: f(b)
|
|
520
|
+
z4^3 + z4^2 + z4 + 4
|
|
521
|
+
"""
|
|
522
|
+
Fbar = self.parent()
|
|
523
|
+
x = self._value
|
|
524
|
+
l = self._level
|
|
525
|
+
|
|
526
|
+
if minimal:
|
|
527
|
+
m = x.minpoly().degree()
|
|
528
|
+
if m == 1:
|
|
529
|
+
x = Fbar.base_ring()(x)
|
|
530
|
+
else:
|
|
531
|
+
x = Fbar.inclusion(m, l).section()(x)
|
|
532
|
+
l = m
|
|
533
|
+
|
|
534
|
+
F, phi = Fbar.subfield(l)
|
|
535
|
+
return (F, x, phi)
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
class AlgebraicClosureFiniteField_generic(Field):
|
|
539
|
+
"""
|
|
540
|
+
Algebraic closure of a finite field.
|
|
541
|
+
|
|
542
|
+
TESTS::
|
|
543
|
+
|
|
544
|
+
sage: GF(3).algebraic_closure().cardinality()
|
|
545
|
+
+Infinity
|
|
546
|
+
|
|
547
|
+
sage: GF(3).algebraic_closure().is_finite()
|
|
548
|
+
False
|
|
549
|
+
"""
|
|
550
|
+
def __init__(self, base_ring, name, category=None):
|
|
551
|
+
"""
|
|
552
|
+
TESTS::
|
|
553
|
+
|
|
554
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic
|
|
555
|
+
sage: F = AlgebraicClosureFiniteField_generic(GF(5), 'z')
|
|
556
|
+
sage: F
|
|
557
|
+
Algebraic closure of Finite Field of size 5
|
|
558
|
+
"""
|
|
559
|
+
Field.__init__(self, base_ring=base_ring, names=name,
|
|
560
|
+
normalize=False, category=category)
|
|
561
|
+
|
|
562
|
+
def __eq__(self, other):
|
|
563
|
+
"""
|
|
564
|
+
Compare ``self`` with ``other``.
|
|
565
|
+
|
|
566
|
+
TESTS::
|
|
567
|
+
|
|
568
|
+
sage: F3 = GF(3).algebraic_closure()
|
|
569
|
+
sage: F3 == F3
|
|
570
|
+
True
|
|
571
|
+
sage: F5 = GF(5).algebraic_closure()
|
|
572
|
+
sage: F3 == F5
|
|
573
|
+
False
|
|
574
|
+
"""
|
|
575
|
+
if self is other:
|
|
576
|
+
return True
|
|
577
|
+
if type(self) is not type(other):
|
|
578
|
+
return False
|
|
579
|
+
return ((self.base_ring(), self.variable_name(), self.category()) ==
|
|
580
|
+
(other.base_ring(), other.variable_name(), other.category()))
|
|
581
|
+
|
|
582
|
+
def __ne__(self, other):
|
|
583
|
+
"""
|
|
584
|
+
Check whether ``self`` and ``other`` are not equal.
|
|
585
|
+
|
|
586
|
+
TESTS::
|
|
587
|
+
|
|
588
|
+
sage: F3 = GF(3).algebraic_closure()
|
|
589
|
+
sage: F3 != F3
|
|
590
|
+
False
|
|
591
|
+
sage: F5 = GF(5).algebraic_closure()
|
|
592
|
+
sage: F3 != F5
|
|
593
|
+
True
|
|
594
|
+
"""
|
|
595
|
+
return not (self == other)
|
|
596
|
+
|
|
597
|
+
def characteristic(self):
|
|
598
|
+
"""
|
|
599
|
+
Return the characteristic of ``self``.
|
|
600
|
+
|
|
601
|
+
EXAMPLES::
|
|
602
|
+
|
|
603
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
604
|
+
sage: p = next_prime(1000)
|
|
605
|
+
sage: F = AlgebraicClosureFiniteField(GF(p), 'z')
|
|
606
|
+
sage: F.characteristic() == p
|
|
607
|
+
True
|
|
608
|
+
"""
|
|
609
|
+
return self.base_ring().characteristic()
|
|
610
|
+
|
|
611
|
+
Element = AlgebraicClosureFiniteFieldElement
|
|
612
|
+
|
|
613
|
+
def _element_constructor_(self, x):
|
|
614
|
+
"""
|
|
615
|
+
Construct an element of ``self``.
|
|
616
|
+
|
|
617
|
+
TESTS::
|
|
618
|
+
|
|
619
|
+
sage: F = GF(5).algebraic_closure()
|
|
620
|
+
sage: type(F(3))
|
|
621
|
+
<class 'sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField_pseudo_conway_with_category.element_class'>
|
|
622
|
+
|
|
623
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
624
|
+
sage: F1 = AlgebraicClosureFiniteField(GF(3), 'z')
|
|
625
|
+
sage: F2 = AlgebraicClosureFiniteField(GF(3), 'z')
|
|
626
|
+
sage: F1(F2.gen(1))
|
|
627
|
+
Traceback (most recent call last):
|
|
628
|
+
...
|
|
629
|
+
ValueError: no conversion defined between different algebraic closures
|
|
630
|
+
"""
|
|
631
|
+
if isinstance(x, self.element_class):
|
|
632
|
+
if x.parent() is not self:
|
|
633
|
+
raise ValueError('no conversion defined between different algebraic closures')
|
|
634
|
+
return x
|
|
635
|
+
else:
|
|
636
|
+
return self.element_class(self, x)
|
|
637
|
+
|
|
638
|
+
def _coerce_map_from_(self, other):
|
|
639
|
+
"""
|
|
640
|
+
Return ``True`` if elements of ``other`` can be coerced into
|
|
641
|
+
``self``.
|
|
642
|
+
|
|
643
|
+
EXAMPLES::
|
|
644
|
+
|
|
645
|
+
sage: F = GF(7).algebraic_closure()
|
|
646
|
+
sage: F.has_coerce_map_from(Integers())
|
|
647
|
+
True
|
|
648
|
+
"""
|
|
649
|
+
if other is self:
|
|
650
|
+
return True
|
|
651
|
+
elif isinstance(other, FiniteField) and self._subfield(other.degree()) is other:
|
|
652
|
+
return True
|
|
653
|
+
elif self._subfield(1).has_coerce_map_from(other):
|
|
654
|
+
return True
|
|
655
|
+
|
|
656
|
+
def _repr_(self):
|
|
657
|
+
"""
|
|
658
|
+
Return a string representation of ``self``.
|
|
659
|
+
|
|
660
|
+
EXAMPLES::
|
|
661
|
+
|
|
662
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
663
|
+
sage: F = AlgebraicClosureFiniteField(GF(5), 'z')
|
|
664
|
+
sage: F._repr_()
|
|
665
|
+
'Algebraic closure of Finite Field of size 5'
|
|
666
|
+
"""
|
|
667
|
+
return 'Algebraic closure of %s' % self.base_ring()
|
|
668
|
+
|
|
669
|
+
def _latex_(self):
|
|
670
|
+
r"""
|
|
671
|
+
Return a LaTeX representation of ``self``.
|
|
672
|
+
|
|
673
|
+
EXAMPLES::
|
|
674
|
+
|
|
675
|
+
sage: F = GF(3).algebraic_closure()
|
|
676
|
+
sage: latex(F)
|
|
677
|
+
\overline{\Bold{F}_{3}}
|
|
678
|
+
"""
|
|
679
|
+
return "\\overline{{{}}}".format(self.base_ring()._latex_())
|
|
680
|
+
|
|
681
|
+
def _to_common_subfield(self, x, y):
|
|
682
|
+
"""
|
|
683
|
+
Coerce `x` and `y` to a common subfield of ``self``.
|
|
684
|
+
|
|
685
|
+
TESTS::
|
|
686
|
+
|
|
687
|
+
sage: F = GF(3).algebraic_closure()
|
|
688
|
+
sage: x, y = F._to_common_subfield(F.gen(2), F.gen(3))
|
|
689
|
+
sage: x.parent()
|
|
690
|
+
Finite Field in z6 of size 3^6
|
|
691
|
+
sage: y.parent()
|
|
692
|
+
Finite Field in z6 of size 3^6
|
|
693
|
+
"""
|
|
694
|
+
if x._level == y._level:
|
|
695
|
+
return x._value, y._value
|
|
696
|
+
n = x._level.lcm(y._level)
|
|
697
|
+
mx = self.inclusion(x._level, n)
|
|
698
|
+
my = self.inclusion(y._level, n)
|
|
699
|
+
return mx(x._value), my(y._value)
|
|
700
|
+
|
|
701
|
+
@abstract_method
|
|
702
|
+
def _get_polynomial(self, n):
|
|
703
|
+
"""
|
|
704
|
+
Return the polynomial defining the unique subfield of degree
|
|
705
|
+
`n` of ``self``.
|
|
706
|
+
|
|
707
|
+
This must be implemented by subclasses.
|
|
708
|
+
|
|
709
|
+
EXAMPLES::
|
|
710
|
+
|
|
711
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic
|
|
712
|
+
sage: F = AlgebraicClosureFiniteField_generic(GF(5), 'z')
|
|
713
|
+
sage: F._get_polynomial(1)
|
|
714
|
+
Traceback (most recent call last):
|
|
715
|
+
...
|
|
716
|
+
NotImplementedError: <abstract method _get_polynomial at ...>
|
|
717
|
+
"""
|
|
718
|
+
|
|
719
|
+
@abstract_method
|
|
720
|
+
def _get_im_gen(self, m, n):
|
|
721
|
+
"""
|
|
722
|
+
Return the image of ``self.gen(m)`` under the canonical
|
|
723
|
+
inclusion into ``self.subfield(n)``.
|
|
724
|
+
|
|
725
|
+
This must be implemented by subclasses.
|
|
726
|
+
|
|
727
|
+
EXAMPLES::
|
|
728
|
+
|
|
729
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic
|
|
730
|
+
sage: F = AlgebraicClosureFiniteField_generic(GF(5), 'z')
|
|
731
|
+
sage: F._get_im_gen(2, 4)
|
|
732
|
+
Traceback (most recent call last):
|
|
733
|
+
...
|
|
734
|
+
NotImplementedError: <abstract method _get_im_gen at ...>
|
|
735
|
+
"""
|
|
736
|
+
|
|
737
|
+
def _subfield(self, n):
|
|
738
|
+
"""
|
|
739
|
+
Return the unique subfield of degree `n` of ``self``.
|
|
740
|
+
|
|
741
|
+
EXAMPLES::
|
|
742
|
+
|
|
743
|
+
sage: F = GF(3).algebraic_closure()
|
|
744
|
+
sage: F._subfield(4)
|
|
745
|
+
Finite Field in z4 of size 3^4
|
|
746
|
+
"""
|
|
747
|
+
if n == 1:
|
|
748
|
+
return self.base_ring()
|
|
749
|
+
else:
|
|
750
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField
|
|
751
|
+
return FiniteField(self.base_ring().cardinality() ** n,
|
|
752
|
+
name=self.variable_name() + str(n),
|
|
753
|
+
prefix=self.variable_name(),
|
|
754
|
+
modulus=self._get_polynomial(n),
|
|
755
|
+
check_irreducible=False)
|
|
756
|
+
|
|
757
|
+
def subfield(self, n):
|
|
758
|
+
"""
|
|
759
|
+
Return the unique subfield of degree `n` of ``self``
|
|
760
|
+
together with its canonical embedding into ``self``.
|
|
761
|
+
|
|
762
|
+
EXAMPLES::
|
|
763
|
+
|
|
764
|
+
sage: F = GF(3).algebraic_closure()
|
|
765
|
+
sage: F.subfield(1)
|
|
766
|
+
(Finite Field of size 3,
|
|
767
|
+
Ring morphism:
|
|
768
|
+
From: Finite Field of size 3
|
|
769
|
+
To: Algebraic closure of Finite Field of size 3
|
|
770
|
+
Defn: 1 |--> 1)
|
|
771
|
+
sage: F.subfield(4)
|
|
772
|
+
(Finite Field in z4 of size 3^4,
|
|
773
|
+
Ring morphism:
|
|
774
|
+
From: Finite Field in z4 of size 3^4
|
|
775
|
+
To: Algebraic closure of Finite Field of size 3
|
|
776
|
+
Defn: z4 |--> z4)
|
|
777
|
+
"""
|
|
778
|
+
Fn = self._subfield(n)
|
|
779
|
+
return Fn, Fn.hom( (self.gen(n),), check=False)
|
|
780
|
+
|
|
781
|
+
def inclusion(self, m, n):
|
|
782
|
+
"""
|
|
783
|
+
Return the canonical inclusion map from the subfield
|
|
784
|
+
of degree `m` to the subfield of degree `n`.
|
|
785
|
+
|
|
786
|
+
EXAMPLES::
|
|
787
|
+
|
|
788
|
+
sage: F = GF(3).algebraic_closure()
|
|
789
|
+
sage: F.inclusion(1, 2)
|
|
790
|
+
Ring morphism:
|
|
791
|
+
From: Finite Field of size 3
|
|
792
|
+
To: Finite Field in z2 of size 3^2
|
|
793
|
+
Defn: 1 |--> 1
|
|
794
|
+
sage: F.inclusion(2, 4)
|
|
795
|
+
Ring morphism:
|
|
796
|
+
From: Finite Field in z2 of size 3^2
|
|
797
|
+
To: Finite Field in z4 of size 3^4
|
|
798
|
+
Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1
|
|
799
|
+
"""
|
|
800
|
+
if m.divides(n):
|
|
801
|
+
# check=False is required to avoid "coercion hell": an
|
|
802
|
+
# infinite loop in checking the morphism involving
|
|
803
|
+
# polynomial_compiled.pyx on the modulus().
|
|
804
|
+
return self._subfield(m).hom( (self._get_im_gen(m, n),), check=False)
|
|
805
|
+
else:
|
|
806
|
+
raise ValueError("subfield of degree %s not contained in subfield of degree %s" % (m, n))
|
|
807
|
+
|
|
808
|
+
def ngens(self):
|
|
809
|
+
"""
|
|
810
|
+
Return the number of generators of ``self``, which is
|
|
811
|
+
infinity.
|
|
812
|
+
|
|
813
|
+
EXAMPLES::
|
|
814
|
+
|
|
815
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
816
|
+
sage: AlgebraicClosureFiniteField(GF(5), 'z').ngens()
|
|
817
|
+
+Infinity
|
|
818
|
+
"""
|
|
819
|
+
from sage.rings.infinity import Infinity
|
|
820
|
+
return Infinity
|
|
821
|
+
|
|
822
|
+
def gen(self, n):
|
|
823
|
+
"""
|
|
824
|
+
Return the `n`-th generator of ``self``.
|
|
825
|
+
|
|
826
|
+
EXAMPLES::
|
|
827
|
+
|
|
828
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
829
|
+
sage: F = AlgebraicClosureFiniteField(GF(5), 'z')
|
|
830
|
+
sage: F.gen(2)
|
|
831
|
+
z2
|
|
832
|
+
"""
|
|
833
|
+
F = self._subfield(n)
|
|
834
|
+
return self(F.gen())
|
|
835
|
+
|
|
836
|
+
def gens(self) -> AbstractFamily:
|
|
837
|
+
"""
|
|
838
|
+
Return a family of generators of ``self``.
|
|
839
|
+
|
|
840
|
+
OUTPUT:
|
|
841
|
+
|
|
842
|
+
- a :class:`~sage.sets.family.Family`, indexed by the positive
|
|
843
|
+
integers, whose `n`-th element is ``self.gen(n)``.
|
|
844
|
+
|
|
845
|
+
EXAMPLES::
|
|
846
|
+
|
|
847
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
848
|
+
sage: F = AlgebraicClosureFiniteField(GF(5), 'z')
|
|
849
|
+
sage: g = F.gens(); g
|
|
850
|
+
Lazy family (...(i))_{i in Positive integers}
|
|
851
|
+
sage: g[3]
|
|
852
|
+
z3
|
|
853
|
+
"""
|
|
854
|
+
from sage.sets.family import Family
|
|
855
|
+
from sage.sets.positive_integers import PositiveIntegers
|
|
856
|
+
return Family(PositiveIntegers(), self.gen)
|
|
857
|
+
|
|
858
|
+
def _first_ngens(self, n):
|
|
859
|
+
"""
|
|
860
|
+
Return the first `n` generators of ``self``.
|
|
861
|
+
|
|
862
|
+
EXAMPLES::
|
|
863
|
+
|
|
864
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
865
|
+
sage: F = AlgebraicClosureFiniteField(GF(5), 'z')
|
|
866
|
+
sage: F._first_ngens(3)
|
|
867
|
+
(1, z2, z3)
|
|
868
|
+
"""
|
|
869
|
+
return tuple(self.gen(i + 1) for i in range(n))
|
|
870
|
+
|
|
871
|
+
def algebraic_closure(self):
|
|
872
|
+
"""
|
|
873
|
+
Return an algebraic closure of ``self``.
|
|
874
|
+
|
|
875
|
+
This always returns ``self``.
|
|
876
|
+
|
|
877
|
+
EXAMPLES::
|
|
878
|
+
|
|
879
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
880
|
+
sage: F = AlgebraicClosureFiniteField(GF(5), 'z')
|
|
881
|
+
sage: F.algebraic_closure() is F
|
|
882
|
+
True
|
|
883
|
+
"""
|
|
884
|
+
return self
|
|
885
|
+
|
|
886
|
+
def _an_element_(self):
|
|
887
|
+
"""
|
|
888
|
+
TESTS::
|
|
889
|
+
|
|
890
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
891
|
+
sage: F = AlgebraicClosureFiniteField(GF(5), 'w')
|
|
892
|
+
sage: F.an_element() # indirect doctest
|
|
893
|
+
w2
|
|
894
|
+
"""
|
|
895
|
+
return self.gen(2)
|
|
896
|
+
|
|
897
|
+
def some_elements(self):
|
|
898
|
+
r"""
|
|
899
|
+
Return some elements of this field.
|
|
900
|
+
|
|
901
|
+
EXAMPLES::
|
|
902
|
+
|
|
903
|
+
sage: F = GF(7).algebraic_closure()
|
|
904
|
+
sage: F.some_elements()
|
|
905
|
+
(1, z2, z3 + 1)
|
|
906
|
+
"""
|
|
907
|
+
return (self(1), self.gen(2), 1+self.gen(3))
|
|
908
|
+
|
|
909
|
+
def _roots_univariate_polynomial(self, p, ring=None, multiplicities=None, algorithm=None):
|
|
910
|
+
r"""
|
|
911
|
+
Return a list of pairs ``(root,multiplicity)`` of roots of the polynomial ``p``.
|
|
912
|
+
|
|
913
|
+
If the argument ``multiplicities`` is set to ``False`` then return the
|
|
914
|
+
list of roots.
|
|
915
|
+
|
|
916
|
+
.. SEEALSO::
|
|
917
|
+
|
|
918
|
+
:meth:`_factor_univariate_polynomial`
|
|
919
|
+
|
|
920
|
+
EXAMPLES::
|
|
921
|
+
|
|
922
|
+
sage: R.<x> = PolynomialRing(GF(5),'x')
|
|
923
|
+
sage: K = GF(5).algebraic_closure('t')
|
|
924
|
+
|
|
925
|
+
sage: sorted((x^6 - 1).roots(K,multiplicities=False))
|
|
926
|
+
[1, 4, 2*t2 + 1, 2*t2 + 2, 3*t2 + 3, 3*t2 + 4]
|
|
927
|
+
sage: ((K.gen(2)*x - K.gen(3))**2).roots(K)
|
|
928
|
+
[(3*t6^5 + 2*t6^4 + 2*t6^2 + 3, 2)]
|
|
929
|
+
|
|
930
|
+
sage: for _ in range(10):
|
|
931
|
+
....: p = R.random_element(degree=randint(2,8))
|
|
932
|
+
....: for r in p.roots(K, multiplicities=False):
|
|
933
|
+
....: assert p(r).is_zero(), "r={} is not a root of p={}".format(r,p)
|
|
934
|
+
"""
|
|
935
|
+
from sage.arith.functions import lcm
|
|
936
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
937
|
+
|
|
938
|
+
# first build a polynomial over some finite field
|
|
939
|
+
coeffs = [v.as_finite_field_element(minimal=True) for v in p.list()]
|
|
940
|
+
l = lcm([c[0].degree() for c in coeffs])
|
|
941
|
+
F, phi = self.subfield(l)
|
|
942
|
+
P = p.parent().change_ring(F)
|
|
943
|
+
|
|
944
|
+
new_coeffs = [self.inclusion(c[0].degree(), l)(c[1]) for c in coeffs]
|
|
945
|
+
|
|
946
|
+
polys = [(g, m, l, phi) for g, m in P(new_coeffs).factor()]
|
|
947
|
+
roots = [] # a list of pair (root,multiplicity)
|
|
948
|
+
while polys:
|
|
949
|
+
g, m, l, phi = polys.pop()
|
|
950
|
+
|
|
951
|
+
if g.degree() == 1: # found a root
|
|
952
|
+
r = phi(-g.constant_coefficient())
|
|
953
|
+
roots.append((r, m))
|
|
954
|
+
else:
|
|
955
|
+
# look at the extension of degree g.degree() which
|
|
956
|
+
# contains at least one root of g
|
|
957
|
+
ll = l * g.degree()
|
|
958
|
+
psi = self.inclusion(l, ll)
|
|
959
|
+
FF, pphi = self.subfield(ll)
|
|
960
|
+
# note: there is no coercion from the l-th subfield to
|
|
961
|
+
# the ll-th subfield. The line below does the
|
|
962
|
+
# conversion manually.
|
|
963
|
+
g = PolynomialRing(FF, 'x')([psi(_) for _ in g])
|
|
964
|
+
polys.extend((gg, m, ll, pphi) for gg, _ in g.factor())
|
|
965
|
+
|
|
966
|
+
return roots if multiplicities else [r[0] for r in roots]
|
|
967
|
+
|
|
968
|
+
def _factor_univariate_polynomial(self, p, **kwds):
|
|
969
|
+
r"""
|
|
970
|
+
Factorization of univariate polynomials.
|
|
971
|
+
|
|
972
|
+
EXAMPLES::
|
|
973
|
+
|
|
974
|
+
sage: K = GF(3).algebraic_closure()
|
|
975
|
+
sage: R = PolynomialRing(K, 'T')
|
|
976
|
+
sage: T = R.gen()
|
|
977
|
+
sage: (K.gen(2) * T^2 - 1).factor()
|
|
978
|
+
(z2) * (T + z4^3 + z4^2 + z4) * (T + 2*z4^3 + 2*z4^2 + 2*z4)
|
|
979
|
+
|
|
980
|
+
sage: for d in range(10):
|
|
981
|
+
....: p = R.random_element(degree=randint(2,8))
|
|
982
|
+
....: assert p.factor().prod() == p, "error in the factorization of p={}".format(p)
|
|
983
|
+
"""
|
|
984
|
+
from sage.structure.factorization import Factorization
|
|
985
|
+
R = p.parent()
|
|
986
|
+
return Factorization([(R([-root, self.one()]), m) for root, m in p.roots()], unit=p[p.degree()])
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
class AlgebraicClosureFiniteField_pseudo_conway(WithEqualityById, AlgebraicClosureFiniteField_generic):
|
|
990
|
+
"""
|
|
991
|
+
Algebraic closure of a finite field, constructed using
|
|
992
|
+
pseudo-Conway polynomials.
|
|
993
|
+
|
|
994
|
+
EXAMPLES::
|
|
995
|
+
|
|
996
|
+
sage: F = GF(5).algebraic_closure(implementation='pseudo_conway')
|
|
997
|
+
sage: F.cardinality()
|
|
998
|
+
+Infinity
|
|
999
|
+
sage: F.algebraic_closure() is F
|
|
1000
|
+
True
|
|
1001
|
+
sage: x = F(3).nth_root(12); x
|
|
1002
|
+
z4^3 + z4^2 + 4*z4
|
|
1003
|
+
sage: x**12
|
|
1004
|
+
3
|
|
1005
|
+
|
|
1006
|
+
TESTS::
|
|
1007
|
+
|
|
1008
|
+
sage: F3 = GF(3).algebraic_closure()
|
|
1009
|
+
sage: F3 == F3
|
|
1010
|
+
True
|
|
1011
|
+
sage: F5 = GF(5).algebraic_closure()
|
|
1012
|
+
sage: F3 == F5
|
|
1013
|
+
False
|
|
1014
|
+
"""
|
|
1015
|
+
def __init__(self, base_ring, name, category=None, lattice=None, use_database=True):
|
|
1016
|
+
"""
|
|
1017
|
+
INPUT:
|
|
1018
|
+
|
|
1019
|
+
- ``base_ring`` -- the finite field of which to construct an
|
|
1020
|
+
algebraic closure. Currently only prime fields are
|
|
1021
|
+
accepted.
|
|
1022
|
+
|
|
1023
|
+
- ``name`` -- prefix to use for generators of the finite
|
|
1024
|
+
subfields
|
|
1025
|
+
|
|
1026
|
+
- ``category`` -- if provided, specifies the category in which
|
|
1027
|
+
this algebraic closure will be placed
|
|
1028
|
+
|
|
1029
|
+
- ``lattice`` -- :class:`~sage.rings.finite_rings.conway_polynomials.PseudoConwayPolynomialLattice`
|
|
1030
|
+
(default: ``None``); if provided, use this pseudo-Conway
|
|
1031
|
+
polynomial lattice to construct an algebraic closure.
|
|
1032
|
+
|
|
1033
|
+
- ``use_database`` -- boolean. If ``True`` (default), use actual
|
|
1034
|
+
Conway polynomials whenever they are available in the
|
|
1035
|
+
database. If ``False``, always compute pseudo-Conway
|
|
1036
|
+
polynomials from scratch.
|
|
1037
|
+
|
|
1038
|
+
TESTS::
|
|
1039
|
+
|
|
1040
|
+
sage: F = GF(5).algebraic_closure(implementation='pseudo_conway')
|
|
1041
|
+
sage: print(F.__class__.__name__)
|
|
1042
|
+
AlgebraicClosureFiniteField_pseudo_conway_with_category
|
|
1043
|
+
sage: TestSuite(F).run(skip=['_test_elements', '_test_pickling'])
|
|
1044
|
+
|
|
1045
|
+
sage: from sage.rings.finite_rings.conway_polynomials import PseudoConwayLattice
|
|
1046
|
+
sage: L = PseudoConwayLattice(11, use_database=False)
|
|
1047
|
+
sage: F = GF(7).algebraic_closure(lattice=L)
|
|
1048
|
+
Traceback (most recent call last):
|
|
1049
|
+
...
|
|
1050
|
+
TypeError: lattice must be a pseudo-Conway lattice with characteristic 7
|
|
1051
|
+
sage: F = GF(11).algebraic_closure(lattice=L)
|
|
1052
|
+
sage: F.gen(2).minimal_polynomial()
|
|
1053
|
+
x^2 + 4*x + 2
|
|
1054
|
+
|
|
1055
|
+
sage: F = GF(11).algebraic_closure(use_database=True)
|
|
1056
|
+
sage: F.gen(2).minimal_polynomial()
|
|
1057
|
+
x^2 + 7*x + 2
|
|
1058
|
+
|
|
1059
|
+
.. NOTE::
|
|
1060
|
+
|
|
1061
|
+
In the test suite, ``_test_pickling`` has to be skipped
|
|
1062
|
+
because ``F`` and ``loads(dumps(F))`` cannot consistently
|
|
1063
|
+
be made to compare equal, and ``_test_elements`` has to be
|
|
1064
|
+
skipped for the reason described in
|
|
1065
|
+
:meth:`AlgebraicClosureFiniteFieldElement.__init__`.
|
|
1066
|
+
"""
|
|
1067
|
+
if not (isinstance(base_ring, FiniteField) and base_ring.is_prime_field()):
|
|
1068
|
+
raise NotImplementedError('algebraic closures of finite fields are only implemented for prime fields')
|
|
1069
|
+
from sage.rings.finite_rings.conway_polynomials import PseudoConwayLattice
|
|
1070
|
+
p = base_ring.characteristic()
|
|
1071
|
+
if lattice is None:
|
|
1072
|
+
lattice = PseudoConwayLattice(p, use_database)
|
|
1073
|
+
elif not isinstance(lattice, PseudoConwayLattice) or lattice.p != p:
|
|
1074
|
+
raise TypeError('lattice must be a pseudo-Conway lattice with characteristic %s' % p)
|
|
1075
|
+
self._pseudo_conway_lattice = lattice
|
|
1076
|
+
AlgebraicClosureFiniteField_generic.__init__(self, base_ring, name, category)
|
|
1077
|
+
|
|
1078
|
+
def _get_polynomial(self, n):
|
|
1079
|
+
"""
|
|
1080
|
+
Return the defining polynomial of the unique subfield of
|
|
1081
|
+
degree `n` of ``self``.
|
|
1082
|
+
|
|
1083
|
+
EXAMPLES::
|
|
1084
|
+
|
|
1085
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_pseudo_conway
|
|
1086
|
+
sage: F = AlgebraicClosureFiniteField_pseudo_conway(GF(5), 'z')
|
|
1087
|
+
sage: F._get_polynomial(1)
|
|
1088
|
+
x + 3
|
|
1089
|
+
"""
|
|
1090
|
+
return self._pseudo_conway_lattice.polynomial(n)
|
|
1091
|
+
|
|
1092
|
+
def _get_im_gen(self, m, n):
|
|
1093
|
+
"""
|
|
1094
|
+
Return the image of ``self.gen(m)`` under the canonical
|
|
1095
|
+
inclusion into ``self.subfield(n)``.
|
|
1096
|
+
|
|
1097
|
+
EXAMPLES::
|
|
1098
|
+
|
|
1099
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_pseudo_conway
|
|
1100
|
+
sage: F = AlgebraicClosureFiniteField_pseudo_conway(GF(5), 'z')
|
|
1101
|
+
sage: F._get_im_gen(2, 4)
|
|
1102
|
+
z4^3 + z4^2 + z4 + 3
|
|
1103
|
+
"""
|
|
1104
|
+
p = self.characteristic()
|
|
1105
|
+
if m == 1:
|
|
1106
|
+
return self._subfield(n).one()
|
|
1107
|
+
return self._subfield(n).gen() ** ((p**n - 1)//(p**m - 1))
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
def AlgebraicClosureFiniteField(base_ring, name, category=None, implementation=None, **kwds):
|
|
1111
|
+
"""
|
|
1112
|
+
Construct an algebraic closure of a finite field.
|
|
1113
|
+
|
|
1114
|
+
The recommended way to use this functionality is by calling the
|
|
1115
|
+
:meth:`~sage.rings.finite_rings.finite_field_base.FiniteField.algebraic_closure`
|
|
1116
|
+
method of the finite field.
|
|
1117
|
+
|
|
1118
|
+
.. NOTE::
|
|
1119
|
+
|
|
1120
|
+
Algebraic closures of finite fields in Sage do not have the
|
|
1121
|
+
unique representation property, because they are not
|
|
1122
|
+
determined up to unique isomorphism by their defining data.
|
|
1123
|
+
|
|
1124
|
+
EXAMPLES::
|
|
1125
|
+
|
|
1126
|
+
sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField
|
|
1127
|
+
sage: F = GF(2).algebraic_closure()
|
|
1128
|
+
sage: F1 = AlgebraicClosureFiniteField(GF(2), 'z')
|
|
1129
|
+
sage: F1 is F
|
|
1130
|
+
False
|
|
1131
|
+
|
|
1132
|
+
In the pseudo-Conway implementation, non-identical instances never
|
|
1133
|
+
compare equal::
|
|
1134
|
+
|
|
1135
|
+
sage: F1 == F
|
|
1136
|
+
False
|
|
1137
|
+
sage: loads(dumps(F)) == F
|
|
1138
|
+
False
|
|
1139
|
+
|
|
1140
|
+
This is to ensure that the result of comparing two instances
|
|
1141
|
+
cannot change with time.
|
|
1142
|
+
"""
|
|
1143
|
+
if category is None:
|
|
1144
|
+
from sage.categories.fields import Fields
|
|
1145
|
+
category = Fields().Infinite()
|
|
1146
|
+
|
|
1147
|
+
if implementation is None:
|
|
1148
|
+
implementation = 'pseudo_conway'
|
|
1149
|
+
|
|
1150
|
+
if implementation == 'pseudo_conway':
|
|
1151
|
+
return AlgebraicClosureFiniteField_pseudo_conway(base_ring, name, category, **kwds)
|
|
1152
|
+
else:
|
|
1153
|
+
raise ValueError('unknown implementation for algebraic closure of finite field: %s'
|
|
1154
|
+
% implementation)
|