passagemath-flint 10.6.1rc10__cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
- passagemath_flint-10.6.1rc10.dist-info/RECORD +360 -0
- passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
- passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
- passagemath_flint.libs/libflint-3701249d.so.21.0.0 +0 -0
- passagemath_flint.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_flint.libs/libgfortran-8a9a71bc.so.5.0.0 +0 -0
- passagemath_flint.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_flint.libs/libgsl-e3525837.so.28.0.0 +0 -0
- passagemath_flint.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
- passagemath_flint.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
- passagemath_flint.libs/libntl-1004113e.so.44.0.1 +0 -0
- passagemath_flint.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
- sage/all__sagemath_flint.py +29 -0
- sage/combinat/all__sagemath_flint.py +1 -0
- sage/combinat/posets/all__sagemath_flint.py +1 -0
- sage/combinat/posets/hasse_cython_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython_flint.pyx +194 -0
- sage/data_structures/all__sagemath_flint.py +1 -0
- sage/data_structures/bounded_integer_sequences.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/data_structures/bounded_integer_sequences.pxd +62 -0
- sage/data_structures/bounded_integer_sequences.pyx +1418 -0
- sage/graphs/all__sagemath_flint.py +1 -0
- sage/graphs/chrompoly.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/graphs/matchpoly.pyx +412 -0
- sage/libs/all__sagemath_flint.py +17 -0
- sage/libs/arb/__init__.py +1 -0
- sage/libs/arb/acb.pxd +154 -0
- sage/libs/arb/acb_calc.pxd +9 -0
- sage/libs/arb/acb_elliptic.pxd +25 -0
- sage/libs/arb/acb_hypgeom.pxd +74 -0
- sage/libs/arb/acb_mat.pxd +62 -0
- sage/libs/arb/acb_modular.pxd +17 -0
- sage/libs/arb/acb_poly.pxd +216 -0
- sage/libs/arb/arb.pxd +240 -0
- sage/libs/arb/arb_fmpz_poly.pxd +21 -0
- sage/libs/arb/arb_hypgeom.pxd +83 -0
- sage/libs/arb/arb_wrap.h +34 -0
- sage/libs/arb/arf.pxd +131 -0
- sage/libs/arb/arith.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/arb/arith.pyx +87 -0
- sage/libs/arb/bernoulli.pxd +6 -0
- sage/libs/arb/mag.pxd +77 -0
- sage/libs/arb/types.pxd +37 -0
- sage/libs/flint/__init__.py +1 -0
- sage/libs/flint/acb.pxd +270 -0
- sage/libs/flint/acb_calc.pxd +22 -0
- sage/libs/flint/acb_dft.pxd +51 -0
- sage/libs/flint/acb_dirichlet.pxd +112 -0
- sage/libs/flint/acb_elliptic.pxd +42 -0
- sage/libs/flint/acb_hypgeom.pxd +169 -0
- sage/libs/flint/acb_macros.pxd +9 -0
- sage/libs/flint/acb_mat.pxd +136 -0
- sage/libs/flint/acb_mat_macros.pxd +10 -0
- sage/libs/flint/acb_modular.pxd +62 -0
- sage/libs/flint/acb_poly.pxd +251 -0
- sage/libs/flint/acb_poly_macros.pxd +8 -0
- sage/libs/flint/acb_theta.pxd +124 -0
- sage/libs/flint/acf.pxd +32 -0
- sage/libs/flint/aprcl.pxd +84 -0
- sage/libs/flint/arb.pxd +382 -0
- sage/libs/flint/arb_calc.pxd +31 -0
- sage/libs/flint/arb_fmpz_poly.pxd +34 -0
- sage/libs/flint/arb_fpwrap.pxd +215 -0
- sage/libs/flint/arb_hypgeom.pxd +147 -0
- sage/libs/flint/arb_macros.pxd +9 -0
- sage/libs/flint/arb_mat.pxd +140 -0
- sage/libs/flint/arb_mat_macros.pxd +10 -0
- sage/libs/flint/arb_poly.pxd +237 -0
- sage/libs/flint/arf.pxd +167 -0
- sage/libs/flint/arith.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/arith.pxd +76 -0
- sage/libs/flint/arith.pyx +77 -0
- sage/libs/flint/arith_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/arith_sage.pyx +308 -0
- sage/libs/flint/bernoulli.pxd +28 -0
- sage/libs/flint/bool_mat.pxd +52 -0
- sage/libs/flint/ca.pxd +203 -0
- sage/libs/flint/ca_ext.pxd +34 -0
- sage/libs/flint/ca_field.pxd +32 -0
- sage/libs/flint/ca_mat.pxd +117 -0
- sage/libs/flint/ca_poly.pxd +104 -0
- sage/libs/flint/ca_vec.pxd +46 -0
- sage/libs/flint/calcium.pxd +27 -0
- sage/libs/flint/d_mat.pxd +39 -0
- sage/libs/flint/d_vec.pxd +32 -0
- sage/libs/flint/dirichlet.pxd +57 -0
- sage/libs/flint/dlog.pxd +53 -0
- sage/libs/flint/double_extras.pxd +24 -0
- sage/libs/flint/double_interval.pxd +36 -0
- sage/libs/flint/fexpr.pxd +104 -0
- sage/libs/flint/fexpr_builtin.pxd +20 -0
- sage/libs/flint/fft.pxd +66 -0
- sage/libs/flint/flint.pxd +36 -0
- sage/libs/flint/flint_ntl_wrap.h +35 -0
- sage/libs/flint/flint_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/flint_sage.pyx +163 -0
- sage/libs/flint/flint_wrap.h +190 -0
- sage/libs/flint/fmpq.pxd +137 -0
- sage/libs/flint/fmpq_mat.pxd +105 -0
- sage/libs/flint/fmpq_mat_macros.pxd +10 -0
- sage/libs/flint/fmpq_mpoly.pxd +165 -0
- sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
- sage/libs/flint/fmpq_poly.pxd +241 -0
- sage/libs/flint/fmpq_poly_macros.pxd +9 -0
- sage/libs/flint/fmpq_poly_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/fmpq_poly_sage.pxd +31 -0
- sage/libs/flint/fmpq_poly_sage.pyx +48 -0
- sage/libs/flint/fmpq_vec.pxd +27 -0
- sage/libs/flint/fmpz.pxd +256 -0
- sage/libs/flint/fmpz_extras.pxd +32 -0
- sage/libs/flint/fmpz_factor.pxd +42 -0
- sage/libs/flint/fmpz_factor_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_factor_sage.pxd +4 -0
- sage/libs/flint/fmpz_factor_sage.pyx +29 -0
- sage/libs/flint/fmpz_lll.pxd +49 -0
- sage/libs/flint/fmpz_macros.pxd +8 -0
- sage/libs/flint/fmpz_mat.pxd +184 -0
- sage/libs/flint/fmpz_mat_macros.pxd +10 -0
- sage/libs/flint/fmpz_mod.pxd +46 -0
- sage/libs/flint/fmpz_mod_mat.pxd +71 -0
- sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
- sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fmpz_mod_poly.pxd +249 -0
- sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
- sage/libs/flint/fmpz_mod_vec.pxd +27 -0
- sage/libs/flint/fmpz_mpoly.pxd +224 -0
- sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
- sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
- sage/libs/flint/fmpz_poly.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly.pxd +407 -0
- sage/libs/flint/fmpz_poly.pyx +19 -0
- sage/libs/flint/fmpz_poly_factor.pxd +33 -0
- sage/libs/flint/fmpz_poly_macros.pxd +8 -0
- sage/libs/flint/fmpz_poly_mat.pxd +71 -0
- sage/libs/flint/fmpz_poly_q.pxd +55 -0
- sage/libs/flint/fmpz_poly_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly_sage.pxd +20 -0
- sage/libs/flint/fmpz_poly_sage.pyx +500 -0
- sage/libs/flint/fmpz_vec.pxd +80 -0
- sage/libs/flint/fmpzi.pxd +52 -0
- sage/libs/flint/fq.pxd +97 -0
- sage/libs/flint/fq_default.pxd +84 -0
- sage/libs/flint/fq_default_mat.pxd +70 -0
- sage/libs/flint/fq_default_poly.pxd +97 -0
- sage/libs/flint/fq_default_poly_factor.pxd +39 -0
- sage/libs/flint/fq_embed.pxd +28 -0
- sage/libs/flint/fq_mat.pxd +83 -0
- sage/libs/flint/fq_nmod.pxd +95 -0
- sage/libs/flint/fq_nmod_embed.pxd +28 -0
- sage/libs/flint/fq_nmod_mat.pxd +83 -0
- sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
- sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fq_nmod_poly.pxd +202 -0
- sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
- sage/libs/flint/fq_nmod_vec.pxd +33 -0
- sage/libs/flint/fq_poly.pxd +204 -0
- sage/libs/flint/fq_poly_factor.pxd +47 -0
- sage/libs/flint/fq_vec.pxd +33 -0
- sage/libs/flint/fq_zech.pxd +99 -0
- sage/libs/flint/fq_zech_embed.pxd +28 -0
- sage/libs/flint/fq_zech_mat.pxd +78 -0
- sage/libs/flint/fq_zech_poly.pxd +198 -0
- sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
- sage/libs/flint/fq_zech_vec.pxd +33 -0
- sage/libs/flint/gr.pxd +174 -0
- sage/libs/flint/gr_generic.pxd +215 -0
- sage/libs/flint/gr_mat.pxd +161 -0
- sage/libs/flint/gr_mpoly.pxd +68 -0
- sage/libs/flint/gr_poly.pxd +276 -0
- sage/libs/flint/gr_special.pxd +237 -0
- sage/libs/flint/gr_vec.pxd +120 -0
- sage/libs/flint/hypgeom.pxd +24 -0
- sage/libs/flint/long_extras.pxd +23 -0
- sage/libs/flint/mag.pxd +131 -0
- sage/libs/flint/mag_macros.pxd +8 -0
- sage/libs/flint/mpf_mat.pxd +36 -0
- sage/libs/flint/mpf_vec.pxd +34 -0
- sage/libs/flint/mpfr_mat.pxd +27 -0
- sage/libs/flint/mpfr_vec.pxd +25 -0
- sage/libs/flint/mpn_extras.pxd +41 -0
- sage/libs/flint/mpoly.pxd +72 -0
- sage/libs/flint/nf.pxd +19 -0
- sage/libs/flint/nf_elem.pxd +74 -0
- sage/libs/flint/nmod.pxd +35 -0
- sage/libs/flint/nmod_mat.pxd +104 -0
- sage/libs/flint/nmod_mpoly.pxd +144 -0
- sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/nmod_poly.pxd +339 -0
- sage/libs/flint/nmod_poly_factor.pxd +44 -0
- sage/libs/flint/nmod_poly_linkage.pxi +710 -0
- sage/libs/flint/nmod_poly_mat.pxd +76 -0
- sage/libs/flint/nmod_vec.pxd +40 -0
- sage/libs/flint/ntl_interface.pxd +17 -0
- sage/libs/flint/padic.pxd +93 -0
- sage/libs/flint/padic_mat.pxd +64 -0
- sage/libs/flint/padic_poly.pxd +88 -0
- sage/libs/flint/partitions.pxd +23 -0
- sage/libs/flint/perm.pxd +26 -0
- sage/libs/flint/profiler.pxd +24 -0
- sage/libs/flint/qadic.pxd +77 -0
- sage/libs/flint/qfb.pxd +44 -0
- sage/libs/flint/qqbar.pxd +172 -0
- sage/libs/flint/qsieve.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve.pxd +41 -0
- sage/libs/flint/qsieve.pyx +21 -0
- sage/libs/flint/qsieve_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve_sage.pyx +67 -0
- sage/libs/flint/thread_pool.pxd +25 -0
- sage/libs/flint/types.pxd +2076 -0
- sage/libs/flint/ulong_extras.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras.pxd +141 -0
- sage/libs/flint/ulong_extras.pyx +21 -0
- sage/libs/flint/ulong_extras_sage.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras_sage.pyx +21 -0
- sage/matrix/all__sagemath_flint.py +1 -0
- sage/matrix/change_ring.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_complex_ball_dense.pxd +14 -0
- sage/matrix/matrix_complex_ball_dense.pyx +973 -0
- sage/matrix/matrix_cyclo_dense.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_cyclo_dense.pxd +16 -0
- sage/matrix/matrix_cyclo_dense.pyx +1761 -0
- sage/matrix/matrix_integer_dense.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_dense.pxd +32 -0
- sage/matrix/matrix_integer_dense.pyx +5801 -0
- sage/matrix/matrix_integer_dense_hnf.py +1294 -0
- sage/matrix/matrix_integer_dense_saturation.py +346 -0
- sage/matrix/matrix_integer_sparse.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_sparse.pxd +9 -0
- sage/matrix/matrix_integer_sparse.pyx +1090 -0
- sage/matrix/matrix_rational_dense.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_dense.pxd +23 -0
- sage/matrix/matrix_rational_dense.pyx +2995 -0
- sage/matrix/matrix_rational_sparse.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_sparse.pxd +11 -0
- sage/matrix/matrix_rational_sparse.pyx +789 -0
- sage/matrix/misc_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/matrix/misc_flint.pyx +109 -0
- sage/modular/all__sagemath_flint.py +1 -0
- sage/modular/modform/all__sagemath_flint.py +1 -0
- sage/modular/modform/eis_series_cython.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/modular/modform/eis_series_cython.pyx +226 -0
- sage/modular/modsym/all__sagemath_flint.py +1 -0
- sage/modular/modsym/apply.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/modular/modsym/apply.pxd +6 -0
- sage/modular/modsym/apply.pyx +113 -0
- sage/modular/modsym/heilbronn.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/modular/modsym/heilbronn.pyx +966 -0
- sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
- sage/modular/pollack_stevens/dist.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/modular/pollack_stevens/dist.pxd +38 -0
- sage/modular/pollack_stevens/dist.pyx +1439 -0
- sage/quivers/algebra.py +691 -0
- sage/quivers/algebra_elements.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/quivers/algebra_elements.pxd +97 -0
- sage/quivers/algebra_elements.pxi +1324 -0
- sage/quivers/algebra_elements.pyx +1424 -0
- sage/quivers/all.py +1 -0
- sage/quivers/ar_quiver.py +917 -0
- sage/quivers/homspace.py +640 -0
- sage/quivers/morphism.py +1282 -0
- sage/quivers/path_semigroup.py +1155 -0
- sage/quivers/paths.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/quivers/paths.pxd +13 -0
- sage/quivers/paths.pyx +809 -0
- sage/quivers/representation.py +2975 -0
- sage/rings/all__sagemath_flint.py +37 -0
- sage/rings/cif.py +4 -0
- sage/rings/complex_arb.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/complex_arb.pxd +29 -0
- sage/rings/complex_arb.pyx +5176 -0
- sage/rings/complex_interval.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/complex_interval.pxd +30 -0
- sage/rings/complex_interval.pyx +2475 -0
- sage/rings/complex_interval_field.py +711 -0
- sage/rings/convert/all.py +1 -0
- sage/rings/convert/mpfi.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/convert/mpfi.pxd +6 -0
- sage/rings/convert/mpfi.pyx +576 -0
- sage/rings/factorint_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/fraction_field_FpT.pxd +28 -0
- sage/rings/fraction_field_FpT.pyx +2043 -0
- sage/rings/imaginary_unit.py +5 -0
- sage/rings/monomials.py +73 -0
- sage/rings/number_field/S_unit_solver.py +2870 -0
- sage/rings/number_field/all__sagemath_flint.py +7 -0
- sage/rings/number_field/bdd_height.py +664 -0
- sage/rings/number_field/class_group.py +762 -0
- sage/rings/number_field/galois_group.py +1307 -0
- sage/rings/number_field/homset.py +612 -0
- sage/rings/number_field/maps.py +687 -0
- sage/rings/number_field/morphism.py +272 -0
- sage/rings/number_field/number_field.py +12820 -0
- sage/rings/number_field/number_field_element.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element.pxd +59 -0
- sage/rings/number_field/number_field_element.pyx +5735 -0
- sage/rings/number_field/number_field_element_quadratic.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
- sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
- sage/rings/number_field/number_field_ideal_rel.py +925 -0
- sage/rings/number_field/number_field_morphisms.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_morphisms.pyx +781 -0
- sage/rings/number_field/number_field_rel.py +2734 -0
- sage/rings/number_field/order.py +2981 -0
- sage/rings/number_field/order_ideal.py +804 -0
- sage/rings/number_field/selmer_group.py +715 -0
- sage/rings/number_field/small_primes_of_degree_one.py +242 -0
- sage/rings/number_field/splitting_field.py +606 -0
- sage/rings/number_field/structure.py +380 -0
- sage/rings/number_field/unit_group.py +721 -0
- sage/rings/padics/all__sagemath_flint.py +3 -0
- sage/rings/polynomial/all__sagemath_flint.py +1 -0
- sage/rings/polynomial/complex_roots.py +312 -0
- sage/rings/polynomial/evaluation_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_flint.pxd +7 -0
- sage/rings/polynomial/evaluation_flint.pyx +68 -0
- sage/rings/polynomial/hilbert.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
- sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
- sage/rings/polynomial/polynomial_number_field.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
- sage/rings/polynomial/polynomial_zmod_flint.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
- sage/rings/polynomial/real_roots.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/real_roots.pxd +81 -0
- sage/rings/polynomial/real_roots.pyx +4704 -0
- sage/rings/polynomial/refine_root.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/refine_root.pyx +142 -0
- sage/rings/polynomial/weil/all.py +4 -0
- sage/rings/polynomial/weil/power_sums.h +46 -0
- sage/rings/polynomial/weil/weil_polynomials.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
- sage/rings/qqbar.py +9025 -0
- sage/rings/real_arb.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/real_arb.pxd +21 -0
- sage/rings/real_arb.pyx +4065 -0
- sage/rings/real_interval_absolute.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/rings/real_mpfi.pyx +5428 -0
- sage/schemes/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.cpython-313-aarch64-linux-gnu.so +0 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
- sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,1090 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
r"""
|
3
|
+
Sparse integer matrices
|
4
|
+
|
5
|
+
AUTHORS:
|
6
|
+
|
7
|
+
- William Stein (2007-02-21)
|
8
|
+
- Soroosh Yazdani (2007-02-21)
|
9
|
+
|
10
|
+
TESTS::
|
11
|
+
|
12
|
+
sage: a = matrix(ZZ,2,range(4), sparse=True)
|
13
|
+
sage: TestSuite(a).run() # needs sage.libs.pari
|
14
|
+
sage: Matrix(ZZ,0,0,sparse=True).inverse()
|
15
|
+
[]
|
16
|
+
"""
|
17
|
+
|
18
|
+
# ****************************************************************************
|
19
|
+
# Copyright (C) 2007 William Stein <wstein@gmail.com>
|
20
|
+
# Copyright (C) 2018 Vincent Delecroix <20100.delecroix@gmail.com>
|
21
|
+
#
|
22
|
+
# This program is free software: you can redistribute it and/or modify
|
23
|
+
# it under the terms of the GNU General Public License as published by
|
24
|
+
# the Free Software Foundation, either version 2 of the License, or
|
25
|
+
# (at your option) any later version.
|
26
|
+
# https://www.gnu.org/licenses/
|
27
|
+
# ****************************************************************************
|
28
|
+
|
29
|
+
from cysignals.memory cimport check_calloc, sig_free
|
30
|
+
from cysignals.signals cimport sig_on, sig_off
|
31
|
+
|
32
|
+
from sage.ext.stdsage cimport PY_NEW
|
33
|
+
from sage.ext.mod_int cimport *
|
34
|
+
|
35
|
+
from sage.data_structures.binary_search cimport *
|
36
|
+
from sage.modules.vector_integer_sparse cimport *
|
37
|
+
from sage.modules.vector_integer_dense cimport Vector_integer_dense
|
38
|
+
from sage.modules.vector_modn_sparse cimport *
|
39
|
+
|
40
|
+
from sage.libs.gmp.mpz cimport *
|
41
|
+
|
42
|
+
from sage.rings.integer cimport Integer
|
43
|
+
from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint
|
44
|
+
from sage.matrix.matrix cimport Matrix
|
45
|
+
|
46
|
+
from sage.matrix.args cimport SparseEntry, MatrixArgs_init
|
47
|
+
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
|
48
|
+
|
49
|
+
from sage.matrix.matrix_modn_sparse cimport Matrix_modn_sparse
|
50
|
+
from sage.structure.element cimport Element
|
51
|
+
|
52
|
+
import sage.matrix.matrix_space as matrix_space
|
53
|
+
|
54
|
+
from sage.rings.integer_ring import ZZ
|
55
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
|
56
|
+
|
57
|
+
cimport sage.structure.element
|
58
|
+
|
59
|
+
cdef class Matrix_integer_sparse(Matrix_sparse):
|
60
|
+
def __cinit__(self):
|
61
|
+
self._matrix = <mpz_vector*>check_calloc(self._nrows, sizeof(mpz_vector))
|
62
|
+
# Initialize the rows
|
63
|
+
cdef Py_ssize_t i
|
64
|
+
for i in range(self._nrows):
|
65
|
+
mpz_vector_init(&self._matrix[i], self._ncols, 0)
|
66
|
+
|
67
|
+
def __dealloc__(self):
|
68
|
+
cdef Py_ssize_t i
|
69
|
+
if self._matrix is not NULL:
|
70
|
+
for i in range(self._nrows):
|
71
|
+
mpz_vector_clear(&self._matrix[i])
|
72
|
+
sig_free(self._matrix)
|
73
|
+
|
74
|
+
def __init__(self, parent, entries=None, copy=None, bint coerce=True):
|
75
|
+
r"""
|
76
|
+
Create a sparse matrix over the integers.
|
77
|
+
|
78
|
+
INPUT:
|
79
|
+
|
80
|
+
- ``parent`` -- a matrix space over ``ZZ``
|
81
|
+
|
82
|
+
- ``entries`` -- see :func:`matrix`
|
83
|
+
|
84
|
+
- ``copy`` -- ignored (for backwards compatibility)
|
85
|
+
|
86
|
+
- ``coerce`` -- if ``False``, assume without checking that the
|
87
|
+
entries are of type :class:`Integer`
|
88
|
+
"""
|
89
|
+
ma = MatrixArgs_init(parent, entries)
|
90
|
+
cdef Integer z
|
91
|
+
for t in ma.iter(coerce, True):
|
92
|
+
se = <SparseEntry>t
|
93
|
+
z = <Integer>se.entry
|
94
|
+
if z:
|
95
|
+
mpz_vector_set_entry(&self._matrix[se.i], se.j, z.value)
|
96
|
+
|
97
|
+
cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, x):
|
98
|
+
mpz_vector_set_entry(&self._matrix[i], j, (<Integer> x).value)
|
99
|
+
|
100
|
+
cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
|
101
|
+
cdef Integer x
|
102
|
+
x = Integer()
|
103
|
+
mpz_vector_get_entry(x.value, &self._matrix[i], j)
|
104
|
+
return x
|
105
|
+
|
106
|
+
cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
|
107
|
+
"""
|
108
|
+
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
|
109
|
+
|
110
|
+
EXAMPLES::
|
111
|
+
|
112
|
+
sage: M = matrix(ZZ, [[0,1,0],[0,0,0]], sparse=True)
|
113
|
+
sage: M.zero_pattern_matrix() # indirect doctest
|
114
|
+
[1 0 1]
|
115
|
+
[1 1 1]
|
116
|
+
"""
|
117
|
+
return mpz_vector_is_entry_zero_unsafe(&self._matrix[i], j)
|
118
|
+
|
119
|
+
########################################################################
|
120
|
+
# LEVEL 2 functionality
|
121
|
+
# * def _pickle
|
122
|
+
# * def _unpickle
|
123
|
+
# * cdef _add_
|
124
|
+
# * cdef _sub_
|
125
|
+
# * cdef _mul_
|
126
|
+
# * cpdef _richcmp_
|
127
|
+
# * __neg__
|
128
|
+
# * __invert__
|
129
|
+
# * __copy__
|
130
|
+
# * _multiply_classical
|
131
|
+
# * _matrix_times_matrix_
|
132
|
+
# * _list -- list of underlying elements (need not be a copy)
|
133
|
+
# * x _dict -- sparse dictionary of underlying elements (need not be a copy)
|
134
|
+
########################################################################
|
135
|
+
# def _pickle(self):
|
136
|
+
# def _unpickle(self, data, int version): # use version >= 0
|
137
|
+
# cpdef _add_(self, right):
|
138
|
+
# cdef _mul_(self, Matrix right):
|
139
|
+
# cpdef _richcmp_(self, Matrix right, int op):
|
140
|
+
# def __neg__(self):
|
141
|
+
# def __invert__(self):
|
142
|
+
# def __copy__(self):
|
143
|
+
# def _multiply_classical(left, matrix.Matrix _right):
|
144
|
+
# def _list(self):
|
145
|
+
|
146
|
+
cpdef _lmul_(self, Element right):
|
147
|
+
"""
|
148
|
+
EXAMPLES::
|
149
|
+
|
150
|
+
sage: a = matrix(ZZ,2,range(6), sparse=True)
|
151
|
+
sage: 3 * a
|
152
|
+
[ 0 3 6]
|
153
|
+
[ 9 12 15]
|
154
|
+
"""
|
155
|
+
cdef Py_ssize_t i
|
156
|
+
cdef mpz_vector *self_row
|
157
|
+
cdef mpz_vector *M_row
|
158
|
+
cdef Matrix_integer_sparse M
|
159
|
+
cdef Integer _x
|
160
|
+
_x = Integer(right)
|
161
|
+
M = Matrix_integer_sparse.__new__(Matrix_integer_sparse, self._parent, None, None, None)
|
162
|
+
for i from 0 <= i < self._nrows:
|
163
|
+
self_row = &self._matrix[i]
|
164
|
+
M_row = &M._matrix[i]
|
165
|
+
mpz_vector_scalar_multiply(M_row, self_row, _x.value)
|
166
|
+
return M
|
167
|
+
|
168
|
+
cpdef _add_(self, right):
|
169
|
+
cdef Py_ssize_t i
|
170
|
+
cdef Matrix_integer_sparse M
|
171
|
+
|
172
|
+
M = Matrix_integer_sparse.__new__(Matrix_integer_sparse, self._parent, None, None, None)
|
173
|
+
cdef mpz_t mul
|
174
|
+
mpz_init_set_si(mul,1)
|
175
|
+
for i in range(self._nrows):
|
176
|
+
mpz_vector_clear(&M._matrix[i])
|
177
|
+
add_mpz_vector_init(&M._matrix[i], &self._matrix[i],
|
178
|
+
&(<Matrix_integer_sparse>right)._matrix[i], mul)
|
179
|
+
mpz_clear(mul)
|
180
|
+
return M
|
181
|
+
|
182
|
+
cpdef _sub_(self, right):
|
183
|
+
cdef Py_ssize_t i
|
184
|
+
cdef Matrix_integer_sparse M
|
185
|
+
|
186
|
+
M = Matrix_integer_sparse.__new__(Matrix_integer_sparse, self._parent, None, None, None)
|
187
|
+
cdef mpz_t mul
|
188
|
+
mpz_init_set_si(mul,-1)
|
189
|
+
for i from 0 <= i < self._nrows:
|
190
|
+
mpz_vector_clear(&M._matrix[i])
|
191
|
+
add_mpz_vector_init(&M._matrix[i], &self._matrix[i], &(<Matrix_integer_sparse>right)._matrix[i], mul)
|
192
|
+
mpz_clear(mul)
|
193
|
+
return M
|
194
|
+
|
195
|
+
def _dict(self):
|
196
|
+
"""
|
197
|
+
Unsafe version of the dict method, mainly for internal use.
|
198
|
+
|
199
|
+
This may return the dict of elements, but as an *unsafe*
|
200
|
+
reference to the underlying dict of the object. It might
|
201
|
+
be dangerous if you change entries of the returned dict.
|
202
|
+
"""
|
203
|
+
d = self.fetch('dict')
|
204
|
+
if d is not None:
|
205
|
+
return d
|
206
|
+
|
207
|
+
cdef Py_ssize_t i, j
|
208
|
+
d = {}
|
209
|
+
for i in range(self._nrows):
|
210
|
+
for j in range(self._matrix[i].num_nonzero):
|
211
|
+
x = Integer()
|
212
|
+
mpz_set((<Integer>x).value, self._matrix[i].entries[j])
|
213
|
+
d[(int(i), int(self._matrix[i].positions[j]))] = x
|
214
|
+
self.cache('dict', d)
|
215
|
+
return d
|
216
|
+
|
217
|
+
cdef sage.structure.element.Matrix _matrix_times_matrix_(self, sage.structure.element.Matrix _right):
|
218
|
+
"""
|
219
|
+
Return the product of the sparse integer matrices
|
220
|
+
``self`` and ``_right``.
|
221
|
+
|
222
|
+
EXAMPLES::
|
223
|
+
|
224
|
+
sage: a = matrix(ZZ, 2, [1,2,3,4], sparse=True)
|
225
|
+
sage: b = matrix(ZZ, 2, 3, [1..6], sparse=True)
|
226
|
+
sage: a * b
|
227
|
+
[ 9 12 15]
|
228
|
+
[19 26 33]
|
229
|
+
"""
|
230
|
+
cdef Matrix_integer_sparse right, ans
|
231
|
+
right = _right
|
232
|
+
|
233
|
+
cdef mpz_vector* v
|
234
|
+
|
235
|
+
# Build a table that gives the nonzero positions in each column of right
|
236
|
+
cdef list nonzero_positions_in_columns = [set() for _ in range(right._ncols)]
|
237
|
+
cdef Py_ssize_t i, j, k
|
238
|
+
for i in range(right._nrows):
|
239
|
+
v = &(right._matrix[i])
|
240
|
+
for j in range(v.num_nonzero):
|
241
|
+
(<set> nonzero_positions_in_columns[v.positions[j]]).add(i)
|
242
|
+
# pre-computes the list of nonzero columns of right
|
243
|
+
cdef list right_indices
|
244
|
+
right_indices = [j for j in range(right._ncols)
|
245
|
+
if nonzero_positions_in_columns[j]]
|
246
|
+
|
247
|
+
ans = self.new_matrix(self._nrows, right._ncols)
|
248
|
+
|
249
|
+
# Now do the multiplication, getting each row completely before filling it in.
|
250
|
+
cdef set c
|
251
|
+
cdef mpz_t x, y, s
|
252
|
+
mpz_init(x)
|
253
|
+
mpz_init(y)
|
254
|
+
mpz_init(s)
|
255
|
+
for i in range(self._nrows):
|
256
|
+
v = &(self._matrix[i])
|
257
|
+
if not v.num_nonzero:
|
258
|
+
continue
|
259
|
+
for j in right_indices:
|
260
|
+
mpz_set_si(s, 0)
|
261
|
+
c = <set> nonzero_positions_in_columns[j]
|
262
|
+
for k in range(v.num_nonzero):
|
263
|
+
if v.positions[k] in c:
|
264
|
+
mpz_vector_get_entry(y, &right._matrix[v.positions[k]], j)
|
265
|
+
mpz_mul(x, v.entries[k], y)
|
266
|
+
mpz_add(s, s, x)
|
267
|
+
mpz_vector_set_entry(&ans._matrix[i], j, s)
|
268
|
+
|
269
|
+
mpz_clear(x)
|
270
|
+
mpz_clear(y)
|
271
|
+
mpz_clear(s)
|
272
|
+
return ans
|
273
|
+
|
274
|
+
########################################################################
|
275
|
+
# LEVEL 3 functionality (Optional)
|
276
|
+
# * cdef _sub_
|
277
|
+
# * __deepcopy__
|
278
|
+
# * __invert__
|
279
|
+
# * Matrix windows -- only if you need strassen for that base
|
280
|
+
# * Other functions (list them here):
|
281
|
+
########################################################################
|
282
|
+
|
283
|
+
def _nonzero_positions_by_row(self, copy=True):
|
284
|
+
"""
|
285
|
+
Return the list of pairs (i,j) such that ``self[i,j] != 0``.
|
286
|
+
|
287
|
+
It is safe to change the resulting list (unless you give the option copy=False).
|
288
|
+
|
289
|
+
EXAMPLES::
|
290
|
+
|
291
|
+
sage: M = Matrix(ZZ, [[0,0,0,1,0,0,0,0],[0,1,0,0,0,0,1,0]], sparse=True); M
|
292
|
+
[0 0 0 1 0 0 0 0]
|
293
|
+
[0 1 0 0 0 0 1 0]
|
294
|
+
sage: M._nonzero_positions_by_row()
|
295
|
+
[(0, 3), (1, 1), (1, 6)]
|
296
|
+
"""
|
297
|
+
x = self.fetch('nonzero_positions')
|
298
|
+
if x is not None:
|
299
|
+
if copy:
|
300
|
+
return list(x)
|
301
|
+
return x
|
302
|
+
nzp = []
|
303
|
+
cdef Py_ssize_t i, j
|
304
|
+
for i from 0 <= i < self._nrows:
|
305
|
+
for j from 0 <= j < self._matrix[i].num_nonzero:
|
306
|
+
nzp.append((i,self._matrix[i].positions[j]))
|
307
|
+
self.cache('nonzero_positions', nzp)
|
308
|
+
if copy:
|
309
|
+
return list(nzp)
|
310
|
+
return nzp
|
311
|
+
|
312
|
+
def _nonzero_positions_by_column(self, copy=True):
|
313
|
+
"""
|
314
|
+
Return the list of pairs (i,j) such that ``self[i,j] != 0``, but
|
315
|
+
sorted by columns, i.e., column j=0 entries occur first, then
|
316
|
+
column j=1 entries, etc.
|
317
|
+
|
318
|
+
It is safe to change the resulting list (unless you give the option copy=False).
|
319
|
+
|
320
|
+
EXAMPLES::
|
321
|
+
|
322
|
+
sage: M = Matrix(ZZ, [[0,0,0,1,0,0,0,0],[0,1,0,0,0,0,1,0]], sparse=True); M
|
323
|
+
[0 0 0 1 0 0 0 0]
|
324
|
+
[0 1 0 0 0 0 1 0]
|
325
|
+
sage: M._nonzero_positions_by_column()
|
326
|
+
[(1, 1), (0, 3), (1, 6)]
|
327
|
+
"""
|
328
|
+
x = self.fetch('nonzero_positions_by_column')
|
329
|
+
if x is not None:
|
330
|
+
if copy:
|
331
|
+
return list(x)
|
332
|
+
return x
|
333
|
+
nzc = [[] for _ in range(self._ncols)]
|
334
|
+
cdef Py_ssize_t i, j
|
335
|
+
for i from 0 <= i < self._nrows:
|
336
|
+
for j from 0 <= j < self._matrix[i].num_nonzero:
|
337
|
+
p = self._matrix[i].positions[j]
|
338
|
+
nzc[p].append((i,p))
|
339
|
+
nzc = sum(nzc,[])
|
340
|
+
self.cache('nonzero_positions_by_column', nzc)
|
341
|
+
if copy:
|
342
|
+
return list(nzc)
|
343
|
+
return nzc
|
344
|
+
|
345
|
+
def _mod_int(self, modulus):
|
346
|
+
r"""
|
347
|
+
Helper function in reducing matrices mod n.
|
348
|
+
|
349
|
+
INPUT:
|
350
|
+
|
351
|
+
- ``modulus`` -- a number
|
352
|
+
|
353
|
+
OUTPUT: this matrix, over `\ZZ/n\ZZ`
|
354
|
+
|
355
|
+
TESTS::
|
356
|
+
|
357
|
+
sage: M = Matrix(ZZ, sparse=True)
|
358
|
+
sage: B = M._mod_int(7)
|
359
|
+
sage: B.parent()
|
360
|
+
Full MatrixSpace of 0 by 0 sparse matrices over Ring of integers modulo 7
|
361
|
+
"""
|
362
|
+
return self._mod_int_c(modulus)
|
363
|
+
|
364
|
+
cdef _mod_int_c(self, mod_int p):
|
365
|
+
cdef Py_ssize_t i, j
|
366
|
+
cdef Matrix_modn_sparse res
|
367
|
+
cdef mpz_vector* self_row
|
368
|
+
cdef c_vector_modint* res_row
|
369
|
+
res = Matrix_modn_sparse.__new__(Matrix_modn_sparse, matrix_space.MatrixSpace(
|
370
|
+
IntegerModRing(p), self._nrows, self._ncols, sparse=True), None, None, None)
|
371
|
+
for i from 0 <= i < self._nrows:
|
372
|
+
self_row = &(self._matrix[i])
|
373
|
+
res_row = &(res.rows[i])
|
374
|
+
for j from 0 <= j < self_row.num_nonzero:
|
375
|
+
set_entry(res_row, self_row.positions[j], mpz_fdiv_ui(self_row.entries[j], p))
|
376
|
+
return res
|
377
|
+
|
378
|
+
def rational_reconstruction(self, N):
|
379
|
+
"""
|
380
|
+
Use rational reconstruction to lift ``self`` to a matrix over the
|
381
|
+
rational numbers (if possible), where we view ``self`` as a matrix
|
382
|
+
modulo `N`.
|
383
|
+
|
384
|
+
EXAMPLES::
|
385
|
+
|
386
|
+
sage: A = matrix(ZZ, 3, 4, [(1/3)%500, 2, 3, (-4)%500,
|
387
|
+
....: 7, 2, 2, 3,
|
388
|
+
....: 4, 3, 4, (5/7)%500], sparse=True)
|
389
|
+
sage: A.rational_reconstruction(500)
|
390
|
+
[1/3 2 3 -4]
|
391
|
+
[ 7 2 2 3]
|
392
|
+
[ 4 3 4 5/7]
|
393
|
+
|
394
|
+
TESTS:
|
395
|
+
|
396
|
+
Check that :issue:`9345` is fixed::
|
397
|
+
|
398
|
+
sage: A = random_matrix(ZZ, 3, 3, sparse=True)
|
399
|
+
sage: A.rational_reconstruction(0)
|
400
|
+
Traceback (most recent call last):
|
401
|
+
...
|
402
|
+
ZeroDivisionError: The modulus cannot be zero
|
403
|
+
"""
|
404
|
+
from sage.matrix.misc import matrix_integer_sparse_rational_reconstruction
|
405
|
+
return matrix_integer_sparse_rational_reconstruction(self, N)
|
406
|
+
|
407
|
+
def _right_kernel_matrix(self, **kwds):
|
408
|
+
r"""
|
409
|
+
Return a pair that includes a matrix of basis vectors
|
410
|
+
for the right kernel of ``self``.
|
411
|
+
|
412
|
+
INPUT:
|
413
|
+
|
414
|
+
- ``algorithm`` -- determines which algorithm to use, options are:
|
415
|
+
|
416
|
+
- ``'pari'`` -- use the :pari:`matkerint` function from the PARI library
|
417
|
+
- ``'padic'`` -- use the `p`-adic algorithm from the IML library
|
418
|
+
- ``'default'`` -- use a heuristic to decide which of the two above
|
419
|
+
routines is fastest. This is the default value.
|
420
|
+
|
421
|
+
- ``proof`` -- this is passed to the `p`-adic IML algorithm
|
422
|
+
If not specified, the global flag for linear algebra will be used
|
423
|
+
|
424
|
+
OUTPUT:
|
425
|
+
|
426
|
+
Returns a pair. First item is the string is either
|
427
|
+
'computed-pari-int', 'computed-iml-int' or 'computed-flint-int', which identifies
|
428
|
+
the nature of the basis vectors.
|
429
|
+
|
430
|
+
Second item is a matrix whose rows are a basis for the right kernel,
|
431
|
+
over the integers, as computed by either the IML or PARI libraries.
|
432
|
+
|
433
|
+
EXAMPLES::
|
434
|
+
|
435
|
+
sage: A = matrix(ZZ, [[4, 7, 9, 7, 5, 0],
|
436
|
+
....: [1, 0, 5, 8, 9, 1],
|
437
|
+
....: [0, 1, 0, 1, 9, 7],
|
438
|
+
....: [4, 7, 6, 5, 1, 4]],
|
439
|
+
....: sparse = True)
|
440
|
+
|
441
|
+
sage: # needs sage.libs.pari
|
442
|
+
sage: result = A._right_kernel_matrix(algorithm='pari')
|
443
|
+
sage: result[0]
|
444
|
+
'computed-pari-int'
|
445
|
+
sage: X = result[1]; X
|
446
|
+
[ 26 -31 30 -21 -2 10]
|
447
|
+
[-47 -13 48 -14 -11 18]
|
448
|
+
sage: A*X.transpose() == zero_matrix(ZZ, 4, 2)
|
449
|
+
True
|
450
|
+
|
451
|
+
sage: result = A._right_kernel_matrix(algorithm='padic')
|
452
|
+
sage: result[0]
|
453
|
+
'computed-iml-int'
|
454
|
+
sage: X = result[1]; X
|
455
|
+
[-469 214 -30 119 -37 0]
|
456
|
+
[ 370 -165 18 -91 30 -2]
|
457
|
+
|
458
|
+
sage: A*X.transpose() == zero_matrix(ZZ, 4, 2)
|
459
|
+
True
|
460
|
+
|
461
|
+
sage: result = A._right_kernel_matrix(algorithm='default')
|
462
|
+
sage: result[0]
|
463
|
+
'computed-flint-int'
|
464
|
+
sage: result[1]
|
465
|
+
[ 469 -214 30 -119 37 0]
|
466
|
+
[-370 165 -18 91 -30 2]
|
467
|
+
|
468
|
+
sage: result = A._right_kernel_matrix()
|
469
|
+
sage: result[0]
|
470
|
+
'computed-flint-int'
|
471
|
+
sage: result[1]
|
472
|
+
[ 469 -214 30 -119 37 0]
|
473
|
+
[-370 165 -18 91 -30 2]
|
474
|
+
|
475
|
+
With the 'default' given as the algorithm, several heuristics are
|
476
|
+
used to determine if PARI or IML ('padic') is used. The code has
|
477
|
+
exact details, but roughly speaking, relevant factors are: the
|
478
|
+
absolute size of the matrix, or the relative dimensions, or the
|
479
|
+
magnitude of the entries. ::
|
480
|
+
|
481
|
+
sage: A = random_matrix(ZZ, 18, 11, sparse=True)
|
482
|
+
sage: A._right_kernel_matrix(algorithm='default')[0]
|
483
|
+
'computed-pari-int'
|
484
|
+
sage: A = random_matrix(ZZ, 18, 11, x = 10^200, sparse=True)
|
485
|
+
sage: A._right_kernel_matrix(algorithm='default')[0]
|
486
|
+
'computed-iml-int'
|
487
|
+
sage: A = random_matrix(ZZ, 60, 60, sparse=True)
|
488
|
+
sage: A._right_kernel_matrix(algorithm='default')[0]
|
489
|
+
'computed-iml-int'
|
490
|
+
sage: A = random_matrix(ZZ, 60, 55, sparse=True)
|
491
|
+
sage: A._right_kernel_matrix(algorithm='default')[0]
|
492
|
+
'computed-pari-int'
|
493
|
+
|
494
|
+
TESTS:
|
495
|
+
|
496
|
+
We test three trivial cases. PARI is used for small matrices,
|
497
|
+
but we let the heuristic decide that. ::
|
498
|
+
|
499
|
+
sage: A = matrix(ZZ, 0, 2, sparse=True)
|
500
|
+
sage: A._right_kernel_matrix()[1]
|
501
|
+
[]
|
502
|
+
sage: A = matrix(ZZ, 2, 0, sparse=True)
|
503
|
+
sage: A._right_kernel_matrix()[1].parent()
|
504
|
+
Full MatrixSpace of 0 by 0 dense matrices over Integer Ring
|
505
|
+
sage: A = zero_matrix(ZZ, 4, 3, sparse=True)
|
506
|
+
sage: A._right_kernel_matrix()[1]
|
507
|
+
[1 0 0]
|
508
|
+
[0 1 0]
|
509
|
+
[0 0 1]
|
510
|
+
"""
|
511
|
+
return self.dense_matrix()._right_kernel_matrix(**kwds)
|
512
|
+
|
513
|
+
hermite_form = Matrix.echelon_form
|
514
|
+
|
515
|
+
def elementary_divisors(self, algorithm='pari'):
|
516
|
+
"""
|
517
|
+
Return the elementary divisors of self, in order.
|
518
|
+
|
519
|
+
The elementary divisors are the invariants of the finite
|
520
|
+
abelian group that is the cokernel of *left* multiplication by
|
521
|
+
this matrix. They are ordered in reverse by divisibility.
|
522
|
+
|
523
|
+
INPUT:
|
524
|
+
|
525
|
+
- ``self`` -- matrix
|
526
|
+
- ``algorithm`` -- (default: ``'pari'``)
|
527
|
+
|
528
|
+
* 'pari': works robustly, but is slower
|
529
|
+
* 'linbox' -- use linbox (currently off, broken)
|
530
|
+
|
531
|
+
OUTPUT: list of integers
|
532
|
+
|
533
|
+
EXAMPLES::
|
534
|
+
|
535
|
+
sage: matrix(3, range(9),sparse=True).elementary_divisors()
|
536
|
+
[1, 3, 0]
|
537
|
+
sage: M = matrix(ZZ, 3, [1,5,7, 3,6,9, 0,1,2], sparse=True)
|
538
|
+
sage: M.elementary_divisors()
|
539
|
+
[1, 1, 6]
|
540
|
+
|
541
|
+
This returns a copy, which is safe to change::
|
542
|
+
|
543
|
+
sage: edivs = M.elementary_divisors()
|
544
|
+
sage: edivs.pop()
|
545
|
+
6
|
546
|
+
sage: M.elementary_divisors()
|
547
|
+
[1, 1, 6]
|
548
|
+
|
549
|
+
.. SEEALSO::
|
550
|
+
|
551
|
+
:meth:`smith_form`
|
552
|
+
"""
|
553
|
+
return self.dense_matrix().elementary_divisors(algorithm=algorithm)
|
554
|
+
|
555
|
+
def smith_form(self, transformation=True, integral=None):
|
556
|
+
r"""
|
557
|
+
Return the smith normal form of this matrix, that is the diagonal
|
558
|
+
matrix `S` with diagonal entries the ordered elementary divisors of
|
559
|
+
this matrix.
|
560
|
+
|
561
|
+
INPUT:
|
562
|
+
|
563
|
+
- ``transformation`` -- boolean (default: ``True``); whether to
|
564
|
+
return the transformation matrices `U` and `V` such that `S = U\cdot
|
565
|
+
self\cdot V`
|
566
|
+
|
567
|
+
- ``integral`` -- a subring of the base ring or ``True`` (default:
|
568
|
+
``None``); ignored for matrices with integer entries
|
569
|
+
|
570
|
+
This version is for sparse matrices and simply makes the matrix
|
571
|
+
dense and calls the version for dense integer matrices.
|
572
|
+
|
573
|
+
.. NOTE::
|
574
|
+
|
575
|
+
The :meth:`elementary_divisors` function, which returns the diagonal
|
576
|
+
entries of S, is VASTLY faster than this function.
|
577
|
+
|
578
|
+
The elementary divisors are the invariants of the finite abelian
|
579
|
+
group that is the cokernel of this matrix. They are ordered in
|
580
|
+
reverse by divisibility.
|
581
|
+
|
582
|
+
EXAMPLES::
|
583
|
+
|
584
|
+
sage: A = MatrixSpace(IntegerRing(), 3, sparse=True)(range(9))
|
585
|
+
sage: D, U, V = A.smith_form()
|
586
|
+
sage: D
|
587
|
+
[1 0 0]
|
588
|
+
[0 3 0]
|
589
|
+
[0 0 0]
|
590
|
+
sage: U
|
591
|
+
[ 0 2 -1]
|
592
|
+
[ 0 -1 1]
|
593
|
+
[ 1 -2 1]
|
594
|
+
sage: V
|
595
|
+
[ 0 0 1]
|
596
|
+
[-1 2 -2]
|
597
|
+
[ 1 -1 1]
|
598
|
+
sage: U*A*V
|
599
|
+
[1 0 0]
|
600
|
+
[0 3 0]
|
601
|
+
[0 0 0]
|
602
|
+
|
603
|
+
It also makes sense for nonsquare matrices::
|
604
|
+
|
605
|
+
sage: A = Matrix(ZZ,3,2,range(6), sparse=True)
|
606
|
+
sage: D, U, V = A.smith_form()
|
607
|
+
sage: D
|
608
|
+
[1 0]
|
609
|
+
[0 2]
|
610
|
+
[0 0]
|
611
|
+
sage: U
|
612
|
+
[ 0 2 -1]
|
613
|
+
[ 0 -1 1]
|
614
|
+
[ 1 -2 1]
|
615
|
+
sage: V
|
616
|
+
[-1 1]
|
617
|
+
[ 1 0]
|
618
|
+
sage: U * A * V
|
619
|
+
[1 0]
|
620
|
+
[0 2]
|
621
|
+
[0 0]
|
622
|
+
|
623
|
+
The examples above show that :issue:`10626` has been implemented.
|
624
|
+
|
625
|
+
|
626
|
+
.. SEEALSO::
|
627
|
+
|
628
|
+
:meth:`elementary_divisors`
|
629
|
+
"""
|
630
|
+
return self.dense_matrix().smith_form(transformation=transformation)
|
631
|
+
|
632
|
+
def rank(self, algorithm=None):
|
633
|
+
r"""
|
634
|
+
Compute the rank of this matrix.
|
635
|
+
|
636
|
+
INPUT:
|
637
|
+
|
638
|
+
- ``algorithm`` -- (optional) one of ``None``, ``'linbox'`` or
|
639
|
+
``'generic'``
|
640
|
+
|
641
|
+
EXAMPLES::
|
642
|
+
|
643
|
+
sage: M = MatrixSpace(ZZ, 3, 2, sparse=True)
|
644
|
+
sage: m = M([1, 0, 2, 3, -1, 0])
|
645
|
+
sage: m.rank()
|
646
|
+
2
|
647
|
+
"""
|
648
|
+
if self._nrows == 0 or self._ncols == 0:
|
649
|
+
return 0
|
650
|
+
|
651
|
+
x = self.fetch('rank')
|
652
|
+
if x is not None:
|
653
|
+
return x
|
654
|
+
|
655
|
+
if algorithm is None or algorithm == "linbox":
|
656
|
+
from .matrix_integer_sparse_linbox import _rank_linbox
|
657
|
+
r = _rank_linbox(self)
|
658
|
+
self.cache("rank", r)
|
659
|
+
elif algorithm == "generic":
|
660
|
+
r = Matrix_sparse.rank(self)
|
661
|
+
self.cache("rank", r)
|
662
|
+
else:
|
663
|
+
raise ValueError("no algorithm '%s'" % algorithm)
|
664
|
+
|
665
|
+
return r
|
666
|
+
|
667
|
+
def _rank_linbox(self):
|
668
|
+
r"""
|
669
|
+
Compute the rank using linbox.
|
670
|
+
|
671
|
+
The result is not cached contrarily to the method ``rank``.
|
672
|
+
|
673
|
+
EXAMPLES::
|
674
|
+
|
675
|
+
sage: M = MatrixSpace(ZZ, 3, sparse=True)
|
676
|
+
sage: m = M([1,0,1,0,2,0,2,0,2])
|
677
|
+
sage: m._rank_linbox() # needs sage.libs.linbox
|
678
|
+
2
|
679
|
+
|
680
|
+
TESTS::
|
681
|
+
|
682
|
+
sage: # needs sage.libs.linbox
|
683
|
+
sage: MatrixSpace(ZZ, 0, 0, sparse=True)()._rank_linbox()
|
684
|
+
0
|
685
|
+
sage: MatrixSpace(ZZ, 1, 0, sparse=True)()._rank_linbox()
|
686
|
+
0
|
687
|
+
sage: MatrixSpace(ZZ, 0, 1, sparse=True)()._rank_linbox()
|
688
|
+
0
|
689
|
+
sage: MatrixSpace(ZZ, 1, 1, sparse=True)()._rank_linbox()
|
690
|
+
0
|
691
|
+
"""
|
692
|
+
from .matrix_integer_sparse_linbox import _rank_linbox
|
693
|
+
return _rank_linbox(self)
|
694
|
+
|
695
|
+
def _det_linbox(self):
|
696
|
+
r"""
|
697
|
+
Return the determinant computed with LinBox.
|
698
|
+
|
699
|
+
.. NOTE::
|
700
|
+
|
701
|
+
This method is much slower than converting to a dense matrix and
|
702
|
+
computing the determinant there. There is not much point in making
|
703
|
+
it available. See :issue:`28318`.
|
704
|
+
|
705
|
+
EXAMPLES::
|
706
|
+
|
707
|
+
sage: M = MatrixSpace(ZZ, 2, 2, sparse=True)
|
708
|
+
sage: M([2,0,1,1])._det_linbox() # needs sage.libs.linbox
|
709
|
+
2
|
710
|
+
|
711
|
+
TESTS::
|
712
|
+
|
713
|
+
sage: # needs sage.libs.linbox
|
714
|
+
sage: MatrixSpace(ZZ, 0, 0, sparse=True)()._det_linbox()
|
715
|
+
1
|
716
|
+
sage: MatrixSpace(ZZ, 1, 1, sparse=True)()._det_linbox()
|
717
|
+
0
|
718
|
+
sage: m = diagonal_matrix(ZZ, [2] * 46)
|
719
|
+
sage: m._det_linbox() == 2**46
|
720
|
+
True
|
721
|
+
sage: m = diagonal_matrix(ZZ, [3] * 100)
|
722
|
+
sage: m._det_linbox() == 3**100
|
723
|
+
True
|
724
|
+
"""
|
725
|
+
from .matrix_integer_sparse_linbox import _det_linbox
|
726
|
+
return _det_linbox(self)
|
727
|
+
|
728
|
+
def charpoly(self, var='x', algorithm=None):
|
729
|
+
r"""
|
730
|
+
Return the characteristic polynomial of this matrix.
|
731
|
+
|
732
|
+
INPUT:
|
733
|
+
|
734
|
+
- ``var`` -- (default: ``'x'``) the name of the variable
|
735
|
+
of the polynomial
|
736
|
+
|
737
|
+
- ``algorithm`` -- (default: ``None``) one of ``None``,
|
738
|
+
``'linbox'``, or an algorithm accepted by
|
739
|
+
:meth:`sage.matrix.matrix_sparse.Matrix_sparse.charpoly`
|
740
|
+
|
741
|
+
EXAMPLES::
|
742
|
+
|
743
|
+
sage: M = MatrixSpace(ZZ, 4, sparse=True)
|
744
|
+
sage: m = M()
|
745
|
+
sage: m[0,0] = m[1,2] = m[2,3] = m[3,3] = 1
|
746
|
+
sage: m[0,2] = m[1,3] = m[2,0] = m[3,0] = -3
|
747
|
+
sage: m[1,1] = 2
|
748
|
+
sage: m
|
749
|
+
[ 1 0 -3 0]
|
750
|
+
[ 0 2 1 -3]
|
751
|
+
[-3 0 0 1]
|
752
|
+
[-3 0 0 1]
|
753
|
+
sage: m.charpoly()
|
754
|
+
x^4 - 4*x^3 - 4*x^2 + 16*x
|
755
|
+
|
756
|
+
TESTS::
|
757
|
+
|
758
|
+
sage: matrix(ZZ, 0, 0, sparse=True).charpoly(algorithm='linbox') # needs sage.libs.linbox
|
759
|
+
1
|
760
|
+
sage: matrix(ZZ, 0, 0, sparse=True).charpoly(algorithm='generic')
|
761
|
+
1
|
762
|
+
"""
|
763
|
+
if self._nrows != self._ncols:
|
764
|
+
raise ArithmeticError("only valid for square matrix")
|
765
|
+
|
766
|
+
cdef Polynomial_integer_dense_flint g
|
767
|
+
|
768
|
+
if algorithm is None:
|
769
|
+
algorithm = 'linbox'
|
770
|
+
|
771
|
+
g = self.fetch('charpoly')
|
772
|
+
if g is not None:
|
773
|
+
return g.change_variable_name(var)
|
774
|
+
|
775
|
+
if algorithm == 'linbox':
|
776
|
+
from sage.matrix.matrix_integer_sparse_linbox import _charpoly_linbox
|
777
|
+
g = _charpoly_linbox(self)
|
778
|
+
else:
|
779
|
+
g = Matrix_sparse.charpoly(self, var, algorithm=algorithm)
|
780
|
+
|
781
|
+
self.cache('charpoly', g)
|
782
|
+
return g
|
783
|
+
|
784
|
+
def _charpoly_linbox(self, var='x'):
|
785
|
+
r"""
|
786
|
+
Compute the charpoly using LinBox.
|
787
|
+
|
788
|
+
EXAMPLES::
|
789
|
+
|
790
|
+
sage: m = matrix(ZZ, 2, [2,1,1,1], sparse=True)
|
791
|
+
sage: m._charpoly_linbox() # needs sage.libs.linbox
|
792
|
+
x^2 - 3*x + 1
|
793
|
+
|
794
|
+
TESTS::
|
795
|
+
|
796
|
+
sage: # needs sage.libs.linbox
|
797
|
+
sage: matrix(ZZ, 0, 0, sparse=True)._charpoly_linbox()
|
798
|
+
1
|
799
|
+
sage: matrix(ZZ, 1, 1, sparse=True)._charpoly_linbox()
|
800
|
+
x
|
801
|
+
"""
|
802
|
+
from .matrix_integer_sparse_linbox import _charpoly_linbox
|
803
|
+
return _charpoly_linbox(self, var)
|
804
|
+
|
805
|
+
def minpoly(self, var='x', algorithm=None):
|
806
|
+
r"""
|
807
|
+
Return the minimal polynomial of this matrix.
|
808
|
+
|
809
|
+
INPUT:
|
810
|
+
|
811
|
+
- ``var`` -- (default: ``'x'``) the name of the variable
|
812
|
+
of the polynomial
|
813
|
+
|
814
|
+
- ``algorithm`` -- (default: ``None``) one of ``None``,
|
815
|
+
``'linbox'``, or an algorithm accepted by
|
816
|
+
:meth:`sage.matrix.matrix_sparse.Matrix_sparse.minpoly`
|
817
|
+
|
818
|
+
EXAMPLES::
|
819
|
+
|
820
|
+
sage: M = MatrixSpace(ZZ, 4, sparse=True)
|
821
|
+
sage: m = M({(0, 0):2, (1, 1):1, (2, 1):-8, (2, 2):2, (2, 3):-1, (3, 3):1})
|
822
|
+
sage: m
|
823
|
+
[ 2 0 0 0]
|
824
|
+
[ 0 1 0 0]
|
825
|
+
[ 0 -8 2 -1]
|
826
|
+
[ 0 0 0 1]
|
827
|
+
sage: m.minpoly() # needs sage.libs.pari
|
828
|
+
x^2 - 3*x + 2
|
829
|
+
|
830
|
+
TESTS::
|
831
|
+
|
832
|
+
sage: matrix(ZZ, 0, 0, sparse=True).minpoly(algorithm='linbox') # needs sage.libs.linbox
|
833
|
+
1
|
834
|
+
sage: matrix(ZZ, 0, 0, sparse=True).minpoly(algorithm='generic') # needs sage.libs.pari
|
835
|
+
1
|
836
|
+
"""
|
837
|
+
if self._nrows != self._ncols:
|
838
|
+
raise ArithmeticError("only valid for square matrix")
|
839
|
+
|
840
|
+
cdef Polynomial_integer_dense_flint g
|
841
|
+
|
842
|
+
if algorithm is None:
|
843
|
+
algorithm = 'linbox'
|
844
|
+
|
845
|
+
g = self.fetch('minpoly')
|
846
|
+
if g is not None:
|
847
|
+
return g.change_variable_name(var)
|
848
|
+
|
849
|
+
if algorithm == 'linbox':
|
850
|
+
from .matrix_integer_sparse_linbox import _minpoly_linbox
|
851
|
+
g = _minpoly_linbox(self)
|
852
|
+
else:
|
853
|
+
g = Matrix_sparse.minpoly(self, var, algorithm=algorithm)
|
854
|
+
|
855
|
+
self.cache('minpoly', g)
|
856
|
+
return g
|
857
|
+
|
858
|
+
def _minpoly_linbox(self, var='x'):
|
859
|
+
r"""
|
860
|
+
Compute the minpoly using LinBox.
|
861
|
+
|
862
|
+
EXAMPLES::
|
863
|
+
|
864
|
+
sage: m = matrix(ZZ, 2, [2,1,1,1], sparse=True)
|
865
|
+
sage: m._minpoly_linbox() # needs sage.libs.linbox
|
866
|
+
x^2 - 3*x + 1
|
867
|
+
|
868
|
+
TESTS::
|
869
|
+
|
870
|
+
sage: # needs sage.libs.linbox
|
871
|
+
sage: matrix(ZZ, 0, 0, sparse=True)._minpoly_linbox()
|
872
|
+
1
|
873
|
+
sage: matrix(ZZ, 1, 1, sparse=True)._minpoly_linbox()
|
874
|
+
x
|
875
|
+
"""
|
876
|
+
from .matrix_integer_sparse_linbox import _minpoly_linbox
|
877
|
+
return _minpoly_linbox(self, var)
|
878
|
+
|
879
|
+
def _solve_right_nonsingular_square(self, B, algorithm=None, check_rank=False):
|
880
|
+
r"""
|
881
|
+
If ``self`` is a matrix `A`, then this function returns a
|
882
|
+
vector or matrix `X` such that `A X = B`. If
|
883
|
+
`B` is a vector then `X` is a vector and if
|
884
|
+
`B` is a matrix, then `X` is a matrix.
|
885
|
+
|
886
|
+
.. NOTE::
|
887
|
+
|
888
|
+
DEPRECATED. In Sage one can also write ``A \ B`` for
|
889
|
+
``A.solve_right(B)``, i.e., Sage implements the "the
|
890
|
+
MATLAB/Octave backslash operator".
|
891
|
+
|
892
|
+
INPUT:
|
893
|
+
|
894
|
+
- ``B`` -- a matrix or vector
|
895
|
+
|
896
|
+
- ``algorithm`` -- one of the following:
|
897
|
+
|
898
|
+
- ``'linbox'`` or ``'linbox_default'`` -- (default) use LinBox
|
899
|
+
and let it chooses the appropriate algorithm
|
900
|
+
|
901
|
+
- ``linbox_dense_elimination'`` -- use LinBox dense elimination
|
902
|
+
|
903
|
+
- ``'linbox_sparse_elimination'`` -- use LinBox sparse elimination
|
904
|
+
|
905
|
+
- ``'linbox_ blackbox'`` -- LinBox via a Blackbox algorithm
|
906
|
+
|
907
|
+
- ``'linbox_wiedemann'`` -- use LinBox implementation of
|
908
|
+
Wiedemann's algorithm
|
909
|
+
|
910
|
+
- ``'generic'`` -- use the Sage generic implementation
|
911
|
+
(via inversion)
|
912
|
+
|
913
|
+
- ``check_rank`` -- whether to check that the rank is maximal
|
914
|
+
|
915
|
+
OUTPUT: a matrix or vector
|
916
|
+
|
917
|
+
EXAMPLES::
|
918
|
+
|
919
|
+
sage: A = matrix(ZZ, 3, [1,2,3,-1,2,5,2,3,1], sparse=True)
|
920
|
+
sage: b = vector(ZZ, [1,2,3])
|
921
|
+
sage: x = A.solve_right(b)
|
922
|
+
sage: x
|
923
|
+
(-13/12, 23/12, -7/12)
|
924
|
+
sage: A * x
|
925
|
+
(1, 2, 3)
|
926
|
+
|
927
|
+
sage: u = matrix(ZZ, 3, 2, [0,1,1,1,0,2])
|
928
|
+
sage: x = A.solve_right(u)
|
929
|
+
sage: x
|
930
|
+
[-7/12 -1/6]
|
931
|
+
[ 5/12 5/6]
|
932
|
+
[-1/12 -1/6]
|
933
|
+
sage: A * x
|
934
|
+
[0 1]
|
935
|
+
[1 1]
|
936
|
+
[0 2]
|
937
|
+
"""
|
938
|
+
if check_rank and self.rank() < self.nrows():
|
939
|
+
from sage.matrix.matrix2 import NotFullRankError
|
940
|
+
raise NotFullRankError
|
941
|
+
|
942
|
+
if self.base_ring() != B.base_ring():
|
943
|
+
B = B.change_ring(self.base_ring())
|
944
|
+
if self.nrows() != B.nrows():
|
945
|
+
raise ValueError("input matrices must have the same number of rows.")
|
946
|
+
|
947
|
+
if algorithm == "generic":
|
948
|
+
return Matrix_sparse.solve_right(self, B)
|
949
|
+
else:
|
950
|
+
if isinstance(B, sage.structure.element.Matrix):
|
951
|
+
from sage.rings.rational_field import QQ
|
952
|
+
from sage.matrix.special import diagonal_matrix
|
953
|
+
from sage.matrix.matrix_integer_sparse_linbox import _solve_matrix_linbox
|
954
|
+
m, d = _solve_matrix_linbox(self, B, algorithm)
|
955
|
+
return m * diagonal_matrix([QQ((1,x)) for x in d])
|
956
|
+
else:
|
957
|
+
from sage.matrix.matrix_integer_sparse_linbox import _solve_vector_linbox
|
958
|
+
v, d = _solve_vector_linbox(self, B, algorithm)
|
959
|
+
return v / d
|
960
|
+
|
961
|
+
def _solve_vector_linbox(self, v, algorithm=None):
|
962
|
+
r"""
|
963
|
+
Return a pair ``(a, d)`` so that ``d * b = m * a``.
|
964
|
+
|
965
|
+
If there is no solution a :exc:`ValueError` is raised.
|
966
|
+
|
967
|
+
INPUT:
|
968
|
+
|
969
|
+
- ``b`` -- dense integer vector
|
970
|
+
|
971
|
+
- ``algorithm`` -- (optional) either ``None``, ``'dense_elimination'``,
|
972
|
+
``'sparse_elimination'``, ``'wiedemann'`` or ``'blackbox'``
|
973
|
+
|
974
|
+
OUTPUT: a pair ``(a, d)`` consisting of
|
975
|
+
|
976
|
+
- ``a`` -- dense integer vector
|
977
|
+
|
978
|
+
- ``d`` -- integer
|
979
|
+
|
980
|
+
EXAMPLES::
|
981
|
+
|
982
|
+
sage: # needs sage.libs.linbox
|
983
|
+
sage: m = matrix(ZZ, 4, sparse=True)
|
984
|
+
sage: m[0,0] = m[1,2] = m[2,0] = m[3,3] = 2
|
985
|
+
sage: m[0,2] = m[1,1] = -1
|
986
|
+
sage: m[2,3] = m[3,0] = -3
|
987
|
+
sage: b0 = vector((1,1,1,1))
|
988
|
+
sage: m._solve_vector_linbox(b0)
|
989
|
+
((-1, -7, -3, -1), 1)
|
990
|
+
sage: m._solve_vector_linbox(b0, 'dense_elimination')
|
991
|
+
((-1, -7, -3, -1), 1)
|
992
|
+
sage: m._solve_vector_linbox(b0, 'sparse_elimination')
|
993
|
+
((-1, -7, -3, -1), 1)
|
994
|
+
sage: m._solve_vector_linbox(b0, 'wiedemann')
|
995
|
+
((-1, -7, -3, -1), 1)
|
996
|
+
sage: m._solve_vector_linbox(b0, 'blackbox')
|
997
|
+
((-1, -7, -3, -1), 1)
|
998
|
+
sage: b1 = vector((1,2,3,4))
|
999
|
+
sage: m._solve_vector_linbox(b1)
|
1000
|
+
((-18, -92, -41, -17), 5)
|
1001
|
+
sage: m._solve_vector_linbox(b1, 'dense_elimination')
|
1002
|
+
((-18, -92, -41, -17), 5)
|
1003
|
+
sage: m._solve_vector_linbox(b1, 'sparse_elimination')
|
1004
|
+
((-18, -92, -41, -17), 5)
|
1005
|
+
sage: m._solve_vector_linbox(b1, 'wiedemann')
|
1006
|
+
((-18, -92, -41, -17), 5)
|
1007
|
+
sage: m._solve_vector_linbox(b1, 'blackbox')
|
1008
|
+
((-18, -92, -41, -17), 5)
|
1009
|
+
sage: a1, d1 = m._solve_vector_linbox(b1)
|
1010
|
+
sage: d1 * b1 == m * a1
|
1011
|
+
True
|
1012
|
+
|
1013
|
+
TESTS::
|
1014
|
+
|
1015
|
+
sage: # needs sage.libs.linbox
|
1016
|
+
sage: algos = ["default", "dense_elimination", "sparse_elimination",
|
1017
|
+
....: "blackbox", "wiedemann"]
|
1018
|
+
sage: for i in range(20):
|
1019
|
+
....: dim = randint(1, 30)
|
1020
|
+
....: M = MatrixSpace(ZZ, dim, sparse=True)
|
1021
|
+
....: density = min(1, 4/dim)
|
1022
|
+
....: m = M.random_element(density=density)
|
1023
|
+
....: while m.rank() != dim:
|
1024
|
+
....: m = M.random_element(density=density)
|
1025
|
+
....: U = m.column_space().dense_module()
|
1026
|
+
....: for algo in algos:
|
1027
|
+
....: u, d = m._solve_vector_linbox(U.zero(), algorithm=algo)
|
1028
|
+
....: assert u.is_zero()
|
1029
|
+
....: b = U.random_element()
|
1030
|
+
....: x, d = m._solve_vector_linbox(b, algorithm=algo)
|
1031
|
+
....: assert m * x == d * b
|
1032
|
+
"""
|
1033
|
+
from .matrix_integer_sparse_linbox import _solve_vector_linbox
|
1034
|
+
return _solve_vector_linbox(self, v, algorithm)
|
1035
|
+
|
1036
|
+
def _solve_matrix_linbox(self, mat, algorithm=None):
|
1037
|
+
r"""
|
1038
|
+
Solve the equation ``A x = mat`` where ``A`` is this matrix.
|
1039
|
+
|
1040
|
+
EXAMPLES::
|
1041
|
+
|
1042
|
+
sage: # needs sage.libs.linbox
|
1043
|
+
sage: m = matrix(ZZ, [[1,2],[1,0]], sparse=True)
|
1044
|
+
sage: b = matrix(ZZ, 2, 4, [1,0,2,0,1,1,2,0], sparse=False)
|
1045
|
+
sage: u, d = m._solve_matrix_linbox(b)
|
1046
|
+
sage: u
|
1047
|
+
[ 1 2 2 0]
|
1048
|
+
[ 0 -1 0 0]
|
1049
|
+
sage: m * u == b * diagonal_matrix(d)
|
1050
|
+
True
|
1051
|
+
sage: u, d = m._solve_matrix_linbox([[1,3,4],[0,1,0]])
|
1052
|
+
sage: u
|
1053
|
+
[0 1 0]
|
1054
|
+
[1 1 2]
|
1055
|
+
sage: d
|
1056
|
+
(2, 1, 1)
|
1057
|
+
|
1058
|
+
Test input::
|
1059
|
+
|
1060
|
+
sage: # needs sage.libs.linbox
|
1061
|
+
sage: m = matrix(ZZ, [[1,2],[1,0]], sparse=True)
|
1062
|
+
sage: b = matrix(ZZ, 3, 3, range(9))
|
1063
|
+
sage: m._solve_matrix_linbox(b)
|
1064
|
+
Traceback (most recent call last):
|
1065
|
+
...
|
1066
|
+
ValueError: wrong matrix dimension
|
1067
|
+
sage: m._solve_matrix_linbox([[1,1],[2,3]], algorithm='hop')
|
1068
|
+
Traceback (most recent call last):
|
1069
|
+
...
|
1070
|
+
ValueError: unknown algorithm
|
1071
|
+
|
1072
|
+
TESTS::
|
1073
|
+
|
1074
|
+
sage: # needs sage.libs.linbox
|
1075
|
+
sage: algos = ["default", "dense_elimination", "sparse_elimination",
|
1076
|
+
....: "blackbox", "wiedemann"]
|
1077
|
+
sage: for _ in range(10):
|
1078
|
+
....: dim = randint(2, 10)
|
1079
|
+
....: M = MatrixSpace(ZZ, dim, sparse=True)
|
1080
|
+
....: m = M.random_element(density=min(1,10/dim))
|
1081
|
+
....: while m.rank() != dim:
|
1082
|
+
....: m = M.random_element(density=min(1,10/dim))
|
1083
|
+
....: b = random_matrix(ZZ, dim, 7)
|
1084
|
+
....: Mb = b.parent()
|
1085
|
+
....: for algo in algos:
|
1086
|
+
....: u, d = m._solve_matrix_linbox(b, algo)
|
1087
|
+
....: assert m * u == b * diagonal_matrix(d)
|
1088
|
+
"""
|
1089
|
+
from .matrix_integer_sparse_linbox import _solve_matrix_linbox
|
1090
|
+
return _solve_matrix_linbox(self, mat, algorithm)
|