passagemath-modules 10.6.31rc3__cp314-cp314-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.
Potentially problematic release.
This version of passagemath-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
- passagemath_modules-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_modules.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-23768756.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-7897025b.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-e34bb864.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-503f0c35.3.29.so +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-musl.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-aarch64-linux-musl.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-aarch64-linux-musl.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-aarch64-linux-musl.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-aarch64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-aarch64-linux-musl.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,2087 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
Drinfeld modules
|
|
5
|
+
|
|
6
|
+
This module provides the class
|
|
7
|
+
:class:`sage.rings.function_field.drinfeld_module.drinfeld_module.DrinfeldModule`.
|
|
8
|
+
|
|
9
|
+
For finite Drinfeld modules and their theory of complex multiplication, see
|
|
10
|
+
class
|
|
11
|
+
:class:`sage.rings.function_field.drinfeld_module.finite_drinfeld_module.DrinfeldModule`.
|
|
12
|
+
|
|
13
|
+
AUTHORS:
|
|
14
|
+
|
|
15
|
+
- Antoine Leudière (2022-04): initial version
|
|
16
|
+
- Xavier Caruso (2022-06): initial version
|
|
17
|
+
- David Ayotte (2023-03): added basic `j`-invariants
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# *****************************************************************************
|
|
21
|
+
# Copyright (C) 2022 Antoine Leudière <antoine.leudiere@inria.fr>
|
|
22
|
+
#
|
|
23
|
+
# This program is free software: you can redistribute it and/or modify
|
|
24
|
+
# it under the terms of the GNU General Public License as published by
|
|
25
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
26
|
+
# (at your option) any later version.
|
|
27
|
+
# http://www.gnu.org/licenses/
|
|
28
|
+
# *****************************************************************************
|
|
29
|
+
|
|
30
|
+
from sage.arith.misc import gcd
|
|
31
|
+
from sage.categories.drinfeld_modules import DrinfeldModules
|
|
32
|
+
from sage.categories.homset import Hom
|
|
33
|
+
from sage.misc.latex import latex
|
|
34
|
+
from sage.misc.latex import latex_variable_name
|
|
35
|
+
from sage.misc.lazy_import import lazy_import
|
|
36
|
+
from sage.misc.lazy_string import _LazyString
|
|
37
|
+
from sage.misc.misc_c import prod
|
|
38
|
+
from sage.rings.integer import Integer
|
|
39
|
+
from sage.rings.integer_ring import ZZ
|
|
40
|
+
from sage.rings.fraction_field import FractionField_generic
|
|
41
|
+
from sage.rings.polynomial.ore_polynomial_element import OrePolynomial
|
|
42
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
43
|
+
from sage.structure.parent import Parent
|
|
44
|
+
from sage.structure.sage_object import SageObject
|
|
45
|
+
from sage.structure.sequence import Sequence
|
|
46
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
47
|
+
|
|
48
|
+
lazy_import('sage.rings.ring_extension', 'RingExtension_generic')
|
|
49
|
+
lazy_import('sage.geometry.polyhedron.constructor', 'Polyhedron')
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class DrinfeldModule(Parent, UniqueRepresentation):
|
|
53
|
+
r"""
|
|
54
|
+
This class implements Drinfeld `\mathbb{F}_q[T]`-modules.
|
|
55
|
+
|
|
56
|
+
Let `\mathbb{F}_q[T]` be a polynomial ring with coefficients in a
|
|
57
|
+
finite field `\mathbb{F}_q` and let `K` be a field. Fix a ring
|
|
58
|
+
morphism `\gamma: \mathbb{F}_q[T] \to K`; we say that `K` is an
|
|
59
|
+
`\mathbb{F}_q[T]`-*field*. Let `K\{\tau\}` be the ring of Ore
|
|
60
|
+
polynomials with coefficients in `K`, whose multiplication is given
|
|
61
|
+
by the rule `\tau \lambda = \lambda^q \tau` for any `\lambda \in K`.
|
|
62
|
+
|
|
63
|
+
A Drinfeld `\mathbb{F}_q[T]`-module over the base
|
|
64
|
+
`\mathbb{F}_q[T]`-field `K` is an `\mathbb{F}_q`-algebra morphism
|
|
65
|
+
`\phi: \mathbb{F}_q[T] \to K\{\tau\}` such that `\mathrm{Im}(\phi)
|
|
66
|
+
\not\subset K` and `\phi` agrees with `\gamma` on `\mathbb{F}_q`.
|
|
67
|
+
|
|
68
|
+
For `a` in `\mathbb{F}_q[T]`, `\phi(a)` is denoted `\phi_a`.
|
|
69
|
+
|
|
70
|
+
The Drinfeld `\mathbb{F}_q[T]`-module `\phi` is uniquely determined
|
|
71
|
+
by the image `\phi_T` of `T`; this serves as input of the class.
|
|
72
|
+
|
|
73
|
+
.. NOTE::
|
|
74
|
+
|
|
75
|
+
See also :class:`sage.categories.drinfeld_modules`.
|
|
76
|
+
|
|
77
|
+
The *base morphism* is the morphism `\gamma: \mathbb{F}_q[T] \to K`.
|
|
78
|
+
The monic polynomial that generates the kernel of `\gamma` is called
|
|
79
|
+
the `\mathbb{F}_q[T]`-*characteristic*, or *function-field
|
|
80
|
+
characteristic*, of the base field. We say that `\mathbb{F}_q[T]` is
|
|
81
|
+
the *function ring* of `\phi`; `K\{\tau\}` is the *Ore polynomial
|
|
82
|
+
ring*. Further, the *generator* is `\phi_T` and the *constant
|
|
83
|
+
coefficient* is the constant coefficient of `\phi_T`.
|
|
84
|
+
|
|
85
|
+
A Drinfeld module is said to be *finite* if the field `K` is.
|
|
86
|
+
Despite an emphasis on this case, the base field can be any
|
|
87
|
+
extension of `\mathbb{F}_q`::
|
|
88
|
+
|
|
89
|
+
sage: Fq = GF(25)
|
|
90
|
+
sage: A.<T> = Fq[]
|
|
91
|
+
sage: K.<z> = Fq.extension(6)
|
|
92
|
+
sage: phi = DrinfeldModule(A, [z, 4, 1])
|
|
93
|
+
sage: phi
|
|
94
|
+
Drinfeld module defined by T |--> t^2 + 4*t + z
|
|
95
|
+
|
|
96
|
+
::
|
|
97
|
+
|
|
98
|
+
sage: Fq = GF(49)
|
|
99
|
+
sage: A.<T> = Fq[]
|
|
100
|
+
sage: K = Frac(A)
|
|
101
|
+
sage: psi = DrinfeldModule(A, [K(T), T+1])
|
|
102
|
+
sage: psi
|
|
103
|
+
Drinfeld module defined by T |--> (T + 1)*t + T
|
|
104
|
+
|
|
105
|
+
.. NOTE::
|
|
106
|
+
|
|
107
|
+
Finite Drinfeld modules are implemented in the class
|
|
108
|
+
:class:`sage.rings.function_field.drinfeld_modules.finite_drinfeld_module`.
|
|
109
|
+
|
|
110
|
+
Classical references on Drinfeld modules include [Gos1998]_,
|
|
111
|
+
[Rosen2002]_, [VS06]_ and [Gek1991]_.
|
|
112
|
+
|
|
113
|
+
.. NOTE::
|
|
114
|
+
|
|
115
|
+
Drinfeld modules are defined in a larger setting, in which the
|
|
116
|
+
polynomial ring `\mathbb{F}_q[T]` is replaced by a more general
|
|
117
|
+
function ring: the ring of functions in `k` that are regular
|
|
118
|
+
outside `\infty`, where `k` is a function field over
|
|
119
|
+
`\mathbb{F}_q` with transcendence degree `1` and `\infty` is a
|
|
120
|
+
fixed place of `k`. This is out of the scope of this
|
|
121
|
+
implementation.
|
|
122
|
+
|
|
123
|
+
INPUT:
|
|
124
|
+
|
|
125
|
+
- ``function_ring`` -- a univariate polynomial ring whose base field
|
|
126
|
+
is a finite field
|
|
127
|
+
|
|
128
|
+
- ``gen`` -- the generator of the Drinfeld module; as a list of
|
|
129
|
+
coefficients or an Ore polynomial
|
|
130
|
+
|
|
131
|
+
- ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring
|
|
132
|
+
generator
|
|
133
|
+
|
|
134
|
+
.. RUBRIC:: Construction
|
|
135
|
+
|
|
136
|
+
A Drinfeld module object is constructed by giving the function ring
|
|
137
|
+
and the generator::
|
|
138
|
+
|
|
139
|
+
sage: Fq.<z2> = GF(3^2)
|
|
140
|
+
sage: A.<T> = Fq[]
|
|
141
|
+
sage: K.<z> = Fq.extension(6)
|
|
142
|
+
sage: phi = DrinfeldModule(A, [z, 1, 1])
|
|
143
|
+
sage: phi
|
|
144
|
+
Drinfeld module defined by T |--> t^2 + t + z
|
|
145
|
+
|
|
146
|
+
.. NOTE::
|
|
147
|
+
|
|
148
|
+
Note that the definition of the base field is implicit; it is
|
|
149
|
+
automatically defined as the compositum of all the parents of
|
|
150
|
+
the coefficients.
|
|
151
|
+
|
|
152
|
+
The above Drinfeld module is finite; it can also be infinite::
|
|
153
|
+
|
|
154
|
+
sage: L = Frac(A)
|
|
155
|
+
sage: psi = DrinfeldModule(A, [L(T), 1, T^3 + T + 1])
|
|
156
|
+
sage: psi
|
|
157
|
+
Drinfeld module defined by T |--> (T^3 + T + 1)*t^2 + t + T
|
|
158
|
+
|
|
159
|
+
::
|
|
160
|
+
|
|
161
|
+
sage: phi.is_finite()
|
|
162
|
+
True
|
|
163
|
+
sage: psi.is_finite()
|
|
164
|
+
False
|
|
165
|
+
|
|
166
|
+
In those examples, we used a list of coefficients (``[z, 1, 1]``) to
|
|
167
|
+
represent the generator `\phi_T = z + t + t^2`. One can also use
|
|
168
|
+
regular Ore polynomials::
|
|
169
|
+
|
|
170
|
+
sage: ore_polring = phi.ore_polring()
|
|
171
|
+
sage: t = ore_polring.gen()
|
|
172
|
+
sage: rho_T = z + t^3
|
|
173
|
+
sage: rho = DrinfeldModule(A, rho_T)
|
|
174
|
+
sage: rho
|
|
175
|
+
Drinfeld module defined by T |--> t^3 + z
|
|
176
|
+
sage: rho(T) == rho_T
|
|
177
|
+
True
|
|
178
|
+
|
|
179
|
+
Images under the Drinfeld module are computed by calling the
|
|
180
|
+
object::
|
|
181
|
+
|
|
182
|
+
sage: phi(T) # phi_T, the generator of the Drinfeld module
|
|
183
|
+
t^2 + t + z
|
|
184
|
+
sage: phi(T^3 + T + 1) # phi_(T^3 + T + 1)
|
|
185
|
+
t^6 + (z^11 + z^9 + 2*z^6 + 2*z^4 + 2*z + 1)*t^4
|
|
186
|
+
+ (2*z^11 + 2*z^10 + z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^3)*t^3
|
|
187
|
+
+ (2*z^11 + z^10 + z^9 + 2*z^7 + 2*z^6 + z^5 + z^4 + 2*z^3 + 2*z + 2)*t^2
|
|
188
|
+
+ (2*z^11 + 2*z^8 + 2*z^6 + z^5 + z^4 + 2*z^2)*t + z^3 + z + 1
|
|
189
|
+
sage: phi(1) # phi_1
|
|
190
|
+
1
|
|
191
|
+
|
|
192
|
+
.. RUBRIC:: The category of Drinfeld modules
|
|
193
|
+
|
|
194
|
+
Drinfeld modules have their own category (see class
|
|
195
|
+
:class:`sage.categories.drinfeld_modules.DrinfeldModules`)::
|
|
196
|
+
|
|
197
|
+
sage: phi.category()
|
|
198
|
+
Category of Drinfeld modules over Finite Field in z of size 3^12 over its base
|
|
199
|
+
sage: phi.category() is psi.category()
|
|
200
|
+
False
|
|
201
|
+
sage: phi.category() is rho.category()
|
|
202
|
+
True
|
|
203
|
+
|
|
204
|
+
One can use the category to directly create new objects::
|
|
205
|
+
|
|
206
|
+
sage: cat = phi.category()
|
|
207
|
+
sage: cat.object([z, 0, 0, 1])
|
|
208
|
+
Drinfeld module defined by T |--> t^3 + z
|
|
209
|
+
|
|
210
|
+
.. RUBRIC:: The base field of a Drinfeld module
|
|
211
|
+
|
|
212
|
+
The base field of the Drinfeld module is retrieved using
|
|
213
|
+
:meth:`base`::
|
|
214
|
+
|
|
215
|
+
sage: phi.base()
|
|
216
|
+
Finite Field in z of size 3^12 over its base
|
|
217
|
+
|
|
218
|
+
The base morphism is retrieved using :meth:`base_morphism`::
|
|
219
|
+
|
|
220
|
+
sage: phi.base_morphism()
|
|
221
|
+
Ring morphism:
|
|
222
|
+
From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
|
|
223
|
+
To: Finite Field in z of size 3^12 over its base
|
|
224
|
+
Defn: T |--> z
|
|
225
|
+
|
|
226
|
+
Note that the base field is *not* the field `K`. Rather, it is a
|
|
227
|
+
ring extension
|
|
228
|
+
(see :class:`sage.rings.ring_extension.RingExtension`) whose
|
|
229
|
+
underlying ring is `K` and whose base is the base morphism::
|
|
230
|
+
|
|
231
|
+
sage: phi.base() is K
|
|
232
|
+
False
|
|
233
|
+
|
|
234
|
+
.. RUBRIC:: Getters
|
|
235
|
+
|
|
236
|
+
One can retrieve basic properties::
|
|
237
|
+
|
|
238
|
+
sage: phi.base_morphism()
|
|
239
|
+
Ring morphism:
|
|
240
|
+
From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
|
|
241
|
+
To: Finite Field in z of size 3^12 over its base
|
|
242
|
+
Defn: T |--> z
|
|
243
|
+
|
|
244
|
+
::
|
|
245
|
+
|
|
246
|
+
sage: phi.ore_polring() # K{t}
|
|
247
|
+
Ore Polynomial Ring in t over Finite Field in z of size 3^12 over its base
|
|
248
|
+
twisted by Frob^2
|
|
249
|
+
|
|
250
|
+
::
|
|
251
|
+
|
|
252
|
+
sage: phi.function_ring() # Fq[T]
|
|
253
|
+
Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
|
|
254
|
+
|
|
255
|
+
::
|
|
256
|
+
|
|
257
|
+
sage: phi.gen() # phi_T
|
|
258
|
+
t^2 + t + z
|
|
259
|
+
sage: phi.gen() == phi(T)
|
|
260
|
+
True
|
|
261
|
+
|
|
262
|
+
::
|
|
263
|
+
|
|
264
|
+
sage: phi.constant_coefficient() # Constant coefficient of phi_T
|
|
265
|
+
z
|
|
266
|
+
|
|
267
|
+
::
|
|
268
|
+
|
|
269
|
+
sage: phi.morphism() # The Drinfeld module as a morphism
|
|
270
|
+
Ring morphism:
|
|
271
|
+
From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
|
|
272
|
+
To: Ore Polynomial Ring in t
|
|
273
|
+
over Finite Field in z of size 3^12 over its base
|
|
274
|
+
twisted by Frob^2
|
|
275
|
+
Defn: T |--> t^2 + t + z
|
|
276
|
+
|
|
277
|
+
One can compute the rank and height::
|
|
278
|
+
|
|
279
|
+
sage: phi.rank()
|
|
280
|
+
2
|
|
281
|
+
sage: phi.height()
|
|
282
|
+
1
|
|
283
|
+
|
|
284
|
+
As well as the j-invariant::
|
|
285
|
+
|
|
286
|
+
sage: phi.j_invariant() # j-invariant
|
|
287
|
+
1
|
|
288
|
+
|
|
289
|
+
A Drinfeld `\mathbb{F}_q[T]`-module can be seen as an Ore polynomial
|
|
290
|
+
with positive degree and constant coefficient `\gamma(T)`, where
|
|
291
|
+
`\gamma` is the base morphism. This analogy is the motivation for
|
|
292
|
+
the following methods::
|
|
293
|
+
|
|
294
|
+
sage: phi.coefficients()
|
|
295
|
+
[z, 1, 1]
|
|
296
|
+
|
|
297
|
+
::
|
|
298
|
+
|
|
299
|
+
sage: phi.coefficient(1)
|
|
300
|
+
1
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
.. RUBRIC:: Morphisms and isogenies
|
|
304
|
+
|
|
305
|
+
A *morphism* of Drinfeld modules `\phi \to \psi` is an Ore
|
|
306
|
+
polynomial `f \in K\{\tau\}` such that `f \phi_a = \psi_a f` for
|
|
307
|
+
every `a` in the function ring. In our case, this is equivalent to
|
|
308
|
+
`f \phi_T = \psi_T f`. An *isogeny* is a nonzero morphism.
|
|
309
|
+
|
|
310
|
+
Use the ``in`` syntax to test if an Ore polynomial defines a
|
|
311
|
+
morphism::
|
|
312
|
+
|
|
313
|
+
sage: phi(T) in Hom(phi, phi)
|
|
314
|
+
True
|
|
315
|
+
sage: t^6 in Hom(phi, phi)
|
|
316
|
+
True
|
|
317
|
+
sage: t^5 + 2*t^3 + 1 in Hom(phi, phi)
|
|
318
|
+
False
|
|
319
|
+
sage: 1 in Hom(phi, rho)
|
|
320
|
+
False
|
|
321
|
+
sage: 1 in Hom(phi, phi)
|
|
322
|
+
True
|
|
323
|
+
sage: 0 in Hom(phi, rho)
|
|
324
|
+
True
|
|
325
|
+
|
|
326
|
+
To create a SageMath object representing the morphism, call the
|
|
327
|
+
homset (``hom``)::
|
|
328
|
+
|
|
329
|
+
sage: hom = Hom(phi, phi)
|
|
330
|
+
sage: frobenius_endomorphism = hom(t^6)
|
|
331
|
+
sage: identity_morphism = hom(1)
|
|
332
|
+
sage: zero_morphism = hom(0)
|
|
333
|
+
sage: frobenius_endomorphism
|
|
334
|
+
Endomorphism of Drinfeld module defined by T |--> t^2 + t + z
|
|
335
|
+
Defn: t^6
|
|
336
|
+
sage: identity_morphism
|
|
337
|
+
Identity morphism of Drinfeld module defined by T |--> t^2 + t + z
|
|
338
|
+
sage: zero_morphism
|
|
339
|
+
Endomorphism of Drinfeld module defined by T |--> t^2 + t + z
|
|
340
|
+
Defn: 0
|
|
341
|
+
|
|
342
|
+
The underlying Ore polynomial is retrieved with the method
|
|
343
|
+
:meth:`ore_polynomial`::
|
|
344
|
+
|
|
345
|
+
sage: frobenius_endomorphism.ore_polynomial()
|
|
346
|
+
t^6
|
|
347
|
+
sage: identity_morphism.ore_polynomial()
|
|
348
|
+
1
|
|
349
|
+
|
|
350
|
+
One checks if a morphism is an isogeny, endomorphism or
|
|
351
|
+
isomorphism::
|
|
352
|
+
|
|
353
|
+
sage: frobenius_endomorphism.is_isogeny()
|
|
354
|
+
True
|
|
355
|
+
sage: identity_morphism.is_isogeny()
|
|
356
|
+
True
|
|
357
|
+
sage: zero_morphism.is_isogeny()
|
|
358
|
+
False
|
|
359
|
+
sage: frobenius_endomorphism.is_isomorphism()
|
|
360
|
+
False
|
|
361
|
+
sage: identity_morphism.is_isomorphism()
|
|
362
|
+
True
|
|
363
|
+
sage: zero_morphism.is_isomorphism()
|
|
364
|
+
False
|
|
365
|
+
|
|
366
|
+
.. RUBRIC:: The Vélu formula
|
|
367
|
+
|
|
368
|
+
Let ``P`` be a nonzero Ore polynomial. We can decide if ``P``
|
|
369
|
+
defines an isogeny with a given domain and, if it does, find
|
|
370
|
+
the codomain::
|
|
371
|
+
|
|
372
|
+
sage: P = (2*z^6 + z^3 + 2*z^2 + z + 2)*t + z^11 + 2*z^10 + 2*z^9 + 2*z^8 + z^7 + 2*z^6 + z^5 + z^3 + z^2 + z
|
|
373
|
+
sage: psi = phi.velu(P)
|
|
374
|
+
sage: psi
|
|
375
|
+
Drinfeld module defined by T |--> (2*z^11 + 2*z^9 + z^6 + 2*z^5 + 2*z^4 + 2*z^2 + 1)*t^2
|
|
376
|
+
+ (2*z^11 + 2*z^10 + 2*z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^4 + 2*z^2 + 2*z)*t + z
|
|
377
|
+
sage: P in Hom(phi, psi)
|
|
378
|
+
True
|
|
379
|
+
sage: P * phi(T) == psi(T) * P
|
|
380
|
+
True
|
|
381
|
+
|
|
382
|
+
If the input does not define an isogeny, an exception is raised::
|
|
383
|
+
|
|
384
|
+
sage: phi.velu(0)
|
|
385
|
+
Traceback (most recent call last):
|
|
386
|
+
...
|
|
387
|
+
ValueError: the input does not define an isogeny
|
|
388
|
+
sage: phi.velu(t)
|
|
389
|
+
Traceback (most recent call last):
|
|
390
|
+
...
|
|
391
|
+
ValueError: the input does not define an isogeny
|
|
392
|
+
|
|
393
|
+
.. RUBRIC:: The action of a Drinfeld module
|
|
394
|
+
|
|
395
|
+
The `\mathbb{F}_q[T]`-Drinfeld module `\phi` induces a special left
|
|
396
|
+
`\mathbb{F}_q[T]`-module structure on any field extension `L/K`. Let
|
|
397
|
+
`x \in L` and `a` be in the function ring; the action is defined as
|
|
398
|
+
`(a, x) \mapsto \phi_a(x)`. The method :meth:`action` returns a
|
|
399
|
+
:class:`sage.rings.function_field.drinfeld_modules.action.Action`
|
|
400
|
+
object representing the Drinfeld module action.
|
|
401
|
+
|
|
402
|
+
.. NOTE::
|
|
403
|
+
|
|
404
|
+
In this implementation, `L` is `K`::
|
|
405
|
+
|
|
406
|
+
sage: action = phi.action()
|
|
407
|
+
sage: action
|
|
408
|
+
Action on Finite Field in z of size 3^12 over its base
|
|
409
|
+
induced by Drinfeld module defined by T |--> t^2 + t + z
|
|
410
|
+
|
|
411
|
+
The action on elements is computed by calling the action object::
|
|
412
|
+
|
|
413
|
+
sage: P = T + 1
|
|
414
|
+
sage: a = z
|
|
415
|
+
sage: action(P, a)
|
|
416
|
+
...
|
|
417
|
+
z^9 + 2*z^8 + 2*z^7 + 2*z^6 + 2*z^3 + z^2
|
|
418
|
+
sage: action(0, K.random_element())
|
|
419
|
+
0
|
|
420
|
+
sage: action(A.random_element(), 0)
|
|
421
|
+
0
|
|
422
|
+
|
|
423
|
+
.. WARNING::
|
|
424
|
+
|
|
425
|
+
The class ``DrinfeldModuleAction`` may be replaced later on. See
|
|
426
|
+
issues #34833 and #34834.
|
|
427
|
+
|
|
428
|
+
TESTS:
|
|
429
|
+
|
|
430
|
+
The generator must have positive degree::
|
|
431
|
+
|
|
432
|
+
sage: Fq = GF(2)
|
|
433
|
+
sage: K.<z> = Fq.extension(2)
|
|
434
|
+
sage: A.<T> = Fq[]
|
|
435
|
+
sage: DrinfeldModule(A, [K(1)])
|
|
436
|
+
Traceback (most recent call last):
|
|
437
|
+
...
|
|
438
|
+
ValueError: generator must have positive degree
|
|
439
|
+
|
|
440
|
+
The constant coefficient must be nonzero::
|
|
441
|
+
|
|
442
|
+
sage: Fq = GF(2)
|
|
443
|
+
sage: K.<z> = Fq.extension(2)
|
|
444
|
+
sage: A.<T> = Fq[]
|
|
445
|
+
sage: DrinfeldModule(A, [K(0), K(1)])
|
|
446
|
+
Traceback (most recent call last):
|
|
447
|
+
...
|
|
448
|
+
ValueError: constant coefficient must be nonzero
|
|
449
|
+
|
|
450
|
+
The coefficients of the generator must lie in an
|
|
451
|
+
`\mathbb{F}_q[T]`-field, where `\mathbb{F}_q[T]` is the function
|
|
452
|
+
ring of the Drinfeld module::
|
|
453
|
+
|
|
454
|
+
sage: Fq = GF(2)
|
|
455
|
+
sage: K.<z> = Fq.extension(2)
|
|
456
|
+
sage: A.<T> = Fq[]
|
|
457
|
+
sage: DrinfeldModule(A, [z, QQ(1)])
|
|
458
|
+
Traceback (most recent call last):
|
|
459
|
+
...
|
|
460
|
+
ValueError: function ring base must coerce into base field
|
|
461
|
+
|
|
462
|
+
::
|
|
463
|
+
|
|
464
|
+
sage: Fq = GF(2)
|
|
465
|
+
sage: K.<z> = Fq.extension(2)
|
|
466
|
+
sage: A.<T> = Fq[]
|
|
467
|
+
sage: DrinfeldModule(A, [1, QQ(1)])
|
|
468
|
+
Traceback (most recent call last):
|
|
469
|
+
...
|
|
470
|
+
ValueError: function ring base must coerce into base field
|
|
471
|
+
|
|
472
|
+
The function ring must be an univariate polynomial ring whose
|
|
473
|
+
base is a finite field::
|
|
474
|
+
|
|
475
|
+
sage: Fq = GF(2)
|
|
476
|
+
sage: K.<z> = Fq.extension(2)
|
|
477
|
+
sage: A.<T> = Fq[]
|
|
478
|
+
sage: DrinfeldModule(K, [z, 1, 1])
|
|
479
|
+
Traceback (most recent call last):
|
|
480
|
+
...
|
|
481
|
+
NotImplementedError: function ring must be a polynomial ring
|
|
482
|
+
|
|
483
|
+
::
|
|
484
|
+
|
|
485
|
+
sage: Fq = GF(2)
|
|
486
|
+
sage: K.<z> = Fq.extension(2)
|
|
487
|
+
sage: A.<T> = Fq[]
|
|
488
|
+
sage: AY.<Y> = A[]
|
|
489
|
+
sage: DrinfeldModule(AY, [z, 1, 1])
|
|
490
|
+
Traceback (most recent call last):
|
|
491
|
+
...
|
|
492
|
+
TypeError: function ring base must be a finite field
|
|
493
|
+
|
|
494
|
+
If you already defined a category of Drinfeld modules, and you
|
|
495
|
+
create a Drinfeld module through this category, you must ensure that
|
|
496
|
+
the constant coefficient is that of the category::
|
|
497
|
+
|
|
498
|
+
sage: Fq = GF(2)
|
|
499
|
+
sage: K.<z> = Fq.extension(2)
|
|
500
|
+
sage: A.<T> = Fq[]
|
|
501
|
+
sage: phi = DrinfeldModule(A, [z, 1])
|
|
502
|
+
sage: phi.category().object([1, 1, K(1)])
|
|
503
|
+
Traceback (most recent call last):
|
|
504
|
+
...
|
|
505
|
+
ValueError: constant coefficient must equal that of the category
|
|
506
|
+
|
|
507
|
+
::
|
|
508
|
+
|
|
509
|
+
sage: Fq = K = GF(2)
|
|
510
|
+
sage: A.<T> = Fq[]
|
|
511
|
+
sage: phi = DrinfeldModule(A, [1, 1])
|
|
512
|
+
Traceback (most recent call last):
|
|
513
|
+
...
|
|
514
|
+
ValueError: function ring base must coerce into base field
|
|
515
|
+
|
|
516
|
+
::
|
|
517
|
+
|
|
518
|
+
sage: Fq = K = GF(2)
|
|
519
|
+
sage: A.<T> = Fq[]
|
|
520
|
+
sage: phi = DrinfeldModule(A, [K(1), 1])
|
|
521
|
+
sage: isinstance(phi.ore_polring(), OrePolynomialRing)
|
|
522
|
+
True
|
|
523
|
+
"""
|
|
524
|
+
|
|
525
|
+
@staticmethod
|
|
526
|
+
def __classcall_private__(cls, function_ring, gen, name='t'):
|
|
527
|
+
"""
|
|
528
|
+
Check input validity and return a ``DrinfeldModule`` or
|
|
529
|
+
``DrinfeldModule_finite`` object accordingly.
|
|
530
|
+
|
|
531
|
+
INPUT:
|
|
532
|
+
|
|
533
|
+
- ``function_ring`` -- a univariate polynomial ring whose base
|
|
534
|
+
is a finite field
|
|
535
|
+
|
|
536
|
+
- ``gen`` -- the generator of the Drinfeld module; as a list of
|
|
537
|
+
coefficients or an Ore polynomial
|
|
538
|
+
|
|
539
|
+
- ``name`` -- (default: ``'t'``) the name of the Ore polynomial
|
|
540
|
+
ring gen
|
|
541
|
+
|
|
542
|
+
OUTPUT: a DrinfeldModule or DrinfeldModule_finite
|
|
543
|
+
|
|
544
|
+
TESTS::
|
|
545
|
+
|
|
546
|
+
sage: from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite
|
|
547
|
+
sage: Fq = GF(25)
|
|
548
|
+
sage: A.<T> = Fq[]
|
|
549
|
+
sage: K.<z12> = Fq.extension(6)
|
|
550
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
551
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
552
|
+
sage: isinstance(phi, DrinfeldModule_finite)
|
|
553
|
+
True
|
|
554
|
+
|
|
555
|
+
::
|
|
556
|
+
|
|
557
|
+
sage: K = Frac(A)
|
|
558
|
+
sage: phi = DrinfeldModule(A, [K(T), 1])
|
|
559
|
+
sage: isinstance(psi, DrinfeldModule_finite)
|
|
560
|
+
False
|
|
561
|
+
"""
|
|
562
|
+
|
|
563
|
+
# FIXME: function_ring must be checked before calling base_ring
|
|
564
|
+
# on it. But then it is checked twice: firstly here, secondly in
|
|
565
|
+
# the category. Another problem is that those lines are
|
|
566
|
+
# duplicate. As a general comment, there are sanity checks both
|
|
567
|
+
# here and in the category constructor, which is not ideal.
|
|
568
|
+
# Check domain is Fq[T]
|
|
569
|
+
if not isinstance(function_ring, PolynomialRing_generic):
|
|
570
|
+
raise NotImplementedError('function ring must be a polynomial '
|
|
571
|
+
'ring')
|
|
572
|
+
function_ring_base = function_ring.base_ring()
|
|
573
|
+
if not function_ring_base.is_field() \
|
|
574
|
+
or not function_ring_base.is_finite():
|
|
575
|
+
raise TypeError('function ring base must be a finite field')
|
|
576
|
+
|
|
577
|
+
# Check all possible input types for gen
|
|
578
|
+
# `gen` is an Ore polynomial:
|
|
579
|
+
if isinstance(gen, OrePolynomial):
|
|
580
|
+
ore_polring = gen.parent()
|
|
581
|
+
# Base ring without morphism structure:
|
|
582
|
+
base_field_noext = ore_polring.base()
|
|
583
|
+
name = ore_polring.variable_name()
|
|
584
|
+
# `gen` is a list of coefficients (function_ring = Fq[T]):
|
|
585
|
+
elif isinstance(gen, (list, tuple)):
|
|
586
|
+
ore_polring = None
|
|
587
|
+
# Base ring without morphism structure:
|
|
588
|
+
base_field_noext = Sequence(gen).universe()
|
|
589
|
+
else:
|
|
590
|
+
raise TypeError('generator must be list of coefficients or Ore '
|
|
591
|
+
'polynomial')
|
|
592
|
+
# Constant coefficient must be nonzero:
|
|
593
|
+
if gen[0].is_zero():
|
|
594
|
+
raise ValueError('constant coefficient must be nonzero')
|
|
595
|
+
# The coefficients are in a base field that has coercion from Fq:
|
|
596
|
+
if not (hasattr(base_field_noext, 'has_coerce_map_from') and
|
|
597
|
+
base_field_noext.has_coerce_map_from(function_ring.base_ring())):
|
|
598
|
+
raise ValueError('function ring base must coerce into base field')
|
|
599
|
+
|
|
600
|
+
# Build the category
|
|
601
|
+
T = function_ring.gen()
|
|
602
|
+
if isinstance(base_field_noext, RingExtension_generic):
|
|
603
|
+
base_field = base_field_noext
|
|
604
|
+
elif base_field_noext.has_coerce_map_from(function_ring) \
|
|
605
|
+
and T == gen[0]:
|
|
606
|
+
base_morphism = base_field_noext.coerce_map_from(function_ring)
|
|
607
|
+
base_field = base_field_noext.over(base_morphism)
|
|
608
|
+
else:
|
|
609
|
+
base_morphism = Hom(function_ring, base_field_noext)(gen[0])
|
|
610
|
+
base_field = base_field_noext.over(base_morphism)
|
|
611
|
+
|
|
612
|
+
# This test is also done in the category. We put it here also
|
|
613
|
+
# to have a friendlier error message
|
|
614
|
+
if not base_field.is_field():
|
|
615
|
+
raise ValueError('generator coefficients must live in a field')
|
|
616
|
+
|
|
617
|
+
category = DrinfeldModules(base_field, name=name)
|
|
618
|
+
|
|
619
|
+
# Check gen as Ore polynomial
|
|
620
|
+
ore_polring = category.ore_polring() # Sanity cast
|
|
621
|
+
gen = ore_polring(gen)
|
|
622
|
+
if gen.degree() <= 0:
|
|
623
|
+
raise ValueError('generator must have positive degree')
|
|
624
|
+
|
|
625
|
+
# Instantiate the appropriate class:
|
|
626
|
+
backend = base_field.backend(force=True)
|
|
627
|
+
if backend.is_finite():
|
|
628
|
+
from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite
|
|
629
|
+
return DrinfeldModule_finite(gen, category)
|
|
630
|
+
if isinstance(backend, FractionField_generic):
|
|
631
|
+
ring = backend.ring()
|
|
632
|
+
if (isinstance(ring, PolynomialRing_generic)
|
|
633
|
+
and ring.base_ring() is function_ring_base
|
|
634
|
+
and base_morphism(T) == ring.gen()):
|
|
635
|
+
from .charzero_drinfeld_module import DrinfeldModule_rational
|
|
636
|
+
return DrinfeldModule_rational(gen, category)
|
|
637
|
+
if not category._characteristic:
|
|
638
|
+
from .charzero_drinfeld_module import DrinfeldModule_charzero
|
|
639
|
+
return DrinfeldModule_charzero(gen, category)
|
|
640
|
+
return cls.__classcall__(cls, gen, category)
|
|
641
|
+
|
|
642
|
+
def __init__(self, gen, category):
|
|
643
|
+
"""
|
|
644
|
+
Initialize ``self``.
|
|
645
|
+
|
|
646
|
+
Validity of the input is checked in meth:`__classcall_private__`.
|
|
647
|
+
The meth:`__init__` just saves attributes.
|
|
648
|
+
|
|
649
|
+
INPUT:
|
|
650
|
+
|
|
651
|
+
- ``function_ring`` -- a univariate polynomial ring whose base
|
|
652
|
+
is a finite field
|
|
653
|
+
|
|
654
|
+
- ``gen`` -- the generator of the Drinfeld module; as a list of
|
|
655
|
+
coefficients or an Ore polynomial
|
|
656
|
+
|
|
657
|
+
- ``name`` -- (default: ``'t'``) the name of the Ore polynomial
|
|
658
|
+
ring gen
|
|
659
|
+
|
|
660
|
+
TESTS::
|
|
661
|
+
|
|
662
|
+
sage: Fq = GF(25)
|
|
663
|
+
sage: A.<T> = Fq[]
|
|
664
|
+
sage: K.<z12> = Fq.extension(6)
|
|
665
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
666
|
+
sage: gen = [p_root, z12^3, z12^5]
|
|
667
|
+
sage: phi = DrinfeldModule(A, gen)
|
|
668
|
+
sage: ore_polring = phi.ore_polring()
|
|
669
|
+
sage: phi._base == phi.category().base()
|
|
670
|
+
True
|
|
671
|
+
sage: phi._function_ring == A
|
|
672
|
+
True
|
|
673
|
+
sage: phi._gen == ore_polring(gen)
|
|
674
|
+
True
|
|
675
|
+
sage: phi._ore_polring == ore_polring
|
|
676
|
+
True
|
|
677
|
+
sage: phi._morphism == Hom(A, ore_polring)(phi._gen)
|
|
678
|
+
True
|
|
679
|
+
|
|
680
|
+
::
|
|
681
|
+
|
|
682
|
+
sage: TestSuite(phi).run()
|
|
683
|
+
"""
|
|
684
|
+
self._base = category.base()
|
|
685
|
+
self._function_ring = category.function_ring()
|
|
686
|
+
self._gen = gen
|
|
687
|
+
self._morphism = category._function_ring.hom([gen])
|
|
688
|
+
self._ore_polring = gen.parent()
|
|
689
|
+
self._Fq = self._function_ring.base_ring() # Must be last
|
|
690
|
+
super().__init__(base=self._base, category=category)
|
|
691
|
+
|
|
692
|
+
def __call__(self, a):
|
|
693
|
+
r"""
|
|
694
|
+
Return the image of input ``a`` by the morphism that defines the
|
|
695
|
+
Drinfeld module; i.e. `\phi_a` if the Drinfeld module is denoted
|
|
696
|
+
`phi`.
|
|
697
|
+
|
|
698
|
+
INPUT:
|
|
699
|
+
|
|
700
|
+
- ``a`` -- a function ring element
|
|
701
|
+
|
|
702
|
+
OUTPUT: an element in the base codomain
|
|
703
|
+
|
|
704
|
+
TESTS::
|
|
705
|
+
|
|
706
|
+
sage: Fq = GF(25)
|
|
707
|
+
sage: A.<T> = Fq[]
|
|
708
|
+
sage: K.<z12> = Fq.extension(6)
|
|
709
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
710
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
711
|
+
|
|
712
|
+
::
|
|
713
|
+
sage: a = T^3 + 4*T + 2
|
|
714
|
+
sage: phi(a) == phi(T)^3 + 4*phi(T) + 2
|
|
715
|
+
True
|
|
716
|
+
sage: phi(a)[0] == p_root^3 + 4*p_root + 2
|
|
717
|
+
True
|
|
718
|
+
|
|
719
|
+
::
|
|
720
|
+
|
|
721
|
+
sage: phi(0)
|
|
722
|
+
0
|
|
723
|
+
sage: phi(1)
|
|
724
|
+
1
|
|
725
|
+
sage: phi(T) == phi._gen
|
|
726
|
+
True
|
|
727
|
+
|
|
728
|
+
::
|
|
729
|
+
|
|
730
|
+
sage: a = A.random_element(5)
|
|
731
|
+
sage: phi(a)[0] == phi.category().base()(a)
|
|
732
|
+
True
|
|
733
|
+
"""
|
|
734
|
+
return self._morphism(a)
|
|
735
|
+
|
|
736
|
+
def _Hom_(self, other, category):
|
|
737
|
+
r"""
|
|
738
|
+
Return the set of morphisms from ``self`` to ``other``.
|
|
739
|
+
|
|
740
|
+
Validity of the input is checked at the instantiation of
|
|
741
|
+
``DrinfeldModuleHomset``; ``self`` and ``other`` only need be in
|
|
742
|
+
the same category.
|
|
743
|
+
|
|
744
|
+
INPUT:
|
|
745
|
+
|
|
746
|
+
- ``other`` -- the codomain of the homset
|
|
747
|
+
|
|
748
|
+
- ``category`` -- the category in which we consider the
|
|
749
|
+
morphisms, usually ``self.category()``
|
|
750
|
+
|
|
751
|
+
EXAMPLES::
|
|
752
|
+
|
|
753
|
+
sage: Fq = GF(25)
|
|
754
|
+
sage: A.<T> = Fq[]
|
|
755
|
+
sage: K.<z12> = Fq.extension(6)
|
|
756
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
757
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
758
|
+
sage: t = phi.ore_polring().gen()
|
|
759
|
+
sage: isog = t + 2*z12^11 + 4*z12^9 + 2*z12^8 + 2*z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + 4*z12^2 + 4*z12 + 4
|
|
760
|
+
sage: psi = phi.velu(isog)
|
|
761
|
+
sage: hom = phi._Hom_(psi, category=phi.category())
|
|
762
|
+
sage: hom is Hom(phi, psi) # known bug
|
|
763
|
+
True
|
|
764
|
+
sage: from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset
|
|
765
|
+
sage: isinstance(hom, DrinfeldModuleHomset)
|
|
766
|
+
True
|
|
767
|
+
"""
|
|
768
|
+
from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset
|
|
769
|
+
return DrinfeldModuleHomset(self, other, category)
|
|
770
|
+
|
|
771
|
+
def _latex_(self):
|
|
772
|
+
r"""
|
|
773
|
+
Return a LaTeX representation of the Drinfeld module.
|
|
774
|
+
|
|
775
|
+
If a representation name is given with meth:`rename`, it is
|
|
776
|
+
taken into account for LaTeX representation.
|
|
777
|
+
|
|
778
|
+
EXAMPLES::
|
|
779
|
+
|
|
780
|
+
sage: Fq = GF(25)
|
|
781
|
+
sage: A.<T> = Fq[]
|
|
782
|
+
sage: K.<z12> = Fq.extension(6)
|
|
783
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
784
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
785
|
+
sage: latex(phi)
|
|
786
|
+
\phi: T \mapsto z_{12}^{5} t^{2} + z_{12}^{3} t + 2 z_{12}^{11} + 2 z_{12}^{10} + z_{12}^{9} + 3 z_{12}^{8} + z_{12}^{7} + 2 z_{12}^{5} + 2 z_{12}^{4} + 3 z_{12}^{3} + z_{12}^{2} + 2 z_{12}
|
|
787
|
+
|
|
788
|
+
::
|
|
789
|
+
|
|
790
|
+
sage: phi.rename('phi')
|
|
791
|
+
sage: latex(phi)
|
|
792
|
+
\phi
|
|
793
|
+
sage: phi.reset_name()
|
|
794
|
+
"""
|
|
795
|
+
if self.get_custom_name() is not None:
|
|
796
|
+
return latex_variable_name(self.get_custom_name())
|
|
797
|
+
else:
|
|
798
|
+
return f'\\phi: {latex(self._function_ring.gen())} \\mapsto ' \
|
|
799
|
+
f'{latex(self._gen)}'
|
|
800
|
+
|
|
801
|
+
def _repr_(self):
|
|
802
|
+
r"""
|
|
803
|
+
Return a string representation of this Drinfeld module.
|
|
804
|
+
|
|
805
|
+
EXAMPLES::
|
|
806
|
+
|
|
807
|
+
sage: Fq = GF(25)
|
|
808
|
+
sage: A.<T> = Fq[]
|
|
809
|
+
sage: K.<z12> = Fq.extension(6)
|
|
810
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
811
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
812
|
+
sage: phi
|
|
813
|
+
Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
814
|
+
"""
|
|
815
|
+
return f'Drinfeld module defined by {self._function_ring.gen()} ' \
|
|
816
|
+
f'|--> {self._gen}'
|
|
817
|
+
|
|
818
|
+
def _test_category(self, **options):
|
|
819
|
+
"""
|
|
820
|
+
Run generic tests on the method :meth:`.category`.
|
|
821
|
+
|
|
822
|
+
EXAMPLES::
|
|
823
|
+
|
|
824
|
+
sage: Fq = GF(25)
|
|
825
|
+
sage: A.<T> = Fq[]
|
|
826
|
+
sage: K.<z12> = Fq.extension(6)
|
|
827
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
828
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
829
|
+
sage: phi._test_category()
|
|
830
|
+
|
|
831
|
+
.. NOTE::
|
|
832
|
+
|
|
833
|
+
We reimplemented this method because Drinfeld modules are
|
|
834
|
+
parents, and
|
|
835
|
+
meth:`sage.structure.parent.Parent._test_category` requires
|
|
836
|
+
parents' categories to be subcategories of ``Sets()``.
|
|
837
|
+
"""
|
|
838
|
+
tester = self._tester(**options)
|
|
839
|
+
SageObject._test_category(self, tester=tester)
|
|
840
|
+
category = self.category()
|
|
841
|
+
# Tests that self inherits methods from the categories
|
|
842
|
+
tester.assertTrue(isinstance(self, category.parent_class),
|
|
843
|
+
_LazyString("category of %s improperly initialized", (self,), {}))
|
|
844
|
+
|
|
845
|
+
def __hash__(self):
|
|
846
|
+
r"""
|
|
847
|
+
Return a hash of ``self``.
|
|
848
|
+
|
|
849
|
+
EXAMPLES::
|
|
850
|
+
|
|
851
|
+
sage: Fq = GF(25)
|
|
852
|
+
sage: A.<T> = Fq[]
|
|
853
|
+
sage: K.<z12> = Fq.extension(6)
|
|
854
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
855
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
856
|
+
sage: hash(phi) # random
|
|
857
|
+
-6894299335185957188
|
|
858
|
+
"""
|
|
859
|
+
return hash((self.base(), self._gen))
|
|
860
|
+
|
|
861
|
+
def action(self):
|
|
862
|
+
r"""
|
|
863
|
+
Return the action object
|
|
864
|
+
(:class:`sage.rings.function_field.drinfeld_modules.action.Action`)
|
|
865
|
+
that represents the module action, on the base codomain, that is
|
|
866
|
+
induced by the Drinfeld module.
|
|
867
|
+
|
|
868
|
+
OUTPUT: a Drinfeld module action object
|
|
869
|
+
|
|
870
|
+
EXAMPLES::
|
|
871
|
+
|
|
872
|
+
sage: Fq = GF(25)
|
|
873
|
+
sage: A.<T> = Fq[]
|
|
874
|
+
sage: K.<z12> = Fq.extension(6)
|
|
875
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
876
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
877
|
+
sage: action = phi.action()
|
|
878
|
+
sage: action
|
|
879
|
+
Action on Finite Field in z12 of size 5^12 over its base
|
|
880
|
+
induced by Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11
|
|
881
|
+
+ 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
882
|
+
|
|
883
|
+
The action on elements is computed as follows::
|
|
884
|
+
|
|
885
|
+
sage: P = T^2 + T + 1
|
|
886
|
+
sage: a = z12 + 1
|
|
887
|
+
sage: action(P, a)
|
|
888
|
+
3*z12^11 + 2*z12^10 + 3*z12^9 + 3*z12^7 + 4*z12^5 + z12^4 + z12^3 + 2*z12 + 1
|
|
889
|
+
sage: action(0, a)
|
|
890
|
+
0
|
|
891
|
+
sage: action(P, 0)
|
|
892
|
+
0
|
|
893
|
+
"""
|
|
894
|
+
from sage.rings.function_field.drinfeld_modules.action import DrinfeldModuleAction
|
|
895
|
+
return DrinfeldModuleAction(self)
|
|
896
|
+
|
|
897
|
+
def basic_j_invariant_parameters(self, coeff_indices=None, nonzero=False):
|
|
898
|
+
r"""
|
|
899
|
+
Return the list of basic `j`-invariant parameters.
|
|
900
|
+
|
|
901
|
+
See the method :meth:`j_invariant` for definitions.
|
|
902
|
+
|
|
903
|
+
INPUT:
|
|
904
|
+
|
|
905
|
+
- ``coeff_indices`` -- list or tuple, or NoneType (default:
|
|
906
|
+
``None``); indices of the Drinfeld module generator
|
|
907
|
+
coefficients to be considered in the computation. If the
|
|
908
|
+
parameter is ``None`` (default), all the coefficients are
|
|
909
|
+
involved.
|
|
910
|
+
|
|
911
|
+
- ``nonzero``-- boolean (default: ``False``); if this flag
|
|
912
|
+
is set to ``True``, then only the parameters for which the
|
|
913
|
+
corresponding basic `j`-invariant is nonzero are returned
|
|
914
|
+
|
|
915
|
+
.. WARNING::
|
|
916
|
+
|
|
917
|
+
The usage of this method can be computationally
|
|
918
|
+
expensive e.g. if the rank is greater than four,
|
|
919
|
+
or if `q` is large. Setting the ``nonzero`` flag to ``True``
|
|
920
|
+
can speed up the computation considerably if the Drinfeld
|
|
921
|
+
module generator possesses multiple zero coefficients.
|
|
922
|
+
|
|
923
|
+
EXAMPLES::
|
|
924
|
+
|
|
925
|
+
sage: A = GF(5)['T']
|
|
926
|
+
sage: K.<T> = Frac(A)
|
|
927
|
+
sage: phi = DrinfeldModule(A, [T, 0, T+1, T^2 + 1])
|
|
928
|
+
sage: phi.basic_j_invariant_parameters() # needs sage.geometry.polyhedron
|
|
929
|
+
[((1,), (31, 1)),
|
|
930
|
+
((1, 2), (1, 5, 1)),
|
|
931
|
+
((1, 2), (7, 4, 1)),
|
|
932
|
+
((1, 2), (8, 9, 2)),
|
|
933
|
+
((1, 2), (9, 14, 3)),
|
|
934
|
+
((1, 2), (10, 19, 4)),
|
|
935
|
+
((1, 2), (11, 24, 5)),
|
|
936
|
+
((1, 2), (12, 29, 6)),
|
|
937
|
+
((1, 2), (13, 3, 1)),
|
|
938
|
+
((1, 2), (15, 13, 3)),
|
|
939
|
+
((1, 2), (17, 23, 5)),
|
|
940
|
+
((1, 2), (19, 2, 1)),
|
|
941
|
+
((1, 2), (20, 7, 2)),
|
|
942
|
+
((1, 2), (22, 17, 4)),
|
|
943
|
+
((1, 2), (23, 22, 5)),
|
|
944
|
+
((1, 2), (25, 1, 1)),
|
|
945
|
+
((1, 2), (27, 11, 3)),
|
|
946
|
+
((1, 2), (29, 21, 5)),
|
|
947
|
+
((1, 2), (31, 31, 7)),
|
|
948
|
+
((2,), (31, 6))]
|
|
949
|
+
|
|
950
|
+
Use the ``nonzero=True`` flag to display only the parameters
|
|
951
|
+
whose `j`-invariant value is nonzero::
|
|
952
|
+
|
|
953
|
+
sage: phi.basic_j_invariant_parameters(nonzero=True) # needs sage.geometry.polyhedron
|
|
954
|
+
[((2,), (31, 6))]
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
One can specify the list of coefficients indices to be
|
|
958
|
+
considered in the computation::
|
|
959
|
+
|
|
960
|
+
sage: A = GF(2)['T']
|
|
961
|
+
sage: K.<T> = Frac(A)
|
|
962
|
+
sage: phi = DrinfeldModule(A, [T, T, 1, T])
|
|
963
|
+
sage: phi.basic_j_invariant_parameters([1, 2]) # needs sage.geometry.polyhedron
|
|
964
|
+
[((1,), (7, 1)),
|
|
965
|
+
((1, 2), (1, 2, 1)),
|
|
966
|
+
((1, 2), (4, 1, 1)),
|
|
967
|
+
((1, 2), (5, 3, 2)),
|
|
968
|
+
((1, 2), (6, 5, 3)),
|
|
969
|
+
((1, 2), (7, 7, 4)),
|
|
970
|
+
((2,), (7, 3))]
|
|
971
|
+
|
|
972
|
+
TESTS::
|
|
973
|
+
|
|
974
|
+
sage: A = GF(5)['T']
|
|
975
|
+
sage: K.<T> = Frac(A)
|
|
976
|
+
sage: phi = DrinfeldModule(A, [T, 0, T+1, T^2 + 1])
|
|
977
|
+
sage: phi.basic_j_invariant_parameters([1, 'x']) # needs sage.geometry.polyhedron
|
|
978
|
+
Traceback (most recent call last):
|
|
979
|
+
...
|
|
980
|
+
TypeError: coefficients indices must be integers
|
|
981
|
+
|
|
982
|
+
::
|
|
983
|
+
|
|
984
|
+
sage: phi.basic_j_invariant_parameters([1, 10]) # needs sage.geometry.polyhedron
|
|
985
|
+
Traceback (most recent call last):
|
|
986
|
+
...
|
|
987
|
+
ValueError: indices must be > 0 and < 3
|
|
988
|
+
|
|
989
|
+
::
|
|
990
|
+
|
|
991
|
+
sage: phi.basic_j_invariant_parameters([1, 1]) # needs sage.geometry.polyhedron
|
|
992
|
+
Traceback (most recent call last):
|
|
993
|
+
...
|
|
994
|
+
ValueError: indices must be distinct and sorted
|
|
995
|
+
|
|
996
|
+
::
|
|
997
|
+
|
|
998
|
+
sage: phi.basic_j_invariant_parameters([2, 1]) # needs sage.geometry.polyhedron
|
|
999
|
+
Traceback (most recent call last):
|
|
1000
|
+
...
|
|
1001
|
+
ValueError: indices must be distinct and sorted
|
|
1002
|
+
|
|
1003
|
+
::
|
|
1004
|
+
|
|
1005
|
+
sage: phi.basic_j_invariant_parameters('x') # needs sage.geometry.polyhedron
|
|
1006
|
+
Traceback (most recent call last):
|
|
1007
|
+
...
|
|
1008
|
+
TypeError: indices must be None, a tuple or a list
|
|
1009
|
+
"""
|
|
1010
|
+
r = self._gen.degree()
|
|
1011
|
+
if coeff_indices is None:
|
|
1012
|
+
if nonzero:
|
|
1013
|
+
coeff_indices = [k for k, g in enumerate(
|
|
1014
|
+
self.coefficients(sparse=False)[1:-1], start=1) if g]
|
|
1015
|
+
else:
|
|
1016
|
+
coeff_indices = list(range(1, r))
|
|
1017
|
+
# Check if coeff_indices is valid:
|
|
1018
|
+
elif isinstance(coeff_indices, (tuple, list)):
|
|
1019
|
+
coeff_indices = list(coeff_indices)
|
|
1020
|
+
if not all(isinstance(k, (int, Integer)) for k in coeff_indices):
|
|
1021
|
+
raise TypeError('coefficients indices must be integers')
|
|
1022
|
+
if max(coeff_indices) >= r or min(coeff_indices) <= 0:
|
|
1023
|
+
raise ValueError(f'indices must be > 0 and < {r}')
|
|
1024
|
+
if not all(coeff_indices[i] < coeff_indices[i+1] for i in
|
|
1025
|
+
range(len(coeff_indices) - 1)):
|
|
1026
|
+
raise ValueError('indices must be distinct and sorted')
|
|
1027
|
+
if nonzero:
|
|
1028
|
+
coeff_indices = [k for k in coeff_indices if self._gen[k]]
|
|
1029
|
+
else:
|
|
1030
|
+
raise TypeError('indices must be None, a tuple or a list')
|
|
1031
|
+
# Create the equation and inequalities for the polyhedron:
|
|
1032
|
+
q = self._Fq.order()
|
|
1033
|
+
equation = [0]
|
|
1034
|
+
inequalities = []
|
|
1035
|
+
# Create the equation:
|
|
1036
|
+
# d_1 (q - 1) + ... + d_{r-1} (q^{r-1} - 1)
|
|
1037
|
+
# = d_r (q^r - 1)
|
|
1038
|
+
for idx, i in enumerate(coeff_indices):
|
|
1039
|
+
equation.append(q**i - 1)
|
|
1040
|
+
# Create inequalities of the form 0 <= delta_i
|
|
1041
|
+
lower_bounds = [0] * (len(coeff_indices) + 2)
|
|
1042
|
+
lower_bounds[idx + 1] = 1
|
|
1043
|
+
# Create inequalities of the form
|
|
1044
|
+
# delta_i <= (q^r - 1)/(q^{gcd(i,r)} - 1)
|
|
1045
|
+
upper_bounds = [Integer((q**r - 1) / (q**(gcd(i, r)) - 1))]\
|
|
1046
|
+
+ [0]*(len(coeff_indices) + 1)
|
|
1047
|
+
upper_bounds[idx + 1] = -1
|
|
1048
|
+
inequalities.extend((lower_bounds, upper_bounds))
|
|
1049
|
+
equation.append(1 - q**r)
|
|
1050
|
+
# Create the polyhedron defined by the equation and the
|
|
1051
|
+
# inequalities.
|
|
1052
|
+
polyhedron = Polyhedron(ieqs=inequalities, eqns=[equation])
|
|
1053
|
+
# Compute its integral points
|
|
1054
|
+
integral_points = polyhedron.integral_points()
|
|
1055
|
+
# Format the result
|
|
1056
|
+
parameters = []
|
|
1057
|
+
for p in integral_points:
|
|
1058
|
+
if gcd(p) != 1:
|
|
1059
|
+
continue
|
|
1060
|
+
ks = list(coeff_indices)
|
|
1061
|
+
ds = p.list()
|
|
1062
|
+
i = 0
|
|
1063
|
+
while i < len(ks):
|
|
1064
|
+
if ds[i] == 0:
|
|
1065
|
+
del ds[i]
|
|
1066
|
+
del ks[i]
|
|
1067
|
+
else:
|
|
1068
|
+
i += 1
|
|
1069
|
+
parameters.append((tuple(ks), tuple(ds)))
|
|
1070
|
+
parameters.sort()
|
|
1071
|
+
return parameters
|
|
1072
|
+
|
|
1073
|
+
def basic_j_invariants(self, nonzero=False):
|
|
1074
|
+
r"""
|
|
1075
|
+
Return a dictionary whose keys are all the basic `j`-invariants
|
|
1076
|
+
parameters and values are the corresponding `j`-invariant.
|
|
1077
|
+
|
|
1078
|
+
See the method :meth:`j_invariant` for definitions.
|
|
1079
|
+
|
|
1080
|
+
INPUT:
|
|
1081
|
+
|
|
1082
|
+
- ``nonzero``-- boolean (default: ``False``); if this flag
|
|
1083
|
+
is set to ``True``, then only the parameters for which the
|
|
1084
|
+
corresponding basic `j`-invariant is nonzero are returned
|
|
1085
|
+
|
|
1086
|
+
.. WARNING::
|
|
1087
|
+
|
|
1088
|
+
The usage of this method can be computationally
|
|
1089
|
+
expensive e.g. if the rank is greater than four,
|
|
1090
|
+
or if `q` is large. Setting the ``nonzero`` flag to ``True``
|
|
1091
|
+
can speed up the computation considerably if the Drinfeld
|
|
1092
|
+
module generator possesses multiple zero coefficients.
|
|
1093
|
+
|
|
1094
|
+
EXAMPLES::
|
|
1095
|
+
|
|
1096
|
+
sage: Fq = GF(25)
|
|
1097
|
+
sage: A.<T> = Fq[]
|
|
1098
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1099
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1100
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1101
|
+
sage: phi.basic_j_invariants() # needs sage.geometry.polyhedron
|
|
1102
|
+
{((1,), (26, 1)): z12^10 + 4*z12^9 + 3*z12^8 + 2*z12^7 + 3*z12^6 + z12^5 + z12^3 + 4*z12^2 + z12 + 2}
|
|
1103
|
+
|
|
1104
|
+
::
|
|
1105
|
+
|
|
1106
|
+
sage: phi = DrinfeldModule(A, [p_root, 0, 1, z12])
|
|
1107
|
+
sage: phi.basic_j_invariants(nonzero=True) # needs sage.geometry.polyhedron
|
|
1108
|
+
{((2,), (651, 26)): z12^11 + 3*z12^10 + 4*z12^9 + 3*z12^8 + z12^7 + 2*z12^6 + 3*z12^4 + 2*z12^3 + z12^2 + 4*z12}
|
|
1109
|
+
|
|
1110
|
+
::
|
|
1111
|
+
|
|
1112
|
+
sage: A = GF(5)['T']
|
|
1113
|
+
sage: K.<T> = Frac(A)
|
|
1114
|
+
sage: phi = DrinfeldModule(A, [T, T + 2, T+1, 1])
|
|
1115
|
+
sage: J_phi = phi.basic_j_invariants(); J_phi # needs sage.geometry.polyhedron
|
|
1116
|
+
{((1,), (31, 1)): T^31 + 2*T^30 + 2*T^26 + 4*T^25 + 2*T^6 + 4*T^5 + 4*T + 3,
|
|
1117
|
+
((1, 2), (1, 5, 1)): T^6 + 2*T^5 + T + 2,
|
|
1118
|
+
((1, 2), (7, 4, 1)): T^11 + 3*T^10 + T^9 + 4*T^8 + T^7 + 2*T^6 + 2*T^4 + 3*T^3 + 2*T^2 + 3,
|
|
1119
|
+
((1, 2), (8, 9, 2)): T^17 + 2*T^15 + T^14 + 4*T^13 + 4*T^11 + 4*T^10 + 3*T^9 + 2*T^8 + 3*T^7 + 2*T^6 + 3*T^5 + 2*T^4 + 3*T^3 + 4*T^2 + 3*T + 1,
|
|
1120
|
+
((1, 2), (9, 14, 3)): T^23 + 2*T^22 + 2*T^21 + T^19 + 4*T^18 + T^17 + 4*T^16 + T^15 + 4*T^14 + 2*T^12 + 4*T^11 + 4*T^10 + 2*T^8 + 4*T^7 + 4*T^6 + 2*T^4 + T^2 + 2*T + 2,
|
|
1121
|
+
((1, 2), (10, 19, 4)): T^29 + 4*T^28 + T^27 + 4*T^26 + T^25 + 2*T^24 + 3*T^23 + 2*T^22 + 3*T^21 + 2*T^20 + 4*T^19 + T^18 + 4*T^17 + T^16 + 4*T^15 + T^9 + 4*T^8 + T^7 + 4*T^6 + T^5 + 4*T^4 + T^3 + 4*T^2 + T + 4,
|
|
1122
|
+
...
|
|
1123
|
+
((2,), (31, 6)): T^31 + T^30 + T^26 + T^25 + T^6 + T^5 + T + 1}
|
|
1124
|
+
sage: J_phi[((1, 2), (7, 4, 1))] # needs sage.geometry.polyhedron
|
|
1125
|
+
T^11 + 3*T^10 + T^9 + 4*T^8 + T^7 + 2*T^6 + 2*T^4 + 3*T^3 + 2*T^2 + 3
|
|
1126
|
+
"""
|
|
1127
|
+
return {parameter: self.j_invariant(parameter, check=False)
|
|
1128
|
+
for parameter in self.basic_j_invariant_parameters(nonzero=nonzero)}
|
|
1129
|
+
|
|
1130
|
+
def coefficient(self, n):
|
|
1131
|
+
r"""
|
|
1132
|
+
Return the `n`-th coefficient of the generator.
|
|
1133
|
+
|
|
1134
|
+
INPUT:
|
|
1135
|
+
|
|
1136
|
+
- ``n`` -- nonnegative integer
|
|
1137
|
+
|
|
1138
|
+
OUTPUT: an element in the base codomain
|
|
1139
|
+
|
|
1140
|
+
EXAMPLES::
|
|
1141
|
+
|
|
1142
|
+
sage: Fq = GF(25)
|
|
1143
|
+
sage: A.<T> = Fq[]
|
|
1144
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1145
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1146
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1147
|
+
sage: phi.coefficient(0)
|
|
1148
|
+
2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5
|
|
1149
|
+
+ 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1150
|
+
sage: phi.coefficient(0) == p_root
|
|
1151
|
+
True
|
|
1152
|
+
sage: phi.coefficient(1)
|
|
1153
|
+
z12^3
|
|
1154
|
+
sage: phi.coefficient(2)
|
|
1155
|
+
z12^5
|
|
1156
|
+
sage: phi.coefficient(5)
|
|
1157
|
+
Traceback (most recent call last):
|
|
1158
|
+
...
|
|
1159
|
+
ValueError: input must be >= 0 and <= rank
|
|
1160
|
+
"""
|
|
1161
|
+
n = Integer(n)
|
|
1162
|
+
if not 0 <= n <= self.rank():
|
|
1163
|
+
raise ValueError('input must be >= 0 and <= rank')
|
|
1164
|
+
return self.coefficients(sparse=False)[n]
|
|
1165
|
+
|
|
1166
|
+
def coefficients(self, sparse=True):
|
|
1167
|
+
r"""
|
|
1168
|
+
Return the coefficients of the generator, as a list.
|
|
1169
|
+
|
|
1170
|
+
If the flag ``sparse`` is ``True`` (default), only return the
|
|
1171
|
+
nonzero coefficients; otherwise, return all of them.
|
|
1172
|
+
|
|
1173
|
+
INPUT:
|
|
1174
|
+
|
|
1175
|
+
- ``sparse`` -- boolean
|
|
1176
|
+
|
|
1177
|
+
EXAMPLES::
|
|
1178
|
+
|
|
1179
|
+
sage: Fq = GF(25)
|
|
1180
|
+
sage: A.<T> = Fq[]
|
|
1181
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1182
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1183
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1184
|
+
sage: phi.coefficients()
|
|
1185
|
+
[2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7
|
|
1186
|
+
+ 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12,
|
|
1187
|
+
z12^3,
|
|
1188
|
+
z12^5]
|
|
1189
|
+
|
|
1190
|
+
Careful, the method only returns the nonzero coefficients,
|
|
1191
|
+
unless otherwise specified::
|
|
1192
|
+
|
|
1193
|
+
sage: rho = DrinfeldModule(A, [p_root, 0, 0, 0, 1])
|
|
1194
|
+
sage: rho.coefficients()
|
|
1195
|
+
[2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7
|
|
1196
|
+
+ 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12,
|
|
1197
|
+
1]
|
|
1198
|
+
sage: rho.coefficients(sparse=False)
|
|
1199
|
+
[2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7
|
|
1200
|
+
+ 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12,
|
|
1201
|
+
0,
|
|
1202
|
+
0,
|
|
1203
|
+
0,
|
|
1204
|
+
1]
|
|
1205
|
+
"""
|
|
1206
|
+
return self._gen.coefficients(sparse=sparse)
|
|
1207
|
+
|
|
1208
|
+
def gen(self):
|
|
1209
|
+
r"""
|
|
1210
|
+
Return the generator of the Drinfeld module.
|
|
1211
|
+
|
|
1212
|
+
EXAMPLES::
|
|
1213
|
+
|
|
1214
|
+
sage: Fq = GF(25)
|
|
1215
|
+
sage: A.<T> = Fq[]
|
|
1216
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1217
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1218
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1219
|
+
sage: phi.gen() == phi(T)
|
|
1220
|
+
True
|
|
1221
|
+
"""
|
|
1222
|
+
return self._gen
|
|
1223
|
+
|
|
1224
|
+
def height(self):
|
|
1225
|
+
r"""
|
|
1226
|
+
Return the height of the Drinfeld module if the function field
|
|
1227
|
+
characteristic is a prime ideal; raise :exc:`ValueError` otherwise.
|
|
1228
|
+
|
|
1229
|
+
The height of a Drinfeld module is defined when the function
|
|
1230
|
+
field characteristic is a prime ideal. In our case, this ideal
|
|
1231
|
+
is even generated by a monic polynomial `\mathfrak{p}` in the
|
|
1232
|
+
function field. Write `\phi_\mathfrak{p} = a_s \tau^s + \dots +
|
|
1233
|
+
\tau^{r*\deg(\mathfrak{p})}`. The height of the Drinfeld module
|
|
1234
|
+
is the well-defined positive integer `h =
|
|
1235
|
+
\frac{s}{\deg(\mathfrak{p})}`.
|
|
1236
|
+
|
|
1237
|
+
.. NOTE::
|
|
1238
|
+
|
|
1239
|
+
See [Gos1998]_, Definition 4.5.8 for the general definition.
|
|
1240
|
+
|
|
1241
|
+
EXAMPLES::
|
|
1242
|
+
|
|
1243
|
+
sage: Fq = GF(25)
|
|
1244
|
+
sage: A.<T> = Fq[]
|
|
1245
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1246
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1247
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1248
|
+
sage: phi.height() == 1
|
|
1249
|
+
True
|
|
1250
|
+
sage: phi.is_ordinary()
|
|
1251
|
+
True
|
|
1252
|
+
|
|
1253
|
+
::
|
|
1254
|
+
|
|
1255
|
+
sage: Fq = GF(343)
|
|
1256
|
+
sage: A.<T> = Fq[]
|
|
1257
|
+
sage: K.<z6> = Fq.extension(2)
|
|
1258
|
+
sage: phi = DrinfeldModule(A, [1, 0, z6])
|
|
1259
|
+
sage: phi.height()
|
|
1260
|
+
2
|
|
1261
|
+
sage: phi.is_supersingular()
|
|
1262
|
+
True
|
|
1263
|
+
|
|
1264
|
+
In characteristic zero, height is not defined::
|
|
1265
|
+
|
|
1266
|
+
sage: L = A.fraction_field()
|
|
1267
|
+
sage: phi = DrinfeldModule(A, [L(T), L(1)])
|
|
1268
|
+
sage: phi.height()
|
|
1269
|
+
Traceback (most recent call last):
|
|
1270
|
+
...
|
|
1271
|
+
ValueError: height is only defined for prime function field characteristic
|
|
1272
|
+
|
|
1273
|
+
TESTS:
|
|
1274
|
+
|
|
1275
|
+
In the following case, sage is unable to determine the
|
|
1276
|
+
characteristic; that is why an error is raised::
|
|
1277
|
+
|
|
1278
|
+
sage: B.<Y> = Fq[]
|
|
1279
|
+
sage: L = Frac(B)
|
|
1280
|
+
sage: phi = DrinfeldModule(A, [L(2), L(1)])
|
|
1281
|
+
sage: phi.height()
|
|
1282
|
+
Traceback (most recent call last):
|
|
1283
|
+
...
|
|
1284
|
+
NotImplementedError: height not implemented in this case
|
|
1285
|
+
"""
|
|
1286
|
+
try:
|
|
1287
|
+
if self.characteristic().is_zero():
|
|
1288
|
+
raise ValueError('height is only defined for prime '
|
|
1289
|
+
'function field characteristic')
|
|
1290
|
+
else:
|
|
1291
|
+
p = self.characteristic()
|
|
1292
|
+
return Integer(self(p).valuation() // p.degree())
|
|
1293
|
+
except NotImplementedError:
|
|
1294
|
+
raise NotImplementedError('height not implemented in this case')
|
|
1295
|
+
|
|
1296
|
+
def is_isomorphic(self, other, absolutely=False):
|
|
1297
|
+
r"""
|
|
1298
|
+
Return ``True`` if this Drinfeld module is isomorphic to ``other``;
|
|
1299
|
+
return ``False`` otherwise.
|
|
1300
|
+
|
|
1301
|
+
INPUT:
|
|
1302
|
+
|
|
1303
|
+
- ``absolutely`` -- a boolean (default: ``False``); if ``False``,
|
|
1304
|
+
check the existence of an isomorphism defined on the base
|
|
1305
|
+
field. If ``True``, check over an algebraic closure.
|
|
1306
|
+
|
|
1307
|
+
EXAMPLES::
|
|
1308
|
+
|
|
1309
|
+
sage: Fq = GF(5)
|
|
1310
|
+
sage: A.<T> = Fq[]
|
|
1311
|
+
sage: K.<z> = Fq.extension(3)
|
|
1312
|
+
sage: phi = DrinfeldModule(A, [z, 0, 1, z])
|
|
1313
|
+
sage: t = phi.ore_variable()
|
|
1314
|
+
|
|
1315
|
+
We create a second Drinfeld module, which is isomorphic to `\phi`
|
|
1316
|
+
and then check that they are indeed isomorphic::
|
|
1317
|
+
|
|
1318
|
+
sage: psi = phi.velu(z)
|
|
1319
|
+
sage: phi.is_isomorphic(psi)
|
|
1320
|
+
True
|
|
1321
|
+
|
|
1322
|
+
In the example below, `\phi` and `\psi` are isogenous but not
|
|
1323
|
+
isomorphic::
|
|
1324
|
+
|
|
1325
|
+
sage: psi = phi.velu(t + 1)
|
|
1326
|
+
sage: phi.is_isomorphic(psi)
|
|
1327
|
+
False
|
|
1328
|
+
|
|
1329
|
+
Here is an example of two Drinfeld modules which are isomorphic
|
|
1330
|
+
on an algebraic closure but not on the base field::
|
|
1331
|
+
|
|
1332
|
+
sage: phi = DrinfeldModule(A, [z, 1])
|
|
1333
|
+
sage: psi = DrinfeldModule(A, [z, z])
|
|
1334
|
+
sage: phi.is_isomorphic(psi)
|
|
1335
|
+
False
|
|
1336
|
+
sage: phi.is_isomorphic(psi, absolutely=True)
|
|
1337
|
+
True
|
|
1338
|
+
|
|
1339
|
+
In particular, two Drinfeld modules may have the same
|
|
1340
|
+
`j`-invariant, while not being isomorphic on the base field::
|
|
1341
|
+
|
|
1342
|
+
sage: phi = DrinfeldModule(A, [z, 0, 1])
|
|
1343
|
+
sage: psi = DrinfeldModule(A, [z, 0, z])
|
|
1344
|
+
sage: phi.j_invariant() == psi.j_invariant()
|
|
1345
|
+
True
|
|
1346
|
+
sage: phi.is_isomorphic(psi)
|
|
1347
|
+
False
|
|
1348
|
+
sage: phi.is_isomorphic(psi, absolutely=True)
|
|
1349
|
+
True
|
|
1350
|
+
|
|
1351
|
+
On certain fields, testing isomorphisms over the base field may
|
|
1352
|
+
fail::
|
|
1353
|
+
|
|
1354
|
+
sage: L = A.fraction_field()
|
|
1355
|
+
sage: T = L.gen()
|
|
1356
|
+
sage: phi = DrinfeldModule(A, [T, 0, 1])
|
|
1357
|
+
sage: psi = DrinfeldModule(A, [T, 0, T])
|
|
1358
|
+
sage: psi.is_isomorphic(phi)
|
|
1359
|
+
Traceback (most recent call last):
|
|
1360
|
+
...
|
|
1361
|
+
NotImplementedError: cannot solve the equation u^24 == T
|
|
1362
|
+
|
|
1363
|
+
However, it never fails over the algebraic closure::
|
|
1364
|
+
|
|
1365
|
+
sage: psi.is_isomorphic(phi, absolutely=True)
|
|
1366
|
+
True
|
|
1367
|
+
|
|
1368
|
+
Note finally that when the constant coefficients of `\phi_T` and
|
|
1369
|
+
`\psi_T` differ, `\phi` and `\psi` do not belong to the same category
|
|
1370
|
+
and checking whether they are isomorphic does not make sense; in this
|
|
1371
|
+
case, an error is raised::
|
|
1372
|
+
|
|
1373
|
+
sage: phi = DrinfeldModule(A, [z, 0, 1])
|
|
1374
|
+
sage: psi = DrinfeldModule(A, [z^2, 0, 1])
|
|
1375
|
+
sage: phi.is_isomorphic(psi)
|
|
1376
|
+
Traceback (most recent call last):
|
|
1377
|
+
...
|
|
1378
|
+
ValueError: Drinfeld modules are not in the same category
|
|
1379
|
+
|
|
1380
|
+
TESTS:
|
|
1381
|
+
|
|
1382
|
+
A Drinfeld module is always isomorphic to itself::
|
|
1383
|
+
|
|
1384
|
+
sage: phi = DrinfeldModule(A, [z] + [K.random_element() for _ in range(3)] + [1])
|
|
1385
|
+
sage: phi.is_isomorphic(phi)
|
|
1386
|
+
True
|
|
1387
|
+
|
|
1388
|
+
Two Drinfeld modules of different ranks are never isomorphic::
|
|
1389
|
+
|
|
1390
|
+
sage: psi = DrinfeldModule(A, [z] + [K.random_element() for _ in range(5)] + [1])
|
|
1391
|
+
sage: phi.is_isomorphic(psi)
|
|
1392
|
+
False
|
|
1393
|
+
|
|
1394
|
+
Two Drinfeld modules which are not patterned-alike are also not
|
|
1395
|
+
isomorphic::
|
|
1396
|
+
|
|
1397
|
+
sage: phi = DrinfeldModule(A, [T, 1, 0, 1])
|
|
1398
|
+
sage: psi = DrinfeldModule(A, [T, 1, 1, 1])
|
|
1399
|
+
sage: phi.is_isomorphic(psi)
|
|
1400
|
+
False
|
|
1401
|
+
"""
|
|
1402
|
+
# Trivial cases
|
|
1403
|
+
if self.category() is not other.category():
|
|
1404
|
+
raise ValueError("Drinfeld modules are not in the same category")
|
|
1405
|
+
if self is other:
|
|
1406
|
+
return True
|
|
1407
|
+
r = self.rank()
|
|
1408
|
+
if other.rank() != r:
|
|
1409
|
+
return False
|
|
1410
|
+
# Check if there exists u such that u*self_X = other_X*u:
|
|
1411
|
+
# if self_X = a_0 + a_1*t + ... + a_r*t^r
|
|
1412
|
+
# and other_x = b_0 + b_1*t + ... + b_r*t^r
|
|
1413
|
+
# this reduces to find a solution of the system:
|
|
1414
|
+
# b_i * u^(q^i - 1) = a_i (0 <= i <= r)
|
|
1415
|
+
# which, using gcds, can be reduced to a unique equation
|
|
1416
|
+
# of the form u^e = ue.
|
|
1417
|
+
q = self._Fq.cardinality()
|
|
1418
|
+
A = self.gen()
|
|
1419
|
+
B = other.gen()
|
|
1420
|
+
e = Integer(0)
|
|
1421
|
+
ue = self._base(1)
|
|
1422
|
+
for i in range(1, r+1):
|
|
1423
|
+
ai = A[i]
|
|
1424
|
+
bi = B[i]
|
|
1425
|
+
if ai == 0 and bi == 0:
|
|
1426
|
+
continue
|
|
1427
|
+
if ai == 0 or bi == 0:
|
|
1428
|
+
return False
|
|
1429
|
+
if e != q - 1:
|
|
1430
|
+
# u^e = ue
|
|
1431
|
+
# u^(q^i - 1) = ai/bi
|
|
1432
|
+
e, s, t = e.xgcd(q**i - 1)
|
|
1433
|
+
ue = ue**s * (ai/bi)**t
|
|
1434
|
+
for i in range(1, r+1):
|
|
1435
|
+
if A[i]:
|
|
1436
|
+
f = (q**i - 1) // e
|
|
1437
|
+
if A[i] != B[i] * ue**f:
|
|
1438
|
+
return False
|
|
1439
|
+
# Solve the equation u^e = ue
|
|
1440
|
+
# - when absolutely=True, over the algebraic closure (then a
|
|
1441
|
+
# solution always exists)
|
|
1442
|
+
# - when absolutely=False, over the ground field.
|
|
1443
|
+
if absolutely:
|
|
1444
|
+
return True
|
|
1445
|
+
else:
|
|
1446
|
+
ue = ue.backend(force=True)
|
|
1447
|
+
try:
|
|
1448
|
+
_ = ue.nth_root(e)
|
|
1449
|
+
except ValueError:
|
|
1450
|
+
return False
|
|
1451
|
+
except (AttributeError, NotImplementedError):
|
|
1452
|
+
raise NotImplementedError(f"cannot solve the equation u^{e} == {ue}")
|
|
1453
|
+
return True
|
|
1454
|
+
|
|
1455
|
+
def is_finite(self) -> bool:
|
|
1456
|
+
r"""
|
|
1457
|
+
Return ``True`` if this Drinfeld module is finite,
|
|
1458
|
+
``False`` otherwise.
|
|
1459
|
+
|
|
1460
|
+
EXAMPLES::
|
|
1461
|
+
|
|
1462
|
+
sage: Fq = GF(25)
|
|
1463
|
+
sage: A.<T> = Fq[]
|
|
1464
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1465
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1466
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1467
|
+
sage: phi.is_finite()
|
|
1468
|
+
True
|
|
1469
|
+
sage: B.<Y> = Fq[]
|
|
1470
|
+
sage: L = Frac(B)
|
|
1471
|
+
sage: psi = DrinfeldModule(A, [L(2), L(1)])
|
|
1472
|
+
sage: psi.is_finite()
|
|
1473
|
+
False
|
|
1474
|
+
"""
|
|
1475
|
+
from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite
|
|
1476
|
+
return isinstance(self, DrinfeldModule_finite)
|
|
1477
|
+
|
|
1478
|
+
def j_invariant(self, parameter=None, check=True):
|
|
1479
|
+
r"""
|
|
1480
|
+
Return the `j`-invariant of the Drinfeld
|
|
1481
|
+
`\mathbb{F}_q[T]`-module for the given parameter.
|
|
1482
|
+
|
|
1483
|
+
Suppose that `\phi_T = g_0 + g_1\tau + \cdots + g_r \tau^r` with
|
|
1484
|
+
`g_r \neq 0`. Then the
|
|
1485
|
+
`((k_1, \ldots, k_n), (d_1, \ldots, d_n, d_r))`-`j`-*invariant*
|
|
1486
|
+
of `\phi` is defined by
|
|
1487
|
+
|
|
1488
|
+
.. MATH::
|
|
1489
|
+
|
|
1490
|
+
j_{k_1, \ldots, k_n}^{d_1, \ldots, d_n, d_r}(\phi)
|
|
1491
|
+
:= \frac{1}{g_r^{d_r}}\prod_{i = 1}^n g_{k_i}^{d_i}
|
|
1492
|
+
|
|
1493
|
+
where `1\leqslant k_1 < k_2 < \ldots < k_n \leqslant r - 1` and
|
|
1494
|
+
the integers `d_i` satisfy the *weight-0 condition*:
|
|
1495
|
+
|
|
1496
|
+
.. MATH::
|
|
1497
|
+
|
|
1498
|
+
d_1 (q^{k_1} - 1) + d_2 (q^{k_2} - 1)
|
|
1499
|
+
+ \cdots + d_{n} (q^{k_n} - 1) = d_r (q^r - 1).
|
|
1500
|
+
|
|
1501
|
+
Furthermore, if `\gcd(d_1,\ldots, d_n, d_r) = 1` and
|
|
1502
|
+
|
|
1503
|
+
.. MATH::
|
|
1504
|
+
|
|
1505
|
+
0 \leq d_i \leq (q^r - 1)/(q^{\gcd(i, r)} - 1),
|
|
1506
|
+
\quad 1 \leq i \leq n,
|
|
1507
|
+
|
|
1508
|
+
then the `j`-invariant is called *basic*. See the method
|
|
1509
|
+
:meth:`basic_j_invariant_parameters` for computing the list of
|
|
1510
|
+
all basic `j`-invariant parameters.
|
|
1511
|
+
|
|
1512
|
+
.. NOTE::
|
|
1513
|
+
|
|
1514
|
+
In [Pap2023]_, Papikian follows a slightly different
|
|
1515
|
+
convention:
|
|
1516
|
+
|
|
1517
|
+
- His `j`-invariants (see Definition 3.8.7) correspond to
|
|
1518
|
+
our basic `j`-invariants, as defined above.
|
|
1519
|
+
- His *basic* `j`-invariant (see Example 3.8.10) correspond
|
|
1520
|
+
to our `j_k`-invariants, as implemented in
|
|
1521
|
+
:meth:`jk_invariants`.
|
|
1522
|
+
|
|
1523
|
+
We chose to follow Potemine's convention, as he introduced
|
|
1524
|
+
those objects in [Pot1998]_. Theorem 2.2 of [Pot1998]_ or
|
|
1525
|
+
Theorem 3.8.11 of [Pap2023]_ assert that two Drinfeld
|
|
1526
|
+
`\mathbb F_q[T]`-modules over `K` are isomorphic over the
|
|
1527
|
+
separable closure of `K` if and only if their basic
|
|
1528
|
+
`j`-invariants (as implemented here) coincide for any
|
|
1529
|
+
well-defined couple of tuples `((k_1, k_2, \ldots, k_n),
|
|
1530
|
+
(d_1, d_2, \ldots, d_n, d_r))`, .
|
|
1531
|
+
|
|
1532
|
+
INPUT:
|
|
1533
|
+
|
|
1534
|
+
- ``parameter`` -- tuple or list, integer or NoneType (default:
|
|
1535
|
+
``None``); the `j`-invariant parameter:
|
|
1536
|
+
|
|
1537
|
+
- If ``parameter`` is a list or a tuple, then it must be of
|
|
1538
|
+
the form:
|
|
1539
|
+
`((k_1, k_2, \ldots, k_n), (d_1, d_2, \ldots, d_n, d_r))`,
|
|
1540
|
+
where the `k_i` and `d_i` are integers satisfying the
|
|
1541
|
+
weight-0 condition described above.
|
|
1542
|
+
|
|
1543
|
+
- If ``parameter`` is an integer `k` then the method returns
|
|
1544
|
+
the ``j``-invariant associated to the parameter
|
|
1545
|
+
`((k,), (d_k, d_r))`;
|
|
1546
|
+
|
|
1547
|
+
- If ``parameter`` is ``None`` and the rank of the Drinfeld
|
|
1548
|
+
module is 2, then the method returns its usual
|
|
1549
|
+
`j`-invariant, that is the `j`-invariant for the parameter
|
|
1550
|
+
`((1,), (q+1, 1))`.
|
|
1551
|
+
|
|
1552
|
+
- ``check`` -- boolean (default: ``True``); if this flag is set to
|
|
1553
|
+
``False`` then the code will not check if the given parameter
|
|
1554
|
+
is valid and satisfy the weight-0 condition.
|
|
1555
|
+
|
|
1556
|
+
OUTPUT: the `j`-invariant of ``self`` for the given parameter
|
|
1557
|
+
|
|
1558
|
+
EXAMPLES::
|
|
1559
|
+
|
|
1560
|
+
sage: Fq = GF(25)
|
|
1561
|
+
sage: A.<T> = Fq[]
|
|
1562
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1563
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1564
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1565
|
+
sage: phi.j_invariant()
|
|
1566
|
+
z12^10 + 4*z12^9 + 3*z12^8 + 2*z12^7 + 3*z12^6 + z12^5 + z12^3 + 4*z12^2 + z12 + 2
|
|
1567
|
+
sage: psi = DrinfeldModule(A, [p_root, 1, 1])
|
|
1568
|
+
sage: psi.j_invariant()
|
|
1569
|
+
1
|
|
1570
|
+
sage: rho = DrinfeldModule(A, [p_root, 0, 1])
|
|
1571
|
+
sage: rho.j_invariant()
|
|
1572
|
+
0
|
|
1573
|
+
|
|
1574
|
+
::
|
|
1575
|
+
|
|
1576
|
+
sage: A = GF(5)['T']
|
|
1577
|
+
sage: K.<T> = Frac(A)
|
|
1578
|
+
sage: phi = DrinfeldModule(A, [T, T^2, 1, T + 1, T^3])
|
|
1579
|
+
sage: phi.j_invariant(1)
|
|
1580
|
+
T^309
|
|
1581
|
+
sage: phi.j_invariant(2)
|
|
1582
|
+
1/T^3
|
|
1583
|
+
sage: phi.j_invariant(3)
|
|
1584
|
+
(T^156 + T^155 + T^151 + T^150 + T^131 + T^130 + T^126 + T^125 + T^31 + T^30 + T^26 + T^25 + T^6 + T^5 + T + 1)/T^93
|
|
1585
|
+
|
|
1586
|
+
The parameter can either be a tuple or a list::
|
|
1587
|
+
|
|
1588
|
+
sage: Fq.<a> = GF(7)
|
|
1589
|
+
sage: A.<T> = Fq[]
|
|
1590
|
+
sage: phi = DrinfeldModule(A, [a, a^2 + a, 0, 3*a, a^2+1])
|
|
1591
|
+
sage: J = phi.j_invariant(((1, 3), (267, 269, 39))); J
|
|
1592
|
+
5
|
|
1593
|
+
sage: J == (phi.coefficient(1)**267)*(phi.coefficient(3)**269)/(phi.coefficient(4)**39)
|
|
1594
|
+
True
|
|
1595
|
+
sage: phi.j_invariant([[3], [400, 57]])
|
|
1596
|
+
4
|
|
1597
|
+
sage: phi.j_invariant([[3], [400, 57]]) == phi.j_invariant(3)
|
|
1598
|
+
True
|
|
1599
|
+
|
|
1600
|
+
The list of all basic `j`-invariant parameters can be retrieved
|
|
1601
|
+
using the method :meth:`basic_j_invariant_parameters`::
|
|
1602
|
+
|
|
1603
|
+
sage: A = GF(3)['T']
|
|
1604
|
+
sage: K.<T> = Frac(A)
|
|
1605
|
+
sage: phi = DrinfeldModule(A, [T, T^2 + T + 1, 0, T^4 + 1, T - 1])
|
|
1606
|
+
sage: param = phi.basic_j_invariant_parameters(nonzero=True) # needs sage.geometry.polyhedron
|
|
1607
|
+
sage: phi.j_invariant(param[1]) # needs sage.geometry.polyhedron
|
|
1608
|
+
T^13 + 2*T^12 + T + 2
|
|
1609
|
+
sage: phi.j_invariant(param[2]) # needs sage.geometry.polyhedron
|
|
1610
|
+
T^35 + 2*T^31 + T^27 + 2*T^8 + T^4 + 2
|
|
1611
|
+
|
|
1612
|
+
TESTS::
|
|
1613
|
+
|
|
1614
|
+
sage: A = GF(5)['T']
|
|
1615
|
+
sage: K.<T> = Frac(A)
|
|
1616
|
+
sage: phi = DrinfeldModule(A, [T, T^2, 1, T + 1, T^3])
|
|
1617
|
+
sage: phi.j_invariant()
|
|
1618
|
+
Traceback (most recent call last):
|
|
1619
|
+
...
|
|
1620
|
+
TypeError: parameter must not be None if the rank is greater than 2
|
|
1621
|
+
|
|
1622
|
+
::
|
|
1623
|
+
|
|
1624
|
+
sage: phi.j_invariant(-1)
|
|
1625
|
+
Traceback (most recent call last):
|
|
1626
|
+
...
|
|
1627
|
+
ValueError: integer parameter must be >= 1 and < the rank (=4)
|
|
1628
|
+
|
|
1629
|
+
::
|
|
1630
|
+
|
|
1631
|
+
sage: phi.j_invariant('x')
|
|
1632
|
+
Traceback (most recent call last):
|
|
1633
|
+
...
|
|
1634
|
+
TypeError: parameter must be a tuple or a list of length 2 or an integer
|
|
1635
|
+
|
|
1636
|
+
::
|
|
1637
|
+
|
|
1638
|
+
sage: phi.j_invariant((1, 2, 3))
|
|
1639
|
+
Traceback (most recent call last):
|
|
1640
|
+
...
|
|
1641
|
+
ValueError: list or tuple parameter must be of length 2
|
|
1642
|
+
|
|
1643
|
+
::
|
|
1644
|
+
|
|
1645
|
+
sage: phi.j_invariant(('x', (1, 2, 3)))
|
|
1646
|
+
Traceback (most recent call last):
|
|
1647
|
+
...
|
|
1648
|
+
TypeError: list or tuple parameter must contain tuples or lists
|
|
1649
|
+
|
|
1650
|
+
::
|
|
1651
|
+
|
|
1652
|
+
sage: phi.j_invariant(((1, 2), 'x'))
|
|
1653
|
+
Traceback (most recent call last):
|
|
1654
|
+
...
|
|
1655
|
+
TypeError: list or tuple parameter must contain tuples or lists
|
|
1656
|
+
|
|
1657
|
+
::
|
|
1658
|
+
|
|
1659
|
+
sage: phi.j_invariant(((1, 2, 3, 4, 5), (2, 1)))
|
|
1660
|
+
Traceback (most recent call last):
|
|
1661
|
+
...
|
|
1662
|
+
ValueError: components of tuple or list parameter have incorrect length
|
|
1663
|
+
|
|
1664
|
+
::
|
|
1665
|
+
|
|
1666
|
+
sage: phi.j_invariant(((1, 'x'), (2, 3, 8)))
|
|
1667
|
+
Traceback (most recent call last):
|
|
1668
|
+
...
|
|
1669
|
+
TypeError: components of tuple or list parameter must contain only integers
|
|
1670
|
+
|
|
1671
|
+
::
|
|
1672
|
+
|
|
1673
|
+
sage: phi.j_invariant(((1, 2), (2, 3, 'x')))
|
|
1674
|
+
Traceback (most recent call last):
|
|
1675
|
+
...
|
|
1676
|
+
TypeError: components of tuple or list parameter must contain only integers
|
|
1677
|
+
|
|
1678
|
+
::
|
|
1679
|
+
|
|
1680
|
+
sage: phi.j_invariant(((1, 2), (4, 3, 7)))
|
|
1681
|
+
Traceback (most recent call last):
|
|
1682
|
+
...
|
|
1683
|
+
ValueError: parameter does not satisfy the weight-0 condition
|
|
1684
|
+
|
|
1685
|
+
::
|
|
1686
|
+
|
|
1687
|
+
sage: phi.j_invariant(((1, 2), (4, 3, 7)), check=False)
|
|
1688
|
+
1/T^13
|
|
1689
|
+
"""
|
|
1690
|
+
r = self._gen.degree()
|
|
1691
|
+
q = self._Fq.order()
|
|
1692
|
+
if parameter is None:
|
|
1693
|
+
if r != 2:
|
|
1694
|
+
raise TypeError("parameter must not be None "
|
|
1695
|
+
"if the rank is greater than 2")
|
|
1696
|
+
return self._gen[1]**(q+1)/self._gen[2]
|
|
1697
|
+
if parameter in ZZ:
|
|
1698
|
+
parameter = ZZ(parameter)
|
|
1699
|
+
if parameter <= 0 or parameter >= r:
|
|
1700
|
+
raise ValueError("integer parameter must be >= 1 and < the "
|
|
1701
|
+
f"rank (={r})")
|
|
1702
|
+
dk = Integer((q**r - 1)/(q**gcd(parameter, r) - 1))
|
|
1703
|
+
dr = Integer((q**parameter - 1)/(q**gcd(parameter, r) - 1))
|
|
1704
|
+
return self._gen[parameter]**dk / self._gen[-1]**dr
|
|
1705
|
+
elif isinstance(parameter, (tuple, list)):
|
|
1706
|
+
if len(parameter) != 2:
|
|
1707
|
+
raise ValueError("list or tuple parameter must be of length 2")
|
|
1708
|
+
if not isinstance(parameter[0], (tuple, list)) \
|
|
1709
|
+
or not isinstance(parameter[1], (tuple, list)):
|
|
1710
|
+
raise TypeError("list or tuple parameter must contain tuples "
|
|
1711
|
+
"or lists")
|
|
1712
|
+
if not len(parameter[0]) < r or\
|
|
1713
|
+
not len(parameter[1]) == len(parameter[0]) + 1:
|
|
1714
|
+
raise ValueError("components of tuple or list parameter have "
|
|
1715
|
+
"incorrect length")
|
|
1716
|
+
try: # Check parameter's type
|
|
1717
|
+
parameter_0 = [ZZ(p) for p in parameter[0]]
|
|
1718
|
+
parameter_1 = [ZZ(p) for p in parameter[1]]
|
|
1719
|
+
except TypeError:
|
|
1720
|
+
raise TypeError("components of tuple or list parameter must "
|
|
1721
|
+
"contain only integers")
|
|
1722
|
+
# Check that the weight-0 condition is satisfied:
|
|
1723
|
+
# d_1 (q - 1) + ... + d_{r-1} (q^{r-1} - 1)
|
|
1724
|
+
# = d_r (q^r - 1)
|
|
1725
|
+
if check:
|
|
1726
|
+
right = parameter_1[-1]*(q**r - 1)
|
|
1727
|
+
left = sum(parameter_1[i]*(q**(parameter_0[i]) - 1) for i in
|
|
1728
|
+
range(len(parameter_0)))
|
|
1729
|
+
if left != right:
|
|
1730
|
+
raise ValueError("parameter does not satisfy the "
|
|
1731
|
+
"weight-0 condition")
|
|
1732
|
+
else:
|
|
1733
|
+
raise TypeError("parameter must be a tuple or a list of "
|
|
1734
|
+
"length 2 or an integer")
|
|
1735
|
+
num = prod(self._gen[k]**d
|
|
1736
|
+
for k, d in zip(parameter_0, parameter_1[:-1]))
|
|
1737
|
+
return num / (self._gen[-1]**parameter_1[-1])
|
|
1738
|
+
|
|
1739
|
+
def jk_invariants(self):
|
|
1740
|
+
r"""
|
|
1741
|
+
Return a dictionary whose keys are all the integers
|
|
1742
|
+
`1 \leqslant k \leqslant r-1` and the values are the
|
|
1743
|
+
corresponding `j_k`-invariants
|
|
1744
|
+
|
|
1745
|
+
Recall that the `j_k`-invariant of ``self`` is defined by:
|
|
1746
|
+
|
|
1747
|
+
.. MATH::
|
|
1748
|
+
|
|
1749
|
+
j_k := \frac{g_k^{(q^r - 1)/(\mathrm{gcd}(k, r) - 1)}}{g_r^{(q^k - 1)/(\mathrm{gcd}(k, r) - 1)}}
|
|
1750
|
+
|
|
1751
|
+
where `g_i` is the `i`-th coefficient of the generator of ``self``.
|
|
1752
|
+
|
|
1753
|
+
EXAMPLES::
|
|
1754
|
+
|
|
1755
|
+
sage: A = GF(3)['T']
|
|
1756
|
+
sage: K.<T> = Frac(A)
|
|
1757
|
+
sage: phi = DrinfeldModule(A, [T, 1, T+1, T^3, T^6])
|
|
1758
|
+
sage: jk_inv = phi.jk_invariants(); jk_inv
|
|
1759
|
+
{1: 1/T^6, 2: (T^10 + T^9 + T + 1)/T^6, 3: T^42}
|
|
1760
|
+
sage: jk_inv[2]
|
|
1761
|
+
(T^10 + T^9 + T + 1)/T^6
|
|
1762
|
+
|
|
1763
|
+
::
|
|
1764
|
+
|
|
1765
|
+
sage: F = GF(7**2)
|
|
1766
|
+
sage: A = F['T']
|
|
1767
|
+
sage: E.<z> = F.extension(4)
|
|
1768
|
+
sage: phi = DrinfeldModule(A, [z^2, 1, z+1, z^2, z, z+1])
|
|
1769
|
+
sage: phi.jk_invariants()
|
|
1770
|
+
{1: 5*z^7 + 2*z^6 + 5*z^5 + 2*z^4 + 5*z^3 + z^2 + z + 2,
|
|
1771
|
+
2: 3*z^7 + 4*z^6 + 5*z^5 + 6*z^4 + 4*z,
|
|
1772
|
+
3: 5*z^7 + 6*z^6 + 6*z^5 + 4*z^3 + z^2 + 2*z + 1,
|
|
1773
|
+
4: 3*z^6 + 2*z^5 + 4*z^4 + 2*z^3 + 4*z^2 + 6*z + 2}
|
|
1774
|
+
"""
|
|
1775
|
+
r = self._gen.degree() # rank of self
|
|
1776
|
+
return {k: self.j_invariant(k) for k in range(1, r)}
|
|
1777
|
+
|
|
1778
|
+
def morphism(self):
|
|
1779
|
+
r"""
|
|
1780
|
+
Return the morphism object that defines the Drinfeld module.
|
|
1781
|
+
|
|
1782
|
+
OUTPUT: a ring morphism from the function ring to the Ore
|
|
1783
|
+
polynomial ring
|
|
1784
|
+
|
|
1785
|
+
EXAMPLES::
|
|
1786
|
+
|
|
1787
|
+
sage: Fq = GF(25)
|
|
1788
|
+
sage: A.<T> = Fq[]
|
|
1789
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1790
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1791
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1792
|
+
sage: phi.morphism()
|
|
1793
|
+
Ring morphism:
|
|
1794
|
+
From: Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2
|
|
1795
|
+
To: Ore Polynomial Ring in t over Finite Field in z12 of size 5^12
|
|
1796
|
+
over its base twisted by Frob^2
|
|
1797
|
+
Defn: T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8
|
|
1798
|
+
+ z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1799
|
+
sage: from sage.rings.morphism import RingHomomorphism
|
|
1800
|
+
sage: isinstance(phi.morphism(), RingHomomorphism)
|
|
1801
|
+
True
|
|
1802
|
+
|
|
1803
|
+
Actually, the ``DrinfeldModule`` method :meth:`__call__` simply
|
|
1804
|
+
class the ``__call__`` method of this morphism::
|
|
1805
|
+
|
|
1806
|
+
sage: phi.morphism()(T) == phi(T)
|
|
1807
|
+
True
|
|
1808
|
+
sage: a = A.random_element()
|
|
1809
|
+
sage: phi.morphism()(a) == phi(a)
|
|
1810
|
+
True
|
|
1811
|
+
|
|
1812
|
+
And many methods of the Drinfeld module have a counterpart in
|
|
1813
|
+
the morphism object::
|
|
1814
|
+
|
|
1815
|
+
sage: m = phi.morphism()
|
|
1816
|
+
sage: m.domain() is phi.function_ring()
|
|
1817
|
+
True
|
|
1818
|
+
sage: m.codomain() is phi.ore_polring()
|
|
1819
|
+
True
|
|
1820
|
+
sage: m.im_gens()
|
|
1821
|
+
[z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8
|
|
1822
|
+
+ z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12]
|
|
1823
|
+
sage: phi(T) == m.im_gens()[0]
|
|
1824
|
+
True
|
|
1825
|
+
"""
|
|
1826
|
+
return self._morphism
|
|
1827
|
+
|
|
1828
|
+
def rank(self):
|
|
1829
|
+
r"""
|
|
1830
|
+
Return the rank of the Drinfeld module.
|
|
1831
|
+
|
|
1832
|
+
In our case, the rank is the degree of the generator.
|
|
1833
|
+
|
|
1834
|
+
OUTPUT: integer
|
|
1835
|
+
|
|
1836
|
+
EXAMPLES::
|
|
1837
|
+
|
|
1838
|
+
sage: Fq = GF(25)
|
|
1839
|
+
sage: A.<T> = Fq[]
|
|
1840
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1841
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1842
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1843
|
+
sage: phi.rank()
|
|
1844
|
+
2
|
|
1845
|
+
sage: psi = DrinfeldModule(A, [p_root, 2])
|
|
1846
|
+
sage: psi.rank()
|
|
1847
|
+
1
|
|
1848
|
+
sage: rho = DrinfeldModule(A, [p_root, 0, 0, 0, 1])
|
|
1849
|
+
sage: rho.rank()
|
|
1850
|
+
4
|
|
1851
|
+
|
|
1852
|
+
TESTS:
|
|
1853
|
+
|
|
1854
|
+
The rank must be an ``Integer`` (see PR #35519)::
|
|
1855
|
+
|
|
1856
|
+
sage: Fq = GF(25)
|
|
1857
|
+
sage: A.<T> = Fq[]
|
|
1858
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1859
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1860
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1861
|
+
sage: isinstance(phi.rank(), Integer)
|
|
1862
|
+
True
|
|
1863
|
+
"""
|
|
1864
|
+
return self._gen.degree()
|
|
1865
|
+
|
|
1866
|
+
def velu(self, isog):
|
|
1867
|
+
r"""
|
|
1868
|
+
Return a new Drinfeld module such that ``isog`` defines an
|
|
1869
|
+
isogeny to this module with domain ``self``; if no such isogeny
|
|
1870
|
+
exists, raise an exception.
|
|
1871
|
+
|
|
1872
|
+
INPUT:
|
|
1873
|
+
|
|
1874
|
+
- ``isog`` -- the Ore polynomial that defines the isogeny
|
|
1875
|
+
|
|
1876
|
+
OUTPUT: a Drinfeld module
|
|
1877
|
+
|
|
1878
|
+
ALGORITHM:
|
|
1879
|
+
|
|
1880
|
+
The input defines an isogeny if only if:
|
|
1881
|
+
|
|
1882
|
+
1. The degree of the characteristic divides the height of
|
|
1883
|
+
the input. (The height of an Ore polynomial `P(\tau)` is the
|
|
1884
|
+
maximum `n` such that `\tau^n` right-divides `P(\tau)`.)
|
|
1885
|
+
|
|
1886
|
+
2. The input right-divides the generator, which can
|
|
1887
|
+
be tested with Euclidean division.
|
|
1888
|
+
|
|
1889
|
+
We test if the input is an isogeny, and, if it is, we
|
|
1890
|
+
return the quotient of the Euclidean division.
|
|
1891
|
+
|
|
1892
|
+
Height and Euclidean division of Ore polynomials are
|
|
1893
|
+
implemented as methods of class
|
|
1894
|
+
:class:`sage.rings.polynomial.ore_polynomial_element.OrePolynomial`.
|
|
1895
|
+
|
|
1896
|
+
Another possible algorithm is to recursively solve a system,
|
|
1897
|
+
see :arxiv:`2203.06970`, Eq. 1.1.
|
|
1898
|
+
|
|
1899
|
+
EXAMPLES::
|
|
1900
|
+
|
|
1901
|
+
sage: Fq = GF(25)
|
|
1902
|
+
sage: A.<T> = Fq[]
|
|
1903
|
+
sage: K.<z12> = Fq.extension(6)
|
|
1904
|
+
sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1905
|
+
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
|
|
1906
|
+
sage: t = phi.ore_polring().gen()
|
|
1907
|
+
sage: isog = t + 2*z12^11 + 4*z12^9 + 2*z12^8 + 2*z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + 4*z12^2 + 4*z12 + 4
|
|
1908
|
+
sage: psi = phi.velu(isog)
|
|
1909
|
+
sage: psi
|
|
1910
|
+
Drinfeld module defined by T |-->
|
|
1911
|
+
(z12^11 + 3*z12^10 + z12^9 + z12^7 + z12^5 + 4*z12^4 + 4*z12^3 + z12^2 + 1)*t^2
|
|
1912
|
+
+ (2*z12^11 + 4*z12^10 + 2*z12^8 + z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + z12^2 + z12 + 4)*t
|
|
1913
|
+
+ 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
|
|
1914
|
+
sage: isog in Hom(phi, psi)
|
|
1915
|
+
True
|
|
1916
|
+
|
|
1917
|
+
This method works for endomorphisms as well::
|
|
1918
|
+
|
|
1919
|
+
sage: phi.velu(phi(T)) is phi
|
|
1920
|
+
True
|
|
1921
|
+
sage: phi.velu(t^6) is phi
|
|
1922
|
+
True
|
|
1923
|
+
|
|
1924
|
+
The following inputs do not define isogenies, and the method
|
|
1925
|
+
returns ``None``::
|
|
1926
|
+
|
|
1927
|
+
sage: phi.velu(0)
|
|
1928
|
+
Traceback (most recent call last):
|
|
1929
|
+
...
|
|
1930
|
+
ValueError: the input does not define an isogeny
|
|
1931
|
+
sage: phi.velu(t)
|
|
1932
|
+
Traceback (most recent call last):
|
|
1933
|
+
...
|
|
1934
|
+
ValueError: the input does not define an isogeny
|
|
1935
|
+
sage: phi.velu(t^3 + t + 2)
|
|
1936
|
+
Traceback (most recent call last):
|
|
1937
|
+
...
|
|
1938
|
+
ValueError: the input does not define an isogeny
|
|
1939
|
+
"""
|
|
1940
|
+
if isog not in self.ore_polring():
|
|
1941
|
+
raise TypeError('input must be an Ore polynomial')
|
|
1942
|
+
e = ValueError('the input does not define an isogeny')
|
|
1943
|
+
if isog == 0:
|
|
1944
|
+
raise e
|
|
1945
|
+
quo, rem = (isog * self.gen()).right_quo_rem(isog)
|
|
1946
|
+
if rem.is_zero() and quo[0] == self.gen()[0]:
|
|
1947
|
+
return self.category().object(quo)
|
|
1948
|
+
else:
|
|
1949
|
+
raise e
|
|
1950
|
+
|
|
1951
|
+
def hom(self, x, codomain=None):
|
|
1952
|
+
r"""
|
|
1953
|
+
Return the homomorphism defined by ``x`` having this Drinfeld
|
|
1954
|
+
module as domain.
|
|
1955
|
+
|
|
1956
|
+
We recall that a homomorphism `f : \phi \to \psi` between
|
|
1957
|
+
two Drinfeld modules is defined by an Ore polynomial `u`,
|
|
1958
|
+
which is subject to the relation `phi_T u = u \psi_T`.
|
|
1959
|
+
|
|
1960
|
+
INPUT:
|
|
1961
|
+
|
|
1962
|
+
- ``x`` -- an element of the ring of functions, or an
|
|
1963
|
+
Ore polynomial
|
|
1964
|
+
|
|
1965
|
+
- ``codomain`` -- a Drinfeld module or ``None`` (default:
|
|
1966
|
+
``None``)
|
|
1967
|
+
|
|
1968
|
+
EXAMPLES::
|
|
1969
|
+
|
|
1970
|
+
sage: Fq = GF(5)
|
|
1971
|
+
sage: A.<T> = Fq[]
|
|
1972
|
+
sage: K.<z> = Fq.extension(3)
|
|
1973
|
+
sage: phi = DrinfeldModule(A, [z, 0, 1, z])
|
|
1974
|
+
sage: phi
|
|
1975
|
+
Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
1976
|
+
|
|
1977
|
+
An important class of endomorphisms of a Drinfeld module
|
|
1978
|
+
`\phi` is given by scalar multiplications, that are endomorphisms
|
|
1979
|
+
corresponding to the Ore polynomials `\phi_a` with `a` in the function
|
|
1980
|
+
ring `A`. We construct them as follows::
|
|
1981
|
+
|
|
1982
|
+
sage: phi.hom(T)
|
|
1983
|
+
Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
1984
|
+
Defn: z*t^3 + t^2 + z
|
|
1985
|
+
|
|
1986
|
+
::
|
|
1987
|
+
|
|
1988
|
+
sage: phi.hom(T^2 + 1)
|
|
1989
|
+
Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
1990
|
+
Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1
|
|
1991
|
+
|
|
1992
|
+
We can also define a morphism by passing in the Ore polynomial
|
|
1993
|
+
defining it.
|
|
1994
|
+
For example, below, we construct the Frobenius endomorphism
|
|
1995
|
+
of `\phi`::
|
|
1996
|
+
|
|
1997
|
+
sage: t = phi.ore_variable()
|
|
1998
|
+
sage: phi.hom(t^3)
|
|
1999
|
+
Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
2000
|
+
Defn: t^3
|
|
2001
|
+
|
|
2002
|
+
If the input Ore polynomial defines a morphism to another
|
|
2003
|
+
Drinfeld module, the latter is determined automatically::
|
|
2004
|
+
|
|
2005
|
+
sage: phi.hom(t + 1)
|
|
2006
|
+
Drinfeld Module morphism:
|
|
2007
|
+
From: Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
2008
|
+
To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z
|
|
2009
|
+
Defn: t + 1
|
|
2010
|
+
|
|
2011
|
+
TESTS::
|
|
2012
|
+
|
|
2013
|
+
sage: phi.hom(t)
|
|
2014
|
+
Traceback (most recent call last):
|
|
2015
|
+
...
|
|
2016
|
+
ValueError: the input does not define an isogeny
|
|
2017
|
+
|
|
2018
|
+
::
|
|
2019
|
+
|
|
2020
|
+
sage: phi.hom(T + z)
|
|
2021
|
+
Traceback (most recent call last):
|
|
2022
|
+
...
|
|
2023
|
+
ValueError: the input does not define an isogeny
|
|
2024
|
+
|
|
2025
|
+
::
|
|
2026
|
+
|
|
2027
|
+
sage: phi.hom(t + 1, codomain=phi)
|
|
2028
|
+
Traceback (most recent call last):
|
|
2029
|
+
...
|
|
2030
|
+
ValueError: Ore polynomial does not define a morphism
|
|
2031
|
+
|
|
2032
|
+
Check that x = 0 (without specified codomain) gives the zero endomorphism::
|
|
2033
|
+
|
|
2034
|
+
sage: phi.hom(K.zero())
|
|
2035
|
+
Endomorphism of Drinfeld module defined by ...
|
|
2036
|
+
Defn: 0
|
|
2037
|
+
"""
|
|
2038
|
+
# When `x` is in the function ring (or something that coerces to it):
|
|
2039
|
+
if self.function_ring().has_coerce_map_from(x.parent()):
|
|
2040
|
+
return self.Hom(self)(x)
|
|
2041
|
+
if codomain is None:
|
|
2042
|
+
if x.is_zero():
|
|
2043
|
+
return self.Hom(self)(0)
|
|
2044
|
+
try:
|
|
2045
|
+
codomain = self.velu(x)
|
|
2046
|
+
except TypeError:
|
|
2047
|
+
raise ValueError("the input does not define an isogeny")
|
|
2048
|
+
H = self.Hom(codomain)
|
|
2049
|
+
return H(x)
|
|
2050
|
+
|
|
2051
|
+
# TODO: implement the method `moh`, the analogue of `hom`
|
|
2052
|
+
# with fixed codomain.
|
|
2053
|
+
# It's not straightforward because `left_divides` does not
|
|
2054
|
+
# work currently because Sage does not know how to invert the
|
|
2055
|
+
# Frobenius endomorphism; this is due to the RingExtension stuff.
|
|
2056
|
+
|
|
2057
|
+
def scalar_multiplication(self, x):
|
|
2058
|
+
r"""
|
|
2059
|
+
Return the endomorphism of this Drinfeld module, which is
|
|
2060
|
+
the multiplication by `x`, i.e. the isogeny defined by the
|
|
2061
|
+
Ore polynomial `\phi_x`.
|
|
2062
|
+
|
|
2063
|
+
INPUT:
|
|
2064
|
+
|
|
2065
|
+
- ``x`` -- an element in the ring of functions
|
|
2066
|
+
|
|
2067
|
+
EXAMPLES::
|
|
2068
|
+
|
|
2069
|
+
sage: Fq = GF(5)
|
|
2070
|
+
sage: A.<T> = Fq[]
|
|
2071
|
+
sage: K.<z> = Fq.extension(3)
|
|
2072
|
+
sage: phi = DrinfeldModule(A, [z, 0, 1, z])
|
|
2073
|
+
sage: phi
|
|
2074
|
+
Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
2075
|
+
sage: phi.hom(T) # indirect doctest
|
|
2076
|
+
Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
2077
|
+
Defn: z*t^3 + t^2 + z
|
|
2078
|
+
|
|
2079
|
+
::
|
|
2080
|
+
|
|
2081
|
+
sage: phi.hom(T^2 + 1)
|
|
2082
|
+
Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
|
|
2083
|
+
Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1
|
|
2084
|
+
"""
|
|
2085
|
+
if not self.function_ring().has_coerce_map_from(x.parent()):
|
|
2086
|
+
raise ValueError("%s is not element of the function ring" % x)
|
|
2087
|
+
return self.Hom(self)(x)
|