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,1753 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
"""
|
|
3
|
+
Quadratic forms overview
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- Jon Hanke (2007-06-19)
|
|
8
|
+
- Anna Haensch (2010-07-01): Formatting and ReSTification
|
|
9
|
+
- Simon Brandhorst (2019-10-15): :meth:`quadratic_form_from_invariants`
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# ****************************************************************************
|
|
13
|
+
# Copyright (C) 2007 William Stein and Jonathan Hanke
|
|
14
|
+
#
|
|
15
|
+
# This program is free software: you can redistribute it and/or modify
|
|
16
|
+
# it under the terms of the GNU General Public License as published by
|
|
17
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
18
|
+
# (at your option) any later version.
|
|
19
|
+
# https://www.gnu.org/licenses/
|
|
20
|
+
# ****************************************************************************
|
|
21
|
+
|
|
22
|
+
from warnings import warn
|
|
23
|
+
from copy import deepcopy
|
|
24
|
+
|
|
25
|
+
from sage.matrix.constructor import matrix
|
|
26
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
27
|
+
from sage.misc.lazy_import import lazy_import
|
|
28
|
+
from sage.structure.element import Matrix
|
|
29
|
+
from sage.categories.rings import Rings
|
|
30
|
+
from sage.categories.fields import Fields
|
|
31
|
+
from sage.categories.principal_ideal_domains import PrincipalIdealDomains
|
|
32
|
+
from sage.rings.integer_ring import IntegerRing, ZZ
|
|
33
|
+
from sage.misc.functional import denominator, is_even
|
|
34
|
+
from sage.arith.misc import GCD
|
|
35
|
+
from sage.arith.functions import lcm as LCM
|
|
36
|
+
from sage.rings.ideal import Ideal
|
|
37
|
+
from sage.rings.rational_field import QQ
|
|
38
|
+
from sage.structure.element import Vector
|
|
39
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
40
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
41
|
+
from sage.rings.polynomial.multi_polynomial import MPolynomial
|
|
42
|
+
from sage.modules.free_module_element import vector
|
|
43
|
+
from sage.quadratic_forms.quadratic_form__evaluate import QFEvaluateVector, QFEvaluateMatrix
|
|
44
|
+
from sage.structure.sage_object import SageObject
|
|
45
|
+
from sage.misc.superseded import deprecation, deprecated_function_alias
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def is_QuadraticForm(Q):
|
|
49
|
+
"""
|
|
50
|
+
Determine if the object ``Q`` is an element of the :class:`QuadraticForm` class.
|
|
51
|
+
|
|
52
|
+
This function is deprecated.
|
|
53
|
+
|
|
54
|
+
EXAMPLES::
|
|
55
|
+
|
|
56
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
57
|
+
sage: from sage.quadratic_forms.quadratic_form import is_QuadraticForm
|
|
58
|
+
sage: is_QuadraticForm(Q)
|
|
59
|
+
doctest:...: DeprecationWarning: the function is_QuadraticForm is deprecated;
|
|
60
|
+
use isinstance(x, sage.quadratic_forms.quadratic_form.QuadraticForm) instead...
|
|
61
|
+
True
|
|
62
|
+
sage: is_QuadraticForm(2)
|
|
63
|
+
False
|
|
64
|
+
"""
|
|
65
|
+
deprecation(35305,
|
|
66
|
+
"the function is_QuadraticForm is deprecated; use "
|
|
67
|
+
"isinstance(x, sage.quadratic_forms.quadratic_form.QuadraticForm) instead")
|
|
68
|
+
return isinstance(Q, QuadraticForm)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def quadratic_form_from_invariants(F, rk, det, P, sminus):
|
|
72
|
+
r"""
|
|
73
|
+
Return a rational quadratic form with given invariants.
|
|
74
|
+
|
|
75
|
+
INPUT:
|
|
76
|
+
|
|
77
|
+
- ``F`` -- the base field; currently only ``QQ`` is allowed
|
|
78
|
+
- ``rk`` -- integer; the rank
|
|
79
|
+
- ``det`` -- rational; the determinant
|
|
80
|
+
- ``P`` -- list of primes where Cassel's Hasse invariant
|
|
81
|
+
is negative
|
|
82
|
+
- ``sminus`` -- integer; the number of negative eigenvalues
|
|
83
|
+
of any Gram matrix
|
|
84
|
+
|
|
85
|
+
OUTPUT: a quadratic form with the specified invariants
|
|
86
|
+
|
|
87
|
+
Let `(a_1, \ldots, a_n)` be the Gram matrix of a regular quadratic space.
|
|
88
|
+
Then Cassel's Hasse invariant is defined as
|
|
89
|
+
|
|
90
|
+
.. MATH::
|
|
91
|
+
|
|
92
|
+
\prod_{i<j} (a_i,a_j),
|
|
93
|
+
|
|
94
|
+
where `(a_i,a_j)` denotes the Hilbert symbol.
|
|
95
|
+
|
|
96
|
+
ALGORITHM:
|
|
97
|
+
|
|
98
|
+
We follow [Kir2016]_.
|
|
99
|
+
|
|
100
|
+
EXAMPLES::
|
|
101
|
+
|
|
102
|
+
sage: P = [3,5]
|
|
103
|
+
sage: q = quadratic_form_from_invariants(QQ,2,-15,P,1); q # needs sage.rings.padics
|
|
104
|
+
Quadratic form in 2 variables over Rational Field with coefficients:
|
|
105
|
+
[ 5 0 ]
|
|
106
|
+
[ * -3 ]
|
|
107
|
+
sage: all(q.hasse_invariant(p) == -1 for p in P) # needs sage.rings.padics
|
|
108
|
+
True
|
|
109
|
+
|
|
110
|
+
TESTS:
|
|
111
|
+
|
|
112
|
+
This shows that :issue:`28955` is fixed::
|
|
113
|
+
|
|
114
|
+
sage: quadratic_form_from_invariants(QQ,3,2,[2],2) # needs sage.rings.padics
|
|
115
|
+
Quadratic form in 3 variables over Rational Field with coefficients:
|
|
116
|
+
[ -1 0 0 ]
|
|
117
|
+
[ * 1 0 ]
|
|
118
|
+
[ * * -2 ]
|
|
119
|
+
|
|
120
|
+
sage: quadratic_form_from_invariants(QQ,4,2,[2],4) # needs sage.rings.padics
|
|
121
|
+
Traceback (most recent call last):
|
|
122
|
+
...
|
|
123
|
+
ValueError: invariants do not define a rational quadratic form
|
|
124
|
+
"""
|
|
125
|
+
from sage.arith.misc import hilbert_symbol
|
|
126
|
+
# normalize input
|
|
127
|
+
if F != QQ:
|
|
128
|
+
raise NotImplementedError('base field must be QQ. If you want this over any field, implement weak approximation.')
|
|
129
|
+
P = [ZZ(p) for p in P]
|
|
130
|
+
rk = ZZ(rk)
|
|
131
|
+
d = QQ(det).squarefree_part()
|
|
132
|
+
sminus = ZZ(sminus)
|
|
133
|
+
# check if the invariants define a global quadratic form
|
|
134
|
+
if d.sign() != (-1)**sminus:
|
|
135
|
+
raise ValueError("invariants do not define a rational quadratic form")
|
|
136
|
+
if rk == 1 and len(P) != 0:
|
|
137
|
+
raise ValueError("invariants do not define a rational quadratic form")
|
|
138
|
+
if rk == 2:
|
|
139
|
+
for p in P:
|
|
140
|
+
if QQ(-d).is_padic_square(p):
|
|
141
|
+
raise ValueError("invariants do not define a rational quadratic form")
|
|
142
|
+
f = 0
|
|
143
|
+
if sminus % 4 in (2, 3):
|
|
144
|
+
f = 1
|
|
145
|
+
if (f + len(P)) % 2 == 1:
|
|
146
|
+
raise ValueError("invariants do not define a rational quadratic form")
|
|
147
|
+
D = []
|
|
148
|
+
while rk >= 2:
|
|
149
|
+
if rk >= 4:
|
|
150
|
+
if sminus > 0:
|
|
151
|
+
a = ZZ(-1)
|
|
152
|
+
else:
|
|
153
|
+
a = ZZ(1)
|
|
154
|
+
elif rk == 3:
|
|
155
|
+
Pprime = [p for p in P if hilbert_symbol(-1, -d, p) == 1]
|
|
156
|
+
Pprime += [p for p in (2 * d).prime_divisors()
|
|
157
|
+
if hilbert_symbol(-1, -d, p) == -1 and p not in P]
|
|
158
|
+
if sminus > 0:
|
|
159
|
+
a = ZZ(-1)
|
|
160
|
+
else:
|
|
161
|
+
a = ZZ(1)
|
|
162
|
+
for p in Pprime:
|
|
163
|
+
if d.valuation(p) % 2 == 0:
|
|
164
|
+
a *= p
|
|
165
|
+
assert all((a * d).valuation(p) % 2 == 1 for p in Pprime)
|
|
166
|
+
elif rk == 2:
|
|
167
|
+
S = P
|
|
168
|
+
if sminus == 2:
|
|
169
|
+
S += [-1]
|
|
170
|
+
a = QQ.hilbert_symbol_negative_at_S(S, -d)
|
|
171
|
+
a = ZZ(a)
|
|
172
|
+
P = ([p for p in P if hilbert_symbol(a, -d, p) == 1]
|
|
173
|
+
+ [p for p in (2 * a * d).prime_divisors()
|
|
174
|
+
if hilbert_symbol(a, -d, p) == -1 and p not in P])
|
|
175
|
+
sminus = max(0, sminus - 1)
|
|
176
|
+
rk = rk - 1
|
|
177
|
+
d = a * d
|
|
178
|
+
D.append(a.squarefree_part())
|
|
179
|
+
d = d.squarefree_part()
|
|
180
|
+
D.append(d)
|
|
181
|
+
return DiagonalQuadraticForm(QQ, D)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class QuadraticForm(SageObject):
|
|
185
|
+
r"""
|
|
186
|
+
The ``QuadraticForm`` class represents a quadratic form in `n` variables with
|
|
187
|
+
coefficients in the ring `R`.
|
|
188
|
+
|
|
189
|
+
INPUT:
|
|
190
|
+
|
|
191
|
+
The constructor may be called in any of the following ways.
|
|
192
|
+
|
|
193
|
+
#. ``QuadraticForm(R, n, entries)``, where
|
|
194
|
+
|
|
195
|
+
- ``R`` -- ring for which the quadratic form is defined
|
|
196
|
+
- ``n`` -- integer `\geq 0`
|
|
197
|
+
- ``entries`` -- list of `n(n+1)/2` coefficients of the quadratic form
|
|
198
|
+
in `R` (given lexicographically, or equivalently, by rows of the
|
|
199
|
+
matrix)
|
|
200
|
+
|
|
201
|
+
#. ``QuadraticForm(p)``, where
|
|
202
|
+
|
|
203
|
+
- ``p`` -- a homogeneous polynomial of degree `2`
|
|
204
|
+
|
|
205
|
+
#. ``QuadraticForm(R, n)``, where
|
|
206
|
+
|
|
207
|
+
- ``R`` -- a ring
|
|
208
|
+
- ``n`` -- a symmetric `n \times n` matrix with even diagonal (relative to
|
|
209
|
+
`R`)
|
|
210
|
+
|
|
211
|
+
#. ``QuadraticForm(R)``, where
|
|
212
|
+
|
|
213
|
+
- ``R`` -- a symmetric `n \times n` matrix with even diagonal (relative to
|
|
214
|
+
its base ring)
|
|
215
|
+
|
|
216
|
+
If the keyword argument ``unsafe_initialize`` is True, then the subsequent
|
|
217
|
+
fields may by used to force the external initialization of various fields
|
|
218
|
+
of the quadratic form. Currently the only fields which can be set are:
|
|
219
|
+
|
|
220
|
+
- ``number_of_automorphisms``
|
|
221
|
+
- ``determinant``
|
|
222
|
+
|
|
223
|
+
OUTPUT: quadratic form
|
|
224
|
+
|
|
225
|
+
EXAMPLES::
|
|
226
|
+
|
|
227
|
+
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]); Q
|
|
228
|
+
Quadratic form in 3 variables over Integer Ring with coefficients:
|
|
229
|
+
[ 1 2 3 ]
|
|
230
|
+
[ * 4 5 ]
|
|
231
|
+
[ * * 6 ]
|
|
232
|
+
|
|
233
|
+
::
|
|
234
|
+
|
|
235
|
+
sage: Q = QuadraticForm(QQ, 3, [1,2,3,4/3,5,6]); Q
|
|
236
|
+
Quadratic form in 3 variables over Rational Field with coefficients:
|
|
237
|
+
[ 1 2 3 ]
|
|
238
|
+
[ * 4/3 5 ]
|
|
239
|
+
[ * * 6 ]
|
|
240
|
+
sage: Q[0,0]
|
|
241
|
+
1
|
|
242
|
+
sage: Q[0,0].parent()
|
|
243
|
+
Rational Field
|
|
244
|
+
|
|
245
|
+
::
|
|
246
|
+
|
|
247
|
+
sage: Q = QuadraticForm(QQ, 7, range(28)); Q
|
|
248
|
+
Quadratic form in 7 variables over Rational Field with coefficients:
|
|
249
|
+
[ 0 1 2 3 4 5 6 ]
|
|
250
|
+
[ * 7 8 9 10 11 12 ]
|
|
251
|
+
[ * * 13 14 15 16 17 ]
|
|
252
|
+
[ * * * 18 19 20 21 ]
|
|
253
|
+
[ * * * * 22 23 24 ]
|
|
254
|
+
[ * * * * * 25 26 ]
|
|
255
|
+
[ * * * * * * 27 ]
|
|
256
|
+
|
|
257
|
+
::
|
|
258
|
+
|
|
259
|
+
sage: Q = QuadraticForm(QQ, 2, range(1,4))
|
|
260
|
+
sage: A = Matrix(ZZ, 2, 2, [-1,0,0,1])
|
|
261
|
+
sage: Q(A)
|
|
262
|
+
Quadratic form in 2 variables over Rational Field with coefficients:
|
|
263
|
+
[ 1 -2 ]
|
|
264
|
+
[ * 3 ]
|
|
265
|
+
|
|
266
|
+
::
|
|
267
|
+
|
|
268
|
+
sage: m = matrix(2, 2, [1,2,3,4])
|
|
269
|
+
sage: m + m.transpose()
|
|
270
|
+
[2 5]
|
|
271
|
+
[5 8]
|
|
272
|
+
sage: QuadraticForm(m + m.transpose())
|
|
273
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
274
|
+
[ 1 5 ]
|
|
275
|
+
[ * 4 ]
|
|
276
|
+
|
|
277
|
+
::
|
|
278
|
+
|
|
279
|
+
sage: P.<x,y,z> = QQ[]
|
|
280
|
+
sage: p = x^2 + 2*x*y + x*z/2 + y^2 + y*z/3
|
|
281
|
+
sage: QuadraticForm(p)
|
|
282
|
+
Quadratic form in 3 variables over Rational Field with coefficients:
|
|
283
|
+
[ 1 2 1/2 ]
|
|
284
|
+
[ * 1 1/3 ]
|
|
285
|
+
[ * * 0 ]
|
|
286
|
+
|
|
287
|
+
::
|
|
288
|
+
|
|
289
|
+
sage: QuadraticForm(ZZ, m + m.transpose())
|
|
290
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
291
|
+
[ 1 5 ]
|
|
292
|
+
[ * 4 ]
|
|
293
|
+
|
|
294
|
+
::
|
|
295
|
+
|
|
296
|
+
sage: QuadraticForm(QQ, m + m.transpose())
|
|
297
|
+
Quadratic form in 2 variables over Rational Field with coefficients:
|
|
298
|
+
[ 1 5 ]
|
|
299
|
+
[ * 4 ]
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
# Import specialized methods:
|
|
303
|
+
# ---------------------------
|
|
304
|
+
|
|
305
|
+
# Routines to compute the p-adic local normal form
|
|
306
|
+
lazy_import("sage.quadratic_forms.quadratic_form__local_normal_form", [
|
|
307
|
+
"find_entry_with_minimal_scale_at_prime",
|
|
308
|
+
"local_normal_form",
|
|
309
|
+
"jordan_blocks_by_scale_and_unimodular",
|
|
310
|
+
"jordan_blocks_in_unimodular_list_by_scale_power"
|
|
311
|
+
])
|
|
312
|
+
|
|
313
|
+
# Routines to perform elementary variable substitutions
|
|
314
|
+
from sage.quadratic_forms.quadratic_form__variable_substitutions import \
|
|
315
|
+
swap_variables, \
|
|
316
|
+
multiply_variable, \
|
|
317
|
+
divide_variable, \
|
|
318
|
+
scale_by_factor, \
|
|
319
|
+
extract_variables, \
|
|
320
|
+
elementary_substitution, \
|
|
321
|
+
add_symmetric
|
|
322
|
+
|
|
323
|
+
# Routines to compute p-adic field invariants
|
|
324
|
+
from sage.quadratic_forms.quadratic_form__local_field_invariants import \
|
|
325
|
+
rational_diagonal_form, \
|
|
326
|
+
_rational_diagonal_form_and_transformation, \
|
|
327
|
+
signature_vector, \
|
|
328
|
+
signature, \
|
|
329
|
+
hasse_invariant, \
|
|
330
|
+
hasse_invariant__OMeara, \
|
|
331
|
+
is_hyperbolic, \
|
|
332
|
+
is_anisotropic, \
|
|
333
|
+
is_isotropic, \
|
|
334
|
+
anisotropic_primes, \
|
|
335
|
+
compute_definiteness, \
|
|
336
|
+
compute_definiteness_string_by_determinants, \
|
|
337
|
+
is_positive_definite, \
|
|
338
|
+
is_negative_definite, \
|
|
339
|
+
is_indefinite, \
|
|
340
|
+
is_definite
|
|
341
|
+
|
|
342
|
+
# Routines to compute local densities by the reduction procedure
|
|
343
|
+
from sage.quadratic_forms.quadratic_form__local_density_congruence import \
|
|
344
|
+
count_modp_solutions__by_Gauss_sum, \
|
|
345
|
+
local_good_density_congruence_odd, \
|
|
346
|
+
local_good_density_congruence_even, \
|
|
347
|
+
local_good_density_congruence, \
|
|
348
|
+
local_zero_density_congruence, \
|
|
349
|
+
local_badI_density_congruence, \
|
|
350
|
+
local_badII_density_congruence, \
|
|
351
|
+
local_bad_density_congruence, \
|
|
352
|
+
local_density_congruence, \
|
|
353
|
+
local_primitive_density_congruence
|
|
354
|
+
|
|
355
|
+
# Routines to compute local densities by counting solutions of various types
|
|
356
|
+
from sage.quadratic_forms.quadratic_form__count_local_2 import \
|
|
357
|
+
count_congruence_solutions_as_vector, \
|
|
358
|
+
count_congruence_solutions, \
|
|
359
|
+
count_congruence_solutions__good_type, \
|
|
360
|
+
count_congruence_solutions__zero_type, \
|
|
361
|
+
count_congruence_solutions__bad_type, \
|
|
362
|
+
count_congruence_solutions__bad_type_I, \
|
|
363
|
+
count_congruence_solutions__bad_type_II
|
|
364
|
+
|
|
365
|
+
# Routines to be called by the user to compute local densities
|
|
366
|
+
lazy_import('sage.quadratic_forms.quadratic_form__local_density_interfaces', [
|
|
367
|
+
'local_density',
|
|
368
|
+
'local_primitive_density'
|
|
369
|
+
])
|
|
370
|
+
|
|
371
|
+
# Routines for computing with ternary forms
|
|
372
|
+
from sage.quadratic_forms.quadratic_form__ternary_Tornaria import \
|
|
373
|
+
disc, \
|
|
374
|
+
content, \
|
|
375
|
+
adjoint, \
|
|
376
|
+
antiadjoint, \
|
|
377
|
+
is_adjoint, \
|
|
378
|
+
reciprocal, \
|
|
379
|
+
omega, \
|
|
380
|
+
delta, \
|
|
381
|
+
level__Tornaria, \
|
|
382
|
+
discrec, \
|
|
383
|
+
hasse_conductor, \
|
|
384
|
+
clifford_invariant, \
|
|
385
|
+
clifford_conductor, \
|
|
386
|
+
basiclemma, \
|
|
387
|
+
basiclemmavec, \
|
|
388
|
+
xi, \
|
|
389
|
+
xi_rec, \
|
|
390
|
+
lll, \
|
|
391
|
+
representation_number_list, \
|
|
392
|
+
representation_vector_list, \
|
|
393
|
+
is_zero, \
|
|
394
|
+
is_zero_nonsingular, \
|
|
395
|
+
is_zero_singular
|
|
396
|
+
|
|
397
|
+
# Routines to compute the theta function
|
|
398
|
+
from sage.quadratic_forms.quadratic_form__theta import \
|
|
399
|
+
theta_series, \
|
|
400
|
+
theta_series_degree_2, \
|
|
401
|
+
theta_by_pari, \
|
|
402
|
+
theta_by_cholesky
|
|
403
|
+
|
|
404
|
+
# Routines to compute the product of all local densities
|
|
405
|
+
lazy_import('sage.quadratic_forms.quadratic_form__siegel_product', [
|
|
406
|
+
'siegel_product'
|
|
407
|
+
])
|
|
408
|
+
|
|
409
|
+
# Routines to compute p-neighbors
|
|
410
|
+
from sage.quadratic_forms.quadratic_form__neighbors import \
|
|
411
|
+
find_primitive_p_divisible_vector__random, \
|
|
412
|
+
find_primitive_p_divisible_vector__next, \
|
|
413
|
+
find_p_neighbor_from_vec, \
|
|
414
|
+
neighbor_iteration, \
|
|
415
|
+
orbits_lines_mod_p
|
|
416
|
+
|
|
417
|
+
# Routines to reduce a given quadratic form
|
|
418
|
+
from sage.quadratic_forms.quadratic_form__reduction_theory import \
|
|
419
|
+
reduced_binary_form1, \
|
|
420
|
+
reduced_ternary_form__Dickson, \
|
|
421
|
+
reduced_binary_form, \
|
|
422
|
+
minkowski_reduction, \
|
|
423
|
+
minkowski_reduction_for_4vars__SP
|
|
424
|
+
# Wrappers for Conway-Sloane genus routines (in ./genera/)
|
|
425
|
+
lazy_import('sage.quadratic_forms.quadratic_form__genus', [
|
|
426
|
+
'global_genus_symbol',
|
|
427
|
+
'local_genus_symbol',
|
|
428
|
+
'CS_genus_symbol_list'
|
|
429
|
+
])
|
|
430
|
+
|
|
431
|
+
# Routines to compute local masses for ZZ.
|
|
432
|
+
lazy_import('sage.quadratic_forms.quadratic_form__mass', [
|
|
433
|
+
'shimura_mass__maximal',
|
|
434
|
+
'GHY_mass__maximal'
|
|
435
|
+
])
|
|
436
|
+
lazy_import('sage.quadratic_forms.quadratic_form__mass__Siegel_densities', [
|
|
437
|
+
'mass__by_Siegel_densities',
|
|
438
|
+
'Pall_mass_density_at_odd_prime',
|
|
439
|
+
'Watson_mass_at_2',
|
|
440
|
+
'Kitaoka_mass_at_2',
|
|
441
|
+
'mass_at_two_by_counting_mod_power'
|
|
442
|
+
])
|
|
443
|
+
lazy_import('sage.quadratic_forms.quadratic_form__mass__Conway_Sloane_masses', [
|
|
444
|
+
'parity',
|
|
445
|
+
'is_even',
|
|
446
|
+
'is_odd',
|
|
447
|
+
'conway_species_list_at_odd_prime',
|
|
448
|
+
'conway_species_list_at_2',
|
|
449
|
+
'conway_octane_of_this_unimodular_Jordan_block_at_2',
|
|
450
|
+
'conway_diagonal_factor',
|
|
451
|
+
'conway_cross_product_doubled_power',
|
|
452
|
+
'conway_type_factor',
|
|
453
|
+
'conway_p_mass',
|
|
454
|
+
'conway_standard_p_mass',
|
|
455
|
+
'conway_standard_mass',
|
|
456
|
+
'conway_mass'
|
|
457
|
+
# conway_generic_mass, \
|
|
458
|
+
# conway_p_mass_adjustment
|
|
459
|
+
])
|
|
460
|
+
|
|
461
|
+
# Routines to check local representability of numbers
|
|
462
|
+
lazy_import('sage.quadratic_forms.quadratic_form__local_representation_conditions', [
|
|
463
|
+
'local_representation_conditions',
|
|
464
|
+
'is_locally_universal_at_prime',
|
|
465
|
+
'is_locally_universal_at_all_primes',
|
|
466
|
+
'is_locally_universal_at_all_places',
|
|
467
|
+
'is_locally_represented_number_at_place',
|
|
468
|
+
'is_locally_represented_number'
|
|
469
|
+
])
|
|
470
|
+
|
|
471
|
+
# Routines to make a split local covering of the given quadratic form.
|
|
472
|
+
from sage.quadratic_forms.quadratic_form__split_local_covering import \
|
|
473
|
+
cholesky_decomposition, \
|
|
474
|
+
vectors_by_length, \
|
|
475
|
+
complementary_subform_to_vector, \
|
|
476
|
+
split_local_cover
|
|
477
|
+
|
|
478
|
+
# Routines to make automorphisms of the given quadratic form.
|
|
479
|
+
lazy_import('sage.quadratic_forms.quadratic_form__automorphisms', [
|
|
480
|
+
'basis_of_short_vectors',
|
|
481
|
+
'short_vector_list_up_to_length',
|
|
482
|
+
'short_primitive_vector_list_up_to_length',
|
|
483
|
+
'_compute_automorphisms',
|
|
484
|
+
'automorphism_group',
|
|
485
|
+
'automorphisms',
|
|
486
|
+
'number_of_automorphisms',
|
|
487
|
+
'set_number_of_automorphisms'
|
|
488
|
+
])
|
|
489
|
+
|
|
490
|
+
# Routines to test the local and global equivalence/isometry of two quadratic forms.
|
|
491
|
+
from sage.quadratic_forms.quadratic_form__equivalence_testing import \
|
|
492
|
+
is_globally_equivalent_to, \
|
|
493
|
+
is_locally_equivalent_to, \
|
|
494
|
+
has_equivalent_Jordan_decomposition_at_prime, \
|
|
495
|
+
is_rationally_isometric
|
|
496
|
+
|
|
497
|
+
# Routines for solving equations of the form Q(x) = c.
|
|
498
|
+
lazy_import('sage.quadratic_forms.qfsolve', [
|
|
499
|
+
'solve'
|
|
500
|
+
])
|
|
501
|
+
|
|
502
|
+
# Genus
|
|
503
|
+
lazy_import('sage.quadratic_forms.genera.genus',
|
|
504
|
+
'_genera_staticmethod', as_='genera')
|
|
505
|
+
|
|
506
|
+
def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_of_automorphisms=None, determinant=None):
|
|
507
|
+
"""
|
|
508
|
+
EXAMPLES::
|
|
509
|
+
|
|
510
|
+
sage: s = QuadraticForm(ZZ, 4, range(10))
|
|
511
|
+
sage: s.dim()
|
|
512
|
+
4
|
|
513
|
+
|
|
514
|
+
sage: P.<x,y,z> = QQ[]
|
|
515
|
+
sage: p = x^2 + y^2 + 2*x*z
|
|
516
|
+
sage: QuadraticForm(p)
|
|
517
|
+
Quadratic form in 3 variables over Rational Field with coefficients:
|
|
518
|
+
[ 1 0 2 ]
|
|
519
|
+
[ * 1 0 ]
|
|
520
|
+
[ * * 0 ]
|
|
521
|
+
sage: z = P.zero()
|
|
522
|
+
sage: QuadraticForm(z)
|
|
523
|
+
Quadratic form in 3 variables over Rational Field with coefficients:
|
|
524
|
+
[ 0 0 0 ]
|
|
525
|
+
[ * 0 0 ]
|
|
526
|
+
[ * * 0 ]
|
|
527
|
+
sage: q = x^2 + 3*y - z
|
|
528
|
+
sage: QuadraticForm(q)
|
|
529
|
+
Traceback (most recent call last):
|
|
530
|
+
...
|
|
531
|
+
ValueError: polynomial is neither zero nor homogeneous of degree 2
|
|
532
|
+
|
|
533
|
+
TESTS::
|
|
534
|
+
|
|
535
|
+
sage: s == loads(dumps(s))
|
|
536
|
+
True
|
|
537
|
+
sage: QuadraticForm(ZZ, -1)
|
|
538
|
+
Traceback (most recent call last):
|
|
539
|
+
...
|
|
540
|
+
ValueError: the size must be a nonnegative integer, not -1
|
|
541
|
+
|
|
542
|
+
sage: x = polygen(ZZ, 'x')
|
|
543
|
+
sage: QuadraticForm(x**2)
|
|
544
|
+
Quadratic form in 1 variables over Integer Ring with coefficients:
|
|
545
|
+
[ 1 ]
|
|
546
|
+
|
|
547
|
+
sage: QuadraticForm(1)
|
|
548
|
+
Traceback (most recent call last):
|
|
549
|
+
....
|
|
550
|
+
TypeError: wrong input for QuadraticForm
|
|
551
|
+
"""
|
|
552
|
+
# Deal with: QuadraticForm(ring, matrix)
|
|
553
|
+
matrix_init_flag = False
|
|
554
|
+
if R in Rings():
|
|
555
|
+
if isinstance(n, Matrix):
|
|
556
|
+
# Test if n is symmetric and has even diagonal
|
|
557
|
+
if not self._is_even_symmetric_matrix_(n, R):
|
|
558
|
+
raise TypeError("the matrix is not a symmetric with even diagonal defined over R")
|
|
559
|
+
|
|
560
|
+
# Rename the matrix and ring
|
|
561
|
+
M = n
|
|
562
|
+
M_ring = R
|
|
563
|
+
matrix_init_flag = True
|
|
564
|
+
|
|
565
|
+
elif isinstance(R, Matrix):
|
|
566
|
+
M = R
|
|
567
|
+
|
|
568
|
+
# Test if R is symmetric and has even diagonal
|
|
569
|
+
if not self._is_even_symmetric_matrix_(M):
|
|
570
|
+
raise TypeError("the matrix is not a symmetric with even diagonal")
|
|
571
|
+
|
|
572
|
+
M_ring = M.base_ring()
|
|
573
|
+
matrix_init_flag = True
|
|
574
|
+
|
|
575
|
+
elif isinstance(R, (Polynomial, MPolynomial)):
|
|
576
|
+
p = R
|
|
577
|
+
|
|
578
|
+
if not p.is_zero() and not (p.is_homogeneous() and p.degree() == 2):
|
|
579
|
+
raise ValueError("polynomial is neither zero nor homogeneous of degree 2")
|
|
580
|
+
|
|
581
|
+
P = p.parent()
|
|
582
|
+
R, n = P.base_ring(), P.ngens()
|
|
583
|
+
|
|
584
|
+
# Extract quadratic form coefficients
|
|
585
|
+
entries = []
|
|
586
|
+
if n == 0:
|
|
587
|
+
exponents = []
|
|
588
|
+
elif n == 1:
|
|
589
|
+
exponents = [2]
|
|
590
|
+
else:
|
|
591
|
+
from sage.combinat.integer_lists.invlex import IntegerListsLex
|
|
592
|
+
|
|
593
|
+
exponents = IntegerListsLex(2, length=n)
|
|
594
|
+
for alpha in exponents:
|
|
595
|
+
entries.append(p[alpha])
|
|
596
|
+
|
|
597
|
+
else:
|
|
598
|
+
raise TypeError('wrong input for QuadraticForm')
|
|
599
|
+
|
|
600
|
+
# Perform the quadratic form initialization
|
|
601
|
+
if matrix_init_flag:
|
|
602
|
+
self.__n = ZZ(M.nrows())
|
|
603
|
+
self.__base_ring = M_ring
|
|
604
|
+
self.__coeffs = []
|
|
605
|
+
for i in range(M.nrows()):
|
|
606
|
+
for j in range(i, M.nrows()):
|
|
607
|
+
if i == j:
|
|
608
|
+
self.__coeffs += [M_ring(M[i, j] / 2)]
|
|
609
|
+
else:
|
|
610
|
+
self.__coeffs += [M_ring(M[i, j])]
|
|
611
|
+
|
|
612
|
+
return
|
|
613
|
+
|
|
614
|
+
# -----------------------------------------------------------
|
|
615
|
+
|
|
616
|
+
# Verify the size of the matrix is an integer >= 0
|
|
617
|
+
n = ZZ(n)
|
|
618
|
+
if n < 0:
|
|
619
|
+
raise ValueError(f"the size must be a nonnegative integer, not {n}")
|
|
620
|
+
|
|
621
|
+
# Store the relevant variables
|
|
622
|
+
N = n * (n + 1) // 2
|
|
623
|
+
self.__n = n
|
|
624
|
+
self.__base_ring = R
|
|
625
|
+
self.__coeffs = [self.__base_ring.zero() for i in range(N)]
|
|
626
|
+
|
|
627
|
+
# Check if entries is a list, tuple or iterator for the
|
|
628
|
+
# current size, and if so, write the upper-triangular matrix
|
|
629
|
+
if entries is not None:
|
|
630
|
+
try:
|
|
631
|
+
entries = list(entries)
|
|
632
|
+
except TypeError:
|
|
633
|
+
raise TypeError('entries must be an iterable')
|
|
634
|
+
|
|
635
|
+
if len(entries) == N:
|
|
636
|
+
for i in range(N):
|
|
637
|
+
self.__coeffs[i] = self.__base_ring(entries[i])
|
|
638
|
+
else:
|
|
639
|
+
raise TypeError(f"the entries {entries} must be a list of size n(n+1)/2")
|
|
640
|
+
|
|
641
|
+
# -----------------------------------------------------------
|
|
642
|
+
|
|
643
|
+
# Process possible forced initialization of various fields
|
|
644
|
+
self._external_initialization_list = []
|
|
645
|
+
if unsafe_initialization:
|
|
646
|
+
|
|
647
|
+
# Set the number of automorphisms
|
|
648
|
+
if number_of_automorphisms is not None:
|
|
649
|
+
self.set_number_of_automorphisms(number_of_automorphisms)
|
|
650
|
+
# self.__number_of_automorphisms = number_of_automorphisms
|
|
651
|
+
# self.__external_initialization_list.append('number_of_automorphisms')
|
|
652
|
+
|
|
653
|
+
# Set the determinant
|
|
654
|
+
if determinant is not None:
|
|
655
|
+
self.__det = determinant
|
|
656
|
+
self._external_initialization_list.append('determinant')
|
|
657
|
+
|
|
658
|
+
def list_external_initializations(self):
|
|
659
|
+
"""
|
|
660
|
+
Return a list of the fields which were set externally at
|
|
661
|
+
creation, and not created through the usual :class:`QuadraticForm`
|
|
662
|
+
methods. These fields are as good as the external process
|
|
663
|
+
that made them, and are thus not guaranteed to be correct.
|
|
664
|
+
|
|
665
|
+
EXAMPLES::
|
|
666
|
+
|
|
667
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,5])
|
|
668
|
+
sage: Q.list_external_initializations()
|
|
669
|
+
[]
|
|
670
|
+
|
|
671
|
+
sage: # needs sage.libs.pari
|
|
672
|
+
sage: T = Q.theta_series()
|
|
673
|
+
sage: Q.list_external_initializations()
|
|
674
|
+
[]
|
|
675
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False,
|
|
676
|
+
....: number_of_automorphisms=3, determinant=0)
|
|
677
|
+
sage: Q.list_external_initializations()
|
|
678
|
+
[]
|
|
679
|
+
|
|
680
|
+
::
|
|
681
|
+
|
|
682
|
+
sage: # needs sage.libs.pari
|
|
683
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False,
|
|
684
|
+
....: number_of_automorphisms=3, determinant=0)
|
|
685
|
+
sage: Q.list_external_initializations()
|
|
686
|
+
[]
|
|
687
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=True,
|
|
688
|
+
....: number_of_automorphisms=3, determinant=0)
|
|
689
|
+
sage: Q.list_external_initializations()
|
|
690
|
+
['number_of_automorphisms', 'determinant']
|
|
691
|
+
"""
|
|
692
|
+
return deepcopy(self._external_initialization_list)
|
|
693
|
+
|
|
694
|
+
def __pari__(self):
|
|
695
|
+
"""
|
|
696
|
+
Return a PARI-formatted Hessian matrix for Q.
|
|
697
|
+
|
|
698
|
+
EXAMPLES::
|
|
699
|
+
|
|
700
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,5])
|
|
701
|
+
sage: Q.__pari__() # needs sage.libs.pari
|
|
702
|
+
[2, 0; 0, 10]
|
|
703
|
+
"""
|
|
704
|
+
return self.matrix().__pari__()
|
|
705
|
+
|
|
706
|
+
def _pari_init_(self):
|
|
707
|
+
"""
|
|
708
|
+
Return a PARI-formatted Hessian matrix for Q, as string.
|
|
709
|
+
|
|
710
|
+
EXAMPLES::
|
|
711
|
+
|
|
712
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,5])
|
|
713
|
+
sage: Q._pari_init_() # needs sage.libs.pari
|
|
714
|
+
'Mat([2,0;0,10])'
|
|
715
|
+
"""
|
|
716
|
+
return self.matrix()._pari_init_()
|
|
717
|
+
|
|
718
|
+
def _repr_(self):
|
|
719
|
+
"""
|
|
720
|
+
Give a text representation for the quadratic form given as an upper-triangular matrix of coefficients.
|
|
721
|
+
|
|
722
|
+
EXAMPLES::
|
|
723
|
+
|
|
724
|
+
sage: QuadraticForm(ZZ, 2, [1,3,5])
|
|
725
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
726
|
+
[ 1 3 ]
|
|
727
|
+
[ * 5 ]
|
|
728
|
+
"""
|
|
729
|
+
n = self.dim()
|
|
730
|
+
out_str = "Quadratic form in " + str(n) + " variables over " + str(self.base_ring()) + " with coefficients: \n"
|
|
731
|
+
for i in range(n):
|
|
732
|
+
if i > 0:
|
|
733
|
+
out_str += '\n'
|
|
734
|
+
out_str += "[ "
|
|
735
|
+
for j in range(n):
|
|
736
|
+
if (i > j):
|
|
737
|
+
out_str += "* "
|
|
738
|
+
else:
|
|
739
|
+
out_str += str(self[i, j]) + " "
|
|
740
|
+
out_str += "]"
|
|
741
|
+
return out_str
|
|
742
|
+
|
|
743
|
+
def _latex_(self):
|
|
744
|
+
"""
|
|
745
|
+
Give a LaTeX representation for the quadratic form given as an upper-triangular matrix of coefficients.
|
|
746
|
+
|
|
747
|
+
EXAMPLES::
|
|
748
|
+
|
|
749
|
+
sage: Q = QuadraticForm(ZZ, 2, [2,3,5])
|
|
750
|
+
sage: Q._latex_()
|
|
751
|
+
'Quadratic form in 2 variables over Integer Ring with coefficients: \\newline\\left[ \\begin{array}{cc}2 & 3 & * & 5 & \\end{array} \\right]'
|
|
752
|
+
"""
|
|
753
|
+
n = self.dim()
|
|
754
|
+
out_str = ""
|
|
755
|
+
out_str += "Quadratic form in " + str(n) + " variables over " + str(self.base_ring())
|
|
756
|
+
out_str += " with coefficients: \\newline"
|
|
757
|
+
out_str += "\\left[ \\begin{array}{" + n * "c" + "}"
|
|
758
|
+
for i in range(n):
|
|
759
|
+
for j in range(n):
|
|
760
|
+
if (i > j):
|
|
761
|
+
out_str += " * & "
|
|
762
|
+
else:
|
|
763
|
+
out_str += str(self[i, j]) + " & "
|
|
764
|
+
# if i < (n-1):
|
|
765
|
+
# out_str += "\\"
|
|
766
|
+
out_str += "\\end{array} \\right]"
|
|
767
|
+
return out_str
|
|
768
|
+
|
|
769
|
+
def __getitem__(self, ij):
|
|
770
|
+
r"""
|
|
771
|
+
Return the coefficient `a_{ij}` of `x_i\cdot x_j`.
|
|
772
|
+
|
|
773
|
+
EXAMPLES::
|
|
774
|
+
|
|
775
|
+
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
|
|
776
|
+
sage: matrix(ZZ, 3, 3, [Q[i,j] for i in range(3) for j in range(3)])
|
|
777
|
+
[1 2 3]
|
|
778
|
+
[2 4 5]
|
|
779
|
+
[3 5 6]
|
|
780
|
+
"""
|
|
781
|
+
# Unpack the list of indices
|
|
782
|
+
i, j = ij
|
|
783
|
+
i = int(i)
|
|
784
|
+
j = int(j)
|
|
785
|
+
|
|
786
|
+
# Ensure we're using upper-triangular coordinates
|
|
787
|
+
if i > j:
|
|
788
|
+
tmp = i
|
|
789
|
+
i = j
|
|
790
|
+
j = tmp
|
|
791
|
+
|
|
792
|
+
return self.__coeffs[i*self.__n - i*(i-1)//2 + j - i]
|
|
793
|
+
|
|
794
|
+
def __setitem__(self, ij, coeff):
|
|
795
|
+
r"""
|
|
796
|
+
Set the coefficient `a_{ij}` in front of `x_i\cdot x_j`.
|
|
797
|
+
|
|
798
|
+
EXAMPLES::
|
|
799
|
+
|
|
800
|
+
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
|
|
801
|
+
sage: Q
|
|
802
|
+
Quadratic form in 3 variables over Integer Ring with coefficients:
|
|
803
|
+
[ 1 2 3 ]
|
|
804
|
+
[ * 4 5 ]
|
|
805
|
+
[ * * 6 ]
|
|
806
|
+
sage: Q[2,1] = 17
|
|
807
|
+
sage: Q
|
|
808
|
+
Quadratic form in 3 variables over Integer Ring with coefficients:
|
|
809
|
+
[ 1 2 3 ]
|
|
810
|
+
[ * 4 17 ]
|
|
811
|
+
[ * * 6 ]
|
|
812
|
+
"""
|
|
813
|
+
# Unpack the list of indices
|
|
814
|
+
i, j = ij
|
|
815
|
+
i = int(i)
|
|
816
|
+
j = int(j)
|
|
817
|
+
|
|
818
|
+
# TO DO: Verify that 0 <= i, j <= (n-1)
|
|
819
|
+
|
|
820
|
+
# Ensure we're using upper-triangular coordinates
|
|
821
|
+
if i > j:
|
|
822
|
+
tmp = i
|
|
823
|
+
i = j
|
|
824
|
+
j = tmp
|
|
825
|
+
|
|
826
|
+
# Set the entry
|
|
827
|
+
try:
|
|
828
|
+
self.__coeffs[i*self.__n - i*(i-1)//2 + j - i] = self.__base_ring(coeff)
|
|
829
|
+
except Exception:
|
|
830
|
+
raise RuntimeError("this coefficient cannot be coerced to an element of the base ring for the quadratic form")
|
|
831
|
+
|
|
832
|
+
def __hash__(self):
|
|
833
|
+
r"""
|
|
834
|
+
TESTS::
|
|
835
|
+
|
|
836
|
+
sage: Q1 = QuadraticForm(QQ, 2, [1,1,1])
|
|
837
|
+
sage: Q2 = QuadraticForm(QQ, 2, [1,1,1])
|
|
838
|
+
sage: Q3 = QuadraticForm(QuadraticField(2), 2, [1,1,1]) # needs sage.rings.number_field
|
|
839
|
+
sage: hash(Q1) == hash(Q2)
|
|
840
|
+
True
|
|
841
|
+
sage: hash(Q1) == hash(Q3) # needs sage.rings.number_field
|
|
842
|
+
False
|
|
843
|
+
"""
|
|
844
|
+
return hash(self.__base_ring) ^ hash(tuple(self.__coeffs))
|
|
845
|
+
|
|
846
|
+
def __eq__(self, right):
|
|
847
|
+
"""
|
|
848
|
+
Determines if two quadratic forms are equal.
|
|
849
|
+
|
|
850
|
+
EXAMPLES::
|
|
851
|
+
|
|
852
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,4,10])
|
|
853
|
+
sage: Q == Q
|
|
854
|
+
True
|
|
855
|
+
|
|
856
|
+
sage: Q1 = QuadraticForm(QQ, 2, [1,4,10])
|
|
857
|
+
sage: Q == Q1
|
|
858
|
+
False
|
|
859
|
+
|
|
860
|
+
sage: Q2 = QuadraticForm(ZZ, 2, [1,4,-10])
|
|
861
|
+
sage: Q == Q1
|
|
862
|
+
False
|
|
863
|
+
sage: Q == Q2
|
|
864
|
+
False
|
|
865
|
+
sage: Q1 == Q2
|
|
866
|
+
False
|
|
867
|
+
"""
|
|
868
|
+
if not isinstance(right, QuadraticForm):
|
|
869
|
+
return False
|
|
870
|
+
return (self.__base_ring == right.__base_ring) and (self.__coeffs == right.__coeffs)
|
|
871
|
+
|
|
872
|
+
def __add__(self, right):
|
|
873
|
+
"""
|
|
874
|
+
Return the direct sum of two quadratic forms.
|
|
875
|
+
|
|
876
|
+
EXAMPLES::
|
|
877
|
+
|
|
878
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,4,10]); Q
|
|
879
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
880
|
+
[ 1 4 ]
|
|
881
|
+
[ * 10 ]
|
|
882
|
+
sage: Q2 = QuadraticForm(ZZ, 2, [1,4,-10])
|
|
883
|
+
sage: Q + Q2
|
|
884
|
+
Quadratic form in 4 variables over Integer Ring with coefficients:
|
|
885
|
+
[ 1 4 0 0 ]
|
|
886
|
+
[ * 10 0 0 ]
|
|
887
|
+
[ * * 1 4 ]
|
|
888
|
+
[ * * * -10 ]
|
|
889
|
+
"""
|
|
890
|
+
if not isinstance(right, QuadraticForm):
|
|
891
|
+
raise TypeError("cannot add these objects since they are not both quadratic forms")
|
|
892
|
+
elif (self.base_ring() != right.base_ring()):
|
|
893
|
+
raise TypeError("cannot add these since the quadratic forms do not have the same base rings")
|
|
894
|
+
|
|
895
|
+
Q = QuadraticForm(self.base_ring(), self.dim() + right.dim())
|
|
896
|
+
n = self.dim()
|
|
897
|
+
m = right.dim()
|
|
898
|
+
|
|
899
|
+
for i in range(n):
|
|
900
|
+
for j in range(i, n):
|
|
901
|
+
Q[i, j] = self[i, j]
|
|
902
|
+
|
|
903
|
+
for i in range(m):
|
|
904
|
+
for j in range(i, m):
|
|
905
|
+
Q[n + i, n + j] = right[i, j]
|
|
906
|
+
|
|
907
|
+
return Q
|
|
908
|
+
|
|
909
|
+
def sum_by_coefficients_with(self, right):
|
|
910
|
+
"""
|
|
911
|
+
Return the sum (on coefficients) of two quadratic forms of the same size.
|
|
912
|
+
|
|
913
|
+
EXAMPLES::
|
|
914
|
+
|
|
915
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,4,10]); Q
|
|
916
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
917
|
+
[ 1 4 ]
|
|
918
|
+
[ * 10 ]
|
|
919
|
+
sage: Q + Q
|
|
920
|
+
Quadratic form in 4 variables over Integer Ring with coefficients:
|
|
921
|
+
[ 1 4 0 0 ]
|
|
922
|
+
[ * 10 0 0 ]
|
|
923
|
+
[ * * 1 4 ]
|
|
924
|
+
[ * * * 10 ]
|
|
925
|
+
|
|
926
|
+
sage: Q2 = QuadraticForm(ZZ, 2, [1,4,-10])
|
|
927
|
+
sage: Q.sum_by_coefficients_with(Q2)
|
|
928
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
929
|
+
[ 2 8 ]
|
|
930
|
+
[ * 0 ]
|
|
931
|
+
"""
|
|
932
|
+
if not isinstance(right, QuadraticForm):
|
|
933
|
+
raise TypeError("cannot add these objects since they are not both quadratic forms")
|
|
934
|
+
elif self.__n != right.__n:
|
|
935
|
+
raise TypeError("cannot add these since the quadratic forms do not have the same sizes")
|
|
936
|
+
elif self.__base_ring != right.__base_ring:
|
|
937
|
+
raise TypeError("cannot add these since the quadratic forms do not have the same base rings")
|
|
938
|
+
return QuadraticForm(self.__base_ring, self.__n, [self.__coeffs[i] + right.__coeffs[i] for i in range(len(self.__coeffs))])
|
|
939
|
+
|
|
940
|
+
# ======================== CHANGE THIS TO A TENSOR PRODUCT?!? Even in Characteristic 2?!? =======================
|
|
941
|
+
# def __mul__(self, right):
|
|
942
|
+
# """
|
|
943
|
+
# Multiply (on the right) the quadratic form Q by an element of the ring that Q is defined over.
|
|
944
|
+
#
|
|
945
|
+
# EXAMPLES::
|
|
946
|
+
#
|
|
947
|
+
# sage: Q = QuadraticForm(ZZ, 2, [1,4,10])
|
|
948
|
+
# sage: Q*2
|
|
949
|
+
# Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
950
|
+
# [ 2 8 ]
|
|
951
|
+
# [ * 20 ]
|
|
952
|
+
#
|
|
953
|
+
# sage: Q+Q == Q*2
|
|
954
|
+
# True
|
|
955
|
+
# """
|
|
956
|
+
# try:
|
|
957
|
+
# c = self.base_ring()(right)
|
|
958
|
+
# except Exception:
|
|
959
|
+
# raise TypeError("the multiplier cannot be coerced into the base ring of the quadratic form")
|
|
960
|
+
# return QuadraticForm(self.base_ring(), self.dim(), [c * self.__coeffs[i] for i in range(len(self.__coeffs))])
|
|
961
|
+
|
|
962
|
+
def __call__(self, v):
|
|
963
|
+
r"""
|
|
964
|
+
Evaluate this quadratic form `Q` on a vector or matrix of elements
|
|
965
|
+
coercible to the base ring of the quadratic form.
|
|
966
|
+
|
|
967
|
+
If a vector is given then the output will be the ring element
|
|
968
|
+
`Q(v)`, but if a matrix is given then the output will be the
|
|
969
|
+
quadratic form `Q'` which in matrix notation is given by:
|
|
970
|
+
|
|
971
|
+
.. MATH::
|
|
972
|
+
|
|
973
|
+
Q' = v^t\cdot Q\cdot v.
|
|
974
|
+
|
|
975
|
+
EXAMPLES:
|
|
976
|
+
|
|
977
|
+
Evaluate a quadratic form at a vector::
|
|
978
|
+
|
|
979
|
+
sage: Q = QuadraticForm(QQ, 3, range(6))
|
|
980
|
+
sage: Q
|
|
981
|
+
Quadratic form in 3 variables over Rational Field with coefficients:
|
|
982
|
+
[ 0 1 2 ]
|
|
983
|
+
[ * 3 4 ]
|
|
984
|
+
[ * * 5 ]
|
|
985
|
+
sage: Q([1,2,3])
|
|
986
|
+
89
|
|
987
|
+
sage: Q([1,0,0])
|
|
988
|
+
0
|
|
989
|
+
sage: Q([1,1,1])
|
|
990
|
+
15
|
|
991
|
+
|
|
992
|
+
Evaluate a quadratic form using a column matrix::
|
|
993
|
+
|
|
994
|
+
sage: Q = QuadraticForm(QQ, 2, range(1,4))
|
|
995
|
+
sage: A = Matrix(ZZ,2,2,[-1,0,0,1])
|
|
996
|
+
sage: Q(A)
|
|
997
|
+
Quadratic form in 2 variables over Rational Field with coefficients:
|
|
998
|
+
[ 1 -2 ]
|
|
999
|
+
[ * 3 ]
|
|
1000
|
+
sage: Q([1,0])
|
|
1001
|
+
1
|
|
1002
|
+
sage: type(Q([1,0]))
|
|
1003
|
+
<... 'sage.rings.rational.Rational'>
|
|
1004
|
+
sage: Q = QuadraticForm(QQ, 2, range(1,4))
|
|
1005
|
+
sage: Q(matrix(2, [1,0]))
|
|
1006
|
+
Quadratic form in 1 variables over Rational Field with coefficients:
|
|
1007
|
+
[ 1 ]
|
|
1008
|
+
|
|
1009
|
+
Simple 2x2 change of variables::
|
|
1010
|
+
|
|
1011
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,0,1])
|
|
1012
|
+
sage: Q
|
|
1013
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
1014
|
+
[ 1 0 ]
|
|
1015
|
+
[ * 1 ]
|
|
1016
|
+
sage: M = Matrix(ZZ, 2, 2, [1,1,0,1])
|
|
1017
|
+
sage: M
|
|
1018
|
+
[1 1]
|
|
1019
|
+
[0 1]
|
|
1020
|
+
sage: Q(M)
|
|
1021
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
1022
|
+
[ 1 2 ]
|
|
1023
|
+
[ * 2 ]
|
|
1024
|
+
|
|
1025
|
+
Some more tests::
|
|
1026
|
+
|
|
1027
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1])
|
|
1028
|
+
sage: Q([1,2,3])
|
|
1029
|
+
14
|
|
1030
|
+
sage: v = vector([1,2,3])
|
|
1031
|
+
sage: Q(v)
|
|
1032
|
+
14
|
|
1033
|
+
sage: t = tuple([1,2,3])
|
|
1034
|
+
sage: Q(v)
|
|
1035
|
+
14
|
|
1036
|
+
sage: M = Matrix(ZZ, 3, [1,2,3])
|
|
1037
|
+
sage: Q(M)
|
|
1038
|
+
Quadratic form in 1 variables over Integer Ring with coefficients:
|
|
1039
|
+
[ 14 ]
|
|
1040
|
+
"""
|
|
1041
|
+
# If we are passed a matrix A, return the quadratic form Q(A(x))
|
|
1042
|
+
# (In matrix notation: A^t * Q * A)
|
|
1043
|
+
n = self.dim()
|
|
1044
|
+
|
|
1045
|
+
if isinstance(v, Matrix):
|
|
1046
|
+
# Check that v has the correct number of rows
|
|
1047
|
+
if v.nrows() != n:
|
|
1048
|
+
raise TypeError(f"the matrix must have {n} rows")
|
|
1049
|
+
|
|
1050
|
+
# Create the new quadratic form
|
|
1051
|
+
m = v.ncols()
|
|
1052
|
+
Q2 = QuadraticForm(self.base_ring(), m)
|
|
1053
|
+
return QFEvaluateMatrix(self, v, Q2)
|
|
1054
|
+
|
|
1055
|
+
elif isinstance(v, (Vector, list, tuple)):
|
|
1056
|
+
# Check the vector/tuple/list has the correct length
|
|
1057
|
+
if len(v) != n:
|
|
1058
|
+
raise TypeError(f"your vector needs to have length {n}")
|
|
1059
|
+
|
|
1060
|
+
# TO DO: Check that the elements can be coerced into the base ring of Q -- on first elt.
|
|
1061
|
+
if len(v) > 0:
|
|
1062
|
+
try:
|
|
1063
|
+
self.base_ring()(v[0])
|
|
1064
|
+
except Exception:
|
|
1065
|
+
raise TypeError("your vector is not coercible to the base ring of the quadratic form")
|
|
1066
|
+
|
|
1067
|
+
# Attempt to evaluate Q[v]
|
|
1068
|
+
return QFEvaluateVector(self, v)
|
|
1069
|
+
|
|
1070
|
+
else:
|
|
1071
|
+
raise TypeError
|
|
1072
|
+
|
|
1073
|
+
# ===============================================
|
|
1074
|
+
|
|
1075
|
+
def _is_even_symmetric_matrix_(self, A, R=None):
|
|
1076
|
+
"""
|
|
1077
|
+
Test if a matrix is symmetric, defined over `R`, and has even diagonal in `R`.
|
|
1078
|
+
|
|
1079
|
+
INPUT:
|
|
1080
|
+
|
|
1081
|
+
- ``A`` -- matrix
|
|
1082
|
+
|
|
1083
|
+
- ``R`` -- ring
|
|
1084
|
+
|
|
1085
|
+
EXAMPLES::
|
|
1086
|
+
|
|
1087
|
+
sage: Q = QuadraticForm(ZZ, 2, [2,3,5])
|
|
1088
|
+
sage: A = Q.matrix()
|
|
1089
|
+
sage: A
|
|
1090
|
+
[ 4 3]
|
|
1091
|
+
[ 3 10]
|
|
1092
|
+
sage: Q._is_even_symmetric_matrix_(A)
|
|
1093
|
+
True
|
|
1094
|
+
sage: A[0,0] = 1
|
|
1095
|
+
sage: Q._is_even_symmetric_matrix_(A)
|
|
1096
|
+
False
|
|
1097
|
+
"""
|
|
1098
|
+
if not isinstance(A, Matrix):
|
|
1099
|
+
raise TypeError("A is not a matrix.")
|
|
1100
|
+
|
|
1101
|
+
ring_coerce_test = True
|
|
1102
|
+
if R is None: # This allows us to omit the ring from the variables, and take it from the matrix
|
|
1103
|
+
R = A.base_ring()
|
|
1104
|
+
ring_coerce_test = False
|
|
1105
|
+
|
|
1106
|
+
if R not in Rings():
|
|
1107
|
+
raise TypeError("R is not a ring.")
|
|
1108
|
+
|
|
1109
|
+
if not (A.is_square() and A.is_symmetric()):
|
|
1110
|
+
return False
|
|
1111
|
+
|
|
1112
|
+
# Test that all entries coerce to R
|
|
1113
|
+
n = A.nrows()
|
|
1114
|
+
if not ((A.base_ring() == R) or ring_coerce_test):
|
|
1115
|
+
try:
|
|
1116
|
+
for i in range(n):
|
|
1117
|
+
for j in range(i, n):
|
|
1118
|
+
R(A[i, j])
|
|
1119
|
+
except (TypeError, ValueError):
|
|
1120
|
+
return False
|
|
1121
|
+
|
|
1122
|
+
# Test that the diagonal is even (if 1/2 isn't in R)
|
|
1123
|
+
if not R(2).is_unit():
|
|
1124
|
+
for i in range(n):
|
|
1125
|
+
if not is_even(R(A[i, i])):
|
|
1126
|
+
return False
|
|
1127
|
+
|
|
1128
|
+
return True
|
|
1129
|
+
|
|
1130
|
+
# =====================================================================
|
|
1131
|
+
|
|
1132
|
+
def matrix(self):
|
|
1133
|
+
r"""
|
|
1134
|
+
Return the Hessian matrix `A` for which `Q(X) = (1/2) X^t\cdot A\cdot X`.
|
|
1135
|
+
|
|
1136
|
+
EXAMPLES::
|
|
1137
|
+
|
|
1138
|
+
sage: Q = QuadraticForm(ZZ, 3, range(6))
|
|
1139
|
+
sage: Q.matrix()
|
|
1140
|
+
[ 0 1 2]
|
|
1141
|
+
[ 1 6 4]
|
|
1142
|
+
[ 2 4 10]
|
|
1143
|
+
"""
|
|
1144
|
+
return self.Hessian_matrix()
|
|
1145
|
+
|
|
1146
|
+
def Hessian_matrix(self):
|
|
1147
|
+
r"""
|
|
1148
|
+
Return the Hessian matrix `A` for which `Q(X) = (1/2) X^t\cdot A\cdot X`.
|
|
1149
|
+
|
|
1150
|
+
EXAMPLES::
|
|
1151
|
+
|
|
1152
|
+
sage: Q = QuadraticForm(QQ, 2, range(1,4)); Q
|
|
1153
|
+
Quadratic form in 2 variables over Rational Field with coefficients:
|
|
1154
|
+
[ 1 2 ]
|
|
1155
|
+
[ * 3 ]
|
|
1156
|
+
sage: Q.Hessian_matrix()
|
|
1157
|
+
[2 2]
|
|
1158
|
+
[2 6]
|
|
1159
|
+
sage: Q.matrix().base_ring()
|
|
1160
|
+
Rational Field
|
|
1161
|
+
"""
|
|
1162
|
+
mat_entries = []
|
|
1163
|
+
for i in range(self.dim()):
|
|
1164
|
+
for j in range(self.dim()):
|
|
1165
|
+
if i == j:
|
|
1166
|
+
mat_entries += [2 * self[i, j]]
|
|
1167
|
+
else:
|
|
1168
|
+
mat_entries += [self[i, j]]
|
|
1169
|
+
|
|
1170
|
+
return matrix(self.base_ring(), self.dim(), self.dim(), mat_entries)
|
|
1171
|
+
|
|
1172
|
+
def Gram_matrix_rational(self):
|
|
1173
|
+
r"""
|
|
1174
|
+
Return a (symmetric) Gram matrix `A` for the quadratic form `Q`,
|
|
1175
|
+
meaning that
|
|
1176
|
+
|
|
1177
|
+
.. MATH::
|
|
1178
|
+
|
|
1179
|
+
Q(x) = x^t\cdot A\cdot x,
|
|
1180
|
+
|
|
1181
|
+
defined over the fraction field of the base ring.
|
|
1182
|
+
|
|
1183
|
+
EXAMPLES::
|
|
1184
|
+
|
|
1185
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
|
|
1186
|
+
sage: A = Q.Gram_matrix_rational(); A
|
|
1187
|
+
[1 0 0 0]
|
|
1188
|
+
[0 3 0 0]
|
|
1189
|
+
[0 0 5 0]
|
|
1190
|
+
[0 0 0 7]
|
|
1191
|
+
sage: A.base_ring()
|
|
1192
|
+
Rational Field
|
|
1193
|
+
"""
|
|
1194
|
+
return (ZZ(1) / ZZ(2)) * self.matrix()
|
|
1195
|
+
|
|
1196
|
+
def Gram_matrix(self):
|
|
1197
|
+
r"""
|
|
1198
|
+
Return a (symmetric) Gram matrix `A` for the quadratic form `Q`,
|
|
1199
|
+
meaning that
|
|
1200
|
+
|
|
1201
|
+
.. MATH::
|
|
1202
|
+
|
|
1203
|
+
Q(x) = x^t\cdot A\cdot x,
|
|
1204
|
+
|
|
1205
|
+
defined over the base ring of `Q`. If this is not possible,
|
|
1206
|
+
then a :exc:`TypeError` is raised.
|
|
1207
|
+
|
|
1208
|
+
EXAMPLES::
|
|
1209
|
+
|
|
1210
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
|
|
1211
|
+
sage: A = Q.Gram_matrix(); A
|
|
1212
|
+
[1 0 0 0]
|
|
1213
|
+
[0 3 0 0]
|
|
1214
|
+
[0 0 5 0]
|
|
1215
|
+
[0 0 0 7]
|
|
1216
|
+
sage: A.base_ring()
|
|
1217
|
+
Integer Ring
|
|
1218
|
+
"""
|
|
1219
|
+
A = (ZZ.one() / ZZ(2)) * self.matrix()
|
|
1220
|
+
n = self.dim()
|
|
1221
|
+
|
|
1222
|
+
# Test to see if it has an integral Gram matrix
|
|
1223
|
+
Int_flag = True
|
|
1224
|
+
for i in range(n):
|
|
1225
|
+
for j in range(i, n):
|
|
1226
|
+
Int_flag &= A[i, j] in self.base_ring()
|
|
1227
|
+
|
|
1228
|
+
# Return the Gram matrix, or an error
|
|
1229
|
+
if Int_flag:
|
|
1230
|
+
return MatrixSpace(self.base_ring(), n, n)(A)
|
|
1231
|
+
raise TypeError("this form does not have an integral Gram matrix")
|
|
1232
|
+
|
|
1233
|
+
def has_integral_Gram_matrix(self) -> bool:
|
|
1234
|
+
r"""
|
|
1235
|
+
Return whether the quadratic form has an integral Gram matrix (with respect to its base ring).
|
|
1236
|
+
|
|
1237
|
+
A warning is issued if the form is defined over a field,
|
|
1238
|
+
since in that case the return is trivially true.
|
|
1239
|
+
|
|
1240
|
+
EXAMPLES::
|
|
1241
|
+
|
|
1242
|
+
sage: Q = QuadraticForm(ZZ, 2, [7,8,9])
|
|
1243
|
+
sage: Q.has_integral_Gram_matrix()
|
|
1244
|
+
True
|
|
1245
|
+
|
|
1246
|
+
::
|
|
1247
|
+
|
|
1248
|
+
sage: Q = QuadraticForm(ZZ, 2, [4,5,6])
|
|
1249
|
+
sage: Q.has_integral_Gram_matrix()
|
|
1250
|
+
False
|
|
1251
|
+
"""
|
|
1252
|
+
# Warning over fields
|
|
1253
|
+
if self.base_ring() in Fields():
|
|
1254
|
+
warn("Warning -- A quadratic form over a field always has integral Gram matrix. Do you really want to do this?!?")
|
|
1255
|
+
|
|
1256
|
+
# Determine integrality of the Gram matrix
|
|
1257
|
+
try:
|
|
1258
|
+
self.Gram_matrix()
|
|
1259
|
+
except TypeError:
|
|
1260
|
+
return False
|
|
1261
|
+
else:
|
|
1262
|
+
return True
|
|
1263
|
+
|
|
1264
|
+
def gcd(self):
|
|
1265
|
+
"""
|
|
1266
|
+
Return the greatest common divisor of the coefficients of the
|
|
1267
|
+
quadratic form (as a polynomial).
|
|
1268
|
+
|
|
1269
|
+
EXAMPLES::
|
|
1270
|
+
|
|
1271
|
+
sage: Q = QuadraticForm(ZZ, 4, range(1, 21, 2))
|
|
1272
|
+
sage: Q.gcd()
|
|
1273
|
+
1
|
|
1274
|
+
|
|
1275
|
+
sage: Q = QuadraticForm(ZZ, 4, range(0, 20, 2))
|
|
1276
|
+
sage: Q.gcd()
|
|
1277
|
+
2
|
|
1278
|
+
"""
|
|
1279
|
+
if self.base_ring() != ZZ:
|
|
1280
|
+
raise TypeError("the given quadratic form must be defined over ZZ")
|
|
1281
|
+
return GCD(self.coefficients())
|
|
1282
|
+
|
|
1283
|
+
def polynomial(self, names='x'):
|
|
1284
|
+
r"""
|
|
1285
|
+
Return the quadratic form as a polynomial in `n` variables.
|
|
1286
|
+
|
|
1287
|
+
INPUT:
|
|
1288
|
+
|
|
1289
|
+
- ``self`` -- a quadratic form over a commutative ring
|
|
1290
|
+
|
|
1291
|
+
- ``names`` -- specification of the names of the variables; see :func:`PolynomialRing`
|
|
1292
|
+
|
|
1293
|
+
OUTPUT: the polynomial form of the quadratic form
|
|
1294
|
+
|
|
1295
|
+
EXAMPLES::
|
|
1296
|
+
|
|
1297
|
+
sage: Q = DiagonalQuadraticForm(QQ,[1, 3, 5, 7])
|
|
1298
|
+
sage: P = Q.polynomial(); P
|
|
1299
|
+
x0^2 + 3*x1^2 + 5*x2^2 + 7*x3^2
|
|
1300
|
+
|
|
1301
|
+
::
|
|
1302
|
+
|
|
1303
|
+
sage: # needs sage.rings.number_field
|
|
1304
|
+
sage: x = polygen(ZZ, 'x')
|
|
1305
|
+
sage: F.<a> = NumberField(x^2 - 5)
|
|
1306
|
+
sage: Z = F.ring_of_integers()
|
|
1307
|
+
sage: Q = QuadraticForm(Z, 3, [2*a, 3*a, 0, 1 - a, 0, 2*a + 4])
|
|
1308
|
+
sage: P = Q.polynomial(names='y'); P
|
|
1309
|
+
2*a*y0^2 + 3*a*y0*y1 + (-a + 1)*y1^2 + (2*a + 4)*y2^2
|
|
1310
|
+
sage: Q = QuadraticForm(F, 4,
|
|
1311
|
+
....: [a, 3*a, 0, 1 - a, a - 3, 0, 2*a + 4, 4 + a, 0, 1])
|
|
1312
|
+
sage: Q.polynomial(names='z')
|
|
1313
|
+
a*z0^2 + (3*a)*z0*z1 + (a - 3)*z1^2 + (a + 4)*z2^2
|
|
1314
|
+
+ (-a + 1)*z0*z3 + (2*a + 4)*z1*z3 + z3^2
|
|
1315
|
+
sage: B.<i,j,k> = QuaternionAlgebra(F,-1,-1)
|
|
1316
|
+
sage: Q = QuadraticForm(B, 3, [2*a, 3*a, i, 1 - a, 0, 2*a + 4])
|
|
1317
|
+
sage: Q.polynomial()
|
|
1318
|
+
Traceback (most recent call last):
|
|
1319
|
+
...
|
|
1320
|
+
ValueError: Can only create polynomial rings over commutative rings
|
|
1321
|
+
"""
|
|
1322
|
+
B = self.base_ring()
|
|
1323
|
+
if B not in Rings().Commutative():
|
|
1324
|
+
raise ValueError('Can only create polynomial rings over commutative rings')
|
|
1325
|
+
n = self.dim()
|
|
1326
|
+
M = matrix(B, n)
|
|
1327
|
+
for i in range(n):
|
|
1328
|
+
for j in range(i, n):
|
|
1329
|
+
M[i, j] = self[i, j]
|
|
1330
|
+
R = PolynomialRing(self.base_ring(), names, n)
|
|
1331
|
+
V = vector(R.gens())
|
|
1332
|
+
return (V * M).dot_product(V)
|
|
1333
|
+
|
|
1334
|
+
@staticmethod
|
|
1335
|
+
def from_polynomial(poly):
|
|
1336
|
+
r"""
|
|
1337
|
+
Construct a :class:`QuadraticForm` from a multivariate
|
|
1338
|
+
polynomial. Inverse of :meth:`polynomial`.
|
|
1339
|
+
|
|
1340
|
+
EXAMPLES::
|
|
1341
|
+
|
|
1342
|
+
sage: R.<x,y,z> = ZZ[]
|
|
1343
|
+
sage: f = 5*x^2 - x*z - 3*y*z - 2*y^2 + 9*z^2
|
|
1344
|
+
sage: Q = QuadraticForm.from_polynomial(f); Q
|
|
1345
|
+
Quadratic form in 3 variables over Integer Ring with coefficients:
|
|
1346
|
+
[ 5 0 -1 ]
|
|
1347
|
+
[ * -2 -3 ]
|
|
1348
|
+
[ * * 9 ]
|
|
1349
|
+
sage: Q.polynomial()
|
|
1350
|
+
5*x0^2 - 2*x1^2 - x0*x2 - 3*x1*x2 + 9*x2^2
|
|
1351
|
+
sage: Q.polynomial()(R.gens()) == f
|
|
1352
|
+
True
|
|
1353
|
+
|
|
1354
|
+
The method fails if the given polynomial is not a quadratic form::
|
|
1355
|
+
|
|
1356
|
+
sage: QuadraticForm.from_polynomial(x^3 + x*z + 5*y^2)
|
|
1357
|
+
Traceback (most recent call last):
|
|
1358
|
+
...
|
|
1359
|
+
ValueError: polynomial has monomials of degree != 2
|
|
1360
|
+
"""
|
|
1361
|
+
R = poly.parent()
|
|
1362
|
+
from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
|
|
1363
|
+
if not isinstance(R, MPolynomialRing_base):
|
|
1364
|
+
raise TypeError(f'not a multivariate polynomial ring: {R}')
|
|
1365
|
+
if not all(mon.degree() == 2 for mon in poly.monomials()):
|
|
1366
|
+
raise ValueError('polynomial has monomials of degree != 2')
|
|
1367
|
+
base = R.base_ring()
|
|
1368
|
+
vs = R.gens()
|
|
1369
|
+
coeffs = [poly.monomial_coefficient(v * w)
|
|
1370
|
+
for i, v in enumerate(vs) for w in vs[i:]]
|
|
1371
|
+
return QuadraticForm(base, len(vs), coeffs)
|
|
1372
|
+
|
|
1373
|
+
def is_primitive(self) -> bool:
|
|
1374
|
+
"""
|
|
1375
|
+
Determine if the given integer-valued form is primitive.
|
|
1376
|
+
|
|
1377
|
+
This means not an integer (`> 1`) multiple of another integer-valued
|
|
1378
|
+
quadratic form.
|
|
1379
|
+
|
|
1380
|
+
EXAMPLES::
|
|
1381
|
+
|
|
1382
|
+
sage: Q = QuadraticForm(ZZ, 2, [2,3,4])
|
|
1383
|
+
sage: Q.is_primitive()
|
|
1384
|
+
True
|
|
1385
|
+
sage: Q = QuadraticForm(ZZ, 2, [2,4,8])
|
|
1386
|
+
sage: Q.is_primitive()
|
|
1387
|
+
False
|
|
1388
|
+
"""
|
|
1389
|
+
return self.gcd() == 1
|
|
1390
|
+
|
|
1391
|
+
def primitive(self):
|
|
1392
|
+
r"""
|
|
1393
|
+
Return a primitive version of an integer-valued quadratic form, defined over `\ZZ`.
|
|
1394
|
+
|
|
1395
|
+
EXAMPLES::
|
|
1396
|
+
|
|
1397
|
+
sage: Q = QuadraticForm(ZZ, 2, [2,3,4])
|
|
1398
|
+
sage: Q.primitive()
|
|
1399
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
1400
|
+
[ 2 3 ]
|
|
1401
|
+
[ * 4 ]
|
|
1402
|
+
sage: Q = QuadraticForm(ZZ, 2, [2,4,8])
|
|
1403
|
+
sage: Q.primitive()
|
|
1404
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
1405
|
+
[ 1 2 ]
|
|
1406
|
+
[ * 4 ]
|
|
1407
|
+
"""
|
|
1408
|
+
if self.base_ring() != ZZ:
|
|
1409
|
+
raise TypeError("the given quadratic form must be defined over ZZ")
|
|
1410
|
+
g = self.gcd()
|
|
1411
|
+
return QuadraticForm(ZZ, self.dim(),
|
|
1412
|
+
[x // g for x in self.coefficients()])
|
|
1413
|
+
|
|
1414
|
+
def adjoint_primitive(self):
|
|
1415
|
+
"""
|
|
1416
|
+
Return the primitive adjoint of the quadratic form, which is
|
|
1417
|
+
the smallest discriminant integer-valued quadratic form whose
|
|
1418
|
+
matrix is a scalar multiple of the inverse of the matrix of
|
|
1419
|
+
the given quadratic form.
|
|
1420
|
+
|
|
1421
|
+
EXAMPLES::
|
|
1422
|
+
|
|
1423
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
1424
|
+
sage: Q.adjoint_primitive() # needs sage.libs.pari
|
|
1425
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
1426
|
+
[ 3 -2 ]
|
|
1427
|
+
[ * 1 ]
|
|
1428
|
+
"""
|
|
1429
|
+
return QuadraticForm(self.Hessian_matrix().adjoint_classical()).primitive()
|
|
1430
|
+
|
|
1431
|
+
def dim(self):
|
|
1432
|
+
"""
|
|
1433
|
+
Return the number of variables of the quadratic form.
|
|
1434
|
+
|
|
1435
|
+
EXAMPLES::
|
|
1436
|
+
|
|
1437
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
1438
|
+
sage: Q.dim()
|
|
1439
|
+
2
|
|
1440
|
+
sage: parent(Q.dim())
|
|
1441
|
+
Integer Ring
|
|
1442
|
+
sage: Q = QuadraticForm(Q.matrix())
|
|
1443
|
+
sage: Q.dim()
|
|
1444
|
+
2
|
|
1445
|
+
sage: parent(Q.dim())
|
|
1446
|
+
Integer Ring
|
|
1447
|
+
"""
|
|
1448
|
+
return self.__n
|
|
1449
|
+
|
|
1450
|
+
def base_ring(self):
|
|
1451
|
+
"""
|
|
1452
|
+
Return the ring over which the quadratic form is defined.
|
|
1453
|
+
|
|
1454
|
+
EXAMPLES::
|
|
1455
|
+
|
|
1456
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
1457
|
+
sage: Q.base_ring()
|
|
1458
|
+
Integer Ring
|
|
1459
|
+
"""
|
|
1460
|
+
return self.__base_ring
|
|
1461
|
+
|
|
1462
|
+
def coefficients(self):
|
|
1463
|
+
r"""
|
|
1464
|
+
Return the matrix of upper triangular coefficients,
|
|
1465
|
+
by reading across the rows from the main diagonal.
|
|
1466
|
+
|
|
1467
|
+
EXAMPLES::
|
|
1468
|
+
|
|
1469
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
1470
|
+
sage: Q.coefficients()
|
|
1471
|
+
[1, 2, 3]
|
|
1472
|
+
"""
|
|
1473
|
+
return self.__coeffs
|
|
1474
|
+
|
|
1475
|
+
def det(self):
|
|
1476
|
+
r"""
|
|
1477
|
+
Return the determinant of the Gram matrix of `2\cdot Q`, or
|
|
1478
|
+
equivalently the determinant of the Hessian matrix of `Q`.
|
|
1479
|
+
|
|
1480
|
+
.. NOTE::
|
|
1481
|
+
|
|
1482
|
+
This is always defined over the same ring as the quadratic form.
|
|
1483
|
+
|
|
1484
|
+
EXAMPLES::
|
|
1485
|
+
|
|
1486
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
1487
|
+
sage: Q.det()
|
|
1488
|
+
8
|
|
1489
|
+
"""
|
|
1490
|
+
try:
|
|
1491
|
+
return self.__det
|
|
1492
|
+
except AttributeError:
|
|
1493
|
+
# Compute the determinant
|
|
1494
|
+
if self.dim() == 0:
|
|
1495
|
+
new_det = self.base_ring()(1)
|
|
1496
|
+
else:
|
|
1497
|
+
new_det = self.matrix().det()
|
|
1498
|
+
|
|
1499
|
+
# Cache and return the determinant
|
|
1500
|
+
self.__det = new_det
|
|
1501
|
+
return new_det
|
|
1502
|
+
|
|
1503
|
+
def Gram_det(self):
|
|
1504
|
+
r"""
|
|
1505
|
+
Return the determinant of the Gram matrix of `Q`.
|
|
1506
|
+
|
|
1507
|
+
.. NOTE::
|
|
1508
|
+
|
|
1509
|
+
This is defined over the fraction field of the ring of
|
|
1510
|
+
the quadratic form, but is often not defined over the same
|
|
1511
|
+
ring as the quadratic form.
|
|
1512
|
+
|
|
1513
|
+
EXAMPLES::
|
|
1514
|
+
|
|
1515
|
+
sage: Q = QuadraticForm(ZZ, 2, [1,2,3])
|
|
1516
|
+
sage: Q.Gram_det()
|
|
1517
|
+
2
|
|
1518
|
+
"""
|
|
1519
|
+
return self.det() / ZZ(2**self.dim())
|
|
1520
|
+
|
|
1521
|
+
def change_ring(self, R):
|
|
1522
|
+
"""
|
|
1523
|
+
Alters the quadratic form to have all coefficients
|
|
1524
|
+
defined over the new base ring `R`. Here `R` must be
|
|
1525
|
+
coercible to from the current base ring.
|
|
1526
|
+
|
|
1527
|
+
.. NOTE::
|
|
1528
|
+
|
|
1529
|
+
This is preferable to performing an explicit
|
|
1530
|
+
coercion through the :meth:`base_ring` method, which does
|
|
1531
|
+
not affect the individual coefficients. This is
|
|
1532
|
+
particularly useful for performing fast modular
|
|
1533
|
+
arithmetic evaluations.
|
|
1534
|
+
|
|
1535
|
+
INPUT:
|
|
1536
|
+
|
|
1537
|
+
- ``R`` -- a ring
|
|
1538
|
+
|
|
1539
|
+
OUTPUT: quadratic form
|
|
1540
|
+
|
|
1541
|
+
EXAMPLES::
|
|
1542
|
+
|
|
1543
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,1]); Q
|
|
1544
|
+
Quadratic form in 2 variables over Integer Ring with coefficients:
|
|
1545
|
+
[ 1 0 ]
|
|
1546
|
+
[ * 1 ]
|
|
1547
|
+
|
|
1548
|
+
sage: Q1 = Q.change_ring(IntegerModRing(5)); Q1
|
|
1549
|
+
Quadratic form in 2 variables over Ring of integers modulo 5 with coefficients:
|
|
1550
|
+
[ 1 0 ]
|
|
1551
|
+
[ * 1 ]
|
|
1552
|
+
|
|
1553
|
+
sage: Q1([35,11])
|
|
1554
|
+
1
|
|
1555
|
+
"""
|
|
1556
|
+
# Check that a canonical coercion is possible
|
|
1557
|
+
if R not in Rings():
|
|
1558
|
+
raise TypeError("R is not a ring")
|
|
1559
|
+
if not R.has_coerce_map_from(self.base_ring()):
|
|
1560
|
+
raise TypeError(f"there is no canonical coercion from {self.base_ring()} to R")
|
|
1561
|
+
# Return the coerced form
|
|
1562
|
+
return QuadraticForm(R, self.dim(), [R(x) for x in self.coefficients()])
|
|
1563
|
+
|
|
1564
|
+
base_change_to = deprecated_function_alias(35248, change_ring)
|
|
1565
|
+
|
|
1566
|
+
def level(self):
|
|
1567
|
+
r"""
|
|
1568
|
+
Determines the level of the quadratic form over a PID, which is a
|
|
1569
|
+
generator for the smallest ideal `N` of `R` such that `N\cdot (` the matrix of
|
|
1570
|
+
`2*Q` `)^{(-1)}` is in `R` with diagonal in `2R`.
|
|
1571
|
+
|
|
1572
|
+
Over `\ZZ` this returns a nonnegative number.
|
|
1573
|
+
|
|
1574
|
+
(Caveat: This always returns the unit ideal when working over a field!)
|
|
1575
|
+
|
|
1576
|
+
EXAMPLES::
|
|
1577
|
+
|
|
1578
|
+
sage: Q = QuadraticForm(ZZ, 2, range(1,4))
|
|
1579
|
+
sage: Q.level()
|
|
1580
|
+
8
|
|
1581
|
+
|
|
1582
|
+
sage: Q1 = QuadraticForm(QQ, 2, range(1,4))
|
|
1583
|
+
sage: Q1.level() # random
|
|
1584
|
+
UserWarning: Warning -- The level of a quadratic form over a field is always 1.
|
|
1585
|
+
Do you really want to do this?!?
|
|
1586
|
+
1
|
|
1587
|
+
|
|
1588
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
|
|
1589
|
+
sage: Q.level()
|
|
1590
|
+
420
|
|
1591
|
+
"""
|
|
1592
|
+
# Try to return the cached level
|
|
1593
|
+
try:
|
|
1594
|
+
return self.__level
|
|
1595
|
+
except AttributeError:
|
|
1596
|
+
|
|
1597
|
+
# Check that the base ring is a PID
|
|
1598
|
+
if self.base_ring() not in PrincipalIdealDomains():
|
|
1599
|
+
raise TypeError("the level (as a number) is only defined over a Principal Ideal Domain ; try using level_ideal()")
|
|
1600
|
+
|
|
1601
|
+
# Warn the user if the form is defined over a field!
|
|
1602
|
+
if self.base_ring() in Fields():
|
|
1603
|
+
warn("Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?")
|
|
1604
|
+
# raise RuntimeError("Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?")
|
|
1605
|
+
|
|
1606
|
+
# Check invertibility and find the inverse
|
|
1607
|
+
try:
|
|
1608
|
+
mat_inv = self.matrix()**(-1)
|
|
1609
|
+
except ZeroDivisionError:
|
|
1610
|
+
raise TypeError("the quadratic form is degenerate")
|
|
1611
|
+
|
|
1612
|
+
# Compute the level
|
|
1613
|
+
inv_denoms = []
|
|
1614
|
+
for i in range(self.dim()):
|
|
1615
|
+
for j in range(i, self.dim()):
|
|
1616
|
+
if (i == j):
|
|
1617
|
+
inv_denoms += [denominator(mat_inv[i, j] / 2)]
|
|
1618
|
+
else:
|
|
1619
|
+
inv_denoms += [denominator(mat_inv[i, j])]
|
|
1620
|
+
lvl = LCM(inv_denoms)
|
|
1621
|
+
lvl = Ideal(self.base_ring()(lvl)).gen()
|
|
1622
|
+
##############################################################
|
|
1623
|
+
# To do this properly, the level should be the inverse of the
|
|
1624
|
+
# fractional ideal (over R) generated by the entries whose
|
|
1625
|
+
# denominators we take above. =)
|
|
1626
|
+
##############################################################
|
|
1627
|
+
|
|
1628
|
+
# Normalize the result over ZZ
|
|
1629
|
+
if self.base_ring() == IntegerRing():
|
|
1630
|
+
lvl = abs(lvl)
|
|
1631
|
+
|
|
1632
|
+
# Cache and return the level
|
|
1633
|
+
self.__level = lvl
|
|
1634
|
+
return lvl
|
|
1635
|
+
|
|
1636
|
+
def level_ideal(self):
|
|
1637
|
+
r"""
|
|
1638
|
+
Determine the level of the quadratic form (over `R`), which is the
|
|
1639
|
+
smallest ideal `N` of `R` such that `N \cdot (` the matrix of `2Q` `)^{(-1)}` is
|
|
1640
|
+
in `R` with diagonal in `2R`.
|
|
1641
|
+
(Caveat: This always returns the principal ideal when working over a field!)
|
|
1642
|
+
|
|
1643
|
+
.. WARNING::
|
|
1644
|
+
|
|
1645
|
+
This only works over a PID ring of integers for now!
|
|
1646
|
+
(Waiting for Sage fractional ideal support.)
|
|
1647
|
+
|
|
1648
|
+
EXAMPLES::
|
|
1649
|
+
|
|
1650
|
+
sage: Q = QuadraticForm(ZZ, 2, range(1,4))
|
|
1651
|
+
sage: Q.level_ideal()
|
|
1652
|
+
Principal ideal (8) of Integer Ring
|
|
1653
|
+
|
|
1654
|
+
sage: Q1 = QuadraticForm(QQ, 2, range(1,4))
|
|
1655
|
+
sage: Q1.level_ideal()
|
|
1656
|
+
Principal ideal (1) of Rational Field
|
|
1657
|
+
|
|
1658
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
|
|
1659
|
+
sage: Q.level_ideal()
|
|
1660
|
+
Principal ideal (420) of Integer Ring
|
|
1661
|
+
"""
|
|
1662
|
+
##############################################################
|
|
1663
|
+
# To do this properly, the level should be the inverse of the
|
|
1664
|
+
# fractional ideal (over R) generated by the entries whose
|
|
1665
|
+
# denominators we take above.
|
|
1666
|
+
##############################################################
|
|
1667
|
+
return Ideal(self.base_ring()(self.level()))
|
|
1668
|
+
|
|
1669
|
+
def bilinear_map(self, v, w):
|
|
1670
|
+
r"""
|
|
1671
|
+
Return the value of the associated bilinear map on two vectors.
|
|
1672
|
+
|
|
1673
|
+
Given a quadratic form `Q` over some base ring `R` with
|
|
1674
|
+
characteristic not equal to 2, this gives the image of two
|
|
1675
|
+
vectors with coefficients in `R` under the associated bilinear
|
|
1676
|
+
map `B`, given by the relation `2 B(v,w) = Q(v) + Q(w) - Q(v+w)`.
|
|
1677
|
+
|
|
1678
|
+
INPUT:
|
|
1679
|
+
|
|
1680
|
+
- ``v``, ``w`` -- two vectors
|
|
1681
|
+
|
|
1682
|
+
OUTPUT: an element of the base ring `R`
|
|
1683
|
+
|
|
1684
|
+
EXAMPLES:
|
|
1685
|
+
|
|
1686
|
+
First, an example over `\ZZ`::
|
|
1687
|
+
|
|
1688
|
+
sage: Q = QuadraticForm(ZZ, 3, [1,4,0,1,4,1])
|
|
1689
|
+
sage: v = vector(ZZ, (1,2,0))
|
|
1690
|
+
sage: w = vector(ZZ, (0,1,1))
|
|
1691
|
+
sage: Q.bilinear_map(v, w)
|
|
1692
|
+
8
|
|
1693
|
+
|
|
1694
|
+
This also works over `\QQ`::
|
|
1695
|
+
|
|
1696
|
+
sage: Q = QuadraticForm(QQ, 2, [1/2,2,1])
|
|
1697
|
+
sage: v = vector(QQ, (1,1))
|
|
1698
|
+
sage: w = vector(QQ, (1/2,2))
|
|
1699
|
+
sage: Q.bilinear_map(v, w)
|
|
1700
|
+
19/4
|
|
1701
|
+
|
|
1702
|
+
The vectors must have the correct length::
|
|
1703
|
+
|
|
1704
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,7,7])
|
|
1705
|
+
sage: v = vector((1,2))
|
|
1706
|
+
sage: w = vector((1,1,1))
|
|
1707
|
+
sage: Q.bilinear_map(v, w)
|
|
1708
|
+
Traceback (most recent call last):
|
|
1709
|
+
...
|
|
1710
|
+
TypeError: vectors must have length 3
|
|
1711
|
+
|
|
1712
|
+
This does not work if the characteristic is 2::
|
|
1713
|
+
|
|
1714
|
+
sage: # needs sage.rings.finite_rings
|
|
1715
|
+
sage: Q = DiagonalQuadraticForm(GF(2), [1,1,1])
|
|
1716
|
+
sage: v = vector((1,1,1))
|
|
1717
|
+
sage: w = vector((1,1,1))
|
|
1718
|
+
sage: Q.bilinear_map(v, w)
|
|
1719
|
+
Traceback (most recent call last):
|
|
1720
|
+
...
|
|
1721
|
+
TypeError: not defined for rings of characteristic 2
|
|
1722
|
+
"""
|
|
1723
|
+
if len(v) != self.dim() or len(w) != self.dim():
|
|
1724
|
+
raise TypeError("vectors must have length " + str(self.dim()))
|
|
1725
|
+
if self.base_ring().characteristic() == 2:
|
|
1726
|
+
raise TypeError("not defined for rings of characteristic 2")
|
|
1727
|
+
return (self(v + w) - self(v) - self(w)) / 2
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
def DiagonalQuadraticForm(R, diag):
|
|
1731
|
+
"""
|
|
1732
|
+
Return a quadratic form over `R` which is a sum of squares.
|
|
1733
|
+
|
|
1734
|
+
INPUT:
|
|
1735
|
+
|
|
1736
|
+
- ``R`` -- ring
|
|
1737
|
+
- ``diag`` -- list/tuple of elements coercible to `R`
|
|
1738
|
+
|
|
1739
|
+
OUTPUT: quadratic form
|
|
1740
|
+
|
|
1741
|
+
EXAMPLES::
|
|
1742
|
+
|
|
1743
|
+
sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7]); Q
|
|
1744
|
+
Quadratic form in 4 variables over Integer Ring with coefficients:
|
|
1745
|
+
[ 1 0 0 0 ]
|
|
1746
|
+
[ * 3 0 0 ]
|
|
1747
|
+
[ * * 5 0 ]
|
|
1748
|
+
[ * * * 7 ]
|
|
1749
|
+
"""
|
|
1750
|
+
Q = QuadraticForm(R, len(diag))
|
|
1751
|
+
for i in range(len(diag)):
|
|
1752
|
+
Q[i, i] = diag[i]
|
|
1753
|
+
return Q
|