passagemath-flint 10.6.1rc10__cp310-cp310-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-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-310-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-310-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-310-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-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-310-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-310-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-310-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-310-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-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-310-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-310-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,1881 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
# distutils: libraries = NTL_LIBRARIES gmp
|
3
|
+
# distutils: extra_compile_args = NTL_CFLAGS
|
4
|
+
# distutils: include_dirs = NTL_INCDIR
|
5
|
+
# distutils: library_dirs = NTL_LIBDIR
|
6
|
+
# distutils: extra_link_args = NTL_LIBEXTRA
|
7
|
+
# distutils: language = c++
|
8
|
+
r"""
|
9
|
+
Dense univariate polynomials over `\ZZ`, implemented using FLINT
|
10
|
+
|
11
|
+
AUTHORS:
|
12
|
+
|
13
|
+
- David Harvey: rewrote to talk to NTL directly, instead of via ntl.pyx
|
14
|
+
(2007-09); a lot of this was based on Joel Mohler's recent rewrite of the NTL
|
15
|
+
wrapper
|
16
|
+
- David Harvey: split off from polynomial_element_generic.py (2007-09)
|
17
|
+
- Burcin Erocal: rewrote to use FLINT (2008-06-16)
|
18
|
+
|
19
|
+
TESTS:
|
20
|
+
|
21
|
+
We check that the buggy gcd is fixed (see :issue:`17816`)::
|
22
|
+
|
23
|
+
sage: R.<q> = ZZ[]
|
24
|
+
sage: X = 3*q^12 - 8*q^11 - 24*q^10 - 48*q^9 - 84*q^8 - 92*q^7 - 92*q^6 - 70*q^5 - 50*q^4 - 27*q^3 - 13*q^2 - 4*q - 1
|
25
|
+
sage: Y = q^13 - 2*q^12 + 2*q^10 - q^9
|
26
|
+
sage: gcd(X,Y)
|
27
|
+
1
|
28
|
+
"""
|
29
|
+
|
30
|
+
#*****************************************************************************
|
31
|
+
# Copyright (C) 2007 William Stein <wstein@gmail.com>
|
32
|
+
# Copyright (C) 2008-2010 Burcin Erocal <burcin@erocal.org>
|
33
|
+
#
|
34
|
+
# This program is free software: you can redistribute it and/or modify
|
35
|
+
# it under the terms of the GNU General Public License as published by
|
36
|
+
# the Free Software Foundation, either version 2 of the License, or
|
37
|
+
# (at your option) any later version.
|
38
|
+
# http://www.gnu.org/licenses/
|
39
|
+
#*****************************************************************************
|
40
|
+
|
41
|
+
from cysignals.memory cimport sig_free
|
42
|
+
from cysignals.signals cimport sig_on, sig_off
|
43
|
+
|
44
|
+
include "sage/libs/ntl/decl.pxi"
|
45
|
+
|
46
|
+
from cpython.long cimport PyLong_AsLong
|
47
|
+
from sage.libs.gmp.mpz cimport *
|
48
|
+
from sage.arith.long cimport pyobject_to_long, is_small_python_int
|
49
|
+
|
50
|
+
from sage.rings.polynomial.polynomial_element cimport Polynomial
|
51
|
+
from sage.structure.element cimport Element
|
52
|
+
from sage.structure.element import coerce_binop
|
53
|
+
|
54
|
+
from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
|
55
|
+
|
56
|
+
from sage.rings.integer_ring import ZZ
|
57
|
+
from sage.rings.rational_field import QQ
|
58
|
+
|
59
|
+
from sage.structure.factorization import Factorization
|
60
|
+
|
61
|
+
from sage.rings.fraction_field_element import FractionFieldElement
|
62
|
+
from sage.arith.functions import lcm
|
63
|
+
|
64
|
+
from sage.libs.flint.arb_fmpz_poly cimport arb_fmpz_poly_evaluate_arb, arb_fmpz_poly_evaluate_acb
|
65
|
+
from sage.libs.flint.fmpz cimport *
|
66
|
+
from sage.libs.flint.fmpz_poly cimport *
|
67
|
+
from sage.libs.flint.fmpz_poly_sage cimport *
|
68
|
+
from sage.libs.flint.types cimport ulong, fmpz_poly_t
|
69
|
+
from sage.libs.flint.ntl_interface cimport fmpz_set_ZZ, fmpz_poly_set_ZZX, fmpz_poly_get_ZZX
|
70
|
+
from sage.libs.ntl.ZZX cimport *
|
71
|
+
from sage.rings.complex_arb cimport ComplexBall
|
72
|
+
from sage.rings.integer cimport Integer, smallInteger
|
73
|
+
from sage.rings.real_arb cimport RealBall
|
74
|
+
from sage.rings.real_mpfr cimport RealNumber
|
75
|
+
from sage.rings.real_mpfi cimport RealIntervalFieldElement
|
76
|
+
|
77
|
+
from sage.rings.polynomial.evaluation_flint cimport fmpz_poly_evaluation_mpfr, fmpz_poly_evaluation_mpfi
|
78
|
+
|
79
|
+
try:
|
80
|
+
from sage.libs.pari import pari
|
81
|
+
from cypari2.gen import Gen as pari_gen
|
82
|
+
except ImportError:
|
83
|
+
pari_gen = ()
|
84
|
+
|
85
|
+
|
86
|
+
cdef class Polynomial_integer_dense_flint(Polynomial):
|
87
|
+
r"""
|
88
|
+
A dense polynomial over the integers, implemented via FLINT.
|
89
|
+
|
90
|
+
TESTS::
|
91
|
+
|
92
|
+
sage: f = ZZ['x'].random_element()
|
93
|
+
sage: from sage.rings.polynomial.polynomial_integer_dense_flint import Polynomial_integer_dense_flint
|
94
|
+
sage: isinstance(f, Polynomial_integer_dense_flint)
|
95
|
+
True
|
96
|
+
|
97
|
+
.. automethod:: _add_
|
98
|
+
.. automethod:: _sub_
|
99
|
+
.. automethod:: _lmul_
|
100
|
+
.. automethod:: _rmul_
|
101
|
+
.. automethod:: _mul_
|
102
|
+
.. automethod:: _mul_trunc_
|
103
|
+
"""
|
104
|
+
|
105
|
+
def __cinit__(self):
|
106
|
+
r"""
|
107
|
+
This calls the underlying FLINT fmpz_poly constructor
|
108
|
+
"""
|
109
|
+
fmpz_poly_init(self._poly)
|
110
|
+
|
111
|
+
def __dealloc__(self):
|
112
|
+
r"""
|
113
|
+
Call the underlying FLINT fmpz_poly destructor
|
114
|
+
"""
|
115
|
+
fmpz_poly_clear(self._poly)
|
116
|
+
|
117
|
+
cdef Polynomial_integer_dense_flint _new(self):
|
118
|
+
r"""
|
119
|
+
Quickly create a new initialized ``Polynomial_integer_dense_flint``
|
120
|
+
with the correct parent and ``_is_gen == 0``.
|
121
|
+
"""
|
122
|
+
cdef Polynomial_integer_dense_flint x = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint)
|
123
|
+
x._parent = self._parent
|
124
|
+
x._is_gen = 0
|
125
|
+
return x
|
126
|
+
|
127
|
+
cpdef Polynomial _new_constant_poly(self, a, Parent P):
|
128
|
+
r"""
|
129
|
+
Quickly create a new constant polynomial with value ``a`` in parent ``P``.
|
130
|
+
|
131
|
+
ASSUMPTION:
|
132
|
+
|
133
|
+
The given value has to be in the base ring of ``P``. This assumption is
|
134
|
+
not verified.
|
135
|
+
|
136
|
+
EXAMPLES::
|
137
|
+
|
138
|
+
sage: R.<x> = ZZ[]
|
139
|
+
sage: x._new_constant_poly(2,R)
|
140
|
+
2
|
141
|
+
"""
|
142
|
+
cdef Polynomial_integer_dense_flint x = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint)
|
143
|
+
x._parent = P
|
144
|
+
x._is_gen = 0
|
145
|
+
if not isinstance(a, Integer):
|
146
|
+
a = ZZ(a)
|
147
|
+
fmpz_poly_set_coeff_mpz(x._poly, 0, (<Integer>a).value)
|
148
|
+
return x
|
149
|
+
|
150
|
+
def __init__(self, parent, x=None, check=True, is_gen=False,
|
151
|
+
construct=False):
|
152
|
+
r"""
|
153
|
+
EXAMPLES::
|
154
|
+
|
155
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
156
|
+
sage: x
|
157
|
+
x
|
158
|
+
|
159
|
+
Construct from list and tuple::
|
160
|
+
|
161
|
+
sage: R([])
|
162
|
+
0
|
163
|
+
sage: R([1, -2, 3])
|
164
|
+
3*x^2 - 2*x + 1
|
165
|
+
|
166
|
+
sage: R(())
|
167
|
+
0
|
168
|
+
sage: R((1, -2, 3))
|
169
|
+
3*x^2 - 2*x + 1
|
170
|
+
|
171
|
+
Coercions from other rings are attempted automatically::
|
172
|
+
|
173
|
+
sage: R([1, -6/3, 3])
|
174
|
+
3*x^2 - 2*x + 1
|
175
|
+
sage: R([1, 5/2, 2])
|
176
|
+
Traceback (most recent call last):
|
177
|
+
...
|
178
|
+
TypeError: no conversion of this rational to integer
|
179
|
+
|
180
|
+
Construct from constant::
|
181
|
+
|
182
|
+
sage: R(3)
|
183
|
+
3
|
184
|
+
|
185
|
+
Coercion from PARI polynomial::
|
186
|
+
|
187
|
+
sage: # needs sage.libs.pari
|
188
|
+
sage: f = R([-1, 2, 5]); f
|
189
|
+
5*x^2 + 2*x - 1
|
190
|
+
sage: type(f)
|
191
|
+
<class 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint'>
|
192
|
+
sage: type(pari(f))
|
193
|
+
<class 'cypari2.gen.Gen'>
|
194
|
+
sage: type(R(pari(f)))
|
195
|
+
<class 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint'>
|
196
|
+
sage: R(pari(f))
|
197
|
+
5*x^2 + 2*x - 1
|
198
|
+
|
199
|
+
Coercion from NTL polynomial::
|
200
|
+
|
201
|
+
sage: f = ntl.ZZX([1, 2, 3])
|
202
|
+
sage: print(R(f))
|
203
|
+
3*x^2 + 2*x + 1
|
204
|
+
|
205
|
+
Coercion from dictionary::
|
206
|
+
|
207
|
+
sage: f = R({2: -4, 3: 47}); f
|
208
|
+
47*x^3 - 4*x^2
|
209
|
+
|
210
|
+
Coercion from fraction field element with trivial denominator::
|
211
|
+
|
212
|
+
sage: f = (x^3 - 1) / (x - 1)
|
213
|
+
sage: type(f)
|
214
|
+
<class 'sage.rings.fraction_field_element.FractionFieldElement'>
|
215
|
+
sage: g = R(f); g
|
216
|
+
x^2 + x + 1
|
217
|
+
|
218
|
+
sage: ZZ['x']({2^3: 1})
|
219
|
+
x^8
|
220
|
+
"""
|
221
|
+
Polynomial.__init__(self, parent, is_gen=is_gen)
|
222
|
+
|
223
|
+
cdef Py_ssize_t degree
|
224
|
+
cdef Py_ssize_t i
|
225
|
+
|
226
|
+
if x is None:
|
227
|
+
return # leave initialized to 0 polynomial.
|
228
|
+
|
229
|
+
if isinstance(x, Polynomial):
|
230
|
+
if x.parent() is self.parent():
|
231
|
+
sig_on()
|
232
|
+
fmpz_poly_set(self._poly,
|
233
|
+
(<Polynomial_integer_dense_flint>x)._poly)
|
234
|
+
sig_off()
|
235
|
+
return
|
236
|
+
else:
|
237
|
+
# coerce coefficients into Sage integers
|
238
|
+
x = [Integer(a) for a in x.list()]
|
239
|
+
check = False
|
240
|
+
|
241
|
+
elif isinstance(x, dict):
|
242
|
+
x = x.items()
|
243
|
+
degree = 0
|
244
|
+
# find max degree to allocate only once
|
245
|
+
for ii, a in x:
|
246
|
+
# mpoly dict style has tuple keys
|
247
|
+
i = ii[0] if type(ii) is tuple else ii
|
248
|
+
if i < 0:
|
249
|
+
raise ValueError("Negative monomial degrees not allowed: %s" % i)
|
250
|
+
elif i > degree:
|
251
|
+
degree = i
|
252
|
+
try:
|
253
|
+
sig_on()
|
254
|
+
fmpz_poly_realloc(self._poly, degree + 1)
|
255
|
+
sig_off()
|
256
|
+
except RuntimeError:
|
257
|
+
raise OverflowError("Cannot allocate memory!")
|
258
|
+
# now fill them in
|
259
|
+
for ii, a in x:
|
260
|
+
i = ii[0] if type(ii) is tuple else ii
|
261
|
+
if is_small_python_int(a):
|
262
|
+
sig_on()
|
263
|
+
fmpz_poly_set_coeff_si(self._poly, i, a)
|
264
|
+
sig_off()
|
265
|
+
else:
|
266
|
+
if not isinstance(a, Integer):
|
267
|
+
a = ZZ(a)
|
268
|
+
sig_on()
|
269
|
+
fmpz_poly_set_coeff_mpz(self._poly, i, (<Integer>a).value)
|
270
|
+
sig_off()
|
271
|
+
return
|
272
|
+
|
273
|
+
elif isinstance(x, pari_gen):
|
274
|
+
x = [Integer(w) for w in x.list()]
|
275
|
+
check = False
|
276
|
+
|
277
|
+
elif isinstance(x, ntl_ZZX): # coercion from ntl.pyx object
|
278
|
+
fmpz_poly_set_ZZX(self._poly, (<ntl_ZZX>x).x)
|
279
|
+
return
|
280
|
+
|
281
|
+
elif isinstance(x, FractionFieldElement) and \
|
282
|
+
isinstance(x.numerator(), Polynomial_integer_dense_flint):
|
283
|
+
if x.denominator() == 1:
|
284
|
+
# fraction of the form f(x)/1
|
285
|
+
sig_on()
|
286
|
+
fmpz_poly_set(self._poly,
|
287
|
+
(<Polynomial_integer_dense_flint>x.numerator())._poly)
|
288
|
+
sig_off()
|
289
|
+
return
|
290
|
+
|
291
|
+
elif not isinstance(x, (list, tuple)):
|
292
|
+
x = [x] # constant polynomials
|
293
|
+
|
294
|
+
sig_on()
|
295
|
+
fmpz_poly_realloc(self._poly, len(x))
|
296
|
+
sig_off()
|
297
|
+
for i from 0 <= i < len(x):
|
298
|
+
a = x[i]
|
299
|
+
if is_small_python_int(a):
|
300
|
+
sig_on()
|
301
|
+
fmpz_poly_set_coeff_si(self._poly, i, a)
|
302
|
+
sig_off()
|
303
|
+
else:
|
304
|
+
if not isinstance(a, Integer):
|
305
|
+
a = ZZ(a)
|
306
|
+
sig_on()
|
307
|
+
fmpz_poly_set_coeff_mpz(self._poly, i, (<Integer>a).value)
|
308
|
+
sig_off()
|
309
|
+
|
310
|
+
def _eval_mpfr_(self, RealNumber a):
|
311
|
+
r"""
|
312
|
+
Evaluate this polynomial on the real number element ``a``.
|
313
|
+
|
314
|
+
This method uses Horner's rule and might not be appropriate for
|
315
|
+
polynomials of large degree.
|
316
|
+
|
317
|
+
TESTS::
|
318
|
+
|
319
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='FLINT')
|
320
|
+
sage: (x+1)._eval_mpfr_(RR(1.2))
|
321
|
+
2.20000000000000
|
322
|
+
sage: (x^2)._eval_mpfr_(RR(2.2))
|
323
|
+
4.84000000000000
|
324
|
+
sage: R.zero()._eval_mpfr_(RR(2.1))
|
325
|
+
0.000000000000000
|
326
|
+
sage: R.one()._eval_mpfr_(RR(2.1))
|
327
|
+
1.00000000000000
|
328
|
+
|
329
|
+
sage: p = x^3 - 2*x^2 + x -1
|
330
|
+
sage: p._eval_mpfr_(RR(1.3))
|
331
|
+
-0.883000000000000
|
332
|
+
"""
|
333
|
+
cdef RealNumber res = a._new()
|
334
|
+
sig_on()
|
335
|
+
fmpz_poly_evaluation_mpfr(res.value, self._poly, a.value)
|
336
|
+
sig_off()
|
337
|
+
return res
|
338
|
+
|
339
|
+
def _eval_mpfi_(self, RealIntervalFieldElement a):
|
340
|
+
r"""
|
341
|
+
Evaluate this polynomial on the real interval ``a``.
|
342
|
+
|
343
|
+
This method uses Horner's rule and might not be appropriate for
|
344
|
+
polynomials of large degree.
|
345
|
+
|
346
|
+
TESTS::
|
347
|
+
|
348
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='FLINT')
|
349
|
+
sage: (x+1)._eval_mpfi_(RIF(1.5))
|
350
|
+
2.5000000000000000?
|
351
|
+
sage: (x^2)._eval_mpfi_(RIF(1.333,1.334))
|
352
|
+
1.78?
|
353
|
+
sage: R.zero()._eval_mpfi_(RIF(2.1))
|
354
|
+
0
|
355
|
+
sage: R.one()._eval_mpfi_(RIF(2.1))
|
356
|
+
1
|
357
|
+
|
358
|
+
sage: p = x^3 - x^2 - x - 1
|
359
|
+
sage: r = p.roots(RIF, multiplicities=False)[0] # needs sage.libs.linbox
|
360
|
+
sage: p._eval_mpfi_(r) # needs sage.libs.linbox
|
361
|
+
0.?e-27
|
362
|
+
"""
|
363
|
+
cdef RealIntervalFieldElement res = a._new()
|
364
|
+
sig_on()
|
365
|
+
fmpz_poly_evaluation_mpfi(res.value, self._poly, a.value)
|
366
|
+
sig_off()
|
367
|
+
return res
|
368
|
+
|
369
|
+
def __call__(self, *x, **kwds):
|
370
|
+
"""
|
371
|
+
Call this polynomial with the given parameters, which can be
|
372
|
+
interpreted as polynomial composition or evaluation by this
|
373
|
+
method.
|
374
|
+
|
375
|
+
If the argument is not simply an integer (``int`` or
|
376
|
+
``Integer``) a real number (``RealNumber``) a real interval
|
377
|
+
(``RealIntervalFieldElement``) or a polynomial (of the same type as
|
378
|
+
``self``), the call is passed on to the generic implementation in the
|
379
|
+
``Polynomial`` class.
|
380
|
+
|
381
|
+
EXAMPLES:
|
382
|
+
|
383
|
+
The first example illustrates polynomial composition::
|
384
|
+
|
385
|
+
sage: R.<t> = ZZ[]
|
386
|
+
sage: f = t^2 - 1
|
387
|
+
sage: g = t + 1
|
388
|
+
sage: f(g) # indirect doctest
|
389
|
+
t^2 + 2*t
|
390
|
+
|
391
|
+
Now we illustrate how a polynomial can be evaluated at an
|
392
|
+
integer::
|
393
|
+
|
394
|
+
sage: f(2) # indirect doctest
|
395
|
+
3
|
396
|
+
|
397
|
+
TESTS:
|
398
|
+
|
399
|
+
sage: t(-sys.maxsize-1r) == t(-sys.maxsize-1)
|
400
|
+
True
|
401
|
+
sage: (t^2+3)(RealBallField(100)(1/3))
|
402
|
+
[3.1111111111111111111111111111...]
|
403
|
+
sage: (t^2+3)(ComplexBallField(10)(i)) # needs sage.symbolic
|
404
|
+
2.00
|
405
|
+
"""
|
406
|
+
cdef Polynomial_integer_dense_flint f
|
407
|
+
cdef Integer a, z
|
408
|
+
cdef RealBall arb_a, arb_z
|
409
|
+
cdef ComplexBall acb_a, acb_z
|
410
|
+
|
411
|
+
cdef fmpz_t a_fmpz
|
412
|
+
cdef fmpz_t z_fmpz
|
413
|
+
|
414
|
+
if len(x) == 1:
|
415
|
+
x0 = x[0]
|
416
|
+
if isinstance(x, Polynomial_integer_dense_flint):
|
417
|
+
f = self._new()
|
418
|
+
sig_on()
|
419
|
+
fmpz_poly_compose(f._poly, self._poly,
|
420
|
+
(<Polynomial_integer_dense_flint> x0)._poly)
|
421
|
+
sig_off()
|
422
|
+
return f
|
423
|
+
if is_small_python_int(x0):
|
424
|
+
z = Integer.__new__(Integer)
|
425
|
+
sig_on()
|
426
|
+
fmpz_init(a_fmpz)
|
427
|
+
fmpz_init(z_fmpz)
|
428
|
+
fmpz_set_si(a_fmpz, PyLong_AsLong(x0))
|
429
|
+
fmpz_poly_evaluate_fmpz(z_fmpz, self._poly, a_fmpz)
|
430
|
+
fmpz_get_mpz(z.value, z_fmpz)
|
431
|
+
fmpz_clear(a_fmpz)
|
432
|
+
fmpz_clear(z_fmpz)
|
433
|
+
sig_off()
|
434
|
+
return z
|
435
|
+
if isinstance(x0, int):
|
436
|
+
x0 = Integer(x0)
|
437
|
+
if isinstance(x0, Integer):
|
438
|
+
a = <Integer> x0
|
439
|
+
|
440
|
+
if fmpz_poly_length(self._poly) == 0:
|
441
|
+
return ZZ.zero()
|
442
|
+
if mpz_sgn(a.value) == 0:
|
443
|
+
return self[0]
|
444
|
+
|
445
|
+
z = Integer.__new__(Integer)
|
446
|
+
|
447
|
+
sig_on()
|
448
|
+
fmpz_init(a_fmpz)
|
449
|
+
fmpz_init(z_fmpz)
|
450
|
+
fmpz_set_mpz(a_fmpz, a.value)
|
451
|
+
fmpz_poly_evaluate_fmpz(z_fmpz, self._poly, a_fmpz)
|
452
|
+
fmpz_get_mpz(z.value, z_fmpz)
|
453
|
+
fmpz_clear(a_fmpz)
|
454
|
+
fmpz_clear(z_fmpz)
|
455
|
+
sig_off()
|
456
|
+
|
457
|
+
return z
|
458
|
+
|
459
|
+
if isinstance(x0, RealNumber):
|
460
|
+
return self._eval_mpfr_(<RealNumber> x0)
|
461
|
+
if isinstance(x0, RealIntervalFieldElement):
|
462
|
+
return self._eval_mpfi_(<RealIntervalFieldElement> x0)
|
463
|
+
if isinstance(x0, RealBall):
|
464
|
+
arb_a = <RealBall> x0
|
465
|
+
arb_z = arb_a._new()
|
466
|
+
sig_on()
|
467
|
+
arb_fmpz_poly_evaluate_arb(arb_z.value, self._poly, arb_a.value, arb_a._parent._prec)
|
468
|
+
sig_off()
|
469
|
+
return arb_z
|
470
|
+
if isinstance(x0, ComplexBall):
|
471
|
+
acb_a = <ComplexBall> x0
|
472
|
+
acb_z = acb_a._new()
|
473
|
+
sig_on()
|
474
|
+
arb_fmpz_poly_evaluate_acb(acb_z.value, self._poly, acb_a.value, acb_a._parent._prec)
|
475
|
+
sig_off()
|
476
|
+
return acb_z
|
477
|
+
|
478
|
+
return Polynomial.__call__(self, *x, **kwds)
|
479
|
+
|
480
|
+
cpdef Integer content(self):
|
481
|
+
r"""
|
482
|
+
Return the greatest common divisor of the coefficients of this
|
483
|
+
polynomial. The sign is the sign of the leading coefficient. The
|
484
|
+
content of the zero polynomial is zero.
|
485
|
+
|
486
|
+
EXAMPLES::
|
487
|
+
|
488
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
489
|
+
sage: (2*x^2 - 4*x^4 + 14*x^7).content()
|
490
|
+
2
|
491
|
+
sage: x.content()
|
492
|
+
1
|
493
|
+
sage: R(1).content()
|
494
|
+
1
|
495
|
+
sage: R(0).content()
|
496
|
+
0
|
497
|
+
|
498
|
+
TESTS::
|
499
|
+
|
500
|
+
sage: t = x^2+x+1
|
501
|
+
sage: t.content()
|
502
|
+
1
|
503
|
+
sage: (123456789123456789123456789123456789123456789*t).content()
|
504
|
+
123456789123456789123456789123456789123456789
|
505
|
+
|
506
|
+
Verify that :issue:`13053` has been resolved::
|
507
|
+
|
508
|
+
sage: R(-1).content()
|
509
|
+
-1
|
510
|
+
"""
|
511
|
+
if self.is_zero():
|
512
|
+
return ZZ.zero()
|
513
|
+
|
514
|
+
cdef fmpz_t c
|
515
|
+
fmpz_init(c)
|
516
|
+
fmpz_poly_get_coeff_fmpz(c, self._poly, fmpz_poly_degree(self._poly))
|
517
|
+
cdef int sign = fmpz_sgn(c)
|
518
|
+
|
519
|
+
fmpz_poly_content(c, self._poly)
|
520
|
+
|
521
|
+
cdef Integer z = Integer.__new__(Integer)
|
522
|
+
fmpz_get_mpz(z.value, c)
|
523
|
+
fmpz_clear(c)
|
524
|
+
return z if sign == 1 else -z
|
525
|
+
|
526
|
+
def __reduce__(self):
|
527
|
+
r"""
|
528
|
+
Used for pickling.
|
529
|
+
|
530
|
+
EXAMPLES::
|
531
|
+
|
532
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
533
|
+
sage: loads(dumps(x)) == x
|
534
|
+
True
|
535
|
+
sage: f = 2*x + 3
|
536
|
+
sage: loads(dumps(f)) == f
|
537
|
+
True
|
538
|
+
"""
|
539
|
+
return Polynomial_integer_dense_flint, \
|
540
|
+
(self.parent(), self.list(), False, self.is_gen())
|
541
|
+
|
542
|
+
cdef get_unsafe(self, Py_ssize_t n):
|
543
|
+
"""
|
544
|
+
Return the `n`-th coefficient of ``self``.
|
545
|
+
|
546
|
+
EXAMPLES::
|
547
|
+
|
548
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
549
|
+
sage: f = 2*x^2 - 3
|
550
|
+
sage: f[0]
|
551
|
+
-3
|
552
|
+
sage: f[1]
|
553
|
+
0
|
554
|
+
sage: f[2]
|
555
|
+
2
|
556
|
+
sage: f[3]
|
557
|
+
0
|
558
|
+
sage: f[-1]
|
559
|
+
0
|
560
|
+
sage: f = 1 + x + 2*x^2 + 3*x^3 + 4*x^4 + 5*x^5
|
561
|
+
sage: f[:4]
|
562
|
+
3*x^3 + 2*x^2 + x + 1
|
563
|
+
sage: f[:100]
|
564
|
+
5*x^5 + 4*x^4 + 3*x^3 + 2*x^2 + x + 1
|
565
|
+
"""
|
566
|
+
cdef Integer z = Integer.__new__(Integer)
|
567
|
+
fmpz_poly_get_coeff_mpz(z.value, self._poly, n)
|
568
|
+
return z
|
569
|
+
|
570
|
+
def _repr(self, name=None, bint latex=False):
|
571
|
+
"""
|
572
|
+
Return string representation of this polynomial.
|
573
|
+
|
574
|
+
EXAMPLES::
|
575
|
+
|
576
|
+
sage: R.<x> = ZZ['x']
|
577
|
+
sage: (-x+1)^5
|
578
|
+
-x^5 + 5*x^4 - 10*x^3 + 10*x^2 - 5*x + 1
|
579
|
+
sage: ((-x+1)^5)._repr()
|
580
|
+
'-x^5 + 5*x^4 - 10*x^3 + 10*x^2 - 5*x + 1'
|
581
|
+
sage: ((-x+1)^5)._repr(name='y')
|
582
|
+
'-y^5 + 5*y^4 - 10*y^3 + 10*y^2 - 5*y + 1'
|
583
|
+
"""
|
584
|
+
if name is None:
|
585
|
+
name = self.parent().variable_name()
|
586
|
+
cdef long i
|
587
|
+
cdef Integer coef = Integer.__new__(Integer)
|
588
|
+
cdef list all = []
|
589
|
+
for i from fmpz_poly_degree(self._poly) >= i >= 0:
|
590
|
+
fmpz_poly_get_coeff_mpz(coef.value, self._poly, i)
|
591
|
+
if coef:
|
592
|
+
if coef > 0:
|
593
|
+
sign_str = '+'
|
594
|
+
coeff_str = str(coef)
|
595
|
+
else:
|
596
|
+
sign_str = '-'
|
597
|
+
coeff_str = str(coef)[1:]
|
598
|
+
if i > 0:
|
599
|
+
if coeff_str == '1':
|
600
|
+
coeff_str = ''
|
601
|
+
elif not latex:
|
602
|
+
coeff_str = coeff_str + '*'
|
603
|
+
if i > 1:
|
604
|
+
if latex:
|
605
|
+
all.append(" %s %s%s^{%s}" % (sign_str,
|
606
|
+
coeff_str, name, i))
|
607
|
+
else:
|
608
|
+
all.append(" %s %s%s^%s" % (sign_str,
|
609
|
+
coeff_str, name, i))
|
610
|
+
elif i == 1:
|
611
|
+
all.append(" %s %s%s" % (sign_str, coeff_str, name))
|
612
|
+
else:
|
613
|
+
all.append(" %s %s" % (sign_str, coeff_str))
|
614
|
+
if len(all) == 0:
|
615
|
+
return '0'
|
616
|
+
leading = all[0]
|
617
|
+
if leading[1] == '+':
|
618
|
+
all[0] = leading[3:]
|
619
|
+
else:
|
620
|
+
all[0] = '-' + leading[3:]
|
621
|
+
return ''.join(all)
|
622
|
+
|
623
|
+
def _latex_(self, name=None):
|
624
|
+
"""
|
625
|
+
Return the latex representation of this polynomial.
|
626
|
+
|
627
|
+
EXAMPLES::
|
628
|
+
|
629
|
+
sage: R.<t> = ZZ['t']
|
630
|
+
sage: latex(t^10-t^2-5*t+1)
|
631
|
+
t^{10} - t^{2} - 5t + 1
|
632
|
+
sage: cyclotomic_polynomial(10^5)._latex_()
|
633
|
+
'x^{40000} - x^{30000} + x^{20000} - x^{10000} + 1'
|
634
|
+
sage: cyclotomic_polynomial(10^5)._latex_(name='y')
|
635
|
+
'y^{40000} - y^{30000} + y^{20000} - y^{10000} + 1'
|
636
|
+
"""
|
637
|
+
if name is None:
|
638
|
+
name = self.parent().latex_variable_names()[0]
|
639
|
+
return self._repr(name=name, latex=True)
|
640
|
+
|
641
|
+
cpdef _add_(self, right):
|
642
|
+
r"""
|
643
|
+
Return ``self`` plus ``right``.
|
644
|
+
|
645
|
+
EXAMPLES::
|
646
|
+
|
647
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
648
|
+
sage: f = 2*x + 1
|
649
|
+
sage: g = -3*x^2 + 6
|
650
|
+
sage: f + g
|
651
|
+
-3*x^2 + 2*x + 7
|
652
|
+
"""
|
653
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
654
|
+
sig_on()
|
655
|
+
fmpz_poly_add(x._poly, self._poly,
|
656
|
+
(<Polynomial_integer_dense_flint>right)._poly)
|
657
|
+
sig_off()
|
658
|
+
return x
|
659
|
+
|
660
|
+
cpdef _sub_(self, right):
|
661
|
+
r"""
|
662
|
+
Return ``self`` minus ``right``.
|
663
|
+
|
664
|
+
EXAMPLES::
|
665
|
+
|
666
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
667
|
+
sage: f = 2*x + 1
|
668
|
+
sage: g = -3*x^2 + 6
|
669
|
+
sage: f - g
|
670
|
+
3*x^2 + 2*x - 5
|
671
|
+
"""
|
672
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
673
|
+
sig_on()
|
674
|
+
fmpz_poly_sub(x._poly, self._poly,
|
675
|
+
(<Polynomial_integer_dense_flint>right)._poly)
|
676
|
+
sig_off()
|
677
|
+
return x
|
678
|
+
|
679
|
+
cpdef _neg_(self):
|
680
|
+
r"""
|
681
|
+
Return negative of ``self``.
|
682
|
+
|
683
|
+
EXAMPLES::
|
684
|
+
|
685
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
686
|
+
sage: f = 2*x - 1
|
687
|
+
sage: -f
|
688
|
+
-2*x + 1
|
689
|
+
"""
|
690
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
691
|
+
sig_on()
|
692
|
+
fmpz_poly_neg(x._poly, self._poly)
|
693
|
+
sig_off()
|
694
|
+
return x
|
695
|
+
|
696
|
+
@coerce_binop
|
697
|
+
def quo_rem(self, Polynomial_integer_dense_flint right):
|
698
|
+
r"""
|
699
|
+
Attempts to divide ``self`` by ``right``, and return a quotient and remainder.
|
700
|
+
|
701
|
+
EXAMPLES::
|
702
|
+
|
703
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
704
|
+
sage: f = R(range(10)); g = R([-1, 0, 1])
|
705
|
+
sage: q, r = f.quo_rem(g)
|
706
|
+
sage: q, r
|
707
|
+
(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)
|
708
|
+
sage: q*g + r == f
|
709
|
+
True
|
710
|
+
|
711
|
+
sage: f = x^2
|
712
|
+
sage: f.quo_rem(0)
|
713
|
+
Traceback (most recent call last):
|
714
|
+
...
|
715
|
+
ZeroDivisionError: division by zero polynomial
|
716
|
+
|
717
|
+
sage: f = (x^2 + 3) * (2*x - 1)
|
718
|
+
sage: f.quo_rem(2*x - 1)
|
719
|
+
(x^2 + 3, 0)
|
720
|
+
|
721
|
+
sage: f = x^2
|
722
|
+
sage: f.quo_rem(2*x - 1)
|
723
|
+
(0, x^2)
|
724
|
+
|
725
|
+
TESTS::
|
726
|
+
|
727
|
+
sage: z = R(0)
|
728
|
+
sage: z.quo_rem(1)
|
729
|
+
(0, 0)
|
730
|
+
sage: z.quo_rem(x)
|
731
|
+
(0, 0)
|
732
|
+
sage: z.quo_rem(2*x)
|
733
|
+
(0, 0)
|
734
|
+
|
735
|
+
:issue:`383`, make sure things get coerced correctly::
|
736
|
+
|
737
|
+
sage: f = x+1; parent(f)
|
738
|
+
Univariate Polynomial Ring in x over Integer Ring
|
739
|
+
sage: g = x/2; parent(g)
|
740
|
+
Univariate Polynomial Ring in x over Rational Field
|
741
|
+
sage: f.quo_rem(g)
|
742
|
+
(2, 1)
|
743
|
+
sage: g.quo_rem(f)
|
744
|
+
(1/2, -1/2)
|
745
|
+
sage: parent(f.quo_rem(g)[0])
|
746
|
+
Univariate Polynomial Ring in x over Rational Field
|
747
|
+
sage: f.quo_rem(3)
|
748
|
+
(0, x + 1)
|
749
|
+
sage: (5*x+7).quo_rem(3)
|
750
|
+
(x + 2, 2*x + 1)
|
751
|
+
"""
|
752
|
+
if right.is_zero():
|
753
|
+
raise ZeroDivisionError("division by zero polynomial")
|
754
|
+
|
755
|
+
if self.is_zero():
|
756
|
+
return self, self
|
757
|
+
|
758
|
+
cdef Polynomial_integer_dense_flint qq = self._new()
|
759
|
+
cdef Polynomial_integer_dense_flint rr = self._new()
|
760
|
+
|
761
|
+
sig_on()
|
762
|
+
fmpz_poly_divrem(qq._poly, rr._poly, self._poly, right._poly)
|
763
|
+
sig_off()
|
764
|
+
return qq, rr
|
765
|
+
|
766
|
+
cpdef bint is_zero(self) except -1:
|
767
|
+
"""
|
768
|
+
Return ``True`` if ``self`` is equal to zero.
|
769
|
+
|
770
|
+
EXAMPLES::
|
771
|
+
|
772
|
+
sage: R.<x> = ZZ[]
|
773
|
+
sage: R(0).is_zero()
|
774
|
+
True
|
775
|
+
sage: R(1).is_zero()
|
776
|
+
False
|
777
|
+
sage: x.is_zero()
|
778
|
+
False
|
779
|
+
"""
|
780
|
+
return (fmpz_poly_degree(self._poly) == -1)
|
781
|
+
|
782
|
+
cpdef bint is_one(self) except -1:
|
783
|
+
"""
|
784
|
+
Return ``True`` if ``self`` is equal to one.
|
785
|
+
|
786
|
+
EXAMPLES::
|
787
|
+
|
788
|
+
sage: R.<x> = ZZ[]
|
789
|
+
sage: R(0).is_one()
|
790
|
+
False
|
791
|
+
sage: R(1).is_one()
|
792
|
+
True
|
793
|
+
sage: x.is_one()
|
794
|
+
False
|
795
|
+
"""
|
796
|
+
return fmpz_poly_is_one(self._poly)
|
797
|
+
|
798
|
+
def __bool__(self):
|
799
|
+
"""
|
800
|
+
Check if ``self`` is not zero.
|
801
|
+
|
802
|
+
EXAMPLES::
|
803
|
+
|
804
|
+
sage: R.<x> = ZZ[]
|
805
|
+
sage: bool(R(0))
|
806
|
+
False
|
807
|
+
sage: bool(R(1))
|
808
|
+
True
|
809
|
+
sage: bool(x)
|
810
|
+
True
|
811
|
+
"""
|
812
|
+
return not (fmpz_poly_degree(self._poly) == -1)
|
813
|
+
|
814
|
+
@coerce_binop
|
815
|
+
def gcd(self, right):
|
816
|
+
r"""
|
817
|
+
Return the GCD of ``self`` and ``right``. The leading
|
818
|
+
coefficient need not be 1.
|
819
|
+
|
820
|
+
EXAMPLES::
|
821
|
+
|
822
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
823
|
+
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
|
824
|
+
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
|
825
|
+
sage: f.gcd(g)
|
826
|
+
6*x + 47
|
827
|
+
"""
|
828
|
+
cdef Polynomial_integer_dense_flint _right = <Polynomial_integer_dense_flint> right
|
829
|
+
if self.is_zero() or _right.is_one():
|
830
|
+
return right
|
831
|
+
elif self.is_one() or _right.is_zero():
|
832
|
+
return self
|
833
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
834
|
+
sig_on()
|
835
|
+
fmpz_poly_gcd(x._poly, self._poly,
|
836
|
+
(<Polynomial_integer_dense_flint>right)._poly)
|
837
|
+
sig_off()
|
838
|
+
return x
|
839
|
+
|
840
|
+
@coerce_binop
|
841
|
+
def lcm(self, right):
|
842
|
+
"""
|
843
|
+
Return the LCM of ``self`` and ``right``.
|
844
|
+
|
845
|
+
EXAMPLES::
|
846
|
+
|
847
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
848
|
+
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
|
849
|
+
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
|
850
|
+
sage: h = f.lcm(g); h
|
851
|
+
126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786
|
852
|
+
sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1)
|
853
|
+
True
|
854
|
+
|
855
|
+
TESTS:
|
856
|
+
|
857
|
+
Check that :issue:`32033` has been fixed::
|
858
|
+
|
859
|
+
sage: R.<t> = ZZ[]
|
860
|
+
sage: lcm(R(0), R(0))
|
861
|
+
0
|
862
|
+
"""
|
863
|
+
if self.is_zero() or right.is_zero():
|
864
|
+
P = self.parent()
|
865
|
+
return P.zero()
|
866
|
+
g = self.gcd(right)
|
867
|
+
return (self//g)*right
|
868
|
+
|
869
|
+
@coerce_binop
|
870
|
+
def xgcd(self, right):
|
871
|
+
r"""
|
872
|
+
Return a triple `(g,s,t)` such that `g = s\cdot{}` ``self`` + `t\cdot{}` ``right`` and such
|
873
|
+
that `g` is the gcd of ``self`` and ``right`` up to a divisor of the
|
874
|
+
resultant of ``self`` and ``other``.
|
875
|
+
|
876
|
+
As integer polynomials do not form a principal ideal domain, it is not
|
877
|
+
always possible given `a` and `b` to find a pair `s,t` such that
|
878
|
+
`gcd(a,b) = sa + tb`. Take `a=x+2` and `b=x+4` as an example for which the
|
879
|
+
gcd is `1` but the best you can achieve in the Bezout identity is `2`.
|
880
|
+
|
881
|
+
If ``self`` and ``right`` are coprime as polynomials over the
|
882
|
+
rationals, then ``g`` is guaranteed to be the resultant of
|
883
|
+
``self`` and ``right``, as a constant polynomial.
|
884
|
+
|
885
|
+
EXAMPLES::
|
886
|
+
|
887
|
+
sage: P.<x> = PolynomialRing(ZZ)
|
888
|
+
|
889
|
+
sage: (x + 2).xgcd(x + 4)
|
890
|
+
(2, -1, 1)
|
891
|
+
sage: (x + 2).resultant(x + 4)
|
892
|
+
2
|
893
|
+
sage: (x + 2).gcd(x + 4)
|
894
|
+
1
|
895
|
+
|
896
|
+
sage: F = (x^2 + 2)*x^3; G = (x^2 + 2) * (x - 3)
|
897
|
+
sage: g, u, v = F.xgcd(G)
|
898
|
+
sage: g, u, v
|
899
|
+
(27*x^2 + 54, 1, -x^2 - 3*x - 9)
|
900
|
+
sage: u*F + v*G
|
901
|
+
27*x^2 + 54
|
902
|
+
|
903
|
+
sage: zero = P(0)
|
904
|
+
sage: x.xgcd(zero)
|
905
|
+
(x, 1, 0)
|
906
|
+
sage: zero.xgcd(x)
|
907
|
+
(x, 0, 1)
|
908
|
+
|
909
|
+
sage: F = (x - 3)^3; G = (x - 15)^2
|
910
|
+
sage: g, u, v = F.xgcd(G)
|
911
|
+
sage: g, u, v
|
912
|
+
(2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)
|
913
|
+
sage: u*F + v*G
|
914
|
+
2985984
|
915
|
+
|
916
|
+
TESTS:
|
917
|
+
|
918
|
+
Check that :issue:`17675` is fixed::
|
919
|
+
|
920
|
+
sage: R.<x> = ZZ['x']
|
921
|
+
sage: R(2).xgcd(R(2))
|
922
|
+
(2, 0, 1)
|
923
|
+
sage: R.zero().xgcd(R(2))
|
924
|
+
(2, 0, 1)
|
925
|
+
sage: R(2).xgcd(R.zero())
|
926
|
+
(2, 1, 0)
|
927
|
+
"""
|
928
|
+
# trivial cases first
|
929
|
+
if self.is_zero():
|
930
|
+
return (right, Integer(0), Integer(1))
|
931
|
+
elif right.is_zero():
|
932
|
+
return (self, Integer(1), Integer(0))
|
933
|
+
elif self.is_constant() and right.is_constant():
|
934
|
+
# this case is needed as the behavior of the function fmpz_poly_xgcd
|
935
|
+
# in FLINT is not defined with constant input
|
936
|
+
return self.constant_coefficient().xgcd(right.constant_coefficient())
|
937
|
+
|
938
|
+
cdef Polynomial_integer_dense_flint ss = self._new()
|
939
|
+
cdef Polynomial_integer_dense_flint tt = self._new()
|
940
|
+
cdef fmpz_t r
|
941
|
+
fmpz_init(r)
|
942
|
+
|
943
|
+
sig_on()
|
944
|
+
fmpz_poly_xgcd(r, ss._poly, tt._poly, self._poly,
|
945
|
+
(<Polynomial_integer_dense_flint>right)._poly)
|
946
|
+
sig_off()
|
947
|
+
cdef Integer rr = Integer.__new__(Integer)
|
948
|
+
fmpz_get_mpz(rr.value, r)
|
949
|
+
fmpz_clear(r)
|
950
|
+
|
951
|
+
if rr.is_zero():
|
952
|
+
f = self.base_extend(QQ)
|
953
|
+
g, u, v = f.xgcd(right.base_extend(QQ))
|
954
|
+
d = lcm([g.denominator(), u.denominator(), v.denominator()])
|
955
|
+
R = self.parent()
|
956
|
+
return R(d*g), R(d*u), R(d*v)
|
957
|
+
else:
|
958
|
+
return self._parent(rr), ss, tt
|
959
|
+
|
960
|
+
cpdef _mul_(self, right):
|
961
|
+
r"""
|
962
|
+
Return ``self`` multiplied by ``right``.
|
963
|
+
|
964
|
+
EXAMPLES::
|
965
|
+
|
966
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
967
|
+
sage: (x - 2)*(x^2 - 8*x + 16)
|
968
|
+
x^3 - 10*x^2 + 32*x - 32
|
969
|
+
"""
|
970
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
971
|
+
sig_on()
|
972
|
+
fmpz_poly_mul(x._poly, self._poly,
|
973
|
+
(<Polynomial_integer_dense_flint>right)._poly)
|
974
|
+
sig_off()
|
975
|
+
return x
|
976
|
+
|
977
|
+
cpdef Polynomial _mul_trunc_(self, Polynomial right, long n):
|
978
|
+
r"""
|
979
|
+
Truncated multiplication.
|
980
|
+
|
981
|
+
.. SEEALSO::
|
982
|
+
|
983
|
+
:meth:`_mul_` for standard multiplication
|
984
|
+
|
985
|
+
EXAMPLES::
|
986
|
+
|
987
|
+
sage: x = polygen(ZZ)
|
988
|
+
sage: p1 = 1 + x + x^2 + x^4
|
989
|
+
sage: p2 = -2 + 3*x^2 + 5*x^4
|
990
|
+
sage: p1._mul_trunc_(p2, 4)
|
991
|
+
3*x^3 + x^2 - 2*x - 2
|
992
|
+
sage: (p1*p2).truncate(4)
|
993
|
+
3*x^3 + x^2 - 2*x - 2
|
994
|
+
sage: p1._mul_trunc_(p2, 6)
|
995
|
+
5*x^5 + 6*x^4 + 3*x^3 + x^2 - 2*x - 2
|
996
|
+
"""
|
997
|
+
if n <= 0:
|
998
|
+
raise ValueError("length must be > 0")
|
999
|
+
|
1000
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
1001
|
+
sig_on()
|
1002
|
+
fmpz_poly_mullow(x._poly, self._poly,
|
1003
|
+
(<Polynomial_integer_dense_flint>right)._poly,
|
1004
|
+
n)
|
1005
|
+
sig_off()
|
1006
|
+
return x
|
1007
|
+
|
1008
|
+
cpdef _lmul_(self, Element right):
|
1009
|
+
r"""
|
1010
|
+
Return ``self`` multiplied by ``right``, where ``right`` is a scalar (integer).
|
1011
|
+
|
1012
|
+
EXAMPLES::
|
1013
|
+
|
1014
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1015
|
+
sage: x*3
|
1016
|
+
3*x
|
1017
|
+
sage: (2*x^2 + 4)*3
|
1018
|
+
6*x^2 + 12
|
1019
|
+
"""
|
1020
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
1021
|
+
sig_on()
|
1022
|
+
fmpz_poly_scalar_mul_mpz(x._poly, self._poly, (<Integer>right).value)
|
1023
|
+
sig_off()
|
1024
|
+
return x
|
1025
|
+
|
1026
|
+
cpdef _rmul_(self, Element right):
|
1027
|
+
r"""
|
1028
|
+
Return ``self`` multiplied by ``right``, where right is a scalar (integer).
|
1029
|
+
|
1030
|
+
EXAMPLES::
|
1031
|
+
|
1032
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1033
|
+
sage: 3*x
|
1034
|
+
3*x
|
1035
|
+
sage: 3*(2*x^2 + 4)
|
1036
|
+
6*x^2 + 12
|
1037
|
+
"""
|
1038
|
+
cdef Polynomial_integer_dense_flint x = self._new()
|
1039
|
+
sig_on()
|
1040
|
+
fmpz_poly_scalar_mul_mpz(x._poly, self._poly, (<Integer>right).value)
|
1041
|
+
sig_off()
|
1042
|
+
return x
|
1043
|
+
|
1044
|
+
def __pow__(Polynomial_integer_dense_flint self, exp, mod):
|
1045
|
+
"""
|
1046
|
+
EXAMPLES::
|
1047
|
+
|
1048
|
+
sage: R.<x> = ZZ[]
|
1049
|
+
sage: r = 2*x + 2
|
1050
|
+
sage: r^0
|
1051
|
+
1
|
1052
|
+
sage: r^2
|
1053
|
+
4*x^2 + 8*x + 4
|
1054
|
+
sage: r^-2
|
1055
|
+
1/(4*x^2 + 8*x + 4)
|
1056
|
+
|
1057
|
+
sage: x^(2^20)
|
1058
|
+
x^1048576
|
1059
|
+
|
1060
|
+
TESTS::
|
1061
|
+
|
1062
|
+
sage: z = R(0)
|
1063
|
+
sage: z^0
|
1064
|
+
1
|
1065
|
+
sage: z^1
|
1066
|
+
0
|
1067
|
+
sage: z^-1
|
1068
|
+
Traceback (most recent call last):
|
1069
|
+
...
|
1070
|
+
ZeroDivisionError: negative exponent in power of zero
|
1071
|
+
|
1072
|
+
Check that :issue:`18278` is fixed::
|
1073
|
+
|
1074
|
+
sage: R.<x> = ZZ[]
|
1075
|
+
sage: x^(1/2)
|
1076
|
+
Traceback (most recent call last):
|
1077
|
+
...
|
1078
|
+
ValueError: not a 2nd power
|
1079
|
+
|
1080
|
+
sage: x^(2^100)
|
1081
|
+
Traceback (most recent call last):
|
1082
|
+
...
|
1083
|
+
OverflowError: Sage Integer too large to convert to C long
|
1084
|
+
|
1085
|
+
Test fractional powers (:issue:`20086`)::
|
1086
|
+
|
1087
|
+
sage: P.<R> = ZZ[]
|
1088
|
+
sage: (R^3 + 6*R^2 + 12*R + 8)^(1/3)
|
1089
|
+
R + 2
|
1090
|
+
sage: _.parent()
|
1091
|
+
Univariate Polynomial Ring in R over Integer Ring
|
1092
|
+
sage: P(4)^(1/2)
|
1093
|
+
2
|
1094
|
+
sage: _.parent()
|
1095
|
+
Univariate Polynomial Ring in R over Integer Ring
|
1096
|
+
|
1097
|
+
sage: (R^2 + 3)^(1/2)
|
1098
|
+
Traceback (most recent call last):
|
1099
|
+
...
|
1100
|
+
ValueError: 3 is not a 2nd power
|
1101
|
+
|
1102
|
+
Ring in R over Integer Ring
|
1103
|
+
sage: P(2)^P(2)
|
1104
|
+
Traceback (most recent call last):
|
1105
|
+
...
|
1106
|
+
TypeError: no canonical coercion from Univariate Polynomial
|
1107
|
+
Ring in R over Integer Ring to Rational Field
|
1108
|
+
sage: (R + 1)^P(2)
|
1109
|
+
Traceback (most recent call last):
|
1110
|
+
...
|
1111
|
+
TypeError: no canonical coercion from Univariate Polynomial
|
1112
|
+
Ring in R over Integer Ring to Rational Field
|
1113
|
+
sage: (R + 1)^R
|
1114
|
+
Traceback (most recent call last):
|
1115
|
+
...
|
1116
|
+
TypeError: no canonical coercion from Univariate Polynomial
|
1117
|
+
Ring in R over Integer Ring to Rational Field
|
1118
|
+
sage: 2^R
|
1119
|
+
Traceback (most recent call last):
|
1120
|
+
...
|
1121
|
+
TypeError: no canonical coercion from Univariate Polynomial
|
1122
|
+
Ring in R over Integer Ring to Rational Field
|
1123
|
+
|
1124
|
+
Check that using third argument raises an error::
|
1125
|
+
|
1126
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='FLINT')
|
1127
|
+
sage: pow(x, 2, x)
|
1128
|
+
Traceback (most recent call last):
|
1129
|
+
...
|
1130
|
+
NotImplementedError: pow() with a modulus is not implemented for this ring
|
1131
|
+
"""
|
1132
|
+
cdef long nn
|
1133
|
+
cdef Polynomial_integer_dense_flint res
|
1134
|
+
|
1135
|
+
if mod is not None:
|
1136
|
+
raise NotImplementedError(
|
1137
|
+
"pow() with a modulus is not implemented for this ring"
|
1138
|
+
)
|
1139
|
+
|
1140
|
+
try:
|
1141
|
+
nn = pyobject_to_long(exp)
|
1142
|
+
except TypeError:
|
1143
|
+
n = QQ.coerce(exp)
|
1144
|
+
num = n.numerator()
|
1145
|
+
den = n.denominator()
|
1146
|
+
|
1147
|
+
if fmpz_poly_degree(self._poly) == 0:
|
1148
|
+
return self.parent()(self[0].nth_root(den) ** num)
|
1149
|
+
|
1150
|
+
return self.nth_root(den) ** num
|
1151
|
+
|
1152
|
+
else:
|
1153
|
+
res = self._new()
|
1154
|
+
|
1155
|
+
if self.is_zero():
|
1156
|
+
if nn == 0:
|
1157
|
+
fmpz_poly_set_coeff_si(res._poly, 0, 1)
|
1158
|
+
return res
|
1159
|
+
elif nn < 0:
|
1160
|
+
raise ZeroDivisionError("negative exponent in power of zero")
|
1161
|
+
else:
|
1162
|
+
return res
|
1163
|
+
if nn < 0:
|
1164
|
+
sig_on()
|
1165
|
+
fmpz_poly_pow(res._poly, self._poly, -nn)
|
1166
|
+
sig_off()
|
1167
|
+
return ~res
|
1168
|
+
else:
|
1169
|
+
if self is self._parent.gen():
|
1170
|
+
sig_on()
|
1171
|
+
fmpz_poly_set_coeff_ui(res._poly, nn, 1)
|
1172
|
+
sig_off()
|
1173
|
+
else:
|
1174
|
+
sig_on()
|
1175
|
+
fmpz_poly_pow(res._poly, self._poly, nn)
|
1176
|
+
sig_off()
|
1177
|
+
return res
|
1178
|
+
|
1179
|
+
cpdef Polynomial _power_trunc(self, unsigned long n, long prec):
|
1180
|
+
r"""
|
1181
|
+
Truncated power.
|
1182
|
+
|
1183
|
+
TESTS::
|
1184
|
+
|
1185
|
+
sage: R.<x> = ZZ[]
|
1186
|
+
sage: (x**2 - x + 1).power_trunc(100, 5)
|
1187
|
+
4411275*x^4 - 171600*x^3 + 5050*x^2 - 100*x + 1
|
1188
|
+
sage: R.zero().power_trunc(0, 1)
|
1189
|
+
1
|
1190
|
+
|
1191
|
+
sage: x._power_trunc(2, -1)
|
1192
|
+
0
|
1193
|
+
sage: parent(_) is R
|
1194
|
+
True
|
1195
|
+
"""
|
1196
|
+
if prec <= 0:
|
1197
|
+
# NOTE: flint crashes for prec < 0
|
1198
|
+
return self._parent.zero()
|
1199
|
+
|
1200
|
+
cdef Polynomial_integer_dense_flint res
|
1201
|
+
res = self._new()
|
1202
|
+
fmpz_poly_pow_trunc(res._poly, self._poly, n, prec)
|
1203
|
+
return res
|
1204
|
+
|
1205
|
+
def __floordiv__(Polynomial_integer_dense_flint self, right):
|
1206
|
+
"""
|
1207
|
+
EXAMPLES::
|
1208
|
+
|
1209
|
+
sage: R.<x> = ZZ[]
|
1210
|
+
sage: (x^2+1)//x
|
1211
|
+
x
|
1212
|
+
sage: (5*x^2+1)//(2*x)
|
1213
|
+
2*x
|
1214
|
+
|
1215
|
+
Divide by a scalar.
|
1216
|
+
|
1217
|
+
::
|
1218
|
+
|
1219
|
+
sage: (5*x^3 + 5*x + 10)//5
|
1220
|
+
x^3 + x + 2
|
1221
|
+
|
1222
|
+
TESTS::
|
1223
|
+
|
1224
|
+
sage: x//0
|
1225
|
+
Traceback (most recent call last):
|
1226
|
+
...
|
1227
|
+
ZeroDivisionError: division by zero
|
1228
|
+
|
1229
|
+
sage: (x^2 + 13*x + 169) // 13
|
1230
|
+
x + 13
|
1231
|
+
"""
|
1232
|
+
cdef Polynomial_integer_dense_flint _right
|
1233
|
+
cdef Polynomial_integer_dense_flint res
|
1234
|
+
if not isinstance(right, Polynomial_integer_dense_flint):
|
1235
|
+
if isinstance(right, Integer):
|
1236
|
+
if (<Integer> right).is_zero():
|
1237
|
+
raise ZeroDivisionError("division by zero")
|
1238
|
+
else:
|
1239
|
+
res = self._new()
|
1240
|
+
sig_on()
|
1241
|
+
fmpz_poly_scalar_fdiv_mpz(res._poly, self._poly,
|
1242
|
+
(<Integer> right).value)
|
1243
|
+
sig_off()
|
1244
|
+
return res
|
1245
|
+
elif right in ZZ:
|
1246
|
+
res = self._new()
|
1247
|
+
sig_on()
|
1248
|
+
fmpz_poly_scalar_fdiv_mpz(res._poly, self._poly,
|
1249
|
+
(<Integer>ZZ(right)).value)
|
1250
|
+
sig_off()
|
1251
|
+
return res
|
1252
|
+
else:
|
1253
|
+
right = self._parent(right)
|
1254
|
+
_right = <Polynomial_integer_dense_flint> right
|
1255
|
+
if _right.is_zero():
|
1256
|
+
raise ZeroDivisionError("division by zero")
|
1257
|
+
elif _right.is_one():
|
1258
|
+
# quite typical when removing gcds...
|
1259
|
+
return self
|
1260
|
+
else:
|
1261
|
+
res = self._new()
|
1262
|
+
sig_on()
|
1263
|
+
fmpz_poly_div(res._poly, self._poly, _right._poly)
|
1264
|
+
sig_off()
|
1265
|
+
return res
|
1266
|
+
|
1267
|
+
cpdef Polynomial inverse_series_trunc(self, long prec):
|
1268
|
+
r"""
|
1269
|
+
Return a polynomial approximation of precision ``prec`` of the inverse
|
1270
|
+
series of this polynomial.
|
1271
|
+
|
1272
|
+
EXAMPLES::
|
1273
|
+
|
1274
|
+
sage: x = polygen(ZZ)
|
1275
|
+
sage: p = 1 + x + 2*x^2
|
1276
|
+
sage: q5 = p.inverse_series_trunc(5)
|
1277
|
+
sage: q5
|
1278
|
+
-x^4 + 3*x^3 - x^2 - x + 1
|
1279
|
+
sage: p*q5
|
1280
|
+
-2*x^6 + 5*x^5 + 1
|
1281
|
+
|
1282
|
+
sage: (x-1).inverse_series_trunc(5)
|
1283
|
+
-x^4 - x^3 - x^2 - x - 1
|
1284
|
+
|
1285
|
+
sage: q100 = p.inverse_series_trunc(100)
|
1286
|
+
sage: (q100 * p).truncate(100)
|
1287
|
+
1
|
1288
|
+
|
1289
|
+
TESTS::
|
1290
|
+
|
1291
|
+
sage: ZZ['x'].zero().inverse_series_trunc(4)
|
1292
|
+
Traceback (most recent call last):
|
1293
|
+
...
|
1294
|
+
ValueError: constant term is zero
|
1295
|
+
sage: ZZ['x'](2).inverse_series_trunc(4)
|
1296
|
+
Traceback (most recent call last):
|
1297
|
+
...
|
1298
|
+
ValueError: constant term 2 is not a unit
|
1299
|
+
sage: x = polygen(ZZ)
|
1300
|
+
sage: (x+1).inverse_series_trunc(0)
|
1301
|
+
Traceback (most recent call last):
|
1302
|
+
...
|
1303
|
+
ValueError: the precision must be positive, got 0
|
1304
|
+
"""
|
1305
|
+
if prec <= 0:
|
1306
|
+
raise ValueError("the precision must be positive, got {}".format(prec))
|
1307
|
+
|
1308
|
+
if fmpz_poly_degree(self._poly) == -1:
|
1309
|
+
raise ValueError("constant term is zero")
|
1310
|
+
cdef fmpz_t c = fmpz_poly_get_coeff_ptr(self._poly, 0)
|
1311
|
+
if fmpz_cmp_si(c, 1) and fmpz_cmp_si(c, -1):
|
1312
|
+
raise ValueError("constant term {} is not a unit".format(self[0]))
|
1313
|
+
|
1314
|
+
cdef Polynomial_integer_dense_flint res = self._new()
|
1315
|
+
if prec <= 0:
|
1316
|
+
return res
|
1317
|
+
sig_on()
|
1318
|
+
fmpz_poly_inv_series(res._poly, self._poly, prec)
|
1319
|
+
sig_off()
|
1320
|
+
return res
|
1321
|
+
|
1322
|
+
cpdef _unsafe_mutate(self, long n, value):
|
1323
|
+
r"""
|
1324
|
+
Set coefficient of `x^n` to value.
|
1325
|
+
|
1326
|
+
This is very unsafe, because Sage polynomials are supposed to be
|
1327
|
+
immutable.
|
1328
|
+
|
1329
|
+
EXAMPLES::
|
1330
|
+
|
1331
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1332
|
+
sage: f = 2*x^2 + 3; f
|
1333
|
+
2*x^2 + 3
|
1334
|
+
sage: f._unsafe_mutate(1, 42); f
|
1335
|
+
2*x^2 + 42*x + 3
|
1336
|
+
|
1337
|
+
sage: f._unsafe_mutate(1, int(5)); f
|
1338
|
+
2*x^2 + 5*x + 3
|
1339
|
+
sage: f._unsafe_mutate(1, Zmod(15)(7)); f
|
1340
|
+
2*x^2 + 7*x + 3
|
1341
|
+
"""
|
1342
|
+
if n < 0:
|
1343
|
+
raise IndexError("n must be >= 0")
|
1344
|
+
if isinstance(value, int):
|
1345
|
+
sig_on()
|
1346
|
+
fmpz_poly_set_coeff_si(self._poly, n, value)
|
1347
|
+
sig_off()
|
1348
|
+
elif isinstance(value, Integer):
|
1349
|
+
sig_on()
|
1350
|
+
fmpz_poly_set_coeff_mpz(self._poly, n, (<Integer>value).value)
|
1351
|
+
sig_off()
|
1352
|
+
else:
|
1353
|
+
value = Integer(value)
|
1354
|
+
sig_on()
|
1355
|
+
fmpz_poly_set_coeff_mpz(self._poly, n, (<Integer>value).value)
|
1356
|
+
sig_off()
|
1357
|
+
|
1358
|
+
def real_root_intervals(self):
|
1359
|
+
"""
|
1360
|
+
Return isolating intervals for the real roots of this
|
1361
|
+
polynomial.
|
1362
|
+
|
1363
|
+
EXAMPLES:
|
1364
|
+
We compute the roots of the characteristic polynomial of some
|
1365
|
+
Salem numbers::
|
1366
|
+
|
1367
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1368
|
+
sage: f = 1 - x^2 - x^3 - x^4 + x^6
|
1369
|
+
sage: f.real_root_intervals() # needs sage.libs.linbox
|
1370
|
+
[((1/2, 3/4), 1), ((1, 3/2), 1)]
|
1371
|
+
"""
|
1372
|
+
|
1373
|
+
from sage.rings.polynomial.real_roots import real_roots
|
1374
|
+
|
1375
|
+
return real_roots(self)
|
1376
|
+
|
1377
|
+
# def __copy__(self):
|
1378
|
+
# f = Polynomial_integer_dense(self.parent())
|
1379
|
+
# f._poly = self._poly.copy()
|
1380
|
+
# return f
|
1381
|
+
|
1382
|
+
def degree(self, gen=None):
|
1383
|
+
"""
|
1384
|
+
Return the degree of this polynomial.
|
1385
|
+
|
1386
|
+
The zero polynomial has degree `-1`.
|
1387
|
+
|
1388
|
+
EXAMPLES::
|
1389
|
+
|
1390
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1391
|
+
sage: x.degree()
|
1392
|
+
1
|
1393
|
+
sage: (x^2).degree()
|
1394
|
+
2
|
1395
|
+
sage: R(1).degree()
|
1396
|
+
0
|
1397
|
+
sage: R(0).degree()
|
1398
|
+
-1
|
1399
|
+
|
1400
|
+
TESTS::
|
1401
|
+
|
1402
|
+
sage: type(x.degree())
|
1403
|
+
<class 'sage.rings.integer.Integer'>
|
1404
|
+
"""
|
1405
|
+
return smallInteger(fmpz_poly_degree(self._poly))
|
1406
|
+
|
1407
|
+
def pseudo_divrem(self, B):
|
1408
|
+
r"""
|
1409
|
+
Write ``A = self``. This function computes polynomials `Q` and `R`
|
1410
|
+
and an integer `d` such that
|
1411
|
+
|
1412
|
+
.. MATH::
|
1413
|
+
|
1414
|
+
\mathop{\mathrm{lead}}(B)^d A = B Q + R
|
1415
|
+
|
1416
|
+
where R has degree less than that of B.
|
1417
|
+
|
1418
|
+
INPUT:
|
1419
|
+
|
1420
|
+
- ``B`` -- a polynomial over `\ZZ`
|
1421
|
+
|
1422
|
+
OUTPUT:
|
1423
|
+
|
1424
|
+
- ``Q``, ``R`` -- polynomials
|
1425
|
+
- ``d`` -- nonnegative integer
|
1426
|
+
|
1427
|
+
EXAMPLES::
|
1428
|
+
|
1429
|
+
sage: R.<x> = ZZ['x']
|
1430
|
+
sage: A = R(range(10))
|
1431
|
+
sage: B = 3*R([-1, 0, 1])
|
1432
|
+
sage: Q, R, d = A.pseudo_divrem(B)
|
1433
|
+
sage: Q, R, d
|
1434
|
+
(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 75*x + 60, 1)
|
1435
|
+
sage: B.leading_coefficient()^d * A == B*Q + R
|
1436
|
+
True
|
1437
|
+
"""
|
1438
|
+
cdef Polynomial_integer_dense_flint Q = self._new(), R = self._new(), _B = B
|
1439
|
+
cdef ulong d
|
1440
|
+
fmpz_poly_pseudo_divrem(Q._poly, R._poly, &d, self._poly, _B._poly)
|
1441
|
+
return Q, R, Integer(d)
|
1442
|
+
|
1443
|
+
def discriminant(self, proof=True):
|
1444
|
+
r"""
|
1445
|
+
Return the discriminant of ``self``, which is by definition
|
1446
|
+
|
1447
|
+
.. MATH::
|
1448
|
+
|
1449
|
+
(-1)^{m(m-1)/2} \mathop{\mathrm{resultant}}(a, a')/\mathop{\mathrm{lc}}(a),
|
1450
|
+
|
1451
|
+
where `m = \mathop{\mathrm{deg}}(a)`, and `\mathop{\mathrm{lc}}(a)` is
|
1452
|
+
the leading coefficient of a. If ``proof`` is False (the default is
|
1453
|
+
True), then this function may use a randomized strategy that errors
|
1454
|
+
with probability no more than `2^{-80}`.
|
1455
|
+
|
1456
|
+
EXAMPLES::
|
1457
|
+
|
1458
|
+
sage: R.<x> = ZZ[]
|
1459
|
+
sage: f = 3*x^3 + 2*x + 1
|
1460
|
+
sage: f.discriminant()
|
1461
|
+
-339
|
1462
|
+
sage: f.discriminant(proof=False)
|
1463
|
+
-339
|
1464
|
+
|
1465
|
+
TESTS:
|
1466
|
+
|
1467
|
+
Confirm that :issue:`17603` has been applied::
|
1468
|
+
|
1469
|
+
sage: f.disc()
|
1470
|
+
-339
|
1471
|
+
"""
|
1472
|
+
cdef ZZX_c ntl_poly
|
1473
|
+
cdef ZZ_c* temp
|
1474
|
+
fmpz_poly_get_ZZX(ntl_poly, self._poly)
|
1475
|
+
|
1476
|
+
temp = ZZX_discriminant(&ntl_poly, proof)
|
1477
|
+
cdef Integer x = Integer.__new__(Integer)
|
1478
|
+
ZZ_to_mpz(x.value, temp)
|
1479
|
+
del temp
|
1480
|
+
|
1481
|
+
return x
|
1482
|
+
|
1483
|
+
# Alias for discriminant
|
1484
|
+
disc = discriminant
|
1485
|
+
|
1486
|
+
def __pari__(self, variable=None):
|
1487
|
+
"""
|
1488
|
+
EXAMPLES::
|
1489
|
+
|
1490
|
+
sage: t = PolynomialRing(ZZ,"t").gen()
|
1491
|
+
sage: f = t^3 + 3*t - 17
|
1492
|
+
sage: pari(f) # needs sage.libs.pari
|
1493
|
+
t^3 + 3*t - 17
|
1494
|
+
sage: f.__pari__(variable='y') # needs sage.libs.pari
|
1495
|
+
y^3 + 3*y - 17
|
1496
|
+
"""
|
1497
|
+
if variable is None:
|
1498
|
+
variable = self.parent().variable_name()
|
1499
|
+
return pari(self.list()).Polrev(variable)
|
1500
|
+
|
1501
|
+
def squarefree_decomposition(Polynomial_integer_dense_flint self):
|
1502
|
+
"""
|
1503
|
+
Return the square-free decomposition of ``self``. This is
|
1504
|
+
a partial factorization of ``self`` into square-free, relatively
|
1505
|
+
prime polynomials.
|
1506
|
+
|
1507
|
+
This is a wrapper for the NTL function ``SquareFreeDecomp``.
|
1508
|
+
|
1509
|
+
EXAMPLES::
|
1510
|
+
|
1511
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1512
|
+
sage: p = (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
|
1513
|
+
sage: p.squarefree_decomposition()
|
1514
|
+
(x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
|
1515
|
+
sage: p = 37 * (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
|
1516
|
+
sage: p.squarefree_decomposition()
|
1517
|
+
(37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
|
1518
|
+
|
1519
|
+
TESTS:
|
1520
|
+
|
1521
|
+
Verify that :issue:`13053` has been resolved::
|
1522
|
+
|
1523
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='FLINT')
|
1524
|
+
sage: f=-x^2
|
1525
|
+
sage: f.squarefree_decomposition()
|
1526
|
+
(-1) * x^2
|
1527
|
+
"""
|
1528
|
+
cdef ZZX_c** v
|
1529
|
+
cdef long* e
|
1530
|
+
cdef long i, n
|
1531
|
+
cdef fmpz_poly_t ppart
|
1532
|
+
cdef ZZX_c ntl_poly
|
1533
|
+
cdef Integer z
|
1534
|
+
cdef Polynomial_integer_dense_flint fac
|
1535
|
+
|
1536
|
+
# the sign of the content is the sign of the leading coefficient
|
1537
|
+
z = self.content()
|
1538
|
+
if not z.is_one():
|
1539
|
+
fmpz_poly_init(ppart)
|
1540
|
+
|
1541
|
+
# the primitive part returned by FLINT has positive leading
|
1542
|
+
# coefficient
|
1543
|
+
fmpz_poly_primitive_part(ppart, self._poly)
|
1544
|
+
|
1545
|
+
fmpz_poly_get_ZZX(ntl_poly, ppart)
|
1546
|
+
fmpz_poly_clear(ppart)
|
1547
|
+
else:
|
1548
|
+
fmpz_poly_get_ZZX(ntl_poly, self._poly)
|
1549
|
+
|
1550
|
+
# input is primitive, with positive leading coefficient
|
1551
|
+
ZZX_squarefree_decomposition(&v, &e, &n, &ntl_poly)
|
1552
|
+
|
1553
|
+
F = []
|
1554
|
+
for i from 0 <= i < n:
|
1555
|
+
fac = self._new()
|
1556
|
+
fmpz_poly_set_ZZX(fac._poly, v[i][0])
|
1557
|
+
F.append( (fac,e[i]) )
|
1558
|
+
del v[i]
|
1559
|
+
sig_free(v)
|
1560
|
+
sig_free(e)
|
1561
|
+
|
1562
|
+
return Factorization(F, unit=z, sort=False)
|
1563
|
+
|
1564
|
+
def _factor_pari(self):
|
1565
|
+
"""
|
1566
|
+
EXAMPLES::
|
1567
|
+
|
1568
|
+
sage: R.<x> = ZZ[]
|
1569
|
+
sage: f = (x^2-2)*(x^5-3)^2
|
1570
|
+
sage: f._factor_pari() # needs sage.libs.pari
|
1571
|
+
(x^2 - 2) * (x^5 - 3)^2
|
1572
|
+
sage: (1234567898765432123456789876543212345678987*f)._factor_pari() # needs sage.libs.pari
|
1573
|
+
1234567898765432123456789876543212345678987 * (x^2 - 2) * (x^5 - 3)^2
|
1574
|
+
"""
|
1575
|
+
return Polynomial.factor(self) # uses pari for integers over ZZ
|
1576
|
+
|
1577
|
+
def _factor_ntl(self):
|
1578
|
+
"""
|
1579
|
+
EXAMPLES::
|
1580
|
+
|
1581
|
+
sage: R.<x> = ZZ[]
|
1582
|
+
sage: f = (x^2-2)*(x^5-3)^2
|
1583
|
+
sage: f._factor_ntl()
|
1584
|
+
(x^2 - 2) * (x^5 - 3)^2
|
1585
|
+
sage: (12345678987654321234567898765432123456789876*f)._factor_ntl()
|
1586
|
+
12345678987654321234567898765432123456789876 * (x^2 - 2) * (x^5 - 3)^2
|
1587
|
+
"""
|
1588
|
+
cdef Polynomial_integer_dense_flint fac_py
|
1589
|
+
cdef fmpz_t tcontent
|
1590
|
+
cdef ZZX_c ntl_poly
|
1591
|
+
cdef ZZ_c content
|
1592
|
+
cdef vec_pair_ZZX_long_c factors
|
1593
|
+
cdef long i
|
1594
|
+
cdef int sig_me = fmpz_poly_degree(self._poly)
|
1595
|
+
|
1596
|
+
fmpz_poly_get_ZZX(ntl_poly, self._poly)
|
1597
|
+
|
1598
|
+
if sig_me > 10:
|
1599
|
+
sig_on()
|
1600
|
+
ZZX_factor(content, factors, ntl_poly, 0, 0)
|
1601
|
+
if sig_me > 10:
|
1602
|
+
sig_off()
|
1603
|
+
|
1604
|
+
results = []
|
1605
|
+
unit = None
|
1606
|
+
|
1607
|
+
if ZZ_sign(content) < 0:
|
1608
|
+
unit = Integer(-1)
|
1609
|
+
ZZ_abs(content, content)
|
1610
|
+
|
1611
|
+
if not ZZ_IsOne(content):
|
1612
|
+
fac_py = self._new()
|
1613
|
+
fmpz_init(tcontent)
|
1614
|
+
fmpz_set_ZZ(tcontent, content)
|
1615
|
+
fmpz_poly_set_coeff_fmpz(fac_py._poly, 0, tcontent)
|
1616
|
+
results.append( (fac_py,1) )
|
1617
|
+
fmpz_clear(tcontent)
|
1618
|
+
|
1619
|
+
for i from 0 <= i < factors.length():
|
1620
|
+
fac_py = self._new()
|
1621
|
+
fmpz_poly_set_ZZX(fac_py._poly, factors.RawGet(i).a)
|
1622
|
+
results.append( (fac_py,factors.RawGet(i).b) )
|
1623
|
+
return Factorization(results, unit = unit)
|
1624
|
+
|
1625
|
+
def factor(self):
|
1626
|
+
"""
|
1627
|
+
This function overrides the generic polynomial factorization to
|
1628
|
+
make a somewhat intelligent decision to use PARI or NTL based on
|
1629
|
+
some benchmarking.
|
1630
|
+
|
1631
|
+
Note: This function factors the content of the polynomial,
|
1632
|
+
which can take very long if it's a really big integer. If you
|
1633
|
+
do not need the content factored, divide it out of your
|
1634
|
+
polynomial before calling this function.
|
1635
|
+
|
1636
|
+
EXAMPLES::
|
1637
|
+
|
1638
|
+
sage: R.<x> = ZZ[]
|
1639
|
+
sage: f = x^4 - 1
|
1640
|
+
sage: f.factor()
|
1641
|
+
(x - 1) * (x + 1) * (x^2 + 1)
|
1642
|
+
sage: f = 1 - x
|
1643
|
+
sage: f.factor()
|
1644
|
+
(-1) * (x - 1)
|
1645
|
+
sage: f.factor().unit()
|
1646
|
+
-1
|
1647
|
+
sage: f = -30*x; f.factor()
|
1648
|
+
(-1) * 2 * 3 * 5 * x
|
1649
|
+
"""
|
1650
|
+
cdef long deg = fmpz_poly_degree(self._poly)
|
1651
|
+
# it appears that pari has a window from about degrees 30 and 300
|
1652
|
+
# in which it beats NTL.
|
1653
|
+
c = self.content()
|
1654
|
+
g = self // c
|
1655
|
+
if deg < 30 or deg > 300:
|
1656
|
+
return c.factor() * g._factor_ntl()
|
1657
|
+
else:
|
1658
|
+
return c.factor() * g._factor_pari()
|
1659
|
+
|
1660
|
+
def factor_mod(self, p):
|
1661
|
+
"""
|
1662
|
+
Return the factorization of ``self`` modulo the prime `p`.
|
1663
|
+
|
1664
|
+
INPUT:
|
1665
|
+
|
1666
|
+
- ``p`` -- prime
|
1667
|
+
|
1668
|
+
OUTPUT: factorization of ``self`` reduced modulo `p`
|
1669
|
+
|
1670
|
+
EXAMPLES::
|
1671
|
+
|
1672
|
+
sage: # needs sage.libs.pari
|
1673
|
+
sage: R.<x> = ZZ['x']
|
1674
|
+
sage: f = -3*x*(x-2)*(x-9) + x
|
1675
|
+
sage: f.factor_mod(3)
|
1676
|
+
x
|
1677
|
+
sage: f = -3 * x * (x - 2) * (x - 9)
|
1678
|
+
sage: f.factor_mod(3)
|
1679
|
+
Traceback (most recent call last):
|
1680
|
+
...
|
1681
|
+
ArithmeticError: factorization of 0 is not defined
|
1682
|
+
sage: f = 2 * x * (x - 2) * (x - 9)
|
1683
|
+
sage: f.factor_mod(7)
|
1684
|
+
(2) * x * (x + 5)^2
|
1685
|
+
"""
|
1686
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField
|
1687
|
+
p = Integer(p)
|
1688
|
+
if not p.is_prime():
|
1689
|
+
raise ValueError("p must be prime")
|
1690
|
+
if not any(c % p for c in self.coefficients()):
|
1691
|
+
raise ArithmeticError("factorization of 0 is not defined")
|
1692
|
+
f = self.__pari__()
|
1693
|
+
G = f.factormod(p)
|
1694
|
+
k = FiniteField(p)
|
1695
|
+
R = k[self.parent().variable_name()]
|
1696
|
+
return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient())
|
1697
|
+
|
1698
|
+
def factor_padic(self, p, prec=10):
|
1699
|
+
"""
|
1700
|
+
Return `p`-adic factorization of ``self`` to given precision.
|
1701
|
+
|
1702
|
+
INPUT:
|
1703
|
+
|
1704
|
+
- ``p`` -- prime
|
1705
|
+
|
1706
|
+
- ``prec`` -- integer; the precision
|
1707
|
+
|
1708
|
+
OUTPUT: factorization of ``self`` over the completion at `p`
|
1709
|
+
|
1710
|
+
EXAMPLES::
|
1711
|
+
|
1712
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
1713
|
+
sage: f = x^2 + 1
|
1714
|
+
sage: f.factor_padic(5, 4) # needs sage.rings.padics
|
1715
|
+
((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))
|
1716
|
+
* ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))
|
1717
|
+
|
1718
|
+
A more difficult example::
|
1719
|
+
|
1720
|
+
sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
|
1721
|
+
sage: f.factor_padic(5, 10) # needs sage.rings.padics
|
1722
|
+
(4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2
|
1723
|
+
* ((5 + O(5^10))*x + 1 + O(5^10))^2
|
1724
|
+
"""
|
1725
|
+
from sage.rings.padics.factory import Zp
|
1726
|
+
|
1727
|
+
p = Integer(p)
|
1728
|
+
prec = Integer(prec)
|
1729
|
+
|
1730
|
+
# Parent field for coefficients and polynomial
|
1731
|
+
K = Zp(p, prec, type='capped-rel')
|
1732
|
+
R = K[self.parent().variable_name()]
|
1733
|
+
|
1734
|
+
# Factor the *exact* polynomial using factorpadic()
|
1735
|
+
G = self._pari_with_name().factorpadic(p, prec)
|
1736
|
+
|
1737
|
+
from sage.rings.polynomial.padics.polynomial_padic import _pari_padic_factorization_to_sage
|
1738
|
+
return _pari_padic_factorization_to_sage(G, R, self.leading_coefficient())
|
1739
|
+
|
1740
|
+
cpdef list list(self, bint copy=True):
|
1741
|
+
"""
|
1742
|
+
Return a new copy of the list of the underlying
|
1743
|
+
elements of ``self``.
|
1744
|
+
|
1745
|
+
EXAMPLES::
|
1746
|
+
|
1747
|
+
sage: x = PolynomialRing(ZZ,'x').0
|
1748
|
+
sage: f = x^3 + 3*x - 17
|
1749
|
+
sage: f.list()
|
1750
|
+
[-17, 3, 0, 1]
|
1751
|
+
sage: f = PolynomialRing(ZZ,'x')(0)
|
1752
|
+
sage: f.list()
|
1753
|
+
[]
|
1754
|
+
"""
|
1755
|
+
return [self.get_unsafe(i) for i in range(self.degree()+1)]
|
1756
|
+
|
1757
|
+
@coerce_binop
|
1758
|
+
def resultant(self, other, proof=True):
|
1759
|
+
"""
|
1760
|
+
Return the resultant of ``self`` and ``other``, which must lie in the same
|
1761
|
+
polynomial ring.
|
1762
|
+
|
1763
|
+
If ``proof=False`` (the default is ``proof=True``), then this function may
|
1764
|
+
use a randomized strategy that errors with probability no more than
|
1765
|
+
`2^{-80}`.
|
1766
|
+
|
1767
|
+
INPUT:
|
1768
|
+
|
1769
|
+
- ``other`` -- a polynomial
|
1770
|
+
|
1771
|
+
OUTPUT: an element of the base ring of the polynomial ring
|
1772
|
+
|
1773
|
+
EXAMPLES::
|
1774
|
+
|
1775
|
+
sage: x = PolynomialRing(ZZ,'x').0
|
1776
|
+
sage: f = x^3 + x + 1; g = x^3 - x - 1
|
1777
|
+
sage: r = f.resultant(g); r
|
1778
|
+
-8
|
1779
|
+
sage: r.parent() is ZZ
|
1780
|
+
True
|
1781
|
+
"""
|
1782
|
+
if not isinstance(other, Polynomial_integer_dense_flint):
|
1783
|
+
other = self.parent()(other)
|
1784
|
+
elif self.parent() is not other.parent():
|
1785
|
+
raise TypeError
|
1786
|
+
|
1787
|
+
cdef fmpz_t res
|
1788
|
+
fmpz_init(res)
|
1789
|
+
cdef Integer x = Integer.__new__(Integer)
|
1790
|
+
|
1791
|
+
sig_on()
|
1792
|
+
fmpz_poly_resultant(res, self._poly,
|
1793
|
+
(<Polynomial_integer_dense_flint>other)._poly)
|
1794
|
+
sig_off()
|
1795
|
+
fmpz_get_mpz(x.value, res)
|
1796
|
+
fmpz_clear(res)
|
1797
|
+
return x
|
1798
|
+
|
1799
|
+
def reverse(self, degree=None):
|
1800
|
+
"""
|
1801
|
+
Return a polynomial with the coefficients of this polynomial reversed.
|
1802
|
+
|
1803
|
+
If an optional degree argument is given the coefficient list will be
|
1804
|
+
truncated or zero padded as necessary before computing the reverse.
|
1805
|
+
|
1806
|
+
EXAMPLES::
|
1807
|
+
|
1808
|
+
sage: R.<x> = ZZ[]
|
1809
|
+
sage: p = R([1,2,3,4]); p
|
1810
|
+
4*x^3 + 3*x^2 + 2*x + 1
|
1811
|
+
sage: p.reverse()
|
1812
|
+
x^3 + 2*x^2 + 3*x + 4
|
1813
|
+
sage: p.reverse(degree=6)
|
1814
|
+
x^6 + 2*x^5 + 3*x^4 + 4*x^3
|
1815
|
+
sage: p.reverse(degree=2)
|
1816
|
+
x^2 + 2*x + 3
|
1817
|
+
|
1818
|
+
TESTS::
|
1819
|
+
|
1820
|
+
sage: p.reverse(degree=1.5r)
|
1821
|
+
Traceback (most recent call last):
|
1822
|
+
...
|
1823
|
+
ValueError: degree argument must be a nonnegative integer, got 1.5
|
1824
|
+
|
1825
|
+
Check that this implementation is compatible with the generic one::
|
1826
|
+
|
1827
|
+
sage: p = R([0,1,0,2])
|
1828
|
+
sage: all(p.reverse(d) == Polynomial.reverse(p, d)
|
1829
|
+
....: for d in [None, 0, 1, 2, 3, 4])
|
1830
|
+
True
|
1831
|
+
"""
|
1832
|
+
cdef Polynomial_integer_dense_flint res = self._new()
|
1833
|
+
cdef unsigned long d
|
1834
|
+
if degree is not None:
|
1835
|
+
if degree < 0:
|
1836
|
+
raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree))
|
1837
|
+
d = degree
|
1838
|
+
if d != degree:
|
1839
|
+
raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree))
|
1840
|
+
# FLINT expects length
|
1841
|
+
fmpz_poly_reverse(res._poly, self._poly, d+1)
|
1842
|
+
else:
|
1843
|
+
fmpz_poly_reverse(res._poly, self._poly,
|
1844
|
+
fmpz_poly_length(self._poly))
|
1845
|
+
return res
|
1846
|
+
|
1847
|
+
def revert_series(self, n):
|
1848
|
+
r"""
|
1849
|
+
Return a polynomial `f` such that `f(` ``self`` `(x)) =` ``self`` `(f(x)) = x` (mod `x^n`).
|
1850
|
+
|
1851
|
+
EXAMPLES::
|
1852
|
+
|
1853
|
+
sage: R.<t> = ZZ[]
|
1854
|
+
sage: f = t - t^3 + t^5
|
1855
|
+
sage: f.revert_series(6)
|
1856
|
+
2*t^5 + t^3 + t
|
1857
|
+
|
1858
|
+
sage: f.revert_series(-1)
|
1859
|
+
Traceback (most recent call last):
|
1860
|
+
...
|
1861
|
+
ValueError: argument n must be a nonnegative integer, got -1
|
1862
|
+
|
1863
|
+
sage: g = - t^3 + t^5
|
1864
|
+
sage: g.revert_series(6)
|
1865
|
+
Traceback (most recent call last):
|
1866
|
+
...
|
1867
|
+
ValueError: self must have constant coefficient 0 and a unit for coefficient t^1
|
1868
|
+
"""
|
1869
|
+
cdef Polynomial_integer_dense_flint res = self._new()
|
1870
|
+
cdef unsigned long m
|
1871
|
+
if n < 0:
|
1872
|
+
raise ValueError("argument n must be a nonnegative integer, got {}".format(n))
|
1873
|
+
m = n
|
1874
|
+
if not self[0].is_zero() or not self[1].is_unit():
|
1875
|
+
raise ValueError("self must have constant coefficient 0 and a unit for coefficient {}^1".format(self.parent().gen()))
|
1876
|
+
|
1877
|
+
sig_on()
|
1878
|
+
fmpz_poly_revert_series(res._poly, self._poly, m)
|
1879
|
+
sig_off()
|
1880
|
+
|
1881
|
+
return res
|