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,1464 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# distutils: language = c++
|
|
3
|
+
# distutils: extra_compile_args = -std=c++11
|
|
4
|
+
r"""
|
|
5
|
+
Pairing Heap
|
|
6
|
+
|
|
7
|
+
This module proposes several implementations of the pairing heap data structure
|
|
8
|
+
[FSST1986]_. See the :wikipedia:`Pairing_heap` for more information on this
|
|
9
|
+
min-heap data structure.
|
|
10
|
+
|
|
11
|
+
- :class:`PairingHeap_of_n_integers`: a pairing heap data structure with fixed
|
|
12
|
+
capacity `n`. Its items are integers in the range `[0, n-1]`. Values can be of
|
|
13
|
+
any type equipped with a comparison method (``<=``).
|
|
14
|
+
|
|
15
|
+
- :class:`PairingHeap_of_n_hashables`: a pairing heap data structure with fixed
|
|
16
|
+
capacity `n`. Its items can be of any hashable type. Values can be of any type
|
|
17
|
+
equipped with a comparison method (``<=``).
|
|
18
|
+
|
|
19
|
+
- ``PairingHeap``: interface to a pairing heap data structure written in C++.
|
|
20
|
+
The advantages of this data structure are that: its capacity is unbounded;
|
|
21
|
+
items can be of any hashable type equipped with a hashing method that can be
|
|
22
|
+
supported by ``std::unordered_map``; values can be of any specified type
|
|
23
|
+
equipped with a comparison method (``<=``). This data structure is for
|
|
24
|
+
internal use and therefore cannot be accessed from a shell.
|
|
25
|
+
|
|
26
|
+
EXAMPLES:
|
|
27
|
+
|
|
28
|
+
Pairing heap of `n` integers in the range `[0, n-1]`::
|
|
29
|
+
|
|
30
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
31
|
+
sage: P = PairingHeap_of_n_integers(10); P
|
|
32
|
+
PairingHeap_of_n_integers: capacity 10, size 0
|
|
33
|
+
sage: P.push(1, 3)
|
|
34
|
+
sage: P.push(2, 2)
|
|
35
|
+
sage: P
|
|
36
|
+
PairingHeap_of_n_integers: capacity 10, size 2
|
|
37
|
+
sage: P.top()
|
|
38
|
+
(2, 2)
|
|
39
|
+
sage: P.decrease(1, 1)
|
|
40
|
+
sage: P.top()
|
|
41
|
+
(1, 1)
|
|
42
|
+
sage: P.pop()
|
|
43
|
+
sage: P.top()
|
|
44
|
+
(2, 2)
|
|
45
|
+
|
|
46
|
+
sage: P = PairingHeap_of_n_integers(10)
|
|
47
|
+
sage: P.push(1, (2, 'a'))
|
|
48
|
+
sage: P.push(2, (2, 'b'))
|
|
49
|
+
sage: P.top()
|
|
50
|
+
(1, (2, 'a'))
|
|
51
|
+
|
|
52
|
+
Pairing heap of `n` hashables::
|
|
53
|
+
|
|
54
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
55
|
+
sage: P = PairingHeap_of_n_hashables(10); P
|
|
56
|
+
PairingHeap_of_n_hashables: capacity 10, size 0
|
|
57
|
+
sage: P.push(1, 3)
|
|
58
|
+
sage: P.push('b', 2)
|
|
59
|
+
sage: P.push((1, 'abc'), 4)
|
|
60
|
+
sage: P.top()
|
|
61
|
+
('b', 2)
|
|
62
|
+
sage: P.decrease((1, 'abc'), 1)
|
|
63
|
+
sage: P.top()
|
|
64
|
+
((1, 'abc'), 1)
|
|
65
|
+
sage: P.pop()
|
|
66
|
+
sage: P.top()
|
|
67
|
+
('b', 2)
|
|
68
|
+
|
|
69
|
+
sage: # needs sage.graphs
|
|
70
|
+
sage: P = PairingHeap_of_n_hashables(10)
|
|
71
|
+
sage: P.push(('a', 1), (2, 'b'))
|
|
72
|
+
sage: P.push(2, (2, 'a'))
|
|
73
|
+
sage: g = Graph(2, immutable=True)
|
|
74
|
+
sage: P.push(g, (3, 'z'))
|
|
75
|
+
sage: P.top()
|
|
76
|
+
(2, (2, 'a'))
|
|
77
|
+
sage: P.decrease(g, (1, 'z'))
|
|
78
|
+
sage: P.top()
|
|
79
|
+
(Graph on 2 vertices, (1, 'z'))
|
|
80
|
+
sage: while P:
|
|
81
|
+
....: print(P.top())
|
|
82
|
+
....: P.pop()
|
|
83
|
+
(Graph on 2 vertices, (1, 'z'))
|
|
84
|
+
(2, (2, 'a'))
|
|
85
|
+
(('a', 1), (2, 'b'))
|
|
86
|
+
"""
|
|
87
|
+
# ******************************************************************************
|
|
88
|
+
# Copyright (C) 2024 David Coudert <david.coudert@inria.fr>
|
|
89
|
+
#
|
|
90
|
+
# This program is free software: you can redistribute it and/or modify
|
|
91
|
+
# it under the terms of the GNU General Public License as published by
|
|
92
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
93
|
+
# (at your option) any later version.
|
|
94
|
+
# https://www.gnu.org/licenses/
|
|
95
|
+
# ******************************************************************************
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
from libcpp.pair cimport pair
|
|
99
|
+
from cpython.ref cimport PyObject, Py_INCREF, Py_XDECREF
|
|
100
|
+
from cysignals.signals cimport sig_on, sig_off, sig_check
|
|
101
|
+
from cysignals.memory cimport check_allocarray, sig_free
|
|
102
|
+
from sage.data_structures.bitset_base cimport (bitset_init, bitset_free,
|
|
103
|
+
bitset_add, bitset_remove,
|
|
104
|
+
bitset_in)
|
|
105
|
+
from sage.misc.prandom import shuffle
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# ==============================================================================
|
|
109
|
+
# Class PairingHeap_class
|
|
110
|
+
# ==============================================================================
|
|
111
|
+
|
|
112
|
+
cdef class PairingHeap_class:
|
|
113
|
+
r"""
|
|
114
|
+
Common class and methods for :class:`PairingHeap_of_n_integers` and
|
|
115
|
+
:class:`PairingHeap_of_n_hashables`.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def __repr__(self):
|
|
119
|
+
r"""
|
|
120
|
+
Return a string representing ``self``.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
125
|
+
sage: P = PairingHeap_of_n_integers(5); P
|
|
126
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
127
|
+
sage: P.push(1, 2)
|
|
128
|
+
sage: P
|
|
129
|
+
PairingHeap_of_n_integers: capacity 5, size 1
|
|
130
|
+
"""
|
|
131
|
+
return f"{type(self).__name__}: capacity {self.n}, size {len(self)}"
|
|
132
|
+
|
|
133
|
+
def __bool__(self):
|
|
134
|
+
r"""
|
|
135
|
+
Check whether ``self`` is not empty.
|
|
136
|
+
|
|
137
|
+
EXAMPLES::
|
|
138
|
+
|
|
139
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
140
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
141
|
+
sage: 'not empty' if P else 'empty'
|
|
142
|
+
'empty'
|
|
143
|
+
sage: P.push(1, 2)
|
|
144
|
+
sage: 'not empty' if P else 'empty'
|
|
145
|
+
'not empty'
|
|
146
|
+
"""
|
|
147
|
+
return self.root != NULL
|
|
148
|
+
|
|
149
|
+
cpdef bint empty(self) noexcept:
|
|
150
|
+
r"""
|
|
151
|
+
Check whether the heap is empty.
|
|
152
|
+
|
|
153
|
+
EXAMPLES::
|
|
154
|
+
|
|
155
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
156
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
157
|
+
sage: P.empty()
|
|
158
|
+
True
|
|
159
|
+
sage: P.push(1, 2)
|
|
160
|
+
sage: P.empty()
|
|
161
|
+
False
|
|
162
|
+
"""
|
|
163
|
+
return self.root == NULL
|
|
164
|
+
|
|
165
|
+
cpdef bint full(self) noexcept:
|
|
166
|
+
r"""
|
|
167
|
+
Check whether the heap is full.
|
|
168
|
+
|
|
169
|
+
EXAMPLES::
|
|
170
|
+
|
|
171
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
172
|
+
sage: P = PairingHeap_of_n_integers(2)
|
|
173
|
+
sage: P.full()
|
|
174
|
+
False
|
|
175
|
+
sage: P.push(0, 2)
|
|
176
|
+
sage: P.push(1, 3)
|
|
177
|
+
sage: P.full()
|
|
178
|
+
True
|
|
179
|
+
"""
|
|
180
|
+
return self.n == self.number_of_items
|
|
181
|
+
|
|
182
|
+
cpdef size_t capacity(self) noexcept:
|
|
183
|
+
r"""
|
|
184
|
+
Return the maximum capacity of the heap.
|
|
185
|
+
|
|
186
|
+
EXAMPLES::
|
|
187
|
+
|
|
188
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
189
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
190
|
+
sage: P.capacity()
|
|
191
|
+
5
|
|
192
|
+
sage: P.push(1, 2)
|
|
193
|
+
sage: P.capacity()
|
|
194
|
+
5
|
|
195
|
+
"""
|
|
196
|
+
return self.n
|
|
197
|
+
|
|
198
|
+
cpdef size_t size(self) noexcept:
|
|
199
|
+
r"""
|
|
200
|
+
Return the number of items in the heap.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
205
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
206
|
+
sage: P.size()
|
|
207
|
+
0
|
|
208
|
+
sage: P.push(1, 2)
|
|
209
|
+
sage: P.size()
|
|
210
|
+
1
|
|
211
|
+
|
|
212
|
+
One may also use Python's ``__len__``::
|
|
213
|
+
|
|
214
|
+
sage: len(P)
|
|
215
|
+
1
|
|
216
|
+
"""
|
|
217
|
+
return self.number_of_items
|
|
218
|
+
|
|
219
|
+
def __len__(self):
|
|
220
|
+
r"""
|
|
221
|
+
Return the number of items in the heap.
|
|
222
|
+
|
|
223
|
+
EXAMPLES::
|
|
224
|
+
|
|
225
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
226
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
227
|
+
sage: len(P)
|
|
228
|
+
0
|
|
229
|
+
sage: P.push(1, 2)
|
|
230
|
+
sage: len(P)
|
|
231
|
+
1
|
|
232
|
+
"""
|
|
233
|
+
return self.number_of_items
|
|
234
|
+
|
|
235
|
+
cpdef tuple top(self):
|
|
236
|
+
r"""
|
|
237
|
+
Return the top pair (item, value) of the heap.
|
|
238
|
+
|
|
239
|
+
EXAMPLES::
|
|
240
|
+
|
|
241
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
242
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
243
|
+
sage: P.push(1, 2)
|
|
244
|
+
sage: P.top()
|
|
245
|
+
(1, 2)
|
|
246
|
+
sage: P.push(3, 1)
|
|
247
|
+
sage: P.top()
|
|
248
|
+
(3, 1)
|
|
249
|
+
|
|
250
|
+
sage: P = PairingHeap_of_n_integers(3)
|
|
251
|
+
sage: P.top()
|
|
252
|
+
Traceback (most recent call last):
|
|
253
|
+
...
|
|
254
|
+
ValueError: trying to access the top of an empty heap
|
|
255
|
+
"""
|
|
256
|
+
raise NotImplementedError()
|
|
257
|
+
|
|
258
|
+
cpdef object top_value(self):
|
|
259
|
+
r"""
|
|
260
|
+
Return the value of the top item of the heap.
|
|
261
|
+
|
|
262
|
+
EXAMPLES::
|
|
263
|
+
|
|
264
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
265
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
266
|
+
sage: P.push(1, 2)
|
|
267
|
+
sage: P.top()
|
|
268
|
+
(1, 2)
|
|
269
|
+
sage: P.top_value()
|
|
270
|
+
2
|
|
271
|
+
|
|
272
|
+
sage: P = PairingHeap_of_n_integers(3)
|
|
273
|
+
sage: P.top_value()
|
|
274
|
+
Traceback (most recent call last):
|
|
275
|
+
...
|
|
276
|
+
ValueError: trying to access the top of an empty heap
|
|
277
|
+
"""
|
|
278
|
+
if not self:
|
|
279
|
+
raise ValueError("trying to access the top of an empty heap")
|
|
280
|
+
return <object>self.root.value
|
|
281
|
+
|
|
282
|
+
cpdef void pop(self) noexcept:
|
|
283
|
+
r"""
|
|
284
|
+
Remove the top item from the heap.
|
|
285
|
+
|
|
286
|
+
If the heap is already empty, we do nothing.
|
|
287
|
+
|
|
288
|
+
EXAMPLES::
|
|
289
|
+
|
|
290
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
291
|
+
sage: P = PairingHeap_of_n_integers(5); P
|
|
292
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
293
|
+
sage: P.push(1, 2); P
|
|
294
|
+
PairingHeap_of_n_integers: capacity 5, size 1
|
|
295
|
+
sage: P.pop(); P
|
|
296
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
297
|
+
sage: P.pop(); P
|
|
298
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
299
|
+
"""
|
|
300
|
+
raise NotImplementedError()
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# ==============================================================================
|
|
304
|
+
# Class PairingHeap_of_n_integers
|
|
305
|
+
# ==============================================================================
|
|
306
|
+
|
|
307
|
+
cdef class PairingHeap_of_n_integers(PairingHeap_class):
|
|
308
|
+
r"""
|
|
309
|
+
Pairing Heap for items in range `[0, n - 1]`.
|
|
310
|
+
|
|
311
|
+
EXAMPLES::
|
|
312
|
+
|
|
313
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
314
|
+
sage: P = PairingHeap_of_n_integers(5); P
|
|
315
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
316
|
+
sage: P.push(1, 3)
|
|
317
|
+
sage: P.push(2, 2)
|
|
318
|
+
sage: P
|
|
319
|
+
PairingHeap_of_n_integers: capacity 5, size 2
|
|
320
|
+
sage: P.top()
|
|
321
|
+
(2, 2)
|
|
322
|
+
sage: P.decrease(1, 1)
|
|
323
|
+
sage: P.top()
|
|
324
|
+
(1, 1)
|
|
325
|
+
sage: P.pop()
|
|
326
|
+
sage: P.top()
|
|
327
|
+
(2, 2)
|
|
328
|
+
|
|
329
|
+
TESTS::
|
|
330
|
+
|
|
331
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
332
|
+
sage: P = PairingHeap_of_n_integers(0)
|
|
333
|
+
Traceback (most recent call last):
|
|
334
|
+
...
|
|
335
|
+
ValueError: the capacity of the heap must be strictly positive
|
|
336
|
+
sage: P = PairingHeap_of_n_integers(1); P
|
|
337
|
+
PairingHeap_of_n_integers: capacity 1, size 0
|
|
338
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
339
|
+
sage: P.push(11, 3)
|
|
340
|
+
Traceback (most recent call last):
|
|
341
|
+
...
|
|
342
|
+
ValueError: item must be in range [0, 4]
|
|
343
|
+
"""
|
|
344
|
+
|
|
345
|
+
def __init__(self, size_t n):
|
|
346
|
+
r"""
|
|
347
|
+
Construct the ``PairingHeap_of_n_integers`` where items are integers
|
|
348
|
+
from `0` to `n-1`.
|
|
349
|
+
|
|
350
|
+
INPUT:
|
|
351
|
+
|
|
352
|
+
- ``n`` -- strictly positive integer; the maximum number of items in the heap
|
|
353
|
+
|
|
354
|
+
EXAMPLES::
|
|
355
|
+
|
|
356
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
357
|
+
sage: P = PairingHeap_of_n_integers(5); P
|
|
358
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
359
|
+
sage: P.push(1, 2); P
|
|
360
|
+
PairingHeap_of_n_integers: capacity 5, size 1
|
|
361
|
+
sage: P.push(2, 3); P
|
|
362
|
+
PairingHeap_of_n_integers: capacity 5, size 2
|
|
363
|
+
sage: P.pop(); P
|
|
364
|
+
PairingHeap_of_n_integers: capacity 5, size 1
|
|
365
|
+
sage: P.push(10, 1)
|
|
366
|
+
Traceback (most recent call last):
|
|
367
|
+
...
|
|
368
|
+
ValueError: item must be in range [0, 4]
|
|
369
|
+
sage: PairingHeap_of_n_integers(1)
|
|
370
|
+
PairingHeap_of_n_integers: capacity 1, size 0
|
|
371
|
+
|
|
372
|
+
TESTS::
|
|
373
|
+
|
|
374
|
+
sage: PairingHeap_of_n_integers(0)
|
|
375
|
+
Traceback (most recent call last):
|
|
376
|
+
...
|
|
377
|
+
ValueError: the capacity of the heap must be strictly positive
|
|
378
|
+
sage: P = PairingHeap_of_n_integers(10)
|
|
379
|
+
sage: P.push(1, 1); P.push(7, 0); P.push(0, 4); P.pop(); P.push(5, 5)
|
|
380
|
+
sage: TestSuite(P).run(skip="_test_pickling")
|
|
381
|
+
"""
|
|
382
|
+
if not n:
|
|
383
|
+
raise ValueError("the capacity of the heap must be strictly positive")
|
|
384
|
+
self.n = n
|
|
385
|
+
self.root = NULL
|
|
386
|
+
self.nodes = <PairingHeapNodePy *>check_allocarray(n, sizeof(PairingHeapNodePy))
|
|
387
|
+
bitset_init(self.active, n)
|
|
388
|
+
self.number_of_items = 0
|
|
389
|
+
|
|
390
|
+
def __dealloc__(self):
|
|
391
|
+
"""
|
|
392
|
+
Deallocate ``self``.
|
|
393
|
+
|
|
394
|
+
EXAMPLES::
|
|
395
|
+
|
|
396
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
397
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
398
|
+
sage: del P
|
|
399
|
+
"""
|
|
400
|
+
sig_free(self.nodes)
|
|
401
|
+
bitset_free(self.active)
|
|
402
|
+
|
|
403
|
+
cpdef void push(self, size_t item, object value) except *:
|
|
404
|
+
r"""
|
|
405
|
+
Insert an item into the heap with specified value (priority).
|
|
406
|
+
|
|
407
|
+
INPUT:
|
|
408
|
+
|
|
409
|
+
- ``item`` -- nonnegative integer; the item to consider
|
|
410
|
+
|
|
411
|
+
- ``value`` -- the value associated with ``item``
|
|
412
|
+
|
|
413
|
+
EXAMPLES::
|
|
414
|
+
|
|
415
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
416
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
417
|
+
sage: P.push(1, 2)
|
|
418
|
+
sage: P.top()
|
|
419
|
+
(1, 2)
|
|
420
|
+
sage: P.push(3, 1)
|
|
421
|
+
sage: P.top()
|
|
422
|
+
(3, 1)
|
|
423
|
+
|
|
424
|
+
TESTS::
|
|
425
|
+
|
|
426
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
427
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
428
|
+
sage: P.push(1, 2)
|
|
429
|
+
sage: P.push(1, 2)
|
|
430
|
+
Traceback (most recent call last):
|
|
431
|
+
...
|
|
432
|
+
ValueError: 1 is already in the heap
|
|
433
|
+
sage: P.push(11, 2)
|
|
434
|
+
Traceback (most recent call last):
|
|
435
|
+
...
|
|
436
|
+
ValueError: item must be in range [0, 4]
|
|
437
|
+
sage: P.push(-1, 0)
|
|
438
|
+
Traceback (most recent call last):
|
|
439
|
+
...
|
|
440
|
+
OverflowError: can't convert negative value to size_t
|
|
441
|
+
"""
|
|
442
|
+
if item >= self.n:
|
|
443
|
+
raise ValueError(f"item must be in range [0, {self.n - 1}]")
|
|
444
|
+
if item in self:
|
|
445
|
+
raise ValueError(f"{item} is already in the heap")
|
|
446
|
+
|
|
447
|
+
cdef PairingHeapNodePy * p = self.nodes + item
|
|
448
|
+
Py_INCREF(value)
|
|
449
|
+
p.value = <PyObject *>value
|
|
450
|
+
p.prev = p.next = p.child = NULL
|
|
451
|
+
if self.root == NULL:
|
|
452
|
+
self.root = p
|
|
453
|
+
else:
|
|
454
|
+
self.root = PairingHeapNodePy._merge(self.root, p)
|
|
455
|
+
bitset_add(self.active, item)
|
|
456
|
+
self.number_of_items += 1
|
|
457
|
+
|
|
458
|
+
cpdef tuple top(self):
|
|
459
|
+
r"""
|
|
460
|
+
Return the top pair (item, value) of the heap.
|
|
461
|
+
|
|
462
|
+
EXAMPLES::
|
|
463
|
+
|
|
464
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
465
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
466
|
+
sage: P.push(1, 2)
|
|
467
|
+
sage: P.top()
|
|
468
|
+
(1, 2)
|
|
469
|
+
sage: P.push(3, 1)
|
|
470
|
+
sage: P.top()
|
|
471
|
+
(3, 1)
|
|
472
|
+
|
|
473
|
+
sage: P = PairingHeap_of_n_integers(3)
|
|
474
|
+
sage: P.top()
|
|
475
|
+
Traceback (most recent call last):
|
|
476
|
+
...
|
|
477
|
+
ValueError: trying to access the top of an empty heap
|
|
478
|
+
"""
|
|
479
|
+
if not self:
|
|
480
|
+
raise ValueError("trying to access the top of an empty heap")
|
|
481
|
+
return self.root - self.nodes, <object>self.root.value
|
|
482
|
+
|
|
483
|
+
cpdef size_t top_item(self) except *:
|
|
484
|
+
r"""
|
|
485
|
+
Return the top item of the heap.
|
|
486
|
+
|
|
487
|
+
EXAMPLES::
|
|
488
|
+
|
|
489
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
490
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
491
|
+
sage: P.push(1, 2)
|
|
492
|
+
sage: P.top()
|
|
493
|
+
(1, 2)
|
|
494
|
+
sage: P.top_item()
|
|
495
|
+
1
|
|
496
|
+
|
|
497
|
+
sage: P = PairingHeap_of_n_integers(3)
|
|
498
|
+
sage: P.top_item()
|
|
499
|
+
Traceback (most recent call last):
|
|
500
|
+
...
|
|
501
|
+
ValueError: trying to access the top of an empty heap
|
|
502
|
+
"""
|
|
503
|
+
if not self:
|
|
504
|
+
raise ValueError("trying to access the top of an empty heap")
|
|
505
|
+
return self.root - self.nodes
|
|
506
|
+
|
|
507
|
+
cpdef void pop(self) noexcept:
|
|
508
|
+
r"""
|
|
509
|
+
Remove the top item from the heap.
|
|
510
|
+
|
|
511
|
+
If the heap is already empty, we do nothing.
|
|
512
|
+
|
|
513
|
+
EXAMPLES::
|
|
514
|
+
|
|
515
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
516
|
+
sage: P = PairingHeap_of_n_integers(5); P
|
|
517
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
518
|
+
sage: P.push(1, 2); P
|
|
519
|
+
PairingHeap_of_n_integers: capacity 5, size 1
|
|
520
|
+
sage: P.push(2, 3); P
|
|
521
|
+
PairingHeap_of_n_integers: capacity 5, size 2
|
|
522
|
+
sage: P.pop(); P
|
|
523
|
+
PairingHeap_of_n_integers: capacity 5, size 1
|
|
524
|
+
sage: P.pop(); P
|
|
525
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
526
|
+
sage: P.pop(); P
|
|
527
|
+
PairingHeap_of_n_integers: capacity 5, size 0
|
|
528
|
+
"""
|
|
529
|
+
if not self:
|
|
530
|
+
return
|
|
531
|
+
cdef size_t item = self.top_item()
|
|
532
|
+
Py_XDECREF(<PyObject *>self.nodes[item].value)
|
|
533
|
+
bitset_remove(self.active, item)
|
|
534
|
+
self.number_of_items -= 1
|
|
535
|
+
self.root = PairingHeapNodePy._pair(self.root.child)
|
|
536
|
+
|
|
537
|
+
cpdef void decrease(self, size_t item, object new_value) except *:
|
|
538
|
+
r"""
|
|
539
|
+
Decrease the value of specified item.
|
|
540
|
+
|
|
541
|
+
This method is more permissive than it should as it can also be used to
|
|
542
|
+
push an item in the heap.
|
|
543
|
+
|
|
544
|
+
INPUT:
|
|
545
|
+
|
|
546
|
+
- ``item`` -- nonnegative integer; the item to consider
|
|
547
|
+
|
|
548
|
+
- ``new_value`` -- the new value for ``item``
|
|
549
|
+
|
|
550
|
+
EXAMPLES::
|
|
551
|
+
|
|
552
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
553
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
554
|
+
sage: 3 in P
|
|
555
|
+
False
|
|
556
|
+
sage: P.decrease(3, 33)
|
|
557
|
+
sage: 3 in P
|
|
558
|
+
True
|
|
559
|
+
sage: P.top()
|
|
560
|
+
(3, 33)
|
|
561
|
+
sage: P.push(1, 10)
|
|
562
|
+
sage: P.top()
|
|
563
|
+
(1, 10)
|
|
564
|
+
sage: P.decrease(3, 7)
|
|
565
|
+
sage: P.top()
|
|
566
|
+
(3, 7)
|
|
567
|
+
|
|
568
|
+
TESTS::
|
|
569
|
+
|
|
570
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
571
|
+
sage: P.push(1, 3)
|
|
572
|
+
sage: P.decrease(1, 2)
|
|
573
|
+
sage: P.decrease(1, 2)
|
|
574
|
+
Traceback (most recent call last):
|
|
575
|
+
...
|
|
576
|
+
ValueError: the new value must be less than the current value
|
|
577
|
+
"""
|
|
578
|
+
if item >= self.n:
|
|
579
|
+
raise ValueError(f"item must be in range [0, {self.n - 1}]")
|
|
580
|
+
cdef PairingHeapNodePy * p
|
|
581
|
+
if bitset_in(self.active, item):
|
|
582
|
+
p = self.nodes + item
|
|
583
|
+
if <object>p.value <= new_value:
|
|
584
|
+
raise ValueError("the new value must be less than the current value")
|
|
585
|
+
Py_XDECREF(<PyObject *>p.value)
|
|
586
|
+
Py_INCREF(new_value)
|
|
587
|
+
p.value = <PyObject *>new_value
|
|
588
|
+
if p.prev != NULL:
|
|
589
|
+
PairingHeapNodePy._unlink(p)
|
|
590
|
+
self.root = PairingHeapNodePy._merge(self.root, p)
|
|
591
|
+
else:
|
|
592
|
+
self.push(item, new_value)
|
|
593
|
+
|
|
594
|
+
def __contains__(self, size_t item):
|
|
595
|
+
r"""
|
|
596
|
+
Check whether the specified item is in the heap.
|
|
597
|
+
|
|
598
|
+
INPUT:
|
|
599
|
+
|
|
600
|
+
- ``item`` -- nonnegative integer; the item to consider
|
|
601
|
+
|
|
602
|
+
EXAMPLES::
|
|
603
|
+
|
|
604
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
605
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
606
|
+
sage: 3 in P
|
|
607
|
+
False
|
|
608
|
+
sage: P.push(3, 33)
|
|
609
|
+
sage: 3 in P
|
|
610
|
+
True
|
|
611
|
+
sage: 100 in P
|
|
612
|
+
False
|
|
613
|
+
"""
|
|
614
|
+
if item >= self.n:
|
|
615
|
+
return False
|
|
616
|
+
return bitset_in(self.active, item)
|
|
617
|
+
|
|
618
|
+
contains = __contains__
|
|
619
|
+
|
|
620
|
+
cpdef object value(self, size_t item):
|
|
621
|
+
r"""
|
|
622
|
+
Return the value associated with the item.
|
|
623
|
+
|
|
624
|
+
INPUT:
|
|
625
|
+
|
|
626
|
+
- ``item`` -- nonnegative integer; the item to consider
|
|
627
|
+
|
|
628
|
+
EXAMPLES::
|
|
629
|
+
|
|
630
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
631
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
632
|
+
sage: P.push(3, 33)
|
|
633
|
+
sage: P.push(1, 10)
|
|
634
|
+
sage: P.value(3)
|
|
635
|
+
33
|
|
636
|
+
sage: P.value(7)
|
|
637
|
+
Traceback (most recent call last):
|
|
638
|
+
...
|
|
639
|
+
ValueError: 7 is not in the heap
|
|
640
|
+
"""
|
|
641
|
+
if item not in self:
|
|
642
|
+
raise ValueError(f"{item} is not in the heap")
|
|
643
|
+
return <object>self.nodes[item].value
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
# ==============================================================================
|
|
647
|
+
# Class PairingHeap_of_n_hashables
|
|
648
|
+
# ==============================================================================
|
|
649
|
+
|
|
650
|
+
cdef class PairingHeap_of_n_hashables(PairingHeap_class):
|
|
651
|
+
r"""
|
|
652
|
+
Pairing Heap for `n` hashable items.
|
|
653
|
+
|
|
654
|
+
EXAMPLES::
|
|
655
|
+
|
|
656
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
657
|
+
sage: P = PairingHeap_of_n_hashables(5); P
|
|
658
|
+
PairingHeap_of_n_hashables: capacity 5, size 0
|
|
659
|
+
sage: P.push(1, 3)
|
|
660
|
+
sage: P.push('abc', 2); P
|
|
661
|
+
PairingHeap_of_n_hashables: capacity 5, size 2
|
|
662
|
+
sage: P.top()
|
|
663
|
+
('abc', 2)
|
|
664
|
+
sage: P.decrease(1, 1)
|
|
665
|
+
sage: P.top()
|
|
666
|
+
(1, 1)
|
|
667
|
+
sage: P.pop()
|
|
668
|
+
sage: P.top()
|
|
669
|
+
('abc', 2)
|
|
670
|
+
|
|
671
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
672
|
+
sage: P.push(1, (2, 3))
|
|
673
|
+
sage: P.push('a', (2, 2))
|
|
674
|
+
sage: P.push('b', (3, 3))
|
|
675
|
+
sage: P.push('c', (2, 1))
|
|
676
|
+
sage: P.top()
|
|
677
|
+
('c', (2, 1))
|
|
678
|
+
sage: P.push(Graph(2, immutable=True), (1, 7)) # needs sage.graphs
|
|
679
|
+
sage: P.top() # needs sage.graphs
|
|
680
|
+
(Graph on 2 vertices, (1, 7))
|
|
681
|
+
sage: P.decrease('b', (1, 5))
|
|
682
|
+
sage: P.top()
|
|
683
|
+
('b', (1, 5))
|
|
684
|
+
|
|
685
|
+
TESTS::
|
|
686
|
+
|
|
687
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
688
|
+
sage: P = PairingHeap_of_n_hashables(0)
|
|
689
|
+
Traceback (most recent call last):
|
|
690
|
+
...
|
|
691
|
+
ValueError: the capacity of the heap must be strictly positive
|
|
692
|
+
sage: P = PairingHeap_of_n_hashables(1); P
|
|
693
|
+
PairingHeap_of_n_hashables: capacity 1, size 0
|
|
694
|
+
sage: P.push(11, 3)
|
|
695
|
+
sage: P.push(12, 4)
|
|
696
|
+
Traceback (most recent call last):
|
|
697
|
+
...
|
|
698
|
+
ValueError: the heap is full
|
|
699
|
+
|
|
700
|
+
sage: P = PairingHeap_of_n_hashables(10)
|
|
701
|
+
sage: P.push(1, 'John')
|
|
702
|
+
sage: P.push(4, 42)
|
|
703
|
+
Traceback (most recent call last):
|
|
704
|
+
...
|
|
705
|
+
TypeError: unsupported operand parent(s) for >=: 'Integer Ring' and '<class 'str'>'
|
|
706
|
+
"""
|
|
707
|
+
|
|
708
|
+
def __init__(self, size_t n):
|
|
709
|
+
r"""
|
|
710
|
+
Construct the ``PairingHeap_of_n_hashables``.
|
|
711
|
+
|
|
712
|
+
This pairing heap has a maximum capacity of `n` items and each item is a
|
|
713
|
+
hashable object.
|
|
714
|
+
|
|
715
|
+
INPUT:
|
|
716
|
+
|
|
717
|
+
- ``n`` -- strictly positive integer; the maximum number of items in the heap
|
|
718
|
+
|
|
719
|
+
EXAMPLES::
|
|
720
|
+
|
|
721
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
722
|
+
sage: P = PairingHeap_of_n_hashables(2); P
|
|
723
|
+
PairingHeap_of_n_hashables: capacity 2, size 0
|
|
724
|
+
sage: P.push(1, 2)
|
|
725
|
+
sage: P
|
|
726
|
+
PairingHeap_of_n_hashables: capacity 2, size 1
|
|
727
|
+
sage: P.push(2, 3)
|
|
728
|
+
sage: P
|
|
729
|
+
PairingHeap_of_n_hashables: capacity 2, size 2
|
|
730
|
+
sage: P.full()
|
|
731
|
+
True
|
|
732
|
+
sage: P.push(10, 1)
|
|
733
|
+
Traceback (most recent call last):
|
|
734
|
+
...
|
|
735
|
+
ValueError: the heap is full
|
|
736
|
+
sage: P.pop()
|
|
737
|
+
sage: P
|
|
738
|
+
PairingHeap_of_n_hashables: capacity 2, size 1
|
|
739
|
+
sage: P.push(10, 1)
|
|
740
|
+
|
|
741
|
+
TESTS::
|
|
742
|
+
|
|
743
|
+
sage: P = PairingHeap_of_n_hashables(0)
|
|
744
|
+
Traceback (most recent call last):
|
|
745
|
+
...
|
|
746
|
+
ValueError: the capacity of the heap must be strictly positive
|
|
747
|
+
sage: P = PairingHeap_of_n_hashables(1); P
|
|
748
|
+
PairingHeap_of_n_hashables: capacity 1, size 0
|
|
749
|
+
sage: P = PairingHeap_of_n_hashables(6)
|
|
750
|
+
sage: P.push(1, -0.5); P.push(frozenset(), 1); P.pop(); P.push('a', 3.5)
|
|
751
|
+
sage: TestSuite(P).run(skip="_test_pickling")
|
|
752
|
+
"""
|
|
753
|
+
if not n:
|
|
754
|
+
raise ValueError("the capacity of the heap must be strictly positive")
|
|
755
|
+
self.n = n
|
|
756
|
+
self.root = NULL
|
|
757
|
+
self.nodes = <PairingHeapNodePy *>check_allocarray(n, sizeof(PairingHeapNodePy))
|
|
758
|
+
self.number_of_items = 0
|
|
759
|
+
self._int_to_item = [None] * n
|
|
760
|
+
self._item_to_int = dict()
|
|
761
|
+
self.free_idx = list(range(n))
|
|
762
|
+
|
|
763
|
+
def __dealloc__(self):
|
|
764
|
+
"""
|
|
765
|
+
Deallocate ``self``.
|
|
766
|
+
|
|
767
|
+
EXAMPLES::
|
|
768
|
+
|
|
769
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_integers
|
|
770
|
+
sage: P = PairingHeap_of_n_integers(5)
|
|
771
|
+
sage: del P
|
|
772
|
+
"""
|
|
773
|
+
sig_free(self.nodes)
|
|
774
|
+
|
|
775
|
+
cpdef void push(self, object item, object value) except *:
|
|
776
|
+
r"""
|
|
777
|
+
Insert an item into the heap with specified value (priority).
|
|
778
|
+
|
|
779
|
+
INPUT:
|
|
780
|
+
|
|
781
|
+
- ``item`` -- a hashable object; the item to add
|
|
782
|
+
|
|
783
|
+
- ``value`` -- the value associated with ``item``
|
|
784
|
+
|
|
785
|
+
EXAMPLES::
|
|
786
|
+
|
|
787
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
788
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
789
|
+
sage: P.push(1, 2)
|
|
790
|
+
sage: P.top()
|
|
791
|
+
(1, 2)
|
|
792
|
+
sage: P.push(3, 1)
|
|
793
|
+
sage: P.top()
|
|
794
|
+
(3, 1)
|
|
795
|
+
|
|
796
|
+
TESTS::
|
|
797
|
+
|
|
798
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
799
|
+
sage: P = PairingHeap_of_n_hashables(2)
|
|
800
|
+
sage: P.push(1, 2)
|
|
801
|
+
sage: P.push(1, 2)
|
|
802
|
+
Traceback (most recent call last):
|
|
803
|
+
...
|
|
804
|
+
ValueError: 1 is already in the heap
|
|
805
|
+
sage: P.push(11, 2)
|
|
806
|
+
sage: P.push(7, 5)
|
|
807
|
+
Traceback (most recent call last):
|
|
808
|
+
...
|
|
809
|
+
ValueError: the heap is full
|
|
810
|
+
"""
|
|
811
|
+
if item in self:
|
|
812
|
+
raise ValueError(f"{item} is already in the heap")
|
|
813
|
+
if self.full():
|
|
814
|
+
raise ValueError("the heap is full")
|
|
815
|
+
|
|
816
|
+
cdef size_t idx = self.free_idx.pop()
|
|
817
|
+
self._int_to_item[idx] = item
|
|
818
|
+
self._item_to_int[item] = idx
|
|
819
|
+
cdef PairingHeapNodePy * p = self.nodes + idx
|
|
820
|
+
Py_INCREF(value)
|
|
821
|
+
p.value = <PyObject *>value
|
|
822
|
+
p.prev = p.next = p.child = NULL
|
|
823
|
+
if self.root == NULL:
|
|
824
|
+
self.root = p
|
|
825
|
+
else:
|
|
826
|
+
self.root = PairingHeapNodePy._merge(self.root, p)
|
|
827
|
+
self.number_of_items += 1
|
|
828
|
+
|
|
829
|
+
cpdef tuple top(self):
|
|
830
|
+
r"""
|
|
831
|
+
Return the top pair (item, value) of the heap.
|
|
832
|
+
|
|
833
|
+
EXAMPLES::
|
|
834
|
+
|
|
835
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
836
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
837
|
+
sage: P.push(1, 2)
|
|
838
|
+
sage: P.top()
|
|
839
|
+
(1, 2)
|
|
840
|
+
sage: P.push(3, 1)
|
|
841
|
+
sage: P.top()
|
|
842
|
+
(3, 1)
|
|
843
|
+
|
|
844
|
+
sage: P = PairingHeap_of_n_hashables(3)
|
|
845
|
+
sage: P.top()
|
|
846
|
+
Traceback (most recent call last):
|
|
847
|
+
...
|
|
848
|
+
ValueError: trying to access the top of an empty heap
|
|
849
|
+
"""
|
|
850
|
+
if not self:
|
|
851
|
+
raise ValueError("trying to access the top of an empty heap")
|
|
852
|
+
cdef size_t idx = self.root - self.nodes
|
|
853
|
+
return self._int_to_item[idx], <object>self.root.value
|
|
854
|
+
|
|
855
|
+
cpdef object top_item(self):
|
|
856
|
+
r"""
|
|
857
|
+
Return the top item of the heap.
|
|
858
|
+
|
|
859
|
+
EXAMPLES::
|
|
860
|
+
|
|
861
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
862
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
863
|
+
sage: P.push(1, 2)
|
|
864
|
+
sage: P.top()
|
|
865
|
+
(1, 2)
|
|
866
|
+
sage: P.top_item()
|
|
867
|
+
1
|
|
868
|
+
|
|
869
|
+
sage: P = PairingHeap_of_n_hashables(3)
|
|
870
|
+
sage: P.top_item()
|
|
871
|
+
Traceback (most recent call last):
|
|
872
|
+
...
|
|
873
|
+
ValueError: trying to access the top of an empty heap
|
|
874
|
+
"""
|
|
875
|
+
if not self:
|
|
876
|
+
raise ValueError("trying to access the top of an empty heap")
|
|
877
|
+
cdef size_t idx = self.root - self.nodes
|
|
878
|
+
return self._int_to_item[idx]
|
|
879
|
+
|
|
880
|
+
cpdef void pop(self) noexcept:
|
|
881
|
+
r"""
|
|
882
|
+
Remove the top item from the heap.
|
|
883
|
+
|
|
884
|
+
If the heap is already empty, we do nothing.
|
|
885
|
+
|
|
886
|
+
EXAMPLES::
|
|
887
|
+
|
|
888
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
889
|
+
sage: P = PairingHeap_of_n_hashables(5); len(P)
|
|
890
|
+
0
|
|
891
|
+
sage: P.push(1, 2); len(P)
|
|
892
|
+
1
|
|
893
|
+
sage: P.push(2, 3); len(P)
|
|
894
|
+
2
|
|
895
|
+
sage: P.pop(); len(P)
|
|
896
|
+
1
|
|
897
|
+
sage: P.pop(); len(P)
|
|
898
|
+
0
|
|
899
|
+
sage: P.pop(); len(P)
|
|
900
|
+
0
|
|
901
|
+
"""
|
|
902
|
+
if not self:
|
|
903
|
+
return
|
|
904
|
+
cdef object item = self.top_item()
|
|
905
|
+
cdef size_t idx = self._item_to_int[item]
|
|
906
|
+
Py_XDECREF(<PyObject *>self.nodes[idx].value)
|
|
907
|
+
self.free_idx.append(idx)
|
|
908
|
+
del self._item_to_int[item]
|
|
909
|
+
self.number_of_items -= 1
|
|
910
|
+
self.root = PairingHeapNodePy._pair(self.root.child)
|
|
911
|
+
|
|
912
|
+
cpdef void decrease(self, object item, object new_value) except *:
|
|
913
|
+
r"""
|
|
914
|
+
Decrease the value of specified item.
|
|
915
|
+
|
|
916
|
+
This method is more permissive than it should as it can also be used to
|
|
917
|
+
push an item in the heap.
|
|
918
|
+
|
|
919
|
+
INPUT:
|
|
920
|
+
|
|
921
|
+
- ``item`` -- the item to consider
|
|
922
|
+
|
|
923
|
+
- ``new_value`` -- the new value for ``item``
|
|
924
|
+
|
|
925
|
+
EXAMPLES::
|
|
926
|
+
|
|
927
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
928
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
929
|
+
sage: 3 in P
|
|
930
|
+
False
|
|
931
|
+
sage: P.decrease(3, 33)
|
|
932
|
+
sage: 3 in P
|
|
933
|
+
True
|
|
934
|
+
sage: P.top()
|
|
935
|
+
(3, 33)
|
|
936
|
+
sage: P.push(1, 10)
|
|
937
|
+
sage: P.top()
|
|
938
|
+
(1, 10)
|
|
939
|
+
sage: P.decrease(3, 7)
|
|
940
|
+
sage: P.top()
|
|
941
|
+
(3, 7)
|
|
942
|
+
|
|
943
|
+
TESTS::
|
|
944
|
+
|
|
945
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
946
|
+
sage: P.push(1, 3)
|
|
947
|
+
sage: P.decrease(1, 2)
|
|
948
|
+
sage: P.decrease(1, 2)
|
|
949
|
+
Traceback (most recent call last):
|
|
950
|
+
...
|
|
951
|
+
ValueError: the new value must be less than the current value
|
|
952
|
+
"""
|
|
953
|
+
cdef PairingHeapNodePy * p
|
|
954
|
+
cdef size_t idx
|
|
955
|
+
if item in self:
|
|
956
|
+
idx = self._item_to_int[item]
|
|
957
|
+
p = self.nodes + idx
|
|
958
|
+
if <object>p.value <= new_value:
|
|
959
|
+
raise ValueError("the new value must be less than the current value")
|
|
960
|
+
Py_XDECREF(<PyObject *>p.value)
|
|
961
|
+
Py_INCREF(new_value)
|
|
962
|
+
p.value = <PyObject *>new_value
|
|
963
|
+
if p.prev != NULL:
|
|
964
|
+
PairingHeapNodePy._unlink(p)
|
|
965
|
+
self.root = PairingHeapNodePy._merge(self.root, p)
|
|
966
|
+
else:
|
|
967
|
+
self.push(item, new_value)
|
|
968
|
+
|
|
969
|
+
def __contains__(self, object item):
|
|
970
|
+
r"""
|
|
971
|
+
Check whether the specified item is in the heap.
|
|
972
|
+
|
|
973
|
+
INPUT:
|
|
974
|
+
|
|
975
|
+
- ``item`` -- the item to consider
|
|
976
|
+
|
|
977
|
+
EXAMPLES::
|
|
978
|
+
|
|
979
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
980
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
981
|
+
sage: 3 in P
|
|
982
|
+
False
|
|
983
|
+
sage: P.push(3, 33)
|
|
984
|
+
sage: 3 in P
|
|
985
|
+
True
|
|
986
|
+
sage: 100 in P
|
|
987
|
+
False
|
|
988
|
+
"""
|
|
989
|
+
return item in self._item_to_int
|
|
990
|
+
|
|
991
|
+
contains = __contains__
|
|
992
|
+
|
|
993
|
+
cpdef object value(self, object item):
|
|
994
|
+
r"""
|
|
995
|
+
Return the value associated with the item.
|
|
996
|
+
|
|
997
|
+
INPUT:
|
|
998
|
+
|
|
999
|
+
- ``item`` -- the item to consider
|
|
1000
|
+
|
|
1001
|
+
EXAMPLES::
|
|
1002
|
+
|
|
1003
|
+
sage: from sage.data_structures.pairing_heap import PairingHeap_of_n_hashables
|
|
1004
|
+
sage: P = PairingHeap_of_n_hashables(5)
|
|
1005
|
+
sage: P.push(3, 33)
|
|
1006
|
+
sage: P.push(1, 10)
|
|
1007
|
+
sage: P.value(3)
|
|
1008
|
+
33
|
|
1009
|
+
sage: P.value(7)
|
|
1010
|
+
Traceback (most recent call last):
|
|
1011
|
+
...
|
|
1012
|
+
ValueError: 7 is not in the heap
|
|
1013
|
+
"""
|
|
1014
|
+
if item not in self:
|
|
1015
|
+
raise ValueError(f"{item} is not in the heap")
|
|
1016
|
+
cdef size_t idx = self._item_to_int[item]
|
|
1017
|
+
return <object>self.nodes[idx].value
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
# ==============================================================================
|
|
1021
|
+
# Methods to check the validity of the pairing heaps
|
|
1022
|
+
# ==============================================================================
|
|
1023
|
+
|
|
1024
|
+
def _test_PairingHeap_from_C(n=100):
|
|
1025
|
+
r"""
|
|
1026
|
+
Test :class:`~sage.data_structures.pairing_heap.PairingHeap`.
|
|
1027
|
+
|
|
1028
|
+
INPUT:
|
|
1029
|
+
|
|
1030
|
+
- ``n`` -- a strictly positive integer (default: 100); the maximum capacity
|
|
1031
|
+
of the heap
|
|
1032
|
+
|
|
1033
|
+
TESTS::
|
|
1034
|
+
|
|
1035
|
+
sage: from sage.data_structures.pairing_heap import _test_PairingHeap_from_C
|
|
1036
|
+
sage: _test_PairingHeap_from_C(100) # needs sage.symbolic
|
|
1037
|
+
"""
|
|
1038
|
+
from sage.misc.prandom import randint, shuffle
|
|
1039
|
+
sig_on()
|
|
1040
|
+
cdef PairingHeap[size_t, size_t] PH = PairingHeap[size_t, size_t]()
|
|
1041
|
+
sig_off()
|
|
1042
|
+
|
|
1043
|
+
# Initialize a list of tuples (value, item) randomly ordered
|
|
1044
|
+
items = list(range(n))
|
|
1045
|
+
values = list(range(n))
|
|
1046
|
+
shuffle(items)
|
|
1047
|
+
shuffle(values)
|
|
1048
|
+
cdef list Lref = list(zip(values, items))
|
|
1049
|
+
|
|
1050
|
+
for value, item in Lref:
|
|
1051
|
+
PH.push(item, value)
|
|
1052
|
+
sig_check()
|
|
1053
|
+
|
|
1054
|
+
L = []
|
|
1055
|
+
while not PH.empty():
|
|
1056
|
+
item, value = PH.top()
|
|
1057
|
+
L.append((value, item))
|
|
1058
|
+
PH.pop()
|
|
1059
|
+
sig_check()
|
|
1060
|
+
|
|
1061
|
+
if L != sorted(Lref):
|
|
1062
|
+
raise ValueError('the order is not good')
|
|
1063
|
+
|
|
1064
|
+
# Test decrease key operations. We first push items in the heap with an
|
|
1065
|
+
# excess of k in the value. Then we decrease the keys in a random order by
|
|
1066
|
+
# random values until returning to the original values. We finally check the
|
|
1067
|
+
# validity of the resulting ordering.
|
|
1068
|
+
k = 10
|
|
1069
|
+
dec = {item: k for item in items}
|
|
1070
|
+
shuffle(Lref)
|
|
1071
|
+
for value, item in Lref:
|
|
1072
|
+
PH.push(item, value + k)
|
|
1073
|
+
sig_check()
|
|
1074
|
+
|
|
1075
|
+
L = list(items)
|
|
1076
|
+
while L:
|
|
1077
|
+
i = randint(0, len(L) - 1)
|
|
1078
|
+
item = L[i]
|
|
1079
|
+
d = randint(1, dec[item])
|
|
1080
|
+
dec[item] -= d
|
|
1081
|
+
if not dec[item]:
|
|
1082
|
+
L[i] = L[-1]
|
|
1083
|
+
L.pop()
|
|
1084
|
+
PH.decrease(item, PH.value(item) - d)
|
|
1085
|
+
sig_check()
|
|
1086
|
+
|
|
1087
|
+
L = []
|
|
1088
|
+
while not PH.empty():
|
|
1089
|
+
item, value = PH.top()
|
|
1090
|
+
L.append((value, item))
|
|
1091
|
+
PH.pop()
|
|
1092
|
+
sig_check()
|
|
1093
|
+
|
|
1094
|
+
if L != sorted(Lref):
|
|
1095
|
+
raise ValueError('the order is not good')
|
|
1096
|
+
|
|
1097
|
+
# Different cost function
|
|
1098
|
+
from sage.functions.trig import sin, cos
|
|
1099
|
+
sig_on()
|
|
1100
|
+
cdef PairingHeap[size_t, pair[size_t, size_t]] HH = PairingHeap[size_t, pair[size_t, size_t]]()
|
|
1101
|
+
sig_off()
|
|
1102
|
+
|
|
1103
|
+
for i in range(n):
|
|
1104
|
+
HH.push(i, (sin(i), cos(i)))
|
|
1105
|
+
sig_check()
|
|
1106
|
+
|
|
1107
|
+
L = []
|
|
1108
|
+
while not HH.empty():
|
|
1109
|
+
L.append(HH.top())
|
|
1110
|
+
HH.pop()
|
|
1111
|
+
sig_check()
|
|
1112
|
+
|
|
1113
|
+
for (u, cu), (v, cv) in zip(L, L[1:]):
|
|
1114
|
+
if cu > cv:
|
|
1115
|
+
print(u, cu, v, cv)
|
|
1116
|
+
|
|
1117
|
+
# We finally show that an error is raised when trying to access the top of
|
|
1118
|
+
# an empty heap
|
|
1119
|
+
try:
|
|
1120
|
+
_ = HH.top()
|
|
1121
|
+
print("something goes wrong, the error has not been raised")
|
|
1122
|
+
except ValueError as msg:
|
|
1123
|
+
# The error has been properly handled
|
|
1124
|
+
pass
|
|
1125
|
+
|
|
1126
|
+
try:
|
|
1127
|
+
_ = HH.top_item()
|
|
1128
|
+
print("something goes wrong, the error has not been raised")
|
|
1129
|
+
except ValueError as msg:
|
|
1130
|
+
# The error has been properly handled
|
|
1131
|
+
pass
|
|
1132
|
+
|
|
1133
|
+
try:
|
|
1134
|
+
_ = HH.top_value()
|
|
1135
|
+
print("something goes wrong, the error has not been raised")
|
|
1136
|
+
except ValueError as msg:
|
|
1137
|
+
# The error has been properly handled
|
|
1138
|
+
pass
|
|
1139
|
+
|
|
1140
|
+
# Or to get the value associated to an item that is not in the heap
|
|
1141
|
+
try:
|
|
1142
|
+
_ = HH.value(123)
|
|
1143
|
+
print("something goes wrong, the error has not been raised")
|
|
1144
|
+
except ValueError as msg:
|
|
1145
|
+
# The error has been properly handled
|
|
1146
|
+
pass
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
def _test_PairingHeap_of_n_integers(n=100):
|
|
1150
|
+
r"""
|
|
1151
|
+
Test :class:`~sage.data_structures.pairing_heap.PairingHeap_of_n_integers`.
|
|
1152
|
+
|
|
1153
|
+
INPUT:
|
|
1154
|
+
|
|
1155
|
+
- ``n`` -- a strictly positive integer (default: 100); the maximum capacity
|
|
1156
|
+
of the heap
|
|
1157
|
+
|
|
1158
|
+
TESTS::
|
|
1159
|
+
|
|
1160
|
+
sage: from sage.data_structures.pairing_heap import _test_PairingHeap_of_n_integers
|
|
1161
|
+
sage: _test_PairingHeap_of_n_integers(100)
|
|
1162
|
+
"""
|
|
1163
|
+
from sage.misc.prandom import randint, shuffle
|
|
1164
|
+
|
|
1165
|
+
sig_on()
|
|
1166
|
+
cdef PairingHeap_of_n_integers P = PairingHeap_of_n_integers(n)
|
|
1167
|
+
sig_off()
|
|
1168
|
+
|
|
1169
|
+
# Initialize a list of tuples (value, item) randomly ordered
|
|
1170
|
+
cdef list items = list(range(n))
|
|
1171
|
+
cdef list values = list(range(n))
|
|
1172
|
+
shuffle(items)
|
|
1173
|
+
shuffle(values)
|
|
1174
|
+
cdef list Lref = list(zip(values, items))
|
|
1175
|
+
|
|
1176
|
+
cdef int value, item
|
|
1177
|
+
for value, item in Lref:
|
|
1178
|
+
P.push(item, value)
|
|
1179
|
+
sig_check()
|
|
1180
|
+
|
|
1181
|
+
cdef list L = []
|
|
1182
|
+
while P:
|
|
1183
|
+
item, value = P.top()
|
|
1184
|
+
L.append((value, item))
|
|
1185
|
+
P.pop()
|
|
1186
|
+
sig_check()
|
|
1187
|
+
|
|
1188
|
+
if L != sorted(Lref):
|
|
1189
|
+
raise ValueError('the order is not good')
|
|
1190
|
+
|
|
1191
|
+
# Test decrease key operations. We first push items in the heap with an
|
|
1192
|
+
# excess of k in the value. Then we decrease the keys in a random order by
|
|
1193
|
+
# random values until returning to the original values. We finally check the
|
|
1194
|
+
# validity of the resulting ordering.
|
|
1195
|
+
cdef int k = 10
|
|
1196
|
+
cdef list dec = [k] * n
|
|
1197
|
+
shuffle(Lref)
|
|
1198
|
+
for value, item in Lref:
|
|
1199
|
+
P.push(item, value + k)
|
|
1200
|
+
sig_check()
|
|
1201
|
+
|
|
1202
|
+
L = list(items)
|
|
1203
|
+
while L:
|
|
1204
|
+
i = randint(0, len(L) - 1)
|
|
1205
|
+
item = L[i]
|
|
1206
|
+
d = randint(1, dec[item])
|
|
1207
|
+
dec[item] -= d
|
|
1208
|
+
if not dec[item]:
|
|
1209
|
+
L[i] = L[-1]
|
|
1210
|
+
L.pop()
|
|
1211
|
+
P.decrease(item, P.value(item) - d)
|
|
1212
|
+
sig_check()
|
|
1213
|
+
|
|
1214
|
+
L = []
|
|
1215
|
+
while P:
|
|
1216
|
+
item, value = P.top()
|
|
1217
|
+
L.append((value, item))
|
|
1218
|
+
P.pop()
|
|
1219
|
+
sig_check()
|
|
1220
|
+
|
|
1221
|
+
if L != sorted(Lref):
|
|
1222
|
+
raise ValueError('the order is not good')
|
|
1223
|
+
|
|
1224
|
+
# We finally show that an error is raised when trying to access the top of
|
|
1225
|
+
# an empty heap
|
|
1226
|
+
try:
|
|
1227
|
+
_ = P.top()
|
|
1228
|
+
print("something goes wrong, the error has not been raised")
|
|
1229
|
+
except ValueError as msg:
|
|
1230
|
+
# The error has been properly handled
|
|
1231
|
+
pass
|
|
1232
|
+
|
|
1233
|
+
try:
|
|
1234
|
+
_ = P.top_item()
|
|
1235
|
+
print("something goes wrong, the error has not been raised")
|
|
1236
|
+
except ValueError as msg:
|
|
1237
|
+
# The error has been properly handled
|
|
1238
|
+
pass
|
|
1239
|
+
|
|
1240
|
+
try:
|
|
1241
|
+
_ = P.top_value()
|
|
1242
|
+
print("something goes wrong, the error has not been raised")
|
|
1243
|
+
except ValueError as msg:
|
|
1244
|
+
# The error has been properly handled
|
|
1245
|
+
pass
|
|
1246
|
+
|
|
1247
|
+
# Or to get the value associated to an item that is not in the heap
|
|
1248
|
+
try:
|
|
1249
|
+
_ = P.value(123)
|
|
1250
|
+
print("something goes wrong, the error has not been raised")
|
|
1251
|
+
except ValueError as msg:
|
|
1252
|
+
# The error has been properly handled
|
|
1253
|
+
pass
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
def _test_PairingHeap_of_n_hashables(n=100):
|
|
1257
|
+
r"""
|
|
1258
|
+
Test :class:`~sage.data_structures.pairing_heap.PairingHeap_of_n_hashables`.
|
|
1259
|
+
|
|
1260
|
+
INPUT:
|
|
1261
|
+
|
|
1262
|
+
- ``n`` -- a strictly positive integer (default: 100); the maximum capacity
|
|
1263
|
+
of the heap
|
|
1264
|
+
|
|
1265
|
+
TESTS::
|
|
1266
|
+
|
|
1267
|
+
sage: from sage.data_structures.pairing_heap import _test_PairingHeap_of_n_hashables
|
|
1268
|
+
sage: _test_PairingHeap_of_n_hashables(100)
|
|
1269
|
+
"""
|
|
1270
|
+
from sage.misc.prandom import randint, shuffle
|
|
1271
|
+
|
|
1272
|
+
sig_on()
|
|
1273
|
+
cdef PairingHeap_of_n_hashables P = PairingHeap_of_n_hashables(n)
|
|
1274
|
+
sig_off()
|
|
1275
|
+
|
|
1276
|
+
# Initialize a list of tuples (value, item) randomly ordered
|
|
1277
|
+
cdef list items = [(str(i), i) for i in range(n)]
|
|
1278
|
+
cdef list values = list(range(n))
|
|
1279
|
+
shuffle(items)
|
|
1280
|
+
shuffle(values)
|
|
1281
|
+
cdef list Lref = list(zip(values, items))
|
|
1282
|
+
|
|
1283
|
+
for value, item in Lref:
|
|
1284
|
+
P.push(item, value)
|
|
1285
|
+
sig_check()
|
|
1286
|
+
|
|
1287
|
+
cdef list L = []
|
|
1288
|
+
while P:
|
|
1289
|
+
item, value = P.top()
|
|
1290
|
+
L.append((value, item))
|
|
1291
|
+
P.pop()
|
|
1292
|
+
sig_check()
|
|
1293
|
+
|
|
1294
|
+
if L != sorted(Lref):
|
|
1295
|
+
raise ValueError('the order is not good')
|
|
1296
|
+
|
|
1297
|
+
# Test decrease key operations. We first push items in the heap with an
|
|
1298
|
+
# excess of k in the value. Then we decrease the keys in a random order by
|
|
1299
|
+
# random values until returning to the original values. We finally check the
|
|
1300
|
+
# validity of the resulting ordering.
|
|
1301
|
+
cdef int k = 10
|
|
1302
|
+
cdef dict dec = {item: k for item in items}
|
|
1303
|
+
shuffle(Lref)
|
|
1304
|
+
for value, item in Lref:
|
|
1305
|
+
P.push(item, value + k)
|
|
1306
|
+
sig_check()
|
|
1307
|
+
|
|
1308
|
+
L = list(items)
|
|
1309
|
+
while L:
|
|
1310
|
+
i = randint(0, len(L) - 1)
|
|
1311
|
+
item = L[i]
|
|
1312
|
+
d = randint(1, dec[item])
|
|
1313
|
+
dec[item] -= d
|
|
1314
|
+
if not dec[item]:
|
|
1315
|
+
L[i] = L[-1]
|
|
1316
|
+
L.pop()
|
|
1317
|
+
P.decrease(item, P.value(item) - d)
|
|
1318
|
+
sig_check()
|
|
1319
|
+
|
|
1320
|
+
L = []
|
|
1321
|
+
while P:
|
|
1322
|
+
item, value = P.top()
|
|
1323
|
+
L.append((value, item))
|
|
1324
|
+
P.pop()
|
|
1325
|
+
sig_check()
|
|
1326
|
+
|
|
1327
|
+
if L != sorted(Lref):
|
|
1328
|
+
raise ValueError('the order is not good')
|
|
1329
|
+
|
|
1330
|
+
# We finally show that an error is raised when trying to access the top of
|
|
1331
|
+
# an empty heap
|
|
1332
|
+
try:
|
|
1333
|
+
_ = P.top()
|
|
1334
|
+
print("something goes wrong, the error has not been raised")
|
|
1335
|
+
except ValueError as msg:
|
|
1336
|
+
# The error has been properly handled
|
|
1337
|
+
pass
|
|
1338
|
+
|
|
1339
|
+
try:
|
|
1340
|
+
_ = P.top_item()
|
|
1341
|
+
print("something goes wrong, the error has not been raised")
|
|
1342
|
+
except ValueError as msg:
|
|
1343
|
+
# The error has been properly handled
|
|
1344
|
+
pass
|
|
1345
|
+
|
|
1346
|
+
try:
|
|
1347
|
+
_ = P.top_value()
|
|
1348
|
+
print("something goes wrong, the error has not been raised")
|
|
1349
|
+
except ValueError as msg:
|
|
1350
|
+
# The error has been properly handled
|
|
1351
|
+
pass
|
|
1352
|
+
|
|
1353
|
+
# Or to get the value associated to an item that is not in the heap
|
|
1354
|
+
try:
|
|
1355
|
+
_ = P.value(123)
|
|
1356
|
+
print("something goes wrong, the error has not been raised")
|
|
1357
|
+
except ValueError as msg:
|
|
1358
|
+
# The error has been properly handled
|
|
1359
|
+
pass
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
def _compare_heaps(n=100, verbose=False):
|
|
1363
|
+
r"""
|
|
1364
|
+
Check that the heaps behave the same.
|
|
1365
|
+
|
|
1366
|
+
This method selects a list of instructions: push items in some order,
|
|
1367
|
+
decrease the values of the items in some order, extract all items in order.
|
|
1368
|
+
Then it applies the same instructions to a ``PairingHeap``, a
|
|
1369
|
+
:class:`PairingHeap_of_n_integers` and a
|
|
1370
|
+
:class:`PairingHeap_of_n_hashables`. It checks that all heaps report the
|
|
1371
|
+
list of items in the same order and it measures the running time.
|
|
1372
|
+
|
|
1373
|
+
INPUT:
|
|
1374
|
+
|
|
1375
|
+
- ``n`` -- a strictly positive integer (default: 100); the maximum capacity
|
|
1376
|
+
of the heap
|
|
1377
|
+
|
|
1378
|
+
- ``verbose`` -- boolean (default: ``False``); whether to display
|
|
1379
|
+
information about the running times
|
|
1380
|
+
|
|
1381
|
+
EXAMPLES::
|
|
1382
|
+
|
|
1383
|
+
sage: from sage.data_structures.pairing_heap import _compare_heaps
|
|
1384
|
+
sage: _compare_heaps(n=100)
|
|
1385
|
+
sage: _compare_heaps(n=100, verbose=True) # random
|
|
1386
|
+
PairingHeap_of_n_integers: 7.800000000024454e-05
|
|
1387
|
+
PairingHeap_of_n_hashables: 9.400000000026054e-05
|
|
1388
|
+
PairingHeap (C++): 6.899999999987472e-05
|
|
1389
|
+
sage: _compare_heaps(1000000, verbose=True) # not tested (long time), random
|
|
1390
|
+
PairingHeap_of_n_integers: 1.5106779999999995
|
|
1391
|
+
PairingHeap_of_n_hashables: 4.998040000000001
|
|
1392
|
+
PairingHeap (C++): 1.7841750000000012
|
|
1393
|
+
"""
|
|
1394
|
+
from sage.misc.prandom import shuffle
|
|
1395
|
+
from sage.misc.timing import cputime
|
|
1396
|
+
|
|
1397
|
+
items = list(range(n))
|
|
1398
|
+
values = list(range(n))
|
|
1399
|
+
shuffle(items)
|
|
1400
|
+
shuffle(values)
|
|
1401
|
+
Lref = list(zip(values, items))
|
|
1402
|
+
k = 10
|
|
1403
|
+
dec_order = list(items)
|
|
1404
|
+
shuffle(dec_order)
|
|
1405
|
+
|
|
1406
|
+
t = cputime()
|
|
1407
|
+
sig_on()
|
|
1408
|
+
cdef PairingHeap_of_n_integers P = PairingHeap_of_n_integers(n)
|
|
1409
|
+
sig_off()
|
|
1410
|
+
for value, item in Lref:
|
|
1411
|
+
P.push(item, value + k)
|
|
1412
|
+
sig_check()
|
|
1413
|
+
for item in dec_order:
|
|
1414
|
+
P.decrease(item, P.value(item) - k)
|
|
1415
|
+
sig_check()
|
|
1416
|
+
LP = []
|
|
1417
|
+
while P:
|
|
1418
|
+
LP.append(P.top())
|
|
1419
|
+
P.pop()
|
|
1420
|
+
sig_check()
|
|
1421
|
+
t = cputime(t)
|
|
1422
|
+
if verbose:
|
|
1423
|
+
print(f"PairingHeap_of_n_integers: {t}")
|
|
1424
|
+
|
|
1425
|
+
t = cputime()
|
|
1426
|
+
sig_on()
|
|
1427
|
+
cdef PairingHeap_of_n_hashables Q = PairingHeap_of_n_hashables(n)
|
|
1428
|
+
sig_off()
|
|
1429
|
+
for value, item in Lref:
|
|
1430
|
+
Q.push(item, value + k)
|
|
1431
|
+
sig_check()
|
|
1432
|
+
for item in dec_order:
|
|
1433
|
+
Q.decrease(item, Q.value(item) - k)
|
|
1434
|
+
sig_check()
|
|
1435
|
+
LQ = []
|
|
1436
|
+
while Q:
|
|
1437
|
+
LQ.append(Q.top())
|
|
1438
|
+
Q.pop()
|
|
1439
|
+
sig_check()
|
|
1440
|
+
t = cputime(t)
|
|
1441
|
+
if verbose:
|
|
1442
|
+
print(f"PairingHeap_of_n_hashables: {t}")
|
|
1443
|
+
|
|
1444
|
+
t = cputime()
|
|
1445
|
+
sig_on()
|
|
1446
|
+
cdef PairingHeap[size_t, size_t] PH = PairingHeap[size_t, size_t]()
|
|
1447
|
+
sig_off()
|
|
1448
|
+
for value, item in Lref:
|
|
1449
|
+
PH.push(item, value + k)
|
|
1450
|
+
sig_check()
|
|
1451
|
+
for item in dec_order:
|
|
1452
|
+
PH.decrease(item, PH.value(item) - k)
|
|
1453
|
+
sig_check()
|
|
1454
|
+
LPH = []
|
|
1455
|
+
while not PH.empty():
|
|
1456
|
+
LPH.append(PH.top())
|
|
1457
|
+
PH.pop()
|
|
1458
|
+
sig_check()
|
|
1459
|
+
t = cputime(t)
|
|
1460
|
+
if verbose:
|
|
1461
|
+
print(f"PairingHeap (C++): {t}")
|
|
1462
|
+
|
|
1463
|
+
if LPH != LP or LP != LQ:
|
|
1464
|
+
print('something goes wrong')
|