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
sage/combinat/subset.py
ADDED
|
@@ -0,0 +1,1561 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Subsets
|
|
4
|
+
|
|
5
|
+
The set of subsets of a finite set. The set can be given as a list or a :class:`Set`
|
|
6
|
+
or else as an integer `n` which encodes the set `\{1,2,...,n\}`.
|
|
7
|
+
See :class:`Subsets` for more information and examples.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Mike Hansen: initial version
|
|
12
|
+
|
|
13
|
+
- Florent Hivert (2009/02/06): doc improvements + new methods
|
|
14
|
+
"""
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
# Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
|
|
17
|
+
# 2014 Vincent Delecroix <20100.delecroix@gmail.com>,
|
|
18
|
+
#
|
|
19
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
20
|
+
#
|
|
21
|
+
# This code is distributed in the hope that it will be useful,
|
|
22
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
23
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
24
|
+
# General Public License for more details.
|
|
25
|
+
#
|
|
26
|
+
# The full text of the GPL is available at:
|
|
27
|
+
#
|
|
28
|
+
# https://www.gnu.org/licenses/
|
|
29
|
+
# ****************************************************************************
|
|
30
|
+
|
|
31
|
+
import sage.misc.prandom as rnd
|
|
32
|
+
import itertools
|
|
33
|
+
|
|
34
|
+
from sage.categories.sets_cat import EmptySetError, Sets
|
|
35
|
+
from sage.categories.enumerated_sets import EnumeratedSets
|
|
36
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
37
|
+
|
|
38
|
+
from sage.structure.parent import Parent
|
|
39
|
+
from sage.structure.element import Element
|
|
40
|
+
|
|
41
|
+
from sage.sets.set import Set, Set_object_enumerated
|
|
42
|
+
from sage.arith.misc import binomial
|
|
43
|
+
from sage.rings.integer_ring import ZZ
|
|
44
|
+
from sage.rings.integer import Integer
|
|
45
|
+
from . import combination
|
|
46
|
+
|
|
47
|
+
ZZ_0 = ZZ.zero()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def Subsets(s, k=None, submultiset=False):
|
|
51
|
+
r"""
|
|
52
|
+
Return the combinatorial class of the subsets of the finite set
|
|
53
|
+
``s``. The set can be given as a list, Set or any iterable
|
|
54
|
+
convertible to a set. Alternatively, a nonnegative integer `n`
|
|
55
|
+
can be provided in place of ``s``; in this case, the result is
|
|
56
|
+
the combinatorial class of the subsets of the set
|
|
57
|
+
`\{1,2,\dots,n\}` (i.e. of the Sage ``range(1,n+1)``).
|
|
58
|
+
|
|
59
|
+
A second optional parameter ``k`` can be given. In this case,
|
|
60
|
+
``Subsets`` returns the combinatorial class of subsets of ``s``
|
|
61
|
+
of size ``k``.
|
|
62
|
+
|
|
63
|
+
.. WARNING::
|
|
64
|
+
|
|
65
|
+
The subsets are returned as Sets. Do not assume that
|
|
66
|
+
these Sets are ordered; they often are not!
|
|
67
|
+
(E.g., ``Subsets(10).list()[619]`` returns
|
|
68
|
+
``{10, 4, 5, 6, 7}`` on my system.)
|
|
69
|
+
See :class:`SubsetsSorted` for a similar class which
|
|
70
|
+
returns the subsets as sorted tuples.
|
|
71
|
+
|
|
72
|
+
Finally the option ``submultiset`` allows one to deal with sets with
|
|
73
|
+
repeated elements, usually called multisets. The method then
|
|
74
|
+
returns the class of all multisets in which every element is
|
|
75
|
+
contained at most as often as it is contained in ``s``. These
|
|
76
|
+
multisets are encoded as lists.
|
|
77
|
+
|
|
78
|
+
EXAMPLES::
|
|
79
|
+
|
|
80
|
+
sage: S = Subsets([1, 2, 3]); S
|
|
81
|
+
Subsets of {1, 2, 3}
|
|
82
|
+
sage: S.cardinality()
|
|
83
|
+
8
|
|
84
|
+
sage: S.first()
|
|
85
|
+
{}
|
|
86
|
+
sage: S.last()
|
|
87
|
+
{1, 2, 3}
|
|
88
|
+
sage: S.random_element() in S
|
|
89
|
+
True
|
|
90
|
+
sage: S.list()
|
|
91
|
+
[{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
|
|
92
|
+
|
|
93
|
+
Here is the same example where the set is given as an integer::
|
|
94
|
+
|
|
95
|
+
sage: S = Subsets(3)
|
|
96
|
+
sage: S.list()
|
|
97
|
+
[{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
|
|
98
|
+
|
|
99
|
+
We demonstrate various the effect of the various options::
|
|
100
|
+
|
|
101
|
+
sage: S = Subsets(3, 2); S
|
|
102
|
+
Subsets of {1, 2, 3} of size 2
|
|
103
|
+
sage: S.list()
|
|
104
|
+
[{1, 2}, {1, 3}, {2, 3}]
|
|
105
|
+
|
|
106
|
+
sage: S = Subsets([1, 2, 2], submultiset=True); S
|
|
107
|
+
SubMultiset of [1, 2, 2]
|
|
108
|
+
sage: S.list()
|
|
109
|
+
[[], [1], [2], [1, 2], [2, 2], [1, 2, 2]]
|
|
110
|
+
|
|
111
|
+
sage: S = Subsets([1, 2, 2, 3], 3, submultiset=True); S
|
|
112
|
+
SubMultiset of [1, 2, 2, 3] of size 3
|
|
113
|
+
sage: S.list()
|
|
114
|
+
[[1, 2, 2], [1, 2, 3], [2, 2, 3]]
|
|
115
|
+
|
|
116
|
+
sage: S = Subsets(['a','b','a','b'], 2, submultiset=True); S.list()
|
|
117
|
+
[['a', 'a'], ['a', 'b'], ['b', 'b']]
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
And it is possible to play with subsets of subsets::
|
|
121
|
+
|
|
122
|
+
sage: S = Subsets(3)
|
|
123
|
+
sage: S2 = Subsets(S); S2
|
|
124
|
+
Subsets of Subsets of {1, 2, 3}
|
|
125
|
+
sage: S2.cardinality()
|
|
126
|
+
256
|
|
127
|
+
sage: it = iter(S2)
|
|
128
|
+
sage: [next(it) for _ in range(8)]
|
|
129
|
+
[{}, {{}}, {{1}}, {{2}}, {{3}}, {{1, 2}}, {{1, 3}}, {{2, 3}}]
|
|
130
|
+
sage: S2.random_element() # random
|
|
131
|
+
{{2}, {1, 2, 3}, {}}
|
|
132
|
+
sage: [S2.unrank(k) for k in range(256)] == S2.list()
|
|
133
|
+
True
|
|
134
|
+
|
|
135
|
+
sage: S3 = Subsets(S2)
|
|
136
|
+
sage: S3.cardinality()
|
|
137
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639936
|
|
138
|
+
sage: S3.unrank(14123091480) # random
|
|
139
|
+
{{{2}, {1, 2, 3}, {1, 2}, {3}, {}},
|
|
140
|
+
{{1, 2, 3}, {2}, {1}, {1, 3}},
|
|
141
|
+
{{}, {2}, {2, 3}, {1, 2}},
|
|
142
|
+
{{}, {2}, {1, 2, 3}, {1, 2}},
|
|
143
|
+
{},
|
|
144
|
+
{{}, {1}, {1, 2, 3}}}
|
|
145
|
+
|
|
146
|
+
sage: T = Subsets(S2, 10)
|
|
147
|
+
sage: T.cardinality()
|
|
148
|
+
278826214642518400
|
|
149
|
+
sage: T.unrank(1441231049) # random
|
|
150
|
+
{{{1, 2, 3}, {2}, {2, 3}}, {{3}, {1, 3}, ..., {3}, {1}, {}, {1, 3}}}
|
|
151
|
+
"""
|
|
152
|
+
if k is not None:
|
|
153
|
+
k = Integer(k)
|
|
154
|
+
|
|
155
|
+
if isinstance(s, (int, Integer)):
|
|
156
|
+
if s < 0:
|
|
157
|
+
raise ValueError("s must be nonnegative")
|
|
158
|
+
from sage.sets.integer_range import IntegerRange
|
|
159
|
+
s = IntegerRange(1,s+1)
|
|
160
|
+
|
|
161
|
+
if k is None:
|
|
162
|
+
if submultiset:
|
|
163
|
+
return SubMultiset_s(s)
|
|
164
|
+
else:
|
|
165
|
+
return Subsets_s(s)
|
|
166
|
+
else:
|
|
167
|
+
if submultiset:
|
|
168
|
+
return SubMultiset_sk(s, k)
|
|
169
|
+
else:
|
|
170
|
+
return Subsets_sk(s, k)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class Subsets_s(Parent):
|
|
174
|
+
r"""
|
|
175
|
+
Subsets of a given set.
|
|
176
|
+
|
|
177
|
+
EXAMPLES::
|
|
178
|
+
|
|
179
|
+
sage: S = Subsets(4); S
|
|
180
|
+
Subsets of {1, 2, 3, 4}
|
|
181
|
+
sage: S.cardinality()
|
|
182
|
+
16
|
|
183
|
+
sage: Subsets(4).list()
|
|
184
|
+
[{}, {1}, {2}, {3}, {4},
|
|
185
|
+
{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4},
|
|
186
|
+
{1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4},
|
|
187
|
+
{1, 2, 3, 4}]
|
|
188
|
+
|
|
189
|
+
sage: S = Subsets(Subsets(Subsets(GF(3)))); S
|
|
190
|
+
Subsets of Subsets of Subsets of Finite Field of size 3
|
|
191
|
+
sage: S.cardinality()
|
|
192
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639936
|
|
193
|
+
sage: S.unrank(3149254230) # random
|
|
194
|
+
{{{1}, {0, 2}}, {{0, 1, 2}, {0, 1}, {1}, {1, 2}},
|
|
195
|
+
{{2}, {1, 2}, {0, 1, 2}, {0, 2}, {1}, {}},
|
|
196
|
+
{{1, 2}, {0}},
|
|
197
|
+
{{0, 1, 2}, {0, 1}, {0, 2}, {1, 2}}}
|
|
198
|
+
"""
|
|
199
|
+
# TODO: Set_object_enumerated does not inherit from Element... so we set
|
|
200
|
+
# directly element_class as Set_object_enumerated
|
|
201
|
+
# (see also below the failed test in __init__)
|
|
202
|
+
element_class = Set_object_enumerated
|
|
203
|
+
|
|
204
|
+
def __init__(self, s):
|
|
205
|
+
"""
|
|
206
|
+
TESTS::
|
|
207
|
+
|
|
208
|
+
sage: s = Subsets(Set([1]))
|
|
209
|
+
sage: e = s.first()
|
|
210
|
+
sage: isinstance(e, s.element_class)
|
|
211
|
+
True
|
|
212
|
+
|
|
213
|
+
In the following "_test_elements" is temporarily disabled
|
|
214
|
+
until :class:`sage.sets.set.Set_object_enumerated` objects
|
|
215
|
+
pass the category tests::
|
|
216
|
+
|
|
217
|
+
sage: S = Subsets([1,2,3])
|
|
218
|
+
sage: TestSuite(S).run(skip=["_test_elements"])
|
|
219
|
+
|
|
220
|
+
sage: S = sage.sets.set.Set_object_enumerated([1,2])
|
|
221
|
+
sage: TestSuite(S).run()
|
|
222
|
+
"""
|
|
223
|
+
Parent.__init__(self, category=EnumeratedSets().Finite())
|
|
224
|
+
if s not in EnumeratedSets():
|
|
225
|
+
from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
|
|
226
|
+
L = list(uniq(s))
|
|
227
|
+
s = FiniteEnumeratedSet(L)
|
|
228
|
+
self._s = s
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def _ls(self):
|
|
232
|
+
r"""
|
|
233
|
+
The list of elements of the underlying set.
|
|
234
|
+
|
|
235
|
+
We try as much as possible to *not* use it.
|
|
236
|
+
|
|
237
|
+
TESTS::
|
|
238
|
+
|
|
239
|
+
sage: S = Subsets([1,2,3,4])
|
|
240
|
+
sage: S._ls
|
|
241
|
+
[1, 2, 3, 4]
|
|
242
|
+
"""
|
|
243
|
+
return self._s.list()
|
|
244
|
+
|
|
245
|
+
def underlying_set(self):
|
|
246
|
+
r"""
|
|
247
|
+
Return the set of elements.
|
|
248
|
+
|
|
249
|
+
EXAMPLES::
|
|
250
|
+
|
|
251
|
+
sage: Subsets(GF(13)).underlying_set()
|
|
252
|
+
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
|
253
|
+
"""
|
|
254
|
+
return self.element_class(self._s)
|
|
255
|
+
|
|
256
|
+
def __eq__(self, other):
|
|
257
|
+
r"""
|
|
258
|
+
Equality test.
|
|
259
|
+
|
|
260
|
+
TESTS::
|
|
261
|
+
|
|
262
|
+
sage: Subsets([0,1,2]) == Subsets([1,2,3])
|
|
263
|
+
False
|
|
264
|
+
sage: Subsets([0,1,2]) == Subsets([0,1,2])
|
|
265
|
+
True
|
|
266
|
+
sage: Subsets([0,1,2]) == Subsets([0,1,2],2)
|
|
267
|
+
False
|
|
268
|
+
"""
|
|
269
|
+
if self.__class__ != other.__class__:
|
|
270
|
+
return False
|
|
271
|
+
return self._s == other._s
|
|
272
|
+
|
|
273
|
+
def __ne__(self, other):
|
|
274
|
+
r"""
|
|
275
|
+
Difference test.
|
|
276
|
+
|
|
277
|
+
TESTS::
|
|
278
|
+
|
|
279
|
+
sage: Subsets([0,1,2]) != Subsets([1,2,3])
|
|
280
|
+
True
|
|
281
|
+
sage: Subsets([0,1,2]) != Subsets([0,1,2])
|
|
282
|
+
False
|
|
283
|
+
sage: Subsets([0,1,2]) != Subsets([0,1,2],2)
|
|
284
|
+
True
|
|
285
|
+
"""
|
|
286
|
+
return not self == other
|
|
287
|
+
|
|
288
|
+
def __hash__(self):
|
|
289
|
+
"""
|
|
290
|
+
Return the hash of ``self``.
|
|
291
|
+
|
|
292
|
+
TESTS::
|
|
293
|
+
|
|
294
|
+
sage: hash(Subsets([0,1,2])) == hash(Subsets([1,2,3]))
|
|
295
|
+
False
|
|
296
|
+
sage: hash(Subsets([0,1,2])) == hash(Subsets([0,1,2]))
|
|
297
|
+
True
|
|
298
|
+
sage: hash(Subsets([0,1,2])) == hash(Subsets([0,1,2],2))
|
|
299
|
+
False
|
|
300
|
+
"""
|
|
301
|
+
return hash(self._s)
|
|
302
|
+
|
|
303
|
+
def _repr_(self):
|
|
304
|
+
"""
|
|
305
|
+
TESTS::
|
|
306
|
+
|
|
307
|
+
sage: repr(Subsets([1,2,3])) #indirect doctest
|
|
308
|
+
'Subsets of {1, 2, 3}'
|
|
309
|
+
"""
|
|
310
|
+
return "Subsets of {}".format(self._s)
|
|
311
|
+
|
|
312
|
+
def __contains__(self, value):
|
|
313
|
+
"""
|
|
314
|
+
TESTS::
|
|
315
|
+
|
|
316
|
+
sage: S = Subsets([1,2,3])
|
|
317
|
+
sage: Set([1,2]) in S
|
|
318
|
+
True
|
|
319
|
+
sage: Set([1,4]) in S
|
|
320
|
+
False
|
|
321
|
+
sage: Set([]) in S
|
|
322
|
+
True
|
|
323
|
+
sage: 2 in S
|
|
324
|
+
False
|
|
325
|
+
sage: {1, 2} in S
|
|
326
|
+
True
|
|
327
|
+
"""
|
|
328
|
+
if value not in Sets() and not isinstance(value, (set, frozenset)):
|
|
329
|
+
return False
|
|
330
|
+
return all(v in self._s for v in value)
|
|
331
|
+
|
|
332
|
+
def cardinality(self):
|
|
333
|
+
r"""
|
|
334
|
+
Return the number of subsets of the set ``s``.
|
|
335
|
+
|
|
336
|
+
This is given by `2^{|s|}`.
|
|
337
|
+
|
|
338
|
+
EXAMPLES::
|
|
339
|
+
|
|
340
|
+
sage: Subsets(Set([1,2,3])).cardinality()
|
|
341
|
+
8
|
|
342
|
+
sage: Subsets([1,2,3,3]).cardinality()
|
|
343
|
+
8
|
|
344
|
+
sage: Subsets(3).cardinality()
|
|
345
|
+
8
|
|
346
|
+
|
|
347
|
+
TESTS:
|
|
348
|
+
|
|
349
|
+
``__len__`` should return a Python int::
|
|
350
|
+
|
|
351
|
+
sage: S = Subsets(Set([1,2,3]))
|
|
352
|
+
sage: len(S)
|
|
353
|
+
8
|
|
354
|
+
sage: type(len(S)) is int
|
|
355
|
+
True
|
|
356
|
+
"""
|
|
357
|
+
return Integer(1) << self._s.cardinality()
|
|
358
|
+
|
|
359
|
+
__len__ = cardinality
|
|
360
|
+
|
|
361
|
+
def first(self):
|
|
362
|
+
"""
|
|
363
|
+
Return the first subset of ``s``. Since we aren't restricted to
|
|
364
|
+
subsets of a certain size, this is always the empty set.
|
|
365
|
+
|
|
366
|
+
EXAMPLES::
|
|
367
|
+
|
|
368
|
+
sage: Subsets([1,2,3]).first()
|
|
369
|
+
{}
|
|
370
|
+
sage: Subsets(3).first()
|
|
371
|
+
{}
|
|
372
|
+
"""
|
|
373
|
+
return self.element_class([])
|
|
374
|
+
|
|
375
|
+
def last(self):
|
|
376
|
+
"""
|
|
377
|
+
Return the last subset of ``s``. Since we aren't restricted to
|
|
378
|
+
subsets of a certain size, this is always the set ``s`` itself.
|
|
379
|
+
|
|
380
|
+
EXAMPLES::
|
|
381
|
+
|
|
382
|
+
sage: Subsets([1,2,3]).last()
|
|
383
|
+
{1, 2, 3}
|
|
384
|
+
sage: Subsets(3).last()
|
|
385
|
+
{1, 2, 3}
|
|
386
|
+
"""
|
|
387
|
+
return self.element_class(self._s)
|
|
388
|
+
|
|
389
|
+
def __iter__(self):
|
|
390
|
+
"""
|
|
391
|
+
Iterate through the subsets of ``s``.
|
|
392
|
+
|
|
393
|
+
EXAMPLES::
|
|
394
|
+
|
|
395
|
+
sage: [sub for sub in Subsets(Set([1,2,3]))]
|
|
396
|
+
[{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
|
|
397
|
+
sage: [sub for sub in Subsets(3)]
|
|
398
|
+
[{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
|
|
399
|
+
sage: [sub for sub in Subsets([1,2,3,3])]
|
|
400
|
+
[{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}]
|
|
401
|
+
"""
|
|
402
|
+
k = ZZ_0
|
|
403
|
+
while k <= self._s.cardinality():
|
|
404
|
+
for ss in Subsets_sk(self._s, k)._fast_iterator():
|
|
405
|
+
yield self.element_class(ss)
|
|
406
|
+
k += 1
|
|
407
|
+
|
|
408
|
+
def random_element(self):
|
|
409
|
+
"""
|
|
410
|
+
Return a random element of the class of subsets of ``s`` (in other
|
|
411
|
+
words, a random subset of ``s``).
|
|
412
|
+
|
|
413
|
+
EXAMPLES::
|
|
414
|
+
|
|
415
|
+
sage: Subsets(3).random_element() # random
|
|
416
|
+
{2}
|
|
417
|
+
sage: Subsets([4,5,6]).random_element() # random
|
|
418
|
+
{5}
|
|
419
|
+
|
|
420
|
+
sage: S = Subsets(Subsets(Subsets([0,1,2])))
|
|
421
|
+
sage: S.cardinality()
|
|
422
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639936
|
|
423
|
+
sage: s = S.random_element()
|
|
424
|
+
sage: s # random
|
|
425
|
+
{{{1, 2}, {2}, {0}, {1}}, {{1, 2}, {0, 1, 2}, {0, 2}, {0}, {0, 1}}, ..., {{1, 2}, {2}, {1}}, {{2}, {0, 2}, {}, {1}}}
|
|
426
|
+
sage: s in S
|
|
427
|
+
True
|
|
428
|
+
"""
|
|
429
|
+
k = ZZ.random_element(0, self.cardinality())
|
|
430
|
+
return self.unrank(k)
|
|
431
|
+
|
|
432
|
+
def rank(self, sub):
|
|
433
|
+
"""
|
|
434
|
+
Return the rank of ``sub`` as a subset of ``s``.
|
|
435
|
+
|
|
436
|
+
EXAMPLES::
|
|
437
|
+
|
|
438
|
+
sage: Subsets(3).rank([])
|
|
439
|
+
0
|
|
440
|
+
sage: Subsets(3).rank([1,2])
|
|
441
|
+
4
|
|
442
|
+
sage: Subsets(3).rank([1,2,3])
|
|
443
|
+
7
|
|
444
|
+
sage: Subsets(3).rank([2,3,4])
|
|
445
|
+
Traceback (most recent call last):
|
|
446
|
+
...
|
|
447
|
+
ValueError: {2, 3, 4} is not a subset of {1, 2, 3}
|
|
448
|
+
"""
|
|
449
|
+
if sub not in Sets():
|
|
450
|
+
ssub = Set(sub)
|
|
451
|
+
if len(sub) != len(ssub):
|
|
452
|
+
raise ValueError("repeated elements in {}".format(sub))
|
|
453
|
+
sub = ssub
|
|
454
|
+
|
|
455
|
+
try:
|
|
456
|
+
index_list = sorted(self._s.rank(x) for x in sub)
|
|
457
|
+
except (ValueError,IndexError):
|
|
458
|
+
raise ValueError("{} is not a subset of {}".format(
|
|
459
|
+
Set(sub), self._s))
|
|
460
|
+
|
|
461
|
+
n = self._s.cardinality()
|
|
462
|
+
r = sum(binomial(n,i) for i in range(len(index_list)))
|
|
463
|
+
return r + combination.rank(index_list,n)
|
|
464
|
+
|
|
465
|
+
def unrank(self, r):
|
|
466
|
+
"""
|
|
467
|
+
Return the subset of ``s`` that has rank ``k``.
|
|
468
|
+
|
|
469
|
+
EXAMPLES::
|
|
470
|
+
|
|
471
|
+
sage: Subsets(3).unrank(0)
|
|
472
|
+
{}
|
|
473
|
+
sage: Subsets([2,4,5]).unrank(1)
|
|
474
|
+
{2}
|
|
475
|
+
sage: Subsets([1,2,3]).unrank(257)
|
|
476
|
+
Traceback (most recent call last):
|
|
477
|
+
...
|
|
478
|
+
IndexError: index out of range
|
|
479
|
+
"""
|
|
480
|
+
r = Integer(r)
|
|
481
|
+
if r >= self.cardinality() or r < 0:
|
|
482
|
+
raise IndexError("index out of range")
|
|
483
|
+
else:
|
|
484
|
+
k = ZZ_0
|
|
485
|
+
n = self._s.cardinality()
|
|
486
|
+
bin = Integer(1)
|
|
487
|
+
while r >= bin:
|
|
488
|
+
r -= bin
|
|
489
|
+
k += 1
|
|
490
|
+
bin = binomial(n,k)
|
|
491
|
+
return self.element_class([self._s.unrank(i) for i in combination.from_rank(r, n, k)])
|
|
492
|
+
|
|
493
|
+
def __call__(self, el):
|
|
494
|
+
r"""
|
|
495
|
+
Workaround for returning non elements.
|
|
496
|
+
|
|
497
|
+
See the extensive documentation in
|
|
498
|
+
:meth:`sage.sets.finite_enumerated_set.FiniteEnumeratedSet.__call__`.
|
|
499
|
+
|
|
500
|
+
TESTS::
|
|
501
|
+
|
|
502
|
+
sage: sorted(Subsets(['a','b','c'])(['a','b'])) # indirect doctest
|
|
503
|
+
['a', 'b']
|
|
504
|
+
"""
|
|
505
|
+
if not isinstance(el, Element):
|
|
506
|
+
return self._element_constructor_(el)
|
|
507
|
+
else:
|
|
508
|
+
return Parent.__call__(self, el)
|
|
509
|
+
|
|
510
|
+
def _element_constructor_(self, X):
|
|
511
|
+
"""
|
|
512
|
+
TESTS::
|
|
513
|
+
|
|
514
|
+
sage: S3 = Subsets(3); S3([1,2]) #indirect doctest
|
|
515
|
+
{1, 2}
|
|
516
|
+
sage: S3([0,1,2])
|
|
517
|
+
Traceback (most recent call last):
|
|
518
|
+
...
|
|
519
|
+
ValueError: {0, 1, 2} not in Subsets of {1, 2, 3}
|
|
520
|
+
"""
|
|
521
|
+
e = self.element_class(X)
|
|
522
|
+
if e not in self:
|
|
523
|
+
raise ValueError("{} not in {}".format(e,self))
|
|
524
|
+
return e
|
|
525
|
+
|
|
526
|
+
def _an_element_(self):
|
|
527
|
+
"""
|
|
528
|
+
Return an example of subset.
|
|
529
|
+
|
|
530
|
+
EXAMPLES::
|
|
531
|
+
|
|
532
|
+
sage: Subsets(0).an_element()
|
|
533
|
+
{}
|
|
534
|
+
sage: Subsets(3).an_element()
|
|
535
|
+
{1, 2}
|
|
536
|
+
sage: Subsets([2,4,5]).an_element()
|
|
537
|
+
{2, 4}
|
|
538
|
+
|
|
539
|
+
Check that :issue:`33988` is fixed::
|
|
540
|
+
|
|
541
|
+
sage: Subsets([1,2,3]).an_element() == Subsets([1,2,3])._an_element_()
|
|
542
|
+
True
|
|
543
|
+
"""
|
|
544
|
+
return self.unrank(self.cardinality() // 2)
|
|
545
|
+
|
|
546
|
+
def lattice(self):
|
|
547
|
+
r"""
|
|
548
|
+
Return the lattice of subsets ordered by containment.
|
|
549
|
+
|
|
550
|
+
EXAMPLES::
|
|
551
|
+
|
|
552
|
+
sage: X = Subsets([7,8,9])
|
|
553
|
+
sage: X.lattice() # needs sage.combinat sage.graphs
|
|
554
|
+
Finite lattice containing 8 elements
|
|
555
|
+
sage: Y = Subsets(0)
|
|
556
|
+
sage: Y.lattice() # needs sage.combinat sage.graphs
|
|
557
|
+
Finite lattice containing 1 elements
|
|
558
|
+
"""
|
|
559
|
+
S = self.underlying_set()
|
|
560
|
+
return S.subsets_lattice()
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
class Subsets_sk(Subsets_s):
|
|
564
|
+
r"""
|
|
565
|
+
Subsets of fixed size of a set.
|
|
566
|
+
|
|
567
|
+
EXAMPLES::
|
|
568
|
+
|
|
569
|
+
sage: S = Subsets([0,1,2,5,7], 3); S
|
|
570
|
+
Subsets of {0, 1, 2, 5, 7} of size 3
|
|
571
|
+
sage: S.cardinality()
|
|
572
|
+
10
|
|
573
|
+
sage: S.first(), S.last()
|
|
574
|
+
({0, 1, 2}, {2, 5, 7})
|
|
575
|
+
sage: S.random_element() # random
|
|
576
|
+
{0, 5, 7}
|
|
577
|
+
sage: S([0,2,7])
|
|
578
|
+
{0, 2, 7}
|
|
579
|
+
sage: S([0,3,5])
|
|
580
|
+
Traceback (most recent call last):
|
|
581
|
+
...
|
|
582
|
+
ValueError: {0, 3, 5} not in Subsets of {0, 1, 2, 5, 7} of size 3
|
|
583
|
+
sage: S([0])
|
|
584
|
+
Traceback (most recent call last):
|
|
585
|
+
...
|
|
586
|
+
ValueError: {0} not in Subsets of {0, 1, 2, 5, 7} of size 3
|
|
587
|
+
"""
|
|
588
|
+
|
|
589
|
+
def __init__(self, s, k):
|
|
590
|
+
"""
|
|
591
|
+
TESTS::
|
|
592
|
+
|
|
593
|
+
sage: s = Subsets(Set([1]))
|
|
594
|
+
sage: e = s.first()
|
|
595
|
+
sage: isinstance(e, s.element_class)
|
|
596
|
+
True
|
|
597
|
+
|
|
598
|
+
In the following "_test_elements" is temporarily disabled
|
|
599
|
+
until :class:`sage.sets.set.Set_object_enumerated` objects
|
|
600
|
+
pass the category tests::
|
|
601
|
+
|
|
602
|
+
sage: S = Subsets(3,2)
|
|
603
|
+
sage: TestSuite(S).run(skip=["_test_elements"])
|
|
604
|
+
"""
|
|
605
|
+
Subsets_s.__init__(self, s)
|
|
606
|
+
self._k = Integer(k)
|
|
607
|
+
if self._k < 0:
|
|
608
|
+
raise ValueError("the integer k (={}) should be nonnegative".format(k))
|
|
609
|
+
|
|
610
|
+
def _repr_(self):
|
|
611
|
+
"""
|
|
612
|
+
TESTS::
|
|
613
|
+
|
|
614
|
+
sage: repr(Subsets(3,2)) #indirect doctest
|
|
615
|
+
'Subsets of {1, 2, 3} of size 2'
|
|
616
|
+
"""
|
|
617
|
+
return Subsets_s._repr_(self) + " of size {}".format(self._k)
|
|
618
|
+
|
|
619
|
+
def __contains__(self, value):
|
|
620
|
+
"""
|
|
621
|
+
TESTS::
|
|
622
|
+
|
|
623
|
+
sage: S = Subsets([1,2,3], 2)
|
|
624
|
+
sage: Set([1,2]) in S
|
|
625
|
+
True
|
|
626
|
+
sage: Set([1,4]) in S
|
|
627
|
+
False
|
|
628
|
+
sage: Set([]) in S
|
|
629
|
+
False
|
|
630
|
+
"""
|
|
631
|
+
return len(value) == self._k and Subsets_s.__contains__(self,value)
|
|
632
|
+
|
|
633
|
+
def __eq__(self, other):
|
|
634
|
+
r"""
|
|
635
|
+
Equality test.
|
|
636
|
+
|
|
637
|
+
TESTS::
|
|
638
|
+
|
|
639
|
+
sage: Subsets(5,3) == Subsets(5,3)
|
|
640
|
+
True
|
|
641
|
+
sage: Subsets(4,2) == Subsets(5,2) or Subsets(4,2) == Subsets(4,3)
|
|
642
|
+
False
|
|
643
|
+
"""
|
|
644
|
+
if self.__class__ != other.__class__:
|
|
645
|
+
return False
|
|
646
|
+
return self._s == other._s and self._k == other._k
|
|
647
|
+
|
|
648
|
+
def __ne__(self, other):
|
|
649
|
+
r"""
|
|
650
|
+
Difference test.
|
|
651
|
+
|
|
652
|
+
TESTS::
|
|
653
|
+
|
|
654
|
+
sage: Subsets(5,3) != Subsets(5,3)
|
|
655
|
+
False
|
|
656
|
+
sage: Subsets(4,2) != Subsets(5,2) and Subsets(4,2) != Subsets(4,3)
|
|
657
|
+
True
|
|
658
|
+
"""
|
|
659
|
+
return not self == other
|
|
660
|
+
|
|
661
|
+
def __hash__(self):
|
|
662
|
+
"""
|
|
663
|
+
Return the hash of ``self``.
|
|
664
|
+
|
|
665
|
+
TESTS::
|
|
666
|
+
|
|
667
|
+
sage: hash(Subsets(5,3)) == hash(Subsets(5,3))
|
|
668
|
+
True
|
|
669
|
+
sage: hash(Subsets(4,2)) == hash(Subsets(5,2))
|
|
670
|
+
False
|
|
671
|
+
"""
|
|
672
|
+
return hash((self._s, self._k))
|
|
673
|
+
|
|
674
|
+
def cardinality(self):
|
|
675
|
+
"""
|
|
676
|
+
EXAMPLES::
|
|
677
|
+
|
|
678
|
+
sage: Subsets(Set([1,2,3]), 2).cardinality()
|
|
679
|
+
3
|
|
680
|
+
sage: Subsets([1,2,3,3], 2).cardinality()
|
|
681
|
+
3
|
|
682
|
+
sage: Subsets([1,2,3], 1).cardinality()
|
|
683
|
+
3
|
|
684
|
+
sage: Subsets([1,2,3], 3).cardinality()
|
|
685
|
+
1
|
|
686
|
+
sage: Subsets([1,2,3], 0).cardinality()
|
|
687
|
+
1
|
|
688
|
+
sage: Subsets([1,2,3], 4).cardinality()
|
|
689
|
+
0
|
|
690
|
+
sage: Subsets(3,2).cardinality()
|
|
691
|
+
3
|
|
692
|
+
sage: Subsets(3,4).cardinality()
|
|
693
|
+
0
|
|
694
|
+
"""
|
|
695
|
+
if self._k > self._s.cardinality():
|
|
696
|
+
return ZZ_0
|
|
697
|
+
return binomial(self._s.cardinality(), self._k)
|
|
698
|
+
|
|
699
|
+
__len__ = cardinality
|
|
700
|
+
|
|
701
|
+
def first(self):
|
|
702
|
+
"""
|
|
703
|
+
Return the first subset of s of size k.
|
|
704
|
+
|
|
705
|
+
EXAMPLES::
|
|
706
|
+
|
|
707
|
+
sage: Subsets(Set([1,2,3]), 2).first()
|
|
708
|
+
{1, 2}
|
|
709
|
+
sage: Subsets([1,2,3,3], 2).first()
|
|
710
|
+
{1, 2}
|
|
711
|
+
sage: Subsets(3,2).first()
|
|
712
|
+
{1, 2}
|
|
713
|
+
sage: Subsets(3,4).first()
|
|
714
|
+
Traceback (most recent call last):
|
|
715
|
+
...
|
|
716
|
+
EmptySetError
|
|
717
|
+
"""
|
|
718
|
+
if self._k < 0 or self._k > self._s.cardinality():
|
|
719
|
+
raise EmptySetError
|
|
720
|
+
else:
|
|
721
|
+
return self.element_class(list(itertools.islice(self._s,
|
|
722
|
+
int(self._k))))
|
|
723
|
+
|
|
724
|
+
def last(self):
|
|
725
|
+
"""
|
|
726
|
+
Return the last subset of s of size k.
|
|
727
|
+
|
|
728
|
+
EXAMPLES::
|
|
729
|
+
|
|
730
|
+
sage: Subsets(Set([1,2,3]), 2).last()
|
|
731
|
+
{2, 3}
|
|
732
|
+
sage: Subsets([1,2,3,3], 2).last()
|
|
733
|
+
{2, 3}
|
|
734
|
+
sage: Subsets(3,2).last()
|
|
735
|
+
{2, 3}
|
|
736
|
+
sage: Subsets(3,4).last()
|
|
737
|
+
Traceback (most recent call last):
|
|
738
|
+
...
|
|
739
|
+
EmptySetError
|
|
740
|
+
"""
|
|
741
|
+
if self._k > self._s.cardinality():
|
|
742
|
+
raise EmptySetError
|
|
743
|
+
|
|
744
|
+
return self.element_class(list(itertools.islice(reversed(self._s),
|
|
745
|
+
int(self._k))))
|
|
746
|
+
|
|
747
|
+
def _fast_iterator(self):
|
|
748
|
+
r"""
|
|
749
|
+
Iterate through the subsets of size k if s.
|
|
750
|
+
|
|
751
|
+
Beware that this function yield tuples and not sets. If you need sets
|
|
752
|
+
use __iter__
|
|
753
|
+
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: list(Subsets(range(3), 2)._fast_iterator())
|
|
757
|
+
[(0, 1), (0, 2), (1, 2)]
|
|
758
|
+
"""
|
|
759
|
+
return itertools.combinations(self._s, self._k)
|
|
760
|
+
|
|
761
|
+
def __iter__(self):
|
|
762
|
+
"""
|
|
763
|
+
Iterate through the subsets of s of size k.
|
|
764
|
+
|
|
765
|
+
EXAMPLES::
|
|
766
|
+
|
|
767
|
+
sage: Subsets(Set([1,2,3]), 2).list()
|
|
768
|
+
[{1, 2}, {1, 3}, {2, 3}]
|
|
769
|
+
sage: Subsets([1,2,3,3], 2).list()
|
|
770
|
+
[{1, 2}, {1, 3}, {2, 3}]
|
|
771
|
+
sage: Subsets(3,2).list()
|
|
772
|
+
[{1, 2}, {1, 3}, {2, 3}]
|
|
773
|
+
sage: Subsets(3,3).list()
|
|
774
|
+
[{1, 2, 3}]
|
|
775
|
+
"""
|
|
776
|
+
for x in self._fast_iterator():
|
|
777
|
+
yield self.element_class(x)
|
|
778
|
+
|
|
779
|
+
def random_element(self):
|
|
780
|
+
"""
|
|
781
|
+
Return a random element of the class of subsets of ``s`` of size
|
|
782
|
+
``k`` (in other words, a random subset of ``s`` of size ``k``).
|
|
783
|
+
|
|
784
|
+
EXAMPLES::
|
|
785
|
+
|
|
786
|
+
sage: s = Subsets(3, 2).random_element()
|
|
787
|
+
sage: s in Subsets(3, 2)
|
|
788
|
+
True
|
|
789
|
+
|
|
790
|
+
sage: Subsets(3,4).random_element()
|
|
791
|
+
Traceback (most recent call last):
|
|
792
|
+
...
|
|
793
|
+
EmptySetError
|
|
794
|
+
"""
|
|
795
|
+
lset = self._ls
|
|
796
|
+
|
|
797
|
+
if self._k > len(lset):
|
|
798
|
+
raise EmptySetError
|
|
799
|
+
else:
|
|
800
|
+
return self.element_class(rnd.sample(lset, self._k))
|
|
801
|
+
|
|
802
|
+
def rank(self, sub):
|
|
803
|
+
"""
|
|
804
|
+
Return the rank of ``sub`` as a subset of ``s`` of size ``k``.
|
|
805
|
+
|
|
806
|
+
EXAMPLES::
|
|
807
|
+
|
|
808
|
+
sage: Subsets(3,2).rank([1,2])
|
|
809
|
+
0
|
|
810
|
+
sage: Subsets([2,3,4],2).rank([3,4])
|
|
811
|
+
2
|
|
812
|
+
sage: Subsets([2,3,4],2).rank([2])
|
|
813
|
+
Traceback (most recent call last):
|
|
814
|
+
...
|
|
815
|
+
ValueError: {2} is not a subset of length 2 of {2, 3, 4}
|
|
816
|
+
sage: Subsets([2,3,4],4).rank([2,3,4,5])
|
|
817
|
+
Traceback (most recent call last):
|
|
818
|
+
...
|
|
819
|
+
ValueError: {2, 3, 4, 5} is not a subset of length 4 of {2, 3, 4}
|
|
820
|
+
"""
|
|
821
|
+
sub = Set(sub)
|
|
822
|
+
n = self._s.cardinality()
|
|
823
|
+
|
|
824
|
+
if self._k != sub.cardinality() or self._k > n:
|
|
825
|
+
raise ValueError("{} is not a subset of length {} of {}".format(
|
|
826
|
+
sub, self._k, self._s))
|
|
827
|
+
|
|
828
|
+
try:
|
|
829
|
+
index_list = sorted(self._s.rank(x) for x in sub)
|
|
830
|
+
except ValueError:
|
|
831
|
+
raise ValueError("{} is not a subset of length {} of {}".format(
|
|
832
|
+
sub, self._k, self._s))
|
|
833
|
+
|
|
834
|
+
return combination.rank(index_list, n)
|
|
835
|
+
|
|
836
|
+
def unrank(self, r):
|
|
837
|
+
"""
|
|
838
|
+
Return the subset of ``s`` of size ``k`` that has rank ``r``.
|
|
839
|
+
|
|
840
|
+
EXAMPLES::
|
|
841
|
+
|
|
842
|
+
sage: Subsets(3,2).unrank(0)
|
|
843
|
+
{1, 2}
|
|
844
|
+
sage: Subsets([2,4,5],2).unrank(0)
|
|
845
|
+
{2, 4}
|
|
846
|
+
sage: Subsets([1,2,8],3).unrank(42)
|
|
847
|
+
Traceback (most recent call last):
|
|
848
|
+
...
|
|
849
|
+
IndexError: index out of range
|
|
850
|
+
"""
|
|
851
|
+
lset = self._ls
|
|
852
|
+
n = len(lset)
|
|
853
|
+
|
|
854
|
+
if self._k > n or r >= self.cardinality() or r < 0:
|
|
855
|
+
raise IndexError("index out of range")
|
|
856
|
+
else:
|
|
857
|
+
return self.element_class([lset[i] for i in combination.from_rank(r, n, self._k)])
|
|
858
|
+
|
|
859
|
+
def _an_element_(self):
|
|
860
|
+
"""
|
|
861
|
+
Return an example of subset.
|
|
862
|
+
|
|
863
|
+
EXAMPLES::
|
|
864
|
+
|
|
865
|
+
sage: Subsets(0,0).an_element()
|
|
866
|
+
{}
|
|
867
|
+
sage: Subsets(3,2).an_element()
|
|
868
|
+
{1, 3}
|
|
869
|
+
sage: Subsets([2,4,5],2).an_element()
|
|
870
|
+
{2, 5}
|
|
871
|
+
"""
|
|
872
|
+
return self.unrank(self.cardinality() // 2)
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
def dict_to_list(d):
|
|
876
|
+
r"""
|
|
877
|
+
Return a list whose elements are the elements of ``i`` of ``d`` repeated with
|
|
878
|
+
multiplicity ``d[i]``.
|
|
879
|
+
|
|
880
|
+
EXAMPLES::
|
|
881
|
+
|
|
882
|
+
sage: from sage.combinat.subset import dict_to_list
|
|
883
|
+
sage: dict_to_list({'a':1, 'b':3})
|
|
884
|
+
['a', 'b', 'b', 'b']
|
|
885
|
+
"""
|
|
886
|
+
l = []
|
|
887
|
+
for i, j in d.items():
|
|
888
|
+
l.extend([i] * j)
|
|
889
|
+
return l
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
def list_to_dict(l):
|
|
893
|
+
r"""
|
|
894
|
+
Return a dictionary of multiplicities and the list of its keys.
|
|
895
|
+
|
|
896
|
+
INPUT:
|
|
897
|
+
|
|
898
|
+
- ``l`` -- list with possibly repeated elements
|
|
899
|
+
|
|
900
|
+
The keys are the elements of ``l`` (in the same order in which they appear)
|
|
901
|
+
and values are the multiplicities of each element in ``l``.
|
|
902
|
+
|
|
903
|
+
EXAMPLES::
|
|
904
|
+
|
|
905
|
+
sage: from sage.combinat.subset import list_to_dict
|
|
906
|
+
sage: list_to_dict(['a', 'b', 'b', 'b'])
|
|
907
|
+
({'a': 1, 'b': 3}, ['a', 'b'])
|
|
908
|
+
"""
|
|
909
|
+
d = {}
|
|
910
|
+
keys = []
|
|
911
|
+
for elt in l:
|
|
912
|
+
if elt not in d:
|
|
913
|
+
d[elt] = 0
|
|
914
|
+
keys.append(elt)
|
|
915
|
+
d[elt] += 1
|
|
916
|
+
return d, keys
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
class SubMultiset_s(Parent):
|
|
920
|
+
"""
|
|
921
|
+
The combinatorial class of the sub multisets of ``s``.
|
|
922
|
+
|
|
923
|
+
EXAMPLES::
|
|
924
|
+
|
|
925
|
+
sage: S = Subsets([1,2,2,3], submultiset=True)
|
|
926
|
+
sage: S.cardinality()
|
|
927
|
+
12
|
|
928
|
+
sage: S.list()
|
|
929
|
+
[[],
|
|
930
|
+
[1],
|
|
931
|
+
[2],
|
|
932
|
+
[3],
|
|
933
|
+
[1, 2],
|
|
934
|
+
[1, 3],
|
|
935
|
+
[2, 2],
|
|
936
|
+
[2, 3],
|
|
937
|
+
[1, 2, 2],
|
|
938
|
+
[1, 2, 3],
|
|
939
|
+
[2, 2, 3],
|
|
940
|
+
[1, 2, 2, 3]]
|
|
941
|
+
sage: S.first()
|
|
942
|
+
[]
|
|
943
|
+
sage: S.last()
|
|
944
|
+
[1, 2, 2, 3]
|
|
945
|
+
"""
|
|
946
|
+
# TODO: list does not inherit from Element... so we set
|
|
947
|
+
# directly element_class as list
|
|
948
|
+
element_class = list
|
|
949
|
+
|
|
950
|
+
def __init__(self, s):
|
|
951
|
+
"""
|
|
952
|
+
Construct the combinatorial class of the sub multisets of s.
|
|
953
|
+
|
|
954
|
+
EXAMPLES::
|
|
955
|
+
|
|
956
|
+
sage: S = Subsets([1,2,2,3], submultiset=True)
|
|
957
|
+
sage: Subsets([1,2,3,3], submultiset=True).cardinality()
|
|
958
|
+
12
|
|
959
|
+
sage: TestSuite(S).run()
|
|
960
|
+
|
|
961
|
+
TESTS::
|
|
962
|
+
|
|
963
|
+
sage: from sage.combinat.subset import SubMultiset_s
|
|
964
|
+
sage: T = SubMultiset_s({'a':2,'b':1,'c':2})
|
|
965
|
+
sage: T.cardinality()
|
|
966
|
+
18
|
|
967
|
+
"""
|
|
968
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
969
|
+
|
|
970
|
+
if isinstance(s, dict):
|
|
971
|
+
self._d = s
|
|
972
|
+
self._l = dict_to_list(s)
|
|
973
|
+
self._keys = list(self._d)
|
|
974
|
+
else:
|
|
975
|
+
self._l = s
|
|
976
|
+
self._d, self._keys = list_to_dict(s)
|
|
977
|
+
|
|
978
|
+
def _repr_(self):
|
|
979
|
+
"""
|
|
980
|
+
TESTS::
|
|
981
|
+
|
|
982
|
+
sage: S = Subsets([1, 2, 2, 3], submultiset=True); S #indirect doctest
|
|
983
|
+
SubMultiset of [1, 2, 2, 3]
|
|
984
|
+
"""
|
|
985
|
+
return "SubMultiset of {}".format(self._l)
|
|
986
|
+
|
|
987
|
+
def __eq__(self, other):
|
|
988
|
+
r"""
|
|
989
|
+
TESTS::
|
|
990
|
+
|
|
991
|
+
sage: Subsets([1,2,2,3], submultiset=True) == Subsets([1,2,2,3], submultiset=True)
|
|
992
|
+
True
|
|
993
|
+
sage: Subsets([1,2,2,3], submultiset=True) == Subsets([1,2,3,3], submultiset=True)
|
|
994
|
+
False
|
|
995
|
+
"""
|
|
996
|
+
if self.__class__ != other.__class__:
|
|
997
|
+
return False
|
|
998
|
+
return self._d == other._d
|
|
999
|
+
|
|
1000
|
+
def __ne__(self, other):
|
|
1001
|
+
r"""
|
|
1002
|
+
TESTS::
|
|
1003
|
+
|
|
1004
|
+
sage: Subsets([1,2,2,3], submultiset=True) != Subsets([1,2,2,3], submultiset=True)
|
|
1005
|
+
False
|
|
1006
|
+
sage: Subsets([1,2,2,3], submultiset=True) != Subsets([1,2,3,3], submultiset=True)
|
|
1007
|
+
True
|
|
1008
|
+
"""
|
|
1009
|
+
return not self == other
|
|
1010
|
+
|
|
1011
|
+
def __contains__(self, s):
|
|
1012
|
+
"""
|
|
1013
|
+
TESTS::
|
|
1014
|
+
|
|
1015
|
+
sage: S = Subsets([1,2,2,3], submultiset=True)
|
|
1016
|
+
sage: [] in S
|
|
1017
|
+
True
|
|
1018
|
+
sage: [1, 2, 2] in S
|
|
1019
|
+
True
|
|
1020
|
+
sage: all(i in S for i in S)
|
|
1021
|
+
True
|
|
1022
|
+
sage: [1, 2, 2, 2] in S
|
|
1023
|
+
False
|
|
1024
|
+
sage: [1, 3, 2, 2] in S
|
|
1025
|
+
True
|
|
1026
|
+
sage: [4] in S
|
|
1027
|
+
False
|
|
1028
|
+
"""
|
|
1029
|
+
dd = {}
|
|
1030
|
+
for elt in s:
|
|
1031
|
+
if elt in dd:
|
|
1032
|
+
dd[elt] += 1
|
|
1033
|
+
if dd[elt] > self._d[elt]:
|
|
1034
|
+
return False
|
|
1035
|
+
elif elt not in self._d:
|
|
1036
|
+
return False
|
|
1037
|
+
else:
|
|
1038
|
+
dd[elt] = 1
|
|
1039
|
+
return True
|
|
1040
|
+
|
|
1041
|
+
def cardinality(self):
|
|
1042
|
+
r"""
|
|
1043
|
+
Return the cardinality of ``self``.
|
|
1044
|
+
|
|
1045
|
+
EXAMPLES::
|
|
1046
|
+
|
|
1047
|
+
sage: S = Subsets([1,1,2,3],submultiset=True)
|
|
1048
|
+
sage: S.cardinality()
|
|
1049
|
+
12
|
|
1050
|
+
sage: len(S.list())
|
|
1051
|
+
12
|
|
1052
|
+
|
|
1053
|
+
sage: S = Subsets([1,1,2,2,3],submultiset=True)
|
|
1054
|
+
sage: S.cardinality()
|
|
1055
|
+
18
|
|
1056
|
+
sage: len(S.list())
|
|
1057
|
+
18
|
|
1058
|
+
|
|
1059
|
+
sage: S = Subsets([1,1,1,2,2,3],submultiset=True)
|
|
1060
|
+
sage: S.cardinality()
|
|
1061
|
+
24
|
|
1062
|
+
sage: len(S.list())
|
|
1063
|
+
24
|
|
1064
|
+
"""
|
|
1065
|
+
from sage.misc.misc_c import prod
|
|
1066
|
+
return Integer(prod(k + 1 for k in self._d.values()))
|
|
1067
|
+
|
|
1068
|
+
def random_element(self):
|
|
1069
|
+
r"""
|
|
1070
|
+
Return a random element of ``self`` with uniform law.
|
|
1071
|
+
|
|
1072
|
+
EXAMPLES::
|
|
1073
|
+
|
|
1074
|
+
sage: S = Subsets([1,1,2,3], submultiset=True)
|
|
1075
|
+
sage: s = S.random_element()
|
|
1076
|
+
sage: s in S
|
|
1077
|
+
True
|
|
1078
|
+
"""
|
|
1079
|
+
l = []
|
|
1080
|
+
for i, di in self._d.items():
|
|
1081
|
+
l.extend([i] * rnd.randint(0, di))
|
|
1082
|
+
return l
|
|
1083
|
+
|
|
1084
|
+
def generating_serie(self, variable='x'):
|
|
1085
|
+
r"""
|
|
1086
|
+
Return the polynomial associated to the counting of the
|
|
1087
|
+
elements of ``self`` weighted by the number of element they contain.
|
|
1088
|
+
|
|
1089
|
+
EXAMPLES::
|
|
1090
|
+
|
|
1091
|
+
sage: Subsets([1,1],submultiset=True).generating_serie()
|
|
1092
|
+
x^2 + x + 1
|
|
1093
|
+
sage: Subsets([1,1,2,3],submultiset=True).generating_serie()
|
|
1094
|
+
x^4 + 3*x^3 + 4*x^2 + 3*x + 1
|
|
1095
|
+
sage: Subsets([1,1,1,2,2,3,3,4],submultiset=True).generating_serie()
|
|
1096
|
+
x^8 + 4*x^7 + 9*x^6 + 14*x^5 + 16*x^4 + 14*x^3 + 9*x^2 + 4*x + 1
|
|
1097
|
+
|
|
1098
|
+
sage: S = Subsets([1,1,1,2,2,3,3,4],submultiset=True)
|
|
1099
|
+
sage: S.cardinality()
|
|
1100
|
+
72
|
|
1101
|
+
sage: sum(S.generating_serie())
|
|
1102
|
+
72
|
|
1103
|
+
"""
|
|
1104
|
+
R = ZZ[variable]
|
|
1105
|
+
return R.prod(R([1] * (n + 1)) for n in self._d.values())
|
|
1106
|
+
|
|
1107
|
+
def __iter__(self):
|
|
1108
|
+
"""
|
|
1109
|
+
Iterate through the subsets of ``self``.
|
|
1110
|
+
|
|
1111
|
+
Note that each subset is represented by a list of its elements
|
|
1112
|
+
rather than a set since we can have multiplicities (no
|
|
1113
|
+
multiset data structure yet in sage).
|
|
1114
|
+
|
|
1115
|
+
EXAMPLES::
|
|
1116
|
+
|
|
1117
|
+
sage: S = Subsets([1,2,2,3], submultiset=True)
|
|
1118
|
+
sage: S.list()
|
|
1119
|
+
[[],
|
|
1120
|
+
[1],
|
|
1121
|
+
[2],
|
|
1122
|
+
[3],
|
|
1123
|
+
[1, 2],
|
|
1124
|
+
[1, 3],
|
|
1125
|
+
[2, 2],
|
|
1126
|
+
[2, 3],
|
|
1127
|
+
[1, 2, 2],
|
|
1128
|
+
[1, 2, 3],
|
|
1129
|
+
[2, 2, 3],
|
|
1130
|
+
[1, 2, 2, 3]]
|
|
1131
|
+
"""
|
|
1132
|
+
for k in range(len(self._l) + 1):
|
|
1133
|
+
yield from SubMultiset_sk(self._l, k)
|
|
1134
|
+
|
|
1135
|
+
def __call__(self, el):
|
|
1136
|
+
r"""
|
|
1137
|
+
Workaround for returning non elements.
|
|
1138
|
+
|
|
1139
|
+
See the extensive documentation in
|
|
1140
|
+
:meth:`sage.sets.finite_enumerated_set.FiniteEnumeratedSet.__call__`.
|
|
1141
|
+
|
|
1142
|
+
TESTS::
|
|
1143
|
+
|
|
1144
|
+
sage: Subsets(['a','b','b','c'], submultiset=True)(['a','b']) # indirect doctest
|
|
1145
|
+
['a', 'b']
|
|
1146
|
+
"""
|
|
1147
|
+
if not isinstance(el, Element):
|
|
1148
|
+
return self._element_constructor_(el)
|
|
1149
|
+
else:
|
|
1150
|
+
return Parent.__call__(self, el)
|
|
1151
|
+
|
|
1152
|
+
def _element_constructor_(self, X):
|
|
1153
|
+
"""
|
|
1154
|
+
TESTS::
|
|
1155
|
+
|
|
1156
|
+
sage: S = Subsets(['a','b','b','c'], submultiset=True)
|
|
1157
|
+
sage: S(['d'])
|
|
1158
|
+
Traceback (most recent call last):
|
|
1159
|
+
...
|
|
1160
|
+
ValueError: ['d'] not in SubMultiset of [...]
|
|
1161
|
+
"""
|
|
1162
|
+
e = self.element_class(X)
|
|
1163
|
+
if e not in self:
|
|
1164
|
+
raise ValueError("{} not in {}".format(e,self))
|
|
1165
|
+
return e
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
class SubMultiset_sk(SubMultiset_s):
|
|
1169
|
+
"""
|
|
1170
|
+
The combinatorial class of the subsets of size ``k`` of a multiset ``s``. Note
|
|
1171
|
+
that each subset is represented by a list of the elements rather than a
|
|
1172
|
+
set since we can have multiplicities (no multiset data structure yet in
|
|
1173
|
+
sage).
|
|
1174
|
+
|
|
1175
|
+
EXAMPLES::
|
|
1176
|
+
|
|
1177
|
+
sage: S = Subsets([1,2,3,3],2,submultiset=True)
|
|
1178
|
+
sage: S._k
|
|
1179
|
+
2
|
|
1180
|
+
sage: S.cardinality()
|
|
1181
|
+
4
|
|
1182
|
+
sage: S.first()
|
|
1183
|
+
[1, 2]
|
|
1184
|
+
sage: S.last()
|
|
1185
|
+
[3, 3]
|
|
1186
|
+
sage: [sub for sub in S]
|
|
1187
|
+
[[1, 2], [1, 3], [2, 3], [3, 3]]
|
|
1188
|
+
"""
|
|
1189
|
+
|
|
1190
|
+
def __init__(self, s, k):
|
|
1191
|
+
"""
|
|
1192
|
+
TESTS::
|
|
1193
|
+
|
|
1194
|
+
sage: S = Subsets([1,2,3,3],2,submultiset=True)
|
|
1195
|
+
sage: [sub for sub in S]
|
|
1196
|
+
[[1, 2], [1, 3], [2, 3], [3, 3]]
|
|
1197
|
+
sage: TestSuite(S).run()
|
|
1198
|
+
"""
|
|
1199
|
+
SubMultiset_s.__init__(self, s)
|
|
1200
|
+
self._k = k
|
|
1201
|
+
|
|
1202
|
+
def __eq__(self, other):
|
|
1203
|
+
r"""
|
|
1204
|
+
TESTS::
|
|
1205
|
+
|
|
1206
|
+
sage: Subsets([1,2,2,3], submultiset=True) == Subsets([1,2,2,3], submultiset=True)
|
|
1207
|
+
True
|
|
1208
|
+
sage: Subsets([1,2,2,3], submultiset=True) == Subsets([1,2,3,3], submultiset=True)
|
|
1209
|
+
False
|
|
1210
|
+
"""
|
|
1211
|
+
if self.__class__ != other.__class__:
|
|
1212
|
+
return False
|
|
1213
|
+
return self._d == other._d and self._k == other._k
|
|
1214
|
+
|
|
1215
|
+
def generating_serie(self, variable='x'):
|
|
1216
|
+
r"""
|
|
1217
|
+
Return the polynomial associated to the counting of the
|
|
1218
|
+
elements of ``self`` weighted by the number of elements they contains
|
|
1219
|
+
|
|
1220
|
+
EXAMPLES::
|
|
1221
|
+
|
|
1222
|
+
sage: x = ZZ['x'].gen()
|
|
1223
|
+
sage: l = [1,1,1,1,2,2,3]
|
|
1224
|
+
sage: for k in range(len(l)):
|
|
1225
|
+
....: S = Subsets(l,k,submultiset=True)
|
|
1226
|
+
....: print(S.generating_serie('x') == S.cardinality()*x**k)
|
|
1227
|
+
True
|
|
1228
|
+
True
|
|
1229
|
+
True
|
|
1230
|
+
True
|
|
1231
|
+
True
|
|
1232
|
+
True
|
|
1233
|
+
True
|
|
1234
|
+
"""
|
|
1235
|
+
x = ZZ[variable].gen()
|
|
1236
|
+
P = SubMultiset_s.generating_serie(self)
|
|
1237
|
+
return P[self._k] * (x**self._k)
|
|
1238
|
+
|
|
1239
|
+
def cardinality(self):
|
|
1240
|
+
r"""
|
|
1241
|
+
Return the cardinality of ``self``.
|
|
1242
|
+
|
|
1243
|
+
EXAMPLES::
|
|
1244
|
+
|
|
1245
|
+
sage: S = Subsets([1,2,2,3,3,3],4,submultiset=True)
|
|
1246
|
+
sage: S.cardinality()
|
|
1247
|
+
5
|
|
1248
|
+
sage: len(list(S))
|
|
1249
|
+
5
|
|
1250
|
+
|
|
1251
|
+
sage: S = Subsets([1,2,2,3,3,3],3,submultiset=True)
|
|
1252
|
+
sage: S.cardinality()
|
|
1253
|
+
6
|
|
1254
|
+
sage: len(list(S))
|
|
1255
|
+
6
|
|
1256
|
+
"""
|
|
1257
|
+
return Integer(sum(1 for _ in self))
|
|
1258
|
+
|
|
1259
|
+
def _repr_(self):
|
|
1260
|
+
"""
|
|
1261
|
+
TESTS::
|
|
1262
|
+
|
|
1263
|
+
sage: S = Subsets([1, 2, 2, 3], 3, submultiset=True)
|
|
1264
|
+
sage: repr(S) #indirect doctest
|
|
1265
|
+
'SubMultiset of [1, 2, 2, 3] of size 3'
|
|
1266
|
+
"""
|
|
1267
|
+
return "{} of size {}".format(SubMultiset_s._repr_(self), self._k)
|
|
1268
|
+
|
|
1269
|
+
def __contains__(self, s):
|
|
1270
|
+
"""
|
|
1271
|
+
TESTS::
|
|
1272
|
+
|
|
1273
|
+
sage: S = Subsets([1,2,2,3], 2, submultiset=True)
|
|
1274
|
+
sage: [] in S
|
|
1275
|
+
False
|
|
1276
|
+
sage: [1, 2, 2] in S
|
|
1277
|
+
False
|
|
1278
|
+
sage: all(i in S for i in S)
|
|
1279
|
+
True
|
|
1280
|
+
sage: [2, 2] in S
|
|
1281
|
+
True
|
|
1282
|
+
sage: [1, 3] in S
|
|
1283
|
+
True
|
|
1284
|
+
sage: [4] in S
|
|
1285
|
+
False
|
|
1286
|
+
sage: [3, 3] in S
|
|
1287
|
+
False
|
|
1288
|
+
"""
|
|
1289
|
+
return len(s) == self._k and SubMultiset_s.__contains__(self, s)
|
|
1290
|
+
|
|
1291
|
+
def random_element(self):
|
|
1292
|
+
r"""
|
|
1293
|
+
Return a random submultiset of given length.
|
|
1294
|
+
|
|
1295
|
+
EXAMPLES::
|
|
1296
|
+
|
|
1297
|
+
sage: s = Subsets(7,3).random_element()
|
|
1298
|
+
sage: s in Subsets(7,3)
|
|
1299
|
+
True
|
|
1300
|
+
|
|
1301
|
+
sage: s = Subsets(7,5).random_element()
|
|
1302
|
+
sage: s in Subsets(7,5)
|
|
1303
|
+
True
|
|
1304
|
+
"""
|
|
1305
|
+
return rnd.sample(self._l, self._k)
|
|
1306
|
+
|
|
1307
|
+
def __iter__(self):
|
|
1308
|
+
"""
|
|
1309
|
+
Iterate through the subsets of size ``self._k`` of the multiset
|
|
1310
|
+
``self._s``.
|
|
1311
|
+
|
|
1312
|
+
Note that each subset is represented by a list of the
|
|
1313
|
+
elements rather than a set since we can have multiplicities (no
|
|
1314
|
+
multiset data structure yet in sage).
|
|
1315
|
+
|
|
1316
|
+
EXAMPLES::
|
|
1317
|
+
|
|
1318
|
+
sage: S = Subsets([1,2,2,3],2, submultiset=True)
|
|
1319
|
+
sage: S.list()
|
|
1320
|
+
[[1, 2], [1, 3], [2, 2], [2, 3]]
|
|
1321
|
+
|
|
1322
|
+
Check that :issue:`28588` is fixed::
|
|
1323
|
+
|
|
1324
|
+
sage: Subsets([3,2,2], submultiset=True).list()
|
|
1325
|
+
[[], [3], [2], [3, 2], [2, 2], [3, 2, 2]]
|
|
1326
|
+
"""
|
|
1327
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
1328
|
+
elts = self._keys
|
|
1329
|
+
for iv in IntegerVectors(self._k, len(self._d),
|
|
1330
|
+
outer=[self._d[k] for k in elts]):
|
|
1331
|
+
yield sum([[elts[i]] * iv[i] for i in range(len(iv))], [])
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
class SubsetsSorted(Subsets_s):
|
|
1335
|
+
"""
|
|
1336
|
+
Lightweight class of all subsets of some set `S`, with each
|
|
1337
|
+
subset being encoded as a sorted tuple.
|
|
1338
|
+
|
|
1339
|
+
Used to model indices of algebras given by subsets (so we don't
|
|
1340
|
+
have to explicitly build all `2^n` subsets in memory).
|
|
1341
|
+
For example, :class:`CliffordAlgebra`.
|
|
1342
|
+
"""
|
|
1343
|
+
element_class = tuple
|
|
1344
|
+
|
|
1345
|
+
def __contains__(self, value):
|
|
1346
|
+
"""
|
|
1347
|
+
TESTS::
|
|
1348
|
+
|
|
1349
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1350
|
+
sage: S = SubsetsSorted(range(3))
|
|
1351
|
+
sage: Set([1,2]) in S
|
|
1352
|
+
True
|
|
1353
|
+
sage: Set([1,4]) in S
|
|
1354
|
+
False
|
|
1355
|
+
sage: Set([]) in S
|
|
1356
|
+
True
|
|
1357
|
+
sage: (0,2) in S
|
|
1358
|
+
True
|
|
1359
|
+
sage: 2 in S
|
|
1360
|
+
False
|
|
1361
|
+
"""
|
|
1362
|
+
if not isinstance(value, (list, tuple)) and value not in Sets():
|
|
1363
|
+
return False
|
|
1364
|
+
return all(v in self._s for v in value)
|
|
1365
|
+
|
|
1366
|
+
def __iter__(self):
|
|
1367
|
+
"""
|
|
1368
|
+
Iterate over ``self``.
|
|
1369
|
+
|
|
1370
|
+
EXAMPLES::
|
|
1371
|
+
|
|
1372
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1373
|
+
sage: S = SubsetsSorted(range(3))
|
|
1374
|
+
sage: [s for s in S]
|
|
1375
|
+
[(), (0,), (1,), (2,), (0, 1), (0, 2), (1, 2), (0, 1, 2)]
|
|
1376
|
+
"""
|
|
1377
|
+
k = ZZ_0
|
|
1378
|
+
while k <= self._s.cardinality():
|
|
1379
|
+
for ss in Subsets_sk(self._s, k)._fast_iterator():
|
|
1380
|
+
yield self.element_class(sorted(ss))
|
|
1381
|
+
k += 1
|
|
1382
|
+
|
|
1383
|
+
def first(self):
|
|
1384
|
+
"""
|
|
1385
|
+
Return the first element of ``self``.
|
|
1386
|
+
|
|
1387
|
+
EXAMPLES::
|
|
1388
|
+
|
|
1389
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1390
|
+
sage: S = SubsetsSorted(range(3))
|
|
1391
|
+
sage: S.first()
|
|
1392
|
+
()
|
|
1393
|
+
"""
|
|
1394
|
+
return self.element_class([])
|
|
1395
|
+
|
|
1396
|
+
def last(self):
|
|
1397
|
+
"""
|
|
1398
|
+
Return the last element of ``self``.
|
|
1399
|
+
|
|
1400
|
+
EXAMPLES::
|
|
1401
|
+
|
|
1402
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1403
|
+
sage: S = SubsetsSorted(range(3))
|
|
1404
|
+
sage: S.last()
|
|
1405
|
+
(0, 1, 2)
|
|
1406
|
+
"""
|
|
1407
|
+
return tuple(sorted(self._s))
|
|
1408
|
+
|
|
1409
|
+
def random_element(self):
|
|
1410
|
+
"""
|
|
1411
|
+
Return a random element of ``self``.
|
|
1412
|
+
|
|
1413
|
+
EXAMPLES::
|
|
1414
|
+
|
|
1415
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1416
|
+
sage: S = SubsetsSorted(range(3))
|
|
1417
|
+
sage: isinstance(S.random_element(), tuple)
|
|
1418
|
+
True
|
|
1419
|
+
"""
|
|
1420
|
+
return tuple(sorted(Subsets_s.random_element(self)))
|
|
1421
|
+
|
|
1422
|
+
def unrank(self, r):
|
|
1423
|
+
"""
|
|
1424
|
+
Return the subset which has rank ``r``.
|
|
1425
|
+
|
|
1426
|
+
EXAMPLES::
|
|
1427
|
+
|
|
1428
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1429
|
+
sage: S = SubsetsSorted(range(3))
|
|
1430
|
+
sage: S.unrank(4)
|
|
1431
|
+
(0, 1)
|
|
1432
|
+
"""
|
|
1433
|
+
r = Integer(r)
|
|
1434
|
+
if r >= self.cardinality() or r < 0:
|
|
1435
|
+
raise IndexError("index out of range")
|
|
1436
|
+
|
|
1437
|
+
k = ZZ_0
|
|
1438
|
+
n = self._s.cardinality()
|
|
1439
|
+
binom = ZZ.one()
|
|
1440
|
+
while r >= binom:
|
|
1441
|
+
r -= binom
|
|
1442
|
+
k += 1
|
|
1443
|
+
binom = binomial(n,k)
|
|
1444
|
+
C = combination.from_rank(r, n, k)
|
|
1445
|
+
return self.element_class(sorted([self._s.unrank(i) for i in C]))
|
|
1446
|
+
|
|
1447
|
+
def _an_element_(self):
|
|
1448
|
+
"""
|
|
1449
|
+
Return an element of ``self``.
|
|
1450
|
+
|
|
1451
|
+
EXAMPLES::
|
|
1452
|
+
|
|
1453
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1454
|
+
sage: S = SubsetsSorted(range(3))
|
|
1455
|
+
sage: S.an_element()
|
|
1456
|
+
(0, 1)
|
|
1457
|
+
"""
|
|
1458
|
+
return self.element_class(sorted(Subsets_s._an_element_(self)))
|
|
1459
|
+
|
|
1460
|
+
def _element_constructor_(self, x):
|
|
1461
|
+
"""
|
|
1462
|
+
Construct an element of ``self``.
|
|
1463
|
+
|
|
1464
|
+
EXAMPLES::
|
|
1465
|
+
|
|
1466
|
+
sage: from sage.combinat.subset import SubsetsSorted
|
|
1467
|
+
sage: S = SubsetsSorted(range(3))
|
|
1468
|
+
sage: [s for s in S]
|
|
1469
|
+
[(), (0,), (1,), (2,), (0, 1), (0, 2), (1, 2), (0, 1, 2)]
|
|
1470
|
+
"""
|
|
1471
|
+
return self.element_class(sorted(set(x)))
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
def powerset(X):
|
|
1475
|
+
r"""
|
|
1476
|
+
Iterator over the *list* of all subsets of the iterable ``X``, in no
|
|
1477
|
+
particular order. Each list appears exactly once, up to order.
|
|
1478
|
+
|
|
1479
|
+
INPUT:
|
|
1480
|
+
|
|
1481
|
+
- ``X`` -- an iterable
|
|
1482
|
+
|
|
1483
|
+
OUTPUT: iterator of lists
|
|
1484
|
+
|
|
1485
|
+
EXAMPLES::
|
|
1486
|
+
|
|
1487
|
+
sage: list(powerset([1,2,3]))
|
|
1488
|
+
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
|
|
1489
|
+
sage: [z for z in powerset([0,[1,2]])]
|
|
1490
|
+
[[], [0], [[1, 2]], [0, [1, 2]]]
|
|
1491
|
+
|
|
1492
|
+
Iterating over the power set of an infinite set is also allowed::
|
|
1493
|
+
|
|
1494
|
+
sage: i = 0
|
|
1495
|
+
sage: L = []
|
|
1496
|
+
sage: for x in powerset(ZZ):
|
|
1497
|
+
....: if i > 10:
|
|
1498
|
+
....: break
|
|
1499
|
+
....: else:
|
|
1500
|
+
....: i += 1
|
|
1501
|
+
....: L.append(x)
|
|
1502
|
+
sage: print(" ".join(str(x) for x in L))
|
|
1503
|
+
[] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2]
|
|
1504
|
+
|
|
1505
|
+
You may also use subsets as an alias for powerset::
|
|
1506
|
+
|
|
1507
|
+
sage: subsets([1,2,3])
|
|
1508
|
+
<generator object ...powerset at 0x...>
|
|
1509
|
+
sage: list(subsets([1,2,3]))
|
|
1510
|
+
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
|
|
1511
|
+
|
|
1512
|
+
The reason we return lists instead of sets is that the elements of
|
|
1513
|
+
sets must be hashable and many structures on which one wants the
|
|
1514
|
+
powerset consist of non-hashable objects.
|
|
1515
|
+
|
|
1516
|
+
AUTHORS:
|
|
1517
|
+
|
|
1518
|
+
- William Stein
|
|
1519
|
+
|
|
1520
|
+
- Nils Bruin (2006-12-19): rewrite to work for not-necessarily
|
|
1521
|
+
finite objects X.
|
|
1522
|
+
"""
|
|
1523
|
+
yield []
|
|
1524
|
+
pairs = []
|
|
1525
|
+
power2 = 1
|
|
1526
|
+
for x in X:
|
|
1527
|
+
pairs.append((power2, x))
|
|
1528
|
+
next_power2 = power2 << 1
|
|
1529
|
+
for w in range(power2, next_power2):
|
|
1530
|
+
yield [x for m, x in pairs if m & w]
|
|
1531
|
+
power2 = next_power2
|
|
1532
|
+
|
|
1533
|
+
|
|
1534
|
+
subsets = powerset
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
def uniq(L):
|
|
1538
|
+
"""
|
|
1539
|
+
Iterate over the elements of ``L``, yielding every element at most
|
|
1540
|
+
once: keep only the first occurrence of any item.
|
|
1541
|
+
|
|
1542
|
+
The items must be hashable.
|
|
1543
|
+
|
|
1544
|
+
INPUT:
|
|
1545
|
+
|
|
1546
|
+
- ``L`` -- iterable
|
|
1547
|
+
|
|
1548
|
+
EXAMPLES::
|
|
1549
|
+
|
|
1550
|
+
sage: L = [1, 1, 8, -5, 3, -5, 'a', 'x', 'a']
|
|
1551
|
+
sage: it = uniq(L); it
|
|
1552
|
+
<generator object uniq at ...>
|
|
1553
|
+
sage: list(it)
|
|
1554
|
+
[1, 8, -5, 3, 'a', 'x']
|
|
1555
|
+
"""
|
|
1556
|
+
seen = set()
|
|
1557
|
+
for x in L:
|
|
1558
|
+
if x in seen:
|
|
1559
|
+
continue
|
|
1560
|
+
yield x
|
|
1561
|
+
seen.add(x)
|