passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- sage/typeset/unicode_characters.py +101 -0
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# sage.doctest: optional - primecountpy
|
|
3
|
+
"""
|
|
4
|
+
Utility classes for multi-modular algorithms
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# ****************************************************************************
|
|
8
|
+
# Copyright (C) 2006 William Stein
|
|
9
|
+
#
|
|
10
|
+
# This program is free software: you can redistribute it and/or modify
|
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
|
12
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
13
|
+
# (at your option) any later version.
|
|
14
|
+
# https://www.gnu.org/licenses/
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
|
|
17
|
+
from cysignals.memory cimport check_allocarray, check_reallocarray, sig_free
|
|
18
|
+
|
|
19
|
+
from sage.libs.gmp.mpz cimport *
|
|
20
|
+
from sage.rings.integer cimport Integer, smallInteger
|
|
21
|
+
from sage.arith.misc import random_prime
|
|
22
|
+
from types import GeneratorType
|
|
23
|
+
from sage.ext.stdsage cimport PY_NEW
|
|
24
|
+
from cpython.object cimport PyObject_RichCompare
|
|
25
|
+
|
|
26
|
+
# should I have mod_int versions of these functions?
|
|
27
|
+
# c_inverse_mod_longlong modular inverse used exactly once in _refresh_precomputations
|
|
28
|
+
from sage.rings.fast_arith cimport arith_llong
|
|
29
|
+
cdef arith_llong ai
|
|
30
|
+
ai = arith_llong()
|
|
31
|
+
|
|
32
|
+
# This is the maximum modulus for the code in this module, i.e. the
|
|
33
|
+
# largest prime that can be used as modulus is
|
|
34
|
+
# previous_prime(MAX_MODULUS)
|
|
35
|
+
MAX_MODULUS = MOD_INT_MAX
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
cdef class MultiModularBasis_base():
|
|
39
|
+
r"""
|
|
40
|
+
This class stores a list of machine-sized prime numbers,
|
|
41
|
+
and can do reduction and Chinese Remainder Theorem lifting
|
|
42
|
+
modulo these primes.
|
|
43
|
+
|
|
44
|
+
Lifting implemented via Garner's algorithm, which has the advantage
|
|
45
|
+
that all reductions are word-sized. For each `i`, precompute
|
|
46
|
+
`\prod_j=1^{i-1} m_j` and `\prod_j=1^{i-1} m_j^{-1} (mod m_i)`.
|
|
47
|
+
|
|
48
|
+
This class can be initialized in two ways, either with a list of prime
|
|
49
|
+
moduli or an upper bound for the product of the prime moduli. The prime
|
|
50
|
+
moduli are generated automatically in the second case.
|
|
51
|
+
|
|
52
|
+
EXAMPLES::
|
|
53
|
+
|
|
54
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
55
|
+
sage: mm = MultiModularBasis_base([3, 5, 7]); mm
|
|
56
|
+
MultiModularBasis with moduli [3, 5, 7]
|
|
57
|
+
|
|
58
|
+
sage: height = 52348798724
|
|
59
|
+
sage: mm = MultiModularBasis_base(height); mm
|
|
60
|
+
MultiModularBasis with moduli [...]
|
|
61
|
+
sage: mm.prod() >= 2*height
|
|
62
|
+
True
|
|
63
|
+
|
|
64
|
+
TESTS::
|
|
65
|
+
|
|
66
|
+
sage: mm = MultiModularBasis_base((3,5,7)); mm
|
|
67
|
+
MultiModularBasis with moduli [3, 5, 7]
|
|
68
|
+
sage: mm = MultiModularBasis_base(primes(10,20)); mm
|
|
69
|
+
MultiModularBasis with moduli [11, 13, 17, 19]
|
|
70
|
+
|
|
71
|
+
There is no overflow if the modulus is below ``MAX_MODULUS``::
|
|
72
|
+
|
|
73
|
+
sage: from sage.arith.multi_modular import MAX_MODULUS
|
|
74
|
+
sage: p0 = previous_prime(MAX_MODULUS)
|
|
75
|
+
sage: p1 = previous_prime(p0)
|
|
76
|
+
sage: MultiModularBasis_base([p0, p1]).crt([p0-1, p1-1])
|
|
77
|
+
-1
|
|
78
|
+
|
|
79
|
+
If we add another bit to the prime length then there is an
|
|
80
|
+
overflow, as expected::
|
|
81
|
+
|
|
82
|
+
sage: p0 = previous_prime(2*MAX_MODULUS)
|
|
83
|
+
sage: p1 = previous_prime(p0)
|
|
84
|
+
sage: MultiModularBasis_base([p0, p1]).crt([p0-1, p1-1])
|
|
85
|
+
Traceback (most recent call last):
|
|
86
|
+
...
|
|
87
|
+
OverflowError: given modulus 6074000981 is larger than 3037000498
|
|
88
|
+
"""
|
|
89
|
+
def __cinit__(self):
|
|
90
|
+
r"""
|
|
91
|
+
Allocate the space for the moduli and precomputation lists
|
|
92
|
+
and initialize the first element of that list.
|
|
93
|
+
|
|
94
|
+
EXAMPLES::
|
|
95
|
+
|
|
96
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
97
|
+
sage: mm = MultiModularBasis_base([1099511627791])
|
|
98
|
+
Traceback (most recent call last):
|
|
99
|
+
...
|
|
100
|
+
OverflowError: given modulus 1099511627791 is larger than 3037000498
|
|
101
|
+
"""
|
|
102
|
+
mpz_init(self.product)
|
|
103
|
+
mpz_init(self.half_product)
|
|
104
|
+
|
|
105
|
+
cdef _realloc_to_new_count(self, new_count):
|
|
106
|
+
self.moduli = <mod_int*>check_reallocarray(self.moduli, new_count, sizeof(mod_int))
|
|
107
|
+
self.partial_products = <mpz_t*>check_reallocarray(self.partial_products, new_count, sizeof(mpz_t))
|
|
108
|
+
self.C = <mod_int*>check_reallocarray(self.C, new_count, sizeof(mod_int))
|
|
109
|
+
|
|
110
|
+
def __dealloc__(self):
|
|
111
|
+
"""
|
|
112
|
+
TESTS::
|
|
113
|
+
|
|
114
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
115
|
+
sage: mm = MultiModularBasis_base(1099511627791); mm
|
|
116
|
+
MultiModularBasis with moduli [...]
|
|
117
|
+
sage: del mm
|
|
118
|
+
"""
|
|
119
|
+
sig_free(self.moduli)
|
|
120
|
+
for i in range(self.n):
|
|
121
|
+
mpz_clear(self.partial_products[i])
|
|
122
|
+
sig_free(self.partial_products)
|
|
123
|
+
sig_free(self.C)
|
|
124
|
+
mpz_clear(self.product)
|
|
125
|
+
mpz_clear(self.half_product)
|
|
126
|
+
|
|
127
|
+
def __init__(self, val, unsigned long l_bound=2**10, unsigned long u_bound=2**15):
|
|
128
|
+
r"""
|
|
129
|
+
Initialize a multi-modular basis and perform precomputations.
|
|
130
|
+
|
|
131
|
+
INPUT:
|
|
132
|
+
|
|
133
|
+
- ``val`` -- as integer
|
|
134
|
+
determines how many primes are computed
|
|
135
|
+
(their product will be at least 2*val)
|
|
136
|
+
as list, tuple or generator
|
|
137
|
+
a list of prime moduli to start with
|
|
138
|
+
- ``l_bound`` -- integer (default: 2^10); lower bound for the random primes
|
|
139
|
+
- ``u_bound`` -- integer (default: 2^15); upper bound for the random primes
|
|
140
|
+
|
|
141
|
+
EXAMPLES::
|
|
142
|
+
|
|
143
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
144
|
+
sage: mm = MultiModularBasis_base([1009, 10007]); mm
|
|
145
|
+
MultiModularBasis with moduli [1009, 10007]
|
|
146
|
+
sage: mm.prod()
|
|
147
|
+
10097063
|
|
148
|
+
|
|
149
|
+
sage: height = 10097063
|
|
150
|
+
sage: mm = MultiModularBasis_base(height); mm
|
|
151
|
+
MultiModularBasis with moduli [...]
|
|
152
|
+
|
|
153
|
+
sage: mm.prod()//height >= 2
|
|
154
|
+
True
|
|
155
|
+
|
|
156
|
+
sage: mm = MultiModularBasis_base([1000000000000000000000000000057])
|
|
157
|
+
Traceback (most recent call last):
|
|
158
|
+
...
|
|
159
|
+
OverflowError: given modulus 1000000000000000000000000000057 is larger than 3037000498
|
|
160
|
+
|
|
161
|
+
sage: mm = MultiModularBasis_base(0); mm
|
|
162
|
+
MultiModularBasis with moduli [...]
|
|
163
|
+
|
|
164
|
+
sage: mm = MultiModularBasis_base([6, 10])
|
|
165
|
+
Traceback (most recent call last):
|
|
166
|
+
...
|
|
167
|
+
ArithmeticError: The inverse of 6 modulo 10 is not defined.
|
|
168
|
+
"""
|
|
169
|
+
if l_bound < 2:
|
|
170
|
+
raise ValueError(f"minimum value for lower bound is 2, given: {l_bound}")
|
|
171
|
+
if u_bound > MAX_MODULUS:
|
|
172
|
+
raise ValueError(f"upper bound cannot be greater than {MAX_MODULUS}, given: {u_bound}")
|
|
173
|
+
|
|
174
|
+
self._l_bound = l_bound
|
|
175
|
+
self._u_bound = u_bound
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
from primecountpy.primecount import prime_pi
|
|
179
|
+
except ImportError:
|
|
180
|
+
self._num_primes = (self._u_bound - self._l_bound + 1) // 2
|
|
181
|
+
else:
|
|
182
|
+
self._num_primes = prime_pi(self._u_bound) - prime_pi(self._l_bound-1)
|
|
183
|
+
|
|
184
|
+
if isinstance(val, (list, tuple, GeneratorType)):
|
|
185
|
+
self.extend_with_primes(val, check=True)
|
|
186
|
+
else:
|
|
187
|
+
self._extend_moduli_to_height(val)
|
|
188
|
+
|
|
189
|
+
cdef mod_int _new_random_prime(self, set known_primes) except 1:
|
|
190
|
+
"""
|
|
191
|
+
Choose a new random prime for inclusion in the list of moduli,
|
|
192
|
+
or raise a :exc:`RuntimeError` if there are no more primes.
|
|
193
|
+
|
|
194
|
+
INPUT:
|
|
195
|
+
|
|
196
|
+
- ``known_primes`` -- Python set of already known primes in
|
|
197
|
+
the allowed interval; we will not return a prime in
|
|
198
|
+
known_primes
|
|
199
|
+
"""
|
|
200
|
+
cdef mod_int p
|
|
201
|
+
while True:
|
|
202
|
+
if len(known_primes) >= self._num_primes:
|
|
203
|
+
raise RuntimeError("there are not enough primes in the interval [%s, %s] to complete this multimodular computation" % (self._l_bound, self._u_bound))
|
|
204
|
+
p = random_prime(self._u_bound, lbound=self._l_bound)
|
|
205
|
+
if p not in known_primes:
|
|
206
|
+
return p
|
|
207
|
+
|
|
208
|
+
def extend_with_primes(self, plist, partial_products=None, check=True):
|
|
209
|
+
"""
|
|
210
|
+
Extend the stored list of moduli with the given primes in ``plist``.
|
|
211
|
+
|
|
212
|
+
EXAMPLES::
|
|
213
|
+
|
|
214
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
215
|
+
sage: mm = MultiModularBasis_base([1009, 10007]); mm
|
|
216
|
+
MultiModularBasis with moduli [1009, 10007]
|
|
217
|
+
sage: mm.extend_with_primes([10037, 10039])
|
|
218
|
+
4
|
|
219
|
+
sage: mm
|
|
220
|
+
MultiModularBasis with moduli [1009, 10007, 10037, 10039]
|
|
221
|
+
"""
|
|
222
|
+
if isinstance(plist, GeneratorType):
|
|
223
|
+
plist = list(plist)
|
|
224
|
+
elif not isinstance(plist, (tuple, list)):
|
|
225
|
+
raise TypeError("plist should be a list, tuple or a generator, got: %s" % (str(type(plist))))
|
|
226
|
+
|
|
227
|
+
cdef Py_ssize_t len_plist = len(plist)
|
|
228
|
+
|
|
229
|
+
if len_plist == 0:
|
|
230
|
+
return self.n
|
|
231
|
+
if check:
|
|
232
|
+
for p in plist:
|
|
233
|
+
if p > MAX_MODULUS:
|
|
234
|
+
raise OverflowError(f"given modulus {p} is larger than {MAX_MODULUS}")
|
|
235
|
+
self._realloc_to_new_count(self.n + len_plist)
|
|
236
|
+
|
|
237
|
+
cdef Py_ssize_t i
|
|
238
|
+
for i in range(len_plist):
|
|
239
|
+
self.moduli[self.n+i] = plist[i]
|
|
240
|
+
mpz_init(self.partial_products[self.n + i])
|
|
241
|
+
if partial_products:
|
|
242
|
+
mpz_set(self.partial_products[self.n + i],
|
|
243
|
+
(<Integer>partial_products[i]).value)
|
|
244
|
+
|
|
245
|
+
cdef int old_count = self.n
|
|
246
|
+
self.n += len_plist
|
|
247
|
+
if not partial_products:
|
|
248
|
+
self._refresh_products(old_count)
|
|
249
|
+
else:
|
|
250
|
+
self._refresh_prod()
|
|
251
|
+
self._refresh_precomputations(old_count)
|
|
252
|
+
return self.n
|
|
253
|
+
|
|
254
|
+
def __richcmp__(self, other, int op):
|
|
255
|
+
"""
|
|
256
|
+
EXAMPLES::
|
|
257
|
+
|
|
258
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
259
|
+
sage: mm = MultiModularBasis_base([10007])
|
|
260
|
+
sage: nn = MultiModularBasis_base([10007])
|
|
261
|
+
sage: mm == nn
|
|
262
|
+
True
|
|
263
|
+
"""
|
|
264
|
+
if not isinstance(other, MultiModularBasis_base):
|
|
265
|
+
return NotImplemented
|
|
266
|
+
left = self.__getstate__()
|
|
267
|
+
right = other.__getstate__()
|
|
268
|
+
return PyObject_RichCompare(left, right, op)
|
|
269
|
+
|
|
270
|
+
def __setstate__(self, state):
|
|
271
|
+
"""
|
|
272
|
+
Initialize a new :class:`MultiModularBasis_base` object from a
|
|
273
|
+
state stored in a pickle.
|
|
274
|
+
|
|
275
|
+
TESTS::
|
|
276
|
+
|
|
277
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
278
|
+
sage: mm = MultiModularBasis_base([10007, 10009])
|
|
279
|
+
sage: mm == loads(dumps(mm))
|
|
280
|
+
True
|
|
281
|
+
|
|
282
|
+
sage: mm = MultiModularBasis_base([])
|
|
283
|
+
sage: mm.__setstate__(([10007, 10009], 2^10, 2^15))
|
|
284
|
+
|
|
285
|
+
sage: mm
|
|
286
|
+
MultiModularBasis with moduli [10007, 10009]
|
|
287
|
+
"""
|
|
288
|
+
nmoduli, lbound, ubound = state
|
|
289
|
+
self._realloc_to_new_count(len(nmoduli))
|
|
290
|
+
self._l_bound = lbound
|
|
291
|
+
self._u_bound = ubound
|
|
292
|
+
self.extend_with_primes(nmoduli, check=False)
|
|
293
|
+
|
|
294
|
+
def __getstate__(self):
|
|
295
|
+
"""
|
|
296
|
+
Return a tuple describing the state of this object for pickling.
|
|
297
|
+
|
|
298
|
+
TESTS::
|
|
299
|
+
|
|
300
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
301
|
+
sage: mm = MultiModularBasis_base([10007, 10009])
|
|
302
|
+
sage: mm.__getstate__()
|
|
303
|
+
([10007, 10009], 1024, 32768)
|
|
304
|
+
"""
|
|
305
|
+
return (self.list(), self._l_bound, self._u_bound)
|
|
306
|
+
|
|
307
|
+
def _extend_moduli_to_height(self, height):
|
|
308
|
+
"""
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
312
|
+
sage: mm = MultiModularBasis_base(0); mm
|
|
313
|
+
MultiModularBasis with moduli [...]
|
|
314
|
+
sage: p = mm[0]
|
|
315
|
+
|
|
316
|
+
sage: mm._extend_moduli_to_height(70000)
|
|
317
|
+
sage: mm
|
|
318
|
+
MultiModularBasis with moduli [...]
|
|
319
|
+
sage: p == mm[0]
|
|
320
|
+
True
|
|
321
|
+
sage: mm.prod() >= 2*70000
|
|
322
|
+
True
|
|
323
|
+
|
|
324
|
+
sage: mm = MultiModularBasis_base([46307]); mm
|
|
325
|
+
MultiModularBasis with moduli [46307]
|
|
326
|
+
|
|
327
|
+
sage: mm._extend_moduli_to_height(10^30); mm
|
|
328
|
+
MultiModularBasis with moduli [...]
|
|
329
|
+
sage: mm.prod() >= 2*10^30
|
|
330
|
+
True
|
|
331
|
+
|
|
332
|
+
TESTS:
|
|
333
|
+
|
|
334
|
+
Verify that :issue:`11358` is fixed::
|
|
335
|
+
|
|
336
|
+
sage: set_random_seed(0); m = sage.arith.multi_modular.MultiModularBasis_base(0)
|
|
337
|
+
sage: m._extend_moduli_to_height(prod(prime_range(50)))
|
|
338
|
+
sage: m = sage.arith.multi_modular.MultiModularBasis_base([],2,100)
|
|
339
|
+
sage: m._extend_moduli_to_height(prod(prime_range(90)))
|
|
340
|
+
sage: m._extend_moduli_to_height(prod(prime_range(150)))
|
|
341
|
+
Traceback (most recent call last):
|
|
342
|
+
...
|
|
343
|
+
RuntimeError: there are not enough primes in the interval [2, 100] to complete this multimodular computation
|
|
344
|
+
|
|
345
|
+
Another check (which fails horribly before :issue:`11358` is fixed)::
|
|
346
|
+
|
|
347
|
+
sage: set_random_seed(0); m = sage.arith.multi_modular.MultiModularBasis_base(0); m._extend_moduli_to_height(10**10000)
|
|
348
|
+
sage: len(set(m)) == len(m)
|
|
349
|
+
True
|
|
350
|
+
sage: len(m)
|
|
351
|
+
2440
|
|
352
|
+
"""
|
|
353
|
+
cdef Integer h = Integer(height)
|
|
354
|
+
if h < self._l_bound:
|
|
355
|
+
h = Integer(self._l_bound)
|
|
356
|
+
self._extend_moduli_to_height_c(h.value)
|
|
357
|
+
|
|
358
|
+
cdef int _extend_moduli_to_height_c(self, mpz_t height0) except -1:
|
|
359
|
+
r"""
|
|
360
|
+
Expand the list of primes and perform precomputations.
|
|
361
|
+
|
|
362
|
+
INPUT:
|
|
363
|
+
|
|
364
|
+
- ``height`` -- determines how many primes are computed
|
|
365
|
+
(their product must be at least 2*height)
|
|
366
|
+
"""
|
|
367
|
+
# real height we use is twice the given, set height to 2*height0
|
|
368
|
+
cdef mpz_t height
|
|
369
|
+
mpz_init(height)
|
|
370
|
+
mpz_mul_2exp(height, height0, 1)
|
|
371
|
+
# check if we already have enough prime moduli
|
|
372
|
+
if self.n > 0 and mpz_cmp(height, self.partial_products[self.n-1]) <= 0:
|
|
373
|
+
mpz_clear(height)
|
|
374
|
+
return self.n
|
|
375
|
+
|
|
376
|
+
# find new prime moduli
|
|
377
|
+
new_moduli = []
|
|
378
|
+
new_partial_products = []
|
|
379
|
+
cdef Integer M # keeps current height
|
|
380
|
+
cdef mod_int p # keeps current prime moduli
|
|
381
|
+
|
|
382
|
+
if self.n == 0:
|
|
383
|
+
M = smallInteger(1)
|
|
384
|
+
else:
|
|
385
|
+
M = PY_NEW(Integer)
|
|
386
|
+
mpz_set(M.value, self.partial_products[self.n-1])
|
|
387
|
+
|
|
388
|
+
known_primes = set(self)
|
|
389
|
+
while mpz_cmp(height, M.value) > 0:
|
|
390
|
+
p = self._new_random_prime(known_primes)
|
|
391
|
+
new_moduli.append(p)
|
|
392
|
+
known_primes.add(p)
|
|
393
|
+
M *= p
|
|
394
|
+
new_partial_products.append(M)
|
|
395
|
+
mpz_clear(height)
|
|
396
|
+
return self.extend_with_primes(new_moduli, new_partial_products,
|
|
397
|
+
check=False)
|
|
398
|
+
|
|
399
|
+
def _extend_moduli_to_count(self, int count):
|
|
400
|
+
r"""
|
|
401
|
+
Expand the list of primes and perform precomputations.
|
|
402
|
+
|
|
403
|
+
INPUT:
|
|
404
|
+
|
|
405
|
+
- ``count`` -- the minimum number of moduli in the resulting list
|
|
406
|
+
|
|
407
|
+
EXAMPLES::
|
|
408
|
+
|
|
409
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
410
|
+
sage: mm = MultiModularBasis_base([46307]); mm
|
|
411
|
+
MultiModularBasis with moduli [46307]
|
|
412
|
+
sage: mm._extend_moduli_to_count(3)
|
|
413
|
+
3
|
|
414
|
+
sage: mm
|
|
415
|
+
MultiModularBasis with moduli [...]
|
|
416
|
+
sage: len(mm)
|
|
417
|
+
3
|
|
418
|
+
"""
|
|
419
|
+
if count <= self.n:
|
|
420
|
+
return self.n
|
|
421
|
+
new_moduli = []
|
|
422
|
+
|
|
423
|
+
cdef int i
|
|
424
|
+
cdef mod_int p
|
|
425
|
+
known_primes = set(self)
|
|
426
|
+
for i in range(self.n, count):
|
|
427
|
+
p = self._new_random_prime(known_primes)
|
|
428
|
+
known_primes.add(p)
|
|
429
|
+
new_moduli.append(p)
|
|
430
|
+
|
|
431
|
+
return self.extend_with_primes(new_moduli, check=False)
|
|
432
|
+
|
|
433
|
+
def _extend_moduli(self, count):
|
|
434
|
+
"""
|
|
435
|
+
Expand the list of prime moduli with `count` new random primes.
|
|
436
|
+
|
|
437
|
+
EXAMPLES::
|
|
438
|
+
|
|
439
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
440
|
+
sage: mm = MultiModularBasis_base([46307]); mm
|
|
441
|
+
MultiModularBasis with moduli [46307]
|
|
442
|
+
sage: mm._extend_moduli(2); mm # random
|
|
443
|
+
MultiModularBasis with moduli [46307, 31051, 16981]
|
|
444
|
+
sage: mm[0]
|
|
445
|
+
46307
|
|
446
|
+
sage: all(p.is_prime() for p in mm)
|
|
447
|
+
True
|
|
448
|
+
"""
|
|
449
|
+
self._extend_moduli_to_count(self.n + count)
|
|
450
|
+
|
|
451
|
+
cdef void _refresh_products(self, int start) noexcept:
|
|
452
|
+
r"""
|
|
453
|
+
Compute and store `\prod_j=1^{i-1} m_j` for i > start.
|
|
454
|
+
"""
|
|
455
|
+
cdef mpz_t z
|
|
456
|
+
mpz_init(z)
|
|
457
|
+
if start == 0:
|
|
458
|
+
mpz_set_si(self.partial_products[0], self.moduli[0])
|
|
459
|
+
start += 1
|
|
460
|
+
for i in range(start, self.n):
|
|
461
|
+
mpz_set_si(z, self.moduli[i])
|
|
462
|
+
mpz_mul(self.partial_products[i], self.partial_products[i-1], z)
|
|
463
|
+
mpz_clear(z)
|
|
464
|
+
self._refresh_prod()
|
|
465
|
+
|
|
466
|
+
cdef void _refresh_prod(self) noexcept:
|
|
467
|
+
# record the product and half product for balancing the lifts.
|
|
468
|
+
mpz_set(self.product, self.partial_products[self.n-1])
|
|
469
|
+
mpz_fdiv_q_ui(self.half_product, self.product, 2)
|
|
470
|
+
|
|
471
|
+
cdef void _refresh_precomputations(self, int start) except *:
|
|
472
|
+
r"""
|
|
473
|
+
Compute and store `\prod_j=1^{i-1} m_j^{-1} (mod m_i)` for i >= start.
|
|
474
|
+
"""
|
|
475
|
+
if start == 0:
|
|
476
|
+
start = 1 # first one is trivial, never used
|
|
477
|
+
self.C[0] = 1
|
|
478
|
+
for i in range(start, self.n):
|
|
479
|
+
self.C[i] = ai.c_inverse_mod_longlong(mpz_fdiv_ui(self.partial_products[i-1], self.moduli[i]), self.moduli[i])
|
|
480
|
+
|
|
481
|
+
cdef int min_moduli_count(self, mpz_t height) except -1:
|
|
482
|
+
r"""
|
|
483
|
+
Compute the minimum number of primes needed to uniquely determine
|
|
484
|
+
an integer mod height.
|
|
485
|
+
"""
|
|
486
|
+
self._extend_moduli_to_height_c(height)
|
|
487
|
+
|
|
488
|
+
cdef int count
|
|
489
|
+
count = self.n * mpz_sizeinbase(height, 2) / mpz_sizeinbase(self.partial_products[self.n-1], 2) # an estimate
|
|
490
|
+
count = max(min(count, self.n), 1)
|
|
491
|
+
while count > 1 and mpz_cmp(height, self.partial_products[count-1]) < 0:
|
|
492
|
+
count -= 1
|
|
493
|
+
while mpz_cmp(height, self.partial_products[count-1]) > 0:
|
|
494
|
+
count += 1
|
|
495
|
+
|
|
496
|
+
return count
|
|
497
|
+
|
|
498
|
+
cdef mod_int last_prime(self) noexcept:
|
|
499
|
+
return self.moduli[self.n-1]
|
|
500
|
+
|
|
501
|
+
cdef int mpz_reduce_tail(self, mpz_t z, mod_int* b, int offset, int len) except -1:
|
|
502
|
+
r"""
|
|
503
|
+
Perform reduction mod `m_i` for offset <= i < len.
|
|
504
|
+
|
|
505
|
+
`b[i] = z mod m_{i+offset}` for 0 <= i < len
|
|
506
|
+
|
|
507
|
+
INPUT:
|
|
508
|
+
|
|
509
|
+
- ``z`` -- the integer being reduced
|
|
510
|
+
- ``b`` -- array to hold the reductions mod each `m_i`;
|
|
511
|
+
it *must* be allocated and have length at least len
|
|
512
|
+
- ``offset`` -- first prime in list to reduce against
|
|
513
|
+
- ``len`` -- number of primes in list to reduce against
|
|
514
|
+
"""
|
|
515
|
+
cdef int i
|
|
516
|
+
cdef mod_int* m
|
|
517
|
+
m = self.moduli + offset
|
|
518
|
+
for i in range(len):
|
|
519
|
+
b[i] = mpz_fdiv_ui(z, m[i])
|
|
520
|
+
return 0
|
|
521
|
+
|
|
522
|
+
cdef int mpz_reduce_vec_tail(self, mpz_t* z, mod_int** b, int vn, int offset, int len) except -1:
|
|
523
|
+
r"""
|
|
524
|
+
Perform reduction mod `m_i` for offset <= i < len.
|
|
525
|
+
|
|
526
|
+
`b[i][j] = z[j] mod m_{i+offset}` for 0 <= i < len
|
|
527
|
+
|
|
528
|
+
INPUT:
|
|
529
|
+
|
|
530
|
+
- ``z`` -- an array of integers being reduced
|
|
531
|
+
- ``b`` -- array to hold the reductions mod each m_i.
|
|
532
|
+
It *must* be fully allocated and each have length at least len.
|
|
533
|
+
- ``vn`` -- length of z and each b[i]
|
|
534
|
+
- ``offset`` -- first prime in list to reduce against
|
|
535
|
+
- ``len`` -- number of primes in list to reduce against
|
|
536
|
+
"""
|
|
537
|
+
cdef int i, j
|
|
538
|
+
cdef mod_int* m
|
|
539
|
+
m = self.moduli + offset
|
|
540
|
+
for i in range(len):
|
|
541
|
+
mi = m[i]
|
|
542
|
+
for j in range(vn):
|
|
543
|
+
b[i][j] = mpz_fdiv_ui(z[j], mi)
|
|
544
|
+
return 0
|
|
545
|
+
|
|
546
|
+
cdef int mpz_crt_tail(self, mpz_t z, mod_int* b, int offset, int len) except -1:
|
|
547
|
+
r"""
|
|
548
|
+
Calculate lift mod `\prod_{i=0}^{offset+len-1} m_i`.
|
|
549
|
+
|
|
550
|
+
z = b[i] mod `m_{i+offset}` for 0 <= i < len
|
|
551
|
+
|
|
552
|
+
In the case that offset > 0,
|
|
553
|
+
z remains unchanged mod `\prod_{i=0}^{offset-1} m_i`
|
|
554
|
+
|
|
555
|
+
INPUT:
|
|
556
|
+
|
|
557
|
+
- ``z`` -- a placeholder for the constructed integer; *must* be
|
|
558
|
+
initialized if and only if ``offset > 0``
|
|
559
|
+
- ``b`` -- array holding the reductions mod each m_i; *must* have
|
|
560
|
+
length at least ``len``
|
|
561
|
+
- ``offset`` -- first prime in list to reduce against
|
|
562
|
+
- ``len`` -- number of primes in list to reduce against
|
|
563
|
+
"""
|
|
564
|
+
cdef int i, s
|
|
565
|
+
cdef mpz_t u
|
|
566
|
+
cdef mod_int* m
|
|
567
|
+
m = self.moduli + offset
|
|
568
|
+
mpz_init(u)
|
|
569
|
+
if offset == 0:
|
|
570
|
+
s = 1
|
|
571
|
+
mpz_init_set_si(z, b[0])
|
|
572
|
+
if b[0] == 0:
|
|
573
|
+
while s < len and b[s] == 0: # fast forward to first nonzero
|
|
574
|
+
s += 1
|
|
575
|
+
else:
|
|
576
|
+
s = 0
|
|
577
|
+
for i in range(s, len):
|
|
578
|
+
mpz_set_si(u, ((b[i] + m[i] - mpz_fdiv_ui(z, m[i])) * self.C[i]) % m[i])
|
|
579
|
+
mpz_mul(u, u, self.partial_products[i-1])
|
|
580
|
+
mpz_add(z, z, u)
|
|
581
|
+
|
|
582
|
+
# normalize to be between -prod/2 and prod/2.
|
|
583
|
+
if mpz_cmp(z, self.half_product) > 0:
|
|
584
|
+
mpz_sub(z, z, self.product)
|
|
585
|
+
mpz_clear(u)
|
|
586
|
+
return 0
|
|
587
|
+
|
|
588
|
+
cdef int mpz_crt_vec_tail(self, mpz_t* z, mod_int** b, int vc, int offset, int len) except -1:
|
|
589
|
+
r"""
|
|
590
|
+
Calculate lift mod `\prod_{i=0}^{offset+len-1} m_i`.
|
|
591
|
+
|
|
592
|
+
`z[j] = b[i][j] mod m_{i+offset}` for 0 <= i < len
|
|
593
|
+
|
|
594
|
+
In the case that offset > 0,
|
|
595
|
+
z[j] remains unchanged mod `\prod_{i=0}^{offset-1} m_i`
|
|
596
|
+
|
|
597
|
+
INPUT:
|
|
598
|
+
|
|
599
|
+
- ``z`` -- a placeholder for the constructed integers; *must* be
|
|
600
|
+
allocated and have length at least ``vc``. z[j] *must* be initialized
|
|
601
|
+
if and only if ``offset > 0``.
|
|
602
|
+
- ``b`` -- array holding the reductions mod each m_i. *must* have
|
|
603
|
+
length at least ``len``.
|
|
604
|
+
- ``vn`` -- length of z and each b[i]
|
|
605
|
+
- ``offset`` -- first prime in list to reduce against
|
|
606
|
+
- ``len`` -- number of primes in list to reduce against
|
|
607
|
+
"""
|
|
608
|
+
cdef int i, j
|
|
609
|
+
cdef mpz_t u
|
|
610
|
+
cdef mod_int* m
|
|
611
|
+
|
|
612
|
+
m = self.moduli + offset
|
|
613
|
+
mpz_init(u)
|
|
614
|
+
if offset == 0:
|
|
615
|
+
s = 1
|
|
616
|
+
else:
|
|
617
|
+
s = 0
|
|
618
|
+
|
|
619
|
+
for j in range(vc):
|
|
620
|
+
i = s
|
|
621
|
+
if offset == 0:
|
|
622
|
+
mpz_set_si(z[j], b[0][j])
|
|
623
|
+
if b[0][j] == 0:
|
|
624
|
+
while i < len and b[i][j] == 0: # fast forward to first nonzero
|
|
625
|
+
i += 1
|
|
626
|
+
while i < len:
|
|
627
|
+
mpz_set_si(u, ((b[i][j] + m[i] - mpz_fdiv_ui(z[j], m[i])) * self.C[i]) % m[i]) # u = ((b_i - z) * C_i) % m_i
|
|
628
|
+
mpz_mul(u, u, self.partial_products[i-1])
|
|
629
|
+
mpz_add(z[j], z[j], u)
|
|
630
|
+
i += 1
|
|
631
|
+
|
|
632
|
+
# normalize to be between -prod/2 and prod/2.
|
|
633
|
+
if mpz_cmp(z[j], self.half_product) > 0:
|
|
634
|
+
mpz_sub(z[j], z[j], self.product)
|
|
635
|
+
|
|
636
|
+
cdef Integer zz
|
|
637
|
+
zz = PY_NEW(Integer)
|
|
638
|
+
mpz_set(zz.value, self.half_product)
|
|
639
|
+
|
|
640
|
+
mpz_clear(u)
|
|
641
|
+
return 0
|
|
642
|
+
|
|
643
|
+
def crt(self, b):
|
|
644
|
+
r"""
|
|
645
|
+
Calculate lift mod `\prod_{i=0}^{len(b)-1} m_i`.
|
|
646
|
+
|
|
647
|
+
In the case that offset > 0,
|
|
648
|
+
z[j] remains unchanged mod `\prod_{i=0}^{offset-1} m_i`
|
|
649
|
+
|
|
650
|
+
INPUT:
|
|
651
|
+
|
|
652
|
+
- ``b`` -- list of length at most self.n
|
|
653
|
+
|
|
654
|
+
OUTPUT:
|
|
655
|
+
|
|
656
|
+
Integer z where `z = b[i] mod m_i` for 0 <= i < len(b)
|
|
657
|
+
|
|
658
|
+
EXAMPLES::
|
|
659
|
+
|
|
660
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
661
|
+
sage: mm = MultiModularBasis_base([10007, 10009, 10037, 10039, 17351])
|
|
662
|
+
sage: res = mm.crt([3,5,7,9]); res
|
|
663
|
+
8474803647063985
|
|
664
|
+
sage: res % 10007
|
|
665
|
+
3
|
|
666
|
+
sage: res % 10009
|
|
667
|
+
5
|
|
668
|
+
sage: res % 10037
|
|
669
|
+
7
|
|
670
|
+
sage: res % 10039
|
|
671
|
+
9
|
|
672
|
+
"""
|
|
673
|
+
cdef int i, n
|
|
674
|
+
n = len(b)
|
|
675
|
+
if n > self.n:
|
|
676
|
+
raise IndexError("beyond bound for multi-modular prime list")
|
|
677
|
+
cdef mod_int* bs
|
|
678
|
+
bs = <mod_int*>check_allocarray(n, sizeof(mod_int))
|
|
679
|
+
for i in range(n):
|
|
680
|
+
bs[i] = b[i]
|
|
681
|
+
cdef Integer z
|
|
682
|
+
z = PY_NEW(Integer)
|
|
683
|
+
self.mpz_crt_tail(z.value, bs, 0, n)
|
|
684
|
+
sig_free(bs)
|
|
685
|
+
return z
|
|
686
|
+
|
|
687
|
+
def precomputation_list(self):
|
|
688
|
+
r"""
|
|
689
|
+
Return a list of the precomputed coefficients
|
|
690
|
+
`\prod_j=1^{i-1} m_j^{-1} (mod m_i)`
|
|
691
|
+
where `m_i` are the prime moduli.
|
|
692
|
+
|
|
693
|
+
EXAMPLES::
|
|
694
|
+
|
|
695
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
696
|
+
sage: mm = MultiModularBasis_base([46307, 10007]); mm
|
|
697
|
+
MultiModularBasis with moduli [46307, 10007]
|
|
698
|
+
sage: mm.precomputation_list()
|
|
699
|
+
[1, 4013]
|
|
700
|
+
"""
|
|
701
|
+
return [Integer(self.C[i]) for i in range(self.n)]
|
|
702
|
+
|
|
703
|
+
def partial_product(self, n):
|
|
704
|
+
"""
|
|
705
|
+
Return a list containing precomputed partial products.
|
|
706
|
+
|
|
707
|
+
EXAMPLES::
|
|
708
|
+
|
|
709
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
710
|
+
sage: mm = MultiModularBasis_base([46307, 10007]); mm
|
|
711
|
+
MultiModularBasis with moduli [46307, 10007]
|
|
712
|
+
sage: mm.partial_product(0)
|
|
713
|
+
46307
|
|
714
|
+
sage: mm.partial_product(1)
|
|
715
|
+
463394149
|
|
716
|
+
|
|
717
|
+
TESTS::
|
|
718
|
+
|
|
719
|
+
sage: mm.partial_product(2)
|
|
720
|
+
Traceback (most recent call last):
|
|
721
|
+
...
|
|
722
|
+
IndexError: beyond bound for multi-modular prime list
|
|
723
|
+
sage: mm.partial_product(-2)
|
|
724
|
+
Traceback (most recent call last):
|
|
725
|
+
...
|
|
726
|
+
IndexError: negative index not valid
|
|
727
|
+
"""
|
|
728
|
+
if n >= self.n:
|
|
729
|
+
raise IndexError("beyond bound for multi-modular prime list")
|
|
730
|
+
if n < 0:
|
|
731
|
+
raise IndexError("negative index not valid")
|
|
732
|
+
cdef Integer z
|
|
733
|
+
z = PY_NEW(Integer)
|
|
734
|
+
mpz_set(z.value, self.partial_products[n])
|
|
735
|
+
return z
|
|
736
|
+
|
|
737
|
+
def prod(self):
|
|
738
|
+
"""
|
|
739
|
+
Return the product of the prime moduli.
|
|
740
|
+
|
|
741
|
+
EXAMPLES::
|
|
742
|
+
|
|
743
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
744
|
+
sage: mm = MultiModularBasis_base([46307]); mm
|
|
745
|
+
MultiModularBasis with moduli [46307]
|
|
746
|
+
sage: mm.prod()
|
|
747
|
+
46307
|
|
748
|
+
sage: mm = MultiModularBasis_base([46307, 10007]); mm
|
|
749
|
+
MultiModularBasis with moduli [46307, 10007]
|
|
750
|
+
sage: mm.prod()
|
|
751
|
+
463394149
|
|
752
|
+
|
|
753
|
+
TESTS::
|
|
754
|
+
|
|
755
|
+
sage: mm = MultiModularBasis_base([]); mm
|
|
756
|
+
MultiModularBasis with moduli []
|
|
757
|
+
sage: len(mm)
|
|
758
|
+
0
|
|
759
|
+
sage: mm.prod()
|
|
760
|
+
1
|
|
761
|
+
"""
|
|
762
|
+
if self.n == 0:
|
|
763
|
+
return 1
|
|
764
|
+
cdef Integer z
|
|
765
|
+
z = PY_NEW(Integer)
|
|
766
|
+
mpz_set(z.value, self.partial_products[self.n-1])
|
|
767
|
+
return z
|
|
768
|
+
|
|
769
|
+
def list(self):
|
|
770
|
+
"""
|
|
771
|
+
Return a list with the prime moduli.
|
|
772
|
+
|
|
773
|
+
EXAMPLES::
|
|
774
|
+
|
|
775
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
776
|
+
sage: mm = MultiModularBasis_base([46307, 10007])
|
|
777
|
+
sage: mm.list()
|
|
778
|
+
[46307, 10007]
|
|
779
|
+
"""
|
|
780
|
+
return [Integer(self.moduli[i]) for i in range(self.n)]
|
|
781
|
+
|
|
782
|
+
def __len__(self):
|
|
783
|
+
"""
|
|
784
|
+
Return the number of moduli stored.
|
|
785
|
+
|
|
786
|
+
EXAMPLES::
|
|
787
|
+
|
|
788
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
789
|
+
sage: mm = MultiModularBasis_base([10007])
|
|
790
|
+
sage: len(mm)
|
|
791
|
+
1
|
|
792
|
+
sage: mm._extend_moduli_to_count(2)
|
|
793
|
+
2
|
|
794
|
+
sage: len(mm)
|
|
795
|
+
2
|
|
796
|
+
"""
|
|
797
|
+
return self.n
|
|
798
|
+
|
|
799
|
+
def __iter__(self):
|
|
800
|
+
"""
|
|
801
|
+
Return an iterator over the prime moduli.
|
|
802
|
+
|
|
803
|
+
EXAMPLES::
|
|
804
|
+
|
|
805
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
806
|
+
sage: mm = MultiModularBasis_base([10007, 10009])
|
|
807
|
+
sage: t = iter(mm); t
|
|
808
|
+
<list...iterator object at ...>
|
|
809
|
+
sage: list(mm.__iter__())
|
|
810
|
+
[10007, 10009]
|
|
811
|
+
"""
|
|
812
|
+
return iter(self.list())
|
|
813
|
+
|
|
814
|
+
def __getitem__(self, ix):
|
|
815
|
+
"""
|
|
816
|
+
Return the moduli stored at index `ix` as a Python long.
|
|
817
|
+
|
|
818
|
+
EXAMPLES::
|
|
819
|
+
|
|
820
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
821
|
+
sage: mm = MultiModularBasis_base([10007, 10009])
|
|
822
|
+
sage: mm[1]
|
|
823
|
+
10009
|
|
824
|
+
sage: mm[-1]
|
|
825
|
+
Traceback (most recent call last):
|
|
826
|
+
...
|
|
827
|
+
IndexError: index out of range
|
|
828
|
+
|
|
829
|
+
sage: mm[:1]
|
|
830
|
+
MultiModularBasis with moduli [10007]
|
|
831
|
+
"""
|
|
832
|
+
if isinstance(ix, slice):
|
|
833
|
+
return self.__class__(self.list()[ix], l_bound = self._l_bound,
|
|
834
|
+
u_bound = self._u_bound)
|
|
835
|
+
|
|
836
|
+
cdef Py_ssize_t i = ix
|
|
837
|
+
if i != ix:
|
|
838
|
+
raise TypeError("index must be an integer")
|
|
839
|
+
if i < 0 or i >= self.n:
|
|
840
|
+
raise IndexError("index out of range")
|
|
841
|
+
return self.moduli[i]
|
|
842
|
+
|
|
843
|
+
def __repr__(self):
|
|
844
|
+
"""
|
|
845
|
+
Return a string representation of this object.
|
|
846
|
+
|
|
847
|
+
EXAMPLES::
|
|
848
|
+
|
|
849
|
+
sage: from sage.arith.multi_modular import MultiModularBasis_base
|
|
850
|
+
sage: MultiModularBasis_base([10007])
|
|
851
|
+
MultiModularBasis with moduli [10007]
|
|
852
|
+
"""
|
|
853
|
+
return "MultiModularBasis with moduli " + str(self.list())
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
cdef class MultiModularBasis(MultiModularBasis_base):
|
|
857
|
+
"""
|
|
858
|
+
Class used for storing a MultiModular bases of a fixed length.
|
|
859
|
+
"""
|
|
860
|
+
cdef int mpz_reduce(self, mpz_t z, mod_int* b) except -1:
|
|
861
|
+
r"""
|
|
862
|
+
Perform reduction mod `m_i` for each modulus `m_i`.
|
|
863
|
+
|
|
864
|
+
`b[i] = z mod m_i` for 0 <= i < len(self)
|
|
865
|
+
|
|
866
|
+
INPUT:
|
|
867
|
+
|
|
868
|
+
- ``z`` -- the integer being reduced
|
|
869
|
+
- ``b`` -- array to hold the reductions mod each `m_i`; it *must* be
|
|
870
|
+
allocated and have length at least len
|
|
871
|
+
"""
|
|
872
|
+
self.mpz_reduce_tail(z, b, 0, self.n)
|
|
873
|
+
|
|
874
|
+
cdef int mpz_reduce_vec(self, mpz_t* z, mod_int** b, int vn) except -1:
|
|
875
|
+
r"""
|
|
876
|
+
Perform reduction mod `m_i` for each modulus `m_i`.
|
|
877
|
+
|
|
878
|
+
`b[i][j] = z[j] mod m_i` for 0 <= i < len(self)
|
|
879
|
+
|
|
880
|
+
INPUT:
|
|
881
|
+
|
|
882
|
+
- ``z`` -- an array of integers being reduced
|
|
883
|
+
- ``b`` -- array to hold the reductions mod each `m_i`; it *must* be
|
|
884
|
+
fully allocated and each have length at least len
|
|
885
|
+
- ``vn`` -- length of ``z`` and each ``b[i]``
|
|
886
|
+
"""
|
|
887
|
+
self.mpz_reduce_vec_tail(z, b, vn, 0, self.n)
|
|
888
|
+
|
|
889
|
+
cdef int mpz_crt(self, mpz_t z, mod_int* b) except -1:
|
|
890
|
+
r"""
|
|
891
|
+
Calculate lift mod `\prod m_i`.
|
|
892
|
+
|
|
893
|
+
`z = b[i] mod m_{i+offset}` for 0 <= i < len(self)
|
|
894
|
+
|
|
895
|
+
INPUT:
|
|
896
|
+
|
|
897
|
+
- ``z`` -- a placeholder for the constructed integer; *must not* be
|
|
898
|
+
initialized
|
|
899
|
+
- ``b`` -- array holding the reductions mod each `m_i`; it *must* have
|
|
900
|
+
length at least ``len(self)``
|
|
901
|
+
"""
|
|
902
|
+
self.mpz_crt_tail(z, b, 0, self.n)
|
|
903
|
+
|
|
904
|
+
cdef int mpz_crt_vec(self, mpz_t* z, mod_int** b, int vn) except -1:
|
|
905
|
+
r"""
|
|
906
|
+
Calculate lift mod `\prod m_i`.
|
|
907
|
+
|
|
908
|
+
`z[j] = b[i][j] mod m_i` for 0 <= i < len(self)
|
|
909
|
+
|
|
910
|
+
INPUT:
|
|
911
|
+
|
|
912
|
+
- ``z`` -- a placeholder for the constructed integers; *must* be
|
|
913
|
+
allocated and have length at least vn,but each z[j] *must not* be
|
|
914
|
+
initialized
|
|
915
|
+
- ``b`` -- array holding the reductions mod each `m_i`; it *must* have
|
|
916
|
+
length at least ``len(self)``
|
|
917
|
+
- ``vn`` -- length of ``z`` and each ``b[i]``
|
|
918
|
+
"""
|
|
919
|
+
self.mpz_crt_vec_tail(z, b, vn, 0, self.n)
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
cdef class MutableMultiModularBasis(MultiModularBasis):
|
|
923
|
+
"""
|
|
924
|
+
Class used for performing multi-modular methods,
|
|
925
|
+
with the possibility of removing bad primes.
|
|
926
|
+
"""
|
|
927
|
+
cpdef mod_int next_prime(self) except -1:
|
|
928
|
+
"""
|
|
929
|
+
Pick a new random prime between the bounds given during the
|
|
930
|
+
initialization of this object, update the precomputed data,
|
|
931
|
+
and return the new prime modulus.
|
|
932
|
+
|
|
933
|
+
EXAMPLES::
|
|
934
|
+
|
|
935
|
+
sage: from sage.arith.multi_modular import MutableMultiModularBasis
|
|
936
|
+
sage: mm = MutableMultiModularBasis([10007])
|
|
937
|
+
sage: p = mm.next_prime()
|
|
938
|
+
sage: 1024 < p < 32768
|
|
939
|
+
True
|
|
940
|
+
sage: p != 10007
|
|
941
|
+
True
|
|
942
|
+
sage: mm.list() == [10007, p]
|
|
943
|
+
True
|
|
944
|
+
"""
|
|
945
|
+
self._extend_moduli(1)
|
|
946
|
+
return self.moduli[self.n-1]
|
|
947
|
+
|
|
948
|
+
cpdef mod_int replace_prime(self, int ix) except -1:
|
|
949
|
+
"""
|
|
950
|
+
Replace the prime moduli at the given index with a different one,
|
|
951
|
+
update the precomputed data accordingly, and return the new prime.
|
|
952
|
+
|
|
953
|
+
INPUT:
|
|
954
|
+
|
|
955
|
+
- ``ix`` -- index into list of moduli
|
|
956
|
+
|
|
957
|
+
OUTPUT: the new prime modulus
|
|
958
|
+
|
|
959
|
+
EXAMPLES::
|
|
960
|
+
|
|
961
|
+
sage: from sage.arith.multi_modular import MutableMultiModularBasis
|
|
962
|
+
sage: mm = MutableMultiModularBasis([10007, 10009, 10037, 10039])
|
|
963
|
+
sage: mm
|
|
964
|
+
MultiModularBasis with moduli [10007, 10009, 10037, 10039]
|
|
965
|
+
sage: prev_prod = mm.prod(); prev_prod
|
|
966
|
+
10092272478850909
|
|
967
|
+
sage: mm.precomputation_list()
|
|
968
|
+
[1, 5004, 6536, 6060]
|
|
969
|
+
sage: mm.partial_product(2)
|
|
970
|
+
1005306552331
|
|
971
|
+
sage: p = mm.replace_prime(1)
|
|
972
|
+
sage: mm.list() == [10007, p, 10037, 10039]
|
|
973
|
+
True
|
|
974
|
+
sage: mm.prod()*10009 == prev_prod*p
|
|
975
|
+
True
|
|
976
|
+
sage: precomputed = mm.precomputation_list()
|
|
977
|
+
sage: precomputed == [prod(Integers(mm[i])(1 / mm[j])
|
|
978
|
+
....: for j in range(i))
|
|
979
|
+
....: for i in range(4)]
|
|
980
|
+
True
|
|
981
|
+
sage: mm.partial_product(2) == prod(mm.list()[:3])
|
|
982
|
+
True
|
|
983
|
+
"""
|
|
984
|
+
cdef mod_int new_p
|
|
985
|
+
|
|
986
|
+
if ix < 0 or ix >= self.n:
|
|
987
|
+
raise IndexError("index out of range")
|
|
988
|
+
|
|
989
|
+
new_p = self._new_random_prime(set(self))
|
|
990
|
+
self.moduli[ix] = new_p
|
|
991
|
+
|
|
992
|
+
self._refresh_products(ix)
|
|
993
|
+
self._refresh_precomputations(ix)
|
|
994
|
+
return new_p
|