passagemath-modules 10.6.31rc3__cp314-cp314-musllinux_1_2_x86_64.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 +808 -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-0cd532bd.so.1 +0 -0
- passagemath_modules.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-42cda06f.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-d8ebe4b5.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
- passagemath_modules.libs/libquadmath-bb76a5fc.so.0.0.0 +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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,2023 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
r"""
|
|
3
|
+
Elements of multivariate Laurent polynomial rings
|
|
4
|
+
"""
|
|
5
|
+
# ****************************************************************************
|
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
# https://www.gnu.org/licenses/
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
|
|
13
|
+
from sage.rings.integer cimport Integer
|
|
14
|
+
from sage.structure.element cimport CommutativeAlgebraElement, Element, ModuleElement, RingElement
|
|
15
|
+
from sage.structure.element import coerce_binop, parent
|
|
16
|
+
from sage.structure.factorization import Factorization
|
|
17
|
+
from sage.misc.derivative import multi_derivative
|
|
18
|
+
from sage.rings.polynomial.polydict cimport monomial_exponent
|
|
19
|
+
from sage.matrix.matrix0 cimport Matrix
|
|
20
|
+
from sage.rings.infinity import Infinity, minus_infinity
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
cdef class LaurentPolynomial_mpair(LaurentPolynomial):
|
|
24
|
+
"""
|
|
25
|
+
Multivariate Laurent polynomials.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, parent, x, mon=None, reduce=True):
|
|
29
|
+
"""
|
|
30
|
+
Currently, one can only create LaurentPolynomials out of dictionaries
|
|
31
|
+
and elements of the base ring.
|
|
32
|
+
|
|
33
|
+
INPUT:
|
|
34
|
+
|
|
35
|
+
- ``parent`` -- a SageMath parent
|
|
36
|
+
|
|
37
|
+
- ``x`` -- an element or dictionary or anything the underlying
|
|
38
|
+
polynomial ring accepts
|
|
39
|
+
|
|
40
|
+
- ``mon`` -- (default: ``None``) a tuple specifying the shift
|
|
41
|
+
in the exponents
|
|
42
|
+
|
|
43
|
+
- ``reduce`` -- boolean (default: ``True``)
|
|
44
|
+
|
|
45
|
+
EXAMPLES::
|
|
46
|
+
|
|
47
|
+
sage: L.<w,z> = LaurentPolynomialRing(QQ)
|
|
48
|
+
sage: f = L({(-1,-1):1}); f
|
|
49
|
+
w^-1*z^-1
|
|
50
|
+
sage: f = L({(1,1):1}); f
|
|
51
|
+
w*z
|
|
52
|
+
sage: f = L({(-1,-1):1, (1,3):4}); f
|
|
53
|
+
4*w*z^3 + w^-1*z^-1
|
|
54
|
+
sage: L(1/2)
|
|
55
|
+
1/2
|
|
56
|
+
|
|
57
|
+
TESTS:
|
|
58
|
+
|
|
59
|
+
Check that :issue:`19538` is fixed::
|
|
60
|
+
|
|
61
|
+
sage: R = LaurentPolynomialRing(QQ,'x2,x0')
|
|
62
|
+
sage: S = LaurentPolynomialRing(QQ,'x',3)
|
|
63
|
+
sage: f = S.coerce_map_from(R)
|
|
64
|
+
sage: f(R.gen(0) + R.gen(1)^2)
|
|
65
|
+
x0^2 + x2
|
|
66
|
+
sage: _.parent()
|
|
67
|
+
Multivariate Laurent Polynomial Ring in x0, x1, x2 over Rational Field
|
|
68
|
+
|
|
69
|
+
::
|
|
70
|
+
|
|
71
|
+
sage: from sage.rings.polynomial.laurent_polynomial_mpair import LaurentPolynomial_mpair
|
|
72
|
+
sage: LaurentPolynomial_mpair(L, {(1,2): 1/42}, mon=(-3, -3))
|
|
73
|
+
1/42*w^-2*z^-1
|
|
74
|
+
|
|
75
|
+
:issue:`22398`::
|
|
76
|
+
|
|
77
|
+
sage: LQ = LaurentPolynomialRing(QQ, 'x0, x1, x2, y0, y1, y2, y3, y4, y5')
|
|
78
|
+
sage: LZ = LaurentPolynomialRing(ZZ, 'x0, x1, x2, y0, y1, y2, y3, y4, y5')
|
|
79
|
+
sage: LQ.inject_variables()
|
|
80
|
+
Defining x0, x1, x2, y0, y1, y2, y3, y4, y5
|
|
81
|
+
sage: x2^-1*y0*y1*y2*y3*y4*y5 + x1^-1*x2^-1*y0*y1*y3*y4 + x0^-1 in LZ
|
|
82
|
+
True
|
|
83
|
+
sage: x2^-1*y0*y1*y2*y3*y4*y5 + x1^-1*x2^-1*y0*y1*y3*y4 + x0^-1*x1^-1*y0*y3 + x0^-1 in LZ
|
|
84
|
+
True
|
|
85
|
+
|
|
86
|
+
Check that input is not modified::
|
|
87
|
+
|
|
88
|
+
sage: LQ.<x,y> = LaurentPolynomialRing(QQ)
|
|
89
|
+
sage: D = {(-1, 1): 1}
|
|
90
|
+
sage: k = tuple(D)[0]
|
|
91
|
+
sage: v = D[k]
|
|
92
|
+
sage: type(k), type(v)
|
|
93
|
+
(<... 'tuple'>, <class 'sage.rings.integer.Integer'>)
|
|
94
|
+
sage: LQ(D)
|
|
95
|
+
x^-1*y
|
|
96
|
+
sage: tuple(D)[0] is k
|
|
97
|
+
True
|
|
98
|
+
sage: D[k] is v
|
|
99
|
+
True
|
|
100
|
+
"""
|
|
101
|
+
if isinstance(x, PolyDict):
|
|
102
|
+
x = x.dict()
|
|
103
|
+
if mon is not None:
|
|
104
|
+
if isinstance(mon, ETuple):
|
|
105
|
+
self._mon = mon
|
|
106
|
+
else:
|
|
107
|
+
self._mon = ETuple(mon)
|
|
108
|
+
else:
|
|
109
|
+
if isinstance(x, dict):
|
|
110
|
+
self._mon = ETuple({}, int(parent.ngens()))
|
|
111
|
+
D = {}
|
|
112
|
+
for k, x_k in x.items(): # ETuple-ize keys, set _mon
|
|
113
|
+
if not isinstance(k, (tuple, ETuple)) or len(k) != parent.ngens():
|
|
114
|
+
self._mon = ETuple({}, int(parent.ngens()))
|
|
115
|
+
break
|
|
116
|
+
if isinstance(k, tuple):
|
|
117
|
+
k = ETuple(k)
|
|
118
|
+
D[k] = x_k
|
|
119
|
+
self._mon = self._mon.emin(k) # point-wise min of _mon and k
|
|
120
|
+
else:
|
|
121
|
+
x = D
|
|
122
|
+
if not self._mon.is_constant(): # factor out _mon
|
|
123
|
+
x = {k.esub(self._mon): x_k for k, x_k in x.items()}
|
|
124
|
+
elif (isinstance(x, LaurentPolynomial_mpair) and
|
|
125
|
+
parent.variable_names() == x.parent().variable_names()):
|
|
126
|
+
self._mon = ( < LaurentPolynomial_mpair > x)._mon
|
|
127
|
+
x = ( < LaurentPolynomial_mpair > x)._poly
|
|
128
|
+
else: # since x should coerce into parent, _mon should be (0,...,0)
|
|
129
|
+
self._mon = ETuple({}, int(parent.ngens()))
|
|
130
|
+
self._poly = parent._R(x)
|
|
131
|
+
CommutativeAlgebraElement.__init__(self, parent)
|
|
132
|
+
|
|
133
|
+
def __reduce__(self):
|
|
134
|
+
"""
|
|
135
|
+
TESTS::
|
|
136
|
+
|
|
137
|
+
sage: R = LaurentPolynomialRing(QQ, 2, 'x')
|
|
138
|
+
sage: R.<x1,x2> = LaurentPolynomialRing(QQ)
|
|
139
|
+
sage: loads(dumps(x1)) == x1 # indirect doctest
|
|
140
|
+
True
|
|
141
|
+
sage: z = x1/x2
|
|
142
|
+
sage: loads(dumps(z)) == z
|
|
143
|
+
True
|
|
144
|
+
"""
|
|
145
|
+
return self._parent, (self._poly, self._mon)
|
|
146
|
+
|
|
147
|
+
def __hash__(self):
|
|
148
|
+
r"""
|
|
149
|
+
TESTS:
|
|
150
|
+
|
|
151
|
+
Test that the hash is non-constant (see also :issue:`27914`)::
|
|
152
|
+
|
|
153
|
+
sage: L.<w,z> = LaurentPolynomialRing(QQ)
|
|
154
|
+
sage: len({hash(w^i*z^j) for i in [-2..2] for j in [-2..2]})
|
|
155
|
+
25
|
|
156
|
+
|
|
157
|
+
Check that :issue:`20490` is fixed::
|
|
158
|
+
|
|
159
|
+
sage: R.<a,b> = LaurentPolynomialRing(ZZ)
|
|
160
|
+
sage: p = a*~a
|
|
161
|
+
sage: p._fraction_pair()
|
|
162
|
+
(a, a)
|
|
163
|
+
sage: p == R.one()
|
|
164
|
+
True
|
|
165
|
+
sage: hash(p)
|
|
166
|
+
1
|
|
167
|
+
|
|
168
|
+
Check that :issue:`23864` is fixed (compatibility with integers, rationals
|
|
169
|
+
and polynomial rings)::
|
|
170
|
+
|
|
171
|
+
sage: L = LaurentPolynomialRing(QQ, 'x0,x1,x2')
|
|
172
|
+
sage: hash(L.zero())
|
|
173
|
+
0
|
|
174
|
+
sage: hash(L.one())
|
|
175
|
+
1
|
|
176
|
+
sage: hash(-L.one())
|
|
177
|
+
-2
|
|
178
|
+
sage: hash(L(1/2)) == hash(1/2)
|
|
179
|
+
True
|
|
180
|
+
|
|
181
|
+
sage: R = PolynomialRing(QQ, 'x0,x1,x2')
|
|
182
|
+
sage: x0,x1,x2 = R.gens()
|
|
183
|
+
sage: hash(x0) == hash(L(x0))
|
|
184
|
+
True
|
|
185
|
+
sage: hash(1 - 7*x0 + x1*x2) == hash(L(1 - 7*x0 + x1*x2))
|
|
186
|
+
True
|
|
187
|
+
|
|
188
|
+
Check that :issue:`27914` is fixed::
|
|
189
|
+
|
|
190
|
+
sage: L.<w,z> = LaurentPolynomialRing(QQ)
|
|
191
|
+
sage: Lw = LaurentPolynomialRing(QQ, 'w')
|
|
192
|
+
sage: Lz = LaurentPolynomialRing(QQ, 'z')
|
|
193
|
+
sage: all(hash(w^k) == hash(Lw(w^k))
|
|
194
|
+
....: and hash(z^k) == hash(Lz(z^k)) for k in (-5..5))
|
|
195
|
+
True
|
|
196
|
+
sage: p = w^-1 + 2 + w
|
|
197
|
+
sage: hash(p) == hash(Lw(p))
|
|
198
|
+
True
|
|
199
|
+
"""
|
|
200
|
+
# we reimplement the hash from multipolynomial to handle negative exponents
|
|
201
|
+
# (see multi_polynomial.pyx)
|
|
202
|
+
cdef long result = 0
|
|
203
|
+
cdef long exponent
|
|
204
|
+
cdef list var_name_hash = [hash(v) for v in self._parent.variable_names()]
|
|
205
|
+
cdef int p
|
|
206
|
+
cdef int n = len(var_name_hash)
|
|
207
|
+
cdef long c_hash
|
|
208
|
+
for m, c in self._poly.iterator_exp_coeff():
|
|
209
|
+
c_hash = hash(c)
|
|
210
|
+
if c_hash != 0:
|
|
211
|
+
for p in range(n):
|
|
212
|
+
exponent = m[p] + self._mon[p]
|
|
213
|
+
if exponent > 0:
|
|
214
|
+
c_hash = (1000003 * c_hash) ^ var_name_hash[p]
|
|
215
|
+
c_hash = (1000003 * c_hash) ^ exponent
|
|
216
|
+
elif exponent < 0:
|
|
217
|
+
c_hash = (1000003 * c_hash) ^ var_name_hash[p]
|
|
218
|
+
c_hash = (700005 * c_hash) ^ exponent
|
|
219
|
+
result += c_hash
|
|
220
|
+
|
|
221
|
+
return result
|
|
222
|
+
|
|
223
|
+
def _im_gens_(self, codomain, im_gens, base_map=None):
|
|
224
|
+
"""
|
|
225
|
+
Return the image of ``self`` under the morphism defined by
|
|
226
|
+
``im_gens`` in ``codomain``.
|
|
227
|
+
|
|
228
|
+
EXAMPLES::
|
|
229
|
+
|
|
230
|
+
sage: L.<x,y> = LaurentPolynomialRing(ZZ)
|
|
231
|
+
sage: M.<u,v> = LaurentPolynomialRing(ZZ)
|
|
232
|
+
sage: phi = L.hom([u,v])
|
|
233
|
+
sage: phi(x^2*~y -5*y**3) # indirect doctest
|
|
234
|
+
-5*v^3 + u^2*v^-1
|
|
235
|
+
|
|
236
|
+
TESTS:
|
|
237
|
+
|
|
238
|
+
check compatibility with :issue:`26105`::
|
|
239
|
+
|
|
240
|
+
sage: # needs sage.rings.finite_rings
|
|
241
|
+
sage: F.<t> = GF(4)
|
|
242
|
+
sage: LF.<a,b> = LaurentPolynomialRing(F)
|
|
243
|
+
sage: rho = LF.hom([b,a], base_map=F.frobenius_endomorphism())
|
|
244
|
+
sage: s = t*~a + b +~t*(b**-3)*a**2; rs = rho(s); rs
|
|
245
|
+
a + (t + 1)*b^-1 + t*a^-3*b^2
|
|
246
|
+
sage: s == rho(rs)
|
|
247
|
+
True
|
|
248
|
+
"""
|
|
249
|
+
p = self._poly
|
|
250
|
+
m = self._mon
|
|
251
|
+
if base_map is not None:
|
|
252
|
+
p = p.map_coefficients(base_map)
|
|
253
|
+
from sage.misc.misc_c import prod
|
|
254
|
+
return codomain(p(im_gens) * prod(ig**m[im_gens.index(ig)] for ig in im_gens))
|
|
255
|
+
|
|
256
|
+
cdef _normalize(self, i=None):
|
|
257
|
+
r"""
|
|
258
|
+
Remove the common monomials from ``self._poly`` and store
|
|
259
|
+
them in ``self._mon``.
|
|
260
|
+
|
|
261
|
+
INPUT:
|
|
262
|
+
|
|
263
|
+
- ``i`` -- integer
|
|
264
|
+
|
|
265
|
+
EXAMPLES::
|
|
266
|
+
|
|
267
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ)
|
|
268
|
+
sage: f = x*y + 2*y*x^2 + y # indirect doctest
|
|
269
|
+
sage: f.factor() # Notice the y has been factored out.
|
|
270
|
+
(y) * (2*x^2 + x + 1)
|
|
271
|
+
|
|
272
|
+
Check that :issue:`23864` has been fixed::
|
|
273
|
+
|
|
274
|
+
sage: hash(L.zero())
|
|
275
|
+
0
|
|
276
|
+
"""
|
|
277
|
+
if not self._poly:
|
|
278
|
+
self._mon = ETuple({}, int(self._parent.ngens()))
|
|
279
|
+
return
|
|
280
|
+
|
|
281
|
+
# cdef dict D = <dict> self._poly._mpoly_dict_recursive(
|
|
282
|
+
# <tuple> self._parent.variable_names(),
|
|
283
|
+
# self._parent.base_ring()
|
|
284
|
+
# )
|
|
285
|
+
cdef dict D = <dict > self._poly.monomial_coefficients()
|
|
286
|
+
|
|
287
|
+
cdef ETuple e
|
|
288
|
+
if i is None:
|
|
289
|
+
e = None
|
|
290
|
+
for k in D:
|
|
291
|
+
if e is None:
|
|
292
|
+
e = <ETuple > k
|
|
293
|
+
else:
|
|
294
|
+
e = e.emin(k)
|
|
295
|
+
if not e.is_constant():
|
|
296
|
+
self._poly = <ModuleElement > (self._poly // self._poly._parent({e: 1}))
|
|
297
|
+
self._mon = self._mon.eadd(e)
|
|
298
|
+
else:
|
|
299
|
+
e = None
|
|
300
|
+
for k in D:
|
|
301
|
+
if e is None or k[i] < e:
|
|
302
|
+
e = <ETuple > k[i]
|
|
303
|
+
if e > 0:
|
|
304
|
+
self._poly = <ModuleElement > (self._poly // self._poly._parent.gen(i))
|
|
305
|
+
self._mon = self._mon.eadd_p(e, i)
|
|
306
|
+
|
|
307
|
+
cdef _compute_polydict(self):
|
|
308
|
+
"""
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: L.<w,z> = LaurentPolynomialRing(QQ)
|
|
312
|
+
sage: a = w^2*z^-1 +3
|
|
313
|
+
sage: a.monomial_coefficients() # indirect doctest
|
|
314
|
+
{(0, 0): 3, (2, -1): 1}
|
|
315
|
+
"""
|
|
316
|
+
# cdef dict D = <dict> self._poly._mpoly_dict_recursive(self._parent.variable_names(),
|
|
317
|
+
# self._parent.base_ring())
|
|
318
|
+
cdef dict D = <dict > self._poly.monomial_coefficients()
|
|
319
|
+
cdef dict DD
|
|
320
|
+
if self._mon.is_constant():
|
|
321
|
+
self._prod = PolyDict(D)
|
|
322
|
+
return
|
|
323
|
+
DD = {}
|
|
324
|
+
for k in D:
|
|
325
|
+
DD[k.eadd(self._mon)] = D[k]
|
|
326
|
+
self._prod = PolyDict(DD)
|
|
327
|
+
|
|
328
|
+
def is_unit(self):
|
|
329
|
+
"""
|
|
330
|
+
Return ``True`` if ``self`` is a unit.
|
|
331
|
+
|
|
332
|
+
The ground ring is assumed to be an integral domain.
|
|
333
|
+
|
|
334
|
+
This means that the Laurent polynomial is a monomial
|
|
335
|
+
with unit coefficient.
|
|
336
|
+
|
|
337
|
+
EXAMPLES::
|
|
338
|
+
|
|
339
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ)
|
|
340
|
+
sage: (x*y/2).is_unit()
|
|
341
|
+
True
|
|
342
|
+
sage: (x + y).is_unit()
|
|
343
|
+
False
|
|
344
|
+
sage: (L.zero()).is_unit()
|
|
345
|
+
False
|
|
346
|
+
sage: (L.one()).is_unit()
|
|
347
|
+
True
|
|
348
|
+
|
|
349
|
+
sage: L.<x,y> = LaurentPolynomialRing(ZZ)
|
|
350
|
+
sage: (2*x*y).is_unit()
|
|
351
|
+
False
|
|
352
|
+
"""
|
|
353
|
+
coeffs = self.coefficients()
|
|
354
|
+
if len(coeffs) != 1:
|
|
355
|
+
return False
|
|
356
|
+
return coeffs[0].is_unit()
|
|
357
|
+
|
|
358
|
+
def _repr_(self):
|
|
359
|
+
"""
|
|
360
|
+
EXAMPLES::
|
|
361
|
+
|
|
362
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ)
|
|
363
|
+
sage: f = x^2 + x*y/2 + 2*y^-1
|
|
364
|
+
sage: f._repr_()
|
|
365
|
+
'x^2 + 1/2*x*y + 2*y^-1'
|
|
366
|
+
"""
|
|
367
|
+
if self._prod is None:
|
|
368
|
+
self._compute_polydict()
|
|
369
|
+
try:
|
|
370
|
+
key = self.parent().term_order().sortkey
|
|
371
|
+
except AttributeError:
|
|
372
|
+
key = None
|
|
373
|
+
atomic = self.parent().base_ring()._repr_option('element_is_atomic')
|
|
374
|
+
return self._prod.poly_repr(self.parent().variable_names(),
|
|
375
|
+
atomic_coefficients=atomic, sortkey=key)
|
|
376
|
+
|
|
377
|
+
def _latex_(self):
|
|
378
|
+
r"""
|
|
379
|
+
EXAMPLES::
|
|
380
|
+
|
|
381
|
+
sage: L.<w,z> = LaurentPolynomialRing(QQ)
|
|
382
|
+
sage: a = w^2*z^-1+3; a
|
|
383
|
+
w^2*z^-1 + 3
|
|
384
|
+
sage: latex(a)
|
|
385
|
+
w^{2} z^{-1} + 3
|
|
386
|
+
|
|
387
|
+
TESTS::
|
|
388
|
+
|
|
389
|
+
sage: L.<lambda2, y2> = LaurentPolynomialRing(QQ)
|
|
390
|
+
sage: latex(1/lambda2 + y2^(-3))
|
|
391
|
+
\lambda_{2}^{-1} + y_{2}^{-3}
|
|
392
|
+
"""
|
|
393
|
+
if self._prod is None:
|
|
394
|
+
self._compute_polydict()
|
|
395
|
+
try:
|
|
396
|
+
key = self.parent().term_order().sortkey
|
|
397
|
+
except AttributeError:
|
|
398
|
+
key = None
|
|
399
|
+
atomic = self.parent().base_ring()._repr_option('element_is_atomic')
|
|
400
|
+
return self._prod.latex(self.parent().latex_variable_names(),
|
|
401
|
+
atomic_coefficients=atomic, sortkey=key)
|
|
402
|
+
|
|
403
|
+
cpdef long number_of_terms(self) except -1:
|
|
404
|
+
"""
|
|
405
|
+
Return the number of nonzero coefficients of ``self``.
|
|
406
|
+
|
|
407
|
+
Also called weight, hamming weight or sparsity.
|
|
408
|
+
|
|
409
|
+
EXAMPLES::
|
|
410
|
+
|
|
411
|
+
sage: R.<x, y> = LaurentPolynomialRing(ZZ)
|
|
412
|
+
sage: f = x^3 - y
|
|
413
|
+
sage: f.number_of_terms()
|
|
414
|
+
2
|
|
415
|
+
sage: R(0).number_of_terms()
|
|
416
|
+
0
|
|
417
|
+
sage: f = (x+1/y)^100
|
|
418
|
+
sage: f.number_of_terms()
|
|
419
|
+
101
|
|
420
|
+
|
|
421
|
+
The method :meth:`hamming_weight` is an alias::
|
|
422
|
+
|
|
423
|
+
sage: f.hamming_weight()
|
|
424
|
+
101
|
|
425
|
+
"""
|
|
426
|
+
return self._poly.number_of_terms()
|
|
427
|
+
|
|
428
|
+
def __invert__(LaurentPolynomial_mpair self):
|
|
429
|
+
"""
|
|
430
|
+
Return the inverse of ``self``.
|
|
431
|
+
|
|
432
|
+
This treats monomials specially so they remain Laurent
|
|
433
|
+
polynomials; the inverse of any other polynomial is an element
|
|
434
|
+
of the rational function field.
|
|
435
|
+
|
|
436
|
+
TESTS::
|
|
437
|
+
|
|
438
|
+
sage: L.<x,y> = LaurentPolynomialRing(ZZ)
|
|
439
|
+
sage: f = ~x
|
|
440
|
+
sage: parent(f)
|
|
441
|
+
Multivariate Laurent Polynomial Ring in x, y over Integer Ring
|
|
442
|
+
sage: parent(f.coefficients()[0]) is parent(f).base_ring()
|
|
443
|
+
True
|
|
444
|
+
sage: g = ~(2*x)
|
|
445
|
+
sage: parent(g)
|
|
446
|
+
Multivariate Laurent Polynomial Ring in x, y over Rational Field
|
|
447
|
+
sage: parent(g.coefficients()[0]) is parent(g).base_ring()
|
|
448
|
+
True
|
|
449
|
+
"""
|
|
450
|
+
cdef ETuple e
|
|
451
|
+
if self._poly.is_term():
|
|
452
|
+
(e, c), = self.monomial_coefficients().items()
|
|
453
|
+
e = e.emul(-1)
|
|
454
|
+
P = self._parent
|
|
455
|
+
try:
|
|
456
|
+
c = c.inverse_of_unit()
|
|
457
|
+
except (AttributeError, ZeroDivisionError, ArithmeticError):
|
|
458
|
+
c = ~c
|
|
459
|
+
if c.parent() is not P.base_ring():
|
|
460
|
+
P = P.change_ring(c.parent())
|
|
461
|
+
return P({e: c})
|
|
462
|
+
return super().__invert__()
|
|
463
|
+
|
|
464
|
+
def __pow__(LaurentPolynomial_mpair self, n, mod):
|
|
465
|
+
"""
|
|
466
|
+
EXAMPLES::
|
|
467
|
+
|
|
468
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ)
|
|
469
|
+
sage: f = x + y
|
|
470
|
+
sage: f^2
|
|
471
|
+
x^2 + 2*x*y + y^2
|
|
472
|
+
sage: f^(-1)
|
|
473
|
+
1/(x + y)
|
|
474
|
+
|
|
475
|
+
TESTS:
|
|
476
|
+
|
|
477
|
+
Check that :issue:`2952` is fixed::
|
|
478
|
+
|
|
479
|
+
sage: R.<q> = QQ[]
|
|
480
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(R)
|
|
481
|
+
sage: f = (x+y+z^-1)^2
|
|
482
|
+
sage: f.substitute(z=1)
|
|
483
|
+
x^2 + 2*x*y + y^2 + 2*x + 2*y + 1
|
|
484
|
+
|
|
485
|
+
Check that using third argument raises an error::
|
|
486
|
+
|
|
487
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(R)
|
|
488
|
+
sage: pow(x + y + z, 2, x)
|
|
489
|
+
Traceback (most recent call last):
|
|
490
|
+
...
|
|
491
|
+
NotImplementedError: pow() with a modulus is not implemented for this ring
|
|
492
|
+
"""
|
|
493
|
+
cdef LaurentPolynomial_mpair ans
|
|
494
|
+
if mod is not None:
|
|
495
|
+
raise NotImplementedError(
|
|
496
|
+
"pow() with a modulus is not implemented for this ring"
|
|
497
|
+
)
|
|
498
|
+
if n < 0:
|
|
499
|
+
return ~(self ** -n)
|
|
500
|
+
ans = self._new_c()
|
|
501
|
+
ans._poly = self._poly ** n
|
|
502
|
+
ans._mon = self._mon.emul(n)
|
|
503
|
+
return ans
|
|
504
|
+
|
|
505
|
+
def __getitem__(self, n):
|
|
506
|
+
r"""
|
|
507
|
+
Return the coefficient of `x^n = x_1^{n_1} \cdots x_k^{n_k}` where
|
|
508
|
+
`n` is a tuple of length `k` and `k` is the number of variables.
|
|
509
|
+
|
|
510
|
+
If the number of inputs is not equal to the number of variables, this
|
|
511
|
+
raises a :exc:`TypeError`.
|
|
512
|
+
|
|
513
|
+
EXAMPLES::
|
|
514
|
+
|
|
515
|
+
sage: P.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
516
|
+
sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + x*z; f
|
|
517
|
+
-x^6 + x*z - 7*x^-2*y^3 + 5*x^-2*y + x^-3*y^2
|
|
518
|
+
sage: f[6,0,0]
|
|
519
|
+
-1
|
|
520
|
+
sage: f[-2,3,0]
|
|
521
|
+
-7
|
|
522
|
+
sage: f[-1,4,2]
|
|
523
|
+
0
|
|
524
|
+
sage: f[1,0,1]
|
|
525
|
+
1
|
|
526
|
+
sage: f[6]
|
|
527
|
+
Traceback (most recent call last):
|
|
528
|
+
...
|
|
529
|
+
TypeError: must have exactly 3 inputs
|
|
530
|
+
sage: f[6,0]
|
|
531
|
+
Traceback (most recent call last):
|
|
532
|
+
...
|
|
533
|
+
TypeError: must have exactly 3 inputs
|
|
534
|
+
sage: f[6,0,0,0]
|
|
535
|
+
Traceback (most recent call last):
|
|
536
|
+
...
|
|
537
|
+
TypeError: must have exactly 3 inputs
|
|
538
|
+
"""
|
|
539
|
+
if isinstance(n, slice):
|
|
540
|
+
raise TypeError("multivariate Laurent polynomials are not iterable")
|
|
541
|
+
if not isinstance(n, tuple) or len(n) != self._parent.ngens():
|
|
542
|
+
raise TypeError("must have exactly %s inputs" %
|
|
543
|
+
self.parent().ngens())
|
|
544
|
+
cdef ETuple t = ETuple(n)
|
|
545
|
+
if self._prod is None:
|
|
546
|
+
self._compute_polydict()
|
|
547
|
+
try:
|
|
548
|
+
return self._prod[t]
|
|
549
|
+
except KeyError:
|
|
550
|
+
return self._parent.base_ring().zero()
|
|
551
|
+
|
|
552
|
+
def __iter__(self):
|
|
553
|
+
"""
|
|
554
|
+
Iterate through all terms by returning a list of the coefficient and
|
|
555
|
+
the corresponding monomial.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
560
|
+
sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3
|
|
561
|
+
sage: sorted(f) # indirect doctest
|
|
562
|
+
[(-7, x^-2*y^3), (-1, x^6), (1, x^-3*y^2), (5, x^-2*y)]
|
|
563
|
+
"""
|
|
564
|
+
P = self._parent
|
|
565
|
+
one = P._R.one()
|
|
566
|
+
if self._mon.is_constant():
|
|
567
|
+
for exp, coeff in self._poly.iterator_exp_coeff():
|
|
568
|
+
yield (coeff, P.element_class(P, one, exp))
|
|
569
|
+
else:
|
|
570
|
+
for exp, coeff in self._poly.iterator_exp_coeff():
|
|
571
|
+
yield (coeff, P.element_class(P, one, exp.eadd(self._mon)))
|
|
572
|
+
|
|
573
|
+
def _as_extended_polynomial(self):
|
|
574
|
+
"""
|
|
575
|
+
This Laurent polynomial seen as a polynomial in twice as many variables,
|
|
576
|
+
where half of the variables are the inverses of the other half.
|
|
577
|
+
|
|
578
|
+
EXAMPLES::
|
|
579
|
+
|
|
580
|
+
sage: L.<t1,t2> = LaurentPolynomialRing(QQ)
|
|
581
|
+
sage: f = t1-t2^-2
|
|
582
|
+
sage: f
|
|
583
|
+
t1 - t2^-2
|
|
584
|
+
sage: f._as_extended_polynomial()
|
|
585
|
+
-t2inv^2 + t1
|
|
586
|
+
sage: _.parent()
|
|
587
|
+
Multivariate Polynomial Ring in t1, t1inv, t2, t2inv over Rational Field
|
|
588
|
+
"""
|
|
589
|
+
dres = {}
|
|
590
|
+
for e, c in self.monomial_coefficients().items():
|
|
591
|
+
exps = []
|
|
592
|
+
for t in e:
|
|
593
|
+
if t > 0:
|
|
594
|
+
exps += [t, 0]
|
|
595
|
+
else:
|
|
596
|
+
exps += [0, -t]
|
|
597
|
+
dres[tuple(exps)] = c
|
|
598
|
+
return self.parent()._extended_ring(dres)
|
|
599
|
+
|
|
600
|
+
def iterator_exp_coeff(self):
|
|
601
|
+
"""
|
|
602
|
+
Iterate over ``self`` as pairs of (ETuple, coefficient).
|
|
603
|
+
|
|
604
|
+
EXAMPLES::
|
|
605
|
+
|
|
606
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
607
|
+
sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3
|
|
608
|
+
sage: list(f.iterator_exp_coeff())
|
|
609
|
+
[((6, 0), -1), ((-2, 3), -7), ((-2, 1), 5), ((-3, 2), 1)]
|
|
610
|
+
"""
|
|
611
|
+
for exp, coeff in self._poly.iterator_exp_coeff():
|
|
612
|
+
yield (exp.eadd(self._mon), coeff)
|
|
613
|
+
|
|
614
|
+
def monomials(self):
|
|
615
|
+
"""
|
|
616
|
+
Return the list of monomials in ``self``.
|
|
617
|
+
|
|
618
|
+
EXAMPLES::
|
|
619
|
+
|
|
620
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
621
|
+
sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3
|
|
622
|
+
sage: sorted(f.monomials())
|
|
623
|
+
[x^-3*y^2, x^-2*y, x^-2*y^3, x^6]
|
|
624
|
+
"""
|
|
625
|
+
return [mon for coeff, mon in self]
|
|
626
|
+
|
|
627
|
+
def monomial_coefficient(self, mon):
|
|
628
|
+
"""
|
|
629
|
+
Return the coefficient in the base ring of the monomial ``mon`` in
|
|
630
|
+
``self``, where ``mon`` must have the same parent as ``self``.
|
|
631
|
+
|
|
632
|
+
This function contrasts with the function :meth:`coefficient()`
|
|
633
|
+
which returns the coefficient of a monomial viewing this
|
|
634
|
+
polynomial in a polynomial ring over a base ring having fewer
|
|
635
|
+
variables.
|
|
636
|
+
|
|
637
|
+
INPUT:
|
|
638
|
+
|
|
639
|
+
- ``mon`` -- a monomial
|
|
640
|
+
|
|
641
|
+
.. SEEALSO::
|
|
642
|
+
|
|
643
|
+
For coefficients in a base ring of fewer variables, see
|
|
644
|
+
:meth:`coefficient()`.
|
|
645
|
+
|
|
646
|
+
EXAMPLES::
|
|
647
|
+
|
|
648
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
649
|
+
sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3
|
|
650
|
+
sage: f.monomial_coefficient(x^-2*y^3)
|
|
651
|
+
-7
|
|
652
|
+
sage: f.monomial_coefficient(x^2)
|
|
653
|
+
0
|
|
654
|
+
|
|
655
|
+
TESTS::
|
|
656
|
+
|
|
657
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
658
|
+
sage: f = y^2 * x^-2
|
|
659
|
+
sage: f.monomial_coefficient(x + y)
|
|
660
|
+
Traceback (most recent call last):
|
|
661
|
+
...
|
|
662
|
+
ValueError: not a monomial
|
|
663
|
+
"""
|
|
664
|
+
if parent(mon) != self._parent:
|
|
665
|
+
raise TypeError("input must have the same parent")
|
|
666
|
+
cdef LaurentPolynomial_mpair m = <LaurentPolynomial_mpair > mon
|
|
667
|
+
if m._prod is None:
|
|
668
|
+
m._compute_polydict()
|
|
669
|
+
if self._prod is None:
|
|
670
|
+
self._compute_polydict()
|
|
671
|
+
exp = monomial_exponent(m._prod)
|
|
672
|
+
zero = self._parent.base_ring().zero()
|
|
673
|
+
return self._prod.get(exp, zero)
|
|
674
|
+
|
|
675
|
+
def constant_coefficient(self):
|
|
676
|
+
"""
|
|
677
|
+
Return the constant coefficient of ``self``.
|
|
678
|
+
|
|
679
|
+
EXAMPLES::
|
|
680
|
+
|
|
681
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
682
|
+
sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f
|
|
683
|
+
-x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2
|
|
684
|
+
sage: f.constant_coefficient()
|
|
685
|
+
0
|
|
686
|
+
sage: f = (x^3 + 2*x^-2*y+y^3)*y^-3; f
|
|
687
|
+
x^3*y^-3 + 1 + 2*x^-2*y^-2
|
|
688
|
+
sage: f.constant_coefficient()
|
|
689
|
+
1
|
|
690
|
+
"""
|
|
691
|
+
return self[(0,)*self._parent.ngens()]
|
|
692
|
+
|
|
693
|
+
def coefficient(self, mon):
|
|
694
|
+
r"""
|
|
695
|
+
Return the coefficient of ``mon`` in ``self``, where ``mon`` must
|
|
696
|
+
have the same parent as ``self``.
|
|
697
|
+
|
|
698
|
+
The coefficient is defined as follows. If `f` is this polynomial, then
|
|
699
|
+
the coefficient `c_m` is sum:
|
|
700
|
+
|
|
701
|
+
.. MATH::
|
|
702
|
+
|
|
703
|
+
c_m := \sum_T \frac{T}{m}
|
|
704
|
+
|
|
705
|
+
where the sum is over terms `T` in `f` that are exactly divisible
|
|
706
|
+
by `m`.
|
|
707
|
+
|
|
708
|
+
A monomial `m(x,y)` 'exactly divides' `f(x,y)` if `m(x,y) | f(x,y)`
|
|
709
|
+
and neither `x \cdot m(x,y)` nor `y \cdot m(x,y)` divides `f(x,y)`.
|
|
710
|
+
|
|
711
|
+
INPUT:
|
|
712
|
+
|
|
713
|
+
- ``mon`` -- a monomial
|
|
714
|
+
|
|
715
|
+
OUTPUT: element of the parent of ``self``
|
|
716
|
+
|
|
717
|
+
.. NOTE::
|
|
718
|
+
|
|
719
|
+
To get the constant coefficient, call
|
|
720
|
+
:meth:`constant_coefficient()`.
|
|
721
|
+
|
|
722
|
+
EXAMPLES::
|
|
723
|
+
|
|
724
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
725
|
+
|
|
726
|
+
The coefficient returned is an element of the parent of ``self``; in
|
|
727
|
+
this case, ``P``. ::
|
|
728
|
+
|
|
729
|
+
sage: f = 2 * x * y
|
|
730
|
+
sage: c = f.coefficient(x*y); c
|
|
731
|
+
2
|
|
732
|
+
sage: c.parent()
|
|
733
|
+
Multivariate Laurent Polynomial Ring in x, y over Rational Field
|
|
734
|
+
|
|
735
|
+
sage: P.<x,y> = LaurentPolynomialRing(QQ)
|
|
736
|
+
sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f
|
|
737
|
+
-x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2
|
|
738
|
+
sage: f.coefficient(y)
|
|
739
|
+
5*x^-2
|
|
740
|
+
sage: f.coefficient(y^2)
|
|
741
|
+
-7*x^-2 + x^-3
|
|
742
|
+
sage: f.coefficient(x*y)
|
|
743
|
+
0
|
|
744
|
+
sage: f.coefficient(x^-2)
|
|
745
|
+
-7*y^2 + 5*y
|
|
746
|
+
sage: f.coefficient(x^-2*y^2)
|
|
747
|
+
-7
|
|
748
|
+
sage: f.coefficient(1)
|
|
749
|
+
-x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2
|
|
750
|
+
"""
|
|
751
|
+
if mon.parent() is not self._parent:
|
|
752
|
+
mon = self._parent(mon)
|
|
753
|
+
cdef LaurentPolynomial_mpair m = <LaurentPolynomial_mpair > mon
|
|
754
|
+
if self._prod is None:
|
|
755
|
+
self._compute_polydict()
|
|
756
|
+
if m._prod is None:
|
|
757
|
+
m._compute_polydict()
|
|
758
|
+
return self._parent(self._prod.coefficient(m.monomial_coefficients()))
|
|
759
|
+
|
|
760
|
+
def coefficients(self):
|
|
761
|
+
"""
|
|
762
|
+
Return the nonzero coefficients of ``self`` in a list.
|
|
763
|
+
|
|
764
|
+
The returned list is decreasingly ordered by the term ordering
|
|
765
|
+
of ``self.parent()``.
|
|
766
|
+
|
|
767
|
+
EXAMPLES::
|
|
768
|
+
|
|
769
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ, order='degrevlex')
|
|
770
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
771
|
+
sage: f.coefficients()
|
|
772
|
+
[4, 3, 2, 1]
|
|
773
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ,order='lex')
|
|
774
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
775
|
+
sage: f.coefficients()
|
|
776
|
+
[4, 1, 2, 3]
|
|
777
|
+
"""
|
|
778
|
+
return self._poly.coefficients()
|
|
779
|
+
|
|
780
|
+
def variables(self, sort=True):
|
|
781
|
+
"""
|
|
782
|
+
Return a tuple of all variables occurring in ``self``.
|
|
783
|
+
|
|
784
|
+
INPUT:
|
|
785
|
+
|
|
786
|
+
- ``sort`` -- specifies whether the indices shall be sorted
|
|
787
|
+
|
|
788
|
+
EXAMPLES::
|
|
789
|
+
|
|
790
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
791
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
792
|
+
sage: f.variables()
|
|
793
|
+
(z, y, x)
|
|
794
|
+
sage: f.variables(sort=False) #random
|
|
795
|
+
(y, z, x)
|
|
796
|
+
"""
|
|
797
|
+
cdef dict d = self.monomial_coefficients()
|
|
798
|
+
cdef tuple g = self._parent.gens()
|
|
799
|
+
cdef Py_ssize_t nvars = len(g)
|
|
800
|
+
cdef set vars = set()
|
|
801
|
+
for k in d:
|
|
802
|
+
vars.update(k.nonzero_positions())
|
|
803
|
+
if len(vars) == nvars:
|
|
804
|
+
break
|
|
805
|
+
cdef list v = [g[i] for i in vars]
|
|
806
|
+
if sort:
|
|
807
|
+
v.sort()
|
|
808
|
+
return tuple(v)
|
|
809
|
+
|
|
810
|
+
cpdef dict monomial_coefficients(self):
|
|
811
|
+
"""
|
|
812
|
+
Return ``self`` represented as a ``dict``.
|
|
813
|
+
|
|
814
|
+
EXAMPLES::
|
|
815
|
+
|
|
816
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
817
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
818
|
+
sage: sorted(f.monomial_coefficients().items())
|
|
819
|
+
[((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)]
|
|
820
|
+
|
|
821
|
+
``dict`` is an alias::
|
|
822
|
+
|
|
823
|
+
sage: sorted(f.dict().items())
|
|
824
|
+
[((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)]
|
|
825
|
+
"""
|
|
826
|
+
if self._prod is None:
|
|
827
|
+
self._compute_polydict()
|
|
828
|
+
return < dict > self._prod.dict()
|
|
829
|
+
|
|
830
|
+
dict = monomial_coefficients
|
|
831
|
+
|
|
832
|
+
def _fraction_pair(self):
|
|
833
|
+
"""
|
|
834
|
+
Return one representation of ``self`` as a pair
|
|
835
|
+
``(numerator, denominator)``.
|
|
836
|
+
|
|
837
|
+
Here both the numerator and the denominator are polynomials.
|
|
838
|
+
|
|
839
|
+
This is used for coercion into the fraction field.
|
|
840
|
+
|
|
841
|
+
EXAMPLES::
|
|
842
|
+
|
|
843
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
844
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
845
|
+
sage: f._fraction_pair()
|
|
846
|
+
(4*x^7*y^7*z + 3*x^3*y^8*z^2 + 2*x^4*y^7 + x^6*z^2, y^7*z^2)
|
|
847
|
+
"""
|
|
848
|
+
ring = self._parent._R
|
|
849
|
+
numer = self._poly
|
|
850
|
+
denom = ring.one()
|
|
851
|
+
var = ring.gens()
|
|
852
|
+
for i, j in enumerate(self._mon):
|
|
853
|
+
if j > 0:
|
|
854
|
+
numer *= var[i] ** j
|
|
855
|
+
else:
|
|
856
|
+
denom *= var[i] ** (-j)
|
|
857
|
+
return (numer, denom)
|
|
858
|
+
|
|
859
|
+
cpdef _add_(self, _right):
|
|
860
|
+
"""
|
|
861
|
+
Return the Laurent polynomial ``self + right``.
|
|
862
|
+
|
|
863
|
+
EXAMPLES::
|
|
864
|
+
|
|
865
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
866
|
+
sage: f = x + y^-1
|
|
867
|
+
sage: g = y + z
|
|
868
|
+
sage: f + g
|
|
869
|
+
x + y + z + y^-1
|
|
870
|
+
"""
|
|
871
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
872
|
+
cdef LaurentPolynomial_mpair right = <LaurentPolynomial_mpair > _right
|
|
873
|
+
ans._mon, a, b = self._mon.combine_to_positives(right._mon)
|
|
874
|
+
if not a.is_constant():
|
|
875
|
+
ans._poly = self._poly * self._poly._parent({a: 1})
|
|
876
|
+
else:
|
|
877
|
+
ans._poly = self._poly
|
|
878
|
+
if not b.is_constant():
|
|
879
|
+
ans._poly += right._poly * self._poly._parent({b: 1})
|
|
880
|
+
else:
|
|
881
|
+
ans._poly += right._poly
|
|
882
|
+
return ans
|
|
883
|
+
|
|
884
|
+
cpdef _sub_(self, _right):
|
|
885
|
+
"""
|
|
886
|
+
Return the Laurent polynomial ``self - right``.
|
|
887
|
+
|
|
888
|
+
EXAMPLES::
|
|
889
|
+
|
|
890
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
891
|
+
sage: f = x + y^-1
|
|
892
|
+
sage: g = y + z + x
|
|
893
|
+
sage: f - g
|
|
894
|
+
-y - z + y^-1
|
|
895
|
+
"""
|
|
896
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
897
|
+
cdef LaurentPolynomial_mpair right = <LaurentPolynomial_mpair > _right
|
|
898
|
+
cdef ETuple a, b
|
|
899
|
+
ans._mon, a, b = self._mon.combine_to_positives(right._mon)
|
|
900
|
+
if not a.is_constant():
|
|
901
|
+
ans._poly = self._poly * self._poly._parent({a: 1})
|
|
902
|
+
else:
|
|
903
|
+
ans._poly = self._poly
|
|
904
|
+
if not b.is_constant():
|
|
905
|
+
ans._poly -= right._poly * self._poly._parent({b: 1})
|
|
906
|
+
else:
|
|
907
|
+
ans._poly -= right._poly
|
|
908
|
+
return ans
|
|
909
|
+
|
|
910
|
+
cpdef _div_(self, rhs):
|
|
911
|
+
"""
|
|
912
|
+
Return the division of ``self`` by ``rhs``.
|
|
913
|
+
|
|
914
|
+
If the denominator is not a unit,
|
|
915
|
+
the result will be given in the fraction field.
|
|
916
|
+
|
|
917
|
+
EXAMPLES::
|
|
918
|
+
|
|
919
|
+
sage: R.<s,q,t> = LaurentPolynomialRing(QQ)
|
|
920
|
+
sage: 1/s
|
|
921
|
+
s^-1
|
|
922
|
+
sage: 1/(s*q)
|
|
923
|
+
s^-1*q^-1
|
|
924
|
+
sage: 1/(s+q)
|
|
925
|
+
1/(s + q)
|
|
926
|
+
sage: (1/(s+q)).parent()
|
|
927
|
+
Fraction Field of Multivariate Polynomial Ring in s, q, t over Rational Field
|
|
928
|
+
sage: (1/(s*q)).parent()
|
|
929
|
+
Multivariate Laurent Polynomial Ring in s, q, t over Rational Field
|
|
930
|
+
sage: (s+q)/(q^2*t^(-2))
|
|
931
|
+
s*q^-2*t^2 + q^-1*t^2
|
|
932
|
+
"""
|
|
933
|
+
cdef LaurentPolynomial_mpair right = <LaurentPolynomial_mpair > rhs
|
|
934
|
+
if right.is_zero():
|
|
935
|
+
raise ZeroDivisionError
|
|
936
|
+
if right._poly.is_term():
|
|
937
|
+
return self * ~right
|
|
938
|
+
else:
|
|
939
|
+
return RingElement._div_(self, rhs)
|
|
940
|
+
|
|
941
|
+
def is_monomial(self):
|
|
942
|
+
"""
|
|
943
|
+
Return ``True`` if ``self`` is a monomial.
|
|
944
|
+
|
|
945
|
+
EXAMPLES::
|
|
946
|
+
|
|
947
|
+
sage: k.<y,z> = LaurentPolynomialRing(QQ)
|
|
948
|
+
sage: z.is_monomial()
|
|
949
|
+
True
|
|
950
|
+
sage: k(1).is_monomial()
|
|
951
|
+
True
|
|
952
|
+
sage: (z+1).is_monomial()
|
|
953
|
+
False
|
|
954
|
+
sage: (z^-2909).is_monomial()
|
|
955
|
+
True
|
|
956
|
+
sage: (38*z^-2909).is_monomial()
|
|
957
|
+
False
|
|
958
|
+
"""
|
|
959
|
+
return self._poly.is_monomial()
|
|
960
|
+
|
|
961
|
+
cpdef _neg_(self):
|
|
962
|
+
"""
|
|
963
|
+
Return ``-self``.
|
|
964
|
+
|
|
965
|
+
EXAMPLES::
|
|
966
|
+
|
|
967
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
968
|
+
sage: f = x + y^-1
|
|
969
|
+
sage: -f
|
|
970
|
+
-x - y^-1
|
|
971
|
+
"""
|
|
972
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
973
|
+
ans._mon = self._mon
|
|
974
|
+
ans._poly = -self._poly
|
|
975
|
+
return ans
|
|
976
|
+
|
|
977
|
+
cpdef _lmul_(self, Element right):
|
|
978
|
+
"""
|
|
979
|
+
Return ``self * right`` where ``right`` is in ``self``'s base ring.
|
|
980
|
+
|
|
981
|
+
EXAMPLES::
|
|
982
|
+
|
|
983
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
984
|
+
sage: f = x + y^-1
|
|
985
|
+
sage: f*(1/2)
|
|
986
|
+
1/2*x + 1/2*y^-1
|
|
987
|
+
"""
|
|
988
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
989
|
+
ans._mon = self._mon
|
|
990
|
+
ans._poly = self._poly * right
|
|
991
|
+
return ans
|
|
992
|
+
|
|
993
|
+
cpdef _rmul_(self, Element left):
|
|
994
|
+
"""
|
|
995
|
+
Return ``left * self`` where ``left`` is in ``self``'s base ring.
|
|
996
|
+
|
|
997
|
+
EXAMPLES::
|
|
998
|
+
|
|
999
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1000
|
+
sage: f = x + y^-1
|
|
1001
|
+
sage: (1/2)*f
|
|
1002
|
+
1/2*x + 1/2*y^-1
|
|
1003
|
+
"""
|
|
1004
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
1005
|
+
ans._mon = self._mon
|
|
1006
|
+
ans._poly = left * self._poly
|
|
1007
|
+
return ans
|
|
1008
|
+
|
|
1009
|
+
cpdef _mul_(self, right):
|
|
1010
|
+
"""
|
|
1011
|
+
Return ``self * right``.
|
|
1012
|
+
|
|
1013
|
+
EXAMPLES::
|
|
1014
|
+
|
|
1015
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1016
|
+
sage: f = x + y^-1
|
|
1017
|
+
sage: g = y + z
|
|
1018
|
+
sage: f*g
|
|
1019
|
+
x*y + x*z + 1 + y^-1*z
|
|
1020
|
+
"""
|
|
1021
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
1022
|
+
ans._mon = self._mon.eadd(( < LaurentPolynomial_mpair > right)._mon)
|
|
1023
|
+
ans._poly = self._poly * ( < LaurentPolynomial_mpair > right)._poly
|
|
1024
|
+
return ans
|
|
1025
|
+
|
|
1026
|
+
cpdef _floordiv_(self, right):
|
|
1027
|
+
"""
|
|
1028
|
+
Perform division with remainder and return the quotient.
|
|
1029
|
+
|
|
1030
|
+
EXAMPLES::
|
|
1031
|
+
|
|
1032
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ)
|
|
1033
|
+
sage: f = x^3 + y^-3
|
|
1034
|
+
sage: g = y + x
|
|
1035
|
+
sage: f // g # needs sage.libs.singular
|
|
1036
|
+
x^5*y^-3 - x^4*y^-2 + x^3*y^-1
|
|
1037
|
+
|
|
1038
|
+
sage: h = x + y^(-1)
|
|
1039
|
+
sage: f // h # needs sage.libs.singular
|
|
1040
|
+
x^2 - x*y^-1 + y^-2
|
|
1041
|
+
sage: h * (f // h) == f # needs sage.libs.singular
|
|
1042
|
+
True
|
|
1043
|
+
sage: f // 1
|
|
1044
|
+
x^3 + y^-3
|
|
1045
|
+
sage: 1 // f # needs sage.libs.singular
|
|
1046
|
+
0
|
|
1047
|
+
|
|
1048
|
+
TESTS:
|
|
1049
|
+
|
|
1050
|
+
Check that :issue:`19357` is fixed::
|
|
1051
|
+
|
|
1052
|
+
sage: x // y
|
|
1053
|
+
x*y^-1
|
|
1054
|
+
|
|
1055
|
+
Check that :issue:`21999` is fixed::
|
|
1056
|
+
|
|
1057
|
+
sage: L.<a,b> = LaurentPolynomialRing(QQbar) # needs sage.rings.number_field
|
|
1058
|
+
sage: (a+a*b) // a # needs sage.libs.singular sage.rings.number_field
|
|
1059
|
+
b + 1
|
|
1060
|
+
"""
|
|
1061
|
+
cdef LaurentPolynomial_mpair ans = self._new_c()
|
|
1062
|
+
cdef LaurentPolynomial_mpair rightl = <LaurentPolynomial_mpair > right
|
|
1063
|
+
self._normalize()
|
|
1064
|
+
rightl._normalize()
|
|
1065
|
+
ans._mon = self._mon.esub(rightl._mon)
|
|
1066
|
+
ans._poly = self._poly // rightl._poly
|
|
1067
|
+
return ans
|
|
1068
|
+
|
|
1069
|
+
@coerce_binop
|
|
1070
|
+
def quo_rem(self, right):
|
|
1071
|
+
"""
|
|
1072
|
+
Divide this Laurent polynomial by ``right`` and return a quotient and
|
|
1073
|
+
a remainder.
|
|
1074
|
+
|
|
1075
|
+
INPUT:
|
|
1076
|
+
|
|
1077
|
+
- ``right`` -- a Laurent polynomial
|
|
1078
|
+
|
|
1079
|
+
OUTPUT: a pair of Laurent polynomials
|
|
1080
|
+
|
|
1081
|
+
EXAMPLES::
|
|
1082
|
+
|
|
1083
|
+
sage: R.<s, t> = LaurentPolynomialRing(QQ)
|
|
1084
|
+
sage: (s^2 - t^2).quo_rem(s - t) # needs sage.libs.singular
|
|
1085
|
+
(s + t, 0)
|
|
1086
|
+
sage: (s^-2 - t^2).quo_rem(s - t) # needs sage.libs.singular
|
|
1087
|
+
(s + t, -s^2 + s^-2)
|
|
1088
|
+
sage: (s^-2 - t^2).quo_rem(s^-1 - t) # needs sage.libs.singular
|
|
1089
|
+
(t + s^-1, 0)
|
|
1090
|
+
|
|
1091
|
+
TESTS:
|
|
1092
|
+
|
|
1093
|
+
Verify that :issue:`31257` is fixed::
|
|
1094
|
+
|
|
1095
|
+
sage: # needs sage.libs.singular
|
|
1096
|
+
sage: R.<x,y> = LaurentPolynomialRing(QQ)
|
|
1097
|
+
sage: q, r = (1/x).quo_rem(y)
|
|
1098
|
+
sage: q, r
|
|
1099
|
+
(x^-1*y^-1, 0)
|
|
1100
|
+
sage: q*y + r == 1/x
|
|
1101
|
+
True
|
|
1102
|
+
sage: q, r = (x^-2 - y^2).quo_rem(x - y)
|
|
1103
|
+
sage: q*(x - y) + r == x^-2 - y^2
|
|
1104
|
+
True
|
|
1105
|
+
"""
|
|
1106
|
+
# make copies of self and right so that the input can be normalized
|
|
1107
|
+
# without affecting the objects that were passed to the method
|
|
1108
|
+
cdef LaurentPolynomial_mpair selfl = self._new_c()
|
|
1109
|
+
selfl._poly = self._poly
|
|
1110
|
+
selfl._mon = self._mon
|
|
1111
|
+
cdef LaurentPolynomial_mpair rightl = self._new_c()
|
|
1112
|
+
rightl._poly = (< LaurentPolynomial_mpair > right)._poly
|
|
1113
|
+
rightl._mon = (< LaurentPolynomial_mpair > right)._mon
|
|
1114
|
+
|
|
1115
|
+
selfl._normalize()
|
|
1116
|
+
rightl._normalize()
|
|
1117
|
+
q, r = selfl._poly.quo_rem(rightl._poly)
|
|
1118
|
+
ql = LaurentPolynomial_mpair(self._parent, q,
|
|
1119
|
+
mon=selfl._mon.esub(rightl._mon))
|
|
1120
|
+
rl = LaurentPolynomial_mpair(self._parent, r,
|
|
1121
|
+
mon=selfl._mon)
|
|
1122
|
+
ql._normalize()
|
|
1123
|
+
rl._normalize()
|
|
1124
|
+
return (ql, rl)
|
|
1125
|
+
|
|
1126
|
+
cpdef _richcmp_(self, right, int op):
|
|
1127
|
+
"""
|
|
1128
|
+
Compare two polynomials in a `LaurentPolynomialRing` based on the term
|
|
1129
|
+
order from the parent ring. If the parent ring does not specify a term
|
|
1130
|
+
order then only comparison by equality is supported.
|
|
1131
|
+
|
|
1132
|
+
EXAMPLES::
|
|
1133
|
+
|
|
1134
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1135
|
+
sage: f = x + y^-1
|
|
1136
|
+
sage: g = y + z
|
|
1137
|
+
sage: f == f
|
|
1138
|
+
True
|
|
1139
|
+
sage: f == g
|
|
1140
|
+
False
|
|
1141
|
+
sage: f == 2
|
|
1142
|
+
False
|
|
1143
|
+
"""
|
|
1144
|
+
if self._prod is None:
|
|
1145
|
+
self._compute_polydict()
|
|
1146
|
+
if (< LaurentPolynomial_mpair > right)._prod is None:
|
|
1147
|
+
(< LaurentPolynomial_mpair > right)._compute_polydict()
|
|
1148
|
+
|
|
1149
|
+
try:
|
|
1150
|
+
sortkey = self._parent.term_order().sortkey
|
|
1151
|
+
except AttributeError:
|
|
1152
|
+
sortkey = None
|
|
1153
|
+
|
|
1154
|
+
return self._prod.rich_compare(( < LaurentPolynomial_mpair > right)._prod,
|
|
1155
|
+
op, sortkey)
|
|
1156
|
+
|
|
1157
|
+
def exponents(self):
|
|
1158
|
+
"""
|
|
1159
|
+
Return a list of the exponents of ``self``.
|
|
1160
|
+
|
|
1161
|
+
EXAMPLES::
|
|
1162
|
+
|
|
1163
|
+
sage: L.<w,z> = LaurentPolynomialRing(QQ)
|
|
1164
|
+
sage: a = w^2*z^-1 + 3; a
|
|
1165
|
+
w^2*z^-1 + 3
|
|
1166
|
+
sage: e = a.exponents()
|
|
1167
|
+
sage: e.sort(); e
|
|
1168
|
+
[(0, 0), (2, -1)]
|
|
1169
|
+
"""
|
|
1170
|
+
return [a.eadd(self._mon) for a in self._poly.exponents()]
|
|
1171
|
+
|
|
1172
|
+
def degree(self, x=None):
|
|
1173
|
+
r"""
|
|
1174
|
+
Return the degree of ``self``.
|
|
1175
|
+
|
|
1176
|
+
INPUT:
|
|
1177
|
+
|
|
1178
|
+
- ``x`` -- (default: ``None``) a generator of the parent ring
|
|
1179
|
+
|
|
1180
|
+
OUTPUT:
|
|
1181
|
+
|
|
1182
|
+
If ``x`` is ``None``, return the total degree of ``self``.
|
|
1183
|
+
If ``x`` is a given generator of the parent ring,
|
|
1184
|
+
the output is the maximum degree of ``x`` in ``self``.
|
|
1185
|
+
|
|
1186
|
+
EXAMPLES::
|
|
1187
|
+
|
|
1188
|
+
sage: R.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1189
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
1190
|
+
sage: f.degree()
|
|
1191
|
+
6
|
|
1192
|
+
sage: f.degree(x)
|
|
1193
|
+
7
|
|
1194
|
+
sage: f.degree(y)
|
|
1195
|
+
1
|
|
1196
|
+
sage: f.degree(z)
|
|
1197
|
+
0
|
|
1198
|
+
|
|
1199
|
+
The zero polynomial is defined to have degree `-\infty`::
|
|
1200
|
+
|
|
1201
|
+
sage: R.<x, y, z> = LaurentPolynomialRing(ZZ)
|
|
1202
|
+
sage: R.zero().degree()
|
|
1203
|
+
-Infinity
|
|
1204
|
+
sage: R.zero().degree(x)
|
|
1205
|
+
-Infinity
|
|
1206
|
+
sage: R.zero().degree(x) == R.zero().degree(y) == R.zero().degree(z)
|
|
1207
|
+
True
|
|
1208
|
+
|
|
1209
|
+
TESTS::
|
|
1210
|
+
|
|
1211
|
+
sage: R.<x, y, z> = LaurentPolynomialRing(ZZ)
|
|
1212
|
+
sage: f = x + y + z
|
|
1213
|
+
sage: f.degree(1)
|
|
1214
|
+
Traceback (most recent call last):
|
|
1215
|
+
...
|
|
1216
|
+
TypeError: 1 is not a generator of parent
|
|
1217
|
+
"""
|
|
1218
|
+
# The zero polynomial is defined to have degree -Infinity
|
|
1219
|
+
if self.is_zero():
|
|
1220
|
+
return minus_infinity
|
|
1221
|
+
|
|
1222
|
+
if x is None:
|
|
1223
|
+
return self._poly.total_degree() + sum(self._mon)
|
|
1224
|
+
|
|
1225
|
+
# Get the index of the generator or error
|
|
1226
|
+
cdef tuple g = <tuple > self._parent.gens()
|
|
1227
|
+
cdef Py_ssize_t i
|
|
1228
|
+
try:
|
|
1229
|
+
i = g.index(x)
|
|
1230
|
+
except ValueError: # not in the tuple
|
|
1231
|
+
raise TypeError(f"{x} is not a generator of parent")
|
|
1232
|
+
return self._poly.degree(self._parent._R.gens()[i]) + self._mon[i]
|
|
1233
|
+
|
|
1234
|
+
def valuation(self, x=None):
|
|
1235
|
+
r"""
|
|
1236
|
+
Return the valuation of ``self``.
|
|
1237
|
+
|
|
1238
|
+
If ``x`` is ``None``, the returned valuation is the minimal total degree
|
|
1239
|
+
of the monomials occurring in ``self``. Geometrically, this is the order
|
|
1240
|
+
of vanishing of ``self`` at the generic point of the blow-up of the
|
|
1241
|
+
point `(0,0,\ldots,0)`.
|
|
1242
|
+
|
|
1243
|
+
If ``x`` is not ``None``, then it must be a generator. In that case, the
|
|
1244
|
+
minimum degree of that generator occurring in ``self`` is returned.
|
|
1245
|
+
Geometrically, this is the order of vanishing of ``self`` at the generic
|
|
1246
|
+
point of the curve `x = 0`.
|
|
1247
|
+
|
|
1248
|
+
INPUT:
|
|
1249
|
+
|
|
1250
|
+
- ``x`` -- (optional) a generator; if given, return the valuation
|
|
1251
|
+
with respect to this generator
|
|
1252
|
+
|
|
1253
|
+
EXAMPLES::
|
|
1254
|
+
|
|
1255
|
+
sage: R.<x,y> = LaurentPolynomialRing(ZZ)
|
|
1256
|
+
sage: f = 2*x^2*y^-3 - 13*x^-1*y^-3 + 2*x^2*y^-5 - 2*x^-3*y^2
|
|
1257
|
+
sage: f.valuation()
|
|
1258
|
+
-4
|
|
1259
|
+
sage: f.valuation(x)
|
|
1260
|
+
-3
|
|
1261
|
+
sage: f.valuation(y)
|
|
1262
|
+
-5
|
|
1263
|
+
sage: R.zero().valuation()
|
|
1264
|
+
+Infinity
|
|
1265
|
+
|
|
1266
|
+
TESTS:
|
|
1267
|
+
|
|
1268
|
+
If supplied, ``x`` must be a generator::
|
|
1269
|
+
|
|
1270
|
+
sage: R.<x,y> = LaurentPolynomialRing(ZZ)
|
|
1271
|
+
sage: f = 1 + x + x^2*y^-1
|
|
1272
|
+
sage: f.valuation(1)
|
|
1273
|
+
Traceback (most recent call last):
|
|
1274
|
+
...
|
|
1275
|
+
TypeError: 1 is not a generator of parent
|
|
1276
|
+
"""
|
|
1277
|
+
# Valuation of zero polynomial is defined to be +Infinity
|
|
1278
|
+
if self.is_zero():
|
|
1279
|
+
return Infinity
|
|
1280
|
+
|
|
1281
|
+
# When x is None find the minimal valuation by finding the minimal
|
|
1282
|
+
# valuation of the sum of exponents
|
|
1283
|
+
if x is None:
|
|
1284
|
+
return Integer(min(sum(e) for e in self.exponents()))
|
|
1285
|
+
|
|
1286
|
+
# Get the index of the generator or error
|
|
1287
|
+
cdef tuple g = <tuple > self._parent.gens()
|
|
1288
|
+
cdef Py_ssize_t i
|
|
1289
|
+
try:
|
|
1290
|
+
i = g.index(x)
|
|
1291
|
+
except ValueError: # not in the tuple
|
|
1292
|
+
raise TypeError(f"{x} is not a generator of parent")
|
|
1293
|
+
|
|
1294
|
+
# Find the minimal valuation of x by checking each term
|
|
1295
|
+
return Integer(min(e[i] for e in self.exponents()))
|
|
1296
|
+
|
|
1297
|
+
def has_inverse_of(self, i):
|
|
1298
|
+
"""
|
|
1299
|
+
INPUT:
|
|
1300
|
+
|
|
1301
|
+
- ``i`` -- the index of a generator of ``self.parent()``
|
|
1302
|
+
|
|
1303
|
+
OUTPUT:
|
|
1304
|
+
|
|
1305
|
+
Return ``True`` if ``self`` contains a monomial including the inverse of
|
|
1306
|
+
``self.parent().gen(i)``, ``False`` otherwise.
|
|
1307
|
+
|
|
1308
|
+
EXAMPLES::
|
|
1309
|
+
|
|
1310
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1311
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
1312
|
+
sage: f.has_inverse_of(0)
|
|
1313
|
+
False
|
|
1314
|
+
sage: f.has_inverse_of(1)
|
|
1315
|
+
True
|
|
1316
|
+
sage: f.has_inverse_of(2)
|
|
1317
|
+
True
|
|
1318
|
+
"""
|
|
1319
|
+
if (not isinstance(i, (int, Integer))) or (i < 0) or (i >= self._parent.ngens()):
|
|
1320
|
+
raise TypeError("argument is not the index of a generator")
|
|
1321
|
+
if self._mon[i] < 0:
|
|
1322
|
+
self._normalize(i)
|
|
1323
|
+
if self._mon[i] < 0:
|
|
1324
|
+
return True
|
|
1325
|
+
return False
|
|
1326
|
+
return False
|
|
1327
|
+
|
|
1328
|
+
def has_any_inverse(self):
|
|
1329
|
+
"""
|
|
1330
|
+
Return ``True`` if ``self`` contains any monomials with a negative
|
|
1331
|
+
exponent, ``False`` otherwise.
|
|
1332
|
+
|
|
1333
|
+
EXAMPLES::
|
|
1334
|
+
|
|
1335
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1336
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
1337
|
+
sage: f.has_any_inverse()
|
|
1338
|
+
True
|
|
1339
|
+
sage: g = x^2 + y^2
|
|
1340
|
+
sage: g.has_any_inverse()
|
|
1341
|
+
False
|
|
1342
|
+
"""
|
|
1343
|
+
for m in self._mon.nonzero_values(sort=False):
|
|
1344
|
+
if m < 0:
|
|
1345
|
+
return True
|
|
1346
|
+
return False
|
|
1347
|
+
|
|
1348
|
+
def __call__(self, *x, **kwds):
|
|
1349
|
+
"""
|
|
1350
|
+
Compute value of ``self`` at ``x``.
|
|
1351
|
+
|
|
1352
|
+
EXAMPLES::
|
|
1353
|
+
|
|
1354
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1355
|
+
sage: f = x + 2*y + 3*z
|
|
1356
|
+
sage: f(1,1,1)
|
|
1357
|
+
6
|
|
1358
|
+
sage: f = x^-1 + y + z
|
|
1359
|
+
sage: f(0,1,1)
|
|
1360
|
+
Traceback (most recent call last):
|
|
1361
|
+
...
|
|
1362
|
+
ZeroDivisionError
|
|
1363
|
+
|
|
1364
|
+
TESTS::
|
|
1365
|
+
|
|
1366
|
+
sage: f = x + 2*y + 3*z
|
|
1367
|
+
sage: f(2)
|
|
1368
|
+
Traceback (most recent call last):
|
|
1369
|
+
...
|
|
1370
|
+
TypeError: number of arguments does not match the number of generators in parent
|
|
1371
|
+
sage: f(2,0)
|
|
1372
|
+
Traceback (most recent call last):
|
|
1373
|
+
...
|
|
1374
|
+
TypeError: number of arguments does not match the number of generators in parent
|
|
1375
|
+
sage: f( (1,1,1) )
|
|
1376
|
+
6
|
|
1377
|
+
"""
|
|
1378
|
+
if kwds:
|
|
1379
|
+
f = self.subs(**kwds)
|
|
1380
|
+
if x: # More than 1 non-keyword argument
|
|
1381
|
+
return f(*x)
|
|
1382
|
+
else:
|
|
1383
|
+
return f
|
|
1384
|
+
|
|
1385
|
+
cdef int l = len(x)
|
|
1386
|
+
|
|
1387
|
+
if l == 1 and isinstance(x[0], (tuple, list)):
|
|
1388
|
+
x = x[0]
|
|
1389
|
+
l = len(x)
|
|
1390
|
+
|
|
1391
|
+
if l != self._parent.ngens():
|
|
1392
|
+
raise TypeError("number of arguments does not match the number"
|
|
1393
|
+
" of generators in parent")
|
|
1394
|
+
|
|
1395
|
+
# Check to make sure that we aren't dividing by zero
|
|
1396
|
+
cdef Py_ssize_t m
|
|
1397
|
+
for m in range(l):
|
|
1398
|
+
if x[m] == 0:
|
|
1399
|
+
if self.has_inverse_of(m):
|
|
1400
|
+
raise ZeroDivisionError
|
|
1401
|
+
|
|
1402
|
+
ans = self._poly(*x)
|
|
1403
|
+
if ans:
|
|
1404
|
+
for m in self._mon.nonzero_positions():
|
|
1405
|
+
ans *= x[m]**self._mon[m]
|
|
1406
|
+
|
|
1407
|
+
return ans
|
|
1408
|
+
|
|
1409
|
+
def subs(self, in_dict=None, **kwds):
|
|
1410
|
+
"""
|
|
1411
|
+
Substitute some variables in this Laurent polynomial.
|
|
1412
|
+
|
|
1413
|
+
Variable/value pairs for the substitution may be given
|
|
1414
|
+
as a dictionary or via keyword-value pairs. If both are
|
|
1415
|
+
present, the latter take precedence.
|
|
1416
|
+
|
|
1417
|
+
INPUT:
|
|
1418
|
+
|
|
1419
|
+
- ``in_dict`` -- dictionary (optional)
|
|
1420
|
+
|
|
1421
|
+
- ``**kwds`` -- keyword arguments
|
|
1422
|
+
|
|
1423
|
+
OUTPUT: a Laurent polynomial
|
|
1424
|
+
|
|
1425
|
+
EXAMPLES::
|
|
1426
|
+
|
|
1427
|
+
sage: L.<x, y, z> = LaurentPolynomialRing(QQ)
|
|
1428
|
+
sage: f = x + 2*y + 3*z
|
|
1429
|
+
sage: f.subs(x=1)
|
|
1430
|
+
2*y + 3*z + 1
|
|
1431
|
+
sage: f.subs(y=1)
|
|
1432
|
+
x + 3*z + 2
|
|
1433
|
+
sage: f.subs(z=1)
|
|
1434
|
+
x + 2*y + 3
|
|
1435
|
+
sage: f.subs(x=1, y=1, z=1)
|
|
1436
|
+
6
|
|
1437
|
+
|
|
1438
|
+
sage: f = x^-1
|
|
1439
|
+
sage: f.subs(x=2)
|
|
1440
|
+
1/2
|
|
1441
|
+
sage: f.subs({x: 2})
|
|
1442
|
+
1/2
|
|
1443
|
+
|
|
1444
|
+
sage: f = x + 2*y + 3*z
|
|
1445
|
+
sage: f.subs({x: 1, y: 1, z: 1})
|
|
1446
|
+
6
|
|
1447
|
+
sage: f.substitute(x=1, y=1, z=1)
|
|
1448
|
+
6
|
|
1449
|
+
|
|
1450
|
+
TESTS::
|
|
1451
|
+
|
|
1452
|
+
sage: f = x + 2*y + 3*z
|
|
1453
|
+
sage: f(q=10)
|
|
1454
|
+
x + 2*y + 3*z
|
|
1455
|
+
|
|
1456
|
+
sage: x.subs({x: 2}, x=1)
|
|
1457
|
+
1
|
|
1458
|
+
|
|
1459
|
+
sage: f.subs({1: 2}, x=1)
|
|
1460
|
+
3*z + 5
|
|
1461
|
+
"""
|
|
1462
|
+
cdef list variables = list(self._parent.gens())
|
|
1463
|
+
cdef Py_ssize_t i
|
|
1464
|
+
for i in range(len(variables)):
|
|
1465
|
+
if str(variables[i]) in kwds:
|
|
1466
|
+
variables[i] = kwds[str(variables[i])]
|
|
1467
|
+
elif in_dict:
|
|
1468
|
+
if variables[i] in in_dict:
|
|
1469
|
+
variables[i] = in_dict[variables[i]]
|
|
1470
|
+
elif i in in_dict:
|
|
1471
|
+
variables[i] = in_dict[i]
|
|
1472
|
+
return self(tuple(variables))
|
|
1473
|
+
|
|
1474
|
+
def is_constant(self):
|
|
1475
|
+
r"""
|
|
1476
|
+
Return whether this Laurent polynomial is constant.
|
|
1477
|
+
|
|
1478
|
+
EXAMPLES::
|
|
1479
|
+
|
|
1480
|
+
sage: L.<a, b> = LaurentPolynomialRing(QQ)
|
|
1481
|
+
sage: L(0).is_constant()
|
|
1482
|
+
True
|
|
1483
|
+
sage: L(42).is_constant()
|
|
1484
|
+
True
|
|
1485
|
+
sage: a.is_constant()
|
|
1486
|
+
False
|
|
1487
|
+
sage: (1/b).is_constant()
|
|
1488
|
+
False
|
|
1489
|
+
"""
|
|
1490
|
+
return (self._mon == ETuple({}, int(self._parent.ngens())) and
|
|
1491
|
+
self._poly.is_constant())
|
|
1492
|
+
|
|
1493
|
+
def _symbolic_(self, R):
|
|
1494
|
+
"""
|
|
1495
|
+
EXAMPLES::
|
|
1496
|
+
|
|
1497
|
+
sage: # needs sage.symbolic
|
|
1498
|
+
sage: R.<x,y> = LaurentPolynomialRing(QQ)
|
|
1499
|
+
sage: f = x^3 + y/x
|
|
1500
|
+
sage: g = f._symbolic_(SR); g
|
|
1501
|
+
(x^4 + y)/x
|
|
1502
|
+
sage: g(x=2, y=2)
|
|
1503
|
+
9
|
|
1504
|
+
sage: g = SR(f)
|
|
1505
|
+
sage: g(x=2, y=2)
|
|
1506
|
+
9
|
|
1507
|
+
"""
|
|
1508
|
+
d = {repr(g): R.var(g) for g in self._parent.gens()}
|
|
1509
|
+
return self.subs(**d)
|
|
1510
|
+
|
|
1511
|
+
def derivative(self, *args):
|
|
1512
|
+
r"""
|
|
1513
|
+
The formal derivative of this Laurent polynomial, with respect
|
|
1514
|
+
to variables supplied in args.
|
|
1515
|
+
|
|
1516
|
+
Multiple variables and iteration counts may be supplied; see
|
|
1517
|
+
documentation for the global :func:`derivative` function for more
|
|
1518
|
+
details.
|
|
1519
|
+
|
|
1520
|
+
.. SEEALSO::
|
|
1521
|
+
|
|
1522
|
+
:meth:`_derivative`
|
|
1523
|
+
|
|
1524
|
+
EXAMPLES::
|
|
1525
|
+
|
|
1526
|
+
sage: R = LaurentPolynomialRing(ZZ,'x, y')
|
|
1527
|
+
sage: x, y = R.gens()
|
|
1528
|
+
sage: t = x**4*y + x*y + y + x**(-1) + y**(-3)
|
|
1529
|
+
sage: t.derivative(x, x)
|
|
1530
|
+
12*x^2*y + 2*x^-3
|
|
1531
|
+
sage: t.derivative(y, 2)
|
|
1532
|
+
12*y^-5
|
|
1533
|
+
"""
|
|
1534
|
+
return multi_derivative(self, args)
|
|
1535
|
+
|
|
1536
|
+
# add .diff(), .differentiate() as aliases for .derivative()
|
|
1537
|
+
diff = differentiate = derivative
|
|
1538
|
+
|
|
1539
|
+
def _derivative(self, var=None):
|
|
1540
|
+
"""
|
|
1541
|
+
Compute formal derivative of this Laurent polynomial with
|
|
1542
|
+
respect to the given variable.
|
|
1543
|
+
|
|
1544
|
+
If ``var`` is among the generators of this ring, the derivative
|
|
1545
|
+
is with respect to the generator. Otherwise, ``_derivative(var)`` is called
|
|
1546
|
+
recursively for each coefficient of this polynomial.
|
|
1547
|
+
|
|
1548
|
+
.. SEEALSO:: :meth:`derivative`
|
|
1549
|
+
|
|
1550
|
+
EXAMPLES::
|
|
1551
|
+
|
|
1552
|
+
sage: R = LaurentPolynomialRing(ZZ,'x, y')
|
|
1553
|
+
sage: x, y = R.gens()
|
|
1554
|
+
sage: t = x**4*y+x*y+y+x**(-1)+y**(-3)
|
|
1555
|
+
sage: t._derivative(x)
|
|
1556
|
+
4*x^3*y + y - x^-2
|
|
1557
|
+
sage: t._derivative(y)
|
|
1558
|
+
x^4 + x + 1 - 3*y^-4
|
|
1559
|
+
|
|
1560
|
+
sage: R = LaurentPolynomialRing(QQ['z'],'x')
|
|
1561
|
+
sage: z = R.base_ring().gen()
|
|
1562
|
+
sage: x = R.gen()
|
|
1563
|
+
sage: t = 33*z*x**4+x**(-1)
|
|
1564
|
+
sage: t._derivative(z)
|
|
1565
|
+
33*x^4
|
|
1566
|
+
sage: t._derivative(x)
|
|
1567
|
+
-x^-2 + 132*z*x^3
|
|
1568
|
+
"""
|
|
1569
|
+
if var is None:
|
|
1570
|
+
raise ValueError("must specify which variable to differentiate "
|
|
1571
|
+
"with respect to")
|
|
1572
|
+
P = self._parent
|
|
1573
|
+
cdef list gens = list(P.gens())
|
|
1574
|
+
|
|
1575
|
+
# check if var is one of the generators
|
|
1576
|
+
try:
|
|
1577
|
+
index = gens.index(var)
|
|
1578
|
+
except ValueError:
|
|
1579
|
+
# call _derivative() recursively on coefficients
|
|
1580
|
+
return P({m: c._derivative(var)
|
|
1581
|
+
for m, c in self.monomial_coefficients().items()})
|
|
1582
|
+
|
|
1583
|
+
# compute formal derivative with respect to generator
|
|
1584
|
+
cdef dict d = {}
|
|
1585
|
+
for m, c in self.monomial_coefficients().items():
|
|
1586
|
+
if m[index] != 0:
|
|
1587
|
+
new_m = [u for u in m]
|
|
1588
|
+
new_m[index] += -1
|
|
1589
|
+
d[ETuple(new_m)] = m[index] * c
|
|
1590
|
+
return P(d)
|
|
1591
|
+
|
|
1592
|
+
def is_univariate(self):
|
|
1593
|
+
"""
|
|
1594
|
+
Return ``True`` if this is a univariate or constant Laurent polynomial,
|
|
1595
|
+
and ``False`` otherwise.
|
|
1596
|
+
|
|
1597
|
+
EXAMPLES::
|
|
1598
|
+
|
|
1599
|
+
sage: R.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1600
|
+
sage: f = (x^3 + y^-3)*z
|
|
1601
|
+
sage: f.is_univariate()
|
|
1602
|
+
False
|
|
1603
|
+
sage: g = f(1, y, 4)
|
|
1604
|
+
sage: g.is_univariate()
|
|
1605
|
+
True
|
|
1606
|
+
sage: R(1).is_univariate()
|
|
1607
|
+
True
|
|
1608
|
+
"""
|
|
1609
|
+
return len(self.variables()) < 2
|
|
1610
|
+
|
|
1611
|
+
def univariate_polynomial(self, R=None):
|
|
1612
|
+
"""
|
|
1613
|
+
Return a univariate polynomial associated to this
|
|
1614
|
+
multivariate polynomial.
|
|
1615
|
+
|
|
1616
|
+
INPUT:
|
|
1617
|
+
|
|
1618
|
+
- ``R`` -- (default: ``None``) a univariate Laurent polynomial ring
|
|
1619
|
+
|
|
1620
|
+
If this polynomial is not in at most one variable, then a
|
|
1621
|
+
:exc:`ValueError` exception is raised. The new polynomial is over
|
|
1622
|
+
the same base ring as the given :class:`LaurentPolynomial` and in the
|
|
1623
|
+
variable ``x`` if no ring ``R`` is provided.
|
|
1624
|
+
|
|
1625
|
+
EXAMPLES::
|
|
1626
|
+
|
|
1627
|
+
sage: R.<x, y> = LaurentPolynomialRing(ZZ)
|
|
1628
|
+
sage: f = 3*x^2 - 2*y^-1 + 7*x^2*y^2 + 5
|
|
1629
|
+
sage: f.univariate_polynomial()
|
|
1630
|
+
Traceback (most recent call last):
|
|
1631
|
+
...
|
|
1632
|
+
TypeError: polynomial must involve at most one variable
|
|
1633
|
+
sage: g = f(10, y); g
|
|
1634
|
+
700*y^2 + 305 - 2*y^-1
|
|
1635
|
+
sage: h = g.univariate_polynomial(); h
|
|
1636
|
+
-2*y^-1 + 305 + 700*y^2
|
|
1637
|
+
sage: h.parent()
|
|
1638
|
+
Univariate Laurent Polynomial Ring in y over Integer Ring
|
|
1639
|
+
sage: g.univariate_polynomial(LaurentPolynomialRing(QQ,'z'))
|
|
1640
|
+
-2*z^-1 + 305 + 700*z^2
|
|
1641
|
+
|
|
1642
|
+
Here's an example with a constant multivariate polynomial::
|
|
1643
|
+
|
|
1644
|
+
sage: g = R(1)
|
|
1645
|
+
sage: h = g.univariate_polynomial(); h
|
|
1646
|
+
1
|
|
1647
|
+
sage: h.parent()
|
|
1648
|
+
Univariate Laurent Polynomial Ring in x over Integer Ring
|
|
1649
|
+
"""
|
|
1650
|
+
from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
|
|
1651
|
+
v = self.variables()
|
|
1652
|
+
if len(v) > 1:
|
|
1653
|
+
raise TypeError("polynomial must involve at most one variable")
|
|
1654
|
+
elif len(v) == 1:
|
|
1655
|
+
x = v[0]
|
|
1656
|
+
i = self._parent.gens().index(x)
|
|
1657
|
+
x = str(x)
|
|
1658
|
+
else:
|
|
1659
|
+
x = 'x'
|
|
1660
|
+
i = 0
|
|
1661
|
+
|
|
1662
|
+
# construct ring if none
|
|
1663
|
+
if R is None:
|
|
1664
|
+
R = LaurentPolynomialRing(self.base_ring(), x)
|
|
1665
|
+
|
|
1666
|
+
return R({m[i]: c for m, c in self.monomial_coefficients().items()})
|
|
1667
|
+
|
|
1668
|
+
def monomial_reduction(self):
|
|
1669
|
+
"""
|
|
1670
|
+
Factor ``self`` into a polynomial and a monomial.
|
|
1671
|
+
|
|
1672
|
+
OUTPUT:
|
|
1673
|
+
|
|
1674
|
+
A tuple ``(p, v)`` where ``p`` is the underlying polynomial and ``v``
|
|
1675
|
+
is a monomial.
|
|
1676
|
+
|
|
1677
|
+
EXAMPLES::
|
|
1678
|
+
|
|
1679
|
+
sage: R.<x, y> = LaurentPolynomialRing(QQ)
|
|
1680
|
+
sage: f = y / x + x^2 / y + 3 * x^4 * y^-2
|
|
1681
|
+
sage: f.monomial_reduction()
|
|
1682
|
+
(3*x^5 + x^3*y + y^3, x^-1*y^-2)
|
|
1683
|
+
sage: f = y * x + x^2 / y + 3 * x^4 * y^-2
|
|
1684
|
+
sage: f.monomial_reduction()
|
|
1685
|
+
(3*x^3 + y^3 + x*y, x*y^-2)
|
|
1686
|
+
sage: x.monomial_reduction()
|
|
1687
|
+
(1, x)
|
|
1688
|
+
sage: (y^-1).monomial_reduction()
|
|
1689
|
+
(1, y^-1)
|
|
1690
|
+
"""
|
|
1691
|
+
self._normalize()
|
|
1692
|
+
ring = self._parent
|
|
1693
|
+
g = ring.gens()
|
|
1694
|
+
mon = ring.prod(g[i] ** j for i, j in enumerate(self._mon))
|
|
1695
|
+
return (self._poly, mon)
|
|
1696
|
+
|
|
1697
|
+
def factor(self):
|
|
1698
|
+
"""
|
|
1699
|
+
Return a Laurent monomial (the unit part of the factorization) and a factored multi-polynomial.
|
|
1700
|
+
|
|
1701
|
+
EXAMPLES::
|
|
1702
|
+
|
|
1703
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1704
|
+
sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
|
|
1705
|
+
sage: f.factor()
|
|
1706
|
+
(x^3*y^-7*z^-2) * (4*x^4*y^7*z + 3*y^8*z^2 + 2*x*y^7 + x^3*z^2)
|
|
1707
|
+
|
|
1708
|
+
TESTS:
|
|
1709
|
+
|
|
1710
|
+
Tests for :issue:`29173`::
|
|
1711
|
+
|
|
1712
|
+
sage: L.<a, b> = LaurentPolynomialRing(ZZ, 'a, b')
|
|
1713
|
+
sage: (a*b + a + b + 1).factor()
|
|
1714
|
+
(b + 1) * (a + 1)
|
|
1715
|
+
sage: ((a^-1)*(a*b + a + b + 1)).factor()
|
|
1716
|
+
(a^-1) * (b + 1) * (a + 1)
|
|
1717
|
+
sage: L(-12).factor()
|
|
1718
|
+
-1 * 2^2 * 3
|
|
1719
|
+
"""
|
|
1720
|
+
pf = self._poly.factor()
|
|
1721
|
+
|
|
1722
|
+
if self._poly.degree() == 0:
|
|
1723
|
+
# Factorization is broken for polynomials, see
|
|
1724
|
+
# https://github.com/sagemath/sage/issues/20214
|
|
1725
|
+
return pf
|
|
1726
|
+
|
|
1727
|
+
u = self.parent(pf.unit())
|
|
1728
|
+
|
|
1729
|
+
cdef tuple g = <tuple > self._parent.gens()
|
|
1730
|
+
for i in self._mon.nonzero_positions():
|
|
1731
|
+
u *= g[i] ** self._mon[i]
|
|
1732
|
+
|
|
1733
|
+
cdef list f = []
|
|
1734
|
+
cdef dict d
|
|
1735
|
+
for t in pf:
|
|
1736
|
+
d = <dict > (t[0].monomial_coefficients())
|
|
1737
|
+
if len(d) == 1: # monomials are units
|
|
1738
|
+
u *= self.parent(d) ** t[1]
|
|
1739
|
+
else:
|
|
1740
|
+
f.append((self.parent(d), t[1]))
|
|
1741
|
+
|
|
1742
|
+
return Factorization(f, unit=u)
|
|
1743
|
+
|
|
1744
|
+
def is_square(self, root=False):
|
|
1745
|
+
r"""
|
|
1746
|
+
Test whether this Laurent polynomial is a square.
|
|
1747
|
+
|
|
1748
|
+
INPUT:
|
|
1749
|
+
|
|
1750
|
+
- ``root`` -- boolean (default: ``False``); if set to ``True``
|
|
1751
|
+
then return a pair ``(True, sqrt)`` with ``sqrt`` a square
|
|
1752
|
+
root of this Laurent polynomial when it exists or
|
|
1753
|
+
``(False, None)``
|
|
1754
|
+
|
|
1755
|
+
EXAMPLES::
|
|
1756
|
+
|
|
1757
|
+
sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
|
|
1758
|
+
sage: p = 1 + x*y + z^-3
|
|
1759
|
+
sage: (p**2).is_square()
|
|
1760
|
+
True
|
|
1761
|
+
sage: (p**2).is_square(root=True)
|
|
1762
|
+
(True, x*y + 1 + z^-3)
|
|
1763
|
+
|
|
1764
|
+
sage: x.is_square()
|
|
1765
|
+
False
|
|
1766
|
+
sage: x.is_square(root=True)
|
|
1767
|
+
(False, None)
|
|
1768
|
+
|
|
1769
|
+
sage: (x**-4 * (1 + z)).is_square(root=False)
|
|
1770
|
+
False
|
|
1771
|
+
sage: (x**-4 * (1 + z)).is_square(root=True)
|
|
1772
|
+
(False, None)
|
|
1773
|
+
"""
|
|
1774
|
+
self._normalize()
|
|
1775
|
+
if not self._mon.is_multiple_of(2):
|
|
1776
|
+
return (False, None) if root else False
|
|
1777
|
+
|
|
1778
|
+
cdef LaurentPolynomial_mpair ans
|
|
1779
|
+
|
|
1780
|
+
if not root:
|
|
1781
|
+
return self._poly.is_square(root=False)
|
|
1782
|
+
else:
|
|
1783
|
+
(pans, root) = self._poly.is_square(root=True)
|
|
1784
|
+
if not pans:
|
|
1785
|
+
return (False, None)
|
|
1786
|
+
|
|
1787
|
+
mon = self._mon.escalar_div(2)
|
|
1788
|
+
ans = self._new_c()
|
|
1789
|
+
ans._mon = mon
|
|
1790
|
+
ans._poly = root
|
|
1791
|
+
return (True, ans)
|
|
1792
|
+
|
|
1793
|
+
cpdef rescale_vars(self, dict d, h=None, new_ring=None):
|
|
1794
|
+
r"""
|
|
1795
|
+
Rescale variables in a Laurent polynomial.
|
|
1796
|
+
|
|
1797
|
+
INPUT:
|
|
1798
|
+
|
|
1799
|
+
- ``d`` -- a ``dict`` whose keys are the generator indices
|
|
1800
|
+
and values are the coefficients; so a pair ``(i, v)``
|
|
1801
|
+
means `x_i \mapsto v x_i`
|
|
1802
|
+
- ``h`` -- (optional) a map to be applied to coefficients
|
|
1803
|
+
done after rescaling
|
|
1804
|
+
- ``new_ring`` -- (optional) a new ring to map the result into
|
|
1805
|
+
|
|
1806
|
+
EXAMPLES::
|
|
1807
|
+
|
|
1808
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ, 2)
|
|
1809
|
+
sage: p = x^-2*y + x*y^-2
|
|
1810
|
+
sage: p.rescale_vars({0: 2, 1: 3})
|
|
1811
|
+
2/9*x*y^-2 + 3/4*x^-2*y
|
|
1812
|
+
sage: F = GF(2)
|
|
1813
|
+
sage: p.rescale_vars({0: 3, 1: 7}, new_ring=L.change_ring(F))
|
|
1814
|
+
x*y^-2 + x^-2*y
|
|
1815
|
+
|
|
1816
|
+
Test for :issue:`30331`::
|
|
1817
|
+
|
|
1818
|
+
sage: F.<z> = CyclotomicField(3) # needs sage.rings.number_field
|
|
1819
|
+
sage: p.rescale_vars({0: 2, 1: z}, new_ring=L.change_ring(F)) # needs sage.rings.number_field
|
|
1820
|
+
2*z*x*y^-2 + 1/4*z*x^-2*y
|
|
1821
|
+
"""
|
|
1822
|
+
cdef int i
|
|
1823
|
+
cdef dict df
|
|
1824
|
+
cdef ETuple v
|
|
1825
|
+
cdef LaurentPolynomial_mpair ans
|
|
1826
|
+
|
|
1827
|
+
if self._prod is None:
|
|
1828
|
+
self._compute_polydict()
|
|
1829
|
+
|
|
1830
|
+
df = dict(self._prod.__repn) # This makes a copy for us to manipulate
|
|
1831
|
+
if new_ring is None:
|
|
1832
|
+
R = self._parent._base
|
|
1833
|
+
else:
|
|
1834
|
+
R = new_ring._base
|
|
1835
|
+
if h is None:
|
|
1836
|
+
for v in df:
|
|
1837
|
+
val = df[v]
|
|
1838
|
+
for i in d:
|
|
1839
|
+
val *= d[i]**v[i]
|
|
1840
|
+
df[v] = val
|
|
1841
|
+
else:
|
|
1842
|
+
for v in df:
|
|
1843
|
+
val = df[v]
|
|
1844
|
+
for i in d:
|
|
1845
|
+
val *= d[i]**v[i]
|
|
1846
|
+
df[v] = R(h(val))
|
|
1847
|
+
|
|
1848
|
+
ans = <LaurentPolynomial_mpair > self._new_c()
|
|
1849
|
+
ans._prod = PolyDict(df)
|
|
1850
|
+
ans._mon = self._mon
|
|
1851
|
+
if new_ring is None:
|
|
1852
|
+
S = self._poly._parent
|
|
1853
|
+
else:
|
|
1854
|
+
S = self._poly._parent.change_ring(R)
|
|
1855
|
+
ans._poly = <MPolynomial > S({v.esub(ans._mon): df[v] for v in df})
|
|
1856
|
+
if new_ring is not None:
|
|
1857
|
+
return new_ring(ans)
|
|
1858
|
+
return ans
|
|
1859
|
+
|
|
1860
|
+
cpdef toric_coordinate_change(self, M, h=None, new_ring=None):
|
|
1861
|
+
r"""
|
|
1862
|
+
Apply a matrix to the exponents in a Laurent polynomial.
|
|
1863
|
+
|
|
1864
|
+
For efficiency, we implement this directly, rather than as a substitution.
|
|
1865
|
+
|
|
1866
|
+
The optional argument ``h`` is a map to be applied to coefficients.
|
|
1867
|
+
|
|
1868
|
+
EXAMPLES::
|
|
1869
|
+
|
|
1870
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ, 2)
|
|
1871
|
+
sage: p = 2*x^2 + y - x*y
|
|
1872
|
+
sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]]))
|
|
1873
|
+
2*x^2*y^2 - x^-2*y^2 + x^-3*y
|
|
1874
|
+
sage: F = GF(2)
|
|
1875
|
+
sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]]),
|
|
1876
|
+
....: new_ring=L.change_ring(F))
|
|
1877
|
+
x^-2*y^2 + x^-3*y
|
|
1878
|
+
"""
|
|
1879
|
+
cdef int n, i, j, x
|
|
1880
|
+
cdef dict d, dr
|
|
1881
|
+
cdef ETuple v
|
|
1882
|
+
cdef LaurentPolynomial_mpair ans
|
|
1883
|
+
cdef list mon, exp
|
|
1884
|
+
cdef Matrix mat = M
|
|
1885
|
+
|
|
1886
|
+
n = self._parent.ngens()
|
|
1887
|
+
if mat.dimensions() != (n, n):
|
|
1888
|
+
raise ValueError("the matrix M must be a {k} x {k} matrix".format(k=n))
|
|
1889
|
+
|
|
1890
|
+
if not self:
|
|
1891
|
+
if new_ring is None:
|
|
1892
|
+
return self._parent.zero()
|
|
1893
|
+
else:
|
|
1894
|
+
return new_ring.zero()
|
|
1895
|
+
|
|
1896
|
+
if self._prod is None:
|
|
1897
|
+
self._compute_polydict()
|
|
1898
|
+
|
|
1899
|
+
d = self._prod.__repn
|
|
1900
|
+
dr = {}
|
|
1901
|
+
mon = [0] * n
|
|
1902
|
+
for v in d:
|
|
1903
|
+
# Make a copy of mon as this might be faster than creating the data from scratch.
|
|
1904
|
+
# We will set every entry, so no need to clear the data.
|
|
1905
|
+
exp = list(mon)
|
|
1906
|
+
for j in range(n):
|
|
1907
|
+
x = 0
|
|
1908
|
+
for i in range(n):
|
|
1909
|
+
if not mat.get_is_zero_unsafe(j, i):
|
|
1910
|
+
x += (< int > v[i]) * int(mat.get_unsafe(j, i))
|
|
1911
|
+
if x < (< int > mon[j]):
|
|
1912
|
+
mon[j] = x
|
|
1913
|
+
exp[j] = x
|
|
1914
|
+
dr[ETuple(exp)] = d[v]
|
|
1915
|
+
|
|
1916
|
+
if h is not None:
|
|
1917
|
+
for v in dr:
|
|
1918
|
+
dr[v] = self._parent._base(h(dr[v]))
|
|
1919
|
+
|
|
1920
|
+
ans = <LaurentPolynomial_mpair > self._new_c()
|
|
1921
|
+
ans._prod = PolyDict(dr)
|
|
1922
|
+
ans._mon = ETuple(mon)
|
|
1923
|
+
ans._poly = <MPolynomial > self._poly._parent({v.esub(ans._mon): dr[v] for v in dr})
|
|
1924
|
+
if new_ring is not None:
|
|
1925
|
+
return new_ring(ans)
|
|
1926
|
+
return ans
|
|
1927
|
+
|
|
1928
|
+
cpdef toric_substitute(self, v, v1, a, h=None, new_ring=None):
|
|
1929
|
+
r"""
|
|
1930
|
+
Perform a single-variable substitution up to a toric coordinate change.
|
|
1931
|
+
|
|
1932
|
+
The optional argument ``h`` is a map to be applied to coefficients.
|
|
1933
|
+
|
|
1934
|
+
EXAMPLES::
|
|
1935
|
+
|
|
1936
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ, 2)
|
|
1937
|
+
sage: p = x + y
|
|
1938
|
+
sage: p.toric_substitute((2,3), (-1,1), 2)
|
|
1939
|
+
1/2*x^3*y^3 + 2*x^-2*y^-2
|
|
1940
|
+
sage: F = GF(5)
|
|
1941
|
+
sage: p.toric_substitute((2,3), (-1,1), 2, new_ring=L.change_ring(F))
|
|
1942
|
+
3*x^3*y^3 + 2*x^-2*y^-2
|
|
1943
|
+
|
|
1944
|
+
TESTS:
|
|
1945
|
+
|
|
1946
|
+
Tests for :issue:`30331`::
|
|
1947
|
+
|
|
1948
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ, 2)
|
|
1949
|
+
sage: p = x + y
|
|
1950
|
+
sage: F.<z> = CyclotomicField(3) # needs sage.rings.number_field
|
|
1951
|
+
sage: p.toric_substitute((2,3), (-1,1), z, new_ring=L.change_ring(F)) # needs sage.rings.number_field
|
|
1952
|
+
(-z - 1)*x^3*y^3 + z*x^-2*y^-2
|
|
1953
|
+
|
|
1954
|
+
sage: P.<x> = LaurentPolynomialRing(QQ, 1)
|
|
1955
|
+
sage: u = x - 1
|
|
1956
|
+
sage: v = u.toric_substitute((-1,), (-1,), 1)
|
|
1957
|
+
sage: v.is_zero()
|
|
1958
|
+
True
|
|
1959
|
+
"""
|
|
1960
|
+
cdef dict d, dr
|
|
1961
|
+
cdef ETuple ve, v1e, w, w1, mon
|
|
1962
|
+
cdef LaurentPolynomial_mpair ans
|
|
1963
|
+
cdef int t
|
|
1964
|
+
|
|
1965
|
+
if self._prod is None:
|
|
1966
|
+
self._compute_polydict()
|
|
1967
|
+
|
|
1968
|
+
d = self._prod.__repn
|
|
1969
|
+
dr = {}
|
|
1970
|
+
ve = ETuple(v)
|
|
1971
|
+
v1e = ETuple(v1)
|
|
1972
|
+
mon = self._mon
|
|
1973
|
+
if h is not None:
|
|
1974
|
+
d = dict(d) # Make a copy so we can manipulate it
|
|
1975
|
+
for w in d:
|
|
1976
|
+
d[w] = h(d[w])
|
|
1977
|
+
for w in d:
|
|
1978
|
+
x = d[w]
|
|
1979
|
+
t = w.dotprod(v1e)
|
|
1980
|
+
w1 = w.eadd_scaled(ve, -t)
|
|
1981
|
+
if w1 in dr:
|
|
1982
|
+
dr[w1] += x * a**t
|
|
1983
|
+
else:
|
|
1984
|
+
dr[w1] = x * a**t
|
|
1985
|
+
mon = mon.emin(w1)
|
|
1986
|
+
for v in tuple(dr.keys()):
|
|
1987
|
+
if not dr[v]:
|
|
1988
|
+
del dr[v]
|
|
1989
|
+
|
|
1990
|
+
if new_ring is None:
|
|
1991
|
+
S = self._poly._parent
|
|
1992
|
+
else:
|
|
1993
|
+
S = self._poly._parent.change_ring(new_ring._base)
|
|
1994
|
+
ans = <LaurentPolynomial_mpair > self._new_c()
|
|
1995
|
+
ans._prod = PolyDict(dr)
|
|
1996
|
+
ans._mon = mon
|
|
1997
|
+
ans._poly = <MPolynomial > S({v.esub(ans._mon): dr[v] for v in dr})
|
|
1998
|
+
if new_ring is not None:
|
|
1999
|
+
return new_ring(ans)
|
|
2000
|
+
return ans
|
|
2001
|
+
|
|
2002
|
+
@coerce_binop
|
|
2003
|
+
def divides(self, other):
|
|
2004
|
+
"""
|
|
2005
|
+
Check if ``self`` divides ``other``.
|
|
2006
|
+
|
|
2007
|
+
EXAMPLES::
|
|
2008
|
+
|
|
2009
|
+
sage: R.<x,y> = LaurentPolynomialRing(QQ)
|
|
2010
|
+
sage: f1 = x^-2*y^3 - 9 - 1/14*x^-1*y - 1/3*x^-1
|
|
2011
|
+
sage: h = 3*x^-1 - 3*x^-2*y - 1/2*x^-3*y^2 - x^-3*y + x^-3
|
|
2012
|
+
sage: f2 = f1 * h
|
|
2013
|
+
sage: f3 = f2 + x * y
|
|
2014
|
+
sage: f1.divides(f2)
|
|
2015
|
+
True
|
|
2016
|
+
sage: f1.divides(f3)
|
|
2017
|
+
False
|
|
2018
|
+
sage: f1.divides(3)
|
|
2019
|
+
False
|
|
2020
|
+
"""
|
|
2021
|
+
p = self.monomial_reduction()[0]
|
|
2022
|
+
q = other.monomial_reduction()[0]
|
|
2023
|
+
return p.divides(q)
|