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
sage/rings/derivation.py
ADDED
|
@@ -0,0 +1,2334 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
r"""
|
|
3
|
+
Derivations
|
|
4
|
+
|
|
5
|
+
Let `A` be a ring and `B` be a bimodule over `A`.
|
|
6
|
+
A derivation `d : A \to B` is an additive map that satisfies
|
|
7
|
+
the Leibniz rule
|
|
8
|
+
|
|
9
|
+
.. MATH::
|
|
10
|
+
|
|
11
|
+
d(xy) = x d(y) + d(x) y.
|
|
12
|
+
|
|
13
|
+
If `B` is an algebra over `A` and if we are given in addition a
|
|
14
|
+
ring homomorphism `\theta : A \to B`, a twisted derivation with respect
|
|
15
|
+
to `\theta` (or a `\theta`-derivation) is an additive map `d : A \to B`
|
|
16
|
+
such that
|
|
17
|
+
|
|
18
|
+
.. MATH::
|
|
19
|
+
|
|
20
|
+
d(xy) = \theta(x) d(y) + d(x) y.
|
|
21
|
+
|
|
22
|
+
When `\theta` is the morphism defining the structure of `A`-algebra
|
|
23
|
+
on `B`, a `\theta`-derivation is nothing but a derivation.
|
|
24
|
+
In general, if `\iota : A \to B` denotes the defining morphism above,
|
|
25
|
+
one easily checks that `\theta - \iota` is a `\theta`-derivation.
|
|
26
|
+
|
|
27
|
+
This file provides support for derivations and twisted derivations
|
|
28
|
+
over commutative rings with values in algebras (i.e. we require
|
|
29
|
+
that `B` is a commutative `A`-algebra).
|
|
30
|
+
In this case, the set of derivations (resp. `\theta`-derivations)
|
|
31
|
+
is a module over `B`.
|
|
32
|
+
|
|
33
|
+
Given a ring `A`, the module of derivations over `A` can be created
|
|
34
|
+
as follows::
|
|
35
|
+
|
|
36
|
+
sage: A.<x,y,z> = QQ[]
|
|
37
|
+
sage: M = A.derivation_module()
|
|
38
|
+
sage: M
|
|
39
|
+
Module of derivations over
|
|
40
|
+
Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
41
|
+
|
|
42
|
+
The method :meth:`~sage.rings.derivation.RingDerivationModule.gens`
|
|
43
|
+
returns the generators of this module::
|
|
44
|
+
|
|
45
|
+
sage: A.<x,y,z> = QQ[]
|
|
46
|
+
sage: M = A.derivation_module()
|
|
47
|
+
sage: M.gens()
|
|
48
|
+
(d/dx, d/dy, d/dz)
|
|
49
|
+
|
|
50
|
+
We can combine them in order to create all derivations::
|
|
51
|
+
|
|
52
|
+
sage: d = 2*M.gen(0) + z*M.gen(1) + (x^2 + y^2)*M.gen(2)
|
|
53
|
+
sage: d
|
|
54
|
+
2*d/dx + z*d/dy + (x^2 + y^2)*d/dz
|
|
55
|
+
|
|
56
|
+
and now play with them::
|
|
57
|
+
|
|
58
|
+
sage: d(x + y + z)
|
|
59
|
+
x^2 + y^2 + z + 2
|
|
60
|
+
sage: P = A.random_element()
|
|
61
|
+
sage: Q = A.random_element()
|
|
62
|
+
sage: d(P*Q) == P*d(Q) + d(P)*Q
|
|
63
|
+
True
|
|
64
|
+
|
|
65
|
+
Alternatively we can use the method
|
|
66
|
+
:meth:`~sage.rings.ring.CommutativeRing.derivation`
|
|
67
|
+
of the ring `A` to create derivations::
|
|
68
|
+
|
|
69
|
+
sage: Dx = A.derivation(x); Dx
|
|
70
|
+
d/dx
|
|
71
|
+
sage: Dy = A.derivation(y); Dy
|
|
72
|
+
d/dy
|
|
73
|
+
sage: Dz = A.derivation(z); Dz
|
|
74
|
+
d/dz
|
|
75
|
+
sage: A.derivation([2, z, x^2+y^2])
|
|
76
|
+
2*d/dx + z*d/dy + (x^2 + y^2)*d/dz
|
|
77
|
+
|
|
78
|
+
Sage knows moreover that `M` is a Lie algebra::
|
|
79
|
+
|
|
80
|
+
sage: M.category()
|
|
81
|
+
Join of
|
|
82
|
+
Category of Lie algebras with basis over Rational Field and
|
|
83
|
+
Category of modules with basis over
|
|
84
|
+
Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
85
|
+
|
|
86
|
+
Computations of Lie brackets are implemented as well::
|
|
87
|
+
|
|
88
|
+
sage: Dx.bracket(Dy)
|
|
89
|
+
0
|
|
90
|
+
sage: d.bracket(Dx)
|
|
91
|
+
-2*x*d/dz
|
|
92
|
+
|
|
93
|
+
At the creation of a module of derivations, a codomain can be specified::
|
|
94
|
+
|
|
95
|
+
sage: B = A.fraction_field()
|
|
96
|
+
sage: A.derivation_module(B)
|
|
97
|
+
Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
98
|
+
to Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
99
|
+
|
|
100
|
+
Alternatively, one can specify a morphism `f` with domain `A`.
|
|
101
|
+
In this case, the codomain of the derivations is the codomain of
|
|
102
|
+
`f` but the latter is viewed as an algebra over `A` through the
|
|
103
|
+
homomorphism `f`.
|
|
104
|
+
This construction is useful, for example, if we want to work with
|
|
105
|
+
derivations on `A` at a certain point, e.g. `(0,1,2)`. Indeed,
|
|
106
|
+
in order to achieve this, we first define the evaluation map at
|
|
107
|
+
this point::
|
|
108
|
+
|
|
109
|
+
sage: ev = A.hom([QQ(0), QQ(1), QQ(2)])
|
|
110
|
+
sage: ev
|
|
111
|
+
Ring morphism:
|
|
112
|
+
From: Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
113
|
+
To: Rational Field
|
|
114
|
+
Defn: x |--> 0
|
|
115
|
+
y |--> 1
|
|
116
|
+
z |--> 2
|
|
117
|
+
|
|
118
|
+
Now we use this ring homomorphism to define a structure of `A`-algebra
|
|
119
|
+
on `\QQ` and then build the following module of derivations::
|
|
120
|
+
|
|
121
|
+
sage: M = A.derivation_module(ev)
|
|
122
|
+
sage: M
|
|
123
|
+
Module of derivations
|
|
124
|
+
from Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
125
|
+
to Rational Field
|
|
126
|
+
sage: M.gens()
|
|
127
|
+
(d/dx, d/dy, d/dz)
|
|
128
|
+
|
|
129
|
+
Elements in `M` then acts as derivations at `(0,1,2)`::
|
|
130
|
+
|
|
131
|
+
sage: Dx = M.gen(0)
|
|
132
|
+
sage: Dy = M.gen(1)
|
|
133
|
+
sage: Dz = M.gen(2)
|
|
134
|
+
sage: f = x^2 + y^2 + z^2
|
|
135
|
+
sage: Dx(f) # = 2*x evaluated at (0,1,2)
|
|
136
|
+
0
|
|
137
|
+
sage: Dy(f) # = 2*y evaluated at (0,1,2)
|
|
138
|
+
2
|
|
139
|
+
sage: Dz(f) # = 2*z evaluated at (0,1,2)
|
|
140
|
+
4
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
Twisted derivations are handled similarly::
|
|
144
|
+
|
|
145
|
+
sage: theta = B.hom([B(y),B(z),B(x)])
|
|
146
|
+
sage: theta
|
|
147
|
+
Ring endomorphism of Fraction Field of
|
|
148
|
+
Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
149
|
+
Defn: x |--> y
|
|
150
|
+
y |--> z
|
|
151
|
+
z |--> x
|
|
152
|
+
|
|
153
|
+
sage: M = B.derivation_module(twist=theta)
|
|
154
|
+
sage: M
|
|
155
|
+
Module of twisted derivations over Fraction Field of Multivariate Polynomial Ring
|
|
156
|
+
in x, y, z over Rational Field (twisting morphism: x |--> y, y |--> z, z |--> x)
|
|
157
|
+
|
|
158
|
+
Over a field, one proves that every `\theta`-derivation is a multiple
|
|
159
|
+
of `\theta - id`, so that::
|
|
160
|
+
|
|
161
|
+
sage: d = M.gen(); d
|
|
162
|
+
[x |--> y, y |--> z, z |--> x] - id
|
|
163
|
+
|
|
164
|
+
and then::
|
|
165
|
+
|
|
166
|
+
sage: d(x)
|
|
167
|
+
-x + y
|
|
168
|
+
sage: d(y)
|
|
169
|
+
-y + z
|
|
170
|
+
sage: d(z)
|
|
171
|
+
x - z
|
|
172
|
+
sage: d(x + y + z)
|
|
173
|
+
0
|
|
174
|
+
|
|
175
|
+
AUTHOR:
|
|
176
|
+
|
|
177
|
+
- Xavier Caruso (2018-09)
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
# ***************************************************************************
|
|
181
|
+
# Copyright (C) 2018 Xavier Caruso <xavier.caruso@normalesup.org>
|
|
182
|
+
#
|
|
183
|
+
# This program is free software: you can redistribute it and/or modify
|
|
184
|
+
# it under the terms of the GNU General Public License as published by
|
|
185
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
186
|
+
# (at your option) any later version.
|
|
187
|
+
# http://www.gnu.org/licenses/
|
|
188
|
+
# ***************************************************************************
|
|
189
|
+
|
|
190
|
+
from sage.structure.richcmp import op_EQ, op_NE
|
|
191
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
192
|
+
from sage.sets.family import Family
|
|
193
|
+
from sage.modules.module import Module
|
|
194
|
+
from sage.structure.element import ModuleElement
|
|
195
|
+
from sage.rings.integer_ring import ZZ
|
|
196
|
+
|
|
197
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
198
|
+
from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
|
|
199
|
+
from sage.rings.power_series_ring import PowerSeriesRing_generic
|
|
200
|
+
from sage.rings.laurent_series_ring import LaurentSeriesRing
|
|
201
|
+
from sage.rings.fraction_field import FractionField_generic
|
|
202
|
+
from sage.rings.quotient_ring import QuotientRing_generic
|
|
203
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
|
|
204
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic
|
|
205
|
+
from sage.rings.padics.padic_generic import pAdicGeneric
|
|
206
|
+
from sage.rings.function_field.function_field import FunctionField
|
|
207
|
+
from sage.rings.function_field.function_field_rational import RationalFunctionField
|
|
208
|
+
from sage.categories.number_fields import NumberFields
|
|
209
|
+
from sage.categories.finite_fields import FiniteFields
|
|
210
|
+
from sage.categories.modules import Modules
|
|
211
|
+
from sage.categories.modules_with_basis import ModulesWithBasis
|
|
212
|
+
from sage.categories.lie_algebras import LieAlgebras
|
|
213
|
+
|
|
214
|
+
from sage.categories.map import Map
|
|
215
|
+
from sage.categories.rings import Rings
|
|
216
|
+
|
|
217
|
+
from sage.misc.latex import latex
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class RingDerivationModule(Module, UniqueRepresentation):
|
|
221
|
+
"""
|
|
222
|
+
A class for modules of derivations over a commutative ring.
|
|
223
|
+
"""
|
|
224
|
+
def __init__(self, domain, codomain, twist=None):
|
|
225
|
+
"""
|
|
226
|
+
Initialize this module of derivation.
|
|
227
|
+
|
|
228
|
+
TESTS::
|
|
229
|
+
|
|
230
|
+
sage: A.<x,y> = QQ[]
|
|
231
|
+
sage: M = A.derivation_module()
|
|
232
|
+
sage: TestSuite(M).run()
|
|
233
|
+
|
|
234
|
+
sage: from sage.rings.derivation import RingDerivationModule
|
|
235
|
+
sage: R5.<x> = GF(5)[]
|
|
236
|
+
sage: R25.<x> = GF(25)[] # needs sage.rings.finite_rings
|
|
237
|
+
sage: R7.<x> = GF(7)[]
|
|
238
|
+
|
|
239
|
+
sage: RingDerivationModule(R5, R25) # needs sage.rings.finite_rings
|
|
240
|
+
Module of derivations
|
|
241
|
+
from Univariate Polynomial Ring in x over Finite Field of size 5
|
|
242
|
+
to Univariate Polynomial Ring in x over Finite Field in z2 of size 5^2
|
|
243
|
+
sage: RingDerivationModule(R5, R5^2)
|
|
244
|
+
Traceback (most recent call last):
|
|
245
|
+
...
|
|
246
|
+
TypeError: the codomain must be an algebra over the domain
|
|
247
|
+
or a morphism with the correct domain
|
|
248
|
+
sage: RingDerivationModule(R5, R7) # needs sage.rings.finite_rings
|
|
249
|
+
Traceback (most recent call last):
|
|
250
|
+
...
|
|
251
|
+
TypeError: the codomain must be an algebra over the domain
|
|
252
|
+
or a morphism with the correct domain
|
|
253
|
+
|
|
254
|
+
sage: theta = R5.hom([R5.gen()^2])
|
|
255
|
+
sage: RingDerivationModule(R5, R25, twist=theta) # needs sage.rings.finite_rings
|
|
256
|
+
Module of twisted derivations
|
|
257
|
+
from Univariate Polynomial Ring in x over Finite Field of size 5
|
|
258
|
+
to Univariate Polynomial Ring in x over Finite Field in z2 of size 5^2
|
|
259
|
+
(twisting morphism: x |--> x^2)
|
|
260
|
+
sage: RingDerivationModule(R7, R7, twist=theta) # needs sage.rings.finite_rings
|
|
261
|
+
Traceback (most recent call last):
|
|
262
|
+
...
|
|
263
|
+
TypeError: the domain of the derivation must coerce to the domain of the twisting homomorphism
|
|
264
|
+
"""
|
|
265
|
+
if domain not in Rings().Commutative():
|
|
266
|
+
raise TypeError("the domain must be a commutative ring")
|
|
267
|
+
|
|
268
|
+
if codomain in Rings().Commutative() and codomain.has_coerce_map_from(domain):
|
|
269
|
+
defining_morphism = codomain.coerce_map_from(domain)
|
|
270
|
+
elif (isinstance(codomain,Map)
|
|
271
|
+
and codomain.category_for().is_subcategory(Rings())
|
|
272
|
+
and codomain.domain().has_coerce_map_from(domain)):
|
|
273
|
+
if codomain.domain() is domain:
|
|
274
|
+
defining_morphism = codomain
|
|
275
|
+
else:
|
|
276
|
+
defining_morphism = codomain * codomain.domain().coerce_map_from(domain)
|
|
277
|
+
codomain = defining_morphism.codomain()
|
|
278
|
+
else:
|
|
279
|
+
raise TypeError("the codomain must be an algebra over the domain"
|
|
280
|
+
" or a morphism with the correct domain")
|
|
281
|
+
|
|
282
|
+
if twist is not None:
|
|
283
|
+
if not (isinstance(twist, Map) and twist.category_for().is_subcategory(Rings())):
|
|
284
|
+
raise TypeError("the twisting homomorphism must be a homomorphism of rings")
|
|
285
|
+
if twist.domain() is not domain:
|
|
286
|
+
map = twist.domain().coerce_map_from(domain)
|
|
287
|
+
if map is None:
|
|
288
|
+
raise TypeError("the domain of the derivation must coerce"
|
|
289
|
+
" to the domain of the twisting homomorphism")
|
|
290
|
+
twist = twist * map
|
|
291
|
+
if twist.codomain() is not codomain:
|
|
292
|
+
map = codomain.coerce_map_from(twist.codomain())
|
|
293
|
+
if map is None:
|
|
294
|
+
raise TypeError("the codomain of the twisting homomorphism"
|
|
295
|
+
" must coerce to the codomain of the derivation")
|
|
296
|
+
twist = map * twist
|
|
297
|
+
# We check if the twisting morphism is the defining morphism
|
|
298
|
+
try:
|
|
299
|
+
if twist == defining_morphism:
|
|
300
|
+
twist = None
|
|
301
|
+
else:
|
|
302
|
+
for g in domain.gens():
|
|
303
|
+
if twist(g) != defining_morphism(g):
|
|
304
|
+
break
|
|
305
|
+
else:
|
|
306
|
+
twist = None
|
|
307
|
+
except (AttributeError, NotImplementedError):
|
|
308
|
+
pass
|
|
309
|
+
|
|
310
|
+
self._domain = domain
|
|
311
|
+
self._codomain = codomain
|
|
312
|
+
self._defining_morphism = defining_morphism
|
|
313
|
+
self._twist = twist
|
|
314
|
+
self._base_derivation = None
|
|
315
|
+
self._gens = None
|
|
316
|
+
self._basis = self._dual_basis = None
|
|
317
|
+
# Currently basis and gens play exactly the same role because
|
|
318
|
+
# the only rings that are supported lead to free modules of derivations
|
|
319
|
+
# So the code is a bit redundant but we except to be able to cover more
|
|
320
|
+
# rings (with non free modules of derivations) in a near future
|
|
321
|
+
self._constants = (ZZ, False)
|
|
322
|
+
if twist is not None:
|
|
323
|
+
self.Element = RingDerivationWithTwist_generic
|
|
324
|
+
if domain.is_field():
|
|
325
|
+
self._gens = [ 1 ]
|
|
326
|
+
self._basis = [ 1 ]
|
|
327
|
+
elif (domain is ZZ or domain in NumberFields() or domain in FiniteFields()
|
|
328
|
+
or isinstance(domain, IntegerModRing_generic)
|
|
329
|
+
or (isinstance(domain, pAdicGeneric) and (domain.is_field() or domain.absolute_e() == 1))):
|
|
330
|
+
self.Element = RingDerivationWithoutTwist_zero
|
|
331
|
+
self._gens = [ ]
|
|
332
|
+
self._basis = [ ]
|
|
333
|
+
self._dual_basis = [ ]
|
|
334
|
+
self._constants = (domain, True)
|
|
335
|
+
elif (isinstance(domain, (PolynomialRing_generic, MPolynomialRing_base, PowerSeriesRing_generic, LaurentSeriesRing))
|
|
336
|
+
or (isinstance(domain, FractionField_generic)
|
|
337
|
+
and isinstance(domain.ring(), (PolynomialRing_generic, MPolynomialRing_base)))):
|
|
338
|
+
self._base_derivation = RingDerivationModule(domain.base_ring(), defining_morphism)
|
|
339
|
+
self.Element = RingDerivationWithoutTwist_function
|
|
340
|
+
try:
|
|
341
|
+
self._gens = self._base_derivation.gens() + domain.gens()
|
|
342
|
+
except NotImplementedError:
|
|
343
|
+
pass
|
|
344
|
+
try:
|
|
345
|
+
self._basis = tuple(self._base_derivation.basis()) + domain.gens()
|
|
346
|
+
self._dual_basis = tuple(self._base_derivation.dual_basis()) + domain.gens()
|
|
347
|
+
except NotImplementedError:
|
|
348
|
+
pass
|
|
349
|
+
constants, sharp = self._base_derivation._constants
|
|
350
|
+
if domain.characteristic() == 0:
|
|
351
|
+
self._constants = (constants, sharp)
|
|
352
|
+
else:
|
|
353
|
+
# in this case, the constants are polynomials in x^p
|
|
354
|
+
# TODO: implement this
|
|
355
|
+
self._constants = (constants, False)
|
|
356
|
+
elif isinstance(domain, FractionField_generic):
|
|
357
|
+
self._base_derivation = RingDerivationModule(domain.ring(), defining_morphism)
|
|
358
|
+
self.Element = RingDerivationWithoutTwist_fraction_field
|
|
359
|
+
try:
|
|
360
|
+
self._gens = self._base_derivation.gens()
|
|
361
|
+
except NotImplementedError:
|
|
362
|
+
pass
|
|
363
|
+
try:
|
|
364
|
+
self._basis = self._base_derivation.basis()
|
|
365
|
+
self._dual_basis = self._base_derivation.dual_basis()
|
|
366
|
+
except NotImplementedError:
|
|
367
|
+
pass
|
|
368
|
+
constants, sharp = self._base_derivation._constants
|
|
369
|
+
self._constants = (constants.fraction_field(), False)
|
|
370
|
+
elif isinstance(domain, PolynomialQuotientRing_generic):
|
|
371
|
+
self._base_derivation = RingDerivationModule(domain.base(), defining_morphism)
|
|
372
|
+
modulus = domain.modulus()
|
|
373
|
+
for der in self._base_derivation.gens():
|
|
374
|
+
if der(modulus) != 0:
|
|
375
|
+
raise NotImplementedError("derivations over quotient rings"
|
|
376
|
+
" are not fully supported")
|
|
377
|
+
self.Element = RingDerivationWithoutTwist_quotient
|
|
378
|
+
try:
|
|
379
|
+
self._gens = self._base_derivation.gens()
|
|
380
|
+
except NotImplementedError:
|
|
381
|
+
pass
|
|
382
|
+
try:
|
|
383
|
+
self._basis = self._base_derivation.basis()
|
|
384
|
+
self._dual_basis = self._base_derivation.dual_basis()
|
|
385
|
+
except NotImplementedError:
|
|
386
|
+
pass
|
|
387
|
+
constants, sharp = self._base_derivation._constants
|
|
388
|
+
self._constants = (constants, False) # can we do better?
|
|
389
|
+
elif isinstance(domain, QuotientRing_generic):
|
|
390
|
+
self._base_derivation = RingDerivationModule(domain.cover_ring(), defining_morphism)
|
|
391
|
+
if any(der(modulus) != 0 for modulus in domain.defining_ideal().gens()
|
|
392
|
+
for der in self._base_derivation.gens()):
|
|
393
|
+
raise NotImplementedError("derivations over quotient rings"
|
|
394
|
+
" are not fully supported")
|
|
395
|
+
self.Element = RingDerivationWithoutTwist_quotient
|
|
396
|
+
try:
|
|
397
|
+
self._gens = self._base_derivation.gens()
|
|
398
|
+
except NotImplementedError:
|
|
399
|
+
pass
|
|
400
|
+
try:
|
|
401
|
+
self._basis = self._base_derivation.basis()
|
|
402
|
+
self._dual_basis = self._base_derivation.dual_basis()
|
|
403
|
+
except NotImplementedError:
|
|
404
|
+
pass
|
|
405
|
+
constants, sharp = self._base_derivation._constants
|
|
406
|
+
self._constants = (constants, False) # can we do better?
|
|
407
|
+
elif isinstance(domain, RationalFunctionField):
|
|
408
|
+
from sage.rings.function_field.derivations_rational import FunctionFieldDerivation_rational
|
|
409
|
+
self.Element = FunctionFieldDerivation_rational
|
|
410
|
+
self._gens = self._basis = [ None ]
|
|
411
|
+
self._dual_basis = [ domain.gen() ]
|
|
412
|
+
elif isinstance(domain, FunctionField):
|
|
413
|
+
if domain.is_separable():
|
|
414
|
+
from sage.rings.function_field.derivations_polymod import FunctionFieldDerivation_separable
|
|
415
|
+
self._base_derivation = RingDerivationModule(domain.base_ring(), defining_morphism)
|
|
416
|
+
self.Element = FunctionFieldDerivation_separable
|
|
417
|
+
try:
|
|
418
|
+
self._gens = self._base_derivation.gens()
|
|
419
|
+
except NotImplementedError:
|
|
420
|
+
pass
|
|
421
|
+
try:
|
|
422
|
+
self._basis = self._base_derivation.basis()
|
|
423
|
+
self._dual_basis = self._base_derivation.dual_basis()
|
|
424
|
+
except NotImplementedError:
|
|
425
|
+
pass
|
|
426
|
+
else:
|
|
427
|
+
from sage.rings.function_field.derivations_polymod import FunctionFieldDerivation_inseparable
|
|
428
|
+
M, f, self._t = domain.separable_model()
|
|
429
|
+
self._base_derivation = RingDerivationModule(M, defining_morphism * f)
|
|
430
|
+
self._d = self._base_derivation(None)
|
|
431
|
+
self.Element = FunctionFieldDerivation_inseparable
|
|
432
|
+
self._gens = self._basis = [ None ]
|
|
433
|
+
self._dual_basis = [ f(M.base_ring().gen()) ]
|
|
434
|
+
else:
|
|
435
|
+
raise NotImplementedError("derivations over this ring is not implemented")
|
|
436
|
+
if self._basis is None:
|
|
437
|
+
category = Modules(codomain)
|
|
438
|
+
else:
|
|
439
|
+
category = ModulesWithBasis(codomain)
|
|
440
|
+
if self._twist is None and domain is codomain:
|
|
441
|
+
category &= LieAlgebras(self._constants[0])
|
|
442
|
+
Module.__init__(self, codomain, category=category)
|
|
443
|
+
if self._gens is not None:
|
|
444
|
+
self._gens = [self.element_class(self, x) for x in self._gens]
|
|
445
|
+
if self._basis is not None:
|
|
446
|
+
self._basis = [self.element_class(self, x) for x in self._basis]
|
|
447
|
+
if self._dual_basis is not None:
|
|
448
|
+
self._dual_basis = [domain(x) for x in self._dual_basis]
|
|
449
|
+
|
|
450
|
+
def __hash__(self):
|
|
451
|
+
"""
|
|
452
|
+
Return a hash of ``self``.
|
|
453
|
+
|
|
454
|
+
EXAMPLES::
|
|
455
|
+
|
|
456
|
+
sage: R.<x,y> = ZZ[]
|
|
457
|
+
sage: M = R.derivation_module()
|
|
458
|
+
sage: hash(M) == hash((M.domain(), M.codomain(), M.twisting_morphism()))
|
|
459
|
+
True
|
|
460
|
+
"""
|
|
461
|
+
return hash((self._domain, self._codomain, self._twist))
|
|
462
|
+
|
|
463
|
+
def _coerce_map_from_(self, R):
|
|
464
|
+
"""
|
|
465
|
+
Return ``True`` if there is a coercion map from ``R``
|
|
466
|
+
to this module.
|
|
467
|
+
|
|
468
|
+
EXAMPLES::
|
|
469
|
+
|
|
470
|
+
sage: A.<x> = QQ[]
|
|
471
|
+
sage: B.<y> = A[]
|
|
472
|
+
sage: M1 = A.derivation_module(); M1
|
|
473
|
+
Module of derivations over Univariate Polynomial Ring in x over Rational Field
|
|
474
|
+
sage: M2 = A.derivation_module(B); M2
|
|
475
|
+
Module of derivations
|
|
476
|
+
from Univariate Polynomial Ring in x over Rational Field
|
|
477
|
+
to Univariate Polynomial Ring in y over
|
|
478
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
479
|
+
sage: M1._coerce_map_from_(M2) is None
|
|
480
|
+
True
|
|
481
|
+
sage: M1.has_coerce_map_from(M2)
|
|
482
|
+
False
|
|
483
|
+
sage: M2.has_coerce_map_from(M1)
|
|
484
|
+
True
|
|
485
|
+
|
|
486
|
+
sage: M1.has_coerce_map_from(ZZ)
|
|
487
|
+
False
|
|
488
|
+
sage: M1.has_coerce_map_from(QQ)
|
|
489
|
+
False
|
|
490
|
+
sage: M1.has_coerce_map_from(A)
|
|
491
|
+
False
|
|
492
|
+
"""
|
|
493
|
+
if isinstance(R, RingDerivationModule):
|
|
494
|
+
if R.domain().has_coerce_map_from(self._domain) and self._codomain.has_coerce_map_from(R.codomain()):
|
|
495
|
+
morR = R.defining_morphism()
|
|
496
|
+
morS = self._defining_morphism
|
|
497
|
+
try:
|
|
498
|
+
# this test is not perfect
|
|
499
|
+
for g in self._domain.gens():
|
|
500
|
+
if morR(g) != morS(g):
|
|
501
|
+
return False
|
|
502
|
+
return True
|
|
503
|
+
except (AttributeError, NotImplementedError):
|
|
504
|
+
pass
|
|
505
|
+
return super()._coerce_map_from_(R)
|
|
506
|
+
|
|
507
|
+
def _repr_(self):
|
|
508
|
+
"""
|
|
509
|
+
Return a string representation of this module of derivations.
|
|
510
|
+
|
|
511
|
+
EXAMPLES::
|
|
512
|
+
|
|
513
|
+
sage: R.<x,y> = ZZ[]
|
|
514
|
+
sage: R.derivation_module()
|
|
515
|
+
Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring
|
|
516
|
+
|
|
517
|
+
sage: theta = R.hom([y,x])
|
|
518
|
+
sage: R.derivation_module(twist=theta)
|
|
519
|
+
Module of twisted derivations over Multivariate Polynomial Ring in x, y
|
|
520
|
+
over Integer Ring (twisting morphism: x |--> y, y |--> x)
|
|
521
|
+
"""
|
|
522
|
+
t = ""
|
|
523
|
+
if self._twist is None:
|
|
524
|
+
s = "Module of derivations"
|
|
525
|
+
else:
|
|
526
|
+
s = "Module of twisted derivations"
|
|
527
|
+
try:
|
|
528
|
+
t = " (twisting morphism: %s)" % self._twist._repr_short()
|
|
529
|
+
except AttributeError:
|
|
530
|
+
pass
|
|
531
|
+
if self._domain is self._codomain:
|
|
532
|
+
s += " over %s" % self._domain
|
|
533
|
+
else:
|
|
534
|
+
s += " from %s to %s" % (self._domain, self._codomain)
|
|
535
|
+
return s + t
|
|
536
|
+
|
|
537
|
+
def domain(self):
|
|
538
|
+
"""
|
|
539
|
+
Return the domain of the derivations in this module.
|
|
540
|
+
|
|
541
|
+
EXAMPLES::
|
|
542
|
+
|
|
543
|
+
sage: R.<x,y> = ZZ[]
|
|
544
|
+
sage: M = R.derivation_module(); M
|
|
545
|
+
Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring
|
|
546
|
+
sage: M.domain()
|
|
547
|
+
Multivariate Polynomial Ring in x, y over Integer Ring
|
|
548
|
+
"""
|
|
549
|
+
return self._domain
|
|
550
|
+
|
|
551
|
+
def codomain(self):
|
|
552
|
+
"""
|
|
553
|
+
Return the codomain of the derivations in this module.
|
|
554
|
+
|
|
555
|
+
EXAMPLES::
|
|
556
|
+
|
|
557
|
+
sage: R.<x,y> = ZZ[]
|
|
558
|
+
sage: M = R.derivation_module(); M
|
|
559
|
+
Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring
|
|
560
|
+
sage: M.codomain()
|
|
561
|
+
Multivariate Polynomial Ring in x, y over Integer Ring
|
|
562
|
+
"""
|
|
563
|
+
return self._codomain
|
|
564
|
+
|
|
565
|
+
def defining_morphism(self):
|
|
566
|
+
"""
|
|
567
|
+
Return the morphism defining the structure of algebra
|
|
568
|
+
of the codomain over the domain.
|
|
569
|
+
|
|
570
|
+
EXAMPLES::
|
|
571
|
+
|
|
572
|
+
sage: R.<x> = QQ[]
|
|
573
|
+
sage: M = R.derivation_module()
|
|
574
|
+
sage: M.defining_morphism()
|
|
575
|
+
Identity endomorphism of Univariate Polynomial Ring in x over Rational Field
|
|
576
|
+
|
|
577
|
+
sage: S.<y> = R[]
|
|
578
|
+
sage: M = R.derivation_module(S)
|
|
579
|
+
sage: M.defining_morphism()
|
|
580
|
+
Polynomial base injection morphism:
|
|
581
|
+
From: Univariate Polynomial Ring in x over Rational Field
|
|
582
|
+
To: Univariate Polynomial Ring in y over
|
|
583
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
584
|
+
|
|
585
|
+
sage: ev = R.hom([QQ(0)])
|
|
586
|
+
sage: M = R.derivation_module(ev)
|
|
587
|
+
sage: M.defining_morphism()
|
|
588
|
+
Ring morphism:
|
|
589
|
+
From: Univariate Polynomial Ring in x over Rational Field
|
|
590
|
+
To: Rational Field
|
|
591
|
+
Defn: x |--> 0
|
|
592
|
+
"""
|
|
593
|
+
return self._defining_morphism
|
|
594
|
+
|
|
595
|
+
def twisting_morphism(self):
|
|
596
|
+
r"""
|
|
597
|
+
Return the twisting homomorphism of the derivations in this module.
|
|
598
|
+
|
|
599
|
+
EXAMPLES::
|
|
600
|
+
|
|
601
|
+
sage: R.<x,y> = ZZ[]
|
|
602
|
+
sage: theta = R.hom([y,x])
|
|
603
|
+
sage: M = R.derivation_module(twist=theta); M
|
|
604
|
+
Module of twisted derivations over Multivariate Polynomial Ring in x, y
|
|
605
|
+
over Integer Ring (twisting morphism: x |--> y, y |--> x)
|
|
606
|
+
sage: M.twisting_morphism()
|
|
607
|
+
Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring
|
|
608
|
+
Defn: x |--> y
|
|
609
|
+
y |--> x
|
|
610
|
+
|
|
611
|
+
When the derivations are untwisted, this method returns nothing::
|
|
612
|
+
|
|
613
|
+
sage: M = R.derivation_module()
|
|
614
|
+
sage: M.twisting_morphism()
|
|
615
|
+
"""
|
|
616
|
+
return self._twist
|
|
617
|
+
|
|
618
|
+
def ngens(self):
|
|
619
|
+
r"""
|
|
620
|
+
Return the number of generators of this module of derivations.
|
|
621
|
+
|
|
622
|
+
EXAMPLES::
|
|
623
|
+
|
|
624
|
+
sage: R.<x,y> = ZZ[]
|
|
625
|
+
sage: M = R.derivation_module(); M
|
|
626
|
+
Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring
|
|
627
|
+
sage: M.ngens()
|
|
628
|
+
2
|
|
629
|
+
|
|
630
|
+
Indeed, generators are::
|
|
631
|
+
|
|
632
|
+
sage: M.gens()
|
|
633
|
+
(d/dx, d/dy)
|
|
634
|
+
|
|
635
|
+
We check that, for a nontrivial twist over a field, the module of
|
|
636
|
+
twisted derivation is a vector space of dimension 1 generated by
|
|
637
|
+
``twist - id``::
|
|
638
|
+
|
|
639
|
+
sage: K = R.fraction_field()
|
|
640
|
+
sage: theta = K.hom([K(y),K(x)])
|
|
641
|
+
sage: M = K.derivation_module(twist=theta); M
|
|
642
|
+
Module of twisted derivations over Fraction Field of Multivariate Polynomial
|
|
643
|
+
Ring in x, y over Integer Ring (twisting morphism: x |--> y, y |--> x)
|
|
644
|
+
sage: M.ngens()
|
|
645
|
+
1
|
|
646
|
+
sage: M.gen()
|
|
647
|
+
[x |--> y, y |--> x] - id
|
|
648
|
+
"""
|
|
649
|
+
if self._gens is None:
|
|
650
|
+
raise NotImplementedError("generators are not implemented for this derivation module")
|
|
651
|
+
return len(self._gens)
|
|
652
|
+
|
|
653
|
+
def gens(self) -> tuple:
|
|
654
|
+
r"""
|
|
655
|
+
Return the generators of this module of derivations.
|
|
656
|
+
|
|
657
|
+
EXAMPLES::
|
|
658
|
+
|
|
659
|
+
sage: R.<x,y> = ZZ[]
|
|
660
|
+
sage: M = R.derivation_module(); M
|
|
661
|
+
Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring
|
|
662
|
+
sage: M.gens()
|
|
663
|
+
(d/dx, d/dy)
|
|
664
|
+
|
|
665
|
+
We check that, for a nontrivial twist over a field, the module of
|
|
666
|
+
twisted derivation is a vector space of dimension 1 generated by
|
|
667
|
+
``twist - id``::
|
|
668
|
+
|
|
669
|
+
sage: K = R.fraction_field()
|
|
670
|
+
sage: theta = K.hom([K(y),K(x)])
|
|
671
|
+
sage: M = K.derivation_module(twist=theta); M
|
|
672
|
+
Module of twisted derivations over Fraction Field of Multivariate Polynomial
|
|
673
|
+
Ring in x, y over Integer Ring (twisting morphism: x |--> y, y |--> x)
|
|
674
|
+
sage: M.gens()
|
|
675
|
+
([x |--> y, y |--> x] - id,)
|
|
676
|
+
"""
|
|
677
|
+
if self._gens is None:
|
|
678
|
+
raise NotImplementedError("generators are not implemented for this derivation module")
|
|
679
|
+
return tuple(self._gens)
|
|
680
|
+
|
|
681
|
+
def gen(self, n=0):
|
|
682
|
+
r"""
|
|
683
|
+
Return the `n`-th generator of this module of derivations.
|
|
684
|
+
|
|
685
|
+
INPUT:
|
|
686
|
+
|
|
687
|
+
- ``n`` -- integer (default: `0`)
|
|
688
|
+
|
|
689
|
+
EXAMPLES::
|
|
690
|
+
|
|
691
|
+
sage: R.<x,y> = ZZ[]
|
|
692
|
+
sage: M = R.derivation_module(); M
|
|
693
|
+
Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring
|
|
694
|
+
sage: M.gen()
|
|
695
|
+
d/dx
|
|
696
|
+
sage: M.gen(1)
|
|
697
|
+
d/dy
|
|
698
|
+
"""
|
|
699
|
+
if self._gens is None:
|
|
700
|
+
raise NotImplementedError("generators are not implemented for this derivation module")
|
|
701
|
+
try:
|
|
702
|
+
return self._gens[n]
|
|
703
|
+
except IndexError:
|
|
704
|
+
raise ValueError("generator not defined")
|
|
705
|
+
|
|
706
|
+
def basis(self):
|
|
707
|
+
r"""
|
|
708
|
+
Return a basis of this module of derivations.
|
|
709
|
+
|
|
710
|
+
EXAMPLES::
|
|
711
|
+
|
|
712
|
+
sage: R.<x,y> = ZZ[]
|
|
713
|
+
sage: M = R.derivation_module()
|
|
714
|
+
sage: M.basis()
|
|
715
|
+
Family (d/dx, d/dy)
|
|
716
|
+
"""
|
|
717
|
+
if self._basis is None:
|
|
718
|
+
raise NotImplementedError("basis is not implemented for this derivation module")
|
|
719
|
+
return Family(self._basis)
|
|
720
|
+
|
|
721
|
+
def dual_basis(self):
|
|
722
|
+
r"""
|
|
723
|
+
Return the dual basis of the canonical basis of this module of
|
|
724
|
+
derivations (which is that returned by the method :meth:`basis`).
|
|
725
|
+
|
|
726
|
+
.. NOTE::
|
|
727
|
+
|
|
728
|
+
The dual basis of `(d_1, \dots, d_n)` is a family
|
|
729
|
+
`(x_1, \ldots, x_n)` of elements in the domain such
|
|
730
|
+
that `d_i(x_i) = 1` and `d_i(x_j) = 0` if `i \neq j`.
|
|
731
|
+
|
|
732
|
+
EXAMPLES::
|
|
733
|
+
|
|
734
|
+
sage: R.<x,y> = ZZ[]
|
|
735
|
+
sage: M = R.derivation_module()
|
|
736
|
+
sage: M.basis()
|
|
737
|
+
Family (d/dx, d/dy)
|
|
738
|
+
sage: M.dual_basis()
|
|
739
|
+
Family (x, y)
|
|
740
|
+
"""
|
|
741
|
+
if self._dual_basis is None:
|
|
742
|
+
raise NotImplementedError("basis is not implemented for this derivation module")
|
|
743
|
+
return Family(self._dual_basis)
|
|
744
|
+
|
|
745
|
+
def ring_of_constants(self):
|
|
746
|
+
r"""
|
|
747
|
+
Return the subring of the domain consisting of elements
|
|
748
|
+
`x` such that `d(x) = 0` for all derivation `d` in this module.
|
|
749
|
+
|
|
750
|
+
EXAMPLES::
|
|
751
|
+
|
|
752
|
+
sage: R.<x,y> = QQ[]
|
|
753
|
+
sage: M = R.derivation_module()
|
|
754
|
+
sage: M.basis()
|
|
755
|
+
Family (d/dx, d/dy)
|
|
756
|
+
sage: M.ring_of_constants()
|
|
757
|
+
Rational Field
|
|
758
|
+
"""
|
|
759
|
+
if not self._constants[1]:
|
|
760
|
+
raise NotImplementedError("the computation of the ring of constants"
|
|
761
|
+
" is not implemented for this derivation module")
|
|
762
|
+
return self._constants[0]
|
|
763
|
+
|
|
764
|
+
def random_element(self, *args, **kwds):
|
|
765
|
+
r"""
|
|
766
|
+
Return a random derivation in this module.
|
|
767
|
+
|
|
768
|
+
EXAMPLES::
|
|
769
|
+
|
|
770
|
+
sage: R.<x,y> = ZZ[]
|
|
771
|
+
sage: M = R.derivation_module()
|
|
772
|
+
sage: M.random_element() # random
|
|
773
|
+
(x^2 + x*y - 3*y^2 + x + 1)*d/dx + (-2*x^2 + 3*x*y + 10*y^2 + 2*x + 8)*d/dy
|
|
774
|
+
"""
|
|
775
|
+
if self._gens is None:
|
|
776
|
+
raise NotImplementedError("generators are not implemented for this derivation module")
|
|
777
|
+
return self([ self._codomain.random_element(*args, **kwds) for _ in range(len(self._gens)) ])
|
|
778
|
+
|
|
779
|
+
def some_elements(self):
|
|
780
|
+
r"""
|
|
781
|
+
Return a list of elements of this module.
|
|
782
|
+
|
|
783
|
+
EXAMPLES::
|
|
784
|
+
|
|
785
|
+
sage: R.<x,y> = ZZ[]
|
|
786
|
+
sage: M = R.derivation_module()
|
|
787
|
+
sage: M.some_elements()
|
|
788
|
+
[d/dx, d/dy, x*d/dx, x*d/dy, y*d/dx, y*d/dy]
|
|
789
|
+
"""
|
|
790
|
+
if self._gens is None:
|
|
791
|
+
return self.an_element()
|
|
792
|
+
if self._dual_basis is None:
|
|
793
|
+
return self._gens
|
|
794
|
+
return self._gens + [f * D for f in self._dual_basis for D in self._gens]
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
# The class RingDerivation does not derive from Map (or RingMap)
|
|
798
|
+
# because we don't want to see derivations as morphisms in some
|
|
799
|
+
# category since they are not stable by composition.
|
|
800
|
+
class RingDerivation(ModuleElement):
|
|
801
|
+
r"""
|
|
802
|
+
An abstract class for twisted and untwisted derivations over
|
|
803
|
+
commutative rings.
|
|
804
|
+
|
|
805
|
+
TESTS::
|
|
806
|
+
|
|
807
|
+
sage: R.<x,y> = ZZ[]
|
|
808
|
+
sage: f = R.derivation(x) + 2*R.derivation(y); f
|
|
809
|
+
d/dx + 2*d/dy
|
|
810
|
+
sage: f(x*y)
|
|
811
|
+
2*x + y
|
|
812
|
+
"""
|
|
813
|
+
def __call__(self, x):
|
|
814
|
+
"""
|
|
815
|
+
Return the image of ``x`` under this derivation.
|
|
816
|
+
|
|
817
|
+
EXAMPLES::
|
|
818
|
+
|
|
819
|
+
sage: R.<x,y> = ZZ[]
|
|
820
|
+
sage: f = x*R.derivation(x) + y*R.derivation(y)
|
|
821
|
+
sage: f(x^2 + 3*x*y - y^2)
|
|
822
|
+
2*x^2 + 6*x*y - 2*y^2
|
|
823
|
+
"""
|
|
824
|
+
arg = self.parent().domain()(x)
|
|
825
|
+
return self._call_(arg)
|
|
826
|
+
|
|
827
|
+
def domain(self):
|
|
828
|
+
"""
|
|
829
|
+
Return the domain of this derivation.
|
|
830
|
+
|
|
831
|
+
EXAMPLES::
|
|
832
|
+
|
|
833
|
+
sage: R.<x,y> = QQ[]
|
|
834
|
+
sage: f = R.derivation(y); f
|
|
835
|
+
d/dy
|
|
836
|
+
sage: f.domain()
|
|
837
|
+
Multivariate Polynomial Ring in x, y over Rational Field
|
|
838
|
+
sage: f.domain() is R
|
|
839
|
+
True
|
|
840
|
+
"""
|
|
841
|
+
return self.parent().domain()
|
|
842
|
+
|
|
843
|
+
def codomain(self):
|
|
844
|
+
"""
|
|
845
|
+
Return the codomain of this derivation.
|
|
846
|
+
|
|
847
|
+
EXAMPLES::
|
|
848
|
+
|
|
849
|
+
sage: R.<x> = QQ[]
|
|
850
|
+
sage: f = R.derivation(); f
|
|
851
|
+
d/dx
|
|
852
|
+
sage: f.codomain()
|
|
853
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
854
|
+
sage: f.codomain() is R
|
|
855
|
+
True
|
|
856
|
+
|
|
857
|
+
::
|
|
858
|
+
|
|
859
|
+
sage: S.<y> = R[]
|
|
860
|
+
sage: M = R.derivation_module(S)
|
|
861
|
+
sage: M.random_element().codomain()
|
|
862
|
+
Univariate Polynomial Ring in y over
|
|
863
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
864
|
+
sage: M.random_element().codomain() is S
|
|
865
|
+
True
|
|
866
|
+
"""
|
|
867
|
+
return self.parent().codomain()
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
class RingDerivationWithoutTwist(RingDerivation):
|
|
871
|
+
"""
|
|
872
|
+
An abstract class for untwisted derivations.
|
|
873
|
+
"""
|
|
874
|
+
def _repr_(self):
|
|
875
|
+
r"""
|
|
876
|
+
Return a string representation of this derivation.
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: R.<x,y> = ZZ[]
|
|
881
|
+
sage: R.derivation(x)
|
|
882
|
+
d/dx
|
|
883
|
+
sage: R.derivation(y)
|
|
884
|
+
d/dy
|
|
885
|
+
"""
|
|
886
|
+
parent = self.parent()
|
|
887
|
+
try:
|
|
888
|
+
dual_basis = parent.dual_basis()
|
|
889
|
+
except NotImplementedError:
|
|
890
|
+
return "A derivation on %s" % parent.domain()
|
|
891
|
+
coeffs = self.list()
|
|
892
|
+
s = ""
|
|
893
|
+
for i in range(len(dual_basis)):
|
|
894
|
+
c = coeffs[i]
|
|
895
|
+
sc = str(c)
|
|
896
|
+
if sc == "0":
|
|
897
|
+
continue
|
|
898
|
+
name = str(dual_basis[i])
|
|
899
|
+
if all(name.find(c) == -1 for c in "+-*/ ()"):
|
|
900
|
+
ddx = "d/d%s" % name
|
|
901
|
+
else:
|
|
902
|
+
ddx = "d_{%s}" % name
|
|
903
|
+
if sc == "1":
|
|
904
|
+
s += " + " + ddx
|
|
905
|
+
elif sc == "-1":
|
|
906
|
+
s += " - " + ddx
|
|
907
|
+
elif c._is_atomic() and sc[0] != "-":
|
|
908
|
+
s += " + %s*%s" % (sc, ddx)
|
|
909
|
+
elif (-c)._is_atomic():
|
|
910
|
+
s += " - %s*%s" % (-c, ddx)
|
|
911
|
+
else:
|
|
912
|
+
s += " + (%s)*%s" % (sc, ddx)
|
|
913
|
+
if s[:3] == " + ":
|
|
914
|
+
return s[3:]
|
|
915
|
+
elif s[:3] == " - ":
|
|
916
|
+
return "-" + s[3:]
|
|
917
|
+
elif s == "":
|
|
918
|
+
return "0"
|
|
919
|
+
else:
|
|
920
|
+
return s
|
|
921
|
+
|
|
922
|
+
def _latex_(self):
|
|
923
|
+
r"""
|
|
924
|
+
Return a LaTeX representation of this derivation.
|
|
925
|
+
|
|
926
|
+
EXAMPLES::
|
|
927
|
+
|
|
928
|
+
sage: R.<x,y> = ZZ[]
|
|
929
|
+
sage: ddx = R.derivation(x)
|
|
930
|
+
sage: ddy = R.derivation(y)
|
|
931
|
+
|
|
932
|
+
sage: latex(ddx)
|
|
933
|
+
\frac{d}{dx}
|
|
934
|
+
sage: latex(ddy)
|
|
935
|
+
\frac{d}{dy}
|
|
936
|
+
sage: latex(ddx + ddy)
|
|
937
|
+
\frac{d}{dx} + \frac{d}{dy}
|
|
938
|
+
"""
|
|
939
|
+
parent = self.parent()
|
|
940
|
+
try:
|
|
941
|
+
dual_basis = parent.dual_basis()
|
|
942
|
+
except NotImplementedError:
|
|
943
|
+
return "\\text{A derivation on } %s" % latex(parent.domain())
|
|
944
|
+
coeffs = self.list()
|
|
945
|
+
s = ""
|
|
946
|
+
for i in range(len(dual_basis)):
|
|
947
|
+
c = coeffs[i]
|
|
948
|
+
sc = str(c)
|
|
949
|
+
if sc == "0":
|
|
950
|
+
continue
|
|
951
|
+
name = str(dual_basis[i])
|
|
952
|
+
if all(name.find(c) == -1 for c in "+-*/ ()"):
|
|
953
|
+
ddx = "\\frac{d}{d%s}" % latex(dual_basis[i])
|
|
954
|
+
else:
|
|
955
|
+
ddx = "d_{%s}" % latex(dual_basis[i])
|
|
956
|
+
if sc == "1":
|
|
957
|
+
s += " + " + ddx
|
|
958
|
+
elif sc == "-1":
|
|
959
|
+
s += " - " + ddx
|
|
960
|
+
elif c._is_atomic() and sc[0] != "-":
|
|
961
|
+
s += " + %s %s" % (sc, ddx)
|
|
962
|
+
elif (-c)._is_atomic():
|
|
963
|
+
s += " - %s %s" % (-c, ddx)
|
|
964
|
+
else:
|
|
965
|
+
s += " + \\left(%s\\right) %s" % (sc, ddx)
|
|
966
|
+
if s[:3] == " + ":
|
|
967
|
+
return s[3:]
|
|
968
|
+
elif s[:3] == " - ":
|
|
969
|
+
return "-" + s[3:]
|
|
970
|
+
elif s == "":
|
|
971
|
+
return "0"
|
|
972
|
+
else:
|
|
973
|
+
return s
|
|
974
|
+
|
|
975
|
+
def list(self):
|
|
976
|
+
"""
|
|
977
|
+
Return the list of coefficient of this derivation
|
|
978
|
+
on the canonical basis.
|
|
979
|
+
|
|
980
|
+
EXAMPLES::
|
|
981
|
+
|
|
982
|
+
sage: R.<x,y> = QQ[]
|
|
983
|
+
sage: M = R.derivation_module()
|
|
984
|
+
sage: M.basis()
|
|
985
|
+
Family (d/dx, d/dy)
|
|
986
|
+
|
|
987
|
+
sage: R.derivation(x).list()
|
|
988
|
+
[1, 0]
|
|
989
|
+
sage: R.derivation(y).list()
|
|
990
|
+
[0, 1]
|
|
991
|
+
|
|
992
|
+
sage: f = x*R.derivation(x) + y*R.derivation(y); f
|
|
993
|
+
x*d/dx + y*d/dy
|
|
994
|
+
sage: f.list()
|
|
995
|
+
[x, y]
|
|
996
|
+
"""
|
|
997
|
+
parent = self.parent()
|
|
998
|
+
return [self(x) for x in parent.dual_basis()]
|
|
999
|
+
|
|
1000
|
+
def monomial_coefficients(self, copy=None):
|
|
1001
|
+
r"""
|
|
1002
|
+
Return dictionary of nonzero coordinates (on the canonical
|
|
1003
|
+
basis) of this derivation.
|
|
1004
|
+
|
|
1005
|
+
More precisely, this returns a dictionary whose keys are indices
|
|
1006
|
+
of basis elements and whose values are the corresponding coefficients.
|
|
1007
|
+
|
|
1008
|
+
EXAMPLES::
|
|
1009
|
+
|
|
1010
|
+
sage: R.<x,y> = QQ[]
|
|
1011
|
+
sage: M = R.derivation_module()
|
|
1012
|
+
sage: M.basis()
|
|
1013
|
+
Family (d/dx, d/dy)
|
|
1014
|
+
|
|
1015
|
+
sage: R.derivation(x).monomial_coefficients()
|
|
1016
|
+
{0: 1}
|
|
1017
|
+
sage: R.derivation(y).monomial_coefficients()
|
|
1018
|
+
{1: 1}
|
|
1019
|
+
|
|
1020
|
+
sage: f = x*R.derivation(x) + y*R.derivation(y); f
|
|
1021
|
+
x*d/dx + y*d/dy
|
|
1022
|
+
sage: f.monomial_coefficients()
|
|
1023
|
+
{0: x, 1: y}
|
|
1024
|
+
"""
|
|
1025
|
+
dual_basis = self.parent().dual_basis()
|
|
1026
|
+
dict = { }
|
|
1027
|
+
for i in range(len(dual_basis)):
|
|
1028
|
+
c = self(dual_basis[i])
|
|
1029
|
+
if c != 0:
|
|
1030
|
+
dict[i] = c
|
|
1031
|
+
return dict
|
|
1032
|
+
|
|
1033
|
+
def is_zero(self):
|
|
1034
|
+
"""
|
|
1035
|
+
Return ``True`` if this derivation is zero.
|
|
1036
|
+
|
|
1037
|
+
EXAMPLES::
|
|
1038
|
+
|
|
1039
|
+
sage: R.<x,y> = ZZ[]
|
|
1040
|
+
sage: f = R.derivation(); f
|
|
1041
|
+
d/dx
|
|
1042
|
+
sage: f.is_zero()
|
|
1043
|
+
False
|
|
1044
|
+
|
|
1045
|
+
sage: (f-f).is_zero()
|
|
1046
|
+
True
|
|
1047
|
+
"""
|
|
1048
|
+
for c in self.list():
|
|
1049
|
+
if not c.is_zero():
|
|
1050
|
+
return False
|
|
1051
|
+
return True
|
|
1052
|
+
|
|
1053
|
+
def _richcmp_(self, other, op):
|
|
1054
|
+
"""
|
|
1055
|
+
Compare this derivation with ``other`` according
|
|
1056
|
+
to the comparison operator ``op``.
|
|
1057
|
+
|
|
1058
|
+
EXAMPLES::
|
|
1059
|
+
|
|
1060
|
+
sage: R.<x,y,z> = GF(5)[]
|
|
1061
|
+
sage: D = sum(v*R.derivation(v) for v in R.gens()); D
|
|
1062
|
+
x*d/dx + y*d/dy + z*d/dz
|
|
1063
|
+
sage: D.pth_power() == D
|
|
1064
|
+
True
|
|
1065
|
+
"""
|
|
1066
|
+
if op == op_EQ:
|
|
1067
|
+
if isinstance(other, RingDerivationWithoutTwist):
|
|
1068
|
+
return self.list() == other.list()
|
|
1069
|
+
else:
|
|
1070
|
+
return False
|
|
1071
|
+
if op == op_NE:
|
|
1072
|
+
if isinstance(other, RingDerivationWithoutTwist):
|
|
1073
|
+
return self.list() != other.list()
|
|
1074
|
+
else:
|
|
1075
|
+
return True
|
|
1076
|
+
return NotImplemented
|
|
1077
|
+
|
|
1078
|
+
def _bracket_(self, other):
|
|
1079
|
+
"""
|
|
1080
|
+
Return the Lie bracket (that is the commutator) of
|
|
1081
|
+
this derivation and ``other``.
|
|
1082
|
+
|
|
1083
|
+
EXAMPLES::
|
|
1084
|
+
|
|
1085
|
+
sage: R.<x,y> = QQ[]
|
|
1086
|
+
sage: Dx = R.derivation(x)
|
|
1087
|
+
sage: Dy = R.derivation(y)
|
|
1088
|
+
sage: Dx._bracket_(Dy)
|
|
1089
|
+
0
|
|
1090
|
+
|
|
1091
|
+
sage: Dx.bracket(x*Dy)
|
|
1092
|
+
d/dy
|
|
1093
|
+
|
|
1094
|
+
TESTS::
|
|
1095
|
+
|
|
1096
|
+
sage: M = R.derivation_module()
|
|
1097
|
+
sage: X = M.random_element()
|
|
1098
|
+
sage: X.bracket(X)
|
|
1099
|
+
0
|
|
1100
|
+
|
|
1101
|
+
We check the Jacobi identity::
|
|
1102
|
+
|
|
1103
|
+
sage: Y = M.random_element()
|
|
1104
|
+
sage: Z = M.random_element()
|
|
1105
|
+
sage: X.bracket(Y.bracket(Z)) + Y.bracket(Z.bracket(X)) + Z.bracket(X.bracket(Y))
|
|
1106
|
+
0
|
|
1107
|
+
|
|
1108
|
+
and the product rule::
|
|
1109
|
+
|
|
1110
|
+
sage: f = R.random_element()
|
|
1111
|
+
sage: X.bracket(f*Y) == X(f)*Y + f*X.bracket(Y)
|
|
1112
|
+
True
|
|
1113
|
+
"""
|
|
1114
|
+
parent = self.parent()
|
|
1115
|
+
if parent.domain() is not parent.codomain():
|
|
1116
|
+
raise TypeError("the bracket is only defined for derivations with same domain and codomain")
|
|
1117
|
+
arg = [self(other(x)) - other(self(x)) for x in parent.dual_basis()]
|
|
1118
|
+
return parent(arg)
|
|
1119
|
+
|
|
1120
|
+
def pth_power(self):
|
|
1121
|
+
r"""
|
|
1122
|
+
Return the `p`-th power of this derivation where `p`
|
|
1123
|
+
is the characteristic of the domain.
|
|
1124
|
+
|
|
1125
|
+
.. NOTE::
|
|
1126
|
+
|
|
1127
|
+
Leibniz rule implies that this is again a derivation.
|
|
1128
|
+
|
|
1129
|
+
EXAMPLES::
|
|
1130
|
+
|
|
1131
|
+
sage: # needs sage.rings.finite_rings
|
|
1132
|
+
sage: R.<x,y> = GF(5)[]
|
|
1133
|
+
sage: Dx = R.derivation(x)
|
|
1134
|
+
sage: Dx.pth_power()
|
|
1135
|
+
0
|
|
1136
|
+
sage: (x*Dx).pth_power()
|
|
1137
|
+
x*d/dx
|
|
1138
|
+
sage: (x^6*Dx).pth_power()
|
|
1139
|
+
x^26*d/dx
|
|
1140
|
+
|
|
1141
|
+
sage: Dy = R.derivation(y) # needs sage.rings.finite_rings
|
|
1142
|
+
sage: (x*Dx + y*Dy).pth_power() # needs sage.rings.finite_rings
|
|
1143
|
+
x*d/dx + y*d/dy
|
|
1144
|
+
|
|
1145
|
+
An error is raised if the domain has characteristic zero::
|
|
1146
|
+
|
|
1147
|
+
sage: R.<x,y> = QQ[]
|
|
1148
|
+
sage: Dx = R.derivation(x)
|
|
1149
|
+
sage: Dx.pth_power()
|
|
1150
|
+
Traceback (most recent call last):
|
|
1151
|
+
...
|
|
1152
|
+
TypeError: the domain of the derivation must have positive and prime characteristic
|
|
1153
|
+
|
|
1154
|
+
or if the characteristic is not a prime number::
|
|
1155
|
+
|
|
1156
|
+
sage: R.<x,y> = Integers(10)[]
|
|
1157
|
+
sage: Dx = R.derivation(x)
|
|
1158
|
+
sage: Dx.pth_power()
|
|
1159
|
+
Traceback (most recent call last):
|
|
1160
|
+
...
|
|
1161
|
+
TypeError: the domain of the derivation must have positive and prime characteristic
|
|
1162
|
+
|
|
1163
|
+
TESTS::
|
|
1164
|
+
|
|
1165
|
+
sage: # needs sage.rings.finite_rings
|
|
1166
|
+
sage: R.<x,y> = GF(3)[]
|
|
1167
|
+
sage: D = R.derivation_module().random_element()
|
|
1168
|
+
sage: Dp = D.pth_power()
|
|
1169
|
+
sage: f = R.random_element()
|
|
1170
|
+
sage: Dp(f) == D(D(D(f)))
|
|
1171
|
+
True
|
|
1172
|
+
|
|
1173
|
+
sage: D.bracket(Dp) # needs sage.rings.finite_rings
|
|
1174
|
+
0
|
|
1175
|
+
"""
|
|
1176
|
+
parent = self.parent()
|
|
1177
|
+
if parent.domain() is not parent.codomain():
|
|
1178
|
+
raise TypeError("the derivation must have the same domain and codomain")
|
|
1179
|
+
p = parent.domain().characteristic()
|
|
1180
|
+
if not p.is_prime():
|
|
1181
|
+
raise TypeError("the domain of the derivation must have positive and prime characteristic")
|
|
1182
|
+
arg = [ ]
|
|
1183
|
+
for x in parent.dual_basis():
|
|
1184
|
+
res = x
|
|
1185
|
+
for _ in range(p):
|
|
1186
|
+
res = self(res)
|
|
1187
|
+
arg.append(res)
|
|
1188
|
+
return parent(arg)
|
|
1189
|
+
|
|
1190
|
+
def precompose(self, morphism):
|
|
1191
|
+
r"""
|
|
1192
|
+
Return the derivation obtained by applying first
|
|
1193
|
+
``morphism`` and then this derivation.
|
|
1194
|
+
|
|
1195
|
+
INPUT:
|
|
1196
|
+
|
|
1197
|
+
- ``morphism`` -- a homomorphism of rings whose codomain is
|
|
1198
|
+
the domain of this derivation or a ring that coerces to
|
|
1199
|
+
the domain of this derivation
|
|
1200
|
+
|
|
1201
|
+
EXAMPLES::
|
|
1202
|
+
|
|
1203
|
+
sage: A.<x> = QQ[]
|
|
1204
|
+
sage: B.<x,y> = QQ[]
|
|
1205
|
+
sage: D = B.derivation(x) - 2*x*B.derivation(y); D
|
|
1206
|
+
d/dx - 2*x*d/dy
|
|
1207
|
+
|
|
1208
|
+
When restricting to ``A``, the term ``d/dy`` disappears
|
|
1209
|
+
(since it vanishes on ``A``)::
|
|
1210
|
+
|
|
1211
|
+
sage: D.precompose(A)
|
|
1212
|
+
d/dx
|
|
1213
|
+
|
|
1214
|
+
If we restrict to another well chosen subring, the derivation vanishes::
|
|
1215
|
+
|
|
1216
|
+
sage: C.<t> = QQ[]
|
|
1217
|
+
sage: f = C.hom([x^2 + y]); f
|
|
1218
|
+
Ring morphism:
|
|
1219
|
+
From: Univariate Polynomial Ring in t over Rational Field
|
|
1220
|
+
To: Multivariate Polynomial Ring in x, y over Rational Field
|
|
1221
|
+
Defn: t |--> x^2 + y
|
|
1222
|
+
sage: D.precompose(f)
|
|
1223
|
+
0
|
|
1224
|
+
|
|
1225
|
+
Note that this method cannot be used to compose derivations::
|
|
1226
|
+
|
|
1227
|
+
sage: D.precompose(D)
|
|
1228
|
+
Traceback (most recent call last):
|
|
1229
|
+
...
|
|
1230
|
+
TypeError: you must give a homomorphism of rings
|
|
1231
|
+
|
|
1232
|
+
TESTS::
|
|
1233
|
+
|
|
1234
|
+
sage: D.precompose(C)
|
|
1235
|
+
Traceback (most recent call last):
|
|
1236
|
+
...
|
|
1237
|
+
TypeError: the given ring does not coerce to the domain of the derivation
|
|
1238
|
+
"""
|
|
1239
|
+
parent = self.parent()
|
|
1240
|
+
if morphism in Rings().Commutative():
|
|
1241
|
+
if parent.domain().has_coerce_map_from(morphism):
|
|
1242
|
+
morphism = parent.domain().coerce_map_from(morphism)
|
|
1243
|
+
else:
|
|
1244
|
+
raise TypeError("the given ring does not coerce to the domain of the derivation")
|
|
1245
|
+
elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())):
|
|
1246
|
+
raise TypeError("you must give a homomorphism of rings")
|
|
1247
|
+
M = RingDerivationModule(morphism.domain(), parent.defining_morphism() * morphism)
|
|
1248
|
+
arg = [self(morphism(x)) for x in M.dual_basis()]
|
|
1249
|
+
return M(arg)
|
|
1250
|
+
|
|
1251
|
+
def postcompose(self, morphism):
|
|
1252
|
+
"""
|
|
1253
|
+
Return the derivation obtained by applying first
|
|
1254
|
+
this derivation and then ``morphism``.
|
|
1255
|
+
|
|
1256
|
+
INPUT:
|
|
1257
|
+
|
|
1258
|
+
- ``morphism`` -- a homomorphism of rings whose domain is
|
|
1259
|
+
the codomain of this derivation or a ring into which the
|
|
1260
|
+
codomain of this derivation coerces
|
|
1261
|
+
|
|
1262
|
+
EXAMPLES::
|
|
1263
|
+
|
|
1264
|
+
sage: A.<x,y>= QQ[]
|
|
1265
|
+
sage: ev = A.hom([QQ(0), QQ(1)])
|
|
1266
|
+
sage: Dx = A.derivation(x)
|
|
1267
|
+
sage: Dy = A.derivation(y)
|
|
1268
|
+
|
|
1269
|
+
We can define the derivation at `(0,1)` just by postcomposing
|
|
1270
|
+
with ``ev``::
|
|
1271
|
+
|
|
1272
|
+
sage: dx = Dx.postcompose(ev)
|
|
1273
|
+
sage: dy = Dy.postcompose(ev)
|
|
1274
|
+
sage: f = x^2 + y^2
|
|
1275
|
+
sage: dx(f)
|
|
1276
|
+
0
|
|
1277
|
+
sage: dy(f)
|
|
1278
|
+
2
|
|
1279
|
+
|
|
1280
|
+
Note that we cannot avoid the creation of the evaluation morphism:
|
|
1281
|
+
if we pass in ``QQ`` instead, an error is raised since there is
|
|
1282
|
+
no coercion morphism from ``A`` to ``QQ``::
|
|
1283
|
+
|
|
1284
|
+
sage: Dx.postcompose(QQ)
|
|
1285
|
+
Traceback (most recent call last):
|
|
1286
|
+
...
|
|
1287
|
+
TypeError: the codomain of the derivation does not coerce to the given ring
|
|
1288
|
+
|
|
1289
|
+
Note that this method cannot be used to compose derivations::
|
|
1290
|
+
|
|
1291
|
+
sage: Dx.precompose(Dy)
|
|
1292
|
+
Traceback (most recent call last):
|
|
1293
|
+
...
|
|
1294
|
+
TypeError: you must give a homomorphism of rings
|
|
1295
|
+
"""
|
|
1296
|
+
parent = self.parent()
|
|
1297
|
+
if morphism in Rings().Commutative():
|
|
1298
|
+
if morphism.has_coerce_map_from(parent.codomain()):
|
|
1299
|
+
morphism = morphism.coerce_map_from(parent.codomain())
|
|
1300
|
+
else:
|
|
1301
|
+
raise TypeError("the codomain of the derivation does not coerce to the given ring")
|
|
1302
|
+
elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())):
|
|
1303
|
+
raise TypeError("you must give a homomorphism of rings")
|
|
1304
|
+
M = RingDerivationModule(parent.domain(), morphism * parent.defining_morphism())
|
|
1305
|
+
arg = [morphism(self(x)) for x in M.dual_basis()]
|
|
1306
|
+
return M(arg)
|
|
1307
|
+
|
|
1308
|
+
def extend_to_fraction_field(self):
|
|
1309
|
+
r"""
|
|
1310
|
+
Return the extension of this derivation to fraction fields of
|
|
1311
|
+
the domain and the codomain.
|
|
1312
|
+
|
|
1313
|
+
EXAMPLES::
|
|
1314
|
+
|
|
1315
|
+
sage: S.<x> = QQ[]
|
|
1316
|
+
sage: d = S.derivation()
|
|
1317
|
+
sage: d
|
|
1318
|
+
d/dx
|
|
1319
|
+
|
|
1320
|
+
sage: D = d.extend_to_fraction_field()
|
|
1321
|
+
sage: D
|
|
1322
|
+
d/dx
|
|
1323
|
+
sage: D.domain()
|
|
1324
|
+
Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
1325
|
+
|
|
1326
|
+
sage: D(1/x)
|
|
1327
|
+
-1/x^2
|
|
1328
|
+
"""
|
|
1329
|
+
parent = self.parent()
|
|
1330
|
+
domain = parent.domain().fraction_field()
|
|
1331
|
+
codomain = parent.codomain().fraction_field()
|
|
1332
|
+
M = RingDerivationModule(domain, codomain)
|
|
1333
|
+
try:
|
|
1334
|
+
return M(self)
|
|
1335
|
+
except (ValueError, NotImplementedError):
|
|
1336
|
+
return M(self.list())
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
class RingDerivationWithoutTwist_zero(RingDerivationWithoutTwist):
|
|
1340
|
+
"""
|
|
1341
|
+
This class can only represent the zero derivation.
|
|
1342
|
+
|
|
1343
|
+
It is used when the parent is the zero derivation module
|
|
1344
|
+
(e.g., when its domain is ``ZZ``, ``QQ``, a finite field, etc.)
|
|
1345
|
+
"""
|
|
1346
|
+
def __init__(self, parent, arg=None):
|
|
1347
|
+
"""
|
|
1348
|
+
Initialize this derivation.
|
|
1349
|
+
|
|
1350
|
+
TESTS::
|
|
1351
|
+
|
|
1352
|
+
sage: M = ZZ.derivation_module()
|
|
1353
|
+
sage: der = M(); der
|
|
1354
|
+
0
|
|
1355
|
+
|
|
1356
|
+
sage: from sage.rings.derivation import RingDerivationWithoutTwist_zero
|
|
1357
|
+
sage: isinstance(der, RingDerivationWithoutTwist_zero)
|
|
1358
|
+
True
|
|
1359
|
+
|
|
1360
|
+
sage: TestSuite(der).run()
|
|
1361
|
+
"""
|
|
1362
|
+
if isinstance(arg, list) and len(arg) == 1 and isinstance(arg[0], RingDerivation):
|
|
1363
|
+
arg = arg[0]
|
|
1364
|
+
if arg and not (isinstance(arg, RingDerivation) and arg.is_zero()):
|
|
1365
|
+
raise ValueError("unable to create the derivation")
|
|
1366
|
+
RingDerivation.__init__(self, parent)
|
|
1367
|
+
|
|
1368
|
+
def _repr_(self):
|
|
1369
|
+
"""
|
|
1370
|
+
Return a string representation of this derivation.
|
|
1371
|
+
|
|
1372
|
+
EXAMPLES::
|
|
1373
|
+
|
|
1374
|
+
sage: M = ZZ.derivation_module()
|
|
1375
|
+
sage: M()
|
|
1376
|
+
0
|
|
1377
|
+
"""
|
|
1378
|
+
return "0"
|
|
1379
|
+
|
|
1380
|
+
def _latex_(self):
|
|
1381
|
+
"""
|
|
1382
|
+
Return a string representation of this derivation.
|
|
1383
|
+
|
|
1384
|
+
EXAMPLES::
|
|
1385
|
+
|
|
1386
|
+
sage: M = ZZ.derivation_module()
|
|
1387
|
+
sage: latex(M())
|
|
1388
|
+
0
|
|
1389
|
+
"""
|
|
1390
|
+
return "0"
|
|
1391
|
+
|
|
1392
|
+
def __hash__(self):
|
|
1393
|
+
"""
|
|
1394
|
+
Return a hash of this derivation.
|
|
1395
|
+
|
|
1396
|
+
EXAMPLES::
|
|
1397
|
+
|
|
1398
|
+
sage: R.<x,y> = ZZ[]
|
|
1399
|
+
sage: f = R.derivation(x)
|
|
1400
|
+
sage: hash(f) # random
|
|
1401
|
+
3713081631936575706
|
|
1402
|
+
"""
|
|
1403
|
+
return hash(tuple(self.list()))
|
|
1404
|
+
|
|
1405
|
+
def _add_(self, other):
|
|
1406
|
+
"""
|
|
1407
|
+
Return the sum of this derivation and ``other``.
|
|
1408
|
+
|
|
1409
|
+
EXAMPLES::
|
|
1410
|
+
|
|
1411
|
+
sage: R.<x,y> = ZZ[]
|
|
1412
|
+
sage: Dx = R.derivation(x)
|
|
1413
|
+
sage: Dy = R.derivation(y)
|
|
1414
|
+
sage: Dx + Dy
|
|
1415
|
+
d/dx + d/dy
|
|
1416
|
+
"""
|
|
1417
|
+
return other
|
|
1418
|
+
|
|
1419
|
+
def _sub_(self, other):
|
|
1420
|
+
"""
|
|
1421
|
+
Return the difference of this derivation and ``other``.
|
|
1422
|
+
|
|
1423
|
+
EXAMPLES::
|
|
1424
|
+
|
|
1425
|
+
sage: R.<x,y> = ZZ[]
|
|
1426
|
+
sage: Dx = R.derivation(x)
|
|
1427
|
+
sage: Dy = R.derivation(y)
|
|
1428
|
+
sage: Dx - Dy
|
|
1429
|
+
d/dx - d/dy
|
|
1430
|
+
"""
|
|
1431
|
+
return -other
|
|
1432
|
+
|
|
1433
|
+
def _neg_(self):
|
|
1434
|
+
"""
|
|
1435
|
+
Return the opposite of this derivation.
|
|
1436
|
+
|
|
1437
|
+
EXAMPLES::
|
|
1438
|
+
|
|
1439
|
+
sage: R.<x,y> = ZZ[]
|
|
1440
|
+
sage: Dx = R.derivation(x)
|
|
1441
|
+
sage: -Dx
|
|
1442
|
+
-d/dx
|
|
1443
|
+
"""
|
|
1444
|
+
return self
|
|
1445
|
+
|
|
1446
|
+
def _lmul_(self, factor):
|
|
1447
|
+
"""
|
|
1448
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
1449
|
+
|
|
1450
|
+
EXAMPLES::
|
|
1451
|
+
|
|
1452
|
+
sage: R.<x,y> = ZZ[]
|
|
1453
|
+
sage: Dx = R.derivation(x)
|
|
1454
|
+
sage: Dx * 2
|
|
1455
|
+
2*d/dx
|
|
1456
|
+
sage: Dx * x^2
|
|
1457
|
+
x^2*d/dx
|
|
1458
|
+
"""
|
|
1459
|
+
return self
|
|
1460
|
+
|
|
1461
|
+
def _rmul_(self, left):
|
|
1462
|
+
"""
|
|
1463
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
1464
|
+
|
|
1465
|
+
EXAMPLES::
|
|
1466
|
+
|
|
1467
|
+
sage: R.<x,y> = ZZ[]
|
|
1468
|
+
sage: Dx = R.derivation(x)
|
|
1469
|
+
sage: 2 * Dx
|
|
1470
|
+
2*d/dx
|
|
1471
|
+
sage: x^2 * Dx
|
|
1472
|
+
x^2*d/dx
|
|
1473
|
+
"""
|
|
1474
|
+
return self
|
|
1475
|
+
|
|
1476
|
+
def _call_(self, x):
|
|
1477
|
+
"""
|
|
1478
|
+
Return the image of ``x`` under this derivation.
|
|
1479
|
+
|
|
1480
|
+
EXAMPLES::
|
|
1481
|
+
|
|
1482
|
+
sage: R.<x,y> = ZZ[]
|
|
1483
|
+
sage: f = x*R.derivation(x) + y*R.derivation(y)
|
|
1484
|
+
sage: f(x^2 + 3*x*y - y^2)
|
|
1485
|
+
2*x^2 + 6*x*y - 2*y^2
|
|
1486
|
+
"""
|
|
1487
|
+
return self.parent().codomain().zero()
|
|
1488
|
+
|
|
1489
|
+
def _bracket_(self, other):
|
|
1490
|
+
"""
|
|
1491
|
+
Return the Lie bracket (that is the commutator) of
|
|
1492
|
+
this derivation and ``other``.
|
|
1493
|
+
|
|
1494
|
+
EXAMPLES::
|
|
1495
|
+
|
|
1496
|
+
sage: R.<x,y> = QQ[]
|
|
1497
|
+
sage: Dx = R.derivation(x)
|
|
1498
|
+
sage: Dy = R.derivation(y)
|
|
1499
|
+
sage: Dx._bracket_(Dy)
|
|
1500
|
+
0
|
|
1501
|
+
"""
|
|
1502
|
+
return self
|
|
1503
|
+
|
|
1504
|
+
def is_zero(self):
|
|
1505
|
+
"""
|
|
1506
|
+
Return ``True`` if this derivation vanishes.
|
|
1507
|
+
|
|
1508
|
+
EXAMPLES::
|
|
1509
|
+
|
|
1510
|
+
sage: M = QQ.derivation_module()
|
|
1511
|
+
sage: M().is_zero()
|
|
1512
|
+
True
|
|
1513
|
+
"""
|
|
1514
|
+
return True
|
|
1515
|
+
|
|
1516
|
+
def list(self):
|
|
1517
|
+
"""
|
|
1518
|
+
Return the list of coefficient of this derivation
|
|
1519
|
+
on the canonical basis.
|
|
1520
|
+
|
|
1521
|
+
EXAMPLES::
|
|
1522
|
+
|
|
1523
|
+
sage: M = QQ.derivation_module()
|
|
1524
|
+
sage: M().list()
|
|
1525
|
+
[]
|
|
1526
|
+
"""
|
|
1527
|
+
return []
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
class RingDerivationWithoutTwist_wrapper(RingDerivationWithoutTwist):
|
|
1531
|
+
"""
|
|
1532
|
+
This class is a wrapper for derivation.
|
|
1533
|
+
|
|
1534
|
+
It is useful for changing the parent without changing the
|
|
1535
|
+
computation rules for derivations. It is used for derivations
|
|
1536
|
+
over fraction fields and quotient rings.
|
|
1537
|
+
"""
|
|
1538
|
+
def __init__(self, parent, arg=None):
|
|
1539
|
+
"""
|
|
1540
|
+
Initialize this derivation.
|
|
1541
|
+
|
|
1542
|
+
TESTS::
|
|
1543
|
+
|
|
1544
|
+
sage: # needs sage.libs.singular
|
|
1545
|
+
sage: from sage.rings.derivation import RingDerivationWithoutTwist_wrapper
|
|
1546
|
+
sage: R.<x,y> = GF(5)[]
|
|
1547
|
+
sage: S = R.quo([x^5, y^5])
|
|
1548
|
+
sage: M = S.derivation_module()
|
|
1549
|
+
sage: der = M.random_element()
|
|
1550
|
+
sage: isinstance(der, RingDerivationWithoutTwist_wrapper)
|
|
1551
|
+
True
|
|
1552
|
+
sage: TestSuite(der).run()
|
|
1553
|
+
"""
|
|
1554
|
+
if isinstance(arg, list) and len(arg) == 1 and isinstance(arg[0], RingDerivation):
|
|
1555
|
+
arg = arg[0]
|
|
1556
|
+
if isinstance(arg, RingDerivationWithoutTwist_wrapper):
|
|
1557
|
+
self._base_derivation = arg._base_derivation
|
|
1558
|
+
else:
|
|
1559
|
+
self._base_derivation = parent._base_derivation(arg)
|
|
1560
|
+
RingDerivation.__init__(self, parent)
|
|
1561
|
+
|
|
1562
|
+
def __hash__(self):
|
|
1563
|
+
"""
|
|
1564
|
+
Return a hash of this derivation.
|
|
1565
|
+
|
|
1566
|
+
EXAMPLES::
|
|
1567
|
+
|
|
1568
|
+
sage: R.<x,y> = ZZ[]
|
|
1569
|
+
sage: f = R.derivation(x)
|
|
1570
|
+
sage: hash(f) # random
|
|
1571
|
+
3713081631936575706
|
|
1572
|
+
"""
|
|
1573
|
+
return hash(tuple(self.list()))
|
|
1574
|
+
|
|
1575
|
+
def _add_(self, other):
|
|
1576
|
+
"""
|
|
1577
|
+
Return the sum of this derivation and ``other``.
|
|
1578
|
+
|
|
1579
|
+
EXAMPLES::
|
|
1580
|
+
|
|
1581
|
+
sage: # needs sage.libs.singular
|
|
1582
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1583
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1584
|
+
sage: Dx = S.derivation(x)
|
|
1585
|
+
sage: Dy = S.derivation(y)
|
|
1586
|
+
sage: Dx + Dy
|
|
1587
|
+
d/dx + d/dy
|
|
1588
|
+
"""
|
|
1589
|
+
return type(self)(self.parent(), self._base_derivation + other._base_derivation)
|
|
1590
|
+
|
|
1591
|
+
def _sub_(self, other):
|
|
1592
|
+
"""
|
|
1593
|
+
Return the difference of this derivation and ``other``.
|
|
1594
|
+
|
|
1595
|
+
EXAMPLES::
|
|
1596
|
+
|
|
1597
|
+
sage: # needs sage.libs.singular
|
|
1598
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1599
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1600
|
+
sage: Dx = S.derivation(x)
|
|
1601
|
+
sage: Dy = S.derivation(y)
|
|
1602
|
+
sage: Dx - Dy
|
|
1603
|
+
d/dx - d/dy
|
|
1604
|
+
"""
|
|
1605
|
+
return type(self)(self.parent(), self._base_derivation - other._base_derivation)
|
|
1606
|
+
|
|
1607
|
+
def _neg_(self):
|
|
1608
|
+
"""
|
|
1609
|
+
Return the opposite of this derivation.
|
|
1610
|
+
|
|
1611
|
+
EXAMPLES::
|
|
1612
|
+
|
|
1613
|
+
sage: # needs sage.libs.singular
|
|
1614
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1615
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1616
|
+
sage: Dx = S.derivation(x)
|
|
1617
|
+
sage: -Dx
|
|
1618
|
+
-d/dx
|
|
1619
|
+
"""
|
|
1620
|
+
return type(self)(self.parent(), -self._base_derivation)
|
|
1621
|
+
|
|
1622
|
+
def _lmul_(self, factor):
|
|
1623
|
+
"""
|
|
1624
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
1625
|
+
|
|
1626
|
+
EXAMPLES::
|
|
1627
|
+
|
|
1628
|
+
sage: # needs sage.libs.singular
|
|
1629
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1630
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1631
|
+
sage: Dx = S.derivation(x)
|
|
1632
|
+
sage: Dx * 2
|
|
1633
|
+
2*d/dx
|
|
1634
|
+
sage: Dx * x^2
|
|
1635
|
+
x^2*d/dx
|
|
1636
|
+
"""
|
|
1637
|
+
return type(self)(self.parent(), self._base_derivation * factor)
|
|
1638
|
+
|
|
1639
|
+
def _rmul_(self, factor):
|
|
1640
|
+
"""
|
|
1641
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
1642
|
+
|
|
1643
|
+
EXAMPLES::
|
|
1644
|
+
|
|
1645
|
+
sage: # needs sage.libs.singular
|
|
1646
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1647
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1648
|
+
sage: Dx = S.derivation(x)
|
|
1649
|
+
sage: 2 * Dx
|
|
1650
|
+
2*d/dx
|
|
1651
|
+
sage: x^2 * Dx
|
|
1652
|
+
x^2*d/dx
|
|
1653
|
+
"""
|
|
1654
|
+
return type(self)(self.parent(), factor * self._base_derivation)
|
|
1655
|
+
|
|
1656
|
+
def list(self):
|
|
1657
|
+
"""
|
|
1658
|
+
Return the list of coefficient of this derivation
|
|
1659
|
+
on the canonical basis.
|
|
1660
|
+
|
|
1661
|
+
EXAMPLES::
|
|
1662
|
+
|
|
1663
|
+
sage: # needs sage.libs.singular
|
|
1664
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1665
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1666
|
+
sage: M = S.derivation_module()
|
|
1667
|
+
sage: M.basis()
|
|
1668
|
+
Family (d/dx, d/dy)
|
|
1669
|
+
sage: S.derivation(x).list()
|
|
1670
|
+
[1, 0]
|
|
1671
|
+
sage: S.derivation(y).list()
|
|
1672
|
+
[0, 1]
|
|
1673
|
+
sage: f = x*S.derivation(x) + y*S.derivation(y); f
|
|
1674
|
+
x*d/dx + y*d/dy
|
|
1675
|
+
sage: f.list()
|
|
1676
|
+
[x, y]
|
|
1677
|
+
"""
|
|
1678
|
+
return self._base_derivation.list()
|
|
1679
|
+
|
|
1680
|
+
|
|
1681
|
+
class RingDerivationWithoutTwist_function(RingDerivationWithoutTwist):
|
|
1682
|
+
"""
|
|
1683
|
+
A class for untwisted derivations over rings whose elements
|
|
1684
|
+
are either polynomials, rational fractions, power series or
|
|
1685
|
+
Laurent series.
|
|
1686
|
+
"""
|
|
1687
|
+
def __init__(self, parent, arg=None):
|
|
1688
|
+
"""
|
|
1689
|
+
Initialize this derivation.
|
|
1690
|
+
|
|
1691
|
+
TESTS::
|
|
1692
|
+
|
|
1693
|
+
sage: R.<x,y> = ZZ[]
|
|
1694
|
+
sage: R.derivation(x)
|
|
1695
|
+
d/dx
|
|
1696
|
+
sage: der = R.derivation([1,2])
|
|
1697
|
+
sage: der
|
|
1698
|
+
d/dx + 2*d/dy
|
|
1699
|
+
|
|
1700
|
+
sage: TestSuite(der).run()
|
|
1701
|
+
"""
|
|
1702
|
+
domain = parent.domain()
|
|
1703
|
+
codomain = parent.codomain()
|
|
1704
|
+
ngens = domain.ngens()
|
|
1705
|
+
self._base_derivation = parent._base_derivation()
|
|
1706
|
+
self._images = [codomain.zero() for _ in range(ngens)]
|
|
1707
|
+
if arg is None:
|
|
1708
|
+
arg = domain.gen()
|
|
1709
|
+
if isinstance(arg, list) and len(arg) == 1 and isinstance(arg[0], RingDerivation):
|
|
1710
|
+
arg = arg[0]
|
|
1711
|
+
if not arg:
|
|
1712
|
+
pass
|
|
1713
|
+
elif (isinstance(arg, RingDerivationWithoutTwist_function)
|
|
1714
|
+
and parent.has_coerce_map_from(arg.parent())):
|
|
1715
|
+
self._base_derivation = parent._base_derivation(arg._base_derivation)
|
|
1716
|
+
self._images = [codomain(x) for x in arg._images]
|
|
1717
|
+
elif isinstance(arg, (tuple, list)):
|
|
1718
|
+
if len(arg) < ngens:
|
|
1719
|
+
raise ValueError("the number of images is incorrect")
|
|
1720
|
+
self._base_derivation = parent._base_derivation(arg[:-ngens])
|
|
1721
|
+
self._images = [codomain(x) for x in arg[-ngens:]]
|
|
1722
|
+
else:
|
|
1723
|
+
for i in range(ngens):
|
|
1724
|
+
if arg == domain.gen(i):
|
|
1725
|
+
self._base_derivation = parent._base_derivation()
|
|
1726
|
+
self._images[i] = codomain.one()
|
|
1727
|
+
break
|
|
1728
|
+
else:
|
|
1729
|
+
self._base_derivation = parent._base_derivation(arg)
|
|
1730
|
+
RingDerivation.__init__(self, parent)
|
|
1731
|
+
|
|
1732
|
+
def __hash__(self):
|
|
1733
|
+
"""
|
|
1734
|
+
Return a hash of this derivation.
|
|
1735
|
+
|
|
1736
|
+
EXAMPLES::
|
|
1737
|
+
|
|
1738
|
+
sage: R.<x,y> = ZZ[]
|
|
1739
|
+
sage: f = R.derivation(x)
|
|
1740
|
+
sage: hash(f) # random
|
|
1741
|
+
3713081631936575706
|
|
1742
|
+
"""
|
|
1743
|
+
return hash(tuple(self.list()))
|
|
1744
|
+
|
|
1745
|
+
def _add_(self, other):
|
|
1746
|
+
"""
|
|
1747
|
+
Return the sum of this derivation and ``other``.
|
|
1748
|
+
|
|
1749
|
+
EXAMPLES::
|
|
1750
|
+
|
|
1751
|
+
sage: R.<x,y> = ZZ[]
|
|
1752
|
+
sage: Dx = R.derivation(x)
|
|
1753
|
+
sage: Dy = R.derivation(y)
|
|
1754
|
+
sage: Dx + Dy
|
|
1755
|
+
d/dx + d/dy
|
|
1756
|
+
"""
|
|
1757
|
+
base_derivation = self._base_derivation + other._base_derivation
|
|
1758
|
+
im = [ self._images[i] + other._images[i] for i in range(self.parent().domain().ngens()) ]
|
|
1759
|
+
return type(self)(self.parent(), [base_derivation] + im)
|
|
1760
|
+
|
|
1761
|
+
def _sub_(self, other):
|
|
1762
|
+
"""
|
|
1763
|
+
Return the subtraction of this derivation and ``other``.
|
|
1764
|
+
|
|
1765
|
+
EXAMPLES::
|
|
1766
|
+
|
|
1767
|
+
sage: R.<x,y> = ZZ[]
|
|
1768
|
+
sage: Dx = R.derivation(x)
|
|
1769
|
+
sage: Dy = R.derivation(y)
|
|
1770
|
+
sage: Dx - Dy
|
|
1771
|
+
d/dx - d/dy
|
|
1772
|
+
"""
|
|
1773
|
+
base_derivation = self._base_derivation - other._base_derivation
|
|
1774
|
+
im = [ self._images[i] - other._images[i] for i in range(self.parent().domain().ngens()) ]
|
|
1775
|
+
return type(self)(self.parent(), [base_derivation] + im)
|
|
1776
|
+
|
|
1777
|
+
def _rmul_(self, factor):
|
|
1778
|
+
"""
|
|
1779
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
1780
|
+
|
|
1781
|
+
EXAMPLES::
|
|
1782
|
+
|
|
1783
|
+
sage: R.<x,y> = ZZ[]
|
|
1784
|
+
sage: Dx = R.derivation(x)
|
|
1785
|
+
sage: 2 * Dx
|
|
1786
|
+
2*d/dx
|
|
1787
|
+
sage: x^2 * Dx
|
|
1788
|
+
x^2*d/dx
|
|
1789
|
+
"""
|
|
1790
|
+
factor = self.parent().codomain()(factor)
|
|
1791
|
+
base_derivation = factor * self._base_derivation
|
|
1792
|
+
im = [ factor*x for x in self._images ]
|
|
1793
|
+
return type(self)(self.parent(), [base_derivation] + im)
|
|
1794
|
+
|
|
1795
|
+
def _lmul_(self, factor):
|
|
1796
|
+
"""
|
|
1797
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
1798
|
+
|
|
1799
|
+
EXAMPLES::
|
|
1800
|
+
|
|
1801
|
+
sage: R.<x,y> = ZZ[]
|
|
1802
|
+
sage: Dx = R.derivation(x)
|
|
1803
|
+
sage: Dx * 2
|
|
1804
|
+
2*d/dx
|
|
1805
|
+
sage: Dx * x^2
|
|
1806
|
+
x^2*d/dx
|
|
1807
|
+
"""
|
|
1808
|
+
return self._rmul_(factor)
|
|
1809
|
+
|
|
1810
|
+
def _call_(self, x):
|
|
1811
|
+
"""
|
|
1812
|
+
Return the image of ``x`` under this derivation.
|
|
1813
|
+
|
|
1814
|
+
EXAMPLES::
|
|
1815
|
+
|
|
1816
|
+
sage: R.<x,y> = ZZ[]
|
|
1817
|
+
sage: D = x*R.derivation(x) + y*R.derivation(y)
|
|
1818
|
+
sage: D(x^2 + 3*x*y - y^2)
|
|
1819
|
+
2*x^2 + 6*x*y - 2*y^2
|
|
1820
|
+
"""
|
|
1821
|
+
parent = self.parent()
|
|
1822
|
+
domain = parent.domain()
|
|
1823
|
+
codomain = parent.codomain()
|
|
1824
|
+
defining_morphism = parent.defining_morphism()
|
|
1825
|
+
if isinstance(domain, FractionField_generic):
|
|
1826
|
+
num = x.numerator()
|
|
1827
|
+
den = x.denominator()
|
|
1828
|
+
u = defining_morphism(num)
|
|
1829
|
+
v = defining_morphism(den)
|
|
1830
|
+
up = num.map_coefficients(self._base_derivation, codomain)(*domain.gens())
|
|
1831
|
+
vp = den.map_coefficients(self._base_derivation, codomain)(*domain.gens())
|
|
1832
|
+
res = (up*v - u*vp) / (v*v)
|
|
1833
|
+
else:
|
|
1834
|
+
res = x.map_coefficients(self._base_derivation, codomain)(*domain.gens())
|
|
1835
|
+
for i in range(len(self._images)):
|
|
1836
|
+
res += defining_morphism(x.derivative(domain.gen(i))) * self._images[i]
|
|
1837
|
+
return res
|
|
1838
|
+
|
|
1839
|
+
def is_zero(self):
|
|
1840
|
+
"""
|
|
1841
|
+
Return ``True`` if this derivation is zero.
|
|
1842
|
+
|
|
1843
|
+
EXAMPLES::
|
|
1844
|
+
|
|
1845
|
+
sage: R.<x,y> = ZZ[]
|
|
1846
|
+
sage: f = R.derivation(); f
|
|
1847
|
+
d/dx
|
|
1848
|
+
sage: f.is_zero()
|
|
1849
|
+
False
|
|
1850
|
+
|
|
1851
|
+
sage: (f-f).is_zero()
|
|
1852
|
+
True
|
|
1853
|
+
"""
|
|
1854
|
+
if not self._base_derivation.is_zero():
|
|
1855
|
+
return False
|
|
1856
|
+
return all(im == 0 for im in self._images)
|
|
1857
|
+
|
|
1858
|
+
def list(self):
|
|
1859
|
+
"""
|
|
1860
|
+
Return the list of coefficient of this derivation
|
|
1861
|
+
on the canonical basis.
|
|
1862
|
+
|
|
1863
|
+
EXAMPLES::
|
|
1864
|
+
|
|
1865
|
+
sage: R.<x,y> = GF(5)[[]]
|
|
1866
|
+
sage: M = R.derivation_module()
|
|
1867
|
+
sage: M.basis()
|
|
1868
|
+
Family (d/dx, d/dy)
|
|
1869
|
+
|
|
1870
|
+
sage: R.derivation(x).list()
|
|
1871
|
+
[1, 0]
|
|
1872
|
+
sage: R.derivation(y).list()
|
|
1873
|
+
[0, 1]
|
|
1874
|
+
|
|
1875
|
+
sage: f = x*R.derivation(x) + y*R.derivation(y); f
|
|
1876
|
+
x*d/dx + y*d/dy
|
|
1877
|
+
sage: f.list()
|
|
1878
|
+
[x, y]
|
|
1879
|
+
"""
|
|
1880
|
+
return self._base_derivation.list() + self._images
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
class RingDerivationWithoutTwist_fraction_field(RingDerivationWithoutTwist_wrapper):
|
|
1884
|
+
"""
|
|
1885
|
+
This class handles derivations over fraction fields.
|
|
1886
|
+
"""
|
|
1887
|
+
def __hash__(self):
|
|
1888
|
+
"""
|
|
1889
|
+
Return a hash of this derivation.
|
|
1890
|
+
|
|
1891
|
+
EXAMPLES::
|
|
1892
|
+
|
|
1893
|
+
sage: R.<x,y> = ZZ[]
|
|
1894
|
+
sage: f = R.derivation(x)
|
|
1895
|
+
sage: hash(f) # random
|
|
1896
|
+
3713081631936575706
|
|
1897
|
+
"""
|
|
1898
|
+
return hash(tuple(self.list()))
|
|
1899
|
+
|
|
1900
|
+
def _call_(self, x):
|
|
1901
|
+
"""
|
|
1902
|
+
Return the image of ``x`` under this derivation.
|
|
1903
|
+
|
|
1904
|
+
EXAMPLES::
|
|
1905
|
+
|
|
1906
|
+
sage: R.<x,y> = ZZ[]
|
|
1907
|
+
sage: K = R.fraction_field()
|
|
1908
|
+
sage: f = K.derivation(); f
|
|
1909
|
+
d/dx
|
|
1910
|
+
sage: f(1/x)
|
|
1911
|
+
(-1)/x^2
|
|
1912
|
+
"""
|
|
1913
|
+
defining_morphism = self.parent().defining_morphism()
|
|
1914
|
+
num = x.numerator()
|
|
1915
|
+
den = x.denominator()
|
|
1916
|
+
u = defining_morphism(num)
|
|
1917
|
+
v = defining_morphism(den)
|
|
1918
|
+
up = self._base_derivation(u)
|
|
1919
|
+
vp = self._base_derivation(v)
|
|
1920
|
+
return (up*v - u*vp) / (v*v)
|
|
1921
|
+
|
|
1922
|
+
|
|
1923
|
+
class RingDerivationWithoutTwist_quotient(RingDerivationWithoutTwist_wrapper):
|
|
1924
|
+
"""
|
|
1925
|
+
This class handles derivations over quotient rings.
|
|
1926
|
+
"""
|
|
1927
|
+
def __hash__(self):
|
|
1928
|
+
"""
|
|
1929
|
+
Return a hash of this derivation.
|
|
1930
|
+
|
|
1931
|
+
EXAMPLES::
|
|
1932
|
+
|
|
1933
|
+
sage: R.<x,y> = ZZ[]
|
|
1934
|
+
sage: f = R.derivation(x)
|
|
1935
|
+
sage: hash(f) # random
|
|
1936
|
+
3713081631936575706
|
|
1937
|
+
"""
|
|
1938
|
+
return hash(tuple(self.list()))
|
|
1939
|
+
|
|
1940
|
+
def _call_(self, x):
|
|
1941
|
+
"""
|
|
1942
|
+
Return the image of ``x`` under this derivation.
|
|
1943
|
+
|
|
1944
|
+
EXAMPLES::
|
|
1945
|
+
|
|
1946
|
+
sage: # needs sage.libs.singular
|
|
1947
|
+
sage: R.<X,Y> = GF(5)[]
|
|
1948
|
+
sage: S.<x,y> = R.quo([X^5, Y^5])
|
|
1949
|
+
sage: f = x^3*S.derivation(); f
|
|
1950
|
+
x^3*d/dx
|
|
1951
|
+
sage: f(x^3)
|
|
1952
|
+
0
|
|
1953
|
+
"""
|
|
1954
|
+
return self._base_derivation(x.lift())
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
class RingDerivationWithTwist_generic(RingDerivation):
|
|
1958
|
+
r"""
|
|
1959
|
+
The class handles `\theta`-derivations of the form
|
|
1960
|
+
`\lambda (\theta - \iota)` (where `\iota` is the defining
|
|
1961
|
+
morphism of the codomain over the domain) for a scalar
|
|
1962
|
+
`\lambda` varying in the codomain.
|
|
1963
|
+
"""
|
|
1964
|
+
def __init__(self, parent, scalar=0):
|
|
1965
|
+
"""
|
|
1966
|
+
Initialize this derivation.
|
|
1967
|
+
|
|
1968
|
+
TESTS::
|
|
1969
|
+
|
|
1970
|
+
sage: R.<x,y> = ZZ[]
|
|
1971
|
+
sage: theta = R.hom([y,x])
|
|
1972
|
+
sage: R.derivation(twist=theta)
|
|
1973
|
+
0
|
|
1974
|
+
sage: R.derivation(1, twist=theta)
|
|
1975
|
+
[x |--> y, y |--> x] - id
|
|
1976
|
+
|
|
1977
|
+
sage: der = R.derivation(x, twist=theta)
|
|
1978
|
+
sage: TestSuite(der).run()
|
|
1979
|
+
"""
|
|
1980
|
+
codomain = parent.codomain()
|
|
1981
|
+
self._scalar = codomain(scalar)
|
|
1982
|
+
RingDerivation.__init__(self, parent)
|
|
1983
|
+
|
|
1984
|
+
def __hash__(self):
|
|
1985
|
+
"""
|
|
1986
|
+
Return a hash of this derivation.
|
|
1987
|
+
|
|
1988
|
+
EXAMPLES::
|
|
1989
|
+
|
|
1990
|
+
sage: R.<x,y> = ZZ[]
|
|
1991
|
+
sage: theta = R.hom([y,x])
|
|
1992
|
+
sage: f = R.derivation(1, twist=theta)
|
|
1993
|
+
sage: hash(f) # random
|
|
1994
|
+
-6511057926760520014
|
|
1995
|
+
"""
|
|
1996
|
+
return hash(self._scalar)
|
|
1997
|
+
|
|
1998
|
+
def _repr_(self):
|
|
1999
|
+
r"""
|
|
2000
|
+
Return a string representation of this derivation.
|
|
2001
|
+
|
|
2002
|
+
EXAMPLES::
|
|
2003
|
+
|
|
2004
|
+
sage: R.<x,y> = ZZ[]
|
|
2005
|
+
sage: theta = R.hom([y,x])
|
|
2006
|
+
sage: R.derivation(1, twist=theta)
|
|
2007
|
+
[x |--> y, y |--> x] - id
|
|
2008
|
+
"""
|
|
2009
|
+
scalar = self._scalar
|
|
2010
|
+
sc = str(scalar)
|
|
2011
|
+
if sc == "0":
|
|
2012
|
+
return "0"
|
|
2013
|
+
defining_morphism = self.parent().defining_morphism()
|
|
2014
|
+
twisting_morphism = self.parent().twisting_morphism()
|
|
2015
|
+
try:
|
|
2016
|
+
if defining_morphism.is_identity():
|
|
2017
|
+
sdef = "id"
|
|
2018
|
+
else:
|
|
2019
|
+
sdef = "[%s]" % defining_morphism._repr_short()
|
|
2020
|
+
except (AttributeError, NotImplementedError):
|
|
2021
|
+
sdef = "defining_morphism"
|
|
2022
|
+
try:
|
|
2023
|
+
stwi = "[%s]" % twisting_morphism._repr_short()
|
|
2024
|
+
except AttributeError:
|
|
2025
|
+
stwi = "twisting_morphism"
|
|
2026
|
+
if sc == "1":
|
|
2027
|
+
return "%s - %s" % (stwi, sdef)
|
|
2028
|
+
elif sc == "-1":
|
|
2029
|
+
s = "-"
|
|
2030
|
+
elif scalar._is_atomic():
|
|
2031
|
+
s = "%s*" % sc
|
|
2032
|
+
elif (-scalar)._is_atomic():
|
|
2033
|
+
s = "-%s*" % (-scalar)
|
|
2034
|
+
else:
|
|
2035
|
+
s = "(%s)*" % sc
|
|
2036
|
+
return "%s(%s - %s)" % (s, stwi, sdef)
|
|
2037
|
+
|
|
2038
|
+
def _latex_(self):
|
|
2039
|
+
r"""
|
|
2040
|
+
Return a LaTeX representation of this derivation.
|
|
2041
|
+
|
|
2042
|
+
EXAMPLES::
|
|
2043
|
+
|
|
2044
|
+
sage: # needs sage.rings.finite_rings
|
|
2045
|
+
sage: k.<a> = GF(5^3)
|
|
2046
|
+
sage: Frob = k.frobenius_endomorphism()
|
|
2047
|
+
sage: der = k.derivation(a + 1, twist=Frob)
|
|
2048
|
+
sage: latex(der)
|
|
2049
|
+
\left(a + 1\right) \left(\left[a \mapsto a^{5}\right] - \text{id}\right)
|
|
2050
|
+
"""
|
|
2051
|
+
scalar = self._scalar
|
|
2052
|
+
sc = str(scalar)
|
|
2053
|
+
if sc == "0":
|
|
2054
|
+
return "0"
|
|
2055
|
+
defining_morphism = self.parent().defining_morphism()
|
|
2056
|
+
twisting_morphism = self.parent().twisting_morphism()
|
|
2057
|
+
try:
|
|
2058
|
+
if defining_morphism.is_identity():
|
|
2059
|
+
sdef = "\\text{id}"
|
|
2060
|
+
else:
|
|
2061
|
+
sdef = "\\left[%s\\right]" % latex(defining_morphism)
|
|
2062
|
+
except (AttributeError, NotImplementedError):
|
|
2063
|
+
sdef = "\\text{defining morphism}"
|
|
2064
|
+
try:
|
|
2065
|
+
stwi = "\\left[%s\\right]" % latex(twisting_morphism)
|
|
2066
|
+
except AttributeError:
|
|
2067
|
+
stwi = "\\text{twisting morphism}"
|
|
2068
|
+
if sc == "1":
|
|
2069
|
+
return "%s - %s" % (stwi, sdef)
|
|
2070
|
+
elif sc == "-1":
|
|
2071
|
+
s = "-"
|
|
2072
|
+
elif scalar._is_atomic():
|
|
2073
|
+
s = "%s " % sc
|
|
2074
|
+
elif (-scalar)._is_atomic():
|
|
2075
|
+
s = "-%s " % (-scalar)
|
|
2076
|
+
else:
|
|
2077
|
+
s = "\\left(%s\\right) " % sc
|
|
2078
|
+
return "%s \\left(%s - %s\\right)" % (s, stwi, sdef)
|
|
2079
|
+
|
|
2080
|
+
def _add_(self, other):
|
|
2081
|
+
"""
|
|
2082
|
+
Return the sum of this derivation and ``other``.
|
|
2083
|
+
|
|
2084
|
+
EXAMPLES::
|
|
2085
|
+
|
|
2086
|
+
sage: R.<x,y> = ZZ[]
|
|
2087
|
+
sage: theta = R.hom([y,x])
|
|
2088
|
+
sage: der1 = R.derivation(x, twist=theta); der1
|
|
2089
|
+
x*([x |--> y, y |--> x] - id)
|
|
2090
|
+
sage: der2 = R.derivation(y, twist=theta); der2
|
|
2091
|
+
y*([x |--> y, y |--> x] - id)
|
|
2092
|
+
sage: der1 + der2
|
|
2093
|
+
(x + y)*([x |--> y, y |--> x] - id)
|
|
2094
|
+
"""
|
|
2095
|
+
return type(self)(self.parent(), self._scalar + other._scalar)
|
|
2096
|
+
|
|
2097
|
+
def _sub_(self, other):
|
|
2098
|
+
"""
|
|
2099
|
+
Return the subtraction of this derivation and ``other``.
|
|
2100
|
+
|
|
2101
|
+
EXAMPLES::
|
|
2102
|
+
|
|
2103
|
+
sage: R.<x,y> = ZZ[]
|
|
2104
|
+
sage: theta = R.hom([y,x])
|
|
2105
|
+
sage: der1 = R.derivation(x, twist=theta); der1
|
|
2106
|
+
x*([x |--> y, y |--> x] - id)
|
|
2107
|
+
sage: der2 = R.derivation(y, twist=theta); der2
|
|
2108
|
+
y*([x |--> y, y |--> x] - id)
|
|
2109
|
+
sage: der1 - der2
|
|
2110
|
+
(x - y)*([x |--> y, y |--> x] - id)
|
|
2111
|
+
|
|
2112
|
+
TESTS::
|
|
2113
|
+
|
|
2114
|
+
sage: der1 - der1
|
|
2115
|
+
0
|
|
2116
|
+
sage: der2 - der2
|
|
2117
|
+
0
|
|
2118
|
+
"""
|
|
2119
|
+
return type(self)(self.parent(), self._scalar - other._scalar)
|
|
2120
|
+
|
|
2121
|
+
def _rmul_(self, factor):
|
|
2122
|
+
"""
|
|
2123
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
2124
|
+
|
|
2125
|
+
EXAMPLES::
|
|
2126
|
+
|
|
2127
|
+
sage: R.<x,y> = ZZ[]
|
|
2128
|
+
sage: theta = R.hom([y,x])
|
|
2129
|
+
sage: D = R.derivation(x, twist=theta); D
|
|
2130
|
+
x*([x |--> y, y |--> x] - id)
|
|
2131
|
+
sage: y * D
|
|
2132
|
+
x*y*([x |--> y, y |--> x] - id)
|
|
2133
|
+
"""
|
|
2134
|
+
return type(self)(self.parent(), factor * self._scalar)
|
|
2135
|
+
|
|
2136
|
+
def _lmul_(self, factor):
|
|
2137
|
+
"""
|
|
2138
|
+
Return the product of this derivation by the scalar ``factor``.
|
|
2139
|
+
|
|
2140
|
+
EXAMPLES::
|
|
2141
|
+
|
|
2142
|
+
sage: R.<x,y> = ZZ[]
|
|
2143
|
+
sage: theta = R.hom([y,x])
|
|
2144
|
+
sage: D = R.derivation(x, twist=theta); D
|
|
2145
|
+
x*([x |--> y, y |--> x] - id)
|
|
2146
|
+
sage: D * y
|
|
2147
|
+
x*y*([x |--> y, y |--> x] - id)
|
|
2148
|
+
"""
|
|
2149
|
+
return self._rmul_(factor)
|
|
2150
|
+
|
|
2151
|
+
def _call_(self, x):
|
|
2152
|
+
"""
|
|
2153
|
+
Return the image of ``x`` under this derivation.
|
|
2154
|
+
|
|
2155
|
+
EXAMPLES::
|
|
2156
|
+
|
|
2157
|
+
sage: R.<x,y> = ZZ[]
|
|
2158
|
+
sage: theta = R.hom([y,x])
|
|
2159
|
+
sage: f = R.derivation(1, twist=theta); f
|
|
2160
|
+
[x |--> y, y |--> x] - id
|
|
2161
|
+
sage: f(x)
|
|
2162
|
+
-x + y
|
|
2163
|
+
"""
|
|
2164
|
+
parent = self.parent()
|
|
2165
|
+
return self._scalar * (parent.twisting_morphism()(x) - parent.defining_morphism()(x))
|
|
2166
|
+
|
|
2167
|
+
def list(self):
|
|
2168
|
+
"""
|
|
2169
|
+
Return the list of coefficient of this twisted derivation
|
|
2170
|
+
on the canonical basis.
|
|
2171
|
+
|
|
2172
|
+
EXAMPLES::
|
|
2173
|
+
|
|
2174
|
+
sage: R.<x,y> = QQ[]
|
|
2175
|
+
sage: K = R.fraction_field()
|
|
2176
|
+
sage: theta = K.hom([y,x])
|
|
2177
|
+
sage: M = K.derivation_module(twist=theta)
|
|
2178
|
+
sage: M.basis()
|
|
2179
|
+
Family (twisting_morphism - id,)
|
|
2180
|
+
sage: f = (x+y) * M.gen()
|
|
2181
|
+
sage: f
|
|
2182
|
+
(x + y)*(twisting_morphism - id)
|
|
2183
|
+
sage: f.list()
|
|
2184
|
+
[x + y]
|
|
2185
|
+
"""
|
|
2186
|
+
return [ self._scalar ]
|
|
2187
|
+
|
|
2188
|
+
def precompose(self, morphism):
|
|
2189
|
+
r"""
|
|
2190
|
+
Return the twisted derivation obtained by applying first
|
|
2191
|
+
``morphism`` and then this twisted derivation.
|
|
2192
|
+
|
|
2193
|
+
INPUT:
|
|
2194
|
+
|
|
2195
|
+
- ``morphism`` -- a homomorphism of rings whose codomain is
|
|
2196
|
+
the domain of this derivation or a ring that coerces to
|
|
2197
|
+
the domain of this derivation
|
|
2198
|
+
|
|
2199
|
+
EXAMPLES::
|
|
2200
|
+
|
|
2201
|
+
sage: R.<x,y> = ZZ[]
|
|
2202
|
+
sage: theta = R.hom([y,x])
|
|
2203
|
+
sage: D = R.derivation(x, twist=theta); D
|
|
2204
|
+
x*([x |--> y, y |--> x] - id)
|
|
2205
|
+
|
|
2206
|
+
sage: f = R.hom([x^2, y^3])
|
|
2207
|
+
sage: g = D.postcompose(f); g
|
|
2208
|
+
x^2*([x |--> y^3, y |--> x^2] - [x |--> x^2, y |--> y^3])
|
|
2209
|
+
|
|
2210
|
+
Observe that the `g` is no longer a `\theta`-derivation but
|
|
2211
|
+
a `(f \circ \theta)`-derivation::
|
|
2212
|
+
|
|
2213
|
+
sage: g.parent().twisting_morphism()
|
|
2214
|
+
Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring
|
|
2215
|
+
Defn: x |--> y^3
|
|
2216
|
+
y |--> x^2
|
|
2217
|
+
"""
|
|
2218
|
+
parent = self.parent()
|
|
2219
|
+
if morphism in Rings().Commutative():
|
|
2220
|
+
if parent.domain().has_coerce_map_from(morphism):
|
|
2221
|
+
morphism = parent.domain().coerce_map_from(morphism)
|
|
2222
|
+
else:
|
|
2223
|
+
raise TypeError("the given ring does not coerce to the domain of the derivation")
|
|
2224
|
+
elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())):
|
|
2225
|
+
raise TypeError("you must give a homomorphism of rings")
|
|
2226
|
+
M = RingDerivationModule(morphism.domain(), parent.defining_morphism() * morphism,
|
|
2227
|
+
parent.twisting_morphism() * morphism)
|
|
2228
|
+
return M(self._scalar)
|
|
2229
|
+
|
|
2230
|
+
def postcompose(self, morphism):
|
|
2231
|
+
r"""
|
|
2232
|
+
Return the twisted derivation obtained by applying first
|
|
2233
|
+
this twisted derivation and then ``morphism``.
|
|
2234
|
+
|
|
2235
|
+
INPUT:
|
|
2236
|
+
|
|
2237
|
+
- ``morphism`` -- a homomorphism of rings whose domain is
|
|
2238
|
+
the codomain of this derivation or a ring into which the
|
|
2239
|
+
codomain of this derivation
|
|
2240
|
+
|
|
2241
|
+
EXAMPLES::
|
|
2242
|
+
|
|
2243
|
+
sage: R.<x,y> = ZZ[]
|
|
2244
|
+
sage: theta = R.hom([y,x])
|
|
2245
|
+
sage: D = R.derivation(x, twist=theta); D
|
|
2246
|
+
x*([x |--> y, y |--> x] - id)
|
|
2247
|
+
|
|
2248
|
+
sage: f = R.hom([x^2, y^3])
|
|
2249
|
+
sage: g = D.precompose(f); g
|
|
2250
|
+
x*([x |--> y^2, y |--> x^3] - [x |--> x^2, y |--> y^3])
|
|
2251
|
+
|
|
2252
|
+
Observe that the `g` is no longer a `\theta`-derivation but
|
|
2253
|
+
a `(\theta \circ f)`-derivation::
|
|
2254
|
+
|
|
2255
|
+
sage: g.parent().twisting_morphism()
|
|
2256
|
+
Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring
|
|
2257
|
+
Defn: x |--> y^2
|
|
2258
|
+
y |--> x^3
|
|
2259
|
+
"""
|
|
2260
|
+
parent = self.parent()
|
|
2261
|
+
if morphism in Rings().Commutative():
|
|
2262
|
+
if morphism.has_coerce_map_from(parent.codomain()):
|
|
2263
|
+
morphism = morphism.coerce_map_from(parent.codomain())
|
|
2264
|
+
else:
|
|
2265
|
+
raise TypeError("the codomain of the derivation does not coerce to the given ring")
|
|
2266
|
+
elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())):
|
|
2267
|
+
raise TypeError("you must give a homomorphism of rings")
|
|
2268
|
+
M = RingDerivationModule(parent.domain(), morphism * parent.defining_morphism(),
|
|
2269
|
+
morphism * parent.twisting_morphism())
|
|
2270
|
+
return M(morphism(self._scalar))
|
|
2271
|
+
|
|
2272
|
+
def _richcmp_(self, other, op):
|
|
2273
|
+
"""
|
|
2274
|
+
Compare this derivation with ``other`` according
|
|
2275
|
+
to the comparison operator ``op``.
|
|
2276
|
+
|
|
2277
|
+
EXAMPLES::
|
|
2278
|
+
|
|
2279
|
+
sage: R.<x,y> = ZZ[]
|
|
2280
|
+
sage: theta = R.hom([y,x])
|
|
2281
|
+
sage: Dx = R.derivation(x, twist=theta); Dx
|
|
2282
|
+
x*([x |--> y, y |--> x] - id)
|
|
2283
|
+
sage: Dy = R.derivation(y, twist=theta); Dy
|
|
2284
|
+
y*([x |--> y, y |--> x] - id)
|
|
2285
|
+
sage: D = R.derivation(x+y, twist=theta); D
|
|
2286
|
+
(x + y)*([x |--> y, y |--> x] - id)
|
|
2287
|
+
|
|
2288
|
+
sage: Dx == Dy
|
|
2289
|
+
False
|
|
2290
|
+
sage: D == Dx + Dy
|
|
2291
|
+
True
|
|
2292
|
+
|
|
2293
|
+
sage: D != Dy
|
|
2294
|
+
True
|
|
2295
|
+
"""
|
|
2296
|
+
if op == op_EQ:
|
|
2297
|
+
if isinstance(other, RingDerivationWithTwist_generic):
|
|
2298
|
+
return self._scalar == other._scalar
|
|
2299
|
+
else:
|
|
2300
|
+
return False
|
|
2301
|
+
if op == op_NE:
|
|
2302
|
+
if isinstance(other, RingDerivationWithTwist_generic):
|
|
2303
|
+
return self._scalar != other._scalar
|
|
2304
|
+
else:
|
|
2305
|
+
return True
|
|
2306
|
+
return NotImplemented
|
|
2307
|
+
|
|
2308
|
+
def extend_to_fraction_field(self):
|
|
2309
|
+
r"""
|
|
2310
|
+
Return the extension of this derivation to fraction fields of
|
|
2311
|
+
the domain and the codomain.
|
|
2312
|
+
|
|
2313
|
+
EXAMPLES::
|
|
2314
|
+
|
|
2315
|
+
sage: R.<x,y> = ZZ[]
|
|
2316
|
+
sage: theta = R.hom([y,x])
|
|
2317
|
+
sage: d = R.derivation(x, twist=theta)
|
|
2318
|
+
sage: d
|
|
2319
|
+
x*([x |--> y, y |--> x] - id)
|
|
2320
|
+
|
|
2321
|
+
sage: D = d.extend_to_fraction_field(); D # needs sage.libs.singular
|
|
2322
|
+
x*([x |--> y, y |--> x] - id)
|
|
2323
|
+
sage: D.domain() # needs sage.libs.singular
|
|
2324
|
+
Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring
|
|
2325
|
+
|
|
2326
|
+
sage: D(1/x) # needs sage.libs.singular
|
|
2327
|
+
(x - y)/y
|
|
2328
|
+
"""
|
|
2329
|
+
parent = self.parent()
|
|
2330
|
+
domain = parent.domain().fraction_field()
|
|
2331
|
+
codomain = parent.codomain().fraction_field()
|
|
2332
|
+
twist = parent.twisting_morphism().extend_to_fraction_field()
|
|
2333
|
+
M = RingDerivationModule(domain, codomain, twist)
|
|
2334
|
+
return M(codomain(self._scalar))
|